syd 0.1.3__py3-none-any.whl → 0.1.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- syd/__init__.py +15 -1
- syd/interactive_viewer.py +1139 -81
- syd/notebook_deploy/__init__.py +1 -0
- syd/notebook_deploy/deployer.py +237 -0
- syd/notebook_deploy/widgets.py +471 -0
- syd/parameters.py +1135 -154
- {syd-0.1.3.dist-info → syd-0.1.5.dist-info}/METADATA +10 -2
- syd-0.1.5.dist-info/RECORD +10 -0
- syd/notebook_deploy.py +0 -277
- syd-0.1.3.dist-info/RECORD +0 -8
- {syd-0.1.3.dist-info → syd-0.1.5.dist-info}/WHEEL +0 -0
- {syd-0.1.3.dist-info → syd-0.1.5.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from typing import Any, Dict, Generic, List, TypeVar, Union, Callable
|
|
3
|
+
import ipywidgets as widgets
|
|
4
|
+
|
|
5
|
+
from ..parameters import (
|
|
6
|
+
Parameter,
|
|
7
|
+
TextParameter,
|
|
8
|
+
SelectionParameter,
|
|
9
|
+
MultipleSelectionParameter,
|
|
10
|
+
BooleanParameter,
|
|
11
|
+
IntegerParameter,
|
|
12
|
+
FloatParameter,
|
|
13
|
+
IntegerRangeParameter,
|
|
14
|
+
FloatRangeParameter,
|
|
15
|
+
UnboundedIntegerParameter,
|
|
16
|
+
UnboundedFloatParameter,
|
|
17
|
+
ButtonParameter,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
T = TypeVar("T", bound=Parameter[Any])
|
|
21
|
+
W = TypeVar("W", bound=widgets.Widget)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class BaseParameterWidget(Generic[T, W], ABC):
|
|
25
|
+
"""
|
|
26
|
+
Abstract base class for all parameter widgets.
|
|
27
|
+
|
|
28
|
+
This class defines the common interface and shared functionality
|
|
29
|
+
for widgets that correspond to different parameter types.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
_widget: W
|
|
33
|
+
_callbacks: List[Dict[str, Union[Callable, Union[str, List[str]]]]]
|
|
34
|
+
|
|
35
|
+
def __init__(self, parameter: T, continuous_update: bool = False):
|
|
36
|
+
self._widget = self._create_widget(parameter, continuous_update)
|
|
37
|
+
self._updating = False # Flag to prevent circular updates
|
|
38
|
+
# List of callbacks to remember for quick disabling/enabling
|
|
39
|
+
self._callbacks = []
|
|
40
|
+
|
|
41
|
+
@abstractmethod
|
|
42
|
+
def _create_widget(self, parameter: T, continuous_update: bool) -> W:
|
|
43
|
+
"""Create and return the appropriate ipywidget."""
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def widget(self) -> W:
|
|
48
|
+
"""Get the underlying ipywidget."""
|
|
49
|
+
return self._widget
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def value(self) -> Any:
|
|
53
|
+
"""Get the current value of the widget."""
|
|
54
|
+
return self._widget.value
|
|
55
|
+
|
|
56
|
+
@value.setter
|
|
57
|
+
def value(self, new_value: Any) -> None:
|
|
58
|
+
"""Set the value of the widget."""
|
|
59
|
+
self._widget.value = new_value
|
|
60
|
+
|
|
61
|
+
def matches_parameter(self, parameter: T) -> bool:
|
|
62
|
+
"""Check if the widget matches the parameter."""
|
|
63
|
+
return self.value == parameter.value
|
|
64
|
+
|
|
65
|
+
def update_from_parameter(self, parameter: T) -> None:
|
|
66
|
+
"""Update the widget from the parameter."""
|
|
67
|
+
try:
|
|
68
|
+
self._updating = True
|
|
69
|
+
self.disable_callbacks()
|
|
70
|
+
self.extra_updates_from_parameter(parameter)
|
|
71
|
+
self.value = parameter.value
|
|
72
|
+
finally:
|
|
73
|
+
self.reenable_callbacks()
|
|
74
|
+
self._updating = False
|
|
75
|
+
|
|
76
|
+
def extra_updates_from_parameter(self, parameter: T) -> None:
|
|
77
|
+
"""Extra updates from the parameter."""
|
|
78
|
+
pass
|
|
79
|
+
|
|
80
|
+
def observe(self, callback: Callable) -> None:
|
|
81
|
+
"""Observe the widget and call the callback when the value changes."""
|
|
82
|
+
full_callback = dict(handler=callback, names="value")
|
|
83
|
+
self._widget.observe(**full_callback)
|
|
84
|
+
self._callbacks.append(full_callback)
|
|
85
|
+
|
|
86
|
+
def unobserve(self, callback: Callable[[Any], None]) -> None:
|
|
87
|
+
"""Unobserve the widget and stop calling the callback when the value changes."""
|
|
88
|
+
full_callback = dict(handler=callback, names="value")
|
|
89
|
+
self._widget.unobserve(**full_callback)
|
|
90
|
+
self._callbacks.remove(full_callback)
|
|
91
|
+
|
|
92
|
+
def reenable_callbacks(self) -> None:
|
|
93
|
+
"""Reenable all callbacks from the widget."""
|
|
94
|
+
for callback in self._callbacks:
|
|
95
|
+
self._widget.observe(**callback)
|
|
96
|
+
|
|
97
|
+
def disable_callbacks(self) -> None:
|
|
98
|
+
"""Disable all callbacks from the widget."""
|
|
99
|
+
for callback in self._callbacks:
|
|
100
|
+
self._widget.unobserve(**callback)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class TextParameterWidget(BaseParameterWidget[TextParameter, widgets.Text]):
|
|
104
|
+
"""Widget for text parameters."""
|
|
105
|
+
|
|
106
|
+
def _create_widget(
|
|
107
|
+
self, parameter: TextParameter, continuous_update: bool
|
|
108
|
+
) -> widgets.Text:
|
|
109
|
+
return widgets.Text(
|
|
110
|
+
value=parameter.value,
|
|
111
|
+
description=parameter.name,
|
|
112
|
+
continuous_update=continuous_update,
|
|
113
|
+
layout=widgets.Layout(width="95%"),
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class BooleanParameterWidget(BaseParameterWidget[BooleanParameter, widgets.Checkbox]):
|
|
118
|
+
"""Widget for boolean parameters."""
|
|
119
|
+
|
|
120
|
+
def _create_widget(
|
|
121
|
+
self, parameter: BooleanParameter, continuous_update: bool
|
|
122
|
+
) -> widgets.Checkbox:
|
|
123
|
+
return widgets.Checkbox(value=parameter.value, description=parameter.name)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class SelectionParameterWidget(
|
|
127
|
+
BaseParameterWidget[SelectionParameter, widgets.Dropdown]
|
|
128
|
+
):
|
|
129
|
+
"""Widget for single selection parameters."""
|
|
130
|
+
|
|
131
|
+
def _create_widget(
|
|
132
|
+
self, parameter: SelectionParameter, continuous_update: bool
|
|
133
|
+
) -> widgets.Dropdown:
|
|
134
|
+
return widgets.Dropdown(
|
|
135
|
+
value=parameter.value,
|
|
136
|
+
options=parameter.options,
|
|
137
|
+
description=parameter.name,
|
|
138
|
+
layout=widgets.Layout(width="95%"),
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
def matches_parameter(self, parameter: SelectionParameter) -> bool:
|
|
142
|
+
"""Check if the widget matches the parameter."""
|
|
143
|
+
return (
|
|
144
|
+
self.value == parameter.value and self._widget.options == parameter.options
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
def extra_updates_from_parameter(self, parameter: SelectionParameter) -> None:
|
|
148
|
+
"""Extra updates from the parameter."""
|
|
149
|
+
new_options = parameter.options
|
|
150
|
+
current_value = self._widget.value
|
|
151
|
+
new_value = current_value if current_value in new_options else new_options[0]
|
|
152
|
+
self._widget.options = new_options
|
|
153
|
+
self._widget.value = new_value
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class MultipleSelectionParameterWidget(
|
|
157
|
+
BaseParameterWidget[MultipleSelectionParameter, widgets.SelectMultiple]
|
|
158
|
+
):
|
|
159
|
+
"""Widget for multiple selection parameters."""
|
|
160
|
+
|
|
161
|
+
def _create_widget(
|
|
162
|
+
self, parameter: MultipleSelectionParameter, continuous_update: bool
|
|
163
|
+
) -> widgets.SelectMultiple:
|
|
164
|
+
return widgets.SelectMultiple(
|
|
165
|
+
value=parameter.value,
|
|
166
|
+
options=parameter.options,
|
|
167
|
+
description=parameter.name,
|
|
168
|
+
rows=min(len(parameter.options), 4),
|
|
169
|
+
layout=widgets.Layout(width="95%"),
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
def matches_parameter(self, parameter: MultipleSelectionParameter) -> bool:
|
|
173
|
+
"""Check if the widget matches the parameter."""
|
|
174
|
+
return (
|
|
175
|
+
self.value == parameter.value and self._widget.options == parameter.options
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
def extra_updates_from_parameter(
|
|
179
|
+
self, parameter: MultipleSelectionParameter
|
|
180
|
+
) -> None:
|
|
181
|
+
"""Extra updates from the parameter."""
|
|
182
|
+
new_options = parameter.options
|
|
183
|
+
current_values = set(self._widget.value)
|
|
184
|
+
new_values = [v for v in current_values if v in new_options]
|
|
185
|
+
self._widget.options = new_options
|
|
186
|
+
self._widget.value = new_values
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
class IntegerParameterWidget(BaseParameterWidget[IntegerParameter, widgets.IntSlider]):
|
|
190
|
+
"""Widget for integer parameters."""
|
|
191
|
+
|
|
192
|
+
def _create_widget(
|
|
193
|
+
self, parameter: IntegerParameter, continuous_update: bool
|
|
194
|
+
) -> widgets.IntSlider:
|
|
195
|
+
return widgets.IntSlider(
|
|
196
|
+
value=parameter.value,
|
|
197
|
+
min=parameter.min_value,
|
|
198
|
+
max=parameter.max_value,
|
|
199
|
+
description=parameter.name,
|
|
200
|
+
continuous_update=continuous_update,
|
|
201
|
+
layout=widgets.Layout(width="95%"),
|
|
202
|
+
style={"description_width": "initial"},
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
def matches_parameter(self, parameter: IntegerParameter) -> bool:
|
|
206
|
+
"""Check if the widget matches the parameter."""
|
|
207
|
+
return (
|
|
208
|
+
self.value == parameter.value
|
|
209
|
+
and self._widget.min == parameter.min_value
|
|
210
|
+
and self._widget.max == parameter.max_value
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
def extra_updates_from_parameter(self, parameter: IntegerParameter) -> None:
|
|
214
|
+
"""Extra updates from the parameter."""
|
|
215
|
+
current_value = self._widget.value
|
|
216
|
+
self._widget.min = parameter.min_value
|
|
217
|
+
self._widget.max = parameter.max_value
|
|
218
|
+
self.value = max(parameter.min_value, min(parameter.max_value, current_value))
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
class FloatParameterWidget(BaseParameterWidget[FloatParameter, widgets.FloatSlider]):
|
|
222
|
+
"""Widget for float parameters."""
|
|
223
|
+
|
|
224
|
+
def _create_widget(
|
|
225
|
+
self, parameter: FloatParameter, continuous_update: bool
|
|
226
|
+
) -> widgets.FloatSlider:
|
|
227
|
+
return widgets.FloatSlider(
|
|
228
|
+
value=parameter.value,
|
|
229
|
+
min=parameter.min_value,
|
|
230
|
+
max=parameter.max_value,
|
|
231
|
+
step=parameter.step,
|
|
232
|
+
description=parameter.name,
|
|
233
|
+
continuous_update=continuous_update,
|
|
234
|
+
layout=widgets.Layout(width="95%"),
|
|
235
|
+
style={"description_width": "initial"},
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
def matches_parameter(self, parameter: FloatParameter) -> bool:
|
|
239
|
+
"""Check if the widget matches the parameter."""
|
|
240
|
+
return (
|
|
241
|
+
self.value == parameter.value
|
|
242
|
+
and self._widget.min == parameter.min_value
|
|
243
|
+
and self._widget.max == parameter.max_value
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
def extra_updates_from_parameter(self, parameter: FloatParameter) -> None:
|
|
247
|
+
"""Extra updates from the parameter."""
|
|
248
|
+
current_value = self._widget.value
|
|
249
|
+
self._widget.min = parameter.min_value
|
|
250
|
+
self._widget.max = parameter.max_value
|
|
251
|
+
self._widget.step = parameter.step
|
|
252
|
+
self.value = max(parameter.min_value, min(parameter.max_value, current_value))
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
class IntegerRangeParameterWidget(
|
|
256
|
+
BaseParameterWidget[IntegerRangeParameter, widgets.IntRangeSlider]
|
|
257
|
+
):
|
|
258
|
+
"""Widget for integer range parameters."""
|
|
259
|
+
|
|
260
|
+
def _create_widget(
|
|
261
|
+
self, parameter: IntegerRangeParameter, continuous_update: bool
|
|
262
|
+
) -> widgets.IntRangeSlider:
|
|
263
|
+
return widgets.IntRangeSlider(
|
|
264
|
+
value=parameter.value,
|
|
265
|
+
min=parameter.min_value,
|
|
266
|
+
max=parameter.max_value,
|
|
267
|
+
description=parameter.name,
|
|
268
|
+
continuous_update=continuous_update,
|
|
269
|
+
layout=widgets.Layout(width="95%"),
|
|
270
|
+
style={"description_width": "initial"},
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
def matches_parameter(self, parameter: IntegerRangeParameter) -> bool:
|
|
274
|
+
"""Check if the widget matches the parameter."""
|
|
275
|
+
return (
|
|
276
|
+
self.value == parameter.value
|
|
277
|
+
and self._widget.min == parameter.min_value
|
|
278
|
+
and self._widget.max == parameter.max_value
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
def extra_updates_from_parameter(self, parameter: IntegerRangeParameter) -> None:
|
|
282
|
+
"""Extra updates from the parameter."""
|
|
283
|
+
current_value = self._widget.value
|
|
284
|
+
self._widget.min = parameter.min_value
|
|
285
|
+
self._widget.max = parameter.max_value
|
|
286
|
+
low, high = current_value
|
|
287
|
+
low = max(parameter.min_value, min(parameter.max_value, low))
|
|
288
|
+
high = max(parameter.min_value, min(parameter.max_value, high))
|
|
289
|
+
self.value = (low, high)
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
class FloatRangeParameterWidget(
|
|
293
|
+
BaseParameterWidget[FloatRangeParameter, widgets.FloatRangeSlider]
|
|
294
|
+
):
|
|
295
|
+
"""Widget for float range parameters."""
|
|
296
|
+
|
|
297
|
+
def _create_widget(
|
|
298
|
+
self, parameter: FloatRangeParameter, continuous_update: bool
|
|
299
|
+
) -> widgets.FloatRangeSlider:
|
|
300
|
+
return widgets.FloatRangeSlider(
|
|
301
|
+
value=parameter.value,
|
|
302
|
+
min=parameter.min_value,
|
|
303
|
+
max=parameter.max_value,
|
|
304
|
+
step=parameter.step,
|
|
305
|
+
description=parameter.name,
|
|
306
|
+
continuous_update=continuous_update,
|
|
307
|
+
layout=widgets.Layout(width="95%"),
|
|
308
|
+
style={"description_width": "initial"},
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
def matches_parameter(self, parameter: FloatRangeParameter) -> bool:
|
|
312
|
+
"""Check if the widget matches the parameter."""
|
|
313
|
+
return (
|
|
314
|
+
self.value == parameter.value
|
|
315
|
+
and self._widget.min == parameter.min_value
|
|
316
|
+
and self._widget.max == parameter.max_value
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
def extra_updates_from_parameter(self, parameter: FloatRangeParameter) -> None:
|
|
320
|
+
"""Extra updates from the parameter."""
|
|
321
|
+
current_value = self._widget.value
|
|
322
|
+
self._widget.min = parameter.min_value
|
|
323
|
+
self._widget.max = parameter.max_value
|
|
324
|
+
self._widget.step = parameter.step
|
|
325
|
+
low, high = current_value
|
|
326
|
+
low = max(parameter.min_value, min(parameter.max_value, low))
|
|
327
|
+
high = max(parameter.min_value, min(parameter.max_value, high))
|
|
328
|
+
self.value = (low, high)
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
class UnboundedIntegerParameterWidget(
|
|
332
|
+
BaseParameterWidget[UnboundedIntegerParameter, widgets.BoundedIntText]
|
|
333
|
+
):
|
|
334
|
+
"""Widget for unbounded integer parameters."""
|
|
335
|
+
|
|
336
|
+
def _create_widget(
|
|
337
|
+
self, parameter: UnboundedIntegerParameter, continuous_update: bool
|
|
338
|
+
) -> widgets.BoundedIntText:
|
|
339
|
+
return widgets.BoundedIntText(
|
|
340
|
+
value=parameter.value,
|
|
341
|
+
min=parameter.min_value,
|
|
342
|
+
max=parameter.max_value,
|
|
343
|
+
description=parameter.name,
|
|
344
|
+
layout=widgets.Layout(width="95%"),
|
|
345
|
+
style={"description_width": "initial"},
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
def matches_parameter(self, parameter: UnboundedIntegerParameter) -> bool:
|
|
349
|
+
"""Check if the widget matches the parameter."""
|
|
350
|
+
return self.value == parameter.value
|
|
351
|
+
|
|
352
|
+
def extra_updates_from_parameter(
|
|
353
|
+
self, parameter: UnboundedIntegerParameter
|
|
354
|
+
) -> None:
|
|
355
|
+
"""Extra updates from the parameter."""
|
|
356
|
+
if parameter.min_value is not None:
|
|
357
|
+
self._widget.min = parameter.min_value
|
|
358
|
+
if parameter.max_value is not None:
|
|
359
|
+
self._widget.max = parameter.max_value
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
class UnboundedFloatParameterWidget(
|
|
363
|
+
BaseParameterWidget[UnboundedFloatParameter, widgets.BoundedFloatText]
|
|
364
|
+
):
|
|
365
|
+
"""Widget for unbounded float parameters."""
|
|
366
|
+
|
|
367
|
+
def _create_widget(
|
|
368
|
+
self, parameter: UnboundedFloatParameter, continuous_update: bool
|
|
369
|
+
) -> widgets.BoundedFloatText:
|
|
370
|
+
return widgets.BoundedFloatText(
|
|
371
|
+
value=parameter.value,
|
|
372
|
+
min=parameter.min_value,
|
|
373
|
+
max=parameter.max_value,
|
|
374
|
+
step=parameter.step,
|
|
375
|
+
description=parameter.name,
|
|
376
|
+
layout=widgets.Layout(width="95%"),
|
|
377
|
+
style={"description_width": "initial"},
|
|
378
|
+
)
|
|
379
|
+
|
|
380
|
+
def matches_parameter(self, parameter: UnboundedFloatParameter) -> bool:
|
|
381
|
+
"""Check if the widget matches the parameter."""
|
|
382
|
+
return self.value == parameter.value
|
|
383
|
+
|
|
384
|
+
def extra_updates_from_parameter(self, parameter: UnboundedFloatParameter) -> None:
|
|
385
|
+
"""Extra updates from the parameter."""
|
|
386
|
+
if parameter.min_value is not None:
|
|
387
|
+
self._widget.min = parameter.min_value
|
|
388
|
+
if parameter.max_value is not None:
|
|
389
|
+
self._widget.max = parameter.max_value
|
|
390
|
+
self._widget.step = parameter.step
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
class ButtonParameterWidget(BaseParameterWidget[ButtonParameter, widgets.Button]):
|
|
394
|
+
"""Widget for button parameters."""
|
|
395
|
+
|
|
396
|
+
_is_button: bool = True
|
|
397
|
+
|
|
398
|
+
def _create_widget(
|
|
399
|
+
self, parameter: ButtonParameter, continuous_update: bool
|
|
400
|
+
) -> widgets.Button:
|
|
401
|
+
button = widgets.Button(
|
|
402
|
+
description=parameter.label,
|
|
403
|
+
layout=widgets.Layout(width="auto"),
|
|
404
|
+
style={"description_width": "initial"},
|
|
405
|
+
)
|
|
406
|
+
button.on_click(parameter.callback)
|
|
407
|
+
return button
|
|
408
|
+
|
|
409
|
+
def matches_parameter(self, parameter: ButtonParameter) -> bool:
|
|
410
|
+
"""Check if the widget matches the parameter."""
|
|
411
|
+
return self._widget.description == parameter.label
|
|
412
|
+
|
|
413
|
+
def extra_updates_from_parameter(self, parameter: ButtonParameter) -> None:
|
|
414
|
+
"""Extra updates from the parameter."""
|
|
415
|
+
self._widget.description = parameter.label
|
|
416
|
+
# Update click handler
|
|
417
|
+
self._widget.on_click(parameter.callback, remove=True) # Remove old handler
|
|
418
|
+
self._widget.on_click(parameter.callback) # Add new handler
|
|
419
|
+
|
|
420
|
+
def observe(self, callback: Callable) -> None:
|
|
421
|
+
"""Observe the widget and call the callback when the value changes."""
|
|
422
|
+
self._widget.on_click(callback)
|
|
423
|
+
self._callbacks.append(callback)
|
|
424
|
+
|
|
425
|
+
def unobserve(self, callback: Callable[[Any], None]) -> None:
|
|
426
|
+
"""Unobserve the widget and stop calling the callback when the value changes."""
|
|
427
|
+
self._widget.on_click(None)
|
|
428
|
+
self._callbacks.remove(callback)
|
|
429
|
+
|
|
430
|
+
def reenable_callbacks(self) -> None:
|
|
431
|
+
"""Reenable all callbacks from the widget."""
|
|
432
|
+
for callback in self._callbacks:
|
|
433
|
+
self._widget.on_click(callback)
|
|
434
|
+
|
|
435
|
+
def disable_callbacks(self) -> None:
|
|
436
|
+
"""Disable all callbacks from the widget."""
|
|
437
|
+
for callback in self._callbacks:
|
|
438
|
+
self._widget.on_click(None)
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
def create_parameter_widget(
|
|
442
|
+
parameter: Parameter[Any],
|
|
443
|
+
continuous_update: bool = False,
|
|
444
|
+
) -> BaseParameterWidget[Parameter[Any], widgets.Widget]:
|
|
445
|
+
"""Create and return the appropriate widget for the given parameter.
|
|
446
|
+
|
|
447
|
+
Args:
|
|
448
|
+
parameter: The parameter to create a widget for
|
|
449
|
+
continuous_update: Whether to update the widget value continuously during user interaction
|
|
450
|
+
"""
|
|
451
|
+
widget_map = {
|
|
452
|
+
TextParameter: TextParameterWidget,
|
|
453
|
+
SelectionParameter: SelectionParameterWidget,
|
|
454
|
+
MultipleSelectionParameter: MultipleSelectionParameterWidget,
|
|
455
|
+
BooleanParameter: BooleanParameterWidget,
|
|
456
|
+
IntegerParameter: IntegerParameterWidget,
|
|
457
|
+
FloatParameter: FloatParameterWidget,
|
|
458
|
+
IntegerRangeParameter: IntegerRangeParameterWidget,
|
|
459
|
+
FloatRangeParameter: FloatRangeParameterWidget,
|
|
460
|
+
UnboundedIntegerParameter: UnboundedIntegerParameterWidget,
|
|
461
|
+
UnboundedFloatParameter: UnboundedFloatParameterWidget,
|
|
462
|
+
ButtonParameter: ButtonParameterWidget,
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
widget_class = widget_map.get(type(parameter))
|
|
466
|
+
if widget_class is None:
|
|
467
|
+
raise ValueError(
|
|
468
|
+
f"No widget implementation for parameter type: {type(parameter)}"
|
|
469
|
+
)
|
|
470
|
+
|
|
471
|
+
return widget_class(parameter, continuous_update)
|