summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/src/examples.qdoc6
-rw-r--r--doc/src/examples/stickman.qdoc115
-rw-r--r--doc/src/images/stickman-example.pngbin0 -> 18867 bytes
-rw-r--r--doc/src/images/stickman-example1.pngbin0 -> 64543 bytes
-rw-r--r--doc/src/images/stickman-example2.pngbin0 -> 37412 bytes
-rw-r--r--doc/src/images/stickman-example3.pngbin0 -> 23591 bytes
-rw-r--r--examples/animation/stickman/lifecycle.cpp48
-rw-r--r--examples/animation/stickman/lifecycle.h2
-rw-r--r--src/corelib/statemachine/qabstracttransition.cpp2
-rw-r--r--src/corelib/tools/qeasingcurve.cpp90
10 files changed, 190 insertions, 73 deletions
diff --git a/doc/src/examples.qdoc b/doc/src/examples.qdoc
index 6603390..c55d29f 100644
--- a/doc/src/examples.qdoc
+++ b/doc/src/examples.qdoc
@@ -86,6 +86,12 @@
\o \l{activeqt/webbrowser}{Web Browser}\raisedaster
\o \l{activeqt/wrapper}{Wrapper}\raisedaster
\endlist
+
+ \section1 Animation
+
+ \list
+ \o \l{animation/stickman}{Stick man}\raisedaster
+ \endlist
\section1 Concurrent Programming
diff --git a/doc/src/examples/stickman.qdoc b/doc/src/examples/stickman.qdoc
new file mode 100644
index 0000000..49f4953
--- /dev/null
+++ b/doc/src/examples/stickman.qdoc
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example animation/stickman
+ \title Stickman Example
+
+ The Stickman example shows how to animate transitions in a state machine to implement key frame
+ animations.
+
+ \image stickman-example.png
+
+ In this example, we will write a small application which animates the joints in a skeleton and
+ projects a stickman figure on top. The stickman can be either "alive" or "dead", and when in the
+ "alive" state, he can be performing different actions defined by key frame animations.
+
+ Animations are implemented as composite states. Each child state of the animation state
+ represents a frame in the animation by setting the position of each joint in the stickman's
+ skeleton to the positions defined for the particular frame. The frames are then bound together
+ with animated transitions that trigger on the source state's polished() signal. Thus, the
+ machine will enter the state representing the next frame in the animation immediately after it
+ has finished animating into the previous frame.
+
+ \image stickman-example1.png
+
+ The states for an animation is constructed by reading a custom animation file format and
+ creating states that assign values to the the "position" properties of each of the nodes in the
+ skeleton graph.
+
+ \snippet examples/animation/stickman/lifecycle.cpp 1
+
+ The states are then bound together with signal transitions that listen to the polished() signal.
+
+ \snippet examples/animation/stickman/lifecycle.cpp 2
+
+ The last frame state is given a transition to the first one, so that the animation will loop
+ until it is interrupted when a transition out from the animation state is taken. To get smooth
+ animations between the different key frames, we set a default animation on the state machine.
+ This is a parallel animation group which contains animations for all the "position" properties
+ and will be selected by default when taking any transition that leads into a state that assigns
+ values to these properties.
+
+ \snippet examples/animation/stickman/lifecycle.cpp 3
+
+ Several such animation states are constructed, and are placed together as children of a top
+ level "alive" state which represents the stickman life cycle. Transitions go from the parent
+ state to the child state to ensure that each of the child states inherit them.
+
+ \image stickman-example2.png
+
+ This saves us the effort of connect every state to every state with identical transitions. The
+ state machine makes sure that transitions between the key frame animations are also smooth by
+ applying the default animation when interrupting one and starting another.
+
+ Finally, there is a transition out from the "alive" state and into the "dead" state. This is
+ a custom transition type called LightningSrikesTransition which samples every second and
+ triggers at random (one out of fifty times on average.)
+
+ \snippet examples/animation/stickman/lifecycle.cpp 4
+
+ When it triggers, the machine will first enter a "lightningBlink" state which uses a timer to
+ pause for a brief period of time while the background color of the scene is white. This gives us
+ a flash effect when the lightning strikes.
+
+ \snippet examples/animation/stickman/lifecycle.cpp 5
+
+ We start and stop a QTimer object when entering and exiting the state. Then we transition into
+ the "dead" state when the timer times out.
+
+ \snippet examples/animation/stickman/lifecycle.cpp 0
+
+ When the machine is in the "dead" state, it will be unresponsive. This is because the "dead"
+ state has no transitions leading out.
+
+ \image stickman-example3.png
+
+*/
diff --git a/doc/src/images/stickman-example.png b/doc/src/images/stickman-example.png
new file mode 100644
index 0000000..a40f37b
--- /dev/null
+++ b/doc/src/images/stickman-example.png
Binary files differ
diff --git a/doc/src/images/stickman-example1.png b/doc/src/images/stickman-example1.png
new file mode 100644
index 0000000..1596a68
--- /dev/null
+++ b/doc/src/images/stickman-example1.png
Binary files differ
diff --git a/doc/src/images/stickman-example2.png b/doc/src/images/stickman-example2.png
new file mode 100644
index 0000000..980276a
--- /dev/null
+++ b/doc/src/images/stickman-example2.png
Binary files differ
diff --git a/doc/src/images/stickman-example3.png b/doc/src/images/stickman-example3.png
new file mode 100644
index 0000000..3635ff7
--- /dev/null
+++ b/doc/src/images/stickman-example3.png
Binary files differ
diff --git a/examples/animation/stickman/lifecycle.cpp b/examples/animation/stickman/lifecycle.cpp
index 423d7ad..1feb31d 100644
--- a/examples/animation/stickman/lifecycle.cpp
+++ b/examples/animation/stickman/lifecycle.cpp
@@ -82,6 +82,7 @@ private:
Qt::Key m_key;
};
+//! [4]
class LightningStrikesTransition: public QEventTransition
{
public:
@@ -97,6 +98,7 @@ public:
return QEventTransition::eventTest(e) && ((qrand() % 50) == 0);
}
};
+//! [4]
LifeCycle::LifeCycle(StickMan *stickMan, GraphicsView *keyReceiver)
: m_stickMan(stickMan), m_keyReceiver(keyReceiver)
@@ -110,7 +112,10 @@ LifeCycle::LifeCycle(StickMan *stickMan, GraphicsView *keyReceiver)
}
// Set up intial state graph
+//! [3]
m_machine = new QStateMachine();
+ m_machine->addDefaultAnimation(m_animationGroup);
+//! [3]
m_alive = new QState(m_machine->rootState());
m_alive->setObjectName("alive");
@@ -122,11 +127,13 @@ LifeCycle::LifeCycle(StickMan *stickMan, GraphicsView *keyReceiver)
lightningBlink->assignProperty(m_stickMan, "fillColor", Qt::white);
lightningBlink->assignProperty(m_stickMan, "isDead", true);
+//! [5]
QTimer *timer = new QTimer(lightningBlink);
timer->setSingleShot(true);
timer->setInterval(100);
QObject::connect(lightningBlink, SIGNAL(entered()), timer, SLOT(start()));
QObject::connect(lightningBlink, SIGNAL(exited()), timer, SLOT(stop()));
+//! [5]
m_dead = new QState(m_machine->rootState());
m_dead->assignProperty(m_stickMan->scene(), "backgroundBrush", Qt::black);
@@ -142,8 +149,9 @@ LifeCycle::LifeCycle(StickMan *stickMan, GraphicsView *keyReceiver)
// Lightning strikes at random
m_alive->addTransition(new LightningStrikesTransition(lightningBlink));
- //m_alive->addTransition(new KeyPressTransition(m_keyReceiver, Qt::Key_L, lightningBlink));
- connectByAnimation(lightningBlink, m_dead, new QSignalTransition(timer, SIGNAL(timeout())));
+//! [0]
+ lightningBlink->addTransition(timer, SIGNAL(timeout()), m_dead);
+//! [0]
m_machine->setInitialState(m_alive);
}
@@ -159,22 +167,10 @@ void LifeCycle::start()
m_machine->start();
}
-void LifeCycle::connectByAnimation(QState *s1, QAbstractState *s2,
- QAbstractTransition *transition)
-{
- if (transition == 0) {
- transition = s1->addTransition(s2);
- } else {
- transition->setTargetState(s2);
- s1->addTransition(transition);
- }
- transition->addAnimation(m_animationGroup);
-}
-
void LifeCycle::addActivity(const QString &fileName, Qt::Key key)
{
QState *state = makeState(m_alive, fileName);
- connectByAnimation(m_alive, state, new KeyPressTransition(m_keyReceiver, key));
+ m_alive->addTransition(new KeyPressTransition(m_keyReceiver, key, state));
}
QState *LifeCycle::makeState(QState *parentState, const QString &animationFileName)
@@ -191,26 +187,28 @@ QState *LifeCycle::makeState(QState *parentState, const QString &animationFileNa
const int frameCount = animation.totalFrames();
QState *previousState = 0;
for (int i=0; i<frameCount; ++i) {
- QState *frameState = new QState(topLevel);
- frameState->setObjectName(QString::fromLatin1("frame %0").arg(i));
-
animation.setCurrentFrame(i);
+
+//! [1]
+ QState *frameState = new QState(topLevel);
const int nodeCount = animation.nodeCount();
for (int j=0; j<nodeCount; ++j)
frameState->assignProperty(m_stickMan->node(j), "position", animation.nodePos(j));
+//! [1]
- if (previousState == 0) {
+ frameState->setObjectName(QString::fromLatin1("frame %0").arg(i));
+ if (previousState == 0)
topLevel->setInitialState(frameState);
- } else {
- connectByAnimation(previousState, frameState,
- new QSignalTransition(previousState, SIGNAL(polished())));
- }
+ else
+//! [2]
+ previousState->addTransition(previousState, SIGNAL(polished()), frameState);
+//! [2]
+
previousState = frameState;
}
// Loop
- connectByAnimation(previousState, topLevel->initialState(),
- new QSignalTransition(previousState, SIGNAL(polished())));
+ previousState->addTransition(previousState, SIGNAL(polished()), topLevel->initialState());
return topLevel;
diff --git a/examples/animation/stickman/lifecycle.h b/examples/animation/stickman/lifecycle.h
index e520402..8fd0fb2 100644
--- a/examples/animation/stickman/lifecycle.h
+++ b/examples/animation/stickman/lifecycle.h
@@ -63,8 +63,6 @@ public:
void start();
private:
- void connectByAnimation(QState *s1, QAbstractState *s2,
- QAbstractTransition *transition = 0);
QState *makeState(QState *parentState, const QString &animationFileName);
StickMan *m_stickMan;
diff --git a/src/corelib/statemachine/qabstracttransition.cpp b/src/corelib/statemachine/qabstracttransition.cpp
index a930581..68423cb 100644
--- a/src/corelib/statemachine/qabstracttransition.cpp
+++ b/src/corelib/statemachine/qabstracttransition.cpp
@@ -321,7 +321,7 @@ QList<QAbstractAnimation*> QAbstractTransition::animations() const
#endif
/*!
- \fn QAbstractTransition::eventTest(QEvent *event) const
+ \fn QAbstractTransition::eventTest(QEvent *event)
This function is called to determine whether the given \a event should cause
this transition to trigger. Reimplement this function and return true if the
diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp
index a1a0d1f..9ef9149 100644
--- a/src/corelib/tools/qeasingcurve.cpp
+++ b/src/corelib/tools/qeasingcurve.cpp
@@ -99,7 +99,7 @@
\br
Easing equation function for a simple linear tweening,
with no easing.
- \value InQuad \inlineimage qeasingcurve-inquad.png
+ \value InQuad \inlineimage qeasingcurve-inquad.png
\br
Easing equation function for a quadratic (t^2) easing
in: accelerating from zero velocity.
@@ -107,7 +107,7 @@
\br
Easing equation function for a quadratic (t^2) easing
out: decelerating to zero velocity.
- \value InOutQuad \inlineimage qeasingcurve-inoutquad.png
+ \value InOutQuad \inlineimage qeasingcurve-inoutquad.png
\br
Easing equation function for a quadratic (t^2) easing
in/out: acceleration until halfway, then deceleration.
@@ -121,11 +121,11 @@
in: accelerating from zero velocity.
\value OutCubic \inlineimage qeasingcurve-outcubic.png
\br
- Easing equation function for a cubic (t^3) easing
+ Easing equation function for a cubic (t^3) easing
out: decelerating from zero velocity.
\value InOutCubic \inlineimage qeasingcurve-inoutcubic.png
\br
- Easing equation function for a cubic (t^3) easing
+ Easing equation function for a cubic (t^3) easing
in/out: acceleration until halfway, then deceleration.
\value OutInCubic \inlineimage qeasingcurve-outincubic.png
\br
@@ -133,55 +133,55 @@
out/in: deceleration until halfway, then acceleration.
\value InQuart \inlineimage qeasingcurve-inquart.png
\br
- Easing equation function for a quartic (t^4) easing
+ Easing equation function for a quartic (t^4) easing
in: accelerating from zero velocity.
\value OutQuart \inlineimage qeasingcurve-outquart.png
\br
- Easing equation function for a quartic (t^4) easing
+ Easing equation function for a quartic (t^4) easing
out: decelerating from zero velocity.
\value InOutQuart \inlineimage qeasingcurve-inoutquart.png
\br
- Easing equation function for a quartic (t^4) easing
+ Easing equation function for a quartic (t^4) easing
in/out: acceleration until halfway, then deceleration.
\value OutInQuart \inlineimage qeasingcurve-outinquart.png
\br
- Easing equation function for a quartic (t^4) easing
+ Easing equation function for a quartic (t^4) easing
out/in: deceleration until halfway, then acceleration.
\value InQuint \inlineimage qeasingcurve-inquint.png
\br
- Easing equation function for a quintic (t^5) easing
+ Easing equation function for a quintic (t^5) easing
in: accelerating from zero velocity.
\value OutQuint \inlineimage qeasingcurve-outquint.png
\br
- Easing equation function for a quintic (t^5) easing
+ Easing equation function for a quintic (t^5) easing
out: decelerating from zero velocity.
\value InOutQuint \inlineimage qeasingcurve-inoutquint.png
\br
- Easing equation function for a quintic (t^5) easing
+ Easing equation function for a quintic (t^5) easing
in/out: acceleration until halfway, then deceleration.
\value OutInQuint \inlineimage qeasingcurve-outinquint.png
\br
- Easing equation function for a quintic (t^5) easing
+ Easing equation function for a quintic (t^5) easing
out/in: deceleration until halfway, then acceleration.
\value InSine \inlineimage qeasingcurve-insine.png
\br
- Easing equation function for a sinusoidal (sin(t)) easing
+ Easing equation function for a sinusoidal (sin(t)) easing
in: accelerating from zero velocity.
\value OutSine \inlineimage qeasingcurve-outsine.png
\br
- Easing equation function for a sinusoidal (sin(t)) easing
+ Easing equation function for a sinusoidal (sin(t)) easing
out: decelerating from zero velocity.
\value InOutSine \inlineimage qeasingcurve-inoutsine.png
\br
- Easing equation function for a sinusoidal (sin(t)) easing
+ Easing equation function for a sinusoidal (sin(t)) easing
in/out: acceleration until halfway, then deceleration.
\value OutInSine \inlineimage qeasingcurve-outinsine.png
\br
- Easing equation function for a sinusoidal (sin(t)) easing
+ Easing equation function for a sinusoidal (sin(t)) easing
out/in: deceleration until halfway, then acceleration.
\value InExpo \inlineimage qeasingcurve-inexpo.png
\br
- Easing equation function for an exponential (2^t) easing
+ Easing equation function for an exponential (2^t) easing
in: accelerating from zero velocity.
\value OutExpo \inlineimage qeasingcurve-outexpo.png
\br
@@ -213,47 +213,47 @@
out/in: deceleration until halfway, then acceleration.
\value InElastic \inlineimage qeasingcurve-inelastic.png
\br
- Easing equation function for an elastic
- (exponentially decaying sine wave) easing in:
+ Easing equation function for an elastic
+ (exponentially decaying sine wave) easing in:
accelerating from zero velocity. The peak amplitude
can be set with the \e amplitude parameter, and the
period of decay by the \e period parameter.
\value OutElastic \inlineimage qeasingcurve-outelastic.png
\br
- Easing equation function for an elastic
- (exponentially decaying sine wave) easing out:
- decelerating from zero velocity. The peak amplitude
- can be set with the \e amplitude parameter, and the
+ Easing equation function for an elastic
+ (exponentially decaying sine wave) easing out:
+ decelerating from zero velocity. The peak amplitude
+ can be set with the \e amplitude parameter, and the
period of decay by the \e period parameter.
\value InOutElastic \inlineimage qeasingcurve-inoutelastic.png
\br
- Easing equation function for an elastic
- (exponentially decaying sine wave) easing in/out:
+ Easing equation function for an elastic
+ (exponentially decaying sine wave) easing in/out:
acceleration until halfway, then deceleration.
\value OutInElastic \inlineimage qeasingcurve-outinelastic.png
\br
- Easing equation function for an elastic
- (exponentially decaying sine wave) easing out/in:
+ Easing equation function for an elastic
+ (exponentially decaying sine wave) easing out/in:
deceleration until halfway, then acceleration.
\value InBack \inlineimage qeasingcurve-inback.png
\br
- Easing equation function for a back (overshooting
- cubic easing: (s+1)*t^3 - s*t^2) easing in:
+ Easing equation function for a back (overshooting
+ cubic easing: (s+1)*t^3 - s*t^2) easing in:
accelerating from zero velocity.
\value OutBack \inlineimage qeasingcurve-outback.png
\br
- Easing equation function for a back (overshooting
- cubic easing: (s+1)*t^3 - s*t^2) easing out:
+ Easing equation function for a back (overshooting
+ cubic easing: (s+1)*t^3 - s*t^2) easing out:
decelerating from zero velocity.
\value InOutBack \inlineimage qeasingcurve-inoutback.png
\br
- Easing equation function for a back (overshooting
- cubic easing: (s+1)*t^3 - s*t^2) easing in/out:
+ Easing equation function for a back (overshooting
+ cubic easing: (s+1)*t^3 - s*t^2) easing in/out:
acceleration until halfway, then deceleration.
\value OutInBack \inlineimage qeasingcurve-outinback.png
\br
- Easing equation function for a back (overshooting
- cubic easing: (s+1)*t^3 - s*t^2) easing out/in:
+ Easing equation function for a back (overshooting
+ cubic easing: (s+1)*t^3 - s*t^2) easing out/in:
deceleration until halfway, then acceleration.
\value InBounce \inlineimage qeasingcurve-inbounce.png
\br
@@ -283,14 +283,13 @@
\omitvalue NCurveTypes
*/
-/*!
+/*!
\typedef QEasingCurve::EasingFunction
This is a typedef for a pointer to a function with the following
signature:
\snippet doc/src/snippets/code/src_corelib_tools_qeasingcurve.cpp 0
-
*/
#include "qeasingcurve.h"
@@ -355,6 +354,7 @@ public:
config(0),
func(&easeNone)
{ }
+ ~QEasingCurvePrivate() { delete config; }
void setType_helper(QEasingCurve::Type);
QEasingCurve::Type type;
@@ -646,10 +646,10 @@ bool QEasingCurve::operator==(const QEasingCurve &other) const
\fn bool QEasingCurve::operator!=(const QEasingCurve &other) const
Compare this easing curve with \a other and returns true if they are not equal.
It will also compare the properties of a curve.
-
+
\sa operator==()
*/
-
+
/*!
Returns the amplitude. This is not applicable for all curve types.
It is only applicable for bounce and elastic curves (curves of type()
@@ -664,8 +664,8 @@ qreal QEasingCurve::amplitude() const
/*!
Sets the amplitude to \a amplitude.
-
- This will set the amplitude of the bounce or the amplitude of the
+
+ This will set the amplitude of the bounce or the amplitude of the
elastic "spring" effect. The higher the number, the higher the amplitude.
\sa amplitude()
*/
@@ -688,7 +688,7 @@ qreal QEasingCurve::period() const
/*!
Sets the period to \a period.
- Setting a small period value will give a high frequency of the curve. A
+ Setting a small period value will give a high frequency of the curve. A
large period will give it a small frequency.
\sa period()
@@ -745,7 +745,7 @@ void QEasingCurvePrivate::setType_helper(QEasingCurve::Type newType)
delete config;
config = 0;
}
-
+
if (isConfigFunction(newType) || (amp != -1.0) || (period != -1.0) || (overshoot != -1.0)) {
config = curveToFunctionObject(newType);
if (amp != -1.0)
@@ -800,7 +800,7 @@ void QEasingCurve::setCustomType(EasingFunction func)
/*!
Returns the function pointer to the custom easing curve.
- If type() does not return QEasingCurve::Custom, this function
+ If type() does not return QEasingCurve::Custom, this function
will return 0.
*/
QEasingCurve::EasingFunction QEasingCurve::customType() const
@@ -830,7 +830,7 @@ qreal QEasingCurve::valueForProgress(qreal progress) const
#include <QtCore/QString>
QDebug operator<<(QDebug debug, const QEasingCurve &item)
{
- debug << "type:" << item.d_ptr->type
+ debug << "type:" << item.d_ptr->type
<< "func:" << item.d_ptr->func;
if (item.d_ptr->config) {
debug << QString::fromAscii("period:%1").arg(item.d_ptr->config->_p, 0, 'f', 20)