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