2 * Copyright (c) 2023 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;
146 Integration::TouchEvent GenerateSingleMouse(PointState::Type state, const Vector2& screenPosition, int source, uint32_t time)
148 Integration::TouchEvent touchEvent;
149 Integration::Point point;
150 point.SetState(state);
151 point.SetDeviceId(4);
152 point.SetScreenPosition(screenPosition);
153 point.SetDeviceClass(Device::Class::MOUSE);
154 point.SetDeviceSubclass(Device::Subclass::NONE);
155 point.SetMouseButton(static_cast<MouseButton::Type>(source));
156 touchEvent.points.push_back(point);
157 touchEvent.time = time;
163 ///////////////////////////////////////////////////////////////////////////////
165 // Positive test case for a method
166 int UtcDaliTapGestureDetectorConstructor(void)
168 TestApplication application;
170 TapGestureDetector detector;
171 DALI_TEST_CHECK(!detector);
175 int UtcDaliTapGestureDetectorCopyConstructorP(void)
177 TestApplication application;
179 TapGestureDetector detector = TapGestureDetector::New();
181 TapGestureDetector copy(detector);
182 DALI_TEST_CHECK(detector);
186 int UtcDaliTapGestureDetectorAssignmentOperatorP(void)
188 TestApplication application;
190 TapGestureDetector detector = TapGestureDetector::New();
192 TapGestureDetector assign;
194 DALI_TEST_CHECK(detector);
196 DALI_TEST_CHECK(detector == assign);
200 int UtcDaliRTapGestureDetectorMoveConstructorP(void)
202 TestApplication application;
204 TapGestureDetector detector = TapGestureDetector::New();
205 DALI_TEST_CHECK(detector);
207 TapGestureDetector moved = std::move(detector);
208 DALI_TEST_CHECK(moved);
209 DALI_TEST_CHECK(!detector);
213 int UtcDaliTapGestureDetectorMoveAssignmentOperatorP(void)
215 TestApplication application;
217 TapGestureDetector detector;
218 detector = TapGestureDetector::New();
219 DALI_TEST_CHECK(detector);
221 TapGestureDetector moved;
222 moved = std::move(detector);
223 DALI_TEST_CHECK(moved);
224 DALI_TEST_CHECK(!detector);
228 int UtcDaliTapGestureDetectorNew(void)
230 TestApplication application;
232 TapGestureDetector detector = TapGestureDetector::New();
233 DALI_TEST_CHECK(detector);
234 DALI_TEST_EQUALS(1u, detector.GetMinimumTapsRequired(), TEST_LOCATION);
235 DALI_TEST_EQUALS(1u, detector.GetMaximumTapsRequired(), TEST_LOCATION);
237 TapGestureDetector detector2 = TapGestureDetector::New(5u);
238 DALI_TEST_CHECK(detector2);
239 DALI_TEST_EQUALS(5u, detector2.GetMinimumTapsRequired(), TEST_LOCATION);
240 DALI_TEST_EQUALS(5u, detector2.GetMaximumTapsRequired(), TEST_LOCATION);
242 //Scoped test to test destructor
244 TapGestureDetector detector3 = TapGestureDetector::New();
245 DALI_TEST_CHECK(detector3);
248 // Attach an actor and emit a touch event on the actor to ensure complete line coverage
249 Actor actor = Actor::New();
250 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
251 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
252 application.GetScene().Add(actor);
255 application.SendNotification();
256 application.Render();
258 detector.Attach(actor);
260 TouchEventFunctor touchFunctor;
261 actor.TouchedSignal().Connect(&application, touchFunctor);
263 Integration::TouchEvent touchEvent(1);
264 Integration::Point point;
265 point.SetDeviceId(1);
266 point.SetState(PointState::DOWN);
267 point.SetScreenPosition(Vector2(20.0f, 20.0f));
268 touchEvent.AddPoint(point);
269 application.ProcessEvent(touchEvent);
272 application.SendNotification();
273 application.Render();
278 int UtcDaliTapGestureDetectorDownCast(void)
280 TestApplication application;
281 tet_infoline("Testing Dali::TapGestureDetector::DownCast()");
283 TapGestureDetector detector = TapGestureDetector::New();
285 BaseHandle object(detector);
287 TapGestureDetector detector2 = TapGestureDetector::DownCast(object);
288 DALI_TEST_CHECK(detector2);
290 TapGestureDetector detector3 = DownCast<TapGestureDetector>(object);
291 DALI_TEST_CHECK(detector3);
293 BaseHandle unInitializedObject;
294 TapGestureDetector detector4 = TapGestureDetector::DownCast(unInitializedObject);
295 DALI_TEST_CHECK(!detector4);
297 TapGestureDetector detector5 = DownCast<TapGestureDetector>(unInitializedObject);
298 DALI_TEST_CHECK(!detector5);
300 GestureDetector detector6 = TapGestureDetector::New();
301 TapGestureDetector detector7 = TapGestureDetector::DownCast(detector6);
302 DALI_TEST_CHECK(detector7);
306 int UtcDaliTapGestureSetTapsRequiredMinMaxCheck(void)
308 TestApplication application;
310 // Attach an actor and change the required touches
312 Actor actor = Actor::New();
313 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
314 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
315 application.GetScene().Add(actor);
318 application.SendNotification();
319 application.Render();
321 // Set the minimum to be greater than the maximum, should Assert
325 TapGestureDetector detector = TapGestureDetector::New();
326 detector.SetMinimumTapsRequired(7u);
327 detector.SetMaximumTapsRequired(3u);
328 detector.Attach(actor);
329 DALI_TEST_CHECK(false); // Should not get here
331 catch(DaliException& e)
333 DALI_TEST_CHECK(true);
339 int UtcDaliTapGestureGetTapsRequired(void)
341 TestApplication application;
343 TapGestureDetector detector = TapGestureDetector::New();
344 DALI_TEST_EQUALS(1u, detector.GetMinimumTapsRequired(), TEST_LOCATION);
345 DALI_TEST_EQUALS(1u, detector.GetMaximumTapsRequired(), TEST_LOCATION);
349 int UtcDaliTapGestureSignalReceptionNegative(void)
351 TestApplication application;
353 Actor actor = Actor::New();
354 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
355 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
356 application.GetScene().Add(actor);
359 application.SendNotification();
360 application.Render();
363 GestureReceivedFunctor functor(data);
365 TapGestureDetector detector = TapGestureDetector::New();
366 detector.Attach(actor);
367 detector.DetectedSignal().Connect(&application, functor);
369 // Do a tap outside actor's area
370 TestGenerateTap(application, 112.0f, 112.0f, 100);
371 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
375 int UtcDaliTapGestureSignalReceptionPositive(void)
377 TestApplication application;
379 Actor actor = Actor::New();
380 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
381 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
382 application.GetScene().Add(actor);
385 application.SendNotification();
386 application.Render();
389 GestureReceivedFunctor functor(data);
391 TapGestureDetector detector = TapGestureDetector::New();
392 detector.Attach(actor);
393 detector.DetectedSignal().Connect(&application, functor);
395 // Do a tap inside actor's area
396 TestGenerateTap(application, 50.0f, 50.0f, 100);
397 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
398 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
399 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
400 DALI_TEST_EQUALS(Vector2(50.0f, 50.0f), data.receivedGesture.GetLocalPoint(), 0.1, TEST_LOCATION);
404 int UtcDaliTapGestureSignalReceptionDetach(void)
406 TestApplication application;
408 Actor actor = Actor::New();
409 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
410 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
411 application.GetScene().Add(actor);
414 application.SendNotification();
415 application.Render();
418 GestureReceivedFunctor functor(data);
420 TapGestureDetector detector = TapGestureDetector::New();
421 detector.Attach(actor);
422 detector.DetectedSignal().Connect(&application, functor);
424 // Start tap within the actor's area
425 TestGenerateTap(application, 20.0f, 20.0f, 100);
426 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
427 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
428 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
429 DALI_TEST_EQUALS(Vector2(20.0f, 20.0f), data.receivedGesture.GetLocalPoint(), 0.1, TEST_LOCATION);
431 // repeat the tap within the actor's area - we should still receive the signal
433 TestGenerateTap(application, 50.0f, 50.0f, 700);
434 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
435 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
436 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
437 DALI_TEST_EQUALS(Vector2(50.0f, 50.0f), data.receivedGesture.GetLocalPoint(), 0.1, TEST_LOCATION);
440 detector.DetachAll();
442 // Ensure we are no longer signalled
444 TestGenerateTap(application, 20.0f, 20.0f, 1300);
445 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
446 TestGenerateTap(application, 50.0f, 50.0f, 1900);
447 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
451 int UtcDaliTapGestureSignalReceptionActorDestroyedWhileTapping(void)
453 TestApplication application;
456 GestureReceivedFunctor functor(data);
458 TapGestureDetector detector = TapGestureDetector::New();
459 detector.DetectedSignal().Connect(&application, functor);
461 // Actor lifetime is scoped
463 Actor actor = Actor::New();
464 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
465 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
466 application.GetScene().Add(actor);
469 application.SendNotification();
470 application.Render();
472 detector.Attach(actor);
474 // Start tap within the actor's area
475 TestGenerateTap(application, 20.0f, 20.0f, 100);
476 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
478 // Remove the actor from stage and reset the data
479 application.GetScene().Remove(actor);
482 application.SendNotification();
483 application.Render();
486 // Actor should now have been destroyed
489 TestGenerateTap(application, 20.0f, 20.0f, 700);
490 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
494 int UtcDaliTapGestureSignalReceptionRotatedActor(void)
496 TestApplication application;
498 Actor actor = Actor::New();
499 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
500 actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(90.0f), Vector3::ZAXIS));
501 application.GetScene().Add(actor);
504 application.SendNotification();
505 application.Render();
508 GestureReceivedFunctor functor(data);
510 TapGestureDetector detector = TapGestureDetector::New();
511 detector.Attach(actor);
512 detector.DetectedSignal().Connect(&application, functor);
514 // Do tap, only check finished value
515 TestGenerateTap(application, 5.0f, 5.0f, 100);
516 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
517 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
518 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
519 DALI_TEST_EQUALS(Vector2(5.0f, 5.0f), data.receivedGesture.GetScreenPoint(), 0.1, TEST_LOCATION);
521 // Rotate actor again and render
522 actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(180.0f), Vector3::ZAXIS));
523 application.SendNotification();
524 application.Render();
526 // Do tap, should still receive event
528 TestGenerateTap(application, 5.0f, 5.0f, 700);
529 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
530 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
531 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
532 DALI_TEST_EQUALS(Vector2(5.0f, 5.0f), data.receivedGesture.GetScreenPoint(), 0.1, TEST_LOCATION);
534 // Rotate actor again and render
535 actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(90.0f), Vector3::YAXIS));
536 application.SendNotification();
537 application.Render();
539 // Do tap, inside the actor's area (area if it is not rotated), Should not receive the event
541 TestGenerateTap(application, 70.0f, 70.0f, 1300);
542 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
546 int UtcDaliTapGestureSignalReceptionChildHit(void)
548 TestApplication application;
550 Actor parent = Actor::New();
551 parent.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
552 parent.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
553 application.GetScene().Add(parent);
555 // Set child to completely cover parent.
556 // Change rotation of child to be different from parent so that we can check if our local coordinate
557 // conversion of the parent actor is correct.
558 Actor child = Actor::New();
559 child.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
560 child.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
561 child.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
562 child.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(90.0f), Vector3::ZAXIS));
565 TouchEventFunctor touchFunctor;
566 child.TouchedSignal().Connect(&application, touchFunctor);
569 application.SendNotification();
570 application.Render();
573 GestureReceivedFunctor functor(data);
575 TapGestureDetector detector = TapGestureDetector::New();
576 detector.Attach(parent);
577 detector.DetectedSignal().Connect(&application, functor);
579 // Do tap - hits child area but parent should still receive it
580 TestGenerateTap(application, 50.0f, 50.0f, 100);
581 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
582 DALI_TEST_EQUALS(true, parent == data.tappedActor, TEST_LOCATION);
583 DALI_TEST_EQUALS(Vector2(50.0f, 50.0f), data.receivedGesture.GetScreenPoint(), 0.01f, TEST_LOCATION);
585 // Attach child and generate same touch points
586 // (Also proves that you can detach and then re-attach another actor)
587 detector.Attach(child);
588 detector.Detach(parent);
590 // Do an entire tap, only check finished value
592 TestGenerateTap(application, 51.0f, 51.0f, 700);
593 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
594 DALI_TEST_EQUALS(true, child == data.tappedActor, TEST_LOCATION);
595 DALI_TEST_EQUALS(Vector2(51.0f, 51.0f), data.receivedGesture.GetScreenPoint(), 0.01f, TEST_LOCATION);
599 int UtcDaliTapGestureSignalReceptionAttachDetachMany(void)
601 TestApplication application;
603 Actor first = Actor::New();
604 first.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
605 first.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
606 application.GetScene().Add(first);
608 Actor second = Actor::New();
609 second.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
610 second.SetProperty(Actor::Property::POSITION_X, 100.0f);
611 second.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
612 application.GetScene().Add(second);
615 application.SendNotification();
616 application.Render();
619 GestureReceivedFunctor functor(data);
621 TapGestureDetector detector = TapGestureDetector::New();
622 detector.Attach(first);
623 detector.Attach(second);
624 detector.DetectedSignal().Connect(&application, functor);
626 // Tap within second actor's area
627 TestGenerateTap(application, 120.0f, 10.0f, 100);
628 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
629 DALI_TEST_EQUALS(true, second == data.tappedActor, TEST_LOCATION);
631 // Tap within first actor's area
633 TestGenerateTap(application, 20.0f, 10.0f, 700);
634 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
635 DALI_TEST_EQUALS(true, first == data.tappedActor, TEST_LOCATION);
637 // Detach the second actor
638 detector.Detach(second);
640 // second actor shouldn't receive event
642 TestGenerateTap(application, 120.0f, 10.0f, 1300);
643 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
645 // first actor should continue receiving event
647 TestGenerateTap(application, 20.0f, 10.0f, 1900);
648 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
652 int UtcDaliTapGestureSignalReceptionActorBecomesUntouchable(void)
654 TestApplication application;
656 Actor actor = Actor::New();
657 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
658 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
659 application.GetScene().Add(actor);
662 application.SendNotification();
663 application.Render();
666 GestureReceivedFunctor functor(data);
668 TapGestureDetector detector = TapGestureDetector::New();
669 detector.Attach(actor);
670 detector.DetectedSignal().Connect(&application, functor);
672 // Tap in actor's area
673 TestGenerateTap(application, 50.0f, 10.0f, 100);
674 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
676 // Actor become invisible - actor should not receive the next pan
677 actor.SetProperty(Actor::Property::VISIBLE, false);
680 application.SendNotification();
681 application.Render();
683 // Tap in the same area, shouldn't receive event
685 TestGenerateTap(application, 50.0f, 10.0f, 700);
686 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
690 int UtcDaliTapGestureSignalReceptionMultipleGestureDetectors(void)
692 TestApplication application;
694 Actor first = Actor::New();
695 first.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
696 first.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
697 application.GetScene().Add(first);
699 Actor second = Actor::New();
700 second.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
701 second.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
702 second.SetProperty(Actor::Property::POSITION_X, 100.0f);
706 application.SendNotification();
707 application.Render();
710 GestureReceivedFunctor functor(data);
712 TapGestureDetector firstDetector = TapGestureDetector::New();
713 firstDetector.Attach(first);
714 firstDetector.DetectedSignal().Connect(&application, functor);
716 // secondDetector is scoped
718 TapGestureDetector secondDetector = TapGestureDetector::New(2);
719 secondDetector.Attach(second);
720 secondDetector.DetectedSignal().Connect(&application, functor);
722 // Tap within second actor's area
723 TestGenerateTap(application, 150.0f, 10.0f, 100);
724 TestGenerateTap(application, 150.0f, 10.0f, 200);
726 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
727 DALI_TEST_EQUALS(true, second == data.tappedActor, TEST_LOCATION);
729 // Tap continues as single touch gesture - we should not receive any gesture
731 TestGenerateTap(application, 150.0f, 10.0f, 800);
732 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
734 // Single touch tap starts - first actor should be panned
736 TestGenerateTap(application, 50.0f, 10.0f, 1400);
737 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
738 DALI_TEST_EQUALS(true, first == data.tappedActor, TEST_LOCATION);
740 // Tap changes to double-touch - we shouldn't receive event
743 TestGenerateTwoPointTap(application, 50.0f, 10.0f, 60.0f, 20.0f, 2000);
745 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
751 int UtcDaliTapGestureSignalReceptionMultipleDetectorsOnActor(void)
753 TestApplication application;
755 Actor actor = Actor::New();
756 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
757 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
758 application.GetScene().Add(actor);
761 application.SendNotification();
762 application.Render();
764 // Attach actor to one detector
765 SignalData firstData;
766 GestureReceivedFunctor firstFunctor(firstData);
767 TapGestureDetector firstDetector = TapGestureDetector::New();
768 firstDetector.Attach(actor);
769 firstDetector.DetectedSignal().Connect(&application, firstFunctor);
771 // Attach actor to another detector
772 SignalData secondData;
773 GestureReceivedFunctor secondFunctor(secondData);
774 TapGestureDetector secondDetector = TapGestureDetector::New();
775 secondDetector.Attach(actor);
776 secondDetector.DetectedSignal().Connect(&application, secondFunctor);
778 // Tap in actor's area - both detector's functors should be called
779 TestGenerateTap(application, 50.0f, 10.0f, 100);
780 DALI_TEST_EQUALS(true, firstData.functorCalled, TEST_LOCATION);
781 DALI_TEST_EQUALS(true, secondData.functorCalled, TEST_LOCATION);
785 int UtcDaliTapGestureSignalReceptionDifferentPossible(void)
787 TestApplication application;
789 Actor actor = Actor::New();
790 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
791 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
792 application.GetScene().Add(actor);
795 application.SendNotification();
796 application.Render();
798 // Attach actor to detector
800 GestureReceivedFunctor functor(data);
801 TapGestureDetector detector = TapGestureDetector::New();
802 detector.Attach(actor);
803 detector.DetectedSignal().Connect(&application, functor);
805 // Gesture possible in actor's area.
806 TestStartLongPress(application, 50.0f, 10.0f, 100);
807 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
809 // Move actor somewhere else
810 actor.SetProperty(Actor::Property::POSITION, Vector2(100.0f, 100.0f));
813 application.SendNotification();
814 application.Render();
816 // Emit STARTED event, we should not receive the tap.
817 TestEndPan(application, Vector2(50.0f, 10.0f), 120);
818 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
820 // Tap possible in empty area.
821 TestStartLongPress(application, 50.0f, 10.0f, 700);
822 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
824 // Move actor in to the tap position.
825 actor.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f));
828 application.SendNotification();
829 application.Render();
831 // Emit STARTED event, we should not receive the tap.
832 TestEndPan(application, Vector2(50.0f, 10.0f), 720);
833 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
835 // Normal tap in actor's area for completeness.
836 TestGenerateTap(application, 50.0f, 10.0f, 1300);
837 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
841 int UtcDaliTapGestureActorUnstaged(void)
843 TestApplication application;
845 Actor actor = Actor::New();
846 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
847 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
848 application.GetScene().Add(actor);
851 application.SendNotification();
852 application.Render();
854 // Attach actor to detector
856 UnstageActorFunctor functor(data, application.GetScene());
857 TapGestureDetector detector = TapGestureDetector::New();
858 detector.Attach(actor);
859 detector.DetectedSignal().Connect(&application, functor);
861 TestGenerateTap(application, 50.0f, 10.0f, 100);
862 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
863 tet_result(TET_PASS); // If we get here, then the actor removal on signal handler was handled gracefully.
867 int UtcDaliTapGestureDetectorRemovedWhilePossible(void)
869 TestApplication application;
871 Actor actor = Actor::New();
872 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
873 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
874 application.GetScene().Add(actor);
877 application.SendNotification();
878 application.Render();
880 // Attach actor to detector
882 GestureReceivedFunctor functor(data);
883 TapGestureDetector detector = TapGestureDetector::New();
884 detector.Attach(actor);
885 detector.DetectedSignal().Connect(&application, functor);
887 // Emit a possible - Down press, as emitted by long press function
888 TestStartLongPress(application, 50.0f, 10.0f, 100);
890 // Detach actor and send a STARTED state, no signal.
891 detector.DetachAll();
892 TestEndPan(application, Vector2(50.0f, 10.0f), 120);
893 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
897 int UtcDaliTapGestureActorRemovedWhilePossible(void)
899 TestApplication application;
901 Actor actor = Actor::New();
902 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
903 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
904 application.GetScene().Add(actor);
907 application.SendNotification();
908 application.Render();
910 // Attach actor to detector
912 GestureReceivedFunctor functor(data);
913 TapGestureDetector detector = TapGestureDetector::New();
914 detector.Attach(actor);
915 detector.DetectedSignal().Connect(&application, functor);
917 // Emit a possible - Down press, as emitted by long press function
918 TestStartLongPress(application, 50.0f, 10.0f, 100);
920 // Remove, render and delete actor
921 application.GetScene().Remove(actor);
922 application.SendNotification();
923 application.Render();
926 // Send a STARTED state, no signal - Up motion as provided by end pan function
927 TestEndPan(application, Vector2(50.0f, 10.0f), 120);
928 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
932 int UtcDaliTapGestureLayerConsumesTouch(void)
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);
943 GestureReceivedFunctor functor(data);
944 TapGestureDetector detector = TapGestureDetector::New();
945 detector.Attach(actor);
946 detector.DetectedSignal().Connect(&application, functor);
948 // Add a layer to overlap the actor
949 Layer layer = Layer::New();
950 layer.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
951 layer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
952 application.GetScene().Add(layer);
956 application.SendNotification();
957 application.Render();
959 // Emit signals, should receive
960 TestGenerateTap(application, 50.0f, 50.0f, 100);
961 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
964 // Set layer to consume all touch
965 layer.SetProperty(Layer::Property::CONSUMES_TOUCH, true);
968 application.SendNotification();
969 application.Render();
971 // Emit the same signals again, should not receive
972 TestGenerateTap(application, 50.0f, 50.0f, 700);
973 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
979 int UtcDaliTapGestureDisableDetectionDuringTapN(void)
981 // Crash sometimes occurred when gesture-recognizer was deleted internally during a signal when the attached actor was detached
983 TestApplication application;
985 Actor actor = Actor::New();
986 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
987 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
988 application.GetScene().Add(actor);
991 TapGestureDetector detector = TapGestureDetector::New();
992 bool functorCalled = false;
993 detector.Attach(actor);
994 detector.DetectedSignal().Connect(
996 [&detector, &functorCalled](Actor actor, const TapGesture& gesture) {
997 detector.Detach(actor);
998 functorCalled = true;
1001 // Render and notify
1002 application.SendNotification();
1003 application.Render();
1005 // Try the gesture, should not crash
1008 TestGenerateTap(application, 50.0f, 10.0f);
1010 DALI_TEST_CHECK(true); // No crash, test has passed
1011 DALI_TEST_EQUALS(functorCalled, true, TEST_LOCATION);
1015 DALI_TEST_CHECK(false); // If we crash, the test has failed
1021 int UtcDaliTapGestureWhenGesturePropargation(void)
1023 TestApplication application;
1025 Actor parentActor = Actor::New();
1026 parentActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1027 parentActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1029 Actor childActor = Actor::New();
1030 childActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1031 childActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1033 parentActor.Add(childActor);
1034 application.GetScene().Add(parentActor);
1036 // Render and notify
1037 application.SendNotification();
1038 application.Render();
1041 GestureReceivedFunctor pFunctor(pData);
1043 TapGestureDetector parentDetector = TapGestureDetector::New();
1044 parentDetector.Attach(parentActor);
1045 parentDetector.DetectedSignal().Connect(&application, pFunctor);
1048 GestureReceivedFunctor cFunctor(cData);
1050 TapGestureDetector childDetector = TapGestureDetector::New();
1051 childDetector.Attach(childActor);
1052 childDetector.DetectedSignal().Connect(&application, cFunctor);
1054 // Start gesture within the actor's area, we receive the gesture not parent actor but child actor.
1055 TestGenerateTap(application, 50.0f, 50.0f, 100);
1056 DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
1057 DALI_TEST_EQUALS(false, pData.functorCalled, TEST_LOCATION);
1061 // If GesturePropargation is set, a gesture event is delivered to the parent.
1062 Dali::DevelActor::SetNeedGesturePropagation(childActor, true);
1064 // So now the parent got the gesture event.
1065 TestGenerateTap(application, 50.0f, 50.0f, 700);
1066 DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
1067 DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION);
1074 int UtcDaliTapGestureGetSourceTypeWithMouse(void)
1076 TestApplication application;
1078 Actor actor = Actor::New();
1079 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1080 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1081 application.GetScene().Add(actor);
1083 // Render and notify
1084 application.SendNotification();
1085 application.Render();
1088 GestureReceivedFunctor functor(data);
1090 TapGestureDetector detector = TapGestureDetector::New();
1091 detector.Attach(actor);
1092 detector.DetectedSignal().Connect(&application, functor);
1094 // Emit a down signal with MouseButton
1095 application.ProcessEvent(GenerateSingleMouse(PointState::DOWN, Vector2(20.0f, 20.0f), 1, 100));
1096 application.ProcessEvent(GenerateSingleMouse(PointState::UP, Vector2(20.0f, 20.0f), 1, 120));
1097 application.SendNotification();
1099 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1100 DALI_TEST_EQUALS(data.receivedGesture.GetSourceType(), GestureSourceType::MOUSE, TEST_LOCATION);
1101 DALI_TEST_EQUALS(data.receivedGesture.GetSourceData(), GestureSourceData::MOUSE_PRIMARY, TEST_LOCATION);
1105 // Emit a down signal with MouseButton
1106 application.ProcessEvent(GenerateSingleMouse(PointState::DOWN, Vector2(20.0f, 20.0f), 3, 1300));
1107 application.ProcessEvent(GenerateSingleMouse(PointState::UP, Vector2(20.0f, 20.0f), 3, 1320));
1108 application.SendNotification();
1110 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1111 DALI_TEST_EQUALS(data.receivedGesture.GetSourceType(), GestureSourceType::MOUSE, TEST_LOCATION);
1112 DALI_TEST_EQUALS(data.receivedGesture.GetSourceData(), GestureSourceData::MOUSE_SECONDARY, TEST_LOCATION);
1116 // Emit a down signal with MouseButton
1117 application.ProcessEvent(GenerateSingleMouse(PointState::DOWN, Vector2(20.0f, 20.0f), 2, 1900));
1118 application.ProcessEvent(GenerateSingleMouse(PointState::UP, Vector2(20.0f, 20.0f), 2, 1920));
1119 application.SendNotification();
1121 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1122 DALI_TEST_EQUALS(data.receivedGesture.GetSourceType(), GestureSourceType::MOUSE, TEST_LOCATION);
1123 DALI_TEST_EQUALS(data.receivedGesture.GetSourceData(), GestureSourceData::MOUSE_TERTIARY, TEST_LOCATION);
1128 int UtcDaliTapGestureGetSourceTypeWithTouch(void)
1130 TestApplication application;
1132 Actor actor = Actor::New();
1133 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1134 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1135 application.GetScene().Add(actor);
1137 // Render and notify
1138 application.SendNotification();
1139 application.Render();
1142 GestureReceivedFunctor functor(data);
1144 TapGestureDetector detector = TapGestureDetector::New();
1145 detector.Attach(actor);
1146 detector.DetectedSignal().Connect(&application, functor);
1148 // Emit a down signal with touch
1149 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 1, 100));
1150 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 1, 120));
1151 application.SendNotification();
1153 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1154 DALI_TEST_EQUALS(data.receivedGesture.GetSourceType(), GestureSourceType::TOUCH, TEST_LOCATION);
1161 int UtcDaliTapGestureReceiveAllTapEvents(void)
1163 TestApplication application;
1165 Actor actor = Actor::New();
1166 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1167 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1169 application.GetScene().Add(actor);
1171 // Render and notify
1172 application.SendNotification();
1173 application.Render();
1176 GestureReceivedFunctor functor(data);
1178 TapGestureDetector detector = TapGestureDetector::New();
1179 detector.SetMaximumTapsRequired(2u);
1180 detector.Attach(actor);
1181 detector.DetectedSignal().Connect(&application, functor);
1183 // Emit signals, Because MaximumTapsRequired is 2, a timer that checks whether it is a single tap or a double tap operates internally.
1184 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 0, 100));
1185 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 0, 120));
1186 application.SendNotification();
1188 // So detector don't get the tap event yet.
1189 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1192 // Emit signals, Send the second tab.
1193 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 0, 130));
1194 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 0, 150));
1195 application.SendNotification();
1196 application.GetPlatform().TriggerTimer();
1198 // It find out to be a double tap. Detector receives events.
1199 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1202 // Detector want to receive all tap events.
1203 detector.ReceiveAllTapEvents(true);
1205 // Emit signals, should receive
1206 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 0, 500));
1207 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 0, 520));
1208 application.SendNotification();
1210 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1213 // Emit signals, should receive
1214 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 0, 530));
1215 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 0, 550));
1216 application.SendNotification();
1218 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1224 int UtcDaliTapGestureDoesWantedHitTest(void)
1226 TestApplication application;
1228 Actor blue = Actor::New();
1229 blue.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1230 blue.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1232 Actor green = Actor::New();
1233 green.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1234 green.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1236 application.GetScene().Add(blue);
1237 application.GetScene().Add(green);
1239 // Render and notify
1240 application.SendNotification();
1241 application.Render();
1243 SignalData blueData;
1244 GestureReceivedFunctor blueFunctor(blueData);
1246 TapGestureDetector blueDetector = TapGestureDetector::New();
1247 blueDetector.Attach(blue);
1248 blueDetector.DetectedSignal().Connect(&application, blueFunctor);
1250 SignalData greenData;
1251 GestureReceivedFunctor greenFunctor(greenData);
1253 TapGestureDetector greenDetector = TapGestureDetector::New();
1254 greenDetector.Attach(green);
1255 greenDetector.DetectedSignal().Connect(&application, greenFunctor);
1257 // connect to its hit-test signal
1258 gHitTestTouchCallBackCalled = false;
1259 Dali::DevelActor::HitTestResultSignal(green).Connect(TestHitTestTouchCallback);
1261 // Emit a down signal
1262 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 0, 100));
1263 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 0, 120));
1264 application.SendNotification();
1266 // check hit-test events
1267 // The green actor received an event that the green actor was hit.
1268 DALI_TEST_EQUALS(true, gHitTestTouchCallBackCalled, TEST_LOCATION);
1270 // The green actor passed the hit-test. So blue was the final hit.
1271 DALI_TEST_EQUALS(false, greenData.functorCalled, TEST_LOCATION);
1272 DALI_TEST_EQUALS(true, blueData.functorCalled, TEST_LOCATION);
1280 int UtcDaliTapGestureDetectorCheck(void)
1282 TestApplication application;
1284 Actor actor = Actor::New();
1285 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1286 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1287 application.GetScene().Add(actor);
1289 Actor actor2 = Actor::New();
1290 actor2.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1291 actor2.SetProperty(Actor::Property::POSITION, Vector2(100.0f, 100.0f));
1292 actor2.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1293 application.GetScene().Add(actor2);
1295 // Render and notify
1296 application.SendNotification();
1297 application.Render();
1300 GestureReceivedFunctor functor(data);
1301 TapGestureDetector detector1 = TapGestureDetector::New();
1302 detector1.SetMaximumTapsRequired(1u);
1303 detector1.Attach(actor);
1304 detector1.DetectedSignal().Connect(&application, functor);
1306 TapGestureDetector detector2 = TapGestureDetector::New();
1307 detector2.SetMaximumTapsRequired(2u);
1308 detector2.Attach(actor2);
1310 // Emit signals, Send the single tab.
1311 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 0, 100));
1312 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 0, 120));
1313 application.SendNotification();
1315 // The detector1 get the tap event.
1316 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1319 // Emit signals, Send the second tab.
1320 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 0, 130));
1321 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 0, 150));
1322 application.SendNotification();
1324 // The detector1 must get the tap event. SetMaximumTapsRequired(2u) of detector2 should not affect detector1.
1325 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);