diff --git a/src/declarative/items/qquickspriteengine_p.h b/src/declarative/items/qquickspriteengine_p.h index 44f82044da..1040140a28 100644 --- a/src/declarative/items/qquickspriteengine_p.h +++ b/src/declarative/items/qquickspriteengine_p.h @@ -212,8 +212,6 @@ class Q_AUTOTEST_EXPORT QQuickStochasticEngine : public QObject int count() const {return m_things.count();} void setCount(int c); - - void setGoal(int state, int sprite=0, bool jump=false); void start(int index=0, int state=0); void stop(int index=0); @@ -221,6 +219,13 @@ class Q_AUTOTEST_EXPORT QQuickStochasticEngine : public QObject QQuickStochasticState* state(int idx){return m_states[idx];} int stateIndex(QQuickStochasticState* s){return m_states.indexOf(s);} + int stateIndex(const QString& s) { + for (int i=0; iname() == s) + return i; + return -1; + } + int stateCount() {return m_states.count();} private: signals: diff --git a/src/declarative/items/qquickspriteimage.cpp b/src/declarative/items/qquickspriteimage.cpp index 36ab73490c..098db67f3a 100644 --- a/src/declarative/items/qquickspriteimage.cpp +++ b/src/declarative/items/qquickspriteimage.cpp @@ -249,6 +249,24 @@ struct SpriteVertices { Default is true. */ +/*! + \qmlproperty string QtQuick2::SpriteImage::goalState + + The name of the Sprite which the animation should move to. + + Sprite states have defined durations and transitions between them, setting goalState + will cause it to disregard any path weightings (including 0) and head down the path + which will reach the goalState quickest (fewest animations). It will pass through + intermediate states on that path, and animate them for their duration. + + If it is possible to return to the goalState from the starting point of the goalState + it will continue to do so until goalState is set to "" or an unreachable state. +*/ +/*! \qmlmethod void QtQuick2::SpriteImage::jumpTo(string sprite) + + This function causes the sprite to jump to the specified state immediately, intermediate + states are not played. +*/ /*! \qmlproperty list QtQuick2::SpriteImage::sprites @@ -270,6 +288,22 @@ QQuickSpriteImage::QQuickSpriteImage(QQuickItem *parent) : this, SLOT(update())); } +void QQuickSpriteImage::jumpTo(const QString &sprite) +{ + if (!m_spriteEngine) + return; + m_spriteEngine->setGoal(m_spriteEngine->stateIndex(sprite), 0, true); +} + +void QQuickSpriteImage::setGoalState(const QString &sprite) +{ + if (m_goalState != sprite){ + m_goalState = sprite; + emit goalStateChanged(sprite); + m_spriteEngine->setGoal(m_spriteEngine->stateIndex(sprite)); + } +} + QDeclarativeListProperty QQuickSpriteImage::sprites() { return QDeclarativeListProperty(this, &m_sprites, spriteAppend, spriteCount, spriteAt, spriteClear); diff --git a/src/declarative/items/qquickspriteimage_p.h b/src/declarative/items/qquickspriteimage_p.h index 1ffc95d952..969ff101d7 100644 --- a/src/declarative/items/qquickspriteimage_p.h +++ b/src/declarative/items/qquickspriteimage_p.h @@ -61,6 +61,7 @@ class QQuickSpriteImage : public QQuickItem Q_OBJECT Q_PROPERTY(bool running READ running WRITE setRunning NOTIFY runningChanged) Q_PROPERTY(bool interpolate READ interpolate WRITE setInterpolate NOTIFY interpolateChanged) + Q_PROPERTY(QString goalState READ goalState WRITE setGoalState NOTIFY goalStateChanged) //###try to share similar spriteEngines for less overhead? Q_PROPERTY(QDeclarativeListProperty sprites READ sprites) Q_CLASSINFO("DefaultProperty", "sprites") @@ -80,28 +81,37 @@ class QQuickSpriteImage : public QQuickItem return m_interpolate; } + QString goalState() const + { + return m_goalState; + } + signals: void runningChanged(bool arg); void interpolateChanged(bool arg); + void goalStateChanged(QString arg); public slots: -void setRunning(bool arg) -{ - if (m_running != arg) { - m_running = arg; - emit runningChanged(arg); + void jumpTo(const QString &sprite); + void setGoalState(const QString &sprite); + + void setRunning(bool arg) + { + if (m_running != arg) { + m_running = arg; + emit runningChanged(arg); + } } -} -void setInterpolate(bool arg) -{ - if (m_interpolate != arg) { - m_interpolate = arg; - emit interpolateChanged(arg); + void setInterpolate(bool arg) + { + if (m_interpolate != arg) { + m_interpolate = arg; + emit interpolateChanged(arg); + } } -} private slots: void createEngine(); @@ -120,6 +130,7 @@ private slots: bool m_pleaseReset; bool m_running; bool m_interpolate; + QString m_goalState; }; QT_END_NAMESPACE diff --git a/tests/testapplications/elements/content/GridViewElement.qml b/tests/testapplications/elements/content/GridViewElement.qml index 2b9884d4a9..79b48d55c3 100644 --- a/tests/testapplications/elements/content/GridViewElement.qml +++ b/tests/testapplications/elements/content/GridViewElement.qml @@ -123,5 +123,6 @@ Rectangle { ListElement { label: "Shape"; help: "The Shape element allows you to specify an area for affectors and emitter." } ListElement { label: "TrailEmitter"; help: "The TrailEmitter element allows you to emit logical particles from other logical particles." } ListElement { label: "Direction"; help: "The Direction elements allow you to specify a vector space." } + ListElement { label: "SpriteImage"; help: "The SpriteImage element plays stochastic sprite animations." } } } diff --git a/tests/testapplications/elements/content/SpriteImageElement.qml b/tests/testapplications/elements/content/SpriteImageElement.qml new file mode 100644 index 0000000000..2015eabe8a --- /dev/null +++ b/tests/testapplications/elements/content/SpriteImageElement.qml @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite 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$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + id: spriteimageelementtest + anchors.fill: parent + property string testtext: "" + SpriteImage { + id: spriteimage + sprites: [Sprite { + name: "happy" + source: "pics/squarefacesprite2.png" + frames: 6 + duration: 120 + to: {"silly": 1, "sad":0} + }, Sprite { + name: "silly" + source: "pics/squarefacesprite.png" + frames: 6 + duration: 120 + to: {"happy": 1, "sad": 0} + }, Sprite { + name: "sad" + source: "pics/squarefacesprite3.png" + frames: 6 + duration: 120 + to: {"evil": 0.5, "sad": 1, "cyclops" : 0} + }, Sprite { + name: "cyclops" + source: "pics/squarefacesprite4.png" + frames: 6 + duration: 120 + to: {"love": 0.1, "boggled": 0.1, "cyclops" : 0.1} + }, Sprite { + name: "evil" + source: "pics/squarefacesprite5.png" + frames: 6 + duration: 120 + to: {"sad": 1.0, "cyclops" : 0} + }, Sprite { + name: "love" + source: "pics/squarefacesprite6.png" + frames: 6 + duration: 120 + to: {"love": 0.1, "boggled": 0.1, "cyclops" : 0.1} + }, Sprite { + name: "boggled" + source: "pics/squarefacesprite7.png" + frames: 6 + duration: 120 + to: {"love": 0.1, "boggled": 0.1, "cyclops" : 0.1, "dying":0} + }, Sprite { + name: "dying" + source: "pics/squarefacespriteX.png" + frames: 4 + duration: 120 + to: {"dead":1.0} + }, Sprite { + name: "dead" + source: "pics/squarefacespriteXX.png" + frames: 1 + duration: 10000 + }] + + width: 300 + height: 300 + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + } + + + SystemTestHelp { id: helpbubble; visible: statenum != 0 + anchors { top: parent.top; horizontalCenter: parent.horizontalCenter; topMargin: 50 } + } + BugPanel { id: bugpanel } + + states: [ + State { name: "start"; when: statenum == 1 + StateChangeScript { script: spriteimage.jumpTo("happy"); } + PropertyChanges { target: spriteimageelementtest + testtext: "This is a SpriteImage element. It should be animating currently."+ + "It should alternate between winking and sticking out its tongue." } + }, + State { name: "stochastic2"; when: statenum == 2 + StateChangeScript { script: spriteimage.jumpTo("sad"); } + PropertyChanges { target: spriteimageelementtest + testtext: "The sprite should now be animating between frowning and being evil."+ + "This should not be alternating, but mostly frowning with the occasional evil eyes."+ + "After an evil eyes animation, it should return to frowning at least once." } + }, + State { name: "stochastic3"; when: statenum == 3 + StateChangeScript { script: spriteimage.jumpTo("cyclops"); } + PropertyChanges { target: spriteimageelementtest + testtext: "The sprite should now be animating fairly randomly between three animations where it does silly things with its eyes.\n"+ + "Next the sprite will animate into a static 'dead' state."+ + "When it does, it should first animate to and play through the 'big eyes' animation (if it is not currently playing that animation) before it enters the dying animation."} + }, + State { name: "dead"; when: statenum == 4 + PropertyChanges { target: spriteimage; goalState: "dead" } + PropertyChanges { target: spriteimageelementtest + testtext: "After a brief dying animation, the image should now be static.\n"+ + "Advance to restart the test." } + } + ] +} diff --git a/tests/testapplications/elements/content/pics/squarefacesprite.png b/tests/testapplications/elements/content/pics/squarefacesprite.png new file mode 100644 index 0000000000..f9a5d5fcce Binary files /dev/null and b/tests/testapplications/elements/content/pics/squarefacesprite.png differ diff --git a/tests/testapplications/elements/content/pics/squarefacesprite2.png b/tests/testapplications/elements/content/pics/squarefacesprite2.png new file mode 100644 index 0000000000..7106a520a4 Binary files /dev/null and b/tests/testapplications/elements/content/pics/squarefacesprite2.png differ diff --git a/tests/testapplications/elements/content/pics/squarefacesprite3.png b/tests/testapplications/elements/content/pics/squarefacesprite3.png new file mode 100644 index 0000000000..f4e6f26856 Binary files /dev/null and b/tests/testapplications/elements/content/pics/squarefacesprite3.png differ diff --git a/tests/testapplications/elements/content/pics/squarefacesprite4.png b/tests/testapplications/elements/content/pics/squarefacesprite4.png new file mode 100644 index 0000000000..1e094eed4a Binary files /dev/null and b/tests/testapplications/elements/content/pics/squarefacesprite4.png differ diff --git a/tests/testapplications/elements/content/pics/squarefacesprite5.png b/tests/testapplications/elements/content/pics/squarefacesprite5.png new file mode 100644 index 0000000000..1cfc5c7f8c Binary files /dev/null and b/tests/testapplications/elements/content/pics/squarefacesprite5.png differ diff --git a/tests/testapplications/elements/content/pics/squarefacesprite6.png b/tests/testapplications/elements/content/pics/squarefacesprite6.png new file mode 100644 index 0000000000..b040139a9e Binary files /dev/null and b/tests/testapplications/elements/content/pics/squarefacesprite6.png differ diff --git a/tests/testapplications/elements/content/pics/squarefacesprite7.png b/tests/testapplications/elements/content/pics/squarefacesprite7.png new file mode 100644 index 0000000000..b1e5e4e339 Binary files /dev/null and b/tests/testapplications/elements/content/pics/squarefacesprite7.png differ diff --git a/tests/testapplications/elements/content/pics/squarefacespriteX.png b/tests/testapplications/elements/content/pics/squarefacespriteX.png new file mode 100644 index 0000000000..93a0181dd0 Binary files /dev/null and b/tests/testapplications/elements/content/pics/squarefacespriteX.png differ diff --git a/tests/testapplications/elements/content/pics/squarefacespriteXX.png b/tests/testapplications/elements/content/pics/squarefacespriteXX.png new file mode 100644 index 0000000000..3159efe246 Binary files /dev/null and b/tests/testapplications/elements/content/pics/squarefacespriteXX.png differ