Add devel API to create an initialized HoverEvent handle
[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/devel-api/events/hover-event-devel.h>
25 #include <dali-test-suite-utils.h>
26
27 using namespace Dali;
28
29 void utc_dali_hover_processing_startup(void)
30 {
31   test_return_value = TET_UNDEF;
32 }
33
34 void utc_dali_hover_processing_cleanup(void)
35 {
36   test_return_value = TET_PASS;
37 }
38
39 ///////////////////////////////////////////////////////////////////////////////
40
41 namespace
42 {
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 } // anon 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 UtcDaliHoverMultipleLayers(void)
761 {
762   TestApplication application;
763   Actor rootActor( application.GetScene().GetRootLayer() );
764
765   // Connect to actor's hovered signal
766   SignalData data;
767   HoverEventFunctor functor( data );
768
769   Layer layer1 ( Layer::New() );
770   layer1.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
771   layer1.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
772   application.GetScene().Add( layer1 );
773
774   Actor actor1 ( Actor::New() );
775   actor1.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
776   actor1.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
777   actor1.SetProperty( Actor::Property::POSITION_Z,  1.0f ); // Should hit actor1 in this layer
778   layer1.Add( actor1 );
779
780   // Render and notify
781   application.SendNotification();
782   application.Render();
783
784   // Connect to layer1 and actor1
785   layer1.HoveredSignal().Connect( &application, functor );
786   actor1.HoveredSignal().Connect( &application, functor );
787
788   // Hit in hittable area, actor1 should be hit
789   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( 10.0f, 10.0f ) ) );
790   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
791   DALI_TEST_CHECK( data.hoveredActor == actor1 );
792   data.Reset();
793
794   // Make layer1 insensitive, nothing should be hit
795   layer1.SetProperty( Actor::Property::SENSITIVE, false );
796   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( 10.0f, 10.0f ) ) );
797   DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
798   data.Reset();
799
800   // Make layer1 sensitive again, again actor1 will be hit
801   layer1.SetProperty( Actor::Property::SENSITIVE, true );
802   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( 10.0f, 10.0f ) ) );
803   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
804   DALI_TEST_CHECK( data.hoveredActor == actor1 );
805   data.Reset();
806
807   // Make rootActor insensitive, nothing should be hit
808   rootActor.SetProperty( Actor::Property::SENSITIVE, false );
809   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( 10.0f, 10.0f ) ) );
810   DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
811   data.Reset();
812
813   // Make rootActor sensitive
814   rootActor.SetProperty( Actor::Property::SENSITIVE, true );
815
816   // Add another layer
817   Layer layer2 ( Layer::New() );
818   layer2.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
819   layer2.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
820   layer2.SetProperty( Actor::Property::POSITION_Z,  10.0f ); // Should hit layer2 in this layer rather than actor2
821   application.GetScene().Add( layer2 );
822
823   Actor actor2 ( Actor::New() );
824   actor2.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
825   actor2.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
826   layer2.Add( actor2 );
827
828   // Render and notify
829   application.SendNotification();
830   application.Render();
831
832   // Connect to layer2 and actor2
833   layer2.HoveredSignal().Connect( &application, functor );
834   actor2.HoveredSignal().Connect( &application, functor );
835
836   // Emit an event, should hit layer2
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 == layer2 ); // TODO: Uncomment this after removing renderable hack!
840   data.Reset();
841
842   // Make layer2 insensitive, should hit actor1
843   layer2.SetProperty( Actor::Property::SENSITIVE, false );
844   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( 10.0f, 10.0f ) ) );
845   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
846   DALI_TEST_CHECK( data.hoveredActor == actor1 );
847   data.Reset();
848
849   // Make layer2 sensitive again, should hit layer2
850   layer2.SetProperty( Actor::Property::SENSITIVE, true );
851   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( 10.0f, 10.0f ) ) );
852   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
853   //DALI_TEST_CHECK( data.hoveredActor == layer2 ); // TODO: Uncomment this after removing renderable hack!
854   data.Reset();
855
856   // Make layer2 invisible, render and notify
857   layer2.SetProperty( Actor::Property::VISIBLE, false );
858   application.SendNotification();
859   application.Render();
860
861   // Should hit actor1
862   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( 10.0f, 10.0f ) ) );
863   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
864   DALI_TEST_CHECK( data.hoveredActor == actor1 );
865   data.Reset();
866
867   // Make rootActor invisible, render and notify
868   rootActor.SetProperty( Actor::Property::VISIBLE, false );
869   application.SendNotification();
870   application.Render();
871
872   // Should not hit anything
873   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( 10.0f, 10.0f ) ) );
874   DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
875   data.Reset();
876   END_TEST;
877 }
878
879 int UtcDaliHoverMultipleRenderTasks(void)
880 {
881   TestApplication application;
882   Integration::Scene stage ( application.GetScene() );
883   Vector2 stageSize ( stage.GetSize() );
884
885   Actor actor = Actor::New();
886   actor.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
887   actor.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
888   stage.Add(actor);
889
890   // Create render task
891   Viewport viewport( stageSize.width * 0.5f, stageSize.height * 0.5f, stageSize.width * 0.5f, stageSize.height * 0.5f );
892   RenderTask renderTask ( application.GetScene().GetRenderTaskList().CreateTask() );
893   renderTask.SetViewport( viewport );
894   renderTask.SetInputEnabled( true );
895
896   // Render and notify
897   application.SendNotification();
898   application.Render();
899
900   // Connect to actor's hovered signal
901   SignalData data;
902   HoverEventFunctor functor( data );
903   actor.HoveredSignal().Connect( &application, functor );
904
905   // Emit a started signal
906   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( 10.0f, 10.0f ) ) );
907   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
908   data.Reset();
909
910   // Ensure renderTask actor can be hit too.
911   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( viewport.x + 5.0f, viewport.y + 5.0f ) ) );
912   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
913   data.Reset();
914
915   // Disable input on renderTask, should not be hittable
916   renderTask.SetInputEnabled( false );
917   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( viewport.x + 5.0f, viewport.y + 5.0f ) ) );
918   DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
919   data.Reset();
920   END_TEST;
921 }
922
923 int UtcDaliHoverMultipleRenderTasksWithChildLayer(void)
924 {
925   TestApplication application;
926   Integration::Scene stage ( application.GetScene() );
927   Vector2 stageSize ( stage.GetSize() );
928
929   Actor actor = Actor::New();
930   actor.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
931   actor.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
932   stage.Add(actor);
933
934   Layer layer = Layer::New();
935   layer.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
936   layer.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
937   actor.Add(layer);
938
939   // Create render task
940   Viewport viewport( stageSize.width * 0.5f, stageSize.height * 0.5f, stageSize.width * 0.5f, stageSize.height * 0.5f );
941   RenderTask renderTask ( application.GetScene().GetRenderTaskList().CreateTask() );
942   renderTask.SetViewport( viewport );
943   renderTask.SetInputEnabled( true );
944   renderTask.SetSourceActor( actor );
945
946   // Render and notify
947   application.SendNotification();
948   application.Render();
949
950   // Connect to layer's hovered signal
951   SignalData data;
952   HoverEventFunctor functor( data );
953   actor.HoveredSignal().Connect( &application, functor );
954   layer.HoveredSignal().Connect( &application, functor );
955
956   // Emit a started signal
957   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( 10.0f, 10.0f ) ) );
958   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
959   data.Reset();
960
961   // Ensure renderTask actor can be hit too.
962   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( viewport.x + 5.0f, viewport.y + 5.0f ) ) );
963   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
964   data.Reset();
965
966   // Disable input on renderTask, should not be hittable
967   renderTask.SetInputEnabled( false );
968   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( viewport.x + 5.0f, viewport.y + 5.0f ) ) );
969   DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
970   data.Reset();
971   END_TEST;
972 }
973
974 int UtcDaliHoverOffscreenRenderTasks(void)
975 {
976   TestApplication application;
977   Integration::Scene stage ( application.GetScene() );
978   Vector2 stageSize ( stage.GetSize() );
979
980   // FrameBufferImage for offscreen RenderTask
981   FrameBuffer frameBuffer = FrameBuffer::New( stageSize.width, stageSize.height );
982
983   // Create a renderable actor to display the FrameBufferImage
984   Actor renderableActor = CreateRenderableActor(frameBuffer.GetColorTexture());
985   renderableActor.SetProperty( Actor::Property::PARENT_ORIGIN,ParentOrigin::CENTER);
986   renderableActor.SetProperty( Actor::Property::SIZE, Vector2( stageSize.x, stageSize.y ) );
987   renderableActor.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); // FIXME
988   stage.Add( renderableActor );
989
990   Actor actor = Actor::New();
991   actor.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
992   actor.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
993   stage.Add( actor );
994   application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE ); // Ensure framebuffer connects
995
996   stage.GetRenderTaskList().GetTask( 0u ).SetScreenToFrameBufferFunction( RenderTask::FULLSCREEN_FRAMEBUFFER_FUNCTION );
997
998   // Create a RenderTask
999   RenderTask renderTask = stage.GetRenderTaskList().CreateTask();
1000   renderTask.SetSourceActor( actor );
1001   renderTask.SetFrameBuffer(frameBuffer);
1002   renderTask.SetInputEnabled( true );
1003
1004   // Create another RenderTask
1005   RenderTask renderTask2( stage.GetRenderTaskList().CreateTask() );
1006   renderTask2.SetInputEnabled( true );
1007
1008   // Render and notify
1009   application.SendNotification();
1010   application.Render();
1011
1012   // Connect to actor's hovered signal
1013   SignalData data;
1014   HoverEventFunctor functor( data );
1015   actor.HoveredSignal().Connect( &application, functor );
1016
1017   // Emit a started signal
1018   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( 10.0f, 10.0f ) ) );
1019   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
1020   data.Reset();
1021   END_TEST;
1022 }
1023
1024 int UtcDaliHoverMultipleRenderableActors(void)
1025 {
1026   TestApplication application;
1027   Integration::Scene stage ( application.GetScene() );
1028   Vector2 stageSize ( stage.GetSize() );
1029
1030   Actor parent = CreateRenderableActor();
1031   parent.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
1032   parent.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
1033   stage.Add(parent);
1034
1035   Actor actor = CreateRenderableActor();
1036   actor.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
1037   actor.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
1038   parent.Add(actor);
1039
1040   // Render and notify
1041   application.SendNotification();
1042   application.Render();
1043
1044   // Connect to layer's hovered signal
1045   SignalData data;
1046   HoverEventFunctor functor( data );
1047   parent.HoveredSignal().Connect( &application, functor );
1048   actor.HoveredSignal().Connect( &application, functor );
1049
1050   // Emit a started signal
1051   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( 10.0f, 10.0f ) ) );
1052   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
1053   DALI_TEST_CHECK( actor == data.hoveredActor );
1054   END_TEST;
1055 }
1056
1057 int UtcDaliHoverActorRemovedInSignal(void)
1058 {
1059   TestApplication application;
1060
1061   Actor actor = Actor::New();
1062   actor.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
1063   actor.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
1064   application.GetScene().Add(actor);
1065
1066   // Render and notify
1067   application.SendNotification();
1068   application.Render();
1069
1070   // Connect to actor's hovered signal
1071   SignalData data;
1072   RemoveActorFunctor functor( data );
1073   actor.HoveredSignal().Connect( &application, functor );
1074
1075   // Register for leave events
1076   actor.SetProperty( Actor::Property::LEAVE_REQUIRED, true );
1077
1078   // Emit a started signal
1079   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( 10.0f, 10.0f ) ) );
1080   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
1081   data.Reset();
1082
1083   // Re-add, render and notify
1084   application.GetScene().Add(actor);
1085   application.SendNotification();
1086   application.Render();
1087
1088   // Emit another signal outside of actor's area, should not get anything as the scene has changed.
1089   application.ProcessEvent( GenerateSingleHover( PointState::MOTION, Vector2( 210.0f, 210.0f ) ) );
1090   DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
1091   data.Reset();
1092
1093   // Emit a started signal
1094   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( 10.0f, 10.0f ) ) );
1095   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
1096   data.Reset();
1097
1098   // Render and notify
1099   application.SendNotification();
1100   application.Render();
1101
1102   // Emit another signal outside of actor's area, should not get anything as the scene has changed.
1103   application.ProcessEvent( GenerateSingleHover( PointState::MOTION, Vector2( 210.0f, 210.0f ) ) );
1104   DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
1105   data.Reset();
1106
1107   // Re-add actor back to stage, render and notify
1108   application.GetScene().Add(actor);
1109   application.SendNotification();
1110   application.Render();
1111
1112   // Emit another started event
1113   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( 10.0f, 10.0f ) ) );
1114   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
1115   data.Reset();
1116
1117   // Completely delete the actor
1118   actor.Reset();
1119
1120   // Emit event, should not crash and should not receive an event.
1121   application.ProcessEvent( GenerateSingleHover( PointState::MOTION, Vector2( 210.0f, 210.0f ) ) );
1122   DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
1123   END_TEST;
1124 }
1125
1126 int UtcDaliHoverActorSignalNotConsumed(void)
1127 {
1128   TestApplication application;
1129
1130   Actor actor = Actor::New();
1131   actor.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
1132   actor.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
1133   application.GetScene().Add(actor);
1134
1135   // Render and notify
1136   application.SendNotification();
1137   application.Render();
1138
1139   // Connect to actor's hovered signal
1140   SignalData data;
1141   HoverEventFunctor functor( data, false );
1142   actor.HoveredSignal().Connect( &application, functor );
1143
1144   // Emit a started signal
1145   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( 10.0f, 10.0f ) ) );
1146   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
1147   END_TEST;
1148 }
1149
1150 int UtcDaliHoverActorUnStaged(void)
1151 {
1152   TestApplication application;
1153
1154   Actor actor = Actor::New();
1155   actor.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
1156   actor.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
1157   application.GetScene().Add(actor);
1158
1159   // Render and notify
1160   application.SendNotification();
1161   application.Render();
1162
1163   // Connect to actor's hovered signal
1164   SignalData data;
1165   HoverEventFunctor functor( data );
1166   actor.HoveredSignal().Connect( &application, functor );
1167
1168   // Emit a started signal
1169   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( 10.0f, 10.0f ) ) );
1170   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
1171   data.Reset();
1172
1173   // Remove actor from stage
1174   application.GetScene().Remove( actor );
1175
1176   // Render and notify
1177   application.SendNotification();
1178   application.Render();
1179
1180   // Emit a move at the same point, we should not be signalled.
1181   application.ProcessEvent( GenerateSingleHover( PointState::MOTION, Vector2( 10.0f, 10.0f ) ) );
1182   DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
1183   data.Reset();
1184   END_TEST;
1185 }
1186
1187 int UtcDaliHoverLeaveActorReadded(void)
1188 {
1189   TestApplication application;
1190   Integration::Scene stage = application.GetScene();
1191
1192   Actor actor = Actor::New();
1193   actor.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
1194   actor.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
1195   stage.Add(actor);
1196
1197   // Set actor to receive hover-events
1198   actor.SetProperty( Actor::Property::LEAVE_REQUIRED, true );
1199
1200   // Render and notify
1201   application.SendNotification();
1202   application.Render();
1203
1204   // Connect to actor's hovered signal
1205   SignalData data;
1206   HoverEventFunctor functor( data );
1207   actor.HoveredSignal().Connect( &application, functor );
1208
1209   // Emit a started and motion
1210   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( 10.0f, 10.0f ) ) );
1211   application.ProcessEvent( GenerateSingleHover( PointState::MOTION, Vector2( 11.0f, 10.0f ) ) );
1212   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
1213   data.Reset();
1214
1215   // Remove actor from stage and add again
1216   stage.Remove( actor );
1217   stage.Add( actor );
1218
1219   // Emit a motion within the actor's bounds
1220   application.ProcessEvent( GenerateSingleHover( PointState::MOTION, Vector2( 12.0f, 10.0f ) ) );
1221   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
1222   data.Reset();
1223
1224   // Emit a motion outside the actor's bounds
1225   application.ProcessEvent( GenerateSingleHover( PointState::MOTION, Vector2( 200.0f, 200.0f ) ) );
1226   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
1227   DALI_TEST_EQUALS( PointState::LEAVE, data.hoverEvent.GetState( 0 ), TEST_LOCATION );
1228   data.Reset();
1229
1230   END_TEST;
1231 }
1232
1233 int UtcDaliHoverClippingActor(void)
1234 {
1235   TestApplication application;
1236   Integration::Scene stage = application.GetScene();
1237
1238   Actor actor = Actor::New();
1239   actor.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
1240   actor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
1241   stage.Add( actor );
1242
1243   Actor clippingActor = Actor::New();
1244   clippingActor.SetProperty( Actor::Property::SIZE, Vector2( 50.0f, 50.0f ) );
1245   clippingActor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
1246   clippingActor.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
1247   stage.Add( clippingActor );
1248
1249   // Add a child to the clipped region.
1250   Actor clippingChild = Actor::New();
1251   clippingChild.SetProperty( Actor::Property::SIZE, Vector2( 50.0f, 50.0f ) );
1252   clippingChild.SetProperty( Actor::Property::POSITION, Vector2( 25.0f, 25.0f ));
1253   clippingChild.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
1254   clippingActor.Add( clippingChild );
1255
1256   // Render and notify.
1257   application.SendNotification();
1258   application.Render();
1259
1260   // Connect to actor's hovered signal.
1261   SignalData data;
1262   HoverEventFunctor functor( data );
1263   actor.HoveredSignal().Connect( &application, functor );
1264
1265   // Emit an event within clipped area - no hit.
1266   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( 10.0f, 10.0f ) ) );
1267   DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
1268   data.Reset();
1269
1270   // Emit an event outside the clipped area but within the actor area, we should have a hit.
1271   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( 60.0f, 60.0f ) ) );
1272   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
1273   data.Reset();
1274
1275   clippingChild.HoveredSignal().Connect( &application, functor );
1276
1277   // Emit an event inside part of the child which is within the clipped area, we should have a hit.
1278   application.ProcessEvent( GenerateSingleHover( PointState::STARTED, Vector2( 30.0f, 30.0f ) ) );
1279   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
1280   data.Reset();
1281
1282   END_TEST;
1283 }
1284
1285 int UtcDaliHoverEventCreate(void)
1286 {
1287   TestApplication application;
1288
1289   Dali::HoverEvent hoverEvent = DevelHoverEvent::New( 100 );
1290   DALI_TEST_CHECK( hoverEvent );
1291
1292   // Emit a started signal
1293   DALI_TEST_EQUALS( 100, hoverEvent.GetTime(), TEST_LOCATION );
1294   DALI_TEST_EQUALS( 0, hoverEvent.GetPointCount(), TEST_LOCATION );
1295
1296   END_TEST;
1297 }
1298