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
@@ -1 +0,0 @@
1
- {'files': ['image_widget.py']}
@@ -1,515 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import sys
4
- from typing import Literal, Optional
5
-
6
- import pyqtgraph as pg
7
- from bec_lib.device import ReadoutPriority
8
- from qtpy.QtWidgets import QComboBox, QVBoxLayout, QWidget
9
-
10
- from bec_widgets.qt_utils.error_popups import SafeSlot, WarningPopupUtility
11
- from bec_widgets.qt_utils.settings_dialog import SettingsDialog
12
- from bec_widgets.qt_utils.toolbar import (
13
- DeviceSelectionAction,
14
- MaterialIconAction,
15
- ModularToolBar,
16
- SeparatorAction,
17
- WidgetAction,
18
- )
19
- from bec_widgets.utils.bec_widget import BECWidget
20
- from bec_widgets.widgets.containers.figure import BECFigure
21
- from bec_widgets.widgets.containers.figure.plots.axis_settings import AxisSettings
22
- from bec_widgets.widgets.containers.figure.plots.image.image import ImageConfig
23
- from bec_widgets.widgets.containers.figure.plots.image.image_item import BECImageItem
24
- from bec_widgets.widgets.control.device_input.base_classes.device_input_base import BECDeviceFilter
25
- from bec_widgets.widgets.control.device_input.device_combobox.device_combobox import DeviceComboBox
26
-
27
-
28
- class BECImageWidget(BECWidget, QWidget):
29
- PLUGIN = True
30
- ICON_NAME = "image"
31
- USER_ACCESS = [
32
- "image",
33
- "set",
34
- "set_title",
35
- "set_x_label",
36
- "set_y_label",
37
- "set_x_scale",
38
- "set_y_scale",
39
- "set_x_lim",
40
- "set_y_lim",
41
- "set_vrange",
42
- "set_fft",
43
- "set_transpose",
44
- "set_rotation",
45
- "set_log",
46
- "set_grid",
47
- "enable_fps_monitor",
48
- "lock_aspect_ratio",
49
- ]
50
-
51
- def __init__(
52
- self,
53
- parent: QWidget | None = None,
54
- config: ImageConfig | dict = None,
55
- client=None,
56
- gui_id: str | None = None,
57
- **kwargs,
58
- ) -> None:
59
- if config is None:
60
- config = ImageConfig(widget_class=self.__class__.__name__)
61
- else:
62
- if isinstance(config, dict):
63
- config = ImageConfig(**config)
64
- super().__init__(client=client, gui_id=gui_id, **kwargs)
65
- QWidget.__init__(self, parent)
66
- self.layout = QVBoxLayout(self)
67
- self.layout.setSpacing(0)
68
- self.layout.setContentsMargins(0, 0, 0, 0)
69
-
70
- self.fig = BECFigure()
71
- self.dim_combo_box = QComboBox()
72
- self.dim_combo_box.addItems(["1d", "2d"])
73
- self.toolbar = ModularToolBar(
74
- actions={
75
- "monitor": DeviceSelectionAction(
76
- "Monitor:",
77
- DeviceComboBox(
78
- device_filter=BECDeviceFilter.DEVICE,
79
- readout_priority_filter=[ReadoutPriority.ASYNC],
80
- ),
81
- ),
82
- "monitor_type": WidgetAction(widget=self.dim_combo_box),
83
- "connect": MaterialIconAction(icon_name="link", tooltip="Connect Device"),
84
- "separator_0": SeparatorAction(),
85
- "save": MaterialIconAction(icon_name="save", tooltip="Open Export Dialog"),
86
- "separator_1": SeparatorAction(),
87
- "drag_mode": MaterialIconAction(
88
- icon_name="open_with", tooltip="Drag Mouse Mode", checkable=True
89
- ),
90
- "rectangle_mode": MaterialIconAction(
91
- icon_name="frame_inspect", tooltip="Rectangle Zoom Mode", checkable=True
92
- ),
93
- "auto_range": MaterialIconAction(
94
- icon_name="open_in_full", tooltip="Autorange Plot"
95
- ),
96
- "auto_range_image": MaterialIconAction(
97
- icon_name="hdr_auto", tooltip="Autorange Image Intensity", checkable=True
98
- ),
99
- "aspect_ratio": MaterialIconAction(
100
- icon_name="aspect_ratio", tooltip="Lock image aspect ratio", checkable=True
101
- ),
102
- "separator_2": SeparatorAction(),
103
- "FFT": MaterialIconAction(icon_name="fft", tooltip="Toggle FFT", checkable=True),
104
- "log": MaterialIconAction(
105
- icon_name="log_scale", tooltip="Toggle log scale", checkable=True
106
- ),
107
- "transpose": MaterialIconAction(
108
- icon_name="transform", tooltip="Transpose Image", checkable=True
109
- ),
110
- "rotate_right": MaterialIconAction(
111
- icon_name="rotate_right", tooltip="Rotate image clockwise by 90 deg"
112
- ),
113
- "rotate_left": MaterialIconAction(
114
- icon_name="rotate_left", tooltip="Rotate image counterclockwise by 90 deg"
115
- ),
116
- "reset": MaterialIconAction(
117
- icon_name="reset_settings", tooltip="Reset Image Settings"
118
- ),
119
- "separator_3": SeparatorAction(),
120
- "fps_monitor": MaterialIconAction(
121
- icon_name="speed", tooltip="Show FPS Monitor", checkable=True
122
- ),
123
- "axis_settings": MaterialIconAction(
124
- icon_name="settings", tooltip="Open Configuration Dialog"
125
- ),
126
- },
127
- target_widget=self,
128
- )
129
-
130
- self.layout.addWidget(self.toolbar)
131
- self.layout.addWidget(self.fig)
132
-
133
- self.warning_util = WarningPopupUtility(self)
134
-
135
- self._image = self.fig.image()
136
- self._image.apply_config(config)
137
- self.rotation = 0
138
-
139
- self.config = config
140
-
141
- self._hook_actions()
142
-
143
- self.toolbar.widgets["drag_mode"].action.setChecked(True)
144
- self.toolbar.widgets["auto_range_image"].action.setChecked(True)
145
-
146
- def _hook_actions(self):
147
- self.toolbar.widgets["connect"].action.triggered.connect(self._connect_action)
148
- # sepatator
149
- self.toolbar.widgets["save"].action.triggered.connect(self.export)
150
- # sepatator
151
- self.toolbar.widgets["drag_mode"].action.triggered.connect(self.enable_mouse_pan_mode)
152
- self.toolbar.widgets["rectangle_mode"].action.triggered.connect(
153
- self.enable_mouse_rectangle_mode
154
- )
155
- self.toolbar.widgets["auto_range"].action.triggered.connect(self.toggle_auto_range)
156
- self.toolbar.widgets["auto_range_image"].action.triggered.connect(
157
- self.toggle_image_autorange
158
- )
159
- self.toolbar.widgets["aspect_ratio"].action.triggered.connect(self.toggle_aspect_ratio)
160
- # sepatator
161
- self.toolbar.widgets["FFT"].action.triggered.connect(self.toggle_fft)
162
- self.toolbar.widgets["log"].action.triggered.connect(self.toggle_log)
163
- self.toolbar.widgets["transpose"].action.triggered.connect(self.toggle_transpose)
164
- self.toolbar.widgets["rotate_left"].action.triggered.connect(self.rotate_left)
165
- self.toolbar.widgets["rotate_right"].action.triggered.connect(self.rotate_right)
166
- self.toolbar.widgets["reset"].action.triggered.connect(self.reset_settings)
167
- # sepatator
168
- self.toolbar.widgets["axis_settings"].action.triggered.connect(self.show_axis_settings)
169
- self.toolbar.widgets["fps_monitor"].action.toggled.connect(self.enable_fps_monitor)
170
-
171
- ###################################
172
- # Dialog Windows
173
- ###################################
174
- @SafeSlot(popup_error=True)
175
- def _connect_action(self):
176
- monitor_combo = self.toolbar.widgets["monitor"].device_combobox
177
- monitor_name = monitor_combo.currentText()
178
- monitor_type = self.toolbar.widgets["monitor_type"].widget.currentText()
179
- self.image(monitor=monitor_name, monitor_type=monitor_type)
180
- monitor_combo.setStyleSheet("QComboBox { background-color: " "; }")
181
-
182
- def show_axis_settings(self):
183
- dialog = SettingsDialog(
184
- self,
185
- settings_widget=AxisSettings(),
186
- window_title="Axis Settings",
187
- config=self._config_dict["axis"],
188
- )
189
- dialog.exec()
190
-
191
- ###################################
192
- # User Access Methods from image
193
- ###################################
194
- @SafeSlot(popup_error=True)
195
- def image(
196
- self,
197
- monitor: str,
198
- monitor_type: Optional[Literal["1d", "2d"]] = "2d",
199
- color_map: Optional[str] = "magma",
200
- color_bar: Optional[Literal["simple", "full"]] = "full",
201
- downsample: Optional[bool] = True,
202
- opacity: Optional[float] = 1.0,
203
- vrange: Optional[tuple[int, int]] = None,
204
- # post_processing: Optional[PostProcessingConfig] = None,
205
- **kwargs,
206
- ) -> BECImageItem:
207
- if self.toolbar.widgets["monitor"].device_combobox.currentText() != monitor:
208
- self.toolbar.widgets["monitor"].device_combobox.setCurrentText(monitor)
209
- self.toolbar.widgets["monitor"].device_combobox.setStyleSheet(
210
- "QComboBox {{ background-color: " "; }}"
211
- )
212
- if self.toolbar.widgets["monitor_type"].widget.currentText() != monitor_type:
213
- self.toolbar.widgets["monitor_type"].widget.setCurrentText(monitor_type)
214
- self.toolbar.widgets["monitor_type"].widget.setStyleSheet(
215
- "QComboBox {{ background-color: " "; }}"
216
- )
217
- return self._image.image(
218
- monitor=monitor,
219
- monitor_type=monitor_type,
220
- color_map=color_map,
221
- color_bar=color_bar,
222
- downsample=downsample,
223
- opacity=opacity,
224
- vrange=vrange,
225
- **kwargs,
226
- )
227
-
228
- def set_vrange(self, vmin: float, vmax: float, name: str = None):
229
- """
230
- Set the range of the color bar.
231
- If name is not specified, then set vrange for all images.
232
-
233
- Args:
234
- vmin(float): Minimum value of the color bar.
235
- vmax(float): Maximum value of the color bar.
236
- name(str): The name of the image. If None, apply to all images.
237
- """
238
- self._image.set_vrange(vmin, vmax, name)
239
-
240
- def set_color_map(self, color_map: str, name: str = None):
241
- """
242
- Set the color map of the image.
243
- If name is not specified, then set color map for all images.
244
-
245
- Args:
246
- cmap(str): The color map of the image.
247
- name(str): The name of the image. If None, apply to all images.
248
- """
249
- self._image.set_color_map(color_map, name)
250
-
251
- def set_fft(self, enable: bool = False, name: str = None):
252
- """
253
- Set the FFT of the image.
254
- If name is not specified, then set FFT for all images.
255
-
256
- Args:
257
- enable(bool): Whether to perform FFT on the monitor data.
258
- name(str): The name of the image. If None, apply to all images.
259
- """
260
- self._image.set_fft(enable, name)
261
- self.toolbar.widgets["FFT"].action.setChecked(enable)
262
-
263
- def set_transpose(self, enable: bool = False, name: str = None):
264
- """
265
- Set the transpose of the image.
266
- If name is not specified, then set transpose for all images.
267
-
268
- Args:
269
- enable(bool): Whether to transpose the monitor data before displaying.
270
- name(str): The name of the image. If None, apply to all images.
271
- """
272
- self._image.set_transpose(enable, name)
273
- self.toolbar.widgets["transpose"].action.setChecked(enable)
274
-
275
- def set_rotation(self, deg_90: int = 0, name: str = None):
276
- """
277
- Set the rotation of the image.
278
- If name is not specified, then set rotation for all images.
279
-
280
- Args:
281
- deg_90(int): The rotation angle of the monitor data before displaying.
282
- name(str): The name of the image. If None, apply to all images.
283
- """
284
- self._image.set_rotation(deg_90, name)
285
-
286
- def set_log(self, enable: bool = False, name: str = None):
287
- """
288
- Set the log of the image.
289
- If name is not specified, then set log for all images.
290
-
291
- Args:
292
- enable(bool): Whether to perform log on the monitor data.
293
- name(str): The name of the image. If None, apply to all images.
294
- """
295
- self._image.set_log(enable, name)
296
- self.toolbar.widgets["log"].action.setChecked(enable)
297
-
298
- ###################################
299
- # User Access Methods from Plotbase
300
- ###################################
301
-
302
- def set(self, **kwargs):
303
- """
304
- Set the properties of the plot widget.
305
-
306
- Args:
307
- **kwargs: Keyword arguments for the properties to be set.
308
-
309
- Possible properties:
310
- - title: str
311
- - x_label: str
312
- - y_label: str
313
- - x_scale: Literal["linear", "log"]
314
- - y_scale: Literal["linear", "log"]
315
- - x_lim: tuple
316
- - y_lim: tuple
317
- - legend_label_size: int
318
- """
319
- self._image.set(**kwargs)
320
-
321
- def set_title(self, title: str):
322
- """
323
- Set the title of the plot widget.
324
-
325
- Args:
326
- title(str): Title of the plot.
327
- """
328
- self._image.set_title(title)
329
-
330
- def set_x_label(self, x_label: str):
331
- """
332
- Set the x-axis label of the plot widget.
333
-
334
- Args:
335
- x_label(str): Label of the x-axis.
336
- """
337
- self._image.set_x_label(x_label)
338
-
339
- def set_y_label(self, y_label: str):
340
- """
341
- Set the y-axis label of the plot widget.
342
-
343
- Args:
344
- y_label(str): Label of the y-axis.
345
- """
346
- self._image.set_y_label(y_label)
347
-
348
- def set_x_scale(self, x_scale: Literal["linear", "log"]):
349
- """
350
- Set the scale of the x-axis of the plot widget.
351
-
352
- Args:
353
- x_scale(Literal["linear", "log"]): Scale of the x-axis.
354
- """
355
- self._image.set_x_scale(x_scale)
356
-
357
- def set_y_scale(self, y_scale: Literal["linear", "log"]):
358
- """
359
- Set the scale of the y-axis of the plot widget.
360
-
361
- Args:
362
- y_scale(Literal["linear", "log"]): Scale of the y-axis.
363
- """
364
- self._image.set_y_scale(y_scale)
365
-
366
- def set_x_lim(self, x_lim: tuple):
367
- """
368
- Set the limits of the x-axis of the plot widget.
369
-
370
- Args:
371
- x_lim(tuple): Limits of the x-axis.
372
- """
373
- self._image.set_x_lim(x_lim)
374
-
375
- def set_y_lim(self, y_lim: tuple):
376
- """
377
- Set the limits of the y-axis of the plot widget.
378
-
379
- Args:
380
- y_lim(tuple): Limits of the y-axis.
381
- """
382
- self._image.set_y_lim(y_lim)
383
-
384
- def set_grid(self, x_grid: bool, y_grid: bool):
385
- """
386
- Set the grid visibility of the plot widget.
387
-
388
- Args:
389
- x_grid(bool): Visibility of the x-axis grid.
390
- y_grid(bool): Visibility of the y-axis grid.
391
- """
392
- self._image.set_grid(x_grid, y_grid)
393
-
394
- def lock_aspect_ratio(self, lock: bool):
395
- """
396
- Lock the aspect ratio of the plot widget.
397
-
398
- Args:
399
- lock(bool): Lock the aspect ratio.
400
- """
401
- self._image.lock_aspect_ratio(lock)
402
-
403
- ###################################
404
- # Toolbar Actions
405
- ###################################
406
- @SafeSlot()
407
- def toggle_auto_range(self):
408
- """
409
- Set the auto range of the plot widget from the toolbar.
410
- """
411
- self._image.set_auto_range(True, "xy")
412
-
413
- @SafeSlot()
414
- def toggle_fft(self):
415
- checked = self.toolbar.widgets["FFT"].action.isChecked()
416
- self.set_fft(checked)
417
-
418
- @SafeSlot()
419
- def toggle_log(self):
420
- checked = self.toolbar.widgets["log"].action.isChecked()
421
- self.set_log(checked)
422
-
423
- @SafeSlot()
424
- def toggle_transpose(self):
425
- checked = self.toolbar.widgets["transpose"].action.isChecked()
426
- self.set_transpose(checked)
427
-
428
- @SafeSlot()
429
- def rotate_left(self):
430
- self.rotation = (self.rotation + 1) % 4
431
- self.set_rotation(self.rotation)
432
-
433
- @SafeSlot()
434
- def rotate_right(self):
435
- self.rotation = (self.rotation - 1) % 4
436
- self.set_rotation(self.rotation)
437
-
438
- @SafeSlot()
439
- def reset_settings(self):
440
- self.set_log(False)
441
- self.set_fft(False)
442
- self.set_transpose(False)
443
- self.rotation = 0
444
- self.set_rotation(0)
445
-
446
- self.toolbar.widgets["FFT"].action.setChecked(False)
447
- self.toolbar.widgets["log"].action.setChecked(False)
448
- self.toolbar.widgets["transpose"].action.setChecked(False)
449
-
450
- @SafeSlot()
451
- def toggle_image_autorange(self):
452
- """
453
- Enable the auto range of the image intensity.
454
- """
455
- checked = self.toolbar.widgets["auto_range_image"].action.isChecked()
456
- self._image.set_autorange(checked)
457
-
458
- @SafeSlot()
459
- def toggle_aspect_ratio(self):
460
- """
461
- Enable the auto range of the image intensity.
462
- """
463
- checked = self.toolbar.widgets["aspect_ratio"].action.isChecked()
464
- self._image.lock_aspect_ratio(checked)
465
-
466
- @SafeSlot()
467
- def enable_mouse_rectangle_mode(self):
468
- self.toolbar.widgets["rectangle_mode"].action.setChecked(True)
469
- self.toolbar.widgets["drag_mode"].action.setChecked(False)
470
- self._image.plot_item.getViewBox().setMouseMode(pg.ViewBox.RectMode)
471
-
472
- @SafeSlot()
473
- def enable_mouse_pan_mode(self):
474
- self.toolbar.widgets["drag_mode"].action.setChecked(True)
475
- self.toolbar.widgets["rectangle_mode"].action.setChecked(False)
476
- self._image.plot_item.getViewBox().setMouseMode(pg.ViewBox.PanMode)
477
-
478
- @SafeSlot()
479
- def enable_fps_monitor(self, enabled: bool):
480
- """
481
- Enable the FPS monitor of the plot widget.
482
-
483
- Args:
484
- enabled(bool): If True, enable the FPS monitor.
485
- """
486
- self._image.enable_fps_monitor(enabled)
487
- if self.toolbar.widgets["fps_monitor"].action.isChecked() != enabled:
488
- self.toolbar.widgets["fps_monitor"].action.setChecked(enabled)
489
-
490
- def export(self):
491
- """
492
- Show the export dialog for the plot widget.
493
- """
494
- self._image.export()
495
-
496
- def cleanup(self):
497
- self.fig.cleanup()
498
- self.toolbar.close()
499
- self.toolbar.deleteLater()
500
- return super().cleanup()
501
-
502
-
503
- def main(): # pragma: no cover
504
-
505
- from qtpy.QtWidgets import QApplication
506
-
507
- app = QApplication(sys.argv)
508
- widget = BECImageWidget()
509
- widget.image("waveform", "1d")
510
- widget.show()
511
- sys.exit(app.exec_())
512
-
513
-
514
- if __name__ == "__main__": # pragma: no cover
515
- main()
@@ -1 +0,0 @@
1
- {'files': ['motor_map_widget.py','motor_map_widget_plugin.py']}
@@ -1,56 +0,0 @@
1
- import os
2
-
3
- from qtpy.QtWidgets import QVBoxLayout
4
-
5
- from bec_widgets.qt_utils.error_popups import SafeSlot as Slot
6
- from bec_widgets.qt_utils.settings_dialog import SettingWidget
7
- from bec_widgets.utils import UILoader
8
- from bec_widgets.utils.widget_io import WidgetIO
9
-
10
-
11
- class MotorMapSettings(SettingWidget):
12
- def __init__(self, parent=None, *args, **kwargs):
13
- super().__init__(parent, *args, **kwargs)
14
- current_path = os.path.dirname(__file__)
15
-
16
- self.ui = UILoader(self).loader(os.path.join(current_path, "motor_map_settings.ui"))
17
-
18
- self.layout = QVBoxLayout(self)
19
- self.layout.addWidget(self.ui)
20
-
21
- @Slot(dict)
22
- def display_current_settings(self, config: dict):
23
- WidgetIO.set_value(self.ui.max_points, config["max_points"])
24
- WidgetIO.set_value(self.ui.trace_dim, config["num_dim_points"])
25
- WidgetIO.set_value(self.ui.precision, config["precision"])
26
- WidgetIO.set_value(self.ui.scatter_size, config["scatter_size"])
27
- background_intensity = int((config["background_value"] / 255) * 100)
28
- WidgetIO.set_value(self.ui.background_value, background_intensity)
29
- color = config["color"]
30
- self.ui.color.set_color(color)
31
-
32
- @Slot()
33
- def accept_changes(self):
34
- max_points = WidgetIO.get_value(self.ui.max_points)
35
- num_dim_points = WidgetIO.get_value(self.ui.trace_dim)
36
- precision = WidgetIO.get_value(self.ui.precision)
37
- scatter_size = WidgetIO.get_value(self.ui.scatter_size)
38
- background_intensity = int(WidgetIO.get_value(self.ui.background_value) * 0.01 * 255)
39
- color = self.ui.color.get_color("RGBA")
40
-
41
- if self.target_widget is not None:
42
- self.target_widget.set_max_points(max_points)
43
- self.target_widget.set_num_dim_points(num_dim_points)
44
- self.target_widget.set_precision(precision)
45
- self.target_widget.set_scatter_size(scatter_size)
46
- self.target_widget.set_background_value(background_intensity)
47
- self.target_widget.set_color(color)
48
-
49
- def cleanup(self):
50
- self.ui.color.cleanup()
51
- self.ui.color.close()
52
- self.ui.color.deleteLater()
53
-
54
- def closeEvent(self, event):
55
- self.cleanup()
56
- super().closeEvent(event)
@@ -1,108 +0,0 @@
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>243</width>
10
- <height>233</height>
11
- </rect>
12
- </property>
13
- <property name="windowTitle">
14
- <string>Form</string>
15
- </property>
16
- <layout class="QGridLayout" name="gridLayout">
17
- <item row="3" column="1">
18
- <widget class="QSpinBox" name="scatter_size">
19
- <property name="maximum">
20
- <number>20</number>
21
- </property>
22
- </widget>
23
- </item>
24
- <item row="1" column="0">
25
- <widget class="QLabel" name="trace_label">
26
- <property name="text">
27
- <string>Trace Dim</string>
28
- </property>
29
- </widget>
30
- </item>
31
- <item row="2" column="0">
32
- <widget class="QLabel" name="precision_label">
33
- <property name="text">
34
- <string>Precision</string>
35
- </property>
36
- </widget>
37
- </item>
38
- <item row="4" column="0">
39
- <widget class="QLabel" name="background_label">
40
- <property name="text">
41
- <string>Background Intensity</string>
42
- </property>
43
- </widget>
44
- </item>
45
- <item row="2" column="1">
46
- <widget class="QSpinBox" name="precision">
47
- <property name="maximum">
48
- <number>15</number>
49
- </property>
50
- </widget>
51
- </item>
52
- <item row="4" column="1">
53
- <widget class="QSpinBox" name="background_value">
54
- <property name="maximum">
55
- <number>100</number>
56
- </property>
57
- </widget>
58
- </item>
59
- <item row="0" column="0">
60
- <widget class="QLabel" name="max_point_label">
61
- <property name="text">
62
- <string>Max Points</string>
63
- </property>
64
- </widget>
65
- </item>
66
- <item row="3" column="0">
67
- <widget class="QLabel" name="scatter_size_label">
68
- <property name="text">
69
- <string>Scatter Size</string>
70
- </property>
71
- </widget>
72
- </item>
73
- <item row="0" column="1">
74
- <widget class="QSpinBox" name="max_points">
75
- <property name="maximum">
76
- <number>10000</number>
77
- </property>
78
- </widget>
79
- </item>
80
- <item row="1" column="1">
81
- <widget class="QSpinBox" name="trace_dim">
82
- <property name="maximum">
83
- <number>1000</number>
84
- </property>
85
- </widget>
86
- </item>
87
- <item row="5" column="0">
88
- <widget class="QLabel" name="color_label">
89
- <property name="text">
90
- <string>Color</string>
91
- </property>
92
- </widget>
93
- </item>
94
- <item row="5" column="1">
95
- <widget class="ColorButton" name="color"/>
96
- </item>
97
- </layout>
98
- </widget>
99
- <customwidgets>
100
- <customwidget>
101
- <class>ColorButton</class>
102
- <extends>QPushButton</extends>
103
- <header>color_button</header>
104
- </customwidget>
105
- </customwidgets>
106
- <resources/>
107
- <connections/>
108
- </ui>