Click-to-seek, scroll-to-volume, filetype in preview info bar

- Clicking the seek bar jumps to that position (both preview and slideshow)
- Scroll wheel adjusts volume when viewing video (both preview and slideshow)
- Filetype shown in the info bar below preview (e.g. JPG, WEBM, PNG)
This commit is contained in:
pax 2026-04-05 00:21:19 -05:00
parent 5d87457840
commit 2bca5ca188
2 changed files with 37 additions and 4 deletions

View File

@ -733,7 +733,7 @@ class BooruApp(QMainWindow):
if 0 <= index < len(self._posts): if 0 <= index < len(self._posts):
post = self._posts[index] post = self._posts[index]
self._status.showMessage( 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(): if self._info_panel.isVisible():
self._info_panel.set_post(post) self._info_panel.set_post(post)
@ -753,7 +753,7 @@ class BooruApp(QMainWindow):
async def _load(): async def _load():
try: try:
path = await download_image(post.file_url, progress_callback=_progress) 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) self._signals.image_done.emit(str(path), info)
except Exception as e: except Exception as e:
log.error(f"Image download failed: {e}") log.error(f"Image download failed: {e}")

View File

@ -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.QtGui import QPixmap, QPainter, QWheelEvent, QMouseEvent, QKeyEvent, QColor, QMovie
from PySide6.QtWidgets import ( from PySide6.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QLabel, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QMainWindow,
QStackedWidget, QPushButton, QSlider, QMenu, QInputDialog, QStackedWidget, QPushButton, QSlider, QMenu, QInputDialog, QStyle,
) )
from PySide6.QtMultimedia import QMediaPlayer, QAudioOutput from PySide6.QtMultimedia import QMediaPlayer, QAudioOutput
from PySide6.QtMultimediaWidgets import QVideoWidget from PySide6.QtMultimediaWidgets import QVideoWidget
@ -154,6 +154,14 @@ class FullscreenPreview(QMainWindow):
elif key == Qt.Key.Key_Comma and self._stack.currentIndex() == 1: elif key == Qt.Key.Key_Comma and self._stack.currentIndex() == 1:
self._video._seek_relative(-5000) self._video._seek_relative(-5000)
return True 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) return super().eventFilter(obj, event)
def closeEvent(self, event) -> None: def closeEvent(self, event) -> None:
@ -299,6 +307,20 @@ class ImageViewer(QWidget):
self.update() 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 -- # -- Video Player --
class VideoPlayer(QWidget): class VideoPlayer(QWidget):
@ -335,9 +357,10 @@ class VideoPlayer(QWidget):
self._time_label.setFixedWidth(45) self._time_label.setFixedWidth(45)
controls.addWidget(self._time_label) 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.setRange(0, 0)
self._seek_slider.sliderMoved.connect(self._seek) self._seek_slider.sliderMoved.connect(self._seek)
self._seek_slider.clicked_position.connect(self._seek)
controls.addWidget(self._seek_slider, stretch=1) controls.addWidget(self._seek_slider, stretch=1)
self._duration_label = QLabel("0:00") self._duration_label = QLabel("0:00")
@ -610,6 +633,16 @@ class ImagePreview(QWidget):
else: else:
super().mousePressEvent(event) 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: def keyPressEvent(self, event: QKeyEvent) -> None:
if self._stack.currentIndex() == 0: if self._stack.currentIndex() == 0:
self._image_viewer.keyPressEvent(event) self._image_viewer.keyPressEvent(event)