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.favorite_requested.connect(self._favorite_from_preview)
|
||||||
self._preview.save_to_folder.connect(self._save_from_preview)
|
self._preview.save_to_folder.connect(self._save_from_preview)
|
||||||
self._preview.navigate.connect(self._navigate_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._preview.set_folders_callback(self._db.get_folders)
|
||||||
|
self._fullscreen_window = None
|
||||||
self._preview.setMinimumWidth(300)
|
self._preview.setMinimumWidth(300)
|
||||||
right.addWidget(self._preview)
|
right.addWidget(self._preview)
|
||||||
|
|
||||||
@ -701,6 +703,9 @@ class BooruApp(QMainWindow):
|
|||||||
idx = self._grid.selected_index
|
idx = self._grid.selected_index
|
||||||
if 0 <= idx < len(self._grid._thumbs):
|
if 0 <= idx < len(self._grid._thumbs):
|
||||||
self._grid._thumbs[idx]._cached_path = path
|
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:
|
def _on_favorite_selected(self, fav) -> None:
|
||||||
self._status.showMessage(f"Favorite #{fav.post_id}")
|
self._status.showMessage(f"Favorite #{fav.post_id}")
|
||||||
@ -793,6 +798,24 @@ class BooruApp(QMainWindow):
|
|||||||
self._db.add_folder(folder)
|
self._db.add_folder(folder)
|
||||||
self._save_to_library(self._posts[idx], target)
|
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:
|
def _close_preview(self) -> None:
|
||||||
self._preview.clear()
|
self._preview.clear()
|
||||||
|
|
||||||
@ -1320,22 +1343,63 @@ def _apply_windows_dark_mode(app: QApplication) -> None:
|
|||||||
from PySide6.QtGui import QPalette, QColor
|
from PySide6.QtGui import QPalette, QColor
|
||||||
app.setStyle("Fusion")
|
app.setStyle("Fusion")
|
||||||
palette = QPalette()
|
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.WindowText, QColor(255, 255, 255))
|
||||||
palette.setColor(QPalette.ColorRole.Base, QColor(15, 15, 15))
|
palette.setColor(QPalette.ColorRole.Base, QColor(25, 25, 25))
|
||||||
palette.setColor(QPalette.ColorRole.AlternateBase, QColor(35, 35, 35))
|
palette.setColor(QPalette.ColorRole.AlternateBase, QColor(38, 38, 38))
|
||||||
palette.setColor(QPalette.ColorRole.ToolTipBase, QColor(255, 255, 255))
|
palette.setColor(QPalette.ColorRole.ToolTipBase, QColor(50, 50, 50))
|
||||||
palette.setColor(QPalette.ColorRole.ToolTipText, QColor(255, 255, 255))
|
palette.setColor(QPalette.ColorRole.ToolTipText, QColor(255, 255, 255))
|
||||||
palette.setColor(QPalette.ColorRole.Text, 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.ButtonText, QColor(255, 255, 255))
|
||||||
palette.setColor(QPalette.ColorRole.BrightText, QColor(255, 0, 0))
|
palette.setColor(QPalette.ColorRole.BrightText, QColor(255, 0, 0))
|
||||||
palette.setColor(QPalette.ColorRole.Link, QColor(42, 130, 218))
|
palette.setColor(QPalette.ColorRole.Link, QColor(0, 120, 215))
|
||||||
palette.setColor(QPalette.ColorRole.Highlight, QColor(42, 130, 218))
|
palette.setColor(QPalette.ColorRole.Highlight, QColor(0, 120, 215))
|
||||||
palette.setColor(QPalette.ColorRole.HighlightedText, QColor(0, 0, 0))
|
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.Text, QColor(127, 127, 127))
|
||||||
palette.setColor(QPalette.ColorGroup.Disabled, QPalette.ColorRole.ButtonText, QColor(127, 127, 127))
|
palette.setColor(QPalette.ColorGroup.Disabled, QPalette.ColorRole.ButtonText, QColor(127, 127, 127))
|
||||||
app.setPalette(palette)
|
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:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@ -23,27 +23,34 @@ def _is_video(path: str) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
class FullscreenPreview(QMainWindow):
|
class FullscreenPreview(QMainWindow):
|
||||||
"""Fullscreen image viewer window."""
|
"""Fullscreen image viewer window with navigation."""
|
||||||
|
|
||||||
def __init__(self, pixmap: QPixmap, info: str = "", parent=None) -> None:
|
navigate = Signal(int) # -1 = prev, +1 = next
|
||||||
super().__init__(parent)
|
|
||||||
|
def __init__(self, parent=None) -> None:
|
||||||
|
super().__init__(parent, Qt.WindowType.Window)
|
||||||
self.setWindowTitle("booru-viewer — Fullscreen")
|
self.setWindowTitle("booru-viewer — Fullscreen")
|
||||||
self._preview = ImageViewer()
|
self._viewer = ImageViewer()
|
||||||
self._preview.set_image(pixmap, info)
|
self._viewer.close_requested.connect(self.close)
|
||||||
self._preview.close_requested.connect(self.close)
|
self.setCentralWidget(self._viewer)
|
||||||
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.showFullScreen()
|
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:
|
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()
|
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:
|
else:
|
||||||
super().keyPressEvent(event)
|
super().keyPressEvent(event)
|
||||||
|
|
||||||
@ -175,6 +182,8 @@ class ImageViewer(QWidget):
|
|||||||
elif event.key() == Qt.Key.Key_Minus:
|
elif event.key() == Qt.Key.Key_Minus:
|
||||||
self._zoom = max(self._zoom / 1.2, 0.1)
|
self._zoom = max(self._zoom / 1.2, 0.1)
|
||||||
self.update()
|
self.update()
|
||||||
|
else:
|
||||||
|
event.ignore()
|
||||||
|
|
||||||
def resizeEvent(self, event) -> None:
|
def resizeEvent(self, event) -> None:
|
||||||
if self._pixmap:
|
if self._pixmap:
|
||||||
@ -337,6 +346,7 @@ class ImagePreview(QWidget):
|
|||||||
save_to_folder = Signal(str)
|
save_to_folder = Signal(str)
|
||||||
favorite_requested = Signal()
|
favorite_requested = Signal()
|
||||||
navigate = Signal(int) # -1 = prev, +1 = next
|
navigate = Signal(int) # -1 = prev, +1 = next
|
||||||
|
fullscreen_requested = Signal()
|
||||||
|
|
||||||
def __init__(self, parent: QWidget | None = None) -> None:
|
def __init__(self, parent: QWidget | None = None) -> None:
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
@ -443,6 +453,9 @@ class ImagePreview(QWidget):
|
|||||||
if self._stack.currentIndex() == 0:
|
if self._stack.currentIndex() == 0:
|
||||||
reset_action = menu.addAction("Reset View")
|
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")
|
clear_action = menu.addAction("Clear Preview")
|
||||||
|
|
||||||
action = menu.exec(self.mapToGlobal(pos))
|
action = menu.exec(self.mapToGlobal(pos))
|
||||||
@ -468,6 +481,8 @@ class ImagePreview(QWidget):
|
|||||||
elif action == reset_action:
|
elif action == reset_action:
|
||||||
self._image_viewer._fit_to_view()
|
self._image_viewer._fit_to_view()
|
||||||
self._image_viewer.update()
|
self._image_viewer.update()
|
||||||
|
elif action == slideshow_action:
|
||||||
|
self.fullscreen_requested.emit()
|
||||||
elif action == clear_action:
|
elif action == clear_action:
|
||||||
self.close_requested.emit()
|
self.close_requested.emit()
|
||||||
|
|
||||||
|
|||||||
@ -43,7 +43,7 @@ class SearchBar(QWidget):
|
|||||||
|
|
||||||
# Save search button
|
# Save search button
|
||||||
self._save_btn = QPushButton("Save")
|
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.setToolTip("Save current search")
|
||||||
self._save_btn.clicked.connect(self._save_current_search)
|
self._save_btn.clicked.connect(self._save_current_search)
|
||||||
layout.addWidget(self._save_btn)
|
layout.addWidget(self._save_btn)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user