-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #67 from scipp/switchable-widget
Switchable widget.
- Loading branch information
Showing
7 changed files
with
174 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,3 +3,4 @@ | |
|
||
pytest | ||
numpy | ||
ipywidgets |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,69 @@ | ||
# SHA1:43a90d54540ba9fdbb2c21a785a9d5d7483af53b | ||
# SHA1:8c92c02ac11274f9d1f3b5b2fa648275b8e32140 | ||
# | ||
# This file is autogenerated by pip-compile-multi | ||
# To update, run: | ||
# | ||
# pip-compile-multi | ||
# | ||
asttokens==2.4.1 | ||
# via stack-data | ||
comm==0.2.2 | ||
# via ipywidgets | ||
decorator==5.1.1 | ||
# via ipython | ||
exceptiongroup==1.2.2 | ||
# via pytest | ||
# via | ||
# ipython | ||
# pytest | ||
executing==2.0.1 | ||
# via stack-data | ||
iniconfig==2.0.0 | ||
# via pytest | ||
ipython==8.26.0 | ||
# via ipywidgets | ||
ipywidgets==8.1.3 | ||
# via -r basetest.in | ||
jedi==0.19.1 | ||
# via ipython | ||
jupyterlab-widgets==3.0.11 | ||
# via ipywidgets | ||
matplotlib-inline==0.1.7 | ||
# via ipython | ||
numpy==2.0.1 | ||
# via -r basetest.in | ||
packaging==24.1 | ||
# via pytest | ||
parso==0.8.4 | ||
# via jedi | ||
pexpect==4.9.0 | ||
# via ipython | ||
pluggy==1.5.0 | ||
# via pytest | ||
prompt-toolkit==3.0.47 | ||
# via ipython | ||
ptyprocess==0.7.0 | ||
# via pexpect | ||
pure-eval==0.2.3 | ||
# via stack-data | ||
pygments==2.18.0 | ||
# via ipython | ||
pytest==8.3.2 | ||
# via -r basetest.in | ||
six==1.16.0 | ||
# via asttokens | ||
stack-data==0.6.3 | ||
# via ipython | ||
tomli==2.0.1 | ||
# via pytest | ||
traitlets==5.14.3 | ||
# via | ||
# comm | ||
# ipython | ||
# ipywidgets | ||
# matplotlib-inline | ||
typing-extensions==4.12.2 | ||
# via ipython | ||
wcwidth==0.2.13 | ||
# via prompt-toolkit | ||
widgetsnbextension==4.0.11 | ||
# via ipywidgets |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# SPDX-License-Identifier: BSD-3-Clause | ||
# Copyright (c) 2024 Scipp contributors (https://github.com/scipp) | ||
from typing import Any | ||
|
||
from ipywidgets import Checkbox, HBox, Label, Stack, Widget | ||
|
||
from ._config import default_style | ||
|
||
|
||
class SwitchWidget(HBox): | ||
"""Wrapper widget to handle switchable widgets. | ||
When you retrieve the value of this widget, | ||
it will return the value of the wrapped widget. | ||
It is expected not to be set in the workflow if ``enabled`` is False. | ||
""" | ||
|
||
def __init__(self, wrapped: Widget, name: str = '') -> None: | ||
super().__init__() | ||
self._enable_box = Checkbox(description='', style=default_style) | ||
# The layout is not applied if they are set in the constructor | ||
self._enable_box.layout.description_width = '0px' | ||
self._enable_box.layout.width = 'auto' | ||
|
||
self.wrapped = wrapped | ||
wrapped_stack = Stack([Label(name, style=default_style), self.wrapped]) | ||
# We wanted to implement this by greying out the widget when disabled | ||
# but ``disabled`` is not a common property of all widgets | ||
wrapped_stack.selected_index = 0 | ||
|
||
def handle_checkbox(change) -> None: | ||
wrapped_stack.selected_index = 1 if change.new else 0 | ||
|
||
self._enable_box.observe(handle_checkbox, names='value') | ||
self.children = [self._enable_box, wrapped_stack] | ||
|
||
@property | ||
def enabled(self) -> bool: | ||
return self._enable_box.value | ||
|
||
@enabled.setter | ||
def enabled(self, value: bool) -> None: | ||
self._enable_box.value = value | ||
|
||
@property | ||
def value(self) -> Any: | ||
return self.wrapped.value |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# SPDX-License-Identifier: BSD-3-Clause | ||
# Copyright (c) 2024 Scipp contributors (https://github.com/scipp) | ||
from ess.reduce.parameter import Parameter | ||
from ess.reduce.widgets import SwitchWidget, create_parameter_widget | ||
|
||
|
||
def test_switchable_widget_dispatch() -> None: | ||
switchable_param = Parameter('a', 'a', 1, switchable=True) | ||
assert isinstance(create_parameter_widget(switchable_param), SwitchWidget) | ||
non_switchable_param = Parameter('b', 'b', 2, switchable=False) | ||
assert not isinstance(create_parameter_widget(non_switchable_param), SwitchWidget) | ||
|
||
|
||
def test_collect_values_from_disabled_switchable_widget() -> None: | ||
from ess.reduce.ui import collect_values | ||
from ipywidgets import Box, Text, VBox | ||
|
||
enabled_switch_widget = SwitchWidget(Text('int'), name='int') | ||
enabled_switch_widget.enabled = True | ||
disabled_switch_widget = SwitchWidget(Text('float'), name='float') | ||
disabled_switch_widget.enabled = False | ||
non_switch_widget = Text('str') | ||
test_box = VBox( | ||
[ | ||
Box([enabled_switch_widget]), | ||
Box([disabled_switch_widget]), | ||
Box([non_switch_widget]), | ||
] | ||
) | ||
|
||
values = collect_values(test_box, (int, float, str)) | ||
assert values == {int: 'int', str: 'str'} |