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