Fix prevent issues
[platform/core/uifw/dali-core.git] / dali / internal / event / events / hit-test-algorithm-impl.cpp
index 683ec4a..c0edd51 100644 (file)
@@ -20,6 +20,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/system-overlay.h>
+#include <dali/public-api/actors/layer.h>
 #include <dali/public-api/math/vector2.h>
 #include <dali/public-api/math/vector4.h>
 #include <dali/integration-api/debug.h>
@@ -28,7 +29,6 @@
 #include <dali/internal/event/actors/image-actor-impl.h>
 #include <dali/internal/event/actors/layer-impl.h>
 #include <dali/internal/event/actors/layer-list.h>
-#include <dali/internal/event/actors/renderable-actor-impl.h>
 #include <dali/internal/event/common/system-overlay-impl.h>
 #include <dali/internal/event/common/stage-impl.h>
 #include <dali/internal/event/common/projection.h>
@@ -170,7 +170,8 @@ HitActor HitTestWithinLayer( Actor& actor,
                              HitTestInterface& hitCheck,
                              bool& stencilOnLayer,
                              bool& stencilHit,
-                             bool parentIsStencil )
+                             bool parentIsStencil,
+                             bool layerIs3d )
 {
   HitActor hit;
 
@@ -215,22 +216,16 @@ HitActor HitTestWithinLayer( Actor& actor,
             hit.x = hitPointLocal.x;
             hit.y = hitPointLocal.y;
             hit.distance = distance;
+            hit.depth = actor.GetHierarchyDepth() * Dali::Layer::TREE_DEPTH_MULTIPLIER;
 
             // Is this actor an Image Actor or contains a renderer?
             if ( ImageActor* imageActor = dynamic_cast< ImageActor* >( &actor ) )
             {
-              hit.depth = imageActor->GetDepthIndex();
+              hit.depth += imageActor->GetDepthIndex();
             }
-            else
+            else if ( actor.GetRendererCount() )
             {
-              if ( actor.GetRendererCount() )
-              {
-                hit.depth = actor.GetRendererAt( 0 ).GetDepthIndex();
-              }
-              else
-              {
-                hit.depth = 0;
-              }
+              hit.depth += actor.GetRendererAt( 0 ).GetDepthIndex();
             }
           }
         }
