style: extend the palette with selection, frame, slider, and sample-status tokens

SELECTION_BG/TEXT pin the app-wide selection blue to the banner color
(was Qt's undeclared palette default); FRAME_L1/L2/L3 knobs put window,
panel, and data-view borders on three tunable levels (panel etching off
by default); QTabBar tabs and filter chips go borderless with a hover
underline; QSlider matches the scrollbar look; scrollbar tracks turn
square with a track-colored corner; SAMPLE_STATUS_* and
SAMPLE_ROW_ALT_BG drive the sample-table status tints.

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 efcdc0c191
commit 0bfa9dbbeb
+245 -15
View File
@@ -26,6 +26,37 @@ BORDER = "transparent" # main dividers, e.g. the beamline state bar top line
CARD_BORDER = "transparent" # cards / group boxes (Local Contact, automation)
COMPACT_BORDER = "transparent" # compact-automation cards and buttons
# -- Box-frame borders by nesting level -------------------------------------
# One knob per level so the amount of "boxing" is tunable in one place:
# L1: top-level pop-out window edge (painted by PopoutWindow)
# L2: panel frames inside a dock/tab (TELL sample changer, reference
# tools, sample queue) — transparent by default: banner + table
# already delimit the panel, extra boxes read as clutter
# L3: data views (tables, log text) — a light line so scrollable content
# keeps a visible edge
# (The tab-widget pane is a fourth box, already governed by BORDER above.)
FRAME_L1_WIDTH = "0px" # default off — the pop-out reads as one clean surface
FRAME_L1_COLOR = "#bdbdbd"
FRAME_L2_WIDTH = "0px"
FRAME_L2_COLOR = "transparent"
FRAME_L3_WIDTH = "1px"
FRAME_L3_COLOR = "#c9cfd8"
# Left inset (px, int — used in code, not QSS) for bottom-dock content so its
# left edge lines up with the left-column panels above (Loop centering).
DOCK_CONTENT_LEFT_PAD = 10
# Tab face fill: the selected Dewar/Auxiliary tab AND the unchecked
# All/Queued/Flagged/Measured filter buttons share this background.
TAB_FACE_BG = "#ffffff"
# Selection highlight (combo popups, menus, list rows, text selections).
# Qt's style palette used to supply its own blue here; now it is the banner
# blue, and THIS is the knob for it. (Table-row selection has its own paler
# knob: SAMPLE_STATUS_SELECTED_BG.)
SELECTION_BG = BANNER
SELECTION_TEXT = "#263043" # same as TEXT — readable on the banner blue
# Compact-automation page:
COMPACT_CARD_BG = "#e6eefc"
COMPACT_TITLE = "#17324d" # section titles + menu/secondary button text
@@ -194,11 +225,20 @@ STATE_MSG_INFO = "#005caa"
# -- Sample tables + raster grid --------------------------------------------
SAMPLE_ROW_ACTIVE_BG = "#ff6600"
SAMPLE_ROW_QUEUED_BG = "#729fcf"
SAMPLE_ROW_QUEUED_BG = "#729fcf" # mounted/current-sample row (legacy name)
SAMPLE_ROW_HIGHLIGHT_BG = "#d8e4fd"
RASTER_GRID_LINE = "#729fcf"
TABLE_SHADE_BG = "#e0e0e0"
# -- Sample status row tints (dewar/queue view) -----------------------------
# Status colors now fill the rounded dot in the table's status column; rows
# themselves alternate WHITE / SAMPLE_ROW_ALT_BG. Tune the palette here.
SAMPLE_ROW_ALT_BG = "#eef1f5" # staggered row grey (alternates with white)
SAMPLE_STATUS_QUEUED_BG = "#ffe4c4" # pale orange — waiting in the automation queue
SAMPLE_STATUS_FLAGGED_BG = "#ffd9d9" # pale red — automation failed on this sample
SAMPLE_STATUS_MEASURED_BG = "#dcf2e0" # pale green — already has collected data
SAMPLE_STATUS_SELECTED_BG = "#d8e8fd" # pale blue — table selection highlight
# -- Camera / video overlay (painter colors, alpha at call site) ------------
BEAM_OPEN = "#00ff00" # beam marker: shutter open
BEAM_IDLE = "#f57900" # beam marker: idle
@@ -307,6 +347,11 @@ TOOLTIP_FG = "#263043"
DARK_TOOLTIP_BG = "#363a4f" # surface0
DARK_TOOLTIP_FG = "#cad3f5" # text
# -- Sliders ----------------------------------------------------------------
# Own knob instead of PRIMARY: full-saturation button blue was too loud for a
# passive fill (illumination panel). Muted slate-blue, tweak freely.
SLIDER_FILL = "#8ba3c7"
# -- Scrollbars (rounded, no arrows: grey track, darker draggable handle) ---
SCROLLBAR_TRACK = "#d8dde5"
SCROLLBAR_HANDLE = "#a8b2c0"
@@ -542,10 +587,59 @@ def _original_stylesheet() -> str:
font-weight: bold;
}
/* Disabled = baton-gated ("watch only"): the explicit colors above mask
Qt's native grey, so spell the greyed state out. */
QPushButton:disabled, QCheckBox:disabled, QRadioButton:disabled,
QLabel:disabled, QComboBox:disabled, QLineEdit:disabled,
QAbstractSpinBox:disabled, QTabBar::tab:disabled {
color: $faint_text;
}
QLineEdit:disabled, QAbstractSpinBox:disabled, QComboBox:disabled {
background: $scrollbar_track;
}
QSlider::sub-page:horizontal:disabled {
background: $scrollbar_handle;
}
QTabWidget::pane {
border: 1px solid $border;
}
/* Exp. Config. pane: hand-rolled QTabBar+QStackedWidget (button row sits
between bar and pages), so it needs the pane border by hand too. */
#expConfigPane {
border: 1px solid $border;
}
/* Borderless tabs: the pane isn't outlined, so the native 3-side tab
boxes hung in the air. Selection shows via fill + the raised effect
(unselected tabs sit 3px lower). */
QTabBar::tab {
background: transparent;
border: none;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
padding: 4px 14px;
margin-top: 3px;
color: $muted_text;
}
QTabBar::tab:selected {
background: $tab_face_bg;
color: $text;
margin-top: 0px;
padding: 6px 14px 5px 14px;
}
/* Menu-bar-style hover hint: text-decoration underlines only the text
itself (short, close to the baseline) instead of the full tab box. */
QTabBar::tab:hover:!selected {
color: $text;
text-decoration: underline;
}
QMainWindow::separator {
background: $border;
width: 4px;
@@ -594,18 +688,78 @@ def _original_stylesheet() -> str:
background: transparent;
}
/* Plain scroll containers stay frameless; data views (tables, trees,
text/log views) keep their native frame — those borders are wanted. */
/* Plain scroll containers stay frameless. */
QScrollArea {
border: none;
}
/* Soft scrollbars: rounded track + draggable handle, no end arrows. */
/* Box-frame levels — weights/colors are knobs in styles.py. L2: panel
frames (replaces their native StyledPanel etching); L3: data views. */
TellSamplePanel, ReferenceToolsPanel, SampleQueuePanel {
border: $frame_l2_width solid $frame_l2_color;
}
QTableView, QPlainTextEdit {
border: $frame_l3_width solid $frame_l3_color;
}
/* Pale-blue selection with readable dark text in every sample table;
staggered grey/white rows where alternation is enabled. */
QTableView {
background: $white;
alternate-background-color: $sample_row_alt_bg;
selection-background-color: $sample_status_selected_bg;
selection-color: $text;
}
/* Selection highlight: the banner blue (SELECTION_BG in styles.py)
instead of the style palette's own blue. Tables keep their paler
selection rule below. */
QListView, QTreeView,
QComboBox QAbstractItemView {
selection-background-color: $selection_bg;
selection-color: $selection_text;
}
QMenu::item:selected {
background: $selection_bg;
color: $selection_text;
}
QLineEdit, QAbstractSpinBox, QTextEdit, QPlainTextEdit {
selection-background-color: $selection_bg;
selection-color: $selection_text;
}
/* Sliders: rounded groove ends (like the scrollbar handles) + round
handle. Wheel adjustment needs the right mouse button held — see
WheelValueGuard. */
QSlider::groove:horizontal {
height: 6px;
background: $scrollbar_track;
border-radius: 3px;
}
QSlider::sub-page:horizontal {
background: $slider_fill;
border-radius: 3px;
}
QSlider::handle:horizontal {
background: $white;
border: 1px solid $scrollbar_handle;
width: 14px;
margin: -5px 0;
border-radius: 7px;
}
/* Soft scrollbars: square track band (runs flush to the widget edges —
rounded ends left corner notches in the tables) + rounded draggable
handle, no end arrows. */
QScrollBar:vertical {
background: $scrollbar_track;
width: 10px;
border: none;
border-radius: 5px;
margin: 0px;
}
@@ -613,7 +767,6 @@ def _original_stylesheet() -> str:
background: $scrollbar_track;
height: 10px;
border: none;
border-radius: 5px;
margin: 0px;
}
@@ -645,9 +798,10 @@ def _original_stylesheet() -> str:
background: transparent;
}
/* Kill the square filler where the two scrollbars meet. */
/* The two scrollbar bands meet in a track-colored corner — no white
square, the bands read as one continuous edge. */
QAbstractScrollArea::corner {
background: transparent;
background: $scrollbar_track;
border: none;
}
@@ -705,6 +859,30 @@ def _portrait_stylesheet() -> str:
color: $dark_text;
}
/* Borderless tabs, dark flavor — see the light-theme note. */
QTabBar::tab {
background: transparent;
border: none;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
padding: 4px 14px;
margin-top: 3px;
color: $dark_muted;
}
QTabBar::tab:selected {
background: $dark_elevated;
color: $dark_text;
margin-top: 0px;
padding: 6px 14px 5px 14px;
}
/* Menu-bar-style hover hint — see the light-theme note. */
QTabBar::tab:hover:!selected {
color: $dark_text;
text-decoration: underline;
}
/* Borderless hover hints. The transparent border is required — QToolTip
only honours the stylesheet background once a border is set. */
QToolTip {
@@ -901,18 +1079,71 @@ def _portrait_stylesheet() -> str:
background: transparent;
}
/* Plain scroll containers stay frameless; data views (tables, trees,
text/log views) keep their native frame — those borders are wanted. */
/* Plain scroll containers stay frameless. */
QScrollArea {
border: none;
}
/* Soft scrollbars: rounded track + draggable handle, no end arrows. */
/* Box-frame levels — weights/colors are knobs in styles.py. */
TellSamplePanel, ReferenceToolsPanel, SampleQueuePanel {
border: $frame_l2_width solid $frame_l2_color;
}
QTableView, QPlainTextEdit {
border: $frame_l3_width solid $frame_l3_color;
}
/* Selection + staggered rows, dark flavor. */
QTableView {
background: $dark_bg;
alternate-background-color: $dark_surface;
selection-background-color: $sample_status_selected_bg;
selection-color: $text;
}
/* Selection highlight — same banner-blue knob as the light theme. */
QListView, QTreeView,
QComboBox QAbstractItemView {
selection-background-color: $selection_bg;
selection-color: $selection_text;
}
QMenu::item:selected {
background: $selection_bg;
color: $selection_text;
}
QLineEdit, QAbstractSpinBox, QTextEdit, QPlainTextEdit {
selection-background-color: $selection_bg;
selection-color: $selection_text;
}
/* Sliders, dark flavor — see the light-theme note. */
QSlider::groove:horizontal {
height: 6px;
background: $dark_border;
border-radius: 3px;
}
QSlider::sub-page:horizontal {
background: $dark_accent;
border-radius: 3px;
}
QSlider::handle:horizontal {
background: $dark_elevated;
border: 1px solid $dark_muted;
width: 14px;
margin: -5px 0;
border-radius: 7px;
}
/* Soft scrollbars: square track band + rounded handle, no end arrows
(see light-theme note on the corner notches). */
QScrollBar:vertical {
background: $dark_surface;
width: 10px;
border: none;
border-radius: 5px;
margin: 0px;
}
@@ -920,7 +1151,6 @@ def _portrait_stylesheet() -> str:
background: $dark_surface;
height: 10px;
border: none;
border-radius: 5px;
margin: 0px;
}
@@ -952,9 +1182,9 @@ def _portrait_stylesheet() -> str:
background: transparent;
}
/* Kill the square filler where the two scrollbars meet. */
/* The two scrollbar bands meet in a track-colored corner. */
QAbstractScrollArea::corner {
background: transparent;
background: $dark_surface;
border: none;
}