Move the animation overview doc into QtCore
authorLars Knoll <lars.knoll@nokia.com>
Thu, 16 Aug 2012 07:43:27 +0000 (09:43 +0200)
committerQt by Nokia <qt-info@nokia.com>
Sat, 18 Aug 2012 06:34:53 +0000 (08:34 +0200)
Moved here from the qtdoc module.

Change-Id: Ib263848e0637204ec3b0cba973076ca79a25a953
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
src/corelib/doc/images/animations-architecture.png [new file with mode: 0644]
src/corelib/doc/src/animation.qdoc [new file with mode: 0644]

diff --git a/src/corelib/doc/images/animations-architecture.png b/src/corelib/doc/images/animations-architecture.png
new file mode 100644 (file)
index 0000000..9b581af
Binary files /dev/null and b/src/corelib/doc/images/animations-architecture.png differ
diff --git a/src/corelib/doc/src/animation.qdoc b/src/corelib/doc/src/animation.qdoc
new file mode 100644 (file)
index 0000000..eff606f
--- /dev/null
@@ -0,0 +1,364 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms
+** and conditions contained in a signed written agreement between you
+** and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+    \group animation
+    \title Animation Framework
+*/
+
+/*!
+    \page animation-overview.html
+    \title The Animation Framework
+    \ingroup qt-gui-concepts
+
+    \brief An overview of the Animation Framework
+
+    \ingroup frameworks-technologies
+
+    \keyword Animation
+
+    The animation framework is part of the Kinetic project, and aims
+    to provide an easy way for creating animated and smooth GUI's.  By
+    animating Qt properties, the framework provides great freedom for
+    animating widgets and other \l{QObject}s. The framework can also
+    be used with the Graphics View framework.
+
+    In this overview, we explain the basics of its architecture. We
+    also show examples of the most common techniques that the
+    framework allows for animating QObjects and graphics items.
+
+    \tableofcontents
+
+    \section1 The Animation Architecture
+
+    We will in this section take a high-level look at the animation
+    framework's architecture and how it is used to animate Qt
+    properties. The following diagram shows the most important classes
+    in the animation framework.
+
+    \image animations-architecture.png
+
+    The animation framework foundation consists of the base class
+    QAbstractAnimation, and its two subclasses QVariantAnimation and
+    QAnimationGroup. QAbstractAnimation is the ancestor of all
+    animations. It represents basic properties that are common for all
+    animations in the framework; notably, the ability to start, stop,
+    and pause an animation. It is also receives the time change
+    notifications.
+
+    The animation framework further provides the QPropertyAnimation
+    class, which inherits QVariantAnimation and performs animation of
+    a Qt property, which is part of Qt's \l{Meta-Object
+    System}{meta-object system}. The class performs an interpolation
+    over the property using an easing curve. So when you want to
+    animate a value, you can declare it as a property and make your
+    class a QObject. Note that this gives us great freedom in
+    animating already existing widgets and other \l{QObject}s.
+
+    Complex animations can be constructed by building a tree structure
+    of \l{QAbstractAnimation}s. The tree is built by using
+    \l{QAnimationGroup}s, which function as containers for other
+    animations. Note also that the groups are subclasses of
+    QAbstractAnimation, so groups can themselves contain other groups.
+
+    The animation framework can be used on its own, but is also
+    designed to be part of the state machine framework (See the
+    \l{The State Machine Framework}{state machine framework} for an
+    introduction to the Qt state machine). The state machine provides
+    a special state that can play an animation. A QState can also set
+    properties when the state is entered or exited, and this special
+    animation state will interpolate between these values when given a
+    QPropertyAnimation. We will look more closely at this later.
+
+    Behind the scenes, the animations are controlled by a global
+    timer, which sends \l{QAbstractAnimation::updateCurrentTime()}{updates} to
+    all animations that are playing.
+
+    For detailed descriptions of the classes' function and roles in
+    the framework, please look up their class descriptions.
+
+    \section1 Classes in the Animation Framework
+    
+    These classes provide a framework for creating both simple and complex
+    animations.
+
+    \annotatedlist animation
+
+    \section1 Animating Qt Properties
+
+    As mentioned in the previous section, the QPropertyAnimation class
+    can interpolate over Qt properties. It is this class that should
+    be used for animation of values; in fact, its superclass,
+    QVariantAnimation, is an abstract class, and cannot be used
+    directly.
+
+    A major reason we chose to animate Qt properties is that it
+    presents us with freedom to animate already existing classes in
+    the Qt API. Notably, the QWidget class (which we can also embed in
+    a QGraphicsView) has properties for its bounds, colors, etc.
+    Let's look at a small example:
+
+    \code
+        QPushButton button("Animated Button");
+        button.show();
+
+        QPropertyAnimation animation(&button, "geometry");
+        animation.setDuration(10000);
+        animation.setStartValue(QRect(0, 0, 100, 30));
+        animation.setEndValue(QRect(250, 250, 100, 30));
+
+        animation.start();
+    \endcode
+
+    This code will move \c button from the top left corner of the
+    screen to the position (250, 250) in 10 seconds (10000 milliseconds).
+
+    The example above will do a linear interpolation between the
+    start and end value. It is also possible to set values
+    situated between the start and end value. The interpolation
+    will then go by these points.
+
+    \code
+        QPushButton button("Animated Button");
+        button.show();
+
+        QPropertyAnimation animation(&button, "geometry");
+        animation.setDuration(10000);
+
+        animation.setKeyValueAt(0, QRect(0, 0, 100, 30));
+        animation.setKeyValueAt(0.8, QRect(250, 250, 100, 30));
+        animation.setKeyValueAt(1, QRect(0, 0, 100, 30));
+
+        animation.start();
+    \endcode
+
+    In this example, the animation will take the button to (250, 250)
+    in 8 seconds, and then move it back to its original position in
+    the remaining 2 seconds. The movement will be linearly
+    interpolated between these points.
+
+    You also have the possibility to animate values of a QObject
+    that is not declared as a Qt property. The only requirement is
+    that this value has a setter. You can then subclass the class
+    containing the value and declare a property that uses this setter.
+    Note that each Qt property requires a getter, so you will need to
+    provide a getter yourself if this is not defined.
+
+    \code
+        class MyGraphicsRectItem : public QObject, public QGraphicsRectItem
+        {
+            Q_OBJECT
+            Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry)
+        };
+    \endcode
+
+    In the above code example, we subclass QGraphicsRectItem and
+    define a geometry property. We can now animate the widgets
+    geometry even if QGraphicsRectItem does not provide the geometry
+    property.
+
+    For a general introduction to the Qt property system, see its
+    \l{Qt's Property System}{overview}.
+
+    \section1 Animations and the Graphics View Framework
+
+    When you want to animate \l{QGraphicsItem}s, you also use
+    QPropertyAnimation. However, QGraphicsItem does not inherit QObject.
+    A good solution is to subclass the graphics item you wish to animate.
+    This class will then also inherit QObject.
+    This way, QPropertyAnimation can be used for \l{QGraphicsItem}s.
+    The example below shows how this is done. Another possibility is
+    to inherit QGraphicsWidget, which already is a QObject.
+
+    \code
+        class Pixmap : public QObject, public QGraphicsPixmapItem
+        {
+            Q_OBJECT
+            Q_PROPERTY(QPointF pos READ pos WRITE setPos)
+            ...
+    \endcode
+
+    As described in the previous section, we need to define
+    properties that we wish to animate.
+
+    Note that QObject must be the first class inherited as the
+    meta-object system demands this.
+
+    \section1 Easing Curves
+
+    As mentioned, QPropertyAnimation performs an interpolation between
+    the start and end property value. In addition to adding more key
+    values to the animation, you can also use an easing curve. Easing
+    curves describe a function that controls how the speed of the
+    interpolation between 0 and 1 should be, and are useful if you
+    want to control the speed of an animation without changing the
+    path of the interpolation.
+
+    \code
+        QPushButton button("Animated Button");
+        button.show();
+
+        QPropertyAnimation animation(&button, "geometry");
+        animation.setDuration(3000);
+        animation.setStartValue(QRect(0, 0, 100, 30));
+        animation.setEndValue(QRect(250, 250, 100, 30));
+
+        animation.setEasingCurve(QEasingCurve::OutBounce);
+
+        animation.start();
+    \endcode
+
+    Here the animation will follow a curve that makes it bounce like a
+    ball as if it was dropped from the start to the end position.
+    QEasingCurve has a large collection of curves for you to choose
+    from. These are defined by the QEasingCurve::Type enum. If you are
+    in need of another curve, you can also implement one yourself, and
+    register it with QEasingCurve.
+
+    \omit Drop this for the first Lab release
+    (Example of custom easing curve (without the actual impl of
+    the function I expect)
+    \endomit
+
+    \section1 Putting Animations Together
+
+    An application will often contain more than one animation. For
+    instance, you might want to move more than one graphics item
+    simultaneously or move them in sequence after each other.
+
+    The subclasses of QAnimationGroup (QSequentialAnimationGroup and
+    QParallelAnimationGroup) are containers for other animations so
+    that these animations can be animated either in sequence or
+    parallel. The QAnimationGroup is an example of an animation that
+    does not animate properties, but it gets notified of time changes
+    periodically. This enables it to forward those time changes to its
+    contained animations, and thereby controlling when its animations
+    are played.
+
+    Let's look at code examples that use both
+    QSequentialAnimationGroup and QParallelAnimationGroup, starting
+    off with the latter.
+
+    \code
+        QPushButton *bonnie = new QPushButton("Bonnie");
+        bonnie->show();
+
+        QPushButton *clyde = new QPushButton("Clyde");
+        clyde->show();
+
+        QPropertyAnimation *anim1 = new QPropertyAnimation(bonnie, "geometry");
+        // Set up anim1
+
+        QPropertyAnimation *anim2 = new QPropertyAnimation(clyde, "geometry");
+        // Set up anim2
+
+        QParallelAnimationGroup *group = new QParallelAnimationGroup;
+        group->addAnimation(anim1);
+        group->addAnimation(anim2);
+
+        group->start();
+    \endcode
+
+    A parallel group plays more than one animation at the same time.
+    Calling its \l{QAbstractAnimation::}{start()} function will start
+    all animations it governs.
+
+    \code
+        QPushButton button("Animated Button");
+        button.show();
+
+        QPropertyAnimation anim1(&button, "geometry");
+        anim1.setDuration(3000);
+        anim1.setStartValue(QRect(0, 0, 100, 30));
+        anim1.setEndValue(QRect(500, 500, 100, 30));
+
+        QPropertyAnimation anim2(&button, "geometry");
+        anim2.setDuration(3000);
+        anim2.setStartValue(QRect(500, 500, 100, 30));
+        anim2.setEndValue(QRect(1000, 500, 100, 30));
+
+        QSequentialAnimationGroup group;
+
+        group.addAnimation(&anim1);
+        group.addAnimation(&anim2);
+
+        group.start();
+    \endcode
+
+    As you no doubt have guessed, QSequentialAnimationGroup plays
+    its animations in sequence. It starts the next animation in
+    the list after the previous is finished.
+
+    Since an animation group is an animation itself, you can add
+    it to another group. This way, you can build a tree structure
+    of animations which specifies when the animations are played
+    in relation to each other.
+
+    \section1 Animations and States
+
+    When using a \l{The State Machine Framework}{state machine}, we
+    can associate one or more animations to a transition between states
+    using a QSignalTransition or QEventTransition class. These classes
+    are both derived from QAbstractTransition, which defines the
+    convenience function \l{QAbstractTransition::}{addAnimation()} that
+    enables the appending of one or more animations triggered when the
+    transition occurs.
+
+    We also have the possibility to associate properties with the
+    states rather than setting the start and end values ourselves.
+    Below is a complete code example that animates the geometry of a
+    QPushButton.
+
+    \code
+        QPushButton *button = new QPushButton("Animated Button");
+        button->show();
+
+        QStateMachine *machine = new QStateMachine;
+
+        QState *state1 = new QState(machine);
+        state1->assignProperty(button, "geometry", QRect(0, 0, 100, 30));
+        machine->setInitialState(state1);
+
+        QState *state2 = new QState(machine);
+        state2->assignProperty(button, "geometry", QRect(250, 250, 100, 30));
+
+        QSignalTransition *transition1 = state1->addTransition(button,
+            SIGNAL(clicked()), state2);
+        transition1->addAnimation(new QPropertyAnimation(button, "geometry"));
+
+        QSignalTransition *transition2 = state2->addTransition(button,
+            SIGNAL(clicked()), state1);
+        transition2->addAnimation(new QPropertyAnimation(button, "geometry"));
+
+        machine->start();
+    \endcode
+
+    For a more comprehensive example of how to use the state machine
+    framework for animations, see the states example (it lives in the
+    \c{examples/animation/states} directory).
+*/
+