Consumes if the hitted layer is above the SourceActor's layer. 66/298066/9
authorjoogab.yun <joogab.yun@samsung.com>
Thu, 31 Aug 2023 02:29:35 +0000 (11:29 +0900)
committerjoogab.yun <joogab.yun@samsung.com>
Fri, 1 Sep 2023 02:33:05 +0000 (11:33 +0900)
test code
https://review.tizen.org/gerrit/#/c/platform/core/uifw/dali-demo/+/293175/
The green area must be touched.

Change-Id: I11436d9711c0845d4becbf8c3f97ea80d772eb9c

dali/internal/event/events/hit-test-algorithm-impl.cpp

index 77adf67..20d5c8b 100644 (file)
@@ -482,13 +482,29 @@ bool HitTestRenderTask(const RenderTaskList::ExclusivesContainer& exclusives,
 
         // Hit test starting with the top layer, working towards the bottom layer.
         HitActor hit;
-        bool     overlayHit       = false;
-        bool     layerConsumesHit = false;
+        bool     overlayHit           = false;
+        bool     layerConsumesHit     = false;
+
+        // Be used when we decide to consume layer.
+        // We should not consume hit if sourceLayer is above on consumable layer. Otherwise, we should consume. So just initialize it as 0.
+        // sourceLayerIndex can be a relative value to calculate the relationship with the layer.
+        // If the layer is consumed first, sourceLayerIndex is not the actual index, but it must be guaranteed to have an index smaller than the layer.
+        // If there is a sourceLayer above the consumable layer, the sourceLayerIndex is determined and the index of the consumable layer is also determined.
+        // Then we can calculate the relationship between the two layers.
+        bool     IsHitTestWithinLayer = false;
+        int32_t  sourceLayerIndex     = 0;
+        int32_t  consumedLayerIndex   = -1;
 
         for(int32_t i = layers.GetLayerCount() - 1; i >= 0 && !(hit.actor); --i)
         {
           Layer* layer(layers.GetLayer(i));
           overlayHit = false;
+          IsHitTestWithinLayer = false;
+
+          if(sourceLayer == layer)
+          {
+            sourceLayerIndex = i;
+          }
 
           // Ensure layer is touchable (also checks whether ancestors are also touchable)
           if(IsActuallyHittable(*layer, screenCoordinates, sceneSize, hitCheck))
@@ -496,6 +512,7 @@ bool HitTestRenderTask(const RenderTaskList::ExclusivesContainer& exclusives,
             // Always hit-test the source actor; otherwise test whether the layer is below the source actor in the hierarchy
             if(sourceActorDepth == static_cast<uint32_t>(i))
             {
+              IsHitTestWithinLayer = true;
               // Recursively hit test the source actor & children, without crossing into other layers.
               hit = HitTestWithinLayer(*sourceActor,
                                        renderTask,
@@ -514,6 +531,7 @@ bool HitTestRenderTask(const RenderTaskList::ExclusivesContainer& exclusives,
             }
             else if(IsWithinSourceActors(*sourceActor, *layer))
             {
+              IsHitTestWithinLayer = true;
               // Recursively hit test all the actors, without crossing into other layers.
               hit = HitTestWithinLayer(*layer,
                                        renderTask,
@@ -532,10 +550,10 @@ bool HitTestRenderTask(const RenderTaskList::ExclusivesContainer& exclusives,
             }
 
             // If this layer is set to consume the hit, then do not check any layers behind it
-            if(hitCheck.DoesLayerConsumeHit(layer))
+            if(IsHitTestWithinLayer && hitCheck.DoesLayerConsumeHit(layer))
             {
-              // Consume the hit if this layer is same as SourceActor's layer
-              layerConsumesHit = (sourceLayer == Dali::Layer(layer));
+              consumedLayerIndex = i;
+              layerConsumesHit = true;
               break;
             }
           }
@@ -552,7 +570,8 @@ bool HitTestRenderTask(const RenderTaskList::ExclusivesContainer& exclusives,
 
         if(layerConsumesHit)
         {
-          return true; // Also success if layer is consuming the hit
+          // Consumes if the hitted layer is above the SourceActor's layer.
+          return sourceLayerIndex <= consumedLayerIndex;
         }
       }
     }