From 5ec43bab9c772ca2b1594e32433191b5961a16d2 Mon Sep 17 00:00:00 2001 From: "joogab.yun" Date: Tue, 29 Aug 2023 16:24:20 +0900 Subject: [PATCH] Even if the layer is set to SetTouchConsumed(true), the parent must be able to handle the interceptTouchEvent. With the current logic, if a layer exists in the window and SetTouchConsumed of that layer is true, the touch cannot be intercepted even if the window is the root. Change-Id: I25911f3fb2cfb7ce3e857e25ca2bcd04912f62c1 --- .../src/dali/utc-Dali-TouchProcessing.cpp | 49 ++++++++++++++++++++++ dali/internal/event/actors/layer-impl.cpp | 17 ++++++++ dali/internal/event/actors/layer-impl.h | 11 ++++- .../event/events/hit-test-algorithm-impl.cpp | 8 +++- 4 files changed, 83 insertions(+), 2 deletions(-) diff --git a/automated-tests/src/dali/utc-Dali-TouchProcessing.cpp b/automated-tests/src/dali/utc-Dali-TouchProcessing.cpp index beffb0a..e93a79a 100644 --- a/automated-tests/src/dali/utc-Dali-TouchProcessing.cpp +++ b/automated-tests/src/dali/utc-Dali-TouchProcessing.cpp @@ -2234,6 +2234,55 @@ int UtcDaliTouchEventIntercept02(void) END_TEST; } +int UtcDaliTouchEventIntercept03(void) +{ + TestApplication application; + + // Add a layer to overlap the actor + Layer layer = Layer::New(); + layer.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f)); + layer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + application.GetScene().Add(layer); + layer.RaiseToTop(); + + // Set layer to consume all touch + layer.SetProperty(Layer::Property::CONSUMES_TOUCH, true); + + // Render and notify + application.SendNotification(); + application.Render(); + + Actor actor = Actor::New(); + actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f)); + actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + layer.Add(actor); + + // Render and notify + application.SendNotification(); + application.Render(); + + Actor rootActor(application.GetScene().GetRootLayer()); + + // Connect to root actor's intercept touched signal + SignalData sceneData; + TouchEventFunctor sceneFunctor(sceneData); + Dali::DevelActor::InterceptTouchedSignal(rootActor).Connect(&application, sceneFunctor); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Emit a down signal + application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f))); + + // Even if the layer is touch consumed, the root actor must be able to intercept touch. + DALI_TEST_EQUALS(true, sceneData.functorCalled, TEST_LOCATION); + sceneData.Reset(); + + + END_TEST; +} + int UtcDaliTouchAreaOffset(void) { TestApplication application; diff --git a/dali/internal/event/actors/layer-impl.cpp b/dali/internal/event/actors/layer-impl.cpp index d0d7e23..3c283d9 100644 --- a/dali/internal/event/actors/layer-impl.cpp +++ b/dali/internal/event/actors/layer-impl.cpp @@ -321,9 +321,26 @@ void Layer::SetSortFunction(Dali::Layer::SortFunctionType function) void Layer::SetTouchConsumed(bool consume) { + if(mTouchConsumed != consume) + { + if(consume) + { + this->TouchedSignal().Connect(this, &Layer::OnTouched); + } + else + { + this->TouchedSignal().Disconnect(this, &Layer::OnTouched); + } + } mTouchConsumed = consume; } +bool Layer::OnTouched(Dali::Actor actor, const TouchEvent& touch) +{ + // This event is only called when mTouchConsumed is true. So touch always consumed. + return true; +} + bool Layer::IsTouchConsumed() const { return mTouchConsumed; diff --git a/dali/internal/event/actors/layer-impl.h b/dali/internal/event/actors/layer-impl.h index dcf447a..b94cf30 100644 --- a/dali/internal/event/actors/layer-impl.h +++ b/dali/internal/event/actors/layer-impl.h @@ -37,7 +37,7 @@ class Layer; using ClippingBox = Dali::ClippingBox; -class Layer : public Actor +class Layer : public Actor, public ConnectionTracker { public: /** @@ -247,6 +247,15 @@ private: // From Actor void OnSceneDisconnectionInternal() override; private: + /** + * @brief Callback when Layer is touched + * + * @param[in] actor Layer touched + * @param[in] touch Touch information + * @return True if the touch is consummed. + */ + bool OnTouched(Dali::Actor actor, const TouchEvent& touch); + LayerList* mLayerList; ///< Only valid when layer is on-scene // These properties not animatable; the actor side has the most up-to-date values diff --git a/dali/internal/event/events/hit-test-algorithm-impl.cpp b/dali/internal/event/events/hit-test-algorithm-impl.cpp index 20d5c8b..f40deae 100644 --- a/dali/internal/event/events/hit-test-algorithm-impl.cpp +++ b/dali/internal/event/events/hit-test-algorithm-impl.cpp @@ -571,7 +571,13 @@ bool HitTestRenderTask(const RenderTaskList::ExclusivesContainer& exclusives, if(layerConsumesHit) { // Consumes if the hitted layer is above the SourceActor's layer. - return sourceLayerIndex <= consumedLayerIndex; + bool ret = sourceLayerIndex <= consumedLayerIndex; + if(ret) + { + results.renderTask = RenderTaskPtr(&renderTask); + results.actor = Dali::Layer(layers.GetLayer(consumedLayerIndex)); + } + return ret; } } } -- 2.7.4