[Tizen] Add SetTapMaximumMotionAllowedDistance 36/308636/1 accepted/tizen/8.0/unified/20240401.145116
authorjoogab.yun <joogab.yun@samsung.com>
Thu, 28 Mar 2024 05:03:47 +0000 (14:03 +0900)
committerjoogab.yun <joogab.yun@samsung.com>
Thu, 28 Mar 2024 09:02:30 +0000 (18:02 +0900)
Change-Id: I5c8dd3304774f73d2bda7ca5566406b05039e233

automated-tests/src/dali/utc-Dali-TapGestureRecognizer.cpp
dali/integration-api/input-options.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-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 d70850c..70b1291 100644 (file)
@@ -685,3 +685,60 @@ int UtcDaliTapGestureSetRecognizerTime(void)
 
   END_TEST;
 }
+
+int UtcDaliTapGestureSetMaximumMotionAllowedDistance(void)
+{
+  TestApplication application;
+
+  TapGestureDetector detector = TapGestureDetector::New();
+
+  Actor actor = Actor::New();
+  actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  application.GetScene().Add(actor);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  detector.Attach(actor);
+
+  try
+  {
+    Integration::SetTapMaximumMotionAllowedDistance(0);
+  }
+  catch(...)
+  {
+    DALI_TEST_CHECK(false); // Should not get here
+  }
+
+  // increase the distance. 20 -> 50
+  Integration::SetTapMaximumMotionAllowedDistance(50);
+
+  SignalData             data;
+  GestureReceivedFunctor functor(data);
+  detector.DetectedSignal().Connect(&application, functor);
+
+  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 150));
+
+  application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(60.0f, 60.0f), 200));
+
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  data.Reset();
+
+  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 300));
+
+  application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(80.0f, 80.0f), 450));
+
+  application.SendNotification();
+
+  // The tap fails because the distance has been exceeded
+  DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+  // reset distance
+  Integration::SetTapMaximumMotionAllowedDistance(20);
+
+  END_TEST;
+}
index 48a2a19..27b1025 100644 (file)
@@ -160,6 +160,12 @@ void SetTapRecognizerTime(uint32_t time)
   eventProcessor.SetTapRecognizerTime(time);
 }
 
+void SetTapMaximumMotionAllowedDistance(float distance)
+{
+  GestureEventProcessor& eventProcessor = ThreadLocalStorage::Get().GetGestureEventProcessor();
+  eventProcessor.SetTapMaximumMotionAllowedDistance(distance);
+}
+
 } // namespace Integration
 
 } // namespace Dali
index 2973a00..ff1ead2 100644 (file)
@@ -228,6 +228,22 @@ DALI_CORE_API void SetTapMaximumAllowedTime(uint32_t time);
  */
 DALI_CORE_API void SetTapRecognizerTime(uint32_t time);
 
+/**
+ * @brief Sets the recognizer distance required to be recognized as a tap gesture
+ *
+ * This distance is from touch down to touch up to recognize the tap gesture.
+ *
+ * @note The tab is like below:
+ * touch down <--distance--> touch up
+ * If the distance between touch down and touch up is longer than distance, it is not recognized as a tap gesture.
+ * Default value is 20
+ *
+ * @see SetTapMaximumMotionAllowedDistance()
+ *
+ * @param[in] distance The distance
+ */
+DALI_CORE_API void SetTapMaximumMotionAllowedDistance(float distance);
+
 } // namespace Integration
 
 } // namespace Dali
index 2664557..135097d 100644 (file)
@@ -386,6 +386,11 @@ void GestureEventProcessor::SetTapRecognizerTime(uint32_t time)
   mTapGestureProcessor.SetRecognizerTime(time);
 }
 
