[dali_1.0.43] Merge branch 'tizen'
[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/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)
38 : mType(type),
39   mGestureEventProcessor(ThreadLocalStorage::Get().GetGestureEventProcessor())
40 {
41 }
42
43 GestureDetector::~GestureDetector()
44 {
45   if ( !mAttachedActors.empty() )
46   {
47     for ( GestureDetectorActorContainer::iterator iter = mAttachedActors.begin(), endIter = mAttachedActors.end(); iter != endIter; ++iter )
48     {
49       Actor* actor( *iter );
50       actor->RemoveObserver( *this );
51       actor->GetGestureData().RemoveGestureDetector( *this );
52     }
53
54     mAttachedActors.clear();
55
56     // Guard to allow handle destruction after Core has been destroyed
57     if ( Stage::IsInstalled() )
58     {
59       mGestureEventProcessor.RemoveGestureDetector( this );
60     }
61   }
62 }
63
64 void GestureDetector::Attach(Actor& actor)
65 {
66   if ( !IsAttached(actor) )
67   {
68     // Register with EventProcessor if first actor being added
69     if ( mAttachedActors.empty() )
70     {
71       mGestureEventProcessor.AddGestureDetector(this);
72     }
73
74     mAttachedActors.push_back(&actor);
75
76     // We need to observe the actor's destruction
77     actor.AddObserver(*this);
78
79     // Add the detector to the actor (so the actor knows it requires this gesture when going through hit-test algorithm)
80     actor.GetGestureData().AddGestureDetector( *this );
81
82     // Notification for derived classes
83     OnActorAttach(actor);
84   }
85 }
86
87 void GestureDetector::Detach(Actor& actor)
88 {
89   if ( !mAttachedActors.empty() )
90   {
91     GestureDetectorActorContainer::iterator match = find(mAttachedActors.begin(), mAttachedActors.end(), &actor);
92
93     if ( match != mAttachedActors.end() )
94     {
95       // We no longer need to observe the actor's destruction
96       actor.RemoveObserver(*this);
97
98       // Remove detector from actor-gesture-data
99       actor.GetGestureData().RemoveGestureDetector( *this );
100
101       mAttachedActors.erase(match);
102
103       // Notification for derived classes
104       OnActorDetach(actor);
105
106       // Unregister from gesture event processor if we do not have any actors
107       if ( mAttachedActors.empty() )
108       {
109         mGestureEventProcessor.RemoveGestureDetector(this);
110       }
111     }
112   }
113 }
114
115 void GestureDetector::DetachAll()
116 {
117   if ( !mAttachedActors.empty() )
118   {
119     GestureDetectorActorContainer attachedActors(mAttachedActors);
120
121     // Clear mAttachedActors before we call OnActorDetach in case derived classes call a method which manipulates mAttachedActors.
122     mAttachedActors.clear();
123
124     for ( GestureDetectorActorContainer::iterator iter = attachedActors.begin(), endIter = attachedActors.end(); iter != endIter; ++iter )
125     {
126       Actor* actor(*iter);
127
128       // We no longer need to observe the actor's destruction
129       actor->RemoveObserver(*this);
130
131       // Remove detector from actor-gesture-data
132       actor->GetGestureData().RemoveGestureDetector( *this );
133
134       // Notification for derived classes
135       OnActorDetach(*actor);
136     }
137
138     // Unregister from gesture event processor
139     mGestureEventProcessor.RemoveGestureDetector(this);
140   }
141 }
142
143 size_t GestureDetector::GetAttachedActorCount() const
144 {
145   return mAttachedActors.size();
146 }
147
148 Dali::Actor GestureDetector::GetAttachedActor(size_t index) const
149 {
150   Dali::Actor actor;
151
152   if( index < mAttachedActors.size() )
153   {
154     actor = Dali::Actor( mAttachedActors[index] );
155   }
156
157   return actor;
158 }
159
160 bool GestureDetector::IsAttached(Actor& actor) const
161 {
162   return find(mAttachedActors.begin(), mAttachedActors.end(), &actor) != mAttachedActors.end();
163 }
164
165 void GestureDetector::ObjectDestroyed(Object& object)
166 {
167   if ( !mAttachedActors.empty() )
168   {
169     GestureDetectorActorContainer::iterator match = find(mAttachedActors.begin(), mAttachedActors.end(), &object);
170
171     if ( match != mAttachedActors.end() )
172     {
173       mAttachedActors.erase(match);
174
175       // Notification for derived classes
176       OnActorDestroyed(object);
177
178       // Unregister from gesture event processor if we do not have any actors
179       if ( mAttachedActors.empty() )
180       {
181         mGestureEventProcessor.RemoveGestureDetector(this);
182       }
183     }
184   }
185 }
186
187 unsigned int GestureDetector::GetDefaultPropertyCount() const
188 {
189   return 0;
190 }
191
192 void GestureDetector::GetDefaultPropertyIndices( Property::IndexContainer& ) const
193 {
194 }
195
196 const char* GestureDetector::GetDefaultPropertyName( Property::Index index ) const
197 {
198   return NULL;
199 }
200
201 Property::Index GestureDetector::GetDefaultPropertyIndex(const std::string& name) const
202 {
203   return 0;
204 }
205
206 bool GestureDetector::IsDefaultPropertyWritable(Property::Index index) const
207 {
208   return false;
209 }
210
211 bool GestureDetector::IsDefaultPropertyAnimatable(Property::Index index) const
212 {
213   return false;
214 }
215
216 bool GestureDetector::IsDefaultPropertyAConstraintInput( Property::Index index ) const
217 {
218   return false;
219 }
220
221 Property::Type GestureDetector::GetDefaultPropertyType(Property::Index index) const
222 {
223   return Property::NONE;
224 }
225
226 void GestureDetector::SetDefaultProperty( Property::Index index, const Property::Value& property )
227 {
228   // None of our properties should be settable from Public API
229 }
230
231 Property::Value GestureDetector::GetDefaultProperty(Property::Index index) const
232 {
233   return Property::Value();
234 }
235
236 const SceneGraph::PropertyOwner* GestureDetector::GetSceneObject() const
237 {
238   return NULL;
239 }
240
241 const SceneGraph::PropertyBase* GestureDetector::GetSceneObjectAnimatableProperty( Property::Index index ) const
242 {
243   return NULL;
244 }
245
246 const PropertyInputImpl* GestureDetector::GetSceneObjectInputProperty( Property::Index index ) const
247 {
248   return NULL;
249 }
250
251 } // namespace Internal
252
253 } // namespace Dali