diff --git a/scanslicer/canvas_render.py b/scanslicer/canvas_render.py index 9329f31..0eff838 100644 --- a/scanslicer/canvas_render.py +++ b/scanslicer/canvas_render.py @@ -4,3 +4,71 @@ from PySide6.QtGui import QColor, QFont, QPainter, QPen # CanvasRenderMixin: class definition for ScanSlicer behavior. +class CanvasRenderMixin: + # paintEvent: function definition for ScanSlicer behavior. + def paintEvent(self, event): + painter = QPainter(self) + painter.fillRect(self.rect(), self.OFF_CANVAS_COLOR) + + if self.image is None: + return + + img_rect = self._image_rect_view() + painter.drawImage(img_rect, self.image) + + label_font = QFont(painter.font()) + label_font.setPointSize(18) + label_font.setBold(True) + + for si, s in enumerate(self.slices): + points = [self._image_to_view(p) for p in s.bbox] + + for i in range(4): + a = points[i] + b = points[(i + 1) % 4] + if i == 0: + color = QColor("red") + else: + color = QColor("blue") if s.locked else QColor("lightgreen") + painter.setPen(QPen(color, 3)) + painter.drawLine(a, b) + + painter.setPen(QPen(QColor("blue"), 2)) + painter.setBrush(QColor(128, 128, 128, 170)) + for p in points: + painter.drawRect(QRectF(p.x() - 5, p.y() - 5, 10, 10)) + + center = np.mean(s.bbox, axis=0) + center_view = self._image_to_view(center) + if si == self.active_slice_index: + text_color = QColor("gold") + else: + text_color = QColor("blue") if s.locked else QColor("lightgreen") + painter.setPen(QPen(text_color, 1)) + painter.setFont(label_font) + painter.drawText( + QRectF(center_view.x() - 20, center_view.y() - 16, 40, 32), + Qt.AlignCenter, + str(si), + ) + + if s.side_handles_enabled and s.is_perfect_rectangle(): + handle_color = QColor("orange") if si == self.active_slice_index else QColor(255, 170, 0) + painter.setPen(QPen(handle_color, 2)) + painter.setBrush(QColor(handle_color.red(), handle_color.green(), handle_color.blue(), 170)) + handle_size = ( + float(getattr(self, "SIDE_HANDLE_SIZE_ACTIVE", 11.0)) + if si == self.active_slice_index + else float(getattr(self, "SIDE_HANDLE_SIZE_INACTIVE", 9.0)) + ) + for ei in range(4): + mid = (s.bbox[ei] + s.bbox[(ei + 1) % 4]) / 2.0 + mid_view = self._image_to_view(mid) + painter.drawRect( + QRectF( + mid_view.x() - handle_size / 2.0, + mid_view.y() - handle_size / 2.0, + handle_size, + handle_size, + ) + )