Refine crop border dragging logic to improve responsiveness and accuracy

Enhance the crop border dragging functionality in the VideoEditor class by implementing more precise logic for determining the side of the crop area when dragging outside its bounds. Adjustments to crop dimensions are now consistently based on the drag direction, ensuring a more intuitive user experience. This update also resets the drag state appropriately after the drag operation.
This commit is contained in:
2025-12-23 09:39:28 +01:00
parent bf32bb98ae
commit 238b139b10

View File

@@ -157,6 +157,7 @@ class VideoEditor:
self.crop_border_drag_start_pos = None # (screen_x, screen_y) when drag started
self.crop_border_drag_start_rect = None # (x, y, w, h) in rotated coords when drag started
self.crop_border_drag_inside = None # True if drag started inside crop area, False if outside
self.crop_border_drag_outside_side = None # 'left', 'right', 'top', 'bottom' if outside
# Zoom settings
self.zoom_factor = 1.0
@@ -3126,12 +3127,25 @@ class VideoEditor:
# Check if cursor is inside crop area
inside_crop = sx1 <= x <= sx2 and sy1 <= y <= sy2
# Determine which side we're on if outside (for better contraction logic)
outside_side = None
if not inside_crop:
if x < sx1:
outside_side = 'left'
elif x > sx2:
outside_side = 'right'
elif y < sy1:
outside_side = 'top'
elif y > sy2:
outside_side = 'bottom'
if event == cv2.EVENT_LBUTTONDOWN:
# Start dragging - record position and whether we're inside/outside
self.crop_border_dragging = True
self.crop_border_drag_start_pos = (x, y)
self.crop_border_drag_start_rect = (eff_x, eff_y, eff_w, eff_h)
self.crop_border_drag_inside = inside_crop
self.crop_border_drag_outside_side = outside_side
elif event == cv2.EVENT_MOUSEMOVE and self.crop_border_dragging:
if self.crop_border_drag_start_pos and self.crop_border_drag_start_rect and self.crop_border_drag_inside is not None:
# Convert mouse movement from screen to rotated coords
@@ -3173,17 +3187,21 @@ class VideoEditor:
if new_x + new_w > rot_w:
new_w = rot_w - new_x
else:
# Outside crop: drag left -> adjust right border left (contract), drag right -> adjust right border right (expand)
# Outside crop: always contract based on drag direction
# Drag left -> contract right (move right border left)
# Drag right -> contract left (move left border right)
if dx_r < 0:
# Dragging left -> move right border left (contract right)
new_w = max(self.CROP_MIN_SIZE, new_w + dx_r)
if new_w < self.CROP_MIN_SIZE:
new_w = self.CROP_MIN_SIZE
else:
# Dragging right -> move right border right (expand right)
new_w = max(self.CROP_MIN_SIZE, new_w + dx_r)
if new_x + new_w > rot_w:
new_w = rot_w - new_x
# Dragging right -> move left border right (contract left)
new_x = max(0, new_x + dx_r)
new_w = new_w - dx_r
if new_w < self.CROP_MIN_SIZE:
new_w = self.CROP_MIN_SIZE
new_x = self.crop_border_drag_start_rect[0] + self.crop_border_drag_start_rect[2] - self.CROP_MIN_SIZE
else:
# Vertical movement
if self.crop_border_drag_inside:
@@ -3201,17 +3219,21 @@ class VideoEditor:
if new_y + new_h > rot_h:
new_h = rot_h - new_y
else:
# Outside crop: drag up -> adjust bottom border up (contract), drag down -> adjust bottom border down (expand)
# Outside crop: always contract based on drag direction
# Drag up -> contract bottom (move bottom border up)
# Drag down -> contract top (move top border down)
if dy_r < 0:
# Dragging up -> move bottom border up (contract bottom)
new_h = max(self.CROP_MIN_SIZE, new_h + dy_r)
if new_h < self.CROP_MIN_SIZE:
new_h = self.CROP_MIN_SIZE
else:
# Dragging down -> move bottom border down (expand down)
new_h = max(self.CROP_MIN_SIZE, new_h + dy_r)
if new_y + new_h > rot_h:
new_h = rot_h - new_y
# Dragging down -> move top border down (contract top)
new_y = max(0, new_y + dy_r)
new_h = new_h - dy_r
if new_h < self.CROP_MIN_SIZE:
new_h = self.CROP_MIN_SIZE
new_y = self.crop_border_drag_start_rect[1] + self.crop_border_drag_start_rect[3] - self.CROP_MIN_SIZE
# Convert back from rotated to original frame coords
self._set_crop_from_rotated_rect((new_x, new_y, new_w, new_h))
@@ -3222,6 +3244,7 @@ class VideoEditor:
self.crop_border_drag_start_pos = None
self.crop_border_drag_start_rect = None
self.crop_border_drag_inside = None
self.crop_border_drag_outside_side = None
self.save_state()
# Handle crop selection (Shift + click and drag)