Source code for pyqt_reactive.core.collapsible_splitter_helper

"""
Shared helper for making splitters collapsible with double-click toggle.

Used by ConfigWindow and StepParameterEditor to provide consistent
tree panel collapse/expand behavior.
"""

import logging
from PyQt6.QtCore import QEvent, QObject
from PyQt6.QtWidgets import QSplitter

logger = logging.getLogger(__name__)


[docs] class CollapsibleSplitterHelper: """Helper for adding double-click toggle to splitter handles."""
[docs] def __init__(self, splitter: QSplitter, left_panel_index: int = 0): """ Initialize the collapsible splitter helper. Args: splitter: The QSplitter to make collapsible left_panel_index: Index of the left panel (default 0) """ self.splitter = splitter self.left_panel_index = left_panel_index self._tree_visible = True self._tree_last_size = 300 # Default last size # Install event filter on splitter handle self._install_handle_filter()
def _install_handle_filter(self): """Install event filter on splitter handle for double-click toggle.""" class SplitterHandleFilter(QObject): """Event filter for splitter handle to detect double-clicks.""" def __init__(self, helper): super().__init__() self.helper = helper def eventFilter(self, obj, event): if event.type() == QEvent.Type.MouseButtonDblClick: self.helper.toggle_visibility() return True return False # Get the splitter handle (index 1 is the handle between widgets 0 and 1) handle = self.splitter.handle(1) if handle: self._handle_filter = SplitterHandleFilter(self) handle.installEventFilter(self._handle_filter)
[docs] def toggle_visibility(self): """Toggle left panel visibility by collapsing/expanding.""" sizes = self.splitter.sizes() if self._tree_visible and sizes[self.left_panel_index] > 0: # Panel is visible - collapse it self._tree_last_size = sizes[self.left_panel_index] # Remember current size total = sum(sizes) new_sizes = [0] * len(sizes) new_sizes[self.left_panel_index] = 0 # Give all space to other panels remaining = total for i in range(len(sizes)): if i != self.left_panel_index: new_sizes[i] = remaining break self.splitter.setSizes(new_sizes) self._tree_visible = False logger.debug("Collapsed left panel") else: # Panel is collapsed - expand it total = sum(sizes) new_left_size = min(self._tree_last_size, total - 100) # Ensure right panel has at least 100px new_sizes = [0] * len(sizes) new_sizes[self.left_panel_index] = new_left_size # Give remaining space to other panels remaining = total - new_left_size for i in range(len(sizes)): if i != self.left_panel_index: new_sizes[i] = remaining break self.splitter.setSizes(new_sizes) self._tree_visible = True logger.debug(f"Expanded left panel to {new_left_size}px")
[docs] def set_initial_size(self, size: int): """Set the initial size to remember when collapsed.""" self._tree_last_size = size