Revert "Revert "Revert "[Tizen] Revert "Use touch consumed return to set whether...
[platform/core/uifw/dali-core.git] / dali / internal / event / events / gesture-detector-impl.cpp
index d2dc891..8f2b0d0 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) 2020 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-detector-impl.h>
@@ -22,6 +23,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
+#include <dali/internal/event/events/actor-gesture-data.h>
 #include <dali/internal/event/events/gesture-event-processor.h>
 #include <dali/internal/event/common/thread-local-storage.h>
 #include <dali/internal/event/common/stage-impl.h>
@@ -32,26 +34,34 @@ namespace Dali
 namespace Internal
 {
 
-namespace
-{
-const std::string INVALID_PROPERTY; // Empty string for invalid calls
-}
-
-GestureDetector::GestureDetector(Gesture::Type type)
-: mType(type),
-  mGestureEventProcessor(ThreadLocalStorage::Get().GetGestureEventProcessor()),
-  mSlotDelegate(this)
+GestureDetector::GestureDetector( GestureType::Value type, const SceneGraph::PropertyOwner* sceneObject )
+: Object( sceneObject ),
+  mType( type ),
+  mGestureEventProcessor( ThreadLocalStorage::Get().GetGestureEventProcessor() )
 {
 }
 
 GestureDetector::~GestureDetector()
 {
+  if ( !mPendingAttachActors.empty() )
+  {
+    for ( GestureDetectorActorContainer::iterator iter = mPendingAttachActors.begin(), endIter = mPendingAttachActors.end(); iter != endIter; ++iter )
+    {
+      Actor* actor( *iter );
+      actor->RemoveObserver( *this );
+      actor->GetGestureData().RemoveGestureDetector( *this );
+    }
+
+    mPendingAttachActors.clear();
+  }
+
   if ( !mAttachedActors.empty() )
   {
     for ( GestureDetectorActorContainer::iterator iter = mAttachedActors.begin(), endIter = mAttachedActors.end(); iter != endIter; ++iter )
     {
-      (*iter)->RemoveObserver( *this );
-      (*iter)->TouchedSignal().Disconnect( mSlotDelegate, &GestureDetector::OnTouchEvent );
+      Actor* actor( *iter );
+      actor->RemoveObserver( *this );
+      actor->GetGestureData().RemoveGestureDetector( *this );
     }
 
     mAttachedActors.clear();
@@ -64,31 +74,90 @@ GestureDetector::~GestureDetector()
   }
 }
 
-void GestureDetector::Attach(Actor& actor)
+void GestureDetector::Attach( Actor& actor )
 {
-  if ( !IsAttached(actor) )
+  if ( !IsAttached( actor ) )
   {
-    // Register with EventProcessor if first actor being added
-    if ( mAttachedActors.empty() )
+    if( actor.OnScene() )
     {
-      mGestureEventProcessor.AddGestureDetector(this);
+      // Register with EventProcessor if first actor being added
+      if( mAttachedActors.empty() )
+      {
+        mGestureEventProcessor.AddGestureDetector( this, actor.GetScene() );
+      }
+      mAttachedActors.push_back( &actor );
+      // We need to observe the actor's destruction
+      actor.AddObserver( *this );
+      // Add the detector to the actor (so the actor knows it requires this gesture when going through hit-test algorithm)
+      actor.GetGestureData().AddGestureDetector( *this );
+      // Notification for derived classes
+      OnActorAttach( actor );
+    }
+    else
+    {
+      actor.AddObserver( *this );
+      // Add the detector to the actor (so the actor knows it requires this gesture when going through hit-test algorithm)
+      actor.GetGestureData().AddGestureDetector( *this );
+
+      mPendingAttachActors.push_back( &actor );
     }
+  }
+}
+
+void GestureDetector::SceneObjectAdded( Object& object )
+{
+  Actor& actor = dynamic_cast< Actor& >( object );
 
-    mAttachedActors.push_back(&actor);
+  // Make sure the actor has not already been attached. Can't use IsAttached() as that checks the pending list as well
+  if( find(mAttachedActors.begin(), mAttachedActors.end(), &actor) == mAttachedActors.end() )
+  {
+    GestureDetectorActorContainer::iterator match = find(mPendingAttachActors.begin(), mPendingAttachActors.end(), &actor);
 
-    // We need to observe the actor's destruction
-    actor.AddObserver(*this);
+    if ( match != mPendingAttachActors.end() )
+    {
+      mPendingAttachActors.erase(match);
 
-    // Dummy connection to touch event
-    actor.TouchedSignal().Connect( mSlotDelegate, &GestureDetector::OnTouchEvent );
+      // Register with EventProcessor if first actor being added
+      if( mAttachedActors.empty() )
+      {
+        mGestureEventProcessor.AddGestureDetector( this, actor.GetScene() );
+      }
+      mAttachedActors.push_back( &actor );
 
-    // Notification for derived classes
-    OnActorAttach(actor);
+      // Notification for derived classes
+      OnActorAttach( actor );
+    }
+    else
+    {
+      // Actor was not in the pending list
+      DALI_ASSERT_DEBUG( false );
+    }
+  }
+  else
+  {
+    // Check if actor has been attached and is still in the pending list - this would not be correct
+    DALI_ASSERT_DEBUG( find(mPendingAttachActors.begin(), mPendingAttachActors.end(), &actor) == mPendingAttachActors.end() );
   }
 }
 
 void GestureDetector::Detach(Actor& actor)
 {
+  if ( !mPendingAttachActors.empty() )
+  {
+    GestureDetectorActorContainer::iterator match = find(mPendingAttachActors.begin(), mPendingAttachActors.end(), &actor);
+
+    if ( match != mPendingAttachActors.end() )
+    {
+      // We no longer need to observe the actor's destruction
+      actor.RemoveObserver(*this);
+
+      // Remove detector from actor-gesture-data
+      actor.GetGestureData().RemoveGestureDetector( *this );
+
+      mPendingAttachActors.erase(match);
+    }
+  }
+
   if ( !mAttachedActors.empty() )
   {
     GestureDetectorActorContainer::iterator match = find(mAttachedActors.begin(), mAttachedActors.end(), &actor);
@@ -98,10 +167,10 @@ void GestureDetector::Detach(Actor& actor)
       // We no longer need to observe the actor's destruction
       actor.RemoveObserver(*this);
 
-      mAttachedActors.erase(match);
+      // Remove detector from actor-gesture-data
+      actor.GetGestureData().RemoveGestureDetector( *this );
 
-      // Disconnect connection to touch event
-      actor.TouchedSignal().Disconnect( mSlotDelegate, &PanGestureDetector::OnTouchEvent );
+      mAttachedActors.erase(match);
 
       // Notification for derived classes
       OnActorDetach(actor);
@@ -109,7 +178,11 @@ void GestureDetector::Detach(Actor& actor)
       // Unregister from gesture event processor if we do not have any actors
       if ( mAttachedActors.empty() )
       {
-        mGestureEventProcessor.RemoveGestureDetector(this);
+        // Guard to allow handle destruction after Core has been destroyed
+        if( Stage::IsInstalled() )
+        {
+          mGestureEventProcessor.RemoveGestureDetector(this);
+        }
       }
     }
   }
@@ -117,6 +190,24 @@ void GestureDetector::Detach(Actor& actor)
 
 void GestureDetector::DetachAll()
 {
+  if ( !mPendingAttachActors.empty() )
+  {
+    GestureDetectorActorContainer pendingActors(mPendingAttachActors);
+
+    mPendingAttachActors.clear();
+
+    for ( GestureDetectorActorContainer::iterator iter = pendingActors.begin(), endIter = pendingActors.end(); iter != endIter; ++iter )
+    {
+      Actor* actor(*iter);
+
+      // We no longer need to observe the actor's destruction
+      actor->RemoveObserver(*this);
+
+      // Remove detector from actor-gesture-data
+      actor->GetGestureData().RemoveGestureDetector( *this );
+    }
+  }
+
   if ( !mAttachedActors.empty() )
   {
     GestureDetectorActorContainer attachedActors(mAttachedActors);
@@ -131,141 +222,85 @@ void GestureDetector::DetachAll()
       // We no longer need to observe the actor's destruction
       actor->RemoveObserver(*this);
 
+      // Remove detector from actor-gesture-data
+      actor->GetGestureData().RemoveGestureDetector( *this );
+
       // Notification for derived classes
       OnActorDetach(*actor);
     }
 
-    // Unregister from gesture event processor
-    mGestureEventProcessor.RemoveGestureDetector(this);
+    // Guard to allow handle destruction after Core has been destroyed
+    if ( Stage::IsInstalled() )
+    {
+      // Unregister from gesture event processor
+      mGestureEventProcessor.RemoveGestureDetector(this);
+    }
   }
 }
 
