Fix an issue where TapGesture Events are not being received. 85/277385/4
authorjoogab.yun <joogab.yun@samsung.com>
Tue, 5 Jul 2022 05:29:22 +0000 (14:29 +0900)
committerjoogab.yun <joogab.yun@samsung.com>
Thu, 7 Jul 2022 06:19:28 +0000 (15:19 +0900)
If multiple Tap GestureDetectors are registered, you may not receive gesture events depending on the setting of MaximumTapsRequired.

example)
TapGestureDetector detector1 = TapGestureDetector::New();
detector1.SetMaximumTapsRequired(1u);
detector1.Attach(actor1);

TapGestureDetector detector2 = TapGestureDetector::New();
detector2.SetMaximumTapsRequired(2u);
detector2.Attach(actor2);

When actor1 is tapped multiple times, I expect to receive a gesture event on every tap because MaximumTapsRequired is 1u, but I don't get the event every tap.

It is because the MaximumTapsRequred of detector2 is set to 2u, the MaximumTaps of the tap-gesture-recognizer is set to 2u.

So, if there is a double tap, the tap event is not delivered to detector1 because it exceeds the MaximumTaps of detector1.

For this reason, the check of MaximumTapsRequired is modified to be checked by each detector.

Change-Id: I297debdf7ff680affafc763d4af3db323f80a095

automated-tests/src/dali/utc-Dali-TapGestureDetector.cpp
dali/internal/event/events/tap-gesture/tap-gesture-detector-impl.cpp
dali/internal/event/events/tap-gesture/tap-gesture-processor.cpp

index 24921c3..851040b 100644 (file)
@@ -1207,4 +1207,55 @@ int UtcDaliTapGestureDoesWantedHitTest(void)
   greenData.Reset();
 
   END_TEST;
-}
\ No newline at end of file
+}
+
+int UtcDaliTapGestureDetectorCheck(void)
+{
+  TestApplication application;
+
+  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);
+
+  Actor actor2 = Actor::New();
+  actor2.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+  actor2.SetProperty(Actor::Property::POSITION, Vector2(100.0f, 100.0f));
+  actor2.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  application.GetScene().Add(actor2);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  SignalData             data;
+  GestureReceivedFunctor functor(data);
+  TapGestureDetector     detector1 = TapGestureDetector::New();
+  detector1.SetMaximumTapsRequired(1u);
+  detector1.Attach(actor);
+  detector1.DetectedSignal().Connect(&application, functor);
+
+  TapGestureDetector detector2 = TapGestureDetector::New();
+  detector2.SetMaximumTapsRequired(2u);
+  detector2.Attach(actor2);
+
+  // Emit signals, Send the single tab.
+  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 0, 100));
+  application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 0, 120));
+  application.SendNotification();
+
+  // The detector1 get the tap event.
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  data.Reset();
+
+  // Emit signals, Send the second tab.
+  application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 0, 130));
+  application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 0, 150));
+  application.SendNotification();
+
+  // The detector1 must get the tap event. SetMaximumTapsRequired(2u) of detector2 should not affect detector1.
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  data.Reset();
+
+  END_TEST;
+}
index 6f3784f..210ba57 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -164,27 +164,32 @@ void TapGestureDetector::EmitTapGestureSignal(Dali::Actor tappedActor, const Dal
     platformAbstraction.CancelTimer(mTimerId);
     mTimerId = 0;
   }
-  if(mMaximumTapsRequired > tap.GetNumberOfTaps() && !mReceiveAllTapEvents)
-  {
-    mTappedActor = tappedActor;
-
-    Internal::TapGesturePtr internalTap(new Internal::TapGesture(tap.GetState()));
-    internalTap->SetTime(tap.GetTime());
-    internalTap->SetNumberOfTaps(tap.GetNumberOfTaps());
-    internalTap->SetNumberOfTouches(tap.GetNumberOfTouches());
-    internalTap->SetScreenPoint(tap.GetScreenPoint());
-    internalTap->SetLocalPoint(tap.GetLocalPoint());
-    internalTap->SetGestureSourceType(tap.GetSourceType());
-    mTap = Dali::TapGesture(internalTap.Get());
 
-    mTimerId = platformAbstraction.StartTimer(DEFAULT_TAP_WAIT_TIME, MakeCallback(this, &TapGestureDetector::TimerCallback));
+  if(mMaximumTapsRequired == 0u)
+  {
+    return;
   }
-  else
+
+  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->SetGestureSourceType(tap.GetSourceType());
+  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, tap);
+    mDetectedSignal.Emit(tappedActor, mTap);
+  }
+  else
+  {
+    mTappedActor = tappedActor;
+    mTimerId     = platformAbstraction.StartTimer(DEFAULT_TAP_WAIT_TIME, MakeCallback(this, &TapGestureDetector::TimerCallback));
   }
 }
 
index 085f627..6bde317 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -312,8 +312,7 @@ bool TapGestureProcessor::CheckGestureDetector(GestureDetector* detector, Actor*
 
   TapGestureDetector* tapDetector(static_cast<TapGestureDetector*>(detector));
 
-  return ((tapDetector->GetMinimumTapsRequired() <= mCurrentTapEvent->numberOfTaps) && (tapDetector->GetMaximumTapsRequired() >= mCurrentTapEvent->numberOfTaps)) &&
-         (tapDetector->GetTouchesRequired() == mCurrentTapEvent->numberOfTouches);
+  return (tapDetector->GetMinimumTapsRequired() <= mCurrentTapEvent->numberOfTaps) && (tapDetector->GetTouchesRequired() == mCurrentTapEvent->numberOfTouches);
 }
 
 void TapGestureProcessor::EmitGestureSignal(Actor* actor, const GestureDetectorContainer& gestureDetectors, Vector2 actorCoordinates)