bec-widgets 0.82.2__tar.gz → 0.83.0__tar.gz
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.
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/.gitlab-ci.yml +3 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/CHANGELOG.md +26 -28
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/PKG-INFO +1 -1
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/utils/bec_connector.py +2 -0
- bec_widgets-0.83.0/bec_widgets/utils/bec_widget.py +8 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/utils/generate_designer_plugin.py +6 -5
- bec_widgets-0.83.0/bec_widgets/utils/reference_utils.py +92 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/console/console.py +1 -1
- bec_widgets-0.83.0/bec_widgets/widgets/device_box/device_box.py +197 -0
- bec_widgets-0.83.0/bec_widgets/widgets/device_box/device_box.pyproject +1 -0
- bec_widgets-0.83.0/bec_widgets/widgets/device_box/device_box.ui +179 -0
- bec_widgets-0.83.0/bec_widgets/widgets/device_box/device_box_plugin.py +54 -0
- bec_widgets-0.83.0/bec_widgets/widgets/device_box/register_device_box.py +15 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/figure/figure.py +3 -3
- bec_widgets-0.83.0/bec_widgets/widgets/position_indicator/position_indicator.py +71 -0
- bec_widgets-0.83.0/bec_widgets/widgets/position_indicator/position_indicator.pyproject +1 -0
- bec_widgets-0.83.0/bec_widgets/widgets/position_indicator/position_indicator_plugin.py +54 -0
- bec_widgets-0.83.0/bec_widgets/widgets/position_indicator/register_position_indicator.py +17 -0
- bec_widgets-0.83.0/bec_widgets/widgets/spinner/register_spinner_widget.py +15 -0
- bec_widgets-0.83.0/bec_widgets/widgets/spinner/spinner.py +85 -0
- bec_widgets-0.83.0/bec_widgets/widgets/spinner/spinner_widget.pyproject +1 -0
- bec_widgets-0.83.0/bec_widgets/widgets/spinner/spinner_widget_plugin.py +54 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/vscode/vscode.py +0 -14
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/website/website.py +1 -1
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/pyproject.toml +1 -1
- bec_widgets-0.83.0/tests/references/SpinnerWidget/SpinnerWidget_darwin.png +0 -0
- bec_widgets-0.83.0/tests/references/SpinnerWidget/SpinnerWidget_linux.png +0 -0
- bec_widgets-0.83.0/tests/references/SpinnerWidget/SpinnerWidget_started_darwin.png +0 -0
- bec_widgets-0.83.0/tests/references/SpinnerWidget/SpinnerWidget_started_linux.png +0 -0
- bec_widgets-0.83.0/tests/unit_tests/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/client_mocks.py +9 -1
- bec_widgets-0.83.0/tests/unit_tests/test_device_box.py +98 -0
- bec_widgets-0.83.0/tests/unit_tests/test_msgs/__init__.py +0 -0
- bec_widgets-0.83.0/tests/unit_tests/test_spinner.py +30 -0
- bec_widgets-0.83.0/tests/unit_tests/test_vscode_widget.py +73 -0
- bec_widgets-0.82.2/bec_widgets/utils/bec_widget.py +0 -2
- bec_widgets-0.82.2/tests/unit_tests/test_vscode_widget.py +0 -78
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/.git_hooks/pre-commit +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/.gitignore +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/.gitlab/issue_templates/bug_report_template.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/.gitlab/issue_templates/documentation_update_template.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/.gitlab/issue_templates/feature_request_template.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/.gitlab/merge_request_templates/default.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/.pylintrc +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/.readthedocs.yaml +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/LICENSE +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/README.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/assets/bec_widgets_icon.png +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/assets/terminal_icon.png +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/cli/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/cli/auto_updates.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/cli/client.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/cli/client_utils.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/cli/generate_cli.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/cli/rpc_register.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/cli/rpc_wigdet_handler.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/cli/server.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/examples/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/examples/jupyter_console/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/examples/jupyter_console/jupyter_console_window.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/examples/jupyter_console/jupyter_console_window.ui +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/examples/plugin_example_pyside/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/examples/plugin_example_pyside/main.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/examples/plugin_example_pyside/registertictactoe.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/examples/plugin_example_pyside/taskmenuextension.pyproject +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/examples/plugin_example_pyside/tictactoe.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/examples/plugin_example_pyside/tictactoeplugin.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/examples/plugin_example_pyside/tictactoetaskmenu.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/qt_utils/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/qt_utils/settings_dialog.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/qt_utils/toolbar.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/utils/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/utils/bec_designer.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/utils/bec_dispatcher.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/utils/bec_table.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/utils/colors.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/utils/container_utils.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/utils/crosshair.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/utils/entry_validator.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/utils/layout_manager.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/utils/plugin_templates/plugin.template +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/utils/plugin_templates/register.template +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/utils/plugin_utils.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/utils/rpc_decorator.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/utils/thread_checker.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/utils/ui_loader.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/utils/validator_delegate.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/utils/widget_io.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/utils/yaml_dialog.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/base_classes/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/base_classes/device_input_base.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/bec_queue/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/bec_queue/bec_queue.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/bec_queue/bec_queue.pyproject +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/bec_queue/bec_queue_plugin.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/bec_queue/register_bec_queue.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/bec_status_box/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/bec_status_box/bec_status_box.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/bec_status_box/bec_status_box.pyproject +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/bec_status_box/bec_status_box_plugin.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/bec_status_box/register_bec_status_box.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/bec_status_box/status_item.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/color_button/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/color_button/assets/color_button.png +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/color_button/color_button.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/color_button/color_button.pyproject +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/color_button/color_button_plugin.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/color_button/register_color_button.py +0 -0
- {bec_widgets-0.82.2/bec_widgets/widgets/device_combobox → bec_widgets-0.83.0/bec_widgets/widgets/device_box}/__init__.py +0 -0
- {bec_widgets-0.82.2/bec_widgets/widgets/device_line_edit → bec_widgets-0.83.0/bec_widgets/widgets/device_combobox}/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/device_combobox/assets/device_combobox_icon.png +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/device_combobox/device_combobox.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/device_combobox/device_combobox.pyproject +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/device_combobox/device_combobox_plugin.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/device_combobox/register_device_combobox.py +0 -0
- {bec_widgets-0.82.2/bec_widgets/widgets/figure/plots → bec_widgets-0.83.0/bec_widgets/widgets/device_line_edit}/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/device_line_edit/assets/line_edit_icon.png +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/device_line_edit/device_line_edit.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/device_line_edit/device_line_edit.pyproject +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/device_line_edit/device_line_edit_plugin.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/device_line_edit/register_device_line_edit.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/dock/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/dock/dock.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/dock/dock_area.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/figure/__init__.py +0 -0
- {bec_widgets-0.82.2/bec_widgets/widgets/figure/plots/image → bec_widgets-0.83.0/bec_widgets/widgets/figure/plots}/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/figure/plots/axis_settings.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/figure/plots/axis_settings.ui +0 -0
- {bec_widgets-0.82.2/bec_widgets/widgets/figure/plots/motor_map → bec_widgets-0.83.0/bec_widgets/widgets/figure/plots/image}/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/figure/plots/image/image.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/figure/plots/image/image_item.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/figure/plots/image/image_processor.py +0 -0
- {bec_widgets-0.82.2/bec_widgets/widgets/figure/plots/waveform → bec_widgets-0.83.0/bec_widgets/widgets/figure/plots/motor_map}/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/figure/plots/motor_map/motor_map.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/figure/plots/plot_base.py +0 -0
- {bec_widgets-0.82.2/bec_widgets/widgets/jupyter_console → bec_widgets-0.83.0/bec_widgets/widgets/figure/plots/waveform}/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/figure/plots/waveform/waveform.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/figure/plots/waveform/waveform_curve.py +0 -0
- {bec_widgets-0.82.2/bec_widgets/widgets/motor_map → bec_widgets-0.83.0/bec_widgets/widgets/jupyter_console}/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/jupyter_console/jupyter_console.py +0 -0
- {bec_widgets-0.82.2/bec_widgets/widgets/motor_map/motor_map_dialog → bec_widgets-0.83.0/bec_widgets/widgets/motor_map}/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/motor_map/assets/connection.svg +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/motor_map/assets/history.svg +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/motor_map/assets/motor_map.png +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/motor_map/assets/settings.svg +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/motor_map/bec_motor_map_widget.pyproject +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/motor_map/bec_motor_map_widget_plugin.py +0 -0
- {bec_widgets-0.82.2/bec_widgets/widgets/stop_button → bec_widgets-0.83.0/bec_widgets/widgets/motor_map/motor_map_dialog}/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/motor_map/motor_map_dialog/motor_map_settings.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/motor_map/motor_map_dialog/motor_map_settings.ui +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/motor_map/motor_map_dialog/motor_map_toolbar.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/motor_map/motor_map_widget.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/motor_map/register_bec_motor_map_widget.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/ring_progress_bar/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/ring_progress_bar/ring.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/ring_progress_bar/ring_progress_bar.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/scan_control/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/scan_control/scan_control.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/scan_control/scan_group_box.py +0 -0
- {bec_widgets-0.82.2/bec_widgets/widgets/text_box → bec_widgets-0.83.0/bec_widgets/widgets/spinner}/__init__.py +0 -0
- {bec_widgets-0.82.2/bec_widgets/widgets/toggle → bec_widgets-0.83.0/bec_widgets/widgets/stop_button}/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/stop_button/assets/stop.png +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/stop_button/register_stop_button.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/stop_button/stop_button.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/stop_button/stop_button.pyproject +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/stop_button/stop_button_plugin.py +0 -0
- {bec_widgets-0.82.2/bec_widgets/widgets/vscode → bec_widgets-0.83.0/bec_widgets/widgets/text_box}/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/text_box/text_box.py +0 -0
- {bec_widgets-0.82.2/bec_widgets/widgets/website → bec_widgets-0.83.0/bec_widgets/widgets/toggle}/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/toggle/register_toggle_switch.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/toggle/toggle.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/toggle/toggle_switch.pyproject +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/bec_widgets/widgets/toggle/toggle_switch_plugin.py +0 -0
- {bec_widgets-0.82.2/tests → bec_widgets-0.83.0/bec_widgets/widgets/vscode}/__init__.py +0 -0
- {bec_widgets-0.82.2/tests/end-2-end → bec_widgets-0.83.0/bec_widgets/widgets/website}/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/Makefile +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/_static/custom.css +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/_templates/custom-class-template.rst +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/_templates/custom-module-template.rst +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/api_reference/api_reference.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/assets/apps_48dp.svg +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/assets/display_settings_48dp.svg +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/assets/index_api.svg +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/assets/index_contribute.svg +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/assets/index_getting_started.svg +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/assets/index_user_guide.svg +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/assets/rocket_launch_48dp.svg +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/conf.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/developer/developer.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/developer/getting_started/development.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/developer/getting_started/getting_started.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/developer/widgets/widgets.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/index.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/introduction/introduction.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/make.bat +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/requirements.txt +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/api_reference/api_reference.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/applications/applications.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/customisation.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/getting_started/BECDockArea.png +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/getting_started/auto_updates.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/getting_started/getting_started.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/getting_started/gui_complex_gui.gif +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/getting_started/installation.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/getting_started/quick_start.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/user.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/widgets/BECFigure.png +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/widgets/bec_figure.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/widgets/bec_figure_dap.gif +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/widgets/bec_status_box.gif +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/widgets/bec_status_box.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/widgets/buttons.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/widgets/image_plot.gif +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/widgets/motor.gif +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/widgets/progress_bar.gif +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/widgets/ring_progress_bar.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/widgets/scan_control.gif +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/widgets/scan_control.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/widgets/scatter_2D.gif +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/widgets/text_box.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/widgets/w1D.gif +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/widgets/website.md +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/docs/user/widgets/widgets.md +0 -0
- {bec_widgets-0.82.2/tests/unit_tests → bec_widgets-0.83.0/tests}/__init__.py +0 -0
- {bec_widgets-0.82.2/tests/unit_tests/test_msgs → bec_widgets-0.83.0/tests/end-2-end}/__init__.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/end-2-end/conftest.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/end-2-end/test_bec_dock_rpc_e2e.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/end-2-end/test_bec_figure_rpc_e2e.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/end-2-end/test_rpc_register_e2e.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/end-2-end/test_scan_control_e2e.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/conftest.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_bec_connector.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_bec_dispatcher.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_bec_dock.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_bec_figure.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_bec_image.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_bec_motor_map.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_bec_queue.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_bec_status_box.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_client_utils.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_color_validation.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_configs/config_device.yaml +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_configs/config_device_no_entry.yaml +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_configs/config_scan.yaml +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_crosshair.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_device_input_base.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_device_input_widgets.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_generate_cli_client.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_generate_plugin.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_motor_map_widget.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_msgs/available_scans_message.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_plot_base.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_plugin_utils.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_ring_progress_bar.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_rpc_register.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_rpc_server.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_rpc_widget_handler.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_scan_control.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_scan_control_group_box.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_setting_dialog.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_stop_button.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_text_box_widget.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_toggle.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_waveform1d.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_website_widget.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_widget_io.py +0 -0
- {bec_widgets-0.82.2 → bec_widgets-0.83.0}/tests/unit_tests/test_yaml_dialog.py +0 -0
@@ -1,5 +1,31 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## v0.83.0 (2024-07-08)
|
4
|
+
|
5
|
+
### Feature
|
6
|
+
|
7
|
+
* feat: added reference utils to compare renderings of widgets ([`2988fd3`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/2988fd387e6b8076fffec1d57e3ccab89ddb2aeb))
|
8
|
+
|
9
|
+
* feat(widgets): added device box with spinner ([`1b017ed`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/1b017edfad8e78fa079210486123976695b8915c))
|
10
|
+
|
11
|
+
* feat(designer): added option to skip the widget validation for DesignerPluginGenerator ([`41bcb80`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/41bcb801674ab6c4d6069bba34ffee09c9e665db))
|
12
|
+
|
13
|
+
### Fix
|
14
|
+
|
15
|
+
* fix(terminal): added default args to avoid designer crashes on startup ([`360d171`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/360d17135573e44b80ab517756da3c0b31daab0f))
|
16
|
+
|
17
|
+
* fix(widget): fixed widget cleanup routine ([`2b29e34`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/2b29e34b52d056349647bb2fcf649b749a60d292))
|
18
|
+
|
19
|
+
* fix(bec_widget): added cleanup method to bec widget base class ([`fd8766e`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/fd8766ed87770661da6591aeb4df5abdaf38afc7))
|
20
|
+
|
21
|
+
* fix(website): fixed dummy input ([`903ce7d`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/903ce7d46b5d37d40486d0fda92d3694d3faca62))
|
22
|
+
|
23
|
+
### Test
|
24
|
+
|
25
|
+
* test(vscode): fixed vscode tests for new cleanup routine ([`eb26e2a`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/eb26e2a11b229a52efe2e6d4fb28d760d3740136))
|
26
|
+
|
27
|
+
* test(vscode): improved vscode test ([`5de8804`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/5de8804da1e41eafad2472344904b3324438c13b))
|
28
|
+
|
3
29
|
## v0.82.2 (2024-07-08)
|
4
30
|
|
5
31
|
### Fix
|
@@ -117,31 +143,3 @@
|
|
117
143
|
* fix(toolbar): change default color to black to match BECFigure theme ([`b8774e0`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/b8774e0b0bc43dcd00f94f42539a778e507ca27d))
|
118
144
|
|
119
145
|
* fix(motor_map): fixed bug with residual trace after changing motors ([`aaa0d10`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/aaa0d1003d2e94b45bafe4f700852c2c05288aea))
|
120
|
-
|
121
|
-
* fix(widget_io): widget handler adjusted for spinboxes and comboboxes ([`3dc0532`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/3dc0532df05b6ec0a2522107fa0b1e210ce7d91b))
|
122
|
-
|
123
|
-
### Refactor
|
124
|
-
|
125
|
-
* refactor(toolbar): cleanup and adjusted colors ([`96863ad`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/96863adf53c15112645d20eb6200733617801c6d))
|
126
|
-
|
127
|
-
## v0.78.1 (2024-07-02)
|
128
|
-
|
129
|
-
### Fix
|
130
|
-
|
131
|
-
* fix(ui_loader): ui loader is compatible with bec plugins ([`b787759`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/b787759f44486dc7af2c03811efb156041e4b6cb))
|
132
|
-
|
133
|
-
## v0.78.0 (2024-07-02)
|
134
|
-
|
135
|
-
### Feature
|
136
|
-
|
137
|
-
* feat(color_button): patched ColorButton from pyqtgraph to be able to be opened in another QDialog ([`c36bb80`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/c36bb80d6a4939802a4a1c8e5452c7b94bac185e))
|
138
|
-
|
139
|
-
## v0.77.0 (2024-07-02)
|
140
|
-
|
141
|
-
### Fix
|
142
|
-
|
143
|
-
* fix(waveform): scatter 2D brush error ([`215d59c`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/215d59c8bfe7fda9aff8cec8353bef9e1ce2eca1))
|
144
|
-
|
145
|
-
* fix(figure): API cleanup ([`008a33a`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/008a33a9b192473cc58e90cd6d98c5bcb5f7b8c0))
|
146
|
-
|
147
|
-
* fix(figure): if/else logic corrected in subplot_factory ([`3e78723`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/3e787234c7274b0698423d7bf9a4c54ec46bad5f))
|
@@ -289,6 +289,8 @@ class BECConnector(BECWidget):
|
|
289
289
|
print("No more connections. Shutting down GUI BEC client.")
|
290
290
|
self.bec_dispatcher.disconnect_all()
|
291
291
|
self.client.shutdown()
|
292
|
+
if hasattr(super(), "cleanup"):
|
293
|
+
super().cleanup()
|
292
294
|
|
293
295
|
# def closeEvent(self, event):
|
294
296
|
# self.cleanup()
|
@@ -58,11 +58,12 @@ class DesignerPluginGenerator:
|
|
58
58
|
os.path.dirname(os.path.abspath(__file__)), "plugin_templates"
|
59
59
|
)
|
60
60
|
|
61
|
-
def run(self):
|
61
|
+
def run(self, validate=True):
|
62
62
|
if self._excluded:
|
63
63
|
print(f"Plugin {self.widget.__name__} is excluded from generation.")
|
64
64
|
return
|
65
|
-
|
65
|
+
if validate:
|
66
|
+
self._check_class_validity()
|
66
67
|
self._load_templates()
|
67
68
|
self._write_templates()
|
68
69
|
|
@@ -142,7 +143,7 @@ class DesignerPluginGenerator:
|
|
142
143
|
|
143
144
|
if __name__ == "__main__": # pragma: no cover
|
144
145
|
# from bec_widgets.widgets.bec_queue.bec_queue import BECQueue
|
145
|
-
from bec_widgets.widgets.
|
146
|
+
from bec_widgets.widgets.spinner.spinner import SpinnerWidget
|
146
147
|
|
147
|
-
generator = DesignerPluginGenerator(
|
148
|
-
generator.run()
|
148
|
+
generator = DesignerPluginGenerator(SpinnerWidget)
|
149
|
+
generator.run(validate=False)
|
@@ -0,0 +1,92 @@
|
|
1
|
+
import os
|
2
|
+
import sys
|
3
|
+
|
4
|
+
from PIL import Image, ImageChops
|
5
|
+
from qtpy.QtGui import QPixmap
|
6
|
+
|
7
|
+
import bec_widgets
|
8
|
+
|
9
|
+
REFERENCE_DIR = os.path.join(
|
10
|
+
os.path.dirname(os.path.dirname(bec_widgets.__file__)), "tests/references"
|
11
|
+
)
|
12
|
+
REFERENCE_DIR_FAILURES = os.path.join(
|
13
|
+
os.path.dirname(os.path.dirname(bec_widgets.__file__)), "tests/reference_failures"
|
14
|
+
)
|
15
|
+
|
16
|
+
|
17
|
+
def compare_images(image1_path: str, reference_image_path: str):
|
18
|
+
"""
|
19
|
+
Load two images and compare them pixel by pixel
|
20
|
+
|
21
|
+
Args:
|
22
|
+
image1_path(str): The path to the first image
|
23
|
+
reference_image_path(str): The path to the reference image
|
24
|
+
|
25
|
+
Raises:
|
26
|
+
ValueError: If the images are different
|
27
|
+
"""
|
28
|
+
image1 = Image.open(image1_path)
|
29
|
+
image2 = Image.open(reference_image_path)
|
30
|
+
if image1.size != image2.size:
|
31
|
+
raise ValueError("Image size has changed")
|
32
|
+
diff = ImageChops.difference(image1, image2)
|
33
|
+
if diff.getbbox():
|
34
|
+
# copy image1 to the reference directory to upload as artifact
|
35
|
+
os.makedirs(REFERENCE_DIR_FAILURES, exist_ok=True)
|
36
|
+
image_name = os.path.join(REFERENCE_DIR_FAILURES, os.path.basename(image1_path))
|
37
|
+
image1.save(image_name)
|
38
|
+
print(f"Image saved to {image_name}")
|
39
|
+
|
40
|
+
raise ValueError("Images are different")
|
41
|
+
|
42
|
+
|
43
|
+
def snap_and_compare(widget: any, output_directory: str, suffix: str = ""):
|
44
|
+
"""
|
45
|
+
Save a rendering of a widget and compare it to a reference image
|
46
|
+
|
47
|
+
Args:
|
48
|
+
widget(any): The widget to render
|
49
|
+
output_directory(str): The directory to save the image to
|
50
|
+
suffix(str): A suffix to append to the image name
|
51
|
+
|
52
|
+
Raises:
|
53
|
+
ValueError: If the images are different
|
54
|
+
|
55
|
+
Examples:
|
56
|
+
snap_and_compare(widget, tmpdir, suffix="started")
|
57
|
+
|
58
|
+
"""
|
59
|
+
|
60
|
+
if not isinstance(output_directory, str):
|
61
|
+
output_directory = str(output_directory)
|
62
|
+
|
63
|
+
os_suffix = sys.platform
|
64
|
+
|
65
|
+
name = (
|
66
|
+
f"{widget.__class__.__name__}_{suffix}_{os_suffix}.png"
|
67
|
+
if suffix
|
68
|
+
else f"{widget.__class__.__name__}_{os_suffix}.png"
|
69
|
+
)
|
70
|
+
|
71
|
+
# Save the widget to a pixmap
|
72
|
+
test_image_path = os.path.join(output_directory, name)
|
73
|
+
pixmap = QPixmap(widget.size())
|
74
|
+
widget.render(pixmap)
|
75
|
+
pixmap.save(test_image_path)
|
76
|
+
|
77
|
+
try:
|
78
|
+
reference_path = os.path.join(REFERENCE_DIR, f"{widget.__class__.__name__}")
|
79
|
+
reference_image_path = os.path.join(reference_path, name)
|
80
|
+
|
81
|
+
if not os.path.exists(reference_image_path):
|
82
|
+
raise ValueError(f"Reference image not found: {reference_image_path}")
|
83
|
+
|
84
|
+
compare_images(test_image_path, reference_image_path)
|
85
|
+
|
86
|
+
except ValueError:
|
87
|
+
image = Image.open(test_image_path)
|
88
|
+
os.makedirs(REFERENCE_DIR_FAILURES, exist_ok=True)
|
89
|
+
image_name = os.path.join(REFERENCE_DIR_FAILURES, name)
|
90
|
+
image.save(image_name)
|
91
|
+
print(f"Image saved to {image_name}")
|
92
|
+
raise
|
@@ -222,7 +222,7 @@ class _TerminalWidget(QtWidgets.QPlainTextEdit):
|
|
222
222
|
Start ``Backend`` process and render Pyte output as text.
|
223
223
|
"""
|
224
224
|
|
225
|
-
def __init__(self, parent, numColumns, numLines, **kwargs):
|
225
|
+
def __init__(self, parent, numColumns=125, numLines=50, **kwargs):
|
226
226
|
super().__init__(parent)
|
227
227
|
|
228
228
|
# file descriptor to communicate with the subprocess
|
@@ -0,0 +1,197 @@
|
|
1
|
+
import os
|
2
|
+
import uuid
|
3
|
+
|
4
|
+
from bec_lib.endpoints import MessageEndpoints
|
5
|
+
from bec_lib.messages import ScanQueueMessage
|
6
|
+
from qtpy.QtCore import Property, Signal, Slot
|
7
|
+
from qtpy.QtGui import QDoubleValidator
|
8
|
+
from qtpy.QtWidgets import QDoubleSpinBox, QVBoxLayout, QWidget
|
9
|
+
|
10
|
+
from bec_widgets.utils import UILoader
|
11
|
+
from bec_widgets.utils.bec_connector import BECConnector
|
12
|
+
|
13
|
+
|
14
|
+
class DeviceBox(BECConnector, QWidget):
|
15
|
+
device_changed = Signal(str, str)
|
16
|
+
|
17
|
+
def __init__(self, parent=None, device=None, *args, **kwargs):
|
18
|
+
super().__init__(*args, **kwargs)
|
19
|
+
QWidget.__init__(self, parent=parent)
|
20
|
+
self.get_bec_shortcuts()
|
21
|
+
self._device = ""
|
22
|
+
self._limits = None
|
23
|
+
|
24
|
+
self.init_ui()
|
25
|
+
|
26
|
+
if device is not None:
|
27
|
+
self.device = device
|
28
|
+
self.init_device()
|
29
|
+
|
30
|
+
def init_ui(self):
|
31
|
+
self.device_changed.connect(self.on_device_change)
|
32
|
+
|
33
|
+
current_path = os.path.dirname(__file__)
|
34
|
+
self.ui = UILoader(self).loader(os.path.join(current_path, "device_box.ui"))
|
35
|
+
|
36
|
+
self.layout = QVBoxLayout(self)
|
37
|
+
self.layout.addWidget(self.ui)
|
38
|
+
self.layout.setSpacing(0)
|
39
|
+
self.layout.setContentsMargins(0, 0, 0, 0)
|
40
|
+
|
41
|
+
# fix the size of the device box
|
42
|
+
db = self.ui.device_box
|
43
|
+
db.setFixedHeight(234)
|
44
|
+
db.setFixedWidth(224)
|
45
|
+
|
46
|
+
self.ui.step_size.setStepType(QDoubleSpinBox.AdaptiveDecimalStepType)
|
47
|
+
self.ui.stop.clicked.connect(self.on_stop)
|
48
|
+
self.ui.tweak_right.clicked.connect(self.on_tweak_right)
|
49
|
+
self.ui.tweak_right.setToolTip("Tweak right")
|
50
|
+
self.ui.tweak_left.clicked.connect(self.on_tweak_left)
|
51
|
+
self.ui.tweak_left.setToolTip("Tweak left")
|
52
|
+
self.ui.setpoint.returnPressed.connect(self.on_setpoint_change)
|
53
|
+
|
54
|
+
self.setpoint_validator = QDoubleValidator()
|
55
|
+
self.ui.setpoint.setValidator(self.setpoint_validator)
|
56
|
+
self.ui.spinner_widget.start()
|
57
|
+
|
58
|
+
def init_device(self):
|
59
|
+
if self.device in self.dev:
|
60
|
+
data = self.dev[self.device].read()
|
61
|
+
self.on_device_readback({"signals": data}, {})
|
62
|
+
|
63
|
+
@Property(str)
|
64
|
+
def device(self):
|
65
|
+
return self._device
|
66
|
+
|
67
|
+
@device.setter
|
68
|
+
def device(self, value):
|
69
|
+
if not value or not isinstance(value, str):
|
70
|
+
return
|
71
|
+
old_device = self._device
|
72
|
+
self._device = value
|
73
|
+
self.device_changed.emit(old_device, value)
|
74
|
+
|
75
|
+
@Slot(str, str)
|
76
|
+
def on_device_change(self, old_device: str, new_device: str):
|
77
|
+
if new_device not in self.dev:
|
78
|
+
print(f"Device {new_device} not found in the device list")
|
79
|
+
return
|
80
|
+
print(f"Device changed from {old_device} to {new_device}")
|
81
|
+
self.init_device()
|
82
|
+
self.bec_dispatcher.disconnect_slot(
|
83
|
+
self.on_device_readback, MessageEndpoints.device_readback(old_device)
|
84
|
+
)
|
85
|
+
self.bec_dispatcher.connect_slot(
|
86
|
+
self.on_device_readback, MessageEndpoints.device_readback(new_device)
|
87
|
+
)
|
88
|
+
self.ui.device_box.setTitle(new_device)
|
89
|
+
self.ui.readback.setToolTip(f"{self.device} readback")
|
90
|
+
self.ui.setpoint.setToolTip(f"{self.device} setpoint")
|
91
|
+
self.ui.step_size.setToolTip(f"Step size for {new_device}")
|
92
|
+
|
93
|
+
precision = self.dev[new_device].precision
|
94
|
+
if precision is not None:
|
95
|
+
self.ui.step_size.setDecimals(precision)
|
96
|
+
self.ui.step_size.setValue(10**-precision * 10)
|
97
|
+
|
98
|
+
@Slot(dict, dict)
|
99
|
+
def on_device_readback(self, msg_content: dict, metadata: dict):
|
100
|
+
signals = msg_content.get("signals", {})
|
101
|
+
# pylint: disable=protected-access
|
102
|
+
hinted_signals = self.dev[self.device]._hints
|
103
|
+
precision = self.dev[self.device].precision
|
104
|
+
|
105
|
+
readback_val = None
|
106
|
+
setpoint_val = None
|
107
|
+
|
108
|
+
if len(hinted_signals) == 1:
|
109
|
+
signal = hinted_signals[0]
|
110
|
+
readback_val = signals.get(signal, {}).get("value")
|
111
|
+
|
112
|
+
if f"{self.device}_setpoint" in signals:
|
113
|
+
setpoint_val = signals.get(f"{self.device}_setpoint", {}).get("value")
|
114
|
+
|
115
|
+
if f"{self.device}_motor_is_moving" in signals:
|
116
|
+
is_moving = signals.get(f"{self.device}_motor_is_moving", {}).get("value")
|
117
|
+
if is_moving:
|
118
|
+
self.ui.spinner_widget.start()
|
119
|
+
self.ui.spinner_widget.setToolTip("Device is moving")
|
120
|
+
else:
|
121
|
+
self.ui.spinner_widget.stop()
|
122
|
+
self.ui.spinner_widget.setToolTip("Device is idle")
|
123
|
+
|
124
|
+
if readback_val is not None:
|
125
|
+
self.ui.readback.setText(f"{readback_val:.{precision}f}")
|
126
|
+
|
127
|
+
if setpoint_val is not None:
|
128
|
+
self.ui.setpoint.setText(f"{setpoint_val:.{precision}f}")
|
129
|
+
|
130
|
+
limits = self.dev[self.device].limits
|
131
|
+
self.update_limits(limits)
|
132
|
+
if limits is not None and readback_val is not None and limits[0] != limits[1]:
|
133
|
+
pos = (readback_val - limits[0]) / (limits[1] - limits[0])
|
134
|
+
self.ui.position_indicator.on_position_update(pos)
|
135
|
+
|
136
|
+
def update_limits(self, limits):
|
137
|
+
if limits == self._limits:
|
138
|
+
return
|
139
|
+
self._limits = limits
|
140
|
+
if limits is not None and limits[0] != limits[1]:
|
141
|
+
self.ui.position_indicator.setToolTip(f"Min: {limits[0]}, Max: {limits[1]}")
|
142
|
+
self.setpoint_validator.setRange(limits[0], limits[1])
|
143
|
+
else:
|
144
|
+
self.ui.position_indicator.setToolTip("No limits set")
|
145
|
+
self.setpoint_validator.setRange(float("-inf"), float("inf"))
|
146
|
+
|
147
|
+
@Slot()
|
148
|
+
def on_stop(self):
|
149
|
+
request_id = str(uuid.uuid4())
|
150
|
+
params = {
|
151
|
+
"device": self.device,
|
152
|
+
"rpc_id": request_id,
|
153
|
+
"func": "stop",
|
154
|
+
"args": [],
|
155
|
+
"kwargs": {},
|
156
|
+
}
|
157
|
+
msg = ScanQueueMessage(
|
158
|
+
scan_type="device_rpc",
|
159
|
+
parameter=params,
|
160
|
+
queue="emergency",
|
161
|
+
metadata={"RID": request_id, "response": False},
|
162
|
+
)
|
163
|
+
self.client.connector.send(MessageEndpoints.scan_queue_request(), msg)
|
164
|
+
|
165
|
+
@property
|
166
|
+
def step_size(self):
|
167
|
+
return self.ui.step_size.value()
|
168
|
+
|
169
|
+
@Slot()
|
170
|
+
def on_tweak_right(self):
|
171
|
+
self.dev[self.device].move(self.step_size, relative=True)
|
172
|
+
|
173
|
+
@Slot()
|
174
|
+
def on_tweak_left(self):
|
175
|
+
self.dev[self.device].move(-self.step_size, relative=True)
|
176
|
+
|
177
|
+
@Slot()
|
178
|
+
def on_setpoint_change(self):
|
179
|
+
self.ui.setpoint.clearFocus()
|
180
|
+
setpoint = self.ui.setpoint.text()
|
181
|
+
self.dev[self.device].move(float(setpoint), relative=False)
|
182
|
+
self.ui.tweak_left.setToolTip(f"Tweak left by {self.step_size}")
|
183
|
+
self.ui.tweak_right.setToolTip(f"Tweak right by {self.step_size}")
|
184
|
+
|
185
|
+
|
186
|
+
if __name__ == "__main__": # pragma: no cover
|
187
|
+
import sys
|
188
|
+
|
189
|
+
import qdarktheme
|
190
|
+
from qtpy.QtWidgets import QApplication
|
191
|
+
|
192
|
+
app = QApplication(sys.argv)
|
193
|
+
qdarktheme.setup_theme("light")
|
194
|
+
widget = DeviceBox(device="samx")
|
195
|
+
|
196
|
+
widget.show()
|
197
|
+
sys.exit(app.exec_())
|
@@ -0,0 +1 @@
|
|
1
|
+
{'files': ['device_box.py']}
|
@@ -0,0 +1,179 @@
|
|
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>251</width>
|
10
|
+
<height>289</height>
|
11
|
+
</rect>
|
12
|
+
</property>
|
13
|
+
<property name="minimumSize">
|
14
|
+
<size>
|
15
|
+
<width>0</width>
|
16
|
+
<height>192</height>
|
17
|
+
</size>
|
18
|
+
</property>
|
19
|
+
<property name="maximumSize">
|
20
|
+
<size>
|
21
|
+
<width>16777215</width>
|
22
|
+
<height>16777215</height>
|
23
|
+
</size>
|
24
|
+
</property>
|
25
|
+
<property name="windowTitle">
|
26
|
+
<string>Form</string>
|
27
|
+
</property>
|
28
|
+
<layout class="QVBoxLayout" name="verticalLayout">
|
29
|
+
<item>
|
30
|
+
<widget class="QGroupBox" name="device_box">
|
31
|
+
<property name="title">
|
32
|
+
<string>Device Name</string>
|
33
|
+
</property>
|
34
|
+
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0,0,0">
|
35
|
+
<property name="topMargin">
|
36
|
+
<number>0</number>
|
37
|
+
</property>
|
38
|
+
<item row="3" column="1">
|
39
|
+
<widget class="QDoubleSpinBox" name="step_size"/>
|
40
|
+
</item>
|
41
|
+
<item row="3" column="2">
|
42
|
+
<widget class="QToolButton" name="tweak_right">
|
43
|
+
<property name="minimumSize">
|
44
|
+
<size>
|
45
|
+
<width>50</width>
|
46
|
+
<height>50</height>
|
47
|
+
</size>
|
48
|
+
</property>
|
49
|
+
<property name="maximumSize">
|
50
|
+
<size>
|
51
|
+
<width>50</width>
|
52
|
+
<height>50</height>
|
53
|
+
</size>
|
54
|
+
</property>
|
55
|
+
<property name="text">
|
56
|
+
<string>...</string>
|
57
|
+
</property>
|
58
|
+
<property name="iconSize">
|
59
|
+
<size>
|
60
|
+
<width>30</width>
|
61
|
+
<height>30</height>
|
62
|
+
</size>
|
63
|
+
</property>
|
64
|
+
<property name="arrowType">
|
65
|
+
<enum>Qt::ArrowType::RightArrow</enum>
|
66
|
+
</property>
|
67
|
+
</widget>
|
68
|
+
</item>
|
69
|
+
<item row="2" column="0" colspan="3">
|
70
|
+
<widget class="QLineEdit" name="setpoint"/>
|
71
|
+
</item>
|
72
|
+
<item row="3" column="0">
|
73
|
+
<widget class="QToolButton" name="tweak_left">
|
74
|
+
<property name="minimumSize">
|
75
|
+
<size>
|
76
|
+
<width>50</width>
|
77
|
+
<height>50</height>
|
78
|
+
</size>
|
79
|
+
</property>
|
80
|
+
<property name="maximumSize">
|
81
|
+
<size>
|
82
|
+
<width>50</width>
|
83
|
+
<height>50</height>
|
84
|
+
</size>
|
85
|
+
</property>
|
86
|
+
<property name="text">
|
87
|
+
<string>...</string>
|
88
|
+
</property>
|
89
|
+
<property name="iconSize">
|
90
|
+
<size>
|
91
|
+
<width>30</width>
|
92
|
+
<height>30</height>
|
93
|
+
</size>
|
94
|
+
</property>
|
95
|
+
<property name="arrowType">
|
96
|
+
<enum>Qt::ArrowType::LeftArrow</enum>
|
97
|
+
</property>
|
98
|
+
</widget>
|
99
|
+
</item>
|
100
|
+
<item row="4" column="0" colspan="3">
|
101
|
+
<widget class="QPushButton" name="stop">
|
102
|
+
<property name="text">
|
103
|
+
<string>Stop</string>
|
104
|
+
</property>
|
105
|
+
</widget>
|
106
|
+
</item>
|
107
|
+
<item row="0" column="0" colspan="3">
|
108
|
+
<layout class="QVBoxLayout" name="verticalLayout_2">
|
109
|
+
<item>
|
110
|
+
<layout class="QHBoxLayout" name="horizontalLayout">
|
111
|
+
<item>
|
112
|
+
<spacer name="horizontalSpacer">
|
113
|
+
<property name="orientation">
|
114
|
+
<enum>Qt::Orientation::Horizontal</enum>
|
115
|
+
</property>
|
116
|
+
<property name="sizeType">
|
117
|
+
<enum>QSizePolicy::Policy::Expanding</enum>
|
118
|
+
</property>
|
119
|
+
<property name="sizeHint" stdset="0">
|
120
|
+
<size>
|
121
|
+
<width>40</width>
|
122
|
+
<height>20</height>
|
123
|
+
</size>
|
124
|
+
</property>
|
125
|
+
</spacer>
|
126
|
+
</item>
|
127
|
+
<item>
|
128
|
+
<widget class="SpinnerWidget" name="spinner_widget">
|
129
|
+
<property name="minimumSize">
|
130
|
+
<size>
|
131
|
+
<width>25</width>
|
132
|
+
<height>25</height>
|
133
|
+
</size>
|
134
|
+
</property>
|
135
|
+
<property name="maximumSize">
|
136
|
+
<size>
|
137
|
+
<width>25</width>
|
138
|
+
<height>25</height>
|
139
|
+
</size>
|
140
|
+
</property>
|
141
|
+
</widget>
|
142
|
+
</item>
|
143
|
+
</layout>
|
144
|
+
</item>
|
145
|
+
<item>
|
146
|
+
<widget class="PositionIndicator" name="position_indicator"/>
|
147
|
+
</item>
|
148
|
+
<item>
|
149
|
+
<widget class="QLabel" name="readback">
|
150
|
+
<property name="text">
|
151
|
+
<string>Position</string>
|
152
|
+
</property>
|
153
|
+
<property name="alignment">
|
154
|
+
<set>Qt::AlignmentFlag::AlignCenter</set>
|
155
|
+
</property>
|
156
|
+
</widget>
|
157
|
+
</item>
|
158
|
+
</layout>
|
159
|
+
</item>
|
160
|
+
</layout>
|
161
|
+
</widget>
|
162
|
+
</item>
|
163
|
+
</layout>
|
164
|
+
</widget>
|
165
|
+
<customwidgets>
|
166
|
+
<customwidget>
|
167
|
+
<class>SpinnerWidget</class>
|
168
|
+
<extends>QWidget</extends>
|
169
|
+
<header>spinner_widget</header>
|
170
|
+
</customwidget>
|
171
|
+
<customwidget>
|
172
|
+
<class>PositionIndicator</class>
|
173
|
+
<extends>QWidget</extends>
|
174
|
+
<header>position_indicator</header>
|
175
|
+
</customwidget>
|
176
|
+
</customwidgets>
|
177
|
+
<resources/>
|
178
|
+
<connections/>
|
179
|
+
</ui>
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Copyright (C) 2022 The Qt Company Ltd.
|
2
|
+
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
3
|
+
|
4
|
+
from qtpy.QtDesigner import QDesignerCustomWidgetInterface
|
5
|
+
from qtpy.QtGui import QIcon
|
6
|
+
|
7
|
+
from bec_widgets.widgets.device_box.device_box import DeviceBox
|
8
|
+
|
9
|
+
DOM_XML = """
|
10
|
+
<ui language='c++'>
|
11
|
+
<widget class='DeviceBox' name='device_box'>
|
12
|
+
</widget>
|
13
|
+
</ui>
|
14
|
+
"""
|
15
|
+
|
16
|
+
|
17
|
+
class DeviceBoxPlugin(QDesignerCustomWidgetInterface): # pragma: no cover
|
18
|
+
def __init__(self):
|
19
|
+
super().__init__()
|
20
|
+
self._form_editor = None
|
21
|
+
|
22
|
+
def createWidget(self, parent):
|
23
|
+
t = DeviceBox(parent)
|
24
|
+
return t
|
25
|
+
|
26
|
+
def domXml(self):
|
27
|
+
return DOM_XML
|
28
|
+
|
29
|
+
def group(self):
|
30
|
+
return "Device Control"
|
31
|
+
|
32
|
+
def icon(self):
|
33
|
+
return QIcon()
|
34
|
+
|
35
|
+
def includeFile(self):
|
36
|
+
return "device_box"
|
37
|
+
|
38
|
+
def initialize(self, form_editor):
|
39
|
+
self._form_editor = form_editor
|
40
|
+
|
41
|
+
def isContainer(self):
|
42
|
+
return False
|
43
|
+
|
44
|
+
def isInitialized(self):
|
45
|
+
return self._form_editor is not None
|
46
|
+
|
47
|
+
def name(self):
|
48
|
+
return "DeviceBox"
|
49
|
+
|
50
|
+
def toolTip(self):
|
51
|
+
return "A widget for controlling a single positioner. "
|
52
|
+
|
53
|
+
def whatsThis(self):
|
54
|
+
return self.toolTip()
|
@@ -0,0 +1,15 @@
|
|
1
|
+
def main(): # pragma: no cover
|
2
|
+
from qtpy import PYSIDE6
|
3
|
+
|
4
|
+
if not PYSIDE6:
|
5
|
+
print("PYSIDE6 is not available in the environment. Cannot patch designer.")
|
6
|
+
return
|
7
|
+
from PySide6.QtDesigner import QPyDesignerCustomWidgetCollection
|
8
|
+
|
9
|
+
from bec_widgets.widgets.device_box.device_box_plugin import DeviceBoxPlugin
|
10
|
+
|
11
|
+
QPyDesignerCustomWidgetCollection.addCustomWidget(DeviceBoxPlugin())
|
12
|
+
|
13
|
+
|
14
|
+
if __name__ == "__main__": # pragma: no cover
|
15
|
+
main()
|