feat: let panels opt out of starting collapsed

TitleLabel gains default_collapsed; the small motor/light panels start
open (their per-title persisted choice still wins).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-07 17:08:22 +02:00
co-authored by Claude Fable 5
parent 09b560ec7d
commit 3d58ae59cc
6 changed files with 38 additions and 10 deletions
+1 -1
View File
@@ -41,7 +41,7 @@ class FilePathPanel(QWidget):
self._formatted_date = datetime.now().strftime("%Y%m%d")
grid_layout.addWidget(TitleLabel("Dataset path", self, collapsible=True), 0, 0, 1, 2)
grid_layout.addWidget(TitleLabel("Dataset path", self, collapsible=True, default_collapsed=False), 0, 0, 1, 2)
grid_layout.addWidget(QLabel("Directory", parent=self), 1, 0)
self.directory_edit = QLineEdit("{date}/{puck}/{pos}", parent=self)
+1 -1
View File
@@ -13,7 +13,7 @@ class IlluminationPanel(QWidget):
super().__init__(parent)
grid_layout = QGridLayout(self)
grid_layout.addWidget(TitleLabel("Light", self, collapsible=True), 0, 0, 1, 2)
grid_layout.addWidget(TitleLabel("Light", self, collapsible=True, default_collapsed=False), 0, 0, 1, 2)
front_label = QLabel("Front light", parent=self)
front_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
+1 -1
View File
@@ -29,7 +29,7 @@ class OmegaPanel(QWidget):
grid_layout = QGridLayout(self)
grid_layout.addWidget(TitleLabel("Omega", self, collapsible=True), 0, 0, 1, 2)
grid_layout.addWidget(TitleLabel("Omega", self, collapsible=True, default_collapsed=False), 0, 0, 1, 2)
grid_layout.setColumnStretch(0, 1)
grid_layout.setColumnStretch(1, 1)
omega_settings = [
+1 -1
View File
@@ -58,7 +58,7 @@ class SmargonPanel(QWidget):
grid_layout = QGridLayout(self)
grid_layout.addWidget(TitleLabel("Smargon", self, collapsible=True), 0, 0, 1, 6)
grid_layout.addWidget(TitleLabel("Smargon", self, collapsible=True, default_collapsed=False), 0, 0, 1, 6)
grid_layout.addWidget(QLabel("Chi", parent=self), 1, 0)
self.chi_enter = NumberLineEdit(-0.2, 40, decimals=1, parent=self)
+1 -1
View File
@@ -23,7 +23,7 @@ class ZoomPanel(QWidget):
{"name": "7.5x", "value": 800},
{"name": "12.5x", "value": 1000},
]
grid_layout.addWidget(TitleLabel("Zoom", self, collapsible=True), 0, 0, 1, 2)
grid_layout.addWidget(TitleLabel("Zoom", self, collapsible=True, default_collapsed=False), 0, 0, 1, 2)
i = 2
self._buttons = []
+33 -5
View File
@@ -48,7 +48,13 @@ def section_title(text: str, parent=None) -> QLabel:
class TitleLabel(QLabel):
def __init__(self, text: str, parent=None, collapsible: bool = False):
def __init__(
self,
text: str,
parent=None,
collapsible: bool = False,
default_collapsed: bool = True,
):
super().__init__(parent)
# Plain text + QSS font instead of <H3>: rich-text heading margins
# would clip vertically in the halved banner height.
@@ -94,10 +100,9 @@ class TitleLabel(QLabel):
self.setCursor(Qt.CursorShape.PointingHandCursor)
settings = QSettings("PSI", "AareGUI")
# Default collapsed: a fresh GUI shows only banners (plus the expanded
# Beamline state panel, which manages its own default) until the user
# opens what they need; their choice is then persisted per title.
if settings.value(self._settings_key, True, type=bool):
# Per-panel default (collapsed unless the caller opts out); once the
# user toggles a banner, their choice is persisted per title and wins.
if settings.value(self._settings_key, default_collapsed, type=bool):
self._collapsed = True
# Deferred: the panel adds its other widgets after constructing
# the TitleLabel, so siblings don't exist yet.
@@ -136,10 +141,33 @@ class TitleLabel(QLabel):
if self._collapsible and self._collapsed:
self.toggle_collapsed()
def is_collapsed(self) -> bool:
return bool(self._collapsible and self._collapsed)
def set_collapsed(self, collapsed: bool, persist: bool = True) -> None:
# persist=False: transient programmatic fold (e.g. the session-vacant
# gate) that must not overwrite the user's saved per-panel choice.
if not self._collapsible or collapsed == self._collapsed:
return
self._collapsed = collapsed
self._apply_collapsed()
if persist:
QSettings("PSI", "AareGUI").setValue(self._settings_key, self._collapsed)
def toggle_collapsed(self) -> None:
self._collapsed = not self._collapsed
self._apply_collapsed()
QSettings("PSI", "AareGUI").setValue(self._settings_key, self._collapsed)
if not self._collapsed:
# Expanding a group banner (Beamline / Experiment) opens every
# nested panel banner too — a group opening onto a wall of still-
# collapsed banners reads as broken. No-op for leaf panels, which
# have no nested TitleLabels.
parent = self.parentWidget()
if parent is not None:
for child in parent.findChildren(TitleLabel):
if child is not self:
child.expand()
def _apply_collapsed(self) -> None:
parent = self.parentWidget()