Several smaller fixes to Animators.
authorGunnar Sletta <gunnar.sletta@digia.com>
Fri, 4 Oct 2013 13:42:35 +0000 (15:42 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Tue, 8 Oct 2013 06:02:21 +0000 (08:02 +0200)
Backwards animations are not supported for animators as the
animation system cannot handle uncontrolled backwards animations.

Make sure we write back values only for the animators that have
run at all.

Clockwise rotation to 0 can easily end up on 360 as a result
the _q_interpolateClockwise function not being entirely correct.

Change-Id: If69b8555a1361f46600a40e80419b65438c18097
Reviewed-by: Michael Brasser <michael.brasser@live.com>
src/quick/util/qquickanimator.cpp
src/quick/util/qquickanimatorjob.cpp
src/quick/util/qquickanimatorjob_p.h

index a5bdd82..5ea9a35 100644 (file)
@@ -73,6 +73,10 @@ QT_BEGIN_NAMESPACE
     also be treated as an Animator and be run on the scene graph's rendering
     thread when possible.
 
+    The Animator types can be used for animations during transitions, but
+    they do not support the \l {Transition::reversible}{reversible}
+    property.
+
     The Animator type cannot be used directly in a QML file. It exists
     to provide a set of common properties and methods, available across all the
     other animator types that inherit from it. Attempting to use the Animator
@@ -263,7 +267,7 @@ void QQuickAnimatorPrivate::apply(QQuickAnimatorJob *job,
 
 QAbstractAnimationJob *QQuickAnimator::transition(QQuickStateActions &actions,
                                                   QQmlProperties &modified,
-                                                  TransitionDirection,
+                                                  TransitionDirection direction,
                                                   QObject *)
 {
     Q_D(QQuickAnimator);
@@ -273,6 +277,10 @@ QAbstractAnimationJob *QQuickAnimator::transition(QQuickStateActions &actions,
         return 0;
     }
 
+    // The animation system cannot handle backwards uncontrolled animations.
+    if (direction == Backward)
+        return 0;
+
     QQuickAnimatorJob *job = createJob();
     if (!job)
         return 0;
index 389ef23..78708bd 100644 (file)
@@ -204,7 +204,8 @@ static void qquick_syncback_helper(QAbstractAnimationJob *job)
 {
     if (job->isRenderThreadJob()) {
         QQuickAnimatorJob *a = static_cast<QQuickAnimatorJob *>(job);
-        if (a->controller())
+        // Sync back only those jobs that actually have been running
+        if (a->controller() && a->hasBeenRunning())
             a->writeBack();
     } else if (job->isGroup()) {
         QAnimationGroupJob *g = static_cast<QAnimationGroupJob *>(job);
@@ -227,6 +228,7 @@ QQuickAnimatorJob::QQuickAnimatorJob()
     , m_duration(0)
     , m_isTransform(false)
     , m_isUniform(false)
+    , m_hasBeenRunning(false)
 {
     m_isRenderThreadJob = true;
 }
@@ -265,6 +267,7 @@ void QQuickAnimatorJob::updateState(State newState, State oldState)
 
     if (newState == Running) {
         m_controller->activeLeafAnimations << this;
+        m_hasBeenRunning = true;
     } else if (oldState == Running) {
         m_controller->activeLeafAnimations.remove(this);
     }
@@ -297,6 +300,8 @@ void QQuickTransformAnimatorJob::initialize(QQuickAnimatorController *controller
             QObject::connect(m_target, SIGNAL(destroyed(QObject *)), m_controller, SLOT(itemDestroyed(QObject*)), Qt::DirectConnection);
         } else {
             ++m_helper->ref;
+            // Make sure leftovers from previous runs are being used...
+            m_helper->wasSynced = false;
         }
         m_helper->sync();
     }
@@ -489,6 +494,11 @@ void QQuickRotationAnimatorJob::updateCurrentTime(int time)
     switch (m_direction) {
     case QQuickRotationAnimator::Clockwise:
         m_value = _q_interpolateClockwiseRotation(m_from, m_to, t).toFloat();
+        // The logic in _q_interpolateClockwise comes out a bit wrong
+        // for the case of X->0 where 0<X<360. It ends on 360 which it
+        // shouldn't.
+        if (t == 1)
+            m_value = m_to;
         break;
     case QQuickRotationAnimator::Counterclockwise:
         m_value = _q_interpolateCounterclockwiseRotation(m_from, m_to, t).toFloat();
index 44155c1..bc9c65c 100644 (file)
@@ -133,6 +133,8 @@ public:
     bool isTransform() const { return m_isTransform; }
     bool isUniform() const { return m_isUniform; }
 
+    bool hasBeenRunning() const { return m_hasBeenRunning; }
+
     qreal value() const;
 
     QQuickAnimatorController *controller() const { return m_controller; }
@@ -155,6 +157,7 @@ protected:
     uint m_feedback : 1;
     uint m_isTransform : 1;
     uint m_isUniform : 1;
+    uint m_hasBeenRunning : 1;
 };
 
 class QQuickTransformAnimatorJob : public QQuickAnimatorJob