1
/* ============================================================
3
* This file is a part of digiKam project
4
* http://www.digikam.org
7
* Description : a widget to draw stars rating
9
* Copyright (C) 2005 by Owen Hirst <n8rider@sbcglobal.net>
10
* Copyright (C) 2006-2011 by Gilles Caulier <caulier dot gilles at gmail dot com>
12
* This program is free software; you can redistribute it
13
* and/or modify it under the terms of the GNU General
14
* Public License as published by the Free Software Foundation;
15
* either version 2, or (at your option)
18
* This program is distributed in the hope that it will be useful,
19
* but WITHOUT ANY WARRANTY; without even the implied warranty of
20
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
* GNU General Public License for more details.
23
* ============================================================ */
25
#include "ratingwidget.moc"
43
#include <kglobalsettings.h>
44
#include <ksqueezedtextlabel.h>
49
#include <kapplication.h>
50
#include <kxmlguiwindow.h>
51
#include <kactioncollection.h>
56
#include "thememanager.h"
61
class RatingWidget::RatingWidgetPriv
76
// Pre-computed star polygon for a 15x15 pixmap.
77
starPolygon << QPoint(0, 6);
78
starPolygon << QPoint(5, 5);
79
starPolygon << QPoint(7, 0);
80
starPolygon << QPoint(9, 5);
81
starPolygon << QPoint(14, 6);
82
starPolygon << QPoint(10, 9);
83
starPolygon << QPoint(11, 14);
84
starPolygon << QPoint(7, 11);
85
starPolygon << QPoint(3, 14);
86
starPolygon << QPoint(4, 9);
98
QTimeLine* fadingTimeLine;
100
QPolygon starPolygon;
102
QPixmap selPixmap; // Selected star.
103
QPixmap regPixmap; // Regular star.
104
QPixmap disPixmap; // Disable star.
107
RatingWidget::RatingWidget(QWidget* parent)
108
: QWidget(parent), d(new RatingWidgetPriv)
112
connect(ThemeManager::instance(), SIGNAL(signalThemeChanged()),
113
this, SLOT(slotThemeChanged()));
116
RatingWidget::~RatingWidget()
121
void RatingWidget::setupTimeLine()
123
delete d->fadingTimeLine;
124
d->fadingTimeLine = new QTimeLine(d->duration, this);
125
d->fadingTimeLine->setFrameRange(0, 255);
127
connect(d->fadingTimeLine, SIGNAL(frameChanged(int)),
128
this, SLOT(setFadingValue(int)));
130
d->fadingTimeLine->start();
133
int RatingWidget::regPixmapWidth() const
135
return d->regPixmap.width();
138
void RatingWidget::setRating(int val)
140
if ((val < RatingMin || val > RatingMax) && val != NoRating)
149
emit signalRatingChanged(d->rating);
152
emit signalRatingModified(d->rating);
156
int RatingWidget::rating() const
161
void RatingWidget::setTracking(bool tracking)
163
d->tracking = tracking;
166
bool RatingWidget::hasTracking() const
171
void RatingWidget::setFading(bool fading)
176
bool RatingWidget::hasFading() const
181
void RatingWidget::setFadingValue(int value)
183
d->fadingValue = value;
185
if (d->fadingValue >= 255 && d->fadingTimeLine)
187
d->fadingTimeLine->stop();
193
void RatingWidget::setVisible(bool visible)
195
QWidget::setVisible(visible);
207
int RatingWidget::maximumVisibleWidth() const
209
return RatingMax * (d->disPixmap.width()+1);
212
void RatingWidget::startFading()
227
void RatingWidget::stopFading()
234
if (d->fadingTimeLine)
236
d->fadingTimeLine->stop();
239
d->isHovered = false;
244
void RatingWidget::setVisibleImmediately()
249
QPixmap RatingWidget::starPixmapDisabled() const
254
QPixmap RatingWidget::starPixmapFilled() const
259
QPixmap RatingWidget::starPixmap() const
264
void RatingWidget::regeneratePixmaps()
269
void RatingWidget::mousePressEvent(QMouseEvent* e)
271
if (e->button() != Qt::LeftButton)
276
if (hasFading() && d->fadingValue < 255)
281
int pos = (e->x() - d->offset) / d->regPixmap.width() +1;
283
if (d->rating == pos)
292
if (d->rating > RatingMax)
294
d->rating = RatingMax;
297
if (d->rating < RatingMin)
299
d->rating = RatingMin;
304
emit signalRatingChanged(d->rating);
307
emit signalRatingModified(d->rating);
311
void RatingWidget::mouseMoveEvent(QMouseEvent* e)
313
if (!(e->buttons() & Qt::LeftButton))
318
if (hasFading() && d->fadingValue < 255)
323
int pos = (e->x() - d->offset) / d->regPixmap.width() +1;
325
if (d->rating != pos)
327
if (pos > RatingMax) // NOTE: B.K.O. # 151357
341
emit signalRatingChanged(d->rating);
344
emit signalRatingModified(d->rating);
349
void RatingWidget::mouseReleaseEvent(QMouseEvent* e)
351
if (e->button() != Qt::LeftButton)
356
if (hasFading() && d->fadingValue < 255)
361
emit signalRatingChanged(d->rating);
364
void RatingWidget::slotThemeChanged()
366
d->regPixmap = QPixmap(15, 15);
367
d->regPixmap.fill(Qt::transparent);
368
d->selPixmap = QPixmap(15, 15);
369
d->selPixmap.fill(Qt::transparent);
370
d->disPixmap = QPixmap(15, 15);
371
d->disPixmap.fill(Qt::transparent);
373
QPainter p1(&d->regPixmap);
374
p1.setRenderHint(QPainter::Antialiasing, true);
375
p1.setBrush(palette().color(QPalette::Active, backgroundRole()));
376
p1.setPen(palette().color(QPalette::Active, foregroundRole()));
377
p1.drawPolygon(d->starPolygon, Qt::WindingFill);
380
QPainter p2(&d->selPixmap);
381
p2.setRenderHint(QPainter::Antialiasing, true);
382
p2.setBrush(kapp->palette().color(QPalette::Link));
383
p2.setPen(palette().color(QPalette::Active, foregroundRole()));
384
p2.drawPolygon(d->starPolygon, Qt::WindingFill);
387
QPainter p3(&d->disPixmap);
388
p3.setRenderHint(QPainter::Antialiasing, true);
389
p3.setBrush(palette().color(QPalette::Disabled, backgroundRole()));
390
p3.setPen(palette().color(QPalette::Disabled, foregroundRole()));
391
p3.drawPolygon(d->starPolygon, Qt::WindingFill);
394
setMinimumSize(QSize((d->regPixmap.width()+1)*RatingMax, d->regPixmap.height()));
398
void RatingWidget::paintEvent(QPaintEvent*)
402
d->offset = (width() - RatingMax * (d->disPixmap.width()+1)) / 2;
404
// Widget is disable : drawing grayed frame.
409
for (int i = 0; i < RatingMax; ++i)
411
p.drawPixmap(x, 0, d->disPixmap);
412
x += d->disPixmap.width()+1;
418
int rate = d->rating != NoRating ? d->rating : 0;
419
QPixmap sel = d->selPixmap;
422
for (int i = 0; i < rate; ++i)
424
p.drawPixmap(x, 0, sel);
428
QPixmap reg = d->regPixmap;
431
for (int i = rate; i < RatingMax; ++i)
433
p.drawPixmap(x, 0, reg);
441
void RatingWidget::applyFading(QPixmap& pix)
443
if (hasFading() && d->fadingValue < 255)
445
QPixmap alphaMask(pix.width(), pix.height());
446
const QColor color(d->fadingValue, d->fadingValue, d->fadingValue);
447
alphaMask.fill(color);
448
pix.setAlphaChannel(alphaMask);
452
// -------------------------------------------------------------------------------
454
class RatingBox::RatingBoxPriv
465
KSqueezedTextLabel* shortcut;
467
RatingWidget* ratingWidget;
470
RatingBox::RatingBox(QWidget* parent)
471
: KVBox(parent), d(new RatingBoxPriv)
473
setAttribute(Qt::WA_DeleteOnClose);
474
setFocusPolicy(Qt::NoFocus);
476
d->ratingWidget = new RatingWidget(this);
477
d->ratingWidget->setTracking(false);
479
d->shortcut = new KSqueezedTextLabel(this);
480
QFont fnt = d->shortcut->font();
482
d->shortcut->setFont(fnt);
483
d->shortcut->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
484
d->shortcut->setWordWrap(false);
489
// -------------------------------------------------------------
491
connect(d->ratingWidget, SIGNAL(signalRatingModified(int)),
492
this, SLOT(slotUpdateDescription(int)));
494
connect(d->ratingWidget, SIGNAL(signalRatingChanged(int)),
495
this, SIGNAL(signalRatingChanged(int)));
498
RatingBox::~RatingBox()
503
void RatingBox::slotUpdateDescription(int rating)
505
KXmlGuiWindow* app = dynamic_cast<KXmlGuiWindow*>(kapp->activeWindow());
508
QAction* ac = app->actionCollection()->action(QString("rateshortcut-%1").arg(rating));
510
d->shortcut->setText(ac->shortcut().toString());
514
// -------------------------------------------------------------------------------
516
RatingMenuAction::RatingMenuAction(QMenu* parent)
517
: KActionMenu(parent)
519
setText(i18n("Rating"));
520
QWidgetAction* wa = new QWidgetAction(this);
521
RatingBox* rb = new RatingBox(parent);
522
wa->setDefaultWidget(rb);
525
connect(rb, SIGNAL(signalRatingChanged(int)),
526
this, SIGNAL(signalRatingChanged(int)));
528
connect(rb, SIGNAL(signalRatingChanged(int)),
529
parent, SLOT(close()));
532
RatingMenuAction::~RatingMenuAction()
536
} // namespace Digikam