From bf225098a96afae57462fe05ca294f47fdfc92d0 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Fri, 5 Feb 2010 21:46:51 +0000 Subject: [PATCH] Updated Plasma IconWidget to use new animation API + QPropertyAnimation svn path=/trunk/KDE/kdelibs/; revision=1085753 --- widgets/iconwidget.cpp | 152 ++++++++++++++++++++++++++--------------- widgets/iconwidget.h | 29 +++++++- widgets/iconwidget_p.h | 16 +++-- 3 files changed, 134 insertions(+), 63 deletions(-) diff --git a/widgets/iconwidget.cpp b/widgets/iconwidget.cpp index 91d39a8bf..1d2cdad77 100644 --- a/widgets/iconwidget.cpp +++ b/widgets/iconwidget.cpp @@ -43,10 +43,11 @@ #include #include +#include +#include #include #include -#include "animator.h" #include "svg.h" /* @@ -59,19 +60,55 @@ TODO: 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(parent()); + item->update(); +} + +void IconHoverAnimation::setFadeIn(bool fadeIn) +{ + m_fadeIn = fadeIn; +} + +void IconHoverAnimation::setAnimation(QPropertyAnimation *animation) +{ + m_animation = animation; +} + IconWidgetPrivate::IconWidgetPrivate(IconWidget *i) : ActionWidgetInterface(i), q(i), iconSvg(0), - hoverAnimId(-1), - hoverAlpha(20 / 255), + hoverAnimation(new IconHoverAnimation(q)), iconSize(48, 48), states(IconWidgetPrivate::NoState), orientation(Qt::Vertical), numDisplayLines(2), activeMargins(0), iconSvgElementChanged(false), - fadeIn(false), invertLayout(false), drawBg(false), textBgCustomized(false), @@ -82,6 +119,7 @@ IconWidgetPrivate::IconWidgetPrivate(IconWidget *i) IconWidgetPrivate::~IconWidgetPrivate() { qDeleteAll(cornerActions); + delete hoverAnimation; } void IconWidgetPrivate::readColors() @@ -133,34 +171,43 @@ IconAction::IconAction(IconWidget *icon, QAction *action) m_hovered(false), m_pressed(false), m_selected(false), - m_visible(false), - m_animationId(-1) + m_visible(false) { } void IconAction::show() { - if (m_animationId) { - Animator::self()->stopElementAnimation(m_animationId); + Animation *animation = m_animation.data(); + 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(); - m_animationId = Animator::self()->animateElement(m_icon, Animator::AppearAnimation); - Animator::self()->setInitialPixmap(m_animationId, m_pixmap); + animation->setDirection(QAbstractAnimation::Forward); + animation->start(QAbstractAnimation::DeleteWhenStopped); m_visible = true; } void IconAction::hide() { - if (m_animationId) { - Animator::self()->stopElementAnimation(m_animationId); + Animation *animation = m_animation.data(); + 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(); - m_animationId = Animator::self()->animateElement(m_icon, Animator::DisappearAnimation); - Animator::self()->setInitialPixmap(m_animationId, m_pixmap); + animation->setDirection(QAbstractAnimation::Backward); + animation->start(QAbstractAnimation::DeleteWhenStopped); m_visible = false; } @@ -169,6 +216,11 @@ bool IconAction::isVisible() const return m_visible; } +bool IconAction::isAnimating() const +{ + return (m_animation.data() && m_animation.data()->state() == QAbstractAnimation::Running); +} + bool IconAction::isPressed() const { return m_pressed; @@ -281,11 +333,6 @@ bool IconAction::event(QEvent::Type type, const QPointF &pos) return false; } -int IconAction::animationId() const -{ - return m_animationId; -} - QAction *IconAction::action() const { return m_action; @@ -302,12 +349,12 @@ void IconAction::paint(QPainter *painter) const return; } - QPixmap animPixmap = Animator::self()->currentPixmap(m_animationId); - - if (m_visible && animPixmap.isNull()) { + Animation *animation = m_animation.data(); + if (m_visible && animation->property("currentPixmap").isNull()) { painter->drawPixmap(m_rect.toRect(), m_pixmap); } else { - painter->drawPixmap(m_rect.toRect(), animPixmap); + painter->drawPixmap(m_rect.toRect(), + animation->property("currentPixmap").value()); } } @@ -618,37 +665,32 @@ void IconWidgetPrivate::hoverEffect(bool show) states |= IconWidgetPrivate::HoverState; } - fadeIn = show; - const int FadeInDuration = 150; + hoverAnimation->setFadeIn(show); - if (hoverAnimId != -1) { - Animator::self()->stopCustomAnimation(hoverAnimId); + QPropertyAnimation *animation = hoverAnimation->animation(); + 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( - 40 / (1000 / FadeInDuration), FadeInDuration, - Animator::EaseOutCurve, q, "hoverAnimationUpdate"); + animation->setProperty("direction", show ? + QAbstractAnimation::Forward : QAbstractAnimation::Backward); + animation->start(show ? + QAbstractAnimation::KeepWhenStopped : QAbstractAnimation::DeleteWhenStopped); } -void IconWidgetPrivate::hoverAnimationUpdate(qreal progress) +void IconWidgetPrivate::hoverAnimationFinished() { - if (fadeIn) { - hoverAlpha = progress; - } 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 (!hoverAnimation->fadeIn()) { + states &= ~IconWidgetPrivate::HoverState; } - - if (qFuzzyCompare(qreal(1.0), progress)) { - hoverAnimId = -1; - - if (!fadeIn) { - states &= ~IconWidgetPrivate::HoverState; - } - } - - q->update(); } void IconWidgetPrivate::drawBackground(QPainter *painter, IconWidgetState state) @@ -663,15 +705,15 @@ void IconWidgetPrivate::drawBackground(QPainter *painter, IconWidgetState state) background->setElementPrefix("hover"); } - if (qFuzzyCompare(hoverAlpha, 1)) { + if (qFuzzyCompare(hoverAnimation->value(), 1)) { background->resizeFrame(currentSize); background->paintFrame(painter); - } else if (!qFuzzyCompare(hoverAlpha+1, 1)) { + } else if (!qFuzzyCompare(hoverAnimation->value()+1, 1)) { background->resizeFrame(currentSize); QPixmap frame = background->framePixmap(); QPainter bufferPainter(&frame); 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(); 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 // is KFileItemDelegate. 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); } else { result = PaintUtils::transition( result, 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 foreach (const IconAction *action, d->cornerActions) { - if (action->animationId()) { + if (action->isAnimating()) { action->paint(painter); } } @@ -1036,11 +1078,11 @@ void IconWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option if (d->textBgColor != QColor() && d->textBgColor.alpha() > 0 && !(d->text.isEmpty() && d->infoText.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(); painter->setPen(Qt::transparent); 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()); gradient.setColorAt(0, color.lighter(120)); gradient.setColorAt(1, color.darker(120)); diff --git a/widgets/iconwidget.h b/widgets/iconwidget.h index 672bf3518..316aa2a26 100644 --- a/widgets/iconwidget.h +++ b/widgets/iconwidget.h @@ -24,6 +24,7 @@ #define PLASMA_ICONWIDGET_H #include +#include #include #include #include @@ -33,6 +34,7 @@ #include class QAction; +class QPropertyAnimation; /** * @class IconWidget plasma/widgets/iconwidget.h @@ -51,6 +53,31 @@ namespace Plasma 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 m_animation; +}; + class PLASMA_EXPORT IconWidget : public QGraphicsWidget { Q_OBJECT @@ -319,7 +346,7 @@ private: Q_PRIVATE_SLOT(d, void clearAction()) Q_PRIVATE_SLOT(d, void svgChanged()) 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 iconConfigChanged()) diff --git a/widgets/iconwidget_p.h b/widgets/iconwidget_p.h index 42f2106e6..a19bfccfb 100644 --- a/widgets/iconwidget_p.h +++ b/widgets/iconwidget_p.h @@ -23,6 +23,7 @@ #define PLASMA_ICONWIDGET_P_H #include +#include #include #include #include @@ -35,16 +36,19 @@ #include #include "iconwidget.h" -#include "animator.h" #include "private/actionwidgetinterface_p.h" class QAction; class QPainter; class QTextLayout; +class QPropertyAnimation; namespace Plasma { +class Animation; +class IconHoverAnimation; + class PLASMA_EXPORT IconAction { public: @@ -53,8 +57,8 @@ public: void show(); void hide(); bool isVisible() const; + bool isAnimating() const; - int animationId() const; QAction *action() const; void paint(QPainter *painter) const; @@ -82,7 +86,7 @@ private: bool m_selected; bool m_visible; - int m_animationId; + QWeakPointer m_animation; }; struct Margin @@ -188,7 +192,7 @@ public: void colorConfigChanged(); void iconConfigChanged(); QFont widgetFont() const; - void hoverAnimationUpdate(qreal progress); + void hoverAnimationFinished(); void init(); void layoutIcons(const QStyleOptionGraphicsItem *option); void hoverEffect(bool); @@ -203,8 +207,7 @@ public: QColor textColor; QColor textBgColor; QColor shadowColor; - int hoverAnimId; - qreal hoverAlpha; + IconHoverAnimation *hoverAnimation; QSizeF iconSize; QIcon icon; IconWidgetStates states; @@ -221,7 +224,6 @@ public: Margin *activeMargins; bool iconSvgElementChanged : 1; - bool fadeIn : 1; bool invertLayout : 1; bool drawBg : 1; bool textBgCustomized : 1;