Scroll tilt navigates one cell/post in grid, preview, and popout
This commit is contained in:
parent
92b7a16ab2
commit
56cb5ce1df
@ -64,6 +64,14 @@
|
||||
- Prev/Next buttons hide when at page boundaries instead of just disabling
|
||||
- Source URLs clickable in info panel, truncated at 60 chars for display
|
||||
|
||||
### Changed: scroll tilt navigation
|
||||
- Scroll tilt left/right now navigates between posts everywhere — grid, embedded preview, and popout — mirroring the L/R keys
|
||||
- Grid: moves selection one cell, falls through to `nav_before_start` / `nav_past_end` at the edges
|
||||
- Preview/popout: emits the existing `navigate` signal (±1)
|
||||
- Vertical scroll still adjusts video volume on the video stack; tilt and vertical can no longer interfere
|
||||
- Fixed: tilting over the image preview no longer zooms the image out (latent bug — `angleDelta().y() == 0` on pure tilt fell into the zoom-out branch)
|
||||
- `page_forward` / `page_back` grid signals removed (only consumer was the old tilt handler)
|
||||
|
||||
### Improved: video controls
|
||||
- Seek step changed from 5s to ~3s for `,` and `.` keys
|
||||
- `,` and `.` seek keys now work in the main preview panel, not just popout
|
||||
|
||||
@ -161,7 +161,7 @@ Categories=Graphics;
|
||||
| `Ctrl+A` | Select all |
|
||||
| `Ctrl+Click` / `Shift+Click` | Multi-select |
|
||||
| `Home` / `End` | Jump to first / last |
|
||||
| Scroll tilt left / right | Previous / next page |
|
||||
| Scroll tilt left / right | Previous / next thumbnail (one cell) |
|
||||
| `Ctrl+C` | Copy file to clipboard |
|
||||
| Right click | Context menu |
|
||||
|
||||
@ -169,7 +169,8 @@ Categories=Graphics;
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| Scroll wheel | Zoom |
|
||||
| Scroll wheel | Zoom (image) / volume (video) |
|
||||
| Scroll tilt left / right | Previous / next post |
|
||||
| Middle click / `0` | Reset view |
|
||||
| Arrow keys / `h`/`j`/`k`/`l` | Navigate posts |
|
||||
| `,` / `.` | Seek 3s back / forward (video) |
|
||||
@ -181,6 +182,7 @@ Categories=Graphics;
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| Arrow keys / `h`/`j`/`k`/`l` | Navigate posts |
|
||||
| Scroll tilt left / right | Previous / next post |
|
||||
| `,` / `.` | Seek 3s (video) |
|
||||
| `Space` | Play / pause (video) |
|
||||
| Scroll wheel | Volume up / down (video) |
|
||||
|
||||
@ -424,8 +424,6 @@ class BooruApp(QMainWindow):
|
||||
self._grid.multi_context_requested.connect(self._on_multi_context_menu)
|
||||
self._grid.nav_past_end.connect(self._on_nav_past_end)
|
||||
self._grid.nav_before_start.connect(self._on_nav_before_start)
|
||||
self._grid.page_forward.connect(self._next_page)
|
||||
self._grid.page_back.connect(self._prev_page)
|
||||
self._stack.addWidget(self._grid)
|
||||
|
||||
self._bookmarks_view = BookmarksView(self._db)
|
||||
|
||||
@ -288,10 +288,8 @@ class ThumbnailGrid(QScrollArea):
|
||||
multi_context_requested = Signal(list, object) # list[int], QPoint
|
||||
reached_bottom = Signal() # emitted when scrolled to the bottom
|
||||
reached_top = Signal() # emitted when scrolled to the top
|
||||
nav_past_end = Signal() # keyboard nav past last post
|
||||
nav_before_start = Signal() # keyboard nav before first post
|
||||
page_forward = Signal() # scroll tilt right
|
||||
page_back = Signal() # scroll tilt left
|
||||
nav_past_end = Signal() # nav past last post (keyboard or scroll tilt)
|
||||
nav_before_start = Signal() # nav before first post (keyboard or scroll tilt)
|
||||
|
||||
def __init__(self, parent: QWidget | None = None) -> None:
|
||||
super().__init__(parent)
|
||||
@ -483,15 +481,9 @@ class ThumbnailGrid(QScrollArea):
|
||||
return
|
||||
|
||||
if key in (Qt.Key.Key_Right, Qt.Key.Key_L):
|
||||
if idx + 1 >= len(self._thumbs):
|
||||
self.nav_past_end.emit()
|
||||
else:
|
||||
self._select(idx + 1)
|
||||
self._nav_horizontal(1)
|
||||
elif key in (Qt.Key.Key_Left, Qt.Key.Key_H):
|
||||
if idx - 1 < 0:
|
||||
self.nav_before_start.emit()
|
||||
else:
|
||||
self._select(idx - 1)
|
||||
self._nav_horizontal(-1)
|
||||
elif key in (Qt.Key.Key_Down, Qt.Key.Key_J):
|
||||
target = idx + cols
|
||||
if target >= len(self._thumbs):
|
||||
@ -536,12 +528,23 @@ class ThumbnailGrid(QScrollArea):
|
||||
if value <= 0 and sb.maximum() > 0:
|
||||
self.reached_top.emit()
|
||||
|
||||
def _nav_horizontal(self, direction: int) -> None:
|
||||
"""Move selection one cell left (-1) or right (+1); emit edge signals at boundaries."""
|
||||
idx = self._selected_index
|
||||
target = idx + direction
|
||||
if target < 0:
|
||||
self.nav_before_start.emit()
|
||||
elif target >= len(self._thumbs):
|
||||
self.nav_past_end.emit()
|
||||
else:
|
||||
self._select(target)
|
||||
|
||||
def wheelEvent(self, event: QWheelEvent) -> None:
|
||||
delta = event.angleDelta().x()
|
||||
if delta > 30:
|
||||
self.page_back.emit()
|
||||
self._nav_horizontal(-1)
|
||||
elif delta < -30:
|
||||
self.page_forward.emit()
|
||||
self._nav_horizontal(1)
|
||||
else:
|
||||
super().wheelEvent(event)
|
||||
|
||||
|
||||
@ -361,7 +361,17 @@ class FullscreenPreview(QMainWindow):
|
||||
elif key == Qt.Key.Key_Comma and self._stack.currentIndex() == 1:
|
||||
self._video._seek_relative(-1800)
|
||||
return True
|
||||
if event.type() == QEvent.Type.Wheel and self._stack.currentIndex() == 1 and self.isActiveWindow():
|
||||
if event.type() == QEvent.Type.Wheel and self.isActiveWindow():
|
||||
# Horizontal tilt navigates between posts on either stack
|
||||
tilt = event.angleDelta().x()
|
||||
if tilt > 30:
|
||||
self.navigate.emit(-1)
|
||||
return True
|
||||
if tilt < -30:
|
||||
self.navigate.emit(1)
|
||||
return True
|
||||
# Vertical wheel adjusts volume on the video stack only
|
||||
if self._stack.currentIndex() == 1:
|
||||
delta = event.angleDelta().y()
|
||||
if delta:
|
||||
vol = max(0, min(100, self._video.volume + (5 if delta > 0 else -5)))
|
||||
@ -593,9 +603,13 @@ class ImageViewer(QWidget):
|
||||
def wheelEvent(self, event: QWheelEvent) -> None:
|
||||
if not self._pixmap:
|
||||
return
|
||||
delta = event.angleDelta().y()
|
||||
if delta == 0:
|
||||
# Pure horizontal tilt — let parent handle (navigation)
|
||||
event.ignore()
|
||||
return
|
||||
mouse_pos = event.position()
|
||||
old_zoom = self._zoom
|
||||
delta = event.angleDelta().y()
|
||||
factor = 1.15 if delta > 0 else 1 / 1.15
|
||||
self._zoom = max(0.1, min(self._zoom * factor, 20.0))
|
||||
ratio = self._zoom / old_zoom
|
||||
@ -1367,8 +1381,17 @@ class ImagePreview(QWidget):
|
||||
super().mousePressEvent(event)
|
||||
|
||||
def wheelEvent(self, event) -> None:
|
||||
# Horizontal tilt navigates between posts on either stack
|
||||
tilt = event.angleDelta().x()
|
||||
if tilt > 30:
|
||||
self.navigate.emit(-1)
|
||||
return
|
||||
if tilt < -30:
|
||||
self.navigate.emit(1)
|
||||
return
|
||||
if self._stack.currentIndex() == 1:
|
||||
delta = event.angleDelta().y()
|
||||
if delta:
|
||||
vol = max(0, min(100, self._video_player.volume + (5 if delta > 0 else -5)))
|
||||
self._video_player.volume = vol
|
||||
else:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user