diff --git a/croppa/main.py b/croppa/main.py index 525d29b..18933b1 100644 --- a/croppa/main.py +++ b/croppa/main.py @@ -3495,24 +3495,26 @@ class VideoEditor: # Force immediate display update to recalculate previous/next points and arrows self.display_current_frame() - # Handle scroll wheel: Ctrl+scroll -> zoom; Shift+scroll -> expand/contract crop; plain scroll -> seek ±1 frame + # Handle scroll wheel: plain scroll -> zoom; Shift+scroll -> expand/contract crop; Ctrl+scroll -> scrub timeline if event == cv2.EVENT_MOUSEWHEEL: - if flags & cv2.EVENT_FLAG_CTRLKEY: - if flags > 0: # Scroll up -> zoom in - self.zoom_factor = min(self.MAX_ZOOM, self.zoom_factor + self.ZOOM_INCREMENT) - else: # Scroll down -> zoom out - self.zoom_factor = max(self.MIN_ZOOM, self.zoom_factor - self.ZOOM_INCREMENT) - self.clear_transformation_cache() - elif flags & cv2.EVENT_FLAG_SHIFTKEY: + if flags & cv2.EVENT_FLAG_SHIFTKEY: # Shift+scroll -> expand/contract crop uniformly if flags > 0: # Scroll up -> expand self.adjust_crop_size_uniform(expand=True) else: # Scroll down -> contract self.adjust_crop_size_uniform(expand=False) - else: + elif flags & cv2.EVENT_FLAG_CTRLKEY: + # Ctrl+scroll -> scrub timeline using modifier-based seeking if not self.is_image_mode: direction = 1 if flags > 0 else -1 - self.seek_video_exact_frame(direction) + self.seek_video_with_modifier(direction, shift_pressed=False, ctrl_pressed=True) + else: + # Plain scroll -> zoom + if flags > 0: # Scroll up -> zoom in + self.zoom_factor = min(self.MAX_ZOOM, self.zoom_factor + self.ZOOM_INCREMENT) + else: # Scroll down -> zoom out + self.zoom_factor = max(self.MIN_ZOOM, self.zoom_factor - self.ZOOM_INCREMENT) + self.clear_transformation_cache() def _set_crop_from_rotated_rect(self, rotated_rect): """Set crop_rect from a rectangle in rotated frame coordinates"""