(PanGesture) Phase in the initial pan-threshold if it's a slow pan 39/24139/1
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Tue, 1 Jul 2014 07:57:39 +0000 (16:57 +0900)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Tue, 8 Jul 2014 16:05:03 +0000 (17:05 +0100)
[problem]     When we are doing a slow pan, there is a jump at the start which does not look good
[cause]       To minimise the distance between finger and object, the WHOLE threshold is applied
              when the gesture starts.
[solution]    If it's a slow pan, phase in the pan-threshold.

Change-Id: Ifee6547f66761881d04c3a847b4b3cdb5e3bc4e1
Signed-off-by: Adeel Kazmi <adeel.kazmi@samsung.com>
adaptors/tizen/internal/common/events/pan-gesture-detector-base.cpp
adaptors/tizen/internal/common/events/pan-gesture-detector-base.h

index 189f8f4..9c27caf 100644 (file)
@@ -40,21 +40,25 @@ namespace Adaptor
 
 namespace
 {
-// TODO: Used DPD Value.
-const float MINIMUM_MOTION_BEFORE_PAN_SQUARED( 15.0f * 15.0f );
+const float MINIMUM_MOTION_DISTANCE_BEFORE_PAN( 15.0f );
+const float MINIMUM_MOTION_DISTANCE_BEFORE_PAN_SQUARED( MINIMUM_MOTION_DISTANCE_BEFORE_PAN * MINIMUM_MOTION_DISTANCE_BEFORE_PAN );
+const float MINIMUM_MOTION_DISTANCE_TO_THRESHOLD_ADJUSTMENTS_RATIO( 2.0f / 3.0f );
 const unsigned long MAXIMUM_TIME_DIFF_ALLOWED( 500 );
+const unsigned long MINIMUM_TIME_BEFORE_THRESHOLD_ADJUSTMENTS( 100 );
 const unsigned int MINIMUM_MOTION_EVENTS_BEFORE_PAN(2);
 } // unnamed namespace
 
 PanGestureDetectorBase::PanGestureDetectorBase(Vector2 screenSize, const Integration::PanGestureRequest& request, EnvironmentOptions* environmentOptions)
-: GestureDetector(screenSize, Gesture::Pan),
-  mState(Clear),
-  mPrimaryTouchDownTime(0),
-  mMinimumTouchesRequired(request.minTouches),
-  mMaximumTouchesRequired(request.maxTouches),
-  mMinimumDistanceSquared( MINIMUM_MOTION_BEFORE_PAN_SQUARED ),
+: GestureDetector( screenSize, Gesture::Pan ),
+  mState( Clear ),
+  mThresholdAdjustmentsRemaining( 0 ),
+  mThresholdTotalAdjustments( MINIMUM_MOTION_DISTANCE_BEFORE_PAN * MINIMUM_MOTION_DISTANCE_TO_THRESHOLD_ADJUSTMENTS_RATIO ),
+  mPrimaryTouchDownTime( 0 ),
+  mMinimumTouchesRequired( request.minTouches ),
+  mMaximumTouchesRequired( request.maxTouches ),
+  mMinimumDistanceSquared( MINIMUM_MOTION_DISTANCE_BEFORE_PAN_SQUARED ),
   mMinimumMotionEvents( MINIMUM_MOTION_EVENTS_BEFORE_PAN ),
-  mMotionEvents(0)
+  mMotionEvents( 0 )
 {
   if ( environmentOptions )
   {
@@ -62,6 +66,10 @@ PanGestureDetectorBase::PanGestureDetectorBase(Vector2 screenSize, const Integra
     if ( minimumDistance >= 0 )
     {
       mMinimumDistanceSquared = minimumDistance * minimumDistance;
+
+      // Usually, we do not want to apply the threshold straight away, but phased over the first few pans
+      // Set our distance to threshold adjustments ratio here.
+      mThresholdTotalAdjustments = minimumDistance * MINIMUM_MOTION_DISTANCE_TO_THRESHOLD_ADJUSTMENTS_RATIO;
     }
 
     int minimumEvents = environmentOptions->GetMinimumPanEvents();
@@ -268,7 +276,7 @@ void PanGestureDetectorBase::SendPan(Gesture::State state, const Integration::To
     // Get the second last event in the queue, the last one is the current event
     const Integration::TouchEvent& previousEvent( *( mTouchEvents.rbegin() + 1 ) );
 
-    Vector2 previousPosition( previousEvent.points[0].screen );
+    Vector2 previousPosition( mPreviousPosition );
     unsigned long previousTime( previousEvent.time );
 
     // If we've just started then we want to remove the threshold from Core calculations.
@@ -276,10 +284,32 @@ void PanGestureDetectorBase::SendPan(Gesture::State state, const Integration::To
     {
       previousPosition = mPrimaryTouchDownLocation;
       previousTime = mPrimaryTouchDownTime;
+
+      // If it's a slow pan, we do not want to phase in the threshold over the first few pan-events
+      // A slow pan is defined as one that starts the specified number of milliseconds after the down-event
+      if ( ( currentEvent.time - previousTime ) > MINIMUM_TIME_BEFORE_THRESHOLD_ADJUSTMENTS )
+      {
+        mThresholdAdjustmentsRemaining = mThresholdTotalAdjustments;
+        mThresholdAdjustmentPerFrame = ( gesture.currentPosition - previousPosition ) / mThresholdTotalAdjustments;
+      }
+      else
+      {
+        mThresholdAdjustmentsRemaining = 0;
+        mThresholdAdjustmentPerFrame = Vector2::ZERO;
+      }
     }
 
     gesture.previousPosition = previousPosition;
     gesture.timeDelta = currentEvent.time - previousTime;
+
+    // Apply the threshold with a phased approach
+    if ( mThresholdAdjustmentsRemaining > 0 )
+    {
+      --mThresholdAdjustmentsRemaining;
+      gesture.currentPosition -= mThresholdAdjustmentPerFrame * mThresholdAdjustmentsRemaining;
+    }
+
+    mPreviousPosition = gesture.currentPosition;
   }
   else
   {
index dfbdad5..28a2bf5 100644 (file)
@@ -110,6 +110,12 @@ private:
   std::vector<Integration::TouchEvent> mTouchEvents;     ///< A container of all touch events after an initial down event.
 
   Vector2 mPrimaryTouchDownLocation;    ///< The initial touch down point.
+  Vector2 mThresholdAdjustmentPerFrame; ///< The adjustment per frame at the start of a slow pan.
+  Vector2 mPreviousPosition;            ///< The previous position.
+
+  unsigned int mThresholdAdjustmentsRemaining; ///< No. of threshold adjustments still to apply (for a slow-pan).
+  unsigned int mThresholdTotalAdjustments;     ///< The total number of adjustments required.
+
   unsigned long mPrimaryTouchDownTime;  ///< The initial touch down time.
   unsigned int mMinimumTouchesRequired; ///< The minimum touches required before a pan should be emitted.
   unsigned int mMaximumTouchesRequired; ///< The maximum touches after which a pan should not be emitted.