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