Updated Plasma IconWidget to use new animation API + QPropertyAnimation

svn path=/trunk/KDE/kdelibs/; revision=1085753
This commit is contained in:
Bruno de Oliveira Abinader 2010-02-05 21:46:51 +00:00
parent ed0f495b4e
commit bf225098a9
3 changed files with 134 additions and 63 deletions

View File

@ -43,10 +43,11 @@
#include <kdebug.h> #include <kdebug.h>
#include <kcolorscheme.h> #include <kcolorscheme.h>
#include <plasma/animator.h>
#include <plasma/animations/animation.h>
#include <plasma/paintutils.h> #include <plasma/paintutils.h>
#include <plasma/theme.h> #include <plasma/theme.h>
#include "animator.h"
#include "svg.h" #include "svg.h"
/* /*
@ -59,19 +60,55 @@ TODO:
namespace Plasma namespace Plasma
{ {
IconHoverAnimation::IconHoverAnimation(QObject *parent)
: QObject(parent), m_value(0), m_fadeIn(false)
{
}
qreal IconHoverAnimation::value() const
{
return m_value;
}
bool IconHoverAnimation::fadeIn() const
{
return m_fadeIn;
}
QPropertyAnimation *IconHoverAnimation::animation() const
{
return m_animation.data();
}
void IconHoverAnimation::setValue(qreal value)
{
m_value = value;
QGraphicsItem *item = qobject_cast<QGraphicsItem*>(parent());
item->update();
}
void IconHoverAnimation::setFadeIn(bool fadeIn)
{
m_fadeIn = fadeIn;
}
void IconHoverAnimation::setAnimation(QPropertyAnimation *animation)
{
m_animation = animation;
}
IconWidgetPrivate::IconWidgetPrivate(IconWidget *i) IconWidgetPrivate::IconWidgetPrivate(IconWidget *i)
: ActionWidgetInterface<IconWidget>(i), : ActionWidgetInterface<IconWidget>(i),
q(i), q(i),
iconSvg(0), iconSvg(0),
hoverAnimId(-1), hoverAnimation(new IconHoverAnimation(q)),
hoverAlpha(20 / 255),
iconSize(48, 48), iconSize(48, 48),
states(IconWidgetPrivate::NoState), states(IconWidgetPrivate::NoState),
orientation(Qt::Vertical), orientation(Qt::Vertical),
numDisplayLines(2), numDisplayLines(2),
activeMargins(0), activeMargins(0),
iconSvgElementChanged(false), iconSvgElementChanged(false),
fadeIn(false),
invertLayout(false), invertLayout(false),
drawBg(false), drawBg(false),
textBgCustomized(false), textBgCustomized(false),
@ -82,6 +119,7 @@ IconWidgetPrivate::IconWidgetPrivate(IconWidget *i)
IconWidgetPrivate::~IconWidgetPrivate() IconWidgetPrivate::~IconWidgetPrivate()
{ {
qDeleteAll(cornerActions); qDeleteAll(cornerActions);
delete hoverAnimation;
} }
void IconWidgetPrivate::readColors() void IconWidgetPrivate::readColors()
@ -133,34 +171,43 @@ IconAction::IconAction(IconWidget *icon, QAction *action)
m_hovered(false), m_hovered(false),
m_pressed(false), m_pressed(false),
m_selected(false), m_selected(false),
m_visible(false), m_visible(false)
m_animationId(-1)
{ {
} }
void IconAction::show() void IconAction::show()
{ {
if (m_animationId) { Animation *animation = m_animation.data();
Animator::self()->stopElementAnimation(m_animationId); if (!animation) {
animation = Plasma::Animator::create(Plasma::Animator::PixmapTransitionAnimation);
animation->setTargetWidget(m_icon);
animation->setProperty("targetPixmap", m_pixmap);
} else if (animation->state() == QAbstractAnimation::Running) {
animation->pause();
} }
rebuildPixmap(); rebuildPixmap();
m_animationId = Animator::self()->animateElement(m_icon, Animator::AppearAnimation); animation->setDirection(QAbstractAnimation::Forward);
Animator::self()->setInitialPixmap(m_animationId, m_pixmap); animation->start(QAbstractAnimation::DeleteWhenStopped);
m_visible = true; m_visible = true;
} }
void IconAction::hide() void IconAction::hide()
{ {
if (m_animationId) { Animation *animation = m_animation.data();
Animator::self()->stopElementAnimation(m_animationId); if (!animation) {
animation = Plasma::Animator::create(Plasma::Animator::ZoomAnimation);
animation->setTargetWidget(m_icon);
animation->setProperty("targetPixmap", m_pixmap);
} else if (animation->state() == QAbstractAnimation::Running) {
animation->pause();
} }
rebuildPixmap(); rebuildPixmap();
m_animationId = Animator::self()->animateElement(m_icon, Animator::DisappearAnimation); animation->setDirection(QAbstractAnimation::Backward);
Animator::self()->setInitialPixmap(m_animationId, m_pixmap); animation->start(QAbstractAnimation::DeleteWhenStopped);
m_visible = false; m_visible = false;
} }
@ -169,6 +216,11 @@ bool IconAction::isVisible() const
return m_visible; return m_visible;
} }
bool IconAction::isAnimating() const
{
return (m_animation.data() && m_animation.data()->state() == QAbstractAnimation::Running);
}
bool IconAction::isPressed() const bool IconAction::isPressed() const
{ {
return m_pressed; return m_pressed;
@ -281,11 +333,6 @@ bool IconAction::event(QEvent::Type type, const QPointF &pos)
return false; return false;
} }
int IconAction::animationId() const
{
return m_animationId;
}
QAction *IconAction::action() const QAction *IconAction::action() const
{ {
return m_action; return m_action;
@ -302,12 +349,12 @@ void IconAction::paint(QPainter *painter) const
return; return;
} }
QPixmap animPixmap = Animator::self()->currentPixmap(m_animationId); Animation *animation = m_animation.data();
if (m_visible && animation->property("currentPixmap").isNull()) {
if (m_visible && animPixmap.isNull()) {
painter->drawPixmap(m_rect.toRect(), m_pixmap); painter->drawPixmap(m_rect.toRect(), m_pixmap);
} else { } else {
painter->drawPixmap(m_rect.toRect(), animPixmap); painter->drawPixmap(m_rect.toRect(),
animation->property("currentPixmap").value<QPixmap>());
} }
} }
@ -618,37 +665,32 @@ void IconWidgetPrivate::hoverEffect(bool show)
states |= IconWidgetPrivate::HoverState; states |= IconWidgetPrivate::HoverState;
} }
fadeIn = show; hoverAnimation->setFadeIn(show);
const int FadeInDuration = 150;
if (hoverAnimId != -1) { QPropertyAnimation *animation = hoverAnimation->animation();
Animator::self()->stopCustomAnimation(hoverAnimId); if (!animation) {
animation = new QPropertyAnimation(hoverAnimation, "value");
animation->setProperty("duration", 150);
animation->setProperty("easingCurve", QEasingCurve::OutQuad);
animation->setProperty("startValue", 0.0);
animation->setProperty("endValue", 1.0);
hoverAnimation->setAnimation(animation);
q->connect(animation, SIGNAL(finished()), q, SLOT(hoverAnimationFinished()));
} else if (animation->state() == QAbstractAnimation::Running) {
animation->pause();
} }
hoverAnimId = Animator::self()->customAnimation( animation->setProperty("direction", show ?
40 / (1000 / FadeInDuration), FadeInDuration, QAbstractAnimation::Forward : QAbstractAnimation::Backward);
Animator::EaseOutCurve, q, "hoverAnimationUpdate"); animation->start(show ?
QAbstractAnimation::KeepWhenStopped : QAbstractAnimation::DeleteWhenStopped);
} }
void IconWidgetPrivate::hoverAnimationUpdate(qreal progress) void IconWidgetPrivate::hoverAnimationFinished()
{ {
if (fadeIn) { if (!hoverAnimation->fadeIn()) {
hoverAlpha = progress; states &= ~IconWidgetPrivate::HoverState;
} else {
// If we mouse leaves before the fade in is done, fade out from where we were,
// not from fully faded in
hoverAlpha = qMin(1 - progress, hoverAlpha);
} }
if (qFuzzyCompare(qreal(1.0), progress)) {
hoverAnimId = -1;
if (!fadeIn) {
states &= ~IconWidgetPrivate::HoverState;
}
}
q->update();
} }
void IconWidgetPrivate::drawBackground(QPainter *painter, IconWidgetState state) void IconWidgetPrivate::drawBackground(QPainter *painter, IconWidgetState state)
@ -663,15 +705,15 @@ void IconWidgetPrivate::drawBackground(QPainter *painter, IconWidgetState state)
background->setElementPrefix("hover"); background->setElementPrefix("hover");
} }
if (qFuzzyCompare(hoverAlpha, 1)) { if (qFuzzyCompare(hoverAnimation->value(), 1)) {
background->resizeFrame(currentSize); background->resizeFrame(currentSize);
background->paintFrame(painter); background->paintFrame(painter);
} else if (!qFuzzyCompare(hoverAlpha+1, 1)) { } else if (!qFuzzyCompare(hoverAnimation->value()+1, 1)) {
background->resizeFrame(currentSize); background->resizeFrame(currentSize);
QPixmap frame = background->framePixmap(); QPixmap frame = background->framePixmap();
QPainter bufferPainter(&frame); QPainter bufferPainter(&frame);
bufferPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn); bufferPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
bufferPainter.fillRect(frame.rect(), QColor(0,0,0, 255*hoverAlpha)); bufferPainter.fillRect(frame.rect(), QColor(0,0,0, 255*hoverAnimation->value()));
bufferPainter.end(); bufferPainter.end();
painter->drawPixmap(QPoint(0,0), frame); painter->drawPixmap(QPoint(0,0), frame);
} }
@ -712,13 +754,13 @@ QPixmap IconWidgetPrivate::decoration(const QStyleOptionGraphicsItem *option, bo
// We're assuming that the icon group is desktop/filemanager, since this // We're assuming that the icon group is desktop/filemanager, since this
// is KFileItemDelegate. // is KFileItemDelegate.
if (effect->hasEffect(KIconLoader::Desktop, KIconLoader::ActiveState)) { if (effect->hasEffect(KIconLoader::Desktop, KIconLoader::ActiveState)) {
if (qFuzzyCompare(qreal(1.0), hoverAlpha)) { if (qFuzzyCompare(qreal(1.0), hoverAnimation->value())) {
result = effect->apply(result, KIconLoader::Desktop, KIconLoader::ActiveState); result = effect->apply(result, KIconLoader::Desktop, KIconLoader::ActiveState);
} else { } else {
result = PaintUtils::transition( result = PaintUtils::transition(
result, result,
effect->apply(result, KIconLoader::Desktop, effect->apply(result, KIconLoader::Desktop,
KIconLoader::ActiveState), hoverAlpha); KIconLoader::ActiveState), hoverAnimation->value());
} }
} }
} }
@ -1022,7 +1064,7 @@ void IconWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option
// Draw corner actions // Draw corner actions
foreach (const IconAction *action, d->cornerActions) { foreach (const IconAction *action, d->cornerActions) {
if (action->animationId()) { if (action->isAnimating()) {
action->paint(painter); action->paint(painter);
} }
} }
@ -1036,11 +1078,11 @@ void IconWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option
if (d->textBgColor != QColor() && d->textBgColor.alpha() > 0 && if (d->textBgColor != QColor() && d->textBgColor.alpha() > 0 &&
!(d->text.isEmpty() && d->infoText.isEmpty()) && !(d->text.isEmpty() && d->infoText.isEmpty()) &&
!textBoundingRect.isEmpty() && !textBoundingRect.isEmpty() &&
!qFuzzyCompare(d->hoverAlpha, (qreal)1.0)) { !qFuzzyCompare(d->hoverAnimation->value(), (qreal)1.0)) {
QRectF rect = textBoundingRect.adjusted(-2, -2, 4, 4).toAlignedRect(); QRectF rect = textBoundingRect.adjusted(-2, -2, 4, 4).toAlignedRect();
painter->setPen(Qt::transparent); painter->setPen(Qt::transparent);
QColor color = d->textBgColor; QColor color = d->textBgColor;
color.setAlpha(60 * (1.0 - d->hoverAlpha)); color.setAlpha(60 * (1.0 - d->hoverAnimation->value()));
QLinearGradient gradient(rect.topLeft(), rect.bottomLeft()); QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
gradient.setColorAt(0, color.lighter(120)); gradient.setColorAt(0, color.lighter(120));
gradient.setColorAt(1, color.darker(120)); gradient.setColorAt(1, color.darker(120));

View File

@ -24,6 +24,7 @@
#define PLASMA_ICONWIDGET_H #define PLASMA_ICONWIDGET_H
#include <QtCore/QObject> #include <QtCore/QObject>
#include <QtCore/QWeakPointer>
#include <QtGui/QGraphicsTextItem> #include <QtGui/QGraphicsTextItem>
#include <QtGui/QIcon> #include <QtGui/QIcon>
#include <QtGui/QGraphicsWidget> #include <QtGui/QGraphicsWidget>
@ -33,6 +34,7 @@
#include <plasma/plasma_export.h> #include <plasma/plasma_export.h>
class QAction; class QAction;
class QPropertyAnimation;
/** /**
* @class IconWidget plasma/widgets/iconwidget.h <Plasma/Widgets/IconWidget> * @class IconWidget plasma/widgets/iconwidget.h <Plasma/Widgets/IconWidget>
@ -51,6 +53,31 @@ namespace Plasma
class IconWidgetPrivate; class IconWidgetPrivate;
class IconHoverAnimation : public QObject
{
Q_OBJECT
Q_PROPERTY(qreal value READ value WRITE setValue)
public:
IconHoverAnimation(QObject *parent = 0);
qreal value() const;
bool fadeIn() const;
void setFadeIn(bool fadeIn);
QPropertyAnimation *animation() const;
void setAnimation(QPropertyAnimation *animation);
protected slots:
void setValue(qreal value);
private:
qreal m_value;
bool m_fadeIn;
QWeakPointer<QPropertyAnimation> m_animation;
};
class PLASMA_EXPORT IconWidget : public QGraphicsWidget class PLASMA_EXPORT IconWidget : public QGraphicsWidget
{ {
Q_OBJECT Q_OBJECT
@ -319,7 +346,7 @@ private:
Q_PRIVATE_SLOT(d, void clearAction()) Q_PRIVATE_SLOT(d, void clearAction())
Q_PRIVATE_SLOT(d, void svgChanged()) Q_PRIVATE_SLOT(d, void svgChanged())
Q_PRIVATE_SLOT(d, void actionDestroyed(QObject *obj)) Q_PRIVATE_SLOT(d, void actionDestroyed(QObject *obj))
Q_PRIVATE_SLOT(d, void hoverAnimationUpdate(qreal progress)) Q_PRIVATE_SLOT(d, void hoverAnimationFinished())
Q_PRIVATE_SLOT(d, void colorConfigChanged()) Q_PRIVATE_SLOT(d, void colorConfigChanged())
Q_PRIVATE_SLOT(d, void iconConfigChanged()) Q_PRIVATE_SLOT(d, void iconConfigChanged())

View File

@ -23,6 +23,7 @@
#define PLASMA_ICONWIDGET_P_H #define PLASMA_ICONWIDGET_P_H
#include <QtCore/QEvent> #include <QtCore/QEvent>
#include <QtCore/QWeakPointer>
#include <QtGui/QApplication> #include <QtGui/QApplication>
#include <QtGui/QIcon> #include <QtGui/QIcon>
#include <QtGui/QStyleOptionGraphicsItem> #include <QtGui/QStyleOptionGraphicsItem>
@ -35,16 +36,19 @@
#include <plasma/svg.h> #include <plasma/svg.h>
#include "iconwidget.h" #include "iconwidget.h"
#include "animator.h"
#include "private/actionwidgetinterface_p.h" #include "private/actionwidgetinterface_p.h"
class QAction; class QAction;
class QPainter; class QPainter;
class QTextLayout; class QTextLayout;
class QPropertyAnimation;
namespace Plasma namespace Plasma
{ {
class Animation;
class IconHoverAnimation;
class PLASMA_EXPORT IconAction class PLASMA_EXPORT IconAction
{ {
public: public:
@ -53,8 +57,8 @@ public:
void show(); void show();
void hide(); void hide();
bool isVisible() const; bool isVisible() const;
bool isAnimating() const;
int animationId() const;
QAction *action() const; QAction *action() const;
void paint(QPainter *painter) const; void paint(QPainter *painter) const;
@ -82,7 +86,7 @@ private:
bool m_selected; bool m_selected;
bool m_visible; bool m_visible;
int m_animationId; QWeakPointer<Animation> m_animation;
}; };
struct Margin struct Margin
@ -188,7 +192,7 @@ public:
void colorConfigChanged(); void colorConfigChanged();
void iconConfigChanged(); void iconConfigChanged();
QFont widgetFont() const; QFont widgetFont() const;
void hoverAnimationUpdate(qreal progress); void hoverAnimationFinished();
void init(); void init();
void layoutIcons(const QStyleOptionGraphicsItem *option); void layoutIcons(const QStyleOptionGraphicsItem *option);
void hoverEffect(bool); void hoverEffect(bool);
@ -203,8 +207,7 @@ public:
QColor textColor; QColor textColor;
QColor textBgColor; QColor textBgColor;
QColor shadowColor; QColor shadowColor;
int hoverAnimId; IconHoverAnimation *hoverAnimation;
qreal hoverAlpha;
QSizeF iconSize; QSizeF iconSize;
QIcon icon; QIcon icon;
IconWidgetStates states; IconWidgetStates states;
@ -221,7 +224,6 @@ public:
Margin *activeMargins; Margin *activeMargins;
bool iconSvgElementChanged : 1; bool iconSvgElementChanged : 1;
bool fadeIn : 1;
bool invertLayout : 1; bool invertLayout : 1;
bool drawBg : 1; bool drawBg : 1;
bool textBgCustomized : 1; bool textBgCustomized : 1;