Revert "[Tizen] Not execute the remove callback"
[platform/core/uifw/dali-core.git] / dali / internal / event / events / gesture-processor.cpp
index d517666..1cf4b26 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
 #include <dali/internal/event/actors/actor-impl.h>
 #include <dali/internal/event/actors/layer-impl.h>
 #include <dali/internal/event/common/scene-impl.h>
-#include <dali/internal/event/events/hit-test-algorithm-impl.h>
 #include <dali/internal/event/events/actor-gesture-data.h>
+#include <dali/internal/event/events/hit-test-algorithm-impl.h>
+#include <dali/internal/event/events/ray-test.h>
 #include <dali/internal/event/render-tasks/render-task-impl.h>
 
 namespace Dali
 {
-
 namespace Internal
 {
-
 namespace
 {
-
 /**
  * Functor to check whether an actor requires a particular gesture or not
  */
 struct GestureHitTestCheck : public HitTestAlgorithm::HitTestInterface
 {
-  GestureHitTestCheck( Gesture::Type type )
-  : mType( type )
+  GestureHitTestCheck(GestureType::Value type)
+  : mType(type)
   {
   }
 
-  virtual bool IsActorHittable( Actor* actor )
+  bool IsActorHittable(Actor* actor) override
   {
-    return actor->IsGestureRequred( mType ) && // Does the Application or derived actor type require the gesture?
-           actor->IsHittable();                // Is actor sensitive, visible and on the scene?
+    return actor->IsGestureRequired(mType) && // Does the Application or derived actor type require the gesture?
+           actor->IsHittable();               // Is actor sensitive, visible and on the scene?
   }
 
-  virtual bool DescendActorHierarchy( Actor* actor )
+  bool DescendActorHierarchy(Actor* actor) override
   {
     return actor->IsVisible() && // Actor is visible, if not visible then none of its children are visible.
            actor->IsSensitive(); // Actor is sensitive, if insensitive none of its children should be hittable either.
   }
 
-  virtual bool DoesLayerConsumeHit( Layer* layer )
+  bool DoesLayerConsumeHit(Layer* layer) override
   {
     return layer->IsTouchConsumed();
   }
 
-  Gesture::Type mType;
+  bool ActorRequiresHitResultCheck(Actor* actor, Integration::Point point, Vector2 hitPointLocal, uint32_t timeStamp) override
+  {
+    return actor->EmitHitTestResultSignal(point, hitPointLocal, timeStamp);
+  }
+
+  GestureType::Value mType;
 };
 
 } // unnamed namespace
 
-
-GestureProcessor::GestureProcessor( Gesture::Type type )
+GestureProcessor::GestureProcessor(GestureType::Value type)
 : mGestureRecognizer(),
-  mNeedsUpdate( false ),
-  mType( type ),
-  mCurrentGesturedActor( nullptr ),
-  mGesturedActorDisconnected( false )
+  mNeedsUpdate(false),
+  mType(type),
+  mCurrentGesturedActor(nullptr),
+  mPoint(),
+  mEventTime(0u),
+  mGesturedActorDisconnected(false)
 {
 }
 
@@ -83,34 +87,42 @@ GestureProcessor::~GestureProcessor()
   ResetActor();
 }
 
-void GestureProcessor::ProcessTouch( Scene& scene, const Integration::TouchEvent& event )
+void GestureProcessor::ProcessTouch(Scene& scene, const Integration::TouchEvent& event)
 {
-  mGestureRecognizer->SendEvent(scene, event);
+  if(mGestureRecognizer)
+  {
+    if(!event.points.empty())
+    {
+      mPoint     = event.points[0];
+      mEventTime = event.time;
+    }
+    mGestureRecognizer->SendEvent(scene, event);
+  }
 }
 
-void GestureProcessor::GetGesturedActor( Actor*& actor, GestureDetectorContainer& gestureDetectors )
+void GestureProcessor::GetGesturedActor(Actor*& actor, GestureDetectorContainer& gestureDetectors)
 {
-  while ( actor )
+  while(actor)
   {
     // We may be checking a parent so ensure the parent requires this gesture (and do not unintentionally create the gesture data for the parent)
-    if ( actor->IsGestureRequred( mType ) )
+    if(actor->IsGestureRequired(mType))
     {
       // Retrieve the actor's detectors and check if they satisfy current gesture
-      const GestureDetectorContainer& connectedDetectors( actor->GetGestureData().GetGestureDetectorContainer( mType ) );
-      const GestureDetectorContainer::const_iterator endIter( connectedDetectors.end() );
-      for ( GestureDetectorContainer::const_iterator iter = connectedDetectors.begin(); iter != endIter; ++iter )
+      const GestureDetectorContainer&                connectedDetectors(actor->GetGestureData().GetGestureDetectorContainer(mType));
+      const GestureDetectorContainer::const_iterator endIter(connectedDetectors.end());
+      for(GestureDetectorContainer::const_iterator iter = connectedDetectors.begin(); iter != endIter; ++iter)
       {
         GestureDetector* current(*iter);
 
         // Check deriving class for whether the current gesture satisfies the gesture detector's parameters.
-        if ( CheckGestureDetector( current, actor ) )
+        if(CheckGestureDetector(current, actor))
         {
           gestureDetectors.push_back(current);
         }
       }
 
       // The hit actor or one of the parents is a gestured actor, break out.
-      if ( !gestureDetectors.empty() )
+      if(!gestureDetectors.empty())
       {
         break;
       }
@@ -121,47 +133,58 @@ void GestureProcessor::GetGesturedActor( Actor*& actor, GestureDetectorContainer
   }
 }
 
-void GestureProcessor::ProcessAndEmit( HitTestAlgorithm::Results& hitTestResults )
+void GestureProcessor::ProcessAndEmit(HitTestAlgorithm::Results& hitTestResults)
 {
-  if ( hitTestResults.actor )
+  if(hitTestResults.actor)
   {
-    Actor* hitTestActor( &GetImplementation( hitTestResults.actor ) );
-    Actor* actor( hitTestActor );
+    Actor*  hitTestActor(&GetImplementation(hitTestResults.actor));
+    Actor*  actor(hitTestActor);
+    RayTest rayTest;
 
-    while ( actor )
+    while(actor)
     {
       GestureDetectorContainer gestureDetectors;
-      GetGesturedActor( actor, gestureDetectors );
+      GetGesturedActor(actor, gestureDetectors);
 
-      if ( actor && !gestureDetectors.empty() )
+      if(actor && !gestureDetectors.empty())
       {
         // We have a match but check if the hit point is within the gestured actor's bounds.
         // If it is not then continue up the actor hierarchy.
 
-        if ( actor == hitTestActor )
+        if(actor == hitTestActor)
         {
           // Our gesture detector's attached actor WAS the hit actor so we can can emit the signal.
-          EmitGestureSignal( actor, gestureDetectors, hitTestResults.actorCoordinates );
-          break; // We have found AND emitted a signal on the gestured actor, break out.
+          EmitGestureSignal(actor, gestureDetectors, hitTestResults.actorCoordinates);
+          // If NeedGesturePropagation is true, it passes the gesture to the parent.
+          if(!actor->NeedGesturePropagation())
+          {
+            break; // We have found AND emitted a signal on the gestured actor, break out.
+          }
+          actor->SetNeedGesturePropagation(false);
         }
         else
         {
-          if ( actor->IsHittable() )
+          if(actor->IsHittable())
           {
-            const Vector3 size( actor->GetCurrentSize() );
+            const Vector3 size(actor->GetCurrentSize());
 
-            if ( ( size.x > 0.0f ) && ( size.y > 0.0f ) )
+            if((size.x > 0.0f) && (size.y > 0.0f))
             {
               // Ensure tap is within the actor's area
-              if ( actor->RaySphereTest( hitTestResults.rayOrigin, hitTestResults.rayDirection ) ) // Quick check
+              if(rayTest.SphereTest(*actor, hitTestResults.rayOrigin, hitTestResults.rayDirection)) // Quick check
               {
                 Vector2 hitPointLocal;
-                float distance( 0.0f );
-                if( actor->RayActorTest( hitTestResults.rayOrigin, hitTestResults.rayDirection, hitPointLocal, distance ) )
+                float   distance(0.0f);
+                if(rayTest.ActorTest(*actor, hitTestResults.rayOrigin, hitTestResults.rayDirection, hitPointLocal, distance))
                 {
                   // One of the parents was the gestured actor so we can emit the signal for that actor.
-                  EmitGestureSignal( actor, gestureDetectors, hitPointLocal );
-                  break; // We have found AND emitted a signal on the gestured actor, break out.
+                  EmitGestureSignal(actor, gestureDetectors, hitPointLocal);
+                  // If NeedGesturePropagation is true, it passes the gesture to the parent.
+                  if(!actor->NeedGesturePropagation())
+                  {
+                    break; // We have found AND emitted a signal on the gestured actor, break out.
+                  }
+                  actor->SetNeedGesturePropagation(false);
                 }
               }
             }
@@ -170,7 +193,7 @@ void GestureProcessor::ProcessAndEmit( HitTestAlgorithm::Results& hitTestResults
       }
 
       // Continue up hierarchy to see if any of the parents require this gesture.
-      if ( actor )
+      if(actor)
       {
         actor = actor->GetParent();
       }
@@ -178,31 +201,33 @@ void GestureProcessor::ProcessAndEmit( HitTestAlgorithm::Results& hitTestResults
   }
 }
 
-bool GestureProcessor::HitTest( Scene& scene, Vector2 screenCoordinates, HitTestAlgorithm::Results& hitTestResults )
+bool GestureProcessor::HitTest(Scene& scene, Vector2 screenCoordinates, HitTestAlgorithm::Results& hitTestResults)
 {
-  GestureHitTestCheck hitCheck( mType );
-  HitTestAlgorithm::HitTest( scene.GetSize(), scene.GetRenderTaskList(), scene.GetLayerList(), screenCoordinates, hitTestResults, hitCheck );
+  GestureHitTestCheck hitCheck(mType);
+  hitTestResults.point     = mPoint;
+  hitTestResults.eventTime = mEventTime;
+  HitTestAlgorithm::HitTest(scene.GetSize(), scene.GetRenderTaskList(), scene.GetLayerList(), screenCoordinates, hitTestResults, hitCheck);
   return hitTestResults.renderTask && hitTestResults.actor;
 }
 
-void GestureProcessor::SetActor( Actor* actor )
+void GestureProcessor::SetActor(Actor* actor)
 {
-  if ( actor && actor != mCurrentGesturedActor )
+  if(actor && actor != mCurrentGesturedActor)
   {
     ResetActor();
 
     mCurrentGesturedActor = actor;
-    mCurrentGesturedActor->AddObserver( *this );
+    mCurrentGesturedActor->AddObserver(*this);
   }
   mGesturedActorDisconnected = false;
 }
 
 void GestureProcessor::ResetActor()
 {
-  if ( mCurrentGesturedActor )
+  if(mCurrentGesturedActor)
   {
-    mCurrentGesturedActor->RemoveObserver( *this );
-    mCurrentGesturedActor = nullptr;
+    mCurrentGesturedActor->RemoveObserver(*this);
+    mCurrentGesturedActor      = nullptr;
     mGesturedActorDisconnected = false;
   }
 }
@@ -214,8 +239,8 @@ Actor* GestureProcessor::GetCurrentGesturedActor()
 
 void GestureProcessor::SceneObjectRemoved(Object& object)
 {
-  if ( mCurrentGesturedActor == &object &&
-      !mGesturedActorDisconnected )
+  if(mCurrentGesturedActor == &object &&
+     !mGesturedActorDisconnected)
   {
     // Inform deriving classes.
     OnGesturedActorStageDisconnection();
@@ -227,7 +252,7 @@ void GestureProcessor::SceneObjectRemoved(Object& object)
 
 void GestureProcessor::ObjectDestroyed(Object& object)
 {
-  if ( mCurrentGesturedActor == &object )
+  if(mCurrentGesturedActor == &object)
   {
     // Inform deriving classes.
     OnGesturedActorStageDisconnection();