From 0aa5d139d3788012af0f2ce4f511b0e08af1804e Mon Sep 17 00:00:00 2001 From: pax Date: Sun, 5 Apr 2026 19:55:21 -0500 Subject: [PATCH] Prefetch modes: Off / Adjacent (4 cardinals) / Full page (spiral) - Off: no prefetching - Adjacent: simultaneous left/right/up/down (4 posts) - Full page: ring expansion in all 8 directions Dropdown in Settings > General replaces the old checkbox. --- booru_viewer/gui/app.py | 54 +++++++++++++++++++++--------------- booru_viewer/gui/settings.py | 12 +++++--- 2 files changed, 39 insertions(+), 27 deletions(-) diff --git a/booru_viewer/gui/app.py b/booru_viewer/gui/app.py index 9bbed75..8ee0765 100644 --- a/booru_viewer/gui/app.py +++ b/booru_viewer/gui/app.py @@ -845,7 +845,7 @@ class BooruApp(QMainWindow): self._grid.setFocus() # Start prefetching from top of page - if self._db.get_setting_bool("prefetch_adjacent") and posts: + if self._db.get_setting("prefetch_mode") in ("Adjacent", "Full page") and posts: self._prefetch_adjacent(0) # Infinite scroll: if first page doesn't fill viewport, load more @@ -912,7 +912,7 @@ class BooruApp(QMainWindow): # All done — unlock loading, evict, prefetch self._loading = False self._auto_evict_cache() - if self._db.get_setting_bool("prefetch_adjacent"): + if self._db.get_setting("prefetch_mode") in ("Adjacent", "Full page"): self._prefetch_adjacent(idx) # Check if still at bottom or content doesn't fill viewport sb = self._grid.verticalScrollBar() @@ -1000,37 +1000,45 @@ class BooruApp(QMainWindow): self._run_async(_load) # Prefetch adjacent posts - if self._db.get_setting_bool("prefetch_adjacent"): + if self._db.get_setting("prefetch_mode") in ("Adjacent", "Full page"): self._prefetch_adjacent(index) def _prefetch_adjacent(self, index: int) -> None: - """Prefetch outward from clicked post in all directions, covering the whole page.""" + """Prefetch posts around the given index.""" total = len(self._posts) if total == 0: return cols = self._grid._flow.columns + mode = self._db.get_setting("prefetch_mode") - # Build ring order: at each distance, grab all 8 directions - seen = {index} - order = [] - for dist in range(1, total): - ring = set() - for dy in (-dist, 0, dist): - for dx in (-dist, 0, dist): - if dy == 0 and dx == 0: - continue - adj = index + dy * cols + dx + if mode == "Adjacent": + # Just 4 cardinals: left, right, up, down + order = [] + for offset in [1, -1, cols, -cols]: + adj = index + offset + if 0 <= adj < total: + order.append(adj) + else: + # Full page: ring expansion in all 8 directions + seen = {index} + order = [] + for dist in range(1, total): + ring = set() + for dy in (-dist, 0, dist): + for dx in (-dist, 0, dist): + if dy == 0 and dx == 0: + continue + adj = index + dy * cols + dx + if 0 <= adj < total and adj not in seen: + ring.add(adj) + for adj in (index + dist, index - dist): if 0 <= adj < total and adj not in seen: ring.add(adj) - # Also add pure linear neighbors for non-grid nav - for adj in (index + dist, index - dist): - if 0 <= adj < total and adj not in seen: - ring.add(adj) - for adj in sorted(ring): - seen.add(adj) - order.append(adj) - if len(order) >= total - 1: - break + for adj in sorted(ring): + seen.add(adj) + order.append(adj) + if len(order) >= total - 1: + break async def _prefetch_spiral(): for adj in order: diff --git a/booru_viewer/gui/settings.py b/booru_viewer/gui/settings.py index 61b4581..5b81da8 100644 --- a/booru_viewer/gui/settings.py +++ b/booru_viewer/gui/settings.py @@ -111,9 +111,13 @@ class SettingsDialog(QDialog): form.addRow("", self._preload) # Prefetch adjacent posts - self._prefetch = QCheckBox("Prefetch whole page over time") - self._prefetch.setChecked(self._db.get_setting_bool("prefetch_adjacent")) - form.addRow("", self._prefetch) + self._prefetch_combo = QComboBox() + self._prefetch_combo.addItems(["Off", "Adjacent", "Full page"]) + prefetch_mode = self._db.get_setting("prefetch_mode") or "Off" + idx = self._prefetch_combo.findText(prefetch_mode) + if idx >= 0: + self._prefetch_combo.setCurrentIndex(idx) + form.addRow("Prefetch:", self._prefetch_combo) # Infinite scroll self._infinite_scroll = QCheckBox("Infinite scroll (replaces page buttons)") @@ -681,7 +685,7 @@ class SettingsDialog(QDialog): self._db.set_setting("default_rating", self._default_rating.currentText()) self._db.set_setting("default_score", str(self._default_score.value())) self._db.set_setting("preload_thumbnails", "1" if self._preload.isChecked() else "0") - self._db.set_setting("prefetch_adjacent", "1" if self._prefetch.isChecked() else "0") + self._db.set_setting("prefetch_mode", self._prefetch_combo.currentText()) self._db.set_setting("infinite_scroll", "1" if self._infinite_scroll.isChecked() else "0") self._db.set_setting("slideshow_monitor", self._monitor_combo.currentText()) self._db.set_setting("library_dir", self._library_dir.text().strip())