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();
177 TapGestureDetector assign;
179 DALI_TEST_CHECK(detector);
181 DALI_TEST_CHECK(detector == assign);
185 int UtcDaliRTapGestureDetectorMoveConstructorP(void)
187 TestApplication application;
189 TapGestureDetector detector = TapGestureDetector::New();
190 DALI_TEST_CHECK(detector);
192 TapGestureDetector moved = std::move(detector);
193 DALI_TEST_CHECK(moved);
194 DALI_TEST_CHECK(!detector);
198 int UtcDaliTapGestureDetectorMoveAssignmentOperatorP(void)
200 TestApplication application;
202 TapGestureDetector detector;
203 detector = TapGestureDetector::New();
204 DALI_TEST_CHECK(detector);
206 TapGestureDetector moved;
207 moved = std::move(detector);
208 DALI_TEST_CHECK(moved);
209 DALI_TEST_CHECK(!detector);
213 int UtcDaliTapGestureDetectorNew(void)
215 TestApplication application;
217 TapGestureDetector detector = TapGestureDetector::New();
218 DALI_TEST_CHECK(detector);
219 DALI_TEST_EQUALS(1u, detector.GetMinimumTapsRequired(), TEST_LOCATION);
220 DALI_TEST_EQUALS(1u, detector.GetMaximumTapsRequired(), TEST_LOCATION);
222 TapGestureDetector detector2 = TapGestureDetector::New(5u);
223 DALI_TEST_CHECK(detector2);
224 DALI_TEST_EQUALS(5u, detector2.GetMinimumTapsRequired(), TEST_LOCATION);
225 DALI_TEST_EQUALS(5u, detector2.GetMaximumTapsRequired(), TEST_LOCATION);
227 //Scoped test to test destructor
229 TapGestureDetector detector3 = TapGestureDetector::New();
230 DALI_TEST_CHECK(detector3);
233 // Attach an actor and emit a touch event on the actor to ensure complete line coverage
234 Actor actor = Actor::New();
235 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
236 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
237 application.GetScene().Add(actor);
240 application.SendNotification();
241 application.Render();
243 detector.Attach(actor);
245 TouchEventFunctor touchFunctor;
246 actor.TouchedSignal().Connect(&application, touchFunctor);
248 Integration::TouchEvent touchEvent(1);
249 Integration::Point point;
250 point.SetDeviceId(1);
251 point.SetState(PointState::DOWN);
252 point.SetScreenPosition(Vector2(20.0f, 20.0f));
253 touchEvent.AddPoint(point);
254 application.ProcessEvent(touchEvent);
257 application.SendNotification();
258 application.Render();
263 int UtcDaliTapGestureDetectorDownCast(void)
265 TestApplication application;
266 tet_infoline("Testing Dali::TapGestureDetector::DownCast()");
268 TapGestureDetector detector = TapGestureDetector::New();
270 BaseHandle object(detector);
272 TapGestureDetector detector2 = TapGestureDetector::DownCast(object);
273 DALI_TEST_CHECK(detector2);
275 TapGestureDetector detector3 = DownCast<TapGestureDetector>(object);
276 DALI_TEST_CHECK(detector3);
278 BaseHandle unInitializedObject;
279 TapGestureDetector detector4 = TapGestureDetector::DownCast(unInitializedObject);
280 DALI_TEST_CHECK(!detector4);
282 TapGestureDetector detector5 = DownCast<TapGestureDetector>(unInitializedObject);
283 DALI_TEST_CHECK(!detector5);
285 GestureDetector detector6 = TapGestureDetector::New();
286 TapGestureDetector detector7 = TapGestureDetector::DownCast(detector6);
287 DALI_TEST_CHECK(detector7);
291 int UtcDaliTapGestureSetTapsRequiredMinMaxCheck(void)
293 TestApplication application;
295 // Attach an actor and change the required touches
297 Actor actor = Actor::New();
298 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
299 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
300 application.GetScene().Add(actor);
303 application.SendNotification();
304 application.Render();
306 // Set the minimum to be greater than the maximum, should Assert
310 TapGestureDetector detector = TapGestureDetector::New();
311 detector.SetMinimumTapsRequired(7u);
312 detector.SetMaximumTapsRequired(3u);
313 detector.Attach(actor);
314 DALI_TEST_CHECK(false); // Should not get here
316 catch(DaliException& e)
318 DALI_TEST_CHECK(true);
324 int UtcDaliTapGestureGetTapsRequired(void)
326 TestApplication application;
328 TapGestureDetector detector = TapGestureDetector::New();
329 DALI_TEST_EQUALS(1u, detector.GetMinimumTapsRequired(), TEST_LOCATION);
330 DALI_TEST_EQUALS(1u, detector.GetMaximumTapsRequired(), TEST_LOCATION);
334 int UtcDaliTapGestureSignalReceptionNegative(void)
336 TestApplication application;
338 Actor actor = Actor::New();
339 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
340 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
341 application.GetScene().Add(actor);
344 application.SendNotification();
345 application.Render();
348 GestureReceivedFunctor functor(data);
350 TapGestureDetector detector = TapGestureDetector::New();
351 detector.Attach(actor);
352 detector.DetectedSignal().Connect(&application, functor);
354 // Do a tap outside actor's area
355 TestGenerateTap(application, 112.0f, 112.0f, 100);
356 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
360 int UtcDaliTapGestureSignalReceptionPositive(void)
362 TestApplication application;
364 Actor actor = Actor::New();
365 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
366 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
367 application.GetScene().Add(actor);
370 application.SendNotification();
371 application.Render();
374 GestureReceivedFunctor functor(data);
376 TapGestureDetector detector = TapGestureDetector::New();
377 detector.Attach(actor);
378 detector.DetectedSignal().Connect(&application, functor);
380 // Do a tap inside actor's area
381 TestGenerateTap(application, 50.0f, 50.0f, 100);
382 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
383 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
384 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
385 DALI_TEST_EQUALS(Vector2(50.0f, 50.0f), data.receivedGesture.GetLocalPoint(), 0.1, TEST_LOCATION);
389 int UtcDaliTapGestureSignalReceptionDetach(void)
391 TestApplication application;
393 Actor actor = Actor::New();
394 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
395 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
396 application.GetScene().Add(actor);
399 application.SendNotification();
400 application.Render();
403 GestureReceivedFunctor functor(data);
405 TapGestureDetector detector = TapGestureDetector::New();
406 detector.Attach(actor);
407 detector.DetectedSignal().Connect(&application, functor);
409 // Start tap within the actor's area
410 TestGenerateTap(application, 20.0f, 20.0f, 100);
411 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
412 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
413 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
414 DALI_TEST_EQUALS(Vector2(20.0f, 20.0f), data.receivedGesture.GetLocalPoint(), 0.1, TEST_LOCATION);
416 // repeat the tap within the actor's area - we should still receive the signal
418 TestGenerateTap(application, 50.0f, 50.0f, 700);
419 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
420 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
421 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
422 DALI_TEST_EQUALS(Vector2(50.0f, 50.0f), data.receivedGesture.GetLocalPoint(), 0.1, TEST_LOCATION);
425 detector.DetachAll();
427 // Ensure we are no longer signalled
429 TestGenerateTap(application, 20.0f, 20.0f, 1300);
430 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
431 TestGenerateTap(application, 50.0f, 50.0f, 1900);
432 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
436 int UtcDaliTapGestureSignalReceptionActorDestroyedWhileTapping(void)
438 TestApplication application;
441 GestureReceivedFunctor functor(data);
443 TapGestureDetector detector = TapGestureDetector::New();
444 detector.DetectedSignal().Connect(&application, functor);
446 // Actor lifetime is scoped
448 Actor actor = Actor::New();
449 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
450 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
451 application.GetScene().Add(actor);
454 application.SendNotification();
455 application.Render();
457 detector.Attach(actor);
459 // Start tap within the actor's area
460 TestGenerateTap(application, 20.0f, 20.0f, 100);
461 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
463 // Remove the actor from stage and reset the data
464 application.GetScene().Remove(actor);
467 application.SendNotification();
468 application.Render();
471 // Actor should now have been destroyed
474 TestGenerateTap(application, 20.0f, 20.0f, 700);
475 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
479 int UtcDaliTapGestureSignalReceptionRotatedActor(void)
481 TestApplication application;
483 Actor actor = Actor::New();
484 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
485 actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(90.0f), Vector3::ZAXIS));
486 application.GetScene().Add(actor);
489 application.SendNotification();
490 application.Render();
493 GestureReceivedFunctor functor(data);
495 TapGestureDetector detector = TapGestureDetector::New();
496 detector.Attach(actor);
497 detector.DetectedSignal().Connect(&application, functor);
499 // Do tap, only check finished value
500 TestGenerateTap(application, 5.0f, 5.0f, 100);
501 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
502 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
503 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
504 DALI_TEST_EQUALS(Vector2(5.0f, 5.0f), data.receivedGesture.GetScreenPoint(), 0.1, TEST_LOCATION);
506 // Rotate actor again and render
507 actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(180.0f), Vector3::ZAXIS));
508 application.SendNotification();
509 application.Render();
511 // Do tap, should still receive event
513 TestGenerateTap(application, 5.0f, 5.0f, 700);
514 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
515 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTaps(), TEST_LOCATION);
516 DALI_TEST_EQUALS(1u, data.receivedGesture.GetNumberOfTouches(), TEST_LOCATION);
517 DALI_TEST_EQUALS(Vector2(5.0f, 5.0f), data.receivedGesture.GetScreenPoint(), 0.1, TEST_LOCATION);
519 // Rotate actor again and render
520 actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(90.0f), Vector3::YAXIS));
521 application.SendNotification();
522 application.Render();
524 // Do tap, inside the actor's area (area if it is not rotated), Should not receive the event
526 TestGenerateTap(application, 70.0f, 70.0f, 1300);
527 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
531 int UtcDaliTapGestureSignalReceptionChildHit(void)
533 TestApplication application;
535 Actor parent = Actor::New();
536 parent.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
537 parent.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
538 application.GetScene().Add(parent);
540 // Set child to completely cover parent.
541 // Change rotation of child to be different from parent so that we can check if our local coordinate
542 // conversion of the parent actor is correct.
543 Actor child = Actor::New();
544 child.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
545 child.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
546 child.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
547 child.SetProperty(Actor::Property::ORIENTATION, Quaternion(Dali::Degree(90.0f), Vector3::ZAXIS));
550 TouchEventFunctor touchFunctor;
551 child.TouchedSignal().Connect(&application, touchFunctor);
554 application.SendNotification();
555 application.Render();
558 GestureReceivedFunctor functor(data);
560 TapGestureDetector detector = TapGestureDetector::New();
561 detector.Attach(parent);
562 detector.DetectedSignal().Connect(&application, functor);
564 // Do tap - hits child area but parent should still receive it
565 TestGenerateTap(application, 50.0f, 50.0f, 100);
566 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
567 DALI_TEST_EQUALS(true, parent == data.tappedActor, TEST_LOCATION);
568 DALI_TEST_EQUALS(Vector2(50.0f, 50.0f), data.receivedGesture.GetScreenPoint(), 0.01f, TEST_LOCATION);
570 // Attach child and generate same touch points
571 // (Also proves that you can detach and then re-attach another actor)
572 detector.Attach(child);
573 detector.Detach(parent);
575 // Do an entire tap, only check finished value
577 TestGenerateTap(application, 51.0f, 51.0f, 700);
578 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
579 DALI_TEST_EQUALS(true, child == data.tappedActor, TEST_LOCATION);
580 DALI_TEST_EQUALS(Vector2(51.0f, 51.0f), data.receivedGesture.GetScreenPoint(), 0.01f, TEST_LOCATION);
584 int UtcDaliTapGestureSignalReceptionAttachDetachMany(void)
586 TestApplication application;
588 Actor first = Actor::New();
589 first.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
590 first.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
591 application.GetScene().Add(first);
593 Actor second = Actor::New();
594 second.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
595 second.SetProperty(Actor::Property::POSITION_X, 100.0f);
596 second.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
597 application.GetScene().Add(second);
600 application.SendNotification();
601 application.Render();
604 GestureReceivedFunctor functor(data);
606 TapGestureDetector detector = TapGestureDetector::New();
607 detector.Attach(first);
608 detector.Attach(second);
609 detector.DetectedSignal().Connect(&application, functor);
611 // Tap within second actor's area
612 TestGenerateTap(application, 120.0f, 10.0f, 100);
613 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
614 DALI_TEST_EQUALS(true, second == data.tappedActor, TEST_LOCATION);
616 // Tap within first actor's area
618 TestGenerateTap(application, 20.0f, 10.0f, 700);
619 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
620 DALI_TEST_EQUALS(true, first == data.tappedActor, TEST_LOCATION);
622 // Detach the second actor
623 detector.Detach(second);
625 // second actor shouldn't receive event
627 TestGenerateTap(application, 120.0f, 10.0f, 1300);
628 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
630 // first actor should continue receiving event
632 TestGenerateTap(application, 20.0f, 10.0f, 1900);
633 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
637 int UtcDaliTapGestureSignalReceptionActorBecomesUntouchable(void)
639 TestApplication application;
641 Actor actor = Actor::New();
642 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
643 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
644 application.GetScene().Add(actor);
647 application.SendNotification();
648 application.Render();
651 GestureReceivedFunctor functor(data);
653 TapGestureDetector detector = TapGestureDetector::New();
654 detector.Attach(actor);
655 detector.DetectedSignal().Connect(&application, functor);
657 // Tap in actor's area
658 TestGenerateTap(application, 50.0f, 10.0f, 100);
659 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
661 // Actor become invisible - actor should not receive the next pan
662 actor.SetProperty(Actor::Property::VISIBLE, false);
665 application.SendNotification();
666 application.Render();
668 // Tap in the same area, shouldn't receive event
670 TestGenerateTap(application, 50.0f, 10.0f, 700);
671 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
675 int UtcDaliTapGestureSignalReceptionMultipleGestureDetectors(void)
677 TestApplication application;
679 Actor first = Actor::New();
680 first.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
681 first.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
682 application.GetScene().Add(first);
684 Actor second = Actor::New();
685 second.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
686 second.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
687 second.SetProperty(Actor::Property::POSITION_X, 100.0f);
691 application.SendNotification();
692 application.Render();
695 GestureReceivedFunctor functor(data);
697 TapGestureDetector firstDetector = TapGestureDetector::New();
698 firstDetector.Attach(first);
699 firstDetector.DetectedSignal().Connect(&application, functor);
701 // secondDetector is scoped
703 TapGestureDetector secondDetector = TapGestureDetector::New(2);
704 secondDetector.Attach(second);
705 secondDetector.DetectedSignal().Connect(&application, functor);
707 // Tap within second actor's area
708 TestGenerateTap(application, 150.0f, 10.0f, 100);
709 TestGenerateTap(application, 150.0f, 10.0f, 200);
711 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
712 DALI_TEST_EQUALS(true, second == data.tappedActor, TEST_LOCATION);
714 // Tap continues as single touch gesture - we should not receive any gesture
716 TestGenerateTap(application, 150.0f, 10.0f, 800);
717 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
719 // Single touch tap starts - first actor should be panned
721 TestGenerateTap(application, 50.0f, 10.0f, 1400);
722 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
723 DALI_TEST_EQUALS(true, first == data.tappedActor, TEST_LOCATION);
725 // Tap changes to double-touch - we shouldn't receive event
728 TestGenerateTwoPointTap(application, 50.0f, 10.0f, 60.0f, 20.0f, 2000);
730 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
736 int UtcDaliTapGestureSignalReceptionMultipleDetectorsOnActor(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 one detector
750 SignalData firstData;
751 GestureReceivedFunctor firstFunctor(firstData);
752 TapGestureDetector firstDetector = TapGestureDetector::New();
753 firstDetector.Attach(actor);
754 firstDetector.DetectedSignal().Connect(&application, firstFunctor);
756 // Attach actor to another detector
757 SignalData secondData;
758 GestureReceivedFunctor secondFunctor(secondData);
759 TapGestureDetector secondDetector = TapGestureDetector::New();
760 secondDetector.Attach(actor);
761 secondDetector.DetectedSignal().Connect(&application, secondFunctor);
763 // Tap in actor's area - both detector's functors should be called
764 TestGenerateTap(application, 50.0f, 10.0f, 100);
765 DALI_TEST_EQUALS(true, firstData.functorCalled, TEST_LOCATION);
766 DALI_TEST_EQUALS(true, secondData.functorCalled, TEST_LOCATION);
770 int UtcDaliTapGestureSignalReceptionDifferentPossible(void)
772 TestApplication application;
774 Actor actor = Actor::New();
775 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
776 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
777 application.GetScene().Add(actor);
780 application.SendNotification();
781 application.Render();
783 // Attach actor to detector
785 GestureReceivedFunctor functor(data);
786 TapGestureDetector detector = TapGestureDetector::New();
787 detector.Attach(actor);
788 detector.DetectedSignal().Connect(&application, functor);
790 // Gesture possible in actor's area.
791 TestStartLongPress(application, 50.0f, 10.0f, 100);
792 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
794 // Move actor somewhere else
795 actor.SetProperty(Actor::Property::POSITION, Vector2(100.0f, 100.0f));
798 application.SendNotification();
799 application.Render();
801 // Emit STARTED event, we should not receive the tap.
802 TestEndPan(application, Vector2(50.0f, 10.0f), 120);
803 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
805 // Tap possible in empty area.
806 TestStartLongPress(application, 50.0f, 10.0f, 700);
807 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
809 // Move actor in to the tap position.
810 actor.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.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), 720);
818 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
820 // Normal tap in actor's area for completeness.
821 TestGenerateTap(application, 50.0f, 10.0f, 1300);
822 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
826 int UtcDaliTapGestureActorUnstaged(void)
828 TestApplication application;
830 Actor actor = Actor::New();
831 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
832 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
833 application.GetScene().Add(actor);
836 application.SendNotification();
837 application.Render();
839 // Attach actor to detector
841 UnstageActorFunctor functor(data, application.GetScene());
842 TapGestureDetector detector = TapGestureDetector::New();
843 detector.Attach(actor);
844 detector.DetectedSignal().Connect(&application, functor);
846 TestGenerateTap(application, 50.0f, 10.0f, 100);
847 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
848 tet_result(TET_PASS); // If we get here, then the actor removal on signal handler was handled gracefully.
852 int UtcDaliTapGestureDetectorRemovedWhilePossible(void)
854 TestApplication application;
856 Actor actor = Actor::New();
857 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
858 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
859 application.GetScene().Add(actor);
862 application.SendNotification();
863 application.Render();
865 // Attach actor to detector
867 GestureReceivedFunctor functor(data);
868 TapGestureDetector detector = TapGestureDetector::New();
869 detector.Attach(actor);
870 detector.DetectedSignal().Connect(&application, functor);
872 // Emit a possible - Down press, as emitted by long press function
873 TestStartLongPress(application, 50.0f, 10.0f, 100);
875 // Detach actor and send a STARTED state, no signal.
876 detector.DetachAll();
877 TestEndPan(application, Vector2(50.0f, 10.0f), 120);
878 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
882 int UtcDaliTapGestureActorRemovedWhilePossible(void)
884 TestApplication application;
886 Actor actor = Actor::New();
887 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
888 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
889 application.GetScene().Add(actor);
892 application.SendNotification();
893 application.Render();
895 // Attach actor to detector
897 GestureReceivedFunctor functor(data);
898 TapGestureDetector detector = TapGestureDetector::New();
899 detector.Attach(actor);
900 detector.DetectedSignal().Connect(&application, functor);
902 // Emit a possible - Down press, as emitted by long press function
903 TestStartLongPress(application, 50.0f, 10.0f, 100);
905 // Remove, render and delete actor
906 application.GetScene().Remove(actor);
907 application.SendNotification();
908 application.Render();
911 // Send a STARTED state, no signal - Up motion as provided by end pan function
912 TestEndPan(application, Vector2(50.0f, 10.0f), 120);
913 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
917 int UtcDaliTapGestureLayerConsumesTouch(void)
919 TestApplication application;
921 Actor actor = Actor::New();
922 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
923 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
924 application.GetScene().Add(actor);
928 GestureReceivedFunctor functor(data);
929 TapGestureDetector detector = TapGestureDetector::New();
930 detector.Attach(actor);
931 detector.DetectedSignal().Connect(&application, functor);
933 // Add a layer to overlap the actor
934 Layer layer = Layer::New();
935 layer.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
936 layer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
937 application.GetScene().Add(layer);
941 application.SendNotification();
942 application.Render();
944 // Emit signals, should receive
945 TestGenerateTap(application, 50.0f, 50.0f, 100);
946 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
949 // Set layer to consume all touch
950 layer.SetProperty(Layer::Property::CONSUMES_TOUCH, true);
953 application.SendNotification();
954 application.Render();
956 // Emit the same signals again, should not receive
957 TestGenerateTap(application, 50.0f, 50.0f, 700);
958 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
964 int UtcDaliTapGestureDisableDetectionDuringTapN(void)
966 // Crash sometimes occurred when gesture-recognizer was deleted internally during a signal when the attached actor was detached
968 TestApplication application;
970 Actor actor = Actor::New();
971 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
972 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
973 application.GetScene().Add(actor);
976 TapGestureDetector detector = TapGestureDetector::New();
977 bool functorCalled = false;
978 detector.Attach(actor);
979 detector.DetectedSignal().Connect(
981 [&detector, &functorCalled](Actor actor, const TapGesture& gesture) {
982 detector.Detach(actor);
983 functorCalled = true;
987 application.SendNotification();
988 application.Render();
990 // Try the gesture, should not crash
993 TestGenerateTap(application, 50.0f, 10.0f);
995 DALI_TEST_CHECK(true); // No crash, test has passed
996 DALI_TEST_EQUALS(functorCalled, true, TEST_LOCATION);
1000 DALI_TEST_CHECK(false); // If we crash, the test has failed
1006 int UtcDaliTapGestureWhenGesturePropargation(void)
1008 TestApplication application;
1010 Actor parentActor = Actor::New();
1011 parentActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1012 parentActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1014 Actor childActor = Actor::New();
1015 childActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1016 childActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1018 parentActor.Add(childActor);
1019 application.GetScene().Add(parentActor);
1021 // Render and notify
1022 application.SendNotification();
1023 application.Render();
1026 GestureReceivedFunctor pFunctor(pData);
1028 TapGestureDetector parentDetector = TapGestureDetector::New();
1029 parentDetector.Attach(parentActor);
1030 parentDetector.DetectedSignal().Connect(&application, pFunctor);
1033 GestureReceivedFunctor cFunctor(cData);
1035 TapGestureDetector childDetector = TapGestureDetector::New();
1036 childDetector.Attach(childActor);
1037 childDetector.DetectedSignal().Connect(&application, cFunctor);
1039 // Start gesture within the actor's area, we receive the gesture not parent actor but child actor.
1040 TestGenerateTap(application, 50.0f, 50.0f, 100);
1041 DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
1042 DALI_TEST_EQUALS(false, pData.functorCalled, TEST_LOCATION);
1046 // If GesturePropargation is set, a gesture event is delivered to the parent.
1047 Dali::DevelActor::SetNeedGesturePropagation(childActor, true);
1049 // So now the parent got the gesture event.
1050 TestGenerateTap(application, 50.0f, 50.0f, 700);
1051 DALI_TEST_EQUALS(true, cData.functorCalled, TEST_LOCATION);
1052 DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION);
1059 int UtcDaliTapGestureGetSourceType(void)
1061 TestApplication application;
1063 Actor actor = Actor::New();
1064 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1065 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1066 application.GetScene().Add(actor);
1068 // Render and notify
1069 application.SendNotification();
1070 application.Render();
1073 GestureReceivedFunctor functor(data);
1075 TapGestureDetector detector = TapGestureDetector::New();
1076 detector.Attach(actor);
1077 detector.DetectedSignal().Connect(&application, functor);
1079 // Emit a down signal with MouseButton
1080 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 1, 100));
1081 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 1, 120));
1082 application.SendNotification();
1084 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1085 DALI_TEST_EQUALS(data.receivedGesture.GetSourceType(), GestureSourceType::MOUSE, TEST_LOCATION);
1086 DALI_TEST_EQUALS(data.receivedGesture.GetSourceData(), GestureSourceData::MOUSE_PRIMARY, TEST_LOCATION);
1090 // Emit a down signal with MouseButton
1091 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 3, 1300));
1092 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 3, 1320));
1093 application.SendNotification();
1095 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1096 DALI_TEST_EQUALS(data.receivedGesture.GetSourceType(), GestureSourceType::MOUSE, TEST_LOCATION);
1097 DALI_TEST_EQUALS(data.receivedGesture.GetSourceData(), GestureSourceData::MOUSE_SECONDARY, TEST_LOCATION);
1101 // Emit a down signal with MouseButton
1102 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 2, 1900));
1103 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 2, 1920));
1104 application.SendNotification();
1106 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1107 DALI_TEST_EQUALS(data.receivedGesture.GetSourceType(), GestureSourceType::MOUSE, TEST_LOCATION);
1108 DALI_TEST_EQUALS(data.receivedGesture.GetSourceData(), GestureSourceData::MOUSE_TERTIARY, TEST_LOCATION);
1113 int UtcDaliTapGestureReceiveAllTapEvents(void)
1115 TestApplication application;
1117 Actor actor = Actor::New();
1118 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1119 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1121 application.GetScene().Add(actor);
1123 // Render and notify
1124 application.SendNotification();
1125 application.Render();
1128 GestureReceivedFunctor functor(data);
1130 TapGestureDetector detector = TapGestureDetector::New();
1131 detector.SetMaximumTapsRequired(2u);
1132 detector.Attach(actor);
1133 detector.DetectedSignal().Connect(&application, functor);
1135 // Emit signals, Because MaximumTapsRequired is 2, a timer that checks whether it is a single tap or a double tap operates internally.
1136 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 0, 100));
1137 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 0, 120));
1138 application.SendNotification();
1140 // So detector don't get the tap event yet.
1141 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1144 // Emit signals, Send the second tab.
1145 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 0, 130));
1146 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 0, 150));
1147 application.SendNotification();
1148 application.GetPlatform().TriggerTimer();
1150 // It find out to be a double tap. Detector receives events.
1151 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1154 // Detector want to receive all tap events.
1155 detector.ReceiveAllTapEvents(true);
1157 // Emit signals, should receive
1158 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 0, 500));
1159 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 0, 520));
1160 application.SendNotification();
1162 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1165 // Emit signals, should receive
1166 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 0, 530));
1167 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 0, 550));
1168 application.SendNotification();
1170 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1176 int UtcDaliTapGestureDoesWantedHitTest(void)
1178 TestApplication application;
1180 Actor blue = Actor::New();
1181 blue.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1182 blue.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1184 Actor green = Actor::New();
1185 green.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1186 green.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1188 application.GetScene().Add(blue);
1189 application.GetScene().Add(green);
1191 // Render and notify
1192 application.SendNotification();
1193 application.Render();
1195 SignalData blueData;
1196 GestureReceivedFunctor blueFunctor(blueData);
1198 TapGestureDetector blueDetector = TapGestureDetector::New();
1199 blueDetector.Attach(blue);
1200 blueDetector.DetectedSignal().Connect(&application, blueFunctor);
1202 SignalData greenData;
1203 GestureReceivedFunctor greenFunctor(greenData);
1205 TapGestureDetector greenDetector = TapGestureDetector::New();
1206 greenDetector.Attach(green);
1207 greenDetector.DetectedSignal().Connect(&application, greenFunctor);
1209 // connect to its hit-test signal
1210 gHitTestTouchCallBackCalled = false;
1211 Dali::DevelActor::HitTestResultSignal(green).Connect(TestHitTestTouchCallback);
1213 // Emit a down signal
1214 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 0, 100));
1215 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 0, 120));
1216 application.SendNotification();
1218 // check hit-test events
1219 // The green actor received an event that the green actor was hit.
1220 DALI_TEST_EQUALS(true, gHitTestTouchCallBackCalled, TEST_LOCATION);
1222 // The green actor passed the hit-test. So blue was the final hit.
1223 DALI_TEST_EQUALS(false, greenData.functorCalled, TEST_LOCATION);
1224 DALI_TEST_EQUALS(true, blueData.functorCalled, TEST_LOCATION);
1232 int UtcDaliTapGestureDetectorCheck(void)
1234 TestApplication application;
1236 Actor actor = Actor::New();
1237 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1238 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1239 application.GetScene().Add(actor);
1241 Actor actor2 = Actor::New();
1242 actor2.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1243 actor2.SetProperty(Actor::Property::POSITION, Vector2(100.0f, 100.0f));
1244 actor2.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1245 application.GetScene().Add(actor2);
1247 // Render and notify
1248 application.SendNotification();
1249 application.Render();
1252 GestureReceivedFunctor functor(data);
1253 TapGestureDetector detector1 = TapGestureDetector::New();
1254 detector1.SetMaximumTapsRequired(1u);
1255 detector1.Attach(actor);
1256 detector1.DetectedSignal().Connect(&application, functor);
1258 TapGestureDetector detector2 = TapGestureDetector::New();
1259 detector2.SetMaximumTapsRequired(2u);
1260 detector2.Attach(actor2);
1262 // Emit signals, Send the single tab.
1263 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 0, 100));
1264 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 0, 120));
1265 application.SendNotification();
1267 // The detector1 get the tap event.
1268 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1271 // Emit signals, Send the second tab.
1272 application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 0, 130));
1273 application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 0, 150));
1274 application.SendNotification();
1276 // The detector1 must get the tap event. SetMaximumTapsRequired(2u) of detector2 should not affect detector1.
1277 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);