+void GestureEventProcessor::SetTapMaximumMotionAllowedDistance(float distance)
+{
+  mTapGestureProcessor.SetMaximumMotionAllowedDistance(distance);
+}
+
 const TapGestureProcessor& GestureEventProcessor::GetTapGestureProcessor()
 {
   return mTapGestureProcessor;
index f606971..8f3431f 100644 (file)
@@ -310,6 +310,15 @@ public: // Called by Core
    */
   void SetTapRecognizerTime(uint32_t time);
 
+  /**
+   * @brief Sets the recognizer distance required to be recognized as a tap gesture
+   *
+   * This distance is from touch down to touch up to recognize the tap gesture.
+   *
+   * @param[in] distance The distance
+   */
+  void SetTapMaximumMotionAllowedDistance(float distance);
+
 public: // needed for PanGesture
   /**
    * @return the pan gesture processor
index ceb185f..c2dc673 100644 (file)
@@ -45,6 +45,8 @@ namespace
 DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_PERFORMANCE_MARKER, false);
 constexpr uint32_t DEFAULT_MAXIMUM_ALLOWED_TIME = 330u;
 constexpr uint32_t DEFAULT_RECOGNIZER_TIME      = 330u;
+// TODO: Set these according to DPI
+constexpr float DEFAULT_MAXIMUM_MOTION_ALLOWED = 20.0f;
 
 /**
  * Creates a TapGesture and asks the specified detector to emit its detected signal.
@@ -94,7 +96,8 @@ TapGestureProcessor::TapGestureProcessor()
   mCurrentTapEvent(nullptr),
   mPossibleProcessed(false),
   mMaximumAllowedTime(DEFAULT_MAXIMUM_ALLOWED_TIME),
-  mRecognizerTime(DEFAULT_RECOGNIZER_TIME)
+  mRecognizerTime(DEFAULT_RECOGNIZER_TIME),
+  mMaximumMotionAllowedDistance(DEFAULT_MAXIMUM_MOTION_ALLOWED)
 {
 }
 
@@ -216,7 +219,7 @@ void TapGestureProcessor::AddGestureDetector(TapGestureDetector* gestureDetector
     request.maxTouches = mMaxTouchesRequired;
 
     Size size          = scene.GetSize();
-    mGestureRecognizer = new TapGestureRecognizer(*this, Vector2(size.width, size.height), static_cast<const TapGestureRequest&>(request), mMaximumAllowedTime, mRecognizerTime);
+    mGestureRecognizer = new TapGestureRecognizer(*this, Vector2(size.width, size.height), static_cast<const TapGestureRequest&>(request), mMaximumAllowedTime, mRecognizerTime, mMaximumMotionAllowedDistance);
   }
   else
   {
@@ -315,6 +318,26 @@ void TapGestureProcessor::SetRecognizerTime(uint32_t time)
   }
 }
 
+void TapGestureProcessor::SetMaximumMotionAllowedDistance(float distance)
+{
+  if(distance < 0.0f)
+  {
+    DALI_LOG_WARNING("distance must be greater than zero.");
+    return;
+  }
+
+  mMaximumMotionAllowedDistance = distance;
+
+  if(mGestureRecognizer)
+  {
+    TapGestureRecognizer* tapRecognizer = dynamic_cast<TapGestureRecognizer*>(mGestureRecognizer.Get());
+    if(tapRecognizer)
+    {
+      tapRecognizer->SetMaximumMotionAllowedDistance(distance);
+    }
+  }
+}
+
 void TapGestureProcessor::UpdateDetection()
 {
   DALI_ASSERT_DEBUG(!mTapGestureDetectors.empty());
index 6b1ab28..5296942 100644 (file)
@@ -107,6 +107,15 @@ public: // To be called by GestureEventProcessor
    */
   void SetRecognizerTime(uint32_t time);
 
+  /**
+   * @brief This method sets the recognizer distance required to be recognized as a tap gesture
+   *
+   * This distance is from touch down to touch up to recognize the tap gesture.
+   *
+   * @param[in] distance The distance
+   */
+  void SetMaximumMotionAllowedDistance(float distance);
+
 private:
   // Undefined
   TapGestureProcessor(const TapGestureProcessor&);
@@ -141,15 +150,16 @@ private:
 private:
   TapGestureDetectorContainer mTapGestureDetectors;
 
-  unsigned int mMinTouchesRequired;
-  unsigned int mMaxTouchesRequired;
+  uint32_t mMinTouchesRequired;
+  uint32_t mMaxTouchesRequired;
 
   ActorObserver          mCurrentTapActor;   ///< Observer for the current gesture actor
   const TapGestureEvent* mCurrentTapEvent;   ///< Pointer to current TapEvent, used when calling ProcessAndEmit()
   bool                   mPossibleProcessed; ///< Indication of whether we've processed a touch down for this gestuee
 
-  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)
+  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)
+  float    mMaximumMotionAllowedDistance;    ///< The recognizer distance required to be recognized as a tap gesture
 };
 
 } // namespace Internal
