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