Revert "[3.0] Clipping API feature in Actor"
[platform/core/uifw/dali-core.git] / dali / internal / event / events / gesture-processor.cpp
index f08ef86..a196d1a 100644 (file)
@@ -1,18 +1,19 @@
-//
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed under the Flora License, Version 1.0 (the License);
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://floralicense.org/license/
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an AS IS BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
+/*
+ * Copyright (c) 2014 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
 
 // CLASS HEADER
 #include <dali/internal/event/events/gesture-processor.h>
 // INTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
 #include <dali/internal/event/actors/actor-impl.h>
-#include <dali/internal/event/render-tasks/render-task-impl.h>
+#include <dali/internal/event/actors/layer-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/render-tasks/render-task-impl.h>
 
 namespace Dali
 {
@@ -29,9 +32,46 @@ namespace Dali
 namespace Internal
 {
 
-GestureProcessor::GestureProcessor()
-: mCurrentGesturedActor( NULL ),
-  mGesturedActorDisconnected(false)
+namespace
+{
+
+/**
+ * Functor to check whether an actor requires a particular gesture or not
+ */
+struct GestureHitTestCheck : public HitTestAlgorithm::HitTestInterface
+{
+  GestureHitTestCheck( Gesture::Type type )
+  : mType( type )
+  {
+  }
+
+  virtual bool IsActorHittable( Actor* actor )
+  {
+    return actor->IsGestureRequred( 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 )
+  {
+    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 )
+  {
+    return layer->IsTouchConsumed();
+  }
+
+  Gesture::Type mType;
+};
+
+} // unnamed namespace
+
+
+GestureProcessor::GestureProcessor( Gesture::Type type )
+: mType( type ),
+  mCurrentGesturedActor( NULL ),
+  mGesturedActorDisconnected( false )
 {
 }
 
@@ -40,88 +80,92 @@ GestureProcessor::~GestureProcessor()
   ResetActor();
 }
 
