[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-core-devel
Subject: Making the rating painter class public
From: Sebastian =?iso-8859-1?q?Tr=FCg?= <strueg () mandriva ! com>
Date: 2008-02-25 13:08:58
Message-ID: 200802251408.58392.strueg () mandriva ! com
[Download RAW message or body]
The Nepomuk::RatingPainter class is used in the Nepomuk lib to draw ratings,
in Dolphin to draw rating categorizations, and in nepomuk playground to draw
ratings for search results. Thus, having 3 places where it is used, I propose
to make it public API for 4.1.
Please see the attached files for the class. Any objections?
Cheers,
Sebastian
["ratingpainter.h" (text/x-c++hdr)]
/*
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 {
/**
* \brief Utility class that draws a row of stars for a rating value.
*
* The RatingPainter also allows to determine a rating value from
* a position in the draw area. it supports all different alignments
* and custom icons.
*
* \author Sebastian Trueg <trueg@kde.org>
*/
class NEPOMUK_EXPORT RatingPainter
{
public:
/**
* Create a new RatingPainter.
* For most cases the static methods drawRating and getRatingFromPosition
* should be sufficient.
*/
RatingPainter();
/**
* Destructor
*/
~RatingPainter();
/**
* The maximum rating, i.e. how many stars are drawn
* in total.
*
* \sa setMaxRating
*/
int maxRating() const;
/**
* If half steps are enabled one star equals to 2 rating
* points and uneven rating values result in half-stars being
* drawn.
*
* \sa setHalfStepsEnabled
*/
bool halfStepsEnabled() const;
/**
* The alignment of the stars.
*
* \sa setAlignment
*/
Qt::Alignment alignment() const;
/**
* The layout direction. If RTL the stars
* representing the rating value will be drawn from the
* right.
*
* \sa setLayoutDirection
*/
Qt::LayoutDirection direction() const;
/**
* The icon used to draw a star. In case a custom pixmap has been set
* this value is ignored.
*
* \sa setIcon, setCustomPixmap
*/
KIcon icon() const;
/**
* The custom pixmap set to draw a star. If no custom
* pixmap has been set, an invalid pixmap is returned.
*
* \sa setCustomPixmap
*/
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
["ratingpainter.cpp" (text/x-c++src)]
/*
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 );
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic