Change the multi-tap recognition logic of TapGesture. 01/292901/19
authorjoogab.yun <joogab.yun@samsung.com>
Wed, 17 May 2023 00:55:16 +0000 (09:55 +0900)
committerjoogab.yun <joogab.yun@samsung.com>
Fri, 21 Jul 2023 06:37:27 +0000 (15:37 +0900)
Previously, we checked how many TouchDowns occurred within mMaximumAllowedTime.

Now, after a tap occurs, if the next touchdown occurs within mMaximumAllowedTime., it is recognized as a multi-tap.

ex) If it's a double tap, it's like this:
|(touch down <--recognizerTime--> touch up) <--  wihtin maximumAllowedTime --> (touch down <--recognizerTime--> touch up)|

Change-Id: I8b33bfbe09729d558bb8495738259ae5a757ddc9

automated-tests/src/dali/utc-Dali-TapGestureDetector.cpp
automated-tests/src/dali/utc-Dali-TapGestureRecognizer.cpp
dali/integration-api/input-options.h
dali/internal/event/events/gesture-event-processor.cpp
dali/internal/event/events/gesture-event-processor.h
dali/internal/event/events/tap-gesture/tap-gesture-detector-impl.cpp
dali/internal/event/events/tap-gesture/tap-gesture-detector-impl.h
dali/internal/event/events/tap-gesture/tap-gesture-processor.cpp
dali/internal/event/events/tap-gesture/tap-gesture-processor.h
dali/internal/event/events/tap-gesture/tap-gesture-recognizer.cpp
dali/internal/event/events/tap-gesture/tap-gesture-recognizer.h

index 6eeab2f..5c15b92 100644 (file)
@@ -318,20 +318,24 @@ int UtcDaliTapGestureSetTapsRequiredMinMaxCheck(void)
   application.SendNotification();
   application.Render();
 
-  // Set the minimum to be greater than the maximum, should Assert
+  SignalData             data;
+  GestureReceivedFunctor functor(data);
 
-  try
-  {
-    TapGestureDetector detector = TapGestureDetector::New();
-    detector.SetMinimumTapsRequired(7u);
-    detector.SetMaximumTapsRequired(3u);
-    detector.Attach(actor);
-    DALI_TEST_CHECK(false); // Should not get here
-  }
-  catch(DaliException& e)
-  {
-    DALI_TEST_CHECK(true);
-  }
+  // Set the minimum to be greater than the maximum, should not receive the tap event.
+  TapGestureDetector detector = TapGestureDetector::New();
+  detector.SetMinimumTapsRequired(2u);
+  detector.SetMaximumTapsRequired(1u);
+  detector.Attach(actor);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  TestGenerateTap(application, 50.0f, 50.0f, 100);
+  // detector don't get the tap event.
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+  data.Reset();
+
+  // detector don't get the tap event.
+  TestGenerateTap(application, 50.0f, 50.0f, 120);
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
   END_TEST;
 }
index 0d2064b..d70850c 100644 (file)
@@ -614,7 +614,7 @@ int UtcDaliTapGestureSetMaximumAllowedTime(void)
 
   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
 
-  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 300));
+  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 310));
 
   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 350));
 
index f35de12..2973a00 100644 (file)
@@ -201,12 +201,11 @@ DALI_CORE_API void SetLongPressMinimumHoldingTime(unsigned int value);
 /**
  * @brief Sets the maximum allowed time required to be recognized as a multi tap gesture (millisecond)
  *
- * Recognizes how many tap gestures occurred within the maximum allowed time interval.
- * If there are two tap gestures within this time, it is a double tap gesture.
- *
+ * This is the maximum allowable time interval to recognize as multi-tap.
+ * If taps come in within this time, they are recognized as multi-tap.
 *
  * @note If it's a double tap, it's like this:
- * |<---                                           maximumAllowedTime                                           --->|
- * |(touch down <--recognizerTime--> touch up) <-- maximumAllowedTime --> (touch down <--recognizerTime--> touch up)|
+ * |(touch down <--recognizerTime--> touch up) <--  wihtin maximumAllowedTime --> (touch down <--recognizerTime--> touch up)|
  *
  * @see SetTapRecognizerTime()
  *
index 2ca9caf..99dd285 100644 (file)
@@ -344,6 +344,11 @@ void GestureEventProcessor::SetTapRecognizerTime(uint32_t time)
   mTapGestureProcessor.SetRecognizerTime(time);
 }
 
+const TapGestureProcessor& GestureEventProcessor::GetTapGestureProcessor()
+{
+  return mTapGestureProcessor;
+}
+
 } // namespace Internal
 
 } // namespace Dali
index 9731fe6..212b6bf 100644 (file)
@@ -306,6 +306,11 @@ public: // needed for PanGesture
    */
   const PanGestureProcessor& GetPanGestureProcessor();
 
+  /**
+   * @return the tap gesture processor
+   */
+  const TapGestureProcessor& GetTapGestureProcessor();
+
 private:
   // Undefined
   GestureEventProcessor(const GestureEventProcessor&);
index 2f87991..7a04bc8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 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.
@@ -56,32 +56,21 @@ SignalConnectorType signalConnector1(mType, SIGNAL_TAP_DETECTED, &TapGestureDete
 
 TapGestureDetectorPtr TapGestureDetector::New()
 {
-  return new TapGestureDetector;
+  return new TapGestureDetector(DEFAULT_TAPS_REQUIRED);
 }
 
-TapGestureDetectorPtr TapGestureDetector::New(unsigned int tapsRequired)
+TapGestureDetectorPtr TapGestureDetector::New(uint32_t tapsRequired)
 {
   return new TapGestureDetector(tapsRequired);
 }
 
-TapGestureDetector::TapGestureDetector()
-: GestureDetector(GestureType::TAP),
-  mMinimumTapsRequired(DEFAULT_TAPS_REQUIRED),
-  mMaximumTapsRequired(DEFAULT_TAPS_REQUIRED),
-  mTouchesRequired(DEFAULT_TOUCHES_REQUIRED),
-  mTimerId(0),
-  mTappedActor(),
-  mTap(),
-  mReceiveAllTapEvents(false)
-{
-}
-
-TapGestureDetector::TapGestureDetector(unsigned int tapsRequired)
+TapGestureDetector::TapGestureDetector(uint32_t tapsRequired)
 : GestureDetector(GestureType::TAP),
   mMinimumTapsRequired(tapsRequired),
   mMaximumTapsRequired(tapsRequired),
   mTouchesRequired(DEFAULT_TOUCHES_REQUIRED),
-  mTimerId(0),
+  mTimerId(0u),
+  mWaitTime(DEFAULT_TAP_WAIT_TIME),
   mTappedActor(),
   mTap(),
   mReceiveAllTapEvents(false)
@@ -97,7 +86,21 @@ TapGestureDetector::~TapGestureDetector()
   }
 }
 
-void TapGestureDetector::SetMinimumTapsRequired(unsigned int taps)
+bool TapGestureDetector::CheckMinMaxTapsRequired()
+{
+  if(mMinimumTapsRequired > mMaximumTapsRequired)
+  {
+    DALI_LOG_ERROR("Minimum taps requested is greater than the maximum requested. minimumTapsRequired(%d) maximumTapsRequired(%d)\n", mMinimumTapsRequired, mMaximumTapsRequired);
+    return false;
+  }
+  else
+  {
+    return true;
+  }
+
+}
+
+void TapGestureDetector::SetMinimumTapsRequired(uint32_t taps)
 {
   if(mMinimumTapsRequired != taps)
   {
@@ -105,12 +108,12 @@ void TapGestureDetector::SetMinimumTapsRequired(unsigned int taps)
 
     if(!mAttachedActors.empty())
     {
-      mGestureEventProcessor.GestureDetectorUpdated(this);
+      CheckMinMaxTapsRequired();
     }
   }
 }
 
-void TapGestureDetector::SetMaximumTapsRequired(unsigned int taps)
+void TapGestureDetector::SetMaximumTapsRequired(uint32_t taps)
 {
   if(mMaximumTapsRequired != taps)
   {
@@ -118,12 +121,12 @@ void TapGestureDetector::SetMaximumTapsRequired(unsigned int taps)
 
     if(!mAttachedActors.empty())
     {
-      mGestureEventProcessor.GestureDetectorUpdated(this);
+      CheckMinMaxTapsRequired();
     }
   }
 }
 
