]> cloud.milkyroute.net Git - dolphin.git/blob - src/ratingpainter.cpp
As requested by Peter: upgrade version to 1.0
[dolphin.git] / src / ratingpainter.cpp
1 /*
2 This file is part of the Nepomuk KDE project.
3 Copyright (C) 2007 Sebastian Trueg <trueg@kde.org>
4
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.
8
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.
13
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.
18 */
19
20 #include "ratingpainter.h"
21
22 #include <QtGui/QPainter>
23 #include <QtGui/QPixmap>
24
25 #include <kicon.h>
26 #include <kiconeffect.h>
27 #include <kdebug.h>
28
29
30 class Nepomuk::RatingPainter::Private
31 {
32 public:
33 Private()
34 : maxRating(10),
35 icon( "rating" ),
36 bHalfSteps(true),
37 alignment(Qt::AlignCenter),
38 direction(Qt::LeftToRight) {
39 }
40
41 int maxRating;
42 KIcon icon;
43 bool bHalfSteps;
44 Qt::Alignment alignment;
45 Qt::LayoutDirection direction;
46 QPixmap customPixmap;
47 };
48
49
50 Nepomuk::RatingPainter::RatingPainter()
51 : d(new Private())
52 {
53 }
54
55
56 Nepomuk::RatingPainter::~RatingPainter()
57 {
58 delete d;
59 }
60
61
62 int Nepomuk::RatingPainter::maxRating() const
63 {
64 return d->maxRating;
65 }
66
67
68 bool Nepomuk::RatingPainter::halfStepsEnabled() const
69 {
70 return d->bHalfSteps;
71 }
72
73
74 Qt::Alignment Nepomuk::RatingPainter::alignment() const
75 {
76 return d->alignment;
77 }
78
79
80 Qt::LayoutDirection Nepomuk::RatingPainter::direction() const
81 {
82 return d->direction;
83 }
84
85
86 KIcon Nepomuk::RatingPainter::icon() const
87 {
88 return d->icon;
89 }
90
91
92 QPixmap Nepomuk::RatingPainter::customPixmap() const
93 {
94 return d->customPixmap;
95 }
96
97
98 void Nepomuk::RatingPainter::setMaxRating( int max )
99 {
100 d->maxRating = max;
101 }
102
103
104 void Nepomuk::RatingPainter::setHalfStepsEnabled( bool enabled )
105 {
106 d->bHalfSteps = enabled;
107 }
108
109
110 void Nepomuk::RatingPainter::setAlignment( Qt::Alignment align )
111 {
112 d->alignment = align;
113 }
114
115
116 void Nepomuk::RatingPainter::setLayoutDirection( Qt::LayoutDirection direction )
117 {
118 d->direction = direction;
119 }
120
121
122 void Nepomuk::RatingPainter::setIcon( const KIcon& icon )
123 {
124 d->icon = icon;
125 }
126
127
128 void Nepomuk::RatingPainter::setCustomPixmap( const QPixmap& pixmap )
129 {
130 d->customPixmap = pixmap;
131 }
132
133
134 void Nepomuk::RatingPainter::draw( QPainter* painter, const QRect& rect, int rating, int hoverRating )
135 {
136 rating = qMin( rating, d->maxRating );
137 hoverRating = qMin( hoverRating, d->maxRating );
138
139 int numUsedStars = d->bHalfSteps ? d->maxRating/2 : d->maxRating;
140
141 if ( hoverRating > 0 && hoverRating < rating ) {
142 int tmp = hoverRating;
143 hoverRating = rating;
144 rating = tmp;
145 }
146
147 // get the rating pixmaps
148 QPixmap ratingPix;
149 if ( !d->customPixmap.isNull() ) {
150 ratingPix = d->customPixmap;
151 }
152 else {
153 KIcon ratingIcon( "rating" );
154 int iconSize = qMin( rect.height(), rect.width() / numUsedStars );
155 ratingPix = ratingIcon.pixmap( iconSize );
156 }
157
158 QPixmap disabledRatingPix = KIconEffect().apply( ratingPix, KIconEffect::ToGray, 1.0, QColor(), false );
159 QPixmap hoverPix;
160
161 bool half = d->bHalfSteps && rating%2;
162 int numRatingStars = d->bHalfSteps ? rating/2 : rating;
163
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 );
170 }
171
172 int usedSpacing = 0;
173 if ( d->alignment & Qt::AlignJustify ) {
174 int w = rect.width();
175 w -= numUsedStars * ratingPix.width();
176 usedSpacing = w / ( numUsedStars-1 );
177 }
178
179 int i = 0;
180 int x = rect.x();
181 if ( d->alignment & Qt::AlignRight ) {
182 x += ( rect.width() - ratingPix.width()*numUsedStars );
183 }
184 else if ( d->alignment & Qt::AlignCenter ) {
185 x += ( rect.width() - ratingPix.width()*numUsedStars )/2;
186 }
187
188 int xInc = ratingPix.width() + usedSpacing;
189 if ( d->direction == Qt::RightToLeft ) {
190 x = rect.width() - ratingPix.width() - x;
191 xInc = -xInc;
192 }
193
194 int y = rect.y();
195 if( d->alignment & Qt::AlignVCenter ) {
196 y += ( rect.height() / 2 - ratingPix.height() / 2 );
197 }
198 else if ( d->alignment & Qt::AlignBottom ) {
199 y += ( rect.height() - ratingPix.height() );
200 }
201 for(; i < numRatingStars; ++i ) {
202 painter->drawPixmap( x, y, ratingPix );
203 x += xInc;
204 }
205 if( half ) {
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() );
212 x += xInc;
213 ++i;
214 }
215 for(; i < numHoverStars; ++i ) {
216 painter->drawPixmap( x, y, hoverPix );
217 x += xInc;
218 }
219 if( halfHover ) {
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() );
226 x += xInc;
227 ++i;
228 }
229 for(; i < numUsedStars; ++i ) {
230 painter->drawPixmap( x, y, disabledRatingPix );
231 x += xInc;
232 }
233 }
234
235
236 int Nepomuk::RatingPainter::fromPosition( const QRect& rect, const QPoint& pos )
237 {
238 int numUsedStars = d->bHalfSteps ? d->maxRating/2 : d->maxRating;
239 QPixmap ratingPix;
240 if ( !d->customPixmap.isNull() ) {
241 ratingPix = d->customPixmap;
242 }
243 else {
244 KIcon ratingIcon( "rating" );
245 int iconSize = qMin( rect.height(), rect.width() / numUsedStars );
246 ratingPix = ratingIcon.pixmap( iconSize );
247 }
248
249 QRect usedRect( rect );
250 if ( d->alignment & Qt::AlignRight ) {
251 usedRect.setLeft( rect.right() - numUsedStars * ratingPix.width() );
252 }
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 );
257 }
258 else { // d->alignment & Qt::AlignLeft
259 usedRect.setRight( rect.left() + numUsedStars * ratingPix.width() - 1 );
260 }
261
262 if ( d->alignment & Qt::AlignBottom ) {
263 usedRect.setTop( rect.bottom() - ratingPix.height() + 1 );
264 }
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 );
269 }
270 else { // d->alignment & Qt::AlignTop
271 usedRect.setBottom( rect.top() + ratingPix.height() - 1 );
272 }
273
274 if ( usedRect.contains( pos ) ) {
275 int x = 0;
276 if ( d->direction == Qt::RightToLeft ) {
277 x = usedRect.right() - pos.x();
278 }
279 else {
280 x = pos.x() - usedRect.left();
281 }
282
283 double one = ( double )usedRect.width() / ( double )d->maxRating;
284
285 kDebug() << "rating:" << ( int )( ( double )x/one + 0.5 );
286
287 return ( int )( ( double )x/one + 0.5 );
288 }
289 else {
290 return -1;
291 }
292 }
293
294
295 void Nepomuk::RatingPainter::drawRating( QPainter* painter, const QRect& rect, Qt::Alignment align, int rating, int hoverRating )
296 {
297 RatingPainter rp;
298 rp.setAlignment( align );
299 rp.setLayoutDirection( painter->layoutDirection() );
300 rp.draw( painter, rect, rating, hoverRating );
301 }
302
303
304 int Nepomuk::RatingPainter::getRatingFromPosition( const QRect& rect, Qt::Alignment align, Qt::LayoutDirection direction, const QPoint& pos )
305 {
306 RatingPainter rp;
307 rp.setAlignment( align );
308 rp.setLayoutDirection( direction );
309 return rp.fromPosition( rect, pos );
310 }