Skip to content

base

ControlPanel

Bases: Parameterized

base class for left control pannels

Source code in pyhdx/web/base.py
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
class ControlPanel(param.Parameterized):
    """base class for left control pannels"""

    _type = None

    header = "Default Header"

    parent = param.ClassSelector(MainController, precedence=-1)

    _excluded = param.List(
        [],
        precedence=-1,
        doc="parameters whose widgets are excluded from the control panel view. This list can be modified to update "
        "widget layout",
    )

    def __init__(self, parent, **params):
        # self.parent = parent
        # self.ex
        super(ControlPanel, self).__init__(parent=parent, **params)

        self.widgets = self.make_dict()
        self._box = self.make_box()  # _panel equivalent

        # bind update function when any transform triggers a redraw of widgets
        if self._layout:
            for widget_source, contents in self._layout:
                if widget_source != "self":
                    _type, name = widget_source.split(".")
                    if _type == "transforms":
                        obj = getattr(self, _type)[name]
                        obj.param.watch(self.update_box, ["redrawn"])

    @property  # todo base class
    def own_widget_names(self):
        return [name for name in self.widgets.keys() if name not in self._excluded]

    @property
    def _layout(self):
        return [
            ("self", self.own_widget_names),
        ]

    @property
    def sources(self):
        return self.parent.sources

    @property
    def transforms(self):
        return self.parent.transforms

    @property
    def opts(self):
        return self.parent.opts

    @property
    def views(self):
        return self.parent.views

    def make_box(self):
        return pn.Column(*self.widget_list, name=self.header, width=SIDEBAR_WIDTH)

    def _update_box(self, *events):
        self.update_box()

    def update_box(self, *events):
        self._box[:] = self.widget_list

    def generate_widgets(self, **kwargs) -> dict[str, pn.widgets.Widget]:
        """Creates a dict with keys parameter names and values default mapped widgets"""

        # Get all parameters with precedence >= 1 and not starting with '_', excluding 'name'
        parameters = {p_name for p_name in self.param if not p_name.startswith("_")}
        parameters -= {"name"}
        parameters -= {
            p_name for p_name, par in self.param.objects().items() if not has_precedence(par)
        }

        widgets_layout = Param(
            self.param,
            show_labels=True,
            show_name=False,
            widgets=kwargs,
            parameters=list(parameters),
        )

        return widgets_layout.get_widgets()

    @property
    def widget_list(self):
        """

        Example _layout definitions

        Returns
        -------

        """

        try:
            self._layout
        except AttributeError:
            return [get_view(widget) for widget in self.widgets.values()]

        if self._layout is None:
            return [get_view(widget) for widget in self.widgets.values()]
        else:
            widget_list = []
            for widget_source, contents in self._layout:
                if widget_source == "self":
                    object = self
                else:
                    _type, name = widget_source.split(".")
                    object = getattr(self, _type)[name]

                if isinstance(contents, list):
                    for item in contents:
                        widget_list.append(get_view(object.widgets[item]))
                elif isinstance(contents, str):
                    widget_list.append(get_view(object.widgets[contents]))
                elif contents is None:
                    if hasattr(object, "widgets"):
                        for item in object.widgets.values():
                            widget_list.append(get_view(item))
                    else:
                        panel = object.panel
                        if isinstance(panel, pn.layout.ListLike):
                            for item in panel:
                                widget_list.append(get_view(item))
                        else:
                            widget_list.append(get_view(panel))

        return widget_list

    def make_dict(self):
        """dict of widgets to be shown
        override this method to get custom mapping

        """
        return self.generate_widgets()

    def box_index(self, p_name_or_widget):
        "" "return the index of the widget in the box with parameter p_name"
        if isinstance(p_name_or_widget, str):
            return list(self._box).index(self.widget_dict[p_name_or_widget])
        else:
            return list(self._box).index(p_name_or_widget)

    def box_pop(self, p_name_or_widget):
        """remove the widget with parameter name name from the box"""
        index = self.box_index(p_name_or_widget)
        self._box.pop(index)

    def box_insert_after(self, name_or_widget_after, name_or_widget_insert):
        """insert widget corresponding to parameter with name after the widget name_after"""
        index = self.box_index(name_or_widget_after)
        if isinstance(name_or_widget_insert, str):
            widget = self.widget_dict[name_or_widget_insert]
        else:
            widget = name_or_widget_insert
        self._box.insert(index + 1, widget)

    def get_widget(self, param_name, widget_type, **kwargs):
        """get a single widget with for parameter param_name with type widget_type"""

        # not sure if this function still exists
        return pn.Param.get_widget(getattr(self.param, param_name), widget_type, **kwargs)[0]

    @property
    def panel(self):
        return self._box

