Add SetTapRecognizerTime
[platform/core/uifw/dali-core.git] / dali / internal / event / events / tap-gesture / tap-gesture-recognizer.cpp
index ab8c1a8..609c161 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 #include <dali/public-api/math/vector2.h>
 
-// INTERNAL INCLUDES
 #include <dali/integration-api/events/touch-event-integ.h>
-#include <dali/integration-api/platform-abstraction.h>
+
+// INTERNAL INCLUDES
 #include <dali/internal/event/common/scene-impl.h>
-#include <dali/internal/event/common/thread-local-storage.h>
 #include <dali/internal/event/events/gesture-requests.h>
 
 namespace Dali
@@ -37,12 +36,10 @@ namespace Internal
 namespace
 {
 // TODO: Set these according to DPI
-const float         MAXIMUM_MOTION_ALLOWED = 20.0f;
-const unsigned long MAXIMUM_TIME_ALLOWED   = 500u;
-const uint32_t      WAIT_TIME              = 330u;
+constexpr float MAXIMUM_MOTION_ALLOWED = 20.0f;
 } // unnamed namespace
 
-TapGestureRecognizer::TapGestureRecognizer(Observer& observer, Vector2 screenSize, const TapGestureRequest& request)
+TapGestureRecognizer::TapGestureRecognizer(Observer& observer, Vector2 screenSize, const TapGestureRequest& request, uint32_t maximumAllowedTime, uint32_t recognizerTime)
 : GestureRecognizer(screenSize, GestureType::TAP),
   mObserver(observer),
   mState(CLEAR),
@@ -52,20 +49,13 @@ TapGestureRecognizer::TapGestureRecognizer(Observer& observer, Vector2 screenSiz
   mTouchPosition(),
   mTouchTime(0u),
   mLastTapTime(0u),
-  mEventTime(0u),
-  mGestureSourceType(GestureSourceType::INVALID),
-  mTimerId(0)
+  mLastTouchTime(0u),
+  mMaximumAllowedTime(maximumAllowedTime),
+  mRecognizerTime(recognizerTime)
 {
 }
 
-TapGestureRecognizer::~TapGestureRecognizer()
-{
-  if(mTimerId != 0 && ThreadLocalStorage::Created())
-  {
-    Dali::Integration::PlatformAbstraction& platformAbstraction = ThreadLocalStorage::Get().GetPlatformAbstraction();
-    platformAbstraction.CancelTimer(mTimerId);
-  }
-}
+TapGestureRecognizer::~TapGestureRecognizer() = default;
 
 void TapGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
 {
@@ -73,39 +63,8 @@ void TapGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
 
   if(event.GetPointCount() == 1)
   {
-    const Integration::Point&               point               = event.points[0];
-    PointState::Type                        pointState          = point.GetState();
-    Dali::Integration::PlatformAbstraction& platformAbstraction = ThreadLocalStorage::Get().GetPlatformAbstraction();
-
-    MouseButton::Type mouseButton = point.GetMouseButton();
-    switch(mouseButton)
-    {
-      case MouseButton::INVALID:
-      {
-        mGestureSourceType = GestureSourceType::INVALID;
-        break;
-      }
-      case MouseButton::PRIMARY:
-      {
-        mGestureSourceType = GestureSourceType::PRIMARY;
-        break;
-      }
-      case MouseButton::SECONDARY:
-      {
-        mGestureSourceType = GestureSourceType::SECONDARY;
-        break;
-      }
-      case MouseButton::TERTIARY:
-      {
-        mGestureSourceType = GestureSourceType::TERTIARY;
-        break;
-      }
-      default:
-      {
-        mGestureSourceType = GestureSourceType::INVALID;
-        break;
-      }
-    }
+    const Integration::Point& point      = event.points[0];
+    PointState::Type          pointState = point.GetState();
 
     switch(mState)
     {
@@ -114,6 +73,7 @@ void TapGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
         if(pointState == PointState::DOWN)
         {
           SetupForTouchDown(event, point);
+          mLastTouchTime = event.time;
         }
         break;
       }
@@ -124,15 +84,9 @@ void TapGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
 
         if(pointState == PointState::UP)
         {
-          if(deltaBetweenTouchDownTouchUp < MAXIMUM_TIME_ALLOWED)
+          if(deltaBetweenTouchDownTouchUp < mRecognizerTime)
           {
-            if(mMaximumTapsRequired > mMinimumTapsRequired)
-            {
-              mEventTime = event.time;
-              mTimerId   = platformAbstraction.StartTimer(WAIT_TIME, MakeCallback(this, &TapGestureRecognizer::TimerCallback));
-            }
-
-            mLastTapTime = mTouchTime;
+            mLastTapTime = event.time;
             EmitSingleTap(event.time, point);
             mState = REGISTERED;
           }
@@ -152,30 +106,16 @@ void TapGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
       {
         if(pointState == PointState::UP)
         {
-          // This is a possible multiple tap, so has it been quick enough?
-          uint32_t timeDelta                    = event.time - mLastTapTime;
-          uint32_t deltaBetweenTouchDownTouchUp = event.time - mTouchTime;
-          if(timeDelta > MAXIMUM_TIME_ALLOWED) // If exceeded time between taps then just a single tap
+          uint32_t deltaBetweenLastTouchDownTouchUp = event.time - mLastTouchTime;
+          // Clear if the time between touch down and touch up is long.
+          if(deltaBetweenLastTouchDownTouchUp > mRecognizerTime)
           {
-            mLastTapTime = event.time;
-            EmitSingleTap(event.time, point);
-          }
-          else if(deltaBetweenTouchDownTouchUp < MAXIMUM_TIME_ALLOWED)
-          {
-            ++mTapsRegistered;
-            if(mMaximumTapsRequired > mMinimumTapsRequired)
-            {
-              mEventTime = event.time;
-              mTimerId   = platformAbstraction.StartTimer(WAIT_TIME, MakeCallback(this, &TapGestureRecognizer::TimerCallback));
-            }
-            else
-            {
-              EmitGesture(GestureState::STARTED, event.time);
-            }
+            mState = CLEAR;
           }
-          else // Delta between touch down and touch up too long to be considered a TAP event
+          else
           {
-            mState = CLEAR;
+            mLastTapTime = event.time;
+            EmitGesture(GestureState::STARTED, event.time);
           }
         }
         else if(pointState == PointState::DOWN)
@@ -184,11 +124,16 @@ void TapGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
           Vector2        distanceDelta(std::abs(mTouchPosition.x - screen.x),
                                 std::abs(mTouchPosition.y - screen.y));
 
-          uint32_t timeDelta = event.time - mLastTapTime;
+          uint32_t deltaBetweenInitTouchDownCurrentTouchDown = event.time - mTouchTime;
+          uint32_t timeDelta                                 = event.time - mLastTapTime;
+          mLastTouchTime                                     = event.time;
+          ++mTapsRegistered;
 
           if(distanceDelta.x > MAXIMUM_MOTION_ALLOWED ||
              distanceDelta.y > MAXIMUM_MOTION_ALLOWED ||
-             timeDelta > MAXIMUM_TIME_ALLOWED)
+             timeDelta > mMaximumAllowedTime ||                                 // If the time between tabs is long, it starts over from SetupForTouchDown.
+             deltaBetweenInitTouchDownCurrentTouchDown > mMaximumAllowedTime || // If it times out compared to the first touchdown time, it starts over from SetupForTouchDown.
+             mTapsRegistered > mMaximumTapsRequired)                            // If it is greater than MaximumTapsRequired, it starts over from SetupForTouchDown.
           {
             SetupForTouchDown(event, point);
           }
@@ -196,12 +141,6 @@ void TapGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
           {
             EmitPossibleState(event);
           }
-
-          if(mTimerId != 0)
-          {
-            platformAbstraction.CancelTimer(mTimerId);
-            mTimerId = 0;
-          }
         }
         break;
       }
@@ -223,14 +162,6 @@ void TapGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
   }
 }
 
