eddbe46ce8884fba7d9471a39ce50ed8cd79fb56
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-TouchProcessing.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <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/events/touch-integ.h>
22 #include <dali/integration-api/render-task-list-integ.h>
23 #include <dali/public-api/dali-core.h>
24 #include <stdlib.h>
25
26 #include <iostream>
27
28 using namespace Dali;
29
30 void utc_dali_touch_processing_startup(void)
31 {
32   test_return_value = TET_UNDEF;
33 }
34
35 void utc_dali_touch_processing_cleanup(void)
36 {
37   test_return_value = TET_PASS;
38 }
39
40 ///////////////////////////////////////////////////////////////////////////////
41
42 namespace
43 {
44 struct TestPoint
45 {
46   int32_t                deviceId{-1};
47   PointState::Type       state{PointState::FINISHED};
48   Actor                  hitActor;
49   Vector2                local;
50   Vector2                screen;
51   float                  radius{0};
52   Vector2                ellipseRadius;
53   float                  pressure{0};
54   Degree                 angle;
55   Device::Class::Type    deviceClass{Device::Class::NONE};
56   Device::Subclass::Type deviceSubclass{Device::Subclass::NONE};
57
58   TestPoint() = default;
59   static const TestPoint ZERO;
60 };
61
62 const TestPoint TestPoint::ZERO;
63
64 // Stores data that is populated in the callback and will be read by the TET cases
65 struct SignalData
66 {
67   SignalData()
68   : functorCalled(false),
69     receivedTouch(),
70     touchedActor()
71   {
72   }
73
74   struct TestTouchEvent
75   {
76     unsigned long          time;
77     std::vector<TestPoint> points;
78
79     const TestPoint& GetPoint(size_t i)
80     {
81       if(i < points.size())
82       {
83         return points[i];
84       }
85       return TestPoint::ZERO;
86     }
87     size_t GetPointCount()
88     {
89       return points.size();
90     }
91   };
92
93   void Reset()
94   {
95     functorCalled = false;
96
97     receivedTouch.time = 0u;
98     receivedTouch.points.clear();
99
100     touchedActor.Reset();
101   }
102
103   bool           functorCalled;
104   TestTouchEvent receivedTouch;
105   Actor          touchedActor;
106 };
107
108 // Functor that sets the data when called
109 struct TouchEventFunctor
110 {
111   /**
112    * Constructor.
113    * @param[in]  data         Reference to the data to store callback information.
114    * @param[in]  returnValue  What the functor should return.
115    */
116   TouchEventFunctor(SignalData& data, bool returnValue = true)
117   : signalData(data),
118     returnValue(returnValue)
119   {
120   }
121
122   bool operator()(Actor actor, const TouchEvent& touch)
123   {
124     signalData.functorCalled = true;
125     signalData.touchedActor  = actor;
126
127     signalData.receivedTouch.time = touch.GetTime();
128     signalData.receivedTouch.points.clear();
129
130     for(size_t i = 0; i < touch.GetPointCount(); ++i)
131     {
132       TestPoint p;
133       p.deviceId       = touch.GetDeviceId(i);
134       p.state          = touch.GetState(i);
135       p.hitActor       = touch.GetHitActor(i);
136       p.local          = touch.GetLocalPosition(i);
137       p.screen         = touch.GetScreenPosition(i);
138       p.radius         = touch.GetRadius(i);
139       p.ellipseRadius  = touch.GetEllipseRadius(i);
140       p.pressure       = touch.GetPressure(i);
141       p.angle          = touch.GetAngle(i);
142       p.deviceClass    = touch.GetDeviceClass(i);
143       p.deviceSubclass = touch.GetDeviceSubclass(i);
144       signalData.receivedTouch.points.push_back(p);
145     }
146
147     return returnValue;
148   }
149
150   SignalData& signalData;
151   bool        returnValue;
152 };
153
154 struct HandleData
155 {
156   bool       signalReceived;
157   TouchEvent receivedTouchHandle;
158
159   HandleData()
160   : signalReceived(false)
161   {
162   }
163 };
164
165 struct TouchEventHandleFunctor
166 {
167   /**
168    * Constructor.
169    * @param[in]  data         Reference to the data to store callback information.
170    * @param[in]  returnValue  What the functor should return.
171    */
172   TouchEventHandleFunctor(HandleData& handleData, bool returnValue = true)
173   : handleData(handleData),
174     returnValue(returnValue)
175   {
176   }
177
178   bool operator()(Actor actor, const TouchEvent& someTouchEvent)
179   {
180     handleData.signalReceived      = true;
181     handleData.receivedTouchHandle = someTouchEvent;
182     return returnValue;
183   }
184
185   HandleData& handleData;
186   bool        returnValue;
187 };
188
189 // Functor that removes the actor when called.
190 struct RemoveActorFunctor : public TouchEventFunctor
191 {
192   /**
193    * Constructor.
194    * @param[in]  data         Reference to the data to store callback information.
195    * @param[in]  returnValue  What the functor should return.
196    */
197   RemoveActorFunctor(SignalData& data, bool returnValue = true)
198   : TouchEventFunctor(data, returnValue)
199   {
200   }
201
202   bool operator()(Actor actor, const TouchEvent& touch)
203   {
204     Actor parent(actor.GetParent());
205     if(parent)
206     {
207       parent.Remove(actor);
208     }
209
210     return TouchEventFunctor::operator()(actor, touch);
211   }
212 };
213
214 struct OutOfBoundsData
215 {
216   TestPoint point;
217   bool      functorCalled;
218
219   OutOfBoundsData()
220   : functorCalled(false)
221   {
222   }
223 };
224
225 // Functor that reads out of bounds data when called
226 struct OutOfBoundsFunctor
227 {
228   /**
229    * Constructor.
230    * @param[in]  data         Reference to the data to store callback information.
231    * @param[in]  returnValue  What the functor should return.
232    */
233   OutOfBoundsFunctor(OutOfBoundsData& data, bool returnValue = true)
234   : outOfBoundsData(data),
235     returnValue(returnValue)
236   {
237   }
238
239   bool operator()(Actor actor, const TouchEvent& touch)
240   {
241     outOfBoundsData.functorCalled = true;
242     size_t count                  = touch.GetPointCount();
243
244     // Read out of bounds data
245     outOfBoundsData.point.deviceId = touch.GetDeviceId(count + 1);
246     outOfBoundsData.point.state    = touch.GetState(count + 1);
247     outOfBoundsData.point.hitActor = touch.GetHitActor(count + 1);
248     outOfBoundsData.point.local    = touch.GetLocalPosition(count + 1);
249     outOfBoundsData.point.screen   = touch.GetScreenPosition(count + 1);
250
251     return returnValue;
252   }
253
254   OutOfBoundsData& outOfBoundsData;
255   bool             returnValue;
256 };
257
258 Integration::TouchEvent GenerateSingleTouch(PointState::Type state, const Vector2& screenPosition)
259 {
260   Integration::TouchEvent touchEvent;
261   Integration::Point      point;
262   point.SetState(state);
263   point.SetScreenPosition(screenPosition);
264   point.SetDeviceClass(Device::Class::TOUCH);
265   point.SetDeviceSubclass(Device::Subclass::NONE);
266   touchEvent.points.push_back(point);
267   return touchEvent;
268 }
269
270 } // namespace
271
272 ///////////////////////////////////////////////////////////////////////////////
273
274 int UtcDaliTouchEventNormalProcessing01(void)
275 {
276   TestApplication application;
277
278   Actor actor = Actor::New();
279   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
280   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
281   application.GetScene().Add(actor);
282
283   // Render and notify
284   application.SendNotification();
285   application.Render();
286
287   // Connect to actor's touch signal
288   SignalData        data;
289   TouchEventFunctor functor(data);
290   actor.TouchedSignal().Connect(&application, functor);
291
292   Vector2 screenCoordinates(10.0f, 10.0f);
293   Vector2 localCoordinates;
294   actor.ScreenToLocal(localCoordinates.x, localCoordinates.y, screenCoordinates.x, screenCoordinates.y);
295
296   // Emit a down signal
297   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, screenCoordinates));
298   const TestPoint* point1 = &data.receivedTouch.GetPoint(0);
299   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
300   DALI_TEST_EQUALS(1u, data.receivedTouch.GetPointCount(), TEST_LOCATION);
301   DALI_TEST_EQUALS(PointState::DOWN, point1->state, TEST_LOCATION);
302   DALI_TEST_EQUALS(screenCoordinates, point1->screen, TEST_LOCATION);
303   DALI_TEST_EQUALS(localCoordinates, point1->local, 0.1f, TEST_LOCATION);
304   data.Reset();
305
306   // Emit a motion signal
307   screenCoordinates.x = screenCoordinates.y = 11.0f;
308   actor.ScreenToLocal(localCoordinates.x, localCoordinates.y, screenCoordinates.x, screenCoordinates.y);
309   application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, screenCoordinates));
310   const TestPoint* point2 = &data.receivedTouch.GetPoint(0);
311   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
312   DALI_TEST_EQUALS(1u, data.receivedTouch.GetPointCount(), TEST_LOCATION);
313   DALI_TEST_EQUALS(PointState::MOTION, point2->state, TEST_LOCATION);
314   DALI_TEST_EQUALS(screenCoordinates, point2->screen, TEST_LOCATION);
315   DALI_TEST_EQUALS(localCoordinates, point2->local, 0.1f, TEST_LOCATION);
316   data.Reset();
317
318   // Emit an up signal
319   screenCoordinates.x = screenCoordinates.y = 12.0f;
320   actor.ScreenToLocal(localCoordinates.x, localCoordinates.y, screenCoordinates.x, screenCoordinates.y);
321   application.ProcessEvent(GenerateSingleTouch(PointState::UP, screenCoordinates));
322   const TestPoint* point3 = &data.receivedTouch.GetPoint(0);
323   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
324   DALI_TEST_EQUALS(1u, data.receivedTouch.GetPointCount(), TEST_LOCATION);
325   DALI_TEST_EQUALS(PointState::UP, point3->state, TEST_LOCATION);
326   DALI_TEST_EQUALS(screenCoordinates, point3->screen, TEST_LOCATION);
327   DALI_TEST_EQUALS(localCoordinates, point3->local, 0.1f, TEST_LOCATION);
328   data.Reset();
329
330   // Emit a down signal where the actor is not present
331   screenCoordinates.x = screenCoordinates.y = 200.0f;
332   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, screenCoordinates));
333   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
334   END_TEST;
335 }
336
337 int UtcDaliTouchEventNormalProcessing02(void)
338 {
339   TestApplication application;
340
341   Actor actor = Actor::New();
342   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
343   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
344   application.GetScene().Add(actor);
345
346   // Render and notify
347   application.SendNotification();
348   application.Render();
349
350   // Connect to actor's touched signal
351   HandleData              handleData;
352   TouchEventHandleFunctor functor(handleData);
353   actor.TouchedSignal().Connect(&application, functor);
354
355   Vector2 screenCoordinates(10.0f, 10.0f);
356   Vector2 localCoordinates;
357   actor.ScreenToLocal(localCoordinates.x, localCoordinates.y, screenCoordinates.x, screenCoordinates.y);
358
359   // Emit a down signal
360   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, screenCoordinates));
361   DALI_TEST_EQUALS(true, handleData.signalReceived, TEST_LOCATION);
362   DALI_TEST_EQUALS(1u, handleData.receivedTouchHandle.GetPointCount(), TEST_LOCATION);
363   DALI_TEST_EQUALS(PointState::DOWN, handleData.receivedTouchHandle.GetState(0), TEST_LOCATION);
364   DALI_TEST_EQUALS(screenCoordinates, handleData.receivedTouchHandle.GetScreenPosition(0), TEST_LOCATION);
365   DALI_TEST_EQUALS(localCoordinates, handleData.receivedTouchHandle.GetLocalPosition(0), 0.1f, TEST_LOCATION);
366
367   END_TEST;
368 }
369
370 int UtcDaliTouchEventAPINegative(void)
371 {
372   TestApplication application;
373
374   Actor actor = Actor::New();
375   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
376   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
377   application.GetScene().Add(actor);
378
379   // Render and notify
380   application.SendNotification();
381   application.Render();
382
383   // Connect to actor's touched signal
384   OutOfBoundsData    data;
385   OutOfBoundsFunctor functor(data, true);
386   actor.TouchedSignal().Connect(&application, functor);
387
388   Vector2 screenCoordinates(10.0f, 10.0f);
389   Vector2 localCoordinates;
390   actor.ScreenToLocal(localCoordinates.x, localCoordinates.y, screenCoordinates.x, screenCoordinates.y);
391
392   // Emit a down signal
393   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, screenCoordinates));
394
395   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
396   DALI_TEST_EQUALS(-1, data.point.deviceId, TEST_LOCATION);
397   DALI_TEST_EQUALS(PointState::FINISHED, data.point.state, TEST_LOCATION);
398   DALI_TEST_EQUALS(Vector2::ZERO, data.point.screen, TEST_LOCATION);
399   DALI_TEST_EQUALS(Vector2::ZERO, data.point.local, 0.1f, TEST_LOCATION);
400   DALI_TEST_CHECK(!data.point.hitActor);
401
402   END_TEST;
403 }
404
405 int UtcDaliTouchEventOutsideCameraNearFarPlanes(void)
406 {
407   TestApplication application;
408
409   Integration::Scene scene     = application.GetScene();
410   Vector2            sceneSize = scene.GetSize();
411
412   Actor actor = Actor::New();
413   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
414   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
415   actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
416   scene.Add(actor);
417
418   // Render and notify
419   application.SendNotification();
420   application.Render();
421
422   // Get the camera's near and far planes
423   RenderTaskList   taskList  = scene.GetRenderTaskList();
424   Dali::RenderTask task      = taskList.GetTask(0);
425   CameraActor      camera    = task.GetCameraActor();
426   float            nearPlane = camera.GetNearClippingPlane();
427   float            farPlane  = camera.GetFarClippingPlane();
428
429   // Calculate the current distance of the actor from the camera
430   float tanHalfFov = tanf(camera.GetFieldOfView() * 0.5f);
431   float distance   = (sceneSize.y * 0.5f) / tanHalfFov;
432
433   // Connect to actor's touched signal
434   SignalData        data;
435   TouchEventFunctor functor(data);
436   actor.TouchedSignal().Connect(&application, functor);
437
438   Vector2 screenCoordinates(sceneSize.x * 0.5f, sceneSize.y * 0.5f);
439
440   // Emit a down signal
441   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, screenCoordinates));
442   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
443   data.Reset();
444
445   // Emit a down signal where actor is just at the camera's near plane
446   actor.SetProperty(Actor::Property::POSITION_Z, distance - nearPlane);
447
448   // Render and notify
449   application.SendNotification();
450   application.Render();
451
452   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, screenCoordinates));
453   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
454   data.Reset();
455
456   // Emit a down signal where actor is closer than the camera's near plane
457   actor.SetProperty(Actor::Property::POSITION_Z, (distance - nearPlane) + 1.0f);
458
459   // Render and notify
460   application.SendNotification();
461   application.Render();
462
463   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, screenCoordinates));
464   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
465   data.Reset();
466
467   // Emit a down signal where actor is just at the camera's far plane
468   actor.SetProperty(Actor::Property::POSITION_Z, distance - farPlane);
469
470   // Render and notify
471   application.SendNotification();
472   application.Render();
473
474   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, screenCoordinates));
475   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
476   data.Reset();
477
478   // Emit a down signal where actor is further than the camera's far plane
479   actor.SetProperty(Actor::Property::POSITION_Z, (distance - farPlane) - 1.0f);
480
481   // Render and notify
482   application.SendNotification();
483   application.Render();
484
485   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, screenCoordinates));
486   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
487   data.Reset();
488   END_TEST;
489 }
490
491 int UtcDaliTouchEventEmitEmpty(void)
492 {
493   TestApplication application;
494
495   try
496   {
497     // Emit an empty TouchEvent
498     Integration::TouchEvent event;
499     application.ProcessEvent(event);
500     tet_result(TET_FAIL);
501   }
502   catch(Dali::DaliException& e)
503   {
504     DALI_TEST_ASSERT(e, "!event.points.empty()", TEST_LOCATION);
505   }
506   END_TEST;
507 }
508
509 int UtcDaliTouchEventInterrupted(void)
510 {
511   TestApplication application;
512
513   Actor actor = Actor::New();
514   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
515   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
516   application.GetScene().Add(actor);
517
518   // Render and notify
519   application.SendNotification();
520   application.Render();
521
522   // Connect to actor's touched signal
523   SignalData        data;
524   TouchEventFunctor functor(data);
525   actor.TouchedSignal().Connect(&application, functor);
526
527   // Emit a down signal
528   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
529   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
530   DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION);
531   data.Reset();
532
533   // Emit an interrupted signal, we should be signalled regardless of whether there is a hit or not.
534   application.ProcessEvent(GenerateSingleTouch(PointState::INTERRUPTED, Vector2(200.0f, 200.0f /* Outside actor */)));
535   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
536   DALI_TEST_EQUALS(PointState::INTERRUPTED, data.receivedTouch.points[0].state, TEST_LOCATION);
537   data.Reset();
538
539   // Emit another interrupted signal, our signal handler should not be called.
540   application.ProcessEvent(GenerateSingleTouch(PointState::INTERRUPTED, Vector2(200.0f, 200.0f)));
541   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
542   END_TEST;
543 }
544
545 int UtcDaliTouchEventParentConsumer(void)
546 {
547   TestApplication application;
548   Actor           rootActor(application.GetScene().GetRootLayer());
549
550   Actor actor = Actor::New();
551   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
552   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
553   application.GetScene().Add(actor);
554
555   // Render and notify
556   application.SendNotification();
557   application.Render();
558
559   // Connect to actor's touched signal
560   SignalData        data;
561   TouchEventFunctor functor(data, false);
562   actor.TouchedSignal().Connect(&application, functor);
563
564   // Connect to root actor's touched signal
565   SignalData        rootData;
566   TouchEventFunctor rootFunctor(rootData); // Consumes signal
567   rootActor.TouchedSignal().Connect(&application, rootFunctor);
568
569   Vector2 screenCoordinates(10.0f, 10.0f);
570   Vector2 actorCoordinates, rootCoordinates;
571   actor.ScreenToLocal(actorCoordinates.x, actorCoordinates.y, screenCoordinates.x, screenCoordinates.y);
572   rootActor.ScreenToLocal(rootCoordinates.x, rootCoordinates.y, screenCoordinates.x, screenCoordinates.y);
573
574   // Emit a down signal
575   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, screenCoordinates));
576   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
577   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
578   DALI_TEST_EQUALS(1u, data.receivedTouch.GetPointCount(), TEST_LOCATION);
579   DALI_TEST_EQUALS(1u, rootData.receivedTouch.GetPointCount(), TEST_LOCATION);
580   DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION);
581   DALI_TEST_EQUALS(PointState::DOWN, rootData.receivedTouch.points[0].state, TEST_LOCATION);
582   DALI_TEST_EQUALS(screenCoordinates, data.receivedTouch.points[0].screen, TEST_LOCATION);
583   DALI_TEST_EQUALS(screenCoordinates, rootData.receivedTouch.points[0].screen, TEST_LOCATION);
584   DALI_TEST_EQUALS(actorCoordinates, data.receivedTouch.points[0].local, 0.1f, TEST_LOCATION);
585   DALI_TEST_EQUALS(rootCoordinates, rootData.receivedTouch.points[0].local, 0.1f, TEST_LOCATION);
586   DALI_TEST_CHECK(actor == data.receivedTouch.points[0].hitActor);
587   DALI_TEST_CHECK(actor == rootData.receivedTouch.points[0].hitActor);
588   data.Reset();
589   rootData.Reset();
590
591   // Emit a motion signal
592   screenCoordinates.x = screenCoordinates.y = 11.0f;
593   actor.ScreenToLocal(actorCoordinates.x, actorCoordinates.y, screenCoordinates.x, screenCoordinates.y);
594   rootActor.ScreenToLocal(rootCoordinates.x, rootCoordinates.y, screenCoordinates.x, screenCoordinates.y);
595   application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, screenCoordinates));
596   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
597   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
598   DALI_TEST_EQUALS(1u, data.receivedTouch.GetPointCount(), TEST_LOCATION);
599   DALI_TEST_EQUALS(1u, rootData.receivedTouch.GetPointCount(), TEST_LOCATION);
600   DALI_TEST_EQUALS(PointState::MOTION, data.receivedTouch.points[0].state, TEST_LOCATION);
601   DALI_TEST_EQUALS(PointState::MOTION, rootData.receivedTouch.points[0].state, TEST_LOCATION);
602   DALI_TEST_EQUALS(screenCoordinates, data.receivedTouch.points[0].screen, TEST_LOCATION);
603   DALI_TEST_EQUALS(screenCoordinates, rootData.receivedTouch.points[0].screen, TEST_LOCATION);
604   DALI_TEST_EQUALS(actorCoordinates, data.receivedTouch.points[0].local, 0.1f, TEST_LOCATION);
605   DALI_TEST_EQUALS(rootCoordinates, rootData.receivedTouch.points[0].local, 0.1f, TEST_LOCATION);
606   DALI_TEST_CHECK(actor == data.receivedTouch.points[0].hitActor);
607   DALI_TEST_CHECK(actor == rootData.receivedTouch.points[0].hitActor);
608   data.Reset();
609   rootData.Reset();
610
611   // Emit an up signal
612   screenCoordinates.x = screenCoordinates.y = 12.0f;
613   actor.ScreenToLocal(actorCoordinates.x, actorCoordinates.y, screenCoordinates.x, screenCoordinates.y);
614   rootActor.ScreenToLocal(rootCoordinates.x, rootCoordinates.y, screenCoordinates.x, screenCoordinates.y);
615   application.ProcessEvent(GenerateSingleTouch(PointState::UP, screenCoordinates));
616   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
617   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
618   DALI_TEST_EQUALS(1u, data.receivedTouch.GetPointCount(), TEST_LOCATION);
619   DALI_TEST_EQUALS(1u, rootData.receivedTouch.GetPointCount(), TEST_LOCATION);
620   DALI_TEST_EQUALS(PointState::UP, data.receivedTouch.points[0].state, TEST_LOCATION);
621   DALI_TEST_EQUALS(PointState::UP, rootData.receivedTouch.points[0].state, TEST_LOCATION);
622   DALI_TEST_EQUALS(screenCoordinates, data.receivedTouch.points[0].screen, TEST_LOCATION);
623   DALI_TEST_EQUALS(screenCoordinates, rootData.receivedTouch.points[0].screen, TEST_LOCATION);
624   DALI_TEST_EQUALS(actorCoordinates, data.receivedTouch.points[0].local, 0.1f, TEST_LOCATION);
625   DALI_TEST_EQUALS(rootCoordinates, rootData.receivedTouch.points[0].local, 0.1f, TEST_LOCATION);
626   DALI_TEST_CHECK(actor == data.receivedTouch.points[0].hitActor);
627   DALI_TEST_CHECK(actor == rootData.receivedTouch.points[0].hitActor);
628   data.Reset();
629   rootData.Reset();
630
631   // Emit a down signal where the actor is not present, will hit the root actor though
632   screenCoordinates.x = screenCoordinates.y = 200.0f;
633   rootActor.ScreenToLocal(rootCoordinates.x, rootCoordinates.y, screenCoordinates.x, screenCoordinates.y);
634   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, screenCoordinates));
635   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
636   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
637   DALI_TEST_EQUALS(1u, rootData.receivedTouch.GetPointCount(), TEST_LOCATION);
638   DALI_TEST_EQUALS(PointState::DOWN, rootData.receivedTouch.points[0].state, TEST_LOCATION);
639   DALI_TEST_EQUALS(screenCoordinates, rootData.receivedTouch.points[0].screen, TEST_LOCATION);
640   DALI_TEST_EQUALS(rootCoordinates, rootData.receivedTouch.points[0].local, 0.1f, TEST_LOCATION);
641   DALI_TEST_CHECK(rootActor == rootData.receivedTouch.points[0].hitActor);
642   END_TEST;
643 }
644
645 int UtcDaliTouchEventInterruptedParentConsumer(void)
646 {
647   TestApplication application;
648   Actor           rootActor(application.GetScene().GetRootLayer());
649
650   Actor actor = Actor::New();
651   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
652   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
653   application.GetScene().Add(actor);
654
655   // Render and notify
656   application.SendNotification();
657   application.Render();
658
659   // Connect to actor's touched signal
660   SignalData        data;
661   TouchEventFunctor functor(data, false);
662   actor.TouchedSignal().Connect(&application, functor);
663
664   // Connect to root actor's touched signal
665   SignalData        rootData;
666   TouchEventFunctor rootFunctor(rootData); // Consumes signal
667   rootActor.TouchedSignal().Connect(&application, rootFunctor);
668
669   // Emit a down signal
670   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
671   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
672   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
673   DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION);
674   DALI_TEST_EQUALS(PointState::DOWN, rootData.receivedTouch.points[0].state, TEST_LOCATION);
675   DALI_TEST_CHECK(actor == data.receivedTouch.points[0].hitActor);
676   DALI_TEST_CHECK(actor == rootData.receivedTouch.points[0].hitActor);
677   data.Reset();
678   rootData.Reset();
679
680   // Emit an interrupted signal
681   application.ProcessEvent(GenerateSingleTouch(PointState::INTERRUPTED, Vector2(200.0f, 200.0f)));
682   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
683   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
684   DALI_TEST_EQUALS(PointState::INTERRUPTED, data.receivedTouch.points[0].state, TEST_LOCATION);
685   DALI_TEST_EQUALS(PointState::INTERRUPTED, rootData.receivedTouch.points[0].state, TEST_LOCATION);
686   DALI_TEST_CHECK(actor == data.receivedTouch.points[0].hitActor);
687   DALI_TEST_CHECK(actor == rootData.receivedTouch.points[0].hitActor);
688   data.Reset();
689   rootData.Reset();
690
691   // Emit another down signal
692   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
693   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
694   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
695   DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION);
696   DALI_TEST_EQUALS(PointState::DOWN, rootData.receivedTouch.points[0].state, TEST_LOCATION);
697   data.Reset();
698   rootData.Reset();
699
700   // Remove actor from scene
701   application.GetScene().Remove(actor);
702   data.Reset();
703   rootData.Reset();
704
705   // Render and notify
706   application.SendNotification();
707   application.Render();
708
709   // Emit an interrupted signal, only root actor's signal should be called.
710   application.ProcessEvent(GenerateSingleTouch(PointState::INTERRUPTED, Vector2(200.0f, 200.0f /* Outside actor */)));
711   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
712   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
713   DALI_TEST_EQUALS(PointState::INTERRUPTED, rootData.receivedTouch.points[0].state, TEST_LOCATION);
714   DALI_TEST_CHECK(rootActor == rootData.receivedTouch.points[0].hitActor);
715   data.Reset();
716   rootData.Reset();
717
718   // Emit another interrupted state, none of the signal's should be called.
719   application.ProcessEvent(GenerateSingleTouch(PointState::INTERRUPTED, Vector2(200.0f, 200.0f)));
720   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
721   DALI_TEST_EQUALS(false, rootData.functorCalled, TEST_LOCATION);
722   END_TEST;
723 }
724
725 int UtcDaliTouchEventLeave(void)
726 {
727   TestApplication application;
728
729   Actor actor = Actor::New();
730   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
731   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
732   application.GetScene().Add(actor);
733
734   // Render and notify
735   application.SendNotification();
736   application.Render();
737
738   // Connect to actor's touched signal
739   SignalData        data;
740   TouchEventFunctor functor(data);
741   actor.TouchedSignal().Connect(&application, functor);
742
743   // Set actor to require leave events
744   actor.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
745
746   // Emit a down signal
747   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
748   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
749   DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION);
750   data.Reset();
751
752   // Emit a motion signal outside of actor, should be signalled with a Leave
753   application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(200.0f, 200.0f)));
754   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
755   DALI_TEST_EQUALS(PointState::LEAVE, data.receivedTouch.points[0].state, TEST_LOCATION);
756   data.Reset();
757
758   // Another motion outside of actor, no signalling
759   application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(201.0f, 201.0f)));
760   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
761   data.Reset();
762
763   // Another motion event inside actor, signalled with motion
764   application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(10.0f, 10.0f)));
765   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
766   DALI_TEST_EQUALS(PointState::MOTION, data.receivedTouch.points[0].state, TEST_LOCATION);
767   data.Reset();
768
769   // We do not want to listen to leave events anymore
770   actor.SetProperty(Actor::Property::LEAVE_REQUIRED, false);
771
772   // Another motion event outside of actor, no signalling
773   application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(200.0f, 200.0f)));
774   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
775   data.Reset();
776   END_TEST;
777 }
778
779 int UtcDaliTouchEventLeaveParentConsumer(void)
780 {
781   TestApplication application;
782   Actor           rootActor(application.GetScene().GetRootLayer());
783
784   Actor actor = Actor::New();
785   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
786   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
787   application.GetScene().Add(actor);
788
789   // Render and notify
790   application.SendNotification();
791   application.Render();
792
793   // Connect to actor's touched signal
794   SignalData        data;
795   TouchEventFunctor functor(data, false);
796   actor.TouchedSignal().Connect(&application, functor);
797
798   // Connect to root actor's touched signal
799   SignalData        rootData;
800   TouchEventFunctor rootFunctor(rootData); // Consumes signal
801   rootActor.TouchedSignal().Connect(&application, rootFunctor);
802
803   // Set actor to require leave events
804   actor.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
805   rootActor.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
806
807   // Emit a down signal
808   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
809   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
810   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
811   DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION);
812   DALI_TEST_EQUALS(PointState::DOWN, rootData.receivedTouch.points[0].state, TEST_LOCATION);
813   DALI_TEST_CHECK(actor == data.receivedTouch.points[0].hitActor);
814   DALI_TEST_CHECK(actor == rootData.receivedTouch.points[0].hitActor);
815   data.Reset();
816   rootData.Reset();
817
818   // Emit a motion signal outside of actor, should be signalled with a Leave
819   application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(200.0f, 200.0f)));
820   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
821   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
822   DALI_TEST_EQUALS(PointState::LEAVE, data.receivedTouch.points[0].state, TEST_LOCATION);
823   DALI_TEST_EQUALS(PointState::LEAVE, rootData.receivedTouch.points[0].state, TEST_LOCATION);
824   DALI_TEST_CHECK(actor == data.receivedTouch.points[0].hitActor);
825   DALI_TEST_CHECK(actor == rootData.receivedTouch.points[0].hitActor);
826   data.Reset();
827   rootData.Reset();
828
829   // Another motion outside of actor, only rootActor signalled
830   application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(201.0f, 201.0f)));
831   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
832   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
833   DALI_TEST_EQUALS(PointState::MOTION, rootData.receivedTouch.points[0].state, TEST_LOCATION);
834   DALI_TEST_CHECK(rootActor == rootData.receivedTouch.points[0].hitActor);
835   data.Reset();
836   rootData.Reset();
837
838   // Another motion event inside actor, signalled with motion
839   application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(10.0f, 10.0f)));
840   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
841   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
842   DALI_TEST_EQUALS(PointState::MOTION, data.receivedTouch.points[0].state, TEST_LOCATION);
843   DALI_TEST_EQUALS(PointState::MOTION, rootData.receivedTouch.points[0].state, TEST_LOCATION);
844   DALI_TEST_CHECK(actor == data.receivedTouch.points[0].hitActor);
845   DALI_TEST_CHECK(actor == rootData.receivedTouch.points[0].hitActor);
846   data.Reset();
847   rootData.Reset();
848
849   // We do not want to listen to leave events of actor anymore
850   actor.SetProperty(Actor::Property::LEAVE_REQUIRED, false);
851
852   // Another motion event outside of root actor, only root signalled
853   Vector2 sceneSize(application.GetScene().GetSize());
854   application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(sceneSize.width + 10.0f, sceneSize.height + 10.0f)));
855   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
856   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
857   DALI_TEST_EQUALS(PointState::LEAVE, rootData.receivedTouch.points[0].state, TEST_LOCATION);
858   END_TEST;
859 }
860
861 int UtcDaliTouchEventActorBecomesInsensitive(void)
862 {
863   TestApplication application;
864
865   Actor actor = Actor::New();
866   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
867   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
868   application.GetScene().Add(actor);
869
870   // Render and notify
871   application.SendNotification();
872   application.Render();
873
874   // Connect to actor's touched signal
875   SignalData        data;
876   TouchEventFunctor functor(data);
877   actor.TouchedSignal().Connect(&application, functor);
878
879   // Emit a down signal
880   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
881   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
882   DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION);
883   data.Reset();
884
885   // Change actor to insensitive
886   actor.SetProperty(Actor::Property::SENSITIVE, false);
887
888   // Emit a motion signal, signalled with an interrupted
889   application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(200.0f, 200.0f)));
890   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
891   DALI_TEST_EQUALS(PointState::INTERRUPTED, data.receivedTouch.points[0].state, TEST_LOCATION);
892   data.Reset();
893   END_TEST;
894 }
895
896 int UtcDaliTouchEventActorBecomesInsensitiveParentConsumer(void)
897 {
898   TestApplication application;
899   Actor           rootActor(application.GetScene().GetRootLayer());
900
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);
905
906   // Render and notify
907   application.SendNotification();
908   application.Render();
909
910   // Connect to actor's touched signal
911   SignalData        data;
912   TouchEventFunctor functor(data, false);
913   actor.TouchedSignal().Connect(&application, functor);
914
915   // Connect to root actor's touched signal
916   SignalData        rootData;
917   TouchEventFunctor rootFunctor(rootData); // Consumes signal
918   rootActor.TouchedSignal().Connect(&application, rootFunctor);
919
920   // Emit a down signal
921   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
922   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
923   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
924   DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION);
925   DALI_TEST_EQUALS(PointState::DOWN, rootData.receivedTouch.points[0].state, TEST_LOCATION);
926   DALI_TEST_CHECK(actor == data.receivedTouch.points[0].hitActor);
927   DALI_TEST_CHECK(actor == rootData.receivedTouch.points[0].hitActor);
928   data.Reset();
929   rootData.Reset();
930
931   // Render and notify
932   application.SendNotification();
933   application.Render();
934
935   // Make root actor insensitive
936   rootActor.SetProperty(Actor::Property::SENSITIVE, false);
937
938   // Emit a motion signal, signalled with an interrupted (should get interrupted even if within root actor)
939   application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(200.0f, 200.0f)));
940   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
941   DALI_TEST_EQUALS(PointState::INTERRUPTED, data.receivedTouch.points[0].state, TEST_LOCATION);
942   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
943   DALI_TEST_EQUALS(PointState::INTERRUPTED, rootData.receivedTouch.points[0].state, TEST_LOCATION);
944   END_TEST;
945 }
946
947 int UtcDaliTouchEventMultipleLayers(void)
948 {
949   TestApplication application;
950   Actor           rootActor(application.GetScene().GetRootLayer());
951
952   // Connect to actor's touched signal
953   SignalData        data;
954   TouchEventFunctor functor(data);
955
956   Layer layer1(Layer::New());
957   layer1.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
958   layer1.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
959   application.GetScene().Add(layer1);
960
961   Actor actor1(Actor::New());
962   actor1.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
963   actor1.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
964   actor1.SetProperty(Actor::Property::POSITION_Z, 1.0f); // Should hit actor1 in this layer
965   layer1.Add(actor1);
966
967   // Render and notify
968   application.SendNotification();
969   application.Render();
970
971   // Connect to layer1 and actor1
972   layer1.TouchedSignal().Connect(&application, functor);
973   actor1.TouchedSignal().Connect(&application, functor);
974
975   // Hit in hittable area, actor1 should be hit
976   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
977   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
978   DALI_TEST_CHECK(data.touchedActor == actor1);
979   data.Reset();
980
981   // Make layer1 insensitive, nothing should be hit
982   layer1.SetProperty(Actor::Property::SENSITIVE, false);
983   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
984   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
985   data.Reset();
986
987   // Make layer1 sensitive again, again actor1 will be hit
988   layer1.SetProperty(Actor::Property::SENSITIVE, true);
989   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
990   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
991   DALI_TEST_CHECK(data.touchedActor == actor1);
992   data.Reset();
993
994   // Make rootActor insensitive, nothing should be hit
995   rootActor.SetProperty(Actor::Property::SENSITIVE, false);
996   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
997   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
998   data.Reset();
999
1000   // Make rootActor sensitive
1001   rootActor.SetProperty(Actor::Property::SENSITIVE, true);
1002
1003   // Add another layer
1004   Layer layer2(Layer::New());
1005   layer2.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1006   layer2.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1007   layer2.SetProperty(Actor::Property::POSITION_Z, 10.0f); // Should hit layer2 in this layer rather than actor2
1008   application.GetScene().Add(layer2);
1009
1010   Actor actor2(Actor::New());
1011   actor2.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1012   actor2.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1013   layer2.Add(actor2);
1014
1015   // Render and notify
1016   application.SendNotification();
1017   application.Render();
1018
1019   // Connect to layer2 and actor2
1020   layer2.TouchedSignal().Connect(&application, functor);
1021   actor2.TouchedSignal().Connect(&application, functor);
1022
1023   // Emit an event, should hit layer2
1024   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1025   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1026   //DALI_TEST_CHECK( data.touchedActor == layer2 ); // TODO: Uncomment this after removing renderable hack!
1027   data.Reset();
1028
1029   // Make layer2 insensitive, should hit actor1
1030   layer2.SetProperty(Actor::Property::SENSITIVE, false);
1031   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1032   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1033   DALI_TEST_CHECK(data.touchedActor == actor1);
1034   data.Reset();
1035
1036   // Make layer2 sensitive again, should hit layer2
1037   layer2.SetProperty(Actor::Property::SENSITIVE, true);
1038   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1039   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1040   //DALI_TEST_CHECK( data.touchedActor == layer2 ); // TODO: Uncomment this after removing renderable hack!
1041   data.Reset();
1042
1043   // Make layer2 invisible, render and notify
1044   layer2.SetProperty(Actor::Property::VISIBLE, false);
1045   application.SendNotification();
1046   application.Render();
1047
1048   // Should hit actor1
1049   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1050   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1051   DALI_TEST_CHECK(data.touchedActor == actor1);
1052   data.Reset();
1053
1054   // Make rootActor invisible, render and notify
1055   rootActor.SetProperty(Actor::Property::VISIBLE, false);
1056   application.SendNotification();
1057   application.Render();
1058
1059   // Should not hit anything
1060   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1061   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1062   data.Reset();
1063   END_TEST;
1064 }
1065
1066 int UtcDaliTouchEventMultipleRenderTasks(void)
1067 {
1068   TestApplication    application;
1069   Integration::Scene scene(application.GetScene());
1070   Vector2            sceneSize(scene.GetSize());
1071
1072   Actor actor = Actor::New();
1073   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1074   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1075   scene.Add(actor);
1076
1077   // Create render task
1078   Viewport   viewport(sceneSize.width * 0.5f, sceneSize.height * 0.5f, sceneSize.width * 0.5f, sceneSize.height * 0.5f);
1079   RenderTask renderTask(application.GetScene().GetRenderTaskList().CreateTask());
1080   renderTask.SetViewport(viewport);
1081   renderTask.SetInputEnabled(true);
1082
1083   // Render and notify
1084   application.SendNotification();
1085   application.Render();
1086
1087   // Connect to actor's touched signal
1088   SignalData        data;
1089   TouchEventFunctor functor(data);
1090   actor.TouchedSignal().Connect(&application, functor);
1091
1092   // Emit a down signal
1093   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1094   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1095   data.Reset();
1096
1097   // Ensure renderTask actor can be hit too.
1098   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(viewport.x + 5.0f, viewport.y + 5.0f)));
1099   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1100   data.Reset();
1101
1102   // Disable input on renderTask, should not be hittable
1103   renderTask.SetInputEnabled(false);
1104   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(viewport.x + 5.0f, viewport.y + 5.0f)));
1105   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1106   data.Reset();
1107   END_TEST;
1108 }
1109
1110 int UtcDaliTouchEventMultipleRenderTasksWithChildLayer(void)
1111 {
1112   TestApplication    application;
1113   Integration::Scene scene(application.GetScene());
1114   Vector2            sceneSize(scene.GetSize());
1115
1116   Actor actor = Actor::New();
1117   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1118   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1119   scene.Add(actor);
1120
1121   Layer layer = Layer::New();
1122   layer.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1123   layer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1124   actor.Add(layer);
1125
1126   // Create render task
1127   Viewport   viewport(sceneSize.width * 0.5f, sceneSize.height * 0.5f, sceneSize.width * 0.5f, sceneSize.height * 0.5f);
1128   RenderTask renderTask(application.GetScene().GetRenderTaskList().CreateTask());
1129   renderTask.SetViewport(viewport);
1130   renderTask.SetInputEnabled(true);
1131   renderTask.SetSourceActor(actor);
1132
1133   // Render and notify
1134   application.SendNotification();
1135   application.Render();
1136
1137   // Connect to layer's touched signal
1138   SignalData        data;
1139   TouchEventFunctor functor(data);
1140   actor.TouchedSignal().Connect(&application, functor);
1141   layer.TouchedSignal().Connect(&application, functor);
1142
1143   // Emit a down signal
1144   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1145   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1146   data.Reset();
1147
1148   // Ensure renderTask actor can be hit too.
1149   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(viewport.x + 5.0f, viewport.y + 5.0f)));
1150   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1151   data.Reset();
1152
1153   // Disable input on renderTask, should not be hittable
1154   renderTask.SetInputEnabled(false);
1155   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(viewport.x + 5.0f, viewport.y + 5.0f)));
1156   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1157   data.Reset();
1158   END_TEST;
1159 }
1160
1161 int UtcDaliTouchEventOffscreenRenderTasks(void)
1162 {
1163   TestApplication    application;
1164   Integration::Scene scene(application.GetScene());
1165   Vector2            sceneSize(scene.GetSize());
1166
1167   // FrameBufferImage for offscreen RenderTask
1168   FrameBuffer frameBuffer = FrameBuffer::New(sceneSize.width, sceneSize.height);
1169
1170   // Create a renderable actor to display the FrameBufferImage
1171   Actor renderableActor = CreateRenderableActor(frameBuffer.GetColorTexture());
1172   renderableActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
1173   renderableActor.SetProperty(Actor::Property::SIZE, Vector2(sceneSize.x, sceneSize.y));
1174   renderableActor.ScaleBy(Vector3(1.0f, -1.0f, 1.0f)); // FIXME
1175   scene.Add(renderableActor);
1176
1177   Actor actor = Actor::New();
1178   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1179   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1180   scene.Add(actor);
1181   application.GetGlAbstraction().SetCheckFramebufferStatusResult(GL_FRAMEBUFFER_COMPLETE); // Ensure framebuffer connects
1182
1183   scene.GetRenderTaskList().GetTask(0u).SetScreenToFrameBufferFunction(RenderTask::FULLSCREEN_FRAMEBUFFER_FUNCTION);
1184
1185   // Create a RenderTask
1186   RenderTask renderTask = scene.GetRenderTaskList().CreateTask();
1187   renderTask.SetSourceActor(actor);
1188   renderTask.SetFrameBuffer(frameBuffer);
1189   renderTask.SetInputEnabled(true);
1190
1191   // Create another RenderTask
1192   RenderTask renderTask2(scene.GetRenderTaskList().CreateTask());
1193   renderTask2.SetInputEnabled(true);
1194
1195   // Render and notify
1196   application.SendNotification();
1197   application.Render();
1198
1199   // Connect to actor's touched signal
1200   SignalData        data;
1201   TouchEventFunctor functor(data);
1202   actor.TouchedSignal().Connect(&application, functor);
1203
1204   // Emit a down signal
1205   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1206   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1207   data.Reset();
1208   END_TEST;
1209 }
1210
1211 int UtcDaliTouchEventMultipleRenderableActors(void)
1212 {
1213   TestApplication    application;
1214   Integration::Scene scene(application.GetScene());
1215   Vector2            sceneSize(scene.GetSize());
1216
1217   Actor parent = CreateRenderableActor();
1218   parent.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1219   parent.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1220   scene.Add(parent);
1221
1222   Actor actor = CreateRenderableActor();
1223   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1224   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1225   parent.Add(actor);
1226
1227   // Render and notify
1228   application.SendNotification();
1229   application.Render();
1230
1231   // Connect to layer's touched signal
1232   SignalData        data;
1233   TouchEventFunctor functor(data);
1234   parent.TouchedSignal().Connect(&application, functor);
1235   actor.TouchedSignal().Connect(&application, functor);
1236
1237   // Emit a down signal
1238   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1239   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1240   DALI_TEST_CHECK(actor == data.touchedActor);
1241   END_TEST;
1242 }
1243
1244 int UtcDaliTouchEventActorRemovedInSignal(void)
1245 {
1246   TestApplication application;
1247
1248   Actor actor = Actor::New();
1249   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1250   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1251   application.GetScene().Add(actor);
1252
1253   // Render and notify
1254   application.SendNotification();
1255   application.Render();
1256
1257   // Connect to actor's touched signal
1258   SignalData         data;
1259   RemoveActorFunctor functor(data);
1260   actor.TouchedSignal().Connect(&application, functor);
1261
1262   // Register for leave events
1263   actor.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
1264
1265   // Emit a down signal
1266   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1267   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1268   data.Reset();
1269
1270   // Re-add, render and notify
1271   application.GetScene().Add(actor);
1272   application.SendNotification();
1273   application.Render();
1274
1275   // Emit another signal outside of actor's area, should not get anything as the scene has changed.
1276   application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(210.0f, 210.0f)));
1277   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1278   data.Reset();
1279
1280   // Emit a down signal
1281   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1282   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1283   data.Reset();
1284
1285   // Render and notify
1286   application.SendNotification();
1287   application.Render();
1288
1289   // Emit another signal outside of actor's area, should not get anything as the scene has changed.
1290   application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(210.0f, 210.0f)));
1291   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1292   data.Reset();
1293
1294   // Re-add actor back to scene, render and notify
1295   application.GetScene().Add(actor);
1296   application.SendNotification();
1297   application.Render();
1298
1299   // Emit another down event
1300   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1301   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1302   data.Reset();
1303
1304   // Completely delete the actor
1305   actor.Reset();
1306
1307   // Emit event, should not crash and should not receive an event.
1308   application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(210.0f, 210.0f)));
1309   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1310   END_TEST;
1311 }
1312
1313 int UtcDaliTouchEventActorSignalNotConsumed(void)
1314 {
1315   TestApplication application;
1316
1317   Actor actor = Actor::New();
1318   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1319   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1320   application.GetScene().Add(actor);
1321
1322   // Render and notify
1323   application.SendNotification();
1324   application.Render();
1325
1326   // Connect to actor's touched signal
1327   SignalData        data;
1328   TouchEventFunctor functor(data, false);
1329   actor.TouchedSignal().Connect(&application, functor);
1330
1331   // Emit a down signal
1332   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1333   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1334   END_TEST;
1335 }
1336
1337 int UtcDaliTouchEventActorRemovedFromScene(void)
1338 {
1339   TestApplication application;
1340
1341   Actor actor = Actor::New();
1342   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1343   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1344   application.GetScene().Add(actor);
1345
1346   // Render and notify
1347   application.SendNotification();
1348   application.Render();
1349
1350   // Connect to actor's touched signal
1351   SignalData        data;
1352   TouchEventFunctor functor(data);
1353   actor.TouchedSignal().Connect(&application, functor);
1354
1355   // Emit a down signal
1356   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1357   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1358   data.Reset();
1359
1360   // Remove actor from scene
1361   application.GetScene().Remove(actor);
1362   data.Reset();
1363
1364   // Render and notify
1365   application.SendNotification();
1366   application.Render();
1367
1368   // Emit a move at the same point, we should not be signalled.
1369   application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(10.0f, 10.0f)));
1370   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1371   data.Reset();
1372   END_TEST;
1373 }
1374
1375 int UtcDaliTouchEventLayerConsumesTouch(void)
1376 {
1377   TestApplication application;
1378
1379   Actor actor = Actor::New();
1380   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1381   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1382   application.GetScene().Add(actor);
1383
1384   // Render and notify
1385   application.SendNotification();
1386   application.Render();
1387
1388   // Connect to actor's touched signal
1389   SignalData        data;
1390   TouchEventFunctor functor(data);
1391   actor.TouchedSignal().Connect(&application, functor);
1392
1393   // Add a layer to overlap the actor
1394   Layer layer = Layer::New();
1395   layer.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1396   layer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1397   application.GetScene().Add(layer);
1398   layer.RaiseToTop();
1399
1400   // Render and notify
1401   application.SendNotification();
1402   application.Render();
1403
1404   // Emit a few touch signals
1405   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1406   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(10.0f, 10.0f)));
1407   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1408   data.Reset();
1409
1410   // Set layer to consume all touch
1411   layer.SetProperty(Layer::Property::CONSUMES_TOUCH, true);
1412
1413   // Render and notify
1414   application.SendNotification();
1415   application.Render();
1416
1417   // Emit the same signals again, should not receive
1418   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1419   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(10.0f, 10.0f)));
1420   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1421   data.Reset();
1422
1423   END_TEST;
1424 }
1425
1426 int UtcDaliTouchEventLeaveActorReadded(void)
1427 {
1428   TestApplication    application;
1429   Integration::Scene scene = application.GetScene();
1430
1431   Actor actor = Actor::New();
1432   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1433   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1434   scene.Add(actor);
1435
1436   // Set actor to receive touch-events
1437   actor.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
1438
1439   // Render and notify
1440   application.SendNotification();
1441   application.Render();
1442
1443   // Connect to actor's touched signal
1444   SignalData        data;
1445   TouchEventFunctor functor(data);
1446   actor.TouchedSignal().Connect(&application, functor);
1447
1448   // Emit a down and motion
1449   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1450   application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(11.0f, 10.0f)));
1451   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1452   data.Reset();
1453
1454   // Remove actor from scene and add again
1455   scene.Remove(actor);
1456   scene.Add(actor);
1457
1458   // Emit a motion within the actor's bounds
1459   application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(12.0f, 10.0f)));
1460   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1461   data.Reset();
1462
1463   // Emit a motion outside the actor's bounds
1464   application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(200.0f, 200.0f)));
1465   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1466   DALI_TEST_EQUALS(PointState::LEAVE, data.receivedTouch.points[0].state, TEST_LOCATION);
1467   data.Reset();
1468
1469   END_TEST;
1470 }
1471
1472 int UtcDaliTouchEventClippedActor(void)
1473 {
1474   TestApplication    application;
1475   Integration::Scene scene = application.GetScene();
1476
1477   Actor actor = Actor::New();
1478   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1479   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1480   scene.Add(actor);
1481
1482   Actor clippingActor = Actor::New();
1483   clippingActor.SetProperty(Actor::Property::SIZE, Vector2(50.0f, 50.0f));
1484   clippingActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1485   clippingActor.SetProperty(Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN);
1486   scene.Add(clippingActor);
1487
1488   // Add a child to the clipped region.
1489   Actor clippingChild = Actor::New();
1490   clippingChild.SetProperty(Actor::Property::SIZE, Vector2(50.0f, 50.0f));
1491   clippingChild.SetProperty(Actor::Property::POSITION, Vector2(25.0f, 25.0f));
1492   clippingChild.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1493   clippingActor.Add(clippingChild);
1494
1495   // Render and notify.
1496   application.SendNotification();
1497   application.Render();
1498
1499   // Connect to actor's touch signal.
1500   SignalData        data;
1501   TouchEventFunctor functor(data);
1502   actor.TouchedSignal().Connect(&application, functor);
1503
1504   // Emit an event within clipped area - we should have a hit.
1505   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1506   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1507   data.Reset();
1508
1509   // Emit an event within clipped child area - we should still have a hit.
1510   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(40.0f, 40.0f)));
1511   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1512   data.Reset();
1513
1514   // Now connect to the clippingChild's touch signal
1515   SignalData        clippingChildData;
1516   TouchEventFunctor clippingChildFunctor(clippingChildData);
1517   clippingChild.TouchedSignal().Connect(&application, clippingChildFunctor);
1518
1519   // Emit an event within clipped child area - no hit on actor, but hit on clipped child.
1520   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(40.0f, 40.0f)));
1521   DALI_TEST_EQUALS(true, clippingChildData.functorCalled, TEST_LOCATION);
1522   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1523   data.Reset();
1524   clippingChildData.Reset();
1525
1526   // Emit an event outside the clipped area but within the actor area, we should have a hit.
1527   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(60.0f, 60.0f)));
1528   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1529   data.Reset();
1530   clippingChildData.Reset();
1531
1532   // Emit an event inside part of the child which is within the clipped area, we should have a hit on the clipped child but not the actor.
1533   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(30.0f, 30.0f)));
1534   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1535   DALI_TEST_EQUALS(true, clippingChildData.functorCalled, TEST_LOCATION);
1536   data.Reset();
1537   clippingChildData.Reset();
1538
1539   END_TEST;
1540 }
1541
1542 int UtcDaliTouchEventActorUnparented(void)
1543 {
1544   TestApplication application;
1545
1546   Actor actor = Actor::New();
1547   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1548   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1549   application.GetScene().Add(actor);
1550
1551   // Render and notify
1552   application.SendNotification();
1553   application.Render();
1554
1555   // Connect to actor's touched signal
1556   SignalData        data;
1557   TouchEventFunctor functor(data);
1558   actor.TouchedSignal().Connect(&application, functor);
1559
1560   // Emit a down signal
1561   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1562   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1563   DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION);
1564   DALI_TEST_CHECK(actor == data.receivedTouch.points[0].hitActor);
1565   data.Reset();
1566
1567   // Render and notify
1568   application.SendNotification();
1569   application.Render();
1570
1571   // Unparent the actor
1572   actor.Unparent();
1573
1574   // Should receive an interrupted event
1575   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1576   DALI_TEST_EQUALS(PointState::INTERRUPTED, data.receivedTouch.points[0].state, TEST_LOCATION);
1577   END_TEST;
1578 }
1579
1580 int UtcDaliTouchEventParentRemovedFromScene(void)
1581 {
1582   TestApplication application;
1583
1584   Actor parent = Actor::New();
1585   parent.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1586   parent.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1587   application.GetScene().Add(parent);
1588
1589   Actor actor = Actor::New();
1590   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1591   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1592   parent.Add(actor);
1593
1594   // Render and notify
1595   application.SendNotification();
1596   application.Render();
1597
1598   // Connect to actor's touched signal
1599   SignalData        data;
1600   TouchEventFunctor functor(data);
1601   actor.TouchedSignal().Connect(&application, functor);
1602
1603   // Emit a down signal
1604   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1605   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1606   DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION);
1607   DALI_TEST_CHECK(actor == data.receivedTouch.points[0].hitActor);
1608   data.Reset();
1609
1610   // Render and notify
1611   application.SendNotification();
1612   application.Render();
1613
1614   // Unparent the parent of the touchable actor
1615   parent.Unparent();
1616
1617   // Should receive an interrupted event
1618   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1619   DALI_TEST_EQUALS(PointState::INTERRUPTED, data.receivedTouch.points[0].state, TEST_LOCATION);
1620   END_TEST;
1621 }
1622
1623 int UtcDaliTouchEventActorRemovedFromSceneDifferentConsumer(void)
1624 {
1625   TestApplication application;
1626
1627   Actor parent = Actor::New();
1628   parent.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1629   parent.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1630   application.GetScene().Add(parent);
1631
1632   Actor actor = Actor::New();
1633   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1634   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1635   parent.Add(actor);
1636
1637   // Render and notify
1638   application.SendNotification();
1639   application.Render();
1640
1641   // Connect to actor's touched signal
1642   SignalData        data;
1643   TouchEventFunctor functor(data, false /* Do not consume */);
1644   actor.TouchedSignal().Connect(&application, functor);
1645
1646   // Connect to parent's touched signal
1647   SignalData        parentData;
1648   TouchEventFunctor parentFunctor(parentData);
1649   parent.TouchedSignal().Connect(&application, parentFunctor);
1650
1651   // Emit a down signal
1652   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1653   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1654   DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION);
1655   DALI_TEST_CHECK(actor == data.receivedTouch.points[0].hitActor);
1656   DALI_TEST_CHECK(actor == data.touchedActor);
1657   DALI_TEST_EQUALS(true, parentData.functorCalled, TEST_LOCATION);
1658   DALI_TEST_EQUALS(PointState::DOWN, parentData.receivedTouch.points[0].state, TEST_LOCATION);
1659   DALI_TEST_CHECK(actor == parentData.receivedTouch.points[0].hitActor);
1660   DALI_TEST_CHECK(parent == parentData.touchedActor);
1661   data.Reset();
1662   parentData.Reset();
1663
1664   // Render and notify
1665   application.SendNotification();
1666   application.Render();
1667
1668   // Unparent the actor
1669   actor.Unparent();
1670
1671   // Should receive an interrupted event for both actor & parent
1672   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1673   DALI_TEST_EQUALS(PointState::INTERRUPTED, data.receivedTouch.points[0].state, TEST_LOCATION);
1674   DALI_TEST_EQUALS(true, parentData.functorCalled, TEST_LOCATION);
1675   DALI_TEST_EQUALS(PointState::INTERRUPTED, parentData.receivedTouch.points[0].state, TEST_LOCATION);
1676   data.Reset();
1677   parentData.Reset();
1678
1679   // Readd actor to parent
1680   parent.Add(actor);
1681
1682   // Render and notify
1683   application.SendNotification();
1684   application.Render();
1685
1686   // Emit a motion signal
1687   application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(10.0f, 10.0f)));
1688   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1689   DALI_TEST_EQUALS(true, parentData.functorCalled, TEST_LOCATION);
1690   data.Reset();
1691   parentData.Reset();
1692
1693   // Parent is now consumer, connect again to the touched signal of the actor so that it becomes the consumer
1694   SignalData        secondData;
1695   TouchEventFunctor secondFunctor(secondData /* Consume */);
1696   actor.TouchedSignal().Connect(&application, secondFunctor);
1697
1698   // Unparent the actor
1699   actor.Unparent();
1700
1701   // Should receive an interrupted event for both actor functors & the parent as well as it was last consumer
1702   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1703   DALI_TEST_EQUALS(PointState::INTERRUPTED, data.receivedTouch.points[0].state, TEST_LOCATION);
1704   DALI_TEST_EQUALS(true, parentData.functorCalled, TEST_LOCATION);
1705   DALI_TEST_EQUALS(PointState::INTERRUPTED, parentData.receivedTouch.points[0].state, TEST_LOCATION);
1706   DALI_TEST_EQUALS(true, secondData.functorCalled, TEST_LOCATION);
1707   DALI_TEST_EQUALS(PointState::INTERRUPTED, secondData.receivedTouch.points[0].state, TEST_LOCATION);
1708   data.Reset();
1709   parentData.Reset();
1710   secondData.Reset();
1711
1712   END_TEST;
1713 }
1714
1715 int UtcDaliTouchEventInterruptedDifferentConsumer(void)
1716 {
1717   TestApplication application;
1718   Actor           rootActor(application.GetScene().GetRootLayer());
1719
1720   Actor parent = Actor::New();
1721   parent.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1722   parent.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1723   application.GetScene().Add(parent);
1724
1725   Actor actor = Actor::New();
1726   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1727   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1728   parent.Add(actor);
1729
1730   // Render and notify
1731   application.SendNotification();
1732   application.Render();
1733
1734   // Connect to actor's touched signal
1735   SignalData        data;
1736   TouchEventFunctor functor(data, false /* Do not consume */);
1737   actor.TouchedSignal().Connect(&application, functor);
1738
1739   // Connect to parent's touched signal
1740   SignalData        parentData;
1741   TouchEventFunctor parentFunctor(parentData, false /* Do not consume */);
1742   parent.TouchedSignal().Connect(&application, parentFunctor);
1743
1744   // Connect to root's touched signal and consume
1745   SignalData        rootData;
1746   TouchEventFunctor rootFunctor(rootData);
1747   rootActor.TouchedSignal().Connect(&application, rootFunctor);
1748
1749   // Emit a down signal
1750   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1751   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1752   DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION);
1753   DALI_TEST_CHECK(actor == data.receivedTouch.points[0].hitActor);
1754   DALI_TEST_CHECK(actor == data.touchedActor);
1755   DALI_TEST_EQUALS(true, parentData.functorCalled, TEST_LOCATION);
1756   DALI_TEST_EQUALS(PointState::DOWN, parentData.receivedTouch.points[0].state, TEST_LOCATION);
1757   DALI_TEST_CHECK(actor == parentData.receivedTouch.points[0].hitActor);
1758   DALI_TEST_CHECK(parent == parentData.touchedActor);
1759   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
1760   DALI_TEST_EQUALS(PointState::DOWN, rootData.receivedTouch.points[0].state, TEST_LOCATION);
1761   DALI_TEST_CHECK(actor == rootData.receivedTouch.points[0].hitActor);
1762   DALI_TEST_CHECK(rootActor == rootData.touchedActor);
1763   data.Reset();
1764   parentData.Reset();
1765   rootData.Reset();
1766
1767   // Root is now consumer, connect to the touched signal of the parent so that it becomes the consumer
1768   SignalData        secondData;
1769   TouchEventFunctor secondFunctor(secondData /* Consume */);
1770   parent.TouchedSignal().Connect(&application, secondFunctor);
1771
1772   // Emit an interrupted signal, all three should STILL be called
1773   application.ProcessEvent(GenerateSingleTouch(PointState::INTERRUPTED, Vector2(10.0f, 10.0f)));
1774   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1775   DALI_TEST_EQUALS(PointState::INTERRUPTED, data.receivedTouch.points[0].state, TEST_LOCATION);
1776   DALI_TEST_EQUALS(true, parentData.functorCalled, TEST_LOCATION);
1777   DALI_TEST_EQUALS(PointState::INTERRUPTED, parentData.receivedTouch.points[0].state, TEST_LOCATION);
1778   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
1779   DALI_TEST_EQUALS(PointState::INTERRUPTED, rootData.receivedTouch.points[0].state, TEST_LOCATION);
1780   data.Reset();
1781   parentData.Reset();
1782   rootData.Reset();
1783
1784   END_TEST;
1785 }
1786
1787 int UtcDaliTouchEventGetRadius(void)
1788 {
1789   TestApplication application;
1790
1791   Actor actor = Actor::New();
1792   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1793   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1794   application.GetScene().Add(actor);
1795
1796   // Render and notify
1797   application.SendNotification();
1798   application.Render();
1799
1800   // Connect to actor's touched signal
1801   SignalData        data;
1802   TouchEventFunctor functor(data);
1803   actor.TouchedSignal().Connect(&application, functor);
1804
1805   // Emit a down signal with an angle
1806   Integration::TouchEvent touchEvent = GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f));
1807   touchEvent.points[0].SetRadius(100.0f);
1808   application.ProcessEvent(touchEvent);
1809   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1810   DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION);
1811   DALI_TEST_EQUALS(100.0f, data.receivedTouch.points[0].radius, TEST_LOCATION);
1812   DALI_TEST_EQUALS(100.0f, data.receivedTouch.points[0].ellipseRadius.x, TEST_LOCATION);
1813   DALI_TEST_EQUALS(100.0f, data.receivedTouch.points[0].ellipseRadius.y, TEST_LOCATION);
1814
1815   END_TEST;
1816 }
1817
1818 int UtcDaliTouchEventGetEllipseRadius(void)
1819 {
1820   TestApplication application;
1821
1822   Actor actor = Actor::New();
1823   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1824   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1825   application.GetScene().Add(actor);
1826
1827   // Render and notify
1828   application.SendNotification();
1829   application.Render();
1830
1831   // Connect to actor's touched signal
1832   SignalData        data;
1833   TouchEventFunctor functor(data);
1834   actor.TouchedSignal().Connect(&application, functor);
1835
1836   // Emit a down signal with an angle
1837   Integration::TouchEvent touchEvent = GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f));
1838   touchEvent.points[0].SetRadius(100.0f, Vector2(20.0f, 10.0f));
1839   application.ProcessEvent(touchEvent);
1840   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1841   DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION);
1842   DALI_TEST_EQUALS(100.0f, data.receivedTouch.points[0].radius, TEST_LOCATION);
1843   DALI_TEST_EQUALS(20.0f, data.receivedTouch.points[0].ellipseRadius.x, TEST_LOCATION);
1844   DALI_TEST_EQUALS(10.0f, data.receivedTouch.points[0].ellipseRadius.y, TEST_LOCATION);
1845
1846   END_TEST;
1847 }
1848
1849 int UtcDaliTouchEventGetAngle(void)
1850 {
1851   TestApplication application;
1852
1853   Actor actor = Actor::New();
1854   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1855   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1856   application.GetScene().Add(actor);
1857
1858   // Render and notify
1859   application.SendNotification();
1860   application.Render();
1861
1862   // Connect to actor's touched signal
1863   SignalData        data;
1864   TouchEventFunctor functor(data);
1865   actor.TouchedSignal().Connect(&application, functor);
1866
1867   // Emit a down signal with an angle
1868   Integration::TouchEvent touchEvent = GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f));
1869   touchEvent.points[0].SetAngle(Degree(90.0f));
1870   application.ProcessEvent(touchEvent);
1871   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1872   DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION);
1873   DALI_TEST_EQUALS(Degree(90.0f), data.receivedTouch.points[0].angle, TEST_LOCATION);
1874
1875   END_TEST;
1876 }
1877
1878 int UtcDaliTouchEventGetPressure(void)
1879 {
1880   TestApplication application;
1881
1882   Actor actor = Actor::New();
1883   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1884   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1885   application.GetScene().Add(actor);
1886
1887   // Render and notify
1888   application.SendNotification();
1889   application.Render();
1890
1891   // Connect to actor's touched signal
1892   SignalData        data;
1893   TouchEventFunctor functor(data);
1894   actor.TouchedSignal().Connect(&application, functor);
1895
1896   // Emit a down signal with an angle
1897   Integration::TouchEvent touchEvent = GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f));
1898   touchEvent.points[0].SetPressure(10.0f);
1899   application.ProcessEvent(touchEvent);
1900   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1901   DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION);
1902   DALI_TEST_EQUALS(10.0f, data.receivedTouch.points[0].pressure, TEST_LOCATION);
1903
1904   END_TEST;
1905 }
1906
1907 int UtcDaliTouchEventUsage(void)
1908 {
1909   TestApplication application;
1910
1911   Actor actor = Actor::New();
1912   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1913   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1914   application.GetScene().Add(actor);
1915
1916   // Render and notify
1917   application.SendNotification();
1918   application.Render();
1919
1920   // Connect to actor's touched signal
1921   SignalData        data;
1922   TouchEventFunctor functor(data);
1923   actor.TouchedSignal().Connect(&application, functor);
1924
1925   // Emit a down signal with an angle
1926   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
1927   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1928
1929   END_TEST;
1930 }
1931
1932 int UtcDaliTouchEventGetDeviceAPINegative(void)
1933 {
1934   TestApplication application;
1935
1936   Actor actor = Actor::New();
1937   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1938   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1939   application.GetScene().Add(actor);
1940
1941   // Render and notify
1942   application.SendNotification();
1943   application.Render();
1944
1945   // Connect to actor's touched signal
1946   HandleData              handleData;
1947   TouchEventHandleFunctor functor(handleData);
1948   actor.TouchedSignal().Connect(&application, functor);
1949
1950   Vector2 screenCoordinates(10.0f, 10.0f);
1951   Vector2 localCoordinates;
1952   actor.ScreenToLocal(localCoordinates.x, localCoordinates.y, screenCoordinates.x, screenCoordinates.y);
1953
1954   // Emit a down signal
1955   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, screenCoordinates));
1956
1957   TouchEvent data = handleData.receivedTouchHandle;
1958   DALI_TEST_EQUALS(data.GetDeviceClass(-1), Device::Class::NONE, TEST_LOCATION);
1959   DALI_TEST_EQUALS(data.GetDeviceSubclass(-1), Device::Subclass::NONE, TEST_LOCATION);
1960   END_TEST;
1961 }
1962
1963 int UtcDaliTouchEventGetMouseButtonPositive(void)
1964 {
1965   TestApplication application;
1966
1967   Actor actor = Actor::New();
1968   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1969   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1970   application.GetScene().Add(actor);
1971
1972   // Render and notify
1973   application.SendNotification();
1974   application.Render();
1975
1976   // Connect to actor's touched signal
1977   HandleData              handleData;
1978   TouchEventHandleFunctor functor(handleData);
1979   actor.TouchedSignal().Connect(&application, functor);
1980
1981   // Emit a down signal with MouseButton
1982   Integration::TouchEvent touchEvent = GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f));
1983   touchEvent.points[0].SetMouseButton(static_cast<MouseButton::Type>(3));
1984   application.ProcessEvent(touchEvent);
1985
1986   TouchEvent data = handleData.receivedTouchHandle;
1987   DALI_TEST_EQUALS(data.GetMouseButton(0), MouseButton::SECONDARY, TEST_LOCATION);
1988
1989   END_TEST;
1990 }
1991
1992 int UtcDaliTouchEventGetMouseButtonNagative(void)
1993 {
1994   TestApplication application;
1995
1996   Actor actor = Actor::New();
1997   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1998   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1999   application.GetScene().Add(actor);
2000
2001   // Render and notify
2002   application.SendNotification();
2003   application.Render();
2004
2005   // Connect to actor's touched signal
2006   HandleData              handleData;
2007   TouchEventHandleFunctor functor(handleData);
2008   actor.TouchedSignal().Connect(&application, functor);
2009
2010   // Emit a down signal with MouseButton
2011   Integration::TouchEvent touchEvent = GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f));
2012   touchEvent.points[0].SetMouseButton(static_cast<MouseButton::Type>(2));
2013   application.ProcessEvent(touchEvent);
2014
2015   TouchEvent data = handleData.receivedTouchHandle;
2016   DALI_TEST_EQUALS(data.GetMouseButton(0), MouseButton::TERTIARY, TEST_LOCATION);
2017   DALI_TEST_EQUALS(data.GetMouseButton(3), MouseButton::INVALID, TEST_LOCATION);
2018
2019   END_TEST;
2020 }
2021
2022 int UtcDaliTouchEventCapturePropertySet(void)
2023 {
2024   TestApplication application;
2025
2026   Actor actor = Actor::New();
2027   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
2028   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
2029   application.GetScene().Add(actor);
2030
2031   // Render and notify
2032   application.SendNotification();
2033   application.Render();
2034
2035   // Connect to actor's touched signal
2036   SignalData        data;
2037   TouchEventFunctor functor(data);
2038   actor.TouchedSignal().Connect(&application, functor);
2039
2040   // Emit a down signal
2041   application.ProcessEvent(GenerateSingleTouch(PointState::STARTED, Vector2(10.0f, 10.0f)));
2042   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
2043   data.Reset();
2044
2045   // Now motion outside of actor, we should not receive the event
2046   application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(110.0f, 110.0f)));
2047   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
2048   data.Reset();
2049
2050   // Up event, should receive an interrupted
2051   application.ProcessEvent(GenerateSingleTouch(PointState::FINISHED, Vector2(110.0f, 110.0f)));
2052   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
2053   DALI_TEST_EQUALS(data.receivedTouch.GetPoint(0).state, PointState::INTERRUPTED, TEST_LOCATION);
2054
2055   // Now set the capture property
2056   actor.SetProperty(DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START, true);
2057
2058   // Emit a down signal
2059   application.ProcessEvent(GenerateSingleTouch(PointState::STARTED, Vector2(10.0f, 10.0f)));
2060   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
2061   data.Reset();
2062
2063   // Now motion outside of actor, we now SHOULD receive the event
2064   application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(110.0f, 110.0f)));
2065   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
2066   data.Reset();
2067
2068   // Up event, we should receive it again, but as ended rather than interrupted
2069   application.ProcessEvent(GenerateSingleTouch(PointState::FINISHED, Vector2(110.0f, 110.0f)));
2070   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
2071   DALI_TEST_EQUALS(data.receivedTouch.GetPoint(0).state, PointState::FINISHED, TEST_LOCATION);
2072
2073   END_TEST;
2074 }
2075
2076 int UtcDaliTouchEventIntegNewTouchEvent(void)
2077 {
2078   uint32_t         timestamp = 92858u;
2079   TouchPoint       tp(1, PointState::STARTED, 34.4f, 123.89f, 5.0f, 7.0f);
2080   Dali::TouchEvent touchEvent = Integration::NewTouchEvent(timestamp, tp);
2081
2082   DALI_TEST_EQUALS(touchEvent.GetPointCount(), 1u, TEST_LOCATION);
2083   DALI_TEST_EQUALS(touchEvent.GetState(0), PointState::STARTED, TEST_LOCATION);
2084   DALI_TEST_EQUALS(touchEvent.GetLocalPosition(0), Vector2(5.0f, 7.0f), TEST_LOCATION);
2085   DALI_TEST_EQUALS(touchEvent.GetScreenPosition(0), Vector2(34.4f, 123.89f), TEST_LOCATION);
2086
2087   END_TEST;
2088 }
2089
2090 int UtcDaliTouchEventIntercept(void)
2091 {
2092   TestApplication application;
2093
2094   Actor parent = Actor::New();
2095   parent.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
2096   parent.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
2097   application.GetScene().Add(parent);
2098
2099   Actor actor = Actor::New();
2100   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
2101   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
2102   parent.Add(actor);
2103
2104   // Render and notify
2105   application.SendNotification();
2106   application.Render();
2107
2108   // Connect to actor's touched signal
2109   SignalData        data;
2110   TouchEventFunctor functor(data, false /* Do not consume */);
2111   actor.TouchedSignal().Connect(&application, functor);
2112
2113   // Connect to parent's touched signal
2114   SignalData        parentData;
2115   TouchEventFunctor parentFunctor(parentData, false /* Do not consume */);
2116   parent.TouchedSignal().Connect(&application, parentFunctor);
2117
2118   // Emit a down signal
2119   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
2120   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
2121   DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION);
2122
2123   data.Reset();
2124   parentData.Reset();
2125
2126   // Connect to parent's intercept touched signal
2127   SignalData        interceptData;
2128   TouchEventFunctor interceptFunctor(interceptData, true /* Do intercept */);
2129   Dali::DevelActor::InterceptTouchedSignal(parent).Connect(&application, interceptFunctor);
2130
2131   // Emit a down signal
2132   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(10.0f, 10.0f)));
2133
2134   // The actor gets interrupted. Because touch is intercepted by parent.
2135   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
2136   DALI_TEST_EQUALS(PointState::INTERRUPTED, data.receivedTouch.points[0].state, TEST_LOCATION);
2137   DALI_TEST_EQUALS(true, interceptData.functorCalled, TEST_LOCATION);
2138   DALI_TEST_EQUALS(PointState::DOWN, interceptData.receivedTouch.points[0].state, TEST_LOCATION);
2139   DALI_TEST_CHECK(actor == interceptData.receivedTouch.points[0].hitActor);
2140   DALI_TEST_CHECK(parent == interceptData.touchedActor);
2141   DALI_TEST_EQUALS(true, parentData.functorCalled, TEST_LOCATION);
2142   DALI_TEST_EQUALS(PointState::DOWN, parentData.receivedTouch.points[0].state, TEST_LOCATION);
2143   DALI_TEST_CHECK(actor == parentData.receivedTouch.points[0].hitActor);
2144   DALI_TEST_CHECK(parent == parentData.touchedActor);
2145   data.Reset();
2146   parentData.Reset();
2147
2148   END_TEST;
2149 }
2150
2151 int UtcDaliTouchAreaOffset(void)
2152 {
2153   TestApplication application;
2154
2155   Actor actor = Actor::New();
2156   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
2157   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
2158
2159   application.GetScene().Add(actor);
2160
2161   // Render and notify
2162   application.SendNotification();
2163   application.Render();
2164
2165   // Connect to actor's touched signal
2166   SignalData        data;
2167   TouchEventFunctor functor(data, false /* Do not consume */);
2168   actor.TouchedSignal().Connect(&application, functor);
2169
2170   // Emit a down signal
2171   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(110.0f, 110.0f)));
2172   // The actor touched signal is not called because the touch area is outside actor.
2173   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
2174   data.Reset();
2175
2176   // set a bigger touch area
2177   actor.SetProperty(DevelActor::Property::TOUCH_AREA_OFFSET, Rect<int>(-70, 70, 70, -70)); // left, right, bottom, top
2178
2179   // Render and notify
2180   application.SendNotification();
2181   application.Render();
2182
2183   // Emit a down signal
2184   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(150.0f, 150.0f)));
2185   // The actor touched signal is called because the touch area is inside touchArea.
2186   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
2187   DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION);
2188   DALI_TEST_CHECK(actor == data.receivedTouch.points[0].hitActor);
2189   data.Reset();
2190
2191   // set a offset touch area
2192   actor.SetProperty(DevelActor::Property::TOUCH_AREA_OFFSET, Rect<int>(50, 100, -50, 0)); // left, right, bottom, top
2193
2194   // Render and notify
2195   application.SendNotification();
2196   application.Render();
2197
2198   // Emit a down signal
2199   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(190.0f, 25.0f)));
2200   // The actor touched signal is called because the touch area is inside touchArea.
2201   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
2202   DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION);
2203   DALI_TEST_CHECK(actor == data.receivedTouch.points[0].hitActor);
2204   data.Reset();
2205
2206   // set a smaller touch area
2207   actor.SetProperty(DevelActor::Property::TOUCH_AREA_OFFSET, Rect<int>(50, 0, 0, 50));
2208
2209   // Render and notify
2210   application.SendNotification();
2211   application.Render();
2212
2213   // Emit a down signal
2214   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(40.0f, 40.0f)));
2215   // The actor touched signal is not called because the touch area is outside touchArea.
2216   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
2217   data.Reset();
2218
2219   // Emit a down signal
2220   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(90.0f, 90.0f)));
2221   // The actor touched signal is called because the touch area is inside touchArea.
2222   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
2223   DALI_TEST_EQUALS(PointState::DOWN, data.receivedTouch.points[0].state, TEST_LOCATION);
2224   DALI_TEST_CHECK(actor == data.receivedTouch.points[0].hitActor);
2225   data.Reset();
2226
2227   END_TEST;
2228 }