-//
-// 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) 2019 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>
// 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>
namespace Internal
{
-namespace
+GestureDetector::GestureDetector( DevelGesture::Type type, const SceneGraph::PropertyOwner* sceneObject )
+: Object( sceneObject ),
+ mType( type ),
+ mGestureEventProcessor( ThreadLocalStorage::Get().GetGestureEventProcessor() )
{
-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( Gesture::Type type, const SceneGraph::PropertyOwner* sceneObject )
+: GestureDetector( static_cast< DevelGesture::Type >( type ), sceneObject )
{
}
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();
}
}
-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.OnStage() )
{
- 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 );
- mAttachedActors.push_back(&actor);
+ mPendingAttachActors.push_back( &actor );
+ }
+ }
+}
- // We need to observe the actor's destruction
- actor.AddObserver(*this);
+void GestureDetector::SceneObjectAdded( Object& object )
+{
+ Actor& actor = dynamic_cast< Actor& >( object );
- // Dummy connection to touch event
- actor.TouchedSignal().Connect( mSlotDelegate, &GestureDetector::OnTouchEvent );
+ // 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);
- // Notification for derived classes
- OnActorAttach(actor);
+ if ( match != mPendingAttachActors.end() )
+ {
+ mPendingAttachActors.erase(match);
+
+ // 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 );
+ }
+ 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);
// 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);
// 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);
+ }
}
}
}
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);
// 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() )
+ {
+ actor = Dali::Actor( mPendingAttachActors[index] );
+ }
+ else if( index < mPendingAttachActors.size() + mAttachedActors.size() )
{
- actors.push_back(Dali::Actor(*iter));
+ 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