Slideshow mode, Win10 dark mode fixes, key propagation fix
- Add "Slideshow Mode" to preview right-click context menu - Fix arrow key propagation in fullscreen/slideshow view - Flatten Fusion dark mode buttons with stylesheet - Fix Save button width, fix spinbox arrows on dark theme
This commit is contained in:
parent
967bdb4612
commit
238df9cf3e
@ -301,7 +301,9 @@ class BooruApp(QMainWindow):
|
||||
self._preview.favorite_requested.connect(self._favorite_from_preview)
|
||||
self._preview.save_to_folder.connect(self._save_from_preview)
|
||||
self._preview.navigate.connect(self._navigate_preview)
|
||||
self._preview.fullscreen_requested.connect(self._open_fullscreen_preview)
|
||||
self._preview.set_folders_callback(self._db.get_folders)
|
||||
self._fullscreen_window = None
|
||||
self._preview.setMinimumWidth(300)
|
||||
right.addWidget(self._preview)
|
||||
|
||||
@ -701,6 +703,9 @@ class BooruApp(QMainWindow):
|
||||
idx = self._grid.selected_index
|
||||
if 0 <= idx < len(self._grid._thumbs):
|
||||
self._grid._thumbs[idx]._cached_path = path
|
||||
# Update fullscreen if open
|
||||
if self._fullscreen_window and self._fullscreen_window.isVisible():
|
||||
self._fullscreen_window.set_media(path, info)
|
||||
|
||||
def _on_favorite_selected(self, fav) -> None:
|
||||
self._status.showMessage(f"Favorite #{fav.post_id}")
|
||||
@ -793,6 +798,24 @@ class BooruApp(QMainWindow):
|
||||
self._db.add_folder(folder)
|
||||
self._save_to_library(self._posts[idx], target)
|
||||
|
||||
def _open_fullscreen_preview(self) -> None:
|
||||
path = self._preview._current_path
|
||||
if not path:
|
||||
return
|
||||
from .preview import FullscreenPreview
|
||||
self._fullscreen_window = FullscreenPreview(parent=self)
|
||||
self._fullscreen_window.navigate.connect(self._navigate_fullscreen)
|
||||
self._fullscreen_window.set_media(path, self._preview._info_label.text())
|
||||
|
||||
def _navigate_fullscreen(self, direction: int) -> None:
|
||||
self._navigate_preview(direction)
|
||||
# For synchronous loads (cached/favorites), update immediately
|
||||
if self._fullscreen_window and self._preview._current_path:
|
||||
self._fullscreen_window.set_media(
|
||||
self._preview._current_path,
|
||||
self._preview._info_label.text(),
|
||||
)
|
||||
|
||||
def _close_preview(self) -> None:
|
||||
self._preview.clear()
|
||||
|
||||
@ -1320,22 +1343,63 @@ def _apply_windows_dark_mode(app: QApplication) -> None:
|
||||
from PySide6.QtGui import QPalette, QColor
|
||||
app.setStyle("Fusion")
|
||||
palette = QPalette()
|
||||
palette.setColor(QPalette.ColorRole.Window, QColor(30, 30, 30))
|
||||
palette.setColor(QPalette.ColorRole.Window, QColor(32, 32, 32))
|
||||
palette.setColor(QPalette.ColorRole.WindowText, QColor(255, 255, 255))
|
||||
palette.setColor(QPalette.ColorRole.Base, QColor(15, 15, 15))
|
||||
palette.setColor(QPalette.ColorRole.AlternateBase, QColor(35, 35, 35))
|
||||
palette.setColor(QPalette.ColorRole.ToolTipBase, QColor(255, 255, 255))
|
||||
palette.setColor(QPalette.ColorRole.Base, QColor(25, 25, 25))
|
||||
palette.setColor(QPalette.ColorRole.AlternateBase, QColor(38, 38, 38))
|
||||
palette.setColor(QPalette.ColorRole.ToolTipBase, QColor(50, 50, 50))
|
||||
palette.setColor(QPalette.ColorRole.ToolTipText, QColor(255, 255, 255))
|
||||
palette.setColor(QPalette.ColorRole.Text, QColor(255, 255, 255))
|
||||
palette.setColor(QPalette.ColorRole.Button, QColor(40, 40, 40))
|
||||
palette.setColor(QPalette.ColorRole.Button, QColor(51, 51, 51))
|
||||
palette.setColor(QPalette.ColorRole.ButtonText, QColor(255, 255, 255))
|
||||
palette.setColor(QPalette.ColorRole.BrightText, QColor(255, 0, 0))
|
||||
palette.setColor(QPalette.ColorRole.Link, QColor(42, 130, 218))
|
||||
palette.setColor(QPalette.ColorRole.Highlight, QColor(42, 130, 218))
|
||||
palette.setColor(QPalette.ColorRole.HighlightedText, QColor(0, 0, 0))
|
||||
palette.setColor(QPalette.ColorRole.Link, QColor(0, 120, 215))
|
||||
palette.setColor(QPalette.ColorRole.Highlight, QColor(0, 120, 215))
|
||||
palette.setColor(QPalette.ColorRole.HighlightedText, QColor(255, 255, 255))
|
||||
palette.setColor(QPalette.ColorRole.Mid, QColor(51, 51, 51))
|
||||
palette.setColor(QPalette.ColorRole.Dark, QColor(25, 25, 25))
|
||||
palette.setColor(QPalette.ColorRole.Shadow, QColor(0, 0, 0))
|
||||
palette.setColor(QPalette.ColorRole.Light, QColor(60, 60, 60))
|
||||
palette.setColor(QPalette.ColorRole.Midlight, QColor(55, 55, 55))
|
||||
palette.setColor(QPalette.ColorGroup.Disabled, QPalette.ColorRole.Text, QColor(127, 127, 127))
|
||||
palette.setColor(QPalette.ColorGroup.Disabled, QPalette.ColorRole.ButtonText, QColor(127, 127, 127))
|
||||
app.setPalette(palette)
|
||||
# Flatten Fusion's 3D look
|
||||
app.setStyleSheet(app.styleSheet() + """
|
||||
QPushButton {
|
||||
border: 1px solid #555;
|
||||
border-radius: 2px;
|
||||
padding: 4px 12px;
|
||||
}
|
||||
QPushButton:hover { background-color: #444; }
|
||||
QPushButton:pressed { background-color: #333; }
|
||||
QComboBox {
|
||||
border: 1px solid #555;
|
||||
border-radius: 2px;
|
||||
padding: 3px 6px;
|
||||
}
|
||||
QSpinBox {
|
||||
border: 1px solid #555;
|
||||
border-radius: 2px;
|
||||
}
|
||||
QLineEdit {
|
||||
border: 1px solid #555;
|
||||
border-radius: 2px;
|
||||
padding: 3px;
|
||||
}
|
||||
QScrollBar:vertical {
|
||||
background: #252525;
|
||||
width: 12px;
|
||||
}
|
||||
QScrollBar::handle:vertical {
|
||||
background: #555;
|
||||
border-radius: 4px;
|
||||
min-height: 20px;
|
||||
}
|
||||
QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
|
||||
height: 0;
|
||||
}
|
||||
""")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
@ -23,27 +23,34 @@ def _is_video(path: str) -> bool:
|
||||
|
||||
|
||||
class FullscreenPreview(QMainWindow):
|
||||
"""Fullscreen image viewer window."""
|
||||
"""Fullscreen image viewer window with navigation."""
|
||||
|
||||
def __init__(self, pixmap: QPixmap, info: str = "", parent=None) -> None:
|
||||
super().__init__(parent)
|
||||
navigate = Signal(int) # -1 = prev, +1 = next
|
||||
|
||||
def __init__(self, parent=None) -> None:
|
||||
super().__init__(parent, Qt.WindowType.Window)
|
||||
self.setWindowTitle("booru-viewer — Fullscreen")
|
||||
self._preview = ImageViewer()
|
||||
self._preview.set_image(pixmap, info)
|
||||
self._preview.close_requested.connect(self.close)
|
||||
self.setCentralWidget(self._preview)
|
||||
if parent:
|
||||
screen = parent.screen()
|
||||
else:
|
||||
from PySide6.QtWidgets import QApplication
|
||||
screen = QApplication.primaryScreen()
|
||||
if screen:
|
||||
self.setGeometry(screen.geometry())
|
||||
self._viewer = ImageViewer()
|
||||
self._viewer.close_requested.connect(self.close)
|
||||
self.setCentralWidget(self._viewer)
|
||||
self.showFullScreen()
|
||||
|
||||
def set_media(self, path: str, info: str = "") -> None:
|
||||
ext = Path(path).suffix.lower()
|
||||
if ext == ".gif":
|
||||
self._viewer.set_gif(path, info)
|
||||
else:
|
||||
pix = QPixmap(path)
|
||||
if not pix.isNull():
|
||||
self._viewer.set_image(pix, info)
|
||||
|
||||
def keyPressEvent(self, event: QKeyEvent) -> None:
|
||||
if event.key() in (Qt.Key.Key_Escape, Qt.Key.Key_Q, Qt.Key.Key_F):
|
||||
if event.key() in (Qt.Key.Key_Escape, Qt.Key.Key_Q):
|
||||
self.close()
|
||||
elif event.key() in (Qt.Key.Key_Left, Qt.Key.Key_H):
|
||||
self.navigate.emit(-1)
|
||||
elif event.key() in (Qt.Key.Key_Right, Qt.Key.Key_L):
|
||||
self.navigate.emit(1)
|
||||
else:
|
||||
super().keyPressEvent(event)
|
||||
|
||||
@ -175,6 +182,8 @@ class ImageViewer(QWidget):
|
||||
elif event.key() == Qt.Key.Key_Minus:
|
||||
self._zoom = max(self._zoom / 1.2, 0.1)
|
||||
self.update()
|
||||
else:
|
||||
event.ignore()
|
||||
|
||||
def resizeEvent(self, event) -> None:
|
||||
if self._pixmap:
|
||||
@ -337,6 +346,7 @@ class ImagePreview(QWidget):
|
||||
save_to_folder = Signal(str)
|
||||
favorite_requested = Signal()
|
||||
navigate = Signal(int) # -1 = prev, +1 = next
|
||||
fullscreen_requested = Signal()
|
||||
|
||||
def __init__(self, parent: QWidget | None = None) -> None:
|
||||
super().__init__(parent)
|
||||
@ -443,6 +453,9 @@ class ImagePreview(QWidget):
|
||||
if self._stack.currentIndex() == 0:
|
||||
reset_action = menu.addAction("Reset View")
|
||||
|
||||
slideshow_action = None
|
||||
if self._current_path:
|
||||
slideshow_action = menu.addAction("Slideshow Mode")
|
||||
clear_action = menu.addAction("Clear Preview")
|
||||
|
||||
action = menu.exec(self.mapToGlobal(pos))
|
||||
@ -468,6 +481,8 @@ class ImagePreview(QWidget):
|
||||
elif action == reset_action:
|
||||
self._image_viewer._fit_to_view()
|
||||
self._image_viewer.update()
|
||||
elif action == slideshow_action:
|
||||
self.fullscreen_requested.emit()
|
||||
elif action == clear_action:
|
||||
self.close_requested.emit()
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@ class SearchBar(QWidget):
|
||||
|
||||
# Save search button
|
||||
self._save_btn = QPushButton("Save")
|
||||
self._save_btn.setFixedWidth(40)
|
||||
self._save_btn.setFixedWidth(50)
|
||||
self._save_btn.setToolTip("Save current search")
|
||||
self._save_btn.clicked.connect(self._save_current_search)
|
||||
layout.addWidget(self._save_btn)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user