index cfa5d72..a47c8c5 100644 (file)
@@ -33,13 +33,8 @@ namespace Dali
 {
 namespace Internal
 {
-namespace
-{
-// TODO: Set these according to DPI
-constexpr float MAXIMUM_MOTION_ALLOWED = 20.0f;
-} // unnamed namespace
 
-TapGestureRecognizer::TapGestureRecognizer(Observer& observer, Vector2 screenSize, const TapGestureRequest& request, uint32_t maximumAllowedTime, uint32_t recognizerTime)
+TapGestureRecognizer::TapGestureRecognizer(Observer& observer, Vector2 screenSize, const TapGestureRequest& request, uint32_t maximumAllowedTime, uint32_t recognizerTime, float maximumMotionAllowedDistance)
 : GestureRecognizer(screenSize, GestureType::TAP),
   mObserver(observer),
   mState(CLEAR),
@@ -49,7 +44,8 @@ TapGestureRecognizer::TapGestureRecognizer(Observer& observer, Vector2 screenSiz
   mLastTapTime(0u),
   mDeltaBetweenTouchDownTouchUp(0u),
   mMaximumAllowedTime(maximumAllowedTime),
-  mRecognizerTime(recognizerTime)
+  mRecognizerTime(recognizerTime),
+  mMaximumMotionAllowedDistance(maximumMotionAllowedDistance)
 {
 }
 
@@ -104,7 +100,19 @@ void TapGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
           mDeltaBetweenTouchDownTouchUp = event.time - mTouchTime;
           if(mDeltaBetweenTouchDownTouchUp < mRecognizerTime)
           {
-            EmitGesture(GestureState::STARTED, event.time);
+            const Vector2& screen(point.GetScreenPosition());
+            Vector2        distanceDelta(std::abs(mTouchPosition.x - screen.x),
+                                std::abs(mTouchPosition.y - screen.y));
+            if(distanceDelta.x > mMaximumMotionAllowedDistance ||
+               distanceDelta.y > mMaximumMotionAllowedDistance)
+            {
+              mState = CLEAR;
+              DALI_LOG_RELEASE_INFO("There is a long distance between touch down and touch up. (%f or %f > %f)\n", distanceDelta.x, distanceDelta.y, mMaximumMotionAllowedDistance);
+            }
+            else
+            {
+              EmitGesture(GestureState::STARTED, event.time);
+            }
           }
           else // Clear if the time between touch down and touch up is long.
           {
@@ -121,8 +129,8 @@ void TapGestureRecognizer::SendEvent(const Integration::TouchEvent& event)
           uint32_t timeDelta = event.time - mLastTapTime;
           mTouchTime         = event.time;
 
-          if(distanceDelta.x > MAXIMUM_MOTION_ALLOWED ||
-             distanceDelta.y > MAXIMUM_MOTION_ALLOWED ||
+          if(distanceDelta.x > mMaximumMotionAllowedDistance ||
+             distanceDelta.y > mMaximumMotionAllowedDistance ||
              timeDelta > mMaximumAllowedTime) // If the time between tabs is long, it starts over from SetupForTouchDown.
           {
             SetupForTouchDown(event, point);
@@ -184,6 +192,11 @@ void TapGestureRecognizer::SetRecognizerTime(uint32_t time)
   mRecognizerTime = time;
 }
 
+void TapGestureRecognizer::SetMaximumMotionAllowedDistance(float distance)
+{
+  mMaximumMotionAllowedDistance = distance;
+}
+
 void TapGestureRecognizer::EmitGesture(GestureState state, uint32_t time)
 {
   TapGestureEvent event(state);
@@ -197,8 +210,8 @@ void TapGestureRecognizer::EmitSingleTap(uint32_t time, const Integration::Point
   Vector2         distanceDelta(std::abs(mTouchPosition.x - screen.x),
                         std::abs(mTouchPosition.y - screen.y));
 
-  if(distanceDelta.x > MAXIMUM_MOTION_ALLOWED ||
-     distanceDelta.y > MAXIMUM_MOTION_ALLOWED)
+  if(distanceDelta.x > mMaximumMotionAllowedDistance ||
+     distanceDelta.y > mMaximumMotionAllowedDistance)
   {
     event.state = GestureState::CANCELLED;
   }
index 158b9a0..b36406c 100644 (file)
@@ -53,8 +53,9 @@ public:
    * @param[in]  request     The tap gesture request.
    * @param[in]  maximumAllowedTime    The maximum allowed time required in milliseconds.
    * @param[in]  recognizerTime    This recognizer time required in milliseconds.
+   * @param[in]  maximumMotionAllowedDistance    This recognizer distance required.
    */
-  TapGestureRecognizer(Observer& observer, Vector2 screenSize, const TapGestureRequest& request, uint32_t maximumAllowedTime, uint32_t recognizerTime);
+  TapGestureRecognizer(Observer& observer, Vector2 screenSize, const TapGestureRequest& request, uint32_t maximumAllowedTime, uint32_t recognizerTime, float maximumMotionAllowedDistance);
 
   /**
    * Virtual destructor.
@@ -86,6 +87,17 @@ public:
    */
   void SetRecognizerTime(uint32_t time);
 
+
+  /**
+   * @brief This method sets the recognizer distance required to be recognized as a tap gesture
+   *
+   * This distance is from touch down to touch up to recognize the tap gesture.
+   *
+   * @param[in] distance The distance
+   */
+  void SetMaximumMotionAllowedDistance(float distance);
+
+
 private:
   /**
    * Checks if registered taps are within required bounds and emits tap gesture if they are.
@@ -157,6 +169,7 @@ private:
   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)
+  float    mMaximumMotionAllowedDistance; ///< The recognizer distance required to be recognized as a tap gesture
 };
 
 } // namespace Internal