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,138 @@
1
+ import os
2
+
3
+ from qtpy.QtWidgets import QFrame, QScrollArea, QVBoxLayout
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
+
9
+
10
+ class ScatterCurveSettings(SettingWidget):
11
+ def __init__(self, parent=None, target_widget=None, popup=False, *args, **kwargs):
12
+ super().__init__(parent=parent, *args, **kwargs)
13
+
14
+ # This is a settings widget that depends on the target widget
15
+ # and should mirror what is in the target widget.
16
+ # Saving settings for this widget could result in recursively setting the target widget.
17
+ self.setProperty("skip_settings", True)
18
+
19
+ current_path = os.path.dirname(__file__)
20
+ if popup:
21
+ form = UILoader().load_ui(
22
+ os.path.join(current_path, "scatter_curve_settings_horizontal.ui"), self
23
+ )
24
+ else:
25
+ form = UILoader().load_ui(
26
+ os.path.join(current_path, "scatter_curve_settings_vertical.ui"), self
27
+ )
28
+
29
+ self.target_widget = target_widget
30
+ self.popup = popup
31
+
32
+ # # Scroll area
33
+ self.scroll_area = QScrollArea(self)
34
+ self.scroll_area.setWidgetResizable(True)
35
+ self.scroll_area.setFrameShape(QFrame.NoFrame)
36
+ self.scroll_area.setWidget(form)
37
+
38
+ self.layout = QVBoxLayout(self)
39
+ self.layout.setContentsMargins(0, 0, 0, 0)
40
+ self.layout.addWidget(self.scroll_area)
41
+ self.ui = form
42
+
43
+ self.fetch_all_properties()
44
+
45
+ self.target_widget.scatter_waveform_property_changed.connect(self.fetch_all_properties)
46
+ if popup is False:
47
+ self.ui.button_apply.clicked.connect(self.accept_changes)
48
+
49
+ @SafeSlot()
50
+ def fetch_all_properties(self):
51
+ """
52
+ Fetch all properties from the target widget and update the settings widget.
53
+ """
54
+ if not self.target_widget:
55
+ return
56
+
57
+ # Get properties from the target widget
58
+ color_map = getattr(self.target_widget, "color_map", None)
59
+
60
+ # Default values for device properties
61
+ x_name, x_entry = None, None
62
+ y_name, y_entry = None, None
63
+ z_name, z_entry = None, None
64
+
65
+ # Safely access device properties
66
+ if hasattr(self.target_widget, "main_curve") and self.target_widget.main_curve:
67
+ if hasattr(self.target_widget.main_curve, "config"):
68
+ config = self.target_widget.main_curve.config
69
+
70
+ if hasattr(config, "x_device") and config.x_device:
71
+ x_name = getattr(config.x_device, "name", None)
72
+ x_entry = getattr(config.x_device, "entry", None)
73
+
74
+ if hasattr(config, "y_device") and config.y_device:
75
+ y_name = getattr(config.y_device, "name", None)
76
+ y_entry = getattr(config.y_device, "entry", None)
77
+
78
+ if hasattr(config, "z_device") and config.z_device:
79
+ z_name = getattr(config.z_device, "name", None)
80
+ z_entry = getattr(config.z_device, "entry", None)
81
+
82
+ # Apply the properties to the settings widget
83
+ if hasattr(self.ui, "color_map"):
84
+ self.ui.color_map.colormap = color_map
85
+
86
+ if hasattr(self.ui, "x_name"):
87
+ self.ui.x_name.set_device(x_name)
88
+ if hasattr(self.ui, "x_entry") and x_entry is not None:
89
+ self.ui.x_entry.setText(x_entry)
90
+
91
+ if hasattr(self.ui, "y_name"):
92
+ self.ui.y_name.set_device(y_name)
93
+ if hasattr(self.ui, "y_entry") and y_entry is not None:
94
+ self.ui.y_entry.setText(y_entry)
95
+
96
+ if hasattr(self.ui, "z_name"):
97
+ self.ui.z_name.set_device(z_name)
98
+ if hasattr(self.ui, "z_entry") and z_entry is not None:
99
+ self.ui.z_entry.setText(z_entry)
100
+
101
+ @SafeSlot()
102
+ def accept_changes(self):
103
+ """
104
+ Apply all properties from the settings widget to the target widget.
105
+ """
106
+ x_name = self.ui.x_name.text()
107
+ x_entry = self.ui.x_entry.text()
108
+ y_name = self.ui.y_name.text()
109
+ y_entry = self.ui.y_entry.text()
110
+ z_name = self.ui.z_name.text()
111
+ z_entry = self.ui.z_entry.text()
112
+ validate_bec = self.ui.validate_bec.checked
113
+ color_map = self.ui.color_map.colormap
114
+
115
+ self.target_widget.plot(
116
+ x_name=x_name,
117
+ y_name=y_name,
118
+ z_name=z_name,
119
+ x_entry=x_entry,
120
+ y_entry=y_entry,
121
+ z_entry=z_entry,
122
+ color_map=color_map,
123
+ validate_bec=validate_bec,
124
+ )
125
+
126
+ def cleanup(self):
127
+ self.ui.x_name.close()
128
+ self.ui.x_name.deleteLater()
129
+ self.ui.x_entry.close()
130
+ self.ui.x_entry.deleteLater()
131
+ self.ui.y_name.close()
132
+ self.ui.y_name.deleteLater()
133
+ self.ui.y_entry.close()
134
+ self.ui.y_entry.deleteLater()
135
+ self.ui.z_name.close()
136
+ self.ui.z_name.deleteLater()
137
+ self.ui.z_entry.close()
138
+ self.ui.z_entry.deleteLater()
@@ -0,0 +1,195 @@
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>604</width>
10
+ <height>166</height>
11
+ </rect>
12
+ </property>
13
+ <property name="windowTitle">
14
+ <string>Form</string>
15
+ </property>
16
+ <layout class="QVBoxLayout" name="verticalLayout">
17
+ <item>
18
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
19
+ <item>
20
+ <widget class="QLabel" name="label_7">
21
+ <property name="text">
22
+ <string>Validate BEC</string>
23
+ </property>
24
+ </widget>
25
+ </item>
26
+ <item>
27
+ <widget class="ToggleSwitch" name="validate_bec"/>
28
+ </item>
29
+ <item>
30
+ <widget class="BECColorMapWidget" name="color_map"/>
31
+ </item>
32
+ </layout>
33
+ </item>
34
+ <item>
35
+ <layout class="QHBoxLayout" name="horizontalLayout">
36
+ <item>
37
+ <widget class="QGroupBox" name="groupBox">
38
+ <property name="title">
39
+ <string>X Device</string>
40
+ </property>
41
+ <layout class="QGridLayout" name="gridLayout">
42
+ <item row="0" column="0">
43
+ <widget class="QLabel" name="label">
44
+ <property name="text">
45
+ <string>Name</string>
46
+ </property>
47
+ </widget>
48
+ </item>
49
+ <item row="0" column="1">
50
+ <widget class="DeviceLineEdit" name="x_name"/>
51
+ </item>
52
+ <item row="1" column="0">
53
+ <widget class="QLabel" name="label_2">
54
+ <property name="text">
55
+ <string>Signal</string>
56
+ </property>
57
+ </widget>
58
+ </item>
59
+ <item row="1" column="1">
60
+ <widget class="QLineEdit" name="x_entry"/>
61
+ </item>
62
+ </layout>
63
+ </widget>
64
+ </item>
65
+ <item>
66
+ <widget class="QGroupBox" name="groupBox_2">
67
+ <property name="title">
68
+ <string>Y Device</string>
69
+ </property>
70
+ <layout class="QGridLayout" name="gridLayout_2">
71
+ <item row="0" column="0">
72
+ <widget class="QLabel" name="label_3">
73
+ <property name="text">
74
+ <string>Name</string>
75
+ </property>
76
+ </widget>
77
+ </item>
78
+ <item row="0" column="1">
79
+ <widget class="DeviceLineEdit" name="y_name"/>
80
+ </item>
81
+ <item row="1" column="0">
82
+ <widget class="QLabel" name="label_4">
83
+ <property name="text">
84
+ <string>Signal</string>
85
+ </property>
86
+ </widget>
87
+ </item>
88
+ <item row="1" column="1">
89
+ <widget class="QLineEdit" name="y_entry"/>
90
+ </item>
91
+ </layout>
92
+ </widget>
93
+ </item>
94
+ <item>
95
+ <widget class="QGroupBox" name="groupBox_3">
96
+ <property name="title">
97
+ <string>Z Device</string>
98
+ </property>
99
+ <layout class="QGridLayout" name="gridLayout_3">
100
+ <item row="0" column="0">
101
+ <widget class="QLabel" name="label_5">
102
+ <property name="text">
103
+ <string>Name</string>
104
+ </property>
105
+ </widget>
106
+ </item>
107
+ <item row="1" column="0">
108
+ <widget class="QLabel" name="label_6">
109
+ <property name="text">
110
+ <string>Signal</string>
111
+ </property>
112
+ </widget>
113
+ </item>
114
+ <item row="1" column="1">
115
+ <widget class="QLineEdit" name="z_entry"/>
116
+ </item>
117
+ <item row="0" column="1">
118
+ <widget class="DeviceLineEdit" name="z_name"/>
119
+ </item>
120
+ </layout>
121
+ </widget>
122
+ </item>
123
+ </layout>
124
+ </item>
125
+ </layout>
126
+ </widget>
127
+ <customwidgets>
128
+ <customwidget>
129
+ <class>DeviceLineEdit</class>
130
+ <extends>QLineEdit</extends>
131
+ <header>device_line_edit</header>
132
+ </customwidget>
133
+ <customwidget>
134
+ <class>ToggleSwitch</class>
135
+ <extends>QWidget</extends>
136
+ <header>toggle_switch</header>
137
+ </customwidget>
138
+ <customwidget>
139
+ <class>BECColorMapWidget</class>
140
+ <extends>QWidget</extends>
141
+ <header>bec_color_map_widget</header>
142
+ </customwidget>
143
+ </customwidgets>
144
+ <resources/>
145
+ <connections>
146
+ <connection>
147
+ <sender>x_name</sender>
148
+ <signal>textChanged(QString)</signal>
149
+ <receiver>x_entry</receiver>
150
+ <slot>clear()</slot>
151
+ <hints>
152
+ <hint type="sourcelabel">
153
+ <x>134</x>
154
+ <y>95</y>
155
+ </hint>
156
+ <hint type="destinationlabel">
157
+ <x>138</x>
158
+ <y>128</y>
159
+ </hint>
160
+ </hints>
161
+ </connection>
162
+ <connection>
163
+ <sender>y_name</sender>
164
+ <signal>textChanged(QString)</signal>
165
+ <receiver>y_entry</receiver>
166
+ <slot>clear()</slot>
167
+ <hints>
168
+ <hint type="sourcelabel">
169
+ <x>351</x>
170
+ <y>91</y>
171
+ </hint>
172
+ <hint type="destinationlabel">
173
+ <x>349</x>
174
+ <y>121</y>
175
+ </hint>
176
+ </hints>
177
+ </connection>
178
+ <connection>
179
+ <sender>z_name</sender>
180
+ <signal>textChanged(QString)</signal>
181
+ <receiver>z_entry</receiver>
182
+ <slot>clear()</slot>
183
+ <hints>
184
+ <hint type="sourcelabel">
185
+ <x>520</x>
186
+ <y>98</y>
187
+ </hint>
188
+ <hint type="destinationlabel">
189
+ <x>522</x>
190
+ <y>127</y>
191
+ </hint>
192
+ </hints>
193
+ </connection>
194
+ </connections>
195
+ </ui>
@@ -0,0 +1,204 @@
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>233</width>
10
+ <height>427</height>
11
+ </rect>
12
+ </property>
13
+ <property name="maximumSize">
14
+ <size>
15
+ <width>16777215</width>
16
+ <height>427</height>
17
+ </size>
18
+ </property>
19
+ <property name="windowTitle">
20
+ <string>Form</string>
21
+ </property>
22
+ <layout class="QVBoxLayout" name="verticalLayout">
23
+ <item>
24
+ <widget class="QPushButton" name="button_apply">
25
+ <property name="text">
26
+ <string>Apply</string>
27
+ </property>
28
+ </widget>
29
+ </item>
30
+ <item>
31
+ <widget class="BECColorMapWidget" name="color_map"/>
32
+ </item>
33
+ <item>
34
+ <layout class="QHBoxLayout" name="horizontalLayout">
35
+ <item>
36
+ <widget class="QLabel" name="label_7">
37
+ <property name="text">
38
+ <string>Validate BEC</string>
39
+ </property>
40
+ </widget>
41
+ </item>
42
+ <item>
43
+ <widget class="ToggleSwitch" name="validate_bec"/>
44
+ </item>
45
+ </layout>
46
+ </item>
47
+ <item>
48
+ <widget class="QGroupBox" name="groupBox">
49
+ <property name="title">
50
+ <string>X Device</string>
51
+ </property>
52
+ <layout class="QGridLayout" name="gridLayout">
53
+ <item row="0" column="0">
54
+ <widget class="QLabel" name="label">
55
+ <property name="text">
56
+ <string>Name</string>
57
+ </property>
58
+ </widget>
59
+ </item>
60
+ <item row="0" column="1">
61
+ <widget class="DeviceLineEdit" name="x_name"/>
62
+ </item>
63
+ <item row="1" column="0">
64
+ <widget class="QLabel" name="label_2">
65
+ <property name="text">
66
+ <string>Signal</string>
67
+ </property>
68
+ </widget>
69
+ </item>
70
+ <item row="1" column="1">
71
+ <widget class="QLineEdit" name="x_entry"/>
72
+ </item>
73
+ </layout>
74
+ </widget>
75
+ </item>
76
+ <item>
77
+ <widget class="QGroupBox" name="groupBox_2">
78
+ <property name="title">
79
+ <string>Y Device</string>
80
+ </property>
81
+ <layout class="QGridLayout" name="gridLayout_2">
82
+ <item row="0" column="0">
83
+ <widget class="QLabel" name="label_3">
84
+ <property name="text">
85
+ <string>Name</string>
86
+ </property>
87
+ </widget>
88
+ </item>
89
+ <item row="0" column="1">
90
+ <widget class="DeviceLineEdit" name="y_name"/>
91
+ </item>
92
+ <item row="1" column="0">
93
+ <widget class="QLabel" name="label_4">
94
+ <property name="text">
95
+ <string>Signal</string>
96
+ </property>
97
+ </widget>
98
+ </item>
99
+ <item row="1" column="1">
100
+ <widget class="QLineEdit" name="y_entry"/>
101
+ </item>
102
+ </layout>
103
+ </widget>
104
+ </item>
105
+ <item>
106
+ <widget class="QGroupBox" name="groupBox_3">
107
+ <property name="title">
108
+ <string>Z Device</string>
109
+ </property>
110
+ <layout class="QGridLayout" name="gridLayout_3">
111
+ <item row="0" column="0">
112
+ <widget class="QLabel" name="label_5">
113
+ <property name="text">
114
+ <string>Name</string>
115
+ </property>
116
+ </widget>
117
+ </item>
118
+ <item row="0" column="1">
119
+ <widget class="DeviceLineEdit" name="z_name"/>
120
+ </item>
121
+ <item row="1" column="0">
122
+ <widget class="QLabel" name="label_6">
123
+ <property name="text">
124
+ <string>Signal</string>
125
+ </property>
126
+ </widget>
127
+ </item>
128
+ <item row="1" column="1">
129
+ <widget class="QLineEdit" name="z_entry"/>
130
+ </item>
131
+ </layout>
132
+ </widget>
133
+ </item>
134
+ </layout>
135
+ </widget>
136
+ <customwidgets>
137
+ <customwidget>
138
+ <class>DeviceLineEdit</class>
139
+ <extends>QLineEdit</extends>
140
+ <header>device_line_edit</header>
141
+ </customwidget>
142
+ <customwidget>
143
+ <class>ToggleSwitch</class>
144
+ <extends>QWidget</extends>
145
+ <header>toggle_switch</header>
146
+ </customwidget>
147
+ <customwidget>
148
+ <class>BECColorMapWidget</class>
149
+ <extends>QWidget</extends>
150
+ <header>bec_color_map_widget</header>
151
+ </customwidget>
152
+ </customwidgets>
153
+ <resources/>
154
+ <connections>
155
+ <connection>
156
+ <sender>x_name</sender>
157
+ <signal>textChanged(QString)</signal>
158
+ <receiver>x_entry</receiver>
159
+ <slot>clear()</slot>
160
+ <hints>
161
+ <hint type="sourcelabel">
162
+ <x>156</x>
163
+ <y>123</y>
164
+ </hint>
165
+ <hint type="destinationlabel">
166
+ <x>158</x>
167
+ <y>157</y>
168
+ </hint>
169
+ </hints>
170
+ </connection>
171
+ <connection>
172
+ <sender>y_name</sender>
173
+ <signal>textChanged(QString)</signal>
174
+ <receiver>y_entry</receiver>
175
+ <slot>clear()</slot>
176
+ <hints>
177
+ <hint type="sourcelabel">
178
+ <x>116</x>
179
+ <y>229</y>
180
+ </hint>
181
+ <hint type="destinationlabel">
182
+ <x>116</x>
183
+ <y>251</y>
184
+ </hint>
185
+ </hints>
186
+ </connection>
187
+ <connection>
188
+ <sender>z_name</sender>
189
+ <signal>textChanged(QString)</signal>
190
+ <receiver>z_entry</receiver>
191
+ <slot>clear()</slot>
192
+ <hints>
193
+ <hint type="sourcelabel">
194
+ <x>110</x>
195
+ <y>326</y>
196
+ </hint>
197
+ <hint type="destinationlabel">
198
+ <x>110</x>
199
+ <y>352</y>
200
+ </hint>
201
+ </hints>
202
+ </connection>
203
+ </connections>
204
+ </ui>
@@ -2,9 +2,9 @@ import os
2
2
 
