2 This file is part of the Nepomuk KDE project.
3 Copyright (C) 2007 Sebastian Trueg <trueg@kde.org>
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
20 #include "ratingpainter.h"
22 #include <QtGui/QPainter>
23 #include <QtGui/QPixmap>
26 #include <kiconeffect.h>
30 class Nepomuk::RatingPainter::Private
37 alignment(Qt::AlignCenter
),
38 direction(Qt::LeftToRight
) {
44 Qt::Alignment alignment
;
45 Qt::LayoutDirection direction
;
50 Nepomuk::RatingPainter::RatingPainter()
56 Nepomuk::RatingPainter::~RatingPainter()
62 int Nepomuk::RatingPainter::maxRating() const
68 bool Nepomuk::RatingPainter::halfStepsEnabled() const
74 Qt::Alignment
Nepomuk::RatingPainter::alignment() const
80 Qt::LayoutDirection
Nepomuk::RatingPainter::direction() const
86 KIcon
Nepomuk::RatingPainter::icon() const
92 QPixmap
Nepomuk::RatingPainter::customPixmap() const
94 return d
->customPixmap
;
98 void Nepomuk::RatingPainter::setMaxRating( int max
)
104 void Nepomuk::RatingPainter::setHalfStepsEnabled( bool enabled
)
106 d
->bHalfSteps
= enabled
;
110 void Nepomuk::RatingPainter::setAlignment( Qt::Alignment align
)
112 d
->alignment
= align
;
116 void Nepomuk::RatingPainter::setLayoutDirection( Qt::LayoutDirection direction
)
118 d
->direction
= direction
;
122 void Nepomuk::RatingPainter::setIcon( const KIcon
& icon
)
128 void Nepomuk::RatingPainter::setCustomPixmap( const QPixmap
& pixmap
)
130 d
->customPixmap
= pixmap
;
134 void Nepomuk::RatingPainter::draw( QPainter
* painter
, const QRect
& rect
, int rating
, int hoverRating
)
136 rating
= qMin( rating
, d
->maxRating
);
137 hoverRating
= qMin( hoverRating
, d
->maxRating
);
139 int numUsedStars
= d
->bHalfSteps
? d
->maxRating
/2 : d
->maxRating
;
141 if ( hoverRating
> 0 && hoverRating
< rating
) {
142 int tmp
= hoverRating
;
143 hoverRating
= rating
;
147 // get the rating pixmaps
149 if ( !d
->customPixmap
.isNull() ) {
150 ratingPix
= d
->customPixmap
;
153 KIcon
ratingIcon( "rating" );
154 int iconSize
= qMin( rect
.height(), rect
.width() / numUsedStars
);
155 ratingPix
= ratingIcon
.pixmap( iconSize
);
158 QPixmap disabledRatingPix
= KIconEffect().apply( ratingPix
, KIconEffect::ToGray
, 1.0, QColor(), false );
161 bool half
= d
->bHalfSteps
&& rating%2
;
162 int numRatingStars
= d
->bHalfSteps
? rating
/2 : rating
;
164 int numHoverStars
= 0;
165 bool halfHover
= false;
166 if ( hoverRating
> 0 && rating
!= hoverRating
) {
167 numHoverStars
= d
->bHalfSteps
? hoverRating
/2 : hoverRating
;
168 halfHover
= d
->bHalfSteps
&& hoverRating%2
;
169 hoverPix
= KIconEffect().apply( ratingPix
, KIconEffect::ToGray
, 0.5, QColor(), false );
173 if ( d
->alignment
& Qt::AlignJustify
) {
174 int w
= rect
.width();
175 w
-= numUsedStars
* ratingPix
.width();
176 usedSpacing
= w
/ ( numUsedStars
-1 );
181 if ( d
->alignment
& Qt::AlignRight
) {
182 x
+= ( rect
.width() - ratingPix
.width()*numUsedStars
);
184 else if ( d
->alignment
& Qt::AlignCenter
) {
185 x
+= ( rect
.width() - ratingPix
.width()*numUsedStars
)/2;
188 int xInc
= ratingPix
.width() + usedSpacing
;
189 if ( d
->direction
== Qt::RightToLeft
) {
190 x
= rect
.width() - ratingPix
.width() - x
;
195 if( d
->alignment
& Qt::AlignVCenter
) {
196 y
+= ( rect
.height() / 2 - ratingPix
.height() / 2 );
198 else if ( d
->alignment
& Qt::AlignBottom
) {
199 y
+= ( rect
.height() - ratingPix
.height() );
201 for(; i
< numRatingStars
; ++i
) {
202 painter
->drawPixmap( x
, y
, ratingPix
);
206 painter
->drawPixmap( x
, y
, ratingPix
.width()/2, ratingPix
.height(),
207 d
->direction
== Qt::LeftToRight
? ratingPix
: ( numHoverStars
> 0 ? hoverPix
: disabledRatingPix
),
208 0, 0, ratingPix
.width()/2, ratingPix
.height() );
209 painter
->drawPixmap( x
+ ratingPix
.width()/2, y
, ratingPix
.width()/2, ratingPix
.height(),
210 d
->direction
== Qt::LeftToRight
? ( numHoverStars
> 0 ? hoverPix
: disabledRatingPix
) : ratingPix
,
211 ratingPix
.width()/2, 0, ratingPix
.width()/2, ratingPix
.height() );
215 for(; i
< numHoverStars
; ++i
) {
216 painter
->drawPixmap( x
, y
, hoverPix
);
220 painter
->drawPixmap( x
, y
, ratingPix
.width()/2, ratingPix
.height(),
221 d
->direction
== Qt::LeftToRight
? hoverPix
: disabledRatingPix
,
222 0, 0, ratingPix
.width()/2, ratingPix
.height() );
223 painter
->drawPixmap( x
+ ratingPix
.width()/2, y
, ratingPix
.width()/2, ratingPix
.height(),
224 d
->direction
== Qt::LeftToRight
? disabledRatingPix
: hoverPix
,
225 ratingPix
.width()/2, 0, ratingPix
.width()/2, ratingPix
.height() );
229 for(; i
< numUsedStars
; ++i
) {
230 painter
->drawPixmap( x
, y
, disabledRatingPix
);
236 int Nepomuk::RatingPainter::fromPosition( const QRect
& rect
, const QPoint
& pos
)
238 int numUsedStars
= d
->bHalfSteps
? d
->maxRating
/2 : d
->maxRating
;
240 if ( !d
->customPixmap
.isNull() ) {
241 ratingPix
= d
->customPixmap
;
244 KIcon
ratingIcon( "rating" );
245 int iconSize
= qMin( rect
.height(), rect
.width() / numUsedStars
);
246 ratingPix
= ratingIcon
.pixmap( iconSize
);
249 QRect
usedRect( rect
);
250 if ( d
->alignment
& Qt::AlignRight
) {
251 usedRect
.setLeft( rect
.right() - numUsedStars
* ratingPix
.width() );
253 else if ( d
->alignment
& Qt::AlignHCenter
) {
254 int x
= ( rect
.width() - numUsedStars
* ratingPix
.width() )/2;
255 usedRect
.setLeft( rect
.left() + x
);
256 usedRect
.setRight( rect
.right() - x
);
258 else { // d->alignment & Qt::AlignLeft
259 usedRect
.setRight( rect
.left() + numUsedStars
* ratingPix
.width() - 1 );
262 if ( d
->alignment
& Qt::AlignBottom
) {
263 usedRect
.setTop( rect
.bottom() - ratingPix
.height() + 1 );
265 else if ( d
->alignment
& Qt::AlignVCenter
) {
266 int x
= ( rect
.height() - ratingPix
.height() )/2;
267 usedRect
.setTop( rect
.top() + x
);
268 usedRect
.setBottom( rect
.bottom() - x
);
270 else { // d->alignment & Qt::AlignTop
271 usedRect
.setBottom( rect
.top() + ratingPix
.height() - 1 );
274 if ( usedRect
.contains( pos
) ) {
276 if ( d
->direction
== Qt::RightToLeft
) {
277 x
= usedRect
.right() - pos
.x();
280 x
= pos
.x() - usedRect
.left();
283 double one
= ( double )usedRect
.width() / ( double )d
->maxRating
;
285 kDebug() << "rating:" << ( int )( ( double )x
/one
+ 0.5 );
287 return ( int )( ( double )x
/one
+ 0.5 );
295 void Nepomuk::RatingPainter::drawRating( QPainter
* painter
, const QRect
& rect
, Qt::Alignment align
, int rating
, int hoverRating
)
298 rp
.setAlignment( align
);
299 rp
.setLayoutDirection( painter
->layoutDirection() );
300 rp
.draw( painter
, rect
, rating
, hoverRating
);
304 int Nepomuk::RatingPainter::getRatingFromPosition( const QRect
& rect
, Qt::Alignment align
, Qt::LayoutDirection direction
, const QPoint
& pos
)
307 rp
.setAlignment( align
);
308 rp
.setLayoutDirection( direction
);
309 return rp
.fromPosition( rect
, pos
);