From 9f33a5c81f767824404e262adb8d82eae1a16f98 Mon Sep 17 00:00:00 2001 From: wyzula-jan Date: Tue, 2 Jul 2024 20:00:35 +0200 Subject: [PATCH] feat(motor_map_widget): complete toolbar --- .../figure/plots/motor_map/motor_map.py | 2 +- .../widgets/motor_map/assets/history.svg | 4 + .../widgets/motor_map/motor_map_settings.py | 82 +++++++++++++++++ .../widgets/motor_map/motor_map_settings.ui | 91 +++++++++++++++++++ .../widgets/motor_map/motor_map_toolbar.py | 28 ++++-- .../widgets/motor_map/motor_map_widget.py | 15 ++- 6 files changed, 207 insertions(+), 15 deletions(-) create mode 100644 bec_widgets/widgets/motor_map/assets/history.svg create mode 100644 bec_widgets/widgets/motor_map/motor_map_settings.py create mode 100644 bec_widgets/widgets/motor_map/motor_map_settings.ui diff --git a/bec_widgets/widgets/figure/plots/motor_map/motor_map.py b/bec_widgets/widgets/figure/plots/motor_map/motor_map.py index 9782153d..d906af87 100644 --- a/bec_widgets/widgets/figure/plots/motor_map/motor_map.py +++ b/bec_widgets/widgets/figure/plots/motor_map/motor_map.py @@ -24,7 +24,7 @@ class MotorMapConfig(SubplotConfig): (255, 255, 255, 255), description="The color of the last point of current position." ) scatter_size: Optional[int] = Field(5, description="Size of the scatter points.") - max_points: Optional[int] = Field(1000, description="Maximum number of points to display.") + max_points: Optional[int] = Field(5000, description="Maximum number of points to display.") num_dim_points: Optional[int] = Field( 100, description="Number of points to dim before the color remains same for older recorded position.", diff --git a/bec_widgets/widgets/motor_map/assets/history.svg b/bec_widgets/widgets/motor_map/assets/history.svg new file mode 100644 index 00000000..06a68394 --- /dev/null +++ b/bec_widgets/widgets/motor_map/assets/history.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/bec_widgets/widgets/motor_map/motor_map_settings.py b/bec_widgets/widgets/motor_map/motor_map_settings.py new file mode 100644 index 00000000..75ddb30f --- /dev/null +++ b/bec_widgets/widgets/motor_map/motor_map_settings.py @@ -0,0 +1,82 @@ +import os + +from qtpy.QtCore import Slot +from qtpy.QtWidgets import QDialog, QDialogButtonBox, QLabel, QVBoxLayout, QWidget + +from bec_widgets.utils import UILoader +from bec_widgets.utils.widget_io import WidgetIO +from bec_widgets.widgets.buttons.color_button import ColorButton + + +class MotorMapSettings(QWidget): + def __init__(self, parent=None, target_widget: QWidget = None, *args, **kwargs): + super().__init__(parent, *args, **kwargs) + current_path = os.path.dirname(__file__) + self.ui = UILoader().load_ui(os.path.join(current_path, "motor_map_settings.ui"), self) + + self.target_widget = target_widget + + self.layout = QVBoxLayout(self) + self.layout.addWidget(self.ui) + + self._add_color_button() + + def _add_color_button(self): + label = QLabel("Color") + self.ui.color = ColorButton() + self.ui.gridLayout.addWidget(label, 5, 0) + self.ui.gridLayout.addWidget(self.ui.color, 5, 1) + + @Slot(dict) + def display_current_settings(self, config: dict): + WidgetIO.set_value(self.ui.max_points, config["max_points"]) + WidgetIO.set_value(self.ui.trace_dim, config["num_dim_points"]) + WidgetIO.set_value(self.ui.precision, config["precision"]) + WidgetIO.set_value(self.ui.scatter_size, config["scatter_size"]) + background_intensity = int((config["background_value"] / 255) * 100) + WidgetIO.set_value(self.ui.background_value, background_intensity) + color = config["color"] + self.ui.color.setColor(color) + + @Slot() + def accept_changes(self): + max_points = WidgetIO.get_value(self.ui.max_points) + num_dim_points = WidgetIO.get_value(self.ui.trace_dim) + precision = WidgetIO.get_value(self.ui.precision) + scatter_size = WidgetIO.get_value(self.ui.scatter_size) + background_intensity = int(WidgetIO.get_value(self.ui.background_value) * 0.01 * 255) + color = self.ui.color.color().toTuple() + + if self.target_widget is not None: + self.target_widget.set_max_points(max_points) + self.target_widget.set_num_dim_points(num_dim_points) + self.target_widget.set_precision(precision) + self.target_widget.set_scatter_size(scatter_size) + self.target_widget.set_background_value(background_intensity) + self.target_widget.set_color(color) + + +class MotorMapDialog(QDialog): + def __init__(self, parent=None, target_widget: QWidget = None, *args, **kwargs): + super().__init__(parent, *args, **kwargs) + + self.setModal(False) + + self.setWindowTitle("Motor Map Settings") + + self.target_widget = target_widget + self.widget = MotorMapSettings(target_widget=self.target_widget) + self.widget.display_current_settings(self.target_widget._config_dict) + self.button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) + + self.button_box.accepted.connect(self.accept) + self.button_box.rejected.connect(self.reject) + + self.layout = QVBoxLayout(self) + self.layout.addWidget(self.widget) + self.layout.addWidget(self.button_box) + + @Slot() + def accept(self): + self.widget.accept_changes() + super().accept() diff --git a/bec_widgets/widgets/motor_map/motor_map_settings.ui b/bec_widgets/widgets/motor_map/motor_map_settings.ui new file mode 100644 index 00000000..0bcc769f --- /dev/null +++ b/bec_widgets/widgets/motor_map/motor_map_settings.ui @@ -0,0 +1,91 @@ + + + Form + + + + 0 + 0 + 237 + 184 + + + + Form + + + + + + Max Points + + + + + + + 10000 + + + + + + + Trace Dim + + + + + + + 1000 + + + + + + + Precision + + + + + + + 15 + + + + + + + Scatter Size + + + + + + + 20 + + + + + + + Background Intensity + + + + + + + 100 + + + + + + + + diff --git a/bec_widgets/widgets/motor_map/motor_map_toolbar.py b/bec_widgets/widgets/motor_map/motor_map_toolbar.py index 346c979d..2fd7f4be 100644 --- a/bec_widgets/widgets/motor_map/motor_map_toolbar.py +++ b/bec_widgets/widgets/motor_map/motor_map_toolbar.py @@ -8,16 +8,6 @@ from bec_widgets.widgets.device_inputs import DeviceComboBox from bec_widgets.widgets.toolbar.toolbar import ToolBarAction -class SettingsAction(ToolBarAction): - def add_to_toolbar(self, toolbar, target): - current_path = os.path.dirname(__file__) - icon = QIcon() - icon.addFile(os.path.join(current_path, "assets", "settings.svg"), size=QSize(20, 20)) - action = QAction(icon, "Config", target) - action.triggered.connect(lambda: print(target.config_dict)) - toolbar.addAction(action) - - class DeviceSelectionAction(ToolBarAction): def __init__(self, label: str): self.label = label @@ -46,3 +36,21 @@ class ConnectAction(ToolBarAction): icon.addFile(os.path.join(current_path, "assets", "connection.svg"), size=QSize(20, 20)) self.action = QAction(icon, "Connect Motors", target) toolbar.addAction(self.action) + + +class ResetHistoryAction(ToolBarAction): + def add_to_toolbar(self, toolbar, target): + current_path = os.path.dirname(__file__) + icon = QIcon() + icon.addFile(os.path.join(current_path, "assets", "history.svg"), size=QSize(20, 20)) + self.action = QAction(icon, "Reset History", target) + toolbar.addAction(self.action) + + +class SettingsAction(ToolBarAction): + def add_to_toolbar(self, toolbar, target): + current_path = os.path.dirname(__file__) + icon = QIcon() + icon.addFile(os.path.join(current_path, "assets", "settings.svg"), size=QSize(20, 20)) + self.action = QAction(icon, "Config", target) + toolbar.addAction(self.action) diff --git a/bec_widgets/widgets/motor_map/motor_map_widget.py b/bec_widgets/widgets/motor_map/motor_map_widget.py index 73c11761..1af15507 100644 --- a/bec_widgets/widgets/motor_map/motor_map_widget.py +++ b/bec_widgets/widgets/motor_map/motor_map_widget.py @@ -1,15 +1,15 @@ from __future__ import annotations -import os - from qtpy.QtWidgets import QVBoxLayout, QWidget -from bec_widgets.utils import BECConnector, UILoader +from bec_widgets.utils import BECConnector from bec_widgets.widgets.figure import BECFigure from bec_widgets.widgets.figure.plots.motor_map.motor_map import MotorMapConfig +from bec_widgets.widgets.motor_map.motor_map_settings import MotorMapDialog from bec_widgets.widgets.motor_map.motor_map_toolbar import ( ConnectAction, DeviceSelectionAction, + ResetHistoryAction, SettingsAction, ) from bec_widgets.widgets.toolbar import ModularToolBar @@ -52,6 +52,7 @@ class BECMotorMapWidget(BECConnector, QWidget): "motor_x": DeviceSelectionAction("Motor X:"), "motor_y": DeviceSelectionAction("Motor Y:"), "connect": ConnectAction(), + "history": ResetHistoryAction(), "config": SettingsAction(), }, target_widget=self, @@ -69,6 +70,8 @@ class BECMotorMapWidget(BECConnector, QWidget): def _hook_actions(self): self.toolbar.widgets["connect"].action.triggered.connect(self._action_motors) + self.toolbar.widgets["config"].action.triggered.connect(self.show_settings) + self.toolbar.widgets["history"].action.triggered.connect(self.reset_history) def _action_motors(self): toolbar_x = self.toolbar.widgets["motor_x"].device_combobox @@ -79,6 +82,10 @@ class BECMotorMapWidget(BECConnector, QWidget): toolbar_x.setStyleSheet("QComboBox {{ background-color: " "; }}") toolbar_y.setStyleSheet("QComboBox {{ background-color: " "; }}") + def show_settings(self) -> None: + dialog = MotorMapDialog(self, target_widget=self) + dialog.exec() + ################################### # User Access Methods from MotorMap ################################### @@ -176,7 +183,7 @@ class BECMotorMapWidget(BECConnector, QWidget): if __name__ == "__main__": import sys - from PySide6.QtWidgets import QApplication, QDialog + from PySide6.QtWidgets import QApplication app = QApplication(sys.argv) widget = BECMotorMapWidget()