bec-widgets 1.25.0__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 (197) hide show
  1. .gitlab-ci.yml +11 -6
  2. CHANGELOG.md +650 -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 +37 -18
  60. bec_widgets/widgets/control/device_control/positioner_box/positioner_box/positioner_box.py +28 -4
  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/spinner/spinner.py +2 -2
  143. bec_widgets/widgets/utility/visual/color_button/color_button.py +1 -1
  144. bec_widgets/widgets/utility/visual/colormap_widget/colormap_widget.py +4 -6
  145. bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button.py +4 -8
  146. {bec_widgets-1.25.0.dist-info → bec_widgets-2.0.0.dist-info}/METADATA +3 -3
  147. {bec_widgets-1.25.0.dist-info → bec_widgets-2.0.0.dist-info}/RECORD +169 -154
  148. pyproject.toml +3 -3
  149. bec_widgets/applications/alignment/alignment_1d/alignment_1d.py +0 -198
  150. bec_widgets/applications/alignment/alignment_1d/alignment_1d.ui +0 -615
  151. bec_widgets/applications/bec_app.py +0 -84
  152. bec_widgets/cli/auto_updates.py +0 -168
  153. bec_widgets/widgets/containers/figure/__init__.py +0 -1
  154. bec_widgets/widgets/containers/figure/figure.py +0 -796
  155. bec_widgets/widgets/containers/figure/plots/axis_settings.py +0 -91
  156. bec_widgets/widgets/containers/figure/plots/axis_settings.ui +0 -256
  157. bec_widgets/widgets/containers/figure/plots/image/image.py +0 -772
  158. bec_widgets/widgets/containers/figure/plots/image/image_item.py +0 -337
  159. bec_widgets/widgets/containers/figure/plots/motor_map/motor_map.py +0 -525
  160. bec_widgets/widgets/containers/figure/plots/multi_waveform/multi_waveform.py +0 -340
  161. bec_widgets/widgets/containers/figure/plots/plot_base.py +0 -505
  162. bec_widgets/widgets/containers/figure/plots/waveform/waveform.py +0 -1563
  163. bec_widgets/widgets/plots/image/bec_image_widget.pyproject +0 -1
  164. bec_widgets/widgets/plots/image/image_widget.py +0 -515
  165. bec_widgets/widgets/plots/motor_map/bec_motor_map_widget.pyproject +0 -1
  166. bec_widgets/widgets/plots/motor_map/motor_map_dialog/motor_map_settings.py +0 -56
  167. bec_widgets/widgets/plots/motor_map/motor_map_dialog/motor_map_settings.ui +0 -108
  168. bec_widgets/widgets/plots/motor_map/motor_map_widget.py +0 -234
  169. bec_widgets/widgets/plots/multi_waveform/bec_multi_waveform_widget.pyproject +0 -1
  170. bec_widgets/widgets/plots/multi_waveform/multi_waveform_controls.ui +0 -99
  171. bec_widgets/widgets/plots/multi_waveform/multi_waveform_widget.py +0 -536
  172. bec_widgets/widgets/plots/waveform/bec_waveform_widget.pyproject +0 -1
  173. bec_widgets/widgets/plots/waveform/waveform_popups/curve_dialog/curve_dialog.py +0 -336
  174. bec_widgets/widgets/plots/waveform/waveform_popups/curve_dialog/curve_dialog.ui +0 -372
  175. bec_widgets/widgets/plots/waveform/waveform_popups/dap_summary_dialog/dap_summary_dialog.py +0 -25
  176. bec_widgets/widgets/plots/waveform/waveform_widget.py +0 -751
  177. /bec_widgets/{qt_utils → utils}/collapsible_panel_manager.py +0 -0
  178. /bec_widgets/{applications/alignment → utils/forms_from_types}/__init__.py +0 -0
  179. /bec_widgets/{qt_utils → utils}/redis_message_waiter.py +0 -0
  180. /bec_widgets/{applications/alignment/alignment_1d → widgets/containers/auto_update}/__init__.py +0 -0
  181. /bec_widgets/{qt_utils → widgets/containers/main_window/addons}/__init__.py +0 -0
  182. /bec_widgets/widgets/{containers/figure/plots → plots/image/toolbar_bundles}/__init__.py +0 -0
  183. /bec_widgets/widgets/{containers/figure/plots/image → plots/motor_map/settings}/__init__.py +0 -0
  184. /bec_widgets/widgets/{containers/figure/plots/motor_map → plots/motor_map/toolbar_bundles}/__init__.py +0 -0
  185. /bec_widgets/widgets/{containers/figure/plots/multi_waveform → plots/multi_waveform/settings}/__init__.py +0 -0
  186. /bec_widgets/widgets/{containers/figure/plots/waveform → plots/multi_waveform/toolbar_bundles}/__init__.py +0 -0
  187. /bec_widgets/widgets/plots/{motor_map/motor_map_dialog → scatter_waveform}/__init__.py +0 -0
  188. /bec_widgets/widgets/plots/{waveform/waveform_popups → scatter_waveform/settings}/__init__.py +0 -0
  189. /bec_widgets/widgets/plots/{waveform/waveform_popups/curve_dialog → setting_menus}/__init__.py +0 -0
  190. /bec_widgets/widgets/{plots_next_gen → plots}/setting_menus/axis_settings_horizontal.ui +0 -0
  191. /bec_widgets/widgets/{plots_next_gen → plots}/setting_menus/axis_settings_vertical.ui +0 -0
  192. /bec_widgets/widgets/plots/{waveform/waveform_popups/dap_summary_dialog → toolbar_bundles}/__init__.py +0 -0
  193. /bec_widgets/widgets/{plots_next_gen/setting_menus → plots/waveform/settings}/__init__.py +0 -0
  194. /bec_widgets/widgets/{plots_next_gen/toolbar_bundles → plots/waveform/settings/curve_settings}/__init__.py +0 -0
  195. {bec_widgets-1.25.0.dist-info → bec_widgets-2.0.0.dist-info}/WHEEL +0 -0
  196. {bec_widgets-1.25.0.dist-info → bec_widgets-2.0.0.dist-info}/entry_points.txt +0 -0
  197. {bec_widgets-1.25.0.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()