Warning ratio sur galerie + cadre recadrage auto dans l'éditeur

Galerie :
- Petit badge orange ⚠ en haut à droite des photos pas au ratio 3:2
- Discret, tooltip "Photo à recadrer"
- Tolérance 5% autour du ratio 1.5

Éditeur :
- Si la photo n'est pas au ratio 3:2, le cadre de recadrage
  s'affiche automatiquement en suggestion à l'ouverture
- L'utilisateur peut le déplacer/redimensionner ou le valider

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-21 23:36:12 +01:00
parent e43fc798df
commit 980a80d43a
2 changed files with 97 additions and 1 deletions

View File

@@ -125,6 +125,13 @@ class EditorScreen(QWidget):
self.scene.setSceneRect(QRectF(pixmap.rect())) self.scene.setSceneRect(QRectF(pixmap.rect()))
self.view.fitInView(self.pixmap_item, Qt.AspectRatioMode.KeepAspectRatio) self.view.fitInView(self.pixmap_item, Qt.AspectRatioMode.KeepAspectRatio)
# Auto-afficher le cadre de recadrage si ratio ≠ 3:2
w, h = pixmap.width(), pixmap.height()
if w > 0 and h > 0:
ratio = max(w, h) / min(w, h)
if abs(ratio - 1.5) > 0.075:
self._show_ratio_crop()
def resizeEvent(self, event): def resizeEvent(self, event):
super().resizeEvent(event) super().resizeEvent(event)
if self.pixmap_item: if self.pixmap_item:
@@ -149,6 +156,37 @@ class EditorScreen(QWidget):
image.save(path, "PNG") image.save(path, "PNG")
return path return path
# --- Cadre ratio suggéré ---
def _show_ratio_crop(self):
"""Affiche un cadre de recadrage au ratio 3:2 en suggestion."""
if not self.pixmap_item:
return
self.is_cropping = True
self.view.setDragMode(QGraphicsView.DragMode.NoDrag)
pr = self.pixmap_item.boundingRect()
img_w, img_h = pr.width(), pr.height()
ratio = 1.5
# Adapter au sens de l'image
if img_w < img_h:
ratio = 1.0 / ratio
# Plus grande zone possible
if img_w / img_h > ratio:
crop_h = img_h * 0.95
crop_w = crop_h * ratio
else:
crop_w = img_w * 0.95
crop_h = crop_w / ratio
x = (img_w - crop_w) / 2
y = (img_h - crop_h) / 2
crop_rect = QRectF(x, y, crop_w, crop_h)
self.crop_overlay = CropOverlay(crop_rect)
self.crop_overlay.set_bounds(pr)
self.scene.addItem(self.crop_overlay)
# --- Navigation --- # --- Navigation ---
def _go_back(self): def _go_back(self):
self._cancel_crop() self._cancel_crop()

View File

@@ -32,13 +32,42 @@ class PhotoCard(QFrame):
layout.setContentsMargins(4, 4, 4, 4) layout.setContentsMargins(4, 4, 4, 4)
layout.setSpacing(4) layout.setSpacing(4)
# Conteneur miniature (pour superposer le warning)
from PyQt6.QtWidgets import QStackedLayout
thumb_container = QWidget()
thumb_container.setFixedSize(200, 140)
thumb_stack = QVBoxLayout(thumb_container)
thumb_stack.setContentsMargins(0, 0, 0, 0)
thumb_stack.setSpacing(0)
# Miniature — taille fixe # Miniature — taille fixe
self.thumb_label = QLabel() self.thumb_label = QLabel()
self.thumb_label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.thumb_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.thumb_label.setFixedSize(200, 140) self.thumb_label.setFixedSize(200, 140)
self._pixmap_original = QPixmap(self.path) self._pixmap_original = QPixmap(self.path)
self._update_thumbnail() self._update_thumbnail()
layout.addWidget(self.thumb_label) thumb_stack.addWidget(self.thumb_label)
# Warning ratio (petit indicateur discret)
self.ratio_warning = QLabel("⚠")
self.ratio_warning.setFixedSize(22, 22)
self.ratio_warning.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.ratio_warning.setStyleSheet("""
QLabel {
background: rgba(255, 152, 0, 0.8);
color: white;
border-radius: 11px;
font-size: 13px;
}
""")
self.ratio_warning.setToolTip("Photo à recadrer")
self.ratio_warning.hide()
# Positionner en haut à droite de la miniature
self.ratio_warning.setParent(thumb_container)
self.ratio_warning.move(174, 4)
self._check_ratio()
layout.addWidget(thumb_container)
# Barre du bas : crayon + quantité # Barre du bas : crayon + quantité
bar = QHBoxLayout() bar = QHBoxLayout()
@@ -93,6 +122,21 @@ class PhotoCard(QFrame):
layout.addLayout(bar) layout.addLayout(bar)
def _check_ratio(self):
"""Vérifie si la photo est au ratio 3:2 (10x15). Sinon, affiche le warning."""
if self._pixmap_original.isNull():
return
w = self._pixmap_original.width()
h = self._pixmap_original.height()
if w == 0 or h == 0:
return
ratio = max(w, h) / min(w, h)
# Tolérance de 5% autour du ratio 1.5 (3:2)
if abs(ratio - 1.5) > 0.075:
self.ratio_warning.show()
else:
self.ratio_warning.hide()
def _edit(self): def _edit(self):
self.main_window.show_editor(self.path) self.main_window.show_editor(self.path)
@@ -145,7 +189,21 @@ class PhotoCard(QFrame):
thumb_h = max(100, int(window_height * 0.16)) thumb_h = max(100, int(window_height * 0.16))
thumb_w = max(140, int(thumb_h * 1.45)) thumb_w = max(140, int(thumb_h * 1.45))
self.thumb_label.setFixedSize(thumb_w, thumb_h) self.thumb_label.setFixedSize(thumb_w, thumb_h)
# Redimensionner le conteneur aussi
self.thumb_label.parent().setFixedSize(thumb_w, thumb_h)
self._update_thumbnail() self._update_thumbnail()
# Repositionner le warning en haut à droite
warn_size = max(18, int(window_height * 0.025))
self.ratio_warning.setFixedSize(warn_size, warn_size)
self.ratio_warning.move(thumb_w - warn_size - 4, 4)
self.ratio_warning.setStyleSheet(f"""
QLabel {{
background: rgba(255, 152, 0, 0.8);
color: white;
border-radius: {warn_size // 2}px;
font-size: {warn_size - 4}px;
}}
""")
btn_size = max(28, int(window_height * 0.04)) btn_size = max(28, int(window_height * 0.04))
font_size = max(12, int(window_height * 0.02)) font_size = max(12, int(window_height * 0.02))