Even if the layer is set to SetTouchConsumed(true), the parent must be able to handle... 19/298019/14
authorjoogab.yun <joogab.yun@samsung.com>
Tue, 29 Aug 2023 07:24:20 +0000 (16:24 +0900)
committerjoogab.yun <joogab.yun@samsung.com>
Tue, 5 Sep 2023 07:05:27 +0000 (16:05 +0900)
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

automated-tests/src/dali/utc-Dali-TouchProcessing.cpp
dali/internal/event/actors/layer-impl.cpp
dali/internal/event/actors/layer-impl.h
dali/internal/event/events/hit-test-algorithm-impl.cpp

index beffb0a..e93a79a 100644 (file)
@@ -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;
index d0d7e23..3c283d9 100644 (file)
@@ -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;
index dcf447a..b94cf30 100644 (file)
@@ -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
index 20d5c8b..f40deae 100644 (file)
@@ -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;
         }
       }
     }