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