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