END_TEST;
}
+int UtcDaliGeoTouchEventIntercept05(void)
+{
+ TestApplication application;
+
+ application.GetScene().SetGeometryHittestEnabled(true);
+
+ Actor parentA = Actor::New();
+ parentA.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+ parentA.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ application.GetScene().Add(parentA);
+
+ Actor actorA = Actor::New();
+ actorA.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+ actorA.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ parentA.Add(actorA);
+
+ Actor parentB = Actor::New();
+ parentB.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+ parentB.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ application.GetScene().Add(parentB);
+
+ Actor actorB = Actor::New();
+ actorB.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+ actorB.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ parentB.Add(actorB);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Connect to actor's touched signal
+ SignalData dataA;
+ TouchEventFunctor functorA(dataA); // consume
+ actorA.TouchedSignal().Connect(&application, functorA);
+
+ // Connect to parent's touched signal
+ SignalData parentDataA;
+ TouchEventFunctor parentFunctorA(parentDataA); // consume
+ parentA.TouchedSignal().Connect(&application, parentFunctorA);
+
+ // Connect to actor's touched signal
+ SignalData dataB;
+ TouchEventFunctor functorB(dataB); // consume
+ actorB.TouchedSignal().Connect(&application, functorB);
+
+ // Connect to parent's touched signal
+ SignalData parentDataB;
+ TouchEventFunctor parentFunctorB(parentDataB); // consume
+ parentB.TouchedSignal().Connect(&application, parentFunctorB);
+
+ // Emit a down signal
+ application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
+ DALI_TEST_EQUALS(true, dataB.functorCalled, TEST_LOCATION);
+ DALI_TEST_EQUALS(PointState::DOWN, dataB.receivedTouch.points[0].state, TEST_LOCATION);
+
+ dataA.Reset();
+ parentDataA.Reset();
+ dataB.Reset();
+ parentDataB.Reset();
+
+ // Connect to parent's intercept touched signal
+ SignalData interceptDataA;
+ TouchEventFunctor interceptFunctorA(interceptDataA, true /* Do intercept */);
+ Dali::DevelActor::InterceptTouchedSignal(parentA).Connect(&application, interceptFunctorA);
+
+ SignalData interceptDataB;
+ TouchEventFunctor interceptFunctorB(interceptDataB, true /* Do intercept */);
+ Dali::DevelActor::InterceptTouchedSignal(parentB).Connect(&application, interceptFunctorB);
+
+ // Emit a down signal
+ application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
+
+ // The actor gets interrupted. Because touch is intercepted by parent.
+ // Intercepts are propagated in a parent-child relationship based on the hit actor.
+ DALI_TEST_EQUALS(true, dataB.functorCalled, TEST_LOCATION);
+ DALI_TEST_EQUALS(PointState::INTERRUPTED, dataB.receivedTouch.points[0].state, TEST_LOCATION);
+ DALI_TEST_EQUALS(true, interceptDataB.functorCalled, TEST_LOCATION);
+ DALI_TEST_EQUALS(PointState::DOWN, interceptDataB.receivedTouch.points[0].state, TEST_LOCATION);
+ DALI_TEST_CHECK(actorB == interceptDataB.receivedTouch.points[0].hitActor);
+ DALI_TEST_CHECK(parentB == interceptDataB.touchedActor);
+
+ // parentA and parentB are siblings. So parentA does not receive interceptTouchEvent.
+ DALI_TEST_EQUALS(false, interceptDataA.functorCalled, TEST_LOCATION);
+ DALI_TEST_EQUALS(false, dataA.functorCalled, TEST_LOCATION);
+
+ dataA.Reset();
+ parentDataA.Reset();
+ dataB.Reset();
+ parentDataB.Reset();
+ interceptDataA.Reset();
+ interceptDataB.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, dataB.functorCalled, TEST_LOCATION);
+ DALI_TEST_EQUALS(false, interceptDataB.functorCalled, TEST_LOCATION);
+ DALI_TEST_EQUALS(true, parentDataB.functorCalled, TEST_LOCATION);
+ DALI_TEST_EQUALS(PointState::MOTION, parentDataB.receivedTouch.points[0].state, TEST_LOCATION);
+ DALI_TEST_CHECK(parentB == parentDataB.receivedTouch.points[0].hitActor);
+ DALI_TEST_CHECK(parentB == parentDataB.touchedActor);
+
+ dataA.Reset();
+ parentDataA.Reset();
+ dataB.Reset();
+ parentDataB.Reset();
+ interceptDataA.Reset();
+ interceptDataB.Reset();
+
+ END_TEST;
+}
+
int UtcDaliGeoTouchAreaOffset(void)
{
TestApplication application;
}
// geometry
-// child -> below
-Dali::Actor EmitGeoInterceptTouchSignals(std::list<Dali::Internal::Actor*>& actorLists, std::list<Dali::Internal::Actor*>& interceptActorList, const Dali::TouchEvent& touchEvent, ActorObserver& lastConsumedActor)
+// child -> parent
+Dali::Actor EmitGeoInterceptTouchSignals(Dali::Actor actor,
+ const Dali::TouchEvent& touchEvent,
+ ActorObserver& lastConsumedActor)
{
- interceptActorList.clear();
Dali::Actor interceptedActor;
- for(auto&& actor : actorLists)
+
+ if(actor)
{
- interceptActorList.push_back(actor);
- if(ShouldEmitInterceptTouchEvent(*actor, touchEvent))
+ Dali::Actor parent = actor.GetParent();
+ if(parent)
{
- DALI_TRACE_SCOPE(gTraceFilter, "DALI_EMIT_INTERCEPT_TOUCH_EVENT_SIGNAL");
- if(actor->EmitInterceptTouchEventSignal(touchEvent))
- {
- interceptedActor = Dali::Actor(actor);
- break;
- }
+ // Recursively deliver events to the actor and its parents for intercept touch event.
+ interceptedActor = EmitGeoInterceptTouchSignals(parent, touchEvent, lastConsumedActor);
}
- // If there is a consumed actor, the intercept is sent only up to the moment before the consumed actor.
- if(lastConsumedActor.GetActor() == actor)
+
+ if(!interceptedActor)
{
- break;
+ bool intercepted = false;
+ Actor& actorImpl(GetImplementation(actor));
+ if(ShouldEmitInterceptTouchEvent(actorImpl, touchEvent))
+ {
+ DALI_TRACE_SCOPE(gTraceFilter, "DALI_EMIT_INTERCEPT_TOUCH_EVENT_SIGNAL");
+ intercepted = actorImpl.EmitInterceptTouchEventSignal(touchEvent);
+ if(intercepted)
+ {
+ interceptedActor = Dali::Actor(&actorImpl);
+ }
+ }
+ // If there is a consumed actor, the intercept is sent only up to the moment before the consumed actor.
+ if(lastConsumedActor.GetActor() == actor)
+ {
+ return interceptedActor;
+ }
}
}
return interceptedActor;
{
Dali::Actor interceptedActor;
// Let's find out if there is an intercept actor.
- interceptedActor = EmitGeoInterceptTouchSignals(processor.mCandidateActorLists, processor.mInterceptedActorLists, localVars.touchEventHandle, processor.mLastConsumedActor);
+ interceptedActor = EmitGeoInterceptTouchSignals(localVars.primaryHitActor, localVars.touchEventHandle, processor.mLastConsumedActor);
if(interceptedActor)
{
processor.mInterceptedTouchActor.SetActor(&GetImplementation(interceptedActor));
+ processor.mInterceptedActorLists.clear();
+ // Create a list of intercepted actors from the candidate list.
+ for(auto& actorImpl : processor.mCandidateActorLists)
+ {
+ processor.mInterceptedActorLists.push_back(actorImpl);
+ if(actorImpl == interceptedActor)
+ {
+ break;
+ }
+ }
+
// If there is an interception, send an interrupted event to the last consumed actor or to the actor that hit previously.
if(processor.mLastConsumedActor.GetActor() &&
processor.mLastConsumedActor.GetActor() != interceptedActor &&