From d1edbecce71fafb14de23f3f166a4f4baff43e2f Mon Sep 17 00:00:00 2001 From: "joogab.yun" Date: Tue, 5 Jul 2022 14:29:22 +0900 Subject: [PATCH] Fix an issue where TapGesture Events are not being received. 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 --- .../src/dali/utc-Dali-TapGestureDetector.cpp | 53 +++++++++++++++++++++- .../tap-gesture/tap-gesture-detector-impl.cpp | 37 ++++++++------- .../events/tap-gesture/tap-gesture-processor.cpp | 5 +- 3 files changed, 75 insertions(+), 20 deletions(-) diff --git a/automated-tests/src/dali/utc-Dali-TapGestureDetector.cpp b/automated-tests/src/dali/utc-Dali-TapGestureDetector.cpp index 24921c3..851040b 100644 --- a/automated-tests/src/dali/utc-Dali-TapGestureDetector.cpp +++ b/automated-tests/src/dali/utc-Dali-TapGestureDetector.cpp @@ -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; +} diff --git a/dali/internal/event/events/tap-gesture/tap-gesture-detector-impl.cpp b/dali/internal/event/events/tap-gesture/tap-gesture-detector-impl.cpp index 6f3784f..210ba57 100644 --- a/dali/internal/event/events/tap-gesture/tap-gesture-detector-impl.cpp +++ b/dali/internal/event/events/tap-gesture/tap-gesture-detector-impl.cpp @@ -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)); } } diff --git a/dali/internal/event/events/tap-gesture/tap-gesture-processor.cpp b/dali/internal/event/events/tap-gesture/tap-gesture-processor.cpp index 085f627..6bde317 100644 --- a/dali/internal/event/events/tap-gesture/tap-gesture-processor.cpp +++ b/dali/internal/event/events/tap-gesture/tap-gesture-processor.cpp @@ -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(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) -- 2.7.4