Deretard the help OSD
This commit is contained in:
153
croppa/main.py
153
croppa/main.py
@@ -1346,7 +1346,7 @@ class VideoEditor:
|
||||
|
||||
return (ix, iy, iw, ih), iz
|
||||
|
||||
def set_crop_zoom_keyframe_at_current_frame(self):
|
||||
def _update_crop_zoom_keyframe_for_current_frame(self):
|
||||
"""Create or update crop/zoom keyframe at current frame from current crop/zoom settings."""
|
||||
frame_index = getattr(self, 'current_frame', 0)
|
||||
base_rect = self._get_base_crop_rect_for_frame(frame_index)
|
||||
@@ -1354,10 +1354,6 @@ class VideoEditor:
|
||||
'crop_rect': base_rect,
|
||||
'zoom_factor': self.zoom_factor,
|
||||
}
|
||||
self.crop_rect = base_rect
|
||||
self.clear_transformation_cache()
|
||||
self.display_needs_update = True
|
||||
self.show_feedback_message("Crop/zoom keyframe set")
|
||||
|
||||
def delete_crop_zoom_keyframe_at_current_frame(self):
|
||||
"""Delete crop/zoom keyframe at current frame if it exists."""
|
||||
@@ -3151,22 +3147,118 @@ class VideoEditor:
|
||||
x, y, w, h = self.template_selection_rect
|
||||
cv2.rectangle(canvas, (x, y), (x + w, y + h), (255, 0, 255), 2) # Magenta for template selection
|
||||
|
||||
# Help overlay for keybindings
|
||||
# Help overlay for keybindings (top-left, multi-column, all keybinds)
|
||||
if self.show_help_overlay:
|
||||
help_lines = [
|
||||
"Playback / Seek:",
|
||||
" SPACE - play/pause (video only)",
|
||||
" a / d - step -1 / +1 frame",
|
||||
" A / D - auto-repeat seek -10 / +10 frames",
|
||||
" Ctrl+A / Ctrl+D - auto-repeat seek -60 / +60 frames",
|
||||
" , / . - prev / next cut marker",
|
||||
" 1 / 2 - set cut start / end",
|
||||
" Shift+1 / Shift+2 - jump to cut start / end",
|
||||
" N / n - previous / next video",
|
||||
"",
|
||||
"Speed / Seek Multiplier:",
|
||||
" w / s - speed up / slow down",
|
||||
" Q / Y - increase / decrease seek multiplier",
|
||||
"",
|
||||
"View / Rotation / Screenshots:",
|
||||
" f - toggle fullscreen",
|
||||
" - / _ - rotate 90 degrees",
|
||||
" S - save screenshot",
|
||||
"",
|
||||
"Brightness / Contrast:",
|
||||
" e / E - increase / decrease brightness",
|
||||
" r / R - increase / decrease contrast",
|
||||
"",
|
||||
"Crop / Zoom (mouse):",
|
||||
" Shift+LMB drag - draw new crop",
|
||||
" LMB drag inside crop - expand edge toward drag",
|
||||
" LMB+RMB drag inside crop - contract opposite edge",
|
||||
" scroll - zoom in/out",
|
||||
" Shift+scroll - uniform crop expand/contract",
|
||||
"",
|
||||
"Crop / Zoom (keyboard):",
|
||||
" J/K/L/H - expand up/down/left/right",
|
||||
" k/j/h/l - contract from bottom/top/right/left",
|
||||
" u - undo last crop",
|
||||
" c - clear crop/zoom and keyframes",
|
||||
" C - complete reset",
|
||||
"",
|
||||
"Crop/Zoom Keyframes:",
|
||||
" y - set/update keyframe at current frame",
|
||||
" U - delete keyframe at current frame",
|
||||
" i - clone previous keyframe to current frame",
|
||||
" [ / ] - prev/next keyframe",
|
||||
" ? - toggle this help",
|
||||
" automatic per frame on crop/zoom change",
|
||||
" 3 / 4 - prev / next crop/zoom keyframe",
|
||||
" 5 - clone previous keyframe to current frame",
|
||||
" 6 - delete keyframe at current frame",
|
||||
"",
|
||||
"Motion Tracking / Features / Templates:",
|
||||
" v / V - toggle motion tracking / clear points",
|
||||
" F - toggle feature tracking",
|
||||
" T - extract features from visible area",
|
||||
" g / G - toggle auto tracking / clear feature data",
|
||||
" Z - switch detector type",
|
||||
" z - toggle selective feature extraction mode",
|
||||
" o - toggle optical flow",
|
||||
" m / M - clear templates / toggle full-frame template matching",
|
||||
" ; / : - prev / next template marker",
|
||||
"",
|
||||
"Frame Difference / Interesting Region:",
|
||||
" ; - next interesting point / cancel search",
|
||||
" ' - toggle interesting region selection",
|
||||
" 9 / 0 - decrease / increase diff threshold",
|
||||
" ) / = - threshold -10 / +10",
|
||||
" 7 / 8 - decrease / increase diff gap",
|
||||
" / / ( - diff gap -60 / +60",
|
||||
"",
|
||||
"Rendering / Misc:",
|
||||
" b - render to new _edited_ file",
|
||||
" ENTER - overwrite existing _edited_ file (render)",
|
||||
" x - cancel render",
|
||||
" p - toggle project view",
|
||||
" t - toggle marker looping",
|
||||
" ? - toggle this help overlay",
|
||||
]
|
||||
base_y = self.window_height - self.TIMELINE_HEIGHT - 10
|
||||
for idx, text in enumerate(help_lines):
|
||||
y_pos = base_y - 18 * (len(help_lines) - idx)
|
||||
cv2.putText(canvas, text, (10, y_pos), cv2.FONT_HERSHEY_SIMPLEX, self.FONT_SCALE_SMALL, (255, 255, 255), 2)
|
||||
cv2.putText(canvas, text, (10, y_pos), cv2.FONT_HERSHEY_SIMPLEX, self.FONT_SCALE_SMALL, (0, 0, 0), 1)
|
||||
|
||||
font_scale = 0.7
|
||||
font = cv2.FONT_HERSHEY_SIMPLEX
|
||||
font_thick_white = 2
|
||||
font_thick_black = 0
|
||||
line_height = int(42 * font_scale)
|
||||
margin_x = 30
|
||||
margin_y = 80
|
||||
|
||||
# Two columns: split by line count
|
||||
total_lines = len(help_lines)
|
||||
mid = (total_lines + 1) // 2
|
||||
columns = [
|
||||
(margin_x, help_lines[:mid]),
|
||||
(margin_x + 920, help_lines[mid:]),
|
||||
]
|
||||
|
||||
# First, compute the background rectangle bounds for both columns to cover all lines
|
||||
max_lines_in_col = max(len(col[1]) for col in columns)
|
||||
col_width = 890 # Leave some padding, adjust if needed
|
||||
col_height = max_lines_in_col * line_height + 20
|
||||
bg_rect_margin = 12
|
||||
|
||||
# Draw black background rectangles for both columns
|
||||
for idx, (col_x, lines) in enumerate(columns):
|
||||
if len(lines) == 0:
|
||||
continue
|
||||
x1 = col_x - bg_rect_margin
|
||||
y1 = margin_y - bg_rect_margin
|
||||
x2 = col_x + col_width + bg_rect_margin
|
||||
y2 = margin_y + len(lines) * line_height + bg_rect_margin
|
||||
cv2.rectangle(canvas, (x1, y1), (x2, y2), (0, 0, 0), thickness=-1)
|
||||
|
||||
# Draw text in red on top of the black backgrounds
|
||||
for col_x, lines in columns:
|
||||
for idx, text in enumerate(lines):
|
||||
x_pos = col_x
|
||||
y_pos = margin_y + idx * line_height
|
||||
cv2.putText(canvas, text, (x_pos, y_pos), font, font_scale, (0, 0, 255), font_thick_white, lineType=cv2.LINE_AA)
|
||||
cv2.putText(canvas, text, (x_pos, y_pos), font, font_scale, (0, 0, 0), font_thick_black, lineType=cv2.LINE_AA)
|
||||
# Draw previous and next tracking points with motion path visualization
|
||||
if not self.is_image_mode and self.tracking_points:
|
||||
prev_result = self._get_previous_tracking_point()
|
||||
@@ -3473,6 +3565,7 @@ class VideoEditor:
|
||||
self.crop_border_drag_start_rect = None
|
||||
self.crop_drag_edge = None
|
||||
self.crop_drag_mode = None
|
||||
self._update_crop_zoom_keyframe_for_current_frame()
|
||||
self.save_state()
|
||||
|
||||
# Handle crop selection (Shift + click and drag)
|
||||
@@ -3496,6 +3589,7 @@ class VideoEditor:
|
||||
print(f"DEBUG: Crop end screen_rect={self.crop_preview_rect}")
|
||||
# Convert screen coordinates to video coordinates
|
||||
self.set_crop_from_screen_coords(self.crop_preview_rect)
|
||||
self._update_crop_zoom_keyframe_for_current_frame()
|
||||
self.crop_selecting = False
|
||||
self.crop_start_point = None
|
||||
self.crop_preview_rect = None
|
||||
@@ -3768,6 +3862,7 @@ class VideoEditor:
|
||||
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._update_crop_zoom_keyframe_for_current_frame()
|
||||
self.clear_transformation_cache()
|
||||
|
||||
def _set_crop_from_rotated_rect(self, rotated_rect):
|
||||
@@ -3970,6 +4065,9 @@ class VideoEditor:
|
||||
default_size,
|
||||
default_size
|
||||
)
|
||||
self._update_crop_zoom_keyframe_for_current_frame()
|
||||
self.clear_transformation_cache()
|
||||
self.save_state()
|
||||
return
|
||||
|
||||
x, y, w, h = self.crop_rect
|
||||
@@ -4020,6 +4118,7 @@ class VideoEditor:
|
||||
new_w = w - amount
|
||||
self.crop_rect = (new_x, y, new_w, h)
|
||||
|
||||
self._update_crop_zoom_keyframe_for_current_frame()
|
||||
self.clear_transformation_cache()
|
||||
self.save_state() # Save state when crop is adjusted
|
||||
|
||||
@@ -4040,6 +4139,9 @@ class VideoEditor:
|
||||
default_size,
|
||||
default_size
|
||||
)
|
||||
self._update_crop_zoom_keyframe_for_current_frame()
|
||||
self.clear_transformation_cache()
|
||||
self.save_state()
|
||||
return
|
||||
|
||||
x, y, w, h = self.crop_rect
|
||||
@@ -4059,6 +4161,7 @@ class VideoEditor:
|
||||
new_h = max(10, h - contract_amount * 2)
|
||||
|
||||
self.crop_rect = (new_x, new_y, new_w, new_h)
|
||||
self._update_crop_zoom_keyframe_for_current_frame()
|
||||
self.clear_transformation_cache()
|
||||
self.save_state()
|
||||
|
||||
@@ -5035,17 +5138,15 @@ class VideoEditor:
|
||||
self.show_help_overlay = not self.show_help_overlay
|
||||
self.display_needs_update = True
|
||||
|
||||
# Crop/zoom keyframe controls
|
||||
elif key == ord("y"):
|
||||
self.set_crop_zoom_keyframe_at_current_frame()
|
||||
elif key == ord("U"):
|
||||
self.delete_crop_zoom_keyframe_at_current_frame()
|
||||
elif key == ord("i"):
|
||||
self.clone_previous_crop_zoom_keyframe_to_current()
|
||||
elif key == ord("["):
|
||||
# Crop/zoom keyframe controls (automatic per frame; navigation + clone/delete)
|
||||
elif key == ord("3"):
|
||||
self.jump_to_previous_crop_zoom_keyframe()
|
||||
elif key == ord("]"):
|
||||
elif key == ord("4"):
|
||||
self.jump_to_next_crop_zoom_keyframe()
|
||||
elif key == ord("5"):
|
||||
self.clone_previous_crop_zoom_keyframe_to_current()
|
||||
elif key == ord("6"):
|
||||
self.delete_crop_zoom_keyframe_at_current_frame()
|
||||
|
||||
# Individual direction controls using shift combinations we can detect
|
||||
elif key == ord("J"): # Shift+i - expand up
|
||||
|
||||
Reference in New Issue
Block a user