From 116a8feff104764927f033ac9ac0728001b7eb30 Mon Sep 17 00:00:00 2001 From: Kyle Rich Date: Tue, 25 Apr 2023 15:29:31 -0600 Subject: [PATCH 1/4] Add progressbar and switch widgets to web platform. Signed-off-by: Kyle Rich --- web/src/toga_web/factory.py | 10 +++--- web/src/toga_web/libs.py | 9 +++++ web/src/toga_web/widgets/progressbar.py | 47 +++++++++++++++++++++++++ web/src/toga_web/widgets/switch.py | 29 +++++++++++++++ 4 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 web/src/toga_web/widgets/progressbar.py create mode 100644 web/src/toga_web/widgets/switch.py diff --git a/web/src/toga_web/factory.py b/web/src/toga_web/factory.py index f9b822b8c3..17166c75c0 100644 --- a/web/src/toga_web/factory.py +++ b/web/src/toga_web/factory.py @@ -20,12 +20,14 @@ # from .widgets.numberinput import NumberInput # from .widgets.optioncontainer import OptionContainer # from .widgets.passwordinput import PasswordInput -# from .widgets.progressbar import ProgressBar +from .widgets.progressbar import ProgressBar + # from .widgets.scrollcontainer import ScrollContainer # from .widgets.selection import Selection # from .widgets.slider import Slider # from .widgets.splitcontainer import SplitContainer -# from .widgets.switch import Switch +from .widgets.switch import Switch + # from .widgets.table import Table from .widgets.textinput import TextInput @@ -61,12 +63,12 @@ def not_implemented(feature): # 'NumberInput', # 'OptionContainer', # 'PasswordInput', - # 'ProgressBar', + "ProgressBar", # 'ScrollContainer', # 'Selection', # 'Slider', # 'SplitContainer', - # 'Switch', + "Switch", # 'Table', "TextInput", # 'Tree', diff --git a/web/src/toga_web/libs.py b/web/src/toga_web/libs.py index 0d1da284e7..6afa8aaac5 100644 --- a/web/src/toga_web/libs.py +++ b/web/src/toga_web/libs.py @@ -7,6 +7,15 @@ js = None +try: + # Try to import pyodide from the PyScript namespace. + import pyodide +except ModuleNotFoundError: + # To ensure the code can be imported, provide a js symbol + # as a fallback + pyodide = None + + def create_element( tag, id=None, diff --git a/web/src/toga_web/widgets/progressbar.py b/web/src/toga_web/widgets/progressbar.py new file mode 100644 index 0000000000..de65bf9be3 --- /dev/null +++ b/web/src/toga_web/widgets/progressbar.py @@ -0,0 +1,47 @@ +from .base import Widget + + +class ProgressBar(Widget): + def create(self): + self.native = self._create_native_widget("sl-progress-bar") + self._is_running = False + self._value = 0 + self._max = 0 + + def is_running(self): + return self._is_running + + def get_value(self): + return self._value + + def set_value(self, value): + self._value = value + self.native.value = self.percentage + + def get_max(self): + return self._max + + def set_max(self, value): + self._max = value + if value is None: + if self._is_running: + self.native.indeterminate = True + else: + self.native.value = self.percentage + self.native.indeterminate = False + + def start(self): + self._is_running = True + if self._max is None: + self.native.indeterminate = True + + def stop(self): + self._is_running = False + self.native.indeterminate = False + + @property + def percentage(self): + if self._max is None or self._max == 0: + return 0 + + return self._value / self._max * 100 diff --git a/web/src/toga_web/widgets/switch.py b/web/src/toga_web/widgets/switch.py new file mode 100644 index 0000000000..99633e4ab1 --- /dev/null +++ b/web/src/toga_web/widgets/switch.py @@ -0,0 +1,29 @@ +from toga_web.libs import pyodide + +from .base import Widget + + +class Switch(Widget): + def create(self): + self.native = self._create_native_widget("sl-switch") + + dom_onchange = pyodide.create_proxy(self.dom_onchange) + self.native.addEventListener("sl-change", dom_onchange) + + def dom_onchange(self, event): + self.interface.on_change(None) + + def get_text(self): + return self.native.innerHTML + + def set_text(self, text): + self.native.innerHTML = text + + def get_value(self): + return self.native.checked + + def set_value(self, value): + old_value = self.get_value() + self.native.checked = value + if value != old_value: + self.interface.on_change(self.interface) From 6a74e4f50dddffb9d85a80b0476c86878be43dfb Mon Sep 17 00:00:00 2001 From: Kyle Rich Date: Tue, 25 Apr 2023 15:36:27 -0600 Subject: [PATCH 2/4] Add news fragment for this PR's changes Signed-off-by: Kyle Rich --- changes/1901.feature.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 changes/1901.feature.rst diff --git a/changes/1901.feature.rst b/changes/1901.feature.rst new file mode 100644 index 0000000000..df25c72d92 --- /dev/null +++ b/changes/1901.feature.rst @@ -0,0 +1 @@ +New ProgressBar and Switch widgets were added to the web platform implementation. From 1f2165db40eb8dfa28c6f82edde0c2f7e86bdaf1 Mon Sep 17 00:00:00 2001 From: Kyle Rich Date: Wed, 26 Apr 2023 09:16:06 -0600 Subject: [PATCH 3/4] Inline proxy function creation, clean up attachment of event listener. Signed-off-by: Kyle Rich --- web/src/toga_web/libs.py | 3 +++ web/src/toga_web/widgets/switch.py | 6 ++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/web/src/toga_web/libs.py b/web/src/toga_web/libs.py index 6afa8aaac5..9e630fe091 100644 --- a/web/src/toga_web/libs.py +++ b/web/src/toga_web/libs.py @@ -16,6 +16,9 @@ pyodide = None +create_proxy = pyodide.create_proxy if pyodide else lambda f: f + + def create_element( tag, id=None, diff --git a/web/src/toga_web/widgets/switch.py b/web/src/toga_web/widgets/switch.py index 99633e4ab1..748ee24ab5 100644 --- a/web/src/toga_web/widgets/switch.py +++ b/web/src/toga_web/widgets/switch.py @@ -1,4 +1,4 @@ -from toga_web.libs import pyodide +from toga_web.libs import create_proxy from .base import Widget @@ -6,9 +6,7 @@ class Switch(Widget): def create(self): self.native = self._create_native_widget("sl-switch") - - dom_onchange = pyodide.create_proxy(self.dom_onchange) - self.native.addEventListener("sl-change", dom_onchange) + self.native.addEventListener("sl-change", create_proxy(self.dom_onchange)) def dom_onchange(self, event): self.interface.on_change(None) From 2586e2e711295d86607acc9b3c059d1e3e896816 Mon Sep 17 00:00:00 2001 From: Kyle Rich Date: Wed, 26 Apr 2023 10:08:18 -0600 Subject: [PATCH 4/4] Update docs showing progress on progressbar and switch widgets Signed-off-by: Kyle Rich --- docs/reference/data/widgets_by_platform.csv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/reference/data/widgets_by_platform.csv b/docs/reference/data/widgets_by_platform.csv index f72ca5f5cd..2dab8c95f1 100644 --- a/docs/reference/data/widgets_by_platform.csv +++ b/docs/reference/data/widgets_by_platform.csv @@ -13,10 +13,10 @@ Label,General Widget,:class:`~toga.widgets.label.Label`,Text label,|y|,|y|,|y|,| MultilineTextInput,General Widget,:class:`~toga.widgets.multilinetextinput.MultilineTextInput`,Multi-line Text Input field,|b|,|b|,|b|,|b|,|b|, NumberInput,General Widget,:class:`~toga.widgets.numberinput.NumberInput`,Number Input field,|b|,|b|,|b|,|b|,|b|, PasswordInput,General Widget,:class:`~toga.widgets.passwordinput.PasswordInput`,A text input that hides it’s input,|b|,|b|,|b|,|b|,|b|, -ProgressBar,General Widget,:class:`~toga.widgets.progressbar.ProgressBar`,Progress Bar,|y|,|y|,|y|,|y|,|y|, +ProgressBar,General Widget,:class:`~toga.widgets.progressbar.ProgressBar`,Progress Bar,|y|,|y|,|y|,|y|,|y|,|b| Selection,General Widget,:class:`~toga.widgets.selection.Selection`,Selection,|b|,|b|,|b|,|b|,|b|, Slider,General Widget,:class:`~toga.widgets.slider.Slider`,Slider,|y|,|y|,|y|,|y|,|y|, -Switch,General Widget,:class:`~toga.widgets.switch.Switch`,Switch,|y|,|y|,|y|,|y|,|y|, +Switch,General Widget,:class:`~toga.widgets.switch.Switch`,Switch,|y|,|y|,|y|,|y|,|y|,|b| Table,General Widget,:class:`~toga.widgets.table.Table`,Table of data,|b|,|b|,|b|,,|b|, TextInput,General Widget,:class:`~toga.widgets.textinput.TextInput`,Text Input field,|b|,|b|,|b|,|b|,|b|,|b| TimePicker,General Widget,:class:`~toga.widgets.timepicker.TimePicker`,An input for times,,,|b|,,|b|,