diff --git a/fixtracks/widgets/detectiontimeline.py b/fixtracks/widgets/detectiontimeline.py index 3a168f9..073604b 100644 --- a/fixtracks/widgets/detectiontimeline.py +++ b/fixtracks/widgets/detectiontimeline.py @@ -34,13 +34,20 @@ class Window(QGraphicsRectItem): def setWindowWidth(self, newwidth): logging.debug("timeline.window: update window widthto %.3f", newwidth) - self._width = newwidth r = self.rect() self.setRect(r.x(), r.y(), self._width, r.height()) r = self.rect() self.signals.windowMoved.emit(r.left(), r.right()) + def setWindow(self, newx, newwidth): + logging.debug("timeline.window: update window to range %.3f to %.3f", newx, newwidth) + self._width = newwidth + r = self.rect() + self.setRect(newx, r.y(), self._width, r.height()) + r = self.rect() + self.signals.windowMoved.emit(r.left(), r.right()) + def mouseMoveEvent(self, event): super().mouseMoveEvent(event) @@ -223,6 +230,15 @@ class DetectionTimeline(QWidget): span = np.round(width * self.total_width) self._window.setWindowWidth(span) + def setWindow(self, xpos, width): + span = np.round(width * self.total_width) + if xpos < 0.0: + xpos = 0.0 + elif xpos > 1.0: + xpos = 1.0 + xstart = np.round(xpos * self.total_width) + self._window.setWindow(xstart, span) + def windowBounds(self): return self._rangeStart, self._rangeStop diff --git a/fixtracks/widgets/tracks.py b/fixtracks/widgets/tracks.py index 08ba270..6e33acb 100644 --- a/fixtracks/widgets/tracks.py +++ b/fixtracks/widgets/tracks.py @@ -117,7 +117,7 @@ class SelectionControls(QWidget): quarterstepBackBtn.setFont(font) quarterstepBackBtn.setShortcut(Qt.KeyboardModifier.ShiftModifier | Qt.Key.Key_Left) quarterstepBackBtn.setToolTip(f"Go back by a quarter window ({quarterstepBackBtn.shortcut().toString()})") - quarterstepBackBtn.clicked.connect(lambda: self.on_Fwd(quarterstep)) + quarterstepBackBtn.clicked.connect(lambda: self.on_Back(quarterstep)) fwdBtn = QPushButton(">>|") fwdBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) @@ -306,6 +306,7 @@ class FixTracks(QWidget): self._threadpool = QThreadPool() self._reader = None self._image = None + self._clear_detections = True self._data = DataController() self._brushes = {"assigned_left": QBrush(QColor.fromString("orange")), "assigned_right": QBrush(QColor.fromString("green")), @@ -431,7 +432,8 @@ class FixTracks(QWidget): assigned_right = df[(df.track == self.tracktwo_id)] unassigned = df[(df.track != self.trackone_id) & (df.track != self.tracktwo_id)] - self._detectionView.clearDetections() + if self._clear_detections: + self._detectionView.clearDetections() update_detectionView(unassigned, "unassigned") update_detectionView(assigned_left, "assigned_left") update_detectionView(assigned_right, "assigned_right") @@ -467,7 +469,7 @@ class FixTracks(QWidget): self._data.setData(self._reader.asdict) self._timeline.setDetectionData(self._data.data) maxframes = self._data.max("frame") - rel_width = self._windowspinner.value / maxframes + rel_width = self._windowspinner.value() / maxframes self._timeline.setWindowWidth(rel_width) self.update() self._saveBtn.setEnabled(True) @@ -543,9 +545,35 @@ class FixTracks(QWidget): def on_forward(self, stepsize): logging.debug("Tracks: receive forward command with step-size: %.2f", stepsize) + max_frames = self._data.max("frame") + if stepsize >= 1.0: + self._clear_detections = True + newx = self._timeline.rangeStart + self._windowspinner.value() / max_frames + self._timeline.setWindowPos(newx) + else: + self._clear_detections = True + step = stepsize * (self._windowspinner.value() / max_frames) + stop_pos = self._timeline.rangeStop + step + self._timeline.setWindowWidth(stop_pos - self._timeline.rangeStart) + self._windowspinner.setValue(int(self._windowspinner.value() + int(step * max_frames))) + self.update() def on_backward(self, stepsize): logging.debug("Tracks: receive backward command with step-size: %.2f", stepsize) + max_frames = self._data.max("frame") + if stepsize >= 1.0: + self._clear_detections = True + newx = self._timeline.rangeStart - self._windowspinner.value() / max_frames + self._timeline.setWindowPos(newx) + else: + self._clear_detections = True + step = stepsize * (self._windowspinner.value() / max_frames) + start_pos = self._timeline.rangeStart - step + newwindowwidth = (self._timeline.rangeStop - self._timeline.rangeStart) + step + self._timeline.setWindow(start_pos, newwindowwidth) + self._windowspinner.setValue(int(newwindowwidth *max_frames)) + self.update() + def main(): from PySide6.QtWidgets import QApplication