aboutsummaryrefslogtreecommitdiffstats
path: root/examples/widgets/itemviews/stardelegate/starrating.py
blob: 96c08fca7a6c7c20a63f8b846a7d18b71cc98ced (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# Copyright (C) 2010 Hans-Peter Jansen <hpj@urpla.net>
# Copyright (C) 2011 Arun Srinivasan <rulfzid@gmail.com>
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
from __future__ import annotations

from math import (cos, sin, pi)

from PySide6.QtGui import (QPainter, QPainterStateGuard, QPolygonF)
from PySide6.QtCore import (QPointF, QSize, Qt)

PAINTING_SCALE_FACTOR = 20


class StarRating:
    """ Handle the actual painting of the stars themselves. """

    def __init__(self, starCount=1, maxStarCount=5):
        self.star_count = starCount
        self.MAX_STAR_COUNT = maxStarCount

        # Create the star shape we'll be drawing.
        self._star_polygon = QPolygonF()
        self._star_polygon.append(QPointF(1.0, 0.5))
        for i in range(1, 5):
            self._star_polygon.append(QPointF(0.5 + 0.5 * cos(0.8 * i * pi),
                                      0.5 + 0.5 * sin(0.8 * i * pi)))

        # Create the diamond shape we'll show in the editor
        self._diamond_polygon = QPolygonF()
        diamond_points = [QPointF(0.4, 0.5), QPointF(0.5, 0.4),
                          QPointF(0.6, 0.5), QPointF(0.5, 0.6),
                          QPointF(0.4, 0.5)]
        self._diamond_polygon.append(diamond_points)

    def sizeHint(self):
        """ Tell the caller how big we are. """
        return PAINTING_SCALE_FACTOR * QSize(self.MAX_STAR_COUNT, 1)

    def paint(self, painter, rect, palette, isEditable=False):
        """ Paint the stars (and/or diamonds if we're in editing mode). """
        with QPainterStateGuard(painter):
            painter.setRenderHint(QPainter.RenderHint.Antialiasing, True)
            painter.setPen(Qt.NoPen)

            if isEditable:
                painter.setBrush(palette.highlight())
            else:
                painter.setBrush(palette.windowText())

            y_offset = (rect.height() - PAINTING_SCALE_FACTOR) / 2
            painter.translate(rect.x(), rect.y() + y_offset)
            painter.scale(PAINTING_SCALE_FACTOR, PAINTING_SCALE_FACTOR)

            for i in range(self.MAX_STAR_COUNT):
                if i < self.star_count:
                    painter.drawPolygon(self._star_polygon, Qt.FillRule.WindingFill)
                elif isEditable:
                    painter.drawPolygon(self._diamond_polygon, Qt.FillRule.WindingFill)
                painter.translate(1.0, 0.0)