From ea3f8b933ff26c3873f59496da2813156741d44c Mon Sep 17 00:00:00 2001 From: "joogab.yun" Date: Wed, 13 Dec 2023 14:57:59 +0900 Subject: [PATCH] Touch and Hover event propagrated by geometry way.(2) This is similar to how Android works. If you haven't consumed it in interceptTouchEvent, you need to keep sending interceptTouchEvent. Change-Id: I3594d0abcaae1940be5dc0e7d73badecb3975aa5 --- .../src/dali/utc-Dali-GeoTouchProcessing.cpp | 82 ++++++++++++++++++++++ .../event/events/touch-event-processor.cpp | 36 ++++++---- 2 files changed, 106 insertions(+), 12 deletions(-) diff --git a/automated-tests/src/dali/utc-Dali-GeoTouchProcessing.cpp b/automated-tests/src/dali/utc-Dali-GeoTouchProcessing.cpp index 51f22e8..dbc6165 100644 --- a/automated-tests/src/dali/utc-Dali-GeoTouchProcessing.cpp +++ b/automated-tests/src/dali/utc-Dali-GeoTouchProcessing.cpp @@ -2175,6 +2175,88 @@ int UtcDaliGeoTouchEventIntercept03(void) END_TEST; } +int UtcDaliGeoTouchEventIntercept04(void) +{ + TestApplication application; + + application.GetScene().SetGeometryHittestEnabled(true); + + Actor parent = Actor::New(); + parent.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f)); + parent.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + application.GetScene().Add(parent); + + Actor actor = Actor::New(); + actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f)); + actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + parent.Add(actor); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Connect to actor's touched signal + SignalData data; + TouchEventFunctor functor(data, false /* Do not consume */); + actor.TouchedSignal().Connect(&application, functor); + + // Connect to parent's touched signal + SignalData parentData; + TouchEventFunctor parentFunctor(parentData); // consume + parent.TouchedSignal().Connect(&application, parentFunctor); + + // Emit a down signal + application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f))); + DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION); + DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION); + + data.Reset(); + parentData.Reset(); + + // Connect to parent's intercept touched signal + SignalData interceptData; + TouchEventFunctor interceptFunctor(interceptData, true /* Do intercept */); + Dali::DevelActor::InterceptTouchedSignal(parent).Connect(&application, interceptFunctor); + + // Emit a down signal + application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f))); + + // The actor gets interrupted. Because touch is intercepted by parent. + DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION); + DALI_TEST_EQUALS(PointState::INTERRUPTED, data.receivedTouch.points[0].state, TEST_LOCATION); + DALI_TEST_EQUALS(true, interceptData.functorCalled, TEST_LOCATION); + DALI_TEST_EQUALS(PointState::DOWN, interceptData.receivedTouch.points[0].state, TEST_LOCATION); + DALI_TEST_CHECK(actor == interceptData.receivedTouch.points[0].hitActor); + DALI_TEST_CHECK(parent == interceptData.touchedActor); + DALI_TEST_EQUALS(true, parentData.functorCalled, TEST_LOCATION); + DALI_TEST_EQUALS(PointState::DOWN, parentData.receivedTouch.points[0].state, TEST_LOCATION); + DALI_TEST_CHECK(parent == parentData.receivedTouch.points[0].hitActor); + DALI_TEST_CHECK(parent == parentData.touchedActor); + data.Reset(); + interceptData.Reset(); + parentData.Reset(); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Emit a move signal + application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 20.0f))); + + // Since InterceptTouchEvent is not called because it has already been intercepted by the parent, only the parent will receive the touchEvent. + DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION); + DALI_TEST_EQUALS(false, interceptData.functorCalled, TEST_LOCATION); + DALI_TEST_EQUALS(true, parentData.functorCalled, TEST_LOCATION); + DALI_TEST_EQUALS(PointState::MOTION, parentData.receivedTouch.points[0].state, TEST_LOCATION); + DALI_TEST_CHECK(parent == parentData.receivedTouch.points[0].hitActor); + DALI_TEST_CHECK(parent == parentData.touchedActor); + data.Reset(); + interceptData.Reset(); + parentData.Reset(); + + END_TEST; +} + int UtcDaliGeoTouchAreaOffset(void) { TestApplication application; diff --git a/dali/internal/event/events/touch-event-processor.cpp b/dali/internal/event/events/touch-event-processor.cpp index 9a139f5..15561ce 100644 --- a/dali/internal/event/events/touch-event-processor.cpp +++ b/dali/internal/event/events/touch-event-processor.cpp @@ -493,18 +493,21 @@ bool TouchEventProcessor::ProcessTouchEvent(const Integration::TouchEvent& event { if(isGeometry) { - Actor* touchConsumedActor(mLastConsumedActor.GetActor()); Actor* interceptedTouchActor(mInterceptedTouchActor.GetActor()); - if(touchConsumedActor) // If there is a consultative actor, send events only to the consultative actor. - { - RenderTask& currentRenderTaskImpl = *currentRenderTask.Get(); - consumedActor = EmitTouchSignals(touchConsumedActor, currentRenderTaskImpl, touchEventImpl, primaryPointState, isGeometry); - } - else if(interceptedTouchActor) // If there is an intercepted actor, send a touch event starting from the intercepted actor. + if(interceptedTouchActor) { - Dali::Actor interceptedTouchActorHandle(interceptedTouchActor); - std::list interceptActorLists = mInterceptedActorLists; - consumedActor = EmitGeoTouchSignals(interceptActorLists, touchEventHandle); + Actor* touchConsumedActor(mLastConsumedActor.GetActor()); + if(touchConsumedActor) // If there is a consultative actor, send events only to the consultative actor. + { + RenderTask& currentRenderTaskImpl = *currentRenderTask.Get(); + consumedActor = EmitTouchSignals(touchConsumedActor, currentRenderTaskImpl, touchEventImpl, primaryPointState, isGeometry); + } + else // If there is an intercepted actor, send a touch event starting from the intercepted actor. + { + Dali::Actor interceptedTouchActorHandle(interceptedTouchActor); + std::list interceptActorLists = mInterceptedActorLists; + consumedActor = EmitGeoTouchSignals(interceptActorLists, touchEventHandle); + } } else { @@ -544,8 +547,17 @@ bool TouchEventProcessor::ProcessTouchEvent(const Integration::TouchEvent& event } } - // Let's propagate touch events from the intercepted actor or start propagating touch events from the leaf actor. - consumedActor = EmitGeoTouchSignals(interceptedActor ? mInterceptedActorLists : mCandidateActorLists, touchEventHandle); + Actor* touchConsumedActor(mLastConsumedActor.GetActor()); + if(touchConsumedActor) // If there is a consultative actor, send events only to the consultative actor. + { + RenderTask& currentRenderTaskImpl = *currentRenderTask.Get(); + consumedActor = EmitTouchSignals(touchConsumedActor, currentRenderTaskImpl, touchEventImpl, primaryPointState, isGeometry); + } + else + { + // Let's propagate touch events from the intercepted actor or start propagating touch events from the leaf actor. + consumedActor = EmitGeoTouchSignals(interceptedActor ? mInterceptedActorLists : mCandidateActorLists, touchEventHandle); + } } } else -- 2.7.4