@@ -258,10 +253,10 @@ HitActor HitTestWithinLayer( Actor& actor,
     for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
     {
       // Descend tree only if...
-      if ( !iter->IsLayer() &&    // Child is NOT a layer, hit testing current layer only or Child is not a layer and we've inherited the stencil draw mode
-           ( isStencil || hitCheck.DescendActorHierarchy( &GetImplementation( *iter ) ) ) ) // We are a stencil OR we can descend into child hierarchy
+      if ( !(*iter)->IsLayer() &&    // Child is NOT a layer, hit testing current layer only or Child is not a layer and we've inherited the stencil draw mode
+           ( isStencil || hitCheck.DescendActorHierarchy( ( *iter ).Get() ) ) ) // We are a stencil OR we can descend into child hierarchy
       {
-        HitActor currentHit( HitTestWithinLayer(  GetImplementation(*iter),
+        HitActor currentHit( HitTestWithinLayer(  (*iter->Get()),
                                                   renderTask,
                                                   exclusives,
                                                   rayOrigin,
@@ -271,31 +266,27 @@ HitActor HitTestWithinLayer( Actor& actor,
                                                   hitCheck,
                                                   stencilOnLayer,
                                                   stencilHit,
-                                                  isStencil ) );
+                                                  isStencil,
+                                                  layerIs3d) );
 
         bool updateChildHit = false;
-        // If our ray casting hit, then check then if the hit actor's depth is greater that the favorite, it will be preferred
         if ( currentHit.distance >= 0.0f )
         {
-          if ( currentHit.depth > childHit.depth )
+          if( layerIs3d )
           {
-            updateChildHit = true;
+            updateChildHit = ( ( currentHit.depth > childHit.depth ) ||
+                ( ( currentHit.depth == childHit.depth ) && ( currentHit.distance < childHit.distance ) ) );
           }
-
-          // If the hit actor's depth is equal to current favorite, then we check the distance and prefer the closer
-          else if ( currentHit.depth == childHit.depth )
+          else
           {
-            if ( currentHit.distance < childHit.distance )
-            {
-              updateChildHit = true;
-            }
+            updateChildHit = currentHit.depth >= childHit.depth;
           }
         }
 
         if ( updateChildHit )
         {
           if( !parentIsRenderable || currentHit.depth > hit.depth ||
-            ( currentHit.depth == hit.depth && currentHit.distance < hit.distance ) )
+            ( layerIs3d && ( currentHit.depth == hit.depth && currentHit.distance < hit.distance )) )
             {
               childHit = currentHit;
             }
@@ -382,6 +373,7 @@ void GetCameraClippingPlane( RenderTask& renderTask, float& nearClippingPlane, f
  * Hit test a RenderTask
  */
 bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives,
+                        Stage& stage,
                         LayerList& layers,
                         RenderTask& renderTask,
                         Vector2 screenCoordinates,
@@ -429,7 +421,8 @@ bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives,
         bool stencilOnLayer = false;
         bool stencilHit = false;
         bool layerConsumesHit = false;
-        const Vector2& stageSize = Stage::GetCurrent()->GetSize();
+
+        const Vector2& stageSize = stage.GetSize();
 
         for (int i=layers.GetLayerCount()-1; i>=0 && !(hit.actor); --i)
         {
@@ -455,7 +448,8 @@ bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives,
                                         hitCheck,
                                         stencilOnLayer,
                                         stencilHit,
-                                        false );
+                                        false,
+                                        layer->GetBehavior() == Dali::Layer::LAYER_3D);
             }
             else if ( IsWithinSourceActors( *sourceActor, *layer ) )
             {
@@ -470,7 +464,8 @@ bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives,
                                         hitCheck,
                                         stencilOnLayer,
                                         stencilHit,
-                                        false );
+                                        false,
+                                        layer->GetBehavior() == Dali::Layer::LAYER_3D);
             }
 
             // If a stencil on this layer hasn't been hit, then discard hit results for this layer if our current hit actor is renderable
@@ -511,7 +506,8 @@ bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives,
  *
  * @return true if we have a hit, false otherwise
  */
-bool HitTestForEachRenderTask( LayerList& layers,
+bool HitTestForEachRenderTask( Stage& stage,
+                               LayerList& layers,
                                RenderTaskList& taskList,
                                const Vector2& screenCoordinates,
                                Results& results,
@@ -543,7 +539,7 @@ bool HitTestForEachRenderTask( LayerList& layers,
       }
     }
 
-    if ( HitTestRenderTask( exclusives, layers, renderTask, screenCoordinates, results, hitCheck ) )
+    if ( HitTestRenderTask( exclusives, stage, layers, renderTask, screenCoordinates, results, hitCheck ) )
     {
       // Return true when an actor is hit (or layer in our render-task consumes the hit)
       return true; // don't bother checking off screen tasks
@@ -568,7 +564,7 @@ bool HitTestForEachRenderTask( LayerList& layers,
         continue;
       }
 
-      if ( HitTestRenderTask( exclusives, layers, renderTask, screenCoordinates, results, hitCheck ) )
+      if ( HitTestRenderTask( exclusives, stage, layers, renderTask, screenCoordinates, results, hitCheck ) )
       {
         // Return true when an actor is hit (or a layer in our render-task consumes the hit)
         return true;
@@ -589,7 +585,7 @@ bool HitTest( Stage& stage, const Vector2& screenCoordinates, Dali::HitTestAlgor
 
   Results hitTestResults;
   HitTestFunctionWrapper hitTestFunctionWrapper( func );
-  if (  HitTestForEachRenderTask( layerList, taskList, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) )
+  if (  HitTestForEachRenderTask( stage, layerList, taskList, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) )
   {
     results.actor = hitTestResults.actor;
     results.actorCoordinates = hitTestResults.actorCoordinates;
@@ -610,7 +606,7 @@ bool HitTest( Stage& stage, const Vector2& screenCoordinates, Results& results,
     RenderTaskList& overlayTaskList = systemOverlay->GetOverlayRenderTasks();
     LayerList& overlayLayerList = systemOverlay->GetLayerList();
 
-    wasHit = HitTestForEachRenderTask( overlayLayerList, overlayTaskList, screenCoordinates, results, hitTestInterface );
+    wasHit = HitTestForEachRenderTask( stage, overlayLayerList, overlayTaskList, screenCoordinates, results, hitTestInterface );
   }
 
   // Hit-test the regular on-stage actors
@@ -619,7 +615,7 @@ bool HitTest( Stage& stage, const Vector2& screenCoordinates, Results& results,
     RenderTaskList& taskList = stage.GetRenderTaskList();
     LayerList& layerList = stage.GetLayerList();
 
-    wasHit = HitTestForEachRenderTask( layerList, taskList, screenCoordinates, results, hitTestInterface );
+    wasHit = HitTestForEachRenderTask( stage, layerList, taskList, screenCoordinates, results, hitTestInterface );
   }
   return wasHit;
 }
@@ -636,9 +632,9 @@ bool HitTest( Stage& stage, RenderTask& renderTask, const Vector2& screenCoordin
   bool wasHit( false );
   Results hitTestResults;
 
-  const Vector< RenderTaskList::Exclusive >& exclusives = Stage::GetCurrent()->GetRenderTaskList().GetExclusivesList();
+  const Vector< RenderTaskList::Exclusive >& exclusives = stage.GetRenderTaskList().GetExclusivesList();
   HitTestFunctionWrapper hitTestFunctionWrapper( func );
-  if ( HitTestRenderTask( exclusives, stage.GetLayerList(), renderTask, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) )
+  if ( HitTestRenderTask( exclusives, stage, stage.GetLayerList(), renderTask, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) )
   {
     results.actor = hitTestResults.actor;
     results.actorCoordinates = hitTestResults.actorCoordinates;