diff --git a/animations/rotation.cpp b/animations/rotation.cpp index 97b219897..d250aba2a 100644 --- a/animations/rotation.cpp +++ b/animations/rotation.cpp @@ -26,9 +26,13 @@ namespace Plasma { -RotationAnimation::RotationAnimation(QObject *parent, qint8 reference, Qt::Axis axis, qreal angle) - : Animation(parent) +const int RotationAnimation::s_bounceSteps = 10; + +RotationAnimation::RotationAnimation(QObject *parent, bool isBounceable, qint8 reference, Qt::Axis axis, qreal angle) + : Animation(parent), + m_bounceStep(0) { + setBounceable(isBounceable); setAngle(angle); setAxis(axis); setReference(reference); @@ -40,6 +44,16 @@ RotationAnimation::~RotationAnimation() { } +bool RotationAnimation::isBounceable() const +{ + return m_isBounceable; +} + +void RotationAnimation::setBounceable(const bool isBounceable) +{ + m_isBounceable = isBounceable; +} + Qt::Axis RotationAnimation::axis() const { return m_axis; @@ -154,7 +168,18 @@ void RotationAnimation::updateState(QAbstractAnimation::State newState, QAbstrac if ((oldState == Stopped) && (newState == Running)) { m_rotation->setAngle(direction() == Forward ? 0 : angle()); } else if (newState == Stopped) { - m_rotation->setAngle(direction() == Forward ? angle() : 0); + // Do not bounce if animation is part of a group + if (!m_isBounceable || group()) { + m_rotation->setAngle(direction() == Forward ? angle() : 0); + } else { + setDirection(direction() == Forward ? Backward : Forward); + if (++m_bounceStep < s_bounceSteps) { + start(); + } else { + m_rotation->setAngle(direction() == Forward ? 0 : angle()); + m_bounceStep = 0; + } + } } } @@ -164,7 +189,18 @@ void RotationAnimation::updateCurrentTime(int currentTime) if (w) { qreal delta = Animation::easingCurve().valueForProgress( currentTime / qreal(duration())); - delta = angle() * delta; + const qreal currentAngle = angle(); + if (m_isBounceable) { + const qreal percentage = 1 - qBound(0.0, qreal(m_bounceStep) / qreal(s_bounceSteps), 1.0); + if (m_bounceStep == 0) { // initial bounce + delta = qBound(0.0, currentAngle * percentage * delta * 0.5, (currentAngle / 2.0)); + } else { + delta -= 0.5; + delta = qBound(-(currentAngle / 2.0), currentAngle * percentage * delta, (currentAngle / 2.0)); + } + } else { + delta = qBound(0.0, currentAngle * delta, currentAngle); + } m_rotation->setAngle(delta); } } diff --git a/animations/rotation_p.h b/animations/rotation_p.h index d10d16471..1685182c6 100644 --- a/animations/rotation_p.h +++ b/animations/rotation_p.h @@ -33,16 +33,17 @@ class QGraphicsRotation; namespace Plasma { /** * @class RotationAnimation plasma/animations/rotation_p.h - * @short 2D rotation animation. + * @short 3D rotation animation. * - * This animation rotates a QGraphicsWidget in a axis (reference and - * axis can be defined using properties). See also + * This animation rotates a QGraphicsWidget in a axis (bounce, reference, axis + * and angle can be defined using properties). See also * \ref StackedRotationAnimation. */ class RotationAnimation : public Animation { Q_OBJECT + Q_PROPERTY(bool isBounceable READ isBounceable WRITE setBounceable) Q_PROPERTY(Qt::Axis axis READ axis WRITE setAxis) Q_PROPERTY(qint8 reference READ reference WRITE setReference) Q_PROPERTY(qreal angle READ angle WRITE setAngle) @@ -51,12 +52,14 @@ public: /** Default constructor * * @param parent Animation object parent. + * @param isBounceable Animation bounce behavior. * @param reference See \ref Animation::Reference. * @param axis Which axis to rotate (XAxis, YAxis, ZAxis). * @param angle Rotation angle (0 to 360) * */ explicit RotationAnimation(QObject *parent = 0, + bool isBounceable = false, qint8 reference = Center, Qt::Axis axis = Qt::ZAxis, qreal angle = 180); @@ -64,6 +67,18 @@ public: /** Destructor */ ~RotationAnimation(); + /** + * get animation bounce behavior + */ + bool isBounceable() const; + + /** + * set animation bounce behavior (it can be bounceable only if not part of + * an animation group) + * @arg isBounceable + */ + void setBounceable(const bool isBounceable); + /** * get animation rotation axis (e.g. YAxis, ZAxis, XAxis) */ @@ -106,6 +121,12 @@ protected: private: /** Rotation transform object */ QGraphicsRotation *m_rotation; + /** Actual number of bounce steps */ + int m_bounceStep; + /** Number of bounce steps */ + static const int s_bounceSteps; + /** Animation bounce behavior */ + bool m_isBounceable; /** Rotation angle */ qreal m_angle; /** Axis where to perform the rotation */