summaryrefslogtreecommitdiffstats
path: root/doc/src
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src')
-rw-r--r--doc/src/animation.qdoc365
-rw-r--r--doc/src/diagrams/programs/easingcurve/easingcurve.pro13
-rw-r--r--doc/src/diagrams/programs/easingcurve/main.cpp90
-rw-r--r--doc/src/examples.qdoc6
-rw-r--r--doc/src/examples/trafficlight.qdoc58
-rw-r--r--doc/src/external-resources.qdoc10
-rw-r--r--doc/src/groups.qdoc23
-rw-r--r--doc/src/images/qeasingcurve-cosinecurve.pngbin0 -> 2544 bytes
-rw-r--r--doc/src/images/qeasingcurve-inback.pngbin0 -> 2225 bytes
-rw-r--r--doc/src/images/qeasingcurve-inbounce.pngbin0 -> 2378 bytes
-rw-r--r--doc/src/images/qeasingcurve-incirc.pngbin0 -> 2138 bytes
-rw-r--r--doc/src/images/qeasingcurve-incubic.pngbin0 -> 2230 bytes
-rw-r--r--doc/src/images/qeasingcurve-incurve.pngbin0 -> 2325 bytes
-rw-r--r--doc/src/images/qeasingcurve-inelastic.pngbin0 -> 2314 bytes
-rw-r--r--doc/src/images/qeasingcurve-inexpo.pngbin0 -> 2183 bytes
-rw-r--r--doc/src/images/qeasingcurve-inoutback.pngbin0 -> 2460 bytes
-rw-r--r--doc/src/images/qeasingcurve-inoutbounce.pngbin0 -> 2522 bytes
-rw-r--r--doc/src/images/qeasingcurve-inoutcirc.pngbin0 -> 2352 bytes
-rw-r--r--doc/src/images/qeasingcurve-inoutcubic.pngbin0 -> 2410 bytes
-rw-r--r--doc/src/images/qeasingcurve-inoutelastic.pngbin0 -> 2485 bytes
-rw-r--r--doc/src/images/qeasingcurve-inoutexpo.pngbin0 -> 2383 bytes
-rw-r--r--doc/src/images/qeasingcurve-inoutquad.pngbin0 -> 2392 bytes
-rw-r--r--doc/src/images/qeasingcurve-inoutquart.pngbin0 -> 2331 bytes
-rw-r--r--doc/src/images/qeasingcurve-inoutquint.pngbin0 -> 2244 bytes
-rw-r--r--doc/src/images/qeasingcurve-inoutsine.pngbin0 -> 2405 bytes
-rw-r--r--doc/src/images/qeasingcurve-inquad.pngbin0 -> 2283 bytes
-rw-r--r--doc/src/images/qeasingcurve-inquart.pngbin0 -> 2261 bytes
-rw-r--r--doc/src/images/qeasingcurve-inquint.pngbin0 -> 2178 bytes
-rw-r--r--doc/src/images/qeasingcurve-insine.pngbin0 -> 2167 bytes
-rw-r--r--doc/src/images/qeasingcurve-linear.pngbin0 -> 2165 bytes
-rw-r--r--doc/src/images/qeasingcurve-outback.pngbin0 -> 2371 bytes
-rw-r--r--doc/src/images/qeasingcurve-outbounce.pngbin0 -> 2481 bytes
-rw-r--r--doc/src/images/qeasingcurve-outcirc.pngbin0 -> 2269 bytes
-rw-r--r--doc/src/images/qeasingcurve-outcubic.pngbin0 -> 2336 bytes
-rw-r--r--doc/src/images/qeasingcurve-outcurve.pngbin0 -> 2389 bytes
-rw-r--r--doc/src/images/qeasingcurve-outelastic.pngbin0 -> 2402 bytes
-rw-r--r--doc/src/images/qeasingcurve-outexpo.pngbin0 -> 2299 bytes
-rw-r--r--doc/src/images/qeasingcurve-outinback.pngbin0 -> 2400 bytes
-rw-r--r--doc/src/images/qeasingcurve-outinbounce.pngbin0 -> 2568 bytes
-rw-r--r--doc/src/images/qeasingcurve-outincirc.pngbin0 -> 2339 bytes
-rw-r--r--doc/src/images/qeasingcurve-outincubic.pngbin0 -> 2393 bytes
-rw-r--r--doc/src/images/qeasingcurve-outinelastic.pngbin0 -> 2517 bytes
-rw-r--r--doc/src/images/qeasingcurve-outinexpo.pngbin0 -> 2377 bytes
-rw-r--r--doc/src/images/qeasingcurve-outinquad.pngbin0 -> 2380 bytes
-rw-r--r--doc/src/images/qeasingcurve-outinquart.pngbin0 -> 2319 bytes
-rw-r--r--doc/src/images/qeasingcurve-outinquint.pngbin0 -> 2248 bytes
-rw-r--r--doc/src/images/qeasingcurve-outinsine.pngbin0 -> 2388 bytes
-rw-r--r--doc/src/images/qeasingcurve-outquad.pngbin0 -> 2324 bytes
-rw-r--r--doc/src/images/qeasingcurve-outquart.pngbin0 -> 2304 bytes
-rw-r--r--doc/src/images/qeasingcurve-outquint.pngbin0 -> 2242 bytes
-rw-r--r--doc/src/images/qeasingcurve-outsine.pngbin0 -> 2364 bytes
-rw-r--r--doc/src/images/qeasingcurve-sinecurve.pngbin0 -> 2470 bytes
-rw-r--r--doc/src/images/statemachine-button-history.pngbin0 -> 8493 bytes
-rw-r--r--doc/src/images/statemachine-button-nested.pngbin0 -> 7051 bytes
-rw-r--r--doc/src/images/statemachine-button.pngbin0 -> 4233 bytes
-rw-r--r--doc/src/images/statemachine-customevents.pngbin0 -> 2544 bytes
-rw-r--r--doc/src/images/statemachine-finished.pngbin0 -> 5518 bytes
-rw-r--r--doc/src/images/statemachine-nonparallel.pngbin0 -> 5350 bytes
-rw-r--r--doc/src/images/statemachine-parallel.pngbin0 -> 8631 bytes
-rw-r--r--doc/src/images/trafficlight-example.pngbin0 -> 5325 bytes
-rw-r--r--doc/src/snippets/code/src_corelib_tools_qeasingcurve.cpp4
-rw-r--r--doc/src/statemachine.qdoc398
62 files changed, 967 insertions, 0 deletions
diff --git a/doc/src/animation.qdoc b/doc/src/animation.qdoc
new file mode 100644
index 0000000..081660c
--- /dev/null
+++ b/doc/src/animation.qdoc
@@ -0,0 +1,365 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+/*!
+ \page animation.html
+ \title The Animation Framework
+ \ingroup architecture
+ \ingroup animation
+ \brief An overview of the Animation Framework
+
+ \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 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 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).
+
+ 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 all Qt properties 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. But, unfortunetly, 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.
+
+ \warning The QItemAnimation class, which was initially intended
+ for animating \l{QGraphicsItem}s may be deprecated or removed from
+ the animation framework.
+
+ \omit (need something about the list of animations). \endomit
+
+ \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
+ have a special state, QAnimationState, that will play one or more
+ animations.
+
+ The QState::addAnimatedTransition() convenience function lets you
+ associate an animation to a state transition. The function will
+ create the QAnimationState for you, and insert it into the state
+ machine. 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->rootState());
+ state1->setPropertyOnEntry(button, "geometry",
+ QRect(0, 0, 100, 30));
+ machine->setInitialState(state1);
+
+ QState *state2 = new QState(machine->rootState());
+ state2->setPropertyOnEntry(button, "geometry",
+ QRect(250, 250, 100, 30));
+
+ state1->addAnimatedTransition(button, SIGNAL(clicked()), state2,
+ new QPropertyAnimation(button, "geometry"));
+ state2->addAnimatedTransition(button, SIGNAL(clicked()), state1,
+ 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).
+*/
+
diff --git a/doc/src/diagrams/programs/easingcurve/easingcurve.pro b/doc/src/diagrams/programs/easingcurve/easingcurve.pro
new file mode 100644
index 0000000..0b80127
--- /dev/null
+++ b/doc/src/diagrams/programs/easingcurve/easingcurve.pro
@@ -0,0 +1,13 @@
+######################################################################
+# Automatically generated by qmake (2.01a) fr 13. feb 13:26:38 2009
+######################################################################
+
+TEMPLATE = app
+TARGET =
+DEPENDPATH += .
+INCLUDEPATH += .
+
+# Input
+SOURCES += main.cpp
+
+CONFIG += console \ No newline at end of file
diff --git a/doc/src/diagrams/programs/easingcurve/main.cpp b/doc/src/diagrams/programs/easingcurve/main.cpp
new file mode 100644
index 0000000..98e9d37
--- /dev/null
+++ b/doc/src/diagrams/programs/easingcurve/main.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $TROLLTECH_DUAL_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+
+void createCurveIcons();
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ createCurveIcons();
+ return app.exit();
+}
+
+void createCurveIcons()
+{
+ QDir dir(QDir::current());
+ if (dir.dirName() == QLatin1String("debug") || dir.dirName() == QLatin1String("release")) {
+ dir.cdUp();
+ }
+ dir.cdUp();
+ dir.cdUp();
+ dir.cdUp();
+ QSize iconSize(128, 128);
+ QPixmap pix(iconSize);
+ QPainter painter(&pix);
+ QLinearGradient gradient(0,0, 0, iconSize.height());
+ gradient.setColorAt(0.0, QColor(240, 240, 240));
+ gradient.setColorAt(1.0, QColor(224, 224, 224));
+ QBrush brush(gradient);
+ const QMetaObject &mo = QEasingCurve::staticMetaObject;
+ QMetaEnum metaEnum = mo.enumerator(mo.indexOfEnumerator("Type"));
+ QFont oldFont = painter.font();
+ // Skip QEasingCurve::Custom
+ QString output(QString::fromAscii("%1/images").arg(dir.absolutePath()));
+ printf("Generating images to %s\n", qPrintable(output));
+ for (int i = 0; i < QEasingCurve::NCurveTypes - 1; ++i) {
+ painter.setFont(oldFont);
+ QString name(QLatin1String(metaEnum.key(i)));
+ painter.fillRect(QRect(QPoint(0, 0), iconSize), brush);
+ QEasingCurve curve((QEasingCurve::Type)i);
+ painter.setPen(QColor(0, 0, 255, 64));
+ qreal xAxis = iconSize.height()/1.5;
+ qreal yAxis = iconSize.width()/3;
+ painter.drawLine(0, xAxis, iconSize.width(), xAxis); // hor
+ painter.drawLine(yAxis, 0, yAxis, iconSize.height()); // ver
+
+ qreal curveScale = iconSize.height()/2;
+
+ painter.drawLine(yAxis - 2, xAxis - curveScale, yAxis + 2, xAxis - curveScale); // hor
+ painter.drawLine(yAxis + curveScale, xAxis + 2, yAxis + curveScale, xAxis - 2); // ver
+ painter.drawText(yAxis + curveScale - 8, xAxis - curveScale - 4, QLatin1String("(1,1)"));
+
+ painter.drawText(yAxis + 42, xAxis + 10, QLatin1String("progress"));
+ painter.drawText(15, xAxis - curveScale - 10, QLatin1String("ease"));
+
+ painter.setPen(QPen(Qt::red, 1, Qt::DotLine));
+ painter.drawLine(yAxis, xAxis - curveScale, yAxis + curveScale, xAxis - curveScale); // hor
+ painter.drawLine(yAxis + curveScale, xAxis, yAxis + curveScale, xAxis - curveScale); // ver
+
+ QPoint currentPos(yAxis, xAxis);
+
+ painter.setPen(Qt::black);
+ QFont font = oldFont;
+ font.setPixelSize(oldFont.pixelSize() + 15);
+ painter.setFont(font);
+ painter.drawText(0, iconSize.height() - 20, iconSize.width(), 20, Qt::AlignHCenter, name);
+
+ for (qreal t = 0; t < 1.0; t+=1.0/curveScale) {
+ QPoint to;
+ to.setX(yAxis + curveScale * t);
+ to.setY(xAxis - curveScale * curve.valueForProgress(t));
+ painter.drawLine(currentPos, to);
+ currentPos = to;
+ }
+ QString fileName(QString::fromAscii("qeasingcurve-%1.png").arg(name.toLower()));
+ printf("%s\n", qPrintable(fileName));
+ pix.save(QString::fromAscii("%1/%2").arg(output).arg(fileName), "PNG");
+ }
+}
+
+
diff --git a/doc/src/examples.qdoc b/doc/src/examples.qdoc
index 29c6c0b..06d7727 100644
--- a/doc/src/examples.qdoc
+++ b/doc/src/examples.qdoc
@@ -308,6 +308,12 @@
\o \l{sql/sqlwidgetmapper}{SQL Widget Mapper}\raisedaster
\endlist
+ \section1 State Machine
+
+ \list
+ \o \l{statemachine/trafficlight}{Traffic Light}\raisedaster
+ \endlist
+
\section1 Threads
\list
diff --git a/doc/src/examples/trafficlight.qdoc b/doc/src/examples/trafficlight.qdoc
new file mode 100644
index 0000000..16ee8ad
--- /dev/null
+++ b/doc/src/examples/trafficlight.qdoc
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $TROLLTECH_DUAL_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example statemachine/trafficlight
+ \title Traffic Light Example
+
+ The Traffic Light example shows how to use \l{The State Machine Framework}
+ to implement the control flow of a traffic light.
+
+ \image trafficlight-example.png
+
+ In this example we write a TrafficLightWidget class. The traffic light has
+ three lights: Red, yellow and green. The traffic light transitions from
+ one light to another (red to yellow to green to yellow to red again) at
+ certain intervals.
+
+ \snippet examples/statemachine/trafficlight/main.cpp 0
+
+ The LightWidget class represents a single light of the traffic light. It
+ provides a setOn() function to turn the light on or off. It paints itself
+ in the color that's passed to the constructor.
+
+ \snippet examples/statemachine/trafficlight/main.cpp 2
+
+ The TrafficLightWidget class represents the visual part of the traffic
+ light; it's a widget that contains three lights, and provides accessor
+ functions for these.
+
+ \snippet examples/statemachine/trafficlight/main.cpp 1
+
+ The LightState class represents a state that turns a light on when the
+ state is entered, and off when the state is exited. The class is a timer,
+ and as we shall see the timeout is used to transition from one LightState
+ to another.
+
+ \snippet examples/statemachine/trafficlight/main.cpp 3
+
+ The TrafficLight class combines the TrafficLightWidget with control flow
+ based on the LightState class. The state graph has four states:
+ red-to-yellow, yellow-to-green, green-to-yellow and yellow-to-red. The
+ initial state is red-to-yellow; when the state's timer times out, the
+ state machine transitions to yellow-to-green. The same process repeats
+ through the other states.
+
+ \snippet examples/statemachine/trafficlight/main.cpp 4
+
+ The main() function constructs a TrafficLight and shows it.
+
+*/
diff --git a/doc/src/external-resources.qdoc b/doc/src/external-resources.qdoc
index f48c3d7..3bfb5af 100644
--- a/doc/src/external-resources.qdoc
+++ b/doc/src/external-resources.qdoc
@@ -334,6 +334,16 @@
*/
/*!
+ \externalpage http://www.w3.org/TR/scxml/
+ \title State Chart XML: State Machine Notation for Control Abstraction
+*/
+
+/*!
+ \externalpage http://www.wisdom.weizmann.ac.il/~dharel/SCANNED.PAPERS/Statecharts.pdf
+ \title Statecharts: A visual formalism for complex systems
+*/
+
+/*!
\externalpage http://www.gnu.org/licenses/gpl.html
\title GNU General Public License
*/
diff --git a/doc/src/groups.qdoc b/doc/src/groups.qdoc
index c9cedc4..0411c3a 100644
--- a/doc/src/groups.qdoc
+++ b/doc/src/groups.qdoc
@@ -69,6 +69,18 @@
*/
/*!
+ \group animations
+ \ingroup groups
+
+ \title Animation Framework
+ \brief Classes for animations, states and transitions.
+
+ These classes provide a framework for creating both simple and complex
+ animations. The Animation Framework also provides states and animated
+ transitions, making it easy to create animated stateful forms.
+*/
+
+/*!
\group abstractwidgets
\title Abstract Widget Classes
\ingroup groups
@@ -597,3 +609,14 @@
These classes are relevant to developers who are working with Qt Script's
debugging features.
*/
+
+/*!
+ \group statemachine
+ \ingroup groups
+
+ \title State Machine Classes
+ \brief Classes for constructing and executing state graphs.
+
+ These classes are provided by \l{The State Machine Framework} for creating
+ event-driven state machines.
+*/
diff --git a/doc/src/images/qeasingcurve-cosinecurve.png b/doc/src/images/qeasingcurve-cosinecurve.png
new file mode 100644
index 0000000..b27e763
--- /dev/null
+++ b/doc/src/images/qeasingcurve-cosinecurve.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-inback.png b/doc/src/images/qeasingcurve-inback.png
new file mode 100644
index 0000000..8506c0f
--- /dev/null
+++ b/doc/src/images/qeasingcurve-inback.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-inbounce.png b/doc/src/images/qeasingcurve-inbounce.png
new file mode 100644
index 0000000..275b38c
--- /dev/null
+++ b/doc/src/images/qeasingcurve-inbounce.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-incirc.png b/doc/src/images/qeasingcurve-incirc.png
new file mode 100644
index 0000000..b985e9c
--- /dev/null
+++ b/doc/src/images/qeasingcurve-incirc.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-incubic.png b/doc/src/images/qeasingcurve-incubic.png
new file mode 100644
index 0000000..e417ee1
--- /dev/null
+++ b/doc/src/images/qeasingcurve-incubic.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-incurve.png b/doc/src/images/qeasingcurve-incurve.png
new file mode 100644
index 0000000..d9a9340
--- /dev/null
+++ b/doc/src/images/qeasingcurve-incurve.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-inelastic.png b/doc/src/images/qeasingcurve-inelastic.png
new file mode 100644
index 0000000..b242fd3
--- /dev/null
+++ b/doc/src/images/qeasingcurve-inelastic.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-inexpo.png b/doc/src/images/qeasingcurve-inexpo.png
new file mode 100644
index 0000000..f06316c
--- /dev/null
+++ b/doc/src/images/qeasingcurve-inexpo.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-inoutback.png b/doc/src/images/qeasingcurve-inoutback.png
new file mode 100644
index 0000000..9fd1446
--- /dev/null
+++ b/doc/src/images/qeasingcurve-inoutback.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-inoutbounce.png b/doc/src/images/qeasingcurve-inoutbounce.png
new file mode 100644
index 0000000..fb65f31
--- /dev/null
+++ b/doc/src/images/qeasingcurve-inoutbounce.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-inoutcirc.png b/doc/src/images/qeasingcurve-inoutcirc.png
new file mode 100644
index 0000000..123cc54
--- /dev/null
+++ b/doc/src/images/qeasingcurve-inoutcirc.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-inoutcubic.png b/doc/src/images/qeasingcurve-inoutcubic.png
new file mode 100644
index 0000000..b07695c
--- /dev/null
+++ b/doc/src/images/qeasingcurve-inoutcubic.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-inoutelastic.png b/doc/src/images/qeasingcurve-inoutelastic.png
new file mode 100644
index 0000000..65851e1
--- /dev/null
+++ b/doc/src/images/qeasingcurve-inoutelastic.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-inoutexpo.png b/doc/src/images/qeasingcurve-inoutexpo.png
new file mode 100644
index 0000000..7cbfb13
--- /dev/null
+++ b/doc/src/images/qeasingcurve-inoutexpo.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-inoutquad.png b/doc/src/images/qeasingcurve-inoutquad.png
new file mode 100644
index 0000000..c5eed06
--- /dev/null
+++ b/doc/src/images/qeasingcurve-inoutquad.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-inoutquart.png b/doc/src/images/qeasingcurve-inoutquart.png
new file mode 100644
index 0000000..3b66c0d
--- /dev/null
+++ b/doc/src/images/qeasingcurve-inoutquart.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-inoutquint.png b/doc/src/images/qeasingcurve-inoutquint.png
new file mode 100644
index 0000000..c74efe9
--- /dev/null
+++ b/doc/src/images/qeasingcurve-inoutquint.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-inoutsine.png b/doc/src/images/qeasingcurve-inoutsine.png
new file mode 100644
index 0000000..5964f31
--- /dev/null
+++ b/doc/src/images/qeasingcurve-inoutsine.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-inquad.png b/doc/src/images/qeasingcurve-inquad.png
new file mode 100644
index 0000000..3373310
--- /dev/null
+++ b/doc/src/images/qeasingcurve-inquad.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-inquart.png b/doc/src/images/qeasingcurve-inquart.png
new file mode 100644
index 0000000..28086d8
--- /dev/null
+++ b/doc/src/images/qeasingcurve-inquart.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-inquint.png b/doc/src/images/qeasingcurve-inquint.png
new file mode 100644
index 0000000..330aa85
--- /dev/null
+++ b/doc/src/images/qeasingcurve-inquint.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-insine.png b/doc/src/images/qeasingcurve-insine.png
new file mode 100644
index 0000000..63d9238
--- /dev/null
+++ b/doc/src/images/qeasingcurve-insine.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-linear.png b/doc/src/images/qeasingcurve-linear.png
new file mode 100644
index 0000000..2a05885
--- /dev/null
+++ b/doc/src/images/qeasingcurve-linear.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-outback.png b/doc/src/images/qeasingcurve-outback.png
new file mode 100644
index 0000000..7cb34c6
--- /dev/null
+++ b/doc/src/images/qeasingcurve-outback.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-outbounce.png b/doc/src/images/qeasingcurve-outbounce.png
new file mode 100644
index 0000000..932fc16
--- /dev/null
+++ b/doc/src/images/qeasingcurve-outbounce.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-outcirc.png b/doc/src/images/qeasingcurve-outcirc.png
new file mode 100644
index 0000000..a1a6cb6
--- /dev/null
+++ b/doc/src/images/qeasingcurve-outcirc.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-outcubic.png b/doc/src/images/qeasingcurve-outcubic.png
new file mode 100644
index 0000000..aa1d604
--- /dev/null
+++ b/doc/src/images/qeasingcurve-outcubic.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-outcurve.png b/doc/src/images/qeasingcurve-outcurve.png
new file mode 100644
index 0000000..a949ae4
--- /dev/null
+++ b/doc/src/images/qeasingcurve-outcurve.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-outelastic.png b/doc/src/images/qeasingcurve-outelastic.png
new file mode 100644
index 0000000..2a9ba39
--- /dev/null
+++ b/doc/src/images/qeasingcurve-outelastic.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-outexpo.png b/doc/src/images/qeasingcurve-outexpo.png
new file mode 100644
index 0000000..e771c2e
--- /dev/null
+++ b/doc/src/images/qeasingcurve-outexpo.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-outinback.png b/doc/src/images/qeasingcurve-outinback.png
new file mode 100644
index 0000000..7523727
--- /dev/null
+++ b/doc/src/images/qeasingcurve-outinback.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-outinbounce.png b/doc/src/images/qeasingcurve-outinbounce.png
new file mode 100644
index 0000000..ab73d02
--- /dev/null
+++ b/doc/src/images/qeasingcurve-outinbounce.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-outincirc.png b/doc/src/images/qeasingcurve-outincirc.png
new file mode 100644
index 0000000..ec4b8d3
--- /dev/null
+++ b/doc/src/images/qeasingcurve-outincirc.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-outincubic.png b/doc/src/images/qeasingcurve-outincubic.png
new file mode 100644
index 0000000..8b8ae68
--- /dev/null
+++ b/doc/src/images/qeasingcurve-outincubic.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-outinelastic.png b/doc/src/images/qeasingcurve-outinelastic.png
new file mode 100644
index 0000000..89dde2c
--- /dev/null
+++ b/doc/src/images/qeasingcurve-outinelastic.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-outinexpo.png b/doc/src/images/qeasingcurve-outinexpo.png
new file mode 100644
index 0000000..5909901
--- /dev/null
+++ b/doc/src/images/qeasingcurve-outinexpo.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-outinquad.png b/doc/src/images/qeasingcurve-outinquad.png
new file mode 100644
index 0000000..7ddefee
--- /dev/null
+++ b/doc/src/images/qeasingcurve-outinquad.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-outinquart.png b/doc/src/images/qeasingcurve-outinquart.png
new file mode 100644
index 0000000..00ef597
--- /dev/null
+++ b/doc/src/images/qeasingcurve-outinquart.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-outinquint.png b/doc/src/images/qeasingcurve-outinquint.png
new file mode 100644
index 0000000..361bfaa4
--- /dev/null
+++ b/doc/src/images/qeasingcurve-outinquint.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-outinsine.png b/doc/src/images/qeasingcurve-outinsine.png
new file mode 100644
index 0000000..1737041
--- /dev/null
+++ b/doc/src/images/qeasingcurve-outinsine.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-outquad.png b/doc/src/images/qeasingcurve-outquad.png
new file mode 100644
index 0000000..6f27cbd
--- /dev/null
+++ b/doc/src/images/qeasingcurve-outquad.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-outquart.png b/doc/src/images/qeasingcurve-outquart.png
new file mode 100644
index 0000000..d45a0b8
--- /dev/null
+++ b/doc/src/images/qeasingcurve-outquart.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-outquint.png b/doc/src/images/qeasingcurve-outquint.png
new file mode 100644
index 0000000..6e7df0e
--- /dev/null
+++ b/doc/src/images/qeasingcurve-outquint.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-outsine.png b/doc/src/images/qeasingcurve-outsine.png
new file mode 100644
index 0000000..7546a0d
--- /dev/null
+++ b/doc/src/images/qeasingcurve-outsine.png
Binary files differ
diff --git a/doc/src/images/qeasingcurve-sinecurve.png b/doc/src/images/qeasingcurve-sinecurve.png
new file mode 100644
index 0000000..ca67d44
--- /dev/null
+++ b/doc/src/images/qeasingcurve-sinecurve.png
Binary files differ
diff --git a/doc/src/images/statemachine-button-history.png b/doc/src/images/statemachine-button-history.png
new file mode 100644
index 0000000..7f51cae
--- /dev/null
+++ b/doc/src/images/statemachine-button-history.png
Binary files differ
diff --git a/doc/src/images/statemachine-button-nested.png b/doc/src/images/statemachine-button-nested.png
new file mode 100644
index 0000000..762ac14
--- /dev/null
+++ b/doc/src/images/statemachine-button-nested.png
Binary files differ
diff --git a/doc/src/images/statemachine-button.png b/doc/src/images/statemachine-button.png
new file mode 100644
index 0000000..10102bd
--- /dev/null
+++ b/doc/src/images/statemachine-button.png
Binary files differ
diff --git a/doc/src/images/statemachine-customevents.png b/doc/src/images/statemachine-customevents.png
new file mode 100644
index 0000000..62a4222
--- /dev/null
+++ b/doc/src/images/statemachine-customevents.png
Binary files differ
diff --git a/doc/src/images/statemachine-finished.png b/doc/src/images/statemachine-finished.png
new file mode 100644
index 0000000..0ac081d
--- /dev/null
+++ b/doc/src/images/statemachine-finished.png
Binary files differ
diff --git a/doc/src/images/statemachine-nonparallel.png b/doc/src/images/statemachine-nonparallel.png
new file mode 100644
index 0000000..f9850a7
--- /dev/null
+++ b/doc/src/images/statemachine-nonparallel.png
Binary files differ
diff --git a/doc/src/images/statemachine-parallel.png b/doc/src/images/statemachine-parallel.png
new file mode 100644
index 0000000..a65c297
--- /dev/null
+++ b/doc/src/images/statemachine-parallel.png
Binary files differ
diff --git a/doc/src/images/trafficlight-example.png b/doc/src/images/trafficlight-example.png
new file mode 100644
index 0000000..3431542
--- /dev/null
+++ b/doc/src/images/trafficlight-example.png
Binary files differ
diff --git a/doc/src/snippets/code/src_corelib_tools_qeasingcurve.cpp b/doc/src/snippets/code/src_corelib_tools_qeasingcurve.cpp
new file mode 100644
index 0000000..65358ea
--- /dev/null
+++ b/doc/src/snippets/code/src_corelib_tools_qeasingcurve.cpp
@@ -0,0 +1,4 @@
+//! [0]
+qreal myEasingFunction(qreal progress);
+//! [0]
+
diff --git a/doc/src/statemachine.qdoc b/doc/src/statemachine.qdoc
new file mode 100644
index 0000000..16eae39
--- /dev/null
+++ b/doc/src/statemachine.qdoc
@@ -0,0 +1,398 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $TROLLTECH_DUAL_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \page statemachine-api.html
+ \title The State Machine Framework
+ \brief An overview of the State Machine framework for constructing and executing state graphs.
+ \ingroup architecture
+
+ \tableofcontents
+
+ The State Machine framework provides classes for creating and executing
+ state graphs. The concepts and notation are based on those from Harel's
+ \l{Statecharts: A visual formalism for complex systems}{Statecharts}, which
+ is also the basis of UML state diagrams. The semantics of state machine
+ execution are based on \l{State Chart XML: State Machine Notation for
+ Control Abstraction}{State Chart XML (SCXML)}.
+
+ Statecharts provide a graphical way of modeling how a system reacts to
+ stimuli. This is done by defining the possible \e states that the system can
+ be in, and how the system can move from one state to another (\e transitions
+ between states). A key characteristic of event-driven systems (such as Qt
+ applications) is that behavior often depends not only on the last or current
+ event, but also the events that preceded it. With statecharts, this
+ information is easy to express.
+
+ The State Machine framework provides an API and execution model that can be
+ used to effectively embed the elements and semantics of statecharts in Qt
+ applications. The framework integrates tightly with Qt's meta-object system;
+ for example, transitions between states can be triggered by signals, and
+ states can be configured to set properties and invoke methods on QObjects.
+ Qt's event system is used to drive the state machines.
+
+ \section1 A Simple State Machine
+
+ To demonstrate the core functionality of the State Machine API, let's look
+ at a small example: A state machine with three states, \c s1, \c s2 and \c
+ s3. The state machine is controlled by a single QPushButton; when the button
+ is clicked, the machine transitions to another state. Initially, the state
+ machine is in state \c s1. The statechart for this machine is as follows:
+
+ \img statemachine-button.png
+ \omit
+ \caption This is a caption
+ \endomit
+
+ The following snippet shows the code needed to create such a state machine.
+ First, we create the state machine and states:
+
+ \code
+ QStateMachine machine;
+ QState *s1 = new QState();
+ QState *s2 = new QState();
+ QState *s3 = new QState();
+ \endcode
+
+ Then, we create the transitions by using the QState::addTransition()
+ function:
+
+ \code
+ s1->addTransition(button, SIGNAL(clicked()), s2);
+ s2->addTransition(button, SIGNAL(clicked()), s3);
+ s3->addTransition(button, SIGNAL(clicked()), s1);
+ \endcode
+
+ Next, we add the states to the machine and set the machine's initial state:
+
+ \code
+ machine.addState(s1);
+ machine.addState(s2);
+ machine.addState(s3);
+ machine.setInitialState(s1);
+ \endcode
+
+ Finally, we start the state machine:
+
+ \code
+ machine.start();
+ \endcode
+
+ The state machine executes asynchronously, i.e. it becomes part of your
+ application's event loop.
+
+ \section1 Doing Useful Work on State Entry and Exit
+
+ The above state machine merely transitions from one state to another, it
+ doesn't perform any operations. The QState::assignProperty() function can be
+ used to have a state set a property of a QObject when the state is
+ entered. In the following snippet, the value that should be assigned to a
+ QLabel's text property is specified for each state:
+
+ \code
+ s1->assignProperty(label, "text", "In state s1");
+ s2->assignProperty(label, "text", "In state s2");
+ s3->assignProperty(label, "text", "In state s3");
+ \endcode
+
+ When any of the states is entered, the label's text will be changed
+ accordingly.
+
+ The QState::entered() signal is emitted when the state is entered, and the
+ QState::exited() signal is emitted when the state is exited. In the
+ following snippet, the button's showMaximized() slot will be called when
+ state \c s3 is entered, and the button's showMinimized() slot will be called
+ when \c s3 is exited:
+
+ \code
+ QObject::connect(s3, SIGNAL(entered()), button, SLOT(showMaximized()));
+ QObject::connect(s3, SIGNAL(exited()), button, SLOT(showMinimized()));
+ \endcode
+
+ \section1 State Machines That Finish
+
+ The state machine defined in the previous section never finishes. In order
+ for a state machine to be able to finish, it needs to have a top-level \e
+ final state (QFinalState object). When the state machine enters a top-level
+ final state, the machine will emit the QStateMachine::finished() signal and
+ halt.
+
+ \section1 Sharing Transitions By Grouping States
+
+ Assume we wanted the user to be able to quit the application at any time by
+ clicking a Quit button. In order to achieve this, we need to create a final
+ state and make it the target of a transition associated with the Quit
+ button's clicked() signal. We could add a transition from each of \c s1, \c
+ s2 and \c s3; however, this seems redundant, and one would also have to
+ remember to add such a transition from every new state that is added in the
+ future.
+
+ We can achieve the same behavior (namely that clicking the Quit button quits
+ the state machine, regardless of which state the state machine is in) by
+ grouping states \c s1, \c s2 and \c s3. This is done by creating a new
+ top-level state and making the three original states children of the new
+ state. The following diagram shows the new state machine.
+
+ \img statemachine-button-nested.png
+ \omit
+ \caption This is a caption
+ \endomit
+
+ The three original states have been renamed \c s11, \c s12 and \c s13 to
+ reflect that they are now children of the new top-level state, \c s1. Child
+ states implicitly inherit the transitions of their parent state. This means
+ it is now sufficient to add a single transition from \c s1 to the final
+ state \c s2. New states added to \c s1 will also automatically inherit this
+ transition.
+
+ All that's needed to group states is to specify the proper parent when the
+ state is created. You also need to specify which of the child states is the
+ initial one (i.e. which child state the state machine should enter when the
+ parent state is the target of a transition).
+
+ \code
+ QState *s1 = new QState();
+ QState *s11 = new QState(s1);
+ QState *s12 = new QState(s1);
+ QState *s13 = new QState(s1);
+ s1->setInitialState(s11);
+ machine.addState(s1);
+ \endcode
+
+ \code
+ QFinalState *s2 = new QFinalState();
+ s1->addTransition(quitButton, SIGNAL(clicked()), s2);
+ machine.addState(s2);
+
+ QObject::connect(&machine, SIGNAL(finished()), QApplication::instance(), SLOT(quit()));
+ \endcode
+
+ In this case we want the application to quit when the state machine is
+ finished, so the machine's finished() signal is connected to the
+ application's quit() slot.
+
+ A child state can override an inherited transition. For example, the
+ following code adds a transition that effectively causes the Quit button to
+ be ignored when the state machine is in state \c s12.
+
+ \code
+ s12>addTransition(quitButton, SIGNAL(clicked()), s12);
+ \endcode
+
+ A transition can have any state as its target, i.e. the target state does
+ not have to be on the same level in the state hierarchy as the source state.
+
+ \section1 Using History States to Save and Restore the Current State
+
+ Imagine that we wanted to add an "interrupt" mechanism to the example
+ discussed in the previous section; the user should be able to click a button
+ to have the state machine perform some non-related task, after which the
+ state machine should resume whatever it was doing before (i.e. return to the
+ old state, which is one of \c s11, \c s12 and \c s13 in this case).
+
+ Such behavior can easily be modeled using \e{history states}. A history
+ state (QHistoryState object) is a pseudo-state that represents the child
+ state that the parent state was in the last time the parent state was
+ exited.
+
+ A history state is created as a child of the state for which we wish to
+ record the current child state; when the state machine detects the presence
+ of such a state at runtime, it automatically records the current (real)
+ child state when the parent state is exited. A transition to the history
+ state is in fact a transition to the child state that the state machine had
+ previously saved; the state machine automatically "forwards" the transition
+ to the real child state.
+
+ The following diagram shows the state machine after the interrupt mechanism
+ has been added.
+
+ \img statemachine-button-history.png
+ \omit
+ \caption This is a caption
+ \endomit
+
+ The following code shows how it can be implemented; in this example we
+ simply display a message box when \c s3 is entered, then immediately return
+ to the previous child state of \c s1 via the history state.
+
+ \code
+ QHistoryState *s1h = s1->addHistoryState();
+
+ QState *s3 = new QState();
+ s3->assignProperty(label, "text", "In s3");
+ QMessageBox mbox;
+ mbox.addButton(QMessageBox::Ok);
+ mbox.setText("Interrupted!");
+ mbox.setIcon(QMessageBox::Information);
+ QObject::connect(s3, SIGNAL(entered()), &mbox, SLOT(exec()));
+ s3->addTransition(s1h);
+ machine.addState(s3);
+
+ s1->addTransition(interruptButton, SIGNAL(clicked()), s3);
+ \endcode
+
+ \section1 Using Parallel States to Avoid a Combinatorial Explosion of States
+
+ Assume that you wanted to model a set of mutually exclusive properties of a
+ car in a single state machine. Let's say the properties we are interested in
+ are Clean vs Dirty, and Moving vs Not moving. It would take four mutually
+ exclusive states and eight transitions to be able to represent and freely
+ move between all possible combinations.
+
+ \img statemachine-nonparallel.png
+ \omit
+ \caption This is a caption
+ \endomit
+
+ If we added a third property (say, Red vs Blue), the total number of states
+ would double, to eight; and if we added a fourth property (say, Enclosed vs
+ Convertible), the total number of states would double again, to 16.
+
+ Using parallel states, the total number of states and transitions grows
+ linearly as we add more properties, instead of exponentially. Furthermore,
+ states can be added to or removed from the parallel state without affecting
+ any of their sibling states.
+
+ \img statemachine-parallel.png
+ \omit
+ \caption This is a caption
+ \endomit
+
+ To create a parallel state group, pass QState::ParallelStates to the QState
+ constructor.
+
+ \code
+ QState *s1 = new QState(QState::ParallelStates);
+ // s11 and s12 will be entered in parallel
+ QState *s11 = new QState(s1);
+ QState *s12 = new QState(s1);
+ \endcode
+
+ When a parallel state group is entered, all its child states will be
+ simultaneously entered. Transitions within the individual child states
+ operate normally. However, any of the child states may take a transition
+ outside the parent state. When this happens, the parent state and all of its
+ child states are exited.
+
+ \section1 Detecting that a Composite State has Finished
+
+ A child state can be final (a QFinalState object); when a final child state
+ is entered, the parent state emits the QState::finished() signal.
+
+ \img statemachine-finished.png
+ \omit
+ \caption This is a caption
+ \endomit
+
+ This is useful when you want to hide the internal details of a state;
+ i.e. the only thing the outside world should be able to do is enter the
+ state, and get a notification when the state has completed its work.
+
+ For parallel state groups, the QState::finished() signal is emitted when \e
+ all the child states have entered final states.
+
+ \section1 Events, Transitions and Guards
+
+ A QStateMachine runs its own event loop. For signal transitions
+ (QSignalTransition objects), QStateMachine automatically posts a
+ QSignalEvent to itself when it intercepts the corresponding signal;
+ similarly, for QObject event transitions (QEventTransition objects) a
+ QWrappedEvent is posted.
+
+ You can post your own events to the state machine using
+ QStateMachine::postEvent().
+
+ When posting a custom event to the state machine, you typically also have
+ one or more custom transitions that can be triggered from events of that
+ type. To create such a transition, you subclass QAbstractTransition and
+ reimplement QAbstractTransition::eventTest(), where you check if an event
+ matches your event type (and optionally other criteria, e.g. attributes of
+ the event object).
+
+ Here we define our own custom event type, \c StringEvent, for posting
+ strings to the state machine:
+
+ \code
+ struct StringEvent : public QEvent
+ {
+ StringEvent(const QString &val)
+ : QEvent(QEvent::Type(QEvent::User+1)),
+ value(val) {}
+
+ QString value;
+ };
+ \endcode
+
+ Next, we define a transition that only triggers when the event's string
+ matches a particular string (a \e guarded transition):
+
+ \code
+ class StringTransition : public QAbstractTransition
+ {
+ public:
+ StringTransition(const QString &value)
+ : m_value(value) {}
+
+ protected:
+ virtual bool eventTest(QEvent *e) const
+ {
+ if (e->type() != QEvent::Type(QEvent::User+1)) // StringEvent
+ return false;
+ StringEvent *se = static_cast<StringEvent*>(e);
+ return (m_value == se->value);
+ }
+
+ virtual void onTransition(QEvent *) {}
+
+ private:
+ QString m_value;
+ };
+ \endcode
+
+ In the eventTest() reimplementation, we first check if the event type is the
+ desired one; if so, we cast the event to a StringEvent and perform the
+ string comparison.
+
+ The following is a statechart that uses the custom event and transition:
+
+ \img statemachine-customevents.png
+ \omit
+ \caption This is a caption
+ \endomit
+
+ Here's what the implementation of the statechart looks like:
+
+ \code
+ QStateMachine machine;
+ QState *s1 = new QState();
+ QState *s2 = new QState();
+ QFinalState *done = new QFinalState();
+
+ StringTransition *t1 = new StringTransition("Hello");
+ t1->setTargetState(s2);
+ s1->addTransition(t1);
+ StringTransition *t2 = new StringTransition("world");
+ t2->setTargetState(done);
+ s2->addTransition(t2);
+
+ machine.addState(s1);
+ machine.addState(s2);
+ machine.addState(done);
+ machine.setInitialState(s1);
+ \endcode
+
+ Once the machine is started, we can post events to it.
+
+ \code
+ machine.postEvent(new StringEvent("Hello"));
+ machine.postEvent(new StringEvent("world"));
+ \endcode
+*/