Fix folder navigation and restyle navigation arrows
This commit is contained in:
parent
6de4059291
commit
2d4531013d
|
|
@ -84,38 +84,38 @@ class QtImageProcessor:
|
||||||
|
|
||||||
# image handling --------------------------------------------------------
|
# 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")
|
image = Image.open(path).convert("RGBA")
|
||||||
self.orig_img = image
|
self.orig_img = image
|
||||||
self.preview_paths = [path]
|
if reset_collection:
|
||||||
self.current_index = 0
|
self.preview_paths = [path]
|
||||||
|
self.current_index = 0
|
||||||
self._build_preview()
|
self._build_preview()
|
||||||
if self.reset_exclusions_on_switch:
|
|
||||||
self.exclude_shapes = []
|
|
||||||
self._rebuild_overlay()
|
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)
|
self.preview_paths = list(paths)
|
||||||
if not self.preview_paths:
|
if not self.preview_paths:
|
||||||
raise ValueError("No images in folder.")
|
raise ValueError("No images in folder.")
|
||||||
self.current_index = max(0, min(start_index, len(self.preview_paths) - 1))
|
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:
|
if not self.preview_paths:
|
||||||
return
|
return None
|
||||||
self.current_index = (self.current_index + 1) % len(self.preview_paths)
|
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:
|
if not self.preview_paths:
|
||||||
return
|
return None
|
||||||
self.current_index = (self.current_index - 1) % len(self.preview_paths)
|
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]
|
path = self.preview_paths[self.current_index]
|
||||||
self.load_single_image(path)
|
return self.load_single_image(path, reset_collection=False)
|
||||||
|
|
||||||
# preview/overlay -------------------------------------------------------
|
# preview/overlay -------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -672,9 +672,12 @@ class MainWindow(QtWidgets.QMainWindow, I18nMixin):
|
||||||
layout.setHorizontalSpacing(16)
|
layout.setHorizontalSpacing(16)
|
||||||
|
|
||||||
self.prev_button = QtWidgets.QToolButton()
|
self.prev_button = QtWidgets.QToolButton()
|
||||||
self.prev_button.setText("◀")
|
|
||||||
self.prev_button.setCursor(QtCore.Qt.PointingHandCursor)
|
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"))
|
self.prev_button.clicked.connect(lambda: self._invoke_action("show_previous_image"))
|
||||||
layout.addWidget(self.prev_button, 0, 0, QtCore.Qt.AlignVCenter)
|
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)
|
layout.addWidget(self.overlay_view, 0, 2)
|
||||||
|
|
||||||
self.next_button = QtWidgets.QToolButton()
|
self.next_button = QtWidgets.QToolButton()
|
||||||
self.next_button.setText("▶")
|
|
||||||
self.next_button.setCursor(QtCore.Qt.PointingHandCursor)
|
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"))
|
self.next_button.clicked.connect(lambda: self._invoke_action("show_next_image"))
|
||||||
layout.addWidget(self.next_button, 0, 3, QtCore.Qt.AlignVCenter)
|
layout.addWidget(self.next_button, 0, 3, QtCore.Qt.AlignVCenter)
|
||||||
layout.setColumnStretch(1, 1)
|
layout.setColumnStretch(1, 1)
|
||||||
|
|
@ -742,11 +748,11 @@ class MainWindow(QtWidgets.QMainWindow, I18nMixin):
|
||||||
return
|
return
|
||||||
path = Path(path_str)
|
path = Path(path_str)
|
||||||
try:
|
try:
|
||||||
self.processor.load_single_image(path)
|
loaded_path = self.processor.load_single_image(path)
|
||||||
except Exception as exc: # pragma: no cover - user feedback
|
except Exception as exc: # pragma: no cover - user feedback
|
||||||
QtWidgets.QMessageBox.warning(self, self._t("dialog.error_title"), str(exc))
|
QtWidgets.QMessageBox.warning(self, self._t("dialog.error_title"), str(exc))
|
||||||
return
|
return
|
||||||
self._current_image_path = path
|
self._current_image_path = loaded_path
|
||||||
if self.processor.reset_exclusions_on_switch:
|
if self.processor.reset_exclusions_on_switch:
|
||||||
self.image_view.clear_shapes()
|
self.image_view.clear_shapes()
|
||||||
self.processor.set_exclusions([])
|
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"))
|
QtWidgets.QMessageBox.information(self, self._t("dialog.info_title"), self._t("dialog.folder_empty"))
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
self.processor.load_folder(paths)
|
loaded_path = self.processor.load_folder(paths)
|
||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
QtWidgets.QMessageBox.information(self, self._t("dialog.info_title"), str(exc))
|
QtWidgets.QMessageBox.information(self, self._t("dialog.info_title"), str(exc))
|
||||||
return
|
return
|
||||||
self._current_image_path = paths[0]
|
self._current_image_path = loaded_path
|
||||||
self._refresh_views()
|
self._refresh_views()
|
||||||
|
|
||||||
def show_previous_image(self) -> None:
|
def show_previous_image(self) -> None:
|
||||||
if not self.processor.preview_paths:
|
if not self.processor.preview_paths:
|
||||||
QtWidgets.QMessageBox.information(self, self._t("dialog.info_title"), self._t("dialog.no_image_loaded"))
|
QtWidgets.QMessageBox.information(self, self._t("dialog.info_title"), self._t("dialog.no_image_loaded"))
|
||||||
return
|
return
|
||||||
self.processor.previous_image()
|
path = self.processor.previous_image()
|
||||||
self._current_image_path = self.processor.preview_paths[self.processor.current_index]
|
if path is None:
|
||||||
|
return
|
||||||
|
self._current_image_path = path
|
||||||
if self.processor.reset_exclusions_on_switch:
|
if self.processor.reset_exclusions_on_switch:
|
||||||
self.image_view.clear_shapes()
|
self.image_view.clear_shapes()
|
||||||
self.processor.set_exclusions([])
|
self.processor.set_exclusions([])
|
||||||
|
|
@ -787,8 +795,10 @@ class MainWindow(QtWidgets.QMainWindow, I18nMixin):
|
||||||
if not self.processor.preview_paths:
|
if not self.processor.preview_paths:
|
||||||
QtWidgets.QMessageBox.information(self, self._t("dialog.info_title"), self._t("dialog.no_image_loaded"))
|
QtWidgets.QMessageBox.information(self, self._t("dialog.info_title"), self._t("dialog.no_image_loaded"))
|
||||||
return
|
return
|
||||||
self.processor.next_image()
|
path = self.processor.next_image()
|
||||||
self._current_image_path = self.processor.preview_paths[self.processor.current_index]
|
if path is None:
|
||||||
|
return
|
||||||
|
self._current_image_path = path
|
||||||
if self.processor.reset_exclusions_on_switch:
|
if self.processor.reset_exclusions_on_switch:
|
||||||
self.image_view.clear_shapes()
|
self.image_view.clear_shapes()
|
||||||
self.processor.set_exclusions([])
|
self.processor.set_exclusions([])
|
||||||
|
|
@ -895,13 +905,8 @@ class MainWindow(QtWidgets.QMainWindow, I18nMixin):
|
||||||
for control in self._slider_controls.values():
|
for control in self._slider_controls.values():
|
||||||
control.apply_theme(colours)
|
control.apply_theme(colours)
|
||||||
|
|
||||||
style_button = (
|
self._style_nav_button(self.prev_button)
|
||||||
f"QToolButton {{ border-radius: 22px; background-color: {colours['panel_bg']}; "
|
self._style_nav_button(self.next_button)
|
||||||
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.title_bar.apply_theme(colours)
|
self.title_bar.apply_theme(colours)
|
||||||
|
|
||||||
|
|
@ -917,6 +922,20 @@ class MainWindow(QtWidgets.QMainWindow, I18nMixin):
|
||||||
return self._t(title_key)
|
return self._t(title_key)
|
||||||
return 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:
|
def _refresh_views(self) -> None:
|
||||||
preview_pix = self.processor.preview_pixmap()
|
preview_pix = self.processor.preview_pixmap()
|
||||||
overlay_pix = self.processor.overlay_pixmap()
|
overlay_pix = self.processor.overlay_pixmap()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue