Dali 3D User Interface Engine
gesture-processor.cpp
Go to the documentation of this file.
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
20 
21 // INTERNAL INCLUDES
28 
29 namespace Dali
30 {
31 
32 namespace Internal
33 {
34 
35 namespace
36 {
37 
42 {
44  : mType( type )
45  {
46  }
47 
48  virtual bool IsActorHittable( Actor* actor )
49  {
50  return actor->IsGestureRequred( mType ) && // Does the Application or derived actor type require the gesture?
51  actor->IsHittable(); // Is actor sensitive, visible and on the scene?
52  }
53 
54  virtual bool DescendActorHierarchy( Actor* actor )
55  {
56  return actor->IsVisible() && // Actor is visible, if not visible then none of its children are visible.
57  actor->IsSensitive(); // Actor is sensitive, if insensitive none of its children should be hittable either.
58  }
59 
60  virtual bool DoesLayerConsumeHit( Layer* layer )
61  {
62  return layer->IsTouchConsumed();
63  }
64 
66 };
67 
68 } // unnamed namespace
69 
70 
72 : mType( type ),
73  mCurrentGesturedActor( NULL ),
74  mGesturedActorDisconnected( false )
75 {
76 }
77 
79 {
80  ResetActor();
81 }
82 
84 {
85  while ( actor )
86  {
87  // We may be checking a parent so ensure the parent requires this gesture (and do not unintentionally create the gesture data for the parent)
88  if ( actor->IsGestureRequred( mType ) )
89  {
90  // Retrieve the actor's detectors and check if they satisfy current gesture
91  const GestureDetectorContainer& connectedDetectors( actor->GetGestureData().GetGestureDetectorContainer( mType ) );
92  const GestureDetectorContainer::const_iterator endIter( connectedDetectors.end() );
93  for ( GestureDetectorContainer::const_iterator iter = connectedDetectors.begin(); iter != endIter; ++iter )
94  {
95  GestureDetector* current(*iter);
96 
97  // Check deriving class for whether the current gesture satisfies the gesture detector's parameters.
98  if ( CheckGestureDetector( current, actor ) )
99  {
100  gestureDetectors.push_back(current);
101  }
102  }
103 
104  // The hit actor or one of the parents is a gestured actor, break out.
105  if ( !gestureDetectors.empty() )
106  {
107  break;
108  }
109  }
110 
111  // No match, we should now check the hit actor's parent.
112  actor = actor->GetParent();
113  }
114 }
115 
117 {
118  if ( hitTestResults.actor )
119  {
120  Actor* hitTestActor( &GetImplementation( hitTestResults.actor ) );
121  Actor* actor( hitTestActor );
122 
123  while ( actor )
124  {
125  GestureDetectorContainer gestureDetectors;
126  GetGesturedActor( actor, gestureDetectors );
127 
128  if ( actor && !gestureDetectors.empty() )
129  {
130  // We have a match but check if the hit point is within the gestured actor's bounds.
131  // If it is not then continue up the actor hierarchy.
132 
133  if ( actor == hitTestActor )
134  {
135  // Our gesture detector's attached actor WAS the hit actor so we can can emit the signal.
136  EmitGestureSignal( actor, gestureDetectors, hitTestResults.actorCoordinates );
137  break; // We have found AND emitted a signal on the gestured actor, break out.
138  }
139  else
140  {
141  if ( actor->IsHittable() )
142  {
143  const Vector3 size( actor->GetCurrentSize() );
144 
145  if ( ( size.x > 0.0f ) && ( size.y > 0.0f ) )
146  {
147  // Ensure tap is within the actor's area
148  if ( actor->RaySphereTest( hitTestResults.rayOrigin, hitTestResults.rayDirection ) ) // Quick check
149  {
150  Vector4 hitPointLocal;
151  float distance( 0.0f );
152  if( actor->RayActorTest( hitTestResults.rayOrigin, hitTestResults.rayDirection, hitPointLocal, distance ) )
153  {
154  // One of the parents was the gestured actor so we can emit the signal for that actor.
155  EmitGestureSignal( actor, gestureDetectors, Vector2( hitPointLocal.x, hitPointLocal.y ) );
156  break; // We have found AND emitted a signal on the gestured actor, break out.
157  }
158  }
159  }
160  }
161  }
162  }
163 
164  // Continue up hierarchy to see if any of the parents require this gesture.
165  if ( actor )
166  {
167  actor = actor->GetParent();
168  }
169  }
170  }
171 }
172 
174  Stage& stage,
175  Vector2 screenCoordinates,
176  HitTestAlgorithm::Results& hitTestResults)
177 {
178  GestureHitTestCheck hitCheck( mType );
179  HitTestAlgorithm::HitTest( stage, screenCoordinates, hitTestResults, hitCheck );
180  return hitTestResults.renderTask && hitTestResults.actor;
181 }
182 
184 {
185  if ( actor && actor != mCurrentGesturedActor )
186  {
187  ResetActor();
188 
189  mCurrentGesturedActor = actor;
191  }
193 }
194 
196 {
197  if ( mCurrentGesturedActor )
198  {
200  mCurrentGesturedActor = NULL;
202  }
203 }
204 
206 {
208 }
209 
211 {
212  if ( mCurrentGesturedActor == &object &&
214  {
215  // Inform deriving classes.
217 
218  // do not call object.RemoveObserver here, object is currently iterating through observers... you wouldnt want to upset object now would you?
220  }
221 }
222 
224 {
225  if ( mCurrentGesturedActor == &object )
226  {
227  // Inform deriving classes.
229 
230  mCurrentGesturedActor = NULL;
231  }
232 }
233 
234 } // namespace Internal
235 
236 } // namespace Dali
Dali Docs Home
Read more about Dali