Source code for ess.reduce.widgets

# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2024 Scipp contributors (https://github.com/scipp)
# ruff: noqa: E402, F401
from functools import singledispatch
from typing import Any, Protocol

import ipywidgets as widgets

from ..parameter import (
    BooleanParameter,
    FilenameParameter,
    MultiFilenameParameter,
    MultiStringParameter,
    ParamWithOptions,
    StringParameter,
    Parameter,
    ParamWithBounds,
    BinEdgesParameter,
    Vector2dParameter,
    Vector3dParameter,
)
from ._config import default_layout, default_style

from ._binedges_widget import BinEdgesWidget
from ._filename_widget import FilenameWidget, MultiFilenameWidget
from ._linspace_widget import LinspaceWidget
from ._vector_widget import VectorWidget
from ._bounds_widget import BoundsWidget
from ._string_widget import MultiStringWidget, StringWidget
from ._switchable_widget import SwitchWidget
from ._optional_widget import OptionalWidget


[docs] class EssWidget(Protocol): """Protocol for ESS widgets. All widgets should have a `value` property that returns the value of the widget. It can be composed from multiple widgets. """ @property def value(self) -> Any: ...
from collections.abc import Callable from functools import wraps
[docs] def switchable_widget( func: Callable[[Parameter], widgets.Widget], ) -> Callable[[Parameter], widgets.Widget]: """Wrap a widget in a switchable widget.""" @wraps(func) def wrapper(param: Parameter) -> widgets.Widget: widget = func(param) if param.switchable: return SwitchWidget(widget, name=param.name) return widget return wrapper
[docs] def optional_widget( func: Callable[[Parameter], widgets.Widget], ) -> Callable[[Parameter], widgets.Widget]: """Wrap a widget in a optional widget.""" @wraps(func) def wrapper(param: Parameter) -> widgets.Widget: widget = func(param) if param.optional: return OptionalWidget(widget, name=param.name) return widget return wrapper
[docs] @switchable_widget @optional_widget # optional_widget should be applied first @singledispatch def create_parameter_widget(param: Parameter) -> widgets.Widget: """Create a widget for a parameter depending on the ``param`` type. If the type of the parameter is not supported, a text widget is returned. """ return widgets.Text( '', description=param.name, layout=default_layout, style=default_style )
[docs] @create_parameter_widget.register(BooleanParameter) def boolean_parameter_widget(param: BooleanParameter): name = param.name.split('.')[-1] description = param.description return widgets.Checkbox( value=param.default, description=name, tooltip=description, layout=default_layout, style=default_style, )
[docs] @create_parameter_widget.register(StringParameter) def string_parameter_widget(param: StringParameter): return StringWidget( description=param.name, value=param.default, layout=default_layout, style=default_style, )
[docs] @create_parameter_widget.register(MultiStringParameter) def multi_string_parameter_widget(param: MultiStringParameter): return MultiStringWidget( description=param.name, value=param.default, layout=default_layout, style=default_style, )
[docs] @create_parameter_widget.register(FilenameParameter) def filename_parameter_widget(param: FilenameParameter): return FilenameWidget( description=param.name, value=param.default, layout=default_layout, style=default_style, )
[docs] @create_parameter_widget.register(MultiFilenameParameter) def multi_filename_parameter_widget(param: MultiFilenameParameter): return MultiFilenameWidget( description=param.name, value=param.default, layout=default_layout, style=default_style, )
[docs] @create_parameter_widget.register(ParamWithOptions) def param_with_option_widget(param: ParamWithOptions): return widgets.Dropdown( description=param.name, options=param.options, layout=default_layout, style=default_style, )
[docs] @create_parameter_widget.register(ParamWithBounds) def param_with_bounds_widget(param: ParamWithBounds): return BoundsWidget()
[docs] @create_parameter_widget.register(BinEdgesParameter) def bin_edges_parameter_widget(param: BinEdgesParameter): return BinEdgesWidget( name=param.name, dim=param.dim, start=param.start, stop=param.stop, nbins=param.nbins, unit=param.unit, log=param.log, )
[docs] @create_parameter_widget.register(Vector2dParameter) def vector_2d_parameter_widget(param: Vector2dParameter): return VectorWidget(name=param.name, variable=param.default, components="xy")
[docs] @create_parameter_widget.register(Vector3dParameter) def vector_3d_parameter_widget(param: Vector3dParameter): return VectorWidget(name=param.name, variable=param.default, components="xyz")
__all__ = [ 'BinEdgesWidget', 'BoundsWidget', 'EssWidget', 'FilenameWidget', 'LinspaceWidget', 'MultiFilenameWidget', 'OptionalWidget', 'SwitchWidget', 'VectorWidget', 'create_parameter_widget', ]