From eceeb37e71058e68aa04fa57e32eaeec0716a0a6 Mon Sep 17 00:00:00 2001 From: Adeel Kazmi Date: Mon, 1 Feb 2021 19:55:58 +0000 Subject: [PATCH] (HitTest) Check clipped actor if it is really touchable before using as hit-actor Change-Id: I073f6ddab910acb7aaf850d1f1c93fd6d15e1ebe --- .../src/dali/utc-Dali-HoverProcessing.cpp | 6 ++--- .../src/dali/utc-Dali-TouchProcessing.cpp | 28 ++++++++++++++++++---- .../event/events/hit-test-algorithm-impl.cpp | 8 +++++++ 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/automated-tests/src/dali/utc-Dali-HoverProcessing.cpp b/automated-tests/src/dali/utc-Dali-HoverProcessing.cpp index 7f1784d..70393de 100644 --- a/automated-tests/src/dali/utc-Dali-HoverProcessing.cpp +++ b/automated-tests/src/dali/utc-Dali-HoverProcessing.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 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. @@ -1261,9 +1261,9 @@ int UtcDaliHoverClippingActor(void) HoverEventFunctor functor(data); actor.HoveredSignal().Connect(&application, functor); - // Emit an event within clipped area - no hit. + // Emit an event within clipped area - we should have a hit. application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f))); - DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION); + DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION); data.Reset(); // Emit an event outside the clipped area but within the actor area, we should have a hit. diff --git a/automated-tests/src/dali/utc-Dali-TouchProcessing.cpp b/automated-tests/src/dali/utc-Dali-TouchProcessing.cpp index 275aa2a..d82eacb 100755 --- a/automated-tests/src/dali/utc-Dali-TouchProcessing.cpp +++ b/automated-tests/src/dali/utc-Dali-TouchProcessing.cpp @@ -1501,22 +1501,40 @@ int UtcDaliTouchEventClippedActor(void) TouchEventFunctor functor(data); actor.TouchedSignal().Connect(&application, functor); - // Emit an event within clipped area - no hit. + // Emit an event within clipped area - we should have a hit. application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f))); + DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION); + data.Reset(); + + // Emit an event within clipped child area - we should still have a hit. + application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(40.0f, 40.0f))); + DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION); + data.Reset(); + + // Now connect to the clippingChild's touch signal + SignalData clippingChildData; + TouchEventFunctor clippingChildFunctor(clippingChildData); + clippingChild.TouchedSignal().Connect(&application, clippingChildFunctor); + + // Emit an event within clipped child area - no hit on actor, but hit on clipped child. + application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(40.0f, 40.0f))); + DALI_TEST_EQUALS(true, clippingChildData.functorCalled, TEST_LOCATION); DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION); data.Reset(); + clippingChildData.Reset(); // Emit an event outside the clipped area but within the actor area, we should have a hit. application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(60.0f, 60.0f))); DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION); data.Reset(); + clippingChildData.Reset(); - clippingChild.TouchedSignal().Connect(&application, functor); - - // Emit an event inside part of the child which is within the clipped area, we should have a hit. + // Emit an event inside part of the child which is within the clipped area, we should have a hit on the clipped child but not the actor. application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(30.0f, 30.0f))); - DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION); + DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION); + DALI_TEST_EQUALS(true, clippingChildData.functorCalled, TEST_LOCATION); data.Reset(); + clippingChildData.Reset(); END_TEST; } diff --git a/dali/internal/event/events/hit-test-algorithm-impl.cpp b/dali/internal/event/events/hit-test-algorithm-impl.cpp index 25d6a42..d47f35d 100644 --- a/dali/internal/event/events/hit-test-algorithm-impl.cpp +++ b/dali/internal/event/events/hit-test-algorithm-impl.cpp @@ -301,6 +301,14 @@ HitActor HitTestWithinLayer( Actor& actor, clippingBitPlaneMask, rayTest ) ); + // Make sure the set hit actor is actually hittable. This is usually required when we have some + // clipping as we need to hit-test all actors as we descend the tree regardless of whether they + // are hittable or not. + if(currentHit.actor && !hitCheck.IsActorHittable(currentHit.actor)) + { + continue; + } + bool updateChildHit = false; if( currentHit.distance >= 0.0f ) { -- 2.7.4