pyPhotoAlbum/pyPhotoAlbum/ribbon_widget.py
Duncan Tourolle 5de3384c35
Some checks failed
Python CI / test (push) Successful in 1m19s
Lint / lint (push) Successful in 1m21s
Tests / test (3.10) (push) Failing after 1m2s
Tests / test (3.11) (push) Failing after 57s
Tests / test (3.9) (push) Failing after 59s
Many improvements and fixes
2025-11-21 22:35:47 +01:00

121 lines
4.2 KiB
Python

"""
Ribbon widget for pyPhotoAlbum
"""
from PyQt6.QtWidgets import QWidget, QTabWidget, QHBoxLayout, QVBoxLayout, QPushButton, QLabel, QFrame, QGridLayout
from PyQt6.QtCore import Qt
class RibbonWidget(QWidget):
"""A ribbon-style toolbar using QTabWidget"""
def __init__(self, main_window, ribbon_config=None, buttons_per_row=4, parent=None):
super().__init__(parent)
self.main_window = main_window
self.buttons_per_row = buttons_per_row # Default to 4 buttons per row
# Use provided config or fall back to importing the old one
if ribbon_config is None:
from ribbon_config import RIBBON_CONFIG
self.ribbon_config = RIBBON_CONFIG
else:
self.ribbon_config = ribbon_config
# Main layout
main_layout = QVBoxLayout()
main_layout.setContentsMargins(0, 0, 0, 0)
main_layout.setSpacing(0)
self.setLayout(main_layout)
# Create tab widget
self.tab_widget = QTabWidget()
self.tab_widget.setDocumentMode(True)
main_layout.addWidget(self.tab_widget)
# Build ribbon from config
self._build_ribbon()
def _build_ribbon(self):
"""Build the ribbon UI from configuration"""
for tab_name, tab_config in self.ribbon_config.items():
tab_widget = self._create_tab(tab_config)
self.tab_widget.addTab(tab_widget, tab_name)
def _create_tab(self, tab_config):
"""Create a tab widget with groups and actions"""
tab_widget = QWidget()
tab_layout = QHBoxLayout()
tab_layout.setContentsMargins(5, 5, 5, 5)
tab_layout.setSpacing(10)
tab_widget.setLayout(tab_layout)
# Create groups
for group_config in tab_config.get("groups", []):
group_widget = self._create_group(group_config)
tab_layout.addWidget(group_widget)
# Add stretch to push groups to the left
tab_layout.addStretch()
return tab_widget
def _create_group(self, group_config):
"""Create a group of actions"""
group_widget = QFrame()
group_layout = QVBoxLayout()
group_layout.setContentsMargins(5, 5, 5, 5)
group_layout.setSpacing(5)
group_widget.setLayout(group_layout)
# Create actions grid layout
actions_layout = QGridLayout()
actions_layout.setSpacing(5)
# Get buttons per row from group config or use default
buttons_per_row = group_config.get("buttons_per_row", self.buttons_per_row)
# Add buttons to grid
actions = group_config.get("actions", [])
for i, action_config in enumerate(actions):
button = self._create_action_button(action_config)
row = i // buttons_per_row
col = i % buttons_per_row
actions_layout.addWidget(button, row, col)
group_layout.addLayout(actions_layout)
# Add group label
group_label = QLabel(group_config.get("name", ""))
group_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
group_label.setStyleSheet("font-size: 10px; color: gray;")
group_layout.addWidget(group_label)
# Add separator frame
group_widget.setFrameShape(QFrame.Shape.Box)
group_widget.setFrameShadow(QFrame.Shadow.Sunken)
group_widget.setLineWidth(1)
return group_widget
def _create_action_button(self, action_config):
"""Create a button for an action"""
button = QPushButton(action_config.get("label", ""))
button.setToolTip(action_config.get("tooltip", ""))
button.setMinimumSize(60, 40)
# Connect to action
action_name = action_config.get("action")
if action_name:
button.clicked.connect(lambda: self._execute_action(action_name))
return button
def _execute_action(self, action_name):
"""Execute an action by calling the corresponding method on main window"""
if hasattr(self.main_window, action_name):
method = getattr(self.main_window, action_name)
if callable(method):
method()
else:
print(f"Warning: Action '{action_name}' not implemented in main window")