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