summaryrefslogtreecommitdiffstats
path: root/examples/widgets/animation
diff options
context:
space:
mode:
Diffstat (limited to 'examples/widgets/animation')
-rw-r--r--examples/widgets/animation/README8
-rw-r--r--examples/widgets/animation/animatedtiles/animatedtiles.desktop11
-rw-r--r--examples/widgets/animation/animatedtiles/animatedtiles.pro10
-rw-r--r--examples/widgets/animation/animatedtiles/animatedtiles.qrc11
-rw-r--r--examples/widgets/animation/animatedtiles/images/Time-For-Lunch-2.jpgbin0 -> 32471 bytes
-rw-r--r--examples/widgets/animation/animatedtiles/images/centered.pngbin0 -> 892 bytes
-rw-r--r--examples/widgets/animation/animatedtiles/images/ellipse.pngbin0 -> 10767 bytes
-rw-r--r--examples/widgets/animation/animatedtiles/images/figure8.pngbin0 -> 14050 bytes
-rw-r--r--examples/widgets/animation/animatedtiles/images/kinetic.pngbin0 -> 6776 bytes
-rw-r--r--examples/widgets/animation/animatedtiles/images/random.pngbin0 -> 14969 bytes
-rw-r--r--examples/widgets/animation/animatedtiles/images/tile.pngbin0 -> 16337 bytes
-rw-r--r--examples/widgets/animation/animatedtiles/main.cpp256
-rw-r--r--examples/widgets/animation/animation.pro17
-rw-r--r--examples/widgets/animation/appchooser/accessories-dictionary.pngbin0 -> 5396 bytes
-rw-r--r--examples/widgets/animation/appchooser/akregator.pngbin0 -> 4873 bytes
-rw-r--r--examples/widgets/animation/appchooser/appchooser.desktop11
-rw-r--r--examples/widgets/animation/appchooser/appchooser.pro10
-rw-r--r--examples/widgets/animation/appchooser/appchooser.qrc8
-rw-r--r--examples/widgets/animation/appchooser/digikam.pngbin0 -> 3334 bytes
-rw-r--r--examples/widgets/animation/appchooser/k3b.pngbin0 -> 8220 bytes
-rw-r--r--examples/widgets/animation/appchooser/main.cpp173
-rw-r--r--examples/widgets/animation/easing/animation.h100
-rw-r--r--examples/widgets/animation/easing/easing.desktop11
-rw-r--r--examples/widgets/animation/easing/easing.pro17
-rw-r--r--examples/widgets/animation/easing/easing.qrc5
-rw-r--r--examples/widgets/animation/easing/form.ui270
-rw-r--r--examples/widgets/animation/easing/images/qt-logo.pngbin0 -> 5149 bytes
-rw-r--r--examples/widgets/animation/easing/main.cpp54
-rw-r--r--examples/widgets/animation/easing/window.cpp177
-rw-r--r--examples/widgets/animation/easing/window.h76
-rw-r--r--examples/widgets/animation/moveblocks/main.cpp321
-rw-r--r--examples/widgets/animation/moveblocks/moveblocks.desktop11
-rw-r--r--examples/widgets/animation/moveblocks/moveblocks.pro9
-rw-r--r--examples/widgets/animation/states/accessories-dictionary.pngbin0 -> 5396 bytes
-rw-r--r--examples/widgets/animation/states/akregator.pngbin0 -> 4873 bytes
-rw-r--r--examples/widgets/animation/states/digikam.pngbin0 -> 3334 bytes
-rw-r--r--examples/widgets/animation/states/help-browser.pngbin0 -> 6984 bytes
-rw-r--r--examples/widgets/animation/states/k3b.pngbin0 -> 8220 bytes
-rw-r--r--examples/widgets/animation/states/kchart.pngbin0 -> 4887 bytes
-rw-r--r--examples/widgets/animation/states/main.cpp285
-rw-r--r--examples/widgets/animation/states/states.desktop11
-rw-r--r--examples/widgets/animation/states/states.pro10
-rw-r--r--examples/widgets/animation/states/states.qrc10
-rw-r--r--examples/widgets/animation/stickman/animation.cpp189
-rw-r--r--examples/widgets/animation/stickman/animation.h82
-rw-r--r--examples/widgets/animation/stickman/animations/chilling.binbin0 -> 6508 bytes
-rw-r--r--examples/widgets/animation/stickman/animations/dancing.binbin0 -> 2348 bytes
-rw-r--r--examples/widgets/animation/stickman/animations/dead.binbin0 -> 268 bytes
-rw-r--r--examples/widgets/animation/stickman/animations/jumping.binbin0 -> 1308 bytes
-rw-r--r--examples/widgets/animation/stickman/graphicsview.cpp60
-rw-r--r--examples/widgets/animation/stickman/graphicsview.h64
-rw-r--r--examples/widgets/animation/stickman/lifecycle.cpp217
-rw-r--r--examples/widgets/animation/stickman/lifecycle.h80
-rw-r--r--examples/widgets/animation/stickman/main.cpp106
-rw-r--r--examples/widgets/animation/stickman/node.cpp92
-rw-r--r--examples/widgets/animation/stickman/node.h70
-rw-r--r--examples/widgets/animation/stickman/rectbutton.cpp73
-rw-r--r--examples/widgets/animation/stickman/rectbutton.h65
-rw-r--r--examples/widgets/animation/stickman/stickman.cpp337
-rw-r--r--examples/widgets/animation/stickman/stickman.desktop11
-rw-r--r--examples/widgets/animation/stickman/stickman.h103
-rw-r--r--examples/widgets/animation/stickman/stickman.pro23
-rw-r--r--examples/widgets/animation/stickman/stickman.qrc8
-rw-r--r--examples/widgets/animation/sub-attaq/animationmanager.cpp98
-rw-r--r--examples/widgets/animation/sub-attaq/animationmanager.h73
-rw-r--r--examples/widgets/animation/sub-attaq/boat.cpp272
-rw-r--r--examples/widgets/animation/sub-attaq/boat.h95
-rw-r--r--examples/widgets/animation/sub-attaq/boat_p.h232
-rw-r--r--examples/widgets/animation/sub-attaq/bomb.cpp118
-rw-r--r--examples/widgets/animation/sub-attaq/bomb.h67
-rw-r--r--examples/widgets/animation/sub-attaq/data.xml39
-rw-r--r--examples/widgets/animation/sub-attaq/graphicsscene.cpp282
-rw-r--r--examples/widgets/animation/sub-attaq/graphicsscene.h122
-rw-r--r--examples/widgets/animation/sub-attaq/main.cpp57
-rw-r--r--examples/widgets/animation/sub-attaq/mainwindow.cpp82
-rw-r--r--examples/widgets/animation/sub-attaq/mainwindow.h63
-rw-r--r--examples/widgets/animation/sub-attaq/pics/big/background.pngbin0 -> 48858 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/big/boat.pngbin0 -> 5198 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/big/bomb.pngbin0 -> 760 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/big/explosion/boat/step1.pngbin0 -> 5760 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/big/explosion/boat/step2.pngbin0 -> 9976 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/big/explosion/boat/step3.pngbin0 -> 12411 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/big/explosion/boat/step4.pngbin0 -> 15438 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/big/explosion/submarine/step1.pngbin0 -> 3354 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/big/explosion/submarine/step2.pngbin0 -> 6205 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/big/explosion/submarine/step3.pngbin0 -> 6678 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/big/explosion/submarine/step4.pngbin0 -> 6666 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/big/submarine.pngbin0 -> 3202 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/big/surface.pngbin0 -> 575 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/big/torpedo.pngbin0 -> 951 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/scalable/background-n810.svg171
-rw-r--r--examples/widgets/animation/sub-attaq/pics/scalable/background.svg171
-rw-r--r--examples/widgets/animation/sub-attaq/pics/scalable/boat.svg279
-rw-r--r--examples/widgets/animation/sub-attaq/pics/scalable/bomb.svg138
-rw-r--r--examples/widgets/animation/sub-attaq/pics/scalable/sand.svg103
-rw-r--r--examples/widgets/animation/sub-attaq/pics/scalable/see.svg44
-rw-r--r--examples/widgets/animation/sub-attaq/pics/scalable/sky.svg45
-rw-r--r--examples/widgets/animation/sub-attaq/pics/scalable/sub-attaq.svg1473
-rw-r--r--examples/widgets/animation/sub-attaq/pics/scalable/submarine.svg214
-rw-r--r--examples/widgets/animation/sub-attaq/pics/scalable/surface.svg49
-rw-r--r--examples/widgets/animation/sub-attaq/pics/scalable/torpedo.svg127
-rw-r--r--examples/widgets/animation/sub-attaq/pics/small/background.pngbin0 -> 34634 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/small/boat.pngbin0 -> 2394 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/small/bomb.pngbin0 -> 760 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/small/submarine.pngbin0 -> 1338 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/small/surface.pngbin0 -> 502 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/small/torpedo.pngbin0 -> 951 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/welcome/logo-a.pngbin0 -> 5972 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/welcome/logo-a2.pngbin0 -> 5969 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/welcome/logo-b.pngbin0 -> 6869 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/welcome/logo-dash.pngbin0 -> 2255 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/welcome/logo-excl.pngbin0 -> 2740 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/welcome/logo-q.pngbin0 -> 7016 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/welcome/logo-s.pngbin0 -> 5817 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/welcome/logo-t.pngbin0 -> 3717 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/welcome/logo-t2.pngbin0 -> 3688 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pics/welcome/logo-u.pngbin0 -> 5374 bytes
-rw-r--r--examples/widgets/animation/sub-attaq/pixmapitem.cpp76
-rw-r--r--examples/widgets/animation/sub-attaq/pixmapitem.h63
-rw-r--r--examples/widgets/animation/sub-attaq/progressitem.cpp67
-rw-r--r--examples/widgets/animation/sub-attaq/progressitem.h61
-rw-r--r--examples/widgets/animation/sub-attaq/qanimationstate.cpp150
-rw-r--r--examples/widgets/animation/sub-attaq/qanimationstate.h91
-rw-r--r--examples/widgets/animation/sub-attaq/states.cpp330
-rw-r--r--examples/widgets/animation/sub-attaq/states.h180
-rw-r--r--examples/widgets/animation/sub-attaq/sub-attaq.pro42
-rw-r--r--examples/widgets/animation/sub-attaq/subattaq.qrc39
-rw-r--r--examples/widgets/animation/sub-attaq/submarine.cpp182
-rw-r--r--examples/widgets/animation/sub-attaq/submarine.h93
-rw-r--r--examples/widgets/animation/sub-attaq/submarine_p.h137
-rw-r--r--examples/widgets/animation/sub-attaq/textinformationitem.cpp54
-rw-r--r--examples/widgets/animation/sub-attaq/textinformationitem.h55
-rw-r--r--examples/widgets/animation/sub-attaq/torpedo.cpp114
-rw-r--r--examples/widgets/animation/sub-attaq/torpedo.h67
134 files changed, 9677 insertions, 0 deletions
diff --git a/examples/widgets/animation/README b/examples/widgets/animation/README
new file mode 100644
index 0000000000..e723a28722
--- /dev/null
+++ b/examples/widgets/animation/README
@@ -0,0 +1,8 @@
+The animation framework 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 QObjects. The framework can also be used with
+the Graphics View framework.
+
+
+Documentation for these examples can be found via the Examples
+link in the main Qt documentation.
diff --git a/examples/widgets/animation/animatedtiles/animatedtiles.desktop b/examples/widgets/animation/animatedtiles/animatedtiles.desktop
new file mode 100644
index 0000000000..97e646fdf8
--- /dev/null
+++ b/examples/widgets/animation/animatedtiles/animatedtiles.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=Animated Tiles
+Exec=/opt/usr/bin/animatedtiles
+Icon=animatedtiles
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/examples/widgets/animation/animatedtiles/animatedtiles.pro b/examples/widgets/animation/animatedtiles/animatedtiles.pro
new file mode 100644
index 0000000000..1bba99449c
--- /dev/null
+++ b/examples/widgets/animation/animatedtiles/animatedtiles.pro
@@ -0,0 +1,10 @@
+SOURCES = main.cpp
+RESOURCES = animatedtiles.qrc
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/animation/animatedtiles
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS animatedtiles.pro images
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/animation/animatedtiles
+INSTALLS += target sources
+
+QT += widgets
diff --git a/examples/widgets/animation/animatedtiles/animatedtiles.qrc b/examples/widgets/animation/animatedtiles/animatedtiles.qrc
new file mode 100644
index 0000000000..c43a979723
--- /dev/null
+++ b/examples/widgets/animation/animatedtiles/animatedtiles.qrc
@@ -0,0 +1,11 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>images/Time-For-Lunch-2.jpg</file>
+ <file>images/centered.png</file>
+ <file>images/ellipse.png</file>
+ <file>images/figure8.png</file>
+ <file>images/kinetic.png</file>
+ <file>images/random.png</file>
+ <file>images/tile.png</file>
+</qresource>
+</RCC>
diff --git a/examples/widgets/animation/animatedtiles/images/Time-For-Lunch-2.jpg b/examples/widgets/animation/animatedtiles/images/Time-For-Lunch-2.jpg
new file mode 100644
index 0000000000..c57a555490
--- /dev/null
+++ b/examples/widgets/animation/animatedtiles/images/Time-For-Lunch-2.jpg
Binary files differ
diff --git a/examples/widgets/animation/animatedtiles/images/centered.png b/examples/widgets/animation/animatedtiles/images/centered.png
new file mode 100644
index 0000000000..e416156a0e
--- /dev/null
+++ b/examples/widgets/animation/animatedtiles/images/centered.png
Binary files differ
diff --git a/examples/widgets/animation/animatedtiles/images/ellipse.png b/examples/widgets/animation/animatedtiles/images/ellipse.png
new file mode 100644
index 0000000000..2c3ba881c5
--- /dev/null
+++ b/examples/widgets/animation/animatedtiles/images/ellipse.png
Binary files differ
diff --git a/examples/widgets/animation/animatedtiles/images/figure8.png b/examples/widgets/animation/animatedtiles/images/figure8.png
new file mode 100644
index 0000000000..6b058041c4
--- /dev/null
+++ b/examples/widgets/animation/animatedtiles/images/figure8.png
Binary files differ
diff --git a/examples/widgets/animation/animatedtiles/images/kinetic.png b/examples/widgets/animation/animatedtiles/images/kinetic.png
new file mode 100644
index 0000000000..55cfa5515f
--- /dev/null
+++ b/examples/widgets/animation/animatedtiles/images/kinetic.png
Binary files differ
diff --git a/examples/widgets/animation/animatedtiles/images/random.png b/examples/widgets/animation/animatedtiles/images/random.png
new file mode 100644
index 0000000000..415d96f856
--- /dev/null
+++ b/examples/widgets/animation/animatedtiles/images/random.png
Binary files differ
diff --git a/examples/widgets/animation/animatedtiles/images/tile.png b/examples/widgets/animation/animatedtiles/images/tile.png
new file mode 100644
index 0000000000..c8f39d8d40
--- /dev/null
+++ b/examples/widgets/animation/animatedtiles/images/tile.png
Binary files differ
diff --git a/examples/widgets/animation/animatedtiles/main.cpp b/examples/widgets/animation/animatedtiles/main.cpp
new file mode 100644
index 0000000000..50bd33860e
--- /dev/null
+++ b/examples/widgets/animation/animatedtiles/main.cpp
@@ -0,0 +1,256 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets>
+#include <QtCore/qstate.h>
+
+class Pixmap : public QObject, public QGraphicsPixmapItem
+{
+ Q_OBJECT
+ Q_PROPERTY(QPointF pos READ pos WRITE setPos)
+public:
+ Pixmap(const QPixmap &pix)
+ : QObject(), QGraphicsPixmapItem(pix)
+ {
+ setCacheMode(DeviceCoordinateCache);
+ }
+};
+
+class Button : public QGraphicsWidget
+{
+ Q_OBJECT
+public:
+ Button(const QPixmap &pixmap, QGraphicsItem *parent = 0)
+ : QGraphicsWidget(parent), _pix(pixmap)
+ {
+ setAcceptHoverEvents(true);
+ setCacheMode(DeviceCoordinateCache);
+ }
+
+ QRectF boundingRect() const
+ {
+ return QRectF(-65, -65, 130, 130);
+ }
+
+ QPainterPath shape() const
+ {
+ QPainterPath path;
+ path.addEllipse(boundingRect());
+ return path;
+ }
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
+ {
+ bool down = option->state & QStyle::State_Sunken;
+ QRectF r = boundingRect();
+ QLinearGradient grad(r.topLeft(), r.bottomRight());
+ grad.setColorAt(down ? 1 : 0, option->state & QStyle::State_MouseOver ? Qt::white : Qt::lightGray);
+ grad.setColorAt(down ? 0 : 1, Qt::darkGray);
+ painter->setPen(Qt::darkGray);
+ painter->setBrush(grad);
+ painter->drawEllipse(r);
+ QLinearGradient grad2(r.topLeft(), r.bottomRight());
+ grad.setColorAt(down ? 1 : 0, Qt::darkGray);
+ grad.setColorAt(down ? 0 : 1, Qt::lightGray);
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(grad);
+ if (down)
+ painter->translate(2, 2);
+ painter->drawEllipse(r.adjusted(5, 5, -5, -5));
+ painter->drawPixmap(-_pix.width()/2, -_pix.height()/2, _pix);
+ }
+
+signals:
+ void pressed();
+
+protected:
+ void mousePressEvent(QGraphicsSceneMouseEvent *)
+ {
+ emit pressed();
+ update();
+ }
+
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *)
+ {
+ update();
+ }
+
+private:
+ QPixmap _pix;
+};
+
+class View : public QGraphicsView
+{
+public:
+ View(QGraphicsScene *scene) : QGraphicsView(scene) { }
+
+protected:
+ void resizeEvent(QResizeEvent *event)
+ {
+ QGraphicsView::resizeEvent(event);
+ fitInView(sceneRect(), Qt::KeepAspectRatio);
+ }
+};
+
+int main(int argc, char **argv)
+{
+ Q_INIT_RESOURCE(animatedtiles);
+
+ QApplication app(argc, argv);
+
+ QPixmap kineticPix(":/images/kinetic.png");
+ QPixmap bgPix(":/images/Time-For-Lunch-2.jpg");
+
+ QGraphicsScene scene(-350, -350, 700, 700);
+
+ QList<Pixmap *> items;
+ for (int i = 0; i < 64; ++i) {
+ Pixmap *item = new Pixmap(kineticPix);
+ item->setOffset(-kineticPix.width()/2, -kineticPix.height()/2);
+ item->setZValue(i);
+ items << item;
+ scene.addItem(item);
+ }
+
+ // Buttons
+ QGraphicsItem *buttonParent = new QGraphicsRectItem;
+ Button *ellipseButton = new Button(QPixmap(":/images/ellipse.png"), buttonParent);
+ Button *figure8Button = new Button(QPixmap(":/images/figure8.png"), buttonParent);
+ Button *randomButton = new Button(QPixmap(":/images/random.png"), buttonParent);
+ Button *tiledButton = new Button(QPixmap(":/images/tile.png"), buttonParent);
+ Button *centeredButton = new Button(QPixmap(":/images/centered.png"), buttonParent);
+
+ ellipseButton->setPos(-100, -100);
+ figure8Button->setPos(100, -100);
+ randomButton->setPos(0, 0);
+ tiledButton->setPos(-100, 100);
+ centeredButton->setPos(100, 100);
+
+ scene.addItem(buttonParent);
+ buttonParent->setTransform(QTransform::fromScale(0.75, 0.75), true);
+ buttonParent->setPos(200, 200);
+ buttonParent->setZValue(65);
+
+ // States
+ QState *rootState = new QState;
+ QState *ellipseState = new QState(rootState);
+ QState *figure8State = new QState(rootState);
+ QState *randomState = new QState(rootState);
+ QState *tiledState = new QState(rootState);
+ QState *centeredState = new QState(rootState);
+
+ // Values
+ for (int i = 0; i < items.count(); ++i) {
+ Pixmap *item = items.at(i);
+ // Ellipse
+ ellipseState->assignProperty(item, "pos",
+ QPointF(cos((i / 63.0) * 6.28) * 250,
+ sin((i / 63.0) * 6.28) * 250));
+
+ // Figure 8
+ figure8State->assignProperty(item, "pos",
+ QPointF(sin((i / 63.0) * 6.28) * 250,
+ sin(((i * 2)/63.0) * 6.28) * 250));
+
+ // Random
+ randomState->assignProperty(item, "pos",
+ QPointF(-250 + qrand() % 500,
+ -250 + qrand() % 500));
+
+ // Tiled
+ tiledState->assignProperty(item, "pos",
+ QPointF(((i % 8) - 4) * kineticPix.width() + kineticPix.width() / 2,
+ ((i / 8) - 4) * kineticPix.height() + kineticPix.height() / 2));
+
+ // Centered
+ centeredState->assignProperty(item, "pos", QPointF());
+ }
+
+ // Ui
+ View *view = new View(&scene);
+ view->setWindowTitle(QT_TRANSLATE_NOOP(QGraphicsView, "Animated Tiles"));
+ view->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
+ view->setBackgroundBrush(bgPix);
+ view->setCacheMode(QGraphicsView::CacheBackground);
+ view->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
+ view->show();
+
+ QStateMachine states;
+ states.addState(rootState);
+ states.setInitialState(rootState);
+ rootState->setInitialState(centeredState);
+
+ QParallelAnimationGroup *group = new QParallelAnimationGroup;
+ for (int i = 0; i < items.count(); ++i) {
+ QPropertyAnimation *anim = new QPropertyAnimation(items[i], "pos");
+ anim->setDuration(750 + i * 25);
+ anim->setEasingCurve(QEasingCurve::InOutBack);
+ group->addAnimation(anim);
+ }
+ QAbstractTransition *trans = rootState->addTransition(ellipseButton, SIGNAL(pressed()), ellipseState);
+ trans->addAnimation(group);
+
+ trans = rootState->addTransition(figure8Button, SIGNAL(pressed()), figure8State);
+ trans->addAnimation(group);
+
+ trans = rootState->addTransition(randomButton, SIGNAL(pressed()), randomState);
+ trans->addAnimation(group);
+
+ trans = rootState->addTransition(tiledButton, SIGNAL(pressed()), tiledState);
+ trans->addAnimation(group);
+
+ trans = rootState->addTransition(centeredButton, SIGNAL(pressed()), centeredState);
+ trans->addAnimation(group);
+
+ QTimer timer;
+ timer.start(125);
+ timer.setSingleShot(true);
+ trans = rootState->addTransition(&timer, SIGNAL(timeout()), ellipseState);
+ trans->addAnimation(group);
+
+ states.start();
+
+#ifdef QT_KEYPAD_NAVIGATION
+ QApplication::setNavigationMode(Qt::NavigationModeCursorAuto);
+#endif
+ return app.exec();
+}
+
+#include "main.moc"
diff --git a/examples/widgets/animation/animation.pro b/examples/widgets/animation/animation.pro
new file mode 100644
index 0000000000..b17aa0e0fe
--- /dev/null
+++ b/examples/widgets/animation/animation.pro
@@ -0,0 +1,17 @@
+TEMPLATE = \
+ subdirs
+SUBDIRS += \
+ animatedtiles \
+ appchooser \
+ easing \
+ moveblocks \
+ states \
+ stickman \
+ sub-attaq \
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/animation
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS animation.pro README
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/animation
+INSTALLS += target sources
+QT += widgets
diff --git a/examples/widgets/animation/appchooser/accessories-dictionary.png b/examples/widgets/animation/appchooser/accessories-dictionary.png
new file mode 100644
index 0000000000..e9bd55d918
--- /dev/null
+++ b/examples/widgets/animation/appchooser/accessories-dictionary.png
Binary files differ
diff --git a/examples/widgets/animation/appchooser/akregator.png b/examples/widgets/animation/appchooser/akregator.png
new file mode 100644
index 0000000000..a086f45ab6
--- /dev/null
+++ b/examples/widgets/animation/appchooser/akregator.png
Binary files differ
diff --git a/examples/widgets/animation/appchooser/appchooser.desktop b/examples/widgets/animation/appchooser/appchooser.desktop
new file mode 100644
index 0000000000..8e413e96c2
--- /dev/null
+++ b/examples/widgets/animation/appchooser/appchooser.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=Application Chooser
+Exec=/opt/usr/bin/appchooser
+Icon=appchooser
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/examples/widgets/animation/appchooser/appchooser.pro b/examples/widgets/animation/appchooser/appchooser.pro
new file mode 100644
index 0000000000..158a0eca9f
--- /dev/null
+++ b/examples/widgets/animation/appchooser/appchooser.pro
@@ -0,0 +1,10 @@
+SOURCES = main.cpp
+RESOURCES = appchooser.qrc
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/animation/appchooser
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS appchooser.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/animation/appchooser
+INSTALLS += target sources
+
+QT += widgets
diff --git a/examples/widgets/animation/appchooser/appchooser.qrc b/examples/widgets/animation/appchooser/appchooser.qrc
new file mode 100644
index 0000000000..28a3e1c4c1
--- /dev/null
+++ b/examples/widgets/animation/appchooser/appchooser.qrc
@@ -0,0 +1,8 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>accessories-dictionary.png</file>
+ <file>akregator.png</file>
+ <file>digikam.png</file>
+ <file>k3b.png</file>
+</qresource>
+</RCC>
diff --git a/examples/widgets/animation/appchooser/digikam.png b/examples/widgets/animation/appchooser/digikam.png
new file mode 100644
index 0000000000..9de9fb2f80
--- /dev/null
+++ b/examples/widgets/animation/appchooser/digikam.png
Binary files differ
diff --git a/examples/widgets/animation/appchooser/k3b.png b/examples/widgets/animation/appchooser/k3b.png
new file mode 100644
index 0000000000..bbcafcfba1
--- /dev/null
+++ b/examples/widgets/animation/appchooser/k3b.png
Binary files differ
diff --git a/examples/widgets/animation/appchooser/main.cpp b/examples/widgets/animation/appchooser/main.cpp
new file mode 100644
index 0000000000..c8e60c0641
--- /dev/null
+++ b/examples/widgets/animation/appchooser/main.cpp
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore>
+#include <QtWidgets>
+
+
+class Pixmap : public QGraphicsWidget
+{
+ Q_OBJECT
+
+public:
+ Pixmap(const QPixmap &pix, QGraphicsItem *parent = 0)
+ : QGraphicsWidget(parent), orig(pix), p(pix)
+ {
+ }
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+ {
+ painter->drawPixmap(QPointF(), p);
+ }
+
+ virtual void mousePressEvent(QGraphicsSceneMouseEvent * )
+ {
+ emit clicked();
+ }
+
+ virtual void setGeometry(const QRectF &rect)
+ {
+ QGraphicsWidget::setGeometry(rect);
+
+ if (rect.size().width() > orig.size().width())
+ p = orig.scaled(rect.size().toSize());
+ else
+ p = orig;
+ }
+
+Q_SIGNALS:
+ void clicked();
+
+private:
+ QPixmap orig;
+ QPixmap p;
+};
+
+class GraphicsView : public QGraphicsView
+{
+ Q_OBJECT
+public:
+ GraphicsView(QGraphicsScene *scene, QWidget *parent = 0) : QGraphicsView(scene, parent)
+ {
+ }
+
+ virtual void resizeEvent(QResizeEvent *)
+ {
+ fitInView(sceneRect(), Qt::KeepAspectRatio);
+ }
+};
+
+
+void createStates(const QObjectList &objects,
+ const QRect &selectedRect, QState *parent)
+{
+ for (int i = 0; i < objects.size(); ++i) {
+ QState *state = new QState(parent);
+ state->assignProperty(objects.at(i), "geometry", selectedRect);
+ parent->addTransition(objects.at(i), SIGNAL(clicked()), state);
+ }
+}
+
+void createAnimations(const QObjectList &objects, QStateMachine *machine)
+{
+ for (int i=0; i<objects.size(); ++i)
+ machine->addDefaultAnimation(new QPropertyAnimation(objects.at(i), "geometry"));
+}
+
+int main(int argc, char **argv)
+{
+ Q_INIT_RESOURCE(appchooser);
+
+ QApplication app(argc, argv);
+
+ Pixmap *p1 = new Pixmap(QPixmap(":/digikam.png"));
+ Pixmap *p2 = new Pixmap(QPixmap(":/akregator.png"));
+ Pixmap *p3 = new Pixmap(QPixmap(":/accessories-dictionary.png"));
+ Pixmap *p4 = new Pixmap(QPixmap(":/k3b.png"));
+
+ p1->setObjectName("p1");
+ p2->setObjectName("p2");
+ p3->setObjectName("p3");
+ p4->setObjectName("p4");
+
+ p1->setGeometry(QRectF( 0.0, 0.0, 64.0, 64.0));
+ p2->setGeometry(QRectF(236.0, 0.0, 64.0, 64.0));
+ p3->setGeometry(QRectF(236.0, 236.0, 64.0, 64.0));
+ p4->setGeometry(QRectF( 0.0, 236.0, 64.0, 64.0));
+
+ QGraphicsScene scene(0, 0, 300, 300);
+ scene.setBackgroundBrush(Qt::white);
+ scene.addItem(p1);
+ scene.addItem(p2);
+ scene.addItem(p3);
+ scene.addItem(p4);
+
+ GraphicsView window(&scene);
+ window.setFrameStyle(0);
+ window.setAlignment(Qt::AlignLeft | Qt::AlignTop);
+ window.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ window.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+ QStateMachine machine;
+ machine.setGlobalRestorePolicy(QState::RestoreProperties);
+
+ QState *group = new QState(&machine);
+ group->setObjectName("group");
+
+ QRect selectedRect(86, 86, 128, 128);
+
+ QState *idleState = new QState(group);
+ group->setInitialState(idleState);
+
+ QObjectList objects;
+ objects << p1 << p2 << p3 << p4;
+ createStates(objects, selectedRect, group);
+ createAnimations(objects, &machine);
+
+ machine.setInitialState(group);
+ machine.start();
+
+ window.resize(300, 300);
+ window.show();
+
+ return app.exec();
+}
+
+#include "main.moc"
diff --git a/examples/widgets/animation/easing/animation.h b/examples/widgets/animation/easing/animation.h
new file mode 100644
index 0000000000..35cbed4555
--- /dev/null
+++ b/examples/widgets/animation/easing/animation.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ANIMATION_H
+#define ANIMATION_H
+
+#include <QtWidgets>
+
+#include <QtCore/qpropertyanimation.h>
+
+class Animation : public QPropertyAnimation {
+public:
+ enum PathType {
+ LinearPath,
+ CirclePath,
+ NPathTypes
+ };
+ Animation(QObject *target, const QByteArray &prop)
+ : QPropertyAnimation(target, prop)
+ {
+ setPathType(LinearPath);
+ }
+
+ void setPathType(PathType pathType)
+ {
+ if (pathType >= NPathTypes)
+ qWarning("Unknown pathType %d", pathType);
+
+ m_pathType = pathType;
+ m_path = QPainterPath();
+ }
+
+ void updateCurrentTime(int currentTime)
+ {
+ if (m_pathType == CirclePath) {
+ if (m_path.isEmpty()) {
+ QPointF to = endValue().toPointF();
+ QPointF from = startValue().toPointF();
+ m_path.moveTo(from);
+ m_path.addEllipse(QRectF(from, to));
+ }
+ int dura = duration();
+ const qreal progress = ((dura == 0) ? 1 : ((((currentTime - 1) % dura) + 1) / qreal(dura)));
+
+ qreal easedProgress = easingCurve().valueForProgress(progress);
+ if (easedProgress > 1.0) {
+ easedProgress -= 1.0;
+ } else if (easedProgress < 0) {
+ easedProgress += 1.0;
+ }
+ QPointF pt = m_path.pointAtPercent(easedProgress);
+ updateCurrentValue(pt);
+ emit valueChanged(pt);
+ } else {
+ QPropertyAnimation::updateCurrentTime(currentTime);
+ }
+ }
+
+ QPainterPath m_path;
+ PathType m_pathType;
+};
+
+#endif // ANIMATION_H
diff --git a/examples/widgets/animation/easing/easing.desktop b/examples/widgets/animation/easing/easing.desktop
new file mode 100644
index 0000000000..56d122217a
--- /dev/null
+++ b/examples/widgets/animation/easing/easing.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=Easing Curves
+Exec=/opt/usr/bin/easing
+Icon=easing
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/examples/widgets/animation/easing/easing.pro b/examples/widgets/animation/easing/easing.pro
new file mode 100644
index 0000000000..155d17d9b9
--- /dev/null
+++ b/examples/widgets/animation/easing/easing.pro
@@ -0,0 +1,17 @@
+HEADERS = window.h \
+ animation.h
+SOURCES = main.cpp \
+ window.cpp
+
+FORMS = form.ui
+
+RESOURCES = easing.qrc
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/animation/easing
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS easing.pro images
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/animation/easing
+INSTALLS += target sources
+
+QT += widgets
+
diff --git a/examples/widgets/animation/easing/easing.qrc b/examples/widgets/animation/easing/easing.qrc
new file mode 100644
index 0000000000..7e112d3a9d
--- /dev/null
+++ b/examples/widgets/animation/easing/easing.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+ <qresource>
+ <file>images/qt-logo.png</file>
+ </qresource>
+ </RCC> \ No newline at end of file
diff --git a/examples/widgets/animation/easing/form.ui b/examples/widgets/animation/easing/form.ui
new file mode 100644
index 0000000000..364aebeda6
--- /dev/null
+++ b/examples/widgets/animation/easing/form.ui
@@ -0,0 +1,270 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Form</class>
+ <widget class="QWidget" name="Form">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>545</width>
+ <height>471</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Easing curves</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0" colspan="2">
+ <widget class="QListWidget" name="easingCurvePicker">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>120</height>
+ </size>
+ </property>
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="movement">
+ <enum>QListView::Static</enum>
+ </property>
+ <property name="isWrapping" stdset="0">
+ <bool>false</bool>
+ </property>
+ <property name="viewMode">
+ <enum>QListView::IconMode</enum>
+ </property>
+ <property name="selectionRectVisible">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="title">
+ <string>Path type</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QRadioButton" name="lineRadio">
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>40</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="text">
+ <string>Line</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <attribute name="buttonGroup">
+ <string>buttonGroup</string>
+ </attribute>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QRadioButton" name="circleRadio">
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>40</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Circle</string>
+ </property>
+ <attribute name="buttonGroup">
+ <string>buttonGroup</string>
+ </attribute>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Properties</string>
+ </property>
+ <layout class="QFormLayout" name="formLayout">
+ <property name="fieldGrowthPolicy">
+ <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>30</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Period</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QDoubleSpinBox" name="periodSpinBox">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>30</height>
+ </size>
+ </property>
+ <property name="minimum">
+ <double>-1.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>0.100000000000000</double>
+ </property>
+ <property name="value">
+ <double>-1.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QDoubleSpinBox" name="amplitudeSpinBox">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>30</height>
+ </size>
+ </property>
+ <property name="minimum">
+ <double>-1.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>0.100000000000000</double>
+ </property>
+ <property name="value">
+ <double>-1.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>30</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Overshoot</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QDoubleSpinBox" name="overshootSpinBox">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>30</height>
+ </size>
+ </property>
+ <property name="minimum">
+ <double>-1.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>0.100000000000000</double>
+ </property>
+ <property name="value">
+ <double>-1.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>30</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Amplitude</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="1">
+ <widget class="QGraphicsView" name="graphicsView">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+ <buttongroups>
+ <buttongroup name="buttonGroup"/>
+ </buttongroups>
+</ui>
diff --git a/examples/widgets/animation/easing/images/qt-logo.png b/examples/widgets/animation/easing/images/qt-logo.png
new file mode 100644
index 0000000000..14ddf2a028
--- /dev/null
+++ b/examples/widgets/animation/easing/images/qt-logo.png
Binary files differ
diff --git a/examples/widgets/animation/easing/main.cpp b/examples/widgets/animation/easing/main.cpp
new file mode 100644
index 0000000000..05d4014fc2
--- /dev/null
+++ b/examples/widgets/animation/easing/main.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets>
+#include "window.h"
+
+int main(int argc, char **argv)
+{
+ Q_INIT_RESOURCE(easing);
+ QApplication app(argc, argv);
+ Window w;
+
+ w.resize(400, 400);
+ w.show();
+
+ return app.exec();
+}
diff --git a/examples/widgets/animation/easing/window.cpp b/examples/widgets/animation/easing/window.cpp
new file mode 100644
index 0000000000..33468db59c
--- /dev/null
+++ b/examples/widgets/animation/easing/window.cpp
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "window.h"
+
+Window::Window(QWidget *parent)
+ : QWidget(parent),
+ m_iconSize(64, 64)
+{
+ m_ui.setupUi(this);
+ QButtonGroup *buttonGroup = findChild<QButtonGroup *>(); // ### workaround for uic in 4.4
+ m_ui.easingCurvePicker->setIconSize(m_iconSize);
+ m_ui.easingCurvePicker->setMinimumHeight(m_iconSize.height() + 50);
+ buttonGroup->setId(m_ui.lineRadio, 0);
+ buttonGroup->setId(m_ui.circleRadio, 1);
+
+ QEasingCurve dummy;
+ m_ui.periodSpinBox->setValue(dummy.period());
+ m_ui.amplitudeSpinBox->setValue(dummy.amplitude());
+ m_ui.overshootSpinBox->setValue(dummy.overshoot());
+
+ connect(m_ui.easingCurvePicker, SIGNAL(currentRowChanged(int)), this, SLOT(curveChanged(int)));
+ connect(buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(pathChanged(int)));
+ connect(m_ui.periodSpinBox, SIGNAL(valueChanged(double)), this, SLOT(periodChanged(double)));
+ connect(m_ui.amplitudeSpinBox, SIGNAL(valueChanged(double)), this, SLOT(amplitudeChanged(double)));
+ connect(m_ui.overshootSpinBox, SIGNAL(valueChanged(double)), this, SLOT(overshootChanged(double)));
+ createCurveIcons();
+
+ QPixmap pix(QLatin1String(":/images/qt-logo.png"));
+ m_item = new PixmapItem(pix);
+ m_scene.addItem(m_item);
+ m_ui.graphicsView->setScene(&m_scene);
+
+ m_anim = new Animation(m_item, "pos");
+ m_anim->setEasingCurve(QEasingCurve::OutBounce);
+ m_ui.easingCurvePicker->setCurrentRow(int(QEasingCurve::OutBounce));
+
+ startAnimation();
+}
+
+void Window::createCurveIcons()
+{
+ QPixmap pix(m_iconSize);
+ QPainter painter(&pix);
+ QLinearGradient gradient(0,0, 0, m_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"));
+ // Skip QEasingCurve::Custom
+ for (int i = 0; i < QEasingCurve::NCurveTypes - 1; ++i) {
+ painter.fillRect(QRect(QPoint(0, 0), m_iconSize), brush);
+ QEasingCurve curve((QEasingCurve::Type)i);
+ painter.setPen(QColor(0, 0, 255, 64));
+ qreal xAxis = m_iconSize.height()/1.5;
+ qreal yAxis = m_iconSize.width()/3;
+ painter.drawLine(0, xAxis, m_iconSize.width(), xAxis);
+ painter.drawLine(yAxis, 0, yAxis, m_iconSize.height());
+
+ qreal curveScale = m_iconSize.height()/2;
+
+ painter.setPen(Qt::NoPen);
+
+ // start point
+ painter.setBrush(Qt::red);
+ QPoint start(yAxis, xAxis - curveScale * curve.valueForProgress(0));
+ painter.drawRect(start.x() - 1, start.y() - 1, 3, 3);
+
+ // end point
+ painter.setBrush(Qt::blue);
+ QPoint end(yAxis + curveScale, xAxis - curveScale * curve.valueForProgress(1));
+ painter.drawRect(end.x() - 1, end.y() - 1, 3, 3);
+
+ QPainterPath curvePath;
+ curvePath.moveTo(start);
+ 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));
+ curvePath.lineTo(to);
+ }
+ painter.setRenderHint(QPainter::Antialiasing, true);
+ painter.strokePath(curvePath, QColor(32, 32, 32));
+ painter.setRenderHint(QPainter::Antialiasing, false);
+ QListWidgetItem *item = new QListWidgetItem;
+ item->setIcon(QIcon(pix));
+ item->setText(metaEnum.key(i));
+ m_ui.easingCurvePicker->addItem(item);
+ }
+}
+
+void Window::startAnimation()
+{
+ m_anim->setStartValue(QPointF(0, 0));
+ m_anim->setEndValue(QPointF(100, 100));
+ m_anim->setDuration(2000);
+ m_anim->setLoopCount(-1); // forever
+ m_anim->start();
+}
+
+void Window::curveChanged(int row)
+{
+ QEasingCurve::Type curveType = (QEasingCurve::Type)row;
+ m_anim->setEasingCurve(curveType);
+ m_anim->setCurrentTime(0);
+
+ bool isElastic = curveType >= QEasingCurve::InElastic && curveType <= QEasingCurve::OutInElastic;
+ bool isBounce = curveType >= QEasingCurve::InBounce && curveType <= QEasingCurve::OutInBounce;
+ m_ui.periodSpinBox->setEnabled(isElastic);
+ m_ui.amplitudeSpinBox->setEnabled(isElastic || isBounce);
+ m_ui.overshootSpinBox->setEnabled(curveType >= QEasingCurve::InBack && curveType <= QEasingCurve::OutInBack);
+}
+
+void Window::pathChanged(int index)
+{
+ m_anim->setPathType((Animation::PathType)index);
+}
+
+void Window::periodChanged(double value)
+{
+ QEasingCurve curve = m_anim->easingCurve();
+ curve.setPeriod(value);
+ m_anim->setEasingCurve(curve);
+}
+
+void Window::amplitudeChanged(double value)
+{
+ QEasingCurve curve = m_anim->easingCurve();
+ curve.setAmplitude(value);
+ m_anim->setEasingCurve(curve);
+}
+
+void Window::overshootChanged(double value)
+{
+ QEasingCurve curve = m_anim->easingCurve();
+ curve.setOvershoot(value);
+ m_anim->setEasingCurve(curve);
+}
+
diff --git a/examples/widgets/animation/easing/window.h b/examples/widgets/animation/easing/window.h
new file mode 100644
index 0000000000..bf5014c0cc
--- /dev/null
+++ b/examples/widgets/animation/easing/window.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets>
+
+#include "ui_form.h"
+#include "animation.h"
+
+class PixmapItem : public QObject, public QGraphicsPixmapItem
+{
+ Q_OBJECT
+ Q_PROPERTY(QPointF pos READ pos WRITE setPos)
+public:
+ PixmapItem(const QPixmap &pix) : QGraphicsPixmapItem(pix)
+ {
+ }
+};
+
+class Window : public QWidget {
+ Q_OBJECT
+public:
+ Window(QWidget *parent = 0);
+private slots:
+ void curveChanged(int row);
+ void pathChanged(int index);
+ void periodChanged(double);
+ void amplitudeChanged(double);
+ void overshootChanged(double);
+
+private:
+ void createCurveIcons();
+ void startAnimation();
+
+ Ui::Form m_ui;
+ QGraphicsScene m_scene;
+ PixmapItem *m_item;
+ Animation *m_anim;
+ QSize m_iconSize;
+};
diff --git a/examples/widgets/animation/moveblocks/main.cpp b/examples/widgets/animation/moveblocks/main.cpp
new file mode 100644
index 0000000000..d807bb63d9
--- /dev/null
+++ b/examples/widgets/animation/moveblocks/main.cpp
@@ -0,0 +1,321 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore>
+#include <QtWidgets>
+
+//![15]
+class StateSwitchEvent: public QEvent
+{
+public:
+ StateSwitchEvent()
+ : QEvent(Type(StateSwitchType))
+ {
+ }
+
+ explicit StateSwitchEvent(int rand)
+ : QEvent(Type(StateSwitchType)),
+ m_rand(rand)
+ {
+ }
+
+ enum { StateSwitchType = QEvent::User + 256 };
+
+ int rand() const { return m_rand; }
+
+private:
+ int m_rand;
+};
+//![15]
+
+//![16]
+class QGraphicsRectWidget : public QGraphicsWidget
+{
+public:
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *,
+ QWidget *)
+ {
+ painter->fillRect(rect(), Qt::blue);
+ }
+};
+//![16]
+
+class StateSwitchTransition: public QAbstractTransition
+{
+public:
+ StateSwitchTransition(int rand)
+ : QAbstractTransition(),
+ m_rand(rand)
+ {
+ }
+
+protected:
+//![14]
+ virtual bool eventTest(QEvent *event)
+ {
+ return (event->type() == QEvent::Type(StateSwitchEvent::StateSwitchType))
+ && (static_cast<StateSwitchEvent *>(event)->rand() == m_rand);
+ }
+//![14]
+
+ virtual void onTransition(QEvent *) {}
+
+private:
+ int m_rand;
+};
+
+//![10]
+class StateSwitcher : public QState
+{
+ Q_OBJECT
+public:
+ StateSwitcher(QStateMachine *machine)
+ : QState(machine), m_stateCount(0), m_lastIndex(0)
+ { }
+//![10]
+
+//![11]
+ virtual void onEntry(QEvent *)
+ {
+ int n;
+ while ((n = (qrand() % m_stateCount + 1)) == m_lastIndex)
+ { }
+ m_lastIndex = n;
+ machine()->postEvent(new StateSwitchEvent(n));
+ }
+ virtual void onExit(QEvent *) {}
+//![11]
+
+//![12]
+ void addState(QState *state, QAbstractAnimation *animation) {
+ StateSwitchTransition *trans = new StateSwitchTransition(++m_stateCount);
+ trans->setTargetState(state);
+ addTransition(trans);
+ trans->addAnimation(animation);
+ }
+//![12]
+
+private:
+ int m_stateCount;
+ int m_lastIndex;
+};
+
+//![13]
+QState *createGeometryState(QObject *w1, const QRect &rect1,
+ QObject *w2, const QRect &rect2,
+ QObject *w3, const QRect &rect3,
+ QObject *w4, const QRect &rect4,
+ QState *parent)
+{
+ QState *result = new QState(parent);
+ result->assignProperty(w1, "geometry", rect1);
+ result->assignProperty(w2, "geometry", rect2);
+ result->assignProperty(w3, "geometry", rect3);
+ result->assignProperty(w4, "geometry", rect4);
+
+ return result;
+}
+//![13]
+
+
+class GraphicsView : public QGraphicsView
+{
+ Q_OBJECT
+public:
+ GraphicsView(QGraphicsScene *scene, QWidget *parent = NULL) : QGraphicsView(scene, parent)
+ {
+ }
+
+protected:
+ virtual void resizeEvent(QResizeEvent *event)
+ {
+ fitInView(scene()->sceneRect());
+ QGraphicsView::resizeEvent(event);
+ }
+};
+
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+//![1]
+ QGraphicsRectWidget *button1 = new QGraphicsRectWidget;
+ QGraphicsRectWidget *button2 = new QGraphicsRectWidget;
+ QGraphicsRectWidget *button3 = new QGraphicsRectWidget;
+ QGraphicsRectWidget *button4 = new QGraphicsRectWidget;
+ button2->setZValue(1);
+ button3->setZValue(2);
+ button4->setZValue(3);
+ QGraphicsScene scene(0, 0, 300, 300);
+ scene.setBackgroundBrush(Qt::black);
+ scene.addItem(button1);
+ scene.addItem(button2);
+ scene.addItem(button3);
+ scene.addItem(button4);
+//![1]
+ GraphicsView window(&scene);
+ window.setFrameStyle(0);
+ window.setAlignment(Qt::AlignLeft | Qt::AlignTop);
+ window.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ window.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+//![2]
+ QStateMachine machine;
+
+ QState *group = new QState();
+ group->setObjectName("group");
+ QTimer timer;
+ timer.setInterval(1250);
+ timer.setSingleShot(true);
+ QObject::connect(group, SIGNAL(entered()), &timer, SLOT(start()));
+//![2]
+
+//![3]
+ QState *state1;
+ QState *state2;
+ QState *state3;
+ QState *state4;
+ QState *state5;
+ QState *state6;
+ QState *state7;
+
+ state1 = createGeometryState(button1, QRect(100, 0, 50, 50),
+ button2, QRect(150, 0, 50, 50),
+ button3, QRect(200, 0, 50, 50),
+ button4, QRect(250, 0, 50, 50),
+ group);
+//![3]
+ state2 = createGeometryState(button1, QRect(250, 100, 50, 50),
+ button2, QRect(250, 150, 50, 50),
+ button3, QRect(250, 200, 50, 50),
+ button4, QRect(250, 250, 50, 50),
+ group);
+ state3 = createGeometryState(button1, QRect(150, 250, 50, 50),
+ button2, QRect(100, 250, 50, 50),
+ button3, QRect(50, 250, 50, 50),
+ button4, QRect(0, 250, 50, 50),
+ group);
+ state4 = createGeometryState(button1, QRect(0, 150, 50, 50),
+ button2, QRect(0, 100, 50, 50),
+ button3, QRect(0, 50, 50, 50),
+ button4, QRect(0, 0, 50, 50),
+ group);
+ state5 = createGeometryState(button1, QRect(100, 100, 50, 50),
+ button2, QRect(150, 100, 50, 50),
+ button3, QRect(100, 150, 50, 50),
+ button4, QRect(150, 150, 50, 50),
+ group);
+ state6 = createGeometryState(button1, QRect(50, 50, 50, 50),
+ button2, QRect(200, 50, 50, 50),
+ button3, QRect(50, 200, 50, 50),
+ button4, QRect(200, 200, 50, 50),
+ group);
+//![4]
+ state7 = createGeometryState(button1, QRect(0, 0, 50, 50),
+ button2, QRect(250, 0, 50, 50),
+ button3, QRect(0, 250, 50, 50),
+ button4, QRect(250, 250, 50, 50),
+ group);
+ group->setInitialState(state1);
+//![4]
+
+//![5]
+ QParallelAnimationGroup animationGroup;
+ QSequentialAnimationGroup *subGroup;
+
+ QPropertyAnimation *anim = new QPropertyAnimation(button4, "geometry");
+ anim->setDuration(1000);
+ anim->setEasingCurve(QEasingCurve::OutElastic);
+ animationGroup.addAnimation(anim);
+//![5]
+
+//![6]
+ subGroup = new QSequentialAnimationGroup(&animationGroup);
+ subGroup->addPause(100);
+ anim = new QPropertyAnimation(button3, "geometry");
+ anim->setDuration(1000);
+ anim->setEasingCurve(QEasingCurve::OutElastic);
+ subGroup->addAnimation(anim);
+//![6]
+
+ subGroup = new QSequentialAnimationGroup(&animationGroup);
+ subGroup->addPause(150);
+ anim = new QPropertyAnimation(button2, "geometry");
+ anim->setDuration(1000);
+ anim->setEasingCurve(QEasingCurve::OutElastic);
+ subGroup->addAnimation(anim);
+
+ subGroup = new QSequentialAnimationGroup(&animationGroup);
+ subGroup->addPause(200);
+ anim = new QPropertyAnimation(button1, "geometry");
+ anim->setDuration(1000);
+ anim->setEasingCurve(QEasingCurve::OutElastic);
+ subGroup->addAnimation(anim);
+
+//![7]
+ StateSwitcher *stateSwitcher = new StateSwitcher(&machine);
+ stateSwitcher->setObjectName("stateSwitcher");
+ group->addTransition(&timer, SIGNAL(timeout()), stateSwitcher);
+ stateSwitcher->addState(state1, &animationGroup);
+ stateSwitcher->addState(state2, &animationGroup);
+//![7]
+ stateSwitcher->addState(state3, &animationGroup);
+ stateSwitcher->addState(state4, &animationGroup);
+ stateSwitcher->addState(state5, &animationGroup);
+ stateSwitcher->addState(state6, &animationGroup);
+//![8]
+ stateSwitcher->addState(state7, &animationGroup);
+//![8]
+
+//![9]
+ machine.addState(group);
+ machine.setInitialState(group);
+ machine.start();
+//![9]
+
+ window.resize(300, 300);
+ window.show();
+
+ qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
+
+ return app.exec();
+}
+
+#include "main.moc"
diff --git a/examples/widgets/animation/moveblocks/moveblocks.desktop b/examples/widgets/animation/moveblocks/moveblocks.desktop
new file mode 100644
index 0000000000..4100f448df
--- /dev/null
+++ b/examples/widgets/animation/moveblocks/moveblocks.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=Move Blocks
+Exec=/opt/usr/bin/moveblocks
+Icon=moveblocks
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/examples/widgets/animation/moveblocks/moveblocks.pro b/examples/widgets/animation/moveblocks/moveblocks.pro
new file mode 100644
index 0000000000..7c242e31e6
--- /dev/null
+++ b/examples/widgets/animation/moveblocks/moveblocks.pro
@@ -0,0 +1,9 @@
+SOURCES = main.cpp
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/animation/moveblocks
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS moveblocks.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/animation/moveblocks
+INSTALLS += target sources
+
+QT += widgets
diff --git a/examples/widgets/animation/states/accessories-dictionary.png b/examples/widgets/animation/states/accessories-dictionary.png
new file mode 100644
index 0000000000..e9bd55d918
--- /dev/null
+++ b/examples/widgets/animation/states/accessories-dictionary.png
Binary files differ
diff --git a/examples/widgets/animation/states/akregator.png b/examples/widgets/animation/states/akregator.png
new file mode 100644
index 0000000000..a086f45ab6
--- /dev/null
+++ b/examples/widgets/animation/states/akregator.png
Binary files differ
diff --git a/examples/widgets/animation/states/digikam.png b/examples/widgets/animation/states/digikam.png
new file mode 100644
index 0000000000..9de9fb2f80
--- /dev/null
+++ b/examples/widgets/animation/states/digikam.png
Binary files differ
diff --git a/examples/widgets/animation/states/help-browser.png b/examples/widgets/animation/states/help-browser.png
new file mode 100644
index 0000000000..db92faa4e7
--- /dev/null
+++ b/examples/widgets/animation/states/help-browser.png
Binary files differ
diff --git a/examples/widgets/animation/states/k3b.png b/examples/widgets/animation/states/k3b.png
new file mode 100644
index 0000000000..bbcafcfba1
--- /dev/null
+++ b/examples/widgets/animation/states/k3b.png
Binary files differ
diff --git a/examples/widgets/animation/states/kchart.png b/examples/widgets/animation/states/kchart.png
new file mode 100644
index 0000000000..1dd115be87
--- /dev/null
+++ b/examples/widgets/animation/states/kchart.png
Binary files differ
diff --git a/examples/widgets/animation/states/main.cpp b/examples/widgets/animation/states/main.cpp
new file mode 100644
index 0000000000..faa97ccbd0
--- /dev/null
+++ b/examples/widgets/animation/states/main.cpp
@@ -0,0 +1,285 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets>
+
+class Pixmap : public QGraphicsObject
+{
+ Q_OBJECT
+public:
+ Pixmap(const QPixmap &pix) : QGraphicsObject(), p(pix)
+ {
+ }
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+ {
+ painter->drawPixmap(QPointF(), p);
+ }
+
+ QRectF boundingRect() const
+ {
+ return QRectF( QPointF(0, 0), p.size());
+ }
+
+private:
+ QPixmap p;
+};
+
+class GraphicsView : public QGraphicsView
+{
+public:
+ GraphicsView(QGraphicsScene *scene) : QGraphicsView(scene)
+ {
+ }
+
+ virtual void resizeEvent(QResizeEvent *)
+ {
+ fitInView(sceneRect(), Qt::KeepAspectRatio);
+ }
+};
+
+int main(int argc, char *argv[])
+{
+ Q_INIT_RESOURCE(states);
+
+ QApplication app(argc, argv);
+
+ // Text edit and button
+ QTextEdit *edit = new QTextEdit;
+ edit->setText("asdf lkjha yuoiqwe asd iuaysd u iasyd uiy "
+ "asdf lkjha yuoiqwe asd iuaysd u iasyd uiy "
+ "asdf lkjha yuoiqwe asd iuaysd u iasyd uiy "
+ "asdf lkjha yuoiqwe asd iuaysd u iasyd uiy!");
+
+ QPushButton *button = new QPushButton;
+ QGraphicsProxyWidget *buttonProxy = new QGraphicsProxyWidget;
+ buttonProxy->setWidget(button);
+ QGraphicsProxyWidget *editProxy = new QGraphicsProxyWidget;
+ editProxy->setWidget(edit);
+
+ QGroupBox *box = new QGroupBox;
+ box->setFlat(true);
+ box->setTitle("Options");
+
+ QVBoxLayout *layout2 = new QVBoxLayout;
+ box->setLayout(layout2);
+ layout2->addWidget(new QRadioButton("Herring"));
+ layout2->addWidget(new QRadioButton("Blue Parrot"));
+ layout2->addWidget(new QRadioButton("Petunias"));
+ layout2->addStretch();
+
+ QGraphicsProxyWidget *boxProxy = new QGraphicsProxyWidget;
+ boxProxy->setWidget(box);
+
+ // Parent widget
+ QGraphicsWidget *widget = new QGraphicsWidget;
+ QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical, widget);
+ layout->addItem(editProxy);
+ layout->addItem(buttonProxy);
+ widget->setLayout(layout);
+
+ Pixmap *p1 = new Pixmap(QPixmap(":/digikam.png"));
+ Pixmap *p2 = new Pixmap(QPixmap(":/akregator.png"));
+ Pixmap *p3 = new Pixmap(QPixmap(":/accessories-dictionary.png"));
+ Pixmap *p4 = new Pixmap(QPixmap(":/k3b.png"));
+ Pixmap *p5 = new Pixmap(QPixmap(":/help-browser.png"));
+ Pixmap *p6 = new Pixmap(QPixmap(":/kchart.png"));
+
+ QGraphicsScene scene(0, 0, 400, 300);
+ scene.setBackgroundBrush(scene.palette().window());
+ scene.addItem(widget);
+ scene.addItem(boxProxy);
+ scene.addItem(p1);
+ scene.addItem(p2);
+ scene.addItem(p3);
+ scene.addItem(p4);
+ scene.addItem(p5);
+ scene.addItem(p6);
+
+ QStateMachine machine;
+ QState *state1 = new QState(&machine);
+ QState *state2 = new QState(&machine);
+ QState *state3 = new QState(&machine);
+ machine.setInitialState(state1);
+
+ // State 1
+ state1->assignProperty(button, "text", "Switch to state 2");
+ state1->assignProperty(widget, "geometry", QRectF(0, 0, 400, 150));
+ state1->assignProperty(box, "geometry", QRect(-200, 150, 200, 150));
+ state1->assignProperty(p1, "pos", QPointF(68, 200)); // 185));
+ state1->assignProperty(p2, "pos", QPointF(168, 200)); // 185));
+ state1->assignProperty(p3, "pos", QPointF(268, 200)); // 185));
+ state1->assignProperty(p4, "pos", QPointF(68 - 150, 48 - 150));
+ state1->assignProperty(p5, "pos", QPointF(168, 48 - 150));
+ state1->assignProperty(p6, "pos", QPointF(268 + 150, 48 - 150));
+ state1->assignProperty(p1, "rotation", qreal(0));
+ state1->assignProperty(p2, "rotation", qreal(0));
+ state1->assignProperty(p3, "rotation", qreal(0));
+ state1->assignProperty(p4, "rotation", qreal(-270));
+ state1->assignProperty(p5, "rotation", qreal(-90));
+ state1->assignProperty(p6, "rotation", qreal(270));
+ state1->assignProperty(boxProxy, "opacity", qreal(0));
+ state1->assignProperty(p1, "opacity", qreal(1));
+ state1->assignProperty(p2, "opacity", qreal(1));
+ state1->assignProperty(p3, "opacity", qreal(1));
+ state1->assignProperty(p4, "opacity", qreal(0));
+ state1->assignProperty(p5, "opacity", qreal(0));
+ state1->assignProperty(p6, "opacity", qreal(0));
+
+ // State 2
+ state2->assignProperty(button, "text", "Switch to state 3");
+ state2->assignProperty(widget, "geometry", QRectF(200, 150, 200, 150));
+ state2->assignProperty(box, "geometry", QRect(9, 150, 190, 150));
+ state2->assignProperty(p1, "pos", QPointF(68 - 150, 185 + 150));
+ state2->assignProperty(p2, "pos", QPointF(168, 185 + 150));
+ state2->assignProperty(p3, "pos", QPointF(268 + 150, 185 + 150));
+ state2->assignProperty(p4, "pos", QPointF(64, 48));
+ state2->assignProperty(p5, "pos", QPointF(168, 48));
+ state2->assignProperty(p6, "pos", QPointF(268, 48));
+ state2->assignProperty(p1, "rotation", qreal(-270));
+ state2->assignProperty(p2, "rotation", qreal(90));
+ state2->assignProperty(p3, "rotation", qreal(270));
+ state2->assignProperty(p4, "rotation", qreal(0));
+ state2->assignProperty(p5, "rotation", qreal(0));
+ state2->assignProperty(p6, "rotation", qreal(0));
+ state2->assignProperty(boxProxy, "opacity", qreal(1));
+ state2->assignProperty(p1, "opacity", qreal(0));
+ state2->assignProperty(p2, "opacity", qreal(0));
+ state2->assignProperty(p3, "opacity", qreal(0));
+ state2->assignProperty(p4, "opacity", qreal(1));
+ state2->assignProperty(p5, "opacity", qreal(1));
+ state2->assignProperty(p6, "opacity", qreal(1));
+
+ // State 3
+ state3->assignProperty(button, "text", "Switch to state 1");
+ state3->assignProperty(p1, "pos", QPointF(0, 5));
+ state3->assignProperty(p2, "pos", QPointF(0, 5 + 64 + 5));
+ state3->assignProperty(p3, "pos", QPointF(5, 5 + (64 + 5) + 64));
+ state3->assignProperty(p4, "pos", QPointF(5 + 64 + 5, 5));
+ state3->assignProperty(p5, "pos", QPointF(5 + 64 + 5, 5 + 64 + 5));
+ state3->assignProperty(p6, "pos", QPointF(5 + 64 + 5, 5 + (64 + 5) + 64));
+ state3->assignProperty(widget, "geometry", QRectF(138, 5, 400 - 138, 200));
+ state3->assignProperty(box, "geometry", QRect(5, 205, 400, 90));
+ state3->assignProperty(p1, "opacity", qreal(1));
+ state3->assignProperty(p2, "opacity", qreal(1));
+ state3->assignProperty(p3, "opacity", qreal(1));
+ state3->assignProperty(p4, "opacity", qreal(1));
+ state3->assignProperty(p5, "opacity", qreal(1));
+ state3->assignProperty(p6, "opacity", qreal(1));
+
+ QAbstractTransition *t1 = state1->addTransition(button, SIGNAL(clicked()), state2);
+ QSequentialAnimationGroup *animation1SubGroup = new QSequentialAnimationGroup;
+ animation1SubGroup->addPause(250);
+ animation1SubGroup->addAnimation(new QPropertyAnimation(box, "geometry"));
+ t1->addAnimation(animation1SubGroup);
+ t1->addAnimation(new QPropertyAnimation(widget, "geometry"));
+ t1->addAnimation(new QPropertyAnimation(p1, "pos"));
+ t1->addAnimation(new QPropertyAnimation(p2, "pos"));
+ t1->addAnimation(new QPropertyAnimation(p3, "pos"));
+ t1->addAnimation(new QPropertyAnimation(p4, "pos"));
+ t1->addAnimation(new QPropertyAnimation(p5, "pos"));
+ t1->addAnimation(new QPropertyAnimation(p6, "pos"));
+ t1->addAnimation(new QPropertyAnimation(p1, "rotation"));
+ t1->addAnimation(new QPropertyAnimation(p2, "rotation"));
+ t1->addAnimation(new QPropertyAnimation(p3, "rotation"));
+ t1->addAnimation(new QPropertyAnimation(p4, "rotation"));
+ t1->addAnimation(new QPropertyAnimation(p5, "rotation"));
+ t1->addAnimation(new QPropertyAnimation(p6, "rotation"));
+ t1->addAnimation(new QPropertyAnimation(p1, "opacity"));
+ t1->addAnimation(new QPropertyAnimation(p2, "opacity"));
+ t1->addAnimation(new QPropertyAnimation(p3, "opacity"));
+ t1->addAnimation(new QPropertyAnimation(p4, "opacity"));
+ t1->addAnimation(new QPropertyAnimation(p5, "opacity"));
+ t1->addAnimation(new QPropertyAnimation(p6, "opacity"));
+
+ QAbstractTransition *t2 = state2->addTransition(button, SIGNAL(clicked()), state3);
+ t2->addAnimation(new QPropertyAnimation(box, "geometry"));
+ t2->addAnimation(new QPropertyAnimation(widget, "geometry"));
+ t2->addAnimation(new QPropertyAnimation(p1, "pos"));
+ t2->addAnimation(new QPropertyAnimation(p2, "pos"));
+ t2->addAnimation(new QPropertyAnimation(p3, "pos"));
+ t2->addAnimation(new QPropertyAnimation(p4, "pos"));
+ t2->addAnimation(new QPropertyAnimation(p5, "pos"));
+ t2->addAnimation(new QPropertyAnimation(p6, "pos"));
+ t2->addAnimation(new QPropertyAnimation(p1, "rotation"));
+ t2->addAnimation(new QPropertyAnimation(p2, "rotation"));
+ t2->addAnimation(new QPropertyAnimation(p3, "rotation"));
+ t2->addAnimation(new QPropertyAnimation(p4, "rotation"));
+ t2->addAnimation(new QPropertyAnimation(p5, "rotation"));
+ t2->addAnimation(new QPropertyAnimation(p6, "rotation"));
+ t2->addAnimation(new QPropertyAnimation(p1, "opacity"));
+ t2->addAnimation(new QPropertyAnimation(p2, "opacity"));
+ t2->addAnimation(new QPropertyAnimation(p3, "opacity"));
+ t2->addAnimation(new QPropertyAnimation(p4, "opacity"));
+ t2->addAnimation(new QPropertyAnimation(p5, "opacity"));
+ t2->addAnimation(new QPropertyAnimation(p6, "opacity"));
+
+ QAbstractTransition *t3 = state3->addTransition(button, SIGNAL(clicked()), state1);
+ t3->addAnimation(new QPropertyAnimation(box, "geometry"));
+ t3->addAnimation(new QPropertyAnimation(widget, "geometry"));
+ t3->addAnimation(new QPropertyAnimation(p1, "pos"));
+ t3->addAnimation(new QPropertyAnimation(p2, "pos"));
+ t3->addAnimation(new QPropertyAnimation(p3, "pos"));
+ t3->addAnimation(new QPropertyAnimation(p4, "pos"));
+ t3->addAnimation(new QPropertyAnimation(p5, "pos"));
+ t3->addAnimation(new QPropertyAnimation(p6, "pos"));
+ t3->addAnimation(new QPropertyAnimation(p1, "rotation"));
+ t3->addAnimation(new QPropertyAnimation(p2, "rotation"));
+ t3->addAnimation(new QPropertyAnimation(p3, "rotation"));
+ t3->addAnimation(new QPropertyAnimation(p4, "rotation"));
+ t3->addAnimation(new QPropertyAnimation(p5, "rotation"));
+ t3->addAnimation(new QPropertyAnimation(p6, "rotation"));
+ t3->addAnimation(new QPropertyAnimation(p1, "opacity"));
+ t3->addAnimation(new QPropertyAnimation(p2, "opacity"));
+ t3->addAnimation(new QPropertyAnimation(p3, "opacity"));
+ t3->addAnimation(new QPropertyAnimation(p4, "opacity"));
+ t3->addAnimation(new QPropertyAnimation(p5, "opacity"));
+ t3->addAnimation(new QPropertyAnimation(p6, "opacity"));
+
+ machine.start();
+
+ GraphicsView view(&scene);
+
+ view.show();
+
+ return app.exec();
+}
+
+#include "main.moc"
diff --git a/examples/widgets/animation/states/states.desktop b/examples/widgets/animation/states/states.desktop
new file mode 100644
index 0000000000..8429979f23
--- /dev/null
+++ b/examples/widgets/animation/states/states.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=States
+Exec=/opt/usr/bin/states
+Icon=states
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/examples/widgets/animation/states/states.pro b/examples/widgets/animation/states/states.pro
new file mode 100644
index 0000000000..adf0e8d58c
--- /dev/null
+++ b/examples/widgets/animation/states/states.pro
@@ -0,0 +1,10 @@
+SOURCES += main.cpp
+RESOURCES += states.qrc
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/animation/states
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS states.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/animation/states
+INSTALLS += target sources
+
+QT += widgets
diff --git a/examples/widgets/animation/states/states.qrc b/examples/widgets/animation/states/states.qrc
new file mode 100644
index 0000000000..60ab3f7a60
--- /dev/null
+++ b/examples/widgets/animation/states/states.qrc
@@ -0,0 +1,10 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>accessories-dictionary.png</file>
+ <file>akregator.png</file>
+ <file>digikam.png</file>
+ <file>help-browser.png</file>
+ <file>k3b.png</file>
+ <file>kchart.png</file>
+</qresource>
+</RCC>
diff --git a/examples/widgets/animation/stickman/animation.cpp b/examples/widgets/animation/stickman/animation.cpp
new file mode 100644
index 0000000000..afdfae6eca
--- /dev/null
+++ b/examples/widgets/animation/stickman/animation.cpp
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "animation.h"
+
+#include <QPointF>
+#include <QVector>
+#include <QIODevice>
+#include <QDataStream>
+
+class Frame
+{
+public:
+ Frame() {
+ }
+
+ int nodeCount() const
+ {
+ return m_nodePositions.size();
+ }
+
+ void setNodeCount(int nodeCount)
+ {
+ m_nodePositions.resize(nodeCount);
+ }
+
+ QPointF nodePos(int idx) const
+ {
+ return m_nodePositions.at(idx);
+ }
+
+ void setNodePos(int idx, const QPointF &pos)
+ {
+ m_nodePositions[idx] = pos;
+ }
+
+private:
+ QVector<QPointF> m_nodePositions;
+};
+
+Animation::Animation()
+{
+ m_currentFrame = 0;
+ m_frames.append(new Frame);
+}
+
+Animation::~Animation()
+{
+ qDeleteAll(m_frames);
+}
+
+void Animation::setTotalFrames(int totalFrames)
+{
+ while (m_frames.size() < totalFrames)
+ m_frames.append(new Frame);
+
+ while (totalFrames < m_frames.size())
+ delete m_frames.takeLast();
+}
+
+int Animation::totalFrames() const
+{
+ return m_frames.size();
+}
+
+void Animation::setCurrentFrame(int currentFrame)
+{
+ m_currentFrame = qMax(qMin(currentFrame, totalFrames()-1), 0);
+}
+
+int Animation::currentFrame() const
+{
+ return m_currentFrame;
+}
+
+void Animation::setNodeCount(int nodeCount)
+{
+ Frame *frame = m_frames.at(m_currentFrame);
+ frame->setNodeCount(nodeCount);
+}
+
+int Animation::nodeCount() const
+{
+ Frame *frame = m_frames.at(m_currentFrame);
+ return frame->nodeCount();
+}
+
+void Animation::setNodePos(int idx, const QPointF &pos)
+{
+ Frame *frame = m_frames.at(m_currentFrame);
+ frame->setNodePos(idx, pos);
+}
+
+QPointF Animation::nodePos(int idx) const
+{
+ Frame *frame = m_frames.at(m_currentFrame);
+ return frame->nodePos(idx);
+}
+
+QString Animation::name() const
+{
+ return m_name;
+}
+
+void Animation::setName(const QString &name)
+{
+ m_name = name;
+}
+
+void Animation::save(QIODevice *device) const
+{
+ QDataStream stream(device);
+ stream << m_name;
+ stream << m_frames.size();
+ foreach (Frame *frame, m_frames) {
+ stream << frame->nodeCount();
+ for (int i=0; i<frame->nodeCount(); ++i)
+ stream << frame->nodePos(i);
+ }
+}
+
+void Animation::load(QIODevice *device)
+{
+ if (!m_frames.isEmpty())
+ qDeleteAll(m_frames);
+
+ m_frames.clear();
+
+ QDataStream stream(device);
+ stream >> m_name;
+
+ int frameCount;
+ stream >> frameCount;
+
+ for (int i=0; i<frameCount; ++i) {
+
+ int nodeCount;
+ stream >> nodeCount;
+
+ Frame *frame = new Frame;
+ frame->setNodeCount(nodeCount);
+
+ for (int j=0; j<nodeCount; ++j) {
+ QPointF pos;
+ stream >> pos;
+
+ frame->setNodePos(j, pos);
+ }
+
+ m_frames.append(frame);
+ }
+}
diff --git a/examples/widgets/animation/stickman/animation.h b/examples/widgets/animation/stickman/animation.h
new file mode 100644
index 0000000000..d5dab530e6
--- /dev/null
+++ b/examples/widgets/animation/stickman/animation.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ANIMATION_H
+#define ANIMATION_H
+
+#include <QPointF>
+#include <QList>
+#include <QString>
+
+class Frame;
+QT_BEGIN_NAMESPACE
+class QIODevice;
+QT_END_NAMESPACE
+class Animation
+{
+public:
+ Animation();
+ ~Animation();
+
+ void setTotalFrames(int totalFrames);
+ int totalFrames() const;
+
+ void setCurrentFrame(int currentFrame);
+ int currentFrame() const;
+
+ void setNodeCount(int nodeCount);
+ int nodeCount() const;
+
+ void setNodePos(int idx, const QPointF &pos);
+ QPointF nodePos(int idx) const;
+
+ QString name() const;
+ void setName(const QString &name);
+
+ void save(QIODevice *device) const;
+ void load(QIODevice *device);
+
+private:
+ QString m_name;
+ QList<Frame *> m_frames;
+ int m_currentFrame;
+};
+
+#endif
diff --git a/examples/widgets/animation/stickman/animations/chilling.bin b/examples/widgets/animation/stickman/animations/chilling.bin
new file mode 100644
index 0000000000..a81fc7a18c
--- /dev/null
+++ b/examples/widgets/animation/stickman/animations/chilling.bin
Binary files differ
diff --git a/examples/widgets/animation/stickman/animations/dancing.bin b/examples/widgets/animation/stickman/animations/dancing.bin
new file mode 100644
index 0000000000..462f66f89b
--- /dev/null
+++ b/examples/widgets/animation/stickman/animations/dancing.bin
Binary files differ
diff --git a/examples/widgets/animation/stickman/animations/dead.bin b/examples/widgets/animation/stickman/animations/dead.bin
new file mode 100644
index 0000000000..9859b4b4cd
--- /dev/null
+++ b/examples/widgets/animation/stickman/animations/dead.bin
Binary files differ
diff --git a/examples/widgets/animation/stickman/animations/jumping.bin b/examples/widgets/animation/stickman/animations/jumping.bin
new file mode 100644
index 0000000000..12661a15f8
--- /dev/null
+++ b/examples/widgets/animation/stickman/animations/jumping.bin
Binary files differ
diff --git a/examples/widgets/animation/stickman/graphicsview.cpp b/examples/widgets/animation/stickman/graphicsview.cpp
new file mode 100644
index 0000000000..134fb8acf1
--- /dev/null
+++ b/examples/widgets/animation/stickman/graphicsview.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "graphicsview.h"
+#include "stickman.h"
+
+#include <QtGui/QKeyEvent>
+#include <QtWidgets/QGraphicsScene>
+#include <QtWidgets/QGraphicsView>
+
+GraphicsView::GraphicsView(QWidget *parent) : QGraphicsView(parent), m_editor(0) {}
+
+void GraphicsView::keyPressEvent(QKeyEvent *e)
+{
+ if (e->key() == Qt::Key_Escape)
+ close();
+ emit keyPressed(Qt::Key(e->key()));
+}
+
+void GraphicsView::resizeEvent(QResizeEvent *)
+{
+ fitInView(scene()->sceneRect());
+}
diff --git a/examples/widgets/animation/stickman/graphicsview.h b/examples/widgets/animation/stickman/graphicsview.h
new file mode 100644
index 0000000000..38bf6e1eb6
--- /dev/null
+++ b/examples/widgets/animation/stickman/graphicsview.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GRAPHICSVIEW_H
+#define GRAPHICSVIEW
+
+#include <QtWidgets/QGraphicsView>
+
+class MainWindow;
+class GraphicsView: public QGraphicsView
+{
+ Q_OBJECT
+public:
+ GraphicsView(QWidget *parent = 0);
+
+protected:
+ virtual void resizeEvent(QResizeEvent *event);
+ void keyPressEvent(QKeyEvent *);
+
+signals:
+ void keyPressed(int key);
+
+private:
+ MainWindow *m_editor;
+};
+
+#endif
diff --git a/examples/widgets/animation/stickman/lifecycle.cpp b/examples/widgets/animation/stickman/lifecycle.cpp
new file mode 100644
index 0000000000..53249ccd6f
--- /dev/null
+++ b/examples/widgets/animation/stickman/lifecycle.cpp
@@ -0,0 +1,217 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "lifecycle.h"
+#include "stickman.h"
+#include "node.h"
+#include "animation.h"
+#include "graphicsview.h"
+
+#include <QtCore>
+#include <QtWidgets>
+
+class KeyPressTransition: public QSignalTransition
+{
+public:
+ KeyPressTransition(GraphicsView *receiver, Qt::Key key)
+ : QSignalTransition(receiver, SIGNAL(keyPressed(int))), m_key(key)
+ {
+ }
+ KeyPressTransition(GraphicsView *receiver, Qt::Key key, QAbstractState *target)
+ : QSignalTransition(receiver, SIGNAL(keyPressed(int))), m_key(key)
+ {
+ setTargetState(target);
+ }
+
+ virtual bool eventTest(QEvent *e)
+ {
+ if (QSignalTransition::eventTest(e)) {
+ QVariant key = static_cast<QStateMachine::SignalEvent*>(e)->arguments().at(0);
+ return (key.toInt() == int(m_key));
+ }
+
+ return false;
+ }
+private:
+ Qt::Key m_key;
+};
+
+//! [4]
+class LightningStrikesTransition: public QEventTransition
+{
+public:
+ LightningStrikesTransition(QAbstractState *target)
+ : QEventTransition(this, QEvent::Timer)
+ {
+ setTargetState(target);
+ qsrand((uint)QDateTime::currentDateTime().toTime_t());
+ startTimer(1000);
+ }
+
+ virtual bool eventTest(QEvent *e)
+ {
+ return QEventTransition::eventTest(e) && ((qrand() % 50) == 0);
+ }
+};
+//! [4]
+
+LifeCycle::LifeCycle(StickMan *stickMan, GraphicsView *keyReceiver)
+ : m_stickMan(stickMan), m_keyReceiver(keyReceiver)
+{
+ // Create animation group to be used for all transitions
+ m_animationGroup = new QParallelAnimationGroup();
+ const int stickManNodeCount = m_stickMan->nodeCount();
+ for (int i=0; i<stickManNodeCount; ++i) {
+ QPropertyAnimation *pa = new QPropertyAnimation(m_stickMan->node(i), "pos");
+ m_animationGroup->addAnimation(pa);
+ }
+
+ // Set up initial state graph
+//! [3]
+ m_machine = new QStateMachine();
+ m_machine->addDefaultAnimation(m_animationGroup);
+//! [3]
+
+ m_alive = new QState(m_machine);
+ m_alive->setObjectName("alive");
+
+ // Make it blink when lightning strikes before entering dead animation
+ QState *lightningBlink = new QState(m_machine);
+ lightningBlink->assignProperty(m_stickMan->scene(), "backgroundBrush", Qt::white);
+ lightningBlink->assignProperty(m_stickMan, "penColor", Qt::black);
+ 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);
+ m_dead->assignProperty(m_stickMan->scene(), "backgroundBrush", Qt::black);
+ m_dead->assignProperty(m_stickMan, "penColor", Qt::white);
+ m_dead->assignProperty(m_stickMan, "fillColor", Qt::black);
+ m_dead->setObjectName("dead");
+
+ // Idle state (sets no properties)
+ m_idle = new QState(m_alive);
+ m_idle->setObjectName("idle");
+
+ m_alive->setInitialState(m_idle);
+
+ // Lightning strikes at random
+ m_alive->addTransition(new LightningStrikesTransition(lightningBlink));
+//! [0]
+ lightningBlink->addTransition(timer, SIGNAL(timeout()), m_dead);
+//! [0]
+
+ m_machine->setInitialState(m_alive);
+}
+
+void LifeCycle::setDeathAnimation(const QString &fileName)
+{
+ QState *deathAnimation = makeState(m_dead, fileName);
+ m_dead->setInitialState(deathAnimation);
+}
+
+void LifeCycle::start()
+{
+ m_machine->start();
+}
+
+void LifeCycle::addActivity(const QString &fileName, Qt::Key key, QObject *sender, const char *signal)
+{
+ QState *state = makeState(m_alive, fileName);
+ m_alive->addTransition(new KeyPressTransition(m_keyReceiver, key, state));
+
+ if((sender != NULL) || (signal != NULL)) {
+ m_alive->addTransition(sender, signal, state);
+ }
+}
+
+QState *LifeCycle::makeState(QState *parentState, const QString &animationFileName)
+{
+ QState *topLevel = new QState(parentState);
+
+ Animation animation;
+ {
+ QFile file(animationFileName);
+ if (file.open(QIODevice::ReadOnly))
+ animation.load(&file);
+ }
+
+ const int frameCount = animation.totalFrames();
+ QState *previousState = 0;
+ for (int i=0; i<frameCount; ++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), "pos", animation.nodePos(j));
+//! [1]
+
+ frameState->setObjectName(QString::fromLatin1("frame %0").arg(i));
+ if (previousState == 0)
+ topLevel->setInitialState(frameState);
+ else
+//! [2]
+ previousState->addTransition(previousState, SIGNAL(propertiesAssigned()), frameState);
+//! [2]
+
+ previousState = frameState;
+ }
+
+ // Loop
+ previousState->addTransition(previousState, SIGNAL(propertiesAssigned()), topLevel->initialState());
+
+ return topLevel;
+
+}
+
+LifeCycle::~LifeCycle()
+{
+ delete m_machine;
+ delete m_animationGroup;
+}
diff --git a/examples/widgets/animation/stickman/lifecycle.h b/examples/widgets/animation/stickman/lifecycle.h
new file mode 100644
index 0000000000..8e8bb50659
--- /dev/null
+++ b/examples/widgets/animation/stickman/lifecycle.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LIFECYCLE_H
+#define LIFECYCLE_H
+
+#include <Qt>
+
+class StickMan;
+QT_BEGIN_NAMESPACE
+class QStateMachine;
+class QAnimationGroup;
+class QState;
+class QAbstractState;
+class QAbstractTransition;
+class QObject;
+QT_END_NAMESPACE
+class GraphicsView;
+class LifeCycle
+{
+public:
+ LifeCycle(StickMan *stickMan, GraphicsView *keyEventReceiver);
+ ~LifeCycle();
+
+ void setDeathAnimation(const QString &fileName);
+ void addActivity(const QString &fileName, Qt::Key key, QObject *sender = NULL, const char *signal = NULL);
+
+ void start();
+
+private:
+ QState *makeState(QState *parentState, const QString &animationFileName);
+
+ StickMan *m_stickMan;
+ QStateMachine *m_machine;
+ QAnimationGroup *m_animationGroup;
+ GraphicsView *m_keyReceiver;
+
+ QState *m_alive;
+ QState *m_dead;
+ QState *m_idle;
+};
+
+#endif
diff --git a/examples/widgets/animation/stickman/main.cpp b/examples/widgets/animation/stickman/main.cpp
new file mode 100644
index 0000000000..3e49da8de3
--- /dev/null
+++ b/examples/widgets/animation/stickman/main.cpp
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "animation.h"
+#include "node.h"
+#include "lifecycle.h"
+#include "stickman.h"
+#include "graphicsview.h"
+#include "rectbutton.h"
+
+#include <QtCore>
+#include <QtWidgets>
+
+int main(int argc, char **argv)
+{
+ Q_INIT_RESOURCE(stickman);
+ QApplication app(argc, argv);
+
+ StickMan *stickMan = new StickMan;
+ stickMan->setDrawSticks(false);
+
+ QGraphicsTextItem *textItem = new QGraphicsTextItem();
+ textItem->setHtml("<font color=\"white\"><b>Stickman</b>"
+ "<p>"
+ "Tell the stickman what to do!"
+ "</p>"
+ "<p><i>"
+ "<li>Press <font color=\"purple\">J</font> to make the stickman jump.</li>"
+ "<li>Press <font color=\"purple\">D</font> to make the stickman dance.</li>"
+ "<li>Press <font color=\"purple\">C</font> to make him chill out.</li>"
+ "<li>When you are done, press <font color=\"purple\">Escape</font>.</li>"
+ "</i></p>"
+ "<p>If he is unlucky, the stickman will get struck by lightning, and never jump, dance or chill out again."
+ "</p></font>");
+ qreal w = textItem->boundingRect().width();
+ QRectF stickManBoundingRect = stickMan->mapToScene(stickMan->boundingRect()).boundingRect();
+ textItem->setPos(-w / 2.0, stickManBoundingRect.bottom() + 25.0);
+
+ QGraphicsScene scene;
+ scene.addItem(stickMan);
+
+ scene.addItem(textItem);
+ scene.setBackgroundBrush(Qt::black);
+
+ GraphicsView view;
+ view.setRenderHints(QPainter::Antialiasing);
+ view.setTransformationAnchor(QGraphicsView::NoAnchor);
+ view.setScene(&scene);
+
+ QRectF sceneRect = scene.sceneRect();
+ // making enough room in the scene for stickman to jump and die
+ view.resize(sceneRect.width() + 100, sceneRect.height() + 100);
+ view.setSceneRect(sceneRect);
+
+ view.show();
+ view.setFocus();
+
+ LifeCycle cycle(stickMan, &view);
+ cycle.setDeathAnimation(":/animations/dead.bin");
+
+ cycle.addActivity(":/animations/jumping.bin", Qt::Key_J);
+ cycle.addActivity(":/animations/dancing.bin", Qt::Key_D);
+ cycle.addActivity(":/animations/chilling.bin", Qt::Key_C);
+
+ cycle.start();
+
+
+ return app.exec();
+}
diff --git a/examples/widgets/animation/stickman/node.cpp b/examples/widgets/animation/stickman/node.cpp
new file mode 100644
index 0000000000..2de34b379c
--- /dev/null
+++ b/examples/widgets/animation/stickman/node.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "node.h"
+#include "stickman.h"
+
+#include <QRectF>
+#include <QPainter>
+#include <QGraphicsSceneMouseEvent>
+
+Node::Node(const QPointF &pos, QGraphicsItem *parent)
+ : QGraphicsObject(parent), m_dragging(false)
+{
+ setPos(pos);
+ setFlag(QGraphicsItem::ItemSendsGeometryChanges);
+}
+
+Node::~Node()
+{
+}
+
+QRectF Node::boundingRect() const
+{
+ return QRectF(-6.0, -6.0, 12.0, 12.0);
+}
+
+void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+{
+ painter->setPen(Qt::white);
+ painter->drawEllipse(QPointF(0.0, 0.0), 5.0, 5.0);
+}
+
+QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value)
+{
+ if (change == QGraphicsItem::ItemPositionChange)
+ emit positionChanged();
+
+ return QGraphicsObject::itemChange(change, value);
+}
+
+void Node::mousePressEvent(QGraphicsSceneMouseEvent *)
+{
+ m_dragging = true;
+}
+
+void Node::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (m_dragging)
+ setPos(mapToParent(event->pos()));
+}
+
+void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *)
+{
+ m_dragging = false;
+}
diff --git a/examples/widgets/animation/stickman/node.h b/examples/widgets/animation/stickman/node.h
new file mode 100644
index 0000000000..ae6e2a3ed0
--- /dev/null
+++ b/examples/widgets/animation/stickman/node.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef NODE_H
+#define NODE_H
+
+#include <QGraphicsItem>
+
+class Node: public QGraphicsObject
+{
+ Q_OBJECT
+public:
+ Node(const QPointF &pos, QGraphicsItem *parent = 0);
+ ~Node();
+
+ QRectF boundingRect() const;
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+signals:
+ void positionChanged();
+
+protected:
+ QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+
+ void mousePressEvent(QGraphicsSceneMouseEvent *);
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *);
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
+
+private:
+ bool m_dragging;
+};
+
+#endif
diff --git a/examples/widgets/animation/stickman/rectbutton.cpp b/examples/widgets/animation/stickman/rectbutton.cpp
new file mode 100644
index 0000000000..8b17600ef5
--- /dev/null
+++ b/examples/widgets/animation/stickman/rectbutton.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "rectbutton.h"
+#include <QPainter>
+
+RectButton::RectButton(QString buttonText) : m_ButtonText(buttonText)
+{
+}
+
+
+RectButton::~RectButton()
+{
+}
+
+
+void RectButton::mousePressEvent (QGraphicsSceneMouseEvent *)
+{
+ emit clicked();
+}
+
+
+QRectF RectButton::boundingRect() const
+{
+ return QRectF(0.0, 0.0, 90.0, 40.0);
+}
+
+
+void RectButton::paint(QPainter *painter, const QStyleOptionGraphicsItem * /* option */, QWidget * /* widget */)
+{
+ painter->setBrush(Qt::gray);
+ painter->drawRoundedRect(boundingRect(), 5, 5);
+
+ painter->setPen(Qt::white);
+ painter->drawText(20, 25, m_ButtonText);
+}
diff --git a/examples/widgets/animation/stickman/rectbutton.h b/examples/widgets/animation/stickman/rectbutton.h
new file mode 100644
index 0000000000..ead8f21420
--- /dev/null
+++ b/examples/widgets/animation/stickman/rectbutton.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RECTBUTTON_H
+#define RECTBUTTON_H
+
+#include <QGraphicsObject>
+
+class RectButton : public QGraphicsObject
+{
+ Q_OBJECT
+public:
+ RectButton(QString buttonText);
+ ~RectButton();
+
+ virtual QRectF boundingRect() const;
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+protected:
+ QString m_ButtonText;
+
+ virtual void mousePressEvent (QGraphicsSceneMouseEvent *event);
+
+signals:
+ void clicked();
+};
+
+#endif // RECTBUTTON_H
diff --git a/examples/widgets/animation/stickman/stickman.cpp b/examples/widgets/animation/stickman/stickman.cpp
new file mode 100644
index 0000000000..667ed7d141
--- /dev/null
+++ b/examples/widgets/animation/stickman/stickman.cpp
@@ -0,0 +1,337 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "stickman.h"
+#include "node.h"
+
+#include <QPainter>
+#include <QTimer>
+
+#define _USE_MATH_DEFINES
+#include <math.h>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+static const qreal Coords[NodeCount * 2] = {
+ 0.0, -150.0, // head, #0
+
+ 0.0, -100.0, // body pentagon, top->bottom, left->right, #1 - 5
+ -50.0, -50.0,
+ 50.0, -50.0,
+ -25.0, 50.0,
+ 25.0, 50.0,
+
+ -100.0, 0.0, // right arm, #6 - 7
+ -125.0, 50.0,
+
+ 100.0, 0.0, // left arm, #8 - 9
+ 125.0, 50.0,
+
+ -35.0, 75.0, // lower body, #10 - 11
+ 35.0, 75.0,
+
+ -25.0, 200.0, // right leg, #12 - 13
+ -30.0, 300.0,
+
+ 25.0, 200.0, // left leg, #14 - 15
+ 30.0, 300.0
+
+};
+
+static const int Bones[BoneCount * 2] = {
+ 0, 1, // neck
+
+ 1, 2, // body
+ 1, 3,
+ 1, 4,
+ 1, 5,
+ 2, 3,
+ 2, 4,
+ 2, 5,
+ 3, 4,
+ 3, 5,
+ 4, 5,
+
+ 2, 6, // right arm
+ 6, 7,
+
+ 3, 8, // left arm
+ 8, 9,
+
+ 4, 10, // lower body
+ 4, 11,
+ 5, 10,
+ 5, 11,
+ 10, 11,
+
+ 10, 12, // right leg
+ 12, 13,
+
+ 11, 14, // left leg
+ 14, 15
+
+};
+
+StickMan::StickMan()
+{
+ m_sticks = true;
+ m_isDead = false;
+ m_pixmap = QPixmap("images/head.png");
+ m_penColor = Qt::white;
+ m_fillColor = Qt::black;
+
+ // Set up start position of limbs
+ for (int i=0; i<NodeCount; ++i) {
+ m_nodes[i] = new Node(QPointF(Coords[i * 2], Coords[i * 2 + 1]), this);
+ connect(m_nodes[i], SIGNAL(positionChanged()), this, SLOT(childPositionChanged()));
+ }
+
+ for (int i=0; i<BoneCount; ++i) {
+ int n1 = Bones[i * 2];
+ int n2 = Bones[i * 2 + 1];
+
+ Node *node1 = m_nodes[n1];
+ Node *node2 = m_nodes[n2];
+
+ QPointF dist = node1->pos() - node2->pos();
+ m_perfectBoneLengths[i] = sqrt(pow(dist.x(),2) + pow(dist.y(),2));
+ }
+
+ startTimer(10);
+}
+
+StickMan::~StickMan()
+{
+}
+
+void StickMan::childPositionChanged()
+{
+ prepareGeometryChange();
+}
+
+void StickMan::setDrawSticks(bool on)
+{
+ m_sticks = on;
+ for (int i=0;i<nodeCount();++i) {
+ Node *node = m_nodes[i];
+ node->setVisible(on);
+ }
+}
+
+QRectF StickMan::boundingRect() const
+{
+ // account for head radius=50.0 plus pen which is 5.0
+ return childrenBoundingRect().adjusted(-55.0, -55.0, 55.0, 55.0);
+}
+
+int StickMan::nodeCount() const
+{
+ return NodeCount;
+}
+
+Node *StickMan::node(int idx) const
+{
+ if (idx >= 0 && idx < NodeCount)
+ return m_nodes[idx];
+ else
+ return 0;
+}
+
+void StickMan::timerEvent(QTimerEvent *)
+{
+ update();
+}
+
+void StickMan::stabilize()
+{
+ static const qreal threshold = 0.001;
+
+ for (int i=0; i<BoneCount; ++i) {
+ int n1 = Bones[i * 2];
+ int n2 = Bones[i * 2 + 1];
+
+ Node *node1 = m_nodes[n1];
+ Node *node2 = m_nodes[n2];
+
+ QPointF pos1 = node1->pos();
+ QPointF pos2 = node2->pos();
+
+ QPointF dist = pos1 - pos2;
+ qreal length = sqrt(pow(dist.x(),2) + pow(dist.y(),2));
+ qreal diff = (length - m_perfectBoneLengths[i]) / length;
+
+ QPointF p = dist * (0.5 * diff);
+ if (p.x() > threshold && p.y() > threshold) {
+ pos1 -= p;
+ pos2 += p;
+
+ node1->setPos(pos1);
+ node2->setPos(pos2);
+ }
+ }
+}
+
+QPointF StickMan::posFor(int idx) const
+{
+ return m_nodes[idx]->pos();
+}
+
+//#include <QTime>
+void StickMan::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+{
+ /* static int frames = 0;
+ static QTime time;
+ if (frames++ % 100 == 0) {
+ frames = 1;
+ time.restart();
+ }
+
+ if (time.elapsed() > 0) {
+ painter->setPen(Qt::white);
+ painter->drawText(0, 0, QString::number(frames / (time.elapsed() / 1000.0)));
+ }*/
+
+ stabilize();
+ if (m_sticks) {
+ painter->setPen(Qt::white);
+ for (int i=0; i<BoneCount; ++i) {
+ int n1 = Bones[i * 2];
+ int n2 = Bones[i * 2 + 1];
+
+ Node *node1 = m_nodes[n1];
+ Node *node2 = m_nodes[n2];
+
+ painter->drawLine(node1->pos(), node2->pos());
+ }
+ } else {
+ // first bone is neck and will be used for head
+
+ QPainterPath path;
+ path.moveTo(posFor(0));
+ path.lineTo(posFor(1));
+
+ // right arm
+ path.lineTo(posFor(2));
+ path.lineTo(posFor(6));
+ path.lineTo(posFor(7));
+
+ // left arm
+ path.moveTo(posFor(3));
+ path.lineTo(posFor(8));
+ path.lineTo(posFor(9));
+
+ // body
+ path.moveTo(posFor(2));
+ path.lineTo(posFor(4));
+ path.lineTo(posFor(10));
+ path.lineTo(posFor(11));
+ path.lineTo(posFor(5));
+ path.lineTo(posFor(3));
+ path.lineTo(posFor(1));
+
+ // right leg
+ path.moveTo(posFor(10));
+ path.lineTo(posFor(12));
+ path.lineTo(posFor(13));
+
+ // left leg
+ path.moveTo(posFor(11));
+ path.lineTo(posFor(14));
+ path.lineTo(posFor(15));
+
+ painter->setPen(QPen(m_penColor, 5.0, Qt::SolidLine, Qt::RoundCap));
+ painter->drawPath(path);
+
+ {
+ int n1 = Bones[0];
+ int n2 = Bones[1];
+ Node *node1 = m_nodes[n1];
+ Node *node2 = m_nodes[n2];
+
+ QPointF dist = node2->pos() - node1->pos();
+
+ qreal sinAngle = dist.x() / sqrt(pow(dist.x(), 2) + pow(dist.y(), 2));
+ qreal angle = asin(sinAngle) * 180.0 / M_PI;
+
+ QPointF headPos = node1->pos();
+ painter->translate(headPos);
+ painter->rotate(-angle);
+
+ painter->setBrush(m_fillColor);
+ painter->drawEllipse(QPointF(0,0), 50.0, 50.0);
+
+ painter->setBrush(m_penColor);
+ painter->setPen(QPen(m_penColor, 2.5, Qt::SolidLine, Qt::RoundCap));
+
+ // eyes
+ if (m_isDead) {
+ painter->drawLine(-30.0, -30.0, -20.0, -20.0);
+ painter->drawLine(-20.0, -30.0, -30.0, -20.0);
+
+ painter->drawLine(20.0, -30.0, 30.0, -20.0);
+ painter->drawLine(30.0, -30.0, 20.0, -20.0);
+ } else {
+ painter->drawChord(QRectF(-30.0, -30.0, 25.0, 70.0), 30.0*16, 120.0*16);
+ painter->drawChord(QRectF(5.0, -30.0, 25.0, 70.0), 30.0*16, 120.0*16);
+ }
+
+ // mouth
+ if (m_isDead) {
+ painter->drawLine(-28.0, 2.0, 29.0, 2.0);
+ } else {
+ painter->setBrush(QColor(128, 0, 64 ));
+ painter->drawChord(QRectF(-28.0, 2.0-55.0/2.0, 57.0, 55.0), 0.0, -180.0*16);
+ }
+
+ // pupils
+ if (!m_isDead) {
+ painter->setPen(QPen(m_fillColor, 1.0, Qt::SolidLine, Qt::RoundCap));
+ painter->setBrush(m_fillColor);
+ painter->drawEllipse(QPointF(-12.0, -25.0), 5.0, 5.0);
+ painter->drawEllipse(QPointF(22.0, -25.0), 5.0, 5.0);
+ }
+ }
+ }
+}
+
+
+
diff --git a/examples/widgets/animation/stickman/stickman.desktop b/examples/widgets/animation/stickman/stickman.desktop
new file mode 100644
index 0000000000..1722d4db3e
--- /dev/null
+++ b/examples/widgets/animation/stickman/stickman.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=Stickman
+Exec=/opt/usr/bin/stickman
+Icon=stickman
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/examples/widgets/animation/stickman/stickman.h b/examples/widgets/animation/stickman/stickman.h
new file mode 100644
index 0000000000..f50ed1a6c2
--- /dev/null
+++ b/examples/widgets/animation/stickman/stickman.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef STICKMAN_H
+#define STICKMAN_H
+
+#include <QGraphicsObject>
+
+static const int NodeCount = 16;
+static const int BoneCount = 24;
+
+class Node;
+QT_BEGIN_NAMESPACE
+QT_END_NAMESPACE
+class StickMan: public QGraphicsObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QColor penColor WRITE setPenColor READ penColor)
+ Q_PROPERTY(QColor fillColor WRITE setFillColor READ fillColor)
+ Q_PROPERTY(bool isDead WRITE setIsDead READ isDead)
+public:
+ StickMan();
+ ~StickMan();
+
+ virtual QRectF boundingRect() const;
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+ int nodeCount() const;
+ Node *node(int idx) const;
+
+ void setDrawSticks(bool on);
+ bool drawSticks() const { return m_sticks; }
+
+ QColor penColor() const { return m_penColor; }
+ void setPenColor(const QColor &color) { m_penColor = color; }
+
+ QColor fillColor() const { return m_fillColor; }
+ void setFillColor(const QColor &color) { m_fillColor = color; }
+
+ bool isDead() const { return m_isDead; }
+ void setIsDead(bool isDead) { m_isDead = isDead; }
+
+public slots:
+ void stabilize();
+ void childPositionChanged();
+
+protected:
+ void timerEvent(QTimerEvent *e);
+
+private:
+
+ QPointF posFor(int idx) const;
+
+ Node *m_nodes[NodeCount];
+ qreal m_perfectBoneLengths[BoneCount];
+
+ uint m_sticks : 1;
+ uint m_isDead : 1;
+ uint m_reserved : 30;
+
+ QPixmap m_pixmap;
+ QColor m_penColor;
+ QColor m_fillColor;
+};
+
+#endif // STICKMAN_H
diff --git a/examples/widgets/animation/stickman/stickman.pro b/examples/widgets/animation/stickman/stickman.pro
new file mode 100644
index 0000000000..43aaec113d
--- /dev/null
+++ b/examples/widgets/animation/stickman/stickman.pro
@@ -0,0 +1,23 @@
+HEADERS += stickman.h \
+ animation.h \
+ node.h \
+ lifecycle.h \
+ graphicsview.h \
+ rectbutton.h
+SOURCES += main.cpp \
+ stickman.cpp \
+ animation.cpp \
+ node.cpp \
+ lifecycle.cpp \
+ graphicsview.cpp \
+ rectbutton.cpp
+
+RESOURCES += stickman.qrc
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/animation/stickman
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS stickman.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/animation/stickman
+INSTALLS += target sources
+
+QT += widgets
diff --git a/examples/widgets/animation/stickman/stickman.qrc b/examples/widgets/animation/stickman/stickman.qrc
new file mode 100644
index 0000000000..4cf3ba3828
--- /dev/null
+++ b/examples/widgets/animation/stickman/stickman.qrc
@@ -0,0 +1,8 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>animations/chilling.bin</file>
+ <file>animations/dancing.bin</file>
+ <file>animations/dead.bin</file>
+ <file>animations/jumping.bin</file>
+</qresource>
+</RCC>
diff --git a/examples/widgets/animation/sub-attaq/animationmanager.cpp b/examples/widgets/animation/sub-attaq/animationmanager.cpp
new file mode 100644
index 0000000000..7dcb9dfb50
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/animationmanager.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+//Own
+#include "animationmanager.h"
+
+//Qt
+#include <QtCore/QAbstractAnimation>
+#include <QtCore/QDebug>
+
+// the universe's only animation manager
+AnimationManager *AnimationManager::instance = 0;
+
+AnimationManager::AnimationManager()
+{
+}
+
+AnimationManager *AnimationManager::self()
+{
+ if (!instance)
+ instance = new AnimationManager;
+ return instance;
+}
+
+void AnimationManager::registerAnimation(QAbstractAnimation *anim)
+{
+ QObject::connect(anim, SIGNAL(destroyed(QObject*)), this, SLOT(unregisterAnimation_helper(QObject*)));
+ animations.append(anim);
+}
+
+void AnimationManager::unregisterAnimation_helper(QObject *obj)
+{
+ unregisterAnimation(static_cast<QAbstractAnimation*>(obj));
+}
+
+void AnimationManager::unregisterAnimation(QAbstractAnimation *anim)
+{
+ QObject::disconnect(anim, SIGNAL(destroyed(QObject*)), this, SLOT(unregisterAnimation_helper(QObject*)));
+ animations.removeAll(anim);
+}
+
+void AnimationManager::unregisterAllAnimations()
+{
+ animations.clear();
+}
+
+void AnimationManager::pauseAll()
+{
+ foreach (QAbstractAnimation* animation, animations) {
+ if (animation->state() == QAbstractAnimation::Running)
+ animation->pause();
+ }
+}
+void AnimationManager::resumeAll()
+{
+ foreach (QAbstractAnimation* animation, animations) {
+ if (animation->state() == QAbstractAnimation::Paused)
+ animation->resume();
+ }
+}
diff --git a/examples/widgets/animation/sub-attaq/animationmanager.h b/examples/widgets/animation/sub-attaq/animationmanager.h
new file mode 100644
index 0000000000..6587e39b14
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/animationmanager.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef ANIMATIONMANAGER_H
+#define ANIMATIONMANAGER_H
+
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+class QAbstractAnimation;
+QT_END_NAMESPACE
+
+class AnimationManager : public QObject
+{
+Q_OBJECT
+public:
+ AnimationManager();
+ void registerAnimation(QAbstractAnimation *anim);
+ void unregisterAnimation(QAbstractAnimation *anim);
+ void unregisterAllAnimations();
+ static AnimationManager *self();
+
+public slots:
+ void pauseAll();
+ void resumeAll();
+
+private slots:
+ void unregisterAnimation_helper(QObject *obj);
+
+private:
+ static AnimationManager *instance;
+ QList<QAbstractAnimation *> animations;
+};
+
+#endif // ANIMATIONMANAGER_H
diff --git a/examples/widgets/animation/sub-attaq/boat.cpp b/examples/widgets/animation/sub-attaq/boat.cpp
new file mode 100644
index 0000000000..88332dbfe7
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/boat.cpp
@@ -0,0 +1,272 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+//Own
+#include "boat.h"
+#include "boat_p.h"
+#include "bomb.h"
+#include "pixmapitem.h"
+#include "graphicsscene.h"
+#include "animationmanager.h"
+#include "qanimationstate.h"
+
+//Qt
+#include <QtCore/QPropertyAnimation>
+#include <QtCore/QStateMachine>
+#include <QtCore/QHistoryState>
+#include <QtCore/QFinalState>
+#include <QtCore/QState>
+#include <QtCore/QSequentialAnimationGroup>
+
+static QAbstractAnimation *setupDestroyAnimation(Boat *boat)
+{
+ QSequentialAnimationGroup *group = new QSequentialAnimationGroup(boat);
+ for (int i = 1; i <= 4; i++) {
+ PixmapItem *step = new PixmapItem(QString("explosion/boat/step%1").arg(i),GraphicsScene::Big, boat);
+ step->setZValue(6);
+ step->setOpacity(0);
+
+ //fade-in
+ QPropertyAnimation *anim = new QPropertyAnimation(step, "opacity");
+ anim->setEndValue(1);
+ anim->setDuration(100);
+ group->insertAnimation(i-1, anim);
+
+ //and then fade-out
+ QPropertyAnimation *anim2 = new QPropertyAnimation(step, "opacity");
+ anim2->setEndValue(0);
+ anim2->setDuration(100);
+ group->addAnimation(anim2);
+ }
+
+ AnimationManager::self()->registerAnimation(group);
+ return group;
+}
+
+
+
+Boat::Boat() : PixmapItem(QString("boat"), GraphicsScene::Big),
+ speed(0), bombsAlreadyLaunched(0), direction(Boat::None), movementAnimation(0)
+{
+ setZValue(4);
+ setFlags(QGraphicsItem::ItemIsFocusable);
+
+ //The movement animation used to animate the boat
+ movementAnimation = new QPropertyAnimation(this, "pos");
+
+ //The destroy animation used to explode the boat
+ destroyAnimation = setupDestroyAnimation(this);
+
+ //We setup the state machine of the boat
+ machine = new QStateMachine(this);
+ QState *moving = new QState(machine);
+ StopState *stopState = new StopState(this, moving);
+ machine->setInitialState(moving);
+ moving->setInitialState(stopState);
+ MoveStateRight *moveStateRight = new MoveStateRight(this, moving);
+ MoveStateLeft *moveStateLeft = new MoveStateLeft(this, moving);
+ LaunchStateRight *launchStateRight = new LaunchStateRight(this, machine);
+ LaunchStateLeft *launchStateLeft = new LaunchStateLeft(this, machine);
+
+ //then setup the transitions for the rightMove state
+ KeyStopTransition *leftStopRight = new KeyStopTransition(this, QEvent::KeyPress, Qt::Key_Left);
+ leftStopRight->setTargetState(stopState);
+ KeyMoveTransition *leftMoveRight = new KeyMoveTransition(this, QEvent::KeyPress, Qt::Key_Left);
+ leftMoveRight->setTargetState(moveStateRight);
+ KeyMoveTransition *rightMoveRight = new KeyMoveTransition(this, QEvent::KeyPress, Qt::Key_Right);
+ rightMoveRight->setTargetState(moveStateRight);
+ KeyMoveTransition *rightMoveStop = new KeyMoveTransition(this, QEvent::KeyPress, Qt::Key_Right);
+ rightMoveStop->setTargetState(moveStateRight);
+
+ //then setup the transitions for the leftMove state
+ KeyStopTransition *rightStopLeft = new KeyStopTransition(this, QEvent::KeyPress, Qt::Key_Right);
+ rightStopLeft->setTargetState(stopState);
+ KeyMoveTransition *rightMoveLeft = new KeyMoveTransition(this, QEvent::KeyPress, Qt::Key_Right);
+ rightMoveLeft->setTargetState(moveStateLeft);
+ KeyMoveTransition *leftMoveLeft = new KeyMoveTransition(this, QEvent::KeyPress,Qt::Key_Left);
+ leftMoveLeft->setTargetState(moveStateLeft);
+ KeyMoveTransition *leftMoveStop = new KeyMoveTransition(this, QEvent::KeyPress,Qt::Key_Left);
+ leftMoveStop->setTargetState(moveStateLeft);
+
+ //We set up the right move state
+ moveStateRight->addTransition(leftStopRight);
+ moveStateRight->addTransition(leftMoveRight);
+ moveStateRight->addTransition(rightMoveRight);
+ stopState->addTransition(rightMoveStop);
+
+ //We set up the left move state
+ moveStateLeft->addTransition(rightStopLeft);
+ moveStateLeft->addTransition(leftMoveLeft);
+ moveStateLeft->addTransition(rightMoveLeft);
+ stopState->addTransition(leftMoveStop);
+
+ //The animation is finished, it means we reached the border of the screen, the boat is stopped so we move to the stop state
+ moveStateLeft->addTransition(movementAnimation, SIGNAL(finished()), stopState);
+ moveStateRight->addTransition(movementAnimation, SIGNAL(finished()), stopState);
+
+ //We set up the keys for dropping bombs
+ KeyLaunchTransition *upFireLeft = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Up);
+ upFireLeft->setTargetState(launchStateRight);
+ KeyLaunchTransition *upFireRight = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Up);
+ upFireRight->setTargetState(launchStateRight);
+ KeyLaunchTransition *upFireStop = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Up);
+ upFireStop->setTargetState(launchStateRight);
+ KeyLaunchTransition *downFireLeft = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Down);
+ downFireLeft->setTargetState(launchStateLeft);
+ KeyLaunchTransition *downFireRight = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Down);
+ downFireRight->setTargetState(launchStateLeft);
+ KeyLaunchTransition *downFireMove = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Down);
+ downFireMove->setTargetState(launchStateLeft);
+
+ //We set up transitions for fire up
+ moveStateRight->addTransition(upFireRight);
+ moveStateLeft->addTransition(upFireLeft);
+ stopState->addTransition(upFireStop);
+
+ //We set up transitions for fire down
+ moveStateRight->addTransition(downFireRight);
+ moveStateLeft->addTransition(downFireLeft);
+ stopState->addTransition(downFireMove);
+
+ //Finally the launch state should come back to its original state
+ QHistoryState *historyState = new QHistoryState(moving);
+ launchStateLeft->addTransition(historyState);
+ launchStateRight->addTransition(historyState);
+
+ QFinalState *final = new QFinalState(machine);
+
+ //This state play the destroyed animation
+ QAnimationState *destroyedState = new QAnimationState(machine);
+ destroyedState->setAnimation(destroyAnimation);
+
+ //Play a nice animation when the boat is destroyed
+ moving->addTransition(this, SIGNAL(boatDestroyed()), destroyedState);
+
+ //Transition to final state when the destroyed animation is finished
+ destroyedState->addTransition(destroyedState, SIGNAL(animationFinished()), final);
+
+ //The machine has finished to be executed, then the boat is dead
+ connect(machine,SIGNAL(finished()), this, SIGNAL(boatExecutionFinished()));
+
+}
+
+void Boat::run()
+{
+ //We register animations
+ AnimationManager::self()->registerAnimation(movementAnimation);
+ AnimationManager::self()->registerAnimation(destroyAnimation);
+ machine->start();
+}
+
+void Boat::stop()
+{
+ movementAnimation->stop();
+ machine->stop();
+}
+
+void Boat::updateBoatMovement()
+{
+ if (speed == 0 || direction == Boat::None) {
+ movementAnimation->stop();
+ return;
+ }
+
+ movementAnimation->stop();
+
+ if (direction == Boat::Left) {
+ movementAnimation->setEndValue(QPointF(0,y()));
+ movementAnimation->setDuration(x()/speed*15);
+ }
+ else /*if (direction == Boat::Right)*/ {
+ movementAnimation->setEndValue(QPointF(scene()->width()-size().width(),y()));
+ movementAnimation->setDuration((scene()->width()-size().width()-x())/speed*15);
+ }
+ movementAnimation->start();
+}
+
+void Boat::destroy()
+{
+ movementAnimation->stop();
+ emit boatDestroyed();
+}
+
+int Boat::bombsLaunched() const
+{
+ return bombsAlreadyLaunched;
+}
+
+void Boat::setBombsLaunched(int number)
+{
+ if (number > MAX_BOMB) {
+ qWarning("Boat::setBombsLaunched : It impossible to launch that number of bombs");
+ return;
+ }
+ bombsAlreadyLaunched = number;
+}
+
+int Boat::currentSpeed() const
+{
+ return speed;
+}
+
+void Boat::setCurrentSpeed(int speed)
+{
+ if (speed > 3 || speed < 0) {
+ qWarning("Boat::setCurrentSpeed: The boat can't run on that speed");
+ return;
+ }
+ this->speed = speed;
+}
+
+enum Boat::Movement Boat::currentDirection() const
+{
+ return direction;
+}
+
+void Boat::setCurrentDirection(Movement direction)
+{
+ this->direction = direction;
+}
+
+int Boat::type() const
+{
+ return Type;
+}
diff --git a/examples/widgets/animation/sub-attaq/boat.h b/examples/widgets/animation/sub-attaq/boat.h
new file mode 100644
index 0000000000..0b2fe5c8eb
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/boat.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef __BOAT__H__
+#define __BOAT__H__
+
+#include "pixmapitem.h"
+
+class Bomb;
+QT_BEGIN_NAMESPACE
+class QVariantAnimation;
+class QAbstractAnimation;
+class QStateMachine;
+QT_END_NAMESPACE
+
+class Boat : public PixmapItem
+{
+Q_OBJECT
+public:
+ enum Movement {
+ None = 0,
+ Left,
+ Right
+ };
+ enum { Type = UserType + 2 };
+ Boat();
+ void destroy();
+ void run();
+ void stop();
+
+ int bombsLaunched() const;
+ void setBombsLaunched(int number);
+
+ int currentSpeed() const;
+ void setCurrentSpeed(int speed);
+
+ enum Movement currentDirection() const;
+ void setCurrentDirection(Movement direction);
+
+ void updateBoatMovement();
+
+ virtual int type() const;
+
+signals:
+ void boatDestroyed();
+ void boatExecutionFinished();
+
+private:
+ int speed;
+ int bombsAlreadyLaunched;
+ Movement direction;
+ QVariantAnimation *movementAnimation;
+ QAbstractAnimation *destroyAnimation;
+ QStateMachine *machine;
+};
+
+#endif //__BOAT__H__
diff --git a/examples/widgets/animation/sub-attaq/boat_p.h b/examples/widgets/animation/sub-attaq/boat_p.h
new file mode 100644
index 0000000000..38be985777
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/boat_p.h
@@ -0,0 +1,232 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef BOAT_P_H
+#define BOAT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+//Own
+#include "bomb.h"
+#include "graphicsscene.h"
+
+// Qt
+#include <QtWidgets/QKeyEventTransition>
+
+static const int MAX_BOMB = 5;
+
+
+//These transtion test if we have to stop the boat (i.e current speed is 1)
+class KeyStopTransition : public QKeyEventTransition
+{
+public:
+ KeyStopTransition(Boat *b, QEvent::Type t, int k)
+ : QKeyEventTransition(b, t, k), boat(b), key(k)
+ {
+ }
+protected:
+ virtual bool eventTest(QEvent *event)
+ {
+ if (!QKeyEventTransition::eventTest(event))
+ return false;
+ return (boat->currentSpeed() == 1);
+ }
+private:
+ Boat * boat;
+ int key;
+};
+
+//These transtion test if we have to move the boat (i.e current speed was 0 or another value)
+ class KeyMoveTransition : public QKeyEventTransition
+{
+public:
+ KeyMoveTransition(Boat *b, QEvent::Type t, int k)
+ : QKeyEventTransition(b, t, k), boat(b), key(k)
+ {
+ }
+protected:
+ virtual bool eventTest(QEvent *event)
+ {
+ if (!QKeyEventTransition::eventTest(event))
+ return false;
+ return (boat->currentSpeed() >= 0);
+ }
+ void onTransition(QEvent *)
+ {
+ //We decrease the speed if needed
+ if (key == Qt::Key_Left && boat->currentDirection() == Boat::Right)
+ boat->setCurrentSpeed(boat->currentSpeed() - 1);
+ else if (key == Qt::Key_Right && boat->currentDirection() == Boat::Left)
+ boat->setCurrentSpeed(boat->currentSpeed() - 1);
+ else if (boat->currentSpeed() < 3)
+ boat->setCurrentSpeed(boat->currentSpeed() + 1);
+ boat->updateBoatMovement();
+ }
+private:
+ Boat * boat;
+ int key;
+};
+
+//This transition trigger the bombs launch
+ class KeyLaunchTransition : public QKeyEventTransition
+{
+public:
+ KeyLaunchTransition(Boat *boat, QEvent::Type type, int key)
+ : QKeyEventTransition(boat, type, key), boat(boat), key(key)
+ {
+ }
+protected:
+ virtual bool eventTest(QEvent *event)
+ {
+ if (!QKeyEventTransition::eventTest(event))
+ return false;
+ //We have enough bomb?
+ return (boat->bombsLaunched() < MAX_BOMB);
+ }
+private:
+ Boat * boat;
+ int key;
+};
+
+//This state is describing when the boat is moving right
+class MoveStateRight : public QState
+{
+public:
+ MoveStateRight(Boat *boat,QState *parent = 0) : QState(parent), boat(boat)
+ {
+ }
+protected:
+ void onEntry(QEvent *)
+ {
+ boat->setCurrentDirection(Boat::Right);
+ boat->updateBoatMovement();
+ }
+private:
+ Boat * boat;
+};
+
+ //This state is describing when the boat is moving left
+class MoveStateLeft : public QState
+{
+public:
+ MoveStateLeft(Boat *boat,QState *parent = 0) : QState(parent), boat(boat)
+ {
+ }
+protected:
+ void onEntry(QEvent *)
+ {
+ boat->setCurrentDirection(Boat::Left);
+ boat->updateBoatMovement();
+ }
+private:
+ Boat * boat;
+};
+
+//This state is describing when the boat is in a stand by position
+class StopState : public QState
+{
+public:
+ StopState(Boat *boat,QState *parent = 0) : QState(parent), boat(boat)
+ {
+ }
+protected:
+ void onEntry(QEvent *)
+ {
+ boat->setCurrentSpeed(0);
+ boat->setCurrentDirection(Boat::None);
+ boat->updateBoatMovement();
+ }
+private:
+ Boat * boat;
+};
+
+//This state is describing the launch of the torpedo on the right
+class LaunchStateRight : public QState
+{
+public:
+ LaunchStateRight(Boat *boat,QState *parent = 0) : QState(parent), boat(boat)
+ {
+ }
+protected:
+ void onEntry(QEvent *)
+ {
+ Bomb *b = new Bomb();
+ b->setPos(boat->x()+boat->size().width(),boat->y());
+ GraphicsScene *scene = static_cast<GraphicsScene *>(boat->scene());
+ scene->addItem(b);
+ b->launch(Bomb::Right);
+ boat->setBombsLaunched(boat->bombsLaunched() + 1);
+ }
+private:
+ Boat * boat;
+};
+
+//This state is describing the launch of the torpedo on the left
+class LaunchStateLeft : public QState
+{
+public:
+ LaunchStateLeft(Boat *boat,QState *parent = 0) : QState(parent), boat(boat)
+ {
+ }
+protected:
+ void onEntry(QEvent *)
+ {
+ Bomb *b = new Bomb();
+ b->setPos(boat->x() - b->size().width(), boat->y());
+ GraphicsScene *scene = static_cast<GraphicsScene *>(boat->scene());
+ scene->addItem(b);
+ b->launch(Bomb::Left);
+ boat->setBombsLaunched(boat->bombsLaunched() + 1);
+ }
+private:
+ Boat * boat;
+};
+
+#endif // BOAT_P_H
diff --git a/examples/widgets/animation/sub-attaq/bomb.cpp b/examples/widgets/animation/sub-attaq/bomb.cpp
new file mode 100644
index 0000000000..e47e9423a9
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/bomb.cpp
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+//Own
+#include "bomb.h"
+#include "submarine.h"
+#include "pixmapitem.h"
+#include "animationmanager.h"
+#include "qanimationstate.h"
+
+//Qt
+#include <QtCore/QSequentialAnimationGroup>
+#include <QtCore/QPropertyAnimation>
+#include <QtCore/QStateMachine>
+#include <QtCore/QFinalState>
+
+Bomb::Bomb() : PixmapItem(QString("bomb"), GraphicsScene::Big)
+{
+ setZValue(2);
+}
+
+void Bomb::launch(Bomb::Direction direction)
+{
+ QSequentialAnimationGroup *launchAnimation = new QSequentialAnimationGroup;
+ AnimationManager::self()->registerAnimation(launchAnimation);
+ qreal delta = direction == Right ? 20 : - 20;
+ QPropertyAnimation *anim = new QPropertyAnimation(this, "pos");
+ anim->setEndValue(QPointF(x() + delta,y() - 20));
+ anim->setDuration(150);
+ launchAnimation->addAnimation(anim);
+ anim = new QPropertyAnimation(this, "pos");
+ anim->setEndValue(QPointF(x() + delta*2, y() ));
+ anim->setDuration(150);
+ launchAnimation->addAnimation(anim);
+ anim = new QPropertyAnimation(this, "pos");
+ anim->setEndValue(QPointF(x() + delta*2,scene()->height()));
+ anim->setDuration(y()/2*60);
+ launchAnimation->addAnimation(anim);
+ connect(anim,SIGNAL(valueChanged(QVariant)),this,SLOT(onAnimationLaunchValueChanged(QVariant)));
+ connect(this, SIGNAL(bombExploded()), launchAnimation, SLOT(stop()));
+ //We setup the state machine of the bomb
+ QStateMachine *machine = new QStateMachine(this);
+
+ //This state is when the launch animation is playing
+ QAnimationState *launched = new QAnimationState(machine);
+ launched->setAnimation(launchAnimation);
+
+ //End
+ QFinalState *final = new QFinalState(machine);
+
+ machine->setInitialState(launched);
+
+ //### Add a nice animation when the bomb is destroyed
+ launched->addTransition(this, SIGNAL(bombExploded()),final);
+
+ //If the animation is finished, then we move to the final state
+ launched->addTransition(launched, SIGNAL(animationFinished()), final);
+
+ //The machine has finished to be executed, then the boat is dead
+ connect(machine,SIGNAL(finished()),this, SIGNAL(bombExecutionFinished()));
+
+ machine->start();
+
+}
+
+void Bomb::onAnimationLaunchValueChanged(const QVariant &)
+{
+ foreach (QGraphicsItem * item , collidingItems(Qt::IntersectsItemBoundingRect)) {
+ if (item->type() == SubMarine::Type) {
+ SubMarine *s = static_cast<SubMarine *>(item);
+ destroy();
+ s->destroy();
+ }
+ }
+}
+
+void Bomb::destroy()
+{
+ emit bombExploded();
+}
diff --git a/examples/widgets/animation/sub-attaq/bomb.h b/examples/widgets/animation/sub-attaq/bomb.h
new file mode 100644
index 0000000000..74ed734caf
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/bomb.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef __BOMB__H__
+#define __BOMB__H__
+
+#include "pixmapitem.h"
+
+class Bomb : public PixmapItem
+{
+Q_OBJECT
+public:
+ enum Direction {
+ Left = 0,
+ Right
+ };
+ Bomb();
+ void launch(Direction direction);
+ void destroy();
+
+signals:
+ void bombExploded();
+ void bombExecutionFinished();
+
+private slots:
+ void onAnimationLaunchValueChanged(const QVariant &);
+};
+
+#endif //__BOMB__H__
diff --git a/examples/widgets/animation/sub-attaq/data.xml b/examples/widgets/animation/sub-attaq/data.xml
new file mode 100644
index 0000000000..0f30515ddf
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/data.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<subattaq>
+ <submarines>
+ <submarine type="0" points="10" name="Q1" />
+ <submarine type="1" points="20" name="Q2" />
+ </submarines>
+ <levels>
+ <level id="0" name="Seaman recruit">
+ <subinstance type="0" nb="1"/>
+ </level>
+ <level id="1" name="Seaman apprentice">
+ <subinstance type="0" nb="2"/>
+ </level>
+ <level id="2" name="Seaman">
+ <subinstance type="0" nb="4"/>
+ </level>
+ <level id="3" name="Petty Officer Third Class">
+ <subinstance type="0" nb="6"/>
+ </level>
+ <level id="4" name="Petty Officer Second Class">
+ <subinstance type="0" nb="6"/>
+ </level>
+ <level id="5" name="Petty Officer First Class">
+ <subinstance type="0" nb="8"/>
+ </level>
+ <level id="6" name="Lieutenant">
+ <subinstance type="0" nb="10"/>
+ </level>
+ <level id="7" name="Commander">
+ <subinstance type="0" nb="15"/>
+ </level>
+ <level id="8" name="Captain">
+ <subinstance type="0" nb="12"/>
+ </level>
+ <level id="9" name="Admiral">
+ <subinstance type="0" nb="12"/>
+ </level>
+ </levels>
+</subattaq>
diff --git a/examples/widgets/animation/sub-attaq/graphicsscene.cpp b/examples/widgets/animation/sub-attaq/graphicsscene.cpp
new file mode 100644
index 0000000000..a2b3e2f101
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/graphicsscene.cpp
@@ -0,0 +1,282 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+//Own
+#include "graphicsscene.h"
+#include "states.h"
+#include "boat.h"
+#include "submarine.h"
+#include "torpedo.h"
+#include "bomb.h"
+#include "pixmapitem.h"
+#include "animationmanager.h"
+#include "qanimationstate.h"
+#include "progressitem.h"
+#include "textinformationitem.h"
+
+//Qt
+#include <QtCore/QPropertyAnimation>
+#include <QtCore/QSequentialAnimationGroup>
+#include <QtCore/QParallelAnimationGroup>
+#include <QtCore/QStateMachine>
+#include <QtCore/QFinalState>
+#include <QtCore/QPauseAnimation>
+#include <QtWidgets/QAction>
+#include <QtCore/QDir>
+#include <QtWidgets/QApplication>
+#include <QtWidgets/QMessageBox>
+#include <QtWidgets/QGraphicsView>
+#include <QtWidgets/QGraphicsSceneMouseEvent>
+#include <QtCore/QXmlStreamReader>
+
+GraphicsScene::GraphicsScene(int x, int y, int width, int height, Mode mode)
+ : QGraphicsScene(x , y, width, height), mode(mode), boat(new Boat)
+{
+ PixmapItem *backgroundItem = new PixmapItem(QString("background"),mode);
+ backgroundItem->setZValue(1);
+ backgroundItem->setPos(0,0);
+ addItem(backgroundItem);
+
+ PixmapItem *surfaceItem = new PixmapItem(QString("surface"),mode);
+ surfaceItem->setZValue(3);
+ surfaceItem->setPos(0,sealLevel() - surfaceItem->boundingRect().height()/2);
+ addItem(surfaceItem);
+
+ //The item that display score and level
+ progressItem = new ProgressItem(backgroundItem);
+
+ textInformationItem = new TextInformationItem(backgroundItem);
+ textInformationItem->hide();
+ //We create the boat
+ addItem(boat);
+ boat->setPos(this->width()/2, sealLevel() - boat->size().height());
+ boat->hide();
+
+ //parse the xml that contain all data of the game
+ QXmlStreamReader reader;
+ QFile file(":data.xml");
+ file.open(QIODevice::ReadOnly);
+ reader.setDevice(&file);
+ LevelDescription currentLevel;
+ while (!reader.atEnd()) {
+ reader.readNext();
+ if (reader.tokenType() == QXmlStreamReader::StartElement) {
+ if (reader.name() == "submarine") {
+ SubmarineDescription desc;
+ desc.name = reader.attributes().value("name").toString();
+ desc.points = reader.attributes().value("points").toString().toInt();
+ desc.type = reader.attributes().value("type").toString().toInt();
+ submarinesData.append(desc);
+ } else if (reader.name() == "level") {
+ currentLevel.id = reader.attributes().value("id").toString().toInt();
+ currentLevel.name = reader.attributes().value("name").toString();
+ } else if (reader.name() == "subinstance") {
+ currentLevel.submarines.append(qMakePair(reader.attributes().value("type").toString().toInt(), reader.attributes().value("nb").toString().toInt()));
+ }
+ } else if (reader.tokenType() == QXmlStreamReader::EndElement) {
+ if (reader.name() == "level") {
+ levelsData.insert(currentLevel.id, currentLevel);
+ currentLevel.submarines.clear();
+ }
+ }
+ }
+}
+
+qreal GraphicsScene::sealLevel() const
+{
+ return (mode == Big) ? 220 : 160;
+}
+
+void GraphicsScene::setupScene(QAction *newAction, QAction *quitAction)
+{
+ static const int nLetters = 10;
+ static struct {
+ char const *pix;
+ qreal initX, initY;
+ qreal destX, destY;
+ } logoData[nLetters] = {
+ {"s", -1000, -1000, 300, 150 },
+ {"u", -800, -1000, 350, 150 },
+ {"b", -600, -1000, 400, 120 },
+ {"dash", -400, -1000, 460, 150 },
+ {"a", 1000, 2000, 350, 250 },
+ {"t", 800, 2000, 400, 250 },
+ {"t2", 600, 2000, 430, 250 },
+ {"a2", 400, 2000, 465, 250 },
+ {"q", 200, 2000, 510, 250 },
+ {"excl", 0, 2000, 570, 220 } };
+
+ QSequentialAnimationGroup * lettersGroupMoving = new QSequentialAnimationGroup(this);
+ QParallelAnimationGroup * lettersGroupFading = new QParallelAnimationGroup(this);
+
+ for (int i = 0; i < nLetters; ++i) {
+ PixmapItem *logo = new PixmapItem(QLatin1String(":/logo-") + logoData[i].pix, this);
+ logo->setPos(logoData[i].initX, logoData[i].initY);
+ logo->setZValue(i + 3);
+ //creation of the animations for moving letters
+ QPropertyAnimation *moveAnim = new QPropertyAnimation(logo, "pos", lettersGroupMoving);
+ moveAnim->setEndValue(QPointF(logoData[i].destX, logoData[i].destY));
+ moveAnim->setDuration(200);
+ moveAnim->setEasingCurve(QEasingCurve::OutElastic);
+ lettersGroupMoving->addPause(50);
+ //creation of the animations for fading out the letters
+ QPropertyAnimation *fadeAnim = new QPropertyAnimation(logo, "opacity", lettersGroupFading);
+ fadeAnim->setDuration(800);
+ fadeAnim->setEndValue(0);
+ fadeAnim->setEasingCurve(QEasingCurve::OutQuad);
+ }
+
+ QStateMachine *machine = new QStateMachine(this);
+
+ //This state is when the player is playing
+ PlayState *gameState = new PlayState(this, machine);
+
+ //Final state
+ QFinalState *final = new QFinalState(machine);
+
+ //Animation when the player enter in the game
+ QAnimationState *lettersMovingState = new QAnimationState(machine);
+ lettersMovingState->setAnimation(lettersGroupMoving);
+
+ //Animation when the welcome screen disappear
+ QAnimationState *lettersFadingState = new QAnimationState(machine);
+ lettersFadingState->setAnimation(lettersGroupFading);
+
+ //if new game then we fade out the welcome screen and start playing
+ lettersMovingState->addTransition(newAction, SIGNAL(triggered()), lettersFadingState);
+ lettersFadingState->addTransition(lettersFadingState, SIGNAL(animationFinished()), gameState);
+
+ //New Game is triggered then player start playing
+ gameState->addTransition(newAction, SIGNAL(triggered()), gameState);
+
+ //Wanna quit, then connect to CTRL+Q
+ gameState->addTransition(quitAction, SIGNAL(triggered()), final);
+ lettersMovingState->addTransition(quitAction, SIGNAL(triggered()), final);
+
+ //Welcome screen is the initial state
+ machine->setInitialState(lettersMovingState);
+
+ machine->start();
+
+ //We reach the final state, then we quit
+ connect(machine, SIGNAL(finished()), qApp, SLOT(quit()));
+}
+
+void GraphicsScene::addItem(Bomb *bomb)
+{
+ bombs.insert(bomb);
+ connect(bomb,SIGNAL(bombExecutionFinished()),this, SLOT(onBombExecutionFinished()));
+ QGraphicsScene::addItem(bomb);
+}
+
+void GraphicsScene::addItem(Torpedo *torpedo)
+{
+ torpedos.insert(torpedo);
+ connect(torpedo,SIGNAL(torpedoExecutionFinished()),this, SLOT(onTorpedoExecutionFinished()));
+ QGraphicsScene::addItem(torpedo);
+}
+
+void GraphicsScene::addItem(SubMarine *submarine)
+{
+ submarines.insert(submarine);
+ connect(submarine,SIGNAL(subMarineExecutionFinished()),this, SLOT(onSubMarineExecutionFinished()));
+ QGraphicsScene::addItem(submarine);
+}
+
+void GraphicsScene::addItem(QGraphicsItem *item)
+{
+ QGraphicsScene::addItem(item);
+}
+
+void GraphicsScene::onBombExecutionFinished()
+{
+ Bomb *bomb = qobject_cast<Bomb *>(sender());
+ bombs.remove(bomb);
+ bomb->deleteLater();
+ if (boat)
+ boat->setBombsLaunched(boat->bombsLaunched() - 1);
+}
+
+void GraphicsScene::onTorpedoExecutionFinished()
+{
+ Torpedo *torpedo = qobject_cast<Torpedo *>(sender());
+ torpedos.remove(torpedo);
+ torpedo->deleteLater();
+}
+
+void GraphicsScene::onSubMarineExecutionFinished()
+{
+ SubMarine *submarine = qobject_cast<SubMarine *>(sender());
+ submarines.remove(submarine);
+ if (submarines.count() == 0)
+ emit allSubMarineDestroyed(submarine->points());
+ else
+ emit subMarineDestroyed(submarine->points());
+ submarine->deleteLater();
+}
+
+void GraphicsScene::clearScene()
+{
+ foreach (SubMarine *sub, submarines) {
+ sub->destroy();
+ sub->deleteLater();
+ }
+
+ foreach (Torpedo *torpedo, torpedos) {
+ torpedo->destroy();
+ torpedo->deleteLater();
+ }
+
+ foreach (Bomb *bomb, bombs) {
+ bomb->destroy();
+ bomb->deleteLater();
+ }
+
+ submarines.clear();
+ bombs.clear();
+ torpedos.clear();
+
+ AnimationManager::self()->unregisterAllAnimations();
+
+ boat->stop();
+ boat->hide();
+ boat->setEnabled(true);
+}
diff --git a/examples/widgets/animation/sub-attaq/graphicsscene.h b/examples/widgets/animation/sub-attaq/graphicsscene.h
new file mode 100644
index 0000000000..3e571a878c
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/graphicsscene.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef __GRAPHICSSCENE__H__
+#define __GRAPHICSSCENE__H__
+
+//Qt
+#include <QtWidgets/QGraphicsScene>
+#include <QtCore/QSet>
+#include <QtCore/QState>
+
+
+class Boat;
+class SubMarine;
+class Torpedo;
+class Bomb;
+class PixmapItem;
+class ProgressItem;
+class TextInformationItem;
+QT_BEGIN_NAMESPACE
+class QAction;
+QT_END_NAMESPACE
+
+class GraphicsScene : public QGraphicsScene
+{
+Q_OBJECT
+public:
+ enum Mode {
+ Big = 0,
+ Small
+ };
+
+ struct SubmarineDescription {
+ int type;
+ int points;
+ QString name;
+ };
+
+ struct LevelDescription {
+ int id;
+ QString name;
+ QList<QPair<int,int> > submarines;
+ };
+
+ GraphicsScene(int x, int y, int width, int height, Mode mode = Big);
+ qreal sealLevel() const;
+ void setupScene(QAction *newAction, QAction *quitAction);
+ void addItem(Bomb *bomb);
+ void addItem(Torpedo *torpedo);
+ void addItem(SubMarine *submarine);
+ void addItem(QGraphicsItem *item);
+ void clearScene();
+
+signals:
+ void subMarineDestroyed(int);
+ void allSubMarineDestroyed(int);
+
+private slots:
+ void onBombExecutionFinished();
+ void onTorpedoExecutionFinished();
+ void onSubMarineExecutionFinished();
+
+private:
+ Mode mode;
+ ProgressItem *progressItem;
+ TextInformationItem *textInformationItem;
+ Boat *boat;
+ QSet<SubMarine *> submarines;
+ QSet<Bomb *> bombs;
+ QSet<Torpedo *> torpedos;
+ QVector<SubmarineDescription> submarinesData;
+ QHash<int, LevelDescription> levelsData;
+
+ friend class PauseState;
+ friend class PlayState;
+ friend class LevelState;
+ friend class LostState;
+ friend class WinState;
+ friend class WinTransition;
+ friend class UpdateScoreTransition;
+};
+
+#endif //__GRAPHICSSCENE__H__
+
diff --git a/examples/widgets/animation/sub-attaq/main.cpp b/examples/widgets/animation/sub-attaq/main.cpp
new file mode 100644
index 0000000000..df18c83435
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/main.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+#include <QtWidgets>
+
+#include "mainwindow.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ Q_INIT_RESOURCE(subattaq);
+
+ qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
+
+ MainWindow w;
+ w.show();
+
+ return app.exec();
+}
diff --git a/examples/widgets/animation/sub-attaq/mainwindow.cpp b/examples/widgets/animation/sub-attaq/mainwindow.cpp
new file mode 100644
index 0000000000..70f0303177
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/mainwindow.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+//Own
+#include "mainwindow.h"
+#include "graphicsscene.h"
+
+//Qt
+#include <QGraphicsView>
+#include <QApplication>
+#include <QMenu>
+#include <QMenuBar>
+#include <QLayout>
+
+#ifndef QT_NO_OPENGL
+# include <QtOpenGL/QtOpenGL>
+#endif
+
+MainWindow::MainWindow() : QMainWindow(0)
+{
+ QMenu *file = menuBar()->addMenu(tr("&File"));
+
+ QAction *newAction = file->addAction(tr("New Game"));
+ newAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_N));
+ QAction *quitAction = file->addAction(tr("Quit"));
+ quitAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q));
+
+ if (QApplication::arguments().contains("-fullscreen")) {
+ scene = new GraphicsScene(0, 0, 750, 400, GraphicsScene::Small);
+ setWindowState(Qt::WindowFullScreen);
+ } else {
+ scene = new GraphicsScene(0, 0, 880, 630);
+ layout()->setSizeConstraint(QLayout::SetFixedSize);
+ }
+
+ view = new QGraphicsView(scene, this);
+ view->setAlignment(Qt::AlignLeft | Qt::AlignTop);
+ scene->setupScene(newAction, quitAction);
+#ifndef QT_NO_OPENGL
+ view->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
+#endif
+
+ setCentralWidget(view);
+}
diff --git a/examples/widgets/animation/sub-attaq/mainwindow.h b/examples/widgets/animation/sub-attaq/mainwindow.h
new file mode 100644
index 0000000000..596157d38f
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/mainwindow.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef __MAINWINDOW__H__
+#define __MAINWINDOW__H__
+
+//Qt
+#include <QtWidgets/QMainWindow>
+class GraphicsScene;
+QT_BEGIN_NAMESPACE
+class QGraphicsView;
+QT_END_NAMESPACE
+
+class MainWindow : public QMainWindow
+{
+Q_OBJECT
+public:
+ MainWindow();
+
+private:
+ GraphicsScene *scene;
+ QGraphicsView *view;
+};
+
+#endif //__MAINWINDOW__H__
diff --git a/examples/widgets/animation/sub-attaq/pics/big/background.png b/examples/widgets/animation/sub-attaq/pics/big/background.png
new file mode 100644
index 0000000000..9f581571fa
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/big/background.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/big/boat.png b/examples/widgets/animation/sub-attaq/pics/big/boat.png
new file mode 100644
index 0000000000..be82dff62a
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/big/boat.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/big/bomb.png b/examples/widgets/animation/sub-attaq/pics/big/bomb.png
new file mode 100644
index 0000000000..3af5f2f29c
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/big/bomb.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/big/explosion/boat/step1.png b/examples/widgets/animation/sub-attaq/pics/big/explosion/boat/step1.png
new file mode 100644
index 0000000000..c9fd8b0984
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/big/explosion/boat/step1.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/big/explosion/boat/step2.png b/examples/widgets/animation/sub-attaq/pics/big/explosion/boat/step2.png
new file mode 100644
index 0000000000..7528f2d2da
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/big/explosion/boat/step2.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/big/explosion/boat/step3.png b/examples/widgets/animation/sub-attaq/pics/big/explosion/boat/step3.png
new file mode 100644
index 0000000000..aae9c9c184
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/big/explosion/boat/step3.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/big/explosion/boat/step4.png b/examples/widgets/animation/sub-attaq/pics/big/explosion/boat/step4.png
new file mode 100644
index 0000000000..d697c1bae8
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/big/explosion/boat/step4.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/big/explosion/submarine/step1.png b/examples/widgets/animation/sub-attaq/pics/big/explosion/submarine/step1.png
new file mode 100644
index 0000000000..88ca5144b7
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/big/explosion/submarine/step1.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/big/explosion/submarine/step2.png b/examples/widgets/animation/sub-attaq/pics/big/explosion/submarine/step2.png
new file mode 100644
index 0000000000..524f5890ee
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/big/explosion/submarine/step2.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/big/explosion/submarine/step3.png b/examples/widgets/animation/sub-attaq/pics/big/explosion/submarine/step3.png
new file mode 100644
index 0000000000..2cca1e80fe
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/big/explosion/submarine/step3.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/big/explosion/submarine/step4.png b/examples/widgets/animation/sub-attaq/pics/big/explosion/submarine/step4.png
new file mode 100644
index 0000000000..82100a8260
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/big/explosion/submarine/step4.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/big/submarine.png b/examples/widgets/animation/sub-attaq/pics/big/submarine.png
new file mode 100644
index 0000000000..df435dc47d
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/big/submarine.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/big/surface.png b/examples/widgets/animation/sub-attaq/pics/big/surface.png
new file mode 100644
index 0000000000..4eba29e9cd
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/big/surface.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/big/torpedo.png b/examples/widgets/animation/sub-attaq/pics/big/torpedo.png
new file mode 100644
index 0000000000..f9c26873f1
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/big/torpedo.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/scalable/background-n810.svg b/examples/widgets/animation/sub-attaq/pics/scalable/background-n810.svg
new file mode 100644
index 0000000000..ece9f7aaf1
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/scalable/background-n810.svg
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.0"
+ width="744.09448"
+ height="1052.3622"
+ id="svg2588"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docname="background-n810.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <metadata
+ id="metadata28">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ inkscape:window-height="1141"
+ inkscape:window-width="1920"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ guidetolerance="10.0"
+ gridtolerance="10.0"
+ objecttolerance="10.0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ showgrid="false"
+ inkscape:zoom="1.2399902"
+ inkscape:cx="375"
+ inkscape:cy="461.074"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:current-layer="layer1" />
+ <defs
+ id="defs2590">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective30" />
+ <linearGradient
+ id="linearGradient3746">
+ <stop
+ id="stop3748"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3750"
+ style="stop-color:#0074b7;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <radialGradient
+ cx="82.966125"
+ cy="-178.42453"
+ r="526.79456"
+ fx="82.966125"
+ fy="-178.42453"
+ id="radialGradient3880"
+ xlink:href="#linearGradient3746"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4952094,0.2388475,-0.1040669,0.3734391,-208.61982,418.216)" />
+ <linearGradient
+ id="linearGradient3624">
+ <stop
+ id="stop3626"
+ style="stop-color:#3a8daf;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3636"
+ style="stop-color:#252525;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="552.98486"
+ y1="390.56842"
+ x2="549.39465"
+ y2="702.3479"
+ id="linearGradient3630"
+ xlink:href="#linearGradient3624"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3373776,0,0,1.186038,-986.88716,67.776416)" />
+ <linearGradient
+ id="linearGradient3816">
+ <stop
+ id="stop3818"
+ style="stop-color:#ad8b00;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3820"
+ style="stop-color:#ad8b00;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="573"
+ y1="755.46222"
+ x2="573"
+ y2="700.13464"
+ id="linearGradient3826"
+ xlink:href="#linearGradient3816"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2561681,-151.5,-34.518664)" />
+ <linearGradient
+ id="linearGradient5097">
+ <stop
+ id="stop5099"
+ style="stop-color:#19a2db;stop-opacity:0"
+ offset="0" />
+ <stop
+ id="stop5109"
+ style="stop-color:#1379a7;stop-opacity:0.49803922"
+ offset="0.30000001" />
+ <stop
+ id="stop5101"
+ style="stop-color:#0e5173;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="590.84674"
+ y1="274.57559"
+ x2="590.84674"
+ y2="334.01376"
+ id="linearGradient5103"
+ xlink:href="#linearGradient5097"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-151.5,156.75229)"
+ spreadMethod="pad" />
+ </defs>
+ <g
+ id="layer1">
+ <rect
+ width="1053.5891"
+ height="206.64989"
+ x="-151.79456"
+ y="330.16019"
+ id="rect3638"
+ style="opacity:1;fill:url(#radialGradient3880);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.1880002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ width="1054.4708"
+ height="364.81519"
+ x="-152.23541"
+ y="533.48895"
+ id="rect3622"
+ style="opacity:1;fill:url(#linearGradient3630);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.13464069;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M -152.5,877.11847 C 120.5,865.81296 -202.86309,769.3663 109.5,871.29717 C 172.96247,892.00636 243.5,872.55334 297.5,871.29717 C 351.5,870.041 311.5,859.80335 358.5,876.13354 C 405.5,892.46372 553.5,861.09903 598.5,854.8182 C 643.5,848.53736 756.5,841.79698 795.5,853.10249 C 834.5,864.408 904.5,866.2725 904.5,866.2725 L 901.5,903.95754 L -154.5,902.70137 L -152.5,877.11847 z"
+ id="path3814"
+ style="fill:url(#linearGradient3826);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ d="M 902.20121,894.16261 C 632.01828,889.43035 756.73005,860.2801 614.20403,894.1311 C 596.58819,898.315 408.23621,883.21212 400.43291,894.1311 C 376.86263,927.11261 75.265447,868.1243 34.250926,886.79082 C 31.281885,888.14209 12.514878,884.22134 -12.264082,889.72008 C -48.555335,897.77353 -64.717178,885.62471 -103.31472,890.35697 C -141.91229,895.08922 -145.87102,891.93439 -145.87102,891.93439 L -152.79879,903.10131 L 892.3044,902.5755 L 902.20121,894.16261 z"
+ id="path3828"
+ style="fill:#ad8b00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ </g>
+</svg>
diff --git a/examples/widgets/animation/sub-attaq/pics/scalable/background.svg b/examples/widgets/animation/sub-attaq/pics/scalable/background.svg
new file mode 100644
index 0000000000..0be268010e
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/scalable/background.svg
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.0"
+ width="744.09448"
+ height="1052.3622"
+ id="svg2588"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docname="background.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <metadata
+ id="metadata28">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ inkscape:window-height="1141"
+ inkscape:window-width="1920"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ guidetolerance="10.0"
+ gridtolerance="10.0"
+ objecttolerance="10.0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ showgrid="false"
+ inkscape:zoom="0.93884027"
+ inkscape:cx="473.72605"
+ inkscape:cy="538.63678"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:current-layer="layer1" />
+ <defs
+ id="defs2590">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective30" />
+ <linearGradient
+ id="linearGradient3746">
+ <stop
+ id="stop3748"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3750"
+ style="stop-color:#0074b7;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <radialGradient
+ cx="82.966125"
+ cy="-178.42453"
+ r="526.79456"
+ fx="82.966125"
+ fy="-178.42453"
+ id="radialGradient3880"
+ xlink:href="#linearGradient3746"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4952094,0.3367191,-0.1040669,0.5264617,-208.61982,282.52272)" />
+ <linearGradient
+ id="linearGradient3624">
+ <stop
+ id="stop3626"
+ style="stop-color:#3a8daf;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3636"
+ style="stop-color:#252525;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="552.98486"
+ y1="390.56842"
+ x2="549.39465"
+ y2="702.3479"
+ id="linearGradient3630"
+ xlink:href="#linearGradient3624"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3373776,0,0,1.5004634,-986.88716,-154.07447)" />
+ <linearGradient
+ id="linearGradient3816">
+ <stop
+ id="stop3818"
+ style="stop-color:#ad8b00;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3820"
+ style="stop-color:#ad8b00;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="573"
+ y1="755.46222"
+ x2="573"
+ y2="700.13464"
+ id="linearGradient3826"
+ xlink:href="#linearGradient3816"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.6033628,-151.5,-294.0167)" />
+ <linearGradient
+ id="linearGradient5097">
+ <stop
+ id="stop5099"
+ style="stop-color:#19a2db;stop-opacity:0"
+ offset="0" />
+ <stop
+ id="stop5109"
+ style="stop-color:#1379a7;stop-opacity:0.49803922"
+ offset="0.30000001" />
+ <stop
+ id="stop5101"
+ style="stop-color:#0e5173;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="590.84674"
+ y1="274.57559"
+ x2="590.84674"
+ y2="334.01376"
+ id="linearGradient5103"
+ xlink:href="#linearGradient5097"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-151.5,156.75229)"
+ spreadMethod="pad" />
+ </defs>
+ <g
+ id="layer1">
+ <rect
+ width="1053.5891"
+ height="291.32797"
+ x="-151.79456"
+ y="158.38464"
+ id="rect3638"
+ style="opacity:1;fill:url(#radialGradient3880);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.1880002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ width="1054.4708"
+ height="461.52972"
+ x="-152.23541"
+ y="435.10107"
+ id="rect3622"
+ style="opacity:1;fill:url(#linearGradient3630);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.13464069;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M -152.5,869.5896 C 120.5,855.15934 -202.86309,732.0556 109.5,862.15934 C 172.96247,888.59238 243.5,863.7627 297.5,862.15934 C 351.5,860.55598 311.5,847.48872 358.5,868.33244 C 405.5,889.17615 553.5,849.14252 598.5,841.12571 C 643.5,833.1089 756.5,824.50553 795.5,838.9358 C 834.5,853.36606 904.5,855.74589 904.5,855.74589 L 901.5,903.84677 L -154.5,902.24341 L -152.5,869.5896 z"
+ id="path3814"
+ style="fill:url(#linearGradient3826);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ d="M 902.20121,891.3446 C 632.01828,885.30439 756.73005,848.09724 614.20403,891.30439 C 596.58819,896.64468 408.23621,877.36748 400.43291,891.30439 C 376.86263,933.40172 75.265447,858.10952 34.250926,881.93531 C 31.281885,883.66006 12.514878,878.65564 -12.264082,885.67419 C -48.555335,895.95355 -64.717178,880.4469 -103.31472,886.48711 C -141.91229,892.52732 -145.87102,888.50052 -145.87102,888.50052 L -152.79879,902.75389 L 892.3044,902.08275 L 902.20121,891.3446 z"
+ id="path3828"
+ style="fill:#ad8b00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ </g>
+</svg>
diff --git a/examples/widgets/animation/sub-attaq/pics/scalable/boat.svg b/examples/widgets/animation/sub-attaq/pics/scalable/boat.svg
new file mode 100644
index 0000000000..5298821ba8
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/scalable/boat.svg
@@ -0,0 +1,279 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ width="744.09448"
+ height="1052.3622"
+ id="svg2584">
+ <defs
+ id="defs2666">
+ <linearGradient
+ x1="542.5"
+ y1="222.59448"
+ x2="559"
+ y2="222.59448"
+ id="linearGradient3387"
+ xlink:href="#linearGradient3746"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-110.6791,190.19124)" />
+ <linearGradient
+ id="linearGradient3167">
+ <stop
+ id="stop3169"
+ style="stop-color:#464646;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3345"
+ style="stop-color:#848788;stop-opacity:1"
+ offset="0.44021741" />
+ <stop
+ id="stop3347"
+ style="stop-color:#9ca0a2;stop-opacity:1"
+ offset="0.56799388" />
+ <stop
+ id="stop3171"
+ style="stop-color:#b5babd;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="474.23065"
+ y1="229.92336"
+ x2="474.1944"
+ y2="218.27365"
+ id="linearGradient3416"
+ xlink:href="#linearGradient3167"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-125.98032,185.95625)" />
+ <linearGradient
+ id="linearGradient3692">
+ <stop
+ id="stop3694"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3696"
+ style="stop-color:#b6b6b6;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="573.5"
+ y1="244.2056"
+ x2="578.25"
+ y2="216.9556"
+ id="linearGradient3972"
+ xlink:href="#linearGradient3692"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-126.5541,188.56624)" />
+ <linearGradient
+ id="linearGradient3438">
+ <stop
+ id="stop3440"
+ style="stop-color:#939393;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3444"
+ style="stop-color:#d6d6d6;stop-opacity:1"
+ offset="0.12354442" />
+ <stop
+ id="stop3446"
+ style="stop-color:#dadada;stop-opacity:1"
+ offset="0.74055624" />
+ <stop
+ id="stop3442"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="660.29303"
+ y1="256.53284"
+ x2="444.79303"
+ y2="255.62085"
+ id="linearGradient3948"
+ xlink:href="#linearGradient3438"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-126.5541,185.56624)" />
+ <linearGradient
+ x1="542.5"
+ y1="222.59448"
+ x2="559"
+ y2="222.59448"
+ id="linearGradient3990"
+ xlink:href="#linearGradient3746"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-132.8041,190.19124)" />
+ <linearGradient
+ id="linearGradient3746">
+ <stop
+ id="stop3748"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3750"
+ style="stop-color:#0074b7;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="542.5"
+ y1="222.59448"
+ x2="559"
+ y2="222.59448"
+ id="linearGradient3994"
+ xlink:href="#linearGradient3746"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-88.054101,190.19124)" />
+ <linearGradient
+ id="linearGradient3428">
+ <stop
+ id="stop3430"
+ style="stop-color:#464646;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3432"
+ style="stop-color:#848788;stop-opacity:1"
+ offset="0.18306103" />
+ <stop
+ id="stop3434"
+ style="stop-color:#9ca0a2;stop-opacity:1"
+ offset="0.66368055" />
+ <stop
+ id="stop3436"
+ style="stop-color:#b5babd;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="592.92798"
+ y1="199.43727"
+ x2="557.05743"
+ y2="196.5448"
+ id="linearGradient3426"
+ xlink:href="#linearGradient3428"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-102.5217,149.09845)" />
+ </defs>
+ <g
+ id="layer1">
+ <g
+ id="boat">
+ <path
+ d="M 296.669,434.15623 C 376.12538,436.50959 448.282,436.46711 542.42304,434.15623 C 542.42304,434.15623 544.22253,425.03531 542.42304,422.57953 C 432.90655,403.86953 296.669,418.12547 296.669,422.57953 L 296.669,434.15623 z"
+ id="path3469"
+ style="fill:#a9a9a9;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:3.4975698;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" />
+ <rect
+ width="3.4280596"
+ height="29.611124"
+ x="647.59613"
+ y="173.91156"
+ transform="matrix(0.9327494,0.3605254,-0.3633626,0.9316478,0,0)"
+ id="rect3408"
+ style="opacity:1;fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ width="48.499989"
+ height="8.5"
+ x="318.48221"
+ y="405.82172"
+ transform="matrix(0.9999952,3.0887777e-3,-3.0887777e-3,0.9999952,0,0)"
+ id="rect3376"
+ style="opacity:1;fill:url(#linearGradient3416);fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:2.99999928;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 382.4459,430.66072 C 382.4459,430.66072 420.85999,388.74829 397.4459,385.66072 L 488.4459,397.66072 L 488.4459,432.66072 L 382.4459,430.66072 z"
+ id="path3952"
+ style="fill:url(#linearGradient3972);fill-opacity:1;fill-rule:evenodd;stroke:#323232;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 301.4459,429.66072 C 301.4459,429.66072 330.46329,468.66072 343.4459,468.66072 C 355.42851,471.91072 507.57644,473.70653 525.4459,465.91072 C 534.58031,461.59104 537.90602,455.58662 539.4459,429.66072 C 473.70193,439.43306 371.2651,439.78219 301.4459,429.66072 z"
+ id="path3938"
+ style="fill:url(#linearGradient3948);fill-opacity:1;fill-rule:evenodd;stroke:#545454;stroke-width:3.0999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 339.44863,416.12222 L 357.69854,416.17859 L 368.1622,427.96097 L 339.41234,427.87217 L 339.44863,416.12222 z"
+ id="rect3378"
+ style="fill:#dedede;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" />
+ <rect
+ width="13.5"
+ height="17"
+ x="411.19589"
+ y="404.28574"
+ id="rect3974"
+ style="opacity:1;fill:url(#linearGradient3990);fill-opacity:1;fill-rule:nonzero;stroke:#323232;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ width="13.5"
+ height="17"
+ x="455.94589"
+ y="404.28574"
+ id="rect3992"
+ style="opacity:1;fill:url(#linearGradient3994);fill-opacity:1;fill-rule:nonzero;stroke:#323232;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 295.6959,421.91072 C 360.77923,430.41072 446.61257,432.91072 541.9459,421.91072 C 541.9459,421.91072 543.74902,428.6076 541.9459,430.41072 C 432.20839,444.14823 295.6959,433.68104 295.6959,430.41072 L 295.6959,421.91072 z"
+ id="rect2558"
+ style="fill:#dedede;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" />
+ <rect
+ width="94.427879"
+ height="7.236649"
+ x="437.10614"
+ y="342.2645"
+ transform="matrix(0.9947793,0.1020501,-0.1079723,0.9941539,0,0)"
+ id="rect2569"
+ style="opacity:1;fill:#c1c1c1;fill-opacity:1;fill-rule:nonzero;stroke:#404040;stroke-width:3.0365274;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ width="13.5"
+ height="17"
+ x="433.32089"
+ y="404.28574"
+ id="rect3385"
+ style="opacity:1;fill:url(#linearGradient3387);fill-opacity:1;fill-rule:nonzero;stroke:#323232;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 402.86916,380.21847 L 489.80407,388.85485 L 491.52271,394.54919 L 397.58781,384.91281 L 402.86916,380.21847 z"
+ id="rect3466"
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#404040;stroke-width:3.03650045;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" />
+ <rect
+ width="34.5"
+ height="14.5"
+ x="456.4783"
+ y="336.94293"
+ transform="matrix(0.997157,7.5351915e-2,-7.5351915e-2,0.997157,0,0)"
+ id="rect3418"
+ style="opacity:1;fill:url(#linearGradient3426);fill-opacity:1;fill-rule:nonzero;stroke:#494949;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <g
+ transform="matrix(0.9246214,0.3808874,-0.3808874,0.9246214,-13.252851,-40.129692)"
+ id="flag">
+ <rect
+ width="19.75"
+ height="27.75"
+ x="193.34448"
+ y="-709"
+ transform="matrix(0,1,-1,0,0,0)"
+ id="rect3389"
+ style="opacity:1;fill:#b20000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ width="27.25"
+ height="5.75"
+ x="681.5"
+ y="200.59448"
+ id="rect3393"
+ style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ width="5.75"
+ height="19.5"
+ x="691.25"
+ y="193.59448"
+ id="rect3395"
+ style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ width="27.75"
+ height="2.5"
+ x="681.5"
+ y="202.34448"
+ id="rect3397"
+ style="opacity:1;fill:#000080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ width="3"
+ height="19.25"
+ x="692.5"
+ y="193.59448"
+ id="rect3399"
+ style="opacity:1;fill:#000080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/examples/widgets/animation/sub-attaq/pics/scalable/bomb.svg b/examples/widgets/animation/sub-attaq/pics/scalable/bomb.svg
new file mode 100644
index 0000000000..294771a6dd
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/scalable/bomb.svg
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ width="744.09448"
+ height="1052.3622"
+ id="svg3121">
+ <defs
+ id="defs3123">
+ <radialGradient
+ cx="-135.625"
+ cy="148.71948"
+ r="7.625"
+ fx="-135.625"
+ fy="148.71948"
+ id="radialGradient3439"
+ xlink:href="#linearGradient3366"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ x1="-132.85063"
+ y1="173.6969"
+ x2="-145.3662"
+ y2="177.59828"
+ id="linearGradient3418"
+ xlink:href="#linearGradient3366"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.2134297,-0.5943658,0.6658882,-0.2391126,-274.53441,123.00067)" />
+ <linearGradient
+ x1="-141.85466"
+ y1="181.49153"
+ x2="-144.95044"
+ y2="175.90179"
+ id="linearGradient3414"
+ xlink:href="#linearGradient3366"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2134297,-0.5943658,-0.6658882,-0.2391126,-15.893355,122.67824)" />
+ <linearGradient
+ x1="-149.5"
+ y1="177.59448"
+ x2="-145.7928"
+ y2="180.05936"
+ id="linearGradient3410"
+ xlink:href="#linearGradient3366"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6315243,0,0,0.7075182,-227.03781,54.321514)" />
+ <linearGradient
+ x1="-140.46242"
+ y1="177.40488"
+ x2="-147.04802"
+ y2="172.66473"
+ id="linearGradient3406"
+ xlink:href="#linearGradient3366"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6315243,0,0,-0.7075182,-226.40365,274.91611)" />
+ <linearGradient
+ x1="-147.2406"
+ y1="180.95567"
+ x2="-140.01878"
+ y2="175.57777"
+ id="linearGradient3402"
+ xlink:href="#linearGradient3366"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6315243,0,0,-0.7075182,-64.045217,275.07466)" />
+ <linearGradient
+ x1="-146.98956"
+ y1="174.00922"
+ x2="-142.60332"
+ y2="179.38712"
+ id="linearGradient3398"
+ xlink:href="#linearGradient3366"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6315243,0,0,0.7075182,-62.683611,54.187362)" />
+ <linearGradient
+ id="linearGradient3366">
+ <stop
+ id="stop3368"
+ style="stop-color:#bcbcbc;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3370"
+ style="stop-color:#191b1c;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <radialGradient
+ cx="-208.95004"
+ cy="173.10576"
+ r="31.667252"
+ fx="-208.95004"
+ fy="173.10576"
+ id="radialGradient3364"
+ xlink:href="#linearGradient3366"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <g
+ id="layer1">
+ <g
+ transform="translate(419.4996,488.13454)"
+ id="mine">
+ <path
+ d="M -167.5843,186.54079 A 31.466251,31.466251 0 1 1 -230.5168,186.54079 A 31.466251,31.466251 0 1 1 -167.5843,186.54079 z"
+ transform="matrix(0.6341613,0,0,0.6341613,-18.521242,45.718192)"
+ id="path2586"
+ style="opacity:1;fill:url(#radialGradient3364);fill-opacity:1;stroke:#131313;stroke-width:3.54799318;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M -155.20193,175.4167 C -157.60085,176.6451 -156.78074,184.26068 -156.78074,184.26068 C -156.78074,184.26068 -148.33787,181.58301 -148.57092,178.60053 C -148.74283,176.40051 -153.23774,174.41092 -155.20193,175.4167 z"
+ id="path3382"
+ style="fill:url(#linearGradient3398);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M -156.56354,153.84532 C -158.96246,152.61693 -158.14235,145.00135 -158.14235,145.00135 C -158.14235,145.00135 -149.69948,147.67902 -149.93253,150.66149 C -150.10444,152.86151 -154.59935,154.85111 -156.56354,153.84532 z"
+ id="path3400"
+ style="fill:url(#linearGradient3402);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M -133.88532,153.68678 C -131.48641,152.45838 -132.30652,144.8428 -132.30652,144.8428 C -132.30652,144.8428 -140.74938,147.52047 -140.51633,150.50295 C -140.34442,152.70297 -135.84951,154.69256 -133.88532,153.68678 z"
+ id="path3404"
+ style="fill:url(#linearGradient3406);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M -134.51948,175.55085 C -132.12057,176.77925 -132.94068,184.39483 -132.94068,184.39483 C -132.94068,184.39483 -141.38355,181.71716 -141.15049,178.73469 C -140.97858,176.53467 -136.48367,174.54507 -134.51948,175.55085 z"
+ id="path3408"
+ style="fill:url(#linearGradient3410);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M -161.25709,168.78221 C -163.22395,170.62484 -170.11427,165.85236 -170.11427,165.85236 C -170.11427,165.85236 -164.7408,160.23808 -162.01257,161.46538 C -160.00011,162.37068 -159.64667,167.27352 -161.25709,168.78221 z"
+ id="path3412"
+ style="fill:url(#linearGradient3414);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M -129.17068,169.10464 C -127.20382,170.94727 -120.3135,166.17478 -120.3135,166.17478 C -120.3135,166.17478 -125.68697,160.5605 -128.41519,161.7878 C -130.42766,162.69311 -130.7811,167.59595 -129.17068,169.10464 z"
+ id="path3416"
+ style="fill:url(#linearGradient3418);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M -126,151.21948 A 6.625,6.625 0 1 1 -139.25,151.21948 A 6.625,6.625 0 1 1 -126,151.21948 z"
+ transform="matrix(0.6341613,0,0,0.6341613,-61.039517,68.324922)"
+ id="path3426"
+ style="opacity:1;fill:url(#radialGradient3439);fill-opacity:1;stroke:#131313;stroke-width:3.54799318;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+ </g>
+</svg>
diff --git a/examples/widgets/animation/sub-attaq/pics/scalable/sand.svg b/examples/widgets/animation/sub-attaq/pics/scalable/sand.svg
new file mode 100644
index 0000000000..8af11b7a66
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/scalable/sand.svg
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ width="744.09448"
+ height="1052.3622"
+ id="svg2596">
+ <defs
+ id="defs2598">
+ <linearGradient
+ id="linearGradient3708">
+ <stop
+ id="stop3710"
+ style="stop-color:#202020;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3712"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="518.26996"
+ y1="497.31476"
+ x2="533.02924"
+ y2="497.31476"
+ id="linearGradient3794"
+ xlink:href="#linearGradient3708"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient3718">
+ <stop
+ id="stop3720"
+ style="stop-color:#bcbcbc;stop-opacity:0.28169015"
+ offset="0" />
+ <stop
+ id="stop3722"
+ style="stop-color:#bcbcbc;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="516.89508"
+ y1="503.50137"
+ x2="516.89508"
+ y2="543.80646"
+ id="linearGradient3792"
+ xlink:href="#linearGradient3718"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9947644,0,0,1.3346457,2.7877039,-166.60153)" />
+ <linearGradient
+ id="linearGradient3692">
+ <stop
+ id="stop3694"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3696"
+ style="stop-color:#b6b6b6;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="506.95975"
+ y1="469.73706"
+ x2="525.41608"
+ y2="469.73706"
+ id="linearGradient3790"
+ xlink:href="#linearGradient3692"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient3816">
+ <stop
+ id="stop3818"
+ style="stop-color:#ad8b00;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3820"
+ style="stop-color:#ad8b00;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="573"
+ y1="755.46222"
+ x2="573"
+ y2="700.13464"
+ id="linearGradient3826"
+ xlink:href="#linearGradient3816"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.6033628,-150.63569,-350.3846)" />
+ </defs>
+ <g
+ id="layer1">
+ <path
+ d="M -151.63569,813.2217 C 121.3643,798.79144 -201.99878,675.6877 110.3643,805.79144 C 173.82677,832.22448 244.3643,807.3948 298.3643,805.79144 C 352.3643,804.18808 312.3643,791.12082 359.3643,811.96454 C 406.3643,832.80825 554.3643,792.77462 599.3643,784.75781 C 644.3643,776.741 757.36426,768.13763 796.36426,782.5679 C 835.36426,796.99816 905.36426,799.37799 905.36426,799.37799 L 902.36426,847.47887 L -153.63569,845.87551 L -151.63569,813.2217 z"
+ id="path3814"
+ style="fill:url(#linearGradient3826);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ d="M 908.86426,836.95812 C 635.8643,830.91791 761.87636,793.71076 617.8643,836.91791 C 600.0648,842.2582 409.74894,822.981 401.8643,836.91791 C 378.04825,879.01524 73.306465,803.72304 31.864305,827.54883 C 28.864305,829.27358 9.9016246,824.26916 -15.135695,831.28771 C -51.805335,841.56707 -68.135695,826.06042 -107.1357,832.10063 C -146.1357,838.14084 -150.13569,834.11404 -150.13569,834.11404 L -157.13569,848.36741 L 898.86426,847.69627 L 908.86426,836.95812 z"
+ id="path3828"
+ style="fill:#ad8b00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ </g>
+</svg>
diff --git a/examples/widgets/animation/sub-attaq/pics/scalable/see.svg b/examples/widgets/animation/sub-attaq/pics/scalable/see.svg
new file mode 100644
index 0000000000..0666691215
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/scalable/see.svg
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ width="744.09448"
+ height="1052.3622"
+ id="svg2650">
+ <defs
+ id="defs2652">
+ <linearGradient
+ id="linearGradient3624">
+ <stop
+ id="stop3626"
+ style="stop-color:#3a8daf;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3636"
+ style="stop-color:#252525;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="552.98486"
+ y1="390.56842"
+ x2="549.39465"
+ y2="702.3479"
+ id="linearGradient3630"
+ xlink:href="#linearGradient3624"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3373776,0,0,1.5004634,-996.17287,-279.00679)" />
+ </defs>
+ <g
+ id="layer1">
+ <rect
+ width="1054.4708"
+ height="461.52972"
+ x="-161.52115"
+ y="310.16876"
+ id="rect3622"
+ style="opacity:1;fill:url(#linearGradient3630);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.13464069;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+</svg>
diff --git a/examples/widgets/animation/sub-attaq/pics/scalable/sky.svg b/examples/widgets/animation/sub-attaq/pics/scalable/sky.svg
new file mode 100644
index 0000000000..1546c087a7
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/scalable/sky.svg
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ width="744.09448"
+ height="1052.3622"
+ id="svg2721">
+ <defs
+ id="defs2723">
+ <linearGradient
+ id="linearGradient3746">
+ <stop
+ id="stop3748"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3750"
+ style="stop-color:#0074b7;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <radialGradient
+ cx="82.966125"
+ cy="-178.42453"
+ r="526.79456"
+ fx="82.966125"
+ fy="-178.42453"
+ id="radialGradient3880"
+ xlink:href="#linearGradient3746"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.4952094,0.3367191,-0.1040669,0.5264617,-235.04839,425.12197)" />
+ </defs>
+ <g
+ id="layer1">
+ <rect
+ width="1053.5891"
+ height="291.32797"
+ x="-178.22313"
+ y="300.98392"
+ id="rect3638"
+ style="opacity:1;fill:url(#radialGradient3880);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.1880002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+</svg>
diff --git a/examples/widgets/animation/sub-attaq/pics/scalable/sub-attaq.svg b/examples/widgets/animation/sub-attaq/pics/scalable/sub-attaq.svg
new file mode 100644
index 0000000000..b075179b46
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/scalable/sub-attaq.svg
@@ -0,0 +1,1473 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="1052.3622"
+ height="744.09448"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ version="1.0"
+ sodipodi:docname="sub-attaq.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs4">
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3366"
+ id="radialGradient3439"
+ cx="-135.625"
+ cy="148.71948"
+ fx="-135.625"
+ fy="148.71948"
+ r="7.625"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3366"
+ id="linearGradient3418"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.2134297,-0.5943658,0.6658882,-0.2391126,-274.53441,123.00067)"
+ x1="-132.85063"
+ y1="173.6969"
+ x2="-145.3662"
+ y2="177.59828" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3366"
+ id="linearGradient3414"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2134297,-0.5943658,-0.6658882,-0.2391126,-15.893355,122.67824)"
+ x1="-141.85466"
+ y1="181.49153"
+ x2="-144.95044"
+ y2="175.90179" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3366"
+ id="linearGradient3410"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6315243,0,0,0.7075182,-227.03781,54.321514)"
+ x1="-149.5"
+ y1="177.59448"
+ x2="-145.7928"
+ y2="180.05936" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3366"
+ id="linearGradient3406"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.6315243,0,0,-0.7075182,-226.40365,274.91611)"
+ x1="-140.46242"
+ y1="177.40488"
+ x2="-147.04802"
+ y2="172.66473" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3366"
+ id="linearGradient3402"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6315243,0,0,-0.7075182,-64.045217,275.07466)"
+ x1="-147.2406"
+ y1="180.95567"
+ x2="-140.01878"
+ y2="175.57777" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3366"
+ id="linearGradient3398"
+ x1="-146.98956"
+ y1="174.00922"
+ x2="-142.60332"
+ y2="179.38712"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6315243,0,0,0.7075182,-62.683611,54.187362)" />
+ <linearGradient
+ id="linearGradient3366">
+ <stop
+ id="stop3368"
+ offset="0"
+ style="stop-color:#bcbcbc;stop-opacity:1;" />
+ <stop
+ id="stop3370"
+ offset="1"
+ style="stop-color:#191b1c;stop-opacity:1;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3366"
+ id="radialGradient3364"
+ cx="-208.95004"
+ cy="173.10576"
+ fx="-208.95004"
+ fy="173.10576"
+ r="31.667252"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient5097">
+ <stop
+ style="stop-color:#19a2db;stop-opacity:0;"
+ offset="0"
+ id="stop5099" />
+ <stop
+ id="stop5109"
+ offset="0.30000001"
+ style="stop-color:#1379a7;stop-opacity:0.49803922;" />
+ <stop
+ style="stop-color:#0e5173;stop-opacity:1;"
+ offset="1"
+ id="stop5101" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3523"
+ inkscape:collect="always">
+ <stop
+ id="stop3525"
+ offset="0"
+ style="stop-color:#b9b9b9;stop-opacity:1" />
+ <stop
+ id="stop3527"
+ offset="1"
+ style="stop-color:#444444;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3438">
+ <stop
+ style="stop-color:#939393;stop-opacity:1;"
+ offset="0"
+ id="stop3440" />
+ <stop
+ id="stop3444"
+ offset="0.12354442"
+ style="stop-color:#d6d6d6;stop-opacity:1;" />
+ <stop
+ style="stop-color:#dadada;stop-opacity:1;"
+ offset="0.74055624"
+ id="stop3446" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop3442" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3428">
+ <stop
+ id="stop3430"
+ offset="0"
+ style="stop-color:#464646;stop-opacity:1;" />
+ <stop
+ style="stop-color:#848788;stop-opacity:1;"
+ offset="0.18306103"
+ id="stop3432" />
+ <stop
+ id="stop3434"
+ offset="0.66368055"
+ style="stop-color:#9ca0a2;stop-opacity:1;" />
+ <stop
+ id="stop3436"
+ offset="1"
+ style="stop-color:#b5babd;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4034">
+ <stop
+ id="stop4036"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.49803922;"
+ offset="0.5"
+ id="stop4038" />
+ <stop
+ id="stop4040"
+ offset="0.63705367"
+ style="stop-color:#ffffff;stop-opacity:0.24705882;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.12156863;"
+ offset="0.79425853"
+ id="stop4042" />
+ <stop
+ id="stop4044"
+ offset="1"
+ style="stop-color:#a0a0a0;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4016">
+ <stop
+ style="stop-color:#283e6a;stop-opacity:1;"
+ offset="0"
+ id="stop4018" />
+ <stop
+ style="stop-color:#283e6a;stop-opacity:0;"
+ offset="1"
+ id="stop4020" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4004">
+ <stop
+ style="stop-color:#dbdbdb;stop-opacity:1;"
+ offset="0"
+ id="stop4010" />
+ <stop
+ style="stop-color:#c4c9cb;stop-opacity:1;"
+ offset="1"
+ id="stop4012" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3998">
+ <stop
+ id="stop4000"
+ offset="0"
+ style="stop-color:#adadad;stop-opacity:1;" />
+ <stop
+ id="stop4002"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3864">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3866" />
+ <stop
+ id="stop4028"
+ offset="0.5"
+ style="stop-color:#ffffff;stop-opacity:0.49803922;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.24705882;"
+ offset="0.75"
+ id="stop4030" />
+ <stop
+ id="stop4032"
+ offset="0.875"
+ style="stop-color:#ffffff;stop-opacity:0.12156863;" />
+ <stop
+ style="stop-color:#a0a0a0;stop-opacity:1;"
+ offset="1"
+ id="stop3868" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3816">
+ <stop
+ style="stop-color:#ad8b00;stop-opacity:1;"
+ offset="0"
+ id="stop3818" />
+ <stop
+ style="stop-color:#ad8b00;stop-opacity:0;"
+ offset="1"
+ id="stop3820" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3746">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3748" />
+ <stop
+ style="stop-color:#0074b7;stop-opacity:1;"
+ offset="1"
+ id="stop3750" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3718">
+ <stop
+ style="stop-color:#bcbcbc;stop-opacity:0.28169015;"
+ offset="0"
+ id="stop3720" />
+ <stop
+ style="stop-color:#bcbcbc;stop-opacity:0;"
+ offset="1"
+ id="stop3722" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3708">
+ <stop
+ style="stop-color:#202020;stop-opacity:1;"
+ offset="0"
+ id="stop3710" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop3712" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3692">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3694" />
+ <stop
+ style="stop-color:#b6b6b6;stop-opacity:1;"
+ offset="1"
+ id="stop3696" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3656">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3658" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3660" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3624">
+ <stop
+ style="stop-color:#3a8daf;stop-opacity:1;"
+ offset="0"
+ id="stop3626" />
+ <stop
+ id="stop3636"
+ offset="1"
+ style="stop-color:#252525;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3532">
+ <stop
+ id="stop3534"
+ offset="0"
+ style="stop-color:#545454;stop-opacity:1;" />
+ <stop
+ style="stop-color:#848788;stop-opacity:1;"
+ offset="0.44021741"
+ id="stop3536" />
+ <stop
+ id="stop3538"
+ offset="0.56799388"
+ style="stop-color:#9ca0a2;stop-opacity:1;" />
+ <stop
+ id="stop3540"
+ offset="1"
+ style="stop-color:#565d60;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3345">
+ <stop
+ id="stop3348"
+ offset="0"
+ style="stop-color:#898989;stop-opacity:1;" />
+ <stop
+ style="stop-color:#9ea1a2;stop-opacity:1;"
+ offset="0.44021741"
+ id="stop3350" />
+ <stop
+ id="stop3352"
+ offset="0.56799388"
+ style="stop-color:#bbbdbf;stop-opacity:1;" />
+ <stop
+ id="stop3354"
+ offset="1"
+ style="stop-color:#f0f1f2;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3227">
+ <stop
+ style="stop-color:#444444;stop-opacity:1;"
+ offset="0"
+ id="stop3229" />
+ <stop
+ style="stop-color:#b0b0b0;stop-opacity:1;"
+ offset="1"
+ id="stop3232" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3435">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3437" />
+ <stop
+ style="stop-color:#c0c0c0;stop-opacity:0;"
+ offset="1"
+ id="stop3439" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3421">
+ <stop
+ style="stop-color:#444444;stop-opacity:1;"
+ offset="0"
+ id="stop3423" />
+ <stop
+ style="stop-color:#444444;stop-opacity:0;"
+ offset="1"
+ id="stop3425" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3293">
+ <stop
+ style="stop-color:#c4b434;stop-opacity:1;"
+ offset="0"
+ id="stop3295" />
+ <stop
+ style="stop-color:#9b5500;stop-opacity:1;"
+ offset="1"
+ id="stop3297" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3229">
+ <stop
+ style="stop-color:#125a7a;stop-opacity:1;"
+ offset="0"
+ id="stop3231" />
+ <stop
+ style="stop-color:#308fc0;stop-opacity:1;"
+ offset="1"
+ id="stop3233" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3219">
+ <stop
+ id="stop3221"
+ offset="0"
+ style="stop-color:#a55b00;stop-opacity:1;" />
+ <stop
+ id="stop3223"
+ offset="1"
+ style="stop-color:#f4e45e;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3189">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop3191" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop3193" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3167">
+ <stop
+ style="stop-color:#464646;stop-opacity:1;"
+ offset="0"
+ id="stop3169" />
+ <stop
+ id="stop3345"
+ offset="0.44021741"
+ style="stop-color:#848788;stop-opacity:1;" />
+ <stop
+ style="stop-color:#9ca0a2;stop-opacity:1;"
+ offset="0.56799388"
+ id="stop3347" />
+ <stop
+ style="stop-color:#b5babd;stop-opacity:1;"
+ offset="1"
+ id="stop3171" />
+ </linearGradient>
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective10" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3167"
+ id="linearGradient3175"
+ x1="443.95602"
+ y1="315.31854"
+ x2="443.95602"
+ y2="247.85609"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4908502,0,0,0.4579593,350.98557,542.12189)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3219"
+ id="linearGradient3253"
+ gradientUnits="userSpaceOnUse"
+ x1="325.57214"
+ y1="280.13632"
+ x2="312.84424"
+ y2="257.60013" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3229"
+ id="linearGradient3255"
+ gradientUnits="userSpaceOnUse"
+ x1="310.01578"
+ y1="255.47881"
+ x2="325.92572"
+ y2="280.13632" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3219"
+ id="linearGradient3321"
+ gradientUnits="userSpaceOnUse"
+ x1="325.57214"
+ y1="280.13632"
+ x2="312.84424"
+ y2="257.60013" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3229"
+ id="linearGradient3323"
+ gradientUnits="userSpaceOnUse"
+ x1="310.01578"
+ y1="255.47881"
+ x2="325.92572"
+ y2="280.13632" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3219"
+ id="linearGradient3331"
+ gradientUnits="userSpaceOnUse"
+ x1="325.57214"
+ y1="280.13632"
+ x2="312.84424"
+ y2="257.60013" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3229"
+ id="linearGradient3333"
+ gradientUnits="userSpaceOnUse"
+ x1="310.01578"
+ y1="255.47881"
+ x2="325.92572"
+ y2="280.13632" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3293"
+ id="linearGradient3343"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3292883,0,0,1.10796,1.5038593,-24.232315)"
+ x1="359.5589"
+ y1="258.84247"
+ x2="370.88239"
+ y2="258.84247" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3219"
+ id="linearGradient3365"
+ gradientUnits="userSpaceOnUse"
+ x1="325.57214"
+ y1="280.13632"
+ x2="312.84424"
+ y2="257.60013" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3229"
+ id="linearGradient3367"
+ gradientUnits="userSpaceOnUse"
+ x1="310.01578"
+ y1="255.47881"
+ x2="325.92572"
+ y2="280.13632" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3219"
+ id="linearGradient3369"
+ gradientUnits="userSpaceOnUse"
+ x1="325.57214"
+ y1="280.13632"
+ x2="312.84424"
+ y2="257.60013" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3229"
+ id="linearGradient3371"
+ gradientUnits="userSpaceOnUse"
+ x1="310.01578"
+ y1="255.47881"
+ x2="325.92572"
+ y2="280.13632" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3219"
+ id="linearGradient3379"
+ gradientUnits="userSpaceOnUse"
+ x1="325.57214"
+ y1="280.13632"
+ x2="312.84424"
+ y2="257.60013" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3229"
+ id="linearGradient3381"
+ gradientUnits="userSpaceOnUse"
+ x1="310.01578"
+ y1="255.47881"
+ x2="325.92572"
+ y2="280.13632" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3293"
+ id="linearGradient3385"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3267302,0,0,1.1332782,-1.5786343,-29.194748)"
+ x1="371.79858"
+ y1="258.84247"
+ x2="364.49646"
+ y2="258.84247" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3293"
+ id="linearGradient3401"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.9807835,0,0,1.1280701,-361.45126,-28.553769)"
+ x1="371.79858"
+ y1="258.84247"
+ x2="364.49646"
+ y2="258.84247" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3421"
+ id="radialGradient3431"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1862613,0,0,0.3638703,-186.86143,179.02055)"
+ cx="432.3343"
+ cy="233.80295"
+ fx="432.3343"
+ fy="233.80295"
+ r="59.056834" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3435"
+ id="radialGradient3441"
+ cx="290.5"
+ cy="244.34448"
+ fx="290.5"
+ fy="244.34448"
+ r="37.5"
+ gradientTransform="matrix(0.8202102,0.8202102,-0.7960458,0.7960458,246.73838,-189.686)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3345"
+ id="linearGradient3311"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.466978,0,0,0.4500435,352.00841,540.25044)"
+ x1="510.99884"
+ y1="161.99408"
+ x2="396.48914"
+ y2="161.99408" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3421"
+ id="radialGradient3339"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4181493,0,0,0.1282619,386.09461,620.15777)"
+ cx="432.3343"
+ cy="233.80295"
+ fx="432.3343"
+ fy="233.80295"
+ r="59.056834" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3219"
+ id="linearGradient3434"
+ gradientUnits="userSpaceOnUse"
+ x1="325.57214"
+ y1="280.13632"
+ x2="312.84424"
+ y2="257.60013" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3229"
+ id="linearGradient3436"
+ gradientUnits="userSpaceOnUse"
+ x1="310.01578"
+ y1="255.47881"
+ x2="325.92572"
+ y2="280.13632" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3532"
+ id="linearGradient3520"
+ x1="525"
+ y1="371.09448"
+ x2="525"
+ y2="395.09448"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5865192,0,0,0.2518015,339.73218,572.99479)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3624"
+ id="linearGradient3630"
+ x1="552.98486"
+ y1="390.56842"
+ x2="549.39465"
+ y2="702.3479"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.3373776,0,0,1.5004634,-835.38716,-310.82676)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3656"
+ id="radialGradient3662"
+ cx="656.19507"
+ cy="534.45917"
+ fx="656.19507"
+ fy="534.45917"
+ r="13.227922"
+ gradientTransform="matrix(1,0,0,1.2672781,0,-144.63884)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3656"
+ id="radialGradient3668"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2672781,0,-144.63884)"
+ cx="656.19507"
+ cy="534.45917"
+ fx="656.19507"
+ fy="534.45917"
+ r="13.227922" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3656"
+ id="radialGradient3672"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2672781,0,-144.63884)"
+ cx="656.19507"
+ cy="534.45917"
+ fx="656.19507"
+ fy="534.45917"
+ r="13.227922" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3656"
+ id="radialGradient3676"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2672781,0,-144.63884)"
+ cx="656.19507"
+ cy="534.45917"
+ fx="656.19507"
+ fy="534.45917"
+ r="13.227922" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3692"
+ id="linearGradient3772"
+ gradientUnits="userSpaceOnUse"
+ x1="506.95975"
+ y1="469.73706"
+ x2="525.41608"
+ y2="469.73706" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3718"
+ id="linearGradient3774"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9947644,0,0,1.3346457,2.7877039,-166.60153)"
+ x1="516.89508"
+ y1="503.50137"
+ x2="516.89508"
+ y2="543.80646" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3708"
+ id="linearGradient3776"
+ gradientUnits="userSpaceOnUse"
+ x1="518.26993"
+ y1="497.31477"
+ x2="533.02923"
+ y2="497.31477" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3692"
+ id="linearGradient3790"
+ gradientUnits="userSpaceOnUse"
+ x1="506.95975"
+ y1="469.73706"
+ x2="525.41608"
+ y2="469.73706" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3718"
+ id="linearGradient3792"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9947644,0,0,1.3346457,2.7877039,-166.60153)"
+ x1="516.89508"
+ y1="503.50137"
+ x2="516.89508"
+ y2="543.80646" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3708"
+ id="linearGradient3794"
+ gradientUnits="userSpaceOnUse"
+ x1="518.26993"
+ y1="497.31477"
+ x2="533.02923"
+ y2="497.31477" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3656"
+ id="radialGradient3804"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2672781,0,-144.63884)"
+ cx="656.19507"
+ cy="534.45917"
+ fx="656.19507"
+ fy="534.45917"
+ r="13.227922" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3656"
+ id="radialGradient3808"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2672781,0,-144.63884)"
+ cx="656.19507"
+ cy="534.45917"
+ fx="656.19507"
+ fy="534.45917"
+ r="13.227922" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3227"
+ id="linearGradient3812"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1223608,0,0,0.3849769,-17.516054,565.40983)"
+ x1="543.5"
+ y1="205.19257"
+ x2="587.52001"
+ y2="205.19257" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3816"
+ id="linearGradient3826"
+ x1="573"
+ y1="755.46222"
+ x2="573"
+ y2="700.13464"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.6033628,0,-450.76899)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3864"
+ id="radialGradient3874"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.9674693,0.8647541,-0.8726553,1.0212484,-15.308759,-74.232772)"
+ cx="94.273849"
+ cy="89.893486"
+ fx="94.273849"
+ fy="89.893486"
+ r="74.397521" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3746"
+ id="radialGradient3880"
+ cx="82.966125"
+ cy="-178.42453"
+ fx="82.966125"
+ fy="-178.42453"
+ r="526.79456"
+ gradientTransform="matrix(1.4952094,0.3367191,-0.1040669,0.5264617,-57.119818,125.77043)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3438"
+ id="linearGradient3948"
+ x1="660.29303"
+ y1="256.53284"
+ x2="444.79303"
+ y2="255.62085"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,32.526912)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3692"
+ id="linearGradient3972"
+ x1="573.5"
+ y1="244.2056"
+ x2="578.25"
+ y2="216.9556"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,35.526912)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3746"
+ id="linearGradient3990"
+ x1="542.5"
+ y1="222.59448"
+ x2="559"
+ y2="222.59448"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6.25,37.151912)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3746"
+ id="linearGradient3994"
+ gradientUnits="userSpaceOnUse"
+ x1="542.5"
+ y1="222.59448"
+ x2="559"
+ y2="222.59448"
+ gradientTransform="translate(38.5,37.151912)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4016"
+ id="linearGradient4022"
+ x1="639"
+ y1="262.09448"
+ x2="667"
+ y2="262.09448"
+ gradientUnits="userSpaceOnUse" />
+ <inkscape:perspective
+ id="perspective2578"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3746"
+ id="linearGradient3387"
+ gradientUnits="userSpaceOnUse"
+ x1="542.5"
+ y1="222.59448"
+ x2="559"
+ y2="222.59448"
+ gradientTransform="translate(15.875,37.151912)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3167"
+ id="linearGradient3416"
+ x1="474.23065"
+ y1="229.92336"
+ x2="474.1944"
+ y2="218.27365"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.1004684,32.526757)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3428"
+ id="linearGradient3426"
+ x1="592.92798"
+ y1="199.43727"
+ x2="557.05743"
+ y2="196.5448"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(12.140805,-13.041887)" />
+ <filter
+ inkscape:collect="always"
+ id="filter3507">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="3.0523171"
+ id="feGaussianBlur3509" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3523"
+ id="linearGradient3521"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,-0.7291751,0,521.83983)"
+ x1="562.55634"
+ y1="285.89896"
+ x2="562.55634"
+ y2="244.09448" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5097"
+ id="linearGradient5103"
+ x1="590.84674"
+ y1="274.57559"
+ x2="590.84674"
+ y2="334.01376"
+ gradientUnits="userSpaceOnUse"
+ spreadMethod="pad" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3864"
+ id="radialGradient5107"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.9674693,0.8647541,-0.8726553,1.0212484,-15.308759,-74.232772)"
+ cx="94.273849"
+ cy="89.893486"
+ fx="94.273849"
+ fy="89.893486"
+ r="74.397521" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10"
+ objecttolerance="10"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.70710678"
+ inkscape:cx="532.91407"
+ inkscape:cy="457.84365"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1674"
+ inkscape:window-height="1000"
+ inkscape:window-x="2"
+ inkscape:window-y="14"
+ showguides="false" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <rect
+ style="opacity:1;fill:url(#radialGradient3880);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.1880002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3638"
+ width="1053.5891"
+ height="291.32797"
+ x="-0.29455566"
+ y="1.6323624" />
+ <path
+ style="fill:url(#radialGradient3874);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3507)"
+ d="M 158.37853,75.817898 C 130.95894,49.483192 82.14552,74.615971 85.85382,95.15981 C 49.691853,94.8009 50.214842,139.36083 83.29101,132.16343 C 144.66465,163.16454 159.26268,129.80212 164.6863,136.51386 C 225.60448,157.97672 246.34362,130.65438 265.24417,127.0714 C 294.43981,137.91859 337.16986,121.78798 297.03636,102.77604 C 331.73096,64.597047 277.96882,60.229366 253.07028,70.400868 C 191.09597,33.610112 168.89234,63.292037 158.37853,75.817898 z"
+ id="path3872"
+ sodipodi:nodetypes="cccccccc"
+ transform="matrix(1.5062893,0,0,1.1720951,618.04001,132.36768)" />
+ <rect
+ style="opacity:1;fill:url(#linearGradient3630);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.13464069;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3622"
+ width="1054.4708"
+ height="461.52972"
+ x="-0.7354126"
+ y="278.34879" />
+ <path
+ style="fill:url(#linearGradient3826);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M -0.99999999,712.83731 C 272,698.40705 -51.363087,575.30331 261,705.40705 C 324.46247,731.84009 395,707.01041 449,705.40705 C 503,703.80369 463,690.73643 510,711.58015 C 557,732.42386 705,692.39023 750,684.37342 C 795,676.35661 908,667.75324 947,682.18351 C 986,696.61377 1056,698.9936 1056,698.9936 L 1053,747.09448 L -3,745.49112 L -0.99999999,712.83731 z"
+ id="path3814"
+ sodipodi:nodetypes="cssssscccc" />
+ <rect
+ style="opacity:1;fill:url(#linearGradient3520);fill-opacity:1;fill-rule:nonzero;stroke:#1b1e1f;stroke-width:0.56879884;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3512"
+ width="10.557344"
+ height="6.0432386"
+ x="642.3761"
+ y="666.43695" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#path2455"
+ id="use3258"
+ transform="matrix(0.869168,0,0,-0.869168,81.98751,1246.5374)"
+ width="1052.3622"
+ height="744.09448" />
+ <path
+ style="fill:url(#linearGradient3812);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.77744257;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 593.04822,651.68104 C 593.04822,651.68104 653.65569,615.49321 639.065,637.05192 C 624.47431,658.61061 624.47431,658.61061 624.47431,658.61061 L 593.04822,651.68104 z"
+ id="path2455" />
+ <path
+ style="fill:url(#linearGradient3175);fill-opacity:1;fill-rule:evenodd;stroke:#393939;stroke-width:1.90693891;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 485.26939,643.71814 C 443.15507,651.66437 458.5319,680.53556 502.21486,686.27814 C 551.68229,692.78115 568.45042,691.0115 605.34827,686.27814 C 657.60843,679.57406 657.68143,651.78445 605.34827,643.25553 C 553.98131,634.88408 516.10913,637.89923 485.26939,643.71814 z"
+ id="path2385"
+ sodipodi:nodetypes="cssss" />
+ <path
+ style="fill:url(#radialGradient3339);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 542.18031,648.1112 C 548.56327,665.42741 608.42397,656.72745 586.93551,642.57104 C 586.93551,642.57104 543.33293,648.61096 542.18031,648.1112 z"
+ id="path3403"
+ sodipodi:nodetypes="ccc" />
+ <path
+ style="fill:url(#linearGradient3311);fill-opacity:1;fill-rule:evenodd;stroke:#2d2d2d;stroke-width:2.07042313;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 537.39402,641.90906 C 537.39402,656.7605 583.62247,656.30589 583.62247,641.45445 L 583.62247,636.06071 C 583.62247,621.21003 537.39402,613.87461 537.39402,628.72529 L 537.39402,641.90906 z"
+ id="path3291"
+ sodipodi:nodetypes="cssss" />
+ <g
+ id="g3235"
+ transform="matrix(1.4016868,0,0,1.1319742,112.22001,-99.678822)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:url(#radialGradient3441);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.227;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path3433"
+ sodipodi:cx="303.5"
+ sodipodi:cy="263.09448"
+ sodipodi:rx="37.5"
+ sodipodi:ry="40"
+ d="M 341,263.09448 A 37.5,40 0 1 1 266,263.09448 A 37.5,40 0 1 1 341,263.09448 z"
+ transform="matrix(0.692163,0,1.4106583e-2,0.289185,275.31394,582.37251)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:#444444;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.06500006;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path3458"
+ sodipodi:cx="369.5"
+ sodipodi:cy="316.09448"
+ sodipodi:rx="27.5"
+ sodipodi:ry="7"
+ d="M 397,316.09448 A 27.5,7 0 1 1 342,316.09448 A 27.5,7 0 1 1 397,316.09448 z"
+ transform="matrix(0.5642633,0,0,0.5642633,348.03095,450.47113)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:#444444;fill-opacity:1;fill-rule:nonzero;stroke:#1b1e1f;stroke-width:4.23126984;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path3510"
+ sodipodi:cx="369.5"
+ sodipodi:cy="316.09448"
+ sodipodi:rx="27.5"
+ sodipodi:ry="7"
+ d="M 397,316.09448 A 27.5,7 0 1 1 342,316.09448 A 27.5,7 0 1 1 397,316.09448 z"
+ transform="matrix(0,0.30778,-0.5642633,0,828.66499,563.5944)" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#path3510"
+ id="use3544"
+ transform="translate(0.5000005,-17.23511)"
+ width="1052.3622"
+ height="744.09448" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:#787878;fill-opacity:1;fill-rule:nonzero;stroke:#1b1e1f;stroke-width:2.38492584;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path3584"
+ sodipodi:cx="237.5"
+ sodipodi:cy="366.09448"
+ sodipodi:rx="8.5"
+ sodipodi:ry="8"
+ d="M 246,366.09448 A 8.5,8 0 1 1 229,366.09448 A 8.5,8 0 1 1 246,366.09448 z"
+ transform="matrix(1.7798114,-4.2997512e-2,1.3318941e-2,0.5513151,196.65666,476.1443)" />
+ <path
+ style="fill:#a9a9a9;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:3.49756980000000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
+ d="M 423.2231,281.1169 C 502.67948,283.47026 574.8361,283.42778 668.97714,281.1169 C 668.97714,281.1169 670.77663,271.99598 668.97714,269.5402 C 559.46065,250.8302 423.2231,265.08614 423.2231,269.5402 L 423.2231,281.1169 z"
+ id="path3469"
+ sodipodi:nodetypes="cccsc" />
+ <rect
+ style="opacity:1;fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3408"
+ width="3.4280596"
+ height="29.611124"
+ x="709.89148"
+ y="-14.462622"
+ transform="matrix(0.9327494,0.3605254,-0.3633626,0.9316478,0,0)" />
+ <rect
+ style="opacity:1;fill:url(#linearGradient3416);fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:2.99999928;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3376"
+ width="48.499989"
+ height="8.5"
+ x="444.56302"
+ y="252.39224"
+ transform="matrix(0.9999952,3.0887776e-3,-3.0887776e-3,0.9999952,0,0)" />
+ <path
+ style="fill:url(#linearGradient3972);fill-opacity:1;fill-rule:evenodd;stroke:#323232;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 509,277.62139 C 509,277.62139 547.41409,235.70896 524,232.62139 L 615,244.62139 L 615,279.62139 L 509,277.62139 z"
+ id="path3952"
+ sodipodi:nodetypes="csccc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:url(#radialGradient3662);fill-opacity:1;fill-rule:nonzero;stroke:#41526b;stroke-width:2.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path3654"
+ sodipodi:cx="656.19507"
+ sodipodi:cy="541.15485"
+ sodipodi:rx="12.727922"
+ sodipodi:ry="16.263456"
+ d="M 668.92299,541.15485 A 12.727922,16.263456 0 1 1 643.46715,541.15485 A 12.727922,16.263456 0 1 1 668.92299,541.15485 z"
+ transform="matrix(0.5187874,0,0,0.3968421,374.8524,387.30025)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:url(#radialGradient3668);fill-opacity:1;fill-rule:nonzero;stroke:#41526b;stroke-width:2.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path3666"
+ sodipodi:cx="656.19507"
+ sodipodi:cy="541.15485"
+ sodipodi:rx="12.727922"
+ sodipodi:ry="16.263456"
+ d="M 668.92299,541.15485 A 12.727922,16.263456 0 1 1 643.46715,541.15485 A 12.727922,16.263456 0 1 1 668.92299,541.15485 z"
+ transform="matrix(0.5734968,0,0,0.4386917,316.52295,315.62837)" />
+ <path
+ transform="matrix(0.8598866,0,0,0.5637407,192.52282,220.77351)"
+ d="M 668.92299,541.15485 A 12.727922,16.263456 0 1 1 643.46715,541.15485 A 12.727922,16.263456 0 1 1 668.92299,541.15485 z"
+ sodipodi:ry="16.263456"
+ sodipodi:rx="12.727922"
+ sodipodi:cy="541.15485"
+ sodipodi:cx="656.19507"
+ id="path3670"
+ style="opacity:1;fill:url(#radialGradient3672);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.90000010000000020;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:url(#radialGradient3676);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.90000010000000020;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path3674"
+ sodipodi:cx="656.19507"
+ sodipodi:cy="541.15485"
+ sodipodi:rx="12.727922"
+ sodipodi:ry="16.263456"
+ d="M 668.92299,541.15485 A 12.727922,16.263456 0 1 1 643.46715,541.15485 A 12.727922,16.263456 0 1 1 668.92299,541.15485 z"
+ transform="matrix(0.7435991,0,0,0.6264519,225.8301,127.83701)" />
+ <g
+ id="g3759"
+ transform="matrix(0.8830571,0,0,0.8830571,104.83144,103.2985)">
+ <path
+ d="M 523.9661,469.73706 A 7.7781744,34.648232 0 1 1 508.40975,469.73706 A 7.7781744,34.648232 0 1 1 523.9661,469.73706 z"
+ sodipodi:ry="34.648232"
+ sodipodi:rx="7.7781744"
+ sodipodi:cy="469.73706"
+ sodipodi:cx="516.18793"
+ id="path3682"
+ style="opacity:1;fill:url(#linearGradient3772);fill-opacity:1;fill-rule:nonzero;stroke:#272727;stroke-width:2.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <g
+ id="g3754">
+ <rect
+ style="opacity:1;fill:url(#linearGradient3774);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3716"
+ width="33.58757"
+ height="59.927299"
+ x="498.86386"
+ y="497.84454" />
+ <path
+ style="fill:url(#linearGradient3776);fill-opacity:1;fill-rule:evenodd;stroke:#1f1f1f;stroke-width:1.99788344;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 523.35045,482.89424 C 523.35045,482.89424 532.31256,488.20203 532.02344,500.14638 C 531.73431,512.09072 531.73431,511.73417 531.73431,511.73417 C 531.73431,511.73417 520.70627,493.83104 519.26887,499.77636 L 523.35045,482.89424 z"
+ id="path3704"
+ sodipodi:nodetypes="cscsc" />
+ <path
+ sodipodi:nodetypes="cscsc"
+ id="path3706"
+ d="M 508.50327,482.89424 C 508.50327,482.89424 499.54116,488.20203 499.83028,500.14638 C 500.11941,512.09072 500.11941,511.73417 500.11941,511.73417 C 500.11941,511.73417 511.14745,493.83104 512.58485,499.77636 L 508.50327,482.89424 z"
+ style="fill:#bcbcbc;fill-opacity:1;fill-rule:evenodd;stroke:#1f1f1f;stroke-width:1.99788344;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+ </g>
+ <g
+ transform="matrix(0.8830571,0,0,0.8830571,192.45885,-66.370546)"
+ id="g3778">
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:url(#linearGradient3790);fill-opacity:1;fill-rule:nonzero;stroke:#272727;stroke-width:2.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path3780"
+ sodipodi:cx="516.18793"
+ sodipodi:cy="469.73706"
+ sodipodi:rx="7.7781744"
+ sodipodi:ry="34.648232"
+ d="M 523.9661,469.73706 A 7.7781744,34.648232 0 1 1 508.40975,469.73706 A 7.7781744,34.648232 0 1 1 523.9661,469.73706 z" />
+ <g
+ id="g3782">
+ <rect
+ y="497.84454"
+ x="498.86386"
+ height="59.927299"
+ width="33.58757"
+ id="rect3784"
+ style="opacity:1;fill:url(#linearGradient3792);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="cscsc"
+ id="path3786"
+ d="M 523.35045,482.89424 C 523.35045,482.89424 532.31256,488.20203 532.02344,500.14638 C 531.73431,512.09072 531.73431,511.73417 531.73431,511.73417 C 531.73431,511.73417 520.70627,493.83104 519.26887,499.77636 L 523.35045,482.89424 z"
+ style="fill:url(#linearGradient3794);fill-opacity:1;fill-rule:evenodd;stroke:#1f1f1f;stroke-width:1.99788344;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ style="fill:#bcbcbc;fill-opacity:1;fill-rule:evenodd;stroke:#1f1f1f;stroke-width:1.99788344;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 508.50327,482.89424 C 508.50327,482.89424 499.54116,488.20203 499.83028,500.14638 C 500.11941,512.09072 500.11941,511.73417 500.11941,511.73417 C 500.11941,511.73417 511.14745,493.83104 512.58485,499.77636 L 508.50327,482.89424 z"
+ id="path3788"
+ sodipodi:nodetypes="cscsc" />
+ </g>
+ </g>
+ <path
+ transform="matrix(0.4292897,0,0,0.3283816,384.32775,481.20689)"
+ d="M 668.92299,541.15485 A 12.727922,16.263456 0 1 1 643.46715,541.15485 A 12.727922,16.263456 0 1 1 668.92299,541.15485 z"
+ sodipodi:ry="16.263456"
+ sodipodi:rx="12.727922"
+ sodipodi:cy="541.15485"
+ sodipodi:cx="656.19507"
+ id="path3802"
+ style="opacity:1;fill:url(#radialGradient3804);fill-opacity:1;fill-rule:nonzero;stroke:#41526b;stroke-width:2.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;fill:url(#radialGradient3808);fill-opacity:1;fill-rule:nonzero;stroke:#41526b;stroke-width:2.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path3806"
+ sodipodi:cx="656.19507"
+ sodipodi:cy="541.15485"
+ sodipodi:rx="12.727922"
+ sodipodi:ry="16.263456"
+ d="M 668.92299,541.15485 A 12.727922,16.263456 0 1 1 643.46715,541.15485 A 12.727922,16.263456 0 1 1 668.92299,541.15485 z"
+ transform="matrix(0.5842998,0,0,0.4469553,299.7804,369.91514)" />
+ <path
+ style="fill:#ad8b00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 1059.5,736.57373 C 786.5,730.53352 912.51207,693.32637 768.5,736.53352 C 750.7005,741.87381 560.38464,722.59661 552.5,736.53352 C 528.68395,778.63085 223.94216,703.33865 182.5,727.16444 C 179.5,728.88919 160.53732,723.88477 135.5,730.90332 C 98.830356,741.18268 82.5,725.67603 43.5,731.71624 C 4.5,737.75645 0.5,733.72965 0.5,733.72965 L -6.5,747.98302 L 1049.5,747.31188 L 1059.5,736.57373 z"
+ id="path3828"
+ sodipodi:nodetypes="cssssscccc" />
+ <rect
+ style="opacity:1;fill:url(#linearGradient5103);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3448"
+ width="1053.5891"
+ height="67.882248"
+ x="-0.29455566"
+ y="274.57559" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path3519"
+ d="M 428,343.85222 C 428,343.85222 457.01739,315.41439 470,315.41439 C 481.98261,313.04457 634.13054,311.73511 652,317.41962 C 661.13441,320.56943 664.46012,324.9477 666,343.85222 C 600.25603,336.72647 497.8192,336.4719 428,343.85222 z"
+ style="opacity:0.43933058;fill:url(#linearGradient3521);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ style="fill:url(#linearGradient3948);fill-opacity:1;fill-rule:evenodd;stroke:#545454;stroke-width:3.0999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 428,276.62139 C 428,276.62139 457.01739,315.62139 470,315.62139 C 481.98261,318.87139 634.13054,320.6672 652,312.87139 C 661.13441,308.55171 664.46012,302.54729 666,276.62139 C 600.25603,286.39373 497.8192,286.74286 428,276.62139 z"
+ id="path3938"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:#dedede;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
+ d="M 466.00273,263.08289 L 484.25264,263.13926 L 494.7163,274.92164 L 465.96644,274.83284 L 466.00273,263.08289 z"
+ id="rect3378"
+ sodipodi:nodetypes="ccccc" />
+ <rect
+ style="opacity:1;fill:url(#linearGradient3990);fill-opacity:1;fill-rule:nonzero;stroke:#323232;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3974"
+ width="13.5"
+ height="17"
+ x="537.75"
+ y="251.2464"
+ inkscape:transform-center-x="30" />
+ <rect
+ inkscape:transform-center-x="30"
+ y="251.2464"
+ x="582.5"
+ height="17"
+ width="13.5"
+ id="rect3992"
+ style="opacity:1;fill:url(#linearGradient3994);fill-opacity:1;fill-rule:nonzero;stroke:#323232;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ style="fill:#dedede;fill-opacity:1;fill-rule:nonzero;stroke:#484848;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
+ d="M 422.25,268.87139 C 487.33333,277.37139 573.16667,279.87139 668.5,268.87139 C 668.5,268.87139 670.30312,275.56827 668.5,277.37139 C 558.76249,291.1089 422.25,280.64171 422.25,277.37139 L 422.25,268.87139 z"
+ id="rect2558"
+ sodipodi:nodetypes="cccsc" />
+ <rect
+ style="opacity:1;fill:#c1c1c1;fill-opacity:1;fill-rule:nonzero;stroke:#404040;stroke-width:3.0365274;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect2569"
+ width="94.427879"
+ height="7.236649"
+ x="546.39832"
+ y="177.10637"
+ transform="matrix(0.9947793,0.1020501,-0.1079723,0.9941539,0,0)" />
+ <rect
+ inkscape:transform-center-x="30"
+ y="251.2464"
+ x="559.875"
+ height="17"
+ width="13.5"
+ id="rect3385"
+ style="opacity:1;fill:url(#linearGradient3387);fill-opacity:1;fill-rule:nonzero;stroke:#323232;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <g
+ id="g3401"
+ transform="matrix(0.9246214,0.3808874,-0.3808874,0.9246214,113.30125,-193.16902)"
+ inkscape:transform-center-x="17.590385"
+ inkscape:transform-center-y="-15.415449">
+ <rect
+ inkscape:transform-center-y="-43.888889"
+ transform="matrix(0,1,-1,0,0,0)"
+ style="opacity:1;fill:#b20000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3389"
+ width="19.75"
+ height="27.75"
+ x="193.34448"
+ y="-709" />
+ <rect
+ y="200.59448"
+ x="681.5"
+ height="5.75"
+ width="27.25"
+ id="rect3393"
+ style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ y="193.59448"
+ x="691.25"
+ height="19.5"
+ width="5.75"
+ id="rect3395"
+ style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ y="202.34448"
+ x="681.5"
+ height="2.5"
+ width="27.75"
+ id="rect3397"
+ style="opacity:1;fill:#000080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ y="193.59448"
+ x="692.5"
+ height="19.25"
+ width="3"
+ id="rect3399"
+ style="opacity:1;fill:#000080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+ <path
+ style="fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:#404040;stroke-width:3.03650045;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
+ d="M 529.42326,227.17914 L 616.35817,235.81552 L 618.07681,241.50986 L 524.14191,231.87348 L 529.42326,227.17914 z"
+ id="rect3466"
+ sodipodi:nodetypes="ccccc" />
+ <rect
+ style="opacity:1;fill:url(#linearGradient3426);fill-opacity:1;fill-rule:nonzero;stroke:#494949;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect3418"
+ width="34.5"
+ height="14.5"
+ x="571.14081"
+ y="174.8026"
+ transform="matrix(0.997157,7.5351915e-2,-7.5351915e-2,0.997157,0,0)"
+ inkscape:transform-center-x="-8"
+ inkscape:transform-center-y="2" />
+ <g
+ id="mine"
+ transform="translate(971.11461,237.62715)"
+ inkscape:label="#g3441">
+ <path
+ transform="matrix(0.6341613,0,0,0.6341613,-18.521242,45.718192)"
+ d="M -167.5843,186.54079 A 31.466251,31.466251 0 1 1 -230.5168,186.54079 A 31.466251,31.466251 0 1 1 -167.5843,186.54079 z"
+ sodipodi:ry="31.466251"
+ sodipodi:rx="31.466251"
+ sodipodi:cy="186.54079"
+ sodipodi:cx="-199.05055"
+ id="path2586"
+ style="opacity:1;fill:url(#radialGradient3364);fill-opacity:1;stroke:#131313;stroke-width:3.54799318;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:nodetypes="ccss"
+ id="path3382"
+ d="M -155.20193,175.4167 C -157.60085,176.6451 -156.78074,184.26068 -156.78074,184.26068 C -156.78074,184.26068 -148.33787,181.58301 -148.57092,178.60053 C -148.74283,176.40051 -153.23774,174.41092 -155.20193,175.4167 z"
+ style="fill:url(#linearGradient3398);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccss"
+ id="path3400"
+ d="M -156.56354,153.84532 C -158.96246,152.61693 -158.14235,145.00135 -158.14235,145.00135 C -158.14235,145.00135 -149.69948,147.67902 -149.93253,150.66149 C -150.10444,152.86151 -154.59935,154.85111 -156.56354,153.84532 z"
+ style="fill:url(#linearGradient3402);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccss"
+ id="path3404"
+ d="M -133.88532,153.68678 C -131.48641,152.45838 -132.30652,144.8428 -132.30652,144.8428 C -132.30652,144.8428 -140.74938,147.52047 -140.51633,150.50295 C -140.34442,152.70297 -135.84951,154.69256 -133.88532,153.68678 z"
+ style="fill:url(#linearGradient3406);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccss"
+ id="path3408"
+ d="M -134.51948,175.55085 C -132.12057,176.77925 -132.94068,184.39483 -132.94068,184.39483 C -132.94068,184.39483 -141.38355,181.71716 -141.15049,178.73469 C -140.97858,176.53467 -136.48367,174.54507 -134.51948,175.55085 z"
+ style="fill:url(#linearGradient3410);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccss"
+ id="path3412"
+ d="M -161.25709,168.78221 C -163.22395,170.62484 -170.11427,165.85236 -170.11427,165.85236 C -170.11427,165.85236 -164.7408,160.23808 -162.01257,161.46538 C -160.00011,162.37068 -159.64667,167.27352 -161.25709,168.78221 z"
+ style="fill:url(#linearGradient3414);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccss"
+ id="path3416"
+ d="M -129.17068,169.10464 C -127.20382,170.94727 -120.3135,166.17478 -120.3135,166.17478 C -120.3135,166.17478 -125.68697,160.5605 -128.41519,161.7878 C -130.42766,162.69311 -130.7811,167.59595 -129.17068,169.10464 z"
+ style="fill:url(#linearGradient3418);fill-opacity:1;fill-rule:evenodd;stroke:#131313;stroke-width:2.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ transform="matrix(0.6341613,0,0,0.6341613,-61.039517,68.324922)"
+ d="M -126,151.21948 A 6.625,6.625 0 1 1 -139.25,151.21948 A 6.625,6.625 0 1 1 -126,151.21948 z"
+ sodipodi:ry="6.625"
+ sodipodi:rx="6.625"
+ sodipodi:cy="151.21948"
+ sodipodi:cx="-132.625"
+ id="path3426"
+ style="opacity:1;fill:url(#radialGradient3439);fill-opacity:1;stroke:#131313;stroke-width:3.54799318;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+</svg>
diff --git a/examples/widgets/animation/sub-attaq/pics/scalable/submarine.svg b/examples/widgets/animation/sub-attaq/pics/scalable/submarine.svg
new file mode 100644
index 0000000000..8a0ffddbca
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/scalable/submarine.svg
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ width="744.09448"
+ height="1052.3622"
+ id="svg2594">
+ <defs
+ id="defs2596">
+ <linearGradient
+ id="linearGradient3345">
+ <stop
+ id="stop3348"
+ style="stop-color:#898989;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3350"
+ style="stop-color:#9ea1a2;stop-opacity:1"
+ offset="0.44021741" />
+ <stop
+ id="stop3352"
+ style="stop-color:#bbbdbf;stop-opacity:1"
+ offset="0.56799388" />
+ <stop
+ id="stop3354"
+ style="stop-color:#f0f1f2;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="510.99884"
+ y1="161.99408"
+ x2="396.48914"
+ y2="161.99408"
+ id="linearGradient3311"
+ xlink:href="#linearGradient3345"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.466978,0,0,0.4500435,231.58508,159.95135)" />
+ <linearGradient
+ id="linearGradient3532">
+ <stop
+ id="stop3534"
+ style="stop-color:#545454;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3536"
+ style="stop-color:#848788;stop-opacity:1"
+ offset="0.44021741" />
+ <stop
+ id="stop3538"
+ style="stop-color:#9ca0a2;stop-opacity:1"
+ offset="0.56799388" />
+ <stop
+ id="stop3540"
+ style="stop-color:#565d60;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="525"
+ y1="371.09448"
+ x2="525"
+ y2="395.09448"
+ id="linearGradient3520"
+ xlink:href="#linearGradient3532"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5865192,0,0,0.2518015,219.30885,192.6957)" />
+ <linearGradient
+ id="linearGradient3227">
+ <stop
+ id="stop3229"
+ style="stop-color:#444444;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3232"
+ style="stop-color:#b0b0b0;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="543.5"
+ y1="205.19257"
+ x2="587.52002"
+ y2="205.19257"
+ id="linearGradient3812"
+ xlink:href="#linearGradient3227"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1223608,0,0,0.3849769,-137.93938,185.11074)" />
+ <linearGradient
+ id="linearGradient3167">
+ <stop
+ id="stop3169"
+ style="stop-color:#464646;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3345"
+ style="stop-color:#848788;stop-opacity:1"
+ offset="0.44021741" />
+ <stop
+ id="stop3347"
+ style="stop-color:#9ca0a2;stop-opacity:1"
+ offset="0.56799388" />
+ <stop
+ id="stop3171"
+ style="stop-color:#b5babd;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="443.95602"
+ y1="315.31854"
+ x2="443.95602"
+ y2="247.85609"
+ id="linearGradient3175"
+ xlink:href="#linearGradient3167"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4908502,0,0,0.4579593,230.56224,161.8228)" />
+ <linearGradient
+ id="linearGradient3421">
+ <stop
+ id="stop3423"
+ style="stop-color:#444444;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3425"
+ style="stop-color:#444444;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <radialGradient
+ cx="432.33429"
+ cy="233.80295"
+ r="59.056835"
+ fx="432.33429"
+ fy="233.80295"
+ id="radialGradient3339"
+ xlink:href="#linearGradient3421"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.4181493,0,0,0.1282619,265.67128,239.85868)" />
+ <linearGradient
+ id="linearGradient3435">
+ <stop
+ id="stop3437"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3439"
+ style="stop-color:#c0c0c0;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <radialGradient
+ cx="290.5"
+ cy="244.34448"
+ r="37.5"
+ fx="290.5"
+ fy="244.34448"
+ id="radialGradient3441"
+ xlink:href="#linearGradient3435"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8202102,0.8202102,-0.7960458,0.7960458,246.73838,-189.686)" />
+ </defs>
+ <g
+ id="submarine">
+ <rect
+ width="10.557344"
+ height="6.0432386"
+ x="521.95276"
+ y="286.13785"
+ id="rect3512"
+ style="opacity:1;fill:url(#linearGradient3520);fill-opacity:1;fill-rule:nonzero;stroke:#1b1e1f;stroke-width:0.56879884;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 472.62489,271.38195 C 472.62489,271.38195 533.23236,235.19412 518.64167,256.75283 C 504.05098,278.31152 504.05098,278.31152 504.05098,278.31152 L 472.62489,271.38195 z"
+ id="path2455"
+ style="fill:url(#linearGradient3812);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.77744257;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 364.84606,263.41905 C 322.73174,271.36528 338.10857,300.23647 381.79153,305.97905 C 431.25896,312.48206 448.02709,310.71241 484.92494,305.97905 C 537.1851,299.27497 537.2581,271.48536 484.92494,262.95644 C 433.55798,254.58499 395.6858,257.60014 364.84606,263.41905 z"
+ id="path2385"
+ style="fill:url(#linearGradient3175);fill-opacity:1;fill-rule:evenodd;stroke:#393939;stroke-width:1.90693891;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 421.75698,267.81211 C 428.13994,285.12832 488.00064,276.42836 466.51218,262.27195 C 466.51218,262.27195 422.9096,268.31187 421.75698,267.81211 z"
+ id="path3403"
+ style="fill:url(#radialGradient3339);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ d="M 416.97069,261.60997 C 416.97069,276.46141 463.19914,276.0068 463.19914,261.15536 L 463.19914,255.76162 C 463.19914,240.91094 416.97069,233.57552 416.97069,248.4262 L 416.97069,261.60997 z"
+ id="path3291"
+ style="fill:url(#linearGradient3311);fill-opacity:1;fill-rule:evenodd;stroke:#2d2d2d;stroke-width:2.07042313;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 341,263.09448 A 37.5,40 0 1 1 266,263.09448 A 37.5,40 0 1 1 341,263.09448 z"
+ transform="matrix(0.692163,0,1.4106583e-2,0.289185,154.89061,202.07342)"
+ id="path3433"
+ style="opacity:1;fill:url(#radialGradient3441);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.227;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 397,316.09448 A 27.5,7 0 1 1 342,316.09448 A 27.5,7 0 1 1 397,316.09448 z"
+ transform="matrix(0.5642633,0,0,0.5642633,227.60762,70.172035)"
+ id="path3458"
+ style="opacity:1;fill:#444444;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.06500006;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 397,316.09448 A 27.5,7 0 1 1 342,316.09448 A 27.5,7 0 1 1 397,316.09448 z"
+ transform="matrix(0,0.30778,-0.5642633,0,708.24166,183.29531)"
+ id="path3510"
+ style="opacity:1;fill:#444444;fill-opacity:1;fill-rule:nonzero;stroke:#1b1e1f;stroke-width:4.23126984;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <use
+ transform="translate(0.5000044,-17.235115)"
+ id="use3544"
+ x="0"
+ y="0"
+ width="1052.3622"
+ height="744.09448"
+ xlink:href="#path3510" />
+ <path
+ d="M 246,366.09448 A 8.5,8 0 1 1 229,366.09448 A 8.5,8 0 1 1 246,366.09448 z"
+ transform="matrix(1.7798114,-4.2997512e-2,1.3318941e-2,0.5513151,76.233334,95.845205)"
+ id="path3584"
+ style="opacity:1;fill:#787878;fill-opacity:1;fill-rule:nonzero;stroke:#1b1e1f;stroke-width:2.38492584;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+</svg>
diff --git a/examples/widgets/animation/sub-attaq/pics/scalable/surface.svg b/examples/widgets/animation/sub-attaq/pics/scalable/surface.svg
new file mode 100644
index 0000000000..40ed239638
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/scalable/surface.svg
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ width="744.09448"
+ height="1052.3622"
+ id="svg2685">
+ <defs
+ id="defs2687">
+ <linearGradient
+ id="linearGradient5097">
+ <stop
+ id="stop5099"
+ style="stop-color:#19a2db;stop-opacity:0"
+ offset="0" />
+ <stop
+ id="stop5109"
+ style="stop-color:#1379a7;stop-opacity:0.49803922"
+ offset="0.30000001" />
+ <stop
+ id="stop5101"
+ style="stop-color:#0e5173;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="590.84674"
+ y1="274.57559"
+ x2="590.84674"
+ y2="334.01376"
+ id="linearGradient5103"
+ xlink:href="#linearGradient5097"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-172.21428,209.55976)"
+ spreadMethod="pad" />
+ </defs>
+ <g
+ id="layer1">
+ <rect
+ width="1053.5891"
+ height="67.882248"
+ x="-172.50883"
+ y="484.13535"
+ id="rect3448"
+ style="opacity:1;fill:url(#linearGradient5103);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+</svg>
diff --git a/examples/widgets/animation/sub-attaq/pics/scalable/torpedo.svg b/examples/widgets/animation/sub-attaq/pics/scalable/torpedo.svg
new file mode 100644
index 0000000000..48e429d2bf
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/scalable/torpedo.svg
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ width="744.09448"
+ height="1052.3622"
+ id="svg2584">
+ <defs
+ id="defs2586">
+ <linearGradient
+ id="linearGradient3708">
+ <stop
+ id="stop3710"
+ style="stop-color:#202020;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3712"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="518.26996"
+ y1="497.31476"
+ x2="533.02924"
+ y2="497.31476"
+ id="linearGradient3776"
+ xlink:href="#linearGradient3708"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient3718">
+ <stop
+ id="stop3720"
+ style="stop-color:#bcbcbc;stop-opacity:0.28169015"
+ offset="0" />
+ <stop
+ id="stop3722"
+ style="stop-color:#bcbcbc;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="516.89508"
+ y1="503.50137"
+ x2="516.89508"
+ y2="543.80646"
+ id="linearGradient3774"
+ xlink:href="#linearGradient3718"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9947644,0,0,1.3346457,2.7877039,-166.60153)" />
+ <linearGradient
+ id="linearGradient3692">
+ <stop
+ id="stop3694"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3696"
+ style="stop-color:#b6b6b6;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="506.95975"
+ y1="469.73706"
+ x2="525.41608"
+ y2="469.73706"
+ id="linearGradient3772"
+ xlink:href="#linearGradient3692"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ x1="506.95975"
+ y1="469.73706"
+ x2="525.41608"
+ y2="469.73706"
+ id="linearGradient2403"
+ xlink:href="#linearGradient3692"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ x1="516.89508"
+ y1="503.50137"
+ x2="516.89508"
+ y2="543.80646"
+ id="linearGradient2405"
+ xlink:href="#linearGradient3718"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9947644,0,0,1.3346457,2.7877039,-166.60153)" />
+ <linearGradient
+ x1="518.26996"
+ y1="497.31476"
+ x2="533.02924"
+ y2="497.31476"
+ id="linearGradient2407"
+ xlink:href="#linearGradient3708"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <g
+ transform="translate(-128.69958,6.6568748)"
+ id="torpedo">
+ <g
+ transform="matrix(0.8830571,0,0,0.8830571,-119.78327,177.67947)"
+ id="g3525">
+ <path
+ d="M 523.9661,469.73706 A 7.7781744,34.648232 0 1 1 508.40975,469.73706 A 7.7781744,34.648232 0 1 1 523.9661,469.73706 z"
+ id="path3682"
+ style="opacity:1;fill:url(#linearGradient2403);fill-opacity:1;fill-rule:nonzero;stroke:#272727;stroke-width:2.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <g
+ id="g3754">
+ <rect
+ width="33.58757"
+ height="59.927299"
+ x="498.86386"
+ y="497.84454"
+ id="rect3716"
+ style="opacity:1;fill:url(#linearGradient2405);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 523.35045,482.89424 C 523.35045,482.89424 532.31256,488.20203 532.02344,500.14638 C 531.73431,512.09072 531.73431,511.73417 531.73431,511.73417 C 531.73431,511.73417 520.70627,493.83104 519.26887,499.77636 L 523.35045,482.89424 z"
+ id="path3704"
+ style="fill:url(#linearGradient2407);fill-opacity:1;fill-rule:evenodd;stroke:#1f1f1f;stroke-width:1.99788344;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ d="M 508.50327,482.89424 C 508.50327,482.89424 499.54116,488.20203 499.83028,500.14638 C 500.11941,512.09072 500.11941,511.73417 500.11941,511.73417 C 500.11941,511.73417 511.14745,493.83104 512.58485,499.77636 L 508.50327,482.89424 z"
+ id="path3706"
+ style="fill:#bcbcbc;fill-opacity:1;fill-rule:evenodd;stroke:#1f1f1f;stroke-width:1.99788344;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/examples/widgets/animation/sub-attaq/pics/small/background.png b/examples/widgets/animation/sub-attaq/pics/small/background.png
new file mode 100644
index 0000000000..5ad3db660a
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/small/background.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/small/boat.png b/examples/widgets/animation/sub-attaq/pics/small/boat.png
new file mode 100644
index 0000000000..114ccc310e
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/small/boat.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/small/bomb.png b/examples/widgets/animation/sub-attaq/pics/small/bomb.png
new file mode 100644
index 0000000000..3af5f2f29c
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/small/bomb.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/small/submarine.png b/examples/widgets/animation/sub-attaq/pics/small/submarine.png
new file mode 100644
index 0000000000..0c0c350600
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/small/submarine.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/small/surface.png b/examples/widgets/animation/sub-attaq/pics/small/surface.png
new file mode 100644
index 0000000000..06d0e47a5c
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/small/surface.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/small/torpedo.png b/examples/widgets/animation/sub-attaq/pics/small/torpedo.png
new file mode 100644
index 0000000000..f9c26873f1
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/small/torpedo.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/welcome/logo-a.png b/examples/widgets/animation/sub-attaq/pics/welcome/logo-a.png
new file mode 100644
index 0000000000..67dd76dac0
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/welcome/logo-a.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/welcome/logo-a2.png b/examples/widgets/animation/sub-attaq/pics/welcome/logo-a2.png
new file mode 100644
index 0000000000..17668b07de
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/welcome/logo-a2.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/welcome/logo-b.png b/examples/widgets/animation/sub-attaq/pics/welcome/logo-b.png
new file mode 100644
index 0000000000..cf6c04560b
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/welcome/logo-b.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/welcome/logo-dash.png b/examples/widgets/animation/sub-attaq/pics/welcome/logo-dash.png
new file mode 100644
index 0000000000..219233ce6b
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/welcome/logo-dash.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/welcome/logo-excl.png b/examples/widgets/animation/sub-attaq/pics/welcome/logo-excl.png
new file mode 100644
index 0000000000..8dd0a2eb86
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/welcome/logo-excl.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/welcome/logo-q.png b/examples/widgets/animation/sub-attaq/pics/welcome/logo-q.png
new file mode 100644
index 0000000000..86e588d4d8
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/welcome/logo-q.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/welcome/logo-s.png b/examples/widgets/animation/sub-attaq/pics/welcome/logo-s.png
new file mode 100644
index 0000000000..7b6a36e93a
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/welcome/logo-s.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/welcome/logo-t.png b/examples/widgets/animation/sub-attaq/pics/welcome/logo-t.png
new file mode 100644
index 0000000000..b2e3526bea
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/welcome/logo-t.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/welcome/logo-t2.png b/examples/widgets/animation/sub-attaq/pics/welcome/logo-t2.png
new file mode 100644
index 0000000000..b11a77886e
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/welcome/logo-t2.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pics/welcome/logo-u.png b/examples/widgets/animation/sub-attaq/pics/welcome/logo-u.png
new file mode 100644
index 0000000000..24eede887a
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pics/welcome/logo-u.png
Binary files differ
diff --git a/examples/widgets/animation/sub-attaq/pixmapitem.cpp b/examples/widgets/animation/sub-attaq/pixmapitem.cpp
new file mode 100644
index 0000000000..077151d708
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pixmapitem.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+//Own
+#include "pixmapitem.h"
+
+//Qt
+#include <QPainter>
+
+PixmapItem::PixmapItem(const QString &fileName,GraphicsScene::Mode mode, QGraphicsItem * parent) : QGraphicsObject(parent)
+{
+ if (mode == GraphicsScene::Big)
+ pix = QPixmap(QStringLiteral(":/big/") + fileName);
+ else
+ pix = QPixmap(QStringLiteral(":/small/") + fileName);
+}
+
+PixmapItem::PixmapItem(const QString &fileName, QGraphicsScene *scene) : QGraphicsObject(), pix(fileName)
+{
+ scene->addItem(this);
+}
+
+QSizeF PixmapItem::size() const
+{
+ return pix.size();
+}
+
+QRectF PixmapItem::boundingRect() const
+{
+ return QRectF(QPointF(0, 0), pix.size());
+}
+
+void PixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+{
+ painter->drawPixmap(0, 0, pix);
+}
+
+
diff --git a/examples/widgets/animation/sub-attaq/pixmapitem.h b/examples/widgets/animation/sub-attaq/pixmapitem.h
new file mode 100644
index 0000000000..0a3b1287c7
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/pixmapitem.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef __PIXMAPITEM__H__
+#define __PIXMAPITEM__H__
+
+//Own
+#include "graphicsscene.h"
+
+//Qt
+#include <QtWidgets/QGraphicsObject>
+
+class PixmapItem : public QGraphicsObject
+{
+public:
+ PixmapItem(const QString &fileName, GraphicsScene::Mode mode, QGraphicsItem * parent = 0);
+ PixmapItem(const QString &fileName, QGraphicsScene *scene);
+ QSizeF size() const;
+ QRectF boundingRect() const;
+ void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
+private:
+ QPixmap pix;
+};
+
+#endif //__PIXMAPITEM__H__
diff --git a/examples/widgets/animation/sub-attaq/progressitem.cpp b/examples/widgets/animation/sub-attaq/progressitem.cpp
new file mode 100644
index 0000000000..bad9ceb471
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/progressitem.cpp
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+#include "progressitem.h"
+#include "pixmapitem.h"
+
+ProgressItem::ProgressItem (QGraphicsItem * parent)
+ : QGraphicsTextItem(parent), currentLevel(1), currentScore(0)
+{
+ setFont(QFont("Comic Sans MS"));
+ setPos(parentItem()->boundingRect().topRight() - QPointF(180, -5));
+}
+
+void ProgressItem::setLevel(int level)
+{
+ currentLevel = level;
+ updateProgress();
+}
+
+void ProgressItem::setScore(int score)
+{
+ currentScore = score;
+ updateProgress();
+}
+
+void ProgressItem::updateProgress()
+{
+ setHtml(QString("Level : %1 Score : %2").arg(currentLevel).arg(currentScore));
+}
diff --git a/examples/widgets/animation/sub-attaq/progressitem.h b/examples/widgets/animation/sub-attaq/progressitem.h
new file mode 100644
index 0000000000..dc6d7ba6bc
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/progressitem.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef PROGRESSITEM_H
+#define PROGRESSITEM_H
+
+//Qt
+#include <QtWidgets/QGraphicsTextItem>
+
+class ProgressItem : public QGraphicsTextItem
+{
+public:
+ ProgressItem(QGraphicsItem * parent = 0);
+ void setLevel(int level);
+ void setScore(int score);
+
+private:
+ void updateProgress();
+ int currentLevel;
+ int currentScore;
+};
+
+#endif // PROGRESSITEM_H
diff --git a/examples/widgets/animation/sub-attaq/qanimationstate.cpp b/examples/widgets/animation/sub-attaq/qanimationstate.cpp
new file mode 100644
index 0000000000..b122acc858
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/qanimationstate.cpp
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qanimationstate.h"
+
+#include <QtCore/qstate.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+\class QAnimationState
+
+\brief The QAnimationState class provides state that handle an animation and emit
+a signal when this animation is finished.
+
+\ingroup statemachine
+
+QAnimationState provides a state that handle an animation. It will start this animation
+when the state is entered and stop it when it is leaved. When the animation has finished the
+state emit animationFinished signal.
+QAnimationState is part of \l{The State Machine Framework}.
+
+\code
+QStateMachine machine;
+QAnimationState *s = new QAnimationState(machine->rootState());
+QPropertyAnimation *animation = new QPropertyAnimation(obj, "pos");
+s->setAnimation(animation);
+QState *s2 = new QState(machine->rootState());
+s->addTransition(s, SIGNAL(animationFinished()), s2);
+machine.start();
+\endcode
+
+\sa QState, {The Animation Framework}
+*/
+
+
+#ifndef QT_NO_ANIMATION
+
+/*!
+ Constructs a new state with the given \a parent state.
+*/
+QAnimationState::QAnimationState(QState *parent)
+ : QState(parent), m_animation(0)
+{
+}
+
+/*!
+ Destroys the animation state.
+*/
+QAnimationState::~QAnimationState()
+{
+}
+
+/*!
+ Set an \a animation for this QAnimationState. If an animation was previously handle by this
+ state then it won't emit animationFinished for the old animation. The QAnimationState doesn't
+ take the ownership of the animation.
+*/
+void QAnimationState::setAnimation(QAbstractAnimation *animation)
+{
+ if (animation == m_animation)
+ return;
+
+ //Disconnect from the previous animation if exist
+ if(m_animation)
+ disconnect(m_animation, SIGNAL(finished()), this, SIGNAL(animationFinished()));
+
+ m_animation = animation;
+
+ if (m_animation) {
+ //connect the new animation
+ connect(m_animation, SIGNAL(finished()), this, SIGNAL(animationFinished()));
+ }
+}
+
+/*!
+ Returns the animation handle by this animation state, or 0 if there is no animation.
+*/
+QAbstractAnimation* QAnimationState::animation() const
+{
+ return m_animation;
+}
+
+/*!
+ \reimp
+*/
+void QAnimationState::onEntry(QEvent *)
+{
+ if (m_animation)
+ m_animation->start();
+}
+
+/*!
+ \reimp
+*/
+void QAnimationState::onExit(QEvent *)
+{
+ if (m_animation)
+ m_animation->stop();
+}
+
+/*!
+ \reimp
+*/
+bool QAnimationState::event(QEvent *e)
+{
+ return QState::event(e);
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/examples/widgets/animation/sub-attaq/qanimationstate.h b/examples/widgets/animation/sub-attaq/qanimationstate.h
new file mode 100644
index 0000000000..2672f640e4
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/qanimationstate.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef QANIMATIONSTATE_H
+#define QANIMATIONSTATE_H
+
+#ifndef QT_STATEMACHINE_SOLUTION
+# include <QtCore/qstate.h>
+# include <QtCore/qabstractanimation.h>
+#else
+# include "qstate.h"
+# include "qabstractanimation.h"
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+
+#ifndef QT_NO_ANIMATION
+
+class QAbstractAnimation;
+
+class QAnimationState : public QState
+{
+ Q_OBJECT
+public:
+ QAnimationState(QState *parent = 0);
+ ~QAnimationState();
+
+ void setAnimation(QAbstractAnimation *animation);
+ QAbstractAnimation* animation() const;
+
+signals:
+ void animationFinished();
+
+protected:
+ void onEntry(QEvent *);
+ void onExit(QEvent *);
+ bool event(QEvent *e);
+
+private:
+ Q_DISABLE_COPY(QAnimationState)
+ QAbstractAnimation *m_animation;
+};
+
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QANIMATIONSTATE_H
diff --git a/examples/widgets/animation/sub-attaq/states.cpp b/examples/widgets/animation/sub-attaq/states.cpp
new file mode 100644
index 0000000000..32ad218693
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/states.cpp
@@ -0,0 +1,330 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+//Own
+#include "states.h"
+#include "graphicsscene.h"
+#include "boat.h"
+#include "submarine.h"
+#include "torpedo.h"
+#include "animationmanager.h"
+#include "progressitem.h"
+#include "textinformationitem.h"
+
+//Qt
+#include <QtWidgets/QMessageBox>
+#include <QtWidgets/QGraphicsView>
+#include <QtCore/QStateMachine>
+#include <QtWidgets/QKeyEventTransition>
+#include <QtCore/QFinalState>
+
+PlayState::PlayState(GraphicsScene *scene, QState *parent)
+ : QState(parent),
+ scene(scene),
+ machine(0),
+ currentLevel(0),
+ score(0)
+{
+}
+
+PlayState::~PlayState()
+{
+ delete machine;
+}
+
+void PlayState::onEntry(QEvent *)
+{
+ //We are now playing?
+ if (machine) {
+ machine->stop();
+ //we hide the information
+ scene->textInformationItem->hide();
+ scene->clearScene();
+ currentLevel = 0;
+ score = 0;
+ delete machine;
+ }
+
+ machine = new QStateMachine;
+
+ //This state is when player is playing
+ LevelState *levelState = new LevelState(scene, this, machine);
+
+ //This state is when the player is actually playing but the game is not paused
+ QState *playingState = new QState(levelState);
+ levelState->setInitialState(playingState);
+
+ //This state is when the game is paused
+ PauseState *pauseState = new PauseState(scene, levelState);
+
+ //We have one view, it receive the key press event
+ QKeyEventTransition *pressPplay = new QKeyEventTransition(scene->views().at(0), QEvent::KeyPress, Qt::Key_P);
+ pressPplay->setTargetState(pauseState);
+ QKeyEventTransition *pressPpause = new QKeyEventTransition(scene->views().at(0), QEvent::KeyPress, Qt::Key_P);
+ pressPpause->setTargetState(playingState);
+
+ //Pause "P" is triggered, the player pause the game
+ playingState->addTransition(pressPplay);
+
+ //To get back playing when the game has been paused
+ pauseState->addTransition(pressPpause);
+
+ //This state is when player have lost
+ LostState *lostState = new LostState(scene, this, machine);
+
+ //This state is when player have won
+ WinState *winState = new WinState(scene, this, machine);
+
+ //The boat has been destroyed then the game is finished
+ levelState->addTransition(scene->boat, SIGNAL(boatExecutionFinished()),lostState);
+
+ //This transition check if we won or not
+ WinTransition *winTransition = new WinTransition(scene, this, winState);
+
+ //The boat has been destroyed then the game is finished
+ levelState->addTransition(winTransition);
+
+ //This state is an animation when the score changed
+ UpdateScoreState *scoreState = new UpdateScoreState(this, levelState);
+
+ //This transition update the score when a submarine die
+ UpdateScoreTransition *scoreTransition = new UpdateScoreTransition(scene, this, levelState);
+ scoreTransition->setTargetState(scoreState);
+
+ //The boat has been destroyed then the game is finished
+ playingState->addTransition(scoreTransition);
+
+ //We go back to play state
+ scoreState->addTransition(playingState);
+
+ //We start playing!!!
+ machine->setInitialState(levelState);
+
+ //Final state
+ QFinalState *final = new QFinalState(machine);
+
+ //This transition is triggered when the player press space after completing a level
+ CustomSpaceTransition *spaceTransition = new CustomSpaceTransition(scene->views().at(0), this, QEvent::KeyPress, Qt::Key_Space);
+ spaceTransition->setTargetState(levelState);
+ winState->addTransition(spaceTransition);
+
+ //We lost we should reach the final state
+ lostState->addTransition(lostState, SIGNAL(finished()), final);
+
+ machine->start();
+}
+
+LevelState::LevelState(GraphicsScene *scene, PlayState *game, QState *parent) : QState(parent), scene(scene), game(game)
+{
+}
+void LevelState::onEntry(QEvent *)
+{
+ initializeLevel();
+}
+
+void LevelState::initializeLevel()
+{
+ //we re-init the boat
+ scene->boat->setPos(scene->width()/2, scene->sealLevel() - scene->boat->size().height());
+ scene->boat->setCurrentSpeed(0);
+ scene->boat->setCurrentDirection(Boat::None);
+ scene->boat->setBombsLaunched(0);
+ scene->boat->show();
+ scene->setFocusItem(scene->boat, Qt::OtherFocusReason);
+ scene->boat->run();
+
+ scene->progressItem->setScore(game->score);
+ scene->progressItem->setLevel(game->currentLevel + 1);
+
+ GraphicsScene::LevelDescription currentLevelDescription = scene->levelsData.value(game->currentLevel);
+
+ for (int i = 0; i < currentLevelDescription.submarines.size(); ++i ) {
+
+ QPair<int,int> subContent = currentLevelDescription.submarines.at(i);
+ GraphicsScene::SubmarineDescription submarineDesc = scene->submarinesData.at(subContent.first);
+
+ for (int j = 0; j < subContent.second; ++j ) {
+ SubMarine *sub = new SubMarine(submarineDesc.type, submarineDesc.name, submarineDesc.points);
+ scene->addItem(sub);
+ int random = (qrand() % 15 + 1);
+ qreal x = random == 13 || random == 5 ? 0 : scene->width() - sub->size().width();
+ qreal y = scene->height() -(qrand() % 150 + 1) - sub->size().height();
+ sub->setPos(x,y);
+ sub->setCurrentDirection(x == 0 ? SubMarine::Right : SubMarine::Left);
+ sub->setCurrentSpeed(qrand() % 3 + 1);
+ }
+ }
+}
+
+/** Pause State */
+PauseState::PauseState(GraphicsScene *scene, QState *parent) : QState(parent),scene(scene)
+{
+}
+void PauseState::onEntry(QEvent *)
+{
+ AnimationManager::self()->pauseAll();
+ scene->boat->setEnabled(false);
+}
+void PauseState::onExit(QEvent *)
+{
+ AnimationManager::self()->resumeAll();
+ scene->boat->setEnabled(true);
+ scene->boat->setFocus();
+}
+
+/** Lost State */
+LostState::LostState(GraphicsScene *scene, PlayState *game, QState *parent) : QState(parent), scene(scene), game(game)
+{
+}
+
+void LostState::onEntry(QEvent *)
+{
+ //The message to display
+ QString message = QString("You lose on level %1. Your score is %2.").arg(game->currentLevel+1).arg(game->score);
+
+ //We set the level back to 0
+ game->currentLevel = 0;
+
+ //We set the score back to 0
+ game->score = 0;
+
+ //We clear the scene
+ scene->clearScene();
+
+ //We inform the player
+ scene->textInformationItem->setMessage(message);
+ scene->textInformationItem->show();
+}
+
+void LostState::onExit(QEvent *)
+{
+ //we hide the information
+ scene->textInformationItem->hide();
+}
+
+/** Win State */
+WinState::WinState(GraphicsScene *scene, PlayState *game, QState *parent) : QState(parent), scene(scene), game(game)
+{
+}
+
+void WinState::onEntry(QEvent *)
+{
+ //We clear the scene
+ scene->clearScene();
+
+ QString message;
+ if (scene->levelsData.size() - 1 != game->currentLevel) {
+ message = QString("You win the level %1. Your score is %2.\nPress Space to continue.").arg(game->currentLevel+1).arg(game->score);
+ //We increment the level number
+ game->currentLevel++;
+ } else {
+ message = QString("You finish the game on level %1. Your score is %2.").arg(game->currentLevel+1).arg(game->score);
+ //We set the level back to 0
+ game->currentLevel = 0;
+ //We set the score back to 0
+ game->score = 0;
+ }
+
+ //We inform the player
+ scene->textInformationItem->setMessage(message);
+ scene->textInformationItem->show();
+}
+
+void WinState::onExit(QEvent *)
+{
+ //we hide the information
+ scene->textInformationItem->hide();
+}
+
+/** UpdateScore State */
+UpdateScoreState::UpdateScoreState(PlayState *g, QState *parent) : QState(parent), game(g)
+{
+}
+
+/** Win transition */
+UpdateScoreTransition::UpdateScoreTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target)
+ : QSignalTransition(scene,SIGNAL(subMarineDestroyed(int))),
+ game(game), scene(scene)
+{
+ setTargetState(target);
+}
+
+bool UpdateScoreTransition::eventTest(QEvent *event)
+{
+ if (!QSignalTransition::eventTest(event))
+ return false;
+ QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent*>(event);
+ game->score += se->arguments().at(0).toInt();
+ scene->progressItem->setScore(game->score);
+ return true;
+}
+
+/** Win transition */
+WinTransition::WinTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target)
+ : QSignalTransition(scene,SIGNAL(allSubMarineDestroyed(int))),
+ game(game), scene(scene)
+{
+ setTargetState(target);
+}
+
+bool WinTransition::eventTest(QEvent *event)
+{
+ if (!QSignalTransition::eventTest(event))
+ return false;
+ QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent*>(event);
+ game->score += se->arguments().at(0).toInt();
+ scene->progressItem->setScore(game->score);
+ return true;
+}
+
+/** Space transition */
+CustomSpaceTransition::CustomSpaceTransition(QWidget *widget, PlayState *game, QEvent::Type type, int key)
+ : QKeyEventTransition(widget, type, key),
+ game(game)
+{
+}
+
+bool CustomSpaceTransition::eventTest(QEvent *event)
+{
+ if (!QKeyEventTransition::eventTest(event))
+ return false;
+ return (game->currentLevel != 0);
+}
diff --git a/examples/widgets/animation/sub-attaq/states.h b/examples/widgets/animation/sub-attaq/states.h
new file mode 100644
index 0000000000..e43370302c
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/states.h
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef STATES_H
+#define STATES_H
+
+//Qt
+#include <QtCore/QState>
+#include <QtCore/QSignalTransition>
+#include <QtCore/QPropertyAnimation>
+#include <QtWidgets/QKeyEventTransition>
+#include <QtCore/QSet>
+
+class GraphicsScene;
+class Boat;
+class SubMarine;
+QT_BEGIN_NAMESPACE
+class QStateMachine;
+QT_END_NAMESPACE
+
+class PlayState : public QState
+{
+public:
+ PlayState(GraphicsScene *scene, QState *parent = 0);
+ ~PlayState();
+
+ protected:
+ void onEntry(QEvent *);
+
+private :
+ GraphicsScene *scene;
+ QStateMachine *machine;
+ int currentLevel;
+ int score;
+ QState *parallelChild;
+
+ friend class UpdateScoreState;
+ friend class UpdateScoreTransition;
+ friend class WinTransition;
+ friend class CustomSpaceTransition;
+ friend class WinState;
+ friend class LostState;
+ friend class LevelState;
+};
+
+class LevelState : public QState
+{
+public:
+ LevelState(GraphicsScene *scene, PlayState *game, QState *parent = 0);
+protected:
+ void onEntry(QEvent *);
+private :
+ void initializeLevel();
+ GraphicsScene *scene;
+ PlayState *game;
+};
+
+class PauseState : public QState
+{
+public:
+ PauseState(GraphicsScene *scene, QState *parent = 0);
+
+protected:
+ void onEntry(QEvent *);
+ void onExit(QEvent *);
+private :
+ GraphicsScene *scene;
+ Boat *boat;
+};
+
+class LostState : public QState
+{
+public:
+ LostState(GraphicsScene *scene, PlayState *game, QState *parent = 0);
+
+protected:
+ void onEntry(QEvent *);
+ void onExit(QEvent *);
+private :
+ GraphicsScene *scene;
+ PlayState *game;
+};
+
+class WinState : public QState
+{
+public:
+ WinState(GraphicsScene *scene, PlayState *game, QState *parent = 0);
+
+protected:
+ void onEntry(QEvent *);
+ void onExit(QEvent *);
+private :
+ GraphicsScene *scene;
+ PlayState *game;
+};
+
+class UpdateScoreState : public QState
+{
+public:
+ UpdateScoreState(PlayState *game, QState *parent);
+private:
+ QPropertyAnimation *scoreAnimation;
+ PlayState *game;
+};
+
+//These transtion is used to update the score
+class UpdateScoreTransition : public QSignalTransition
+{
+public:
+ UpdateScoreTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target);
+protected:
+ virtual bool eventTest(QEvent *event);
+private:
+ PlayState * game;
+ GraphicsScene *scene;
+};
+
+//These transtion test if we have won the game
+class WinTransition : public QSignalTransition
+{
+public:
+ WinTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target);
+protected:
+ virtual bool eventTest(QEvent *event);
+private:
+ PlayState * game;
+ GraphicsScene *scene;
+};
+
+//These transtion is true if one level has been completed and the player want to continue
+ class CustomSpaceTransition : public QKeyEventTransition
+{
+public:
+ CustomSpaceTransition(QWidget *widget, PlayState *game, QEvent::Type type, int key);
+protected:
+ virtual bool eventTest(QEvent *event);
+private:
+ PlayState *game;
+ int key;
+};
+
+#endif // STATES_H
diff --git a/examples/widgets/animation/sub-attaq/sub-attaq.pro b/examples/widgets/animation/sub-attaq/sub-attaq.pro
new file mode 100644
index 0000000000..6d9b3195ac
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/sub-attaq.pro
@@ -0,0 +1,42 @@
+QT += widgets
+contains(QT_CONFIG, opengl):QT += opengl
+HEADERS += boat.h \
+ bomb.h \
+ mainwindow.h \
+ submarine.h \
+ torpedo.h \
+ pixmapitem.h \
+ graphicsscene.h \
+ animationmanager.h \
+ states.h \
+ boat_p.h \
+ submarine_p.h \
+ qanimationstate.h \
+ progressitem.h \
+ textinformationitem.h
+SOURCES += boat.cpp \
+ bomb.cpp \
+ main.cpp \
+ mainwindow.cpp \
+ submarine.cpp \
+ torpedo.cpp \
+ pixmapitem.cpp \
+ graphicsscene.cpp \
+ animationmanager.cpp \
+ states.cpp \
+ qanimationstate.cpp \
+ progressitem.cpp \
+ textinformationitem.cpp
+RESOURCES += subattaq.qrc
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/animation/sub-attaq
+sources.files = $$SOURCES \
+ $$HEADERS \
+ $$RESOURCES \
+ $$FORMS \
+ sub-attaq.pro \
+ pics
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/animation/sub-attaq
+INSTALLS += target \
+ sources
diff --git a/examples/widgets/animation/sub-attaq/subattaq.qrc b/examples/widgets/animation/sub-attaq/subattaq.qrc
new file mode 100644
index 0000000000..80a3af11cc
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/subattaq.qrc
@@ -0,0 +1,39 @@
+<RCC>
+ <qresource prefix="/" >
+ <file alias="all" >pics/scalable/sub-attaq.svg</file>
+ <file alias="submarine" >pics/scalable/submarine.svg</file>
+ <file alias="boat" >pics/scalable/boat.svg</file>
+ <file alias="torpedo" >pics/scalable/torpedo.svg</file>
+ <file alias="logo-s" >pics/welcome/logo-s.png</file>
+ <file alias="logo-u" >pics/welcome/logo-u.png</file>
+ <file alias="logo-b" >pics/welcome/logo-b.png</file>
+ <file alias="logo-dash" >pics/welcome/logo-dash.png</file>
+ <file alias="logo-a" >pics/welcome/logo-a.png</file>
+ <file alias="logo-t" >pics/welcome/logo-t.png</file>
+ <file alias="logo-t2" >pics/welcome/logo-t2.png</file>
+ <file alias="logo-a2" >pics/welcome/logo-a2.png</file>
+ <file alias="logo-q" >pics/welcome/logo-q.png</file>
+ <file alias="logo-excl" >pics/welcome/logo-excl.png</file>
+ <file alias="big/background" >pics/big/background.png</file>
+ <file alias="big/boat" >pics/big/boat.png</file>
+ <file alias="big/bomb" >pics/big/bomb.png</file>
+ <file alias="big/submarine" >pics/big/submarine.png</file>
+ <file alias="big/surface" >pics/big/surface.png</file>
+ <file alias="big/torpedo" >pics/big/torpedo.png</file>
+ <file alias="small/background" >pics/small/background.png</file>
+ <file alias="small/boat" >pics/small/boat.png</file>
+ <file alias="small/bomb" >pics/small/bomb.png</file>
+ <file alias="small/submarine" >pics/small/submarine.png</file>
+ <file alias="small/surface" >pics/small/surface.png</file>
+ <file alias="small/torpedo" >pics/small/torpedo.png</file>
+ <file alias="big/explosion/boat/step1" >pics/big/explosion/boat/step1.png</file>
+ <file alias="big/explosion/boat/step2" >pics/big/explosion/boat/step2.png</file>
+ <file alias="big/explosion/boat/step3" >pics/big/explosion/boat/step3.png</file>
+ <file alias="big/explosion/boat/step4" >pics/big/explosion/boat/step4.png</file>
+ <file alias="big/explosion/submarine/step1" >pics/big/explosion/submarine/step1.png</file>
+ <file alias="big/explosion/submarine/step2" >pics/big/explosion/submarine/step2.png</file>
+ <file alias="big/explosion/submarine/step3" >pics/big/explosion/submarine/step3.png</file>
+ <file alias="big/explosion/submarine/step4" >pics/big/explosion/submarine/step4.png</file>
+ <file>data.xml</file>
+ </qresource>
+</RCC>
diff --git a/examples/widgets/animation/sub-attaq/submarine.cpp b/examples/widgets/animation/sub-attaq/submarine.cpp
new file mode 100644
index 0000000000..68eaf7ef38
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/submarine.cpp
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+//Own
+#include "submarine.h"
+#include "submarine_p.h"
+#include "torpedo.h"
+#include "pixmapitem.h"
+#include "graphicsscene.h"
+#include "animationmanager.h"
+#include "qanimationstate.h"
+
+#include <QtCore/QPropertyAnimation>
+#include <QtCore/QStateMachine>
+#include <QtCore/QFinalState>
+#include <QtCore/QSequentialAnimationGroup>
+
+static QAbstractAnimation *setupDestroyAnimation(SubMarine *sub)
+{
+ QSequentialAnimationGroup *group = new QSequentialAnimationGroup(sub);
+ for (int i = 1; i <= 4; ++i) {
+ PixmapItem *step = new PixmapItem(QString::fromLatin1("explosion/submarine/step%1").arg(i), GraphicsScene::Big, sub);
+ step->setZValue(6);
+ step->setOpacity(0);
+ QPropertyAnimation *anim = new QPropertyAnimation(step, "opacity", group);
+ anim->setDuration(100);
+ anim->setEndValue(1);
+ }
+ AnimationManager::self()->registerAnimation(group);
+ return group;
+}
+
+
+SubMarine::SubMarine(int type, const QString &name, int points) : PixmapItem(QString("submarine"), GraphicsScene::Big),
+ subType(type), subName(name), subPoints(points), speed(0), direction(SubMarine::None)
+{
+ setZValue(5);
+ setTransformOriginPoint(boundingRect().center());
+
+ graphicsRotation = new QGraphicsRotation(this);
+ graphicsRotation->setAxis(Qt::YAxis);
+ graphicsRotation->setOrigin(QVector3D(size().width()/2, size().height()/2, 0));
+ QList<QGraphicsTransform *> r;
+ r.append(graphicsRotation);
+ setTransformations(r);
+
+ //We setup the state machine of the submarine
+ QStateMachine *machine = new QStateMachine(this);
+
+ //This state is when the boat is moving/rotating
+ QState *moving = new QState(machine);
+
+ //This state is when the boat is moving from left to right
+ MovementState *movement = new MovementState(this, moving);
+
+ //This state is when the boat is moving from left to right
+ ReturnState *rotation = new ReturnState(this, moving);
+
+ //This is the initial state of the moving root state
+ moving->setInitialState(movement);
+
+ movement->addTransition(this, SIGNAL(subMarineStateChanged()), moving);
+
+ //This is the initial state of the machine
+ machine->setInitialState(moving);
+
+ //End
+ QFinalState *final = new QFinalState(machine);
+
+ //If the moving animation is finished we move to the return state
+ movement->addTransition(movement, SIGNAL(animationFinished()), rotation);
+
+ //If the return animation is finished we move to the moving state
+ rotation->addTransition(rotation, SIGNAL(animationFinished()), movement);
+
+ //This state play the destroyed animation
+ QAnimationState *destroyedState = new QAnimationState(machine);
+ destroyedState->setAnimation(setupDestroyAnimation(this));
+
+ //Play a nice animation when the submarine is destroyed
+ moving->addTransition(this, SIGNAL(subMarineDestroyed()), destroyedState);
+
+ //Transition to final state when the destroyed animation is finished
+ destroyedState->addTransition(destroyedState, SIGNAL(animationFinished()), final);
+
+ //The machine has finished to be executed, then the submarine is dead
+ connect(machine,SIGNAL(finished()),this, SIGNAL(subMarineExecutionFinished()));
+
+ machine->start();
+}
+
+int SubMarine::points() const
+{
+ return subPoints;
+}
+
+void SubMarine::setCurrentDirection(SubMarine::Movement direction)
+{
+ if (this->direction == direction)
+ return;
+ if (direction == SubMarine::Right && this->direction == SubMarine::None) {
+ graphicsRotation->setAngle(180);
+ }
+ this->direction = direction;
+}
+
+enum SubMarine::Movement SubMarine::currentDirection() const
+{
+ return direction;
+}
+
+void SubMarine::setCurrentSpeed(int speed)
+{
+ if (speed < 0 || speed > 3) {
+ qWarning("SubMarine::setCurrentSpeed : The speed is invalid");
+ }
+ this->speed = speed;
+ emit subMarineStateChanged();
+}
+
+int SubMarine::currentSpeed() const
+{
+ return speed;
+}
+
+void SubMarine::launchTorpedo(int speed)
+{
+ Torpedo * torp = new Torpedo();
+ GraphicsScene *scene = static_cast<GraphicsScene *>(this->scene());
+ scene->addItem(torp);
+ torp->setPos(pos());
+ torp->setCurrentSpeed(speed);
+ torp->launch();
+}
+
+void SubMarine::destroy()
+{
+ emit subMarineDestroyed();
+}
+
+int SubMarine::type() const
+{
+ return Type;
+}
diff --git a/examples/widgets/animation/sub-attaq/submarine.h b/examples/widgets/animation/sub-attaq/submarine.h
new file mode 100644
index 0000000000..b113bc8797
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/submarine.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef __SUBMARINE__H__
+#define __SUBMARINE__H__
+
+//Qt
+#include <QtWidgets/QGraphicsTransform>
+
+#include "pixmapitem.h"
+
+class Torpedo;
+
+class SubMarine : public PixmapItem
+{
+Q_OBJECT
+public:
+ enum Movement {
+ None = 0,
+ Left,
+ Right
+ };
+ enum { Type = UserType + 1 };
+ SubMarine(int type, const QString &name, int points);
+
+ int points() const;
+
+ void setCurrentDirection(Movement direction);
+ enum Movement currentDirection() const;
+
+ void setCurrentSpeed(int speed);
+ int currentSpeed() const;
+
+ void launchTorpedo(int speed);
+ void destroy();
+
+ virtual int type() const;
+
+ QGraphicsRotation *rotation() const { return graphicsRotation; }
+
+signals:
+ void subMarineDestroyed();
+ void subMarineExecutionFinished();
+ void subMarineStateChanged();
+
+private:
+ int subType;
+ QString subName;
+ int subPoints;
+ int speed;
+ Movement direction;
+ QGraphicsRotation *graphicsRotation;
+};
+
+#endif //__SUBMARINE__H__
diff --git a/examples/widgets/animation/sub-attaq/submarine_p.h b/examples/widgets/animation/sub-attaq/submarine_p.h
new file mode 100644
index 0000000000..f24487aa17
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/submarine_p.h
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef SUBMARINE_P_H
+#define SUBMARINE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+//Own
+#include "animationmanager.h"
+#include "submarine.h"
+#include "qanimationstate.h"
+
+//Qt
+#include <QtCore/QPropertyAnimation>
+#include <QtWidgets/QGraphicsScene>
+
+//This state is describing when the boat is moving right
+class MovementState : public QAnimationState
+{
+Q_OBJECT
+public:
+ MovementState(SubMarine *submarine, QState *parent = 0) : QAnimationState(parent)
+ {
+ movementAnimation = new QPropertyAnimation(submarine, "pos");
+ connect(movementAnimation,SIGNAL(valueChanged(const QVariant &)),this,SLOT(onAnimationMovementValueChanged(const QVariant &)));
+ setAnimation(movementAnimation);
+ AnimationManager::self()->registerAnimation(movementAnimation);
+ this->submarine = submarine;
+ }
+
+protected slots:
+ void onAnimationMovementValueChanged(const QVariant &)
+ {
+ if (qrand() % 200 + 1 == 3)
+ submarine->launchTorpedo(qrand() % 3 + 1);
+ }
+
+protected:
+ void onEntry(QEvent *e)
+ {
+ if (submarine->currentDirection() == SubMarine::Left) {
+ movementAnimation->setEndValue(QPointF(0,submarine->y()));
+ movementAnimation->setDuration(submarine->x()/submarine->currentSpeed()*12);
+ }
+ else /*if (submarine->currentDirection() == SubMarine::Right)*/ {
+ movementAnimation->setEndValue(QPointF(submarine->scene()->width()-submarine->size().width(),submarine->y()));
+ movementAnimation->setDuration((submarine->scene()->width()-submarine->size().width()-submarine->x())/submarine->currentSpeed()*12);
+ }
+ QAnimationState::onEntry(e);
+ }
+
+private:
+ SubMarine *submarine;
+ QPropertyAnimation *movementAnimation;
+};
+
+//This state is describing when the boat is moving right
+class ReturnState : public QAnimationState
+{
+public:
+ ReturnState(SubMarine *submarine, QState *parent = 0) : QAnimationState(parent)
+ {
+ returnAnimation = new QPropertyAnimation(submarine->rotation(), "angle");
+ returnAnimation->setDuration(500);
+ AnimationManager::self()->registerAnimation(returnAnimation);
+ setAnimation(returnAnimation);
+ this->submarine = submarine;
+ }
+
+protected:
+ void onEntry(QEvent *e)
+ {
+ returnAnimation->stop();
+ returnAnimation->setEndValue(submarine->currentDirection() == SubMarine::Right ? 360. : 180.);
+ QAnimationState::onEntry(e);
+ }
+
+ void onExit(QEvent *e)
+ {
+ submarine->currentDirection() == SubMarine::Right ? submarine->setCurrentDirection(SubMarine::Left) : submarine->setCurrentDirection(SubMarine::Right);
+ QAnimationState::onExit(e);
+ }
+
+private:
+ SubMarine *submarine;
+ QPropertyAnimation *returnAnimation;
+};
+
+#endif // SUBMARINE_P_H
diff --git a/examples/widgets/animation/sub-attaq/textinformationitem.cpp b/examples/widgets/animation/sub-attaq/textinformationitem.cpp
new file mode 100644
index 0000000000..ce2e297287
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/textinformationitem.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+#include "textinformationitem.h"
+#include "pixmapitem.h"
+
+TextInformationItem::TextInformationItem (QGraphicsItem * parent)
+ : QGraphicsTextItem(parent)
+{
+ setFont(QFont("Comic Sans MS", 15));
+}
+#include <QDebug>
+void TextInformationItem::setMessage(const QString& text)
+{
+ setHtml(text);
+ setPos(parentItem()->boundingRect().center().x() - boundingRect().size().width()/2 , parentItem()->boundingRect().center().y());
+}
diff --git a/examples/widgets/animation/sub-attaq/textinformationitem.h b/examples/widgets/animation/sub-attaq/textinformationitem.h
new file mode 100644
index 0000000000..adad8be90b
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/textinformationitem.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef TEXTINFORMATIONITEM_H
+#define TEXTINFORMATIONITEM_H
+
+//Qt
+#include <QtWidgets/QGraphicsTextItem>
+
+class TextInformationItem : public QGraphicsTextItem
+{
+public:
+ TextInformationItem(QGraphicsItem * parent = 0);
+ void setMessage(const QString& text);
+};
+
+#endif // TEXTINFORMATIONITEM_H
diff --git a/examples/widgets/animation/sub-attaq/torpedo.cpp b/examples/widgets/animation/sub-attaq/torpedo.cpp
new file mode 100644
index 0000000000..34c32fe059
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/torpedo.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+//Own
+#include "torpedo.h"
+#include "pixmapitem.h"
+#include "boat.h"
+#include "graphicsscene.h"
+#include "animationmanager.h"
+#include "qanimationstate.h"
+
+#include <QtCore/QPropertyAnimation>
+#include <QtCore/QStateMachine>
+#include <QtCore/QFinalState>
+
+Torpedo::Torpedo() : PixmapItem(QString::fromLatin1("torpedo"),GraphicsScene::Big),
+ currentSpeed(0)
+{
+ setZValue(2);
+}
+
+void Torpedo::launch()
+{
+ QPropertyAnimation *launchAnimation = new QPropertyAnimation(this, "pos");
+ AnimationManager::self()->registerAnimation(launchAnimation);
+ launchAnimation->setEndValue(QPointF(x(),qobject_cast<GraphicsScene *>(scene())->sealLevel() - 15));
+ launchAnimation->setEasingCurve(QEasingCurve::InQuad);
+ launchAnimation->setDuration(y()/currentSpeed*10);
+ connect(launchAnimation,SIGNAL(valueChanged(QVariant)),this,SLOT(onAnimationLaunchValueChanged(QVariant)));
+ connect(this,SIGNAL(torpedoExploded()), launchAnimation, SLOT(stop()));
+
+ //We setup the state machine of the torpedo
+ QStateMachine *machine = new QStateMachine(this);
+
+ //This state is when the launch animation is playing
+ QAnimationState *launched = new QAnimationState(machine);
+ launched->setAnimation(launchAnimation);
+
+ //End
+ QFinalState *final = new QFinalState(machine);
+
+ machine->setInitialState(launched);
+
+ //### Add a nice animation when the torpedo is destroyed
+ launched->addTransition(this, SIGNAL(torpedoExploded()),final);
+
+ //If the animation is finished, then we move to the final state
+ launched->addTransition(launched, SIGNAL(animationFinished()), final);
+
+ //The machine has finished to be executed, then the boat is dead
+ connect(machine,SIGNAL(finished()),this, SIGNAL(torpedoExecutionFinished()));
+
+ machine->start();
+}
+
+void Torpedo::setCurrentSpeed(int speed)
+{
+ if (speed < 0) {
+ qWarning("Torpedo::setCurrentSpeed : The speed is invalid");
+ return;
+ }
+ currentSpeed = speed;
+}
+
+void Torpedo::onAnimationLaunchValueChanged(const QVariant &)
+{
+ foreach (QGraphicsItem *item , collidingItems(Qt::IntersectsItemBoundingRect)) {
+ if (Boat *b = qgraphicsitem_cast<Boat*>(item))
+ b->destroy();
+ }
+}
+
+void Torpedo::destroy()
+{
+ emit torpedoExploded();
+}
diff --git a/examples/widgets/animation/sub-attaq/torpedo.h b/examples/widgets/animation/sub-attaq/torpedo.h
new file mode 100644
index 0000000000..59209e3d75
--- /dev/null
+++ b/examples/widgets/animation/sub-attaq/torpedo.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef __TORPEDO__H__
+#define __TORPEDO__H__
+
+#include "pixmapitem.h"
+
+class Torpedo : public PixmapItem
+{
+Q_OBJECT
+public:
+ Torpedo();
+ void launch();
+ void setCurrentSpeed(int speed);
+ void destroy();
+
+signals:
+ void torpedoExploded();
+ void torpedoExecutionFinished();
+
+private slots:
+ void onAnimationLaunchValueChanged(const QVariant &);
+
+private:
+ int currentSpeed;
+};
+
+#endif //__TORPEDO__H__