Merge "Add SwitchParent api in actor-devel" into devel/master
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-TapGestureDetector.cpp
1 /*
2  * Copyright (c) 2021 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/render-task-list-integ.h>
22 #include <dali/public-api/dali-core.h>
23 #include <stdlib.h>
24 #include <test-touch-event-utils.h>
25
26 #include <iostream>
27
28 using namespace Dali;
29
30 void utc_dali_tap_gesture_detector_startup(void)
31 {
32   test_return_value = TET_UNDEF;
33 }
34
35 void utc_dali_tap_gesture_detector_cleanup(void)
36 {
37   test_return_value = TET_PASS;
38 }
39
40 ///////////////////////////////////////////////////////////////////////////////
41 namespace
42 {
43 // Stores data that is populated in the callback and will be read by the TET cases
44 struct SignalData
45 {
46   SignalData()
47   : functorCalled(false),
48     voidFunctorCalled(false)
49   {
50   }
51
52   void Reset()
53   {
54     functorCalled     = false;
55     voidFunctorCalled = false;
56
57     receivedGesture.Reset();
58
59     tappedActor.Reset();
60   }
61
62   bool       functorCalled;
63   bool       voidFunctorCalled;
64   TapGesture receivedGesture;
65   Actor      tappedActor;
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 TapGesture& tap)
77   {
78     signalData.functorCalled   = true;
79     signalData.receivedGesture = tap;
80     signalData.tappedActor     = 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, Integration::Scene scene)
95   : GestureReceivedFunctor(data),
96     scene(scene)
97   {
98   }
99
100   void operator()(Actor actor, const TapGesture& tap)
101   {
102     GestureReceivedFunctor::operator()(actor, tap);
103     scene.Remove(actor);
104   }
105
106   Integration::Scene scene;
107 };
108
109 // Functor for receiving a touch event
110 struct TouchEventFunctor
111 {
112   bool operator()(Actor actor, const TouchEvent& touch)
113   {
114     //For line coverage
115     unsigned int points = touch.GetPointCount();
116     if(points > 0)
117     {
118       tet_printf("Touch Point state = %d\n", touch.GetState(0));
119     }
120     return false;
121   }
122 };
123
124 } // namespace
125
126 ///////////////////////////////////////////////////////////////////////////////
127
128 // Positive test case for a method
129 int UtcDaliTapGestureDetectorConstructor(void)
130 {
131   TestApplication application;
132
133   TapGestureDetector detector;
134   DALI_TEST_CHECK(!detector);
135   END_TEST;
136 }
137
138 int UtcDaliTapGestureDetectorCopyConstructorP(void)
139 {
140   TestApplication application;
141
142   TapGestureDetector detector = TapGestureDetector::New();
143
144   TapGestureDetector copy(detector);
145   DALI_TEST_CHECK(detector);
146   END_TEST;
147 }
148
149 int UtcDaliTapGestureDetectorAssignmentOperatorP(void)
150 {
151   TestApplication application;
152
153   TapGestureDetector detector = TapGestureDetector::New();
154   ;
155
156   TapGestureDetector assign;
157   assign = detector;
158   DALI_TEST_CHECK(detector);
159
160   DALI_TEST_CHECK(detector == assign);
161   END_TEST;
162 }
163
164 int UtcDaliTapGestureDetectorNew(void)
165 {
166   TestApplication application;
167
168   TapGestureDetector detector = TapGestureDetector::New();
169   DALI_TEST_CHECK(detector);
170   DALI_TEST_EQUALS(1u, detector.GetMinimumTapsRequired(), TEST_LOCATION);
171   DALI_TEST_EQUALS(1u, detector.GetMaximumTapsRequired(), TEST_LOCATION);
172
173   TapGestureDetector detector2 = TapGestureDetector::New(5u);
174   DALI_TEST_CHECK(detector2);
175   DALI_TEST_EQUALS(5u, detector2.GetMinimumTapsRequired(), TEST_LOCATION);
176   DALI_TEST_EQUALS(5u, detector2.GetMaximumTapsRequired(), TEST_LOCATION);
177
178   //Scoped test to test destructor
179   {
180     TapGestureDetector detector3 = TapGestureDetector::New();
181     DALI_TEST_CHECK(detector3);
182   }
183
184   // Attach an actor and emit a touch event on the actor to ensure complete line coverage
185   Actor actor = Actor::New();
186   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
187   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
188   application.GetScene().Add(actor);
189
190   // Render and notify
191   application.SendNotification();
192   application.Render();
193
194   detector.Attach(actor);
195
196   TouchEventFunctor touchFunctor;
197   actor.TouchedSignal().Connect(&application, touchFunctor);
198
199   Integration::TouchEvent touchEvent(1);
200   Integration::Point      point;
201   point.SetDeviceId(1);
202   point.SetState(PointState::DOWN);
203   point.SetScreenPosition(Vector2(20.0f, 20.0f));
204   touchEvent.AddPoint(point);
205   application.ProcessEvent(touchEvent);
206
207   // Render and notify
208   application.SendNotification();
209   application.Render();
210
211   END_TEST;
212 }
213
214 int UtcDaliTapGestureDetectorDownCast(void)
215 {
216   TestApplication application;
217   tet_infoline("Testing Dali::TapGestureDetector::DownCast()");
218
219   TapGestureDetector detector = TapGestureDetector::New();
220
221   BaseHandle object(detector);
222
223   TapGestureDetector detector2 = TapGestureDetector::DownCast(object);
224   DALI_TEST_CHECK(detector2);
225
226   TapGestureDetector detector3 = DownCast<TapGestureDetector>(object);
227   DALI_TEST_CHECK(detector3);
228
229   BaseHandle         unInitializedObject;
230   TapGestureDetector detector4 = TapGestureDetector::DownCast(unInitializedObject);
231   DALI_TEST_CHECK(!detector4);
232
233   TapGestureDetector detector5 = DownCast<TapGestureDetector>(unInitializedObject);
234   DALI_TEST_CHECK(!detector5);
235
236   GestureDetector    detector6 = TapGestureDetector::New();
237   TapGestureDetector detector7 = TapGestureDetector::DownCast(detector6);
238   DALI_TEST_CHECK(detector7);
239   END_TEST;
240 }
241
242 int UtcDaliTapGestureSetTapsRequiredMinMaxCheck(void)
243 {
244   TestApplication application;
245
246   // Attach an actor and change the required touches
247
248   Actor actor = Actor::New();
249   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
250   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
251   application.GetScene().Add(actor);
252
253   // Render and notify
254   application.SendNotification();
255   application.Render();
256
257   // Set the minimum to be greater than the maximum, should Assert
258
259   try
260   {
261     TapGestureDetector detector = TapGestureDetector::New();
262     detector.SetMinimumTapsRequired(7u);
263     detector.SetMaximumTapsRequired(3u);
264     detector.Attach(actor);
265     DALI_TEST_CHECK(false); // Should not get here
266   }
267   catch(DaliException& e)
268   {
269     DALI_TEST_CHECK(true);
270   }
271
272   END_TEST;
273 }
274
275 int UtcDaliTapGestureGetTapsRequired(void)
276 {
277   TestApplication application;
278
279   TapGestureDetector detector = TapGestureDetector::New();
280   DALI_TEST_EQUALS(1u, detector.GetMinimumTapsRequired(), TEST_LOCATION);
281   DALI_TEST_EQUALS(1u, detector.GetMaximumTapsRequired(), TEST_LOCATION);
282   END_TEST;
283 }
284
285 int UtcDaliTapGestureSignalReceptionNegative(void)
286 {
287   TestApplication application;
288
289   Actor actor = Actor::New();
290   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
291   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
292   application.GetScene().Add(actor);
293
294   // Render and notify
295   application.SendNotification();
296   application.Render();
297
298   SignalData             data;
299   GestureReceivedFunctor functor(data);
300
301   TapGestureDetector detector = TapGestureDetector::New();
302   detector.Attach(actor);
303   detector.DetectedSignal().Connect(&application, functor);
304
305   // Do a tap outside actor's area
306   TestGenerateTap(application, 112.0f, 112.0f, 100);
307   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
308   END_TEST;
309 }
310
311 int UtcDaliTapGestureSignalReceptionPositive(void)
312 {
313   TestApplication application;
314
315   Actor actor = Actor::New();
316   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
317   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
318   application.GetScene().Add(actor);
319
320   // Render and notify
321   application.SendNotification();
322   application.Render();
323
324   SignalData             data;
325   GestureReceivedFunctor functor(data);
326
327   TapGestureDetector detector = TapGestureDetector::New();
328   detector.Attach(actor);
329   detector.DetectedSignal().Connect(&application, functor);
330
331   // Do a tap inside actor's area
332   TestGenerateTap(application, 50.0f, 50.0f, 100);
333   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
334   DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
335   DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
336   DALI_TEST_EQUALS(Vector2(50.0f, 50.0f), data.receivedGesture.GetLocalPoint(), 0.1, TEST_LOCATION);
337   END_TEST;
338 }
339
340 int UtcDaliTapGestureSignalReceptionDetach(void)
341 {
342   TestApplication application;
343
344   Actor actor = Actor::New();
345   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
346   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
347   application.GetScene().Add(actor);
348
349   // Render and notify
350   application.SendNotification();
351   application.Render();
352
353   SignalData             data;
354   GestureReceivedFunctor functor(data);
355
356   TapGestureDetector detector = TapGestureDetector::New();
357   detector.Attach(actor);
358   detector.DetectedSignal().Connect(&application, functor);
359
360   // Start tap within the actor's area
361   TestGenerateTap(application, 20.0f, 20.0f, 100);
362   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
363   DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
364   DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
365   DALI_TEST_EQUALS(Vector2(20.0f, 20.0f), data.receivedGesture.GetLocalPoint(), 0.1, TEST_LOCATION);
366
367   // repeat the tap within the actor's area - we should still receive the signal
368   data.Reset();
369   TestGenerateTap(application, 50.0f, 50.0f, 700);
370   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
371   DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
372   DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
373   DALI_TEST_EQUALS(Vector2(50.0f, 50.0f), data.receivedGesture.GetLocalPoint(), 0.1, TEST_LOCATION);
374
375   // Detach actor
376   detector.DetachAll();
377
378   // Ensure we are no longer signalled
379   data.Reset();
380   TestGenerateTap(application, 20.0f, 20.0f, 1300);
381   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
382   TestGenerateTap(application, 50.0f, 50.0f, 1900);
383   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
384   END_TEST;
385 }
386
387 int UtcDaliTapGestureSignalReceptionActorDestroyedWhileTapping(void)
388 {
389   TestApplication application;
390
391   SignalData             data;
392   GestureReceivedFunctor functor(data);
393
394   TapGestureDetector detector = TapGestureDetector::New();
395   detector.DetectedSignal().Connect(&application, functor);
396
397   // Actor lifetime is scoped
398   {
399     Actor actor = Actor::New();
400     actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
401     actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
402     application.GetScene().Add(actor);
403
404     // Render and notify
405     application.SendNotification();
406     application.Render();
407
408     detector.Attach(actor);
409
410     // Start tap within the actor's area
411     TestGenerateTap(application, 20.0f, 20.0f, 100);
412     DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
413
414     // Remove the actor from stage and reset the data
415     application.GetScene().Remove(actor);
416
417     // Render and notify
418     application.SendNotification();
419     application.Render();
420   }
421
422   // Actor should now have been destroyed
423
424   data.Reset();
425   TestGenerateTap(application, 20.0f, 20.0f, 700);
426   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
427   END_TEST;
428 }
429
430 int UtcDaliTapGestureSignalReceptionRotatedActor(void)
431 {
432   TestApplication application;
433
434   Actor actor = Actor::New();
435   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
436   actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(90.0f), Vector3::ZAXIS));
437   application.GetScene().Add(actor);
438
439   // Render and notify
440   application.SendNotification();
441   application.Render();
442
443   SignalData             data;
444   GestureReceivedFunctor functor(data);
445
446   TapGestureDetector detector = TapGestureDetector::New();
447   detector.Attach(actor);
448   detector.DetectedSignal().Connect(&application, functor);
449
450   // Do tap, only check finished value
451   TestGenerateTap(application, 5.0f, 5.0f, 100);
452   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
453   DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
454   DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
455   DALI_TEST_EQUALS(Vector2(5.0f, 5.0f), data.receivedGesture.GetScreenPoint(), 0.1, TEST_LOCATION);
456
457   // Rotate actor again and render
458   actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(180.0f), Vector3::ZAXIS));
459   application.SendNotification();
460   application.Render();
461
462   // Do tap, should still receive event
463   data.Reset();
464   TestGenerateTap(application, 5.0f, 5.0f, 700);
465   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
466   DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
467   DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
468   DALI_TEST_EQUALS(Vector2(5.0f, 5.0f), data.receivedGesture.GetScreenPoint(), 0.1, TEST_LOCATION);
469
470   // Rotate actor again and render
471   actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(90.0f), Vector3::YAXIS));
472   application.SendNotification();
473   application.Render();
474
475   // Do tap, inside the actor's area (area if it is not rotated), Should not receive the event
476   data.Reset();
477   TestGenerateTap(application, 70.0f, 70.0f, 1300);
478   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
479   END_TEST;
480 }
481
482 int UtcDaliTapGestureSignalReceptionChildHit(void)
483 {
484   TestApplication application;
485
486   Actor parent = Actor::New();
487   parent.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
488   parent.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
489   application.GetScene().Add(parent);
490
491   // Set child to completely cover parent.
492   // Change rotation of child to be different from parent so that we can check if our local coordinate
493   // conversion of the parent actor is correct.
494   Actor child = Actor::New();
495   child.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
496   child.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
497   child.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
498   child.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(90.0f), Vector3::ZAXIS));
499   parent.Add(child);
500
501   TouchEventFunctor touchFunctor;
502   child.TouchedSignal().Connect(&application, touchFunctor);
503
504   // Render and notify
505   application.SendNotification();
506   application.Render();
507
508   SignalData             data;
509   GestureReceivedFunctor functor(data);
510
511   TapGestureDetector detector = TapGestureDetector::New();
512   detector.Attach(parent);
513   detector.DetectedSignal().Connect(&application, functor);
514
515   // Do tap - hits child area but parent should still receive it
516   TestGenerateTap(application, 50.0f, 50.0f, 100);
517   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
518   DALI_TEST_EQUALS(true, parent == data.tappedActor, TEST_LOCATION);
519   DALI_TEST_EQUALS(Vector2(50.0f, 50.0f), data.receivedGesture.GetScreenPoint(), 0.01f, TEST_LOCATION);
520
521   // Attach child and generate same touch points
522   // (Also proves that you can detach and then re-attach another actor)
523   detector.Attach(child);
524   detector.Detach(parent);
525
526   // Do an entire tap, only check finished value
527   data.Reset();
528   TestGenerateTap(application, 51.0f, 51.0f, 700);
529   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
530   DALI_TEST_EQUALS(true, child == data.tappedActor, TEST_LOCATION);
531   DALI_TEST_EQUALS(Vector2(51.0f, 51.0f), data.receivedGesture.GetScreenPoint(), 0.01f, TEST_LOCATION);
532   END_TEST;
533 }
534
535 int UtcDaliTapGestureSignalReceptionAttachDetachMany(void)
536 {
537   TestApplication application;
538
539   Actor first = Actor::New();
540   first.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
541   first.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
542   application.GetScene().Add(first);
543
544   Actor second = Actor::New();
545   second.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
546   second.SetProperty(Actor::Property::POSITION_X, 100.0f);
547   second.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
548   application.GetScene().Add(second);
549
550   // Render and notify
551   application.SendNotification();
552   application.Render();
553
554   SignalData             data;
555   GestureReceivedFunctor functor(data);
556
557   TapGestureDetector detector = TapGestureDetector::New();
558   detector.Attach(first);
559   detector.Attach(second);
560   detector.DetectedSignal().Connect(&application, functor);
561
562   // Tap within second actor's area
563   TestGenerateTap(application, 120.0f, 10.0f, 100);
564   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
565   DALI_TEST_EQUALS(true, second == data.tappedActor, TEST_LOCATION);
566
567   // Tap within first actor's area
568   data.Reset();
569   TestGenerateTap(application, 20.0f, 10.0f, 700);
570   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
571   DALI_TEST_EQUALS(true, first == data.tappedActor, TEST_LOCATION);
572
573   // Detach the second actor
574   detector.Detach(second);
575
576   // second actor shouldn't receive event
577   data.Reset();
578   TestGenerateTap(application, 120.0f, 10.0f, 1300);
579   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
580
581   // first actor should continue receiving event
582   data.Reset();
583   TestGenerateTap(application, 20.0f, 10.0f, 1900);
584   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
585   END_TEST;
586 }
587
588 int UtcDaliTapGestureSignalReceptionActorBecomesUntouchable(void)
589 {
590   TestApplication application;
591
592   Actor actor = Actor::New();
593   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
594   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
595   application.GetScene().Add(actor);
596
597   // Render and notify
598   application.SendNotification();
599   application.Render();
600
601   SignalData             data;
602   GestureReceivedFunctor functor(data);
603
604   TapGestureDetector detector = TapGestureDetector::New();
605   detector.Attach(actor);
606   detector.DetectedSignal().Connect(&application, functor);
607
608   // Tap in actor's area
609   TestGenerateTap(application, 50.0f, 10.0f, 100);
610   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
611
612   // Actor become invisible - actor should not receive the next pan
613   actor.SetProperty(Actor::Property::VISIBLE, false);
614
615   // Render and notify
616   application.SendNotification();
617   application.Render();
618
619   // Tap in the same area, shouldn't receive event
620   data.Reset();
621   TestGenerateTap(application, 50.0f, 10.0f, 700);
622   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
623   END_TEST;
624 }
625
626 int UtcDaliTapGestureSignalReceptionMultipleGestureDetectors(void)
627 {
628   TestApplication application;
629
630   Actor first = Actor::New();
631   first.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
632   first.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
633   application.GetScene().Add(first);
634
635   Actor second = Actor::New();
636   second.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
637   second.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
638   second.SetProperty(Actor::Property::POSITION_X, 100.0f);
639   first.Add(second);
640
641   // Render and notify
642   application.SendNotification();
643   application.Render();
644
645   SignalData             data;
646   GestureReceivedFunctor functor(data);
647
648   TapGestureDetector firstDetector = TapGestureDetector::New();
649   firstDetector.Attach(first);
650   firstDetector.DetectedSignal().Connect(&application, functor);
651
652   // secondDetector is scoped
653   {
654     TapGestureDetector secondDetector = TapGestureDetector::New(2);
655     secondDetector.Attach(second);
656     secondDetector.DetectedSignal().Connect(&application, functor);
657
658     // Tap within second actor's area
659     TestGenerateTap(application, 150.0f, 10.0f, 100);
660     TestGenerateTap(application, 150.0f, 10.0f, 200);
661
662     DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
663     DALI_TEST_EQUALS(true, second == data.tappedActor, TEST_LOCATION);
664
665     // Tap continues as single touch gesture - we should not receive any gesture
666     data.Reset();
667     TestGenerateTap(application, 150.0f, 10.0f, 800);
668     DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
669
670     // Single touch tap starts - first actor should be panned
671     data.Reset();
672     TestGenerateTap(application, 50.0f, 10.0f, 1400);
673     DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
674     DALI_TEST_EQUALS(true, first == data.tappedActor, TEST_LOCATION);
675
676     // Tap changes to double-touch - we shouldn't receive event
677     data.Reset();
678
679     TestGenerateTwoPointTap(application, 50.0f, 10.0f, 60.0f, 20.0f, 2000);
680
681     DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
682   }
683
684   END_TEST;
685 }
686
687 int UtcDaliTapGestureSignalReceptionMultipleDetectorsOnActor(void)
688 {
689   TestApplication application;
690
691   Actor actor = Actor::New();
692   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
693   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
694   application.GetScene().Add(actor);
695
696   // Render and notify
697   application.SendNotification();
698   application.Render();
699
700   // Attach actor to one detector
701   SignalData             firstData;
702   GestureReceivedFunctor firstFunctor(firstData);
703   TapGestureDetector     firstDetector = TapGestureDetector::New();
704   firstDetector.Attach(actor);
705   firstDetector.DetectedSignal().Connect(&application, firstFunctor);
706
707   // Attach actor to another detector
708   SignalData             secondData;
709   GestureReceivedFunctor secondFunctor(secondData);
710   TapGestureDetector     secondDetector = TapGestureDetector::New();
711   secondDetector.Attach(actor);
712   secondDetector.DetectedSignal().Connect(&application, secondFunctor);
713
714   // Tap in actor's area - both detector's functors should be called
715   TestGenerateTap(application, 50.0f, 10.0f, 100);
716   DALI_TEST_EQUALS(true, firstData.functorCalled, TEST_LOCATION);
717   DALI_TEST_EQUALS(true, secondData.functorCalled, TEST_LOCATION);
718   END_TEST;
719 }
720
721 int UtcDaliTapGestureSignalReceptionDifferentPossible(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   // Attach actor to detector
735   SignalData             data;
736   GestureReceivedFunctor functor(data);
737   TapGestureDetector     detector = TapGestureDetector::New();
738   detector.Attach(actor);
739   detector.DetectedSignal().Connect(&application, functor);
740
741   // Gesture possible in actor's area.
742   TestStartLongPress(application, 50.0f, 10.0f, 100);
743   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
744
745   // Move actor somewhere else
746   actor.SetProperty(Actor::Property::POSITION, Vector2(100.0f, 100.0f));
747
748   // Render and notify
749   application.SendNotification();
750   application.Render();
751
752   // Emit STARTED event, we should not receive the tap.
753   TestEndPan(application, Vector2(50.0f, 10.0f), 120);
754   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
755
756   // Tap possible in empty area.
757   TestStartLongPress(application, 50.0f, 10.0f, 700);
758   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
759
760   // Move actor in to the tap position.
761   actor.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f));
762
763   // Render and notify
764   application.SendNotification();
765   application.Render();
766
767   // Emit STARTED event, we should not receive the tap.
768   TestEndPan(application, Vector2(50.0f, 10.0f), 720);
769   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
770
771   // Normal tap in actor's area for completeness.
772   TestGenerateTap(application, 50.0f, 10.0f, 1300);
773   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
774   END_TEST;
775 }
776
777 int UtcDaliTapGestureActorUnstaged(void)
778 {
779   TestApplication application;
780
781   Actor actor = Actor::New();
782   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
783   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
784   application.GetScene().Add(actor);
785
786   // Render and notify
787   application.SendNotification();
788   application.Render();
789
790   // Attach actor to detector
791   SignalData          data;
792   UnstageActorFunctor functor(data, application.GetScene());
793   TapGestureDetector  detector = TapGestureDetector::New();
794   detector.Attach(actor);
795   detector.DetectedSignal().Connect(&application, functor);
796
797   TestGenerateTap(application, 50.0f, 10.0f, 100);
798   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
799   tet_result(TET_PASS); // If we get here, then the actor removal on signal handler was handled gracefully.
800   END_TEST;
801 }
802
803 int UtcDaliTapGestureDetectorRemovedWhilePossible(void)
804 {
805   TestApplication application;
806
807   Actor actor = Actor::New();
808   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
809   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
810   application.GetScene().Add(actor);
811
812   // Render and notify
813   application.SendNotification();
814   application.Render();
815
816   // Attach actor to detector
817   SignalData             data;
818   GestureReceivedFunctor functor(data);
819   TapGestureDetector     detector = TapGestureDetector::New();
820   detector.Attach(actor);
821   detector.DetectedSignal().Connect(&application, functor);
822
823   // Emit a possible - Down press, as emitted by long press function
824   TestStartLongPress(application, 50.0f, 10.0f, 100);
825
826   // Detach actor and send a STARTED state, no signal.
827   detector.DetachAll();
828   TestEndPan(application, Vector2(50.0f, 10.0f), 120);
829   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
830   END_TEST;
831 }
832
833 int UtcDaliTapGestureActorRemovedWhilePossible(void)
834 {
835   TestApplication application;
836
837   Actor actor = Actor::New();
838   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
839   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
840   application.GetScene().Add(actor);
841
842   // Render and notify
843   application.SendNotification();
844   application.Render();
845
846   // Attach actor to detector
847   SignalData             data;
848   GestureReceivedFunctor functor(data);
849   TapGestureDetector     detector = TapGestureDetector::New();
850   detector.Attach(actor);
851   detector.DetectedSignal().Connect(&application, functor);
852
853   // Emit a possible - Down press, as emitted by long press function
854   TestStartLongPress(application, 50.0f, 10.0f, 100);
855
856   // Remove, render and delete actor
857   application.GetScene().Remove(actor);
858   application.SendNotification();
859   application.Render();
860   actor.Reset();
861
862   // Send a STARTED state, no signal - Up motion as provided by end pan function
863   TestEndPan(application, Vector2(50.0f, 10.0f), 120);
864   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
865   END_TEST;
866 }
867
868 int UtcDaliTapGestureLayerConsumesTouch(void)
869 {
870   TestApplication application;
871
872   Actor actor = Actor::New();
873   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
874   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
875   application.GetScene().Add(actor);
876
877   // Add a detector
878   SignalData             data;
879   GestureReceivedFunctor functor(data);
880   TapGestureDetector     detector = TapGestureDetector::New();
881   detector.Attach(actor);
882   detector.DetectedSignal().Connect(&application, functor);
883
884   // Add a layer to overlap the actor
885   Layer layer = Layer::New();
886   layer.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
887   layer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
888   application.GetScene().Add(layer);
889   layer.RaiseToTop();
890
891   // Render and notify
892   application.SendNotification();
893   application.Render();
894
895   // Emit signals, should receive
896   TestGenerateTap(application, 50.0f, 50.0f, 100);
897   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
898   data.Reset();
899
900   // Set layer to consume all touch
901   layer.SetProperty(Layer::Property::CONSUMES_TOUCH, true);
902
903   // Render and notify
904   application.SendNotification();
905   application.Render();
906
907   // Emit the same signals again, should not receive
908   TestGenerateTap(application, 50.0f, 50.0f, 700);
909   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
910   data.Reset();
911
912   END_TEST;
913 }
914
915 int UtcDaliTapGestureInterruptedWhenTouchConsumed(void)
916 {
917   TestApplication application;
918
919   Actor actor = Actor::New();
920   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
921   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
922   application.GetScene().Add(actor);
923
924   bool                           consume = false;
925   TouchEventFunctorConsumeSetter touchFunctor(consume);
926   actor.TouchedSignal().Connect(&application, touchFunctor);
927
928   // Render and notify
929   application.SendNotification();
930   application.Render();
931
932   SignalData             data;
933   GestureReceivedFunctor functor(data);
934
935   TapGestureDetector detector = TapGestureDetector::New();
936   detector.Attach(actor);
937   detector.DetectedSignal().Connect(&application, functor);
938
939   // Start gesture within the actor's area, we should receive the gesture as the touch is NOT being consumed
940   TestGenerateTap(application, 50.0f, 50.0f);
941   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
942   data.Reset();
943
944   // Another gesture in the same location, this time we will not receive it as touch is being consumed
945   consume = true;
946   TestGenerateTap(application, 50.0f, 50.0f);
947   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
948   data.Reset();
949
950   END_TEST;
951 }
952
953 int UtcDaliTapGestureDisableDetectionDuringTapN(void)
954 {
955   // Crash sometimes occurred when gesture-recognizer was deleted internally during a signal when the attached actor was detached
956
957   TestApplication application;
958
959   Actor actor = Actor::New();
960   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
961   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
962   application.GetScene().Add(actor);
963
964   // Add a detector
965   TapGestureDetector detector      = TapGestureDetector::New();
966   bool               functorCalled = false;
967   detector.Attach(actor);
968   detector.DetectedSignal().Connect(
969     &application,
970     [&detector, &functorCalled](Actor actor, const TapGesture& gesture) {
971       detector.Detach(actor);
972       functorCalled = true;
973     });
974
975   // Render and notify
976   application.SendNotification();
977   application.Render();
978
979   // Try the gesture, should not crash
980   try
981   {
982     TestGenerateTap(application, 50.0f, 10.0f);
983
984     DALI_TEST_CHECK(true); // No crash, test has passed
985     DALI_TEST_EQUALS(functorCalled, true, TEST_LOCATION);
986   }
987   catch(...)
988   {
989     DALI_TEST_CHECK(false); // If we crash, the test has failed
990   }
991
992   END_TEST;
993 }
994
995 int UtcDaliTapGestureWhenGesturePropargation(void)
996 {
997   TestApplication application;
998
999   Actor parentActor = Actor::New();
1000   parentActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1001   parentActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1002
1003   Actor childActor = Actor::New();
1004   childActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1005   childActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1006
1007   parentActor.Add(childActor);
1008   application.GetScene().Add(parentActor);
1009
1010   // Render and notify
1011   application.SendNotification();
1012   application.Render();
1013
1014   SignalData             pData;
1015   GestureReceivedFunctor pFunctor(pData);
1016
1017   TapGestureDetector parentDetector = TapGestureDetector::New();
1018   parentDetector.Attach(parentActor);
1019   parentDetector.DetectedSignal().Connect(&application, pFunctor);
1020
1021   SignalData             cData;
1022   GestureReceivedFunctor cFunctor(cData);
1023
1024   TapGestureDetector childDetector = TapGestureDetector::New();
1025   childDetector.Attach(childActor);
1026   childDetector.DetectedSignal().Connect(&application, cFunctor);
1027
1028   // Start gesture within the actor's area, we receive the gesture not parent actor but child actor.
1029   TestGenerateTap(application, 50.0f, 50.0f, 100);
1030   DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
1031   DALI_TEST_EQUALS(false, pData.functorCalled, TEST_LOCATION);
1032   cData.Reset();
1033   pData.Reset();
1034
1035   // If GesturePropargation is set, a gesture event is delivered to the parent.
1036   Dali::DevelActor::SetNeedGesturePropagation(childActor, true);
1037
1038   // So now the parent got the gesture event.
1039   TestGenerateTap(application, 50.0f, 50.0f, 700);
1040   DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
1041   DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION);
1042   cData.Reset();
1043   pData.Reset();
1044
1045   END_TEST;
1046 }