diff --git a/booru_viewer/gui/app.py b/booru_viewer/gui/app.py index d30abb2..8a03c7c 100644 --- a/booru_viewer/gui/app.py +++ b/booru_viewer/gui/app.py @@ -733,7 +733,7 @@ class BooruApp(QMainWindow): if 0 <= index < len(self._posts): post = self._posts[index] self._status.showMessage( - f"#{post.id} {post.width}x{post.height} score:{post.score} [{post.rating}]" + f"#{post.id} {post.width}x{post.height} score:{post.score} [{post.rating}] {Path(post.file_url.split('?')[0]).suffix.lstrip('.').upper() if post.file_url else ''}" ) if self._info_panel.isVisible(): self._info_panel.set_post(post) @@ -753,7 +753,7 @@ class BooruApp(QMainWindow): async def _load(): try: path = await download_image(post.file_url, progress_callback=_progress) - info = f"#{post.id} {post.width}x{post.height} score:{post.score} [{post.rating}]" + info = f"#{post.id} {post.width}x{post.height} score:{post.score} [{post.rating}] {Path(post.file_url.split('?')[0]).suffix.lstrip('.').upper() if post.file_url else ''}" self._signals.image_done.emit(str(path), info) except Exception as e: log.error(f"Image download failed: {e}") diff --git a/booru_viewer/gui/preview.py b/booru_viewer/gui/preview.py index 9b9a334..3da3050 100644 --- a/booru_viewer/gui/preview.py +++ b/booru_viewer/gui/preview.py @@ -8,7 +8,7 @@ from PySide6.QtCore import Qt, QPoint, QPointF, Signal, QUrl from PySide6.QtGui import QPixmap, QPainter, QWheelEvent, QMouseEvent, QKeyEvent, QColor, QMovie from PySide6.QtWidgets import ( QWidget, QVBoxLayout, QHBoxLayout, QLabel, QMainWindow, - QStackedWidget, QPushButton, QSlider, QMenu, QInputDialog, + QStackedWidget, QPushButton, QSlider, QMenu, QInputDialog, QStyle, ) from PySide6.QtMultimedia import QMediaPlayer, QAudioOutput from PySide6.QtMultimediaWidgets import QVideoWidget @@ -154,6 +154,14 @@ class FullscreenPreview(QMainWindow): elif key == Qt.Key.Key_Comma and self._stack.currentIndex() == 1: self._video._seek_relative(-5000) return True + if event.type() == QEvent.Type.Wheel and self._stack.currentIndex() == 1: + delta = event.angleDelta().y() + if delta: + vol = self._video._audio.volume() + vol = max(0.0, min(1.0, vol + (0.05 if delta > 0 else -0.05))) + self._video._audio.setVolume(vol) + self._video._vol_slider.setValue(int(vol * 100)) + return True return super().eventFilter(obj, event) def closeEvent(self, event) -> None: @@ -299,6 +307,20 @@ class ImageViewer(QWidget): self.update() +class _ClickSeekSlider(QSlider): + """Slider that jumps to the clicked position instead of page-stepping.""" + clicked_position = Signal(int) + + def mousePressEvent(self, event): + if event.button() == Qt.MouseButton.LeftButton: + val = QStyle.sliderValueFromPosition( + self.minimum(), self.maximum(), int(event.position().x()), self.width() + ) + self.setValue(val) + self.clicked_position.emit(val) + super().mousePressEvent(event) + + # -- Video Player -- class VideoPlayer(QWidget): @@ -335,9 +357,10 @@ class VideoPlayer(QWidget): self._time_label.setFixedWidth(45) controls.addWidget(self._time_label) - self._seek_slider = QSlider(Qt.Orientation.Horizontal) + self._seek_slider = _ClickSeekSlider(Qt.Orientation.Horizontal) self._seek_slider.setRange(0, 0) self._seek_slider.sliderMoved.connect(self._seek) + self._seek_slider.clicked_position.connect(self._seek) controls.addWidget(self._seek_slider, stretch=1) self._duration_label = QLabel("0:00") @@ -610,6 +633,16 @@ class ImagePreview(QWidget): else: super().mousePressEvent(event) + def wheelEvent(self, event) -> None: + if self._stack.currentIndex() == 1: + delta = event.angleDelta().y() + vol = self._video_player._audio.volume() + vol = max(0.0, min(1.0, vol + (0.05 if delta > 0 else -0.05))) + self._video_player._audio.setVolume(vol) + self._video_player._vol_slider.setValue(int(vol * 100)) + else: + super().wheelEvent(event) + def keyPressEvent(self, event: QKeyEvent) -> None: if self._stack.currentIndex() == 0: self._image_viewer.keyPressEvent(event)