ScanSlicer/scanslicer/canvas_render.py

83 lines
3.3 KiB
Python
Raw Normal View History

import numpy as np
from PySide6.QtCore import QRectF, Qt
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")
elif i == 1:
color = QColor("green")
elif i == 2:
color = QColor("orange")
else:
color = QColor("blue") if s.locked else QColor("lightgreen")
painter.setPen(QPen(color, 3))
painter.drawLine(a, b)
# Corners are color-coded: left = orange, right = cyan.
# Edge 0 (top, red) runs TL->TR, so corners 0 and 3 are the left
# side and corners 1 and 2 are the right side.
corner_colors = (QColor("orange"), QColor("cyan"), QColor("cyan"), QColor("orange"))
for p, color in zip(points, corner_colors):
painter.setPen(QPen(QColor("blue"), 2))
painter.setBrush(color)
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,
)
)