Add UserInteractionEnabled property on actor for controlling user interaction.
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-HoverProcessing.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/devel-api/events/hover-event-devel.h>
21 #include <dali/integration-api/events/hover-event-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_hover_processing_startup(void)
31 {
32   test_return_value = TET_UNDEF;
33 }
34
35 void utc_dali_hover_processing_cleanup(void)
36 {
37   test_return_value = TET_PASS;
38 }
39
40 ///////////////////////////////////////////////////////////////////////////////
41
42 namespace
43 {
44 // Stores data that is populated in the callback and will be read by the TET cases
45 struct SignalData
46 {
47   SignalData()
48   : functorCalled(false),
49     hoverEvent(),
50     hoveredActor()
51   {
52   }
53
54   void Reset()
55   {
56     functorCalled = false;
57     hoverEvent.Reset();
58     hoveredActor.Reset();
59   }
60
61   bool       functorCalled;
62   HoverEvent hoverEvent;
63   Actor      hoveredActor;
64 };
65
66 // Functor that sets the data when called
67 struct HoverEventFunctor
68 {
69   /**
70    * Constructor.
71    * @param[in]  data         Reference to the data to store callback information.
72    * @param[in]  returnValue  What the functor should return.
73    */
74   HoverEventFunctor(SignalData& data, bool returnValue = true)
75   : signalData(data),
76     returnValue(returnValue)
77   {
78   }
79
80   bool operator()(Actor actor, const HoverEvent& hoverEvent)
81   {
82     signalData.functorCalled = true;
83     signalData.hoveredActor  = actor;
84     signalData.hoverEvent    = hoverEvent;
85
86     return returnValue;
87   }
88
89   SignalData& signalData;
90   bool        returnValue;
91 };
92
93 // Functor that removes the actor when called.
94 struct RemoveActorFunctor : public HoverEventFunctor
95 {
96   /**
97    * Constructor.
98    * @param[in]  data         Reference to the data to store callback information.
99    * @param[in]  returnValue  What the functor should return.
100    */
101   RemoveActorFunctor(SignalData& data, bool returnValue = true)
102   : HoverEventFunctor(data, returnValue)
103   {
104   }
105
106   bool operator()(Actor actor, const HoverEvent& hoverEvent)
107   {
108     Actor parent(actor.GetParent());
109     if(parent)
110     {
111       parent.Remove(actor);
112     }
113
114     return HoverEventFunctor::operator()(actor, hoverEvent);
115   }
116 };
117
118 Integration::HoverEvent GenerateSingleHover(PointState::Type state, const Vector2& screenPosition)
119 {
120   Integration::HoverEvent hoverEvent;
121   Integration::Point      point;
122   point.SetState(state);
123   point.SetScreenPosition(screenPosition);
124   hoverEvent.points.push_back(point);
125   return hoverEvent;
126 }
127
128 } // namespace
129
130 ///////////////////////////////////////////////////////////////////////////////
131
132 int UtcDaliHoverNormalProcessing(void)
133 {
134   TestApplication application;
135
136   Actor actor = Actor::New();
137   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
138   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
139   application.GetScene().Add(actor);
140
141   // Render and notify
142   application.SendNotification();
143   application.Render();
144
145   // Connect to actor's hovered signal
146   SignalData        data;
147   HoverEventFunctor functor(data);
148   actor.HoveredSignal().Connect(&application, functor);
149
150   Vector2 screenCoordinates(10.0f, 10.0f);
151   Vector2 localCoordinates;
152   actor.ScreenToLocal(localCoordinates.x, localCoordinates.y, screenCoordinates.x, screenCoordinates.y);
153
154   // Emit a started signal
155   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, screenCoordinates));
156   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
157   DALI_TEST_EQUALS(1u, data.hoverEvent.GetPointCount(), TEST_LOCATION);
158   DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
159   DALI_TEST_EQUALS(screenCoordinates, data.hoverEvent.GetScreenPosition(0), TEST_LOCATION);
160   DALI_TEST_EQUALS(localCoordinates, data.hoverEvent.GetLocalPosition(0), 0.1f, TEST_LOCATION);
161   DALI_TEST_EQUALS(0, data.hoverEvent.GetDeviceId(0), TEST_LOCATION);
162   DALI_TEST_EQUALS(0u, data.hoverEvent.GetTime(), TEST_LOCATION);
163   DALI_TEST_EQUALS(actor, data.hoverEvent.GetHitActor(0), TEST_LOCATION);
164   DALI_TEST_EQUALS(-1, data.hoverEvent.GetDeviceId(1), TEST_LOCATION);
165   DALI_TEST_EQUALS(PointState::FINISHED, data.hoverEvent.GetState(1), TEST_LOCATION);
166   DALI_TEST_EQUALS(Vector2::ZERO, data.hoverEvent.GetScreenPosition(1), 0.1f, TEST_LOCATION);
167   DALI_TEST_EQUALS(Vector2::ZERO, data.hoverEvent.GetLocalPosition(1), 0.1f, TEST_LOCATION);
168   DALI_TEST_EQUALS(Dali::Actor(), data.hoverEvent.GetHitActor(1), TEST_LOCATION);
169   data.Reset();
170
171   // Emit a motion signal
172   screenCoordinates.x = screenCoordinates.y = 11.0f;
173   actor.ScreenToLocal(localCoordinates.x, localCoordinates.y, screenCoordinates.x, screenCoordinates.y);
174   application.ProcessEvent(GenerateSingleHover(PointState::MOTION, screenCoordinates));
175   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
176   DALI_TEST_EQUALS(1u, data.hoverEvent.GetPointCount(), TEST_LOCATION);
177   DALI_TEST_EQUALS(PointState::MOTION, data.hoverEvent.GetState(0), TEST_LOCATION);
178   DALI_TEST_EQUALS(screenCoordinates, data.hoverEvent.GetScreenPosition(0), TEST_LOCATION);
179   DALI_TEST_EQUALS(localCoordinates, data.hoverEvent.GetLocalPosition(0), 0.1f, TEST_LOCATION);
180   DALI_TEST_EQUALS(0, data.hoverEvent.GetDeviceId(0), TEST_LOCATION);
181   DALI_TEST_EQUALS(0u, data.hoverEvent.GetTime(), TEST_LOCATION);
182   DALI_TEST_EQUALS(actor, data.hoverEvent.GetHitActor(0), TEST_LOCATION);
183   DALI_TEST_EQUALS(-1, data.hoverEvent.GetDeviceId(1), TEST_LOCATION);
184   DALI_TEST_EQUALS(PointState::FINISHED, data.hoverEvent.GetState(1), TEST_LOCATION);
185   DALI_TEST_EQUALS(Vector2::ZERO, data.hoverEvent.GetScreenPosition(1), 0.1f, TEST_LOCATION);
186   DALI_TEST_EQUALS(Vector2::ZERO, data.hoverEvent.GetLocalPosition(1), 0.1f, TEST_LOCATION);
187   DALI_TEST_EQUALS(Dali::Actor(), data.hoverEvent.GetHitActor(1), TEST_LOCATION);
188   data.Reset();
189
190   // Emit a finished signal
191   screenCoordinates.x = screenCoordinates.y = 12.0f;
192   actor.ScreenToLocal(localCoordinates.x, localCoordinates.y, screenCoordinates.x, screenCoordinates.y);
193   application.ProcessEvent(GenerateSingleHover(PointState::FINISHED, screenCoordinates));
194   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
195   DALI_TEST_EQUALS(1u, data.hoverEvent.GetPointCount(), TEST_LOCATION);
196   DALI_TEST_EQUALS(PointState::FINISHED, data.hoverEvent.GetState(0), TEST_LOCATION);
197   DALI_TEST_EQUALS(screenCoordinates, data.hoverEvent.GetScreenPosition(0), TEST_LOCATION);
198   DALI_TEST_EQUALS(localCoordinates, data.hoverEvent.GetLocalPosition(0), 0.1f, TEST_LOCATION);
199   DALI_TEST_EQUALS(0, data.hoverEvent.GetDeviceId(0), TEST_LOCATION);
200   DALI_TEST_EQUALS(0u, data.hoverEvent.GetTime(), TEST_LOCATION);
201   DALI_TEST_EQUALS(actor, data.hoverEvent.GetHitActor(0), TEST_LOCATION);
202   DALI_TEST_EQUALS(-1, data.hoverEvent.GetDeviceId(1), TEST_LOCATION);
203   DALI_TEST_EQUALS(PointState::FINISHED, data.hoverEvent.GetState(1), TEST_LOCATION);
204   DALI_TEST_EQUALS(Vector2::ZERO, data.hoverEvent.GetScreenPosition(1), 0.1f, TEST_LOCATION);
205   DALI_TEST_EQUALS(Vector2::ZERO, data.hoverEvent.GetLocalPosition(1), 0.1f, TEST_LOCATION);
206   DALI_TEST_EQUALS(Dali::Actor(), data.hoverEvent.GetHitActor(1), TEST_LOCATION);
207   data.Reset();
208
209   // Emit a started signal where the actor is not present
210   screenCoordinates.x = screenCoordinates.y = 200.0f;
211   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, screenCoordinates));
212   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
213   DALI_TEST_CHECK(!data.hoverEvent);
214
215   END_TEST;
216 }
217
218 int UtcDaliHoverOutsideCameraNearFarPlanes(void)
219 {
220   TestApplication application;
221
222   Integration::Scene stage     = application.GetScene();
223   Vector2            stageSize = stage.GetSize();
224
225   Actor actor = Actor::New();
226   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
227   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
228   actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
229   stage.Add(actor);
230
231   // Render and notify
232   application.SendNotification();
233   application.Render();
234
235   // Get the camera's near and far planes
236   RenderTaskList   taskList  = stage.GetRenderTaskList();
237   Dali::RenderTask task      = taskList.GetTask(0);
238   CameraActor      camera    = task.GetCameraActor();
239   float            nearPlane = camera.GetNearClippingPlane();
240   float            farPlane  = camera.GetFarClippingPlane();
241
242   // Calculate the current distance of the actor from the camera
243   float tanHalfFov = tanf(camera.GetFieldOfView() * 0.5f);
244   float distance   = (stageSize.y * 0.5f) / tanHalfFov;
245
246   // Connect to actor's hovered signal
247   SignalData        data;
248   HoverEventFunctor functor(data);
249   actor.HoveredSignal().Connect(&application, functor);
250
251   Vector2 screenCoordinates(stageSize.x * 0.5f, stageSize.y * 0.5f);
252
253   // Emit a started signal
254   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, screenCoordinates));
255   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
256   data.Reset();
257
258   // Emit a started signal where actor is just at the camera's near plane
259   actor.SetProperty(Actor::Property::POSITION_Z, distance - nearPlane);
260
261   // Render and notify
262   application.SendNotification();
263   application.Render();
264
265   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, screenCoordinates));
266   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
267   data.Reset();
268
269   // Emit a started signal where actor is closer than the camera's near plane
270   actor.SetProperty(Actor::Property::POSITION_Z, (distance - nearPlane) + 1.0f);
271
272   // Render and notify
273   application.SendNotification();
274   application.Render();
275
276   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, screenCoordinates));
277   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
278   data.Reset();
279
280   // Emit a started signal where actor is just at the camera's far plane
281   actor.SetProperty(Actor::Property::POSITION_Z, distance - farPlane);
282
283   // Render and notify
284   application.SendNotification();
285   application.Render();
286
287   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, screenCoordinates));
288   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
289   data.Reset();
290
291   // Emit a started signal where actor is further than the camera's far plane
292   actor.SetProperty(Actor::Property::POSITION_Z, (distance - farPlane) - 1.0f);
293
294   // Render and notify
295   application.SendNotification();
296   application.Render();
297
298   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, screenCoordinates));
299   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
300   data.Reset();
301   END_TEST;
302 }
303
304 int UtcDaliHoverEmitEmpty(void)
305 {
306   TestApplication application;
307
308   try
309   {
310     // Emit an empty HoverEvent
311     Integration::HoverEvent event;
312     application.ProcessEvent(event);
313     tet_result(TET_FAIL);
314   }
315   catch(Dali::DaliException& e)
316   {
317     DALI_TEST_ASSERT(e, "!event.points.empty()", TEST_LOCATION);
318   }
319   END_TEST;
320 }
321
322 int UtcDaliHoverInterrupted(void)
323 {
324   TestApplication application;
325
326   Actor actor = Actor::New();
327   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
328   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
329   application.GetScene().Add(actor);
330
331   // Render and notify
332   application.SendNotification();
333   application.Render();
334
335   // Connect to actor's hovered signal
336   SignalData        data;
337   HoverEventFunctor functor(data);
338   actor.HoveredSignal().Connect(&application, functor);
339
340   // Emit a started signal
341   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
342   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
343   DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
344   data.Reset();
345
346   // Emit an interrupted signal, we should be signalled regardless of whether there is a hit or not.
347   application.ProcessEvent(GenerateSingleHover(PointState::INTERRUPTED, Vector2(200.0f, 200.0f /* Outside actor */)));
348   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
349   DALI_TEST_EQUALS(PointState::INTERRUPTED, data.hoverEvent.GetState(0), TEST_LOCATION);
350   data.Reset();
351
352   // Emit another interrupted signal, our signal handler should not be called.
353   application.ProcessEvent(GenerateSingleHover(PointState::INTERRUPTED, Vector2(200.0f, 200.0f)));
354   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
355   END_TEST;
356 }
357
358 int UtcDaliHoverParentConsumer(void)
359 {
360   TestApplication application;
361   Actor           rootActor(application.GetScene().GetRootLayer());
362
363   Actor actor = Actor::New();
364   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
365   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
366   application.GetScene().Add(actor);
367
368   // Render and notify
369   application.SendNotification();
370   application.Render();
371
372   // Connect to actor's hovered signal
373   SignalData        data;
374   HoverEventFunctor functor(data, false);
375   actor.HoveredSignal().Connect(&application, functor);
376
377   // Connect to root actor's hovered signal
378   SignalData        rootData;
379   HoverEventFunctor rootFunctor(rootData); // Consumes signal
380   rootActor.HoveredSignal().Connect(&application, rootFunctor);
381
382   Vector2 screenCoordinates(10.0f, 10.0f);
383   Vector2 actorCoordinates, rootCoordinates;
384   actor.ScreenToLocal(actorCoordinates.x, actorCoordinates.y, screenCoordinates.x, screenCoordinates.y);
385   rootActor.ScreenToLocal(rootCoordinates.x, rootCoordinates.y, screenCoordinates.x, screenCoordinates.y);
386
387   // Emit a started signal
388   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, screenCoordinates));
389   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
390   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
391   DALI_TEST_EQUALS(1u, data.hoverEvent.GetPointCount(), TEST_LOCATION);
392   DALI_TEST_EQUALS(1u, rootData.hoverEvent.GetPointCount(), TEST_LOCATION);
393   DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
394   DALI_TEST_EQUALS(PointState::STARTED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
395   DALI_TEST_EQUALS(screenCoordinates, data.hoverEvent.GetScreenPosition(0), TEST_LOCATION);
396   DALI_TEST_EQUALS(screenCoordinates, rootData.hoverEvent.GetScreenPosition(0), TEST_LOCATION);
397   DALI_TEST_EQUALS(actorCoordinates, data.hoverEvent.GetLocalPosition(0), 0.1f, TEST_LOCATION);
398   DALI_TEST_EQUALS(rootCoordinates, rootData.hoverEvent.GetLocalPosition(0), 0.1f, TEST_LOCATION);
399   DALI_TEST_CHECK(actor == data.hoverEvent.GetHitActor(0));
400   DALI_TEST_CHECK(actor == rootData.hoverEvent.GetHitActor(0));
401   data.Reset();
402   rootData.Reset();
403
404   // Emit a motion signal
405   screenCoordinates.x = screenCoordinates.y = 11.0f;
406   actor.ScreenToLocal(actorCoordinates.x, actorCoordinates.y, screenCoordinates.x, screenCoordinates.y);
407   rootActor.ScreenToLocal(rootCoordinates.x, rootCoordinates.y, screenCoordinates.x, screenCoordinates.y);
408   application.ProcessEvent(GenerateSingleHover(PointState::MOTION, screenCoordinates));
409   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
410   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
411   DALI_TEST_EQUALS(1u, data.hoverEvent.GetPointCount(), TEST_LOCATION);
412   DALI_TEST_EQUALS(1u, rootData.hoverEvent.GetPointCount(), TEST_LOCATION);
413   DALI_TEST_EQUALS(PointState::MOTION, data.hoverEvent.GetState(0), TEST_LOCATION);
414   DALI_TEST_EQUALS(PointState::MOTION, rootData.hoverEvent.GetState(0), TEST_LOCATION);
415   DALI_TEST_EQUALS(screenCoordinates, data.hoverEvent.GetScreenPosition(0), TEST_LOCATION);
416   DALI_TEST_EQUALS(screenCoordinates, rootData.hoverEvent.GetScreenPosition(0), TEST_LOCATION);
417   DALI_TEST_EQUALS(actorCoordinates, data.hoverEvent.GetLocalPosition(0), 0.1f, TEST_LOCATION);
418   DALI_TEST_EQUALS(rootCoordinates, rootData.hoverEvent.GetLocalPosition(0), 0.1f, TEST_LOCATION);
419   DALI_TEST_CHECK(actor == data.hoverEvent.GetHitActor(0));
420   DALI_TEST_CHECK(actor == rootData.hoverEvent.GetHitActor(0));
421   data.Reset();
422   rootData.Reset();
423
424   // Emit a finished signal
425   screenCoordinates.x = screenCoordinates.y = 12.0f;
426   actor.ScreenToLocal(actorCoordinates.x, actorCoordinates.y, screenCoordinates.x, screenCoordinates.y);
427   rootActor.ScreenToLocal(rootCoordinates.x, rootCoordinates.y, screenCoordinates.x, screenCoordinates.y);
428   application.ProcessEvent(GenerateSingleHover(PointState::FINISHED, screenCoordinates));
429   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
430   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
431   DALI_TEST_EQUALS(1u, data.hoverEvent.GetPointCount(), TEST_LOCATION);
432   DALI_TEST_EQUALS(1u, rootData.hoverEvent.GetPointCount(), TEST_LOCATION);
433   DALI_TEST_EQUALS(PointState::FINISHED, data.hoverEvent.GetState(0), TEST_LOCATION);
434   DALI_TEST_EQUALS(PointState::FINISHED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
435   DALI_TEST_EQUALS(screenCoordinates, data.hoverEvent.GetScreenPosition(0), TEST_LOCATION);
436   DALI_TEST_EQUALS(screenCoordinates, rootData.hoverEvent.GetScreenPosition(0), TEST_LOCATION);
437   DALI_TEST_EQUALS(actorCoordinates, data.hoverEvent.GetLocalPosition(0), 0.1f, TEST_LOCATION);
438   DALI_TEST_EQUALS(rootCoordinates, rootData.hoverEvent.GetLocalPosition(0), 0.1f, TEST_LOCATION);
439   DALI_TEST_CHECK(actor == data.hoverEvent.GetHitActor(0));
440   DALI_TEST_CHECK(actor == rootData.hoverEvent.GetHitActor(0));
441   data.Reset();
442   rootData.Reset();
443
444   // Emit a started signal where the actor is not present, will hit the root actor though
445   screenCoordinates.x = screenCoordinates.y = 200.0f;
446   rootActor.ScreenToLocal(rootCoordinates.x, rootCoordinates.y, screenCoordinates.x, screenCoordinates.y);
447   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, screenCoordinates));
448   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
449   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
450   DALI_TEST_EQUALS(1u, rootData.hoverEvent.GetPointCount(), TEST_LOCATION);
451   DALI_TEST_EQUALS(PointState::STARTED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
452   DALI_TEST_EQUALS(screenCoordinates, rootData.hoverEvent.GetScreenPosition(0), TEST_LOCATION);
453   DALI_TEST_EQUALS(rootCoordinates, rootData.hoverEvent.GetLocalPosition(0), 0.1f, TEST_LOCATION);
454   DALI_TEST_CHECK(rootActor == rootData.hoverEvent.GetHitActor(0));
455   END_TEST;
456 }
457
458 int UtcDaliHoverInterruptedParentConsumer(void)
459 {
460   TestApplication application;
461   Actor           rootActor(application.GetScene().GetRootLayer());
462
463   Actor actor = Actor::New();
464   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
465   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
466   application.GetScene().Add(actor);
467
468   // Render and notify
469   application.SendNotification();
470   application.Render();
471
472   // Connect to actor's hovered signal
473   SignalData        data;
474   HoverEventFunctor functor(data, false);
475   actor.HoveredSignal().Connect(&application, functor);
476
477   // Connect to root actor's hovered signal
478   SignalData        rootData;
479   HoverEventFunctor rootFunctor(rootData); // Consumes signal
480   rootActor.HoveredSignal().Connect(&application, rootFunctor);
481
482   // Emit a started signal
483   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
484   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
485   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
486   DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
487   DALI_TEST_EQUALS(PointState::STARTED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
488   DALI_TEST_CHECK(actor == data.hoverEvent.GetHitActor(0));
489   DALI_TEST_CHECK(actor == rootData.hoverEvent.GetHitActor(0));
490   data.Reset();
491   rootData.Reset();
492
493   // Emit an interrupted signal
494   application.ProcessEvent(GenerateSingleHover(PointState::INTERRUPTED, Vector2(200.0f, 200.0f)));
495   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
496   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
497   DALI_TEST_EQUALS(PointState::INTERRUPTED, data.hoverEvent.GetState(0), TEST_LOCATION);
498   DALI_TEST_EQUALS(PointState::INTERRUPTED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
499   DALI_TEST_CHECK(actor == data.hoverEvent.GetHitActor(0));
500   DALI_TEST_CHECK(actor == rootData.hoverEvent.GetHitActor(0));
501   data.Reset();
502   rootData.Reset();
503
504   // Emit another started signal
505   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
506   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
507   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
508   DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
509   DALI_TEST_EQUALS(PointState::STARTED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
510   data.Reset();
511   rootData.Reset();
512
513   // Remove actor from Stage
514   application.GetScene().Remove(actor);
515
516   // Render and notify
517   application.SendNotification();
518   application.Render();
519
520   // Emit an interrupted signal, only root actor's signal should be called.
521   application.ProcessEvent(GenerateSingleHover(PointState::INTERRUPTED, Vector2(200.0f, 200.0f /* Outside actor */)));
522   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
523   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
524   DALI_TEST_EQUALS(PointState::INTERRUPTED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
525   DALI_TEST_CHECK(rootActor == rootData.hoverEvent.GetHitActor(0));
526   data.Reset();
527   rootData.Reset();
528
529   // Emit another interrupted state, none of the signal's should be called.
530   application.ProcessEvent(GenerateSingleHover(PointState::INTERRUPTED, Vector2(200.0f, 200.0f)));
531   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
532   DALI_TEST_EQUALS(false, rootData.functorCalled, TEST_LOCATION);
533   END_TEST;
534 }
535
536 int UtcDaliHoverLeave(void)
537 {
538   TestApplication application;
539
540   Actor actor = Actor::New();
541   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
542   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
543   application.GetScene().Add(actor);
544
545   // Render and notify
546   application.SendNotification();
547   application.Render();
548
549   // Connect to actor's hovered signal
550   SignalData        data;
551   HoverEventFunctor functor(data);
552   actor.HoveredSignal().Connect(&application, functor);
553
554   // Set actor to require leave events
555   actor.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
556
557   // Emit a started signal
558   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
559   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
560   DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
561   data.Reset();
562
563   // Emit a motion signal outside of actor, should be signalled with a Leave
564   application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(200.0f, 200.0f)));
565   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
566   DALI_TEST_EQUALS(PointState::LEAVE, data.hoverEvent.GetState(0), TEST_LOCATION);
567   data.Reset();
568
569   // Another motion outside of actor, no signalling
570   application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(201.0f, 201.0f)));
571   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
572   data.Reset();
573
574   // Another motion event inside actor, signalled with motion
575   application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(10.0f, 10.0f)));
576   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
577   DALI_TEST_EQUALS(PointState::MOTION, data.hoverEvent.GetState(0), TEST_LOCATION);
578   data.Reset();
579
580   // We do not want to listen to leave events anymore
581   actor.SetProperty(Actor::Property::LEAVE_REQUIRED, false);
582
583   // Another motion event outside of actor, no signalling
584   application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(200.0f, 200.0f)));
585   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
586   data.Reset();
587   END_TEST;
588 }
589
590 int UtcDaliHoverLeaveParentConsumer(void)
591 {
592   TestApplication application;
593   Actor           rootActor(application.GetScene().GetRootLayer());
594
595   Actor actor = Actor::New();
596   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
597   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
598   application.GetScene().Add(actor);
599
600   // Render and notify
601   application.SendNotification();
602   application.Render();
603
604   // Connect to actor's hovered signal
605   SignalData        data;
606   HoverEventFunctor functor(data, false);
607   actor.HoveredSignal().Connect(&application, functor);
608
609   // Connect to root actor's hovered signal
610   SignalData        rootData;
611   HoverEventFunctor rootFunctor(rootData); // Consumes signal
612   rootActor.HoveredSignal().Connect(&application, rootFunctor);
613
614   // Set actor to require leave events
615   actor.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
616   rootActor.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
617
618   // Emit a started signal
619   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
620   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
621   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
622   DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
623   DALI_TEST_EQUALS(PointState::STARTED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
624   DALI_TEST_CHECK(actor == data.hoverEvent.GetHitActor(0));
625   DALI_TEST_CHECK(actor == rootData.hoverEvent.GetHitActor(0));
626   data.Reset();
627   rootData.Reset();
628
629   // Emit a motion signal outside of actor, should be signalled with a Leave
630   application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(200.0f, 200.0f)));
631   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
632   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
633   DALI_TEST_EQUALS(PointState::LEAVE, data.hoverEvent.GetState(0), TEST_LOCATION);
634   DALI_TEST_EQUALS(PointState::LEAVE, rootData.hoverEvent.GetState(0), TEST_LOCATION);
635   DALI_TEST_CHECK(actor == data.hoverEvent.GetHitActor(0));
636   DALI_TEST_CHECK(actor == rootData.hoverEvent.GetHitActor(0));
637   data.Reset();
638   rootData.Reset();
639
640   // Another motion outside of actor, only rootActor signalled
641   application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(201.0f, 201.0f)));
642   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
643   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
644   DALI_TEST_EQUALS(PointState::MOTION, rootData.hoverEvent.GetState(0), TEST_LOCATION);
645   DALI_TEST_CHECK(rootActor == rootData.hoverEvent.GetHitActor(0));
646   data.Reset();
647   rootData.Reset();
648
649   // Another motion event inside actor, signalled with motion
650   application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(10.0f, 10.0f)));
651   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
652   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
653   DALI_TEST_EQUALS(PointState::MOTION, data.hoverEvent.GetState(0), TEST_LOCATION);
654   DALI_TEST_EQUALS(PointState::MOTION, rootData.hoverEvent.GetState(0), TEST_LOCATION);
655   DALI_TEST_CHECK(actor == data.hoverEvent.GetHitActor(0));
656   DALI_TEST_CHECK(actor == rootData.hoverEvent.GetHitActor(0));
657   data.Reset();
658   rootData.Reset();
659
660   // We do not want to listen to leave events of actor anymore
661   actor.SetProperty(Actor::Property::LEAVE_REQUIRED, false);
662
663   // Another motion event outside of root actor, only root signalled
664   Vector2 stageSize(application.GetScene().GetSize());
665   application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(stageSize.width + 10.0f, stageSize.height + 10.0f)));
666   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
667   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
668   DALI_TEST_EQUALS(PointState::LEAVE, rootData.hoverEvent.GetState(0), TEST_LOCATION);
669   END_TEST;
670 }
671
672 int UtcDaliHoverActorBecomesInsensitive(void)
673 {
674   TestApplication application;
675
676   Actor actor = Actor::New();
677   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
678   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
679   application.GetScene().Add(actor);
680
681   // Render and notify
682   application.SendNotification();
683   application.Render();
684
685   // Connect to actor's hovered signal
686   SignalData        data;
687   HoverEventFunctor functor(data);
688   actor.HoveredSignal().Connect(&application, functor);
689
690   // Emit a started signal
691   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
692   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
693   DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
694   data.Reset();
695
696   // Change actor to insensitive
697   actor.SetProperty(Actor::Property::SENSITIVE, false);
698
699   // Emit a motion signal, signalled with an interrupted
700   application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(200.0f, 200.0f)));
701   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
702   DALI_TEST_EQUALS(PointState::INTERRUPTED, data.hoverEvent.GetState(0), TEST_LOCATION);
703   data.Reset();
704   END_TEST;
705 }
706
707 int UtcDaliHoverActorBecomesInsensitiveParentConsumer(void)
708 {
709   TestApplication application;
710   Actor           rootActor(application.GetScene().GetRootLayer());
711
712   Actor actor = Actor::New();
713   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
714   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
715   application.GetScene().Add(actor);
716
717   // Render and notify
718   application.SendNotification();
719   application.Render();
720
721   // Connect to actor's hovered signal
722   SignalData        data;
723   HoverEventFunctor functor(data, false);
724   actor.HoveredSignal().Connect(&application, functor);
725
726   // Connect to root actor's hovered signal
727   SignalData        rootData;
728   HoverEventFunctor rootFunctor(rootData); // Consumes signal
729   rootActor.HoveredSignal().Connect(&application, rootFunctor);
730
731   // Emit a started signal
732   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
733   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
734   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
735   DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
736   DALI_TEST_EQUALS(PointState::STARTED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
737   DALI_TEST_CHECK(actor == data.hoverEvent.GetHitActor(0));
738   DALI_TEST_CHECK(actor == rootData.hoverEvent.GetHitActor(0));
739   data.Reset();
740   rootData.Reset();
741
742   // Remove actor from Stage
743   application.GetScene().Remove(actor);
744
745   // Render and notify
746   application.SendNotification();
747   application.Render();
748
749   // Make root actor insensitive
750   rootActor.SetProperty(Actor::Property::SENSITIVE, false);
751
752   // Emit a motion signal, signalled with an interrupted (should get interrupted even if within root actor)
753   application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(200.0f, 200.0f)));
754   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
755   DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
756   DALI_TEST_EQUALS(PointState::INTERRUPTED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
757   END_TEST;
758 }
759
760 int UtcDaliHoverActorBecomesUserInteractionDisabled(void)
761 {
762   TestApplication application;
763
764   Actor actor = Actor::New();
765   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
766   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
767   application.GetScene().Add(actor);
768
769   // Render and notify
770   application.SendNotification();
771   application.Render();
772
773   // Connect to actor's hovered signal
774   SignalData        data;
775   HoverEventFunctor functor(data);
776   actor.HoveredSignal().Connect(&application, functor);
777
778   // Emit a started signal
779   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
780   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
781   DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
782   data.Reset();
783
784   // Change actor to disable user interaction.
785   actor.SetProperty(DevelActor::Property::USER_INTERACTION_ENABLED, false);
786
787   // Emit a motion signal, signalled with an interrupted
788   application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(200.0f, 200.0f)));
789   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
790   DALI_TEST_EQUALS(PointState::INTERRUPTED, data.hoverEvent.GetState(0), TEST_LOCATION);
791   data.Reset();
792   END_TEST;
793 }
794
795 int UtcDaliHoverMultipleLayers(void)
796 {
797   TestApplication application;
798   Actor           rootActor(application.GetScene().GetRootLayer());
799
800   // Connect to actor's hovered signal
801   SignalData        data;
802   HoverEventFunctor functor(data);
803
804   Layer layer1(Layer::New());
805   layer1.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
806   layer1.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
807   application.GetScene().Add(layer1);
808
809   Actor actor1(Actor::New());
810   actor1.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
811   actor1.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
812   actor1.SetProperty(Actor::Property::POSITION_Z, 1.0f); // Should hit actor1 in this layer
813   layer1.Add(actor1);
814
815   // Render and notify
816   application.SendNotification();
817   application.Render();
818
819   // Connect to layer1 and actor1
820   layer1.HoveredSignal().Connect(&application, functor);
821   actor1.HoveredSignal().Connect(&application, functor);
822
823   // Hit in hittable area, actor1 should be hit
824   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
825   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
826   DALI_TEST_CHECK(data.hoveredActor == actor1);
827   data.Reset();
828
829   // Make layer1 insensitive, nothing should be hit
830   layer1.SetProperty(Actor::Property::SENSITIVE, false);
831   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
832   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
833   data.Reset();
834
835   // Make layer1 sensitive again, again actor1 will be hit
836   layer1.SetProperty(Actor::Property::SENSITIVE, true);
837   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
838   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
839   DALI_TEST_CHECK(data.hoveredActor == actor1);
840   data.Reset();
841
842   // Make rootActor insensitive, nothing should be hit
843   rootActor.SetProperty(Actor::Property::SENSITIVE, false);
844   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
845   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
846   data.Reset();
847
848   // Make rootActor sensitive
849   rootActor.SetProperty(Actor::Property::SENSITIVE, true);
850
851   // Add another layer
852   Layer layer2(Layer::New());
853   layer2.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
854   layer2.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
855   layer2.SetProperty(Actor::Property::POSITION_Z, 10.0f); // Should hit layer2 in this layer rather than actor2
856   application.GetScene().Add(layer2);
857
858   Actor actor2(Actor::New());
859   actor2.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
860   actor2.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
861   layer2.Add(actor2);
862
863   // Render and notify
864   application.SendNotification();
865   application.Render();
866
867   // Connect to layer2 and actor2
868   layer2.HoveredSignal().Connect(&application, functor);
869   actor2.HoveredSignal().Connect(&application, functor);
870
871   // Emit an event, should hit layer2
872   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
873   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
874   //DALI_TEST_CHECK( data.hoveredActor == layer2 ); // TODO: Uncomment this after removing renderable hack!
875   data.Reset();
876
877   // Make layer2 insensitive, should hit actor1
878   layer2.SetProperty(Actor::Property::SENSITIVE, false);
879   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
880   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
881   DALI_TEST_CHECK(data.hoveredActor == actor1);
882   data.Reset();
883
884   // Make layer2 sensitive again, should hit layer2
885   layer2.SetProperty(Actor::Property::SENSITIVE, true);
886   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
887   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
888   //DALI_TEST_CHECK( data.hoveredActor == layer2 ); // TODO: Uncomment this after removing renderable hack!
889   data.Reset();
890
891   // Make layer2 invisible, render and notify
892   layer2.SetProperty(Actor::Property::VISIBLE, false);
893   application.SendNotification();
894   application.Render();
895
896   // Should hit actor1
897   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
898   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
899   DALI_TEST_CHECK(data.hoveredActor == actor1);
900   data.Reset();
901
902   // Make rootActor invisible, render and notify
903   rootActor.SetProperty(Actor::Property::VISIBLE, false);
904   application.SendNotification();
905   application.Render();
906
907   // Should not hit anything
908   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
909   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
910   data.Reset();
911   END_TEST;
912 }
913
914 int UtcDaliHoverMultipleRenderTasks(void)
915 {
916   TestApplication    application;
917   Integration::Scene stage(application.GetScene());
918   Vector2            stageSize(stage.GetSize());
919
920   Actor actor = Actor::New();
921   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
922   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
923   stage.Add(actor);
924
925   // Create render task
926   Viewport   viewport(stageSize.width * 0.5f, stageSize.height * 0.5f, stageSize.width * 0.5f, stageSize.height * 0.5f);
927   RenderTask renderTask(application.GetScene().GetRenderTaskList().CreateTask());
928   renderTask.SetViewport(viewport);
929   renderTask.SetInputEnabled(true);
930
931   // Render and notify
932   application.SendNotification();
933   application.Render();
934
935   // Connect to actor's hovered signal
936   SignalData        data;
937   HoverEventFunctor functor(data);
938   actor.HoveredSignal().Connect(&application, functor);
939
940   // Emit a started signal
941   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
942   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
943   data.Reset();
944
945   // Ensure renderTask actor can be hit too.
946   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(viewport.x + 5.0f, viewport.y + 5.0f)));
947   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
948   data.Reset();
949
950   // Disable input on renderTask, should not be hittable
951   renderTask.SetInputEnabled(false);
952   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(viewport.x + 5.0f, viewport.y + 5.0f)));
953   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
954   data.Reset();
955   END_TEST;
956 }
957
958 int UtcDaliHoverMultipleRenderTasksWithChildLayer(void)
959 {
960   TestApplication    application;
961   Integration::Scene stage(application.GetScene());
962   Vector2            stageSize(stage.GetSize());
963
964   Actor actor = Actor::New();
965   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
966   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
967   stage.Add(actor);
968
969   Layer layer = Layer::New();
970   layer.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
971   layer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
972   actor.Add(layer);
973
974   // Create render task
975   Viewport   viewport(stageSize.width * 0.5f, stageSize.height * 0.5f, stageSize.width * 0.5f, stageSize.height * 0.5f);
976   RenderTask renderTask(application.GetScene().GetRenderTaskList().CreateTask());
977   renderTask.SetViewport(viewport);
978   renderTask.SetInputEnabled(true);
979   renderTask.SetSourceActor(actor);
980
981   // Render and notify
982   application.SendNotification();
983   application.Render();
984
985   // Connect to layer's hovered signal
986   SignalData        data;
987   HoverEventFunctor functor(data);
988   actor.HoveredSignal().Connect(&application, functor);
989   layer.HoveredSignal().Connect(&application, functor);
990
991   // Emit a started signal
992   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
993   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
994   data.Reset();
995
996   // Ensure renderTask actor can be hit too.
997   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(viewport.x + 5.0f, viewport.y + 5.0f)));
998   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
999   data.Reset();
1000
1001   // Disable input on renderTask, should not be hittable
1002   renderTask.SetInputEnabled(false);
1003   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(viewport.x + 5.0f, viewport.y + 5.0f)));
1004   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1005   data.Reset();
1006   END_TEST;
1007 }
1008
1009 int UtcDaliHoverOffscreenRenderTasks(void)
1010 {
1011   TestApplication    application;
1012   Integration::Scene stage(application.GetScene());
1013   Vector2            stageSize(stage.GetSize());
1014
1015   // FrameBufferImage for offscreen RenderTask
1016   FrameBuffer frameBuffer = FrameBuffer::New(stageSize.width, stageSize.height);
1017
1018   // Create a renderable actor to display the FrameBufferImage
1019   Actor renderableActor = CreateRenderableActor(frameBuffer.GetColorTexture());
1020   renderableActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
1021   renderableActor.SetProperty(Actor::Property::SIZE, Vector2(stageSize.x, stageSize.y));
1022   renderableActor.ScaleBy(Vector3(1.0f, -1.0f, 1.0f)); // FIXME
1023   stage.Add(renderableActor);
1024
1025   Actor actor = Actor::New();
1026   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1027   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1028   stage.Add(actor);
1029   application.GetGlAbstraction().SetCheckFramebufferStatusResult(GL_FRAMEBUFFER_COMPLETE); // Ensure framebuffer connects
1030
1031   stage.GetRenderTaskList().GetTask(0u).SetScreenToFrameBufferFunction(RenderTask::FULLSCREEN_FRAMEBUFFER_FUNCTION);
1032
1033   // Create a RenderTask
1034   RenderTask renderTask = stage.GetRenderTaskList().CreateTask();
1035   renderTask.SetSourceActor(actor);
1036   renderTask.SetFrameBuffer(frameBuffer);
1037   renderTask.SetInputEnabled(true);
1038
1039   // Create another RenderTask
1040   RenderTask renderTask2(stage.GetRenderTaskList().CreateTask());
1041   renderTask2.SetInputEnabled(true);
1042
1043   // Render and notify
1044   application.SendNotification();
1045   application.Render();
1046
1047   // Connect to actor's hovered signal
1048   SignalData        data;
1049   HoverEventFunctor functor(data);
1050   actor.HoveredSignal().Connect(&application, functor);
1051
1052   // Emit a started signal
1053   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1054   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1055   data.Reset();
1056   END_TEST;
1057 }
1058
1059 int UtcDaliHoverMultipleRenderableActors(void)
1060 {
1061   TestApplication    application;
1062   Integration::Scene stage(application.GetScene());
1063   Vector2            stageSize(stage.GetSize());
1064
1065   Actor parent = CreateRenderableActor();
1066   parent.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1067   parent.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1068   stage.Add(parent);
1069
1070   Actor actor = CreateRenderableActor();
1071   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1072   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1073   parent.Add(actor);
1074
1075   // Render and notify
1076   application.SendNotification();
1077   application.Render();
1078
1079   // Connect to layer's hovered signal
1080   SignalData        data;
1081   HoverEventFunctor functor(data);
1082   parent.HoveredSignal().Connect(&application, functor);
1083   actor.HoveredSignal().Connect(&application, functor);
1084
1085   // Emit a started signal
1086   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1087   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1088   DALI_TEST_CHECK(actor == data.hoveredActor);
1089   END_TEST;
1090 }
1091
1092 int UtcDaliHoverActorRemovedInSignal(void)
1093 {
1094   TestApplication application;
1095
1096   Actor actor = Actor::New();
1097   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1098   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1099   application.GetScene().Add(actor);
1100
1101   // Render and notify
1102   application.SendNotification();
1103   application.Render();
1104
1105   // Connect to actor's hovered signal
1106   SignalData         data;
1107   RemoveActorFunctor functor(data);
1108   actor.HoveredSignal().Connect(&application, functor);
1109
1110   // Register for leave events
1111   actor.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
1112
1113   // Emit a started signal
1114   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1115   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1116   data.Reset();
1117
1118   // Re-add, render and notify
1119   application.GetScene().Add(actor);
1120   application.SendNotification();
1121   application.Render();
1122
1123   // Emit another signal outside of actor's area, should not get anything as the scene has changed.
1124   application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(210.0f, 210.0f)));
1125   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1126   data.Reset();
1127
1128   // Emit a started signal
1129   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1130   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1131   data.Reset();
1132
1133   // Render and notify
1134   application.SendNotification();
1135   application.Render();
1136
1137   // Emit another signal outside of actor's area, should not get anything as the scene has changed.
1138   application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(210.0f, 210.0f)));
1139   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1140   data.Reset();
1141
1142   // Re-add actor back to stage, render and notify
1143   application.GetScene().Add(actor);
1144   application.SendNotification();
1145   application.Render();
1146
1147   // Emit another started event
1148   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1149   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1150   data.Reset();
1151
1152   // Completely delete the actor
1153   actor.Reset();
1154
1155   // Emit event, should not crash and should not receive an event.
1156   application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(210.0f, 210.0f)));
1157   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1158   END_TEST;
1159 }
1160
1161 int UtcDaliHoverActorSignalNotConsumed(void)
1162 {
1163   TestApplication application;
1164
1165   Actor actor = Actor::New();
1166   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1167   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1168   application.GetScene().Add(actor);
1169
1170   // Render and notify
1171   application.SendNotification();
1172   application.Render();
1173
1174   // Connect to actor's hovered signal
1175   SignalData        data;
1176   HoverEventFunctor functor(data, false);
1177   actor.HoveredSignal().Connect(&application, functor);
1178
1179   // Emit a started signal
1180   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1181   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1182   END_TEST;
1183 }
1184
1185 int UtcDaliHoverActorUnStaged(void)
1186 {
1187   TestApplication application;
1188
1189   Actor actor = Actor::New();
1190   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1191   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1192   application.GetScene().Add(actor);
1193
1194   // Render and notify
1195   application.SendNotification();
1196   application.Render();
1197
1198   // Connect to actor's hovered signal
1199   SignalData        data;
1200   HoverEventFunctor functor(data);
1201   actor.HoveredSignal().Connect(&application, functor);
1202
1203   // Emit a started signal
1204   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1205   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1206   data.Reset();
1207
1208   // Remove actor from stage
1209   application.GetScene().Remove(actor);
1210
1211   // Render and notify
1212   application.SendNotification();
1213   application.Render();
1214
1215   // Emit a move at the same point, we should not be signalled.
1216   application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(10.0f, 10.0f)));
1217   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1218   data.Reset();
1219   END_TEST;
1220 }
1221
1222 int UtcDaliHoverLeaveActorReadded(void)
1223 {
1224   TestApplication    application;
1225   Integration::Scene stage = application.GetScene();
1226
1227   Actor actor = Actor::New();
1228   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1229   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1230   stage.Add(actor);
1231
1232   // Set actor to receive hover-events
1233   actor.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
1234
1235   // Render and notify
1236   application.SendNotification();
1237   application.Render();
1238
1239   // Connect to actor's hovered signal
1240   SignalData        data;
1241   HoverEventFunctor functor(data);
1242   actor.HoveredSignal().Connect(&application, functor);
1243
1244   // Emit a started and motion
1245   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1246   application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(11.0f, 10.0f)));
1247   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1248   data.Reset();
1249
1250   // Remove actor from stage and add again
1251   stage.Remove(actor);
1252   stage.Add(actor);
1253
1254   // Emit a motion within the actor's bounds
1255   application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(12.0f, 10.0f)));
1256   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1257   data.Reset();
1258
1259   // Emit a motion outside the actor's bounds
1260   application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(200.0f, 200.0f)));
1261   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1262   DALI_TEST_EQUALS(PointState::LEAVE, data.hoverEvent.GetState(0), TEST_LOCATION);
1263   data.Reset();
1264
1265   END_TEST;
1266 }
1267
1268 int UtcDaliHoverClippingActor(void)
1269 {
1270   TestApplication    application;
1271   Integration::Scene stage = application.GetScene();
1272
1273   Actor actor = Actor::New();
1274   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1275   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1276   stage.Add(actor);
1277
1278   Actor clippingActor = Actor::New();
1279   clippingActor.SetProperty(Actor::Property::SIZE, Vector2(50.0f, 50.0f));
1280   clippingActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1281   clippingActor.SetProperty(Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN);
1282   stage.Add(clippingActor);
1283
1284   // Add a child to the clipped region.
1285   Actor clippingChild = Actor::New();
1286   clippingChild.SetProperty(Actor::Property::SIZE, Vector2(50.0f, 50.0f));
1287   clippingChild.SetProperty(Actor::Property::POSITION, Vector2(25.0f, 25.0f));
1288   clippingChild.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1289   clippingActor.Add(clippingChild);
1290
1291   // Render and notify.
1292   application.SendNotification();
1293   application.Render();
1294
1295   // Connect to actor's hovered signal.
1296   SignalData        data;
1297   HoverEventFunctor functor(data);
1298   actor.HoveredSignal().Connect(&application, functor);
1299
1300   // Emit an event within clipped area - we should have a hit.
1301   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1302   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1303   data.Reset();
1304
1305   // Emit an event outside the clipped area but within the actor area, we should have a hit.
1306   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(60.0f, 60.0f)));
1307   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1308   data.Reset();
1309
1310   clippingChild.HoveredSignal().Connect(&application, functor);
1311
1312   // Emit an event inside part of the child which is within the clipped area, we should have a hit.
1313   application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(30.0f, 30.0f)));
1314   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1315   data.Reset();
1316
1317   END_TEST;
1318 }
1319
1320 int UtcDaliHoverEventCreate(void)
1321 {
1322   TestApplication application;
1323
1324   Dali::HoverEvent hoverEvent = DevelHoverEvent::New(100);
1325   DALI_TEST_CHECK(hoverEvent);
1326
1327   // Emit a started signal
1328   DALI_TEST_EQUALS(100, hoverEvent.GetTime(), TEST_LOCATION);
1329   DALI_TEST_EQUALS(0, hoverEvent.GetPointCount(), TEST_LOCATION);
1330
1331   END_TEST;
1332 }