3
3
  from qtpy.QtWidgets import QFrame, QScrollArea, QVBoxLayout, QWidget
4
4
 
5
- from bec_widgets.qt_utils.error_popups import SafeSlot
6
- from bec_widgets.qt_utils.settings_dialog import SettingWidget
7
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
8
  from bec_widgets.utils.widget_io import WidgetIO
9
9
 
10
10
 
@@ -16,7 +16,6 @@ class AxisSettings(SettingWidget):
16
16
  # and should mirror what is in the target widget.
17
17
  # Saving settings for this widget could result in recursively setting the target widget.
18
18
  self.setProperty("skip_settings", True)
19
- self.setObjectName("AxisSettings")
20
19
  current_path = os.path.dirname(__file__)
21
20
  if popup:
22
21
  form = UILoader().load_ui(
@@ -37,7 +36,6 @@ class AxisSettings(SettingWidget):
37
36
  self.layout = QVBoxLayout(self)
38
37
  self.layout.setContentsMargins(0, 0, 0, 0)
39
38
  self.layout.addWidget(self.scroll_area)
40
- # self.layout.addWidget(self.ui)
41
39
  self.ui = form
42
40
 
43
41
  if self.target_widget is not None and self.popup is False:
@@ -50,8 +48,6 @@ class AxisSettings(SettingWidget):
50
48
  def connect_all_signals(self):
51
49
  for widget in [
52
50
  self.ui.title,
53
- self.ui.inner_axes,
54
- self.ui.outer_axes,
55
51
  self.ui.x_label,
56
52
  self.ui.x_min,
57
53
  self.ui.x_max,
@@ -62,6 +58,8 @@ class AxisSettings(SettingWidget):
62
58
  self.ui.y_max,
63
59
  self.ui.y_log,
64
60
  self.ui.y_grid,
61
+ self.ui.inner_axes,
62
+ self.ui.outer_axes,
65
63
  ]:
66
64
  WidgetIO.connect_widget_change_signal(widget, self.set_property)
67
65
 
@@ -98,6 +96,8 @@ class AxisSettings(SettingWidget):
98
96
  widget_to_set = self.ui.findChild(QWidget, property_name)
99
97
  except RuntimeError:
100
98
  return
99
+ if widget_to_set is None:
100
+ return
101
101
  # Block signals to avoid triggering set_property again
102
102
  was_blocked = widget_to_set.blockSignals(True)
103
103
  WidgetIO.set_value(widget_to_set, value)
@@ -132,8 +132,6 @@ class AxisSettings(SettingWidget):
132
132
  """
133
133
  for widget in [
134
134
  self.ui.title,
135
- self.ui.inner_axes,
136
- self.ui.outer_axes,
137
135
  self.ui.x_label,
138
136
  self.ui.x_min,
139
137
  self.ui.x_max,
@@ -144,6 +142,8 @@ class AxisSettings(SettingWidget):
144
142
  self.ui.y_max,
145
143
  self.ui.y_log,
146
144
  self.ui.y_grid,
145
+ self.ui.outer_axes,
146
+ self.ui.inner_axes,
147
147
  ]:
148
148
  property_name = widget.objectName()
149
149
  value = WidgetIO.get_value(widget)
@@ -1,8 +1,8 @@
1
1
  import pyqtgraph as pg
2
2
  from qtpy.QtCore import QTimer
3
3
 
4
- from bec_widgets.qt_utils.error_popups import SafeSlot
5
- from bec_widgets.qt_utils.toolbar import MaterialIconAction, SwitchableToolBarAction, ToolbarBundle
4
+ from bec_widgets.utils.error_popups import SafeSlot
5
+ from bec_widgets.utils.toolbar import MaterialIconAction, SwitchableToolBarAction, ToolbarBundle
6
6
 
7
7
 
8
8
  class MouseInteractionToolbarBundle(ToolbarBundle):
@@ -38,12 +38,6 @@ class MouseInteractionToolbarBundle(ToolbarBundle):
38
38
  checkable=False,
39
39
  parent=self.target_widget,
40
40
  )
41
- aspect_ratio = MaterialIconAction(
42
- icon_name="aspect_ratio",
43
- tooltip="Lock image aspect ratio",
44
- checkable=True,
45
- parent=self.target_widget,
46
- )
47
41
 
48
42
  self.switch_mouse_action = SwitchableToolBarAction(
49
43
  actions={"drag_mode": drag, "rectangle_mode": rect},
@@ -56,16 +50,11 @@ class MouseInteractionToolbarBundle(ToolbarBundle):
56
50
  # Add them to the bundle
57
51
  self.add_action("switch_mouse", self.switch_mouse_action)
58
52
  self.add_action("auto_range", auto)
59
- self.add_action("aspect_ratio", aspect_ratio)
60
53
 
61
54
  # Immediately connect signals
62
55
  drag.action.toggled.connect(self.enable_mouse_pan_mode)
63
56
  rect.action.toggled.connect(self.enable_mouse_rectangle_mode)
64
57
  auto.action.triggered.connect(self.autorange_plot)
65
- aspect_ratio.action.toggled.connect(self.lock_aspect_ratio)
66
-
67
- # Give some time to check the state
68
- QTimer.singleShot(10, self.get_viewbox_mode)
69
58
 
70
59
  def get_viewbox_mode(self):
71
60
  """
@@ -94,6 +83,7 @@ class MouseInteractionToolbarBundle(ToolbarBundle):
94
83
  self.actions["switch_mouse"].actions["drag_mode"].action.setChecked(not checked)
95
84
  if self.target_widget and checked:
96
85
  self.target_widget.plot_item.getViewBox().setMouseMode(pg.ViewBox.RectMode)
86
+ self.mouse_mode = "RectMode"
97
87
 
98
88
  @SafeSlot(bool)
99
89
  def enable_mouse_pan_mode(self, checked: bool):
@@ -106,6 +96,7 @@ class MouseInteractionToolbarBundle(ToolbarBundle):
106
96
  self.actions["switch_mouse"].actions["rectangle_mode"].action.setChecked(not checked)
107
97
  if self.target_widget and checked:
108
98
  self.target_widget.plot_item.getViewBox().setMouseMode(pg.ViewBox.PanMode)
99
+ self.mouse_mode = "PanMode"
109
100
 
110
101
  @SafeSlot()
111
102
  def autorange_plot(self):
@@ -115,8 +106,3 @@ class MouseInteractionToolbarBundle(ToolbarBundle):
115
106
  if self.target_widget:
116
107
  self.target_widget.auto_range_x = True
117
108
  self.target_widget.auto_range_y = True
118
-
119
- @SafeSlot(bool)
120
- def lock_aspect_ratio(self, checked: bool):
121
- if self.target_widget:
122
- self.target_widget.lock_aspect_ratio = checked