Conversion to Apache 2.0 license
[platform/core/uifw/dali-core.git] / dali / internal / event / events / gesture-detector-impl.cpp
1 /*
2  * Copyright (c) 2014 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/gesture-event-processor.h>
27 #include <dali/internal/event/common/thread-local-storage.h>
28 #include <dali/internal/event/common/stage-impl.h>
29
30 namespace Dali
31 {
32
33 namespace Internal
34 {
35
36 namespace
37 {
38 const std::string INVALID_PROPERTY; // Empty string for invalid calls
39 }
40
41 GestureDetector::GestureDetector(Gesture::Type type)
42 : mType(type),
43   mGestureEventProcessor(ThreadLocalStorage::Get().GetGestureEventProcessor())
44 {
45 }
46
47 GestureDetector::~GestureDetector()
48 {
49   if ( !mAttachedActors.empty() )
50   {
51     for ( GestureDetectorActorContainer::iterator iter = mAttachedActors.begin(), endIter = mAttachedActors.end(); iter != endIter; ++iter )
52     {
53       Actor* actor( *iter );
54       actor->RemoveObserver( *this );
55       actor->RemoveGestureDetector( *this );
56     }
57
58     mAttachedActors.clear();
59
60     // Guard to allow handle destruction after Core has been destroyed
61     if ( Stage::IsInstalled() )
62     {
63       mGestureEventProcessor.RemoveGestureDetector( this );
64     }
65   }
66 }
67
68 void GestureDetector::Attach(Actor& actor)
69 {
70   if ( !IsAttached(actor) )
71   {
72     // Register with EventProcessor if first actor being added
73     if ( mAttachedActors.empty() )
74     {
75       mGestureEventProcessor.AddGestureDetector(this);
76     }
77
78     mAttachedActors.push_back(&actor);
79
80     // We need to observe the actor's destruction
81     actor.AddObserver(*this);
82
83     // Add the detector to the actor (so the actor knows it requires this gesture when going through hit-test algorithm)
84     actor.AddGestureDetector( *this );
85
86     // Notification for derived classes
87     OnActorAttach(actor);
88   }
89 }
90
91 void GestureDetector::Detach(Actor& actor)
92 {
93   if ( !mAttachedActors.empty() )
94   {
95     GestureDetectorActorContainer::iterator match = find(mAttachedActors.begin(), mAttachedActors.end(), &actor);
96
97     if ( match != mAttachedActors.end() )
98     {
99       // We no longer need to observe the actor's destruction
100       actor.RemoveObserver(*this);
101
102       // Remove detector from actor (so it is set to no longer requiring this gesture when going through the hit-test algorithm)
103       actor.RemoveGestureDetector( *this );
104
105       mAttachedActors.erase(match);
106
107       // Notification for derived classes
108       OnActorDetach(actor);
109
110       // Unregister from gesture event processor if we do not have any actors
111       if ( mAttachedActors.empty() )
112       {
113         mGestureEventProcessor.RemoveGestureDetector(this);
114       }
115     }
116   }
117 }
118
119 void GestureDetector::DetachAll()
120 {
121   if ( !mAttachedActors.empty() )
122   {
123     GestureDetectorActorContainer attachedActors(mAttachedActors);
124
125     // Clear mAttachedActors before we call OnActorDetach in case derived classes call a method which manipulates mAttachedActors.
126     mAttachedActors.clear();
127
128     for ( GestureDetectorActorContainer::iterator iter = attachedActors.begin(), endIter = attachedActors.end(); iter != endIter; ++iter )
129     {
130       Actor* actor(*iter);
131
132       // We no longer need to observe the actor's destruction
133       actor->RemoveObserver(*this);
134
135       // Remove detector from actor (so it is set to no longer requiring this gesture when going through the hit-test algorithm)
136       actor->RemoveGestureDetector( *this );
137
138       // Notification for derived classes
139       OnActorDetach(*actor);
140     }
141
142     // Unregister from gesture event processor
143     mGestureEventProcessor.RemoveGestureDetector(this);
144   }
145 }
146
147 std::vector<Dali::Actor> GestureDetector::GetAttachedActors() const
148 {
149   // Will only be used by Public API.
150   // Unlikely that it will be called that often so copying should be OK.
151
152   std::vector<Dali::Actor> actors;
153
154   for ( GestureDetectorActorContainer::const_iterator iter = mAttachedActors.begin(), endIter = mAttachedActors.end(); iter != endIter; ++iter )
155   {
156     actors.push_back(Dali::Actor(*iter));
157   }
158
159   return actors;
160 }
161
162 bool GestureDetector::IsAttached(Actor& actor) const
163 {
164   return find(mAttachedActors.begin(), mAttachedActors.end(), &actor) != mAttachedActors.end();
165 }
166
167 void GestureDetector::ProxyDestroyed(ProxyObject& proxy)
168 {
169   if ( !mAttachedActors.empty() )
170   {
171     GestureDetectorActorContainer::iterator match = find(mAttachedActors.begin(), mAttachedActors.end(), &proxy);
172
173     if ( match != mAttachedActors.end() )
174     {
175       mAttachedActors.erase(match);
176
177       // Notification for derived classes
178       OnActorDestroyed(proxy);
179
180       // Unregister from gesture event processor if we do not have any actors
181       if ( mAttachedActors.empty() )
182       {
183         mGestureEventProcessor.RemoveGestureDetector(this);
184       }
185     }
186   }
187 }
188
189 bool GestureDetector::IsSceneObjectRemovable() const
190 {
191   return false;
192 }
193
194 unsigned int GestureDetector::GetDefaultPropertyCount() const
195 {
196   return 0;
197 }
198
199 void GestureDetector::GetDefaultPropertyIndices( Property::IndexContainer& ) const
200 {
201 }
202
203 const std::string& GestureDetector::GetDefaultPropertyName( Property::Index index ) const
204 {
205   return INVALID_PROPERTY;
206 }
207
208 Property::Index GestureDetector::GetDefaultPropertyIndex(const std::string& name) const
209 {
210   return 0;
211 }
212
213 bool GestureDetector::IsDefaultPropertyWritable(Property::Index index) const
214 {
215   return false;
216 }
217
218 bool GestureDetector::IsDefaultPropertyAnimatable(Property::Index index) const
219 {
220   return false;
221 }
222
223 bool GestureDetector::IsDefaultPropertyAConstraintInput( Property::Index index ) const
224 {
225   return false;
226 }
227
228 Property::Type GestureDetector::GetDefaultPropertyType(Property::Index index) const
229 {
230   return Property::NONE;
231 }
232
233 void GestureDetector::SetDefaultProperty( Property::Index index, const Property::Value& property )
234 {
235   // None of our properties should be settable from Public API
236 }
237
238 void GestureDetector::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
239 {
240   // None of our properties should be settable from Public API
241 }
242
243 Property::Value GestureDetector::GetDefaultProperty(Property::Index index) const
244 {
245   return Property::Value();
246 }
247
248 void GestureDetector::InstallSceneObjectProperty( SceneGraph::PropertyBase& newProperty, const std::string& name, unsigned int index )
249 {
250   // We do not want the user to install custom properties
251 }
252
253 const SceneGraph::PropertyOwner* GestureDetector::GetSceneObject() const
254 {
255   return NULL;
256 }
257
258 const SceneGraph::PropertyBase* GestureDetector::GetSceneObjectAnimatableProperty( Property::Index index ) const
259 {
260   return NULL;
261 }
262
263 const PropertyInputImpl* GestureDetector::GetSceneObjectInputProperty( Property::Index index ) const
264 {
265   return NULL;
266 }
267
268 } // namespace Internal
269
270 } // namespace Dali