bec-widgets 1.25.1__py3-none-any.whl → 2.0.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 (196) hide show
  1. .gitlab-ci.yml +3 -5
  2. CHANGELOG.md +631 -0
  3. PKG-INFO +3 -3
  4. bec_widgets/__init__.py +4 -0
  5. bec_widgets/applications/bw_launch.py +23 -0
  6. bec_widgets/applications/launch_window.py +430 -0
  7. bec_widgets/assets/app_icons/auto_update.png +0 -0
  8. bec_widgets/assets/app_icons/ui_loader_tile.png +0 -0
  9. bec_widgets/cli/__init__.py +0 -1
  10. bec_widgets/cli/client.py +1779 -2064
  11. bec_widgets/cli/client_utils.py +346 -174
  12. bec_widgets/cli/generate_cli.py +143 -37
  13. bec_widgets/cli/rpc/rpc_base.py +152 -21
  14. bec_widgets/cli/rpc/rpc_register.py +113 -6
  15. bec_widgets/cli/rpc/rpc_widget_handler.py +13 -11
  16. bec_widgets/cli/server.py +125 -239
  17. bec_widgets/examples/jupyter_console/jupyter_console_window.py +97 -145
  18. bec_widgets/examples/plugin_example_pyside/tictactoetaskmenu.py +1 -1
  19. bec_widgets/utils/bec_connector.py +190 -21
  20. bec_widgets/utils/bec_designer.py +7 -0
  21. bec_widgets/utils/bec_dispatcher.py +71 -4
  22. bec_widgets/utils/bec_plugin_helper.py +89 -0
  23. bec_widgets/utils/bec_signal_proxy.py +1 -1
  24. bec_widgets/utils/bec_widget.py +26 -10
  25. bec_widgets/utils/colors.py +1 -1
  26. bec_widgets/{qt_utils → utils}/compact_popup.py +2 -0
  27. bec_widgets/utils/container_utils.py +37 -12
  28. bec_widgets/utils/crosshair.py +25 -8
  29. bec_widgets/utils/entry_validator.py +3 -1
  30. bec_widgets/{qt_utils → utils}/error_popups.py +18 -0
  31. bec_widgets/{qt_utils → utils}/expandable_frame.py +2 -2
  32. bec_widgets/utils/forms_from_types/forms.py +182 -0
  33. bec_widgets/{widgets/editors/scan_metadata/_metadata_widgets.py → utils/forms_from_types/items.py} +41 -30
  34. bec_widgets/utils/generate_designer_plugin.py +40 -36
  35. bec_widgets/utils/linear_region_selector.py +2 -0
  36. bec_widgets/utils/name_utils.py +16 -0
  37. bec_widgets/{qt_utils → utils}/palette_viewer.py +2 -2
  38. bec_widgets/utils/plot_indicator_items.py +2 -5
  39. bec_widgets/utils/plugin_utils.py +47 -1
  40. bec_widgets/{qt_utils → utils}/round_frame.py +14 -14
  41. bec_widgets/utils/rpc_server.py +277 -0
  42. bec_widgets/utils/serialization.py +44 -0
  43. bec_widgets/{qt_utils → utils}/settings_dialog.py +26 -1
  44. bec_widgets/{qt_utils → utils}/side_panel.py +17 -10
  45. bec_widgets/{qt_utils → utils}/toolbar.py +69 -25
  46. bec_widgets/utils/ui_loader.py +8 -8
  47. bec_widgets/utils/widget_io.py +166 -25
  48. bec_widgets/widgets/containers/auto_update/auto_updates.py +364 -0
  49. bec_widgets/widgets/containers/dock/dock.py +157 -49
  50. bec_widgets/widgets/containers/dock/dock_area.py +186 -138
  51. bec_widgets/widgets/containers/layout_manager/layout_manager.py +2 -1
  52. bec_widgets/widgets/containers/main_window/addons/web_links.py +15 -0
  53. bec_widgets/widgets/containers/main_window/main_window.py +189 -41
  54. bec_widgets/widgets/control/buttons/button_abort/button_abort.py +3 -4
  55. bec_widgets/widgets/control/buttons/button_reset/button_reset.py +3 -4
  56. bec_widgets/widgets/control/buttons/button_resume/button_resume.py +3 -3
  57. bec_widgets/widgets/control/buttons/stop_button/stop_button.py +18 -7
  58. bec_widgets/widgets/control/device_control/position_indicator/position_indicator.py +22 -3
  59. bec_widgets/widgets/control/device_control/positioner_box/_base/positioner_box_base.py +31 -13
  60. bec_widgets/widgets/control/device_control/positioner_box/positioner_box/positioner_box.py +3 -1
  61. bec_widgets/widgets/control/device_control/positioner_box/positioner_box/positioner_box.ui +27 -4
  62. bec_widgets/widgets/control/device_control/positioner_box/positioner_box_2d/positioner_box_2d.py +5 -2
  63. bec_widgets/widgets/control/device_control/positioner_box/positioner_box_2d/positioner_box_2d.ui +97 -31
  64. bec_widgets/widgets/control/device_control/positioner_box/positioner_control_line/positioner_control_line.ui +11 -4
  65. bec_widgets/widgets/control/device_control/positioner_group/positioner_group.py +2 -3
  66. bec_widgets/widgets/control/device_input/base_classes/device_input_base.py +29 -4
  67. bec_widgets/widgets/control/device_input/base_classes/device_signal_input_base.py +1 -0
  68. bec_widgets/widgets/control/device_input/device_combobox/device_combobox.py +2 -2
  69. bec_widgets/widgets/control/device_input/device_line_edit/device_line_edit.py +2 -2
  70. bec_widgets/widgets/control/device_input/signal_combobox/signal_combobox.py +1 -2
  71. bec_widgets/widgets/control/device_input/signal_line_edit/signal_line_edit.py +1 -2
  72. bec_widgets/widgets/control/scan_control/scan_control.py +7 -5
  73. bec_widgets/widgets/control/scan_control/scan_group_box.py +28 -5
  74. bec_widgets/widgets/dap/dap_combo_box/dap_combo_box.py +1 -2
  75. bec_widgets/widgets/dap/lmfit_dialog/lmfit_dialog.py +3 -4
  76. bec_widgets/widgets/dap/lmfit_dialog/lmfit_dialog_vertical.ui +14 -8
  77. bec_widgets/widgets/editors/console/console.py +1 -1
  78. bec_widgets/widgets/editors/{scan_metadata/additional_metadata_table.py → dict_backed_table.py} +29 -6
  79. bec_widgets/widgets/editors/scan_metadata/__init__.py +0 -7
  80. bec_widgets/widgets/editors/scan_metadata/_util.py +1 -1
  81. bec_widgets/widgets/{plots/motor_map/register_bec_motor_map_widget.py → editors/scan_metadata/register_scan_metadata.py} +2 -4
  82. bec_widgets/widgets/editors/scan_metadata/scan_metadata.py +42 -136
  83. bec_widgets/widgets/editors/scan_metadata/scan_metadata.pyproject +1 -0
  84. bec_widgets/widgets/{plots/multi_waveform/bec_multi_waveform_widget_plugin.py → editors/scan_metadata/scan_metadata_plugin.py} +9 -9
  85. bec_widgets/widgets/editors/text_box/text_box.py +2 -3
  86. bec_widgets/widgets/editors/website/website.py +2 -2
  87. bec_widgets/widgets/games/minesweeper.py +3 -2
  88. bec_widgets/widgets/plots/image/image.py +960 -0
  89. bec_widgets/widgets/plots/image/image.pyproject +1 -0
  90. bec_widgets/widgets/plots/image/image_item.py +279 -0
  91. bec_widgets/widgets/plots/{motor_map/bec_motor_map_widget_plugin.py → image/image_plugin.py} +11 -13
  92. bec_widgets/widgets/{containers/figure/plots → plots}/image/image_processor.py +31 -64
  93. bec_widgets/widgets/plots/image/{register_bec_image_widget.py → register_image.py} +2 -2
  94. bec_widgets/widgets/plots/image/toolbar_bundles/image_selection.py +59 -0
  95. bec_widgets/widgets/plots/image/toolbar_bundles/processing.py +79 -0
  96. bec_widgets/widgets/plots/motor_map/motor_map.py +832 -0
  97. bec_widgets/widgets/plots/motor_map/motor_map.pyproject +1 -0
  98. bec_widgets/widgets/plots/motor_map/motor_map_plugin.py +54 -0
  99. bec_widgets/widgets/plots/{multi_waveform/register_bec_multi_waveform_widget.py → motor_map/register_motor_map.py} +2 -4
  100. bec_widgets/widgets/plots/motor_map/settings/motor_map_settings.py +129 -0
  101. bec_widgets/widgets/plots/motor_map/settings/motor_map_settings.ui +120 -0
  102. bec_widgets/widgets/plots/motor_map/toolbar_bundles/motor_selection.py +70 -0
  103. bec_widgets/widgets/plots/multi_waveform/multi_waveform.py +508 -0
  104. bec_widgets/widgets/plots/multi_waveform/multi_waveform.pyproject +1 -0
  105. bec_widgets/widgets/plots/multi_waveform/multi_waveform_plugin.py +54 -0
  106. bec_widgets/widgets/plots/multi_waveform/register_multi_waveform.py +15 -0
  107. bec_widgets/widgets/plots/multi_waveform/settings/control_panel.py +144 -0
  108. bec_widgets/widgets/plots/multi_waveform/settings/multi_waveform_controls.ui +164 -0
  109. bec_widgets/widgets/plots/multi_waveform/toolbar_bundles/monitor_selection.py +65 -0
  110. bec_widgets/widgets/{plots_next_gen → plots}/plot_base.py +321 -40
  111. bec_widgets/widgets/plots/{waveform/register_bec_waveform_widget.py → scatter_waveform/register_scatter_waveform.py} +3 -3
  112. bec_widgets/widgets/plots/scatter_waveform/scatter_curve.py +197 -0
  113. bec_widgets/widgets/plots/scatter_waveform/scatter_waveform.py +553 -0
  114. bec_widgets/widgets/plots/scatter_waveform/scatter_waveform.pyproject +1 -0
  115. bec_widgets/widgets/plots/{image/bec_image_widget_plugin.py → scatter_waveform/scatter_waveform_plugin.py} +9 -13
  116. bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_setting.py +138 -0
  117. bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_settings_horizontal.ui +195 -0
  118. bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_settings_vertical.ui +204 -0
  119. bec_widgets/widgets/{plots_next_gen → plots}/setting_menus/axis_settings.py +8 -8
  120. bec_widgets/widgets/{plots_next_gen → plots}/toolbar_bundles/mouse_interactions.py +4 -18
  121. bec_widgets/widgets/{plots_next_gen → plots}/toolbar_bundles/plot_export.py +14 -3
  122. bec_widgets/widgets/{plots_next_gen → plots}/toolbar_bundles/roi_bundle.py +6 -1
  123. bec_widgets/widgets/{plots_next_gen → plots}/toolbar_bundles/save_state.py +2 -2
  124. bec_widgets/widgets/{containers/figure/plots/waveform/waveform_curve.py → plots/waveform/curve.py} +119 -49
  125. bec_widgets/widgets/plots/waveform/register_waveform.py +15 -0
  126. bec_widgets/widgets/plots/waveform/settings/curve_settings/curve_setting.py +125 -0
  127. bec_widgets/widgets/plots/waveform/settings/curve_settings/curve_tree.py +576 -0
  128. bec_widgets/widgets/plots/waveform/utils/__init__.py +0 -0
  129. bec_widgets/widgets/plots/waveform/utils/roi_manager.py +84 -0
  130. bec_widgets/widgets/plots/waveform/waveform.py +1794 -0
  131. bec_widgets/widgets/plots/waveform/waveform.pyproject +1 -0
  132. bec_widgets/widgets/plots/waveform/{bec_waveform_widget_plugin.py → waveform_plugin.py} +9 -13
  133. bec_widgets/widgets/progress/bec_progressbar/bec_progressbar.py +1 -2
  134. bec_widgets/widgets/progress/ring_progress_bar/ring.py +11 -10
  135. bec_widgets/widgets/progress/ring_progress_bar/ring_progress_bar.py +24 -14
  136. bec_widgets/widgets/services/bec_queue/bec_queue.py +13 -11
  137. bec_widgets/widgets/services/bec_status_box/bec_status_box.py +3 -4
  138. bec_widgets/widgets/services/device_browser/device_browser.py +5 -2
  139. bec_widgets/widgets/services/device_browser/device_item/device_item.py +1 -1
  140. bec_widgets/widgets/utility/logpanel/logpanel.py +36 -17
  141. bec_widgets/widgets/utility/spinbox/decimal_spinbox.py +3 -3
  142. bec_widgets/widgets/utility/visual/color_button/color_button.py +1 -1
  143. bec_widgets/widgets/utility/visual/colormap_widget/colormap_widget.py +4 -6
  144. bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button.py +4 -8
  145. {bec_widgets-1.25.1.dist-info → bec_widgets-2.0.0.dist-info}/METADATA +3 -3
  146. {bec_widgets-1.25.1.dist-info → bec_widgets-2.0.0.dist-info}/RECORD +168 -153
  147. pyproject.toml +3 -3
  148. bec_widgets/applications/alignment/alignment_1d/alignment_1d.py +0 -198
  149. bec_widgets/applications/alignment/alignment_1d/alignment_1d.ui +0 -615
  150. bec_widgets/applications/bec_app.py +0 -84
  151. bec_widgets/cli/auto_updates.py +0 -168
  152. bec_widgets/widgets/containers/figure/__init__.py +0 -1
  153. bec_widgets/widgets/containers/figure/figure.py +0 -796
  154. bec_widgets/widgets/containers/figure/plots/axis_settings.py +0 -91
  155. bec_widgets/widgets/containers/figure/plots/axis_settings.ui +0 -256
  156. bec_widgets/widgets/containers/figure/plots/image/image.py +0 -772
  157. bec_widgets/widgets/containers/figure/plots/image/image_item.py +0 -337
  158. bec_widgets/widgets/containers/figure/plots/motor_map/motor_map.py +0 -525
  159. bec_widgets/widgets/containers/figure/plots/multi_waveform/multi_waveform.py +0 -340
  160. bec_widgets/widgets/containers/figure/plots/plot_base.py +0 -505
  161. bec_widgets/widgets/containers/figure/plots/waveform/waveform.py +0 -1563
  162. bec_widgets/widgets/plots/image/bec_image_widget.pyproject +0 -1
  163. bec_widgets/widgets/plots/image/image_widget.py +0 -515
  164. bec_widgets/widgets/plots/motor_map/bec_motor_map_widget.pyproject +0 -1
  165. bec_widgets/widgets/plots/motor_map/motor_map_dialog/motor_map_settings.py +0 -56
  166. bec_widgets/widgets/plots/motor_map/motor_map_dialog/motor_map_settings.ui +0 -108
  167. bec_widgets/widgets/plots/motor_map/motor_map_widget.py +0 -234
  168. bec_widgets/widgets/plots/multi_waveform/bec_multi_waveform_widget.pyproject +0 -1
  169. bec_widgets/widgets/plots/multi_waveform/multi_waveform_controls.ui +0 -99
  170. bec_widgets/widgets/plots/multi_waveform/multi_waveform_widget.py +0 -536
  171. bec_widgets/widgets/plots/waveform/bec_waveform_widget.pyproject +0 -1
  172. bec_widgets/widgets/plots/waveform/waveform_popups/curve_dialog/curve_dialog.py +0 -336
  173. bec_widgets/widgets/plots/waveform/waveform_popups/curve_dialog/curve_dialog.ui +0 -372
  174. bec_widgets/widgets/plots/waveform/waveform_popups/dap_summary_dialog/dap_summary_dialog.py +0 -25
  175. bec_widgets/widgets/plots/waveform/waveform_widget.py +0 -751
  176. /bec_widgets/{qt_utils → utils}/collapsible_panel_manager.py +0 -0
  177. /bec_widgets/{applications/alignment → utils/forms_from_types}/__init__.py +0 -0
  178. /bec_widgets/{qt_utils → utils}/redis_message_waiter.py +0 -0
  179. /bec_widgets/{applications/alignment/alignment_1d → widgets/containers/auto_update}/__init__.py +0 -0
  180. /bec_widgets/{qt_utils → widgets/containers/main_window/addons}/__init__.py +0 -0
  181. /bec_widgets/widgets/{containers/figure/plots → plots/image/toolbar_bundles}/__init__.py +0 -0
  182. /bec_widgets/widgets/{containers/figure/plots/image → plots/motor_map/settings}/__init__.py +0 -0
  183. /bec_widgets/widgets/{containers/figure/plots/motor_map → plots/motor_map/toolbar_bundles}/__init__.py +0 -0
  184. /bec_widgets/widgets/{containers/figure/plots/multi_waveform → plots/multi_waveform/settings}/__init__.py +0 -0
  185. /bec_widgets/widgets/{containers/figure/plots/waveform → plots/multi_waveform/toolbar_bundles}/__init__.py +0 -0
  186. /bec_widgets/widgets/plots/{motor_map/motor_map_dialog → scatter_waveform}/__init__.py +0 -0
  187. /bec_widgets/widgets/plots/{waveform/waveform_popups → scatter_waveform/settings}/__init__.py +0 -0
  188. /bec_widgets/widgets/plots/{waveform/waveform_popups/curve_dialog → setting_menus}/__init__.py +0 -0
  189. /bec_widgets/widgets/{plots_next_gen → plots}/setting_menus/axis_settings_horizontal.ui +0 -0
  190. /bec_widgets/widgets/{plots_next_gen → plots}/setting_menus/axis_settings_vertical.ui +0 -0
  191. /bec_widgets/widgets/plots/{waveform/waveform_popups/dap_summary_dialog → toolbar_bundles}/__init__.py +0 -0
  192. /bec_widgets/widgets/{plots_next_gen/setting_menus → plots/waveform/settings}/__init__.py +0 -0
  193. /bec_widgets/widgets/{plots_next_gen/toolbar_bundles → plots/waveform/settings/curve_settings}/__init__.py +0 -0
  194. {bec_widgets-1.25.1.dist-info → bec_widgets-2.0.0.dist-info}/WHEEL +0 -0
  195. {bec_widgets-1.25.1.dist-info → bec_widgets-2.0.0.dist-info}/entry_points.txt +0 -0
  196. {bec_widgets-1.25.1.dist-info → bec_widgets-2.0.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,144 @@
1
+ import os
2
+
3
+ from qtpy.QtWidgets import QVBoxLayout, QWidget
4
+
5
+ from bec_widgets.utils import UILoader
6
+ from bec_widgets.utils.error_popups import SafeSlot
7
+ from bec_widgets.utils.settings_dialog import SettingWidget
8
+ from bec_widgets.utils.widget_io import WidgetIO
9
+
10
+
11
+ class MultiWaveformControlPanel(SettingWidget):
12
+ """
13
+ A settings widget MultiWaveformControlPanel that allows the user to modify the properties.
14
+
15
+ The widget has skip_settings property set to True, which means it should not be saved
16
+ in the settings file. It is used to mirror the properties of the target widget.
17
+ """
18
+
19
+ def __init__(self, parent=None, target_widget=None, *args, **kwargs):
20
+ super().__init__(parent=parent, *args, **kwargs)
21
+
22
+ self.setProperty("skip_settings", True)
23
+ current_path = os.path.dirname(__file__)
24
+
25
+ form = UILoader().load_ui(os.path.join(current_path, "multi_waveform_controls.ui"), self)
26
+
27
+ self.target_widget = target_widget
28
+
29
+ self.layout = QVBoxLayout(self)
30
+ self.layout.setContentsMargins(0, 0, 0, 0)
31
+ self.ui = form
32
+
33
+ self.ui_widget_list = [
34
+ self.ui.opacity,
35
+ self.ui.highlighted_index,
36
+ self.ui.highlight_last_curve,
37
+ self.ui.flush_buffer,
38
+ self.ui.max_trace,
39
+ ]
40
+
41
+ if self.target_widget is not None:
42
+ self.connect_all_signals()
43
+ self.target_widget.property_changed.connect(self.update_property)
44
+ self.target_widget.monitor_signal_updated.connect(self.update_controls_limits)
45
+ self.ui.highlight_last_curve.toggled.connect(self.set_highlight_last_curve)
46
+
47
+ self.fetch_all_properties()
48
+
49
+ def connect_all_signals(self):
50
+ for widget in self.ui_widget_list:
51
+ WidgetIO.connect_widget_change_signal(widget, self.set_property)
52
+
53
+ @SafeSlot()
54
+ def set_property(self, widget: QWidget, value):
55
+ """
56
+ Set property of the target widget based on the widget that emitted the signal.
57
+ The name of the property has to be the same as the objectName of the widget
58
+ and compatible with WidgetIO.
59
+
60
+ Args:
61
+ widget(QWidget): The widget that emitted the signal.
62
+ value(): The value to set the property to.
63
+ """
64
+
65
+ try: # to avoid crashing when the widget is not found in Designer
66
+ property_name = widget.objectName()
67
+ setattr(self.target_widget, property_name, value)
68
+ except RuntimeError:
69
+ return
70
+
71
+ @SafeSlot()
72
+ def update_property(self, property_name: str, value):
73
+ """
74
+ Update the value of the widget based on the property name and value.
75
+ The name of the property has to be the same as the objectName of the widget
76
+ and compatible with WidgetIO.
77
+
78
+ Args:
79
+ property_name(str): The name of the property to update.
80
+ value: The value to set the property to.
81
+ """
82
+ try: # to avoid crashing when the widget is not found in Designer
83
+ widget_to_set = self.ui.findChild(QWidget, property_name)
84
+ except RuntimeError:
85
+ return
86
+ if widget_to_set is None:
87
+ return
88
+
89
+ WidgetIO.set_value(widget_to_set, value)
90
+
91
+ def fetch_all_properties(self):
92
+ """
93
+ Fetch all properties from the target widget and update the settings widget.
94
+ """
95
+ for widget in self.ui_widget_list:
96
+ property_name = widget.objectName()
97
+ value = getattr(self.target_widget, property_name)
98
+ WidgetIO.set_value(widget, value)
99
+
100
+ def accept_changes(self):
101
+ """
102
+ Apply all properties from the settings widget to the target widget.
103
+ """
104
+ for widget in self.ui_widget_list:
105
+ property_name = widget.objectName()
106
+ value = WidgetIO.get_value(widget)
107
+ setattr(self.target_widget, property_name, value)
108
+
109
+ @SafeSlot()
110
+ def update_controls_limits(self):
111
+ """
112
+ Update the limits of the controls.
113
+ """
114
+ num_curves = len(self.target_widget.curves)
115
+ if num_curves == 0:
116
+ num_curves = 1 # Avoid setting max to 0
117
+ current_index = num_curves - 1
118
+ self.ui.highlighted_index.setMinimum(0)
119
+ self.ui.highlighted_index.setMaximum(self.target_widget.number_of_visible_curves - 1)
120
+ self.ui.spinbox_index.setMaximum(self.target_widget.number_of_visible_curves - 1)
121
+ if self.ui.highlight_last_curve.isChecked():
122
+ self.ui.highlighted_index.setValue(current_index)
123
+ self.ui.spinbox_index.setValue(current_index)
124
+
125
+ @SafeSlot(bool)
126
+ def set_highlight_last_curve(self, enable: bool) -> None:
127
+ """
128
+ Enable or disable highlighting of the last curve.
129
+
130
+ Args:
131
+ enable(bool): True to enable highlighting of the last curve, False to disable.
132
+ """
133
+ self.target_widget.config.highlight_last_curve = enable
134
+ if enable:
135
+ self.ui.highlighted_index.setEnabled(False)
136
+ self.ui.spinbox_index.setEnabled(False)
137
+ self.ui.highlight_last_curve.setChecked(True)
138
+ self.target_widget.set_curve_highlight(-1)
139
+ else:
140
+ self.ui.highlighted_index.setEnabled(True)
141
+ self.ui.spinbox_index.setEnabled(True)
142
+ self.ui.highlight_last_curve.setChecked(False)
143
+ index = self.ui.spinbox_index.value()
144
+ self.target_widget.set_curve_highlight(index)
@@ -0,0 +1,164 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <ui version="4.0">
3
+ <class>Form</class>
4
+ <widget class="QWidget" name="Form">
5
+ <property name="geometry">
6
+ <rect>
7
+ <x>0</x>
8
+ <y>0</y>
9
+ <width>561</width>
10
+ <height>86</height>
11
+ </rect>
12
+ </property>
13
+ <property name="windowTitle">
14
+ <string>Form</string>
15
+ </property>
16
+ <layout class="QGridLayout" name="gridLayout">
17
+ <item row="0" column="0">
18
+ <widget class="QLabel" name="label_curve_index">
19
+ <property name="text">
20
+ <string>Curve Index</string>
21
+ </property>
22
+ </widget>
23
+ </item>
24
+ <item row="0" column="1">
25
+ <widget class="QSlider" name="highlighted_index">
26
+ <property name="orientation">
27
+ <enum>Qt::Orientation::Horizontal</enum>
28
+ </property>
29
+ </widget>
30
+ </item>
31
+ <item row="0" column="2">
32
+ <widget class="QSpinBox" name="spinbox_index"/>
33
+ </item>
34
+ <item row="0" column="3" colspan="3">
35
+ <widget class="QCheckBox" name="highlight_last_curve">
36
+ <property name="text">
37
+ <string>Highlight always last curve</string>
38
+ </property>
39
+ </widget>
40
+ </item>
41
+ <item row="1" column="0">
42
+ <widget class="QLabel" name="label_opacity">
43
+ <property name="text">
44
+ <string>Opacity</string>
45
+ </property>
46
+ </widget>
47
+ </item>
48
+ <item row="1" column="1">
49
+ <widget class="QSlider" name="opacity">
50
+ <property name="maximum">
51
+ <number>100</number>
52
+ </property>
53
+ <property name="orientation">
54
+ <enum>Qt::Orientation::Horizontal</enum>
55
+ </property>
56
+ </widget>
57
+ </item>
58
+ <item row="1" column="3">
59
+ <widget class="QLabel" name="label_max_trace">
60
+ <property name="text">
61
+ <string>Max Trace</string>
62
+ </property>
63
+ </widget>
64
+ </item>
65
+ <item row="1" column="4">
66
+ <widget class="QSpinBox" name="max_trace">
67
+ <property name="toolTip">
68
+ <string>How many curves should be displayed</string>
69
+ </property>
70
+ <property name="maximum">
71
+ <number>500</number>
72
+ </property>
73
+ <property name="value">
74
+ <number>200</number>
75
+ </property>
76
+ </widget>
77
+ </item>
78
+ <item row="1" column="5">
79
+ <widget class="QCheckBox" name="flush_buffer">
80
+ <property name="toolTip">
81
+ <string>If hiddne curves should be deleted.</string>
82
+ </property>
83
+ <property name="text">
84
+ <string>Flush Buffer</string>
85
+ </property>
86
+ </widget>
87
+ </item>
88
+ <item row="1" column="2">
89
+ <widget class="QSpinBox" name="spinbox_opacity">
90
+ <property name="maximum">
91
+ <number>100</number>
92
+ </property>
93
+ </widget>
94
+ </item>
95
+ </layout>
96
+ </widget>
97
+ <resources/>
98
+ <connections>
99
+ <connection>
100
+ <sender>opacity</sender>
101
+ <signal>valueChanged(int)</signal>
102
+ <receiver>spinbox_opacity</receiver>
103
+ <slot>setValue(int)</slot>
104
+ <hints>
105
+ <hint type="sourcelabel">
106
+ <x>211</x>
107
+ <y>66</y>
108
+ </hint>
109
+ <hint type="destinationlabel">
110
+ <x>260</x>
111
+ <y>59</y>
112
+ </hint>
113
+ </hints>
114
+ </connection>
115
+ <connection>
116
+ <sender>spinbox_opacity</sender>
117
+ <signal>valueChanged(int)</signal>
118
+ <receiver>opacity</receiver>
119
+ <slot>setValue(int)</slot>
120
+ <hints>
121
+ <hint type="sourcelabel">
122
+ <x>269</x>
123
+ <y>62</y>
124
+ </hint>
125
+ <hint type="destinationlabel">
126
+ <x>182</x>
127
+ <y>62</y>
128
+ </hint>
129
+ </hints>
130
+ </connection>
131
+ <connection>
132
+ <sender>highlighted_index</sender>
133
+ <signal>valueChanged(int)</signal>
134
+ <receiver>spinbox_index</receiver>
135
+ <slot>setValue(int)</slot>
136
+ <hints>
137
+ <hint type="sourcelabel">
138
+ <x>191</x>
139
+ <y>27</y>
140
+ </hint>
141
+ <hint type="destinationlabel">
142
+ <x>256</x>
143
+ <y>27</y>
144
+ </hint>
145
+ </hints>
146
+ </connection>
147
+ <connection>
148
+ <sender>spinbox_index</sender>
149
+ <signal>valueChanged(int)</signal>
150
+ <receiver>highlighted_index</receiver>
151
+ <slot>setValue(int)</slot>
152
+ <hints>
153
+ <hint type="sourcelabel">
154
+ <x>264</x>
155
+ <y>20</y>
156
+ </hint>
157
+ <hint type="destinationlabel">
158
+ <x>195</x>
159
+ <y>24</y>
160
+ </hint>
161
+ </hints>
162
+ </connection>
163
+ </connections>
164
+ </ui>
@@ -0,0 +1,65 @@
1
+ from bec_lib.device import ReadoutPriority
2
+ from qtpy.QtCore import Qt
3
+ from qtpy.QtWidgets import QStyledItemDelegate
4
+
5
+ from bec_widgets.utils.error_popups import SafeSlot
6
+ from bec_widgets.utils.toolbar import ToolbarBundle, WidgetAction
7
+ from bec_widgets.widgets.control.device_input.base_classes.device_input_base import BECDeviceFilter
8
+ from bec_widgets.widgets.control.device_input.device_combobox.device_combobox import DeviceComboBox
9
+ from bec_widgets.widgets.utility.visual.colormap_widget.colormap_widget import BECColorMapWidget
10
+
11
+
12
+ class NoCheckDelegate(QStyledItemDelegate):
13
+ """To reduce space in combo boxes by removing the checkmark."""
14
+
15
+ def initStyleOption(self, option, index):
16
+ super().initStyleOption(option, index)
17
+ # Remove any check indicator
18
+ option.checkState = Qt.Unchecked
19
+
20
+
21
+ class MultiWaveformSelectionToolbarBundle(ToolbarBundle):
22
+ """
23
+ A bundle of actions for a toolbar that selects motors.
24
+ """
25
+
26
+ def __init__(self, bundle_id="monitor_selection", target_widget=None, **kwargs):
27
+ super().__init__(bundle_id=bundle_id, actions=[], **kwargs)
28
+ self.target_widget = target_widget
29
+
30
+ # Monitor Selection
31
+ self.monitor = DeviceComboBox(
32
+ device_filter=BECDeviceFilter.DEVICE, readout_priority_filter=ReadoutPriority.ASYNC
33
+ )
34
+ self.monitor.addItem("", None)
35
+ self.monitor.setCurrentText("")
36
+ self.monitor.setToolTip("Select Monitor")
37
+ self.monitor.setItemDelegate(NoCheckDelegate(self.monitor))
38
+ self.add_action("monitor", WidgetAction(widget=self.monitor, adjust_size=False))
39
+
40
+ # Colormap Selection
41
+ self.colormap_widget = BECColorMapWidget(cmap="plasma")
42
+ self.add_action("color_map", WidgetAction(widget=self.colormap_widget, adjust_size=False))
43
+
44
+ # Connect slots, a device will be connected upon change of any combobox
45
+ self.monitor.currentTextChanged.connect(lambda: self.connect())
46
+ self.colormap_widget.colormap_changed_signal.connect(self.change_colormap)
47
+
48
+ @SafeSlot()
49
+ def connect(self):
50
+ monitor = self.monitor.currentText()
51
+
52
+ if monitor != "":
53
+ if monitor != self.target_widget.config.monitor:
54
+ self.target_widget.monitor = monitor
55
+
56
+ @SafeSlot(str)
57
+ def change_colormap(self, colormap: str):
58
+ self.target_widget.color_palette = colormap
59
+
60
+ def cleanup(self):
61
+ """
62
+ Cleanup the toolbar bundle.
63
+ """
64
+ self.monitor.close()
65
+ self.monitor.deleteLater()