-void TapGestureDetector::SetTouchesRequired(unsigned int touches)
+void TapGestureDetector::SetTouchesRequired(uint32_t touches)
 {
   if(mTouchesRequired != touches)
   {
@@ -136,17 +139,17 @@ void TapGestureDetector::SetTouchesRequired(unsigned int touches)
   }
 }
 
-unsigned int TapGestureDetector::GetMinimumTapsRequired() const
+uint32_t TapGestureDetector::GetMinimumTapsRequired() const
 {
   return mMinimumTapsRequired;
 }
 
-unsigned int TapGestureDetector::GetMaximumTapsRequired() const
+uint32_t TapGestureDetector::GetMaximumTapsRequired() const
 {
   return mMaximumTapsRequired;
 }
 
-unsigned int TapGestureDetector::GetTouchesRequired() const
+uint32_t TapGestureDetector::GetTouchesRequired() const
 {
   return mTouchesRequired;
 }
@@ -158,6 +161,11 @@ void TapGestureDetector::ReceiveAllTapEvents(bool receive)
 
 void TapGestureDetector::EmitTapGestureSignal(Dali::Actor tappedActor, const Dali::TapGesture& tap)
 {
+  if(!CheckMinMaxTapsRequired())
+  {
+    return;
+  }
+
   Dali::Integration::PlatformAbstraction& platformAbstraction = ThreadLocalStorage::Get().GetPlatformAbstraction();
   if(mTimerId != 0)
   {
@@ -165,32 +173,35 @@ void TapGestureDetector::EmitTapGestureSignal(Dali::Actor tappedActor, const Dal
     mTimerId = 0;
   }
 
-  if(mMaximumTapsRequired == 0u)
+  uint32_t numberOfTaps = 0u;
+  if(mMaximumTapsRequired > 0u)
   {
-    return;
-  }
-
-  uint32_t                numberOfTaps = tap.GetNumberOfTaps() % mMaximumTapsRequired;
-  Internal::TapGesturePtr internalTap(new Internal::TapGesture(tap.GetState()));
-  internalTap->SetTime(tap.GetTime());
-  internalTap->SetNumberOfTouches(tap.GetNumberOfTouches());
-  internalTap->SetScreenPoint(tap.GetScreenPoint());
-  internalTap->SetLocalPoint(tap.GetLocalPoint());
-  internalTap->SetSourceType(tap.GetSourceType());
-  internalTap->SetSourceData(tap.GetSourceData());
-  internalTap->SetNumberOfTaps(numberOfTaps == 0u ? mMaximumTapsRequired : numberOfTaps);
-  mTap = Dali::TapGesture(internalTap.Get());
-  if(numberOfTaps == 0u || mReceiveAllTapEvents)
-  {
-    // Guard against destruction during signal emission
-    Dali::TapGestureDetector handle(this);
-
-    mDetectedSignal.Emit(tappedActor, mTap);
-  }
-  else
-  {
-    mTappedActor = tappedActor;
-    mTimerId     = platformAbstraction.StartTimer(DEFAULT_TAP_WAIT_TIME, MakeCallback(this, &TapGestureDetector::TimerCallback));
+    numberOfTaps = tap.GetNumberOfTaps() % mMaximumTapsRequired;
+    numberOfTaps = numberOfTaps == 0u ? mMaximumTapsRequired : numberOfTaps;
+    if (numberOfTaps >= mMinimumTapsRequired)
+    {
+      Internal::TapGesturePtr internalTap(new Internal::TapGesture(tap.GetState()));
+      internalTap->SetTime(tap.GetTime());
+      internalTap->SetNumberOfTouches(tap.GetNumberOfTouches());
+      internalTap->SetScreenPoint(tap.GetScreenPoint());
+      internalTap->SetLocalPoint(tap.GetLocalPoint());
+      internalTap->SetSourceType(tap.GetSourceType());
+      internalTap->SetSourceData(tap.GetSourceData());
+      internalTap->SetNumberOfTaps(numberOfTaps);
+      mTap = Dali::TapGesture(internalTap.Get());
+      if(numberOfTaps == mMaximumTapsRequired || mReceiveAllTapEvents)
+      {
+        // Guard against destruction during signal emission
+        Dali::TapGestureDetector handle(this);
+
+        mDetectedSignal.Emit(tappedActor, mTap);
+      }
+      else
+      {
+        mTappedActor = tappedActor;
+        mTimerId     = platformAbstraction.StartTimer(mWaitTime, MakeCallback(this, &TapGestureDetector::TimerCallback));
+      }
+    }
   }
 }
 
@@ -225,7 +236,8 @@ bool TapGestureDetector::DoConnectSignal(BaseObject* object, ConnectionTrackerIn
 
 void TapGestureDetector::OnActorAttach(Actor& actor)
 {
-  // Do nothing
+  CheckMinMaxTapsRequired();
+  mWaitTime = mGestureEventProcessor.GetTapGestureProcessor().GetMaximumAllowedTime();
 }
 
 void TapGestureDetector::OnActorDetach(Actor& actor)
index 1dd5dc8..0f4b8b6 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_TAP_GESTURE_DETECTOR_H
 
 /*
- * 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.
@@ -49,49 +49,44 @@ public: // Creation
    * @param[in]  tapsRequired     The number of taps required.
    * @return A smart-pointer to the newly allocated detector.
    */
-  static TapGestureDetectorPtr New(unsigned int tapsRequired);
-
-  /**
-   * Construct a new GestureDetector.
-   */
-  TapGestureDetector();
+  static TapGestureDetectorPtr New(uint32_t tapsRequired);
 
   /**
    * Construct a new GestureDetector with the specified parameters.
    * @param[in]  tapsRequired     The number of taps required.
    */
-  TapGestureDetector(unsigned int tapsRequired);
+  TapGestureDetector(uint32_t tapsRequired);
 
 public:
   /**
-   * @copydoc Dali::TapGestureDetector::SetTouchesRequired(unsigned int)
+   * @copydoc Dali::TapGestureDetector::SetTouchesRequired(uint32_t)
    */
-  void SetTouchesRequired(unsigned int touches);
+  void SetTouchesRequired(uint32_t touches);
 
   /**
    * @copydoc Dali::TapGestureDetector::SetMinimumTapsRequired()
    */
-  void SetMinimumTapsRequired(unsigned int minTaps);
+  void SetMinimumTapsRequired(uint32_t minTaps);
 
   /**
    * @copydoc Dali::TapGestureDetector::SetMaximumTapsRequired()
    */
-  void SetMaximumTapsRequired(unsigned int maxTaps);
+  void SetMaximumTapsRequired(uint32_t maxTaps);
 
   /**
    * @copydoc Dali::TapGestureDetector::GetMinimumTapsRequired()
    */
-  unsigned int GetMinimumTapsRequired() const;
+  uint32_t GetMinimumTapsRequired() const;
 
   /**
    * @copydoc Dali::TapGestureDetector::SetMaximumTapsRequired()
    */
-  unsigned int GetMaximumTapsRequired() const;
+  uint32_t GetMaximumTapsRequired() const;
 
   /**
    * @copydoc Dali::TapGestureDetector::GetTouchesRequired()
    */
-  unsigned int GetTouchesRequired() const;
+  uint32_t GetTouchesRequired() const;
 
   /**
    * @copydoc Dali::TapGestureDetector::ReceiveAllTapEvents()
@@ -144,6 +139,12 @@ private:
    */
   bool TimerCallback();
 
+  /**
+   * @brief Checks if MinimumTapsRequired is less than or equal to MaximumTapsRequired.
+   * @return true if MinimumTapsRequired is less than or equal to MaximumTapsRequired.
+   */
+  bool CheckMinMaxTapsRequired();
+
 private: // GestureDetector overrides
   /**
    * @copydoc Dali::Internal::GestureDetector::OnActorAttach(Actor&)
@@ -163,10 +164,11 @@ private: // GestureDetector overrides
 private:
   Dali::TapGestureDetector::DetectedSignalType mDetectedSignal;
 
-  unsigned int     mMinimumTapsRequired;
-  unsigned int     mMaximumTapsRequired;
-  unsigned int     mTouchesRequired;
+  uint32_t         mMinimumTapsRequired; ///< Minimum number of taps required.
+  uint32_t         mMaximumTapsRequired; ///< Maximum number of taps required.
+  uint32_t         mTouchesRequired;
   uint32_t         mTimerId;
+  uint32_t         mWaitTime;
   Dali::Actor      mTappedActor;
   Dali::TapGesture mTap;
   bool             mReceiveAllTapEvents;
index 04574ba..7486056 100644 (file)
@@ -43,8 +43,8 @@ namespace Internal
 namespace
 {
 DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_PERFORMANCE_MARKER, false);
-constexpr uint32_t DEFAULT_MAXIMUM_ALLOWED_TIME = 500u;
-constexpr uint32_t DEFAULT_RECOGNIZER_TIME      = 500u;
+constexpr uint32_t DEFAULT_MAXIMUM_ALLOWED_TIME = 330u;
+constexpr uint32_t DEFAULT_RECOGNIZER_TIME      = 330u;
 
 /**
  * Creates a TapGesture and asks the specified detector to emit its detected signal.
@@ -83,8 +83,6 @@ void EmitTapSignal(
 TapGestureProcessor::TapGestureProcessor()
 : GestureProcessor(GestureType::TAP),
   mTapGestureDetectors(),
-  mMinTapsRequired(1),
-  mMaxTapsRequired(1),
   mMinTouchesRequired(1),
   mMaxTouchesRequired(1),
   mCurrentTapEvent(nullptr),
@@ -169,24 +167,16 @@ void TapGestureProcessor::AddGestureDetector(TapGestureDetector* gestureDetector
 
   mTapGestureDetectors.push_back(gestureDetector);
 
-  const unsigned int minTapsRequired = gestureDetector->GetMinimumTapsRequired();
-  const unsigned int maxTapsRequired = gestureDetector->GetMaximumTapsRequired();
   const unsigned int touchesRequired = gestureDetector->GetTouchesRequired();
 
-  DALI_ASSERT_ALWAYS(minTapsRequired <= maxTapsRequired && "Minimum taps requested is greater than the maximum requested");
-
   if(firstRegistration)
   {
     // If this is the first tap gesture detector that has been added, then our minimum and maximum
     // requirements are the same as each other.
 
-    mMinTapsRequired    = minTapsRequired;
-    mMaxTapsRequired    = maxTapsRequired;
     mMinTouchesRequired = mMaxTouchesRequired = touchesRequired;
 
     TapGestureRequest request;
-    request.minTaps    = mMinTapsRequired;
-    request.maxTaps    = mMaxTapsRequired;
     request.minTouches = mMinTouchesRequired;
     request.maxTouches = mMaxTouchesRequired;
 
@@ -201,17 +191,12 @@ void TapGestureProcessor::AddGestureDetector(TapGestureDetector* gestureDetector
 
     // This is quicker than calling UpdateDetection as there is no need to iterate through the container
 
-    unsigned int minTaps    = mMinTapsRequired < minTapsRequired ? mMinTapsRequired : minTapsRequired;
-    unsigned int maxTaps    = mMaxTapsRequired > maxTapsRequired ? mMaxTapsRequired : maxTapsRequired;
     unsigned int minTouches = mMinTouchesRequired < touchesRequired ? mMinTouchesRequired : touchesRequired;
     unsigned int maxTouches = mMaxTouchesRequired > touchesRequired ? mMaxTouchesRequired : touchesRequired;
 
-    if((minTaps != mMinTapsRequired) || (maxTaps != mMaxTapsRequired) ||
-       (minTouches != mMinTouchesRequired) || (maxTouches != mMaxTouchesRequired))
+    if((minTouches != mMinTouchesRequired) || (maxTouches != mMaxTouchesRequired))
     {
       TapGestureRequest request;
-      request.minTaps = mMinTapsRequired = minTaps;
-      request.maxTaps = mMaxTapsRequired = maxTaps;
       request.minTouches = mMinTouchesRequired = minTouches;
       request.maxTouches = mMaxTouchesRequired = maxTouches;
 
@@ -243,14 +228,7 @@ void TapGestureProcessor::RemoveGestureDetector(TapGestureDetector* gestureDetec
 
 void TapGestureProcessor::GestureDetectorUpdated(TapGestureDetector* gestureDetector)
 {
-  DALI_ASSERT_DEBUG(find(mTapGestureDetectors.begin(), mTapGestureDetectors.end(), gestureDetector) != mTapGestureDetectors.end());
-
-  const unsigned int minTapsRequired = gestureDetector->GetMinimumTapsRequired();
-  const unsigned int maxTapsRequired = gestureDetector->GetMaximumTapsRequired();
-
-  DALI_ASSERT_ALWAYS(minTapsRequired <= maxTapsRequired && "Minimum taps requested is greater than the maximum requested");
-
-  UpdateDetection();
+  // Nothing to do.
 }
 
 void TapGestureProcessor::SetMaximumAllowedTime(uint32_t time)
@@ -275,6 +253,11 @@ void TapGestureProcessor::SetMaximumAllowedTime(uint32_t time)
   }
 }
 
+uint32_t TapGestureProcessor::GetMaximumAllowedTime() const
+{
+  return mMaximumAllowedTime;
+}
+
 void TapGestureProcessor::SetRecognizerTime(uint32_t time)
 {
   if(time == 0u)
@@ -301,8 +284,6 @@ void TapGestureProcessor::UpdateDetection()
 {
   DALI_ASSERT_DEBUG(!mTapGestureDetectors.empty());
 
-  unsigned int minTaps    = UINT_MAX;
-  unsigned int maxTaps    = 0;
   unsigned int minTouches = UINT_MAX;
   unsigned int maxTouches = 0;
 
@@ -312,23 +293,16 @@ void TapGestureProcessor::UpdateDetection()
 
     if(detector)
     {
-      const unsigned int minTapsRequired = detector->GetMinimumTapsRequired();
-      const unsigned int maxTapsRequired = detector->GetMaximumTapsRequired();
       const unsigned int touchesRequired = detector->GetTouchesRequired();
 
-      minTaps    = minTapsRequired < minTaps ? minTapsRequired : minTaps;
-      maxTaps    = maxTapsRequired > maxTaps ? maxTapsRequired : maxTaps;
       minTouches = touchesRequired < minTouches ? touchesRequired : minTouches;
       maxTouches = touchesRequired > maxTouches ? touchesRequired : maxTouches;
     }
   }
 
-  if((minTaps != mMinTapsRequired) || (maxTaps != mMaxTapsRequired) ||
-     (minTouches != mMinTouchesRequired) || (maxTouches != mMaxTouchesRequired))
+  if((minTouches != mMinTouchesRequired) || (maxTouches != mMaxTouchesRequired))
   {
     TapGestureRequest request;
-    request.minTaps = mMinTapsRequired = minTaps;
-    request.maxTaps = mMaxTapsRequired = maxTaps;
     request.minTouches = mMinTouchesRequired = minTouches;
     request.maxTouches = mMaxTouchesRequired = maxTouches;
 
index 726d77e..6b1ab28 100644 (file)
@@ -92,6 +92,13 @@ public: // To be called by GestureEventProcessor
   void SetMaximumAllowedTime(uint32_t time);
 
   /**
+   * @brief This method gets the maximum allowed time (millisecond)
+   *
+   * @return The time value in milliseconds
+   */
+  uint32_t GetMaximumAllowedTime() const;
+
+  /**
    * @brief This method sets the recognizer time required to be recognized as a tap gesture (millisecond)
    *
    * This time is from touch down to touch up to recognize the tap gesture.
@@ -134,8 +141,6 @@ private:
 private:
   TapGestureDetectorContainer mTapGestureDetectors;
 
-  unsigned int mMinTapsRequired;
-  unsigned int mMaxTapsRequired;
   unsigned int mMinTouchesRequired;
   unsigned int mMaxTouchesRequired;
 
index 609c161..932de4a 100644 (file)
@@ -43,13 +43,11 @@ TapGestureRecognizer::TapGestureRecognizer(Observer& observer, Vector2 screenSiz
 : GestureRecognizer(screenSize, GestureType::TAP),
   mObserver(observer),
   mState(CLEAR),
-  mMinimumTapsRequired(request.minTaps),
-  mMaximumTapsRequired(request.maxTaps),
-  mTapsRegistered(0),
   mTouchPosition(),
+  mTapsRegistered(0u),
   mTouchTime(0u),
   mLastTapTime(0u),
-  mLastTouchTime(0u),
+  mDeltaBetweenTouchDownTouchUp(0u),
   mMaximumAllowedTime(maximumAllowedTime),
   mRecognizerTime(recognizerTime)
 {
@@ -60,7 +58,6 @@ TapGestureRecognizer::~TapGestureRecognizer() = default;
 void TapGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
 {
   GestureRecognizerPtr ptr(this); // To keep us from being destroyed during the life-time of this method
-
   if(event.GetPointCount() == 1)
   {
     const Integration::Point& point      = event.points[0];
@@ -73,24 +70,21 @@ void TapGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
         if(pointState == PointState::DOWN)
         {
           SetupForTouchDown(event, point);
-          mLastTouchTime = event.time;
         }
         break;
       }
 
       case TOUCHED:
       {
-        uint32_t deltaBetweenTouchDownTouchUp = event.time - mTouchTime;
-
         if(pointState == PointState::UP)
         {
-          if(deltaBetweenTouchDownTouchUp < mRecognizerTime)
+          mDeltaBetweenTouchDownTouchUp = event.time - mTouchTime;
+          if(mDeltaBetweenTouchDownTouchUp < mRecognizerTime)
           {
-            mLastTapTime = event.time;
             EmitSingleTap(event.time, point);
             mState = REGISTERED;
           }
-          else
+          else // Clear if the time between touch down and touch up is long.
           {
             mState = CLEAR;
           }
@@ -106,16 +100,14 @@ void TapGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
       {
         if(pointState == PointState::UP)
         {
-          uint32_t deltaBetweenLastTouchDownTouchUp = event.time - mLastTouchTime;
-          // Clear if the time between touch down and touch up is long.
-          if(deltaBetweenLastTouchDownTouchUp > mRecognizerTime)
+          mDeltaBetweenTouchDownTouchUp = event.time - mTouchTime;
+          if(mDeltaBetweenTouchDownTouchUp < mRecognizerTime)
           {
-            mState = CLEAR;
+            EmitGesture(GestureState::STARTED, event.time);
           }
-          else
+          else // Clear if the time between touch down and touch up is long.
           {
-            mLastTapTime = event.time;
-            EmitGesture(GestureState::STARTED, event.time);
+            mState = CLEAR;
           }
         }
         else if(pointState == PointState::DOWN)
@@ -124,16 +116,12 @@ void TapGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
           Vector2        distanceDelta(std::abs(mTouchPosition.x - screen.x),
                                 std::abs(mTouchPosition.y - screen.y));
 
-          uint32_t deltaBetweenInitTouchDownCurrentTouchDown = event.time - mTouchTime;
-          uint32_t timeDelta                                 = event.time - mLastTapTime;
-          mLastTouchTime                                     = event.time;
-          ++mTapsRegistered;
+          uint32_t timeDelta = event.time - mLastTapTime;
+          mTouchTime         = event.time;
 
           if(distanceDelta.x > MAXIMUM_MOTION_ALLOWED ||
              distanceDelta.y > MAXIMUM_MOTION_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.
+             timeDelta > mMaximumAllowedTime) // If the time between tabs is long, it starts over from SetupForTouchDown.
           {
             SetupForTouchDown(event, point);
           }
@@ -156,19 +144,16 @@ void TapGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
   else
   {
     mState = FAILED;
-
-    // We have entered a multi-touch event so emit registered gestures if required.
-    EmitGesture(GestureState::STARTED, event.time);
   }
 }
 
 void TapGestureRecognizer::SetupForTouchDown(const Integration::TouchEvent& event, const Integration::Point& point)
 {
-  mTouchPosition  = point.GetScreenPosition();
-  mTouchTime      = event.time;
-  mLastTapTime    = 0u;
-  mTapsRegistered = 0;
-  mState          = TOUCHED;
+  mTouchPosition = point.GetScreenPosition();
+  mTouchTime     = event.time;
+  mLastTapTime   = 0u;
+  mState         = TOUCHED;
+  mTapsRegistered = 0u;
 
   EmitPossibleState(event);
 }
@@ -184,10 +169,7 @@ void TapGestureRecognizer::EmitPossibleState(const Integration::TouchEvent& even
 
 void TapGestureRecognizer::Update(const GestureRequest& request)
 {
-  const TapGestureRequest& tap = static_cast<const TapGestureRequest&>(request);
-
-  mMinimumTapsRequired = tap.minTaps;
-  mMaximumTapsRequired = tap.maxTaps;
+  // Nothing to do.
 }
 
 void TapGestureRecognizer::SetMaximumAllowedTime(uint32_t time)
@@ -202,13 +184,8 @@ void TapGestureRecognizer::SetRecognizerTime(uint32_t time)
 
 void TapGestureRecognizer::EmitGesture(GestureState state, uint32_t time)
 {
-  if((state == GestureState::CANCELLED) ||
-     (mTapsRegistered >= mMinimumTapsRequired && mTapsRegistered <= mMaximumTapsRequired))
-
-  {
-    TapGestureEvent event(state);
-    EmitTap(time, event);
-  }
+  TapGestureEvent event(state);
+  EmitTap(time, event);
 }
 
 void TapGestureRecognizer::EmitSingleTap(uint32_t time, const Integration::Point& point)
@@ -223,15 +200,15 @@ void TapGestureRecognizer::EmitSingleTap(uint32_t time, const Integration::Point
   {
     event.state = GestureState::CANCELLED;
   }
-  mTapsRegistered = 1u;
   EmitTap(time, event);
 }
 
 void TapGestureRecognizer::EmitTap(uint32_t time, TapGestureEvent& event)
 {
-  event.numberOfTaps = mTapsRegistered;
-  event.point        = mTouchPosition;
-  event.time         = time;
+  event.numberOfTaps = ++mTapsRegistered;
+  event.point  = mTouchPosition;
+  event.time   = time;
+  mLastTapTime = event.time;
 
   ProcessEvent(event);
 }
index e8e36a8..158b9a0 100644 (file)
@@ -150,17 +150,13 @@ private:
 
   State mState; ///< Current state of the detector.
 
-  int mMinimumTapsRequired; ///< Minimum number of taps required.
-  int mMaximumTapsRequired; ///< Maximum number of taps required.
-  int mTapsRegistered;      ///< In current detection, the number of taps registered.
-
-  Vector2  mTouchPosition; ///< The initial touch down position.
-  uint32_t mTouchTime;     ///< The initial touch down time.
-  uint32_t mLastTapTime;   ///< Time last tap gesture was registered
-  uint32_t mLastTouchTime; ///< The last touch down time.
-
-  uint32_t mMaximumAllowedTime; ///< The maximum allowed time required to be recognized as a multi tap gesture (millisecond)
-  uint32_t mRecognizerTime;     ///< The recognizer time required to be recognized as a tap gesture (millisecond)
+  Vector2  mTouchPosition;                ///< The initial touch down position.
+  uint32_t mTapsRegistered;               ///< In current detection, the number of taps registered.
+  uint32_t mTouchTime;                    ///< The touch down time.
+  uint32_t mLastTapTime;                  ///< Time last tap gesture was registered
+  uint32_t mDeltaBetweenTouchDownTouchUp; ///< Time from touchdown to touchup
+  uint32_t mMaximumAllowedTime;           ///< The maximum allowed time required to be recognized as a multi tap gesture (millisecond)
+  uint32_t mRecognizerTime;               ///< The recognizer time required to be recognized as a tap gesture (millisecond)
 };
 
 } // namespace Internal