-void GestureProcessor::GetGesturedActor( Dali::Actor& actor, const GestureDetectorContainer& connectedDetectors, std::vector<GestureDetector*>& gestureDetectors, Functor& functor )
+void GestureProcessor::GetGesturedActor( Actor*& actor, GestureDetectorContainer& gestureDetectors )
 {
   while ( actor )
   {
-    Actor* actorImpl( &GetImplementation(actor) );
-
-    // Check if our hit actor or any of its parents are attached to any registered detector.
-    // Find all detectors that have the actor attached.
-    for ( GestureDetectorContainer::const_iterator iter = connectedDetectors.begin(), endIter = connectedDetectors.end(); iter != endIter; ++iter )
+    // 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 ) )
     {
-      GestureDetector* current(*iter);
-
-      // Check whether the actor is attached to the gesture detector and then call the functor to
-      // check whether the gesture detector satisfies the current gesture's parameters.
-      if ( current->IsAttached( *actorImpl ) && functor( current, actorImpl ) )
+      // 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 )
       {
-        gestureDetectors.push_back(current);
+        GestureDetector* current(*iter);
+
+        // Check deriving class for whether the current gesture satisfies the gesture detector's parameters.
+        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() )
-    {
-      break;
+      // The hit actor or one of the parents is a gestured actor, break out.
+      if ( !gestureDetectors.empty() )
+      {
+        break;
+      }
     }
 
     // No match, we should now check the hit actor's parent.
-    actor = actor.GetParent();
+    actor = actor->GetParent();
   }
 }
 
-void GestureProcessor::ProcessAndEmit( const HitTestAlgorithm::Results& hitTestResults, const GestureDetectorContainer& connectedDetectors, Functor& functor )
+void GestureProcessor::ProcessAndEmit( HitTestAlgorithm::Results& hitTestResults )
 {
-  Dali::Actor actor( hitTestResults.actor );
-
-  while ( actor )
+  if ( hitTestResults.actor )
   {
-    std::vector<GestureDetector*> gestureDetectors;
-
-    GetGesturedActor( actor, connectedDetectors, gestureDetectors, functor );
+    Actor* hitTestActor( &GetImplementation( hitTestResults.actor ) );
+    Actor* actor( hitTestActor );
 
-    if ( actor && !gestureDetectors.empty() )
+    while ( actor )
     {
-      // 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.
+      GestureDetectorContainer gestureDetectors;
+      GetGesturedActor( actor, gestureDetectors );
 
-      if ( actor == hitTestResults.actor )
+      if ( actor && !gestureDetectors.empty() )
       {
-        // Our gesture detector's attached actor WAS the hit actor so we can call the emitting functor.
-        functor( actor, gestureDetectors, hitTestResults.actorCoordinates );
-        break; // We have found AND emitted a signal on the gestured actor, break out.
-      }
-      else
-      {
-        if ( GetImplementation(actor).IsHittable() )
-        {
-          const Vector3 size( actor.GetCurrentSize() );
+        // 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 ( ( size.x > 0.0f ) && ( size.y > 0.0f ) )
+        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.
+        }
+        else
+        {
+          if ( actor->IsHittable() )
           {
-            // Ensure tap is within the actor's area
-            Actor& actorImpl = GetImplementation(actor);
-            if ( actorImpl.RaySphereTest( hitTestResults.rayOrigin, hitTestResults.rayDirection ) ) // Quick check
+            const Vector3 size( actor->GetCurrentSize() );
+
+            if ( ( size.x > 0.0f ) && ( size.y > 0.0f ) )
             {
-              Vector4 hitPointLocal;
-              float distance( 0.0f );
-              if( actorImpl.RayActorTest( hitTestResults.rayOrigin, hitTestResults.rayDirection, hitPointLocal, distance ) )
+              // Ensure tap is within the actor's area
+              if ( actor->RaySphereTest( hitTestResults.rayOrigin, hitTestResults.rayDirection ) ) // Quick check
               {
-                // One of the hit actor's parents was the gestured actor so call the emitting functor.
-                functor( actor, gestureDetectors, Vector2( hitPointLocal.x, hitPointLocal.y ) );
-                break; // We have found AND emitted a signal on the gestured actor, break out.
+                Vector4 hitPointLocal;
+                float distance( 0.0f );
+                if( actor->RayActorTest( 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, Vector2( hitPointLocal.x, hitPointLocal.y ) );
+                  break; // We have found AND emitted a signal on the gestured actor, break out.
+                }
               }
             }
           }
         }
       }
-    }
 
-    // Continue up hierarchy to see if any of the parents require this gesture.
-    if ( actor )
-    {
-      actor = actor.GetParent();
+      // Continue up hierarchy to see if any of the parents require this gesture.
+      if ( actor )
+      {
+        actor = actor->GetParent();
+      }
     }
   }
 }
@@ -131,30 +175,18 @@ bool GestureProcessor::HitTest(
   Vector2                    screenCoordinates,
   HitTestAlgorithm::Results& hitTestResults)
 {
-  bool hit = false;
-
-  HitTestAlgorithm::HitTest( stage, screenCoordinates, hitTestResults );
-  if( hitTestResults.renderTask && hitTestResults.actor )
-  {
-    if( ! GetImplementation( hitTestResults.renderTask ).IsSystemLevel() )
-    {
-      hit = true;
-    }
-    else
-    {
-      DALI_LOG_ERROR( "Gesture not possible in SystemOverlay" );
-    }
-  }
-  return hit;
+  GestureHitTestCheck hitCheck( mType );
+  HitTestAlgorithm::HitTest( stage, screenCoordinates, hitTestResults, hitCheck );
+  return hitTestResults.renderTask && hitTestResults.actor;
 }
 
-void GestureProcessor::SetActor( Dali::Actor actor )
+void GestureProcessor::SetActor( Actor* actor )
 {
   if ( actor && actor != mCurrentGesturedActor )
   {
     ResetActor();
 
-    mCurrentGesturedActor = &GetImplementation( actor );
+    mCurrentGesturedActor = actor;
     mCurrentGesturedActor->AddObserver( *this );
   }
   mGesturedActorDisconnected = false;
@@ -175,22 +207,22 @@ Actor* GestureProcessor::GetCurrentGesturedActor()
   return mGesturedActorDisconnected ? NULL : mCurrentGesturedActor;
 }
 
-void GestureProcessor::SceneObjectRemoved(ProxyObject& proxy)
+void GestureProcessor::SceneObjectRemoved(Object& object)
 {
-  if ( mCurrentGesturedActor == &proxy &&
+  if ( mCurrentGesturedActor == &object &&
       !mGesturedActorDisconnected )
   {
     // Inform deriving classes.
     OnGesturedActorStageDisconnection();
 
-    // do not call proxy.RemoveObserver here, proxy is currently iterating through observers... you wouldnt want to upset proxy now would you?
+    // do not call object.RemoveObserver here, object is currently iterating through observers... you wouldnt want to upset object now would you?
     mGesturedActorDisconnected = true;
   }
 }
 
-void GestureProcessor::ProxyDestroyed(ProxyObject& proxy)
+void GestureProcessor::ObjectDestroyed(Object& object)
 {
-  if ( mCurrentGesturedActor == &proxy )
+  if ( mCurrentGesturedActor == &object )
   {
     // Inform deriving classes.
     OnGesturedActorStageDisconnection();