-bool TapGestureRecognizer::TimerCallback()
-{
-  EmitGesture(GestureState::STARTED, mEventTime);
-
-  mTimerId = 0;
-  return false;
-}
-
 void TapGestureRecognizer::SetupForTouchDown(const Integration::TouchEvent& event, const Integration::Point& point)
 {
   mTouchPosition  = point.GetScreenPosition();
@@ -245,9 +176,8 @@ void TapGestureRecognizer::SetupForTouchDown(const Integration::TouchEvent& even
 void TapGestureRecognizer::EmitPossibleState(const Integration::TouchEvent& event)
 {
   TapGestureEvent tapEvent(GestureState::POSSIBLE);
-  tapEvent.point             = mTouchPosition;
-  tapEvent.time              = event.time;
-  tapEvent.gestureSourceType = mGestureSourceType;
+  tapEvent.point = mTouchPosition;
+  tapEvent.time  = event.time;
 
   ProcessEvent(tapEvent);
 }
@@ -260,6 +190,16 @@ void TapGestureRecognizer::Update(const GestureRequest& request)
   mMaximumTapsRequired = tap.maxTaps;
 }
 
+void TapGestureRecognizer::SetMaximumAllowedTime(uint32_t time)
+{
+  mMaximumAllowedTime = time;
+}
+
+void TapGestureRecognizer::SetRecognizerTime(uint32_t time)
+{
+  mRecognizerTime = time;
+}
+
 void TapGestureRecognizer::EmitGesture(GestureState state, uint32_t time)
 {
   if((state == GestureState::CANCELLED) ||
@@ -278,36 +218,28 @@ void TapGestureRecognizer::EmitSingleTap(uint32_t time, const Integration::Point
   Vector2         distanceDelta(std::abs(mTouchPosition.x - screen.x),
                         std::abs(mTouchPosition.y - screen.y));
 
-  mTapsRegistered = 1u;
   if(distanceDelta.x > MAXIMUM_MOTION_ALLOWED ||
      distanceDelta.y > MAXIMUM_MOTION_ALLOWED)
   {
     event.state = GestureState::CANCELLED;
-    if(mTimerId != 0)
-    {
-      Dali::Integration::PlatformAbstraction& platformAbstraction = ThreadLocalStorage::Get().GetPlatformAbstraction();
-      platformAbstraction.CancelTimer(mTimerId);
-      mTimerId = 0;
-    }
-  }
-  if(mTimerId == 0)
-  {
-    EmitTap(time, event);
   }
+  mTapsRegistered = 1u;
+  EmitTap(time, event);
 }
 
 void TapGestureRecognizer::EmitTap(uint32_t time, TapGestureEvent& event)
 {
-  event.numberOfTaps      = mTapsRegistered;
-  event.point             = mTouchPosition;
-  event.time              = time;
-  event.gestureSourceType = mGestureSourceType;
+  event.numberOfTaps = mTapsRegistered;
+  event.point        = mTouchPosition;
+  event.time         = time;
 
   ProcessEvent(event);
 }
 
 void TapGestureRecognizer::ProcessEvent(TapGestureEvent& event)
 {
+  event.sourceType = mSourceType;
+  event.sourceData = mSourceData;
   if(mScene)
   {
     // Create another handle so the recognizer cannot be destroyed during process function