From d53ac9d8cac3efea68e614bd0423c94a56e32220 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 17 Oct 2012 16:41:42 +0200 Subject: Introduce QBlendStyleAnimation (based on QWindowsVistaAnimation) Change-Id: Ie289debe69ea7f6bb7833f979e39bb91290cc49c Reviewed-by: Jens Bache-Wiig --- src/widgets/styles/qstyleanimation.cpp | 105 ++++++++++++++++++++++++++++++++- src/widgets/styles/qstyleanimation_p.h | 28 +++++++++ 2 files changed, 132 insertions(+), 1 deletion(-) diff --git a/src/widgets/styles/qstyleanimation.cpp b/src/widgets/styles/qstyleanimation.cpp index 0138996e33..9ddcbcc511 100644 --- a/src/widgets/styles/qstyleanimation.cpp +++ b/src/widgets/styles/qstyleanimation.cpp @@ -41,7 +41,6 @@ #include "qstyleanimation_p.h" #include -#include #include #include @@ -208,4 +207,108 @@ bool QNumberStyleAnimation::isUpdateNeeded() const return false; } +QBlendStyleAnimation::QBlendStyleAnimation(Type type, QObject *target) : + QStyleAnimation(target), _type(type) +{ + setDuration(250); +} + +QImage QBlendStyleAnimation::startImage() const +{ + return _start; +} + +void QBlendStyleAnimation::setStartImage(const QImage& image) +{ + _start = image; +} + +QImage QBlendStyleAnimation::endImage() const +{ + return _end; +} + +void QBlendStyleAnimation::setEndImage(const QImage& image) +{ + _end = image; +} + +QImage QBlendStyleAnimation::currentImage() const +{ + return _current; +} + +/*! \internal + + A helper function to blend two images. + + The result consists of ((alpha)*startImage) + ((1-alpha)*endImage) + +*/ +static QImage blendedImage(const QImage &start, const QImage &end, float alpha) +{ + if (start.isNull() || end.isNull()) + return QImage(); + + QImage blended; + const int a = qRound(alpha*256); + const int ia = 256 - a; + const int sw = start.width(); + const int sh = start.height(); + const int bpl = start.bytesPerLine(); + switch (start.depth()) { + case 32: + { + blended = QImage(sw, sh, start.format()); + uchar *mixed_data = blended.bits(); + const uchar *back_data = start.bits(); + const uchar *front_data = end.bits(); + for (int sy = 0; sy < sh; sy++) { + quint32* mixed = (quint32*)mixed_data; + const quint32* back = (const quint32*)back_data; + const quint32* front = (const quint32*)front_data; + for (int sx = 0; sx < sw; sx++) { + quint32 bp = back[sx]; + quint32 fp = front[sx]; + mixed[sx] = qRgba ((qRed(bp)*ia + qRed(fp)*a)>>8, + (qGreen(bp)*ia + qGreen(fp)*a)>>8, + (qBlue(bp)*ia + qBlue(fp)*a)>>8, + (qAlpha(bp)*ia + qAlpha(fp)*a)>>8); + } + mixed_data += bpl; + back_data += bpl; + front_data += bpl; + } + } + default: + break; + } + return blended; +} + +void QBlendStyleAnimation::updateCurrentTime(int time) +{ + QStyleAnimation::updateCurrentTime(time); + + float alpha = 1.0; + if (duration() > 0) { + if (_type == Pulse) { + time = time % duration() * 2; + if (time > duration()) + time = duration() * 2 - time; + } + + alpha = time / static_cast(duration()); + + if (_type == Transition && time > duration()) { + alpha = 1.0; + stop(); + } + } else if (time > 0) { + stop(); + } + + _current = blendedImage(_start, _end, alpha); +} + QT_END_NAMESPACE diff --git a/src/widgets/styles/qstyleanimation_p.h b/src/widgets/styles/qstyleanimation_p.h index d9869533ef..9dddc7b62c 100644 --- a/src/widgets/styles/qstyleanimation_p.h +++ b/src/widgets/styles/qstyleanimation_p.h @@ -44,6 +44,7 @@ #include "qabstractanimation.h" #include "qdatetime.h" +#include "qimage.h" QT_BEGIN_NAMESPACE @@ -134,6 +135,33 @@ private: mutable qreal _prev; }; +class QBlendStyleAnimation : public QStyleAnimation +{ + Q_OBJECT + +public: + enum Type { Transition, Pulse }; + + QBlendStyleAnimation(Type type, QObject *target); + + QImage startImage() const; + void setStartImage(const QImage& image); + + QImage endImage() const; + void setEndImage(const QImage& image); + + QImage currentImage() const; + +protected: + virtual void updateCurrentTime(int time); + +private: + Type _type; + QImage _start; + QImage _end; + QImage _current; +}; + QT_END_NAMESPACE #endif // QSTYLEANIMATION_P_H -- cgit v1.2.3