|
@@ -1,57 +1,68 @@
|
|
-from dataclasses import fields
|
|
|
|
-from typing import Optional, Callable, Any, Dict, Union, Literal
|
|
|
|
|
|
+from typing import Any, Callable, Dict, Literal, Optional
|
|
|
|
|
|
from ..element import Element
|
|
from ..element import Element
|
|
-from ..events import ScrollEventArguments, ScrollInfo
|
|
|
|
|
|
+from ..events import ScrollEventArguments, handle_event
|
|
|
|
|
|
|
|
|
|
class ScrollArea(Element):
|
|
class ScrollArea(Element):
|
|
|
|
|
|
- def __init__(self, *,
|
|
|
|
- on_scroll: Optional[Callable[..., Any]] = None) -> None:
|
|
|
|
|
|
+ def __init__(self, *, on_scroll: Optional[Callable[..., Any]] = None) -> None:
|
|
"""Scroll Area
|
|
"""Scroll Area
|
|
|
|
|
|
A way of customizing the scrollbars by encapsulating your content.
|
|
A way of customizing the scrollbars by encapsulating your content.
|
|
- This element exposes the Quasar `ScrollArea <https://quasar.dev/vue-components/scroll-area/>`_ component
|
|
|
|
|
|
+ This element exposes the Quasar `ScrollArea <https://quasar.dev/vue-components/scroll-area/>`_ component.
|
|
|
|
+
|
|
|
|
+ :param on_scroll: function to be called when the scroll position changes
|
|
"""
|
|
"""
|
|
super().__init__('q-scroll-area')
|
|
super().__init__('q-scroll-area')
|
|
- self._classes = ['nicegui-scroll']
|
|
|
|
|
|
+ self._classes = ['nicegui-scroll-area']
|
|
|
|
|
|
if on_scroll:
|
|
if on_scroll:
|
|
- self.on('scroll',
|
|
|
|
- lambda x: self._handle_scroll(on_scroll=on_scroll, msg=x), args=[x.name for x in fields(ScrollInfo)]
|
|
|
|
- )
|
|
|
|
|
|
+ self.on('scroll', lambda msg: self._handle_scroll(on_scroll, msg), args=[
|
|
|
|
+ 'verticalPosition',
|
|
|
|
+ 'verticalPercentage',
|
|
|
|
+ 'verticalSize',
|
|
|
|
+ 'verticalContainerSize',
|
|
|
|
+ 'horizontalPosition',
|
|
|
|
+ 'horizontalPercentage',
|
|
|
|
+ 'horizontalSize',
|
|
|
|
+ 'horizontalContainerSize',
|
|
|
|
+ ])
|
|
|
|
|
|
- def _handle_scroll(self, on_scroll: Callable, msg: Dict):
|
|
|
|
- on_scroll(ScrollEventArguments(
|
|
|
|
|
|
+ def _handle_scroll(self, on_scroll: Callable[..., Any], msg: Dict) -> None:
|
|
|
|
+ handle_event(on_scroll, ScrollEventArguments(
|
|
sender=self,
|
|
sender=self,
|
|
client=self.client,
|
|
client=self.client,
|
|
- info=ScrollInfo(**msg['args'])
|
|
|
|
|
|
+ vertical_position=msg['args']['verticalPosition'],
|
|
|
|
+ vertical_percentage=msg['args']['verticalPercentage'],
|
|
|
|
+ vertical_size=msg['args']['verticalSize'],
|
|
|
|
+ vertical_container_size=msg['args']['verticalContainerSize'],
|
|
|
|
+ horizontal_position=msg['args']['horizontalPosition'],
|
|
|
|
+ horizontal_percentage=msg['args']['horizontalPercentage'],
|
|
|
|
+ horizontal_size=msg['args']['horizontalSize'],
|
|
|
|
+ horizontal_container_size=msg['args']['horizontalContainerSize'],
|
|
))
|
|
))
|
|
|
|
|
|
- def set_scroll_position(self, offset: Union[int, float], *,
|
|
|
|
- axis: Literal['vertical', 'horizontal'] = 'vertical', duration_ms: int = 0
|
|
|
|
- ) -> None:
|
|
|
|
- """
|
|
|
|
- Set the scroll area position in percentage (float) or pixel number (int).
|
|
|
|
|
|
+ def scroll_to(self, *,
|
|
|
|
+ pixels: Optional[float] = None,
|
|
|
|
+ percent: Optional[float] = None,
|
|
|
|
+ axis: Literal['vertical', 'horizontal'] = 'vertical',
|
|
|
|
+ duration: float = 0.0,
|
|
|
|
+ ) -> None:
|
|
|
|
+ """Set the scroll area position in percentage (float) or pixel number (int).
|
|
|
|
+
|
|
You can add a delay to the actual scroll action with the `duration_ms` parameter.
|
|
You can add a delay to the actual scroll action with the `duration_ms` parameter.
|
|
|
|
|
|
- :param offset: Scroll position offset from top in pixels or percentage (0.0 <= x <= 1.0) of the total scrolling
|
|
|
|
- size
|
|
|
|
- :param axis: Scroll axis to set
|
|
|
|
- :param duration_ms: Duration (in milliseconds) enabling animated scroll
|
|
|
|
|
|
+ :param pixels: scroll position offset from top in pixels
|
|
|
|
+ :param percent: scroll position offset from top in percentage of the total scrolling size
|
|
|
|
+ :param axis: scroll axis
|
|
|
|
+ :param duration: animation duration (in seconds, default: 0.0 means no animation)
|
|
"""
|
|
"""
|
|
- if offset < 0:
|
|
|
|
- raise ValueError(f'scroll offset must be positive. Got: {offset}')
|
|
|
|
-
|
|
|
|
- if type(offset) == int:
|
|
|
|
- self.run_method('setScrollPosition', axis, offset, duration_ms)
|
|
|
|
-
|
|
|
|
- elif type(offset) == float and offset > 1.0:
|
|
|
|
- raise ValueError(f'a percentage scroll offset must be 0.0 <= x <= 1.0. Got: {offset}')
|
|
|
|
-
|
|
|
|
- elif type(offset) == float and offset <= 1.0:
|
|
|
|
- self.run_method('setScrollPercentage', axis, offset, duration_ms)
|
|
|
|
-
|
|
|
|
|
|
+ if pixels is not None and percent is not None:
|
|
|
|
+ raise ValueError('You can only specify one of pixels or percent')
|
|
|
|
+ if pixels is not None:
|
|
|
|
+ self.run_method('setScrollPosition', axis, pixels, 1000 * duration)
|
|
|
|
+ elif percent is not None:
|
|
|
|
+ self.run_method('setScrollPercentage', axis, percent, 1000 * duration)
|
|
else:
|
|
else:
|
|
- raise ValueError(f'Got unsupported offset: {offset}')
|
|
|
|
|
|
+ raise ValueError('You must specify one of pixels or percent')
|