style: apply the typography ladder and card_style across the GUI

Inline font-size literals become FONT_* tokens and hand-written card
QSS collapses into card_style() (recovery cards and console-log
notifications keep FLAT_CARD_RADIUS). TitleLabel paints its text by
hand — QSS has no text-shadow — for an embossed banner title, elided
when narrow, and gains a section_title() helper for small in-panel
headings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-11 10:35:46 +02:00
co-authored by Claude Fable 5
parent e63ddb090f
commit 913089b9b6
12 changed files with 212 additions and 137 deletions
+6 -3
View File
@@ -15,6 +15,9 @@ from aare.gui.styles import (
AUTOMATION_TITLE_TEXT,
CARD_BORDER,
FAINT_TEXT,
FONT_BODY,
FONT_LABEL,
FONT_TITLE,
MUTED_TEXT,
STEP_ACTIVE_BG,
STEP_ACTIVE_BORDER,
@@ -62,13 +65,13 @@ class AutomationProgressWidget(QWidget):
self._title_label = QLabel("Automation progress")
self._title_label.setStyleSheet(
f"font-size: 16px; font-weight: 700; color: {AUTOMATION_TITLE_TEXT}; margin-bottom: 2px;"
f"font-size: {FONT_TITLE}; font-weight: 700; color: {AUTOMATION_TITLE_TEXT}; margin-bottom: 2px;"
)
layout.addWidget(self._title_label)
self._stats_label = QLabel()
self._stats_label.setStyleSheet(
f"color: {AUTOMATION_HINT_TEXT}; font-size: 13px; "
f"color: {AUTOMATION_HINT_TEXT}; font-size: {FONT_LABEL}; font-weight: 700; "
f"background-color: {SURFACE}; border: 1px solid {CARD_BORDER}; "
"border-radius: 8px; padding: 10px;"
)
@@ -140,7 +143,7 @@ class AutomationProgressWidget(QWidget):
def _style_for_status(status: StepStatus) -> str:
base = (
"padding: 10px 12px; border-radius: 10px; "
"font-size: 14px; border: 1px solid transparent;"
f"font-size: {FONT_BODY}; border: 1px solid transparent;"
)
if status == StepStatus.SUCCESS:
+64 -54
View File
@@ -23,11 +23,13 @@ from aare.gui.styles import (
CHIP_INFO_TEXT,
CHIP_WARN_BG,
CHIP_WARN_TEXT,
FLAT_CARD_RADIUS,
INFO_CARD_BG,
INFO_CARD_BORDER,
PENDING_CARD_BG,
PENDING_CARD_BORDER,
WARN_CARD_BORDER,
card_style,
)
from aare.gui.threads.daq_worker import DAQWorker
@@ -49,13 +51,14 @@ class RecoveryPanel(QWidget):
)
self._warning_primary.setWordWrap(True)
self._warning_primary.setStyleSheet(
"QLabel {"
f" background: {CHIP_WARN_BG};"
f" color: {CHIP_WARN_TEXT};"
f" border: 1px solid {WARN_CARD_BORDER};"
" padding: 10px;"
" font-weight: 600;"
"}"
card_style(
CHIP_WARN_BG,
WARN_CARD_BORDER,
CHIP_WARN_TEXT,
selector="QLabel",
radius=FLAT_CARD_RADIUS,
extra="padding: 10px; font-weight: 600;",
)
)
layout.addWidget(self._warning_primary)
@@ -65,88 +68,95 @@ class RecoveryPanel(QWidget):
)
self._warning_secondary.setWordWrap(True)
self._warning_secondary.setStyleSheet(
"QLabel {"
f" background: {CHIP_BAD_BG};"
f" color: {CHIP_BAD_TEXT};"
f" border: 1px solid {BAD_CARD_BORDER};"
" padding: 10px;"
" font-weight: 600;"
"}"
card_style(
CHIP_BAD_BG,
BAD_CARD_BORDER,
CHIP_BAD_TEXT,
selector="QLabel",
radius=FLAT_CARD_RADIUS,
extra="padding: 10px; font-weight: 600;",
)
)
layout.addWidget(self._warning_secondary)
self._last_action = QLabel("Last action: -", self)
self._last_action.setWordWrap(True)
self._last_action.setStyleSheet(
"QLabel {"
f" background: {INFO_CARD_BG};"
f" color: {CHIP_INFO_TEXT};"
f" border: 1px solid {INFO_CARD_BORDER};"
" padding: 10px;"
" font-weight: 600;"
"}"
card_style(
INFO_CARD_BG,
INFO_CARD_BORDER,
CHIP_INFO_TEXT,
selector="QLabel",
radius=FLAT_CARD_RADIUS,
extra="padding: 10px; font-weight: 600;",
)
)
layout.addWidget(self._last_action)
self._take_over_btn = QPushButton("Take over beamline", self)
self._take_over_btn.setStyleSheet(
"QPushButton {"
f" background: {PENDING_CARD_BG};"
f" border: 1px solid {PENDING_CARD_BORDER};"
" padding: 10px;"
" font-weight: 600;"
"}"
card_style(
PENDING_CARD_BG,
PENDING_CARD_BORDER,
selector="QPushButton",
radius=FLAT_CARD_RADIUS,
extra="padding: 10px; font-weight: 600;",
)
)
self._take_over_btn.clicked.connect(self._take_over_beamline)
layout.addWidget(self._take_over_btn)
self._free_beamline_btn = QPushButton("Free beamline", self)
self._free_beamline_btn.setStyleSheet(
"QPushButton {"
f" background: {PENDING_CARD_BG};"
f" border: 1px solid {PENDING_CARD_BORDER};"
" padding: 10px;"
" font-weight: 600;"
"}"
card_style(
PENDING_CARD_BG,
PENDING_CARD_BORDER,
selector="QPushButton",
radius=FLAT_CARD_RADIUS,
extra="padding: 10px; font-weight: 600;",
)
)
self._free_beamline_btn.clicked.connect(self._free_beamline)
layout.addWidget(self._free_beamline_btn)
self._recover_beamline_btn = QPushButton("Recover beamline", self)
self._recover_beamline_btn.setStyleSheet(
"QPushButton {"
f" background: {CHIP_BAD_BG};"
f" color: {CHIP_BAD_TEXT};"
f" border: 1px solid {BAD_CARD_BORDER};"
" padding: 10px;"
" font-weight: 700;"
"}"
card_style(
CHIP_BAD_BG,
BAD_CARD_BORDER,
CHIP_BAD_TEXT,
selector="QPushButton",
radius=FLAT_CARD_RADIUS,
extra="padding: 10px; font-weight: 700;",
)
)
self._recover_beamline_btn.clicked.connect(self._recover_beamline)
layout.addWidget(self._recover_beamline_btn)
self._recovery_unmount_btn = QPushButton("Unmount sample (recovery)", self)
self._recovery_unmount_btn.setStyleSheet(
"QPushButton {"
f" background: {CHIP_BAD_BG};"
f" color: {CHIP_BAD_TEXT};"
f" border: 1px solid {BAD_CARD_BORDER};"
" padding: 10px;"
" font-weight: 700;"
"}"
card_style(
CHIP_BAD_BG,
BAD_CARD_BORDER,
CHIP_BAD_TEXT,
selector="QPushButton",
radius=FLAT_CARD_RADIUS,
extra="padding: 10px; font-weight: 700;",
)
)
self._recovery_unmount_btn.clicked.connect(self._recovery_unmount_sample)
layout.addWidget(self._recovery_unmount_btn)
self._resync_sample_btn = QPushButton("Resync sample from TELL", self)
self._resync_sample_btn.setStyleSheet(
"QPushButton {"
f" background: {INFO_CARD_BG};"
f" color: {CHIP_INFO_TEXT};"
f" border: 1px solid {INFO_CARD_BORDER};"
" padding: 10px;"
" font-weight: 600;"
"}"
card_style(
INFO_CARD_BG,
INFO_CARD_BORDER,
CHIP_INFO_TEXT,
selector="QPushButton",
radius=FLAT_CARD_RADIUS,
extra="padding: 10px; font-weight: 600;",
)
)
self._resync_sample_btn.clicked.connect(self._resync_sample)
layout.addWidget(self._resync_sample_btn)
+4 -16
View File
@@ -38,6 +38,7 @@ from aare.gui.styles import (
PANEL_BORDER_DARK,
PANEL_BORDER_LIGHT,
WHITE,
card_style,
)
from aare.gui.threads.daq_worker import DAQWorker
@@ -69,12 +70,7 @@ class DeveloperHelpDialog(QDialog):
self._banner.setWordWrap(True)
self._banner.setTextInteractionFlags(Qt.TextInteractionFlag.TextSelectableByMouse)
self._banner.setStyleSheet(
"QLabel {"
f" background: {PANEL_BG_SOFT};"
f" border: 1px solid {PANEL_BORDER};"
" border-radius: 6px;"
" padding: 6px 8px;"
"}"
card_style(PANEL_BG_SOFT, PANEL_BORDER, selector="QLabel", extra="padding: 6px 8px;")
)
root.addWidget(self._banner)
@@ -153,10 +149,7 @@ class DeveloperHelpDialog(QDialog):
self._details_frame = QFrame(self)
self._details_frame.setFrameShape(QFrame.Shape.StyledPanel)
self._details_frame.setStyleSheet(
f"QFrame {{ background: {PANEL_BG_FAINT}; border: 1px solid {PANEL_BORDER};"
" border-radius: 6px;}"
)
self._details_frame.setStyleSheet(card_style(PANEL_BG_FAINT, PANEL_BORDER))
details_layout = QVBoxLayout(self._details_frame)
details_layout.setContentsMargins(10, 10, 10, 10)
@@ -186,12 +179,7 @@ class DeveloperHelpDialog(QDialog):
self._detail_help.setWordWrap(True)
self._detail_help.setTextInteractionFlags(Qt.TextInteractionFlag.TextSelectableByMouse)
self._detail_help.setStyleSheet(
"QLabel {"
f" background: {WHITE};"
f" border: 1px solid {PANEL_BORDER_LIGHT};"
" border-radius: 6px;"
" padding: 8px;"
"}"
card_style(WHITE, PANEL_BORDER_LIGHT, selector="QLabel", extra="padding: 8px;")
)
details_layout.addWidget(QLabel("Help:", self))
details_layout.addWidget(self._detail_help, 1)
+2 -2
View File
@@ -37,6 +37,7 @@ from aare.gui.styles import (
CHIP_BAD_TEXT,
HEADING_TEXT,
SURFACE,
card_style,
)
from aare.gui.threads.daq_worker import DAQWorker
from aare.gui.widgets.local_contact_status_widget import LocalContactStatusWidget
@@ -121,8 +122,7 @@ class LocalContactPanel(QFrame):
self._transfer_error_frame = QFrame(self)
self._transfer_error_frame.setVisible(False)
self._transfer_error_frame.setStyleSheet(
f"QFrame {{ background: {CHIP_BAD_BG}; color: {CHIP_BAD_TEXT};"
f" border: 1px solid {BAD_CARD_BORDER};}}"
card_style(CHIP_BAD_BG, BAD_CARD_BORDER, CHIP_BAD_TEXT)
)
transfer_error_layout = QVBoxLayout(self._transfer_error_frame)
transfer_error_layout.setContentsMargins(10, 10, 10, 10)
+38 -26
View File
@@ -14,6 +14,7 @@ from PySide6.QtWidgets import (
from aare.gui.log import QtLogEmitter, QtLogHandler
from aare.gui.styles import (
FLAT_CARD_RADIUS,
LOG_BORDER,
LOG_ERROR_BG,
LOG_ERROR_BORDER,
@@ -24,6 +25,7 @@ from aare.gui.styles import (
LOG_SUCCESS_BORDER,
LOG_WARN_BG,
LOG_WARN_BORDER,
card_style,
)
@@ -72,6 +74,7 @@ class RuntimeNotificationWidget(QFrame):
button_layout.addWidget(self._clear_button)
self._body = QWidget(self)
self._body.setObjectName("runtimeNotificationBody")
body_layout = QVBoxLayout(self._body)
body_layout.setContentsMargins(0, 0, 0, 0)
body_layout.setSpacing(8)
@@ -90,32 +93,41 @@ class RuntimeNotificationWidget(QFrame):
self._sticky = True
self.setStyleSheet(
f"""
QFrame#runtimeNotification {{
border: 1px solid {LOG_BORDER};
border-radius: 8px;
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;
}}
"""
card_style(
LOG_PANEL_BG,
LOG_BORDER,
selector="QFrame#runtimeNotification",
radius=FLAT_CARD_RADIUS,
)
+ card_style(
LOG_ERROR_BG,
LOG_ERROR_BORDER,
selector='QFrame#runtimeNotification[noticeLevel="error"]',
radius=FLAT_CARD_RADIUS,
)
+ card_style(
LOG_WARN_BG,
LOG_WARN_BORDER,
selector='QFrame#runtimeNotification[noticeLevel="warning"]',
radius=FLAT_CARD_RADIUS,
)
+ card_style(
LOG_SUCCESS_BG,
LOG_SUCCESS_BORDER,
selector='QFrame#runtimeNotification[noticeLevel="success"]',
radius=FLAT_CARD_RADIUS,
)
+ card_style(
LOG_INFO_BG,
LOG_INFO_BORDER,
selector='QFrame#runtimeNotification[noticeLevel="info"]',
radius=FLAT_CARD_RADIUS,
)
# Transparent children: the app-wide QWidget background rule would
# otherwise paint opaque strips over the card tint.
+ " QLabel#runtimeNotificationTitle { font-weight: bold; background: transparent; }"
+ " QLabel#runtimeNotificationMessage { background: transparent; }"
+ " QWidget#runtimeNotificationBody { background: transparent; }"
)
def _set_level(self, level: str) -> None:
+23 -16
View File
@@ -32,6 +32,11 @@ from aare.gui.styles import (
DARK_SUCCESS_BG,
DARK_SUCCESS_BORDER,
DARK_SUCCESS_TEXT,
FONT_FINE,
FONT_HERO,
FONT_HINT,
FONT_LABEL,
FONT_VALUE,
WHITE,
qcolor,
)
@@ -213,13 +218,13 @@ class QueueItemCard(QFrame):
badge.setText("")
badge.setStyleSheet(f"""
color: {ACCENT}; background: {ACCENT_DIM};
border-radius: 16px; font-size: 12px; font-weight: bold;
border-radius: 16px; font-size: {FONT_HINT}; font-weight: bold;
""")
else:
badge.setText(str(index))
badge.setStyleSheet(f"""
color: {SUBTEXT}; background: {BUTTON_BG};
border-radius: 16px; font-size: 12px;
border-radius: 16px; font-size: {FONT_HINT};
""")
layout.addWidget(badge)
@@ -229,11 +234,11 @@ class QueueItemCard(QFrame):
title_lbl = QLabel(title)
title_lbl.setStyleSheet(
f"color: {TEXT}; font-size: 13px; font-weight: 600; background: transparent;"
f"color: {TEXT}; font-size: {FONT_LABEL}; font-weight: 700; background: transparent;"
)
title_lbl.setWordWrap(False)
sub_lbl = QLabel(subtitle)
sub_lbl.setStyleSheet(f"color: {SUBTEXT}; font-size: 11px; background: transparent;")
sub_lbl.setStyleSheet(f"color: {SUBTEXT}; font-size: {FONT_FINE}; background: transparent;")
text_col.addWidget(title_lbl)
text_col.addWidget(sub_lbl)
layout.addLayout(text_col, stretch=1)
@@ -292,7 +297,7 @@ class PortraitModePanel(QWidget):
title = QLabel("S A M C A M E R A")
title.setAlignment(Qt.AlignCenter)
title.setStyleSheet(
f"color: {ACCENT}; font-size: 13px; letter-spacing: 3px; font-weight: 600;"
f"color: {ACCENT}; font-size: {FONT_LABEL}; letter-spacing: 3px; font-weight: 700;"
)
layout.addWidget(title)
@@ -311,7 +316,7 @@ class PortraitModePanel(QWidget):
self._alert_toast_label = QLabel("")
self._alert_toast_label.setWordWrap(True)
self._alert_toast_label.setStyleSheet(
f"color: {DARK_ERROR_TEXT}; font-size: 11px; font-weight: 600; background: transparent;"
f"color: {DARK_ERROR_TEXT}; font-size: {FONT_FINE}; font-weight: 600; background: transparent;"
)
toast_layout.addWidget(self._alert_toast_label)
# Dismiss button
@@ -322,7 +327,7 @@ class PortraitModePanel(QWidget):
color: {SUBTEXT};
background: transparent;
border: none;
font-size: 11px;
font-size: {FONT_FINE};
}}
QPushButton:hover {{ color: {TEXT}; }}
""")
@@ -347,9 +352,9 @@ class PortraitModePanel(QWidget):
# Sample name labels
self._name_lbl = QLabel("")
self._name_lbl.setStyleSheet(f"color: {TEXT}; font-size: 18px; font-weight: 700;")
self._name_lbl.setStyleSheet(f"color: {TEXT}; font-size: {FONT_VALUE}; font-weight: 700;")
self._sub_lbl = QLabel("No sample queued")
self._sub_lbl.setStyleSheet(f"color: {SUBTEXT}; font-size: 12px;")
self._sub_lbl.setStyleSheet(f"color: {SUBTEXT}; font-size: {FONT_HINT};")
layout.addWidget(self._name_lbl)
layout.addWidget(self._sub_lbl)
@@ -381,7 +386,7 @@ class PortraitModePanel(QWidget):
border-radius: 26px;
background: {BUTTON_BG};
color: {ACCENT};
font-size: 28px;
font-size: {FONT_HERO};
font-weight: bold;
}}
QPushButton:checked {{
@@ -408,11 +413,11 @@ class PortraitModePanel(QWidget):
up_next_row = QHBoxLayout()
up_next_lbl = QLabel("UP NEXT")
up_next_lbl.setStyleSheet(
f"color: {ACCENT}; font-size: 11px; letter-spacing: 2px; font-weight: 700;"
f"color: {ACCENT}; font-size: {FONT_FINE}; letter-spacing: 2px; font-weight: 700;"
)
self._samples_count_lbl = QLabel("0 SAMPLES")
self._samples_count_lbl.setStyleSheet(
f"color: {SUBTEXT}; font-size: 11px; letter-spacing: 1px;"
f"color: {SUBTEXT}; font-size: {FONT_FINE}; letter-spacing: 1px;"
)
up_next_row.addWidget(up_next_lbl)
up_next_row.addStretch()
@@ -460,7 +465,7 @@ class PortraitModePanel(QWidget):
title = QLabel("SAMPLE QUEUE")
title.setAlignment(Qt.AlignCenter)
title.setStyleSheet(
f"color: {ACCENT}; font-size: 13px; letter-spacing: 3px; font-weight: 700;"
f"color: {ACCENT}; font-size: {FONT_LABEL}; letter-spacing: 3px; font-weight: 700;"
)
layout.addWidget(title)
@@ -598,7 +603,9 @@ class PortraitModePanel(QWidget):
if not samples:
placeholder = QLabel("No samples in queue")
placeholder.setStyleSheet(f"color: {SUBTEXT}; font-size: 13px;")
placeholder.setStyleSheet(
f"color: {SUBTEXT}; font-size: {FONT_LABEL}; font-weight: 700;"
)
placeholder.setAlignment(Qt.AlignCenter)
self._queue_inner_layout.addWidget(placeholder)
return
@@ -634,7 +641,7 @@ class PortraitModePanel(QWidget):
border: 1.5px solid {ACCENT};
border-radius: 14px;
color: {ACCENT};
font-size: 12px;
font-size: {FONT_HINT};
font-weight: 700;
letter-spacing: 1.5px;
}}
@@ -677,7 +684,7 @@ class PortraitModePanel(QWidget):
}}
""")
self._alert_toast_label.setStyleSheet(
f"color: {text_color}; font-size: 11px; font-weight: 600; background: transparent;"
f"color: {text_color}; font-size: {FONT_FINE}; font-weight: 600; background: transparent;"
)
self._alert_toast.setVisible(True)
@@ -49,6 +49,8 @@ from aare.gui.styles import (
CHART_ORANGE,
CHART_RED,
CONFIDENCE_BIN_COLORS,
FONT_BODY,
FONT_TITLE,
qcolor,
)
from aare.gui.styles import CHART_CLASS_COLORS as CLASS_COLORS
@@ -208,7 +210,7 @@ class ObjectCountWidget(QWidget):
# Create colored indicator square
indicator = QLabel("")
indicator.setStyleSheet(f"color: {color}; font-size: 16px;")
indicator.setStyleSheet(f"color: {color}; font-size: {FONT_TITLE};")
indicator.setFixedWidth(20)
# Class name label
@@ -217,7 +219,7 @@ class ObjectCountWidget(QWidget):
# Count label with matching color
count_label = QLabel("0")
count_label.setStyleSheet(f"color: {color}; font-size: 14px; font-weight: bold;")
count_label.setStyleSheet(f"color: {color}; font-size: {FONT_BODY}; font-weight: bold;")
count_label.setAlignment(Qt.AlignmentFlag.AlignRight)
row = i // 2
+8 -6
View File
@@ -21,6 +21,8 @@ from PySide6.QtWidgets import QLabel, QPushButton, QWidget
from aare.gui.constants import LOGGER_NAME
from aare.gui.styles import (
DEFAULT_TEXT,
FONT_BODY_LG,
FONT_TITLE,
NOTE_TEXT,
SHADOW,
TUTORIAL_BORDER,
@@ -110,17 +112,17 @@ class TutorialOverlay(QWidget):
padding: 16px;
border: 2px solid {TUTORIAL_BORDER};
border-radius: 10px;
font-size: 16px;
font-size: {FONT_TITLE};
""")
self.callout.setWordWrap(True)
self.callout.hide()
button_style = """
QPushButton {
font-size: 15px;
font-weight: 600;
button_style = f"""
QPushButton {{
font-size: {FONT_BODY_LG};
font-weight: 700;
padding: 10px 16px;
}
}}
"""
self.back_button = QPushButton("Back", self)
+4 -2
View File
@@ -9,6 +9,8 @@ from PySide6.QtWidgets import QFrame, QHBoxLayout, QLabel, QVBoxLayout, QWidget
from aare.gui.styles import (
FAINT_TEXT,
FONT_HINT,
FONT_VALUE,
STEP_FAILED_TEXT,
STEP_PAUSED_TEXT,
STEP_RUNNING_TEXT,
@@ -111,8 +113,8 @@ class CompactAutomationProgressStrip(QFrame):
title = self._step_title(step)
return (
f"<div style='text-align:center; background:transparent;'>"
f"<div style='font-size:18px; color:{color}; font-weight:700; background:transparent;'>{icon}</div>"
f"<div style='font-size:12px; color:{color}; font-weight:700; background:transparent;'>{title}</div>"
f"<div style='font-size:{FONT_VALUE}; color:{color}; font-weight:700; background:transparent;'>{icon}</div>"
f"<div style='font-size:{FONT_HINT}; color:{color}; font-weight:700; background:transparent;'>{title}</div>"
f"</div>"
)
+8 -4
View File
@@ -20,6 +20,8 @@ from aare.gui.styles import (
BATON_OK_PRESSED,
BATON_WARN,
DIM_TEXT,
FONT_BODY,
FONT_LABEL,
HINT_TEXT,
LIGHT_BORDER,
PROGRESS_TRACK_BG,
@@ -129,7 +131,7 @@ class BatonRequestDialog(QDialog):
border: none;
border-radius: 5px;
font-weight: bold;
font-size: 13px;
font-size: {FONT_LABEL};
}}
QPushButton:hover {{
background-color: {BATON_OK_HOVER};
@@ -150,7 +152,7 @@ class BatonRequestDialog(QDialog):
border: none;
border-radius: 5px;
font-weight: bold;
font-size: 13px;
font-size: {FONT_LABEL};
}}
QPushButton:hover {{
background-color: {BATON_DANGER_HOVER};
@@ -316,7 +318,7 @@ class BatonPendingDialog(QDialog):
border: none;
border-radius: 5px;
font-weight: bold;
font-size: 13px;
font-size: {FONT_LABEL};
}}
QPushButton:hover {{ background-color: {BATON_DANGER_HOVER}; }}
QPushButton:pressed {{ background-color: {BATON_DANGER_PRESSED}; }}
@@ -348,7 +350,9 @@ class BatonPendingDialog(QDialog):
def set_queued_state(self):
self._timer.stop()
self.header.setText("⏳ Transfer Queued")
self.header.setStyleSheet(f"color: {BATON_WARN}; font-weight: bold; font-size: 14px;")
self.header.setStyleSheet(
f"color: {BATON_WARN}; font-weight: bold; font-size: {FONT_BODY};"
)
self.message_label.setText(
"The beamline is currently <b>busy</b>. Your request was accepted and "
"the baton will be transferred as soon as the current operation completes."
+2 -2
View File
@@ -9,7 +9,7 @@ from PySide6.QtWidgets import (
)
from aare.gui.scan_logic.raster_grid_manager import RasterGridManager
from aare.gui.styles import TABLE_SHADE_BG
from aare.gui.styles import FONT_BODY, TABLE_SHADE_BG
class RasterGridTable(QTableWidget):
@@ -70,7 +70,7 @@ class RasterGridTable(QTableWidget):
QPushButton {{
border: none;
background: transparent;
font-size: 14px;
font-size: {FONT_BODY};
}}
QPushButton:hover {{
background-color: {TABLE_SHADE_BG};
+49 -4
View File
@@ -1,7 +1,17 @@
from PySide6.QtCore import QSettings, Qt, QTimer
from PySide6.QtWidgets import QHBoxLayout, QLabel, QLayout, QPushButton
from PySide6.QtGui import QPainter
from PySide6.QtWidgets import QHBoxLayout, QLabel, QLayout, QPushButton, QStyle, QStyleOption
from aare.gui.styles import BANNER, BANNER_TEXT
from aare.gui.styles import (
BANNER,
BANNER_TEXT,
BANNER_TEXT_SHADOW,
FONT_BODY,
FONT_HINT,
FONT_TITLE,
MUTED_TEXT,
qcolor,
)
# Universal vertical rhythm between stacked panels: each panel contributes
# PANEL_VMARGIN top and bottom, the column adds PANEL_VSPACING between them,
@@ -26,6 +36,17 @@ def tighten_column(layout: QLayout) -> None:
child_layout.setContentsMargins(m.left(), PANEL_VMARGIN, m.right(), PANEL_VMARGIN)
def section_title(text: str, parent=None) -> QLabel:
"""Small in-panel section heading — for controls grouped under one
shared TitleLabel banner (e.g. the Beam Config. panel)."""
label = QLabel(text, parent)
label.setAlignment(Qt.AlignmentFlag.AlignCenter)
label.setStyleSheet(
f"color: {MUTED_TEXT}; font-size: {FONT_HINT}; font-weight: 700; background: transparent;"
)
return label
class TitleLabel(QLabel):
def __init__(self, text: str, parent=None, collapsible: bool = False):
super().__init__(parent)
@@ -37,7 +58,7 @@ class TitleLabel(QLabel):
# the app QSS.
self.setStyleSheet(
f"TitleLabel {{ background-color: {BANNER}; color: {BANNER_TEXT};"
" font-size: 16px; font-weight: 700; }"
f" font-size: {FONT_TITLE}; font-weight: 700; }}"
)
self.setAlignment(Qt.AlignmentFlag.AlignCenter)
@@ -58,7 +79,7 @@ class TitleLabel(QLabel):
# a translucent white background, which is unwanted on these banners.
self.toggle_button.setStyleSheet(
f"QPushButton {{ background: transparent; border: none;"
f" color: {BANNER_TEXT}; font-size: 14px; font-weight: 700; }}"
f" color: {BANNER_TEXT}; font-size: {FONT_BODY}; font-weight: 700; }}"
)
self.toggle_button.setToolTip("Minimise panel")
self.toggle_button.setFixedSize(21, 21)
@@ -82,6 +103,30 @@ class TitleLabel(QLabel):
# the TitleLabel, so siblings don't exist yet.
QTimer.singleShot(0, self._apply_collapsed)
def paintEvent(self, event):
# QSS has no text-shadow, so paint by hand: the QSS background box
# first, then the title twice — an offset dark pass under the normal
# one — for the subtle emboss the OS titlebar text has.
painter = QPainter(self)
opt = QStyleOption()
opt.initFrom(self)
self.style().drawPrimitive(QStyle.PrimitiveElement.PE_Widget, opt, painter, self)
flags = int(self.alignment())
# Reserve the toggle-button zone (21px + 8px margin) on BOTH sides in
# the text rect only — widget margins would move the button itself.
reserve = 29 if self._collapsible else 0
rect = self.rect().adjusted(reserve, 0, -reserve, 0)
painter.setFont(self.font())
# Elide instead of overflowing when the panel column is narrow.
text = painter.fontMetrics().elidedText(
self.text(), Qt.TextElideMode.ElideRight, rect.width()
)
painter.setPen(qcolor(BANNER_TEXT_SHADOW, 110))
painter.drawText(rect.translated(0, 1), flags, text)
painter.setPen(qcolor(BANNER_TEXT))
painter.drawText(rect, flags, text)
def mousePressEvent(self, event):
if self._collapsible:
self.toggle_collapsed()