diff --git a/beeref/widgets/color_gamut.py b/beeref/widgets/color_gamut.py index b9f9353..d45c929 100644 --- a/beeref/widgets/color_gamut.py +++ b/beeref/widgets/color_gamut.py @@ -17,6 +17,7 @@ import math from PyQt6 import QtWidgets, QtGui, QtCore +from PyQt6.QtCore import Qt logger = logging.getLogger(__name__) @@ -27,22 +28,24 @@ class GamutWidget(QtWidgets.QWidget): def __init__(self, parent, item): super().__init__(parent) self.item = item + self.image = None + self.radius = 250 def minimumSizeHint(self): - return QtCore.QSize(100, 100) + return QtCore.QSize(200, 200) - def paintEvent(self, event): - painter = QtGui.QPainter(self) + def draw_gamut_image(self): + self.image = QtGui.QImage( + QtCore.QSize(2 * self.radius, 2 * self.radius), + QtGui.QImage.Format.Format_ARGB32) + self.image.fill(QtGui.QColor(0, 0, 0, 0)) + + painter = QtGui.QPainter(self.image) painter.setRenderHint(QtGui.QPainter.RenderHint.Antialiasing) - painter.setClipRegion(event.region()) painter.setBrush(QtGui.QBrush(QtGui.QColor(0, 0, 0))) - painter.setPen(QtCore.Qt.PenStyle.NoPen) - - # Paint the circle, always centered - center = QtCore.QPoint(int(self.size().width() / 2), - int(self.size().height() / 2)) - radius = int(min(self.size().width(), self.size().height()) / 2) - painter.drawEllipse(center, radius, radius) + painter.setPen(Qt.PenStyle.NoPen) + center = QtCore.QPoint(self.radius, self.radius) + painter.drawEllipse(center, self.radius, self.radius) threshold = max(1, int(len(self.item.color_gamut) / 1000)) print(threshold) @@ -52,15 +55,27 @@ def paintEvent(self, event): for (hue, saturation), value in self.item.color_gamut.items(): if value < threshold: continue - hypotenuse = saturation / 255 * radius + hypotenuse = saturation / 255 * self.radius h = math.radians(hue) x = int(math.sin(h) * hypotenuse) + center.x() y = int(math.cos(h) * hypotenuse) + center.y() color = QtGui.QColor() color.setHsv(hue, saturation, 255) painter.setBrush(QtGui.QBrush(color)) - painter.drawEllipse(x, y, 3, 3) + painter.drawEllipse(QtCore.QPoint(x, y), 3, 3) + def paintEvent(self, event): + painter = QtGui.QPainter(self) + painter.setRenderHint(painter.RenderHint.SmoothPixmapTransform) + if not self.image: + # Draw gamut onto image instead of directly onto the painter + # because it's too slow to redraw it on every paint event + # (when resizing the widget for example). + self.draw_gamut_image() + size = min(self.size().width(), self.size().height()) + x = max((self.size().width() - size) / 2, 0) + y = max((self.size().height() - size) / 2, 0) + painter.drawImage(QtCore.QRectF(x, y, size, size), self.image) class GamutDialog(QtWidgets.QDialog):