Files
copydev-imposing-tool/app/page_panel.py
Jules 98049cd3cb V2.4.0 — Theme moderne Catppuccin + recadrage non-modal
- Theme sombre Catppuccin Mocha sur toute l'interface :
  - Menus, toolbars, dialogues, spinbox, combo, boutons
  - Scrollbars custom, bordures arrondies, hover states
  - Panneau vignettes repensé
  - Sections outils avec titre bleu
- Recadrage : dialogue non-modal (Qt.Tool) pour pouvoir
  interagir avec le viewer pendant la selection
- Fond viewer plus sombre (#11111b)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 14:30:17 +01:00

117 lines
4.2 KiB
Python

"""Panneau lateral de vignettes des pages — V2."""
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QListWidget, QListWidgetItem,
QAbstractItemView, QMenu, QSizePolicy)
from PyQt6.QtGui import QIcon, QPixmap
from PyQt6.QtCore import Qt, pyqtSignal, QSize
class PagePanel(QWidget):
"""Panneau de vignettes avec drag & drop, suppression, insertion."""
page_selected = pyqtSignal(int) # page index cliquee
pages_reordered = pyqtSignal(list) # nouvelle liste d'indices
page_delete_requested = pyqtSignal(int) # demande suppression
page_insert_requested = pyqtSignal(int) # demande insertion page blanche apres
def __init__(self, parent=None):
super().__init__(parent)
self.setMinimumWidth(100)
self.setSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Expanding)
self._setup_ui()
def _setup_ui(self):
layout = QVBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
self._list = QListWidget()
self._list.setIconSize(QSize(120, 170))
self._list.setSpacing(4)
self._list.setStyleSheet("""
QListWidget {
background: #181825;
border: none;
border-right: 1px solid #313244;
padding: 4px;
}
QListWidget::item {
background: #1e1e2e;
border: 1px solid #313244;
border-radius: 6px;
padding: 4px;
color: #a6adc8;
font-size: 10px;
margin: 2px 0;
}
QListWidget::item:hover {
background: #313244;
border-color: #45475a;
}
QListWidget::item:selected {
background: #313244;
border: 1px solid #89b4fa;
color: #cdd6f4;
}
""")
self._list.setDragDropMode(QAbstractItemView.DragDropMode.InternalMove)
self._list.setDefaultDropAction(Qt.DropAction.MoveAction)
self._list.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self._list.customContextMenuRequested.connect(self._context_menu)
self._list.currentRowChanged.connect(self._on_row_changed)
self._list.model().rowsMoved.connect(self._on_rows_moved)
layout.addWidget(self._list)
def load_thumbnails(self, viewer):
"""Charger les miniatures depuis le viewer."""
self._list.clear()
for i in range(viewer.total_pages):
thumb = viewer.get_page_thumbnail(i, 120)
item = QListWidgetItem()
item.setText(f" Page {i + 1}")
item.setData(Qt.ItemDataRole.UserRole, i)
if thumb:
item.setIcon(QIcon(thumb))
self._list.addItem(item)
def select_page(self, index):
"""Selectionner une page sans emettre le signal."""
self._list.blockSignals(True)
self._list.setCurrentRow(index)
self._list.blockSignals(False)
def _on_row_changed(self, row):
if row >= 0:
self.page_selected.emit(row)
def _on_rows_moved(self):
indices = []
for i in range(self._list.count()):
item = self._list.item(i)
original_index = item.data(Qt.ItemDataRole.UserRole)
indices.append(original_index)
self.pages_reordered.emit(indices)
def _context_menu(self, pos):
item = self._list.itemAt(pos)
if not item:
return
row = self._list.row(item)
menu = QMenu(self)
menu.setStyleSheet("""
QMenu { background: #1e1e2e; color: #cdd6f4; border: 1px solid #45475a; border-radius: 8px; padding: 4px; }
QMenu::item { padding: 6px 20px; border-radius: 4px; }
QMenu::item:selected { background: #45475a; }
""")
act_insert = menu.addAction("Inserer une page blanche apres")
act_delete = menu.addAction("Supprimer cette page")
action = menu.exec(self._list.mapToGlobal(pos))
if action == act_delete:
self.page_delete_requested.emit(row)
elif action == act_insert:
self.page_insert_requested.emit(row)