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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user