Revert "[Tizen] Revert "Use touch consumed return to set whether we process a gesture...
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-RotationGestureDetector.cpp
1 /*
2  * Copyright (c) 2020 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 #include <dali-test-suite-utils.h>
19 #include <dali/integration-api/events/touch-event-integ.h>
20 #include <dali/integration-api/render-task-list-integ.h>
21 #include <dali/public-api/dali-core.h>
22 #include <stdlib.h>
23 #include <test-touch-event-utils.h>
24
25 #include <iostream>
26
27 using namespace Dali;
28
29 void utc_dali_rotation_gesture_detector_startup(void)
30 {
31   test_return_value = TET_UNDEF;
32 }
33
34 void utc_dali_rotation_gesture_detector_cleanup(void)
35 {
36   test_return_value = TET_PASS;
37 }
38
39 ///////////////////////////////////////////////////////////////////////////////
40 namespace
41 {
42 // Stores data that is populated in the callback and will be read by the TET cases
43 struct SignalData
44 {
45   SignalData()
46   : functorCalled(false),
47     voidFunctorCalled(false),
48     receivedGesture()
49   {
50   }
51
52   void Reset()
53   {
54     functorCalled     = false;
55     voidFunctorCalled = false;
56
57     receivedGesture.Reset();
58
59     rotatedActor.Reset();
60   }
61
62   bool            functorCalled;
63   bool            voidFunctorCalled;
64   RotationGesture receivedGesture;
65   Actor           rotatedActor;
66 };
67
68 // Functor that sets the data when called
69 struct GestureReceivedFunctor
70 {
71   GestureReceivedFunctor(SignalData& data)
72   : signalData(data)
73   {
74   }
75
76   void operator()(Actor actor, const RotationGesture& rotation)
77   {
78     signalData.functorCalled   = true;
79     signalData.receivedGesture = rotation;
80     signalData.rotatedActor    = actor;
81   }
82
83   void operator()()
84   {
85     signalData.voidFunctorCalled = true;
86   }
87
88   SignalData& signalData;
89 };
90
91 // Functor that removes the gestured actor from stage
92 struct UnstageActorFunctor : public GestureReceivedFunctor
93 {
94   UnstageActorFunctor(SignalData& data, GestureState& stateToUnstage, Integration::Scene scene)
95   : GestureReceivedFunctor(data),
96     stateToUnstage(stateToUnstage),
97     scene(scene)
98   {
99   }
100
101   void operator()(Actor actor, const RotationGesture& rotation)
102   {
103     GestureReceivedFunctor::operator()(actor, rotation);
104
105     if(rotation.GetState() == stateToUnstage)
106     {
107       scene.Remove(actor);
108     }
109   }
110
111   GestureState&      stateToUnstage;
112   Integration::Scene scene;
113 };
114
115 } // namespace
116
117 ///////////////////////////////////////////////////////////////////////////////
118
119 int UtcDaliRotationGestureDetectorConstructor(void)
120 {
121   TestApplication application;
122
123   RotationGestureDetector detector;
124   DALI_TEST_CHECK(!detector);
125   END_TEST;
126 }
127
128 int UtcDaliRotationGestureDetectorCopyConstructorP(void)
129 {
130   TestApplication application;
131
132   RotationGestureDetector detector = RotationGestureDetector::New();
133   ;
134
135   RotationGestureDetector copy(detector);
136   DALI_TEST_CHECK(detector);
137   END_TEST;
138 }
139
140 int UtcDaliRotationGestureDetectorAssignmentOperatorP(void)
141 {
142   TestApplication application;
143
144   RotationGestureDetector detector = RotationGestureDetector::New();
145   ;
146
147   RotationGestureDetector assign;
148   assign = detector;
149   DALI_TEST_CHECK(detector);
150
151   DALI_TEST_CHECK(detector == assign);
152   END_TEST;
153 }
154
155 int UtcDaliRotationGestureDetectorNew(void)
156 {
157   TestApplication application;
158
159   RotationGestureDetector detector = RotationGestureDetector::New();
160
161   DALI_TEST_CHECK(detector);
162
163   // Attach an actor and emit a touch event on the actor to ensure complete line coverage
164   Actor actor = Actor::New();
165   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
166   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
167   application.GetScene().Add(actor);
168
169   // Render and notify
170   application.SendNotification();
171   application.Render();
172
173   detector.Attach(actor);
174
175   Integration::TouchEvent touchEvent(1);
176   Integration::Point      point;
177   point.SetDeviceId(1);
178   point.SetState(PointState::DOWN);
179   point.SetScreenPosition(Vector2(20.0f, 20.0f));
180   touchEvent.AddPoint(point);
181   application.ProcessEvent(touchEvent);
182
183   Integration::Point point2;
184   point.SetDeviceId(1);
185   point.SetState(PointState::DOWN);
186   point.SetScreenPosition(Vector2(20.0f, 20.0f));
187   touchEvent.AddPoint(point2);
188   application.ProcessEvent(touchEvent);
189   END_TEST;
190 }
191
192 int UtcDaliRotationGestureDetectorDownCast(void)
193 {
194   TestApplication application;
195   tet_infoline("Testing Dali::RotationGestureDetector::DownCast()");
196
197   RotationGestureDetector detector = RotationGestureDetector::New();
198
199   BaseHandle object(detector);
200
201   RotationGestureDetector detector2 = RotationGestureDetector::DownCast(object);
202   DALI_TEST_CHECK(detector2);
203
204   RotationGestureDetector detector3 = DownCast<RotationGestureDetector>(object);
205   DALI_TEST_CHECK(detector3);
206
207   BaseHandle              unInitializedObject;
208   RotationGestureDetector detector4 = RotationGestureDetector::DownCast(unInitializedObject);
209   DALI_TEST_CHECK(!detector4);
210
211   RotationGestureDetector detector5 = DownCast<RotationGestureDetector>(unInitializedObject);
212   DALI_TEST_CHECK(!detector5);
213
214   GestureDetector         detector6 = RotationGestureDetector::New();
215   RotationGestureDetector detector7 = RotationGestureDetector::DownCast(detector6);
216   DALI_TEST_CHECK(detector7);
217   END_TEST;
218 }
219
220 // Negative test case for a method
221 int UtcDaliRotationGestureSignalReceptionNegative(void)
222 {
223   TestApplication application;
224
225   Actor actor = Actor::New();
226   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
227   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
228   application.GetScene().Add(actor);
229
230   // Render and notify
231   application.SendNotification();
232   application.Render();
233
234   SignalData             data;
235   GestureReceivedFunctor functor(data);
236
237   RotationGestureDetector detector = RotationGestureDetector::New();
238   detector.Attach(actor);
239   detector.DetectedSignal().Connect(&application, functor);
240
241   // Do a rotation outside actor's area
242   TestStartRotation(application, Vector2(112.0f, 62.0f), Vector2(112.0f, 162.0f), Vector2(112.0f, 100.0f), Vector2(112.0f, 124.0f), 100);
243
244   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
245
246   // Continue rotation into actor's area - we should still not receive the signal
247   data.Reset();
248   TestContinueRotation(application, Vector2(112.0f, 100.0f), Vector2(112.0f, 124.0f), Vector2(5.0f, 5.0f), Vector2(35.0f, 35.0f), 200);
249
250   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
251
252   // Stop rotating - we should still not receive the signal
253   data.Reset();
254   TestEndRotation(application, Vector2(6.0f, 6.0f), Vector2(18.0f, 18.0f), Vector2(10.0f, 8.0f), Vector2(14.0f, 16.0f), 300);
255
256   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
257   END_TEST;
258 }
259
260 int UtcDaliRotationGestureSignalReceptionDownMotionLeave(void)
261 {
262   TestApplication application;
263
264   Actor actor = Actor::New();
265   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
266   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
267   application.GetScene().Add(actor);
268
269   // Render and notify
270   application.SendNotification();
271   application.Render();
272
273   SignalData             data;
274   GestureReceivedFunctor functor(data);
275
276   RotationGestureDetector detector = RotationGestureDetector::New();
277   detector.Attach(actor);
278   detector.DetectedSignal().Connect(&application, functor);
279
280   // Start rotation within the actor's area
281   TestStartRotation(application, Vector2(5.0f, 5.0f), Vector2(20.0f, 20.0f), Vector2(5.0f, 5.0f), Vector2(20.0f, 30.0f), 100);
282   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
283   DALI_TEST_EQUALS(GestureState::STARTED, data.receivedGesture.GetState(), TEST_LOCATION);
284   DALI_TEST_EQUALS(0.244f, data.receivedGesture.GetRotation().radian, 0.01f, TEST_LOCATION);
285   DALI_TEST_EQUALS(Vector2(12.5f, 17.5f), data.receivedGesture.GetScreenCenterPoint(), 0.01f, TEST_LOCATION);
286   DALI_TEST_EQUALS(Vector2(12.48f, 17.5f), data.receivedGesture.GetLocalCenterPoint(), 0.01f, TEST_LOCATION);
287
288   // Continue the rotation within the actor's area - we should still receive the signal
289   data.Reset();
290   TestContinueRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(17.0f, 20.0f), Vector2(25.0f, 20.0f), 400);
291   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
292   DALI_TEST_EQUALS(GestureState::CONTINUING, data.receivedGesture.GetState(), TEST_LOCATION);
293   DALI_TEST_EQUALS(-0.785398f, data.receivedGesture.GetRotation().radian, 0.01f, TEST_LOCATION);
294   DALI_TEST_EQUALS(Vector2(21.0f, 20.0f), data.receivedGesture.GetScreenCenterPoint(), 0.01f, TEST_LOCATION);
295   DALI_TEST_EQUALS(Vector2(21.0f, 20.0f), data.receivedGesture.GetLocalCenterPoint(), 0.01f, TEST_LOCATION);
296
297   // Rotation Gesture leaves actor's area - we should still receive the signal
298   data.Reset();
299   TestContinueRotation(application, Vector2(17.0f, 20.0f), Vector2(25.0f, 20.0f), Vector2(300.0f, 10.0f), Vector2(340.0f, 10.0f), 1000);
300   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
301   DALI_TEST_EQUALS(GestureState::CONTINUING, data.receivedGesture.GetState(), TEST_LOCATION);
302   DALI_TEST_EQUALS(-0.785398f, data.receivedGesture.GetRotation().radian, 0.01f, TEST_LOCATION);
303   DALI_TEST_EQUALS(Vector2(320.0f, 10.0f), data.receivedGesture.GetScreenCenterPoint(), 0.01f, TEST_LOCATION);
304   DALI_TEST_EQUALS(Vector2(320.0f, 10.0f), data.receivedGesture.GetLocalCenterPoint(), 0.01f, TEST_LOCATION);
305
306   // Gesture ends - we would receive a finished state
307   data.Reset();
308   TestEndRotation(application, Vector2(300.0f, 10.0f), Vector2(340.0f, 10.0f), Vector2(305.0f, 10.0f), Vector2(315.0f, 10.0f), 1500);
309   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
310   DALI_TEST_EQUALS(GestureState::FINISHED, data.receivedGesture.GetState(), TEST_LOCATION);
311   DALI_TEST_EQUALS(-0.785398f, data.receivedGesture.GetRotation().radian, 0.01f, TEST_LOCATION);
312   DALI_TEST_EQUALS(Vector2(310.0f, 10.0f), data.receivedGesture.GetScreenCenterPoint(), 0.01f, TEST_LOCATION);
313   DALI_TEST_EQUALS(Vector2(310.0f, 10.0f), data.receivedGesture.GetLocalCenterPoint(), 0.01f, TEST_LOCATION);
314   END_TEST;
315 }
316
317 int UtcDaliRotationGestureSignalReceptionDownMotionUp(void)
318 {
319   TestApplication application;
320
321   Actor actor = Actor::New();
322   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
323   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
324   application.GetScene().Add(actor);
325
326   // Render and notify
327   application.SendNotification();
328   application.Render();
329
330   SignalData             data;
331   GestureReceivedFunctor functor(data);
332
333   RotationGestureDetector detector = RotationGestureDetector::New();
334   detector.Attach(actor);
335   detector.DetectedSignal().Connect(&application, functor);
336
337   // Start rotation within the actor's area
338   TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(31.0f, 29.0f), 100);
339   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
340   DALI_TEST_EQUALS(GestureState::STARTED, data.receivedGesture.GetState(), TEST_LOCATION);
341   DALI_TEST_EQUALS(0.404892f, data.receivedGesture.GetRotation().radian, 0.01f, TEST_LOCATION);
342   DALI_TEST_EQUALS(Vector2(20.5f, 24.5f), data.receivedGesture.GetScreenCenterPoint(), 0.01f, TEST_LOCATION);
343   DALI_TEST_EQUALS(Vector2(20.5f, 24.5f), data.receivedGesture.GetLocalCenterPoint(), 0.01f, TEST_LOCATION);
344
345   // Continue the rotation within the actor's area - we should still receive the signal
346   data.Reset();
347   TestContinueRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(15.0f, 20.0f), Vector2(29.0f, 15.0f), 500);
348   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
349   DALI_TEST_EQUALS(GestureState::CONTINUING, data.receivedGesture.GetState(), TEST_LOCATION);
350   DALI_TEST_EQUALS(-0.343024f, data.receivedGesture.GetRotation().radian, 0.01f, TEST_LOCATION);
351   DALI_TEST_EQUALS(Vector2(22.0f, 17.5f), data.receivedGesture.GetScreenCenterPoint(), 0.01f, TEST_LOCATION);
352   DALI_TEST_EQUALS(Vector2(22.0f, 17.5f), data.receivedGesture.GetLocalCenterPoint(), 0.01f, TEST_LOCATION);
353
354   // Gesture ends within actor's area - we would receive a finished state
355   data.Reset();
356   TestEndRotation(application, Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(29.0f, 15.0f), 1000);
357   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
358   DALI_TEST_EQUALS(GestureState::FINISHED, data.receivedGesture.GetState(), TEST_LOCATION);
359   DALI_TEST_EQUALS(-0.463648f, data.receivedGesture.GetRotation().radian, 0.01f, TEST_LOCATION);
360   DALI_TEST_EQUALS(Vector2(24.0f, 17.5f), data.receivedGesture.GetScreenCenterPoint(), 0.01f, TEST_LOCATION);
361   DALI_TEST_EQUALS(Vector2(24.0f, 17.5f), data.receivedGesture.GetLocalCenterPoint(), 0.01f, TEST_LOCATION);
362   END_TEST;
363 }
364
365 int UtcDaliRotationGestureSignalReceptionDetach(void)
366 {
367   TestApplication application;
368
369   Actor actor = Actor::New();
370   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
371   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
372   application.GetScene().Add(actor);
373
374   // Render and notify
375   application.SendNotification();
376   application.Render();
377
378   SignalData             data;
379   GestureReceivedFunctor functor(data);
380
381   RotationGestureDetector detector = RotationGestureDetector::New();
382   detector.Attach(actor);
383   detector.DetectedSignal().Connect(&application, functor);
384
385   // Start rotation within the actor's area
386   TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
387   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
388   DALI_TEST_EQUALS(GestureState::STARTED, data.receivedGesture.GetState(), TEST_LOCATION);
389
390   // Continue the rotation within the actor's area - we should still receive the signal
391   data.Reset();
392   TestContinueRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), 500);
393   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
394   DALI_TEST_EQUALS(GestureState::CONTINUING, data.receivedGesture.GetState(), TEST_LOCATION);
395
396   // Gesture ends within actor's area
397   data.Reset();
398   TestEndRotation(application, Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(21.0f, 20.0f), 1000);
399   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
400   DALI_TEST_EQUALS(GestureState::FINISHED, data.receivedGesture.GetState(), TEST_LOCATION);
401
402   // Detach actor
403   detector.DetachAll();
404
405   // Ensure we are no longer signalled
406   data.Reset();
407   TestGenerateRotation(application);
408   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
409   END_TEST;
410 }
411
412 int UtcDaliRotationGestureSignalReceptionDetachWhileRotationing(void)
413 {
414   TestApplication application;
415
416   Actor actor = Actor::New();
417   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
418   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
419   application.GetScene().Add(actor);
420
421   // Render and notify
422   application.SendNotification();
423   application.Render();
424
425   SignalData             data;
426   GestureReceivedFunctor functor(data);
427
428   RotationGestureDetector detector = RotationGestureDetector::New();
429   detector.Attach(actor);
430   detector.DetectedSignal().Connect(&application, functor);
431
432   // Start rotation within the actor's area
433   TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
434   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
435   DALI_TEST_EQUALS(GestureState::STARTED, data.receivedGesture.GetState(), TEST_LOCATION);
436
437   // Continue the rotation within the actor's area - we should still receive the signal
438   data.Reset();
439   TestContinueRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), 500);
440   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
441   DALI_TEST_EQUALS(GestureState::CONTINUING, data.receivedGesture.GetState(), TEST_LOCATION);
442
443   // Detach actor during the rotation, we should not receive the next event
444   detector.DetachAll();
445
446   // Gesture ends within actor's area
447   data.Reset();
448   TestEndRotation(application, Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(21.0f, 20.0f), 1000);
449   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
450   END_TEST;
451 }
452
453 int UtcDaliRotationGestureSignalReceptionActorDestroyedWhileRotationing(void)
454 {
455   TestApplication application;
456
457   SignalData             data;
458   GestureReceivedFunctor functor(data);
459
460   RotationGestureDetector detector = RotationGestureDetector::New();
461   detector.DetectedSignal().Connect(&application, functor);
462
463   // Attach a temporary actor to stop detector being removed from RotationGestureProcessor when main actor
464   // is destroyed.
465   Actor tempActor = Actor::New();
466   tempActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
467   tempActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_RIGHT);
468   application.GetScene().Add(tempActor);
469   detector.Attach(tempActor);
470
471   // Actor lifetime is scoped
472   {
473     Actor actor = Actor::New();
474     actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
475     actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
476     application.GetScene().Add(actor);
477
478     // Render and notify
479     application.SendNotification();
480     application.Render();
481
482     detector.Attach(actor);
483
484     // Start rotation within the actor's area
485     TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
486     DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
487     DALI_TEST_EQUALS(GestureState::STARTED, data.receivedGesture.GetState(), TEST_LOCATION);
488
489     // Continue the rotation within the actor's area - we should still receive the signal
490     data.Reset();
491     TestContinueRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), 500);
492     DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
493     DALI_TEST_EQUALS(GestureState::CONTINUING, data.receivedGesture.GetState(), TEST_LOCATION);
494
495     // Remove the actor from stage and reset the data
496     application.GetScene().Remove(actor);
497
498     // Render and notify
499     application.SendNotification();
500     application.Render();
501   }
502
503   // Actor should now have been destroyed
504
505   // Gesture ends within the area where the actor used to be
506   data.Reset();
507   TestEndRotation(application, Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(21.0f, 20.0f), 1000);
508   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
509   END_TEST;
510 }
511
512 int UtcDaliRotationGestureSignalReceptionRotatedActor(void)
513 {
514   TestApplication application;
515
516   Actor actor = Actor::New();
517   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
518   actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(90.0f), Vector3::ZAXIS));
519   application.GetScene().Add(actor);
520
521   // Render and notify a couple of times
522   application.SendNotification();
523   application.Render();
524
525   SignalData             data;
526   GestureReceivedFunctor functor(data);
527
528   RotationGestureDetector detector = RotationGestureDetector::New();
529   detector.Attach(actor);
530   detector.DetectedSignal().Connect(&application, functor);
531
532   // Do an entire rotation, only check finished value
533   TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
534   data.Reset();
535   TestEndRotation(application, Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(27.0f, 15.0f), 1000);
536   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
537   DALI_TEST_EQUALS(-0.558599f, data.receivedGesture.GetRotation().radian, 0.01f, TEST_LOCATION);
538   DALI_TEST_EQUALS(Vector2(23.0f, 17.5f), data.receivedGesture.GetScreenCenterPoint(), 0.01f, TEST_LOCATION);
539   DALI_TEST_EQUALS(Vector2(67.5f, 27.0f), data.receivedGesture.GetLocalCenterPoint(), 0.01f, TEST_LOCATION);
540
541   // Rotate actor again and render and notify
542   actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(180.0f), Vector3::ZAXIS));
543   application.SendNotification();
544   application.Render();
545
546   // Do an entire rotation, only check finished value
547   TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 2100);
548   data.Reset();
549   TestEndRotation(application, Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(27.0f, 15.0f), 3000);
550   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
551   DALI_TEST_EQUALS(-0.558599f, data.receivedGesture.GetRotation().radian, 0.01f, TEST_LOCATION);
552   DALI_TEST_EQUALS(Vector2(23.0f, 17.5f), data.receivedGesture.GetScreenCenterPoint(), 0.01f, TEST_LOCATION);
553   DALI_TEST_EQUALS(Vector2(27.0f, 32.5f), data.receivedGesture.GetLocalCenterPoint(), 0.01f, TEST_LOCATION);
554
555   // Rotate actor again and render and notify
556   actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(270.0f), Vector3::ZAXIS));
557   application.SendNotification();
558   application.Render();
559
560   // Do an entire rotation, only check finished value
561   TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 4100);
562   data.Reset();
563   TestEndRotation(application, Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(27.0f, 15.0f), 5000);
564   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
565   DALI_TEST_EQUALS(-0.558599f, data.receivedGesture.GetRotation().radian, 0.01f, TEST_LOCATION);
566   DALI_TEST_EQUALS(Vector2(23.0f, 17.5f), data.receivedGesture.GetScreenCenterPoint(), 0.01f, TEST_LOCATION);
567   DALI_TEST_EQUALS(Vector2(32.5f, 73.0f), data.receivedGesture.GetLocalCenterPoint(), 0.01f, TEST_LOCATION);
568   END_TEST;
569 }
570
571 int UtcDaliRotationGestureSignalReceptionChildHit(void)
572 {
573   TestApplication application;
574
575   Actor parent = Actor::New();
576   parent.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
577   parent.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
578   application.GetScene().Add(parent);
579
580   // Set child to completely cover parent.
581   // Change rotation of child to be different from parent so that we can check if our local coordinate
582   // conversion of the parent actor is correct.
583   Actor child = Actor::New();
584   child.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
585   child.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
586   child.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
587   child.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(90.0f), Vector3::ZAXIS));
588   parent.Add(child);
589
590   // Render and notify
591   application.SendNotification();
592   application.Render();
593
594   SignalData             data;
595   GestureReceivedFunctor functor(data);
596
597   RotationGestureDetector detector = RotationGestureDetector::New();
598   detector.Attach(parent);
599   detector.DetectedSignal().Connect(&application, functor);
600
601   // Do an entire pan, only check finished value - hits child area but parent should still receive it
602   TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
603   data.Reset();
604   TestEndRotation(application, Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(29.0f, 25.0f), 1000);
605   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
606   DALI_TEST_EQUALS(true, parent == data.rotatedActor, TEST_LOCATION);
607   DALI_TEST_EQUALS(0.463648f, data.receivedGesture.GetRotation().radian, 0.01f, TEST_LOCATION);
608   DALI_TEST_EQUALS(Vector2(24.0f, 22.5f), data.receivedGesture.GetScreenCenterPoint(), 0.01f, TEST_LOCATION);
609   DALI_TEST_EQUALS(Vector2(24.0f, 22.5f), data.receivedGesture.GetLocalCenterPoint(), 0.01f, TEST_LOCATION);
610
611   // Attach child and generate same touch points to yield same results
612   // (Also proves that you can detach and then re-attach another actor)
613   detector.Attach(child);
614   detector.Detach(parent);
615
616   // Do an entire pan, only check finished value
617   TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 2100);
618   data.Reset();
619   TestEndRotation(application, Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(29.0f, 35.0f), 3000);
620   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
621   DALI_TEST_EQUALS(true, child == data.rotatedActor, TEST_LOCATION);
622   DALI_TEST_EQUALS(0.982794f, data.receivedGesture.GetRotation().radian, 0.01f, TEST_LOCATION);
623   DALI_TEST_EQUALS(Vector2(24.0f, 27.5f), data.receivedGesture.GetScreenCenterPoint(), 0.01f, TEST_LOCATION);
624   DALI_TEST_EQUALS(Vector2(27.5f, 76.0f), data.receivedGesture.GetLocalCenterPoint(), 0.01f, TEST_LOCATION);
625   END_TEST;
626 }
627
628 int UtcDaliRotationGestureSignalReceptionAttachDetachMany(void)
629 {
630   TestApplication application;
631
632   Actor first = Actor::New();
633   first.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
634   first.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
635   application.GetScene().Add(first);
636
637   Actor second = Actor::New();
638   second.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
639   second.SetProperty(Actor::Property::POSITION_X, 100.0f);
640   second.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
641   application.GetScene().Add(second);
642
643   // Render and notify
644   application.SendNotification();
645   application.Render();
646
647   SignalData             data;
648   GestureReceivedFunctor functor(data);
649
650   RotationGestureDetector detector = RotationGestureDetector::New();
651   detector.Attach(first);
652   detector.Attach(second);
653   detector.DetectedSignal().Connect(&application, functor);
654
655   // Start rotation within second actor's area
656   TestStartRotation(application, Vector2(102.0f, 20.0f), Vector2(138.0f, 20.0f), Vector2(110.0f, 20.0f), Vector2(130.0f, 20.0f), 100);
657   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
658   DALI_TEST_EQUALS(true, second == data.rotatedActor, TEST_LOCATION);
659
660   // Rotation moves into first actor's area - second actor should receive the rotation
661   data.Reset();
662   TestContinueRotation(application, Vector2(110.0f, 20.0f), Vector2(130.0f, 20.0f), Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), 500);
663   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
664   DALI_TEST_EQUALS(true, second == data.rotatedActor, TEST_LOCATION);
665
666   // Detach the second actor during the rotation, we should not receive the next event
667   detector.Detach(second);
668
669   // Gesture ends within actor's area
670   data.Reset();
671   TestEndRotation(application, Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), Vector2(119.0f, 20.0f), Vector2(121.0f, 20.0f), 3000);
672   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
673   END_TEST;
674 }
675
676 int UtcDaliRotationGestureSignalReceptionActorBecomesUntouchable(void)
677 {
678   TestApplication application;
679
680   Actor actor = Actor::New();
681   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
682   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
683   application.GetScene().Add(actor);
684
685   // Render and notify
686   application.SendNotification();
687   application.Render();
688
689   SignalData             data;
690   GestureReceivedFunctor functor(data);
691
692   RotationGestureDetector detector = RotationGestureDetector::New();
693   detector.Attach(actor);
694   detector.DetectedSignal().Connect(&application, functor);
695
696   // Start rotation in actor's area
697   TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
698   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
699
700   // Rotation continues within actor's area
701   data.Reset();
702   TestContinueRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), 500);
703   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
704
705   // Actor become invisible - actor should not receive the next rotation
706   actor.SetProperty(Actor::Property::VISIBLE, false);
707
708   // Render and notify
709   application.SendNotification();
710   application.Render();
711
712   // Gesture ends within actor's area
713   data.Reset();
714   TestEndRotation(application, Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(21.0f, 20.0f), 3000);
715   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
716   END_TEST;
717 }
718
719 int UtcDaliRotationGestureSignalReceptionMultipleDetectorsOnActor(void)
720 {
721   TestApplication application;
722
723   Actor actor = Actor::New();
724   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
725   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
726   application.GetScene().Add(actor);
727
728   Actor actor2 = Actor::New();
729   actor2.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
730   actor2.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_RIGHT);
731   application.GetScene().Add(actor2);
732
733   // Render and notify
734   application.SendNotification();
735   application.Render();
736
737   // Attach actor to one detector
738   SignalData              firstData;
739   GestureReceivedFunctor  firstFunctor(firstData);
740   RotationGestureDetector firstDetector = RotationGestureDetector::New();
741   firstDetector.Attach(actor);
742   firstDetector.DetectedSignal().Connect(&application, firstFunctor);
743
744   // Attach actor to another detector
745   SignalData              secondData;
746   GestureReceivedFunctor  secondFunctor(secondData);
747   RotationGestureDetector secondDetector = RotationGestureDetector::New();
748   secondDetector.Attach(actor);
749   secondDetector.DetectedSignal().Connect(&application, secondFunctor);
750
751   // Add second actor to second detector, when we remove the actor, this will make sure that this
752   // gesture detector is not removed from the GestureDetectorProcessor.  In this scenario, the
753   // functor should still not be called (which is what we're also testing).
754   secondDetector.Attach(actor2);
755
756   // Rotation in actor's area - both detector's functors should be called
757   TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
758   DALI_TEST_EQUALS(true, firstData.functorCalled, TEST_LOCATION);
759   DALI_TEST_EQUALS(true, secondData.functorCalled, TEST_LOCATION);
760
761   // Rotation continues in actor's area - both detector's functors should be called
762   firstData.Reset();
763   secondData.Reset();
764   TestContinueRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), 500);
765   DALI_TEST_EQUALS(true, firstData.functorCalled, TEST_LOCATION);
766   DALI_TEST_EQUALS(true, secondData.functorCalled, TEST_LOCATION);
767
768   // Detach actor from firstDetector and emit rotation on actor, only secondDetector's functor should be called.
769   firstDetector.Detach(actor);
770   firstData.Reset();
771   secondData.Reset();
772   TestEndRotation(application, Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(21.0f, 20.0f), 1000);
773   DALI_TEST_EQUALS(false, firstData.functorCalled, TEST_LOCATION);
774   DALI_TEST_EQUALS(true, secondData.functorCalled, TEST_LOCATION);
775
776   // New rotation on actor, only secondDetector has actor attached
777   firstData.Reset();
778   secondData.Reset();
779   TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 1500);
780   DALI_TEST_EQUALS(false, firstData.functorCalled, TEST_LOCATION);
781   DALI_TEST_EQUALS(true, secondData.functorCalled, TEST_LOCATION);
782
783   // Detach actor from secondDetector
784   secondDetector.Detach(actor);
785   firstData.Reset();
786   secondData.Reset();
787   TestContinueRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), 2000);
788   DALI_TEST_EQUALS(false, firstData.functorCalled, TEST_LOCATION);
789   DALI_TEST_EQUALS(false, secondData.functorCalled, TEST_LOCATION);
790   END_TEST;
791 }
792
793 int UtcDaliRotationGestureSignalReceptionEnsureCorrectSignalling(void)
794 {
795   TestApplication application;
796
797   Actor actor1 = Actor::New();
798   actor1.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
799   actor1.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
800   application.GetScene().Add(actor1);
801   SignalData              data1;
802   GestureReceivedFunctor  functor1(data1);
803   RotationGestureDetector detector1 = RotationGestureDetector::New();
804   detector1.Attach(actor1);
805   detector1.DetectedSignal().Connect(&application, functor1);
806
807   Actor actor2 = Actor::New();
808   actor2.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
809   actor2.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_RIGHT);
810   actor2.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_RIGHT);
811   application.GetScene().Add(actor2);
812   SignalData              data2;
813   GestureReceivedFunctor  functor2(data2);
814   RotationGestureDetector detector2 = RotationGestureDetector::New();
815   detector2.Attach(actor2);
816   detector2.DetectedSignal().Connect(&application, functor2);
817
818   // Render and notify
819   application.SendNotification();
820   application.Render();
821
822   // Start pan in actor1's area, only data1 should be set
823   TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
824   DALI_TEST_EQUALS(true, data1.functorCalled, TEST_LOCATION);
825   DALI_TEST_EQUALS(false, data2.functorCalled, TEST_LOCATION);
826   END_TEST;
827 }
828
829 int UtcDaliRotationGestureActorUnstaged(void)
830 {
831   TestApplication application;
832
833   Actor actor = Actor::New();
834   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
835   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
836   application.GetScene().Add(actor);
837
838   // Render and notify
839   application.SendNotification();
840   application.Render();
841
842   // State to remove actor in.
843   GestureState stateToUnstage(GestureState::STARTED);
844
845   // Attach actor to detector
846   SignalData              data;
847   UnstageActorFunctor     functor(data, stateToUnstage, application.GetScene());
848   RotationGestureDetector detector = RotationGestureDetector::New();
849   detector.Attach(actor);
850   detector.DetectedSignal().Connect(&application, functor);
851
852   // Emit signals
853   TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
854   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
855   data.Reset();
856   TestEndRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(21.0f, 20.0f), 1000);
857   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
858   data.Reset();
859
860   // Render and notify
861   application.SendNotification();
862   application.Render();
863
864   // Re-add actor to stage
865   application.GetScene().Add(actor);
866
867   // Render and notify
868   application.SendNotification();
869   application.Render();
870
871   // Change state to GestureState::CONTINUING to remove
872   stateToUnstage = GestureState::CONTINUING;
873
874   // Emit signals
875   TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
876   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
877   data.Reset();
878   TestContinueRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), 500);
879   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
880   data.Reset();
881   TestEndRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(21.0f, 20.0f), 1000);
882   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
883   data.Reset();
884
885   // Render and notify
886   application.SendNotification();
887   application.Render();
888
889   // Re-add actor to stage
890   application.GetScene().Add(actor);
891
892   // Render and notify
893   application.SendNotification();
894   application.Render();
895
896   // Change state to GestureState::CONTINUING to remove
897   stateToUnstage = GestureState::FINISHED;
898
899   // Emit signals
900   TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
901   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
902   data.Reset();
903   TestContinueRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), 500);
904   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
905   data.Reset();
906   TestEndRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(21.0f, 20.0f), 1000);
907   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
908   tet_result(TET_PASS); // If we get here then we have handled actor stage removal gracefully.
909   END_TEST;
910 }
911
912 int UtcDaliRotationGestureActorStagedAndDestroyed(void)
913 {
914   TestApplication application;
915
916   Actor actor = Actor::New();
917   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
918   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
919   application.GetScene().Add(actor);
920
921   // Create and add a second actor so that GestureDetector destruction does not come into play.
922   Actor dummyActor(Actor::New());
923   dummyActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
924   dummyActor.SetProperty(Actor::Property::POSITION, Vector2(100.0f, 100.0f));
925   dummyActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
926   application.GetScene().Add(dummyActor);
927
928   // Render and notify
929   application.SendNotification();
930   application.Render();
931
932   // State to remove actor in.
933   GestureState stateToUnstage(GestureState::STARTED);
934
935   // Attach actor to detector
936   SignalData              data;
937   UnstageActorFunctor     functor(data, stateToUnstage, application.GetScene());
938   RotationGestureDetector detector = RotationGestureDetector::New();
939   detector.Attach(actor);
940   detector.Attach(dummyActor);
941   detector.DetectedSignal().Connect(&application, functor);
942
943   // Here we are testing a STARTED actor which is removed in the STARTED callback, but then added back
944   // before we get a continuing state.  As we were removed from the stage, even if we're at the same
945   // position, we should still not be signalled.
946
947   // Emit signals
948   TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
949   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
950   data.Reset();
951
952   // Render and notify
953   application.SendNotification();
954   application.Render();
955
956   // Re add to the stage, we should not be signalled
957   application.GetScene().Add(actor);
958
959   // Render and notify
960   application.SendNotification();
961   application.Render();
962
963   // Continue signal emission
964   TestContinueRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), 500);
965   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
966   data.Reset();
967   TestEndRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(21.0f, 20.0f), 1000);
968   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
969   data.Reset();
970
971   // Here we delete an actor in started, we should not receive any subsequent signalling.
972
973   // Emit signals
974   TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 1500);
975   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
976   data.Reset();
977
978   // Render and notify
979   application.SendNotification();
980   application.Render();
981
982   // Delete actor as well
983   actor.Reset();
984
985   // Render and notify
986   application.SendNotification();
987   application.Render();
988
989   // Continue signal emission
990   TestContinueRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), 2000);
991   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
992   data.Reset();
993   TestEndRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(21.0f, 20.0f), 3000);
994   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
995   END_TEST;
996 }
997
998 int UtcDaliRotationGestureLayerConsumesTouch(void)
999 {
1000   TestApplication application;
1001
1002   Actor actor = Actor::New();
1003   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1004   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1005   application.GetScene().Add(actor);
1006
1007   // Add a detector
1008   SignalData              data;
1009   GestureReceivedFunctor  functor(data);
1010   RotationGestureDetector detector = RotationGestureDetector::New();
1011   detector.Attach(actor);
1012   detector.DetectedSignal().Connect(&application, functor);
1013
1014   // Add a layer to overlap the actor
1015   Layer layer = Layer::New();
1016   layer.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1017   layer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1018   application.GetScene().Add(layer);
1019   layer.RaiseToTop();
1020
1021   // Render and notify
1022   application.SendNotification();
1023   application.Render();
1024
1025   // Emit signals, should receive
1026   TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
1027   TestEndRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(21.0f, 20.0f), 1000);
1028   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1029   data.Reset();
1030
1031   // Set layer to consume all touch
1032   layer.SetProperty(Layer::Property::CONSUMES_TOUCH, true);
1033
1034   // Render and notify
1035   application.SendNotification();
1036   application.Render();
1037
1038   // Emit the same signals again, should not receive
1039   TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 1500);
1040   TestEndRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(21.0f, 20.0f), 2000);
1041   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1042   data.Reset();
1043
1044   END_TEST;
1045 }
1046
1047 int UtcDaliRotationGestureInterruptedWhenTouchConsumed(void)
1048 {
1049   TestApplication application;
1050
1051   Actor actor = Actor::New();
1052   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1053   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1054   application.GetScene().Add(actor);
1055
1056   bool                           consume = false;
1057   TouchEventFunctorConsumeSetter touchFunctor(consume);
1058   actor.TouchedSignal().Connect(&application, touchFunctor);
1059
1060   // Render and notify
1061   application.SendNotification();
1062   application.Render();
1063
1064   SignalData             data;
1065   GestureReceivedFunctor functor(data);
1066
1067   RotationGestureDetector detector = RotationGestureDetector::New();
1068   detector.Attach(actor);
1069   detector.DetectedSignal().Connect(&application, functor);
1070
1071   // Start gesture within the actor's area, we should receive the rotation as the touch is NOT being consumed
1072   TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
1073
1074   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1075   DALI_TEST_EQUALS(GestureState::STARTED, data.receivedGesture.GetState(), TEST_LOCATION);
1076   data.Reset();
1077
1078   // Continue the gesture within the actor's area, but now the touch consumes thus cancelling the gesture
1079   consume = true;
1080
1081   TestContinueRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(15.0f, 20.0f), Vector2(25.0f, 20.0f), 500);
1082   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1083   DALI_TEST_EQUALS(GestureState::CANCELLED, data.receivedGesture.GetState(), TEST_LOCATION);
1084   data.Reset();
1085
1086   // Start another rotation, we should not even get the callback this time
1087   TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
1088   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1089
1090   END_TEST;
1091 }
1092
1093 int UtcDaliRotationGestureDisableDetectionDuringRotationN(void)
1094 {
1095   // Crash sometimes occurred when gesture-recognizer was deleted internally during a signal when the attached actor was detached
1096
1097   TestApplication application;
1098
1099   Actor actor = Actor::New();
1100   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1101   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1102   application.GetScene().Add(actor);
1103
1104   // Add a detector
1105   RotationGestureDetector detector      = RotationGestureDetector::New();
1106   bool                    functorCalled = false;
1107   detector.Attach(actor);
1108   detector.DetectedSignal().Connect(
1109     &application,
1110     [&detector, &functorCalled](Actor actor, const RotationGesture& gesture) {
1111       if(gesture.GetState() == GestureState::FINISHED)
1112       {
1113         detector.Detach(actor);
1114         functorCalled = true;
1115       }
1116     });
1117
1118   // Render and notify
1119   application.SendNotification();
1120   application.Render();
1121
1122   // Try the gesture, should not crash
1123   try
1124   {
1125     TestStartRotation(application, Vector2(2.0f, 20.0f), Vector2(38.0f, 20.0f), Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), 100);
1126     TestContinueRotation(application, Vector2(112.0f, 100.0f), Vector2(112.0f, 124.0f), Vector2(5.0f, 5.0f), Vector2(35.0f, 35.0f), 200);
1127     TestEndRotation(application, Vector2(10.0f, 20.0f), Vector2(30.0f, 20.0f), Vector2(19.0f, 20.0f), Vector2(21.0f, 20.0f), 1000);
1128
1129     DALI_TEST_CHECK(true); // No crash, test has passed
1130     DALI_TEST_EQUALS(functorCalled, true, TEST_LOCATION);
1131   }
1132   catch(...)
1133   {
1134     DALI_TEST_CHECK(false); // If we crash, the test has failed
1135   }
1136
1137   END_TEST;
1138 }