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