diff --git a/src/aare/gui/main_window.py b/src/aare/gui/main_window.py index 6f955dd4..0dbddc3a 100644 --- a/src/aare/gui/main_window.py +++ b/src/aare/gui/main_window.py @@ -63,7 +63,7 @@ from aare.gui.panels.tell_sample_panel import TellSamplePanel from aare.gui.scan_logic.raster_grid_manager import RasterGridManager from aare.gui.scan_logic.rotation_scan_manager import RotationScanManager from aare.gui.scan_logic.sample_mount_logic import SampleMountLogic -from aare.gui.styles import THEME_ORIGINAL, THEME_PORTRAIT, build_app_stylesheet +from aare.gui.styles import BACKGROUND, THEME_ORIGINAL, THEME_PORTRAIT, build_app_stylesheet # Threads from aare.gui.threads.axis_video_thread import VideoThread @@ -182,7 +182,7 @@ class MainWindow(QMainWindow): ) raise - self.setStyleSheet("background-color: rgb(216, 228, 253);") + self.setStyleSheet(f"background-color: {BACKGROUND};") root_widget = QWidget(parent=self) root_widget.setObjectName("mainContentRoot") diff --git a/src/aare/gui/models/bookmark.py b/src/aare/gui/models/bookmark.py index e0370467..54fc5f60 100644 --- a/src/aare/gui/models/bookmark.py +++ b/src/aare/gui/models/bookmark.py @@ -3,6 +3,8 @@ from typing import Literal from aarecommon.math.coordinate import SmargonCoordinate from PySide6.QtGui import QColor +from aare.gui.styles import BOOKMARK_COLORS, qcolor + class SmargonBookmark: coord: SmargonCoordinate @@ -10,13 +12,7 @@ class SmargonBookmark: def qt_color(self) -> QColor: """Convert the color property to a QColor.""" - color_map = { - "red": QColor("red"), - "green": QColor("green"), - "blue": QColor("blue"), - "indigo": QColor("indigo"), - "lime": QColor("lime"), - } + color_map = {name: qcolor(hex_str) for name, hex_str in BOOKMARK_COLORS.items()} return color_map[self.color] # Map the color string to QColor diff --git a/src/aare/gui/models/sample_queue_model.py b/src/aare/gui/models/sample_queue_model.py index f4b19e1a..e6d6844e 100644 --- a/src/aare/gui/models/sample_queue_model.py +++ b/src/aare/gui/models/sample_queue_model.py @@ -1,9 +1,10 @@ from aarecommon.config.logger import setup_logger from aarecommon.models.models import SampleShortInfo, SampleShortInfoList from PySide6.QtCore import QAbstractTableModel, Qt -from PySide6.QtGui import QBrush, QColor +from PySide6.QtGui import QBrush from aare.gui.constants import LOGGER_NAME +from aare.gui.styles import SAMPLE_ROW_ACTIVE_BG, SAMPLE_ROW_QUEUED_BG, WHITE, qcolor logger = setup_logger(LOGGER_NAME) @@ -60,10 +61,10 @@ class SampleQueueSpreadsheet(QAbstractTableModel): elif role == Qt.ItemDataRole.BackgroundRole: if index.row() == 0: if self._running: - return QBrush(QColor(255, 102, 0)) + return QBrush(qcolor(SAMPLE_ROW_ACTIVE_BG)) else: - return QBrush(QColor(114, 159, 207)) - return QBrush(QColor(255, 255, 255)) + return QBrush(qcolor(SAMPLE_ROW_QUEUED_BG)) + return QBrush(qcolor(WHITE)) return None def headerData(self, section, orientation, role=None): diff --git a/src/aare/gui/models/user_sample_model.py b/src/aare/gui/models/user_sample_model.py index 14aee66b..b57b3f37 100644 --- a/src/aare/gui/models/user_sample_model.py +++ b/src/aare/gui/models/user_sample_model.py @@ -3,9 +3,10 @@ import re from aarecommon.config.logger import setup_logger from aarecommon.models.models import SampleShortInfo, SampleShortInfoList from PySide6.QtCore import QAbstractTableModel, QMimeData, Qt -from PySide6.QtGui import QBrush, QColor +from PySide6.QtGui import QBrush from aare.gui.constants import LOGGER_NAME +from aare.gui.styles import SAMPLE_ROW_HIGHLIGHT_BG, SAMPLE_ROW_QUEUED_BG, WHITE, qcolor logger = setup_logger(LOGGER_NAME) @@ -94,10 +95,10 @@ class UserSampleSpreadsheet(QAbstractTableModel): return Qt.AlignmentFlag.AlignCenter elif role == Qt.ItemDataRole.BackgroundRole: if self._sorted_samples[index.row()].db_id == self.current_sample: - return QBrush(QColor(114, 159, 207)) # darker blue + return QBrush(qcolor(SAMPLE_ROW_QUEUED_BG)) if self._sorted_samples[index.row()].puck_name == self.current_puck: - return QBrush(QColor(216, 228, 253)) # light blue - return QBrush(QColor(255, 255, 255)) # White + return QBrush(qcolor(SAMPLE_ROW_HIGHLIGHT_BG)) + return QBrush(qcolor(WHITE)) return None # For other roles, return None def headerData(self, section, orientation, role=None): diff --git a/src/aare/gui/panels/abr_tweak_panel.py b/src/aare/gui/panels/abr_tweak_panel.py index 4d70f17a..f9cd172d 100644 --- a/src/aare/gui/panels/abr_tweak_panel.py +++ b/src/aare/gui/panels/abr_tweak_panel.py @@ -4,6 +4,7 @@ from PySide6.QtCore import Signal, Slot from PySide6.QtGui import Qt from PySide6.QtWidgets import QGridLayout, QLabel, QPushButton, QWidget +from aare.gui.styles import ALERT_TEXT, DEFAULT_TEXT from aare.gui.widgets.button_with_payload import ButtonWithPayload from aare.gui.widgets.number_line_edit import NumberLineEdit from aare.gui.widgets.title_label import TitleLabel @@ -133,17 +134,17 @@ class AbrTweakWidget(QWidget): def update_daq_status(self, s: DAQStatusModel): self._abr_buttons.gmx_label.setText(f"{s.geom.aerotech_meas.x:.3f}") if abs(s.geom.aerotech.x) >= 0.001: - self._abr_buttons.gmx_label.setStyleSheet("color: rgb(255, 0, 0);") + self._abr_buttons.gmx_label.setStyleSheet(f"color: {ALERT_TEXT};") else: - self._abr_buttons.gmx_label.setStyleSheet("color: rgb(0, 0, 0);") + self._abr_buttons.gmx_label.setStyleSheet(f"color: {DEFAULT_TEXT};") self._abr_buttons.gmy_label.setText(f"{s.geom.aerotech_meas.y:.3f}") if abs(s.geom.aerotech.y) >= 0.001: - self._abr_buttons.gmy_label.setStyleSheet("color: rgb(255, 0, 0);") + self._abr_buttons.gmy_label.setStyleSheet(f"color: {ALERT_TEXT};") else: - self._abr_buttons.gmy_label.setStyleSheet("color: rgb(0, 0, 0);") + self._abr_buttons.gmy_label.setStyleSheet(f"color: {DEFAULT_TEXT};") self._abr_buttons.gmz_label.setText(f"{s.geom.aerotech_meas.z:.3f}") if abs(s.geom.aerotech.z) >= 0.001: - self._abr_buttons.gmz_label.setStyleSheet("color: rgb(255, 0, 0);") + self._abr_buttons.gmz_label.setStyleSheet(f"color: {ALERT_TEXT};") else: - self._abr_buttons.gmz_label.setStyleSheet("color: rgb(0, 0, 0);") + self._abr_buttons.gmz_label.setStyleSheet(f"color: {DEFAULT_TEXT};") diff --git a/src/aare/gui/panels/automation_panel.py b/src/aare/gui/panels/automation_panel.py index e9edb4c9..3a9fa166 100644 --- a/src/aare/gui/panels/automation_panel.py +++ b/src/aare/gui/panels/automation_panel.py @@ -10,6 +10,28 @@ from PySide6.QtCore import QTimer, Slot from PySide6.QtWidgets import QLabel, QVBoxLayout, QWidget from aare.gui.constants import LOGGER_NAME +from aare.gui.styles import ( + AUTOMATION_HINT_TEXT, + AUTOMATION_TITLE_TEXT, + CARD_BORDER, + FAINT_TEXT, + MUTED_TEXT, + STEP_ACTIVE_BG, + STEP_ACTIVE_BORDER, + STEP_ACTIVE_TEXT, + STEP_DONE_BG, + STEP_DONE_BORDER, + STEP_DONE_TEXT, + STEP_FAILED_BG, + STEP_FAILED_BORDER, + STEP_FAILED_TEXT, + STEP_IDLE_BG, + STEP_IDLE_BORDER, + STEP_PAUSED_BG, + STEP_PAUSED_BORDER, + STEP_PAUSED_TEXT, + SURFACE, +) logger = setup_logger(LOGGER_NAME) @@ -40,14 +62,14 @@ class AutomationProgressWidget(QWidget): self._title_label = QLabel("Automation progress") self._title_label.setStyleSheet( - "font-size: 16px; font-weight: 700; color: #1F2937; margin-bottom: 2px;" + f"font-size: 16px; font-weight: 700; color: {AUTOMATION_TITLE_TEXT}; margin-bottom: 2px;" ) layout.addWidget(self._title_label) self._stats_label = QLabel() self._stats_label.setStyleSheet( - "color: #374151; font-size: 13px; " - "background-color: #F8FAFC; border: 1px solid #E2E8F0; " + f"color: {AUTOMATION_HINT_TEXT}; font-size: 13px; " + f"background-color: {SURFACE}; border: 1px solid {CARD_BORDER}; " "border-radius: 8px; padding: 10px;" ) self._stats_label.setWordWrap(True) @@ -122,25 +144,34 @@ class AutomationProgressWidget(QWidget): ) if status == StepStatus.SUCCESS: - return base + " background-color: #ECFDF3; color: #166534; border-color: #A7F3D0;" + return ( + base + + f" background-color: {STEP_DONE_BG}; color: {STEP_DONE_TEXT}; border-color: {STEP_DONE_BORDER};" + ) if status == StepStatus.RUNNING: return ( base - + " background-color: #EFF6FF; color: #1D4ED8; font-weight: 700; border-color: #BFDBFE;" + + f" background-color: {STEP_ACTIVE_BG}; color: {STEP_ACTIVE_TEXT}; font-weight: 700; border-color: {STEP_ACTIVE_BORDER};" ) if status == StepStatus.FAILED: return ( base - + " background-color: #FEF2F2; color: #B91C1C; font-weight: 700; border-color: #FECACA;" + + f" background-color: {STEP_FAILED_BG}; color: {STEP_FAILED_TEXT}; font-weight: 700; border-color: {STEP_FAILED_BORDER};" ) if status == StepStatus.PAUSED: return ( base - + " background-color: #FFF7ED; color: #C2410C; font-weight: 700; border-color: #FED7AA;" + + f" background-color: {STEP_PAUSED_BG}; color: {STEP_PAUSED_TEXT}; font-weight: 700; border-color: {STEP_PAUSED_BORDER};" ) if status == StepStatus.SKIPPED: - return base + " background-color: #F8FAFC; color: #475569; border-color: #E2E8F0;" - return base + " background-color: #F8FAFC; color: #64748B; border-color: #E2E8F0;" + return ( + base + + f" background-color: {STEP_IDLE_BG}; color: {MUTED_TEXT}; border-color: {STEP_IDLE_BORDER};" + ) + return ( + base + + f" background-color: {STEP_IDLE_BG}; color: {FAINT_TEXT}; border-color: {STEP_IDLE_BORDER};" + ) @staticmethod def _format_duration(seconds: float | None) -> str: diff --git a/src/aare/gui/panels/beamline_controls.py b/src/aare/gui/panels/beamline_controls.py index 2b7a7dad..771c9845 100644 --- a/src/aare/gui/panels/beamline_controls.py +++ b/src/aare/gui/panels/beamline_controls.py @@ -18,6 +18,7 @@ class BeamlineControls(QFrame): def __init__(self, parent=None, staff: bool = True): super().__init__(parent) + self.setObjectName("beamlineControls") self.setFixedWidth(self.set_width) self.setFrameShape(QFrame.Shape.StyledPanel) self.setFrameShadow(QFrame.Shadow.Raised) diff --git a/src/aare/gui/panels/beamline_recovery_panel.py b/src/aare/gui/panels/beamline_recovery_panel.py index 882f021f..f1d1d038 100644 --- a/src/aare/gui/panels/beamline_recovery_panel.py +++ b/src/aare/gui/panels/beamline_recovery_panel.py @@ -16,6 +16,19 @@ from PySide6.QtWidgets import ( ) from aare.gui.constants import LOGGER_NAME +from aare.gui.styles import ( + BAD_CARD_BORDER, + CHIP_BAD_BG, + CHIP_BAD_TEXT, + CHIP_INFO_TEXT, + CHIP_WARN_BG, + CHIP_WARN_TEXT, + INFO_CARD_BG, + INFO_CARD_BORDER, + PENDING_CARD_BG, + PENDING_CARD_BORDER, + WARN_CARD_BORDER, +) from aare.gui.threads.daq_worker import DAQWorker logger = setup_logger(LOGGER_NAME) @@ -37,9 +50,9 @@ class RecoveryPanel(QWidget): self._warning_primary.setWordWrap(True) self._warning_primary.setStyleSheet( "QLabel {" - " background: #fff3cd;" - " color: #7a4b00;" - " border: 1px solid #f0c36d;" + f" background: {CHIP_WARN_BG};" + f" color: {CHIP_WARN_TEXT};" + f" border: 1px solid {WARN_CARD_BORDER};" " padding: 10px;" " font-weight: 600;" "}" @@ -53,9 +66,9 @@ class RecoveryPanel(QWidget): self._warning_secondary.setWordWrap(True) self._warning_secondary.setStyleSheet( "QLabel {" - " background: #fdeaea;" - " color: #8b1e1e;" - " border: 1px solid #e6a8a8;" + f" background: {CHIP_BAD_BG};" + f" color: {CHIP_BAD_TEXT};" + f" border: 1px solid {BAD_CARD_BORDER};" " padding: 10px;" " font-weight: 600;" "}" @@ -66,9 +79,9 @@ class RecoveryPanel(QWidget): self._last_action.setWordWrap(True) self._last_action.setStyleSheet( "QLabel {" - " background: #eef6ff;" - " color: #12406a;" - " border: 1px solid #a8c7e6;" + f" background: {INFO_CARD_BG};" + f" color: {CHIP_INFO_TEXT};" + f" border: 1px solid {INFO_CARD_BORDER};" " padding: 10px;" " font-weight: 600;" "}" @@ -78,8 +91,8 @@ class RecoveryPanel(QWidget): self._take_over_btn = QPushButton("Take over beamline", self) self._take_over_btn.setStyleSheet( "QPushButton {" - " background: #fff7db;" - " border: 1px solid #e7cb73;" + f" background: {PENDING_CARD_BG};" + f" border: 1px solid {PENDING_CARD_BORDER};" " padding: 10px;" " font-weight: 600;" "}" @@ -90,8 +103,8 @@ class RecoveryPanel(QWidget): self._free_beamline_btn = QPushButton("Free beamline", self) self._free_beamline_btn.setStyleSheet( "QPushButton {" - " background: #fff7db;" - " border: 1px solid #e7cb73;" + f" background: {PENDING_CARD_BG};" + f" border: 1px solid {PENDING_CARD_BORDER};" " padding: 10px;" " font-weight: 600;" "}" @@ -102,9 +115,9 @@ class RecoveryPanel(QWidget): self._recover_beamline_btn = QPushButton("Recover beamline", self) self._recover_beamline_btn.setStyleSheet( "QPushButton {" - " background: #fdeaea;" - " color: #8b1e1e;" - " border: 1px solid #e6a8a8;" + f" background: {CHIP_BAD_BG};" + f" color: {CHIP_BAD_TEXT};" + f" border: 1px solid {BAD_CARD_BORDER};" " padding: 10px;" " font-weight: 700;" "}" @@ -115,9 +128,9 @@ class RecoveryPanel(QWidget): self._recovery_unmount_btn = QPushButton("Unmount sample (recovery)", self) self._recovery_unmount_btn.setStyleSheet( "QPushButton {" - " background: #fdeaea;" - " color: #8b1e1e;" - " border: 1px solid #e6a8a8;" + f" background: {CHIP_BAD_BG};" + f" color: {CHIP_BAD_TEXT};" + f" border: 1px solid {BAD_CARD_BORDER};" " padding: 10px;" " font-weight: 700;" "}" @@ -128,9 +141,9 @@ class RecoveryPanel(QWidget): self._resync_sample_btn = QPushButton("Resync sample from TELL", self) self._resync_sample_btn.setStyleSheet( "QPushButton {" - " background: #eef6ff;" - " color: #12406a;" - " border: 1px solid #a8c7e6;" + f" background: {INFO_CARD_BG};" + f" color: {CHIP_INFO_TEXT};" + f" border: 1px solid {INFO_CARD_BORDER};" " padding: 10px;" " font-weight: 600;" "}" diff --git a/src/aare/gui/panels/beamline_state_panel.py b/src/aare/gui/panels/beamline_state_panel.py index 2fb895ed..c8da2279 100644 --- a/src/aare/gui/panels/beamline_state_panel.py +++ b/src/aare/gui/panels/beamline_state_panel.py @@ -5,6 +5,8 @@ from PySide6.QtCore import Qt, QTimer, Signal, Slot from PySide6.QtGui import QCursor, QFont, QFontMetrics from PySide6.QtWidgets import QFrame, QHBoxLayout, QLabel, QMenu, QPushButton, QSizePolicy, QToolTip +from aare.gui.styles import STATE_AVAILABLE, STATE_MSG_ERROR, STATE_MSG_INFO, STATE_UNAVAILABLE + # Shortcut transitions from the "Available transitions" menu in # widgets/status_bar.py show_state_menu — these come ON TOP of the one-hop # routes between states (_GRAPH), e.g. Manual sample exchange -> Sample @@ -138,8 +140,8 @@ class BeamlineStatePanel(QFrame): self._hover_hint_timer.setInterval(3000) self._hover_hint_timer.timeout.connect(self._show_hover_hint) - self._available_color = "rgb(237, 137, 54)" - self._unavailable_color = "rgb(140, 150, 165)" + self._available_color = STATE_AVAILABLE + self._unavailable_color = STATE_UNAVAILABLE layout = QHBoxLayout(self) layout.setContentsMargins(10, 2, 10, 2) @@ -152,7 +154,7 @@ class BeamlineStatePanel(QFrame): if index: separator = QLabel("–", self) separator.setStyleSheet( - "color: rgb(140, 150, 165); background: transparent; border: none; font-size: 18px;" + f"color: {STATE_UNAVAILABLE}; background: transparent; border: none; font-size: 18px;" ) layout.addWidget(separator) button = HoverableButton(label, self) @@ -308,9 +310,7 @@ class BeamlineStatePanel(QFrame): # No backgrounds, no rounded corners. if is_current or is_pending: color = ( - "rgb(200, 30, 30)" - if state == BeamlineStateEnum.Maintenance - else "rgb(0, 92, 170)" + STATE_MSG_ERROR if state == BeamlineStateEnum.Maintenance else STATE_MSG_INFO ) bold = True elif is_available: diff --git a/src/aare/gui/panels/data_collection_settings.py b/src/aare/gui/panels/data_collection_settings.py index c8cad827..df75e340 100644 --- a/src/aare/gui/panels/data_collection_settings.py +++ b/src/aare/gui/panels/data_collection_settings.py @@ -11,6 +11,7 @@ from aare.gui.panels.raster_data_collection import RasterDataCollectionPanel from aare.gui.panels.rotation_data_collection import RotationDataCollectionPanel from aare.gui.panels.smart_rotation_panel import SimpleRotationSettingsPanel from aare.gui.scan_logic.raster_grid_manager import RasterGridManager +from aare.gui.styles import ABORT_TEXT from aare.gui.widgets.title_label import TitleLabel, tighten_column @@ -27,6 +28,7 @@ class DataCollectionSettings(QFrame): parent=None, ): super().__init__(parent) + self.setObjectName("dataCollectionSettings") self.setFixedWidth(self.set_width) self.setFrameShape(QFrame.Shape.StyledPanel) self.setFrameShadow(QFrame.Shadow.Raised) @@ -66,7 +68,7 @@ class DataCollectionSettings(QFrame): v_layout.addWidget(exp_config) abort_button = QPushButton("Abort measurement", parent=self) - abort_button.setStyleSheet("color: rgb(164, 0, 0);") + abort_button.setStyleSheet(f"color: {ABORT_TEXT};") abort_button.clicked.connect(self.cancel_button_clicked) v_layout.addWidget(abort_button) # Stretch after the button: abort sits snug under the tabs instead of diff --git a/src/aare/gui/panels/developer_help_dialog.py b/src/aare/gui/panels/developer_help_dialog.py index ef1fd449..fb818a24 100644 --- a/src/aare/gui/panels/developer_help_dialog.py +++ b/src/aare/gui/panels/developer_help_dialog.py @@ -31,6 +31,14 @@ from PySide6.QtWidgets import ( from aare.gui.constants import LOGGER_NAME from aare.gui.log import QtLogEmitter, QtLogHandler +from aare.gui.styles import ( + PANEL_BG_FAINT, + PANEL_BG_SOFT, + PANEL_BORDER, + PANEL_BORDER_DARK, + PANEL_BORDER_LIGHT, + WHITE, +) from aare.gui.threads.daq_worker import DAQWorker logger = setup_logger(LOGGER_NAME) @@ -62,8 +70,8 @@ class DeveloperHelpDialog(QDialog): self._banner.setTextInteractionFlags(Qt.TextInteractionFlag.TextSelectableByMouse) self._banner.setStyleSheet( "QLabel {" - " background: #f6f6f6;" - " border: 1px solid #d0d0d0;" + f" background: {PANEL_BG_SOFT};" + f" border: 1px solid {PANEL_BORDER};" " border-radius: 6px;" " padding: 6px 8px;" "}" @@ -83,8 +91,8 @@ class DeveloperHelpDialog(QDialog): self._filter.setMinimumHeight(28) self._filter.setStyleSheet( "QLineEdit {" - " background: white;" - " border: 1px solid #bdbdbd;" + f" background: {WHITE};" + f" border: 1px solid {PANEL_BORDER_DARK};" " border-radius: 6px;" " padding: 4px 8px;" "}" @@ -146,7 +154,8 @@ class DeveloperHelpDialog(QDialog): self._details_frame = QFrame(self) self._details_frame.setFrameShape(QFrame.Shape.StyledPanel) self._details_frame.setStyleSheet( - "QFrame { background: #fafafa; border: 1px solid #d0d0d0; border-radius: 6px;}" + f"QFrame {{ background: {PANEL_BG_FAINT}; border: 1px solid {PANEL_BORDER};" + " border-radius: 6px;}" ) details_layout = QVBoxLayout(self._details_frame) @@ -178,8 +187,8 @@ class DeveloperHelpDialog(QDialog): self._detail_help.setTextInteractionFlags(Qt.TextInteractionFlag.TextSelectableByMouse) self._detail_help.setStyleSheet( "QLabel {" - " background: white;" - " border: 1px solid #e0e0e0;" + f" background: {WHITE};" + f" border: 1px solid {PANEL_BORDER_LIGHT};" " border-radius: 6px;" " padding: 8px;" "}" diff --git a/src/aare/gui/panels/face_detection_panel.py b/src/aare/gui/panels/face_detection_panel.py index 46c9e5e2..fa8cf5d8 100644 --- a/src/aare/gui/panels/face_detection_panel.py +++ b/src/aare/gui/panels/face_detection_panel.py @@ -6,6 +6,7 @@ from PySide6.QtCore import Signal from PySide6.QtWidgets import QGridLayout, QLabel, QPushButton, QVBoxLayout, QWidget from aare.gui.constants import LOGGER_NAME +from aare.gui.styles import GO_TEXT from aare.gui.widgets.number_line_edit import NumberLineEdit from aare.gui.widgets.title_label import TitleLabel @@ -51,7 +52,7 @@ class FaceDetectionPanel(QWidget): self.steps_enter.newValue.connect(_set_steps) self.face_detection_button = QPushButton("Face Detection") - self.face_detection_button.setStyleSheet("color: rgb(78, 154, 6);") + self.face_detection_button.setStyleSheet(f"color: {GO_TEXT};") self.face_detection_button.clicked.connect(self.run_and_refresh) self._top_layout.addWidget(self.face_detection_button, 3, 0, 1, 3) diff --git a/src/aare/gui/panels/file_path_panel.py b/src/aare/gui/panels/file_path_panel.py index 45204210..96937e33 100644 --- a/src/aare/gui/panels/file_path_panel.py +++ b/src/aare/gui/panels/file_path_panel.py @@ -7,6 +7,7 @@ from aarecommon.models.models import DAQStatusModel, SampleShortInfo from PySide6.QtCore import Qt, Signal, Slot from PySide6.QtWidgets import QGridLayout, QLabel, QLineEdit, QMessageBox, QSpinBox, QWidget +from aare.gui.styles import DEFAULT_TEXT, PATH_WARN_TEXT, SURFACE from aare.gui.widgets.title_label import TitleLabel ## Logic for filenames: @@ -44,7 +45,7 @@ class FilePathPanel(QWidget): grid_layout.addWidget(QLabel("Directory", parent=self), 1, 0) self.directory_edit = QLineEdit("{date}/{puck}/{pos}", parent=self) - self.directory_edit.setStyleSheet("background-color: rgb(255, 255, 255);") + self.directory_edit.setStyleSheet(f"background-color: {SURFACE};") self.directory_edit.setToolTip( "Provide subdirectory for your files. The following macros are allowed:
" "{date} - date in format yyyymmdd
" @@ -58,7 +59,7 @@ class FilePathPanel(QWidget): grid_layout.addWidget(QLabel("File prefix", parent=self), 2, 0) self.file_prefix_edit = QLineEdit("{sample}", parent=self) - self.file_prefix_edit.setStyleSheet("background-color: rgb(255, 255, 255);") + self.file_prefix_edit.setStyleSheet(f"background-color: {SURFACE};") self.file_prefix_edit.setToolTip( "Provide file prefix for your files. The following macros are allowed:
" "{date} - date in format yyyymmdd
" @@ -72,7 +73,7 @@ class FilePathPanel(QWidget): grid_layout.addWidget(QLabel("Run number", parent=self), 3, 0) self.run_number_edit = QSpinBox(parent=self) - self.run_number_edit.setStyleSheet("background-color: rgb(255, 255, 255);") + self.run_number_edit.setStyleSheet(f"background-color: {SURFACE};") self.run_number_edit.setValue(1) self.run_number_edit.setRange(1, 999) self.run_number_edit.setAlignment(Qt.AlignmentFlag.AlignRight) @@ -161,7 +162,7 @@ class FilePathPanel(QWidget): exists = os.path.exists(f"{effective}_master.h5") or os.path.exists(effective) self.file_name_label.setText(effective + "_master.h5") self.file_name_label.setStyleSheet( - "color: rgb(200, 0, 0);" if exists else "color: rgb(0, 0, 0);" + f"color: {PATH_WARN_TEXT};" if exists else f"color: {DEFAULT_TEXT};" ) self.path_updated.emit(self._filename) diff --git a/src/aare/gui/panels/fluorescence_data_collection.py b/src/aare/gui/panels/fluorescence_data_collection.py index 9266dfff..ce3980e6 100644 --- a/src/aare/gui/panels/fluorescence_data_collection.py +++ b/src/aare/gui/panels/fluorescence_data_collection.py @@ -2,6 +2,7 @@ from aarecommon.models.models import FluorescenceSpectrumParameterModel from PySide6.QtCore import Signal, Slot from PySide6.QtWidgets import QCheckBox, QGridLayout, QLabel, QPushButton, QWidget +from aare.gui.styles import GO_TEXT from aare.gui.widgets.number_line_edit import NumberLineEdit @@ -34,7 +35,7 @@ class FluorescenceDataCollectionPanel(QWidget): # Run button self.run_btn = QPushButton("Run fluorescence", self) - self.run_btn.setStyleSheet("color: rgb(78, 154, 6);") + self.run_btn.setStyleSheet(f"color: {GO_TEXT};") lay.addWidget(self.run_btn, 4, 0, 1, 3) self.run_btn.clicked.connect(self._emit_params) diff --git a/src/aare/gui/panels/fluorescence_panel.py b/src/aare/gui/panels/fluorescence_panel.py index 49e2ccb7..b67f25a7 100644 --- a/src/aare/gui/panels/fluorescence_panel.py +++ b/src/aare/gui/panels/fluorescence_panel.py @@ -3,10 +3,11 @@ from aarecommon.config.logger import setup_logger from aarecommon.models.models import DAQStatusModel, FluorescenceSpectrumOutputModel from PySide6.QtCharts import QChart, QChartView, QLineSeries, QValueAxis from PySide6.QtCore import QEvent, QPointF, Qt, Slot -from PySide6.QtGui import QColor, QPainter, QPen +from PySide6.QtGui import QPainter, QPen from PySide6.QtWidgets import QGraphicsSimpleTextItem, QGridLayout, QLabel, QWidget from aare.gui.constants import LOGGER_NAME +from aare.gui.styles import SPECTRUM_LINE, qcolor logger = setup_logger(LOGGER_NAME) @@ -65,7 +66,7 @@ class FluorescencePanel(QWidget): # Vertical marker line (two-point series) self._vline = QLineSeries() - pen = QPen(QColor("#cc0000")) + pen = QPen(qcolor(SPECTRUM_LINE)) pen.setWidth(2) self._vline.setPen(pen) self.chart.addSeries(self._vline) diff --git a/src/aare/gui/panels/local_contact_panel.py b/src/aare/gui/panels/local_contact_panel.py index 83a79717..8153b9c8 100644 --- a/src/aare/gui/panels/local_contact_panel.py +++ b/src/aare/gui/panels/local_contact_panel.py @@ -29,6 +29,15 @@ from PySide6.QtWidgets import ( from aare.gui.constants import LOGGER_NAME from aare.gui.panels.beamline_recovery_panel import RecoveryPanel +from aare.gui.styles import ( + BAD_CARD_BORDER, + BORDER, + CARD_BORDER, + CHIP_BAD_BG, + CHIP_BAD_TEXT, + HEADING_TEXT, + SURFACE, +) from aare.gui.threads.daq_worker import DAQWorker from aare.gui.widgets.local_contact_status_widget import LocalContactStatusWidget from aare.gui.widgets.text_list_dialog import TextListDialog @@ -74,23 +83,27 @@ class LocalContactPanel(QFrame): self.setFrameShape(QFrame.Shape.StyledPanel) self.setFrameShadow(QFrame.Shadow.Raised) + self.setObjectName("localContactPanel") self.setStyleSheet( - """ - QGroupBox { - background-color: white; - border: 1px solid #c7d4e5; + f""" + QFrame#localContactPanel {{ + border: 1px solid {BORDER}; + }} + QGroupBox {{ + background-color: {SURFACE}; + border: 1px solid {CARD_BORDER}; margin-top: 15px; padding-top: 15px; font-weight: 700; - color: #1e293b; - } - QGroupBox::title { + color: {HEADING_TEXT}; + }} + QGroupBox::title {{ subcontrol-origin: margin; subcontrol-position: top left; left: 10px; padding: 0 6px 0 6px; font:bold; - } + }} """ ) @@ -108,7 +121,8 @@ class LocalContactPanel(QFrame): self._transfer_error_frame = QFrame(self) self._transfer_error_frame.setVisible(False) self._transfer_error_frame.setStyleSheet( - "QFrame { background: #fdeaea; color: #8b1e1e; border: 1px solid #e6a8a8;}" + f"QFrame {{ background: {CHIP_BAD_BG}; color: {CHIP_BAD_TEXT};" + f" border: 1px solid {BAD_CARD_BORDER};}}" ) transfer_error_layout = QVBoxLayout(self._transfer_error_frame) transfer_error_layout.setContentsMargins(10, 10, 10, 10) diff --git a/src/aare/gui/panels/log_panel.py b/src/aare/gui/panels/log_panel.py index 1de7958c..659c8ae8 100644 --- a/src/aare/gui/panels/log_panel.py +++ b/src/aare/gui/panels/log_panel.py @@ -13,6 +13,18 @@ from PySide6.QtWidgets import ( ) from aare.gui.log import QtLogEmitter, QtLogHandler +from aare.gui.styles import ( + LOG_BORDER, + LOG_ERROR_BG, + LOG_ERROR_BORDER, + LOG_INFO_BG, + LOG_INFO_BORDER, + LOG_PANEL_BG, + LOG_SUCCESS_BG, + LOG_SUCCESS_BORDER, + LOG_WARN_BG, + LOG_WARN_BORDER, +) class RuntimeNotificationWidget(QFrame): @@ -78,31 +90,31 @@ class RuntimeNotificationWidget(QFrame): self._sticky = True self.setStyleSheet( - """ - QFrame#runtimeNotification { - border: 1px solid #8a8a8a; + f""" + QFrame#runtimeNotification {{ + border: 1px solid {LOG_BORDER}; border-radius: 8px; - background-color: #fff4f4; - } - QFrame#runtimeNotification[noticeLevel="error"] { - background-color: #fff1f1; - border: 1px solid #d66; - } - QFrame#runtimeNotification[noticeLevel="warning"] { - background-color: #fff8e8; - border: 1px solid #d7aa42; - } - QFrame#runtimeNotification[noticeLevel="success"] { - background-color: #eefaf0; - border: 1px solid #6cb37a; - } - QFrame#runtimeNotification[noticeLevel="info"] { - background-color: #eef5ff; - border: 1px solid #6b9bd6; - } - QLabel#runtimeNotificationTitle { + background-color: {LOG_PANEL_BG}; + }} + QFrame#runtimeNotification[noticeLevel="error"] {{ + background-color: {LOG_ERROR_BG}; + border: 1px solid {LOG_ERROR_BORDER}; + }} + QFrame#runtimeNotification[noticeLevel="warning"] {{ + background-color: {LOG_WARN_BG}; + border: 1px solid {LOG_WARN_BORDER}; + }} + QFrame#runtimeNotification[noticeLevel="success"] {{ + background-color: {LOG_SUCCESS_BG}; + border: 1px solid {LOG_SUCCESS_BORDER}; + }} + QFrame#runtimeNotification[noticeLevel="info"] {{ + background-color: {LOG_INFO_BG}; + border: 1px solid {LOG_INFO_BORDER}; + }} + QLabel#runtimeNotificationTitle {{ font-weight: bold; - } + }} """ ) diff --git a/src/aare/gui/panels/manual_sample_panel.py b/src/aare/gui/panels/manual_sample_panel.py index 7f86a5f8..f7f554e2 100644 --- a/src/aare/gui/panels/manual_sample_panel.py +++ b/src/aare/gui/panels/manual_sample_panel.py @@ -3,6 +3,7 @@ from aareDB import DataCollectionParameters from PySide6.QtCore import Signal, Slot from PySide6.QtWidgets import QCheckBox, QGridLayout, QLabel, QLineEdit, QPushButton, QWidget +from aare.gui.styles import SURFACE from aare.gui.widgets.number_line_edit import NumberLineEdit from aare.gui.widgets.title_label import TitleLabel @@ -31,7 +32,7 @@ class ManualSamplePanel(QWidget): self._text_name = QLineEdit(self._sample_name) grid_layout.addWidget(self._text_name, 1, 1) self._text_name.textChanged.connect(self._name_changed) - self._text_name.setStyleSheet("background-color: rgb(255, 255, 255);") + self._text_name.setStyleSheet(f"background-color: {SURFACE};") # Unit cell parameters self._unit_cell = QCheckBox("Provide unit cell") diff --git a/src/aare/gui/panels/portrait_mode.py b/src/aare/gui/panels/portrait_mode.py index 08b21114..288a8856 100644 --- a/src/aare/gui/panels/portrait_mode.py +++ b/src/aare/gui/panels/portrait_mode.py @@ -20,22 +20,28 @@ from PySide6.QtWidgets import ( ) from aare.gui.constants import LOGGER_NAME +from aare.gui.styles import DARK_ACCENT as ACCENT +from aare.gui.styles import DARK_BG as BG +from aare.gui.styles import DARK_BORDER as ACCENT_DIM +from aare.gui.styles import DARK_BORDER as LED_OFF +from aare.gui.styles import DARK_ELEVATED as BUTTON_BG +from aare.gui.styles import ( + DARK_ERROR_BG, + DARK_ERROR_BORDER, + DARK_ERROR_TEXT, + DARK_SUCCESS_BG, + DARK_SUCCESS_BORDER, + DARK_SUCCESS_TEXT, + WHITE, + qcolor, +) +from aare.gui.styles import DARK_MUTED as SUBTEXT +from aare.gui.styles import DARK_SURFACE as CARD_BG +from aare.gui.styles import DARK_TEXT as TEXT +from aare.gui.styles import WHITE as ACTIVE_STEP logger = setup_logger(LOGGER_NAME) -# --------------------------------------------------------------------------- -# Colour palette (kept identical to gui_designer.py) -# --------------------------------------------------------------------------- -BG = "#071018" -CARD_BG = "#0E1A26" -ACCENT = "#62D8C8" -ACCENT_DIM = "#1A3A36" -TEXT = "#F5F7FA" -SUBTEXT = "#8A9BB0" -BUTTON_BG = "#132131" -LED_OFF = "#1C2E3E" -ACTIVE_STEP = "#FFFFFF" - # --------------------------------------------------------------------------- # LED step indicator @@ -112,7 +118,8 @@ class LEDStages(QWidget): p.drawLine(QPointF(cx - 4, cy), QPointF(cx - 1, cy + 3)) p.drawLine(QPointF(cx - 1, cy + 3), QPointF(cx + 4, cy - 3)) elif i == self._active: - glow_pen = QPen(QColor(ACCENT + "55"), 4) + # was QColor(ACCENT + "55"), which mis-parsed as #AARRGGBB + glow_pen = QPen(qcolor(ACCENT, 0x55), 4) p.setPen(glow_pen) p.setBrush(Qt.NoBrush) p.drawEllipse(QPointF(cx, cy), led_r + 4, led_r + 4) @@ -166,7 +173,7 @@ class PlayPauseButton(QPushButton): cx, cy = rect.width() / 2, rect.height() / 2 r = min(rect.width(), rect.height()) / 2 - 2 - bg_color = QColor("#FFFFFF") if self._hovered else QColor(ACCENT) + bg_color = qcolor(WHITE) if self._hovered else QColor(ACCENT) p.setBrush(bg_color) p.setPen(Qt.NoPen) p.drawEllipse(QPointF(cx, cy), r, r) @@ -189,7 +196,7 @@ class QueueItemCard(QFrame): self.setFixedHeight(72) self.setStyleSheet(f""" QFrame {{ - background: {"#112030" if is_next else "#0C1720"}; + background: {BUTTON_BG if is_next else CARD_BG}; border-radius: 14px; border: {"1px solid " + ACCENT_DIM if is_next else "none"}; }} @@ -292,19 +299,19 @@ class PortraitModePanel(QWidget): # ── Portrait alert toast (hidden by default) ─────────────────────── self._alert_toast = QFrame() self._alert_toast.setVisible(False) - self._alert_toast.setStyleSheet(""" - QFrame { - background: #1A0E0E; - border: 1px solid #8f1d2c; + self._alert_toast.setStyleSheet(f""" + QFrame {{ + background: {DARK_ERROR_BG}; + border: 1px solid {DARK_ERROR_BORDER}; border-radius: 10px; - } + }} """) toast_layout = QHBoxLayout(self._alert_toast) toast_layout.setContentsMargins(12, 8, 12, 8) self._alert_toast_label = QLabel("") self._alert_toast_label.setWordWrap(True) self._alert_toast_label.setStyleSheet( - "color: #ffb3bc; font-size: 11px; font-weight: 600; background: transparent;" + f"color: {DARK_ERROR_TEXT}; font-size: 11px; font-weight: 600; background: transparent;" ) toast_layout.addWidget(self._alert_toast_label) # Dismiss button @@ -658,9 +665,9 @@ class PortraitModePanel(QWidget): icon = "🛑" if is_error else "✅" self._alert_toast_label.setText(f"{icon} {msg}") - border_color = "#8f1d2c" if is_error else "#2a7a44" - text_color = "#ffb3bc" if is_error else "#a8f0c0" - bg_color = "#1A0E0E" if is_error else "#0E1A12" + border_color = DARK_ERROR_BORDER if is_error else DARK_SUCCESS_BORDER + text_color = DARK_ERROR_TEXT if is_error else DARK_SUCCESS_TEXT + bg_color = DARK_ERROR_BG if is_error else DARK_SUCCESS_BG self._alert_toast.setStyleSheet(f""" QFrame {{ diff --git a/src/aare/gui/panels/prediction_metrics_panel.py b/src/aare/gui/panels/prediction_metrics_panel.py index dce257d6..44f2cab2 100644 --- a/src/aare/gui/panels/prediction_metrics_panel.py +++ b/src/aare/gui/panels/prediction_metrics_panel.py @@ -42,6 +42,16 @@ from PySide6.QtWidgets import ( ) from aare.gui.constants import LOGGER_NAME +from aare.gui.styles import ( + CHART_BLUE, + CHART_GREEN, + CHART_MUTED, + CHART_ORANGE, + CHART_RED, + CONFIDENCE_BIN_COLORS, + qcolor, +) +from aare.gui.styles import CHART_CLASS_COLORS as CLASS_COLORS logger = setup_logger(LOGGER_NAME) @@ -79,17 +89,6 @@ class GroundTruthComparison: # ───────────────────────────────────────────────────────────────────────────── -# Colors matching the bounding box colors in camera_image.py -CLASS_COLORS = { - "Crystal": "#0000ff", # blue - "Loop_face": "#ffff00", # yellow - "Loop_all": "#00ff00", # green - "Pin": "#ff0000", # red - "Ice": "#00ffff", # cyan - "Needle": "#ff00ff", # magenta -} - - def get_class_name(cls_id: int) -> str: """Convert class ID to human-readable name.""" try: @@ -100,7 +99,7 @@ def get_class_name(cls_id: int) -> str: def get_class_color(class_name: str) -> str: """Get color for a class name (matches bounding box colors).""" - return CLASS_COLORS.get(class_name, "#888888") + return CLASS_COLORS.get(class_name, CHART_MUTED) # ───────────────────────────────────────────────────────────────────────────── @@ -112,7 +111,7 @@ class ConfidenceHistogramWidget(QWidget): """Real-time histogram of prediction confidence scores.""" BINS: ClassVar[list[float]] = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0] - BIN_COLORS: ClassVar[list[str]] = ["#d62728", "#ff7f0e", "#ffbb78", "#98df8a", "#2ca02c"] + BIN_COLORS: ClassVar[list[str]] = CONFIDENCE_BIN_COLORS def __init__(self, parent=None): super().__init__(parent) @@ -335,19 +334,19 @@ class ErrorTrackingWidget(QWidget): # Empty frames (no detections) grid.addWidget(QLabel("Empty frames:"), 0, 0) self.empty_frames_label = QLabel("0") - self.empty_frames_label.setStyleSheet("color: #d62728; font-weight: bold;") + self.empty_frames_label.setStyleSheet(f"color: {CHART_RED}; font-weight: bold;") grid.addWidget(self.empty_frames_label, 0, 1) # Low confidence detections grid.addWidget(QLabel("Low conf (<0.5):"), 0, 2) self.low_conf_label = QLabel("0") - self.low_conf_label.setStyleSheet("color: #ff7f0e; font-weight: bold;") + self.low_conf_label.setStyleSheet(f"color: {CHART_ORANGE}; font-weight: bold;") grid.addWidget(self.low_conf_label, 0, 3) # Detection rate grid.addWidget(QLabel("Detection rate:"), 1, 0) self.detection_rate_label = QLabel("-") - self.detection_rate_label.setStyleSheet("color: #2ca02c; font-weight: bold;") + self.detection_rate_label.setStyleSheet(f"color: {CHART_GREEN}; font-weight: bold;") grid.addWidget(self.detection_rate_label, 1, 1) # Reset button @@ -411,12 +410,12 @@ class RollingStatsChart(QWidget): # Detection count series (left Y axis) self.count_series = QLineSeries() self.count_series.setName("Detections") - self.count_series.setPen(QPen(QColor("#1f77b4"), 2)) + self.count_series.setPen(QPen(qcolor(CHART_BLUE), 2)) # Mean confidence series (right Y axis) self.conf_series = QLineSeries() self.conf_series.setName("Mean Confidence") - self.conf_series.setPen(QPen(QColor("#2ca02c"), 2)) + self.conf_series.setPen(QPen(qcolor(CHART_GREEN), 2)) self.chart = QChart() self.chart.addSeries(self.count_series) @@ -554,7 +553,7 @@ class PredictionMetricsPanel(QWidget): controls.addStretch() self.status_label = QLabel("Waiting for predictions...") - self.status_label.setStyleSheet("color: #888;") + self.status_label.setStyleSheet(f"color: {CHART_MUTED};") controls.addWidget(self.status_label) layout.addLayout(controls) @@ -633,14 +632,14 @@ class PredictionMetricsPanel(QWidget): """Update status label.""" if self._paused: self.status_label.setText("Paused") - self.status_label.setStyleSheet("color: #ff7f0e;") + self.status_label.setStyleSheet(f"color: {CHART_ORANGE};") elif self._history: count = len(self._history) self.status_label.setText(f"Live: {count} frames recorded") - self.status_label.setStyleSheet("color: #2ca02c;") + self.status_label.setStyleSheet(f"color: {CHART_GREEN};") else: self.status_label.setText("Waiting for predictions...") - self.status_label.setStyleSheet("color: #888;") + self.status_label.setStyleSheet(f"color: {CHART_MUTED};") def showEvent(self, event) -> None: super().showEvent(event) diff --git a/src/aare/gui/panels/raster_data_collection.py b/src/aare/gui/panels/raster_data_collection.py index bbe4a16e..8bd6ff74 100644 --- a/src/aare/gui/panels/raster_data_collection.py +++ b/src/aare/gui/panels/raster_data_collection.py @@ -15,6 +15,7 @@ from PySide6.QtWidgets import ( from aare.gui.constants import LOGGER_NAME from aare.gui.panels.scan_settings_panel import ScanSettingsPanel from aare.gui.scan_logic.raster_grid_manager import RasterGridManager, RasterGridMetric +from aare.gui.styles import GO_TEXT from aare.gui.widgets.number_line_edit import DbOverrideLineEdit from aare.gui.widgets.raster_grid_table import RasterGridTable @@ -143,12 +144,12 @@ class RasterDataCollectionPanel(ScanSettingsPanel): self.calculate_total_time() self.start_button = QPushButton("Evaluate grid") - self.start_button.setStyleSheet("color: rgb(78, 154, 6);") + self.start_button.setStyleSheet(f"color: {GO_TEXT};") self.start_button.clicked.connect(self._on_evaluate_clicked) self._layout.addWidget(self.start_button, 12, 0, 1, 5) self.auto_button = QPushButton("X-ray Centering") - self.auto_button.setStyleSheet("color: rgb(78, 154, 6);") + self.auto_button.setStyleSheet(f"color: {GO_TEXT};") self.auto_button.clicked.connect(self._on_evaluate_auto_clicked) self._layout.addWidget(self.auto_button, 13, 0, 1, 5) self._reset_to_defaults() diff --git a/src/aare/gui/panels/reference_tools_panel.py b/src/aare/gui/panels/reference_tools_panel.py index 8708c91b..d056235a 100644 --- a/src/aare/gui/panels/reference_tools_panel.py +++ b/src/aare/gui/panels/reference_tools_panel.py @@ -3,7 +3,7 @@ from aarecommon.config.logger import setup_logger from aarecommon.models.models import DAQStatusModel, SampleShortInfo, SampleShortInfoList from PySide6.QtCore import QAbstractTableModel, QModelIndex, Qt, Signal, Slot -from PySide6.QtGui import QBrush, QColor +from PySide6.QtGui import QBrush from PySide6.QtWidgets import ( QAbstractItemView, QFrame, @@ -16,6 +16,7 @@ from PySide6.QtWidgets import ( ) from aare.gui.constants import LOGGER_NAME +from aare.gui.styles import SAMPLE_ROW_QUEUED_BG, WHITE, qcolor from aare.gui.widgets.title_label import TitleLabel logger = setup_logger(LOGGER_NAME) @@ -83,8 +84,8 @@ class ReferenceToolsModel(QAbstractTableModel): return Qt.AlignmentFlag.AlignCenter elif role == Qt.ItemDataRole.BackgroundRole: if self._sorted_samples[index.row()].db_id == self.current_reference: - return QBrush(QColor(114, 159, 207)) # darker blue - return QBrush(QColor(255, 255, 255)) # white + return QBrush(qcolor(SAMPLE_ROW_QUEUED_BG)) + return QBrush(qcolor(WHITE)) return None diff --git a/src/aare/gui/panels/rotation_data_collection.py b/src/aare/gui/panels/rotation_data_collection.py index 0e8dacf4..774fe9f5 100644 --- a/src/aare/gui/panels/rotation_data_collection.py +++ b/src/aare/gui/panels/rotation_data_collection.py @@ -10,6 +10,7 @@ from PySide6.QtWidgets import QComboBox, QLabel, QMessageBox, QPushButton from aare.gui.constants import LOGGER_NAME from aare.gui.panels.scan_settings_panel import ScanSettingsPanel +from aare.gui.styles import GO_TEXT from aare.gui.widgets.number_line_edit import DbOverrideLineEdit, NumberLineEdit logger = setup_logger(LOGGER_NAME) @@ -96,7 +97,7 @@ class RotationDataCollectionPanel(ScanSettingsPanel): self._layout.addWidget(self.screening_type, 7, 0, 1, 6) self.screening_button = QPushButton("Run screening") - self.screening_button.setStyleSheet("color: rgb(78, 154, 6);") + self.screening_button.setStyleSheet(f"color: {GO_TEXT};") self.screening_button.clicked.connect(self.run_screening) self._layout.addWidget(self.screening_button, 8, 0, 1, 6) @@ -160,7 +161,7 @@ class RotationDataCollectionPanel(ScanSettingsPanel): self.reload_params_button.setVisible(True) self.measurement_button = QPushButton("Run rotation") - self.measurement_button.setStyleSheet("color: rgb(78, 154, 6);") + self.measurement_button.setStyleSheet(f"color: {GO_TEXT};") self.measurement_button.clicked.connect(self.run_measurement) self._layout.addWidget(self.measurement_button, 16, 0, 1, 6) self._reset_to_defaults() diff --git a/src/aare/gui/panels/samcam_panel.py b/src/aare/gui/panels/samcam_panel.py index 83ad9777..77dfd9e7 100644 --- a/src/aare/gui/panels/samcam_panel.py +++ b/src/aare/gui/panels/samcam_panel.py @@ -12,6 +12,7 @@ from PySide6.QtWidgets import ( QWidget, ) +from aare.gui.styles import INPUT_BG from aare.gui.widgets.title_label import TitleLabel @@ -43,7 +44,7 @@ class SamcamPanel(QWidget): self.exposure_spinbox = QDoubleSpinBox() self.exposure_spinbox.setRange(0, 1.0) # Adjust range as needed self.exposure_spinbox.setSingleStep(0.001) - self.exposure_spinbox.setStyleSheet("QDoubleSpinBox { background-color: white; }") + self.exposure_spinbox.setStyleSheet(f"QDoubleSpinBox {{ background-color: {INPUT_BG}; }}") self.exposure_spinbox.setDecimals(3) self.exposure_spinbox.valueChanged.connect(self._changed) @@ -57,7 +58,7 @@ class SamcamPanel(QWidget): self.gain_spinbox.setRange(0, 1000) # Adjust range as needed self.gain_spinbox.setSingleStep(1) self.gain_spinbox.setDecimals(1) - self.gain_spinbox.setStyleSheet("QDoubleSpinBox { background-color: white; }") + self.gain_spinbox.setStyleSheet(f"QDoubleSpinBox {{ background-color: {INPUT_BG}; }}") self.gain_spinbox.valueChanged.connect(self._changed) gain_layout.addWidget(gain_label) gain_layout.addWidget(self.gain_spinbox) @@ -71,7 +72,9 @@ class SamcamPanel(QWidget): screenshot_filename_label = QLabel("Filename:") self.screenshot_filename_edit = QLineEdit() self.screenshot_filename_edit.setPlaceholderText("optional") - self.screenshot_filename_edit.setStyleSheet("QLineEdit { background-color: white; }") + self.screenshot_filename_edit.setStyleSheet( + f"QLineEdit {{ background-color: {INPUT_BG}; }}" + ) screenshot_filename_layout.addWidget(screenshot_filename_label) screenshot_filename_layout.addWidget(self.screenshot_filename_edit) @@ -79,7 +82,7 @@ class SamcamPanel(QWidget): screenshot_message_label = QLabel("Message:") self.screenshot_message_edit = QLineEdit() self.screenshot_message_edit.setPlaceholderText("optional") - self.screenshot_message_edit.setStyleSheet("QLineEdit { background-color: white; }") + self.screenshot_message_edit.setStyleSheet(f"QLineEdit {{ background-color: {INPUT_BG}; }}") screenshot_message_layout.addWidget(screenshot_message_label) screenshot_message_layout.addWidget(self.screenshot_message_edit) diff --git a/src/aare/gui/panels/smart_rotation_panel.py b/src/aare/gui/panels/smart_rotation_panel.py index 1a49a873..5b493d74 100644 --- a/src/aare/gui/panels/smart_rotation_panel.py +++ b/src/aare/gui/panels/smart_rotation_panel.py @@ -8,6 +8,7 @@ from PySide6.QtWidgets import QGridLayout, QLabel, QPushButton, QSizePolicy, QSp from aare.gui.constants import LOGGER_NAME from aare.gui.panels.rotation_data_collection import add_data_to_path +from aare.gui.styles import GO_TEXT, STATUS_ALERT from aare.gui.widgets.number_line_edit import NumberLineEdit logger = setup_logger(LOGGER_NAME) @@ -205,7 +206,7 @@ class SimpleRotationSettingsPanel(QWidget): # Run rotation button self.run_rotation_button = QPushButton("Run rotation", parent=self) - self.run_rotation_button.setStyleSheet("color: rgb(78, 154, 6);") + self.run_rotation_button.setStyleSheet(f"color: {GO_TEXT};") self.run_rotation_button.clicked.connect(self.run_measurement) self._layout.addWidget(self.run_rotation_button, 22, 0, 1, 6) @@ -355,9 +356,11 @@ class SimpleRotationSettingsPanel(QWidget): self.image_time_label.setText(f"{self.image_time_s:.4f}") if self.dtz <= 0.0: - self.dtz_label.setText("""-""") + self.dtz_label.setText(f"""-""") elif self.dtz < self._d.bl.dtz_min: - self.dtz_label.setText(f"""{self.dtz:.2f}""") + self.dtz_label.setText( + f"""{self.dtz:.2f}""" + ) self.dtz = self._d.bl.dtz_min else: self.dtz_label.setText(f"{self.dtz:.2f}") diff --git a/src/aare/gui/panels/status_panel.py b/src/aare/gui/panels/status_panel.py index 971f2efc..31f77b69 100644 --- a/src/aare/gui/panels/status_panel.py +++ b/src/aare/gui/panels/status_panel.py @@ -4,6 +4,7 @@ from PySide6.QtCore import Qt, Slot from PySide6.QtGui import QPixmap from PySide6.QtWidgets import QFrame, QGridLayout, QLabel, QSizePolicy, QSpacerItem +from aare.gui.styles import STATUS_ALERT from aare.gui.widgets.status_label import StatusLabel from aare.gui.widgets.title_label import TitleLabel @@ -65,7 +66,7 @@ class StatusPanel(QFrame): if s.bl.ring_current_mA < 390.0: self.ring_current.setText( - f'{s.bl.ring_current_mA:.1f}' + f'{s.bl.ring_current_mA:.1f}' ) else: self.ring_current.setText(f"{s.bl.ring_current_mA:.1f}") diff --git a/src/aare/gui/panels/target_stability_panel.py b/src/aare/gui/panels/target_stability_panel.py index fdbeb00d..03757327 100644 --- a/src/aare/gui/panels/target_stability_panel.py +++ b/src/aare/gui/panels/target_stability_panel.py @@ -23,6 +23,18 @@ from PySide6.QtWidgets import ( ) from aare.gui.constants import LOGGER_NAME +from aare.gui.styles import ( + CHART_BLUE, + CHART_BLUE_LIGHT, + CHART_BLUE_PALE, + CHART_CYAN, + CHART_GREEN, + CHART_ORANGE, + CHART_PURPLE, + CHART_RED, + CHART_RED_DARK, + CHART_RED_LIGHT, +) logger = setup_logger(LOGGER_NAME) @@ -97,19 +109,19 @@ class InteractiveChartView(QChartView): class TargetStabilityPanel(QWidget): - SIGMA_COLOR = "#1f77b4" - SIGMA_X_COLOR = "#6baed6" - SIGMA_Y_COLOR = "#9ecae1" + SIGMA_COLOR = CHART_BLUE + SIGMA_X_COLOR = CHART_BLUE_LIGHT + SIGMA_Y_COLOR = CHART_BLUE_PALE - DISTANCE_COLOR = "#d62728" - DX_COLOR = "#ff9896" - DY_COLOR = "#c43c39" + DISTANCE_COLOR = CHART_RED + DX_COLOR = CHART_RED_LIGHT + DY_COLOR = CHART_RED_DARK - SCORE_COLOR = "#ff7f0e" - STEP_COLOR = "#17becf" + SCORE_COLOR = CHART_ORANGE + STEP_COLOR = CHART_CYAN - TARGET_COLOR = "#2ca02c" - BEAM_COLOR = "#9467bd" + TARGET_COLOR = CHART_GREEN + BEAM_COLOR = CHART_PURPLE SCORE_FROM_STEP_XY = "Step XY" SCORE_FROM_SIGMA_XY = "Sigma XY" diff --git a/src/aare/gui/panels/tell_sample_panel.py b/src/aare/gui/panels/tell_sample_panel.py index 035c487f..81b2d555 100644 --- a/src/aare/gui/panels/tell_sample_panel.py +++ b/src/aare/gui/panels/tell_sample_panel.py @@ -19,6 +19,7 @@ from PySide6.QtWidgets import ( from aare.gui.constants import LOGGER_NAME from aare.gui.models.user_sample_model import UserSampleSpreadsheet +from aare.gui.styles import NOTE_TEXT from aare.gui.widgets.title_label import TitleLabel logger = setup_logger(LOGGER_NAME) @@ -241,7 +242,7 @@ class TellSamplePanel(QFrame): if tell_details: self.curr_sample_label.setText( - f"{base_text}
TELL: {tell_details}" + f"{base_text}
TELL: {tell_details}" ) else: self.curr_sample_label.setText(base_text) diff --git a/src/aare/gui/scan_logic/raster_grid_manager.py b/src/aare/gui/scan_logic/raster_grid_manager.py index c6d7d163..0457ee81 100644 --- a/src/aare/gui/scan_logic/raster_grid_manager.py +++ b/src/aare/gui/scan_logic/raster_grid_manager.py @@ -17,6 +17,7 @@ from PySide6.QtCore import QLineF, QObject, QPointF, QRect, QRectF, Qt, Signal, from PySide6.QtGui import QBrush, QColor, QImage, QPainter, QPen from aare.gui.constants import LOGGER_NAME +from aare.gui.styles import RASTER_GRID_LINE, qcolor logger = setup_logger(LOGGER_NAME) @@ -643,7 +644,9 @@ class RasterGridManager(QObject): painter.drawImage(bounds, image) painter.setOpacity(1.0) - painter.setPen(QPen(QColor(114, 159, 207, min(255, alpha + 40)), 1, Qt.PenStyle.SolidLine)) + painter.setPen( + QPen(qcolor(RASTER_GRID_LINE, min(255, alpha + 40)), 1, Qt.PenStyle.SolidLine) + ) painter.setBrush(Qt.BrushStyle.NoBrush) painter.drawRect(bounds) painter.restore() @@ -697,7 +700,7 @@ class RasterGridManager(QObject): max_value = max((x for x in values if x is not None and not math.isnan(x)), default=1) diff = 1 if min_value == max_value else (max_value - min_value) else: - painter.setPen(QPen(QColor(114, 159, 207), 1, Qt.PenStyle.SolidLine)) + painter.setPen(QPen(qcolor(RASTER_GRID_LINE), 1, Qt.PenStyle.SolidLine)) min_value = 0 diff = 1 @@ -732,7 +735,7 @@ class RasterGridManager(QObject): painter.setBrush(Qt.BrushStyle.NoBrush) else: painter.setPen( - QPen(QColor(114, 159, 207, min(255, alpha + 40)), 1, Qt.PenStyle.SolidLine) + QPen(qcolor(RASTER_GRID_LINE, min(255, alpha + 40)), 1, Qt.PenStyle.SolidLine) ) painter.setBrush(Qt.BrushStyle.NoBrush) painter.drawRect(bounds) @@ -760,7 +763,7 @@ class RasterGridManager(QObject): painter.save() painter.setRenderHint(QPainter.RenderHint.Antialiasing, False) - painter.setPen(QPen(QColor(114, 159, 207), 1, Qt.PenStyle.SolidLine)) + painter.setPen(QPen(qcolor(RASTER_GRID_LINE), 1, Qt.PenStyle.SolidLine)) painter.setBrush(Qt.BrushStyle.NoBrush) painter.drawRect(bounds) @@ -854,7 +857,9 @@ class RasterGridManager(QObject): brush = float_to_viridis_brush((value - min_value) / diff, alpha=alpha) painter.fillRect(QRectF(px, py, draw_w, draw_h), brush) - painter.setPen(QPen(QColor(114, 159, 207, min(255, alpha + 40)), 1, Qt.PenStyle.SolidLine)) + painter.setPen( + QPen(qcolor(RASTER_GRID_LINE, min(255, alpha + 40)), 1, Qt.PenStyle.SolidLine) + ) painter.setBrush(Qt.BrushStyle.NoBrush) painter.drawRect(bounds) diff --git a/tests/unit/gui/test_beamline_state_panel.py b/tests/unit/gui/test_beamline_state_panel.py index 1c42d411..3e9bce74 100644 --- a/tests/unit/gui/test_beamline_state_panel.py +++ b/tests/unit/gui/test_beamline_state_panel.py @@ -2,6 +2,7 @@ from aarecommon.models.models import BeamlineStateEnum from PySide6.QtCore import Qt from aare.gui.panels.beamline_state_panel import BeamlineStatePanel +from aare.gui.styles import STATE_AVAILABLE, STATE_MSG_ERROR, STATE_MSG_INFO, STATE_UNAVAILABLE def _panel(qtbot): @@ -47,7 +48,7 @@ def test_active_maintenance_is_red_and_bold(qtbot): panel.set_current_state(BeamlineStateEnum.Maintenance) maintenance = panel._buttons[BeamlineStateEnum.Maintenance] assert maintenance.font().bold() - assert "rgb(200, 30, 30)" in maintenance.styleSheet() + assert STATE_MSG_ERROR in maintenance.styleSheet() def test_availability_palette_and_cursors(qtbot): @@ -55,10 +56,10 @@ def test_availability_palette_and_cursors(qtbot): panel.set_current_state(BeamlineStateEnum.Maintenance) available = panel._buttons[BeamlineStateEnum.SampleExchange] grey = panel._buttons[BeamlineStateEnum.FluxMeasurement] - assert "rgb(237, 137, 54)" in available.styleSheet() + assert STATE_AVAILABLE in available.styleSheet() assert available.cursor().shape() == Qt.CursorShape.PointingHandCursor assert not available.font().bold() - assert "rgb(140, 150, 165)" in grey.styleSheet() + assert STATE_UNAVAILABLE in grey.styleSheet() assert grey.cursor().shape() == Qt.CursorShape.ForbiddenCursor assert grey.toolTip() == "" assert available.toolTip() != "" @@ -69,7 +70,7 @@ def test_active_non_maintenance_is_blue(qtbot): panel.set_current_state(BeamlineStateEnum.SampleAlignment) active = panel._buttons[BeamlineStateEnum.SampleAlignment] assert active.font().bold() - assert "rgb(0, 92, 170)" in active.styleSheet() + assert STATE_MSG_INFO in active.styleSheet() def test_labels_wrap_when_narrow_and_unwrap_when_wide(qtbot): diff --git a/tests/unit/gui/test_panels.py b/tests/unit/gui/test_panels.py index 424fcc78..d6e1113f 100644 --- a/tests/unit/gui/test_panels.py +++ b/tests/unit/gui/test_panels.py @@ -11,6 +11,7 @@ from aarecommon.models.models import ( ) from aare.gui.panels.status_panel import StatusPanel +from aare.gui.styles import STATUS_ALERT @pytest.fixture @@ -84,5 +85,5 @@ def test_status_panel_low_current(qtbot, mock_daq_status): mock_daq_status.bl.ring_current_mA = 300.0 panel.update_daq_status(mock_daq_status) - assert "color: red" in panel.ring_current.text() + assert f"color: {STATUS_ALERT}" in panel.ring_current.text() assert "300.0" in panel.ring_current.text()