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