feat: add explicit left/right orientation with swap button

Fixes mirrored slice exports by making orientation explicit:

- PhotoSlice.swapped flag persists a user left/right swap
- swap_left_right() mirrors [TL,TR,BR,BL] -> [TR,TL,BL,BR]
- normalize_top_left() honors the flag so squarize/reset_rotation
  no longer overwrite manual orientation
- Swap L/R toolbar button wired through canvas state + controller
- Color-code left (orange) vs right (cyan) corners and edges
This commit is contained in:
dan 2026-09-11 21:33:59 +02:00
parent 047ea60fa5
commit 607f5e0c57
7 changed files with 114 additions and 31 deletions

View file

@ -28,14 +28,22 @@ class CanvasRenderMixin:
b = points[(i + 1) % 4]
if i == 0:
color = QColor("red")
elif i == 1:
color = QColor("green")
elif i == 2:
color = QColor("orange")
else:
color = QColor("blue") if s.locked else QColor("lightgreen")
painter.setPen(QPen(color, 3))
painter.drawLine(a, b)
painter.setPen(QPen(QColor("blue"), 2))
painter.setBrush(QColor(128, 128, 128, 170))
for p in points:
# Corners are color-coded: left = orange, right = cyan.
# Edge 0 (top, red) runs TL->TR, so corners 0 and 3 are the left
# side and corners 1 and 2 are the right side.
corner_colors = (QColor("orange"), QColor("cyan"), QColor("cyan"), QColor("orange"))
for p, color in zip(points, corner_colors):
painter.setPen(QPen(QColor("blue"), 2))
painter.setBrush(color)
painter.drawRect(QRectF(p.x() - 5, p.y() - 5, 10, 10))
center = np.mean(s.bbox, axis=0)