From 3d58ae59cc8a9f3a5ca7226ef267aeb03bbcd814 Mon Sep 17 00:00:00 2001 From: Dawn Date: Fri, 7 Aug 2026 17:08:22 +0200 Subject: [PATCH] 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 --- src/aare/gui/panels/file_path_panel.py | 2 +- src/aare/gui/panels/illumination_panel.py | 2 +- src/aare/gui/panels/omega_panel.py | 2 +- src/aare/gui/panels/smargon_panel.py | 2 +- src/aare/gui/panels/zoom_panel.py | 2 +- src/aare/gui/widgets/title_label.py | 38 ++++++++++++++++++++--- 6 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/aare/gui/panels/file_path_panel.py b/src/aare/gui/panels/file_path_panel.py index 96937e33..cd9b46bb 100644 --- a/src/aare/gui/panels/file_path_panel.py +++ b/src/aare/gui/panels/file_path_panel.py @@ -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) diff --git a/src/aare/gui/panels/illumination_panel.py b/src/aare/gui/panels/illumination_panel.py index 50bac3e9..69f1e04a 100644 --- a/src/aare/gui/panels/illumination_panel.py +++ b/src/aare/gui/panels/illumination_panel.py @@ -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) diff --git a/src/aare/gui/panels/omega_panel.py b/src/aare/gui/panels/omega_panel.py index b7e7a9ae..9e764cd2 100644 --- a/src/aare/gui/panels/omega_panel.py +++ b/src/aare/gui/panels/omega_panel.py @@ -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 = [ diff --git a/src/aare/gui/panels/smargon_panel.py b/src/aare/gui/panels/smargon_panel.py index 2dcaac19..9c580613 100644 --- a/src/aare/gui/panels/smargon_panel.py +++ b/src/aare/gui/panels/smargon_panel.py @@ -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) diff --git a/src/aare/gui/panels/zoom_panel.py b/src/aare/gui/panels/zoom_panel.py index 6ff58f41..850a6139 100644 --- a/src/aare/gui/panels/zoom_panel.py +++ b/src/aare/gui/panels/zoom_panel.py @@ -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 = [] diff --git a/src/aare/gui/widgets/title_label.py b/src/aare/gui/widgets/title_label.py index 500d014a..8eb1a5a7 100644 --- a/src/aare/gui/widgets/title_label.py +++ b/src/aare/gui/widgets/title_label.py @@ -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

: 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()