2026-02-21 11:06:06 +00:00
|
|
|
from .slices import PhotoSlice
|
|
|
|
|
|
|
|
|
|
|
2026-02-21 14:16:07 +00:00
|
|
|
class ScanSlicerCanvasActionsMixin:
|
|
|
|
|
def on_active_slice_changed(self, index):
|
|
|
|
|
self.refresh_active_box_toolbar(index)
|
|
|
|
|
|
|
|
|
|
def refresh_active_box_toolbar(self, index=None):
|
|
|
|
|
if index == -1:
|
|
|
|
|
index = None
|
|
|
|
|
if index is None:
|
|
|
|
|
index = self.slicing_canvas.active_slice_index
|
|
|
|
|
|
|
|
|
|
has_slices = len(self.slicing_canvas.slices) > 0
|
|
|
|
|
self.all_boxes_lock_button.setEnabled(has_slices)
|
|
|
|
|
self.all_boxes_lock_button.blockSignals(True)
|
|
|
|
|
self.all_boxes_lock_button.setChecked(self.slicing_canvas.are_all_slices_locked())
|
|
|
|
|
self.all_boxes_lock_button.blockSignals(False)
|
|
|
|
|
|
|
|
|
|
active_slice = self.slicing_canvas.get_active_slice()
|
|
|
|
|
if active_slice is None:
|
|
|
|
|
self.active_box_label.setText("Active Box: none")
|
|
|
|
|
self.active_box_lock_button.setEnabled(False)
|
|
|
|
|
self.active_box_squarize_button.setEnabled(False)
|
|
|
|
|
self.active_box_reset_rotation_button.setEnabled(False)
|
2026-09-11 21:33:59 +02:00
|
|
|
self.active_box_swap_button.setEnabled(False)
|
2026-02-21 14:16:07 +00:00
|
|
|
self.active_box_remove_button.setEnabled(False)
|
|
|
|
|
self.active_box_lock_button.blockSignals(True)
|
|
|
|
|
self.active_box_lock_button.setChecked(False)
|
|
|
|
|
self.active_box_lock_button.blockSignals(False)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if index is None:
|
|
|
|
|
index = self.slicing_canvas.active_slice_index
|
|
|
|
|
self.active_box_label.setText(f"Active Box: {index}")
|
|
|
|
|
self.active_box_lock_button.setEnabled(True)
|
|
|
|
|
self.active_box_squarize_button.setEnabled(True)
|
|
|
|
|
self.active_box_reset_rotation_button.setEnabled(True)
|
2026-09-11 21:33:59 +02:00
|
|
|
self.active_box_swap_button.setEnabled(True)
|
2026-02-21 14:16:07 +00:00
|
|
|
self.active_box_remove_button.setEnabled(True)
|
|
|
|
|
self.active_box_lock_button.blockSignals(True)
|
|
|
|
|
self.active_box_lock_button.setChecked(active_slice.locked)
|
|
|
|
|
self.active_box_lock_button.blockSignals(False)
|
|
|
|
|
|
|
|
|
|
def toggle_active_box_lock(self, checked):
|
|
|
|
|
if not self.slicing_canvas.set_active_slice_locked(checked):
|
|
|
|
|
self.refresh_active_box_toolbar()
|
|
|
|
|
return
|
|
|
|
|
self.refresh_active_box_toolbar()
|
|
|
|
|
|
|
|
|
|
def toggle_all_boxes_lock(self, checked):
|
|
|
|
|
count = self.slicing_canvas.set_all_slices_locked(checked)
|
|
|
|
|
self.refresh_active_box_toolbar()
|
|
|
|
|
if count == 0:
|
|
|
|
|
self.update_statusbar("No boxes available.")
|
|
|
|
|
return
|
|
|
|
|
if checked:
|
|
|
|
|
self.update_statusbar(f"Locked {count} box(es).")
|
|
|
|
|
else:
|
|
|
|
|
self.update_statusbar(f"Unlocked {count} box(es).")
|
|
|
|
|
|
|
|
|
|
def squarize_active_box(self):
|
|
|
|
|
if not self.slicing_canvas.squarize_active_slice():
|
|
|
|
|
self.update_statusbar("No active box selected.")
|
|
|
|
|
return
|
|
|
|
|
self.update_statusbar("Active box squarized.")
|
|
|
|
|
|
2026-09-11 21:33:59 +02:00
|
|
|
def swap_active_box_left_right(self):
|
|
|
|
|
if not self.slicing_canvas.swap_active_slice_left_right():
|
|
|
|
|
self.update_statusbar("No active box selected.")
|
|
|
|
|
return
|
|
|
|
|
self.update_statusbar("Active box left/right swapped.")
|
|
|
|
|
|
2026-02-21 14:16:07 +00:00
|
|
|
def reset_active_box_rotation(self):
|
|
|
|
|
if not self.slicing_canvas.reset_active_slice_rotation():
|
|
|
|
|
self.update_statusbar("No active box selected.")
|
|
|
|
|
return
|
|
|
|
|
self.update_statusbar("Active box rotation reset.")
|
|
|
|
|
|
|
|
|
|
def remove_active_box(self):
|
|
|
|
|
if not self.slicing_canvas.remove_active_slice():
|
|
|
|
|
self.update_statusbar("No active box selected.")
|
|
|
|
|
return
|
|
|
|
|
self.refresh_active_box_toolbar()
|
|
|
|
|
self.update_statusbar("Active box removed.")
|
|
|
|
|
|
|
|
|
|
def set_preview_filter_enabled(self, checked):
|
|
|
|
|
self.preview_filter_enabled = bool(checked)
|
|
|
|
|
if self.preview_filter_enabled:
|
|
|
|
|
self.update_statusbar("Filter preview enabled.")
|
|
|
|
|
else:
|
|
|
|
|
self.update_statusbar("Filter preview disabled.")
|
|
|
|
|
|
|
|
|
|
if self.autoslicer.image_loaded():
|
|
|
|
|
self.update_preview(new_image=False, run_detection=False)
|
|
|
|
|
|
|
|
|
|
def set_rotate_handles_mode(self, checked):
|
|
|
|
|
self.slicing_canvas.set_rotate_handles_mode(checked)
|
|
|
|
|
if checked:
|
|
|
|
|
self.update_statusbar("Rotate mode enabled.")
|
|
|
|
|
else:
|
|
|
|
|
self.update_statusbar("Rotate mode disabled.")
|
|
|
|
|
|
|
|
|
|
def reset_canvas_view(self):
|
|
|
|
|
if not self.slicing_canvas.reset_view():
|
|
|
|
|
self.update_statusbar("No image loaded.")
|
|
|
|
|
return
|
|
|
|
|
self.update_statusbar("View reset.")
|
|
|
|
|
|
|
|
|
|
def add_box(self):
|
|
|
|
|
new_slice = PhotoSlice(None)
|
|
|
|
|
new_slice.toggle_locked()
|
|
|
|
|
self.slicing_canvas.add_bbox(new_slice)
|