KWidgetsAddons

kratingwidget.cpp
1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 2006-2007 Sebastian Trueg <trueg@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#include "kratingwidget.h"
9#include "kratingpainter.h"
10
11#include <QIcon>
12#include <QMouseEvent>
13#include <QPainter>
14#include <QPixmap>
15
16class KRatingWidgetPrivate
17{
18public:
19 int rating = 0;
20 int hoverRating = -1;
21 int pixSize = 16;
22
23 KRatingPainter ratingPainter;
24};
25
27 : QFrame(parent)
28 , d(new KRatingWidgetPrivate())
29{
30 setMouseTracking(true);
31}
32
34
36{
37 d->ratingPainter.setCustomPixmap(pix);
38 update();
39}
40
42{
43 d->ratingPainter.setIcon(icon);
44 update();
45}
46
48{
49 d->pixSize = size;
51}
52
53int KRatingWidget::spacing() const
54{
55 return d->ratingPainter.spacing();
56}
57
58QIcon KRatingWidget::icon() const
59{
60 return d->ratingPainter.icon();
61}
62
64{
65 d->ratingPainter.setSpacing(s);
66 update();
67}
68
69Qt::Alignment KRatingWidget::alignment() const
70{
71 return d->ratingPainter.alignment();
72}
73
75{
76 d->ratingPainter.setAlignment(align);
77 update();
78}
79
81{
82 return d->ratingPainter.layoutDirection();
83}
84
86{
87 d->ratingPainter.setLayoutDirection(direction);
88 update();
89}
90
91int KRatingWidget::rating() const
92{
93 return d->rating;
94}
95
96int KRatingWidget::maxRating() const
97{
98 return d->ratingPainter.maxRating();
99}
100
101bool KRatingWidget::halfStepsEnabled() const
102{
103 return d->ratingPainter.halfStepsEnabled();
104}
105
107{
108 if (rating != d->rating) {
109 d->rating = rating;
110 d->hoverRating = rating;
111 Q_EMIT ratingChanged(rating);
112 update();
113 }
114}
115
117{
118 d->ratingPainter.setMaxRating(max);
119 update();
120}
121
123{
124 d->ratingPainter.setHalfStepsEnabled(enabled);
125 update();
126}
127
128static inline int adjustedHoverRating(bool halfStep, int hoverRating, int rating)
129{
130 // intentionally skip zero, or half step is disabled.
131 if (!halfStep || hoverRating == 0) {
132 return hoverRating;
133 }
134
135 // See bug 171343, if we click on a star we want it to be full star, click again
136 // make it half, click third time make it clear.
137
138 // round up hoverRating to next full star rating
139 const int hoveredFullStarRating = hoverRating + (hoverRating % 2);
140 // Check if the star under mouse is the last half or whole star of the rating.
141 if (hoveredFullStarRating == rating || hoveredFullStarRating == rating + 1) {
142 // If current pointed star is not empty, next rating will be rating - 1
143 // if we point at 4th star and rating is 8 (4 star), next click will make it 7
144 // if we point at 4th star and rating is 7 (3.5 star), next click will make it 6
145 hoverRating = rating - 1;
146 } else {
147 // otherwise make it a full star rating
148 hoverRating = hoveredFullStarRating;
149 }
150 return hoverRating;
151}
152
153void KRatingWidget::mousePressEvent(QMouseEvent *e)
154{
155 if (e->button() == Qt::LeftButton) {
156 d->hoverRating = adjustedHoverRating(halfStepsEnabled(), d->ratingPainter.ratingFromPosition(contentsRect(), e->pos()), d->rating);
157 // avoid set a rating to something less than zero, it may happen if widget is scaled and
158 // mouse is clicked outside the star region.
159 if (d->hoverRating >= 0) {
160 setRating(d->hoverRating);
161 }
162 }
163}
164
165void KRatingWidget::mouseMoveEvent(QMouseEvent *e)
166{
167 // when moving the mouse we show the user what the result of clicking will be
168 const int prevHoverRating = d->hoverRating;
169 d->hoverRating = adjustedHoverRating(halfStepsEnabled(), d->ratingPainter.ratingFromPosition(contentsRect(), e->pos()), d->rating);
170 if (d->hoverRating != prevHoverRating) {
171 update();
172 }
173}
174
175void KRatingWidget::leaveEvent(QEvent *)
176{
177 d->hoverRating = -1;
178 update();
179}
180
181void KRatingWidget::paintEvent(QPaintEvent *e)
182{
184 QPainter p(this);
185 d->ratingPainter.setEnabled(isEnabled());
186 d->ratingPainter.paint(&p, contentsRect(), d->rating, d->hoverRating);
187}
188
189QSize KRatingWidget::sizeHint() const
190{
191 int numPix = d->ratingPainter.maxRating();
192 if (d->ratingPainter.halfStepsEnabled()) {
193 numPix /= 2;
194 }
195
196 QSize pixSize(d->pixSize, d->pixSize);
197 if (!d->ratingPainter.customPixmap().isNull()) {
198 pixSize = d->ratingPainter.customPixmap().size() / d->ratingPainter.customPixmap().devicePixelRatio();
199 }
200
201 return QSize(pixSize.width() * numPix + spacing() * (numPix - 1) + frameWidth() * 2, pixSize.height() + frameWidth() * 2);
202}
203
204void KRatingWidget::resizeEvent(QResizeEvent *e)
205{
207}
208
209#include "moc_kratingwidget.cpp"
Utility class that draws a row of stars for a rating value.
void setAlignment(Qt::Alignment align)
The alignment of the stars in the drawing rect.
void setMaxRating(int max)
Set the maximum allowed rating value.
~KRatingWidget() override
Destructor.
void setRating(int rating)
Set the current rating.
void setPixmapSize(int size)
Set the recommended size of the pixmaps.
void setSpacing(int)
Set the spacing between the pixmaps.
void ratingChanged(int rating)
This signal is emitted when the rating is changed.
void setCustomPixmap(const QPixmap &pixmap)
Set a custom pixmap.
Qt::LayoutDirection layoutDirection() const
The layout direction.
void setLayoutDirection(Qt::LayoutDirection direction)
LTR or RTL.
void setIcon(const QIcon &icon)
Set a custom icon.
KRatingWidget(QWidget *parent=nullptr)
Creates a new rating widget.
void setHalfStepsEnabled(bool enabled)
If half steps are enabled (the default) then one rating step corresponds to half a star.
virtual void paintEvent(QPaintEvent *) override
QPoint pos() const const
Q_EMITQ_EMIT
T qobject_cast(QObject *object)
Qt::MouseButton button() const const
typedef Alignment
LayoutDirection
LeftButton
QRect contentsRect() const const
void setMouseTracking(bool enable)
virtual void resizeEvent(QResizeEvent *event)
void update()
void updateGeometry()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:14:43 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.