Add API to UpdateProxy
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-TapGestureDetector.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/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 bool        gHitTestTouchCallBackCalled = false;
44 static bool TestHitTestTouchCallback(Actor, const TouchEvent&)
45 {
46   gHitTestTouchCallBackCalled = true;
47   return false;
48   END_TEST;
49 }
50 // Stores data that is populated in the callback and will be read by the TET cases
51 struct SignalData
52 {
53   SignalData()
54   : functorCalled(false),
55     voidFunctorCalled(false)
56   {
57   }
58
59   void Reset()
60   {
61     functorCalled     = false;
62     voidFunctorCalled = false;
63
64     receivedGesture.Reset();
65
66     tappedActor.Reset();
67   }
68
69   bool       functorCalled;
70   bool       voidFunctorCalled;
71   TapGesture receivedGesture;
72   Actor      tappedActor;
73 };
74
75 // Functor that sets the data when called
76 struct GestureReceivedFunctor
77 {
78   GestureReceivedFunctor(SignalData& data)
79   : signalData(data)
80   {
81   }
82
83   void operator()(Actor actor, const TapGesture& tap)
84   {
85     signalData.functorCalled   = true;
86     signalData.receivedGesture = tap;
87     signalData.tappedActor     = actor;
88   }
89
90   void operator()()
91   {
92     signalData.voidFunctorCalled = true;
93   }
94
95   SignalData& signalData;
96 };
97
98 // Functor that removes the gestured actor from stage
99 struct UnstageActorFunctor : public GestureReceivedFunctor
100 {
101   UnstageActorFunctor(SignalData& data, Integration::Scene scene)
102   : GestureReceivedFunctor(data),
103     scene(scene)
104   {
105   }
106
107   void operator()(Actor actor, const TapGesture& tap)
108   {
109     GestureReceivedFunctor::operator()(actor, tap);
110     scene.Remove(actor);
111   }
112
113   Integration::Scene scene;
114 };
115
116 // Functor for receiving a touch event
117 struct TouchEventFunctor
118 {
119   bool operator()(Actor actor, const TouchEvent& touch)
120   {
121     //For line coverage
122     unsigned int points = touch.GetPointCount();
123     if(points > 0)
124     {
125       tet_printf("Touch Point state = %d\n", touch.GetState(0));
126     }
127     return false;
128   }
129 };
130
131 Integration::TouchEvent GenerateSingleTouch(PointState::Type state, const Vector2& screenPosition, int source, uint32_t time)
132 {
133   Integration::TouchEvent touchEvent;
134   Integration::Point      point;
135   point.SetState(state);
136   point.SetDeviceId(4);
137   point.SetScreenPosition(screenPosition);
138   point.SetDeviceClass(Device::Class::TOUCH);
139   point.SetDeviceSubclass(Device::Subclass::NONE);
140   point.SetMouseButton(static_cast<MouseButton::Type>(source));
141   touchEvent.points.push_back(point);
142   touchEvent.time = time;
143   return touchEvent;
144 }
145
146 } // namespace
147
148 ///////////////////////////////////////////////////////////////////////////////
149
150 // Positive test case for a method
151 int UtcDaliTapGestureDetectorConstructor(void)
152 {
153   TestApplication application;
154
155   TapGestureDetector detector;
156   DALI_TEST_CHECK(!detector);
157   END_TEST;
158 }
159
160 int UtcDaliTapGestureDetectorCopyConstructorP(void)
161 {
162   TestApplication application;
163
164   TapGestureDetector detector = TapGestureDetector::New();
165
166   TapGestureDetector copy(detector);
167   DALI_TEST_CHECK(detector);
168   END_TEST;
169 }
170
171 int UtcDaliTapGestureDetectorAssignmentOperatorP(void)
172 {
173   TestApplication application;
174
175   TapGestureDetector detector = TapGestureDetector::New();
176   ;
177
178   TapGestureDetector assign;
179   assign = detector;
180   DALI_TEST_CHECK(detector);
181
182   DALI_TEST_CHECK(detector == assign);
183   END_TEST;
184 }
185
186 int UtcDaliTapGestureDetectorNew(void)
187 {
188   TestApplication application;
189
190   TapGestureDetector detector = TapGestureDetector::New();
191   DALI_TEST_CHECK(detector);
192   DALI_TEST_EQUALS(1u, detector.GetMinimumTapsRequired(), TEST_LOCATION);
193   DALI_TEST_EQUALS(1u, detector.GetMaximumTapsRequired(), TEST_LOCATION);
194
195   TapGestureDetector detector2 = TapGestureDetector::New(5u);
196   DALI_TEST_CHECK(detector2);
197   DALI_TEST_EQUALS(5u, detector2.GetMinimumTapsRequired(), TEST_LOCATION);
198   DALI_TEST_EQUALS(5u, detector2.GetMaximumTapsRequired(), TEST_LOCATION);
199
200   //Scoped test to test destructor
201   {
202     TapGestureDetector detector3 = TapGestureDetector::New();
203     DALI_TEST_CHECK(detector3);
204   }
205
206   // Attach an actor and emit a touch event on the actor to ensure complete line coverage
207   Actor actor = Actor::New();
208   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
209   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
210   application.GetScene().Add(actor);
211
212   // Render and notify
213   application.SendNotification();
214   application.Render();
215
216   detector.Attach(actor);
217
218   TouchEventFunctor touchFunctor;
219   actor.TouchedSignal().Connect(&application, touchFunctor);
220
221   Integration::TouchEvent touchEvent(1);
222   Integration::Point      point;
223   point.SetDeviceId(1);
224   point.SetState(PointState::DOWN);
225   point.SetScreenPosition(Vector2(20.0f, 20.0f));
226   touchEvent.AddPoint(point);
227   application.ProcessEvent(touchEvent);
228
229   // Render and notify
230   application.SendNotification();
231   application.Render();
232
233   END_TEST;
234 }
235
236 int UtcDaliTapGestureDetectorDownCast(void)
237 {
238   TestApplication application;
239   tet_infoline("Testing Dali::TapGestureDetector::DownCast()");
240
241   TapGestureDetector detector = TapGestureDetector::New();
242
243   BaseHandle object(detector);
244
245   TapGestureDetector detector2 = TapGestureDetector::DownCast(object);
246   DALI_TEST_CHECK(detector2);
247
248   TapGestureDetector detector3 = DownCast<TapGestureDetector>(object);
249   DALI_TEST_CHECK(detector3);
250
251   BaseHandle         unInitializedObject;
252   TapGestureDetector detector4 = TapGestureDetector::DownCast(unInitializedObject);
253   DALI_TEST_CHECK(!detector4);
254
255   TapGestureDetector detector5 = DownCast<TapGestureDetector>(unInitializedObject);
256   DALI_TEST_CHECK(!detector5);
257
258   GestureDetector    detector6 = TapGestureDetector::New();
259   TapGestureDetector detector7 = TapGestureDetector::DownCast(detector6);
260   DALI_TEST_CHECK(detector7);
261   END_TEST;
262 }
263
264 int UtcDaliTapGestureSetTapsRequiredMinMaxCheck(void)
265 {
266   TestApplication application;
267
268   // Attach an actor and change the required touches
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   // Set the minimum to be greater than the maximum, should Assert
280
281   try
282   {
283     TapGestureDetector detector = TapGestureDetector::New();
284     detector.SetMinimumTapsRequired(7u);
285     detector.SetMaximumTapsRequired(3u);
286     detector.Attach(actor);
287     DALI_TEST_CHECK(false); // Should not get here
288   }
289   catch(DaliException& e)
290   {
291     DALI_TEST_CHECK(true);
292   }
293
294   END_TEST;
295 }
296
297 int UtcDaliTapGestureGetTapsRequired(void)
298 {
299   TestApplication application;
300
301   TapGestureDetector detector = TapGestureDetector::New();
302   DALI_TEST_EQUALS(1u, detector.GetMinimumTapsRequired(), TEST_LOCATION);
303   DALI_TEST_EQUALS(1u, detector.GetMaximumTapsRequired(), TEST_LOCATION);
304   END_TEST;
305 }
306
307 int UtcDaliTapGestureSignalReceptionNegative(void)
308 {
309   TestApplication application;
310
311   Actor actor = Actor::New();
312   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
313   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
314   application.GetScene().Add(actor);
315
316   // Render and notify
317   application.SendNotification();
318   application.Render();
319
320   SignalData             data;
321   GestureReceivedFunctor functor(data);
322
323   TapGestureDetector detector = TapGestureDetector::New();
324   detector.Attach(actor);
325   detector.DetectedSignal().Connect(&application, functor);
326
327   // Do a tap outside actor's area
328   TestGenerateTap(application, 112.0f, 112.0f, 100);
329   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
330   END_TEST;
331 }
332
333 int UtcDaliTapGestureSignalReceptionPositive(void)
334 {
335   TestApplication application;
336
337   Actor actor = Actor::New();
338   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
339   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
340   application.GetScene().Add(actor);
341
342   // Render and notify
343   application.SendNotification();
344   application.Render();
345
346   SignalData             data;
347   GestureReceivedFunctor functor(data);
348
349   TapGestureDetector detector = TapGestureDetector::New();
350   detector.Attach(actor);
351   detector.DetectedSignal().Connect(&application, functor);
352
353   // Do a tap inside actor's area
354   TestGenerateTap(application, 50.0f, 50.0f, 100);
355   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
356   DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
357   DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
358   DALI_TEST_EQUALS(Vector2(50.0f, 50.0f), data.receivedGesture.GetLocalPoint(), 0.1, TEST_LOCATION);
359   END_TEST;
360 }
361
362 int UtcDaliTapGestureSignalReceptionDetach(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   TapGestureDetector detector = TapGestureDetector::New();
379   detector.Attach(actor);
380   detector.DetectedSignal().Connect(&application, functor);
381
382   // Start tap within the actor's area
383   TestGenerateTap(application, 20.0f, 20.0f, 100);
384   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
385   DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
386   DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
387   DALI_TEST_EQUALS(Vector2(20.0f, 20.0f), data.receivedGesture.GetLocalPoint(), 0.1, TEST_LOCATION);
388
389   // repeat the tap within the actor's area - we should still receive the signal
390   data.Reset();
391   TestGenerateTap(application, 50.0f, 50.0f, 700);
392   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
393   DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
394   DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
395   DALI_TEST_EQUALS(Vector2(50.0f, 50.0f), data.receivedGesture.GetLocalPoint(), 0.1, TEST_LOCATION);
396
397   // Detach actor
398   detector.DetachAll();
399
400   // Ensure we are no longer signalled
401   data.Reset();
402   TestGenerateTap(application, 20.0f, 20.0f, 1300);
403   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
404   TestGenerateTap(application, 50.0f, 50.0f, 1900);
405   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
406   END_TEST;
407 }
408
409 int UtcDaliTapGestureSignalReceptionActorDestroyedWhileTapping(void)
410 {
411   TestApplication application;
412
413   SignalData             data;
414   GestureReceivedFunctor functor(data);
415
416   TapGestureDetector detector = TapGestureDetector::New();
417   detector.DetectedSignal().Connect(&application, functor);
418
419   // Actor lifetime is scoped
420   {
421     Actor actor = Actor::New();
422     actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
423     actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
424     application.GetScene().Add(actor);
425
426     // Render and notify
427     application.SendNotification();
428     application.Render();
429
430     detector.Attach(actor);
431
432     // Start tap within the actor's area
433     TestGenerateTap(application, 20.0f, 20.0f, 100);
434     DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
435
436     // Remove the actor from stage and reset the data
437     application.GetScene().Remove(actor);
438
439     // Render and notify
440     application.SendNotification();
441     application.Render();
442   }
443
444   // Actor should now have been destroyed
445
446   data.Reset();
447   TestGenerateTap(application, 20.0f, 20.0f, 700);
448   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
449   END_TEST;
450 }
451
452 int UtcDaliTapGestureSignalReceptionRotatedActor(void)
453 {
454   TestApplication application;
455
456   Actor actor = Actor::New();
457   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
458   actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(90.0f), Vector3::ZAXIS));
459   application.GetScene().Add(actor);
460
461   // Render and notify
462   application.SendNotification();
463   application.Render();
464
465   SignalData             data;
466   GestureReceivedFunctor functor(data);
467
468   TapGestureDetector detector = TapGestureDetector::New();
469   detector.Attach(actor);
470   detector.DetectedSignal().Connect(&application, functor);
471
472   // Do tap, only check finished value
473   TestGenerateTap(application, 5.0f, 5.0f, 100);
474   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
475   DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
476   DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
477   DALI_TEST_EQUALS(Vector2(5.0f, 5.0f), data.receivedGesture.GetScreenPoint(), 0.1, TEST_LOCATION);
478
479   // Rotate actor again and render
480   actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(180.0f), Vector3::ZAXIS));
481   application.SendNotification();
482   application.Render();
483
484   // Do tap, should still receive event
485   data.Reset();
486   TestGenerateTap(application, 5.0f, 5.0f, 700);
487   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
488   DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
489   DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
490   DALI_TEST_EQUALS(Vector2(5.0f, 5.0f), data.receivedGesture.GetScreenPoint(), 0.1, TEST_LOCATION);
491
492   // Rotate actor again and render
493   actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(90.0f), Vector3::YAXIS));
494   application.SendNotification();
495   application.Render();
496
497   // Do tap, inside the actor's area (area if it is not rotated), Should not receive the event
498   data.Reset();
499   TestGenerateTap(application, 70.0f, 70.0f, 1300);
500   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
501   END_TEST;
502 }
503
504 int UtcDaliTapGestureSignalReceptionChildHit(void)
505 {
506   TestApplication application;
507
508   Actor parent = Actor::New();
509   parent.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
510   parent.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
511   application.GetScene().Add(parent);
512
513   // Set child to completely cover parent.
514   // Change rotation of child to be different from parent so that we can check if our local coordinate
515   // conversion of the parent actor is correct.
516   Actor child = Actor::New();
517   child.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
518   child.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
519   child.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
520   child.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(90.0f), Vector3::ZAXIS));
521   parent.Add(child);
522
523   TouchEventFunctor touchFunctor;
524   child.TouchedSignal().Connect(&application, touchFunctor);
525
526   // Render and notify
527   application.SendNotification();
528   application.Render();
529
530   SignalData             data;
531   GestureReceivedFunctor functor(data);
532
533   TapGestureDetector detector = TapGestureDetector::New();
534   detector.Attach(parent);
535   detector.DetectedSignal().Connect(&application, functor);
536
537   // Do tap - hits child area but parent should still receive it
538   TestGenerateTap(application, 50.0f, 50.0f, 100);
539   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
540   DALI_TEST_EQUALS(true, parent == data.tappedActor, TEST_LOCATION);
541   DALI_TEST_EQUALS(Vector2(50.0f, 50.0f), data.receivedGesture.GetScreenPoint(), 0.01f, TEST_LOCATION);
542
543   // Attach child and generate same touch points
544   // (Also proves that you can detach and then re-attach another actor)
545   detector.Attach(child);
546   detector.Detach(parent);
547
548   // Do an entire tap, only check finished value
549   data.Reset();
550   TestGenerateTap(application, 51.0f, 51.0f, 700);
551   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
552   DALI_TEST_EQUALS(true, child == data.tappedActor, TEST_LOCATION);
553   DALI_TEST_EQUALS(Vector2(51.0f, 51.0f), data.receivedGesture.GetScreenPoint(), 0.01f, TEST_LOCATION);
554   END_TEST;
555 }
556
557 int UtcDaliTapGestureSignalReceptionAttachDetachMany(void)
558 {
559   TestApplication application;
560
561   Actor first = Actor::New();
562   first.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
563   first.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
564   application.GetScene().Add(first);
565
566   Actor second = Actor::New();
567   second.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
568   second.SetProperty(Actor::Property::POSITION_X, 100.0f);
569   second.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
570   application.GetScene().Add(second);
571
572   // Render and notify
573   application.SendNotification();
574   application.Render();
575
576   SignalData             data;
577   GestureReceivedFunctor functor(data);
578
579   TapGestureDetector detector = TapGestureDetector::New();
580   detector.Attach(first);
581   detector.Attach(second);
582   detector.DetectedSignal().Connect(&application, functor);
583
584   // Tap within second actor's area
585   TestGenerateTap(application, 120.0f, 10.0f, 100);
586   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
587   DALI_TEST_EQUALS(true, second == data.tappedActor, TEST_LOCATION);
588
589   // Tap within first actor's area
590   data.Reset();
591   TestGenerateTap(application, 20.0f, 10.0f, 700);
592   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
593   DALI_TEST_EQUALS(true, first == data.tappedActor, TEST_LOCATION);
594
595   // Detach the second actor
596   detector.Detach(second);
597
598   // second actor shouldn't receive event
599   data.Reset();
600   TestGenerateTap(application, 120.0f, 10.0f, 1300);
601   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
602
603   // first actor should continue receiving event
604   data.Reset();
605   TestGenerateTap(application, 20.0f, 10.0f, 1900);
606   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
607   END_TEST;
608 }
609
610 int UtcDaliTapGestureSignalReceptionActorBecomesUntouchable(void)
611 {
612   TestApplication application;
613
614   Actor actor = Actor::New();
615   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
616   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
617   application.GetScene().Add(actor);
618
619   // Render and notify
620   application.SendNotification();
621   application.Render();
622
623   SignalData             data;
624   GestureReceivedFunctor functor(data);
625
626   TapGestureDetector detector = TapGestureDetector::New();
627   detector.Attach(actor);
628   detector.DetectedSignal().Connect(&application, functor);
629
630   // Tap in actor's area
631   TestGenerateTap(application, 50.0f, 10.0f, 100);
632   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
633
634   // Actor become invisible - actor should not receive the next pan
635   actor.SetProperty(Actor::Property::VISIBLE, false);
636
637   // Render and notify
638   application.SendNotification();
639   application.Render();
640
641   // Tap in the same area, shouldn't receive event
642   data.Reset();
643   TestGenerateTap(application, 50.0f, 10.0f, 700);
644   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
645   END_TEST;
646 }
647
648 int UtcDaliTapGestureSignalReceptionMultipleGestureDetectors(void)
649 {
650   TestApplication application;
651
652   Actor first = Actor::New();
653   first.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
654   first.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
655   application.GetScene().Add(first);
656
657   Actor second = Actor::New();
658   second.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
659   second.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
660   second.SetProperty(Actor::Property::POSITION_X, 100.0f);
661   first.Add(second);
662
663   // Render and notify
664   application.SendNotification();
665   application.Render();
666
667   SignalData             data;
668   GestureReceivedFunctor functor(data);
669
670   TapGestureDetector firstDetector = TapGestureDetector::New();
671   firstDetector.Attach(first);
672   firstDetector.DetectedSignal().Connect(&application, functor);
673
674   // secondDetector is scoped
675   {
676     TapGestureDetector secondDetector = TapGestureDetector::New(2);
677     secondDetector.Attach(second);
678     secondDetector.DetectedSignal().Connect(&application, functor);
679
680     // Tap within second actor's area
681     TestGenerateTap(application, 150.0f, 10.0f, 100);
682     TestGenerateTap(application, 150.0f, 10.0f, 200);
683
684     DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
685     DALI_TEST_EQUALS(true, second == data.tappedActor, TEST_LOCATION);
686
687     // Tap continues as single touch gesture - we should not receive any gesture
688     data.Reset();
689     TestGenerateTap(application, 150.0f, 10.0f, 800);
690     DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
691
692     // Single touch tap starts - first actor should be panned
693     data.Reset();
694     TestGenerateTap(application, 50.0f, 10.0f, 1400);
695     DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
696     DALI_TEST_EQUALS(true, first == data.tappedActor, TEST_LOCATION);
697
698     // Tap changes to double-touch - we shouldn't receive event
699     data.Reset();
700
701     TestGenerateTwoPointTap(application, 50.0f, 10.0f, 60.0f, 20.0f, 2000);
702
703     DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
704   }
705
706   END_TEST;
707 }
708
709 int UtcDaliTapGestureSignalReceptionMultipleDetectorsOnActor(void)
710 {
711   TestApplication application;
712
713   Actor actor = Actor::New();
714   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
715   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
716   application.GetScene().Add(actor);
717
718   // Render and notify
719   application.SendNotification();
720   application.Render();
721
722   // Attach actor to one detector
723   SignalData             firstData;
724   GestureReceivedFunctor firstFunctor(firstData);
725   TapGestureDetector     firstDetector = TapGestureDetector::New();
726   firstDetector.Attach(actor);
727   firstDetector.DetectedSignal().Connect(&application, firstFunctor);
728
729   // Attach actor to another detector
730   SignalData             secondData;
731   GestureReceivedFunctor secondFunctor(secondData);
732   TapGestureDetector     secondDetector = TapGestureDetector::New();
733   secondDetector.Attach(actor);
734   secondDetector.DetectedSignal().Connect(&application, secondFunctor);
735
736   // Tap in actor's area - both detector's functors should be called
737   TestGenerateTap(application, 50.0f, 10.0f, 100);
738   DALI_TEST_EQUALS(true, firstData.functorCalled, TEST_LOCATION);
739   DALI_TEST_EQUALS(true, secondData.functorCalled, TEST_LOCATION);
740   END_TEST;
741 }
742
743 int UtcDaliTapGestureSignalReceptionDifferentPossible(void)
744 {
745   TestApplication application;
746
747   Actor actor = Actor::New();
748   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
749   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
750   application.GetScene().Add(actor);
751
752   // Render and notify
753   application.SendNotification();
754   application.Render();
755
756   // Attach actor to detector
757   SignalData             data;
758   GestureReceivedFunctor functor(data);
759   TapGestureDetector     detector = TapGestureDetector::New();
760   detector.Attach(actor);
761   detector.DetectedSignal().Connect(&application, functor);
762
763   // Gesture possible in actor's area.
764   TestStartLongPress(application, 50.0f, 10.0f, 100);
765   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
766
767   // Move actor somewhere else
768   actor.SetProperty(Actor::Property::POSITION, Vector2(100.0f, 100.0f));
769
770   // Render and notify
771   application.SendNotification();
772   application.Render();
773
774   // Emit STARTED event, we should not receive the tap.
775   TestEndPan(application, Vector2(50.0f, 10.0f), 120);
776   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
777
778   // Tap possible in empty area.
779   TestStartLongPress(application, 50.0f, 10.0f, 700);
780   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
781
782   // Move actor in to the tap position.
783   actor.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f));
784
785   // Render and notify
786   application.SendNotification();
787   application.Render();
788
789   // Emit STARTED event, we should not receive the tap.
790   TestEndPan(application, Vector2(50.0f, 10.0f), 720);
791   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
792
793   // Normal tap in actor's area for completeness.
794   TestGenerateTap(application, 50.0f, 10.0f, 1300);
795   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
796   END_TEST;
797 }
798
799 int UtcDaliTapGestureActorUnstaged(void)
800 {
801   TestApplication application;
802
803   Actor actor = Actor::New();
804   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
805   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
806   application.GetScene().Add(actor);
807
808   // Render and notify
809   application.SendNotification();
810   application.Render();
811
812   // Attach actor to detector
813   SignalData          data;
814   UnstageActorFunctor functor(data, application.GetScene());
815   TapGestureDetector  detector = TapGestureDetector::New();
816   detector.Attach(actor);
817   detector.DetectedSignal().Connect(&application, functor);
818
819   TestGenerateTap(application, 50.0f, 10.0f, 100);
820   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
821   tet_result(TET_PASS); // If we get here, then the actor removal on signal handler was handled gracefully.
822   END_TEST;
823 }
824
825 int UtcDaliTapGestureDetectorRemovedWhilePossible(void)
826 {
827   TestApplication application;
828
829   Actor actor = Actor::New();
830   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
831   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
832   application.GetScene().Add(actor);
833
834   // Render and notify
835   application.SendNotification();
836   application.Render();
837
838   // Attach actor to detector
839   SignalData             data;
840   GestureReceivedFunctor functor(data);
841   TapGestureDetector     detector = TapGestureDetector::New();
842   detector.Attach(actor);
843   detector.DetectedSignal().Connect(&application, functor);
844
845   // Emit a possible - Down press, as emitted by long press function
846   TestStartLongPress(application, 50.0f, 10.0f, 100);
847
848   // Detach actor and send a STARTED state, no signal.
849   detector.DetachAll();
850   TestEndPan(application, Vector2(50.0f, 10.0f), 120);
851   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
852   END_TEST;
853 }
854
855 int UtcDaliTapGestureActorRemovedWhilePossible(void)
856 {
857   TestApplication application;
858
859   Actor actor = Actor::New();
860   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
861   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
862   application.GetScene().Add(actor);
863
864   // Render and notify
865   application.SendNotification();
866   application.Render();
867
868   // Attach actor to detector
869   SignalData             data;
870   GestureReceivedFunctor functor(data);
871   TapGestureDetector     detector = TapGestureDetector::New();
872   detector.Attach(actor);
873   detector.DetectedSignal().Connect(&application, functor);
874
875   // Emit a possible - Down press, as emitted by long press function
876   TestStartLongPress(application, 50.0f, 10.0f, 100);
877
878   // Remove, render and delete actor
879   application.GetScene().Remove(actor);
880   application.SendNotification();
881   application.Render();
882   actor.Reset();
883
884   // Send a STARTED state, no signal - Up motion as provided by end pan function
885   TestEndPan(application, Vector2(50.0f, 10.0f), 120);
886   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
887   END_TEST;
888 }
889
890 int UtcDaliTapGestureLayerConsumesTouch(void)
891 {
892   TestApplication application;
893
894   Actor actor = Actor::New();
895   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
896   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
897   application.GetScene().Add(actor);
898
899   // Add a detector
900   SignalData             data;
901   GestureReceivedFunctor functor(data);
902   TapGestureDetector     detector = TapGestureDetector::New();
903   detector.Attach(actor);
904   detector.DetectedSignal().Connect(&application, functor);
905
906   // Add a layer to overlap the actor
907   Layer layer = Layer::New();
908   layer.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
909   layer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
910   application.GetScene().Add(layer);
911   layer.RaiseToTop();
912
913   // Render and notify
914   application.SendNotification();
915   application.Render();
916
917   // Emit signals, should receive
918   TestGenerateTap(application, 50.0f, 50.0f, 100);
919   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
920   data.Reset();
921
922   // Set layer to consume all touch
923   layer.SetProperty(Layer::Property::CONSUMES_TOUCH, true);
924
925   // Render and notify
926   application.SendNotification();
927   application.Render();
928
929   // Emit the same signals again, should not receive
930   TestGenerateTap(application, 50.0f, 50.0f, 700);
931   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
932   data.Reset();
933
934   END_TEST;
935 }
936
937 int UtcDaliTapGestureDisableDetectionDuringTapN(void)
938 {
939   // Crash sometimes occurred when gesture-recognizer was deleted internally during a signal when the attached actor was detached
940
941   TestApplication application;
942
943   Actor actor = Actor::New();
944   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
945   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
946   application.GetScene().Add(actor);
947
948   // Add a detector
949   TapGestureDetector detector      = TapGestureDetector::New();
950   bool               functorCalled = false;
951   detector.Attach(actor);
952   detector.DetectedSignal().Connect(
953     &application,
954     [&detector, &functorCalled](Actor actor, const TapGesture& gesture) {
955       detector.Detach(actor);
956       functorCalled = true;
957     });
958
959   // Render and notify
960   application.SendNotification();
961   application.Render();
962
963   // Try the gesture, should not crash
964   try
965   {
966     TestGenerateTap(application, 50.0f, 10.0f);
967
968     DALI_TEST_CHECK(true); // No crash, test has passed
969     DALI_TEST_EQUALS(functorCalled, true, TEST_LOCATION);
970   }
971   catch(...)
972   {
973     DALI_TEST_CHECK(false); // If we crash, the test has failed
974   }
975
976   END_TEST;
977 }
978
979 int UtcDaliTapGestureWhenGesturePropargation(void)
980 {
981   TestApplication application;
982
983   Actor parentActor = Actor::New();
984   parentActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
985   parentActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
986
987   Actor childActor = Actor::New();
988   childActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
989   childActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
990
991   parentActor.Add(childActor);
992   application.GetScene().Add(parentActor);
993
994   // Render and notify
995   application.SendNotification();
996   application.Render();
997
998   SignalData             pData;
999   GestureReceivedFunctor pFunctor(pData);
1000
1001   TapGestureDetector parentDetector = TapGestureDetector::New();
1002   parentDetector.Attach(parentActor);
1003   parentDetector.DetectedSignal().Connect(&application, pFunctor);
1004
1005   SignalData             cData;
1006   GestureReceivedFunctor cFunctor(cData);
1007
1008   TapGestureDetector childDetector = TapGestureDetector::New();
1009   childDetector.Attach(childActor);
1010   childDetector.DetectedSignal().Connect(&application, cFunctor);
1011
1012   // Start gesture within the actor's area, we receive the gesture not parent actor but child actor.
1013   TestGenerateTap(application, 50.0f, 50.0f, 100);
1014   DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
1015   DALI_TEST_EQUALS(false, pData.functorCalled, TEST_LOCATION);
1016   cData.Reset();
1017   pData.Reset();
1018
1019   // If GesturePropargation is set, a gesture event is delivered to the parent.
1020   Dali::DevelActor::SetNeedGesturePropagation(childActor, true);
1021
1022   // So now the parent got the gesture event.
1023   TestGenerateTap(application, 50.0f, 50.0f, 700);
1024   DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
1025   DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION);
1026   cData.Reset();
1027   pData.Reset();
1028
1029   END_TEST;
1030 }
1031
1032 int UtcDaliTapGestureGetSourceType(void)
1033 {
1034   TestApplication application;
1035
1036   Actor actor = Actor::New();
1037   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1038   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1039   application.GetScene().Add(actor);
1040
1041   // Render and notify
1042   application.SendNotification();
1043   application.Render();
1044
1045   SignalData             data;
1046   GestureReceivedFunctor functor(data);
1047
1048   TapGestureDetector detector = TapGestureDetector::New();
1049   detector.Attach(actor);
1050   detector.DetectedSignal().Connect(&application, functor);
1051
1052   // Emit a down signal with MouseButton
1053   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 0, 100));
1054   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 0, 120));
1055   application.SendNotification();
1056
1057   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1058   DALI_TEST_EQUALS(data.receivedGesture.GetSourceType(), GestureSourceType::INVALID, TEST_LOCATION);
1059
1060   data.Reset();
1061
1062   // Emit a down signal with MouseButton
1063   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 1, 700));
1064   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 1, 720));
1065   application.SendNotification();
1066
1067   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1068   DALI_TEST_EQUALS(data.receivedGesture.GetSourceType(), GestureSourceType::PRIMARY, TEST_LOCATION);
1069
1070   data.Reset();
1071
1072   // Emit a down signal with MouseButton
1073   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 3, 1300));
1074   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 3, 1320));
1075   application.SendNotification();
1076
1077   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1078   DALI_TEST_EQUALS(data.receivedGesture.GetSourceType(), GestureSourceType::SECONDARY, TEST_LOCATION);
1079
1080   data.Reset();
1081
1082   // Emit a down signal with MouseButton
1083   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 2, 1900));
1084   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 2, 1920));
1085   application.SendNotification();
1086
1087   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1088   DALI_TEST_EQUALS(data.receivedGesture.GetSourceType(), GestureSourceType::TERTIARY, TEST_LOCATION);
1089
1090   END_TEST;
1091 }
1092
1093 int UtcDaliTapGestureReceiveAllTapEvents(void)
1094 {
1095   TestApplication application;
1096
1097   Actor actor = Actor::New();
1098   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1099   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1100
1101   application.GetScene().Add(actor);
1102
1103   // Render and notify
1104   application.SendNotification();
1105   application.Render();
1106
1107   SignalData             data;
1108   GestureReceivedFunctor functor(data);
1109
1110   TapGestureDetector detector = TapGestureDetector::New();
1111   detector.SetMaximumTapsRequired(2u);
1112   detector.Attach(actor);
1113   detector.DetectedSignal().Connect(&application, functor);
1114
1115   // Emit signals, Because MaximumTapsRequired is 2, a timer that checks whether it is a single tap or a double tap operates internally.
1116   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 0, 100));
1117   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 0, 120));
1118   application.SendNotification();
1119
1120   // So detector don't get the tap event yet.
1121   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1122   data.Reset();
1123
1124   // Emit signals, Send the second tab.
1125   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 0, 130));
1126   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 0, 150));
1127   application.SendNotification();
1128   application.GetPlatform().TriggerTimer();
1129
1130   // It find out to be a double tap. Detector receives events.
1131   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1132   data.Reset();
1133
1134   // Detector want to receive all tap events.
1135   detector.ReceiveAllTapEvents(true);
1136
1137   // Emit signals, should receive
1138   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 0, 500));
1139   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 0, 520));
1140   application.SendNotification();
1141
1142   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1143   data.Reset();
1144
1145   // Emit signals, should receive
1146   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 0, 530));
1147   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 0, 550));
1148   application.SendNotification();
1149
1150   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1151   data.Reset();
1152
1153   END_TEST;
1154 }
1155
1156 int UtcDaliTapGestureDoesWantedHitTest(void)
1157 {
1158   TestApplication application;
1159
1160   Actor blue = Actor::New();
1161   blue.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1162   blue.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1163
1164   Actor green = Actor::New();
1165   green.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1166   green.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1167
1168   application.GetScene().Add(blue);
1169   application.GetScene().Add(green);
1170
1171   // Render and notify
1172   application.SendNotification();
1173   application.Render();
1174
1175   SignalData             blueData;
1176   GestureReceivedFunctor blueFunctor(blueData);
1177
1178   TapGestureDetector blueDetector = TapGestureDetector::New();
1179   blueDetector.Attach(blue);
1180   blueDetector.DetectedSignal().Connect(&application, blueFunctor);
1181
1182   SignalData             greenData;
1183   GestureReceivedFunctor greenFunctor(greenData);
1184
1185   TapGestureDetector greenDetector = TapGestureDetector::New();
1186   greenDetector.Attach(green);
1187   greenDetector.DetectedSignal().Connect(&application, greenFunctor);
1188
1189   // connect to its hit-test signal
1190   gHitTestTouchCallBackCalled = false;
1191   Dali::DevelActor::HitTestResultSignal(green).Connect(TestHitTestTouchCallback);
1192
1193   // Emit a down signal
1194   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 0, 100));
1195   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 0, 120));
1196   application.SendNotification();
1197
1198   // check hit-test events
1199   // The green actor received an event that the green actor was hit.
1200   DALI_TEST_EQUALS(true, gHitTestTouchCallBackCalled, TEST_LOCATION);
1201
1202   // The green actor passed the hit-test. So blue was the final hit.
1203   DALI_TEST_EQUALS(false, greenData.functorCalled, TEST_LOCATION);
1204   DALI_TEST_EQUALS(true, blueData.functorCalled, TEST_LOCATION);
1205
1206   blueData.Reset();
1207   greenData.Reset();
1208
1209   END_TEST;
1210 }