bec-widgets 1.25.1__py3-none-any.whl → 2.0.1__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.
- .gitlab-ci.yml +3 -5
- CHANGELOG.md +639 -0
- PKG-INFO +3 -3
- bec_widgets/__init__.py +4 -0
- bec_widgets/applications/bw_launch.py +23 -0
- bec_widgets/applications/launch_window.py +430 -0
- bec_widgets/assets/app_icons/auto_update.png +0 -0
- bec_widgets/assets/app_icons/ui_loader_tile.png +0 -0
- bec_widgets/cli/__init__.py +0 -1
- bec_widgets/cli/client.py +1779 -2064
- bec_widgets/cli/client_utils.py +346 -174
- bec_widgets/cli/generate_cli.py +143 -37
- bec_widgets/cli/rpc/rpc_base.py +152 -21
- bec_widgets/cli/rpc/rpc_register.py +113 -6
- bec_widgets/cli/rpc/rpc_widget_handler.py +13 -11
- bec_widgets/cli/server.py +125 -239
- bec_widgets/examples/jupyter_console/jupyter_console_window.py +97 -145
- bec_widgets/examples/plugin_example_pyside/tictactoetaskmenu.py +1 -1
- bec_widgets/utils/bec_connector.py +190 -21
- bec_widgets/utils/bec_designer.py +7 -0
- bec_widgets/utils/bec_dispatcher.py +71 -4
- bec_widgets/utils/bec_plugin_helper.py +89 -0
- bec_widgets/utils/bec_signal_proxy.py +1 -1
- bec_widgets/utils/bec_widget.py +26 -10
- bec_widgets/utils/colors.py +1 -1
- bec_widgets/{qt_utils → utils}/compact_popup.py +2 -0
- bec_widgets/utils/container_utils.py +37 -12
- bec_widgets/utils/crosshair.py +25 -8
- bec_widgets/utils/entry_validator.py +3 -1
- bec_widgets/{qt_utils → utils}/error_popups.py +18 -0
- bec_widgets/{qt_utils → utils}/expandable_frame.py +2 -2
- bec_widgets/utils/forms_from_types/forms.py +182 -0
- bec_widgets/{widgets/editors/scan_metadata/_metadata_widgets.py → utils/forms_from_types/items.py} +41 -30
- bec_widgets/utils/generate_designer_plugin.py +40 -36
- bec_widgets/utils/linear_region_selector.py +2 -0
- bec_widgets/utils/name_utils.py +16 -0
- bec_widgets/{qt_utils → utils}/palette_viewer.py +2 -2
- bec_widgets/utils/plot_indicator_items.py +2 -5
- bec_widgets/utils/plugin_utils.py +47 -1
- bec_widgets/{qt_utils → utils}/round_frame.py +14 -14
- bec_widgets/utils/rpc_server.py +277 -0
- bec_widgets/utils/serialization.py +44 -0
- bec_widgets/{qt_utils → utils}/settings_dialog.py +26 -1
- bec_widgets/{qt_utils → utils}/side_panel.py +17 -10
- bec_widgets/{qt_utils → utils}/toolbar.py +69 -25
- bec_widgets/utils/ui_loader.py +8 -8
- bec_widgets/utils/widget_io.py +166 -25
- bec_widgets/widgets/containers/auto_update/auto_updates.py +364 -0
- bec_widgets/widgets/containers/dock/dock.py +157 -49
- bec_widgets/widgets/containers/dock/dock_area.py +188 -138
- bec_widgets/widgets/containers/layout_manager/layout_manager.py +2 -1
- bec_widgets/widgets/containers/main_window/addons/web_links.py +15 -0
- bec_widgets/widgets/containers/main_window/main_window.py +189 -41
- bec_widgets/widgets/control/buttons/button_abort/button_abort.py +3 -4
- bec_widgets/widgets/control/buttons/button_reset/button_reset.py +3 -4
- bec_widgets/widgets/control/buttons/button_resume/button_resume.py +3 -3
- bec_widgets/widgets/control/buttons/stop_button/stop_button.py +18 -7
- bec_widgets/widgets/control/device_control/position_indicator/position_indicator.py +22 -3
- bec_widgets/widgets/control/device_control/positioner_box/_base/positioner_box_base.py +31 -13
- bec_widgets/widgets/control/device_control/positioner_box/positioner_box/positioner_box.py +3 -1
- bec_widgets/widgets/control/device_control/positioner_box/positioner_box/positioner_box.ui +27 -4
- bec_widgets/widgets/control/device_control/positioner_box/positioner_box_2d/positioner_box_2d.py +5 -2
- bec_widgets/widgets/control/device_control/positioner_box/positioner_box_2d/positioner_box_2d.ui +97 -31
- bec_widgets/widgets/control/device_control/positioner_box/positioner_control_line/positioner_control_line.ui +11 -4
- bec_widgets/widgets/control/device_control/positioner_group/positioner_group.py +2 -3
- bec_widgets/widgets/control/device_input/base_classes/device_input_base.py +29 -4
- bec_widgets/widgets/control/device_input/base_classes/device_signal_input_base.py +1 -0
- bec_widgets/widgets/control/device_input/device_combobox/device_combobox.py +2 -2
- bec_widgets/widgets/control/device_input/device_line_edit/device_line_edit.py +2 -2
- bec_widgets/widgets/control/device_input/signal_combobox/signal_combobox.py +1 -2
- bec_widgets/widgets/control/device_input/signal_line_edit/signal_line_edit.py +1 -2
- bec_widgets/widgets/control/scan_control/scan_control.py +7 -5
- bec_widgets/widgets/control/scan_control/scan_group_box.py +28 -5
- bec_widgets/widgets/dap/dap_combo_box/dap_combo_box.py +1 -2
- bec_widgets/widgets/dap/lmfit_dialog/lmfit_dialog.py +3 -4
- bec_widgets/widgets/dap/lmfit_dialog/lmfit_dialog_vertical.ui +14 -8
- bec_widgets/widgets/editors/console/console.py +1 -1
- bec_widgets/widgets/editors/{scan_metadata/additional_metadata_table.py → dict_backed_table.py} +29 -6
- bec_widgets/widgets/editors/scan_metadata/__init__.py +0 -7
- bec_widgets/widgets/editors/scan_metadata/_util.py +1 -1
- bec_widgets/widgets/{plots/motor_map/register_bec_motor_map_widget.py → editors/scan_metadata/register_scan_metadata.py} +2 -4
- bec_widgets/widgets/editors/scan_metadata/scan_metadata.py +42 -136
- bec_widgets/widgets/editors/scan_metadata/scan_metadata.pyproject +1 -0
- bec_widgets/widgets/{plots/multi_waveform/bec_multi_waveform_widget_plugin.py → editors/scan_metadata/scan_metadata_plugin.py} +9 -9
- bec_widgets/widgets/editors/text_box/text_box.py +2 -3
- bec_widgets/widgets/editors/website/website.py +2 -2
- bec_widgets/widgets/games/minesweeper.py +3 -2
- bec_widgets/widgets/plots/image/image.py +960 -0
- bec_widgets/widgets/plots/image/image.pyproject +1 -0
- bec_widgets/widgets/plots/image/image_item.py +279 -0
- bec_widgets/widgets/plots/{motor_map/bec_motor_map_widget_plugin.py → image/image_plugin.py} +11 -13
- bec_widgets/widgets/{containers/figure/plots → plots}/image/image_processor.py +31 -64
- bec_widgets/widgets/plots/image/{register_bec_image_widget.py → register_image.py} +2 -2
- bec_widgets/widgets/plots/image/toolbar_bundles/image_selection.py +59 -0
- bec_widgets/widgets/plots/image/toolbar_bundles/processing.py +79 -0
- bec_widgets/widgets/plots/motor_map/motor_map.py +832 -0
- bec_widgets/widgets/plots/motor_map/motor_map.pyproject +1 -0
- bec_widgets/widgets/plots/motor_map/motor_map_plugin.py +54 -0
- bec_widgets/widgets/plots/{multi_waveform/register_bec_multi_waveform_widget.py → motor_map/register_motor_map.py} +2 -4
- bec_widgets/widgets/plots/motor_map/settings/motor_map_settings.py +129 -0
- bec_widgets/widgets/plots/motor_map/settings/motor_map_settings.ui +120 -0
- bec_widgets/widgets/plots/motor_map/toolbar_bundles/motor_selection.py +70 -0
- bec_widgets/widgets/plots/multi_waveform/multi_waveform.py +508 -0
- bec_widgets/widgets/plots/multi_waveform/multi_waveform.pyproject +1 -0
- bec_widgets/widgets/plots/multi_waveform/multi_waveform_plugin.py +54 -0
- bec_widgets/widgets/plots/multi_waveform/register_multi_waveform.py +15 -0
- bec_widgets/widgets/plots/multi_waveform/settings/control_panel.py +144 -0
- bec_widgets/widgets/plots/multi_waveform/settings/multi_waveform_controls.ui +164 -0
- bec_widgets/widgets/plots/multi_waveform/toolbar_bundles/monitor_selection.py +65 -0
- bec_widgets/widgets/{plots_next_gen → plots}/plot_base.py +321 -40
- bec_widgets/widgets/plots/{waveform/register_bec_waveform_widget.py → scatter_waveform/register_scatter_waveform.py} +3 -3
- bec_widgets/widgets/plots/scatter_waveform/scatter_curve.py +197 -0
- bec_widgets/widgets/plots/scatter_waveform/scatter_waveform.py +553 -0
- bec_widgets/widgets/plots/scatter_waveform/scatter_waveform.pyproject +1 -0
- bec_widgets/widgets/plots/{image/bec_image_widget_plugin.py → scatter_waveform/scatter_waveform_plugin.py} +9 -13
- bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_setting.py +138 -0
- bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_settings_horizontal.ui +195 -0
- bec_widgets/widgets/plots/scatter_waveform/settings/scatter_curve_settings_vertical.ui +204 -0
- bec_widgets/widgets/{plots_next_gen → plots}/setting_menus/axis_settings.py +8 -8
- bec_widgets/widgets/{plots_next_gen → plots}/toolbar_bundles/mouse_interactions.py +4 -18
- bec_widgets/widgets/{plots_next_gen → plots}/toolbar_bundles/plot_export.py +14 -3
- bec_widgets/widgets/{plots_next_gen → plots}/toolbar_bundles/roi_bundle.py +6 -1
- bec_widgets/widgets/{plots_next_gen → plots}/toolbar_bundles/save_state.py +2 -2
- bec_widgets/widgets/{containers/figure/plots/waveform/waveform_curve.py → plots/waveform/curve.py} +119 -49
- bec_widgets/widgets/plots/waveform/register_waveform.py +15 -0
- bec_widgets/widgets/plots/waveform/settings/curve_settings/curve_setting.py +125 -0
- bec_widgets/widgets/plots/waveform/settings/curve_settings/curve_tree.py +576 -0
- bec_widgets/widgets/plots/waveform/utils/__init__.py +0 -0
- bec_widgets/widgets/plots/waveform/utils/roi_manager.py +84 -0
- bec_widgets/widgets/plots/waveform/waveform.py +1794 -0
- bec_widgets/widgets/plots/waveform/waveform.pyproject +1 -0
- bec_widgets/widgets/plots/waveform/{bec_waveform_widget_plugin.py → waveform_plugin.py} +9 -13
- bec_widgets/widgets/progress/bec_progressbar/bec_progressbar.py +1 -2
- bec_widgets/widgets/progress/ring_progress_bar/ring.py +11 -10
- bec_widgets/widgets/progress/ring_progress_bar/ring_progress_bar.py +24 -14
- bec_widgets/widgets/services/bec_queue/bec_queue.py +13 -11
- bec_widgets/widgets/services/bec_status_box/bec_status_box.py +3 -4
- bec_widgets/widgets/services/device_browser/device_browser.py +5 -2
- bec_widgets/widgets/services/device_browser/device_item/device_item.py +1 -1
- bec_widgets/widgets/utility/logpanel/logpanel.py +36 -17
- bec_widgets/widgets/utility/spinbox/decimal_spinbox.py +3 -3
- bec_widgets/widgets/utility/visual/color_button/color_button.py +1 -1
- bec_widgets/widgets/utility/visual/colormap_widget/colormap_widget.py +4 -6
- bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button.py +4 -8
- {bec_widgets-1.25.1.dist-info → bec_widgets-2.0.1.dist-info}/METADATA +3 -3
- {bec_widgets-1.25.1.dist-info → bec_widgets-2.0.1.dist-info}/RECORD +168 -153
- pyproject.toml +3 -3
- bec_widgets/applications/alignment/alignment_1d/alignment_1d.py +0 -198
- bec_widgets/applications/alignment/alignment_1d/alignment_1d.ui +0 -615
- bec_widgets/applications/bec_app.py +0 -84
- bec_widgets/cli/auto_updates.py +0 -168
- bec_widgets/widgets/containers/figure/__init__.py +0 -1
- bec_widgets/widgets/containers/figure/figure.py +0 -796
- bec_widgets/widgets/containers/figure/plots/axis_settings.py +0 -91
- bec_widgets/widgets/containers/figure/plots/axis_settings.ui +0 -256
- bec_widgets/widgets/containers/figure/plots/image/image.py +0 -772
- bec_widgets/widgets/containers/figure/plots/image/image_item.py +0 -337
- bec_widgets/widgets/containers/figure/plots/motor_map/motor_map.py +0 -525
- bec_widgets/widgets/containers/figure/plots/multi_waveform/multi_waveform.py +0 -340
- bec_widgets/widgets/containers/figure/plots/plot_base.py +0 -505
- bec_widgets/widgets/containers/figure/plots/waveform/waveform.py +0 -1563
- bec_widgets/widgets/plots/image/bec_image_widget.pyproject +0 -1
- bec_widgets/widgets/plots/image/image_widget.py +0 -515
- bec_widgets/widgets/plots/motor_map/bec_motor_map_widget.pyproject +0 -1
- bec_widgets/widgets/plots/motor_map/motor_map_dialog/motor_map_settings.py +0 -56
- bec_widgets/widgets/plots/motor_map/motor_map_dialog/motor_map_settings.ui +0 -108
- bec_widgets/widgets/plots/motor_map/motor_map_widget.py +0 -234
- bec_widgets/widgets/plots/multi_waveform/bec_multi_waveform_widget.pyproject +0 -1
- bec_widgets/widgets/plots/multi_waveform/multi_waveform_controls.ui +0 -99
- bec_widgets/widgets/plots/multi_waveform/multi_waveform_widget.py +0 -536
- bec_widgets/widgets/plots/waveform/bec_waveform_widget.pyproject +0 -1
- bec_widgets/widgets/plots/waveform/waveform_popups/curve_dialog/curve_dialog.py +0 -336
- bec_widgets/widgets/plots/waveform/waveform_popups/curve_dialog/curve_dialog.ui +0 -372
- bec_widgets/widgets/plots/waveform/waveform_popups/dap_summary_dialog/dap_summary_dialog.py +0 -25
- bec_widgets/widgets/plots/waveform/waveform_widget.py +0 -751
- /bec_widgets/{qt_utils → utils}/collapsible_panel_manager.py +0 -0
- /bec_widgets/{applications/alignment → utils/forms_from_types}/__init__.py +0 -0
- /bec_widgets/{qt_utils → utils}/redis_message_waiter.py +0 -0
- /bec_widgets/{applications/alignment/alignment_1d → widgets/containers/auto_update}/__init__.py +0 -0
- /bec_widgets/{qt_utils → widgets/containers/main_window/addons}/__init__.py +0 -0
- /bec_widgets/widgets/{containers/figure/plots → plots/image/toolbar_bundles}/__init__.py +0 -0
- /bec_widgets/widgets/{containers/figure/plots/image → plots/motor_map/settings}/__init__.py +0 -0
- /bec_widgets/widgets/{containers/figure/plots/motor_map → plots/motor_map/toolbar_bundles}/__init__.py +0 -0
- /bec_widgets/widgets/{containers/figure/plots/multi_waveform → plots/multi_waveform/settings}/__init__.py +0 -0
- /bec_widgets/widgets/{containers/figure/plots/waveform → plots/multi_waveform/toolbar_bundles}/__init__.py +0 -0
- /bec_widgets/widgets/plots/{motor_map/motor_map_dialog → scatter_waveform}/__init__.py +0 -0
- /bec_widgets/widgets/plots/{waveform/waveform_popups → scatter_waveform/settings}/__init__.py +0 -0
- /bec_widgets/widgets/plots/{waveform/waveform_popups/curve_dialog → setting_menus}/__init__.py +0 -0
- /bec_widgets/widgets/{plots_next_gen → plots}/setting_menus/axis_settings_horizontal.ui +0 -0
- /bec_widgets/widgets/{plots_next_gen → plots}/setting_menus/axis_settings_vertical.ui +0 -0
- /bec_widgets/widgets/plots/{waveform/waveform_popups/dap_summary_dialog → toolbar_bundles}/__init__.py +0 -0
- /bec_widgets/widgets/{plots_next_gen/setting_menus → plots/waveform/settings}/__init__.py +0 -0
- /bec_widgets/widgets/{plots_next_gen/toolbar_bundles → plots/waveform/settings/curve_settings}/__init__.py +0 -0
- {bec_widgets-1.25.1.dist-info → bec_widgets-2.0.1.dist-info}/WHEEL +0 -0
- {bec_widgets-1.25.1.dist-info → bec_widgets-2.0.1.dist-info}/entry_points.txt +0 -0
- {bec_widgets-1.25.1.dist-info → bec_widgets-2.0.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,25 +1,33 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from typing import TYPE_CHECKING, Any, Literal, Optional
|
3
|
+
from typing import TYPE_CHECKING, Any, Literal, Optional, cast
|
4
4
|
|
5
|
+
from bec_lib.logger import bec_logger
|
5
6
|
from pydantic import Field
|
6
7
|
from pyqtgraph.dockarea import Dock, DockLabel
|
7
8
|
from qtpy import QtCore, QtGui
|
8
9
|
|
10
|
+
from bec_widgets.cli.client_utils import IGNORE_WIDGETS
|
9
11
|
from bec_widgets.cli.rpc.rpc_widget_handler import widget_handler
|
10
12
|
from bec_widgets.utils import ConnectionConfig, GridLayoutManager
|
11
13
|
from bec_widgets.utils.bec_widget import BECWidget
|
14
|
+
from bec_widgets.utils.container_utils import WidgetContainerUtils
|
15
|
+
from bec_widgets.utils.error_popups import SafeSlot
|
12
16
|
|
13
|
-
|
17
|
+
logger = bec_logger.logger
|
18
|
+
|
19
|
+
if TYPE_CHECKING: # pragma: no cover
|
14
20
|
from qtpy.QtWidgets import QWidget
|
15
21
|
|
22
|
+
from bec_widgets.widgets.containers.dock.dock_area import BECDockArea
|
23
|
+
|
16
24
|
|
17
25
|
class DockConfig(ConnectionConfig):
|
18
26
|
widgets: dict[str, Any] = Field({}, description="The widgets in the dock.")
|
19
27
|
position: Literal["bottom", "top", "left", "right", "above", "below"] = Field(
|
20
28
|
"bottom", description="The position of the dock."
|
21
29
|
)
|
22
|
-
parent_dock_area: Optional[str] = Field(
|
30
|
+
parent_dock_area: Optional[str] | None = Field(
|
23
31
|
None, description="The GUI ID of parent dock area of the dock."
|
24
32
|
)
|
25
33
|
|
@@ -103,16 +111,17 @@ class BECDock(BECWidget, Dock):
|
|
103
111
|
ICON_NAME = "widgets"
|
104
112
|
USER_ACCESS = [
|
105
113
|
"_config_dict",
|
106
|
-
"
|
107
|
-
"
|
114
|
+
"element_list",
|
115
|
+
"elements",
|
116
|
+
"new",
|
117
|
+
"show",
|
118
|
+
"hide",
|
108
119
|
"show_title_bar",
|
109
|
-
"hide_title_bar",
|
110
|
-
"get_widgets_positions",
|
111
120
|
"set_title",
|
112
|
-
"
|
113
|
-
"
|
114
|
-
"
|
115
|
-
"
|
121
|
+
"hide_title_bar",
|
122
|
+
"available_widgets",
|
123
|
+
"delete",
|
124
|
+
"delete_all",
|
116
125
|
"remove",
|
117
126
|
"attach",
|
118
127
|
"detach",
|
@@ -121,29 +130,38 @@ class BECDock(BECWidget, Dock):
|
|
121
130
|
def __init__(
|
122
131
|
self,
|
123
132
|
parent: QWidget | None = None,
|
124
|
-
parent_dock_area:
|
133
|
+
parent_dock_area: BECDockArea | None = None,
|
125
134
|
config: DockConfig | None = None,
|
126
135
|
name: str | None = None,
|
136
|
+
object_name: str | None = None,
|
127
137
|
client=None,
|
128
138
|
gui_id: str | None = None,
|
129
139
|
closable: bool = True,
|
130
140
|
**kwargs,
|
131
141
|
) -> None:
|
142
|
+
|
132
143
|
if config is None:
|
133
144
|
config = DockConfig(
|
134
|
-
widget_class=self.__class__.__name__,
|
145
|
+
widget_class=self.__class__.__name__,
|
146
|
+
parent_dock_area=parent_dock_area.gui_id if parent_dock_area else None,
|
135
147
|
)
|
136
148
|
else:
|
137
149
|
if isinstance(config, dict):
|
138
150
|
config = DockConfig(**config)
|
139
151
|
self.config = config
|
140
|
-
super().__init__(client=client, config=config, gui_id=gui_id)
|
141
152
|
label = CustomDockLabel(text=name, closable=closable)
|
142
|
-
|
143
|
-
|
153
|
+
super().__init__(
|
154
|
+
parent=parent_dock_area,
|
155
|
+
name=name,
|
156
|
+
object_name=object_name,
|
157
|
+
client=client,
|
158
|
+
gui_id=gui_id,
|
159
|
+
config=config,
|
160
|
+
label=label,
|
161
|
+
**kwargs,
|
162
|
+
)
|
144
163
|
|
145
164
|
self.parent_dock_area = parent_dock_area
|
146
|
-
|
147
165
|
# Layout Manager
|
148
166
|
self.layout_manager = GridLayoutManager(self.layout)
|
149
167
|
|
@@ -173,7 +191,18 @@ class BECDock(BECWidget, Dock):
|
|
173
191
|
super().float()
|
174
192
|
|
175
193
|
@property
|
176
|
-
def
|
194
|
+
def elements(self) -> dict[str, BECWidget]:
|
195
|
+
"""
|
196
|
+
Get the widgets in the dock.
|
197
|
+
|
198
|
+
Returns:
|
199
|
+
widgets(dict): The widgets in the dock.
|
200
|
+
"""
|
201
|
+
# pylint: disable=protected-access
|
202
|
+
return dict((widget.object_name, widget) for widget in self.element_list)
|
203
|
+
|
204
|
+
@property
|
205
|
+
def element_list(self) -> list[BECWidget]:
|
177
206
|
"""
|
178
207
|
Get the widgets in the dock.
|
179
208
|
|
@@ -182,10 +211,6 @@ class BECDock(BECWidget, Dock):
|
|
182
211
|
"""
|
183
212
|
return self.widgets
|
184
213
|
|
185
|
-
@widget_list.setter
|
186
|
-
def widget_list(self, value: list[BECWidget]):
|
187
|
-
self.widgets = value
|
188
|
-
|
189
214
|
def hide_title_bar(self):
|
190
215
|
"""
|
191
216
|
Hide the title bar of the dock.
|
@@ -194,6 +219,20 @@ class BECDock(BECWidget, Dock):
|
|
194
219
|
self.label.hide()
|
195
220
|
self.labelHidden = True
|
196
221
|
|
222
|
+
def show(self):
|
223
|
+
"""
|
224
|
+
Show the dock.
|
225
|
+
"""
|
226
|
+
super().show()
|
227
|
+
self.show_title_bar()
|
228
|
+
|
229
|
+
def hide(self):
|
230
|
+
"""
|
231
|
+
Hide the dock.
|
232
|
+
"""
|
233
|
+
self.hide_title_bar()
|
234
|
+
super().hide()
|
235
|
+
|
197
236
|
def show_title_bar(self):
|
198
237
|
"""
|
199
238
|
Hide the title bar of the dock.
|
@@ -211,7 +250,6 @@ class BECDock(BECWidget, Dock):
|
|
211
250
|
"""
|
212
251
|
self.orig_area.docks[title] = self.orig_area.docks.pop(self.name())
|
213
252
|
self.setTitle(title)
|
214
|
-
self._name = title
|
215
253
|
|
216
254
|
def get_widgets_positions(self) -> dict:
|
217
255
|
"""
|
@@ -222,7 +260,7 @@ class BECDock(BECWidget, Dock):
|
|
222
260
|
"""
|
223
261
|
return self.layout_manager.get_widgets_positions()
|
224
262
|
|
225
|
-
def
|
263
|
+
def available_widgets(
|
226
264
|
self,
|
227
265
|
) -> list: # TODO can be moved to some util mixin like container class for rpc widgets
|
228
266
|
"""
|
@@ -233,42 +271,69 @@ class BECDock(BECWidget, Dock):
|
|
233
271
|
"""
|
234
272
|
return list(widget_handler.widget_classes.keys())
|
235
273
|
|
236
|
-
def
|
274
|
+
def _get_list_of_widget_name_of_parent_dock_area(self) -> list[str]:
|
275
|
+
if (docks := self.parent_dock_area.panel_list) is None:
|
276
|
+
return []
|
277
|
+
widgets = []
|
278
|
+
for dock in docks:
|
279
|
+
widgets.extend(dock.elements.keys())
|
280
|
+
return widgets
|
281
|
+
|
282
|
+
@SafeSlot(popup_error=True)
|
283
|
+
def new(
|
237
284
|
self,
|
238
285
|
widget: BECWidget | str,
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
286
|
+
name: str | None = None,
|
287
|
+
row: int | None = None,
|
288
|
+
col: int = 0,
|
289
|
+
rowspan: int = 1,
|
290
|
+
colspan: int = 1,
|
243
291
|
shift: Literal["down", "up", "left", "right"] = "down",
|
244
292
|
) -> BECWidget:
|
245
293
|
"""
|
246
294
|
Add a widget to the dock.
|
247
295
|
|
248
296
|
Args:
|
249
|
-
widget(QWidget): The widget to add.
|
297
|
+
widget(QWidget): The widget to add. It can not be BECDock or BECDockArea.
|
298
|
+
name(str): The name of the widget.
|
250
299
|
row(int): The row to add the widget to. If None, the widget will be added to the next available row.
|
251
300
|
col(int): The column to add the widget to.
|
252
301
|
rowspan(int): The number of rows the widget should span.
|
253
302
|
colspan(int): The number of columns the widget should span.
|
254
303
|
shift(Literal["down", "up", "left", "right"]): The direction to shift the widgets if the position is occupied.
|
255
304
|
"""
|
305
|
+
if name is not None:
|
306
|
+
if not WidgetContainerUtils.has_name_valid_chars(name):
|
307
|
+
raise ValueError(
|
308
|
+
f"Name {name} contains invalid characters. "
|
309
|
+
f"Only alphanumeric characters and underscores are allowed."
|
310
|
+
)
|
311
|
+
|
256
312
|
if row is None:
|
257
313
|
row = self.layout.rowCount()
|
258
314
|
|
259
315
|
if self.layout_manager.is_position_occupied(row, col):
|
260
316
|
self.layout_manager.shift_widgets(shift, start_row=row)
|
261
317
|
|
318
|
+
# Check that Widget is not BECDock or BECDockArea
|
319
|
+
widget_class_name = widget if isinstance(widget, str) else widget.__class__.__name__
|
320
|
+
if widget_class_name in IGNORE_WIDGETS:
|
321
|
+
raise ValueError(f"Widget {widget} can not be added to dock.")
|
322
|
+
|
262
323
|
if isinstance(widget, str):
|
263
|
-
widget =
|
324
|
+
widget = cast(
|
325
|
+
BECWidget,
|
326
|
+
widget_handler.create_widget(
|
327
|
+
widget_type=widget, object_name=name, parent_dock=self, parent=self
|
328
|
+
),
|
329
|
+
)
|
264
330
|
else:
|
265
|
-
widget =
|
331
|
+
widget.object_name = name
|
266
332
|
|
267
333
|
self.addWidget(widget, row=row, col=col, rowspan=rowspan, colspan=colspan)
|
268
|
-
|
269
334
|
if hasattr(widget, "config"):
|
270
|
-
|
271
|
-
|
335
|
+
widget.config.gui_id = widget.gui_id
|
336
|
+
self.config.widgets[widget.object_name] = widget.config
|
272
337
|
return widget
|
273
338
|
|
274
339
|
def move_widget(self, widget: QWidget, new_row: int, new_col: int):
|
@@ -294,36 +359,68 @@ class BECDock(BECWidget, Dock):
|
|
294
359
|
"""
|
295
360
|
self.float()
|
296
361
|
|
297
|
-
def
|
362
|
+
def remove(self):
|
363
|
+
"""
|
364
|
+
Remove the dock from the parent dock area.
|
365
|
+
"""
|
366
|
+
self.parent_dock_area.delete(self.object_name)
|
367
|
+
|
368
|
+
def delete(self, widget_name: str) -> None:
|
298
369
|
"""
|
299
370
|
Remove a widget from the dock.
|
300
371
|
|
301
372
|
Args:
|
302
|
-
|
373
|
+
widget_name(str): Delete the widget with the given name.
|
303
374
|
"""
|
304
|
-
|
375
|
+
# pylint: disable=protected-access
|
376
|
+
widgets = [widget for widget in self.widgets if widget.object_name == widget_name]
|
377
|
+
if len(widgets) == 0:
|
378
|
+
logger.warning(
|
379
|
+
f"Widget with name {widget_name} not found in dock {self.name()}. "
|
380
|
+
f"Checking if gui_id was passed as widget_name."
|
381
|
+
)
|
382
|
+
# Try to find the widget in the RPC register, maybe the gui_id was passed as widget_name
|
383
|
+
widget = self.rpc_register.get_rpc_by_id(widget_name)
|
384
|
+
if widget is None:
|
385
|
+
logger.warning(
|
386
|
+
f"Widget not found for name or gui_id: {widget_name} in dock {self.name()}"
|
387
|
+
)
|
388
|
+
return
|
389
|
+
else:
|
390
|
+
widget = widgets[0]
|
305
391
|
self.layout.removeWidget(widget)
|
306
|
-
self.config.widgets.pop(
|
392
|
+
self.config.widgets.pop(widget.object_name, None)
|
393
|
+
if widget in self.widgets:
|
394
|
+
self.widgets.remove(widget)
|
307
395
|
widget.close()
|
308
396
|
|
309
|
-
def
|
397
|
+
def delete_all(self):
|
310
398
|
"""
|
311
|
-
Remove
|
399
|
+
Remove all widgets from the dock.
|
312
400
|
"""
|
313
|
-
|
314
|
-
|
401
|
+
for widget in self.widgets:
|
402
|
+
self.delete(widget.object_name)
|
315
403
|
|
316
404
|
def cleanup(self):
|
317
405
|
"""
|
318
406
|
Clean up the dock, including all its widgets.
|
319
407
|
"""
|
320
|
-
|
321
|
-
|
322
|
-
|
408
|
+
# # FIXME Cleanup might be called twice
|
409
|
+
try:
|
410
|
+
logger.info(f"Cleaning up dock {self.name()}")
|
411
|
+
self.label.close()
|
412
|
+
self.label.deleteLater()
|
413
|
+
except Exception as e:
|
414
|
+
logger.error(f"Error while closing dock label: {e}")
|
415
|
+
|
416
|
+
# Remove the dock from the parent dock area
|
417
|
+
if self.parent_dock_area:
|
418
|
+
self.parent_dock_area.dock_area.docks.pop(self.name(), None)
|
419
|
+
self.parent_dock_area.config.docks.pop(self.name(), None)
|
420
|
+
self.delete_all()
|
323
421
|
self.widgets.clear()
|
324
|
-
self.label.close()
|
325
|
-
self.label.deleteLater()
|
326
422
|
super().cleanup()
|
423
|
+
self.deleteLater()
|
327
424
|
|
328
425
|
def close(self):
|
329
426
|
"""
|
@@ -332,4 +429,15 @@ class BECDock(BECWidget, Dock):
|
|
332
429
|
"""
|
333
430
|
self.cleanup()
|
334
431
|
super().close()
|
335
|
-
|
432
|
+
|
433
|
+
|
434
|
+
if __name__ == "__main__": # pragma: no cover
|
435
|
+
import sys
|
436
|
+
|
437
|
+
from qtpy.QtWidgets import QApplication
|
438
|
+
|
439
|
+
app = QApplication([])
|
440
|
+
dock = BECDock(name="dock")
|
441
|
+
dock.show()
|
442
|
+
app.exec_()
|
443
|
+
sys.exit(app.exec_())
|