bec-widgets 2.8.3__py3-none-any.whl → 2.9.0__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.
Files changed (25) hide show
  1. CHANGELOG.md +37 -0
  2. PKG-INFO +1 -1
  3. bec_widgets/cli/client.py +129 -0
  4. bec_widgets/utils/bec_dispatcher.py +6 -4
  5. bec_widgets/utils/crosshair.py +72 -9
  6. bec_widgets/widgets/control/device_input/base_classes/device_signal_input_base.py +13 -12
  7. bec_widgets/widgets/control/device_input/signal_combobox/signal_combobox.py +11 -5
  8. bec_widgets/widgets/plots/image/image.py +2 -0
  9. bec_widgets/widgets/plots/multi_waveform/multi_waveform.py +2 -0
  10. bec_widgets/widgets/plots/plot_base.py +27 -1
  11. bec_widgets/widgets/plots/scatter_waveform/scatter_waveform.py +2 -0
  12. bec_widgets/widgets/plots/setting_menus/axis_settings.py +3 -0
  13. bec_widgets/widgets/plots/setting_menus/axis_settings_horizontal.ui +111 -88
  14. bec_widgets/widgets/plots/setting_menus/axis_settings_vertical.ui +74 -43
  15. bec_widgets/widgets/plots/waveform/waveform.py +2 -0
  16. bec_widgets/widgets/utility/signal_label/register_signal_label.py +15 -0
  17. bec_widgets/widgets/utility/signal_label/signal_label.py +456 -0
  18. bec_widgets/widgets/utility/signal_label/signal_label.pyproject +1 -0
  19. bec_widgets/widgets/utility/signal_label/signal_label_plugin.py +54 -0
  20. {bec_widgets-2.8.3.dist-info → bec_widgets-2.9.0.dist-info}/METADATA +1 -1
  21. {bec_widgets-2.8.3.dist-info → bec_widgets-2.9.0.dist-info}/RECORD +25 -21
  22. pyproject.toml +1 -1
  23. {bec_widgets-2.8.3.dist-info → bec_widgets-2.9.0.dist-info}/WHEEL +0 -0
  24. {bec_widgets-2.8.3.dist-info → bec_widgets-2.9.0.dist-info}/entry_points.txt +0 -0
  25. {bec_widgets-2.8.3.dist-info → bec_widgets-2.9.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,456 @@
1
+ from __future__ import annotations
2
+
3
+ import sys
4
+ import traceback
5
+ from typing import TYPE_CHECKING
6
+
7
+ from bec_lib.device import Device, Signal
8
+ from bec_lib.endpoints import MessageEndpoints
9
+ from bec_qthemes import material_icon
10
+ from qtpy.QtCore import Signal as QSignal
11
+ from qtpy.QtWidgets import (
12
+ QApplication,
13
+ QComboBox,
14
+ QDialog,
15
+ QDialogButtonBox,
16
+ QGroupBox,
17
+ QHBoxLayout,
18
+ QLabel,
19
+ QLineEdit,
20
+ QToolButton,
21
+ QVBoxLayout,
22
+ QWidget,
23
+ )
24
+
25
+ from bec_widgets.utils.bec_connector import ConnectionConfig
26
+ from bec_widgets.utils.bec_widget import BECWidget
27
+ from bec_widgets.utils.colors import get_accent_colors
28
+ from bec_widgets.utils.error_popups import SafeProperty, SafeSlot
29
+ from bec_widgets.utils.ophyd_kind_util import Kind
30
+ from bec_widgets.widgets.control.device_input.base_classes.device_input_base import (
31
+ DeviceInputConfig,
32
+ )
33
+ from bec_widgets.widgets.control.device_input.base_classes.device_signal_input_base import (
34
+ DeviceSignalInputBaseConfig,
35
+ )
36
+ from bec_widgets.widgets.control.device_input.device_line_edit.device_line_edit import (
37
+ DeviceLineEdit,
38
+ )
39
+ from bec_widgets.widgets.control.device_input.signal_combobox.signal_combobox import SignalComboBox
40
+
41
+ if TYPE_CHECKING:
42
+ from bec_lib.client import BECClient
43
+
44
+
45
+ class ChoiceDialog(QDialog):
46
+ accepted_output = QSignal(str, str)
47
+
48
+ CONNECTION_ERROR_STR = "Error: client is not connected!"
49
+
50
+ def __init__(
51
+ self,
52
+ parent: QWidget | None = None,
53
+ config: ConnectionConfig | None = None,
54
+ client: BECClient | None = None,
55
+ show_hinted: bool = True,
56
+ show_normal: bool = False,
57
+ show_config: bool = False,
58
+ ):
59
+ if not client or not client.started:
60
+ self._display_error()
61
+ return
62
+ super().__init__(parent=parent)
63
+ self.setWindowTitle("Choose device and signal...")
64
+ self._accent_colors = get_accent_colors()
65
+
66
+ layout = QHBoxLayout()
67
+
68
+ config_dict = config.model_dump() if config is not None else {}
69
+ self._device_config = DeviceInputConfig.model_validate(config_dict)
70
+ self._signal_config = DeviceSignalInputBaseConfig.model_validate(config_dict)
71
+ self._device_field = DeviceLineEdit(
72
+ config=self._device_config, parent=parent, client=client
73
+ )
74
+ self._signal_field = SignalComboBox(
75
+ config=self._signal_config,
76
+ device=self._signal_config.device,
77
+ parent=parent,
78
+ client=client,
79
+ )
80
+ layout.addWidget(self._device_field)
81
+ layout.addWidget(self._signal_field)
82
+
83
+ self.button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
84
+ self.button_box.accepted.connect(self.accept)
85
+ self.button_box.rejected.connect(self.reject)
86
+ layout.addWidget(self.button_box)
87
+
88
+ self._signal_field.include_hinted_signals = show_hinted
89
+ self._signal_field.include_normal_signals = show_normal
90
+ self._signal_field.include_config_signals = show_config
91
+
92
+ self.setLayout(layout)
93
+ self._device_field.textChanged.connect(self._update_device)
94
+ self._device_field.setText(config.device if config is not None else "")
95
+
96
+ def _display_error(self):
97
+ try:
98
+ super().__init__()
99
+ except Exception:
100
+ ...
101
+ layout = QHBoxLayout()
102
+ layout.addWidget(QLabel(self.CONNECTION_ERROR_STR))
103
+ self.button_box = QDialogButtonBox(QDialogButtonBox.Cancel)
104
+ self.button_box.accepted.connect(self.reject)
105
+ layout.addWidget(self.button_box)
106
+ self.setLayout(layout)
107
+
108
+ @SafeSlot(str)
109
+ def _update_device(self, device: str):
110
+ if device in self._device_field.dev:
111
+ self._device_field.set_device(device)
112
+ self._signal_field.set_device(device)
113
+ self._device_field.setStyleSheet(
114
+ f"QLineEdit {{ border-style: solid; border-width: 2px; border-color: {self._accent_colors.success.name() if self._accent_colors else 'green'}}}"
115
+ )
116
+ self.button_box.button(QDialogButtonBox.Ok).setEnabled(True)
117
+ else:
118
+ self._device_field.setStyleSheet(
119
+ f"QLineEdit {{ border-style: solid; border-width: 2px; border-color: {self._accent_colors.emergency.name() if self._accent_colors else 'red'}}}"
120
+ )
121
+ self.button_box.button(QDialogButtonBox.Ok).setEnabled(False)
122
+ self._signal_field.clear()
123
+
124
+ def accept(self):
125
+ self.accepted_output.emit(self._device_field.text(), self._signal_field.currentText())
126
+ return super().accept()
127
+
128
+
129
+ class SignalLabel(BECWidget, QWidget):
130
+
131
+ ICON_NAME = "scoreboard"
132
+ RPC = True
133
+ PLUGIN = True
134
+
135
+ USER_ACCESS = [
136
+ "custom_label",
137
+ "custom_units",
138
+ "custom_label.setter",
139
+ "custom_units.setter",
140
+ "decimal_places",
141
+ "decimal_places.setter",
142
+ "show_default_units",
143
+ "show_default_units.setter",
144
+ "show_select_button",
145
+ "show_select_button.setter",
146
+ ]
147
+
148
+ def __init__(
149
+ self,
150
+ parent: QWidget | None = None,
151
+ client: BECClient | None = None,
152
+ device: str | None = None,
153
+ signal: str | None = None,
154
+ show_select_button: bool = True,
155
+ show_default_units: bool = False,
156
+ custom_label: str = "",
157
+ custom_units: str = "",
158
+ **kwargs,
159
+ ):
160
+ """Initialize the SignalLabel widget.
161
+
162
+ Args:
163
+ parent (QWidget, optional): The parent widget. Defaults to None.
164
+ client (BECClient, optional): The BEC client. Defaults to None.
165
+ device (str, optional): The device name. Defaults to None.
166
+ signal (str, optional): The signal name. Defaults to None.
167
+ selection_dialog_config (DeviceSignalInputBaseConfig | dict, optional): Configuration for the signal selection dialog.
168
+ show_select_button (bool, optional): Whether to show the select button. Defaults to True.
169
+ show_default_units (bool, optional): Whether to show default units. Defaults to False.
170
+ custom_label (str, optional): Custom label for the widget. Defaults to "".
171
+ custom_units (str, optional): Custom units for the widget. Defaults to "".
172
+ """
173
+ self._config = DeviceSignalInputBaseConfig(default=signal, device=device)
174
+ super().__init__(parent=parent, client=client, **kwargs)
175
+
176
+ self._device = device
177
+ self._signal = signal
178
+
179
+ self._custom_label: str = custom_label
180
+ self._custom_units: str = custom_units
181
+ self._show_default_units: bool = show_default_units
182
+ self._decimal_places = 3
183
+
184
+ self._show_hinted_signals: bool = True
185
+ self._show_normal_signals: bool = False
186
+ self._show_config_signals: bool = False
187
+
188
+ self._outer_layout = QHBoxLayout()
189
+ self._layout = QHBoxLayout()
190
+ self._outer_layout.setContentsMargins(0, 0, 0, 0)
191
+ self._layout.setContentsMargins(0, 0, 0, 0)
192
+ self.setLayout(self._outer_layout)
193
+
194
+ self._label = QGroupBox(custom_label)
195
+ self._outer_layout.addWidget(self._label)
196
+ self._update_label()
197
+ self._label.setLayout(self._layout)
198
+
199
+ self._value: str = ""
200
+ self._display = QLabel()
201
+ self._layout.addWidget(self._display)
202
+
203
+ self._select_button = QToolButton()
204
+ self._select_button.setIcon(material_icon(icon_name="settings", size=(20, 20)))
205
+ self._show_select_button: bool = show_select_button
206
+ self._layout.addWidget(self._select_button)
207
+ self._display.setMinimumHeight(self._select_button.sizeHint().height())
208
+ self.show_select_button = self._show_select_button
209
+
210
+ self._select_button.clicked.connect(self.show_choice_dialog)
211
+ self.get_bec_shortcuts()
212
+
213
+ self._connected: bool = False
214
+ self.connect_device()
215
+
216
+ def _create_dialog(self):
217
+ return ChoiceDialog(
218
+ config=self._config,
219
+ parent=self,
220
+ client=self.client,
221
+ show_config=self.show_config_signals,
222
+ show_normal=self.show_normal_signals,
223
+ show_hinted=self.show_hinted_signals,
224
+ )
225
+
226
+ @SafeSlot()
227
+ def _process_dialog(self, device: str, signal: str):
228
+ self.disconnect_device()
229
+ self.device = device
230
+ self.signal = signal
231
+ self._update_label()
232
+ self.connect_device()
233
+
234
+ def show_choice_dialog(self):
235
+ dialog = self._create_dialog()
236
+ dialog.accepted_output.connect(self._process_dialog)
237
+ dialog.open()
238
+ return dialog
239
+
240
+ def connect_device(self):
241
+ """Subscribe to the Redis topic for the device to display"""
242
+ if not self._connected and self._device and self._device in self.dev:
243
+ self._connected = True
244
+ self._readback_endpoint = MessageEndpoints.device_readback(self._device)
245
+ self.bec_dispatcher.connect_slot(self.on_device_readback, self._readback_endpoint)
246
+ self._manual_read()
247
+ self.set_display_value(self._value)
248
+
249
+ def disconnect_device(self):
250
+ """Unsubscribe from the Redis topic for the device to display"""
251
+ if self._connected:
252
+ self._connected = False
253
+ self.bec_dispatcher.disconnect_slot(self.on_device_readback, self._readback_endpoint)
254
+
255
+ def _manual_read(self):
256
+ if self._device is None or not isinstance(
257
+ (device := self.dev.get(self._device)), Device | Signal
258
+ ):
259
+ self._units = ""
260
+ self._value = "__"
261
+ return
262
+ signal: Signal = (
263
+ getattr(device, self.signal, None) if isinstance(device, Device) else device
264
+ )
265
+ if not isinstance(signal, Signal): # Avoid getting other attributes of device, e.g. methods
266
+ signal = None
267
+ if signal is None:
268
+ self._units = ""
269
+ self._value = "__"
270
+ return
271
+ self._value = signal.get()
272
+ self._units = signal.get_device_config().get("egu", "")
273
+
274
+ @SafeSlot(dict, dict)
275
+ def on_device_readback(self, msg: dict, metadata: dict) -> None:
276
+ """
277
+ Update the display with the new value.
278
+ """
279
+ try:
280
+ signal_to_read = self._patch_hinted_signal()
281
+ self._value = msg["signals"][signal_to_read]["value"]
282
+ self.set_display_value(self._value)
283
+ except Exception as e:
284
+ self._display.setText("ERROR!")
285
+ self._display.setToolTip(
286
+ f"Error processing incoming reading: {msg}, handled with exception: {''.join(traceback.format_exception(e))}"
287
+ )
288
+
289
+ def _patch_hinted_signal(self):
290
+ if self.dev[self._device]._info["signals"] == {}:
291
+ return self._signal
292
+ signal_info = self.dev[self._device]._info["signals"][self._signal]
293
+ return (
294
+ signal_info["obj_name"] if signal_info["kind_str"] == Kind.hinted.name else self._signal
295
+ )
296
+
297
+ @SafeProperty(str)
298
+ def device(self) -> str:
299
+ """The device from which to select a signal"""
300
+ return self._device or "Not set!"
301
+
302
+ @device.setter
303
+ def device(self, value: str) -> None:
304
+ self.disconnect_device()
305
+ self._device = value
306
+ self._config.device = value
307
+ self.connect_device()
308
+ self._update_label()
309
+
310
+ @SafeProperty(str)
311
+ def signal(self) -> str:
312
+ """The signal to display"""
313
+ return self._signal or "Not set!"
314
+
315
+ @signal.setter
316
+ def signal(self, value: str) -> None:
317
+ self.disconnect_device()
318
+ self._signal = value
319
+ self._config.default = value
320
+ self.connect_device()
321
+ self._update_label()
322
+
323
+ @SafeProperty(bool)
324
+ def show_select_button(self) -> bool:
325
+ """Show the button to select the signal to display"""
326
+ return self._show_select_button
327
+
328
+ @show_select_button.setter
329
+ def show_select_button(self, value: bool) -> None:
330
+ self._show_select_button = value
331
+ self._select_button.setVisible(value)
332
+
333
+ @SafeProperty(bool)
334
+ def show_default_units(self) -> bool:
335
+ """Show default units obtained from the signal alongside it"""
336
+ return self._show_default_units
337
+
338
+ @show_default_units.setter
339
+ def show_default_units(self, value: bool) -> None:
340
+ self._show_default_units = value
341
+ self.set_display_value(self._value)
342
+
343
+ @SafeProperty(str)
344
+ def custom_label(self) -> str:
345
+ """Use a cusom label rather than the signal name"""
346
+ return self._custom_label
347
+
348
+ @custom_label.setter
349
+ def custom_label(self, value: str) -> None:
350
+ self._custom_label = value
351
+ self._update_label()
352
+
353
+ @SafeProperty(str)
354
+ def custom_units(self) -> str:
355
+ """Use a custom unit string"""
356
+ return self._custom_units
357
+
358
+ @custom_units.setter
359
+ def custom_units(self, value: str) -> None:
360
+ self._custom_units = value
361
+ self.set_display_value(self._value)
362
+
363
+ @SafeProperty(int)
364
+ def decimal_places(self) -> int:
365
+ """Format to a given number of decimal_places. Set to 0 to disable."""
366
+ return self._decimal_places
367
+
368
+ @decimal_places.setter
369
+ def decimal_places(self, value: int) -> None:
370
+ self._decimal_places = value
371
+ self._update_label()
372
+
373
+ @SafeProperty(bool)
374
+ def show_hinted_signals(self) -> bool:
375
+ """In the signal selection menu, show hinted signals"""
376
+ return self._show_hinted_signals
377
+
378
+ @show_hinted_signals.setter
379
+ def show_hinted_signals(self, value: bool) -> None:
380
+ self._show_hinted_signals = value
381
+
382
+ @SafeProperty(bool)
383
+ def show_config_signals(self) -> bool:
384
+ """In the signal selection menu, show config signals"""
385
+ return self._show_config_signals
386
+
387
+ @show_config_signals.setter
388
+ def show_config_signals(self, value: bool) -> None:
389
+ self._show_config_signals = value
390
+
391
+ @SafeProperty(bool)
392
+ def show_normal_signals(self) -> bool:
393
+ """In the signal selection menu, show normal signals"""
394
+ return self._show_normal_signals
395
+
396
+ @show_normal_signals.setter
397
+ def show_normal_signals(self, value: bool) -> None:
398
+ self._show_normal_signals = value
399
+
400
+ def _format_value(self, value: str):
401
+ if self._decimal_places == 0:
402
+ return value
403
+ try:
404
+ return f"{float(value):0.{self._decimal_places}f}"
405
+ except ValueError:
406
+ return value
407
+
408
+ @SafeSlot(str)
409
+ def set_display_value(self, value: str):
410
+ """Set the display to a given value, appending the units if specified"""
411
+ self._display.setText(f"{self._format_value(value)}{self._units_string}")
412
+ self._display.setToolTip("")
413
+
414
+ @property
415
+ def _units_string(self):
416
+ if self.custom_units or self._show_default_units:
417
+ return f" {self.custom_units or self._default_units or ''}"
418
+ return ""
419
+
420
+ @property
421
+ def _default_units(self) -> str:
422
+ return self._units
423
+
424
+ @property
425
+ def _default_label(self) -> str:
426
+ return (
427
+ str(self._signal) if self._device == self._signal else f"{self._device} {self._signal}"
428
+ )
429
+
430
+ def _update_label(self):
431
+ self._label.setTitle(
432
+ self._custom_label if self._custom_label else f"{self._default_label}:"
433
+ )
434
+
435
+
436
+ if __name__ == "__main__":
437
+
438
+ app = QApplication(sys.argv)
439
+ w = QWidget()
440
+ w.setLayout(QVBoxLayout())
441
+ w.layout().addWidget(
442
+ SignalLabel(
443
+ device="samx",
444
+ signal="readback",
445
+ custom_label="custom label:",
446
+ custom_units=" m/s/s",
447
+ show_select_button=False,
448
+ )
449
+ )
450
+ w.layout().addWidget(SignalLabel(device="samy", signal="readback", show_default_units=True))
451
+ l = SignalLabel()
452
+ l.device = "bpm4i"
453
+ l.signal = "bpm4i"
454
+ w.layout().addWidget(l)
455
+ w.show()
456
+ sys.exit(app.exec_())
@@ -0,0 +1 @@
1
+ {'files': ['signal_label.py']}
@@ -0,0 +1,54 @@
1
+ # Copyright (C) 2022 The Qt Company Ltd.
2
+ # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
3
+
4
+ from qtpy.QtDesigner import QDesignerCustomWidgetInterface
5
+
6
+ from bec_widgets.utils.bec_designer import designer_material_icon
7
+ from bec_widgets.widgets.utility.signal_label.signal_label import SignalLabel
8
+
9
+ DOM_XML = """
10
+ <ui language='c++'>
11
+ <widget class='SignalLabel' name='signal_label'>
12
+ </widget>
13
+ </ui>
14
+ """
15
+
16
+
17
+ class SignalLabelPlugin(QDesignerCustomWidgetInterface): # pragma: no cover
18
+ def __init__(self):
19
+ super().__init__()
20
+ self._form_editor = None
21
+
22
+ def createWidget(self, parent):
23
+ t = SignalLabel(parent)
24
+ return t
25
+
26
+ def domXml(self):
27
+ return DOM_XML
28
+
29
+ def group(self):
30
+ return "BEC Utils"
31
+
32
+ def icon(self):
33
+ return designer_material_icon(SignalLabel.ICON_NAME)
34
+
35
+ def includeFile(self):
36
+ return "signal_label"
37
+
38
+ def initialize(self, form_editor):
39
+ self._form_editor = form_editor
40
+
41
+ def isContainer(self):
42
+ return False
43
+
44
+ def isInitialized(self):
45
+ return self._form_editor is not None
46
+
47
+ def name(self):
48
+ return "SignalLabel"
49
+
50
+ def toolTip(self):
51
+ return "Display the live value of any signal"
52
+
53
+ def whatsThis(self):
54
+ return self.toolTip()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bec_widgets
3
- Version: 2.8.3
3
+ Version: 2.9.0
4
4
  Summary: BEC Widgets
5
5
  Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec_widgets/issues
6
6
  Project-URL: Homepage, https://gitlab.psi.ch/bec/bec_widgets
@@ -2,11 +2,11 @@
2
2
  .gitlab-ci.yml,sha256=1nMYldzVk0tFkBWYTcUjumOrdSADASheWOAc0kOFDYs,9509
3
3
  .pylintrc,sha256=eeY8YwSI74oFfq6IYIbCqnx3Vk8ZncKaatv96n_Y8Rs,18544
4
4
  .readthedocs.yaml,sha256=ivqg3HTaOxNbEW3bzWh9MXAkrekuGoNdj0Mj3SdRYuw,639
5
- CHANGELOG.md,sha256=0WBTTBgn-v4VUYX03djHKwV47IUSHRDcrZreVEpXtxo,289561
5
+ CHANGELOG.md,sha256=OSzHSaLDu5mXNSmpwp2ap-7qZ1f9GBHYVpGFP2lud3c,290774
6
6
  LICENSE,sha256=Daeiu871NcAp8uYi4eB_qHgvypG-HX0ioRQyQxFwjeg,1531
7
- PKG-INFO,sha256=m4bfcr8jJsEua1MIwebS06gdMZN4x8PzQ5cRHeWZo7I,1273
7
+ PKG-INFO,sha256=7m3lNNzWQOJNlrFeOIh5CNZty3XmjTVzlF26SB9hvnw,1273
8
8
  README.md,sha256=oY5Jc1uXehRASuwUJ0umin2vfkFh7tHF-LLruHTaQx0,3560
9
- pyproject.toml,sha256=K4xA4pMZN1a6gYuOc9qCKFhNfFAROEwAAorG1PDHvPE,2902
9
+ pyproject.toml,sha256=B8K6rKqQOCYlyMtMbH0kkOBNe3pCGvWk0X0EUsCpCrs,2902
10
10
  .git_hooks/pre-commit,sha256=n3RofIZHJl8zfJJIUomcMyYGFi_rwq4CC19z0snz3FI,286
11
11
  .github/pull_request_template.md,sha256=F_cJXzooWMFgMGtLK-7KeGcQt0B4AYFse5oN0zQ9p6g,801
12
12
  .github/ISSUE_TEMPLATE/bug_report.yml,sha256=WdRnt7HGxvsIBLzhkaOWNfg8IJQYa_oV9_F08Ym6znQ,1081
@@ -35,7 +35,7 @@ bec_widgets/assets/app_icons/bec_widgets_icon.png,sha256=K8dgGwIjalDh9PRHUsSQBqg
35
35
  bec_widgets/assets/app_icons/ui_loader_tile.png,sha256=qSK3XHqvnAVGV9Q0ulORcGFbXJ9LDq2uz8l9uTtMsNk,1812476
36
36
  bec_widgets/assets/app_icons/widget_launch_tile.png,sha256=bWsICHFfSe9-ESUj3AwlE95dDOea-f6M-s9fBapsxB4,2252911
37
37
  bec_widgets/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
- bec_widgets/cli/client.py,sha256=xbftm0CWcw5EgKlQg1f4jJ5BznXsXh34u-54sjBXW3M,93493
38
+ bec_widgets/cli/client.py,sha256=Pl93U3IyN5OisaEDCrS2ytY5CppRfuyIiCppXNMf8yg,96703
39
39
  bec_widgets/cli/client_utils.py,sha256=F2hyt--jL53bN8NoWifNUMqwwx5FbpS6I1apERdTRzM,18114
40
40
  bec_widgets/cli/generate_cli.py,sha256=K_wMxo2XBUn92SnY3dSrlyUn8ax6Y20QBGCuP284DsQ,10986
41
41
  bec_widgets/cli/server.py,sha256=h7QyBOOGjyrP_fxJIIOSEMc4E06cLG0JyaofjNV6oCA,5671
@@ -62,7 +62,7 @@ bec_widgets/tests/utils.py,sha256=DSzi6Z70fospjfyx0Uz5bWIDwaAzKbzcHfWPW0YyxzQ,71
62
62
  bec_widgets/utils/__init__.py,sha256=1930ji1Jj6dVuY81Wd2kYBhHYNV-2R0bN_L4o9zBj1U,533
63
63
  bec_widgets/utils/bec_connector.py,sha256=ATOSyZqryn1QHPc7aotiDnUtzFhlj_gmcukMT_pqjHQ,19272
64
64
  bec_widgets/utils/bec_designer.py,sha256=ehNl_i743rijmhPiIGNd1bihE7-l4oJzTVoa4yjPjls,5426
65
- bec_widgets/utils/bec_dispatcher.py,sha256=y9EFIgU3JqIs7R10XnLh0I1_Skts9sbPe3ijOVJumYs,9837
65
+ bec_widgets/utils/bec_dispatcher.py,sha256=qYyd0SjCCUDwihxUFYzlKVxvZwSqQpDDPxF7_xt-sz0,9948
66
66
  bec_widgets/utils/bec_plugin_helper.py,sha256=tLXEyzh0LWuRp-1XhJg32m-hUSLfRStC0YRUWKdhY5Q,3565
67
67
  bec_widgets/utils/bec_signal_proxy.py,sha256=Yc08fdBEDABrowwNPSngT9-28R8FD4ml7oTL6BoMyEE,3263
68
68
  bec_widgets/utils/bec_table.py,sha256=nA2b8ukSeUfquFMAxGrUVOqdrzMoDYD6O_4EYbOG2zk,717
@@ -71,7 +71,7 @@ bec_widgets/utils/collapsible_panel_manager.py,sha256=tvv77-9YTfYpsU6M_Le3bHR6wt
71
71
  bec_widgets/utils/colors.py,sha256=4Oms3kcstf7-WddGMB2TZXPqJwFMGVjFyBO8tHZHnxk,18308
72
72
  bec_widgets/utils/compact_popup.py,sha256=xVK_lQqL5Hy1ZnUzHXB8GU-Ru-mXevKcdM8ync3ssiA,10269
73
73
  bec_widgets/utils/container_utils.py,sha256=J8YXombOlAPa3M8NGZdhntp2NirBu4raDEQZOgP4elM,3791
74
- bec_widgets/utils/crosshair.py,sha256=zWz4rkVD_HQYWhYzX8asjjb1z_G0V3QqyrOXx6f4xXI,20106
74
+ bec_widgets/utils/crosshair.py,sha256=UZNM4GQnpYD6arN6CAgM9CTQ4LX6t24NoHozPU244Fc,22310
75
75
  bec_widgets/utils/entry_validator.py,sha256=lwT8HP0RDG1FXENIeZ3IDEF2DQmD8KXGkRxPoMXbryk,1817
76
76
  bec_widgets/utils/error_popups.py,sha256=UBAmD1YlAgKodpihudyf0VWtI59KGFiLgnjiKmKGjgk,13254
77
77
  bec_widgets/utils/expandable_frame.py,sha256=VV4mgwz4lXbO3r-dNCX2QFUguwWCCXSUkXyjDSTJHbU,2345
@@ -177,7 +177,7 @@ bec_widgets/widgets/control/device_control/positioner_group/register_positioner_
177
177
  bec_widgets/widgets/control/device_input/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
178
178
  bec_widgets/widgets/control/device_input/base_classes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
179
179
  bec_widgets/widgets/control/device_input/base_classes/device_input_base.py,sha256=r4DwWQz2wwNQ3Uswzdy12MGycV7pFrE_Zv4h_2G5IRA,15915
180
- bec_widgets/widgets/control/device_input/base_classes/device_signal_input_base.py,sha256=oylgVQ2XyN7CWrI_Aj4xtKT5tac41JRpGvccaY0SUHw,9271
180
+ bec_widgets/widgets/control/device_input/base_classes/device_signal_input_base.py,sha256=wLEzPfEqaCPL3EpvMgFL5aZqSwuGj1OEkiyKaOQ7M1I,9330
181
181
  bec_widgets/widgets/control/device_input/device_combobox/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
182
182
  bec_widgets/widgets/control/device_input/device_combobox/device_combo_box.pyproject,sha256=wI2eXR5ky_IM9-BCHJnH_9CEqYcZwIuLcgitSEr8OJU,40
183
183
  bec_widgets/widgets/control/device_input/device_combobox/device_combo_box_plugin.py,sha256=E8LD9T4O2w621q25uHqBqZLDiQ6zpMR25ZDuf51jrPw,1434
@@ -192,7 +192,7 @@ bec_widgets/widgets/control/device_input/signal_combobox/__init__.py,sha256=47DE
192
192
  bec_widgets/widgets/control/device_input/signal_combobox/register_signal_combo_box.py,sha256=VEdFRUfLph7JE2arcnzHw8etsE-4wZkwyzlNLMJBsZk,526
193
193
  bec_widgets/widgets/control/device_input/signal_combobox/signal_combo_box.pyproject,sha256=xod6iyRD-WD0Uk6LWXjSxFJCQy-831pvTkKcw2FAdnM,33
194
194
  bec_widgets/widgets/control/device_input/signal_combobox/signal_combo_box_plugin.py,sha256=sstqm2KtyR5wwOIYJRbzOqHMq5_9ExKP-YS5qV5ACrA,1373
195
- bec_widgets/widgets/control/device_input/signal_combobox/signal_combobox.py,sha256=NCT0ql6KCe-YspoYKSv2py7JeqKBGJFU97q6UoG-Oxg,4641
195
+ bec_widgets/widgets/control/device_input/signal_combobox/signal_combobox.py,sha256=vM4PsYDl8RBHb9g083fRpeUZZkW1u1m7uXfaVMGUpyY,4869
196
196
  bec_widgets/widgets/control/device_input/signal_line_edit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
197
197
  bec_widgets/widgets/control/device_input/signal_line_edit/register_signal_line_edit.py,sha256=aQLTy_3gbji0vq5VvvAddHFimpwGGaMYJy5iGgX23aM,527
198
198
  bec_widgets/widgets/control/device_input/signal_line_edit/signal_line_edit.py,sha256=-y_Oy8A7pQVQbzjvHznGxTX-wCisP-4l5py7WOm1_EY,6008
@@ -257,9 +257,9 @@ bec_widgets/widgets/games/minesweeper.pyproject,sha256=wHrLKY3H8uNiVgb9BIrj4S0Je
257
257
  bec_widgets/widgets/games/minesweeper_plugin.py,sha256=oPEjSTpdIIkvuGThHxhVS8Rp47DWiaXHROtm8NJWYwo,1255
258
258
  bec_widgets/widgets/games/register_minesweeper.py,sha256=8fgMBD3yB-5_eGqhG_qxpj3igXDK9WZfHrdYcA1aqz8,467
259
259
  bec_widgets/widgets/plots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
260
- bec_widgets/widgets/plots/plot_base.py,sha256=l8qzLybw6PEBZI5gRXaLY0AX_v81e50TFxOO1Muh774,34872
260
+ bec_widgets/widgets/plots/plot_base.py,sha256=GETUsx51BE_Tuop8bC-KiFVrkR82TJ5S0cr7siouSWM,35848
261
261
  bec_widgets/widgets/plots/image/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
262
- bec_widgets/widgets/plots/image/image.py,sha256=FA2a583iWkDi_zydw_OYi4NEiGHXtM_O0PxxSmdgUiY,42042
262
+ bec_widgets/widgets/plots/image/image.py,sha256=4PamL6EqwpmLMpSagYsBS7ZpU0fXVlzMg7518Tqo5EI,42127
263
263
  bec_widgets/widgets/plots/image/image.pyproject,sha256=_sRCIu4MNgToaB4D7tUMWq3xKX6T2VoRS3UzGNIseHQ,23
264
264
  bec_widgets/widgets/plots/image/image_item.py,sha256=2bn9H5YLmo7ohQnnf1mLlL24TASnlZNzMvF7buMutmI,8728
265
265
  bec_widgets/widgets/plots/image/image_plugin.py,sha256=R0Hzh2GgYlfZLPZwOMgqLKKIA5DxEnTcSrbI7zTe-tI,1204
@@ -282,7 +282,7 @@ bec_widgets/widgets/plots/motor_map/settings/motor_map_settings.ui,sha256=lEKjDU
282
282
  bec_widgets/widgets/plots/motor_map/toolbar_bundles/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
283
283
  bec_widgets/widgets/plots/motor_map/toolbar_bundles/motor_selection.py,sha256=rho8gUGs7cL0YkVYwFFy2FzquB81g5PljpDizfkDTKI,2714
284
284
  bec_widgets/widgets/plots/multi_waveform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
285
- bec_widgets/widgets/plots/multi_waveform/multi_waveform.py,sha256=vSjjE5TOfvVAIG7qpPr2vBzvvyT9Nr14CvOA6ULN-dI,17536
285
+ bec_widgets/widgets/plots/multi_waveform/multi_waveform.py,sha256=Zwtbv1rgDAbZNtwMM76_KLr0Sy4CyaCegRIsdKWqnHM,17621
286
286
  bec_widgets/widgets/plots/multi_waveform/multi_waveform.pyproject,sha256=DnGmG0HymVvUPLFlOYleIW_pJpDrLIbSne5jrI1Gdfk,32
287
287
  bec_widgets/widgets/plots/multi_waveform/multi_waveform_plugin.py,sha256=pSds2QM6VI5BuCNUIZTzFUd0B0beHBe1dcdBgb1AoGY,1296
288
288
  bec_widgets/widgets/plots/multi_waveform/register_multi_waveform.py,sha256=rP9SfyTwmrX-UXcr6Mk73r8jf8s75-1GX2sNh04QHvU,489
@@ -296,7 +296,7 @@ bec_widgets/widgets/plots/roi/image_roi.py,sha256=HIDlsRJtsZf2Iu09tHQuRXI0jFUiBJ
296
296
  bec_widgets/widgets/plots/scatter_waveform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
297
297
  bec_widgets/widgets/plots/scatter_waveform/register_scatter_waveform.py,sha256=KttVjlAK3PfP9tyMfLnqEm6kphap8NZyqyaRry8oebY,514
298
298
  bec_widgets/widgets/plots/scatter_waveform/scatter_curve.py,sha256=nCyZ_6EunS1m5XkLB-CwfBV9L4IX04D9SpHlHc8zG_I,6763
299
- bec_widgets/widgets/plots/scatter_waveform/scatter_waveform.py,sha256=8d6MF5ud8HzqPGQmYNhWpEp8ac9eDRRM5Z4T5Zq77Fk,19794
299
+ bec_widgets/widgets/plots/scatter_waveform/scatter_waveform.py,sha256=kan90pUjfEeJ4z85ZBWnUfEM9XwV6Ehk4XgSD1jMgD0,19879
300
300
  bec_widgets/widgets/plots/scatter_waveform/scatter_waveform.pyproject,sha256=Z_bnXkjDCBJPBCh1_wX3TyCn75aNBYU8SXxxu6DAj0Q,34
301
301
  bec_widgets/widgets/plots/scatter_waveform/scatter_waveform_plugin.py,sha256=3hpAk08kWSi6eE8NB-_vpHbYjBjGOHiCd42MJzmvFw0,1318
302
302
  bec_widgets/widgets/plots/scatter_waveform/settings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -304,9 +304,9 @@ bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_setting.py,sha
304
304
  bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_settings_horizontal.ui,sha256=UdUbOWRMonvsfXSH-NQenDGh3Of4xcirU4kXMniENgY,5013
305
305
  bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_settings_vertical.ui,sha256=68BUUYkMd6fBQlAcV1Co1FRCSDrJ0m8OAsUj_qxoZqU,7814
306
306
  bec_widgets/widgets/plots/setting_menus/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
307
- bec_widgets/widgets/plots/setting_menus/axis_settings.py,sha256=v-esAvJG8SeVv3hWf5L8jyF03jRjd0WvJ9fzbffHY7s,5233
308
- bec_widgets/widgets/plots/setting_menus/axis_settings_horizontal.ui,sha256=v8jJfPLnhORVfJukhRmygrPobMmJLufA4e3C08QeO-o,9526
309
- bec_widgets/widgets/plots/setting_menus/axis_settings_vertical.ui,sha256=k4vsQgZyKZkK3JiOXaQmvgR3IHy90mb4upGAtIwBOsA,9104
307
+ bec_widgets/widgets/plots/setting_menus/axis_settings.py,sha256=REGperW9vSS_ZtZH_zXhId_t4-qax0dFFbHgK84HX88,5380
308
+ bec_widgets/widgets/plots/setting_menus/axis_settings_horizontal.ui,sha256=rXUyB6ciPtYRWBk9-SJpiBl80akCst3U3Nly3_TZiEg,10632
309
+ bec_widgets/widgets/plots/setting_menus/axis_settings_vertical.ui,sha256=-5SYn_o4-EuhG2zaBFVbB5lWs2CpWzB2cYaWXuw-rns,11017
310
310
  bec_widgets/widgets/plots/toolbar_bundles/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
311
311
  bec_widgets/widgets/plots/toolbar_bundles/mouse_interactions.py,sha256=gdQ6Ggdq0rhELncCCUBXwi_k16xXWAgHOtgNmND58cA,4169
312
312
  bec_widgets/widgets/plots/toolbar_bundles/plot_export.py,sha256=43JnNwmp0lAVvSArZ0qa8SWwEAHwrZWBUse0nhlqMkA,3049
@@ -315,7 +315,7 @@ bec_widgets/widgets/plots/toolbar_bundles/save_state.py,sha256=H3fu-bRzNIycCUFb2
315
315
  bec_widgets/widgets/plots/waveform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
316
316
  bec_widgets/widgets/plots/waveform/curve.py,sha256=KlcGbd60lPO9BYcca08fMhWkfx5qu4O9IbSNTwvajGM,10401
317
317
  bec_widgets/widgets/plots/waveform/register_waveform.py,sha256=pdcLCYKkLkSb-5DqbJdC6M3JyoXQBRVAKf7BZVCto80,467
318
- bec_widgets/widgets/plots/waveform/waveform.py,sha256=tNoeqcPPv0nsJT87qSwJFv2jGATvRayxQQjAoaaLKmQ,68552
318
+ bec_widgets/widgets/plots/waveform/waveform.py,sha256=g4aAaeRgvOrwMW6Ju1cx-OKc0lXqN21Xo0rxbAcGBgk,68637
319
319
  bec_widgets/widgets/plots/waveform/waveform.pyproject,sha256=X2T6d4JGt9YSI28e-myjXh1YkUM4Yr3kNb0-F84KvUA,26
320
320
  bec_widgets/widgets/plots/waveform/waveform_plugin.py,sha256=2AZPtBHs75l9cdhwQnY3jpIMRPUUqK3RNvQbTvrFyvg,1237
321
321
  bec_widgets/widgets/plots/waveform/settings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -363,6 +363,10 @@ bec_widgets/widgets/utility/logpanel/log_panel.pyproject,sha256=2ncs1bsu-wICstR1
363
363
  bec_widgets/widgets/utility/logpanel/log_panel_plugin.py,sha256=KY7eS1uGZzLYtDAdBv6S2mw8UjcDGVt3UklN_D5M06A,1250
364
364
  bec_widgets/widgets/utility/logpanel/logpanel.py,sha256=tnjczAwtfe1biL-u9h9tntoQerWo3iLVD9RTSLOvd5o,20651
365
365
  bec_widgets/widgets/utility/logpanel/register_log_panel.py,sha256=LFUE5JzCYvIwJQtTqZASLVAHYy3gO1nrHzPVH_kpCEY,470
366
+ bec_widgets/widgets/utility/signal_label/register_signal_label.py,sha256=wDB4Q3dSbZ51hsxnuB74oXdMRoLgDRd-XfhaomYY2OA,483
367
+ bec_widgets/widgets/utility/signal_label/signal_label.py,sha256=bht1zpHKxrslfFCknnLe3Q9FeF8Do0j6onWAiLXZan0,15875
368
+ bec_widgets/widgets/utility/signal_label/signal_label.pyproject,sha256=DXgt__AGnPCqXo5A92aTPH0SxbWlvgyNzKraWUuumWg,30
369
+ bec_widgets/widgets/utility/signal_label/signal_label_plugin.py,sha256=ZXR8oYl4NkPcXJ8pgDcdXcg3teB0MHtoNZoiGDmgCoU,1298
366
370
  bec_widgets/widgets/utility/spinbox/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
367
371
  bec_widgets/widgets/utility/spinbox/bec_spin_box.pyproject,sha256=RIg1SZuCltuZZuK1O4Djg0TpCInhoCw8KeqNaf1_K0A,33
368
372
  bec_widgets/widgets/utility/spinbox/bec_spin_box_plugin.py,sha256=-XNrUAz1LZQPhJrH1sszfGrpBfpHUIfNO4bw7MPcc3k,1255
@@ -404,8 +408,8 @@ bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button.py,sha256=O
404
408
  bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button.pyproject,sha256=Lbi9zb6HNlIq14k6hlzR-oz6PIFShBuF7QxE6d87d64,34
405
409
  bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button_plugin.py,sha256=CzChz2SSETYsR8-36meqWnsXCT-FIy_J_xeU5coWDY8,1350
406
410
  bec_widgets/widgets/utility/visual/dark_mode_button/register_dark_mode_button.py,sha256=rMpZ1CaoucwobgPj1FuKTnt07W82bV1GaSYdoqcdMb8,521
407
- bec_widgets-2.8.3.dist-info/METADATA,sha256=m4bfcr8jJsEua1MIwebS06gdMZN4x8PzQ5cRHeWZo7I,1273
408
- bec_widgets-2.8.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
409
- bec_widgets-2.8.3.dist-info/entry_points.txt,sha256=dItMzmwA1wizJ1Itx15qnfJ0ZzKVYFLVJ1voxT7K7D4,214
410
- bec_widgets-2.8.3.dist-info/licenses/LICENSE,sha256=Daeiu871NcAp8uYi4eB_qHgvypG-HX0ioRQyQxFwjeg,1531
411
- bec_widgets-2.8.3.dist-info/RECORD,,
411
+ bec_widgets-2.9.0.dist-info/METADATA,sha256=7m3lNNzWQOJNlrFeOIh5CNZty3XmjTVzlF26SB9hvnw,1273
412
+ bec_widgets-2.9.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
413
+ bec_widgets-2.9.0.dist-info/entry_points.txt,sha256=dItMzmwA1wizJ1Itx15qnfJ0ZzKVYFLVJ1voxT7K7D4,214
414
+ bec_widgets-2.9.0.dist-info/licenses/LICENSE,sha256=Daeiu871NcAp8uYi4eB_qHgvypG-HX0ioRQyQxFwjeg,1531
415
+ bec_widgets-2.9.0.dist-info/RECORD,,
pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "bec_widgets"
7
- version = "2.8.3"
7
+ version = "2.9.0"
8
8
  description = "BEC Widgets"
9
9
  requires-python = ">=3.10"
10
10
  classifiers = [