summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp111
-rw-r--r--src/corelib/statemachine/qstatemachine.h16
-rw-r--r--src/corelib/statemachine/qstatemachine_p.h9
-rw-r--r--tests/auto/qstatemachine/tst_qstatemachine.cpp140
4 files changed, 272 insertions, 4 deletions
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index 0a1d248..1f8d8a8 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -612,8 +612,17 @@ void QStateMachinePrivate::applyProperties(const QList<QAbstractTransition*> &tr
// Find the animations to use for the state change.
QList<QAbstractAnimation*> selectedAnimations;
- for (int i = 0; i < transitionList.size(); ++i)
- selectedAnimations << transitionList.at(i)->animations();
+ for (int i = 0; i < transitionList.size(); ++i) {
+ QAbstractTransition *transition = transitionList.at(i);
+
+ selectedAnimations << transition->animations();
+ selectedAnimations << defaultAnimationsForSource.values(transition->sourceState());
+
+ QList<QAbstractState *> targetStates = transition->targetStates();
+ for (int j=0; j<targetStates.size(); ++j)
+ selectedAnimations << defaultAnimationsForTarget.values(targetStates.at(j));
+ }
+ selectedAnimations << defaultAnimations;
#else
Q_UNUSED(transitionList);
#endif
@@ -1828,6 +1837,104 @@ void QStateMachine::endMicrostep(QEvent *event)
Q_UNUSED(event);
}
+#ifndef QT_NO_ANIMATION
+
+/*!
+ Adds a default \a animation to be considered for any transition.
+*/
+void QStateMachine::addDefaultAnimation(QAbstractAnimation *animation)
+{
+ Q_D(QStateMachine);
+ d->defaultAnimations.append(animation);
+}
+
+/*!
+ Returns the list of default animations that will be considered for any transition.
+*/
+QList<QAbstractAnimation*> QStateMachine::defaultAnimations() const
+{
+ Q_D(const QStateMachine);
+ return d->defaultAnimations;
+}
+
+/*!
+ Removes \a animation from the list of default animations.
+*/
+void QStateMachine::removeDefaultAnimation(QAbstractAnimation *animation)
+{
+ Q_D(QStateMachine);
+ d->defaultAnimations.removeAll(animation);
+}
+
+
+/*!
+ Adds a default \a animation to be considered for any transition with the source state
+ \a sourceState.
+*/
+void QStateMachine::addDefaultAnimationForSourceState(QAbstractState *sourceState,
+ QAbstractAnimation *animation)
+{
+ Q_D(QStateMachine);
+ d->defaultAnimationsForSource.insert(sourceState, animation);
+}
+
+
+/*!
+ Returns the list of default animations that will be considered for any transition with
+ the source state \a sourceState.
+*/
+QList<QAbstractAnimation*> QStateMachine::defaultAnimationsForSourceState(QAbstractState *sourceState) const
+{
+ Q_D(const QStateMachine);
+ return d->defaultAnimationsForSource.values(sourceState);
+}
+
+/*!
+ Removes \a animation from the list of default animations for the source state
+ \a sourceState.
+*/
+void QStateMachine::removeDefaultAnimationForSourceState(QAbstractState *sourceState,
+ QAbstractAnimation *animation)
+{
+ Q_D(QStateMachine);
+ d->defaultAnimationsForSource.remove(sourceState, animation);
+}
+
+/*!
+ Adds a default \a animation to be considered for any transition with the target state
+ \a targetState.
+*/
+void QStateMachine::addDefaultAnimationForTargetState(QAbstractState *targetState,
+ QAbstractAnimation *animation)
+{
+ Q_D(QStateMachine);
+ d->defaultAnimationsForTarget.insert(targetState, animation);
+}
+
+/*!
+ Returns the list of default animations that will be considered for any transition with
+ the target state \a targetState.
+*/
+QList<QAbstractAnimation *> QStateMachine::defaultAnimationsForTargetState(QAbstractState *targetState) const
+{
+ Q_D(const QStateMachine);
+ return d->defaultAnimationsForTarget.values(targetState);
+}
+
+/*!
+ Removes \a animation from the list of default animations for the target state
+ \a targetState.
+*/
+void QStateMachine::removeDefaultAnimationForTargetState(QAbstractState *targetState,
+ QAbstractAnimation *animation)
+{
+ Q_D(QStateMachine);
+ d->defaultAnimationsForTarget.remove(targetState, animation);
+}
+
+#endif // QT_NO_ANIMATION
+
+
static const uint qt_meta_data_QSignalEventGenerator[] = {
// content:
diff --git a/src/corelib/statemachine/qstatemachine.h b/src/corelib/statemachine/qstatemachine.h
index c7de171..f39efc7 100644
--- a/src/corelib/statemachine/qstatemachine.h
+++ b/src/corelib/statemachine/qstatemachine.h
@@ -63,6 +63,8 @@ class QAbstractState;
class QState;
class QStateMachinePrivate;
+class QAbstractAnimation;
+class QAbstractState;
class Q_CORE_EXPORT QStateMachine : public QObject
{
Q_OBJECT
@@ -96,6 +98,20 @@ public:
QString errorString() const;
void clearError();
+#ifndef QT_NO_ANIMATION
+ void addDefaultAnimation(QAbstractAnimation *animation);
+ QList<QAbstractAnimation *> defaultAnimations() const;
+ void removeDefaultAnimation(QAbstractAnimation *animation);
+
+ void addDefaultAnimationForSourceState(QAbstractState *sourceState, QAbstractAnimation *animation);
+ QList<QAbstractAnimation *> defaultAnimationsForSourceState(QAbstractState *sourceState) const;
+ void removeDefaultAnimationForSourceState(QAbstractState *sourceState, QAbstractAnimation *animation);
+
+ void addDefaultAnimationForTargetState(QAbstractState *targetState, QAbstractAnimation *animation);
+ QList<QAbstractAnimation *> defaultAnimationsForTargetState(QAbstractState *targetState) const;
+ void removeDefaultAnimationForTargetState(QAbstractState *targetState, QAbstractAnimation *animation);
+#endif // QT_NO_ANIMATION
+
QAbstractState::RestorePolicy globalRestorePolicy() const;
void setGlobalRestorePolicy(QAbstractState::RestorePolicy restorePolicy);
diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h
index 04dc71e..a9fd2de 100644
--- a/src/corelib/statemachine/qstatemachine_p.h
+++ b/src/corelib/statemachine/qstatemachine_p.h
@@ -169,7 +169,7 @@ public:
QSet<QAbstractState*> configuration;
QList<QEvent*> internalEventQueue;
QList<QEvent*> externalEventQueue;
-
+
QStateMachine::Error error;
QActionState::RestorePolicy globalRestorePolicy;
@@ -186,7 +186,12 @@ public:
QList<QPair<QAbstractAnimation*, QPropertyAssignment> > propertiesForAnimations;
QList<QAbstractAnimation*> playingAnimations;
QList<QAbstractAnimation*> resetEndValues;
-#endif
+
+ QList<QAbstractAnimation *> defaultAnimations;
+ QMultiHash<QAbstractState *, QAbstractAnimation *> defaultAnimationsForSource;
+ QMultiHash<QAbstractState *, QAbstractAnimation *> defaultAnimationsForTarget;
+
+#endif // QT_NO_ANIMATION
#ifndef QT_STATEMACHINE_SOLUTION
QSignalEventGenerator *signalEventGenerator;
diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp
index be80bed..5796161 100644
--- a/tests/auto/qstatemachine/tst_qstatemachine.cpp
+++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp
@@ -141,6 +141,10 @@ private slots:
void nestedTargetStateForAnimation();
void animatedGlobalRestoreProperty();
void specificTargetValueOfAnimation();
+ void addDefaultAnimation();
+ void addDefaultAnimationWithUnusedAnimation();
+ void addDefaultAnimationForSource();
+ void addDefaultAnimationForTarget();
};
tst_QStateMachine::tst_QStateMachine()
@@ -2437,6 +2441,142 @@ void tst_QStateMachine::specificTargetValueOfAnimation()
QCOMPARE(anim->endValue().toDouble(), 10.0);
}
+void tst_QStateMachine::addDefaultAnimation()
+{
+ QStateMachine machine;
+
+ QObject *object = new QObject();
+ object->setProperty("foo", 1.0);
+
+ QState *s1 = new QState(machine.rootState());
+
+ QState *s2 = new QState(machine.rootState());
+ s2->assignProperty(object, "foo", 2.0);
+
+ QState *s3 = new QState(machine.rootState());
+ s3->invokeMethodOnEntry(QCoreApplication::instance(), "quit");
+
+ s1->addTransition(new EventTransition(QEvent::User, s2));
+
+ QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", &machine);
+ machine.addDefaultAnimation(pa);
+ s2->addTransition(pa, SIGNAL(finished()), s3);
+
+ machine.setInitialState(s1);
+ machine.start();
+ QCoreApplication::processEvents();
+
+ machine.postEvent(new QEvent(QEvent::User));
+ QCOREAPPLICATION_EXEC(5000);
+
+ QVERIFY(machine.configuration().contains(s3));
+ QCOMPARE(object->property("foo").toDouble(), 2.0);
+}
+
+void tst_QStateMachine::addDefaultAnimationWithUnusedAnimation()
+{
+ QStateMachine machine;
+
+ QObject *object = new QObject();
+ object->setProperty("foo", 1.0);
+ object->setProperty("bar", 2.0);
+
+ SlotCalledCounter counter;
+
+ QState *s1 = new QState(machine.rootState());
+
+ QState *s2 = new QState(machine.rootState());
+ s2->assignProperty(object, "foo", 2.0);
+
+ QState *s3 = new QState(machine.rootState());
+ s3->invokeMethodOnEntry(QCoreApplication::instance(), "quit");
+
+ s1->addTransition(new EventTransition(QEvent::User, s2));
+
+ QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", &machine);
+ connect(pa, SIGNAL(finished()), &counter, SLOT(slot()));
+ machine.addDefaultAnimation(pa);
+ s2->addTransition(pa, SIGNAL(finished()), s3);
+
+ pa = new QPropertyAnimation(object, "bar", &machine);
+ connect(pa, SIGNAL(finished()), &counter, SLOT(slot()));
+ machine.addDefaultAnimation(pa);
+
+ machine.setInitialState(s1);
+ machine.start();
+ QCoreApplication::processEvents();
+
+ machine.postEvent(new QEvent(QEvent::User));
+ QCOREAPPLICATION_EXEC(5000);
+
+ QVERIFY(machine.configuration().contains(s3));
+ QCOMPARE(object->property("foo").toDouble(), 2.0);
+ QCOMPARE(counter.counter, 1);
+}
+
+void tst_QStateMachine::addDefaultAnimationForSource()
+{
+ QStateMachine machine;
+
+ QObject *object = new QObject();
+ object->setProperty("foo", 1.0);
+
+ QState *s1 = new QState(machine.rootState());
+
+ QState *s2 = new QState(machine.rootState());
+ s2->assignProperty(object, "foo", 2.0);
+
+ QState *s3 = new QState(machine.rootState());
+ s3->invokeMethodOnEntry(QCoreApplication::instance(), "quit");
+
+ s1->addTransition(new EventTransition(QEvent::User, s2));
+
+ QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", &machine);
+ machine.addDefaultAnimationForSourceState(s1, pa);
+ s2->addTransition(pa, SIGNAL(finished()), s3);
+
+ machine.setInitialState(s1);
+ machine.start();
+ QCoreApplication::processEvents();
+
+ machine.postEvent(new QEvent(QEvent::User));
+ QCOREAPPLICATION_EXEC(5000);
+
+ QVERIFY(machine.configuration().contains(s3));
+ QCOMPARE(object->property("foo").toDouble(), 2.0);
+}
+
+void tst_QStateMachine::addDefaultAnimationForTarget()
+{
+ QStateMachine machine;
+
+ QObject *object = new QObject();
+ object->setProperty("foo", 1.0);
+
+ QState *s1 = new QState(machine.rootState());
+
+ QState *s2 = new QState(machine.rootState());
+ s2->assignProperty(object, "foo", 2.0);
+
+ QState *s3 = new QState(machine.rootState());
+ s3->invokeMethodOnEntry(QCoreApplication::instance(), "quit");
+
+ s1->addTransition(new EventTransition(QEvent::User, s2));
+
+ QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", &machine);
+ machine.addDefaultAnimationForTargetState(s2, pa);
+ s2->addTransition(pa, SIGNAL(finished()), s3);
+
+ machine.setInitialState(s1);
+ machine.start();
+ QCoreApplication::processEvents();
+
+ machine.postEvent(new QEvent(QEvent::User));
+ QCOREAPPLICATION_EXEC(5000);
+
+ QVERIFY(machine.configuration().contains(s3));
+ QCOMPARE(object->property("foo").toDouble(), 2.0);
+}
QTEST_MAIN(tst_QStateMachine)
#include "tst_qstatemachine.moc"