2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <dali-test-suite-utils.h>
19 #include <dali/devel-api/actors/actor-devel.h>
20 #include <dali/integration-api/events/touch-event-integ.h>
21 #include <dali/integration-api/render-task-list-integ.h>
22 #include <dali/public-api/dali-core.h>
24 #include <test-touch-event-utils.h>
30 void utc_dali_tap_gesture_detector_startup(void)
32 test_return_value = TET_UNDEF;
35 void utc_dali_tap_gesture_detector_cleanup(void)
37 test_return_value = TET_PASS;
40 ///////////////////////////////////////////////////////////////////////////////
43 // Stores data that is populated in the callback and will be read by the TET cases
47 : functorCalled(false),
48 voidFunctorCalled(false)
54 functorCalled = false;
55 voidFunctorCalled = false;
57 receivedGesture.Reset();
63 bool voidFunctorCalled;
64 TapGesture receivedGesture;
68 // Functor that sets the data when called
69 struct GestureReceivedFunctor
71 GestureReceivedFunctor(SignalData& data)
76 void operator()(Actor actor, const TapGesture& tap)
78 signalData.functorCalled = true;
79 signalData.receivedGesture = tap;
80 signalData.tappedActor = actor;
85 signalData.voidFunctorCalled = true;
88 SignalData& signalData;
91 // Functor that removes the gestured actor from stage
92 struct UnstageActorFunctor : public GestureReceivedFunctor
94 UnstageActorFunctor(SignalData& data, Integration::Scene scene)
95 : GestureReceivedFunctor(data),
100 void operator()(Actor actor, const TapGesture& tap)
102 GestureReceivedFunctor::operator()(actor, tap);
106 Integration::Scene scene;
109 // Functor for receiving a touch event
110 struct TouchEventFunctor
112 bool operator()(Actor actor, const TouchEvent& touch)
115 unsigned int points = touch.GetPointCount();
118 tet_printf("Touch Point state = %d\n", touch.GetState(0));
124 Integration::TouchEvent GenerateSingleTouch(PointState::Type state, const Vector2& screenPosition, int source, uint32_t time)
126 Integration::TouchEvent touchEvent;
127 Integration::Point point;
128 point.SetState(state);
129 point.SetDeviceId(4);
130 point.SetScreenPosition(screenPosition);
131 point.SetDeviceClass(Device::Class::TOUCH);
132 point.SetDeviceSubclass(Device::Subclass::NONE);
133 point.SetMouseButton(static_cast<MouseButton::Type>(source));
134 touchEvent.points.push_back(point);
135 touchEvent.time = time;
141 ///////////////////////////////////////////////////////////////////////////////
143 // Positive test case for a method
144 int UtcDaliTapGestureDetectorConstructor(void)
146 TestApplication application;
148 TapGestureDetector detector;
149 DALI_TEST_CHECK(!detector);
153 int UtcDaliTapGestureDetectorCopyConstructorP(void)
155 TestApplication application;
157 TapGestureDetector detector = TapGestureDetector::New();
159 TapGestureDetector copy(detector);
160 DALI_TEST_CHECK(detector);
164 int UtcDaliTapGestureDetectorAssignmentOperatorP(void)
166 TestApplication application;
168 TapGestureDetector detector = TapGestureDetector::New();
171 TapGestureDetector assign;
173 DALI_TEST_CHECK(detector);
175 DALI_TEST_CHECK(detector == assign);
179 int UtcDaliTapGestureDetectorNew(void)
181 TestApplication application;
183 TapGestureDetector detector = TapGestureDetector::New();
184 DALI_TEST_CHECK(detector);
185 DALI_TEST_EQUALS(1u, detector.GetMinimumTapsRequired(), TEST_LOCATION);
186 DALI_TEST_EQUALS(1u, detector.GetMaximumTapsRequired(), TEST_LOCATION);
188 TapGestureDetector detector2 = TapGestureDetector::New(5u);
189 DALI_TEST_CHECK(detector2);
190 DALI_TEST_EQUALS(5u, detector2.GetMinimumTapsRequired(), TEST_LOCATION);
191 DALI_TEST_EQUALS(5u, detector2.GetMaximumTapsRequired(), TEST_LOCATION);
193 //Scoped test to test destructor
195 TapGestureDetector detector3 = TapGestureDetector::New();
196 DALI_TEST_CHECK(detector3);
199 // Attach an actor and emit a touch event on the actor to ensure complete line coverage
200 Actor actor = Actor::New();
201 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
202 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
203 application.GetScene().Add(actor);
206 application.SendNotification();
207 application.Render();
209 detector.Attach(actor);
211 TouchEventFunctor touchFunctor;
212 actor.TouchedSignal().Connect(&application, touchFunctor);
214 Integration::TouchEvent touchEvent(1);
215 Integration::Point point;
216 point.SetDeviceId(1);
217 point.SetState(PointState::DOWN);
218 point.SetScreenPosition(Vector2(20.0f, 20.0f));
219 touchEvent.AddPoint(point);
220 application.ProcessEvent(touchEvent);
223 application.SendNotification();
224 application.Render();
229 int UtcDaliTapGestureDetectorDownCast(void)
231 TestApplication application;
232 tet_infoline("Testing Dali::TapGestureDetector::DownCast()");
234 TapGestureDetector detector = TapGestureDetector::New();
236 BaseHandle object(detector);
238 TapGestureDetector detector2 = TapGestureDetector::DownCast(object);
239 DALI_TEST_CHECK(detector2);
241 TapGestureDetector detector3 = DownCast<TapGestureDetector>(object);
242 DALI_TEST_CHECK(detector3);
244 BaseHandle unInitializedObject;
245 TapGestureDetector detector4 = TapGestureDetector::DownCast(unInitializedObject);
246 DALI_TEST_CHECK(!detector4);
248 TapGestureDetector detector5 = DownCast<TapGestureDetector>(unInitializedObject);
249 DALI_TEST_CHECK(!detector5);
251 GestureDetector detector6 = TapGestureDetector::New();
252 TapGestureDetector detector7 = TapGestureDetector::DownCast(detector6);
253 DALI_TEST_CHECK(detector7);
257 int UtcDaliTapGestureSetTapsRequiredMinMaxCheck(void)
259 TestApplication application;
261 // Attach an actor and change the required touches
263 Actor actor = Actor::New();
264 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
265 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
266 application.GetScene().Add(actor);
269 application.SendNotification();
270 application.Render();
272 // Set the minimum to be greater than the maximum, should Assert
276 TapGestureDetector detector = TapGestureDetector::New();
277 detector.SetMinimumTapsRequired(7u);
278 detector.SetMaximumTapsRequired(3u);
279 detector.Attach(actor);
280 DALI_TEST_CHECK(false); // Should not get here
282 catch(DaliException& e)
284 DALI_TEST_CHECK(true);
290 int UtcDaliTapGestureGetTapsRequired(void)
292 TestApplication application;
294 TapGestureDetector detector = TapGestureDetector::New();
295 DALI_TEST_EQUALS(1u, detector.GetMinimumTapsRequired(), TEST_LOCATION);
296 DALI_TEST_EQUALS(1u, detector.GetMaximumTapsRequired(), TEST_LOCATION);
300 int UtcDaliTapGestureSignalReceptionNegative(void)
302 TestApplication application;
304 Actor actor = Actor::New();
305 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
306 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
307 application.GetScene().Add(actor);
310 application.SendNotification();
311 application.Render();
314 GestureReceivedFunctor functor(data);
316 TapGestureDetector detector = TapGestureDetector::New();
317 detector.Attach(actor);
318 detector.DetectedSignal().Connect(&application, functor);
320 // Do a tap outside actor's area
321 TestGenerateTap(application, 112.0f, 112.0f, 100);
322 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
326 int UtcDaliTapGestureSignalReceptionPositive(void)
328 TestApplication application;
330 Actor actor = Actor::New();
331 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
332 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
333 application.GetScene().Add(actor);
336 application.SendNotification();
337 application.Render();
340 GestureReceivedFunctor functor(data);
342 TapGestureDetector detector = TapGestureDetector::New();
343 detector.Attach(actor);
344 detector.DetectedSignal().Connect(&application, functor);
346 // Do a tap inside actor's area
347 TestGenerateTap(application, 50.0f, 50.0f, 100);
348 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
349 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
350 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
351 DALI_TEST_EQUALS(Vector2(50.0f, 50.0f), data.receivedGesture.GetLocalPoint(), 0.1, TEST_LOCATION);
355 int UtcDaliTapGestureSignalReceptionDetach(void)
357 TestApplication application;
359 Actor actor = Actor::New();
360 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
361 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
362 application.GetScene().Add(actor);
365 application.SendNotification();
366 application.Render();
369 GestureReceivedFunctor functor(data);
371 TapGestureDetector detector = TapGestureDetector::New();
372 detector.Attach(actor);
373 detector.DetectedSignal().Connect(&application, functor);
375 // Start tap within the actor's area
376 TestGenerateTap(application, 20.0f, 20.0f, 100);
377 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
378 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
379 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
380 DALI_TEST_EQUALS(Vector2(20.0f, 20.0f), data.receivedGesture.GetLocalPoint(), 0.1, TEST_LOCATION);
382 // repeat the tap within the actor's area - we should still receive the signal
384 TestGenerateTap(application, 50.0f, 50.0f, 700);
385 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
386 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
387 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
388 DALI_TEST_EQUALS(Vector2(50.0f, 50.0f), data.receivedGesture.GetLocalPoint(), 0.1, TEST_LOCATION);
391 detector.DetachAll();
393 // Ensure we are no longer signalled
395 TestGenerateTap(application, 20.0f, 20.0f, 1300);
396 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
397 TestGenerateTap(application, 50.0f, 50.0f, 1900);
398 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
402 int UtcDaliTapGestureSignalReceptionActorDestroyedWhileTapping(void)
404 TestApplication application;
407 GestureReceivedFunctor functor(data);
409 TapGestureDetector detector = TapGestureDetector::New();
410 detector.DetectedSignal().Connect(&application, functor);
412 // Actor lifetime is scoped
414 Actor actor = Actor::New();
415 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
416 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
417 application.GetScene().Add(actor);
420 application.SendNotification();
421 application.Render();
423 detector.Attach(actor);
425 // Start tap within the actor's area
426 TestGenerateTap(application, 20.0f, 20.0f, 100);
427 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
429 // Remove the actor from stage and reset the data
430 application.GetScene().Remove(actor);
433 application.SendNotification();
434 application.Render();
437 // Actor should now have been destroyed
440 TestGenerateTap(application, 20.0f, 20.0f, 700);
441 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
445 int UtcDaliTapGestureSignalReceptionRotatedActor(void)
447 TestApplication application;
449 Actor actor = Actor::New();
450 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
451 actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(90.0f), Vector3::ZAXIS));
452 application.GetScene().Add(actor);
455 application.SendNotification();
456 application.Render();
459 GestureReceivedFunctor functor(data);
461 TapGestureDetector detector = TapGestureDetector::New();
462 detector.Attach(actor);
463 detector.DetectedSignal().Connect(&application, functor);
465 // Do tap, only check finished value
466 TestGenerateTap(application, 5.0f, 5.0f, 100);
467 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
468 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
469 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
470 DALI_TEST_EQUALS(Vector2(5.0f, 5.0f), data.receivedGesture.GetScreenPoint(), 0.1, TEST_LOCATION);
472 // Rotate actor again and render
473 actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(180.0f), Vector3::ZAXIS));
474 application.SendNotification();
475 application.Render();
477 // Do tap, should still receive event
479 TestGenerateTap(application, 5.0f, 5.0f, 700);
480 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
481 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
482 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
483 DALI_TEST_EQUALS(Vector2(5.0f, 5.0f), data.receivedGesture.GetScreenPoint(), 0.1, TEST_LOCATION);
485 // Rotate actor again and render
486 actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(90.0f), Vector3::YAXIS));
487 application.SendNotification();
488 application.Render();
490 // Do tap, inside the actor's area (area if it is not rotated), Should not receive the event
492 TestGenerateTap(application, 70.0f, 70.0f, 1300);
493 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
497 int UtcDaliTapGestureSignalReceptionChildHit(void)
499 TestApplication application;
501 Actor parent = Actor::New();
502 parent.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
503 parent.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
504 application.GetScene().Add(parent);
506 // Set child to completely cover parent.
507 // Change rotation of child to be different from parent so that we can check if our local coordinate
508 // conversion of the parent actor is correct.
509 Actor child = Actor::New();
510 child.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
511 child.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
512 child.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
513 child.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(90.0f), Vector3::ZAXIS));
516 TouchEventFunctor touchFunctor;
517 child.TouchedSignal().Connect(&application, touchFunctor);
520 application.SendNotification();
521 application.Render();
524 GestureReceivedFunctor functor(data);
526 TapGestureDetector detector = TapGestureDetector::New();
527 detector.Attach(parent);
528 detector.DetectedSignal().Connect(&application, functor);
530 // Do tap - hits child area but parent should still receive it
531 TestGenerateTap(application, 50.0f, 50.0f, 100);
532 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
533 DALI_TEST_EQUALS(true, parent == data.tappedActor, TEST_LOCATION);
534 DALI_TEST_EQUALS(Vector2(50.0f, 50.0f), data.receivedGesture.GetScreenPoint(), 0.01f, TEST_LOCATION);
536 // Attach child and generate same touch points
537 // (Also proves that you can detach and then re-attach another actor)
538 detector.Attach(child);
539 detector.Detach(parent);
541 // Do an entire tap, only check finished value
543 TestGenerateTap(application, 51.0f, 51.0f, 700);
544 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
545 DALI_TEST_EQUALS(true, child == data.tappedActor, TEST_LOCATION);
546 DALI_TEST_EQUALS(Vector2(51.0f, 51.0f), data.receivedGesture.GetScreenPoint(), 0.01f, TEST_LOCATION);
550 int UtcDaliTapGestureSignalReceptionAttachDetachMany(void)
552 TestApplication application;
554 Actor first = Actor::New();
555 first.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
556 first.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
557 application.GetScene().Add(first);
559 Actor second = Actor::New();
560 second.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
561 second.SetProperty(Actor::Property::POSITION_X, 100.0f);
562 second.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
563 application.GetScene().Add(second);
566 application.SendNotification();
567 application.Render();
570 GestureReceivedFunctor functor(data);
572 TapGestureDetector detector = TapGestureDetector::New();
573 detector.Attach(first);
574 detector.Attach(second);
575 detector.DetectedSignal().Connect(&application, functor);
577 // Tap within second actor's area
578 TestGenerateTap(application, 120.0f, 10.0f, 100);
579 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
580 DALI_TEST_EQUALS(true, second == data.tappedActor, TEST_LOCATION);
582 // Tap within first actor's area
584 TestGenerateTap(application, 20.0f, 10.0f, 700);
585 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
586 DALI_TEST_EQUALS(true, first == data.tappedActor, TEST_LOCATION);
588 // Detach the second actor
589 detector.Detach(second);
591 // second actor shouldn't receive event
593 TestGenerateTap(application, 120.0f, 10.0f, 1300);
594 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
596 // first actor should continue receiving event
598 TestGenerateTap(application, 20.0f, 10.0f, 1900);
599 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
603 int UtcDaliTapGestureSignalReceptionActorBecomesUntouchable(void)
605 TestApplication application;
607 Actor actor = Actor::New();
608 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
609 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
610 application.GetScene().Add(actor);
613 application.SendNotification();
614 application.Render();
617 GestureReceivedFunctor functor(data);
619 TapGestureDetector detector = TapGestureDetector::New();
620 detector.Attach(actor);
621 detector.DetectedSignal().Connect(&application, functor);
623 // Tap in actor's area
624 TestGenerateTap(application, 50.0f, 10.0f, 100);
625 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
627 // Actor become invisible - actor should not receive the next pan
628 actor.SetProperty(Actor::Property::VISIBLE, false);
631 application.SendNotification();
632 application.Render();
634 // Tap in the same area, shouldn't receive event
636 TestGenerateTap(application, 50.0f, 10.0f, 700);
637 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
641 int UtcDaliTapGestureSignalReceptionMultipleGestureDetectors(void)
643 TestApplication application;
645 Actor first = Actor::New();
646 first.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
647 first.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
648 application.GetScene().Add(first);
650 Actor second = Actor::New();
651 second.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
652 second.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
653 second.SetProperty(Actor::Property::POSITION_X, 100.0f);
657 application.SendNotification();
658 application.Render();
661 GestureReceivedFunctor functor(data);
663 TapGestureDetector firstDetector = TapGestureDetector::New();
664 firstDetector.Attach(first);
665 firstDetector.DetectedSignal().Connect(&application, functor);
667 // secondDetector is scoped
669 TapGestureDetector secondDetector = TapGestureDetector::New(2);
670 secondDetector.Attach(second);
671 secondDetector.DetectedSignal().Connect(&application, functor);
673 // Tap within second actor's area
674 TestGenerateTap(application, 150.0f, 10.0f, 100);
675 TestGenerateTap(application, 150.0f, 10.0f, 200);
677 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
678 DALI_TEST_EQUALS(true, second == data.tappedActor, TEST_LOCATION);
680 // Tap continues as single touch gesture - we should not receive any gesture
682 TestGenerateTap(application, 150.0f, 10.0f, 800);
683 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
685 // Single touch tap starts - first actor should be panned
687 TestGenerateTap(application, 50.0f, 10.0f, 1400);
688 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
689 DALI_TEST_EQUALS(true, first == data.tappedActor, TEST_LOCATION);
691 // Tap changes to double-touch - we shouldn't receive event
694 TestGenerateTwoPointTap(application, 50.0f, 10.0f, 60.0f, 20.0f, 2000);
696 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
702 int UtcDaliTapGestureSignalReceptionMultipleDetectorsOnActor(void)
704 TestApplication application;
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);
712 application.SendNotification();
713 application.Render();
715 // Attach actor to one detector
716 SignalData firstData;
717 GestureReceivedFunctor firstFunctor(firstData);
718 TapGestureDetector firstDetector = TapGestureDetector::New();
719 firstDetector.Attach(actor);
720 firstDetector.DetectedSignal().Connect(&application, firstFunctor);
722 // Attach actor to another detector
723 SignalData secondData;
724 GestureReceivedFunctor secondFunctor(secondData);
725 TapGestureDetector secondDetector = TapGestureDetector::New();
726 secondDetector.Attach(actor);
727 secondDetector.DetectedSignal().Connect(&application, secondFunctor);
729 // Tap in actor's area - both detector's functors should be called
730 TestGenerateTap(application, 50.0f, 10.0f, 100);
731 DALI_TEST_EQUALS(true, firstData.functorCalled, TEST_LOCATION);
732 DALI_TEST_EQUALS(true, secondData.functorCalled, TEST_LOCATION);
736 int UtcDaliTapGestureSignalReceptionDifferentPossible(void)
738 TestApplication application;
740 Actor actor = Actor::New();
741 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
742 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
743 application.GetScene().Add(actor);
746 application.SendNotification();
747 application.Render();
749 // Attach actor to detector
751 GestureReceivedFunctor functor(data);
752 TapGestureDetector detector = TapGestureDetector::New();
753 detector.Attach(actor);
754 detector.DetectedSignal().Connect(&application, functor);
756 // Gesture possible in actor's area.
757 TestStartLongPress(application, 50.0f, 10.0f, 100);
758 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
760 // Move actor somewhere else
761 actor.SetProperty(Actor::Property::POSITION, Vector2(100.0f, 100.0f));
764 application.SendNotification();
765 application.Render();
767 // Emit STARTED event, we should not receive the tap.
768 TestEndPan(application, Vector2(50.0f, 10.0f), 120);
769 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
771 // Tap possible in empty area.
772 TestStartLongPress(application, 50.0f, 10.0f, 700);
773 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
775 // Move actor in to the tap position.
776 actor.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f));
779 application.SendNotification();
780 application.Render();
782 // Emit STARTED event, we should not receive the tap.
783 TestEndPan(application, Vector2(50.0f, 10.0f), 720);
784 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
786 // Normal tap in actor's area for completeness.
787 TestGenerateTap(application, 50.0f, 10.0f, 1300);
788 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
792 int UtcDaliTapGestureActorUnstaged(void)
794 TestApplication application;
796 Actor actor = Actor::New();
797 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
798 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
799 application.GetScene().Add(actor);
802 application.SendNotification();
803 application.Render();
805 // Attach actor to detector
807 UnstageActorFunctor functor(data, application.GetScene());
808 TapGestureDetector detector = TapGestureDetector::New();
809 detector.Attach(actor);
810 detector.DetectedSignal().Connect(&application, functor);
812 TestGenerateTap(application, 50.0f, 10.0f, 100);
813 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
814 tet_result(TET_PASS); // If we get here, then the actor removal on signal handler was handled gracefully.
818 int UtcDaliTapGestureDetectorRemovedWhilePossible(void)
820 TestApplication application;
822 Actor actor = Actor::New();
823 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
824 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
825 application.GetScene().Add(actor);
828 application.SendNotification();
829 application.Render();
831 // Attach actor to detector
833 GestureReceivedFunctor functor(data);
834 TapGestureDetector detector = TapGestureDetector::New();
835 detector.Attach(actor);
836 detector.DetectedSignal().Connect(&application, functor);
838 // Emit a possible - Down press, as emitted by long press function
839 TestStartLongPress(application, 50.0f, 10.0f, 100);
841 // Detach actor and send a STARTED state, no signal.
842 detector.DetachAll();
843 TestEndPan(application, Vector2(50.0f, 10.0f), 120);
844 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
848 int UtcDaliTapGestureActorRemovedWhilePossible(void)
850 TestApplication application;
852 Actor actor = Actor::New();
853 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
854 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
855 application.GetScene().Add(actor);
858 application.SendNotification();
859 application.Render();
861 // Attach actor to detector
863 GestureReceivedFunctor functor(data);
864 TapGestureDetector detector = TapGestureDetector::New();
865 detector.Attach(actor);
866 detector.DetectedSignal().Connect(&application, functor);
868 // Emit a possible - Down press, as emitted by long press function
869 TestStartLongPress(application, 50.0f, 10.0f, 100);
871 // Remove, render and delete actor
872 application.GetScene().Remove(actor);
873 application.SendNotification();
874 application.Render();
877 // Send a STARTED state, no signal - Up motion as provided by end pan function
878 TestEndPan(application, Vector2(50.0f, 10.0f), 120);
879 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
883 int UtcDaliTapGestureLayerConsumesTouch(void)
885 TestApplication application;
887 Actor actor = Actor::New();
888 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
889 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
890 application.GetScene().Add(actor);
894 GestureReceivedFunctor functor(data);
895 TapGestureDetector detector = TapGestureDetector::New();
896 detector.Attach(actor);
897 detector.DetectedSignal().Connect(&application, functor);
899 // Add a layer to overlap the actor
900 Layer layer = Layer::New();
901 layer.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
902 layer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
903 application.GetScene().Add(layer);
907 application.SendNotification();
908 application.Render();
910 // Emit signals, should receive
911 TestGenerateTap(application, 50.0f, 50.0f, 100);
912 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
915 // Set layer to consume all touch
916 layer.SetProperty(Layer::Property::CONSUMES_TOUCH, true);
919 application.SendNotification();
920 application.Render();
922 // Emit the same signals again, should not receive
923 TestGenerateTap(application, 50.0f, 50.0f, 700);
924 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
930 int UtcDaliTapGestureDisableDetectionDuringTapN(void)
932 // Crash sometimes occurred when gesture-recognizer was deleted internally during a signal when the attached actor was detached
934 TestApplication application;
936 Actor actor = Actor::New();
937 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
938 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
939 application.GetScene().Add(actor);
942 TapGestureDetector detector = TapGestureDetector::New();
943 bool functorCalled = false;
944 detector.Attach(actor);
945 detector.DetectedSignal().Connect(
947 [&detector, &functorCalled](Actor actor, const TapGesture& gesture) {
948 detector.Detach(actor);
949 functorCalled = true;
953 application.SendNotification();
954 application.Render();
956 // Try the gesture, should not crash
959 TestGenerateTap(application, 50.0f, 10.0f);
961 DALI_TEST_CHECK(true); // No crash, test has passed
962 DALI_TEST_EQUALS(functorCalled, true, TEST_LOCATION);
966 DALI_TEST_CHECK(false); // If we crash, the test has failed
972 int UtcDaliTapGestureWhenGesturePropargation(void)
974 TestApplication application;
976 Actor parentActor = Actor::New();
977 parentActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
978 parentActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
980 Actor childActor = Actor::New();
981 childActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
982 childActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
984 parentActor.Add(childActor);
985 application.GetScene().Add(parentActor);
988 application.SendNotification();
989 application.Render();
992 GestureReceivedFunctor pFunctor(pData);
994 TapGestureDetector parentDetector = TapGestureDetector::New();
995 parentDetector.Attach(parentActor);
996 parentDetector.DetectedSignal().Connect(&application, pFunctor);
999 GestureReceivedFunctor cFunctor(cData);
1001 TapGestureDetector childDetector = TapGestureDetector::New();
1002 childDetector.Attach(childActor);
1003 childDetector.DetectedSignal().Connect(&application, cFunctor);
1005 // Start gesture within the actor's area, we receive the gesture not parent actor but child actor.
1006 TestGenerateTap(application, 50.0f, 50.0f, 100);
1007 DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
1008 DALI_TEST_EQUALS(false, pData.functorCalled, TEST_LOCATION);
1012 // If GesturePropargation is set, a gesture event is delivered to the parent.
1013 Dali::DevelActor::SetNeedGesturePropagation(childActor, true);
1015 // So now the parent got the gesture event.
1016 TestGenerateTap(application, 50.0f, 50.0f, 700);
1017 DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
1018 DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION);
1025 int UtcDaliTapGestureGetSourceType(void)
1027 TestApplication application;
1029 Actor actor = Actor::New();
1030 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1031 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1032 application.GetScene().Add(actor);
1034 // Render and notify
1035 application.SendNotification();
1036 application.Render();
1039 GestureReceivedFunctor functor(data);
1041 TapGestureDetector detector = TapGestureDetector::New();
1042 detector.Attach(actor);
1043 detector.DetectedSignal().Connect(&application, functor);
1045 // Emit a down signal with MouseButton
1046 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 0, 100));
1047 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 0, 120));
1048 application.SendNotification();
1050 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1051 DALI_TEST_EQUALS(data.receivedGesture.GetSourceType(), GestureSourceType::INVALID, TEST_LOCATION);
1055 // Emit a down signal with MouseButton
1056 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 1, 700));
1057 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 1, 720));
1058 application.SendNotification();
1060 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1061 DALI_TEST_EQUALS(data.receivedGesture.GetSourceType(), GestureSourceType::PRIMARY, TEST_LOCATION);
1065 // Emit a down signal with MouseButton
1066 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 3, 1300));
1067 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 3, 1320));
1068 application.SendNotification();
1070 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1071 DALI_TEST_EQUALS(data.receivedGesture.GetSourceType(), GestureSourceType::SECONDARY, TEST_LOCATION);
1075 // Emit a down signal with MouseButton
1076 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 2, 1900));
1077 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 2, 1920));
1078 application.SendNotification();
1080 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1081 DALI_TEST_EQUALS(data.receivedGesture.GetSourceType(), GestureSourceType::TERTIARY, TEST_LOCATION);
1086 int UtcDaliTapGestureReceiveAllTapEvents(void)
1088 TestApplication application;
1090 Actor actor = Actor::New();
1091 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1092 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1094 application.GetScene().Add(actor);
1096 // Render and notify
1097 application.SendNotification();
1098 application.Render();
1101 GestureReceivedFunctor functor(data);
1103 TapGestureDetector detector = TapGestureDetector::New();
1104 detector.SetMaximumTapsRequired(2u);
1105 detector.Attach(actor);
1106 detector.DetectedSignal().Connect(&application, functor);
1108 // Emit signals, Because MaximumTapsRequired is 2, a timer that checks whether it is a single tap or a double tap operates internally.
1109 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 0, 100));
1110 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 0, 120));
1111 application.SendNotification();
1113 // So detector don't get the tap event yet.
1114 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1117 // Emit signals, Send the second tab.
1118 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 0, 130));
1119 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 0, 150));
1120 application.SendNotification();
1121 application.GetPlatform().TriggerTimer();
1123 // It find out to be a double tap. Detector receives events.
1124 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1127 // Detector want to receive all tap events.
1128 detector.ReceiveAllTapEvents(true);
1130 // Emit signals, should receive
1131 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 0, 500));
1132 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 0, 520));
1133 application.SendNotification();
1135 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1138 // Emit signals, should receive
1139 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 0, 530));
1140 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 0, 550));
1141 application.SendNotification();
1143 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);