Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions src/jabs/ui/settings_dialog/collapsible_section.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from PySide6.QtCore import Signal
from PySide6.QtGui import Qt
from PySide6.QtCore import QSize, Qt, Signal
from PySide6.QtWidgets import QFrame, QSizePolicy, QToolButton, QVBoxLayout, QWidget
from qt_material_icons import MaterialIcon

# Pixel size of the disclosure triangle.
_INDICATOR_SIZE = 18


class CollapsibleSection(QWidget):
Expand All @@ -16,10 +19,20 @@ class CollapsibleSection(QWidget):
def __init__(self, title: str, content: QWidget, parent: QWidget | None = None) -> None:
super().__init__(parent)
self._content = content

# Disclosure indicator: a small Material triangle that points to the side when
# collapsed and down when expanded. qt_material_icons renders in the palette
# text color, so it follows the application theme.
self._collapsed_icon = MaterialIcon("arrow_right")
self._expanded_icon = MaterialIcon("arrow_drop_down")

self._toggle_btn = QToolButton(self)
self._toggle_btn.setStyleSheet("QToolButton { border: none; }")
self._toggle_btn.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
self._toggle_btn.setArrowType(Qt.ArrowType.RightArrow)
# Only the Material disclosure icon is shown; never the style's native arrow.
self._toggle_btn.setArrowType(Qt.ArrowType.NoArrow)
self._toggle_btn.setIconSize(QSize(_INDICATOR_SIZE, _INDICATOR_SIZE))
self._toggle_btn.setIcon(self._collapsed_icon)
self._toggle_btn.setText(title)
Comment thread
gbeane marked this conversation as resolved.
self._toggle_btn.setCheckable(True)
self._toggle_btn.setChecked(False)
Expand All @@ -43,9 +56,7 @@ def __init__(self, title: str, content: QWidget, parent: QWidget | None = None)

def _on_toggled(self, checked: bool) -> None:
"""Handle toggling the collapsible section."""
self._toggle_btn.setArrowType(
Qt.ArrowType.DownArrow if checked else Qt.ArrowType.RightArrow
)
self._toggle_btn.setIcon(self._expanded_icon if checked else self._collapsed_icon)
self._content.setVisible(checked)
self._content.updateGeometry()

Expand Down
20 changes: 19 additions & 1 deletion tests/ui/test_settings_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
from jabs.core.enums import ClassifierMode

try:
from PySide6.QtWidgets import QApplication
from PySide6.QtCore import Qt
from PySide6.QtWidgets import QApplication, QLabel

from jabs.ui.settings_dialog.classifier_mode_settings_group import (
ClassifierModeSettingsGroup,
)
from jabs.ui.settings_dialog.collapsible_section import CollapsibleSection
from jabs.ui.settings_dialog.settings_dialog import _OverlapCheckThread

SKIP_UI_TESTS = False
Expand Down Expand Up @@ -81,3 +83,19 @@ def test_classifier_mode_group_roundtrips_enum_not_label() -> None:

group.set_values({CLASSIFIER_MODE_KEY: ClassifierMode.BINARY.value})
assert group.get_values() == {CLASSIFIER_MODE_KEY: ClassifierMode.BINARY}


def test_collapsible_section_toggles_disclosure_icon() -> None:
"""The disclosure indicator swaps between the collapsed and expanded icons."""
section = CollapsibleSection("More info", QLabel("content"))

# No native arrow is drawn; only the Material disclosure icon is shown.
assert section._toggle_btn.arrowType() == Qt.ArrowType.NoArrow
collapsed_key = section._toggle_btn.icon().cacheKey()

section.set_expanded(True)
expanded_key = section._toggle_btn.icon().cacheKey()
assert expanded_key != collapsed_key

section.set_expanded(False)
assert section._toggle_btn.icon().cacheKey() == collapsed_key
Loading