Added bouncing effect for Rotation animation

svn path=/trunk/KDE/kdelibs/; revision=1112192
This commit is contained in:
Bruno de Oliveira Abinader 2010-04-07 15:19:07 +00:00
parent a163a59624
commit 7507808e7c
2 changed files with 64 additions and 7 deletions

View File

@ -26,9 +26,13 @@
namespace Plasma namespace Plasma
{ {
RotationAnimation::RotationAnimation(QObject *parent, qint8 reference, Qt::Axis axis, qreal angle) const int RotationAnimation::s_bounceSteps = 10;
: Animation(parent)
RotationAnimation::RotationAnimation(QObject *parent, bool isBounceable, qint8 reference, Qt::Axis axis, qreal angle)
: Animation(parent),
m_bounceStep(0)
{ {
setBounceable(isBounceable);
setAngle(angle); setAngle(angle);
setAxis(axis); setAxis(axis);
setReference(reference); 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 Qt::Axis RotationAnimation::axis() const
{ {
return m_axis; return m_axis;
@ -154,7 +168,18 @@ void RotationAnimation::updateState(QAbstractAnimation::State newState, QAbstrac
if ((oldState == Stopped) && (newState == Running)) { if ((oldState == Stopped) && (newState == Running)) {
m_rotation->setAngle(direction() == Forward ? 0 : angle()); m_rotation->setAngle(direction() == Forward ? 0 : angle());
} else if (newState == Stopped) { } else if (newState == Stopped) {
// Do not bounce if animation is part of a group
if (!m_isBounceable || group()) {
m_rotation->setAngle(direction() == Forward ? angle() : 0); 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) { if (w) {
qreal delta = Animation::easingCurve().valueForProgress( qreal delta = Animation::easingCurve().valueForProgress(
currentTime / qreal(duration())); 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); m_rotation->setAngle(delta);
} }
} }

View File

@ -33,16 +33,17 @@ class QGraphicsRotation;
namespace Plasma { namespace Plasma {
/** /**
* @class RotationAnimation plasma/animations/rotation_p.h * @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 * This animation rotates a QGraphicsWidget in a axis (bounce, reference, axis
* axis can be defined using properties). See also * and angle can be defined using properties). See also
* \ref StackedRotationAnimation. * \ref StackedRotationAnimation.
*/ */
class RotationAnimation : public Animation class RotationAnimation : public Animation
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool isBounceable READ isBounceable WRITE setBounceable)
Q_PROPERTY(Qt::Axis axis READ axis WRITE setAxis) Q_PROPERTY(Qt::Axis axis READ axis WRITE setAxis)
Q_PROPERTY(qint8 reference READ reference WRITE setReference) Q_PROPERTY(qint8 reference READ reference WRITE setReference)
Q_PROPERTY(qreal angle READ angle WRITE setAngle) Q_PROPERTY(qreal angle READ angle WRITE setAngle)
@ -51,12 +52,14 @@ public:
/** Default constructor /** Default constructor
* *
* @param parent Animation object parent. * @param parent Animation object parent.
* @param isBounceable Animation bounce behavior.
* @param reference See \ref Animation::Reference. * @param reference See \ref Animation::Reference.
* @param axis Which axis to rotate (XAxis, YAxis, ZAxis). * @param axis Which axis to rotate (XAxis, YAxis, ZAxis).
* @param angle Rotation angle (0 to 360) * @param angle Rotation angle (0 to 360)
* *
*/ */
explicit RotationAnimation(QObject *parent = 0, explicit RotationAnimation(QObject *parent = 0,
bool isBounceable = false,
qint8 reference = Center, qint8 reference = Center,
Qt::Axis axis = Qt::ZAxis, Qt::Axis axis = Qt::ZAxis,
qreal angle = 180); qreal angle = 180);
@ -64,6 +67,18 @@ public:
/** Destructor */ /** Destructor */
~RotationAnimation(); ~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) * get animation rotation axis (e.g. YAxis, ZAxis, XAxis)
*/ */
@ -106,6 +121,12 @@ protected:
private: private:
/** Rotation transform object */ /** Rotation transform object */
QGraphicsRotation *m_rotation; 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 */ /** Rotation angle */
qreal m_angle; qreal m_angle;
/** Axis where to perform the rotation */ /** Axis where to perform the rotation */