X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fevent%2Fevents%2Fgesture-detector-impl.cpp;h=b3b8981be79cfd7fa079b9d4a1d3961ffee62502;hb=0ed4ee4571aacaf595db0f5b4332fa14113f3d51;hp=98c1481aac7fdece3ccb12842c39f011285d8ce9;hpb=27619bbc4c1d443e89a6cdd116e544f6d9657fa4;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/event/events/gesture-detector-impl.cpp b/dali/internal/event/events/gesture-detector-impl.cpp index 98c1481..b3b8981 100644 --- a/dali/internal/event/events/gesture-detector-impl.cpp +++ b/dali/internal/event/events/gesture-detector-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 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. @@ -23,84 +23,150 @@ // INTERNAL INCLUDES #include -#include -#include #include +#include +#include +#include namespace Dali { - namespace Internal { - -namespace -{ -const std::string INVALID_PROPERTY; // Empty string for invalid calls -} - -GestureDetector::GestureDetector(Gesture::Type type) -: mType(type), +GestureDetector::GestureDetector(GestureType::Value type, const SceneGraph::PropertyOwner* sceneObject) +: Object(sceneObject), + mType(type), mGestureEventProcessor(ThreadLocalStorage::Get().GetGestureEventProcessor()) { } GestureDetector::~GestureDetector() { - if ( !mAttachedActors.empty() ) + if(!mPendingAttachActors.empty()) { - for ( GestureDetectorActorContainer::iterator iter = mAttachedActors.begin(), endIter = mAttachedActors.end(); iter != endIter; ++iter ) + for(GestureDetectorActorContainer::iterator iter = mPendingAttachActors.begin(), endIter = mPendingAttachActors.end(); iter != endIter; ++iter) { - Actor* actor( *iter ); - actor->RemoveObserver( *this ); - actor->RemoveGestureDetector( *this ); + 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) + { + Actor* actor(*iter); + actor->RemoveObserver(*this); + actor->GetGestureData().RemoveGestureDetector(*this); } mAttachedActors.clear(); // Guard to allow handle destruction after Core has been destroyed - if ( Stage::IsInstalled() ) + if(Stage::IsInstalled()) { - mGestureEventProcessor.RemoveGestureDetector( this ); + mGestureEventProcessor.RemoveGestureDetector(this); } } } 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); - 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(object); - // Add the detector to the actor (so the actor knows it requires this gesture when going through hit-test algorithm) - actor.AddGestureDetector( *this ); + // 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 ( !mAttachedActors.empty() ) + 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); - if ( match != mAttachedActors.end() ) + if(match != mAttachedActors.end()) { // We no longer need to observe the actor's destruction actor.RemoveObserver(*this); - // Remove detector from actor (so it is set to no longer requiring this gesture when going through the hit-test algorithm) - actor.RemoveGestureDetector( *this ); + // Remove detector from actor-gesture-data + actor.GetGestureData().RemoveGestureDetector(*this); mAttachedActors.erase(match); @@ -108,9 +174,13 @@ void GestureDetector::Detach(Actor& actor) OnActorDetach(actor); // Unregister from gesture event processor if we do not have any actors - if ( mAttachedActors.empty() ) + if(mAttachedActors.empty()) { - mGestureEventProcessor.RemoveGestureDetector(this); + // Guard to allow handle destruction after Core has been destroyed + if(Stage::IsInstalled()) + { + mGestureEventProcessor.RemoveGestureDetector(this); + } } } } @@ -118,153 +188,117 @@ void GestureDetector::Detach(Actor& actor) void GestureDetector::DetachAll() { - if ( !mAttachedActors.empty() ) + 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); // Clear mAttachedActors before we call OnActorDetach in case derived classes call a method which manipulates mAttachedActors. mAttachedActors.clear(); - for ( GestureDetectorActorContainer::iterator iter = attachedActors.begin(), endIter = attachedActors.end(); iter != endIter; ++iter ) + for(GestureDetectorActorContainer::iterator iter = attachedActors.begin(), endIter = attachedActors.end(); iter != endIter; ++iter) { Actor* actor(*iter); // We no longer need to observe the actor's destruction actor->RemoveObserver(*this); - // Remove detector from actor (so it is set to no longer requiring this gesture when going through the hit-test algorithm) - actor->RemoveGestureDetector( *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 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 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 ( !mAttachedActors.empty() ) + 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() ) + 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() ) + if(mAttachedActors.empty()) { - mGestureEventProcessor.RemoveGestureDetector(this); + // Guard to allow handle destruction after Core has been destroyed + if(Stage::IsInstalled()) + { + mGestureEventProcessor.RemoveGestureDetector(this); + } } } } } -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