1/****************************************************************************
2**
3** Copyright (C) 2015 The Qt Company Ltd.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the documentation of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:FDL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://www.qt.io/contact-us.
16**
17** GNU Free Documentation License Usage
18** Alternatively, this file may be used under the terms of the GNU Free
19** Documentation License version 1.3 as published by the Free Software
20** Foundation and appearing in the file included in the packaging of
21** this file.  Please review the following information to ensure
22** the GNU Free Documentation License version 1.3 requirements
23** will be met: http://www.gnu.org/copyleft/fdl.html.
24** $QT_END_LICENSE$
25**
26****************************************************************************/
27
28/*!
29    \group animation
30    \title Animation Framework
31*/
32
33/*!
34    \page animation-overview.html
35    \title The Animation Framework
36    \ingroup qt-gui-concepts
37
38    \brief An overview of the Animation Framework
39
40    \ingroup frameworks-technologies
41
42    \keyword Animation
43
44    The animation framework is part of the Kinetic project, and aims
45    to provide an easy way for creating animated and smooth GUI's.  By
46    animating Qt properties, the framework provides great freedom for
47    animating widgets and other \l{QObject}s. The framework can also
48    be used with the Graphics View framework.
49
50    In this overview, we explain the basics of its architecture. We
51    also show examples of the most common techniques that the
52    framework allows for animating QObjects and graphics items.
53
54    \tableofcontents
55
56    \section1 The Animation Architecture
57
58    We will in this section take a high-level look at the animation
59    framework's architecture and how it is used to animate Qt
60    properties. The following diagram shows the most important classes
61    in the animation framework.
62
63    \image animations-architecture.png
64
65    The animation framework foundation consists of the base class
66    QAbstractAnimation, and its two subclasses QVariantAnimation and
67    QAnimationGroup. QAbstractAnimation is the ancestor of all
68    animations. It represents basic properties that are common for all
69    animations in the framework; notably, the ability to start, stop,
70    and pause an animation. It is also receives the time change
71    notifications.
72
73    The animation framework further provides the QPropertyAnimation
74    class, which inherits QVariantAnimation and performs animation of
75    a Qt property, which is part of Qt's \l{Meta-Object
76    System}{meta-object system}. The class performs an interpolation
77    over the property using an easing curve. So when you want to
78    animate a value, you can declare it as a property and make your
79    class a QObject. Note that this gives us great freedom in
80    animating already existing widgets and other \l{QObject}s.
81
82    Complex animations can be constructed by building a tree structure
83    of \l{QAbstractAnimation}s. The tree is built by using
84    \l{QAnimationGroup}s, which function as containers for other
85    animations. Note also that the groups are subclasses of
86    QAbstractAnimation, so groups can themselves contain other groups.
87
88    The animation framework can be used on its own, but is also
89    designed to be part of the state machine framework (See the
90    \l{The State Machine Framework}{state machine framework} for an
91    introduction to the Qt state machine). The state machine provides
92    a special state that can play an animation. A QState can also set
93    properties when the state is entered or exited, and this special
94    animation state will interpolate between these values when given a
95    QPropertyAnimation. We will look more closely at this later.
96
97    Behind the scenes, the animations are controlled by a global
98    timer, which sends \l{QAbstractAnimation::updateCurrentTime()}{updates} to
99    all animations that are playing.
100
101    For detailed descriptions of the classes' function and roles in
102    the framework, please look up their class descriptions.
103
104    \section1 Classes in the Animation Framework
105
106    These classes provide a framework for creating both simple and complex
107    animations.
108
109    \annotatedlist animation
110
111    \section1 Animating Qt Properties
112
113    As mentioned in the previous section, the QPropertyAnimation class
114    can interpolate over Qt properties. It is this class that should
115    be used for animation of values; in fact, its superclass,
116    QVariantAnimation, is an abstract class, and cannot be used
117    directly.
118
119    A major reason we chose to animate Qt properties is that it
120    presents us with freedom to animate already existing classes in
121    the Qt API. Notably, the QWidget class (which we can also embed in
122    a QGraphicsView) has properties for its bounds, colors, etc.
123    Let's look at a small example:
124
125    \code
126        QPushButton button("Animated Button");
127        button.show();
128
129        QPropertyAnimation animation(&button, "geometry");
130        animation.setDuration(10000);
131        animation.setStartValue(QRect(0, 0, 100, 30));
132        animation.setEndValue(QRect(250, 250, 100, 30));
133
134        animation.start();
135    \endcode
136
137    This code will move \c button from the top left corner of the
138    screen to the position (250, 250) in 10 seconds (10000 milliseconds).
139
140    The example above will do a linear interpolation between the
141    start and end value. It is also possible to set values
142    situated between the start and end value. The interpolation
143    will then go by these points.
144
145    \code
146        QPushButton button("Animated Button");
147        button.show();
148
149        QPropertyAnimation animation(&button, "geometry");
150        animation.setDuration(10000);
151
152        animation.setKeyValueAt(0, QRect(0, 0, 100, 30));
153        animation.setKeyValueAt(0.8, QRect(250, 250, 100, 30));
154        animation.setKeyValueAt(1, QRect(0, 0, 100, 30));
155
156        animation.start();
157    \endcode
158
159    In this example, the animation will take the button to (250, 250)
160    in 8 seconds, and then move it back to its original position in
161    the remaining 2 seconds. The movement will be linearly
162    interpolated between these points.
163
164    You also have the possibility to animate values of a QObject
165    that is not declared as a Qt property. The only requirement is
166    that this value has a setter. You can then subclass the class
167    containing the value and declare a property that uses this setter.
168    Note that each Qt property requires a getter, so you will need to
169    provide a getter yourself if this is not defined.
170
171    \code
172        class MyGraphicsRectItem : public QObject, public QGraphicsRectItem
173        {
174            Q_OBJECT
175            Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry)
176        };
177    \endcode
178
179    In the above code example, we subclass QGraphicsRectItem and
180    define a geometry property. We can now animate the widgets
181    geometry even if QGraphicsRectItem does not provide the geometry
182    property.
183
184    For a general introduction to the Qt property system, see its
185    \l{Qt's Property System}{overview}.
186
187    \section1 Animations and the Graphics View Framework
188
189    When you want to animate \l{QGraphicsItem}s, you also use
190    QPropertyAnimation. However, QGraphicsItem does not inherit QObject.
191    A good solution is to subclass the graphics item you wish to animate.
192    This class will then also inherit QObject.
193    This way, QPropertyAnimation can be used for \l{QGraphicsItem}s.
194    The example below shows how this is done. Another possibility is
195    to inherit QGraphicsWidget, which already is a QObject.
196
197    \code
198        class Pixmap : public QObject, public QGraphicsPixmapItem
199        {
200            Q_OBJECT
201            Q_PROPERTY(QPointF pos READ pos WRITE setPos)
202            ...
203    \endcode
204
205    As described in the previous section, we need to define
206    properties that we wish to animate.
207
208    Note that QObject must be the first class inherited as the
209    meta-object system demands this.
210
211    \section1 Easing Curves
212
213    As mentioned, QPropertyAnimation performs an interpolation between
214    the start and end property value. In addition to adding more key
215    values to the animation, you can also use an easing curve. Easing
216    curves describe a function that controls how the speed of the
217    interpolation between 0 and 1 should be, and are useful if you
218    want to control the speed of an animation without changing the
219    path of the interpolation.
220
221    \code
222        QPushButton button("Animated Button");
223        button.show();
224
225        QPropertyAnimation animation(&button, "geometry");
226        animation.setDuration(3000);
227        animation.setStartValue(QRect(0, 0, 100, 30));
228        animation.setEndValue(QRect(250, 250, 100, 30));
229
230        animation.setEasingCurve(QEasingCurve::OutBounce);
231
232        animation.start();
233    \endcode
234
235    Here the animation will follow a curve that makes it bounce like a
236    ball as if it was dropped from the start to the end position.
237    QEasingCurve has a large collection of curves for you to choose
238    from. These are defined by the QEasingCurve::Type enum. If you are
239    in need of another curve, you can also implement one yourself, and
240    register it with QEasingCurve.
241
242    \omit Drop this for the first Lab release
243    (Example of custom easing curve (without the actual impl of
244    the function I expect)
245    \endomit
246
247    \section1 Putting Animations Together
248
249    An application will often contain more than one animation. For
250    instance, you might want to move more than one graphics item
251    simultaneously or move them in sequence after each other.
252
253    The subclasses of QAnimationGroup (QSequentialAnimationGroup and
254    QParallelAnimationGroup) are containers for other animations so
255    that these animations can be animated either in sequence or
256    parallel. The QAnimationGroup is an example of an animation that
257    does not animate properties, but it gets notified of time changes
258    periodically. This enables it to forward those time changes to its
259    contained animations, and thereby controlling when its animations
260    are played.
261
262    Let's look at code examples that use both
263    QSequentialAnimationGroup and QParallelAnimationGroup, starting
264    off with the latter.
265
266    \code
267        QPushButton *bonnie = new QPushButton("Bonnie");
268        bonnie->show();
269
270        QPushButton *clyde = new QPushButton("Clyde");
271        clyde->show();
272
273        QPropertyAnimation *anim1 = new QPropertyAnimation(bonnie, "geometry");
274        // Set up anim1
275
276        QPropertyAnimation *anim2 = new QPropertyAnimation(clyde, "geometry");
277        // Set up anim2
278
279        QParallelAnimationGroup *group = new QParallelAnimationGroup;
280        group->addAnimation(anim1);
281        group->addAnimation(anim2);
282
283        group->start();
284    \endcode
285
286    A parallel group plays more than one animation at the same time.
287    Calling its \l{QAbstractAnimation::}{start()} function will start
288    all animations it governs.
289
290    \code
291        QPushButton button("Animated Button");
292        button.show();
293
294        QPropertyAnimation anim1(&button, "geometry");
295        anim1.setDuration(3000);
296        anim1.setStartValue(QRect(0, 0, 100, 30));
297        anim1.setEndValue(QRect(500, 500, 100, 30));
298
299        QPropertyAnimation anim2(&button, "geometry");
300        anim2.setDuration(3000);
301        anim2.setStartValue(QRect(500, 500, 100, 30));
302        anim2.setEndValue(QRect(1000, 500, 100, 30));
303
304        QSequentialAnimationGroup group;
305
306        group.addAnimation(&anim1);
307        group.addAnimation(&anim2);
308
309        group.start();
310    \endcode
311
312    As you no doubt have guessed, QSequentialAnimationGroup plays
313    its animations in sequence. It starts the next animation in
314    the list after the previous is finished.
315
316    Since an animation group is an animation itself, you can add
317    it to another group. This way, you can build a tree structure
318    of animations which specifies when the animations are played
319    in relation to each other.
320
321    \section1 Animations and States
322
323    When using a \l{The State Machine Framework}{state machine}, we
324    can associate one or more animations to a transition between states
325    using a QSignalTransition or QEventTransition class. These classes
326    are both derived from QAbstractTransition, which defines the
327    convenience function \l{QAbstractTransition::}{addAnimation()} that
328    enables the appending of one or more animations triggered when the
329    transition occurs.
330
331    We also have the possibility to associate properties with the
332    states rather than setting the start and end values ourselves.
333    Below is a complete code example that animates the geometry of a
334    QPushButton.
335
336    \code
337        QPushButton *button = new QPushButton("Animated Button");
338        button->show();
339
340        QStateMachine *machine = new QStateMachine;
341
342        QState *state1 = new QState(machine);
343        state1->assignProperty(button, "geometry", QRect(0, 0, 100, 30));
344        machine->setInitialState(state1);
345
346        QState *state2 = new QState(machine);
347        state2->assignProperty(button, "geometry", QRect(250, 250, 100, 30));
348
349        QSignalTransition *transition1 = state1->addTransition(button,
350            SIGNAL(clicked()), state2);
351        transition1->addAnimation(new QPropertyAnimation(button, "geometry"));
352
353        QSignalTransition *transition2 = state2->addTransition(button,
354            SIGNAL(clicked()), state1);
355        transition2->addAnimation(new QPropertyAnimation(button, "geometry"));
356
357        machine->start();
358    \endcode
359
360    For a more comprehensive example of how to use the state machine
361    framework for animations, see the states example (it lives in the
362    \c{examples/animation/states} directory).
363*/
364
365