(ScrollView) Panning is disabled if ScrollTo is called while panning 74/24174/1
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Thu, 19 Jun 2014 13:36:27 +0000 (22:36 +0900)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Tue, 8 Jul 2014 17:47:13 +0000 (18:47 +0100)
[problem]     If application calls ScrollTo while we're panning we go into an incorrect state.
[cause]       When we're panning, and the application calls ScrollTo, swiftly followed by a call
              to disable scroll-sensitivity, the panning value is never cleared.
              When scroll-sensitivity is enabled, we start animating to a wrong position.
              Also trying to use the property value when we set sensitivity which can be out-of-date.
[solution]    Clear the panning value when we want to animate to another position.
              Use event-side panning value when changing scroll-sensitivity.

Change-Id: I3cc2200839ad3a2ec1fc705f542bd8df41502462
Signed-off-by: Adeel Kazmi <adeel.kazmi@samsung.com>
base/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.cpp

index 160546a..790c7f8 100644 (file)
@@ -1051,7 +1051,7 @@ void ScrollView::SetScrollSensitive(bool sensitive)
   Actor self = Self();
   PanGestureDetector panGesture( GetPanGestureDetector() );
 
   Actor self = Self();
   PanGestureDetector panGesture( GetPanGestureDetector() );
 
-  DALI_LOG_SCROLL_STATE("[0x%X] sensitive[%d]", this, int(sensitive));
+  DALI_LOG_SCROLL_STATE("[0x%X] sensitive: before:[%d] setting[%d]", this, int(mSensitive), int(sensitive));
 
   if((!mSensitive) && (sensitive))
   {
 
   if((!mSensitive) && (sensitive))
   {
@@ -1061,8 +1061,7 @@ void ScrollView::SetScrollSensitive(bool sensitive)
   else if((mSensitive) && (!sensitive))
   {
     // while the scroll view is panning, the state needs to be reset.
   else if((mSensitive) && (!sensitive))
   {
     // while the scroll view is panning, the state needs to be reset.
-    bool isPanning = self.GetProperty<bool>( mPropertyPanning );
-    if ( isPanning )
+    if ( mPanning )
     {
       PanGesture cancelGesture( Gesture::Cancelled );
       OnPan( cancelGesture );
     {
       PanGesture cancelGesture( Gesture::Cancelled );
       OnPan( cancelGesture );
@@ -1273,15 +1272,17 @@ void ScrollView::TransformTo(const Vector3& position, const Vector3& scale, floa
 void ScrollView::TransformTo(const Vector3& position, const Vector3& scale, float rotation, float duration,
                              DirectionBias horizontalBias, DirectionBias verticalBias)
 {
 void ScrollView::TransformTo(const Vector3& position, const Vector3& scale, float rotation, float duration,
                              DirectionBias horizontalBias, DirectionBias verticalBias)
 {
+  Actor self( Self() );
+
   // Guard against destruction during signal emission
   // Note that Emit() methods are called indirectly e.g. from within ScrollView::AnimateTo()
   Toolkit::ScrollView handle( GetOwner() );
 
   // Guard against destruction during signal emission
   // Note that Emit() methods are called indirectly e.g. from within ScrollView::AnimateTo()
   Toolkit::ScrollView handle( GetOwner() );
 
-  DALI_LOG_SCROLL_STATE("pos[%.2f,%.2f], scale[%.2f,%.2f], rot[%.2f], duration[%.2f] bias[%d, %d]",
-    position.x, position.y, scale.x, scale.y, rotation, duration, int(horizontalBias), int(verticalBias));
+  DALI_LOG_SCROLL_STATE("[0x%X] pos[%.2f,%.2f], scale[%.2f,%.2f], rot[%.2f], duration[%.2f] bias[%d, %d]",
+    this, position.x, position.y, scale.x, scale.y, rotation, duration, int(horizontalBias), int(verticalBias));
 
   Vector3 currentScrollPosition = GetCurrentScrollPosition();
 
   Vector3 currentScrollPosition = GetCurrentScrollPosition();
-  Self().SetProperty( mPropertyScrollStartPagePosition, currentScrollPosition );
+  self.SetProperty( mPropertyScrollStartPagePosition, currentScrollPosition );
 
   if( mScrolling ) // are we interrupting a current scroll?
   {
 
   if( mScrolling ) // are we interrupting a current scroll?
   {
@@ -1291,7 +1292,19 @@ void ScrollView::TransformTo(const Vector3& position, const Vector3& scale, floa
     mScrollCompletedSignalV2.Emit( currentScrollPosition );
   }
 
     mScrollCompletedSignalV2.Emit( currentScrollPosition );
   }
 
-  Self().SetProperty(mPropertyScrolling, true);
+  if( mPanning ) // are we interrupting a current pan?
+  {
+    DALI_LOG_SCROLL_STATE("[0x%X] Interrupting Pan, set to false", this );
+    mPanning = false;
+    self.SetProperty( mPropertyPanning, false );
+
+    if( mScrollMainInternalPrePositionConstraint )
+    {
+      self.RemoveConstraint(mScrollMainInternalPrePositionConstraint);
+    }
+  }
+
+  self.SetProperty(mPropertyScrolling, true);
   mScrolling = true;
 
   DALI_LOG_SCROLL_STATE("[0x%X] mScrollStartedSignalV2 1 [%.2f, %.2f]", this, currentScrollPosition.x, currentScrollPosition.y);
   mScrolling = true;
 
   DALI_LOG_SCROLL_STATE("[0x%X] mScrollStartedSignalV2 1 [%.2f, %.2f]", this, currentScrollPosition.x, currentScrollPosition.y);
@@ -1311,7 +1324,7 @@ void ScrollView::TransformTo(const Vector3& position, const Vector3& scale, floa
   if(!animating)
   {
     // if not animating, then this pan has completed right now.
   if(!animating)
   {
     // if not animating, then this pan has completed right now.
-    Self().SetProperty(mPropertyScrolling, false);
+    self.SetProperty(mPropertyScrolling, false);
     mScrolling = false;
 
     // If we have no duration, then in the next update frame, we will be at the position specified as we just set.
     mScrolling = false;
 
     // If we have no duration, then in the next update frame, we will be at the position specified as we just set.
@@ -1341,8 +1354,8 @@ void ScrollView::ScrollTo(const Vector3& position, float duration)
 void ScrollView::ScrollTo(const Vector3& position, float duration,
                           DirectionBias horizontalBias, DirectionBias verticalBias)
 {
 void ScrollView::ScrollTo(const Vector3& position, float duration,
                           DirectionBias horizontalBias, DirectionBias verticalBias)
 {
-  DALI_LOG_SCROLL_STATE("position[%.2f, %.2f] duration[%.2f]",
-    position.x, position.y, duration, int(horizontalBias), int(verticalBias));
+  DALI_LOG_SCROLL_STATE("[0x%X] position[%.2f, %.2f] duration[%.2f]",
+    this, position.x, position.y, duration, int(horizontalBias), int(verticalBias));
 
   TransformTo(position, mScrollPostScale, mScrollPostRotation, duration, horizontalBias, verticalBias);
 }
 
   TransformTo(position, mScrollPostScale, mScrollPostRotation, duration, horizontalBias, verticalBias);
 }
@@ -2520,6 +2533,8 @@ void ScrollView::OnPan(PanGesture gesture)
 
   if(!mSensitive)
   {
 
   if(!mSensitive)
   {
+    DALI_LOG_SCROLL_STATE("[0x%X] Pan Ignored, Insensitive", this);
+
     // If another callback on the same original signal disables sensitivity,
     // this callback will still be called, so we must suppress it.
     return;
     // If another callback on the same original signal disables sensitivity,
     // this callback will still be called, so we must suppress it.
     return;
@@ -2530,6 +2545,7 @@ void ScrollView::OnPan(PanGesture gesture)
   {
     case Gesture::Started:
     {
   {
     case Gesture::Started:
     {
+      DALI_LOG_SCROLL_STATE("[0x%X] Pan Started", this);
       UpdateLocalScrollProperties();
       GestureStarted();
       mPanning = true;
       UpdateLocalScrollProperties();
       GestureStarted();
       mPanning = true;
@@ -2542,21 +2558,40 @@ void ScrollView::OnPan(PanGesture gesture)
 
     case Gesture::Continuing:
     {
 
     case Gesture::Continuing:
     {
-      GestureContinuing(gesture.screenDisplacement, Vector2::ZERO, 0.0f);
+      if ( mPanning )
+      {
+        DALI_LOG_SCROLL_STATE("[0x%X] Pan Continuing", this);
+        GestureContinuing(gesture.screenDisplacement, Vector2::ZERO, 0.0f);
+      }
+      else
+      {
+        // If we do not think we are panning, then we should not do anything here
+        return;
+      }
       break;
     }
 
     case Gesture::Finished:
     case Gesture::Cancelled:
     {
       break;
     }
 
     case Gesture::Finished:
     case Gesture::Cancelled:
     {
-      UpdateLocalScrollProperties();
-      mLastVelocity = gesture.velocity;
-      mPanning = false;
-      self.SetProperty( mPropertyPanning, false );
+      if ( mPanning )
+      {
+        DALI_LOG_SCROLL_STATE("[0x%X] Pan %s", this, ( ( gesture.state == Gesture::Finished ) ? "Finished" : "Cancelled" ) );
+
+        UpdateLocalScrollProperties();
+        mLastVelocity = gesture.velocity;
+        mPanning = false;
+        self.SetProperty( mPropertyPanning, false );
 
 
-      if( mScrollMainInternalPrePositionConstraint )
+        if( mScrollMainInternalPrePositionConstraint )
+        {
+          self.RemoveConstraint(mScrollMainInternalPrePositionConstraint);
+        }
+      }
+      else
       {
       {
-        self.RemoveConstraint(mScrollMainInternalPrePositionConstraint);
+        // If we do not think we are panning, then we should not do anything here
+        return;
       }
       break;
     }
       }
       break;
     }