2 * Copyright (c) 2022 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 bool gHitTestTouchCallBackCalled = false;
44 static bool TestHitTestTouchCallback(Actor, const TouchEvent&)
46 gHitTestTouchCallBackCalled = true;
50 // Stores data that is populated in the callback and will be read by the TET cases
54 : functorCalled(false),
55 voidFunctorCalled(false)
61 functorCalled = false;
62 voidFunctorCalled = false;
64 receivedGesture.Reset();
70 bool voidFunctorCalled;
71 TapGesture receivedGesture;
75 // Functor that sets the data when called
76 struct GestureReceivedFunctor
78 GestureReceivedFunctor(SignalData& data)
83 void operator()(Actor actor, const TapGesture& tap)
85 signalData.functorCalled = true;
86 signalData.receivedGesture = tap;
87 signalData.tappedActor = actor;
92 signalData.voidFunctorCalled = true;
95 SignalData& signalData;
98 // Functor that removes the gestured actor from stage
99 struct UnstageActorFunctor : public GestureReceivedFunctor
101 UnstageActorFunctor(SignalData& data, Integration::Scene scene)
102 : GestureReceivedFunctor(data),
107 void operator()(Actor actor, const TapGesture& tap)
109 GestureReceivedFunctor::operator()(actor, tap);
113 Integration::Scene scene;
116 // Functor for receiving a touch event
117 struct TouchEventFunctor
119 bool operator()(Actor actor, const TouchEvent& touch)
122 unsigned int points = touch.GetPointCount();
125 tet_printf("Touch Point state = %d\n", touch.GetState(0));
131 Integration::TouchEvent GenerateSingleTouch(PointState::Type state, const Vector2& screenPosition, int source, uint32_t time)
133 Integration::TouchEvent touchEvent;
134 Integration::Point point;
135 point.SetState(state);
136 point.SetDeviceId(4);
137 point.SetScreenPosition(screenPosition);
138 point.SetDeviceClass(Device::Class::TOUCH);
139 point.SetDeviceSubclass(Device::Subclass::NONE);
140 point.SetMouseButton(static_cast<MouseButton::Type>(source));
141 touchEvent.points.push_back(point);
142 touchEvent.time = time;
148 ///////////////////////////////////////////////////////////////////////////////
150 // Positive test case for a method
151 int UtcDaliTapGestureDetectorConstructor(void)
153 TestApplication application;
155 TapGestureDetector detector;
156 DALI_TEST_CHECK(!detector);
160 int UtcDaliTapGestureDetectorCopyConstructorP(void)
162 TestApplication application;
164 TapGestureDetector detector = TapGestureDetector::New();
166 TapGestureDetector copy(detector);
167 DALI_TEST_CHECK(detector);
171 int UtcDaliTapGestureDetectorAssignmentOperatorP(void)
173 TestApplication application;
175 TapGestureDetector detector = TapGestureDetector::New();
178 TapGestureDetector assign;
180 DALI_TEST_CHECK(detector);
182 DALI_TEST_CHECK(detector == assign);
186 int UtcDaliTapGestureDetectorNew(void)
188 TestApplication application;
190 TapGestureDetector detector = TapGestureDetector::New();
191 DALI_TEST_CHECK(detector);
192 DALI_TEST_EQUALS(1u, detector.GetMinimumTapsRequired(), TEST_LOCATION);
193 DALI_TEST_EQUALS(1u, detector.GetMaximumTapsRequired(), TEST_LOCATION);
195 TapGestureDetector detector2 = TapGestureDetector::New(5u);
196 DALI_TEST_CHECK(detector2);
197 DALI_TEST_EQUALS(5u, detector2.GetMinimumTapsRequired(), TEST_LOCATION);
198 DALI_TEST_EQUALS(5u, detector2.GetMaximumTapsRequired(), TEST_LOCATION);
200 //Scoped test to test destructor
202 TapGestureDetector detector3 = TapGestureDetector::New();
203 DALI_TEST_CHECK(detector3);
206 // Attach an actor and emit a touch event on the actor to ensure complete line coverage
207 Actor actor = Actor::New();
208 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
209 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
210 application.GetScene().Add(actor);
213 application.SendNotification();
214 application.Render();
216 detector.Attach(actor);
218 TouchEventFunctor touchFunctor;
219 actor.TouchedSignal().Connect(&application, touchFunctor);
221 Integration::TouchEvent touchEvent(1);
222 Integration::Point point;
223 point.SetDeviceId(1);
224 point.SetState(PointState::DOWN);
225 point.SetScreenPosition(Vector2(20.0f, 20.0f));
226 touchEvent.AddPoint(point);
227 application.ProcessEvent(touchEvent);
230 application.SendNotification();
231 application.Render();
236 int UtcDaliTapGestureDetectorDownCast(void)
238 TestApplication application;
239 tet_infoline("Testing Dali::TapGestureDetector::DownCast()");
241 TapGestureDetector detector = TapGestureDetector::New();
243 BaseHandle object(detector);
245 TapGestureDetector detector2 = TapGestureDetector::DownCast(object);
246 DALI_TEST_CHECK(detector2);
248 TapGestureDetector detector3 = DownCast<TapGestureDetector>(object);
249 DALI_TEST_CHECK(detector3);
251 BaseHandle unInitializedObject;
252 TapGestureDetector detector4 = TapGestureDetector::DownCast(unInitializedObject);
253 DALI_TEST_CHECK(!detector4);
255 TapGestureDetector detector5 = DownCast<TapGestureDetector>(unInitializedObject);
256 DALI_TEST_CHECK(!detector5);
258 GestureDetector detector6 = TapGestureDetector::New();
259 TapGestureDetector detector7 = TapGestureDetector::DownCast(detector6);
260 DALI_TEST_CHECK(detector7);
264 int UtcDaliTapGestureSetTapsRequiredMinMaxCheck(void)
266 TestApplication application;
268 // Attach an actor and change the required touches
270 Actor actor = Actor::New();
271 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
272 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
273 application.GetScene().Add(actor);
276 application.SendNotification();
277 application.Render();
279 // Set the minimum to be greater than the maximum, should Assert
283 TapGestureDetector detector = TapGestureDetector::New();
284 detector.SetMinimumTapsRequired(7u);
285 detector.SetMaximumTapsRequired(3u);
286 detector.Attach(actor);
287 DALI_TEST_CHECK(false); // Should not get here
289 catch(DaliException& e)
291 DALI_TEST_CHECK(true);
297 int UtcDaliTapGestureGetTapsRequired(void)
299 TestApplication application;
301 TapGestureDetector detector = TapGestureDetector::New();
302 DALI_TEST_EQUALS(1u, detector.GetMinimumTapsRequired(), TEST_LOCATION);
303 DALI_TEST_EQUALS(1u, detector.GetMaximumTapsRequired(), TEST_LOCATION);
307 int UtcDaliTapGestureSignalReceptionNegative(void)
309 TestApplication application;
311 Actor actor = Actor::New();
312 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
313 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
314 application.GetScene().Add(actor);
317 application.SendNotification();
318 application.Render();
321 GestureReceivedFunctor functor(data);
323 TapGestureDetector detector = TapGestureDetector::New();
324 detector.Attach(actor);
325 detector.DetectedSignal().Connect(&application, functor);
327 // Do a tap outside actor's area
328 TestGenerateTap(application, 112.0f, 112.0f, 100);
329 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
333 int UtcDaliTapGestureSignalReceptionPositive(void)
335 TestApplication application;
337 Actor actor = Actor::New();
338 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
339 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
340 application.GetScene().Add(actor);
343 application.SendNotification();
344 application.Render();
347 GestureReceivedFunctor functor(data);
349 TapGestureDetector detector = TapGestureDetector::New();
350 detector.Attach(actor);
351 detector.DetectedSignal().Connect(&application, functor);
353 // Do a tap inside actor's area
354 TestGenerateTap(application, 50.0f, 50.0f, 100);
355 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
356 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
357 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
358 DALI_TEST_EQUALS(Vector2(50.0f, 50.0f), data.receivedGesture.GetLocalPoint(), 0.1, TEST_LOCATION);
362 int UtcDaliTapGestureSignalReceptionDetach(void)
364 TestApplication application;
366 Actor actor = Actor::New();
367 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
368 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
369 application.GetScene().Add(actor);
372 application.SendNotification();
373 application.Render();
376 GestureReceivedFunctor functor(data);
378 TapGestureDetector detector = TapGestureDetector::New();
379 detector.Attach(actor);
380 detector.DetectedSignal().Connect(&application, functor);
382 // Start tap within the actor's area
383 TestGenerateTap(application, 20.0f, 20.0f, 100);
384 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
385 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
386 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
387 DALI_TEST_EQUALS(Vector2(20.0f, 20.0f), data.receivedGesture.GetLocalPoint(), 0.1, TEST_LOCATION);
389 // repeat the tap within the actor's area - we should still receive the signal
391 TestGenerateTap(application, 50.0f, 50.0f, 700);
392 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
393 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
394 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
395 DALI_TEST_EQUALS(Vector2(50.0f, 50.0f), data.receivedGesture.GetLocalPoint(), 0.1, TEST_LOCATION);
398 detector.DetachAll();
400 // Ensure we are no longer signalled
402 TestGenerateTap(application, 20.0f, 20.0f, 1300);
403 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
404 TestGenerateTap(application, 50.0f, 50.0f, 1900);
405 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
409 int UtcDaliTapGestureSignalReceptionActorDestroyedWhileTapping(void)
411 TestApplication application;
414 GestureReceivedFunctor functor(data);
416 TapGestureDetector detector = TapGestureDetector::New();
417 detector.DetectedSignal().Connect(&application, functor);
419 // Actor lifetime is scoped
421 Actor actor = Actor::New();
422 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
423 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
424 application.GetScene().Add(actor);
427 application.SendNotification();
428 application.Render();
430 detector.Attach(actor);
432 // Start tap within the actor's area
433 TestGenerateTap(application, 20.0f, 20.0f, 100);
434 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
436 // Remove the actor from stage and reset the data
437 application.GetScene().Remove(actor);
440 application.SendNotification();
441 application.Render();
444 // Actor should now have been destroyed
447 TestGenerateTap(application, 20.0f, 20.0f, 700);
448 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
452 int UtcDaliTapGestureSignalReceptionRotatedActor(void)
454 TestApplication application;
456 Actor actor = Actor::New();
457 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
458 actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(90.0f), Vector3::ZAXIS));
459 application.GetScene().Add(actor);
462 application.SendNotification();
463 application.Render();
466 GestureReceivedFunctor functor(data);
468 TapGestureDetector detector = TapGestureDetector::New();
469 detector.Attach(actor);
470 detector.DetectedSignal().Connect(&application, functor);
472 // Do tap, only check finished value
473 TestGenerateTap(application, 5.0f, 5.0f, 100);
474 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
475 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
476 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
477 DALI_TEST_EQUALS(Vector2(5.0f, 5.0f), data.receivedGesture.GetScreenPoint(), 0.1, TEST_LOCATION);
479 // Rotate actor again and render
480 actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(180.0f), Vector3::ZAXIS));
481 application.SendNotification();
482 application.Render();
484 // Do tap, should still receive event
486 TestGenerateTap(application, 5.0f, 5.0f, 700);
487 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
488 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
489 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
490 DALI_TEST_EQUALS(Vector2(5.0f, 5.0f), data.receivedGesture.GetScreenPoint(), 0.1, TEST_LOCATION);
492 // Rotate actor again and render
493 actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(90.0f), Vector3::YAXIS));
494 application.SendNotification();
495 application.Render();
497 // Do tap, inside the actor's area (area if it is not rotated), Should not receive the event
499 TestGenerateTap(application, 70.0f, 70.0f, 1300);
500 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
504 int UtcDaliTapGestureSignalReceptionChildHit(void)
506 TestApplication application;
508 Actor parent = Actor::New();
509 parent.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
510 parent.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
511 application.GetScene().Add(parent);
513 // Set child to completely cover parent.
514 // Change rotation of child to be different from parent so that we can check if our local coordinate
515 // conversion of the parent actor is correct.
516 Actor child = Actor::New();
517 child.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
518 child.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
519 child.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
520 child.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(90.0f), Vector3::ZAXIS));
523 TouchEventFunctor touchFunctor;
524 child.TouchedSignal().Connect(&application, touchFunctor);
527 application.SendNotification();
528 application.Render();
531 GestureReceivedFunctor functor(data);
533 TapGestureDetector detector = TapGestureDetector::New();
534 detector.Attach(parent);
535 detector.DetectedSignal().Connect(&application, functor);
537 // Do tap - hits child area but parent should still receive it
538 TestGenerateTap(application, 50.0f, 50.0f, 100);
539 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
540 DALI_TEST_EQUALS(true, parent == data.tappedActor, TEST_LOCATION);
541 DALI_TEST_EQUALS(Vector2(50.0f, 50.0f), data.receivedGesture.GetScreenPoint(), 0.01f, TEST_LOCATION);
543 // Attach child and generate same touch points
544 // (Also proves that you can detach and then re-attach another actor)
545 detector.Attach(child);
546 detector.Detach(parent);
548 // Do an entire tap, only check finished value
550 TestGenerateTap(application, 51.0f, 51.0f, 700);
551 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
552 DALI_TEST_EQUALS(true, child == data.tappedActor, TEST_LOCATION);
553 DALI_TEST_EQUALS(Vector2(51.0f, 51.0f), data.receivedGesture.GetScreenPoint(), 0.01f, TEST_LOCATION);
557 int UtcDaliTapGestureSignalReceptionAttachDetachMany(void)
559 TestApplication application;
561 Actor first = Actor::New();
562 first.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
563 first.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
564 application.GetScene().Add(first);
566 Actor second = Actor::New();
567 second.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
568 second.SetProperty(Actor::Property::POSITION_X, 100.0f);
569 second.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
570 application.GetScene().Add(second);
573 application.SendNotification();
574 application.Render();
577 GestureReceivedFunctor functor(data);
579 TapGestureDetector detector = TapGestureDetector::New();
580 detector.Attach(first);
581 detector.Attach(second);
582 detector.DetectedSignal().Connect(&application, functor);
584 // Tap within second actor's area
585 TestGenerateTap(application, 120.0f, 10.0f, 100);
586 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
587 DALI_TEST_EQUALS(true, second == data.tappedActor, TEST_LOCATION);
589 // Tap within first actor's area
591 TestGenerateTap(application, 20.0f, 10.0f, 700);
592 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
593 DALI_TEST_EQUALS(true, first == data.tappedActor, TEST_LOCATION);
595 // Detach the second actor
596 detector.Detach(second);
598 // second actor shouldn't receive event
600 TestGenerateTap(application, 120.0f, 10.0f, 1300);
601 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
603 // first actor should continue receiving event
605 TestGenerateTap(application, 20.0f, 10.0f, 1900);
606 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
610 int UtcDaliTapGestureSignalReceptionActorBecomesUntouchable(void)
612 TestApplication application;
614 Actor actor = Actor::New();
615 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
616 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
617 application.GetScene().Add(actor);
620 application.SendNotification();
621 application.Render();
624 GestureReceivedFunctor functor(data);
626 TapGestureDetector detector = TapGestureDetector::New();
627 detector.Attach(actor);
628 detector.DetectedSignal().Connect(&application, functor);
630 // Tap in actor's area
631 TestGenerateTap(application, 50.0f, 10.0f, 100);
632 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
634 // Actor become invisible - actor should not receive the next pan
635 actor.SetProperty(Actor::Property::VISIBLE, false);
638 application.SendNotification();
639 application.Render();
641 // Tap in the same area, shouldn't receive event
643 TestGenerateTap(application, 50.0f, 10.0f, 700);
644 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
648 int UtcDaliTapGestureSignalReceptionMultipleGestureDetectors(void)
650 TestApplication application;
652 Actor first = Actor::New();
653 first.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
654 first.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
655 application.GetScene().Add(first);
657 Actor second = Actor::New();
658 second.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
659 second.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
660 second.SetProperty(Actor::Property::POSITION_X, 100.0f);
664 application.SendNotification();
665 application.Render();
668 GestureReceivedFunctor functor(data);
670 TapGestureDetector firstDetector = TapGestureDetector::New();
671 firstDetector.Attach(first);
672 firstDetector.DetectedSignal().Connect(&application, functor);
674 // secondDetector is scoped
676 TapGestureDetector secondDetector = TapGestureDetector::New(2);
677 secondDetector.Attach(second);
678 secondDetector.DetectedSignal().Connect(&application, functor);
680 // Tap within second actor's area
681 TestGenerateTap(application, 150.0f, 10.0f, 100);
682 TestGenerateTap(application, 150.0f, 10.0f, 200);
684 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
685 DALI_TEST_EQUALS(true, second == data.tappedActor, TEST_LOCATION);
687 // Tap continues as single touch gesture - we should not receive any gesture
689 TestGenerateTap(application, 150.0f, 10.0f, 800);
690 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
692 // Single touch tap starts - first actor should be panned
694 TestGenerateTap(application, 50.0f, 10.0f, 1400);
695 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
696 DALI_TEST_EQUALS(true, first == data.tappedActor, TEST_LOCATION);
698 // Tap changes to double-touch - we shouldn't receive event
701 TestGenerateTwoPointTap(application, 50.0f, 10.0f, 60.0f, 20.0f, 2000);
703 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
709 int UtcDaliTapGestureSignalReceptionMultipleDetectorsOnActor(void)
711 TestApplication application;
713 Actor actor = Actor::New();
714 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
715 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
716 application.GetScene().Add(actor);
719 application.SendNotification();
720 application.Render();
722 // Attach actor to one detector
723 SignalData firstData;
724 GestureReceivedFunctor firstFunctor(firstData);
725 TapGestureDetector firstDetector = TapGestureDetector::New();
726 firstDetector.Attach(actor);
727 firstDetector.DetectedSignal().Connect(&application, firstFunctor);
729 // Attach actor to another detector
730 SignalData secondData;
731 GestureReceivedFunctor secondFunctor(secondData);
732 TapGestureDetector secondDetector = TapGestureDetector::New();
733 secondDetector.Attach(actor);
734 secondDetector.DetectedSignal().Connect(&application, secondFunctor);
736 // Tap in actor's area - both detector's functors should be called
737 TestGenerateTap(application, 50.0f, 10.0f, 100);
738 DALI_TEST_EQUALS(true, firstData.functorCalled, TEST_LOCATION);
739 DALI_TEST_EQUALS(true, secondData.functorCalled, TEST_LOCATION);
743 int UtcDaliTapGestureSignalReceptionDifferentPossible(void)
745 TestApplication application;
747 Actor actor = Actor::New();
748 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
749 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
750 application.GetScene().Add(actor);
753 application.SendNotification();
754 application.Render();
756 // Attach actor to detector
758 GestureReceivedFunctor functor(data);
759 TapGestureDetector detector = TapGestureDetector::New();
760 detector.Attach(actor);
761 detector.DetectedSignal().Connect(&application, functor);
763 // Gesture possible in actor's area.
764 TestStartLongPress(application, 50.0f, 10.0f, 100);
765 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
767 // Move actor somewhere else
768 actor.SetProperty(Actor::Property::POSITION, Vector2(100.0f, 100.0f));
771 application.SendNotification();
772 application.Render();
774 // Emit STARTED event, we should not receive the tap.
775 TestEndPan(application, Vector2(50.0f, 10.0f), 120);
776 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
778 // Tap possible in empty area.
779 TestStartLongPress(application, 50.0f, 10.0f, 700);
780 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
782 // Move actor in to the tap position.
783 actor.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f));
786 application.SendNotification();
787 application.Render();
789 // Emit STARTED event, we should not receive the tap.
790 TestEndPan(application, Vector2(50.0f, 10.0f), 720);
791 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
793 // Normal tap in actor's area for completeness.
794 TestGenerateTap(application, 50.0f, 10.0f, 1300);
795 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
799 int UtcDaliTapGestureActorUnstaged(void)
801 TestApplication application;
803 Actor actor = Actor::New();
804 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
805 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
806 application.GetScene().Add(actor);
809 application.SendNotification();
810 application.Render();
812 // Attach actor to detector
814 UnstageActorFunctor functor(data, application.GetScene());
815 TapGestureDetector detector = TapGestureDetector::New();
816 detector.Attach(actor);
817 detector.DetectedSignal().Connect(&application, functor);
819 TestGenerateTap(application, 50.0f, 10.0f, 100);
820 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
821 tet_result(TET_PASS); // If we get here, then the actor removal on signal handler was handled gracefully.
825 int UtcDaliTapGestureDetectorRemovedWhilePossible(void)
827 TestApplication application;
829 Actor actor = Actor::New();
830 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
831 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
832 application.GetScene().Add(actor);
835 application.SendNotification();
836 application.Render();
838 // Attach actor to detector
840 GestureReceivedFunctor functor(data);
841 TapGestureDetector detector = TapGestureDetector::New();
842 detector.Attach(actor);
843 detector.DetectedSignal().Connect(&application, functor);
845 // Emit a possible - Down press, as emitted by long press function
846 TestStartLongPress(application, 50.0f, 10.0f, 100);
848 // Detach actor and send a STARTED state, no signal.
849 detector.DetachAll();
850 TestEndPan(application, Vector2(50.0f, 10.0f), 120);
851 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
855 int UtcDaliTapGestureActorRemovedWhilePossible(void)
857 TestApplication application;
859 Actor actor = Actor::New();
860 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
861 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
862 application.GetScene().Add(actor);
865 application.SendNotification();
866 application.Render();
868 // Attach actor to detector
870 GestureReceivedFunctor functor(data);
871 TapGestureDetector detector = TapGestureDetector::New();
872 detector.Attach(actor);
873 detector.DetectedSignal().Connect(&application, functor);
875 // Emit a possible - Down press, as emitted by long press function
876 TestStartLongPress(application, 50.0f, 10.0f, 100);
878 // Remove, render and delete actor
879 application.GetScene().Remove(actor);
880 application.SendNotification();
881 application.Render();
884 // Send a STARTED state, no signal - Up motion as provided by end pan function
885 TestEndPan(application, Vector2(50.0f, 10.0f), 120);
886 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
890 int UtcDaliTapGestureLayerConsumesTouch(void)
892 TestApplication application;
894 Actor actor = Actor::New();
895 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
896 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
897 application.GetScene().Add(actor);
901 GestureReceivedFunctor functor(data);
902 TapGestureDetector detector = TapGestureDetector::New();
903 detector.Attach(actor);
904 detector.DetectedSignal().Connect(&application, functor);
906 // Add a layer to overlap the actor
907 Layer layer = Layer::New();
908 layer.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
909 layer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
910 application.GetScene().Add(layer);
914 application.SendNotification();
915 application.Render();
917 // Emit signals, should receive
918 TestGenerateTap(application, 50.0f, 50.0f, 100);
919 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
922 // Set layer to consume all touch
923 layer.SetProperty(Layer::Property::CONSUMES_TOUCH, true);
926 application.SendNotification();
927 application.Render();
929 // Emit the same signals again, should not receive
930 TestGenerateTap(application, 50.0f, 50.0f, 700);
931 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
937 int UtcDaliTapGestureDisableDetectionDuringTapN(void)
939 // Crash sometimes occurred when gesture-recognizer was deleted internally during a signal when the attached actor was detached
941 TestApplication application;
943 Actor actor = Actor::New();
944 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
945 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
946 application.GetScene().Add(actor);
949 TapGestureDetector detector = TapGestureDetector::New();
950 bool functorCalled = false;
951 detector.Attach(actor);
952 detector.DetectedSignal().Connect(
954 [&detector, &functorCalled](Actor actor, const TapGesture& gesture) {
955 detector.Detach(actor);
956 functorCalled = true;
960 application.SendNotification();
961 application.Render();
963 // Try the gesture, should not crash
966 TestGenerateTap(application, 50.0f, 10.0f);
968 DALI_TEST_CHECK(true); // No crash, test has passed
969 DALI_TEST_EQUALS(functorCalled, true, TEST_LOCATION);
973 DALI_TEST_CHECK(false); // If we crash, the test has failed
979 int UtcDaliTapGestureWhenGesturePropargation(void)
981 TestApplication application;
983 Actor parentActor = Actor::New();
984 parentActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
985 parentActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
987 Actor childActor = Actor::New();
988 childActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
989 childActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
991 parentActor.Add(childActor);
992 application.GetScene().Add(parentActor);
995 application.SendNotification();
996 application.Render();
999 GestureReceivedFunctor pFunctor(pData);
1001 TapGestureDetector parentDetector = TapGestureDetector::New();
1002 parentDetector.Attach(parentActor);
1003 parentDetector.DetectedSignal().Connect(&application, pFunctor);
1006 GestureReceivedFunctor cFunctor(cData);
1008 TapGestureDetector childDetector = TapGestureDetector::New();
1009 childDetector.Attach(childActor);
1010 childDetector.DetectedSignal().Connect(&application, cFunctor);
1012 // Start gesture within the actor's area, we receive the gesture not parent actor but child actor.
1013 TestGenerateTap(application, 50.0f, 50.0f, 100);
1014 DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
1015 DALI_TEST_EQUALS(false, pData.functorCalled, TEST_LOCATION);
1019 // If GesturePropargation is set, a gesture event is delivered to the parent.
1020 Dali::DevelActor::SetNeedGesturePropagation(childActor, true);
1022 // So now the parent got the gesture event.
1023 TestGenerateTap(application, 50.0f, 50.0f, 700);
1024 DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
1025 DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION);
1032 int UtcDaliTapGestureGetSourceType(void)
1034 TestApplication application;
1036 Actor actor = Actor::New();
1037 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1038 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1039 application.GetScene().Add(actor);
1041 // Render and notify
1042 application.SendNotification();
1043 application.Render();
1046 GestureReceivedFunctor functor(data);
1048 TapGestureDetector detector = TapGestureDetector::New();
1049 detector.Attach(actor);
1050 detector.DetectedSignal().Connect(&application, functor);
1052 // Emit a down signal with MouseButton
1053 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 0, 100));
1054 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 0, 120));
1055 application.SendNotification();
1057 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1058 DALI_TEST_EQUALS(data.receivedGesture.GetSourceType(), GestureSourceType::INVALID, TEST_LOCATION);
1062 // Emit a down signal with MouseButton
1063 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 1, 700));
1064 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 1, 720));
1065 application.SendNotification();
1067 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1068 DALI_TEST_EQUALS(data.receivedGesture.GetSourceType(), GestureSourceType::PRIMARY, TEST_LOCATION);
1072 // Emit a down signal with MouseButton
1073 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 3, 1300));
1074 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 3, 1320));
1075 application.SendNotification();
1077 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1078 DALI_TEST_EQUALS(data.receivedGesture.GetSourceType(), GestureSourceType::SECONDARY, TEST_LOCATION);
1082 // Emit a down signal with MouseButton
1083 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 2, 1900));
1084 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 2, 1920));
1085 application.SendNotification();
1087 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1088 DALI_TEST_EQUALS(data.receivedGesture.GetSourceType(), GestureSourceType::TERTIARY, TEST_LOCATION);
1093 int UtcDaliTapGestureReceiveAllTapEvents(void)
1095 TestApplication application;
1097 Actor actor = Actor::New();
1098 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1099 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1101 application.GetScene().Add(actor);
1103 // Render and notify
1104 application.SendNotification();
1105 application.Render();
1108 GestureReceivedFunctor functor(data);
1110 TapGestureDetector detector = TapGestureDetector::New();
1111 detector.SetMaximumTapsRequired(2u);
1112 detector.Attach(actor);
1113 detector.DetectedSignal().Connect(&application, functor);
1115 // Emit signals, Because MaximumTapsRequired is 2, a timer that checks whether it is a single tap or a double tap operates internally.
1116 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 0, 100));
1117 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 0, 120));
1118 application.SendNotification();
1120 // So detector don't get the tap event yet.
1121 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1124 // Emit signals, Send the second tab.
1125 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 0, 130));
1126 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 0, 150));
1127 application.SendNotification();
1128 application.GetPlatform().TriggerTimer();
1130 // It find out to be a double tap. Detector receives events.
1131 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1134 // Detector want to receive all tap events.
1135 detector.ReceiveAllTapEvents(true);
1137 // Emit signals, should receive
1138 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 0, 500));
1139 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 0, 520));
1140 application.SendNotification();
1142 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1145 // Emit signals, should receive
1146 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 0, 530));
1147 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 0, 550));
1148 application.SendNotification();
1150 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1156 int UtcDaliTapGestureDoesWantedHitTest(void)
1158 TestApplication application;
1160 Actor blue = Actor::New();
1161 blue.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1162 blue.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1164 Actor green = Actor::New();
1165 green.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1166 green.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1168 application.GetScene().Add(blue);
1169 application.GetScene().Add(green);
1171 // Render and notify
1172 application.SendNotification();
1173 application.Render();
1175 SignalData blueData;
1176 GestureReceivedFunctor blueFunctor(blueData);
1178 TapGestureDetector blueDetector = TapGestureDetector::New();
1179 blueDetector.Attach(blue);
1180 blueDetector.DetectedSignal().Connect(&application, blueFunctor);
1182 SignalData greenData;
1183 GestureReceivedFunctor greenFunctor(greenData);
1185 TapGestureDetector greenDetector = TapGestureDetector::New();
1186 greenDetector.Attach(green);
1187 greenDetector.DetectedSignal().Connect(&application, greenFunctor);
1189 // connect to its hit-test signal
1190 gHitTestTouchCallBackCalled = false;
1191 Dali::DevelActor::HitTestResultSignal(green).Connect(TestHitTestTouchCallback);
1193 // Emit a down signal
1194 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 0, 100));
1195 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 0, 120));
1196 application.SendNotification();
1198 // check hit-test events
1199 // The green actor received an event that the green actor was hit.
1200 DALI_TEST_EQUALS(true, gHitTestTouchCallBackCalled, TEST_LOCATION);
1202 // The green actor passed the hit-test. So blue was the final hit.
1203 DALI_TEST_EQUALS(false, greenData.functorCalled, TEST_LOCATION);
1204 DALI_TEST_EQUALS(true, blueData.functorCalled, TEST_LOCATION);