1 /*
2     This file is part of the KDE libraries
3     SPDX-FileCopyrightText: 2007-2008 Sebastian Trueg <trueg@kde.org>
4 
5     SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #ifndef KRATINGPAINTER_H
9 #define KRATINGPAINTER_H
10 
11 #include <kwidgetsaddons_export.h>
12 
13 #include <Qt>
14 #include <memory>
15 
16 class QIcon;
17 class QPixmap;
18 class QPainter;
19 class QPoint;
20 class QRect;
21 
22 /**
23  * \class KRatingPainter kratingpainter.h KRatingPainter
24  *
25  * \brief Utility class that draws a row of stars for a rating value.
26  *
27  * The KRatingPainter also allows to determine a rating value from
28  * a position in the draw area. it supports all different alignments
29  * and custom icons.
30  *
31  * For showing a rating in a widget see KRatingWidget.
32  *
33  * \author Sebastian Trueg <trueg@kde.org>
34  *
35  * \since 4.1
36  */
37 class KWIDGETSADDONS_EXPORT KRatingPainter
38 {
39 public:
40     /**
41      * Create a new KRatingPainter.
42      * For most cases the static methods paintRating and getRatingFromPosition
43      * should be sufficient.
44      */
45     KRatingPainter();
46 
47     /**
48      * Destructor
49      */
50     ~KRatingPainter();
51 
52     KRatingPainter(const KRatingPainter &) = delete;
53     KRatingPainter &operator=(const KRatingPainter &) = delete;
54 
55     /**
56      * The maximum rating, i.e. how many stars are drawn
57      * in total.
58      *
59      * \sa setMaxRating
60      */
61     int maxRating() const;
62 
63     /**
64      * If half steps are enabled one star equals to 2 rating
65      * points and uneven rating values result in half-stars being
66      * drawn.
67      *
68      * \sa setHalfStepsEnabled
69      */
70     bool halfStepsEnabled() const;
71 
72     /**
73      * The alignment of the stars.
74      *
75      * \sa setAlignment
76      */
77     Qt::Alignment alignment() const;
78 
79     /**
80      * The layout direction. If RTL the stars
81      * representing the rating value will be drawn from the
82      * right.
83      *
84      * \sa setLayoutDirection
85      */
86     Qt::LayoutDirection layoutDirection() const;
87 
88     /**
89      * The icon used to draw a star. In case a custom pixmap has been set
90      * this value is ignored.
91      *
92      * \sa setIcon, setCustomPixmap
93      */
94     QIcon icon() const;
95 
96     /**
97      * The rating can be painted in a disabled state where no color
98      * is used and hover ratings are ignored.
99      *
100      * \sa setEnabled
101      */
102     bool isEnabled() const;
103 
104     /**
105      * The custom pixmap set to draw a star. If no custom
106      * pixmap has been set, an invalid pixmap is returned.
107      *
108      * \sa setCustomPixmap
109      */
110     QPixmap customPixmap() const;
111 
112     /**
113      * The spacing between rating pixmaps.
114      *
115      * \sa setSpacing
116      */
117     int spacing() const;
118 
119     /**
120      * The maximum rating. Defaults to 10.
121      */
122     void setMaxRating(int max);
123 
124     /**
125      * If half steps are enabled (the default) then
126      * one rating step corresponds to half a star.
127      */
128     void setHalfStepsEnabled(bool enabled);
129 
130     /**
131      * The alignment of the stars in the drawing rect.
132      * All alignment flags are supported.
133      */
134     void setAlignment(Qt::Alignment align);
135 
136     /**
137      * LTR or RTL
138      */
139     void setLayoutDirection(Qt::LayoutDirection direction);
140 
141     /**
142      * Set a custom icon. Defaults to "rating".
143      */
144     void setIcon(const QIcon &icon);
145 
146     /**
147      * Enable or disable the rating. Default is enabled.
148      */
149     void setEnabled(bool enabled);
150 
151     /**
152      * Set a custom pixmap.
153      */
154     void setCustomPixmap(const QPixmap &pixmap);
155 
156     /**
157      * Set the spacing between rating pixmaps. Be aware that
158      * for justified horizontal alignment this values may be
159      * ignored.
160      */
161     void setSpacing(int spacing);
162 
163     /**
164      * Draw the rating.
165      *
166      * \param painter The painter to draw the rating to.
167      * \param rect The geometry of the rating. The alignment of the rating is used relative
168      *             to this value.
169      * \param rating The actual rating value to draw.
170      * \param hoverRating The hover rating indicates the position the user hovers the mouse
171      *                    pointer at. This will provide visual feedback about the new rating
172      *                    if the user would actually click as well as the difference to the
173      *                    current rating.
174      */
175     void paint(QPainter *painter, const QRect &rect, int rating, int hoverRating = -1) const;
176 
177     /**
178      * Calculate the rating value from mouse position pos.
179      *
180      * \return The rating corresponding to pos or -1 if pos is
181      * outside of the configured rect.
182      */
183     int ratingFromPosition(const QRect &rect, const QPoint &pos) const;
184 
185     /**
186      * Convenience method that paints a rating into the given rect.
187      *
188      * LayoutDirection is read from QPainter.
189      *
190      * \param align can be aligned vertically and horizontally. Using Qt::AlignJustify will insert spacing
191      * between the stars.
192      */
193     static void paintRating(QPainter *p, const QRect &rect, Qt::Alignment align, int rating, int hoverRating = -1);
194 
195     /**
196      * Get the rating that would be selected if the user clicked position pos
197      * within rect if the rating has been drawn with paintRating() using the same
198      * rect and align values.
199      *
200      * \return The new rating or -1 if pos is outside of the rating area.
201      */
202     static int getRatingFromPosition(const QRect &rect, Qt::Alignment align, Qt::LayoutDirection direction, const QPoint &pos);
203 
204 private:
205     std::unique_ptr<class KRatingPainterPrivate> const d;
206 };
207 
208 #endif
209