From ceaed209e95ecfeba1c2582e5e52bc0ddc2c23aa Mon Sep 17 00:00:00 2001 From: Loren Eteval Date: Mon, 10 Aug 2026 00:17:00 +0800 Subject: [PATCH] Refine navigation selection indicator Signed-off-by: Loren Eteval --- Furious/Qt/AppStyleSheet.py | 7 +++++- Furious/Widget/NavigationView.py | 43 ++++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/Furious/Qt/AppStyleSheet.py b/Furious/Qt/AppStyleSheet.py index aff30b3..e7469d8 100644 --- a/Furious/Qt/AppStyleSheet.py +++ b/Furious/Qt/AppStyleSheet.py @@ -476,13 +476,18 @@ class AppStyleSheet: QPushButton#NavigationPageButton:checked {{ border: none; - border-left: 3px solid {palette['accent']}; border-radius: 7px; background-color: {palette['accent_soft']}; color: {palette['text_strong']}; font-weight: 600; }} + QFrame#NavigationSelectionIndicator {{ + border: none; + border-radius: 0; + background-color: {palette['accent']}; + }} + QPushButton#NavigationPageButton:checked:hover {{ background-color: {palette['accent_soft_hover']}; }} diff --git a/Furious/Widget/NavigationView.py b/Furious/Widget/NavigationView.py index ca39b36..7ce4cc6 100644 --- a/Furious/Widget/NavigationView.py +++ b/Furious/Widget/NavigationView.py @@ -42,8 +42,9 @@ class _NavigationButton(IconTextPushButton): IconSize = QtCore.QSize(20, 20) IconTextSpacing = 12 HorizontalMargin = 12 + SelectionIndicatorWidth = 3 - def __init__(self, parent=None): + def __init__(self, parent=None, *, hasSelectionIndicator=False): """Initialize the icon and text presentation.""" super().__init__( parent, @@ -53,10 +54,45 @@ class _NavigationButton(IconTextPushButton): iconSize=self.IconSize, ) + self.selectionIndicator = None + + if hasSelectionIndicator: + self.selectionIndicator = QFrame(parent=self) + self.selectionIndicator.setObjectName('NavigationSelectionIndicator') + self.selectionIndicator.setFixedWidth(self.SelectionIndicatorWidth) + self.selectionIndicator.setAttribute( + QtCore.Qt.WidgetAttribute.WA_TransparentForMouseEvents + ) + self.selectionIndicator.hide() + self.toggled.connect(self._selectionChanged) + def setExpanded(self, expanded: bool): """Show the text label only in expanded navigation mode.""" self.setTextVisible(expanded) + @QtCore.Slot(bool) + def _selectionChanged(self, selected: bool): + """Show the independent indicator for a selected page.""" + self.selectionIndicator.setVisible(selected) + + if selected: + self.selectionIndicator.raise_() + + def resizeEvent(self, event): + """Keep the selection indicator straight along the left edge.""" + super().resizeEvent(event) + + if self.selectionIndicator is not None: + indicatorHeight = min(self.IconSize.height(), self.height()) + indicatorTop = (self.height() - indicatorHeight) // 2 + + self.selectionIndicator.setGeometry( + 0, + indicatorTop, + self.SelectionIndicatorWidth, + indicatorHeight, + ) + @dataclass class _NavigationPage: @@ -155,7 +191,10 @@ class NavigationView(Mixins.QTranslatable, Mixins.ThemeAware, QWidget): if not isinstance(widget, QWidget): raise TypeError('widget must be a QWidget') - button = _NavigationButton(parent=self.navigationPanel) + button = _NavigationButton( + parent=self.navigationPanel, + hasSelectionIndicator=True, + ) button.setObjectName('NavigationPageButton') button.setProperty('pageId', pageId) button.setCheckable(True)