KDEUI
kratingpainter.cpp
Go to the documentation of this file.
00001 /* 00002 This file is part of the Nepomuk KDE project. 00003 Copyright (C) 2007-2008 Sebastian Trueg <trueg@kde.org> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 Boston, MA 02110-1301, USA. 00019 */ 00020 00021 #include "kratingpainter.h" 00022 00023 #include <QtGui/QPainter> 00024 #include <QtGui/QPixmap> 00025 #include <QtGui/QIcon> 00026 #include <QtCore/QRect> 00027 #include <QtCore/QPoint> 00028 00029 #include <kicon.h> 00030 #include <kiconeffect.h> 00031 #include <kiconloader.h> 00032 #include <kdebug.h> 00033 00034 00035 class KRatingPainter::Private 00036 { 00037 public: 00038 Private() 00039 : maxRating(10), 00040 isEnabled( true ), 00041 bHalfSteps(true), 00042 alignment(Qt::AlignCenter), 00043 direction(Qt::LeftToRight), 00044 spacing(0) { 00045 } 00046 00047 QPixmap getPixmap( int size ); 00048 00049 int maxRating; 00050 QIcon icon; 00051 bool isEnabled; 00052 bool bHalfSteps; 00053 Qt::Alignment alignment; 00054 Qt::LayoutDirection direction; 00055 QPixmap customPixmap; 00056 int spacing; 00057 }; 00058 00059 00060 QPixmap KRatingPainter::Private::getPixmap( int size ) 00061 { 00062 if ( !customPixmap.isNull() ) { 00063 return customPixmap.scaled( QSize( size, size ) ); 00064 } 00065 else { 00066 QIcon _icon( icon ); 00067 if ( _icon.isNull() ) { 00068 _icon = KIcon( "rating" ); 00069 } 00070 return _icon.pixmap( size ); 00071 } 00072 } 00073 00074 00075 KRatingPainter::KRatingPainter() 00076 : d(new Private()) 00077 { 00078 } 00079 00080 00081 KRatingPainter::~KRatingPainter() 00082 { 00083 delete d; 00084 } 00085 00086 00087 int KRatingPainter::maxRating() const 00088 { 00089 return d->maxRating; 00090 } 00091 00092 00093 bool KRatingPainter::halfStepsEnabled() const 00094 { 00095 return d->bHalfSteps; 00096 } 00097 00098 00099 Qt::Alignment KRatingPainter::alignment() const 00100 { 00101 return d->alignment; 00102 } 00103 00104 00105 Qt::LayoutDirection KRatingPainter::layoutDirection() const 00106 { 00107 return d->direction; 00108 } 00109 00110 00111 QIcon KRatingPainter::icon() const 00112 { 00113 return d->icon; 00114 } 00115 00116 00117 bool KRatingPainter::isEnabled() const 00118 { 00119 return d->isEnabled; 00120 } 00121 00122 00123 QPixmap KRatingPainter::customPixmap() const 00124 { 00125 return d->customPixmap; 00126 } 00127 00128 00129 int KRatingPainter::spacing() const 00130 { 00131 return d->spacing; 00132 } 00133 00134 00135 void KRatingPainter::setMaxRating( int max ) 00136 { 00137 d->maxRating = max; 00138 } 00139 00140 00141 void KRatingPainter::setHalfStepsEnabled( bool enabled ) 00142 { 00143 d->bHalfSteps = enabled; 00144 } 00145 00146 00147 void KRatingPainter::setAlignment( Qt::Alignment align ) 00148 { 00149 d->alignment = align; 00150 } 00151 00152 00153 void KRatingPainter::setLayoutDirection( Qt::LayoutDirection direction ) 00154 { 00155 d->direction = direction; 00156 } 00157 00158 00159 void KRatingPainter::setIcon( const QIcon& icon ) 00160 { 00161 d->icon = icon; 00162 } 00163 00164 00165 void KRatingPainter::setEnabled( bool enabled ) 00166 { 00167 d->isEnabled = enabled; 00168 } 00169 00170 00171 void KRatingPainter::setCustomPixmap( const QPixmap& pixmap ) 00172 { 00173 d->customPixmap = pixmap; 00174 } 00175 00176 00177 void KRatingPainter::setSpacing( int s ) 00178 { 00179 d->spacing = qMax( 0, s ); 00180 } 00181 00182 00183 void KRatingPainter::paint( QPainter* painter, const QRect& rect, int rating, int hoverRating ) const 00184 { 00185 rating = qMin( rating, d->maxRating ); 00186 hoverRating = qMin( hoverRating, d->maxRating ); 00187 00188 int numUsedStars = d->bHalfSteps ? d->maxRating/2 : d->maxRating; 00189 00190 if ( hoverRating > 0 && hoverRating < rating ) { 00191 int tmp = hoverRating; 00192 hoverRating = rating; 00193 rating = tmp; 00194 } 00195 00196 int usedSpacing = d->spacing; 00197 00198 // get the rating pixmaps 00199 int maxHSizeOnePix = ( rect.width() - (numUsedStars-1)*usedSpacing ) / numUsedStars; 00200 QPixmap ratingPix = d->getPixmap( qMin( rect.height(), maxHSizeOnePix ) ); 00201 00202 KIconEffect *iconEffect = KIconLoader::global()->iconEffect(); 00203 QPixmap disabledRatingPix = iconEffect->apply( ratingPix, KIconEffect::ToGray, 1.0, QColor(), QColor(), false ); 00204 QPixmap hoverPix; 00205 00206 // if we are disabled we become gray and more transparent 00207 if ( !d->isEnabled ) { 00208 ratingPix = disabledRatingPix; 00209 KIconEffect::semiTransparent( disabledRatingPix ); 00210 } 00211 00212 bool half = d->bHalfSteps && rating%2; 00213 int numRatingStars = d->bHalfSteps ? rating/2 : rating; 00214 00215 int numHoverStars = 0; 00216 bool halfHover = false; 00217 if ( hoverRating > 0 && rating != hoverRating && d->isEnabled ) { 00218 numHoverStars = d->bHalfSteps ? hoverRating/2 : hoverRating; 00219 halfHover = d->bHalfSteps && hoverRating%2; 00220 hoverPix = iconEffect->apply( ratingPix, KIconEffect::ToGray, 0.5, QColor(), QColor(), false ); 00221 } 00222 00223 if ( d->alignment & Qt::AlignJustify ) { 00224 int w = rect.width(); 00225 w -= numUsedStars * ratingPix.width(); 00226 usedSpacing = w / ( numUsedStars-1 ); 00227 } 00228 00229 int ratingAreaWidth = ratingPix.width()*numUsedStars + usedSpacing*(numUsedStars-1); 00230 00231 int i = 0; 00232 int x = rect.x(); 00233 if ( d->alignment & Qt::AlignRight ) { 00234 x += ( rect.width() - ratingAreaWidth ); 00235 } 00236 else if ( d->alignment & Qt::AlignHCenter ) { 00237 x += ( rect.width() - ratingAreaWidth )/2; 00238 } 00239 00240 int xInc = ratingPix.width() + usedSpacing; 00241 if ( d->direction == Qt::RightToLeft ) { 00242 x = rect.width() - ratingPix.width() - x; 00243 xInc = -xInc; 00244 } 00245 00246 int y = rect.y(); 00247 if( d->alignment & Qt::AlignVCenter ) { 00248 y += ( rect.height() / 2 - ratingPix.height() / 2 ); 00249 } 00250 else if ( d->alignment & Qt::AlignBottom ) { 00251 y += ( rect.height() - ratingPix.height() ); 00252 } 00253 for(; i < numRatingStars; ++i ) { 00254 painter->drawPixmap( x, y, ratingPix ); 00255 x += xInc; 00256 } 00257 if( half ) { 00258 painter->drawPixmap( x, y, ratingPix.width()/2, ratingPix.height(), 00259 d->direction == Qt::LeftToRight ? ratingPix : ( numHoverStars > 0 ? hoverPix : disabledRatingPix ), 00260 0, 0, ratingPix.width()/2, ratingPix.height() ); 00261 painter->drawPixmap( x + ratingPix.width()/2, y, ratingPix.width()/2, ratingPix.height(), 00262 d->direction == Qt::LeftToRight ? ( numHoverStars > 0 ? hoverPix : disabledRatingPix ) : ratingPix, 00263 ratingPix.width()/2, 0, ratingPix.width()/2, ratingPix.height() ); 00264 x += xInc; 00265 ++i; 00266 } 00267 for(; i < numHoverStars; ++i ) { 00268 painter->drawPixmap( x, y, hoverPix ); 00269 x += xInc; 00270 } 00271 if( halfHover ) { 00272 painter->drawPixmap( x, y, ratingPix.width()/2, ratingPix.height(), 00273 d->direction == Qt::LeftToRight ? hoverPix : disabledRatingPix, 00274 0, 0, ratingPix.width()/2, ratingPix.height() ); 00275 painter->drawPixmap( x + ratingPix.width()/2, y, ratingPix.width()/2, ratingPix.height(), 00276 d->direction == Qt::LeftToRight ? disabledRatingPix : hoverPix, 00277 ratingPix.width()/2, 0, ratingPix.width()/2, ratingPix.height() ); 00278 x += xInc; 00279 ++i; 00280 } 00281 for(; i < numUsedStars; ++i ) { 00282 painter->drawPixmap( x, y, disabledRatingPix ); 00283 x += xInc; 00284 } 00285 } 00286 00287 00288 int KRatingPainter::ratingFromPosition( const QRect& rect, const QPoint& pos ) const 00289 { 00290 int usedSpacing = d->spacing; 00291 int numUsedStars = d->bHalfSteps ? d->maxRating/2 : d->maxRating; 00292 int maxHSizeOnePix = ( rect.width() - (numUsedStars-1)*usedSpacing ) / numUsedStars; 00293 QPixmap ratingPix = d->getPixmap( qMin( rect.height(), maxHSizeOnePix ) ); 00294 00295 int ratingAreaWidth = ratingPix.width()*numUsedStars + usedSpacing*(numUsedStars-1); 00296 00297 QRect usedRect( rect ); 00298 if ( d->alignment & Qt::AlignRight ) { 00299 usedRect.setLeft( rect.right() - ratingAreaWidth ); 00300 } 00301 else if ( d->alignment & Qt::AlignHCenter ) { 00302 int x = ( rect.width() - ratingAreaWidth )/2; 00303 usedRect.setLeft( rect.left() + x ); 00304 usedRect.setRight( rect.right() - x ); 00305 } 00306 else { // d->alignment & Qt::AlignLeft 00307 usedRect.setRight( rect.left() + ratingAreaWidth - 1 ); 00308 } 00309 00310 if ( d->alignment & Qt::AlignBottom ) { 00311 usedRect.setTop( rect.bottom() - ratingPix.height() + 1 ); 00312 } 00313 else if ( d->alignment & Qt::AlignVCenter ) { 00314 int x = ( rect.height() - ratingPix.height() )/2; 00315 usedRect.setTop( rect.top() + x ); 00316 usedRect.setBottom( rect.bottom() - x ); 00317 } 00318 else { // d->alignment & Qt::AlignTop 00319 usedRect.setBottom( rect.top() + ratingPix.height() - 1 ); 00320 } 00321 00322 if ( usedRect.contains( pos ) ) { 00323 int x = 0; 00324 if ( d->direction == Qt::RightToLeft ) { 00325 x = usedRect.right() - pos.x(); 00326 } 00327 else { 00328 x = pos.x() - usedRect.left(); 00329 } 00330 00331 double one = ( double )usedRect.width() / ( double )d->maxRating; 00332 00333 // kDebug() << "rating:" << ( int )( ( double )x/one + 0.5 ); 00334 00335 return ( int )( ( double )x/one + 0.5 ); 00336 } 00337 else { 00338 return -1; 00339 } 00340 } 00341 00342 00343 void KRatingPainter::paintRating( QPainter* painter, const QRect& rect, Qt::Alignment align, int rating, int hoverRating ) 00344 { 00345 KRatingPainter rp; 00346 rp.setAlignment( align ); 00347 rp.setLayoutDirection( painter->layoutDirection() ); 00348 rp.paint( painter, rect, rating, hoverRating ); 00349 } 00350 00351 00352 int KRatingPainter::getRatingFromPosition( const QRect& rect, Qt::Alignment align, Qt::LayoutDirection direction, const QPoint& pos ) 00353 { 00354 KRatingPainter rp; 00355 rp.setAlignment( align ); 00356 rp.setLayoutDirection( direction ); 00357 return rp.ratingFromPosition( rect, pos ); 00358 }
KDE 4.6 API Reference