Prechádzať zdrojové kódy

Merge pull request #144 from hroemer/main

#107: providing ui.linear_progress and ui.circular_progress elements
Falko Schindler 2 rokov pred
rodič
commit
27c33bb0be

+ 17 - 0
api_docs_and_examples.py

@@ -316,6 +316,12 @@ To overlay an SVG, make the `viewBox` exactly the size of the image and provide
         line_updates = ui.timer(0.1, update_line_plot, active=False)
         line_checkbox = ui.checkbox('active').bind_value(line_updates, 'active')
 
+    with example(ui.linear_progress):
+        ui.linear_progress(value=0.3)
+
+    with example(ui.circular_progress):
+        ui.circular_progress(value=0.67)
+
     with example(ui.scene):
         with ui.scene(width=225, height=225) as scene:
             scene.sphere().material('#4488ff')
@@ -544,6 +550,10 @@ Just pass a property of the model as parameter to these methods to create the bi
             def __init__(self):
                 self.number = 1
 
+            @property
+            def progress(self) -> float:
+                return (self.number - 1) / 2
+
         demo = Demo()
         v = ui.checkbox('visible', value=True)
         with ui.column().bind_visibility_from(v, 'value'):
@@ -551,6 +561,13 @@ Just pass a property of the model as parameter to these methods to create the bi
             ui.toggle({1: 'a', 2: 'b', 3: 'c'}).bind_value(demo, 'number')
             ui.number().bind_value(demo, 'number')
 
+            with ui.linear_progress(target_object=demo, target_name='progress'):
+                with ui.container(classes='absolute-full flex flex-center'):
+                    lbl = ui.label(text='number').classes('text-center text-subtitle2 text-white')
+                    lbl.bind_text_from(demo, 'progress')
+
+            ui.circular_progress(target_object=demo, target_name='progress')
+
     ui_updates = '''#### UI Updates
 
 NiceGUI tries to automatically synchronize the state of UI elements with the client, e.g. when a label text, an input value or style/classes/props of an element have changed.

+ 17 - 0
nicegui/auto_context.py

@@ -74,3 +74,20 @@ class AutoUpdaterForAsyncs:
                 message = yield signal
             except BaseException as err:
                 send, message = iter_throw, err
+
+
+class ContextMixin:
+    """
+    Mixin providing a context manager for additional components.
+    copied from nicegui.elements.group.Group
+    """
+
+    def __enter__(self):
+        self._child_count_on_enter = len(self.view)
+        get_view_stack().append(self.view)
+        return self
+
+    def __exit__(self, *_):
+        get_view_stack().pop()
+        if self._child_count_on_enter != len(self.view):
+            self.update()

+ 11 - 0
nicegui/elements/container.py

@@ -0,0 +1,11 @@
+import justpy as jp
+
+from .group import Group
+
+
+class Container(Group):
+
+    def __init__(self, **kwargs):
+        """QDiv Container"""
+        view = jp.QDiv(temp=True, **kwargs)
+        super().__init__(view)

+ 57 - 0
nicegui/elements/progress.py

@@ -0,0 +1,57 @@
+from .float_element import FloatElement
+from .quasarcommponents import QLinearProgressExtended, QCircularProgressExtended
+from ..auto_context import ContextMixin
+
+
+class LinearProgress(FloatElement, ContextMixin):
+
+    def __init__(self, *, value: float = 0.0, target_object=None, target_name=None, **kwargs):
+        """LinearProgress
+
+        An element to create a linear progress bar wrapping
+        `Linear Progress <https://v1.quasar.dev/vue-components/linear-progress>`_ component.
+
+        :param value: the initial value of the field (ratio 0.0 - 1.0)
+        :param target_object: the object to data bind to
+        :param target_name: the field name of the data bound object
+        """
+        view = QLinearProgressExtended(color='primary', size='1.4rem', value=value, temp=False)
+        super().__init__(view, value=value, on_change=None, **kwargs)
+        if target_object and target_name:
+            self.bind_value_from(target_object=target_object, target_name=target_name)
+
+
+class CircularProgress(FloatElement, ContextMixin):
+
+    def __init__(self, *, value: float = 0.0, target_object=None, target_name=None, show_value: bool = True,
+                 **kwargs):
+        """CircularProgress
+
+        An element to create a linear progress bar wrapping
+        `Circular Progress <https://v1.quasar.dev/vue-components/circular-progress>`_ component.
+
+        :param value: the initial value of the field (ratio 0.0 - 1.0)
+        :param target_object: the object to data bind to
+        :param target_name: the field name of the data bound object
+        """
+        value = self._convert_ratio(value)
+        view = QCircularProgressExtended(color='primary', value=value, temp=False,
+                                         track_color='grey-4',
+                                         center_color='transparent',
+                                         size='xl', show_value=show_value)
+        super().__init__(view, value=value, on_change=None, **kwargs)
+        if target_object and target_name:
+            self.bind_value_from(target_object=target_object, target_name=target_name)
+
+    @property
+    def value(self):
+        val = getattr(self, '_value')
+        return val
+
+    @value.setter
+    def value(self, value):
+        val = self._convert_ratio(value=value)
+        setattr(self, '_value', val)
+
+    def _convert_ratio(self, value: float) -> float:
+        return round(value * 100, 2) if 0.0 <= value <= 1.0 else float(value)

+ 18 - 0
nicegui/elements/quasarcommponents.py

@@ -0,0 +1,18 @@
+from justpy import parse_dict, QCircularProgress, QLinearProgress
+
+
+@parse_dict
+class QCircularProgressExtended(QCircularProgress):
+
+    def __init__(self, **kwargs):
+        super().__init__(**kwargs)
+        self.prop_list.extend(['instant-feedback'])
+
+
+@parse_dict
+class QLinearProgressExtended(QLinearProgress):
+
+    def __init__(self, **kwargs):
+        super().__init__(**kwargs)
+        # add upstream missing properties
+        self.prop_list.extend(['size'])

+ 3 - 0
nicegui/ui.py

@@ -22,6 +22,7 @@ class Ui:
     from .elements.color_picker import ColorPicker as color_picker
     from .elements.colors import Colors as colors
     from .elements.column import Column as column
+    from .elements.container import Container as container
     from .elements.dialog import Dialog as dialog
     from .elements.expansion import Expansion as expansion
     from .elements.html import Html as html
@@ -41,6 +42,8 @@ class Ui:
     from .elements.notify import Notify as notify
     from .elements.number import Number as number
     from .elements.open import open, open_async
+    from .elements.progress import LinearProgress as linear_progress
+    from .elements.progress import CircularProgress as circular_progress
     from .elements.radio import Radio as radio
     from .elements.row import Row as row
     from .elements.scene import Scene as scene