widget_list property

Example _layout definitions

Returns

box_index(p_name_or_widget)

return the index of the widget in the box with parameter p_name

Source code in pyhdx/web/base.py
197
198
199
200
201
202
def box_index(self, p_name_or_widget):
    "" "return the index of the widget in the box with parameter p_name"
    if isinstance(p_name_or_widget, str):
        return list(self._box).index(self.widget_dict[p_name_or_widget])
    else:
        return list(self._box).index(p_name_or_widget)

box_insert_after(name_or_widget_after, name_or_widget_insert)

insert widget corresponding to parameter with name after the widget name_after

Source code in pyhdx/web/base.py
209
210
211
212
213
214
215
216
def box_insert_after(self, name_or_widget_after, name_or_widget_insert):
    """insert widget corresponding to parameter with name after the widget name_after"""
    index = self.box_index(name_or_widget_after)
    if isinstance(name_or_widget_insert, str):
        widget = self.widget_dict[name_or_widget_insert]
    else:
        widget = name_or_widget_insert
    self._box.insert(index + 1, widget)

box_pop(p_name_or_widget)

remove the widget with parameter name name from the box

Source code in pyhdx/web/base.py
204
205
206
207
def box_pop(self, p_name_or_widget):
    """remove the widget with parameter name name from the box"""
    index = self.box_index(p_name_or_widget)
    self._box.pop(index)

generate_widgets(**kwargs)

Creates a dict with keys parameter names and values default mapped widgets

Source code in pyhdx/web/base.py
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
def generate_widgets(self, **kwargs) -> dict[str, pn.widgets.Widget]:
    """Creates a dict with keys parameter names and values default mapped widgets"""

    # Get all parameters with precedence >= 1 and not starting with '_', excluding 'name'
    parameters = {p_name for p_name in self.param if not p_name.startswith("_")}
    parameters -= {"name"}
    parameters -= {
        p_name for p_name, par in self.param.objects().items() if not has_precedence(par)
    }

    widgets_layout = Param(
        self.param,
        show_labels=True,
        show_name=False,
        widgets=kwargs,
        parameters=list(parameters),
    )

    return widgets_layout.get_widgets()

get_widget(param_name, widget_type, **kwargs)

get a single widget with for parameter param_name with type widget_type

Source code in pyhdx/web/base.py
218
219
220
221
222
def get_widget(self, param_name, widget_type, **kwargs):
    """get a single widget with for parameter param_name with type widget_type"""

    # not sure if this function still exists
    return pn.Param.get_widget(getattr(self.param, param_name), widget_type, **kwargs)[0]

make_dict()

dict of widgets to be shown override this method to get custom mapping

Source code in pyhdx/web/base.py
190
191
192
193
194
195
def make_dict(self):
    """dict of widgets to be shown
    override this method to get custom mapping

    """
    return self.generate_widgets()

has_precedence(p)

Checks the precedence of a parameter.

Returns:

Type Description
bool

True if the precedence is None or larger or equal then zero, else False.

Source code in pyhdx/web/base.py
41
42
43
44
45
46
47
48
49
50
51
52
53
def has_precedence(p: param.Parameter) -> bool:
    """Checks the precedence of a parameter.

    Returns:
        `True` if the `precedence` is None or larger or equal then zero, else `False`.

    """
    if p.precedence is None:
        return True
    elif p.precedence >= 0:
        return True
    else:
        return False