diff --git a/main.pyw b/main.pyw index 636b16b..2042077 100644 --- a/main.pyw +++ b/main.pyw @@ -192,6 +192,7 @@ KNOWN ISSUES: player becomes slightly less responsive after repeatedly minimizing to system tray (noticable fraction-of-a-second delay when navigating) resizing videos doesn't actually stretch them? or... it does? very strange behavior with phantom black bars that differ from player to player rarely, concatenated videos will have a completely blank frame between clips, causing the theme background to appear for 1 frame + forwards/backwards buttons only work when pressed over the player Medium priority: output-name lineEdit's placeholder text becomes invisible after setting a theme and then changing focus resizing an audio file rarely stalls forever with no error (works upon retry) @@ -1074,7 +1075,9 @@ class GUI_Instance(QtW.QMainWindow, Ui_MainWindow): self.parsed = True - def open(self, file=None, raise_window=True, focus_window=True, remember_old_file=False, _from_cycle=False, _from_dir=False): + def open(self, file=None, raise_window=True, focus_window=True, + update_recent_list=True, remember_old_file=False, + _from_cycle=False, _from_dir=False): ''' Current iteration: III ''' try: if not file: file, cfg.lastdir = qthelpers.browseForFile(cfg.lastdir, 'Select media file to open') @@ -1122,12 +1125,13 @@ class GUI_Instance(QtW.QMainWindow, Ui_MainWindow): else: self.log('Animated GIFs are not supported (just like in VLC).') # update recent media list - if file in self.recent_videos: - self.recent_videos.append(self.recent_videos.pop(self.recent_videos.index(file))) - else: - self.recent_videos.append(file) - if len(self.recent_videos) > 10: - self.recent_videos = self.recent_videos[-10:] + if update_recent_list: + if file in self.recent_videos: + self.recent_videos.append(self.recent_videos.pop(self.recent_videos.index(file))) + else: + self.recent_videos.append(file) + if len(self.recent_videos) > 10: + self.recent_videos = self.recent_videos[-10:] # misc cleanup/setup for new media self.operations = {} diff --git a/widgets.py b/widgets.py index 5d83154..1352cd1 100644 --- a/widgets.py +++ b/widgets.py @@ -430,13 +430,26 @@ def resizeEvent(self, event: QtGui.QResizeEvent): def mousePressEvent(self, event: QtGui.QMouseEvent): - if not self.parent.actionCrop.isChecked(): return - self.panning = False - pos = self.mapFromGlobal(QtGui.QCursor.pos()) # mousePressEvent's event.pos() appears to return incorrect values... - try: # ...in certain areas, leading to bad offsets and mismatched selections - self.dragging = self.get_crop_point_index_in_range(pos) + ''' Handles grabbing crop points/edges in crop-mode, as well as detected the + forwards/backwards buttons and moving through the recent files list. ''' + try: + if not self.parent.actionCrop.isChecked(): # no crop -> check for forward/backward buttons + # NOTE: recent_videos is least recent to most recent -> index 0 is the LEAST recent + if event.button() == Qt.BackButton or event.button() == Qt.ForwardButton: + if self.parent.video not in self.parent.recent_videos: return + current_index = self.parent.recent_videos.index(self.parent.video) + new_index = current_index + (1 if event.button() == Qt.ForwardButton else -1) + if 0 <= new_index <= len(self.parent.recent_videos) - 1: + file = self.parent.recent_videos[new_index] + self.parent.open(file, update_recent_list=False) + self.parent.log(f'Opened recent file #{len(self.parent.recent_videos) - new_index}: {file}') + return # TODO add forward/backwards functionality globally (not as easy as it sounds?) + + self.panning = False + pos = self.mapFromGlobal(QtGui.QCursor.pos()) # mousePressEvent's event.pos() appears to return incorrect values... + self.dragging = self.get_crop_point_index_in_range(pos) # ...in certain areas, leading to bad offsets and mismatched selections if self.dragging is not None: - self.drag_axis_lock = None # reset axis lock before dragging corners + self.drag_axis_lock = None # reset axis lock before dragging corners self.dragging_offset = pos - self.selection[self.dragging] else: edge_index = self.get_crop_edge_index_in_range(pos) @@ -448,25 +461,25 @@ def mousePressEvent(self, event: QtGui.QMouseEvent): self.dragging = 0 if edge_index < 2 else 3 self.drag_axis_lock = 1 self.dragging_offset = pos - self.selection[self.dragging] - elif self.crop_rect.contains(pos): + elif self.crop_rect.contains(pos): # no corners/edges, but clicked inside crop rect -> panning self.dragging = -1 - self.drag_axis_lock = None # reset axis lock before panning + self.drag_axis_lock = None # reset axis lock before panning self.dragging_offset = pos - self.selection[0] if app.overrideCursor() is None: app.setOverrideCursor(QtGui.QCursor(Qt.ClosedHandCursor)) else: app.changeOverrideCursor(QtGui.QCursor(Qt.ClosedHandCursor)) event.accept() self.update() - except: logging.warning(f'(!) Unexpected error while clicking crop points: {format_exc()}') + except: logging.warning(f'(!) Unexpected error while clicking QVideoPlayer: {format_exc()}') return super().mousePressEvent(event) def mouseMoveEvent(self, event: QtGui.QMouseEvent): ''' Allows users to drag crop borders by their corners. ''' - if not self.parent.actionCrop.isChecked(): # idle timeout is handled in QVideoSlider's paintEvent since it's constantly updated, unlike QVideoPlayer + if not self.parent.actionCrop.isChecked(): # idle timeout is handled in QVideoSlider's paintEvent since it constantly updates if self.parent.dialog_settings.checkHideIdleCursor.isChecked() and self.parent.video: - self.last_move_time = time.time() # update move time if a video is playing and idle timeouts are enabled - else: self.last_move_time = 0 # otherwise, keep move time at 0 - return event.ignore() # only handle idle timeouts if we're not cropping + self.last_move_time = time.time() # update move time if a video is playing and idle timeouts are enabled + else: self.last_move_time = 0 # otherwise, keep move time at 0 + return event.ignore() # only handle idle timeouts if we're not cropping self.last_move_time = 0 try: pos = self.mapFromGlobal(event.globalPos()) # event.pos() does not work. I have no explanation.