fix: preview crop lines match main overlay colors

Portrait lines are red, square lines are blue — matching the video
overlay. Both shown simultaneously when both random options are on.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-13 17:07:07 +02:00
parent d031d6c285
commit ccc94ccb5c
+29 -25
View File
@@ -1313,20 +1313,19 @@ class PreviewLabel(QWidget):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self._pixmap: QPixmap | None = None self._pixmap: QPixmap | None = None
self._portrait_ratio: tuple[int, int] | None = None # list of (ratio, crop_center, color)
self._overlays: list[tuple[tuple[int, int], float, QColor]] = []
self._source_ratio: float = 16 / 9 self._source_ratio: float = 16 / 9
self._crop_center: float = 0.5
self.setMinimumSize(160, 120) self.setMinimumSize(160, 120)
def setPixmap(self, px: QPixmap) -> None: def setPixmap(self, px: QPixmap) -> None:
self._pixmap = px self._pixmap = px
self.update() self.update()
def set_crop(self, portrait_ratio: tuple[int, int] | None, def set_overlays(self, overlays: list[tuple[tuple[int, int], float, QColor]],
source_ratio: float, crop_center: float) -> None: source_ratio: float) -> None:
self._portrait_ratio = portrait_ratio self._overlays = overlays
self._source_ratio = source_ratio self._source_ratio = source_ratio
self._crop_center = crop_center
self.update() self.update()
def sizeHint(self): def sizeHint(self):
@@ -1340,7 +1339,6 @@ class PreviewLabel(QWidget):
w, h = self.width(), self.height() w, h = self.width(), self.height()
p.fillRect(0, 0, w, h, QColor(26, 26, 26)) p.fillRect(0, 0, w, h, QColor(26, 26, 26))
if self._pixmap and not self._pixmap.isNull(): if self._pixmap and not self._pixmap.isNull():
# Scale pixmap to fit, centered.
scaled = self._pixmap.scaled( scaled = self._pixmap.scaled(
w, h, w, h,
Qt.AspectRatioMode.KeepAspectRatio, Qt.AspectRatioMode.KeepAspectRatio,
@@ -1349,22 +1347,20 @@ class PreviewLabel(QWidget):
ix = (w - scaled.width()) // 2 ix = (w - scaled.width()) // 2
iy = (h - scaled.height()) // 2 iy = (h - scaled.height()) // 2
p.drawPixmap(ix, iy, scaled) p.drawPixmap(ix, iy, scaled)
# Draw crop lines if portrait mode is active. iw, ih = scaled.width(), scaled.height()
if self._portrait_ratio is not None: for ratio, center, color in self._overlays:
num, den = self._portrait_ratio num, den = ratio
crop_ar = num / den win_frac = (num / den) / self._source_ratio
win_frac = crop_ar / self._source_ratio if win_frac >= 1.0:
if win_frac < 1.0: continue
iw = scaled.width() win_px = int(iw * win_frac)
win_px = iw * win_frac
max_x = iw - win_px max_x = iw - win_px
cx = ix + int(max_x * self._crop_center) cx = ix + int(max_x * center)
cw = int(win_px) pen = QPen(color)
pen = QPen(QColor(100, 160, 240, 200))
pen.setWidth(1) pen.setWidth(1)
p.setPen(pen) p.setPen(pen)
p.drawLine(cx, iy, cx, iy + scaled.height()) p.drawLine(cx, iy, cx, iy + ih)
p.drawLine(cx + cw, iy, cx + cw, iy + scaled.height()) p.drawLine(cx + win_px, iy, cx + win_px, iy + ih)
finally: finally:
p.end() p.end()
@@ -2479,11 +2475,19 @@ class MainWindow(QMainWindow):
self._update_preview_crop() self._update_preview_crop()
def _update_preview_crop(self) -> None: def _update_preview_crop(self) -> None:
self._end_preview.set_crop( overlays: list[tuple[tuple[int, int], float, QColor]] = []
self._crop_bar._portrait_ratio, center = self._crop_bar._crop_center
self._crop_bar._source_ratio, ratio_text = self._cmb_portrait.currentText()
self._crop_bar._crop_center, if ratio_text != "Off":
) # Manual portrait — red lines.
overlays.append((_RATIOS[ratio_text], center, QColor(220, 60, 60, 200)))
else:
# Random modes.
if self._chk_rand_portrait.isChecked():
overlays.append((_RATIOS["9:16"], center, QColor(220, 60, 60, 200)))
if self._chk_rand_square.isChecked():
overlays.append((_RATIOS["1:1"], center, QColor(60, 180, 220, 200)))
self._end_preview.set_overlays(overlays, self._crop_bar._source_ratio)
# --- Playback --- # --- Playback ---