-std::vector<Dali::Actor> GestureDetector::GetAttachedActors() const
+size_t GestureDetector::GetAttachedActorCount() const
 {
-  // Will only be used by Public API.
-  // Unlikely that it will be called that often so copying should be OK.
+  return mPendingAttachActors.size() + mAttachedActors.size();
+}
 
-  std::vector<Dali::Actor> actors;
+Dali::Actor GestureDetector::GetAttachedActor(size_t index) const
+{
+  Dali::Actor actor;
 
-  for ( GestureDetectorActorContainer::const_iterator iter = mAttachedActors.begin(), endIter = mAttachedActors.end(); iter != endIter; ++iter )
+  if( index < mPendingAttachActors.size() )
   {
-    actors.push_back(Dali::Actor(*iter));
+    actor = Dali::Actor( mPendingAttachActors[index] );
+  }
+  else if( index < mPendingAttachActors.size() + mAttachedActors.size() )
+  {
+    actor = Dali::Actor( mAttachedActors[index - mPendingAttachActors.size()] );
   }
 
-  return actors;
+  return actor;
 }
 
 bool GestureDetector::IsAttached(Actor& actor) const
 {
-  return find(mAttachedActors.begin(), mAttachedActors.end(), &actor) != mAttachedActors.end();
+  return ( find(mPendingAttachActors.begin(), mPendingAttachActors.end(), &actor) != mPendingAttachActors.end() ) ||
+         ( find(mAttachedActors.begin(), mAttachedActors.end(), &actor) != mAttachedActors.end() );
 }
 
