*/
#include "dolphincategorydrawer.h"
-
+#include "ratingpainter.h"
#include <QPainter>
#include <QFile>
#include <QDir>
paintText = false;
paintIcon = false;
- starRect.setTop(option.rect.top() + (option.rect.height() / 2) - (iconSize / 2));
- starRect.setSize(QSize(iconSize, iconSize));
-
- QPixmap pixmap = KIconLoader::global()->loadIcon("rating", KIconLoader::Small);
- QPixmap smallPixmap = KIconLoader::global()->loadIcon("rating", KIconLoader::NoGroup, iconSize / 2);
- QPixmap disabledPixmap = KIconLoader::global()->loadIcon("rating", KIconLoader::Small);
-
- QImage img = disabledPixmap.toImage();
- Blitz::grayscale(img);
- disabledPixmap = QPixmap::fromImage(img);
-
- int rating = category.toInt();
-
- for (int i = 0; i < rating - (rating % 2); i += 2) {
- painter->drawPixmap(starRect, pixmap);
-
- if (option.direction == Qt::LeftToRight)
- {
- starRect.setLeft(starRect.left() + iconSize + (iconSize / 4) /* separator between stars */);
- starRect.setRight(starRect.right() + iconSize + (iconSize / 4) /* separator between stars */);
- }
- else
- {
- starRect.setLeft(starRect.left() - iconSize - (iconSize / 4) /* separator between stars */);
- starRect.setRight(starRect.right() - iconSize - (iconSize / 4) /* separator between stars */);
- }
- }
-
- if (rating && rating % 2) {
- if (option.direction == Qt::RightToLeft)
- {
- starRect.setLeft(starRect.left() + (iconSize / 2) /* separator between stars */);
- }
-
- starRect.setTop(option.rect.top() + (option.rect.height() / 2) - (iconSize / 4));
- starRect.setSize(QSize(iconSize / 2, iconSize / 2));
- painter->drawPixmap(starRect, smallPixmap);
- starRect.setTop(opt.rect.top() + (option.rect.height() / 2) - (iconSize / 2));
-
- if (option.direction == Qt::LeftToRight)
- {
- starRect.setLeft(starRect.left() + (iconSize / 2) + (iconSize / 4));
- starRect.setRight(starRect.right() + (iconSize / 2) + (iconSize / 4));
- }
- else
- {
- starRect.setLeft(starRect.left() - (iconSize / 2) - (iconSize / 4));
- starRect.setRight(starRect.right() - (iconSize / 2) - (iconSize / 4));
- }
-
- if (option.direction == Qt::RightToLeft)
- {
- starRect.setLeft(starRect.left() - (iconSize / 2));
- starRect.setRight(starRect.right() - (iconSize / 2));
- }
-
- starRect.setSize(QSize(iconSize, iconSize));
- }
-
- for (int i = rating; i < 9; i += 2) {
- painter->drawPixmap(starRect, disabledPixmap);
-
- if (option.direction == Qt::LeftToRight)
- {
- starRect.setLeft(starRect.left() + iconSize + (iconSize / 4));
- starRect.setRight(starRect.right() + iconSize + (iconSize / 4));
- }
- else
- {
- starRect.setLeft(starRect.left() - iconSize - (iconSize / 4));
- starRect.setRight(starRect.right() - iconSize - (iconSize / 4));
- }
- }
-
+ painter->setLayoutDirection( option.direction );
+ QRect ratingRect( option.rect );
+ ratingRect.setTop(option.rect.top() + (option.rect.height() / 2) - (iconSize / 2));
+ ratingRect.setHeight( iconSize );
+ Nepomuk::RatingPainter::drawRating( painter, ratingRect, Qt::AlignLeft, category.toInt() );
break;
}
--- /dev/null
+/*
+ This file is part of the Nepomuk KDE project.
+ Copyright (C) 2007 Sebastian Trueg <trueg@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+#include "ratingpainter.h"
+
+#include <QtGui/QPainter>
+#include <QtGui/QPixmap>
+
+#include <kicon.h>
+#include <kiconeffect.h>
+#include <kdebug.h>
+
+
+class Nepomuk::RatingPainter::Private
+{
+public:
+ Private()
+ : maxRating(10),
+ icon( "rating" ),
+ bHalfSteps(true),
+ alignment(Qt::AlignCenter),
+ direction(Qt::LeftToRight) {
+ }
+
+ int maxRating;
+ KIcon icon;
+ bool bHalfSteps;
+ Qt::Alignment alignment;
+ Qt::LayoutDirection direction;
+ QPixmap customPixmap;
+};
+
+
+Nepomuk::RatingPainter::RatingPainter()
+ : d(new Private())
+{
+}
+
+
+Nepomuk::RatingPainter::~RatingPainter()
+{
+ delete d;
+}
+
+
+int Nepomuk::RatingPainter::maxRating() const
+{
+ return d->maxRating;
+}
+
+
+bool Nepomuk::RatingPainter::halfStepsEnabled() const
+{
+ return d->bHalfSteps;
+}
+
+
+Qt::Alignment Nepomuk::RatingPainter::alignment() const
+{
+ return d->alignment;
+}
+
+
+Qt::LayoutDirection Nepomuk::RatingPainter::direction() const
+{
+ return d->direction;
+}
+
+
+KIcon Nepomuk::RatingPainter::icon() const
+{
+ return d->icon;
+}
+
+
+QPixmap Nepomuk::RatingPainter::customPixmap() const
+{
+ return d->customPixmap;
+}
+
+
+void Nepomuk::RatingPainter::setMaxRating( int max )
+{
+ d->maxRating = max;
+}
+
+
+void Nepomuk::RatingPainter::setHalfStepsEnabled( bool enabled )
+{
+ d->bHalfSteps = enabled;
+}
+
+
+void Nepomuk::RatingPainter::setAlignment( Qt::Alignment align )
+{
+ d->alignment = align;
+}
+
+
+void Nepomuk::RatingPainter::setLayoutDirection( Qt::LayoutDirection direction )
+{
+ d->direction = direction;
+}
+
+
+void Nepomuk::RatingPainter::setIcon( const KIcon& icon )
+{
+ d->icon = icon;
+}
+
+
+void Nepomuk::RatingPainter::setCustomPixmap( const QPixmap& pixmap )
+{
+ d->customPixmap = pixmap;
+}
+
+
+void Nepomuk::RatingPainter::draw( QPainter* painter, const QRect& rect, int rating, int hoverRating )
+{
+ rating = qMin( rating, d->maxRating );
+ hoverRating = qMin( hoverRating, d->maxRating );
+
+ int numUsedStars = d->bHalfSteps ? d->maxRating/2 : d->maxRating;
+
+ if ( hoverRating > 0 && hoverRating < rating ) {
+ int tmp = hoverRating;
+ hoverRating = rating;
+ rating = tmp;
+ }
+
+ // get the rating pixmaps
+ QPixmap ratingPix;
+ if ( !d->customPixmap.isNull() ) {
+ ratingPix = d->customPixmap;
+ }
+ else {
+ KIcon ratingIcon( "rating" );
+ int iconSize = qMin( rect.height(), rect.width() / numUsedStars );
+ ratingPix = ratingIcon.pixmap( iconSize );
+ }
+
+ QPixmap disabledRatingPix = KIconEffect().apply( ratingPix, KIconEffect::ToGray, 1.0, QColor(), false );
+ QPixmap hoverPix;
+
+ bool half = d->bHalfSteps && rating%2;
+ int numRatingStars = d->bHalfSteps ? rating/2 : rating;
+
+ int numHoverStars = 0;
+ bool halfHover = false;
+ if ( hoverRating > 0 && rating != hoverRating ) {
+ numHoverStars = d->bHalfSteps ? hoverRating/2 : hoverRating;
+ halfHover = d->bHalfSteps && hoverRating%2;
+ hoverPix = KIconEffect().apply( ratingPix, KIconEffect::ToGray, 0.5, QColor(), false );
+ }
+
+ int usedSpacing = 0;
+ if ( d->alignment & Qt::AlignJustify ) {
+ int w = rect.width();
+ w -= numUsedStars * ratingPix.width();
+ usedSpacing = w / ( numUsedStars-1 );
+ }
+
+ int i = 0;
+ int x = rect.x();
+ if ( d->alignment & Qt::AlignRight ) {
+ x += ( rect.width() - ratingPix.width()*numUsedStars );
+ }
+ else if ( d->alignment & Qt::AlignCenter ) {
+ x += ( rect.width() - ratingPix.width()*numUsedStars )/2;
+ }
+
+ int xInc = ratingPix.width() + usedSpacing;
+ if ( d->direction == Qt::RightToLeft ) {
+ x = rect.width() - ratingPix.width() - x;
+ xInc = -xInc;
+ }
+
+ int y = rect.y();
+ if( d->alignment & Qt::AlignVCenter ) {
+ y += ( rect.height() / 2 - ratingPix.height() / 2 );
+ }
+ else if ( d->alignment & Qt::AlignBottom ) {
+ y += ( rect.height() - ratingPix.height() );
+ }
+ for(; i < numRatingStars; ++i ) {
+ painter->drawPixmap( x, y, ratingPix );
+ x += xInc;
+ }
+ if( half ) {
+ painter->drawPixmap( x, y, ratingPix.width()/2, ratingPix.height(),
+ d->direction == Qt::LeftToRight ? ratingPix : ( numHoverStars > 0 ? hoverPix : disabledRatingPix ),
+ 0, 0, ratingPix.width()/2, ratingPix.height() );
+ painter->drawPixmap( x + ratingPix.width()/2, y, ratingPix.width()/2, ratingPix.height(),
+ d->direction == Qt::LeftToRight ? ( numHoverStars > 0 ? hoverPix : disabledRatingPix ) : ratingPix,
+ ratingPix.width()/2, 0, ratingPix.width()/2, ratingPix.height() );
+ x += xInc;
+ ++i;
+ }
+ for(; i < numHoverStars; ++i ) {
+ painter->drawPixmap( x, y, hoverPix );
+ x += xInc;
+ }
+ if( halfHover ) {
+ painter->drawPixmap( x, y, ratingPix.width()/2, ratingPix.height(),
+ d->direction == Qt::LeftToRight ? hoverPix : disabledRatingPix,
+ 0, 0, ratingPix.width()/2, ratingPix.height() );
+ painter->drawPixmap( x + ratingPix.width()/2, y, ratingPix.width()/2, ratingPix.height(),
+ d->direction == Qt::LeftToRight ? disabledRatingPix : hoverPix,
+ ratingPix.width()/2, 0, ratingPix.width()/2, ratingPix.height() );
+ x += xInc;
+ ++i;
+ }
+ for(; i < numUsedStars; ++i ) {
+ painter->drawPixmap( x, y, disabledRatingPix );
+ x += xInc;
+ }
+}
+
+
+int Nepomuk::RatingPainter::fromPosition( const QRect& rect, const QPoint& pos )
+{
+ int numUsedStars = d->bHalfSteps ? d->maxRating/2 : d->maxRating;
+ QPixmap ratingPix;
+ if ( !d->customPixmap.isNull() ) {
+ ratingPix = d->customPixmap;
+ }
+ else {
+ KIcon ratingIcon( "rating" );
+ int iconSize = qMin( rect.height(), rect.width() / numUsedStars );
+ ratingPix = ratingIcon.pixmap( iconSize );
+ }
+
+ QRect usedRect( rect );
+ if ( d->alignment & Qt::AlignRight ) {
+ usedRect.setLeft( rect.right() - numUsedStars * ratingPix.width() );
+ }
+ else if ( d->alignment & Qt::AlignHCenter ) {
+ int x = ( rect.width() - numUsedStars * ratingPix.width() )/2;
+ usedRect.setLeft( rect.left() + x );
+ usedRect.setRight( rect.right() - x );
+ }
+ else { // d->alignment & Qt::AlignLeft
+ usedRect.setRight( rect.left() + numUsedStars * ratingPix.width() - 1 );
+ }
+
+ if ( d->alignment & Qt::AlignBottom ) {
+ usedRect.setTop( rect.bottom() - ratingPix.height() + 1 );
+ }
+ else if ( d->alignment & Qt::AlignVCenter ) {
+ int x = ( rect.height() - ratingPix.height() )/2;
+ usedRect.setTop( rect.top() + x );
+ usedRect.setBottom( rect.bottom() - x );
+ }
+ else { // d->alignment & Qt::AlignTop
+ usedRect.setBottom( rect.top() + ratingPix.height() - 1 );
+ }
+
+ if ( usedRect.contains( pos ) ) {
+ int x = 0;
+ if ( d->direction == Qt::RightToLeft ) {
+ x = usedRect.right() - pos.x();
+ }
+ else {
+ x = pos.x() - usedRect.left();
+ }
+
+ double one = ( double )usedRect.width() / ( double )d->maxRating;
+
+ kDebug() << "rating:" << ( int )( ( double )x/one + 0.5 );
+
+ return ( int )( ( double )x/one + 0.5 );
+ }
+ else {
+ return -1;
+ }
+}
+
+
+void Nepomuk::RatingPainter::drawRating( QPainter* painter, const QRect& rect, Qt::Alignment align, int rating, int hoverRating )
+{
+ RatingPainter rp;
+ rp.setAlignment( align );
+ rp.setLayoutDirection( painter->layoutDirection() );
+ rp.draw( painter, rect, rating, hoverRating );
+}
+
+
+int Nepomuk::RatingPainter::getRatingFromPosition( const QRect& rect, Qt::Alignment align, Qt::LayoutDirection direction, const QPoint& pos )
+{
+ RatingPainter rp;
+ rp.setAlignment( align );
+ rp.setLayoutDirection( direction );
+ return rp.fromPosition( rect, pos );
+}
--- /dev/null
+/*
+ This file is part of the Nepomuk KDE project.
+ Copyright (C) 2007 Sebastian Trueg <trueg@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _NEPOMUK_RATING_PAINTER_H_
+#define _NEPOMUK_RATING_PAINTER_H_
+
+class QPainter;
+
+#include <QtCore/QRect>
+#include <QtCore/QPoint>
+
+#include <kicon.h>
+
+#include <nepomuk/nepomuk_export.h>
+
+
+namespace Nepomuk {
+ /**
+ * Utility class that draws a row of stars for a rating value.
+ */
+ class NEPOMUK_EXPORT RatingPainter
+ {
+ public:
+ /**
+ * Create a new RatingPainter.
+ * Normally the static methods should be sufficient.
+ */
+ RatingPainter();
+ ~RatingPainter();
+
+ int maxRating() const;
+ bool halfStepsEnabled() const;
+ Qt::Alignment alignment() const;
+ Qt::LayoutDirection direction() const;
+ KIcon icon() const;
+ QPixmap customPixmap() const;
+
+ /**
+ * The maximum rating. Defaults to 10.
+ */
+ void setMaxRating( int max );
+
+ /**
+ * If half steps are enabled (the default) then
+ * one rating step corresponds to half a star.
+ */
+ void setHalfStepsEnabled( bool enabled );
+
+ /**
+ * The alignment of the stars in the drawing rect.
+ * All alignment flags are supported.
+ */
+ void setAlignment( Qt::Alignment align );
+
+ /**
+ * LTR or RTL
+ */
+ void setLayoutDirection( Qt::LayoutDirection direction );
+
+ /**
+ * Set a custom icon. Defaults to "rating".
+ */
+ void setIcon( const KIcon& icon );
+
+ /**
+ * Set a custom pixmap.
+ */
+ void setCustomPixmap( const QPixmap& pixmap );
+
+ /**
+ * Draw the rating into the configured rect.
+ */
+ void draw( QPainter* painter, const QRect& rect, int rating, int hoverRating = -1 );
+
+ /**
+ * Calculate the rating value from mouse position pos.
+ *
+ * \return The rating corresponding to pos or -1 if pos is
+ * outside of the configured rect.
+ */
+ int fromPosition( const QRect& rect, const QPoint& pos );
+
+ /**
+ * Convenience method that draws a rating into the given rect.
+ *
+ * LayoutDirection is read from QPainter.
+ *
+ * \param align can be aligned vertically and horizontally. Using Qt::AlignJustify will insert spacing
+ * between the stars.
+ */
+ static void drawRating( QPainter* p, const QRect& rect, Qt::Alignment align, int rating, int hoverRating = -1 );
+
+ /**
+ * Get the rating that would be selected if the user clicked position pos
+ * within rect if the rating has been drawn with drawRating() using the same
+ * rect and align values.
+ *
+ * \return The new rating or -1 if pos is outside of the rating area.
+ */
+ static int getRatingFromPosition( const QRect& rect, Qt::Alignment align, Qt::LayoutDirection direction, const QPoint& pos );
+
+ private:
+ class Private;
+ Private* const d;
+ };
+}
+
+#endif