feat: timeline scan region rendering

Add scan region storage and rendering to TimelineWidget:
- _scan_regions list in __init__ for (start, end, score) tuples
- set_scan_regions() and clear_scan_regions() methods
- paintEvent draws semi-transparent blue rectangles with score-based opacity

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-17 08:53:18 +02:00
parent 9cf9e3233f
commit e7f4de9ec1
+18
View File
@@ -208,6 +208,7 @@ class TimelineWidget(QWidget):
self._crop_keyframes: list[tuple[float, float, str | None, bool, bool]] = []
self._markers: list[tuple[float, int, str]] = []
self._hover_cache: list[tuple[float, str]] = [] # (t/duration, path)
self._scan_regions: list[tuple[float, float, float]] = [] # (start, end, score)
# Cached paint resources — created once, reused every frame
self._cursor_pen = QPen(QColor(255, 210, 0))
@@ -252,6 +253,15 @@ class TimelineWidget(QWidget):
self._rebuild_hover_cache()
self.update()
def set_scan_regions(self, regions: list[tuple[float, float, float]]) -> None:
"""regions: list of (start_time, end_time, score)"""
self._scan_regions = regions
self.update()
def clear_scan_regions(self) -> None:
self._scan_regions = []
self.update()
def set_play_position(self, t: float | None) -> None:
# In lock mode, ignore mpv position updates while the user is dragging
# — the async seek hasn't caught up yet, so mpv reports stale values.
@@ -360,6 +370,14 @@ class TimelineWidget(QWidget):
p.drawLine(x_start, rh, x_start, h)
p.drawLine(x_end, rh, x_end, h)
# ── scan regions ──────────────────────────────────────────────
if self._scan_regions and self._duration > 0:
for (start, end, score) in self._scan_regions:
x1 = int(start / self._duration * w)
x2 = int(end / self._duration * w)
alpha = int(40 + score * 80) # 40120 opacity
p.fillRect(x1, rh, x2 - x1, h - rh, QColor(100, 200, 255, alpha))
# ── export markers ────────────────────────────────────────────
p.setFont(self._marker_font)
for (t, num, _path) in self._markers: