Enhance ProjectView responsiveness: dynamically adjust canvas size and layout based on actual window dimensions, improving thumbnail placement and visibility. Update calculations for text positioning and item display to ensure consistent user experience across varying window sizes.

This commit is contained in:
2025-09-16 09:48:11 +02:00
parent 46f4441357
commit c56b012246

View File

@@ -136,25 +136,41 @@ class ProjectView:
def draw(self) -> np.ndarray: def draw(self) -> np.ndarray:
"""Draw the project view""" """Draw the project view"""
canvas = np.full((self.window_height, self.window_width, 3), self.BG_COLOR, dtype=np.uint8) # Get actual window size dynamically
try:
# Try to get the actual window size from OpenCV
window_rect = cv2.getWindowImageRect("Project View")
if window_rect[2] > 0 and window_rect[3] > 0: # width and height > 0
actual_width = window_rect[2]
actual_height = window_rect[3]
else:
# Fallback to default size
actual_width = self.window_width
actual_height = self.window_height
except:
# Fallback to default size
actual_width = self.window_width
actual_height = self.window_height
canvas = np.full((actual_height, actual_width, 3), self.BG_COLOR, dtype=np.uint8)
if not self.video_files: if not self.video_files:
# No videos message # No videos message
text = "No videos found in directory" text = "No videos found in directory"
font = cv2.FONT_HERSHEY_SIMPLEX font = cv2.FONT_HERSHEY_SIMPLEX
text_size = cv2.getTextSize(text, font, 1.0, 2)[0] text_size = cv2.getTextSize(text, font, 1.0, 2)[0]
text_x = (self.window_width - text_size[0]) // 2 text_x = (actual_width - text_size[0]) // 2
text_y = (self.window_height - text_size[1]) // 2 text_y = (actual_height - text_size[1]) // 2
cv2.putText(canvas, text, (text_x, text_y), font, 1.0, self.TEXT_COLOR, 2) cv2.putText(canvas, text, (text_x, text_y), font, 1.0, self.TEXT_COLOR, 2)
return canvas return canvas
# Calculate layout - dynamically determine items per row based on thumbnail size # Calculate layout - dynamically determine items per row based on thumbnail size
# Calculate how many thumbnails can fit in the window width # Calculate how many thumbnails can fit in the window width
available_width = self.window_width - self.THUMBNAIL_MARGIN # Account for left margin available_width = actual_width - self.THUMBNAIL_MARGIN # Account for left margin
items_per_row = max(1, (available_width + self.THUMBNAIL_MARGIN) // (self.THUMBNAIL_SIZE[0] + self.THUMBNAIL_MARGIN)) items_per_row = max(1, (available_width + self.THUMBNAIL_MARGIN) // (self.THUMBNAIL_SIZE[0] + self.THUMBNAIL_MARGIN))
items_per_row = min(items_per_row, len(self.video_files)) # Don't exceed number of videos items_per_row = min(items_per_row, len(self.video_files)) # Don't exceed number of videos
item_width = (self.window_width - (items_per_row + 1) * self.THUMBNAIL_MARGIN) // items_per_row item_width = (actual_width - (items_per_row + 1) * self.THUMBNAIL_MARGIN) // items_per_row
thumbnail_width = min(item_width, self.THUMBNAIL_SIZE[0]) thumbnail_width = min(item_width, self.THUMBNAIL_SIZE[0])
thumbnail_height = int(thumbnail_width * self.THUMBNAIL_SIZE[1] / self.THUMBNAIL_SIZE[0]) thumbnail_height = int(thumbnail_width * self.THUMBNAIL_SIZE[1] / self.THUMBNAIL_SIZE[0])
@@ -166,7 +182,7 @@ class ProjectView:
# Skip if scrolled out of view # Skip if scrolled out of view
if row < self.scroll_offset: if row < self.scroll_offset:
continue continue
if row > self.scroll_offset + (self.window_height // self.ITEM_HEIGHT): if row > self.scroll_offset + (actual_height // self.ITEM_HEIGHT):
break break
# Calculate position # Calculate position
@@ -192,15 +208,15 @@ class ProjectView:
resized_thumbnail = cv2.resize(thumbnail, (thumbnail_width, thumbnail_height)) resized_thumbnail = cv2.resize(thumbnail, (thumbnail_width, thumbnail_height))
# Ensure thumbnail doesn't exceed canvas bounds # Ensure thumbnail doesn't exceed canvas bounds
end_y = min(y + thumbnail_height, self.window_height) end_y = min(y + thumbnail_height, actual_height)
end_x = min(x + thumbnail_width, self.window_width) end_x = min(x + thumbnail_width, actual_width)
actual_height = end_y - y thumb_height = end_y - y
actual_width = end_x - x thumb_width = end_x - x
if actual_height > 0 and actual_width > 0: if thumb_height > 0 and thumb_width > 0:
# Resize thumbnail to fit within bounds if necessary # Resize thumbnail to fit within bounds if necessary
if actual_height != thumbnail_height or actual_width != thumbnail_width: if thumb_height != thumbnail_height or thumb_width != thumbnail_width:
resized_thumbnail = cv2.resize(thumbnail, (actual_width, actual_height)) resized_thumbnail = cv2.resize(thumbnail, (thumb_width, thumb_height))
canvas[y:end_y, x:end_x] = resized_thumbnail canvas[y:end_y, x:end_x] = resized_thumbnail
@@ -242,7 +258,7 @@ class ProjectView:
cv2.FONT_HERSHEY_SIMPLEX, 0.4, self.TEXT_COLOR, 1) cv2.FONT_HERSHEY_SIMPLEX, 0.4, self.TEXT_COLOR, 1)
# Calculate current items per row for display # Calculate current items per row for display
available_width = self.window_width - self.THUMBNAIL_MARGIN available_width = actual_width - self.THUMBNAIL_MARGIN
current_items_per_row = max(1, (available_width + self.THUMBNAIL_MARGIN) // (self.THUMBNAIL_SIZE[0] + self.THUMBNAIL_MARGIN)) current_items_per_row = max(1, (available_width + self.THUMBNAIL_MARGIN) // (self.THUMBNAIL_SIZE[0] + self.THUMBNAIL_MARGIN))
current_items_per_row = min(current_items_per_row, len(self.video_files)) current_items_per_row = min(current_items_per_row, len(self.video_files))
@@ -254,7 +270,7 @@ class ProjectView:
] ]
for i, instruction in enumerate(instructions): for i, instruction in enumerate(instructions):
y_pos = self.window_height - 60 + i * 20 y_pos = actual_height - 60 + i * 20
cv2.putText(canvas, instruction, (10, y_pos), cv2.putText(canvas, instruction, (10, y_pos),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, self.TEXT_COLOR, 1) cv2.FONT_HERSHEY_SIMPLEX, 0.5, self.TEXT_COLOR, 1)
@@ -269,7 +285,15 @@ class ProjectView:
return f"open_video:{self.video_files[self.selected_index]}" return f"open_video:{self.video_files[self.selected_index]}"
elif key == ord('w') or key == ord('W'): # W - Up elif key == ord('w') or key == ord('W'): # W - Up
# Calculate current items per row dynamically # Calculate current items per row dynamically
try:
window_rect = cv2.getWindowImageRect("Project View")
if window_rect[2] > 0:
available_width = window_rect[2] - self.THUMBNAIL_MARGIN
else:
available_width = self.window_width - self.THUMBNAIL_MARGIN available_width = self.window_width - self.THUMBNAIL_MARGIN
except:
available_width = self.window_width - self.THUMBNAIL_MARGIN
current_items_per_row = max(1, (available_width + self.THUMBNAIL_MARGIN) // (self.THUMBNAIL_SIZE[0] + self.THUMBNAIL_MARGIN)) current_items_per_row = max(1, (available_width + self.THUMBNAIL_MARGIN) // (self.THUMBNAIL_SIZE[0] + self.THUMBNAIL_MARGIN))
current_items_per_row = min(current_items_per_row, len(self.video_files)) current_items_per_row = min(current_items_per_row, len(self.video_files))
@@ -280,7 +304,15 @@ class ProjectView:
self._update_scroll() self._update_scroll()
elif key == ord('s') or key == ord('S'): # S - Down elif key == ord('s') or key == ord('S'): # S - Down
# Calculate current items per row dynamically # Calculate current items per row dynamically
try:
window_rect = cv2.getWindowImageRect("Project View")
if window_rect[2] > 0:
available_width = window_rect[2] - self.THUMBNAIL_MARGIN
else:
available_width = self.window_width - self.THUMBNAIL_MARGIN available_width = self.window_width - self.THUMBNAIL_MARGIN
except:
available_width = self.window_width - self.THUMBNAIL_MARGIN
current_items_per_row = max(1, (available_width + self.THUMBNAIL_MARGIN) // (self.THUMBNAIL_SIZE[0] + self.THUMBNAIL_MARGIN)) current_items_per_row = max(1, (available_width + self.THUMBNAIL_MARGIN) // (self.THUMBNAIL_SIZE[0] + self.THUMBNAIL_MARGIN))
current_items_per_row = min(current_items_per_row, len(self.video_files)) current_items_per_row = min(current_items_per_row, len(self.video_files))
@@ -320,12 +352,23 @@ class ProjectView:
return return
# Calculate current items per row dynamically # Calculate current items per row dynamically
try:
window_rect = cv2.getWindowImageRect("Project View")
if window_rect[2] > 0 and window_rect[3] > 0:
available_width = window_rect[2] - self.THUMBNAIL_MARGIN
window_height = window_rect[3]
else:
available_width = self.window_width - self.THUMBNAIL_MARGIN available_width = self.window_width - self.THUMBNAIL_MARGIN
window_height = self.window_height
except:
available_width = self.window_width - self.THUMBNAIL_MARGIN
window_height = self.window_height
items_per_row = max(1, (available_width + self.THUMBNAIL_MARGIN) // (self.THUMBNAIL_SIZE[0] + self.THUMBNAIL_MARGIN)) items_per_row = max(1, (available_width + self.THUMBNAIL_MARGIN) // (self.THUMBNAIL_SIZE[0] + self.THUMBNAIL_MARGIN))
items_per_row = min(items_per_row, len(self.video_files)) items_per_row = min(items_per_row, len(self.video_files))
selected_row = self.selected_index // items_per_row selected_row = self.selected_index // items_per_row
visible_rows = max(1, self.window_height // self.ITEM_HEIGHT) visible_rows = max(1, window_height // self.ITEM_HEIGHT)
# Calculate how many rows we can actually show # Calculate how many rows we can actually show
total_rows = (len(self.video_files) + items_per_row - 1) // items_per_row total_rows = (len(self.video_files) + items_per_row - 1) // items_per_row