-void GestureDetector::ProxyDestroyed(ProxyObject& proxy)
+void GestureDetector::ObjectDestroyed(Object& object)
 {
+  if ( !mPendingAttachActors.empty() )
+  {
+    GestureDetectorActorContainer::iterator match = find(mPendingAttachActors.begin(), mPendingAttachActors.end(), &object);
+
+    if ( match != mPendingAttachActors.end() )
+    {
+      mPendingAttachActors.erase(match);
+    }
+  }
+
   if ( !mAttachedActors.empty() )
   {
-    GestureDetectorActorContainer::iterator match = find(mAttachedActors.begin(), mAttachedActors.end(), &proxy);
+    GestureDetectorActorContainer::iterator match = find(mAttachedActors.begin(), mAttachedActors.end(), &object);
 
     if ( match != mAttachedActors.end() )
     {
       mAttachedActors.erase(match);
 
       // Notification for derived classes
-      OnActorDestroyed(proxy);
+      OnActorDestroyed(object);
 
       // Unregister from gesture event processor if we do not have any actors
       if ( mAttachedActors.empty() )
       {
-        mGestureEventProcessor.RemoveGestureDetector(this);
+        // Guard to allow handle destruction after Core has been destroyed
+        if ( Stage::IsInstalled() )
+        {
+          mGestureEventProcessor.RemoveGestureDetector(this);
+        }
       }
     }
   }
 }
 
-bool GestureDetector::OnTouchEvent(Dali::Actor actor, const TouchEvent& event)
-{
-  return false;
-}
-
-bool GestureDetector::IsSceneObjectRemovable() const
-{
-  return false;
-}
-
-unsigned int GestureDetector::GetDefaultPropertyCount() const
-{
-  return 0;
-}
-
-void GestureDetector::GetDefaultPropertyIndices( Property::IndexContainer& ) const
-{
-}
-
-const std::string& GestureDetector::GetDefaultPropertyName( Property::Index index ) const
-{
-  return INVALID_PROPERTY;
-}
-
-Property::Index GestureDetector::GetDefaultPropertyIndex(const std::string& name) const
-{
-  return 0;
-}
-
-bool GestureDetector::IsDefaultPropertyWritable(Property::Index index) const
-{
-  return false;
-}
-
-bool GestureDetector::IsDefaultPropertyAnimatable(Property::Index index) const
-{
-  return false;
-}
-
-bool GestureDetector::IsDefaultPropertyAConstraintInput( Property::Index index ) const
-{
-  return false;
-}
-
-Property::Type GestureDetector::GetDefaultPropertyType(Property::Index index) const
-{
-  return Property::NONE;
-}
-
-void GestureDetector::SetDefaultProperty( Property::Index index, const Property::Value& property )
-{
-  // None of our properties should be settable from Public API
-}
-
-void GestureDetector::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
-{
-  // None of our properties should be settable from Public API
-}
-
-Property::Value GestureDetector::GetDefaultProperty(Property::Index index) const
-{
-  return Property::Value();
-}
-
-void GestureDetector::InstallSceneObjectProperty( SceneGraph::PropertyBase& newProperty, const std::string& name, unsigned int index )
-{
-  // We do not want the user to install custom properties
-}
-
-const SceneGraph::PropertyOwner* GestureDetector::GetSceneObject() const
-{
-  return NULL;
-}
-
-const SceneGraph::PropertyBase* GestureDetector::GetSceneObjectAnimatableProperty( Property::Index index ) const
-{
-  return NULL;
-}
-
-const PropertyInputImpl* GestureDetector::GetSceneObjectInputProperty( Property::Index index ) const
-{
-  return NULL;
-}
-
 } // namespace Internal
 
 } // namespace Dali