from PySide6.QtCore import QSize, Qt from PySide6.QtWidgets import QGridLayout, QHBoxLayout, QLabel, QPushButton, QWidget from .canvas import QtSlicingCanvas from .ui_builders_shared import ScanSlicerUiSharedMixin, icon_from_svg_data_url # ScanSlicerUiPreviewMixin: class definition for ScanSlicer behavior. class ScanSlicerUiPreviewMixin(ScanSlicerUiSharedMixin): # _create_toolbar_button: function definition for ScanSlicer behavior. def _create_toolbar_button( self, parent, text, tooltip, icon_data_url, callback, checkable=False, enabled=True, use_toggled=False, ): button = QPushButton(text, parent) if checkable: button.setCheckable(True) button.setEnabled(enabled) button.setToolTip(tooltip) icon = icon_from_svg_data_url(icon_data_url, 20, palette=button.palette()) if icon is not None: button.setText("") button.setIcon(icon) button.setIconSize(QSize(20, 20)) if use_toggled: button.toggled.connect(callback) else: button.clicked.connect(callback) return button # _build_preview_panel: function definition for ScanSlicer behavior. def _build_preview_panel(self, root): preview_panel = QWidget(root) preview_layout = QGridLayout(preview_panel) preview_layout.setContentsMargins(0, 0, 0, 0) preview_toolbar = QWidget(preview_panel) preview_toolbar_layout = QHBoxLayout(preview_toolbar) preview_toolbar_layout.setContentsMargins(0, 0, 0, 0) self.preview_toolbar = preview_toolbar self.detect_button = self._create_toolbar_button( preview_toolbar, text="Detect", tooltip="Detect pictures", icon_data_url=self.DETECT_ICON_DATA_URL, callback=lambda: self.update_preview(), ) preview_toolbar_layout.addWidget(self.detect_button) self.preview_filter_button = self._create_toolbar_button( preview_toolbar, text="Filter", tooltip="Preview filter output", icon_data_url=self.PREVIEW_FILTER_ICON_DATA_URL, callback=self.set_preview_filter_enabled, checkable=True, use_toggled=True, ) preview_toolbar_layout.addWidget(self.preview_filter_button) self.reset_view_button = self._create_toolbar_button( preview_toolbar, text="Reset view", tooltip="Reset and center view (95%)", icon_data_url=self.RESET_VIEW_ICON_DATA_URL, callback=self.reset_canvas_view, ) preview_toolbar_layout.addWidget(self.reset_view_button) self.active_box_label = QLabel("Active Box: none") preview_toolbar_layout.addWidget(self.active_box_label) preview_toolbar_layout.addStretch(1) self.active_box_lock_button = self._create_toolbar_button( preview_toolbar, text="🔒", tooltip="Lock/unlock active box", icon_data_url=self.LOCK_ICON_DATA_URL, callback=self.toggle_active_box_lock, checkable=True, enabled=False, use_toggled=True, ) preview_toolbar_layout.addWidget(self.active_box_lock_button) self.all_boxes_lock_button = self._create_toolbar_button( preview_toolbar, text="Lock all", tooltip="Lock or unlock all boxes", icon_data_url=self.LOCK_ALL_ICON_DATA_URL, callback=self.toggle_all_boxes_lock, checkable=True, enabled=False, use_toggled=True, ) preview_toolbar_layout.addWidget(self.all_boxes_lock_button) self.active_box_squarize_button = self._create_toolbar_button( preview_toolbar, text="▭", tooltip="Squarize active box", icon_data_url=self.SQUARIZE_ICON_DATA_URL, callback=self.squarize_active_box, enabled=False, ) preview_toolbar_layout.addWidget(self.active_box_squarize_button) self.active_box_reset_rotation_button = self._create_toolbar_button( preview_toolbar, text="Reset rotation", tooltip="Reset active box rotation/tilt", icon_data_url=self.RESET_ROTATION_ICON_DATA_URL, callback=self.reset_active_box_rotation, enabled=False, ) preview_toolbar_layout.addWidget(self.active_box_reset_rotation_button) self.add_box_button = self._create_toolbar_button( preview_toolbar, text="Add box", tooltip="Add manual bounding box", icon_data_url=self.ADD_BOX_ICON_DATA_URL, callback=self.add_box, ) preview_toolbar_layout.addWidget(self.add_box_button) self.active_box_remove_button = self._create_toolbar_button( preview_toolbar, text="✕", tooltip="Remove active box", icon_data_url=self.REMOVE_ICON_DATA_URL, callback=self.remove_active_box, enabled=False, ) preview_toolbar_layout.addWidget(self.active_box_remove_button) self.active_box_rotate_button = self._create_toolbar_button( preview_toolbar, text="⟳", tooltip="Rotate mode: drag active box corner handles to rotate", icon_data_url=self.ROTATE_ICON_DATA_URL, callback=self.set_rotate_handles_mode, checkable=True, use_toggled=True, ) preview_toolbar_layout.addWidget(self.active_box_rotate_button) self.slicing_canvas = QtSlicingCanvas(preview_panel) self.slicing_canvas.active_slice_changed.connect(self.on_active_slice_changed) preview_layout.addWidget(preview_toolbar, 0, 0) preview_layout.addWidget(self.slicing_canvas, 1, 0) preview_layout.setRowStretch(1, 1) return preview_panel # _build_status_bar: function definition for ScanSlicer behavior. def _build_status_bar(self): status_bar = self.statusBar() status_bar.setMinimumHeight(30) status_bar.setSizeGripEnabled(False) status_bar.setStyleSheet("QStatusBar::item { border: none; }") self.status_message_label = QLabel("Ready.") self.status_message_label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) status_message_container = QWidget(status_bar) status_message_layout = QHBoxLayout(status_message_container) status_message_layout.setContentsMargins(10, 0, 10, 6) status_message_layout.setSpacing(0) status_message_layout.addWidget(self.status_message_label) status_bar.addWidget(status_message_container, 1) self.status_filename_label = QLabel("No file") self.status_filename_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter) status_filename_container = QWidget(status_bar) status_filename_layout = QHBoxLayout(status_filename_container) status_filename_layout.setContentsMargins(10, 0, 10, 6) status_filename_layout.setSpacing(0) status_filename_layout.addWidget(self.status_filename_label) status_bar.addPermanentWidget(status_filename_container)