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