Fix folder navigation and restyle navigation arrows

This commit is contained in:
lm 2025-10-19 21:16:55 +02:00
parent 6de4059291
commit 2d4531013d
2 changed files with 53 additions and 34 deletions

View File

@ -84,38 +84,38 @@ class QtImageProcessor:
# image handling --------------------------------------------------------
def load_single_image(self, path: Path) -> None:
def load_single_image(self, path: Path, *, reset_collection: bool = True) -> Path:
image = Image.open(path).convert("RGBA")
self.orig_img = image
self.preview_paths = [path]
self.current_index = 0
if reset_collection:
self.preview_paths = [path]
self.current_index = 0
self._build_preview()
if self.reset_exclusions_on_switch:
self.exclude_shapes = []
self._rebuild_overlay()
return path
def load_folder(self, paths: Iterable[Path], start_index: int = 0) -> None:
def load_folder(self, paths: Iterable[Path], start_index: int = 0) -> Path:
self.preview_paths = list(paths)
if not self.preview_paths:
raise ValueError("No images in folder.")
self.current_index = max(0, min(start_index, len(self.preview_paths) - 1))
self._load_current()
return self._load_image_at_current()
def next_image(self) -> None:
def next_image(self) -> Path | None:
if not self.preview_paths:
return
return None
self.current_index = (self.current_index + 1) % len(self.preview_paths)
self._load_current()
return self._load_image_at_current()
def previous_image(self) -> None:
def previous_image(self) -> Path | None:
if not self.preview_paths:
return
return None
self.current_index = (self.current_index - 1) % len(self.preview_paths)
self._load_current()
return self._load_image_at_current()
def _load_current(self) -> None:
def _load_image_at_current(self) -> Path:
path = self.preview_paths[self.current_index]
self.load_single_image(path)
return self.load_single_image(path, reset_collection=False)
# preview/overlay -------------------------------------------------------

View File

@ -672,9 +672,12 @@ class MainWindow(QtWidgets.QMainWindow, I18nMixin):
layout.setHorizontalSpacing(16)
self.prev_button = QtWidgets.QToolButton()
self.prev_button.setText("")
self.prev_button.setCursor(QtCore.Qt.PointingHandCursor)
self.prev_button.setFixedSize(44, 44)
self.prev_button.setAutoRaise(True)
self.prev_button.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)
self.prev_button.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_ArrowBack))
self.prev_button.setIconSize(QtCore.QSize(20, 20))
self.prev_button.setFixedSize(38, 38)
self.prev_button.clicked.connect(lambda: self._invoke_action("show_previous_image"))
layout.addWidget(self.prev_button, 0, 0, QtCore.Qt.AlignVCenter)
@ -687,9 +690,12 @@ class MainWindow(QtWidgets.QMainWindow, I18nMixin):
layout.addWidget(self.overlay_view, 0, 2)
self.next_button = QtWidgets.QToolButton()
self.next_button.setText("")
self.next_button.setCursor(QtCore.Qt.PointingHandCursor)
self.next_button.setFixedSize(44, 44)
self.next_button.setAutoRaise(True)
self.next_button.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)
self.next_button.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_ArrowForward))
self.next_button.setIconSize(QtCore.QSize(20, 20))
self.next_button.setFixedSize(38, 38)
self.next_button.clicked.connect(lambda: self._invoke_action("show_next_image"))
layout.addWidget(self.next_button, 0, 3, QtCore.Qt.AlignVCenter)
layout.setColumnStretch(1, 1)
@ -742,11 +748,11 @@ class MainWindow(QtWidgets.QMainWindow, I18nMixin):
return
path = Path(path_str)
try:
self.processor.load_single_image(path)
loaded_path = self.processor.load_single_image(path)
except Exception as exc: # pragma: no cover - user feedback
QtWidgets.QMessageBox.warning(self, self._t("dialog.error_title"), str(exc))
return
self._current_image_path = path
self._current_image_path = loaded_path
if self.processor.reset_exclusions_on_switch:
self.image_view.clear_shapes()
self.processor.set_exclusions([])
@ -765,19 +771,21 @@ class MainWindow(QtWidgets.QMainWindow, I18nMixin):
QtWidgets.QMessageBox.information(self, self._t("dialog.info_title"), self._t("dialog.folder_empty"))
return
try:
self.processor.load_folder(paths)
loaded_path = self.processor.load_folder(paths)
except ValueError as exc:
QtWidgets.QMessageBox.information(self, self._t("dialog.info_title"), str(exc))
return
self._current_image_path = paths[0]
self._current_image_path = loaded_path
self._refresh_views()
def show_previous_image(self) -> None:
if not self.processor.preview_paths:
QtWidgets.QMessageBox.information(self, self._t("dialog.info_title"), self._t("dialog.no_image_loaded"))
return
self.processor.previous_image()
self._current_image_path = self.processor.preview_paths[self.processor.current_index]
path = self.processor.previous_image()
if path is None:
return
self._current_image_path = path
if self.processor.reset_exclusions_on_switch:
self.image_view.clear_shapes()
self.processor.set_exclusions([])
@ -787,8 +795,10 @@ class MainWindow(QtWidgets.QMainWindow, I18nMixin):
if not self.processor.preview_paths:
QtWidgets.QMessageBox.information(self, self._t("dialog.info_title"), self._t("dialog.no_image_loaded"))
return
self.processor.next_image()
self._current_image_path = self.processor.preview_paths[self.processor.current_index]
path = self.processor.next_image()
if path is None:
return
self._current_image_path = path
if self.processor.reset_exclusions_on_switch:
self.image_view.clear_shapes()
self.processor.set_exclusions([])
@ -895,13 +905,8 @@ class MainWindow(QtWidgets.QMainWindow, I18nMixin):
for control in self._slider_controls.values():
control.apply_theme(colours)
style_button = (
f"QToolButton {{ border-radius: 22px; background-color: {colours['panel_bg']}; "
f"border: 1px solid {colours['border']}; color: {colours['text']}; }}"
f"QToolButton:hover {{ background-color: {colours['accent_secondary']}; color: white; }}"
)
self.prev_button.setStyleSheet(style_button)
self.next_button.setStyleSheet(style_button)
self._style_nav_button(self.prev_button)
self._style_nav_button(self.next_button)
self.title_bar.apply_theme(colours)
@ -917,6 +922,20 @@ class MainWindow(QtWidgets.QMainWindow, I18nMixin):
return self._t(title_key)
return key
def _style_nav_button(self, button: QtWidgets.QToolButton) -> None:
colours = THEMES[self.current_theme]
button.setStyleSheet(
f"QToolButton {{ border-radius: 19px; background-color: {colours['panel_bg']}; "
f"border: 1px solid {colours['border']}; color: {colours['text']}; }}"
f"QToolButton:hover {{ background-color: {colours['accent_secondary']}; color: white; }}"
)
button.setIconSize(QtCore.QSize(20, 20))
if button is getattr(self, "prev_button", None):
button.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_ArrowBack))
elif button is getattr(self, "next_button", None):
button.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_ArrowForward))
def _refresh_views(self) -> None:
preview_pix = self.processor.preview_pixmap()
overlay_pix = self.processor.overlay_pixmap()