Refactor SceneGraphProperty handling code in event side to make RegisterProperty...
[platform/core/uifw/dali-core.git] / dali / internal / event / events / gesture-detector-impl.cpp
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/event/events/gesture-detector-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <algorithm>
23
24 // INTERNAL INCLUDES
25 #include <dali/integration-api/debug.h>
26 #include <dali/internal/event/events/actor-gesture-data.h>
27 #include <dali/internal/event/events/gesture-event-processor.h>
28 #include <dali/internal/event/common/thread-local-storage.h>
29 #include <dali/internal/event/common/stage-impl.h>
30
31 namespace Dali
32 {
33
34 namespace Internal
35 {
36
37 GestureDetector::GestureDetector(Gesture::Type type, const SceneGraph::PropertyOwner* sceneObject )
38 : Object( sceneObject ),
39   mType( type ),
40   mGestureEventProcessor( ThreadLocalStorage::Get().GetGestureEventProcessor() )
41 {
42 }
43
44 GestureDetector::~GestureDetector()
45 {
46   if ( !mAttachedActors.empty() )
47   {
48     for ( GestureDetectorActorContainer::iterator iter = mAttachedActors.begin(), endIter = mAttachedActors.end(); iter != endIter; ++iter )
49     {
50       Actor* actor( *iter );
51       actor->RemoveObserver( *this );
52       actor->GetGestureData().RemoveGestureDetector( *this );
53     }
54
55     mAttachedActors.clear();
56
57     // Guard to allow handle destruction after Core has been destroyed
58     if ( Stage::IsInstalled() )
59     {
60       mGestureEventProcessor.RemoveGestureDetector( this );
61     }
62   }
63 }
64
65 void GestureDetector::Attach(Actor& actor)
66 {
67   if ( !IsAttached(actor) )
68   {
69     // Register with EventProcessor if first actor being added
70     if ( mAttachedActors.empty() )
71     {
72       mGestureEventProcessor.AddGestureDetector(this);
73     }
74
75     mAttachedActors.push_back(&actor);
76
77     // We need to observe the actor's destruction
78     actor.AddObserver(*this);
79
80     // Add the detector to the actor (so the actor knows it requires this gesture when going through hit-test algorithm)
81     actor.GetGestureData().AddGestureDetector( *this );
82
83     // Notification for derived classes
84     OnActorAttach(actor);
85   }
86 }
87
88 void GestureDetector::Detach(Actor& actor)
89 {
90   if ( !mAttachedActors.empty() )
91   {
92     GestureDetectorActorContainer::iterator match = find(mAttachedActors.begin(), mAttachedActors.end(), &actor);
93
94     if ( match != mAttachedActors.end() )
95     {
96       // We no longer need to observe the actor's destruction
97       actor.RemoveObserver(*this);
98
99       // Remove detector from actor-gesture-data
100       actor.GetGestureData().RemoveGestureDetector( *this );
101
102       mAttachedActors.erase(match);
103
104       // Notification for derived classes
105       OnActorDetach(actor);
106
107       // Unregister from gesture event processor if we do not have any actors
108       if ( mAttachedActors.empty() )
109       {
110         // Guard to allow handle destruction after Core has been destroyed
111         if( Stage::IsInstalled() )
112         {
113           mGestureEventProcessor.RemoveGestureDetector(this);
114         }
115       }
116     }
117   }
118 }
119
120 void GestureDetector::DetachAll()
121 {
122   if ( !mAttachedActors.empty() )
123   {
124     GestureDetectorActorContainer attachedActors(mAttachedActors);
125
126     // Clear mAttachedActors before we call OnActorDetach in case derived classes call a method which manipulates mAttachedActors.
127     mAttachedActors.clear();
128
129     for ( GestureDetectorActorContainer::iterator iter = attachedActors.begin(), endIter = attachedActors.end(); iter != endIter; ++iter )
130     {
131       Actor* actor(*iter);
132
133       // We no longer need to observe the actor's destruction
134       actor->RemoveObserver(*this);
135
136       // Remove detector from actor-gesture-data
137       actor->GetGestureData().RemoveGestureDetector( *this );
138
139       // Notification for derived classes
140       OnActorDetach(*actor);
141     }
142
143     // Guard to allow handle destruction after Core has been destroyed
144     if ( Stage::IsInstalled() )
145     {
146       // Unregister from gesture event processor
147       mGestureEventProcessor.RemoveGestureDetector(this);
148     }
149   }
150 }
151
152 size_t GestureDetector::GetAttachedActorCount() const
153 {
154   return mAttachedActors.size();
155 }
156
157 Dali::Actor GestureDetector::GetAttachedActor(size_t index) const
158 {
159   Dali::Actor actor;
160
161   if( index < mAttachedActors.size() )
162   {
163     actor = Dali::Actor( mAttachedActors[index] );
164   }
165
166   return actor;
167 }
168
169 bool GestureDetector::IsAttached(Actor& actor) const
170 {
171   return find(mAttachedActors.begin(), mAttachedActors.end(), &actor) != mAttachedActors.end();
172 }
173
174 void GestureDetector::ObjectDestroyed(Object& object)
175 {
176   if ( !mAttachedActors.empty() )
177   {
178     GestureDetectorActorContainer::iterator match = find(mAttachedActors.begin(), mAttachedActors.end(), &object);
179
180     if ( match != mAttachedActors.end() )
181     {
182       mAttachedActors.erase(match);
183
184       // Notification for derived classes
185       OnActorDestroyed(object);
186
187       // Unregister from gesture event processor if we do not have any actors
188       if ( mAttachedActors.empty() )
189       {
190         // Guard to allow handle destruction after Core has been destroyed
191         if ( Stage::IsInstalled() )
192         {
193           mGestureEventProcessor.RemoveGestureDetector(this);
194         }
195       }
196     }
197   }
198 }
199
200 } // namespace Internal
201
202 } // namespace Dali