2 * Copyright (c) 2024 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <dali-test-suite-utils.h>
19 #include <dali/devel-api/actors/actor-devel.h>
20 #include <dali/devel-api/events/hover-event-devel.h>
21 #include <dali/integration-api/events/hover-event-integ.h>
22 #include <dali/integration-api/events/touch-integ.h>
23 #include <dali/integration-api/render-task-list-integ.h>
24 #include <dali/public-api/dali-core.h>
31 void utc_dali_hover_processing_startup(void)
33 test_return_value = TET_UNDEF;
36 void utc_dali_hover_processing_cleanup(void)
38 test_return_value = TET_PASS;
41 ///////////////////////////////////////////////////////////////////////////////
45 // Stores data that is populated in the callback and will be read by the TET cases
49 : functorCalled(false),
57 functorCalled = false;
63 HoverEvent hoverEvent;
67 // Functor that sets the data when called
68 struct HoverEventFunctor
72 * @param[in] data Reference to the data to store callback information.
73 * @param[in] returnValue What the functor should return.
75 HoverEventFunctor(SignalData& data, bool returnValue = true)
77 returnValue(returnValue)
81 bool operator()(Actor actor, const HoverEvent& hoverEvent)
83 signalData.functorCalled = true;
84 signalData.hoveredActor = actor;
85 signalData.hoverEvent = hoverEvent;
90 SignalData& signalData;
94 // Functor that removes the actor when called.
95 struct RemoveActorFunctor : public HoverEventFunctor
99 * @param[in] data Reference to the data to store callback information.
100 * @param[in] returnValue What the functor should return.
102 RemoveActorFunctor(SignalData& data, bool returnValue = true)
103 : HoverEventFunctor(data, returnValue)
107 bool operator()(Actor actor, const HoverEvent& hoverEvent)
109 Actor parent(actor.GetParent());
112 parent.Remove(actor);
115 return HoverEventFunctor::operator()(actor, hoverEvent);
119 Integration::HoverEvent GenerateSingleHover(PointState::Type state, const Vector2& screenPosition)
121 Integration::HoverEvent hoverEvent;
122 Integration::Point point;
123 point.SetState(state);
124 point.SetScreenPosition(screenPosition);
125 hoverEvent.points.push_back(point);
131 ///////////////////////////////////////////////////////////////////////////////
133 int UtcDaliHoverNormalProcessing(void)
135 TestApplication application;
137 Actor actor = Actor::New();
138 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
139 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
140 application.GetScene().Add(actor);
143 application.SendNotification();
144 application.Render();
146 // Connect to actor's hovered signal
148 HoverEventFunctor functor(data);
149 actor.HoveredSignal().Connect(&application, functor);
151 Vector2 screenCoordinates(10.0f, 10.0f);
152 Vector2 localCoordinates;
153 actor.ScreenToLocal(localCoordinates.x, localCoordinates.y, screenCoordinates.x, screenCoordinates.y);
155 // Emit a started signal
156 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, screenCoordinates));
157 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
158 DALI_TEST_EQUALS(1u, data.hoverEvent.GetPointCount(), TEST_LOCATION);
159 DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
160 DALI_TEST_EQUALS(screenCoordinates, data.hoverEvent.GetScreenPosition(0), TEST_LOCATION);
161 DALI_TEST_EQUALS(localCoordinates, data.hoverEvent.GetLocalPosition(0), 0.1f, TEST_LOCATION);
162 DALI_TEST_EQUALS(0, data.hoverEvent.GetDeviceId(0), TEST_LOCATION);
163 DALI_TEST_EQUALS(0u, data.hoverEvent.GetTime(), TEST_LOCATION);
164 DALI_TEST_EQUALS(actor, data.hoverEvent.GetHitActor(0), TEST_LOCATION);
165 DALI_TEST_EQUALS(-1, data.hoverEvent.GetDeviceId(1), TEST_LOCATION);
166 DALI_TEST_EQUALS(PointState::FINISHED, data.hoverEvent.GetState(1), TEST_LOCATION);
167 DALI_TEST_EQUALS(Vector2::ZERO, data.hoverEvent.GetScreenPosition(1), 0.1f, TEST_LOCATION);
168 DALI_TEST_EQUALS(Vector2::ZERO, data.hoverEvent.GetLocalPosition(1), 0.1f, TEST_LOCATION);
169 DALI_TEST_EQUALS(Dali::Actor(), data.hoverEvent.GetHitActor(1), TEST_LOCATION);
172 // Emit a motion signal
173 screenCoordinates.x = screenCoordinates.y = 11.0f;
174 actor.ScreenToLocal(localCoordinates.x, localCoordinates.y, screenCoordinates.x, screenCoordinates.y);
175 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, screenCoordinates));
176 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
177 DALI_TEST_EQUALS(1u, data.hoverEvent.GetPointCount(), TEST_LOCATION);
178 DALI_TEST_EQUALS(PointState::MOTION, data.hoverEvent.GetState(0), TEST_LOCATION);
179 DALI_TEST_EQUALS(screenCoordinates, data.hoverEvent.GetScreenPosition(0), TEST_LOCATION);
180 DALI_TEST_EQUALS(localCoordinates, data.hoverEvent.GetLocalPosition(0), 0.1f, TEST_LOCATION);
181 DALI_TEST_EQUALS(0, data.hoverEvent.GetDeviceId(0), TEST_LOCATION);
182 DALI_TEST_EQUALS(0u, data.hoverEvent.GetTime(), TEST_LOCATION);
183 DALI_TEST_EQUALS(actor, data.hoverEvent.GetHitActor(0), TEST_LOCATION);
184 DALI_TEST_EQUALS(-1, data.hoverEvent.GetDeviceId(1), TEST_LOCATION);
185 DALI_TEST_EQUALS(PointState::FINISHED, data.hoverEvent.GetState(1), TEST_LOCATION);
186 DALI_TEST_EQUALS(Vector2::ZERO, data.hoverEvent.GetScreenPosition(1), 0.1f, TEST_LOCATION);
187 DALI_TEST_EQUALS(Vector2::ZERO, data.hoverEvent.GetLocalPosition(1), 0.1f, TEST_LOCATION);
188 DALI_TEST_EQUALS(Dali::Actor(), data.hoverEvent.GetHitActor(1), TEST_LOCATION);
191 // Emit a finished signal
192 screenCoordinates.x = screenCoordinates.y = 12.0f;
193 actor.ScreenToLocal(localCoordinates.x, localCoordinates.y, screenCoordinates.x, screenCoordinates.y);
194 application.ProcessEvent(GenerateSingleHover(PointState::FINISHED, screenCoordinates));
195 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
196 DALI_TEST_EQUALS(1u, data.hoverEvent.GetPointCount(), TEST_LOCATION);
197 DALI_TEST_EQUALS(PointState::FINISHED, data.hoverEvent.GetState(0), TEST_LOCATION);
198 DALI_TEST_EQUALS(screenCoordinates, data.hoverEvent.GetScreenPosition(0), TEST_LOCATION);
199 DALI_TEST_EQUALS(localCoordinates, data.hoverEvent.GetLocalPosition(0), 0.1f, TEST_LOCATION);
200 DALI_TEST_EQUALS(0, data.hoverEvent.GetDeviceId(0), TEST_LOCATION);
201 DALI_TEST_EQUALS(0u, data.hoverEvent.GetTime(), TEST_LOCATION);
202 DALI_TEST_EQUALS(actor, data.hoverEvent.GetHitActor(0), TEST_LOCATION);
203 DALI_TEST_EQUALS(-1, data.hoverEvent.GetDeviceId(1), TEST_LOCATION);
204 DALI_TEST_EQUALS(PointState::FINISHED, data.hoverEvent.GetState(1), TEST_LOCATION);
205 DALI_TEST_EQUALS(Vector2::ZERO, data.hoverEvent.GetScreenPosition(1), 0.1f, TEST_LOCATION);
206 DALI_TEST_EQUALS(Vector2::ZERO, data.hoverEvent.GetLocalPosition(1), 0.1f, TEST_LOCATION);
207 DALI_TEST_EQUALS(Dali::Actor(), data.hoverEvent.GetHitActor(1), TEST_LOCATION);
210 // Emit a started signal where the actor is not present
211 screenCoordinates.x = screenCoordinates.y = 200.0f;
212 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, screenCoordinates));
213 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
214 DALI_TEST_CHECK(!data.hoverEvent);
219 int UtcDaliHoverOutsideCameraNearFarPlanes(void)
221 TestApplication application;
223 Integration::Scene stage = application.GetScene();
224 Vector2 stageSize = stage.GetSize();
226 Actor actor = Actor::New();
227 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
228 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
229 actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
233 application.SendNotification();
234 application.Render();
236 // Get the camera's near and far planes
237 RenderTaskList taskList = stage.GetRenderTaskList();
238 Dali::RenderTask task = taskList.GetTask(0);
239 CameraActor camera = task.GetCameraActor();
240 float nearPlane = camera.GetNearClippingPlane();
241 float farPlane = camera.GetFarClippingPlane();
243 // Calculate the current distance of the actor from the camera
244 float tanHalfFov = tanf(camera.GetFieldOfView() * 0.5f);
245 float distance = (stageSize.y * 0.5f) / tanHalfFov;
247 // Connect to actor's hovered signal
249 HoverEventFunctor functor(data);
250 actor.HoveredSignal().Connect(&application, functor);
252 Vector2 screenCoordinates(stageSize.x * 0.5f, stageSize.y * 0.5f);
254 // Emit a started signal
255 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, screenCoordinates));
256 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
259 // Emit a started signal where actor is just at the camera's near plane
260 actor.SetProperty(Actor::Property::POSITION_Z, distance - nearPlane);
263 application.SendNotification();
264 application.Render();
266 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, screenCoordinates));
267 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
270 // Emit a started signal where actor is closer than the camera's near plane
271 actor.SetProperty(Actor::Property::POSITION_Z, (distance - nearPlane) + 1.0f);
274 application.SendNotification();
275 application.Render();
277 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, screenCoordinates));
278 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
281 // Emit a started signal where actor is just at the camera's far plane
282 actor.SetProperty(Actor::Property::POSITION_Z, distance - farPlane);
285 application.SendNotification();
286 application.Render();
288 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, screenCoordinates));
289 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
292 // Emit a started signal where actor is further than the camera's far plane
293 actor.SetProperty(Actor::Property::POSITION_Z, (distance - farPlane) - 1.0f);
296 application.SendNotification();
297 application.Render();
299 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, screenCoordinates));
300 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
305 int UtcDaliHoverEmitEmpty(void)
307 TestApplication application;
311 // Emit an empty HoverEvent
312 Integration::HoverEvent event;
313 application.ProcessEvent(event);
314 tet_result(TET_FAIL);
316 catch(Dali::DaliException& e)
318 DALI_TEST_ASSERT(e, "!event.points.empty()", TEST_LOCATION);
323 int UtcDaliHoverInterrupted(void)
325 TestApplication application;
327 Actor actor = Actor::New();
328 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
329 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
330 application.GetScene().Add(actor);
333 application.SendNotification();
334 application.Render();
336 // Connect to actor's hovered signal
338 HoverEventFunctor functor(data);
339 actor.HoveredSignal().Connect(&application, functor);
341 // Emit a started signal
342 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
343 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
344 DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
347 // Emit an interrupted signal, we should be signalled regardless of whether there is a hit or not.
348 application.ProcessEvent(GenerateSingleHover(PointState::INTERRUPTED, Vector2(200.0f, 200.0f /* Outside actor */)));
349 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
350 DALI_TEST_EQUALS(PointState::INTERRUPTED, data.hoverEvent.GetState(0), TEST_LOCATION);
353 // Emit another interrupted signal, our signal handler should not be called.
354 application.ProcessEvent(GenerateSingleHover(PointState::INTERRUPTED, Vector2(200.0f, 200.0f)));
355 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
359 int UtcDaliHoverParentConsumer(void)
361 TestApplication application;
362 Actor rootActor(application.GetScene().GetRootLayer());
364 Actor actor = Actor::New();
365 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
366 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
367 application.GetScene().Add(actor);
370 application.SendNotification();
371 application.Render();
373 // Connect to actor's hovered signal
375 HoverEventFunctor functor(data, false);
376 actor.HoveredSignal().Connect(&application, functor);
378 // Connect to root actor's hovered signal
380 HoverEventFunctor rootFunctor(rootData); // Consumes signal
381 rootActor.HoveredSignal().Connect(&application, rootFunctor);
383 Vector2 screenCoordinates(10.0f, 10.0f);
384 Vector2 actorCoordinates, rootCoordinates;
385 actor.ScreenToLocal(actorCoordinates.x, actorCoordinates.y, screenCoordinates.x, screenCoordinates.y);
386 rootActor.ScreenToLocal(rootCoordinates.x, rootCoordinates.y, screenCoordinates.x, screenCoordinates.y);
388 // Emit a started signal
389 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, screenCoordinates));
390 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
391 DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
392 DALI_TEST_EQUALS(1u, data.hoverEvent.GetPointCount(), TEST_LOCATION);
393 DALI_TEST_EQUALS(1u, rootData.hoverEvent.GetPointCount(), TEST_LOCATION);
394 DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
395 DALI_TEST_EQUALS(PointState::STARTED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
396 DALI_TEST_EQUALS(screenCoordinates, data.hoverEvent.GetScreenPosition(0), TEST_LOCATION);
397 DALI_TEST_EQUALS(screenCoordinates, rootData.hoverEvent.GetScreenPosition(0), TEST_LOCATION);
398 DALI_TEST_EQUALS(actorCoordinates, data.hoverEvent.GetLocalPosition(0), 0.1f, TEST_LOCATION);
399 DALI_TEST_EQUALS(rootCoordinates, rootData.hoverEvent.GetLocalPosition(0), 0.1f, TEST_LOCATION);
400 DALI_TEST_CHECK(actor == data.hoverEvent.GetHitActor(0));
401 DALI_TEST_CHECK(actor == rootData.hoverEvent.GetHitActor(0));
405 // Emit a motion signal
406 screenCoordinates.x = screenCoordinates.y = 11.0f;
407 actor.ScreenToLocal(actorCoordinates.x, actorCoordinates.y, screenCoordinates.x, screenCoordinates.y);
408 rootActor.ScreenToLocal(rootCoordinates.x, rootCoordinates.y, screenCoordinates.x, screenCoordinates.y);
409 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, screenCoordinates));
410 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
411 DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
412 DALI_TEST_EQUALS(1u, data.hoverEvent.GetPointCount(), TEST_LOCATION);
413 DALI_TEST_EQUALS(1u, rootData.hoverEvent.GetPointCount(), TEST_LOCATION);
414 DALI_TEST_EQUALS(PointState::MOTION, data.hoverEvent.GetState(0), TEST_LOCATION);
415 DALI_TEST_EQUALS(PointState::MOTION, rootData.hoverEvent.GetState(0), TEST_LOCATION);
416 DALI_TEST_EQUALS(screenCoordinates, data.hoverEvent.GetScreenPosition(0), TEST_LOCATION);
417 DALI_TEST_EQUALS(screenCoordinates, rootData.hoverEvent.GetScreenPosition(0), TEST_LOCATION);
418 DALI_TEST_EQUALS(actorCoordinates, data.hoverEvent.GetLocalPosition(0), 0.1f, TEST_LOCATION);
419 DALI_TEST_EQUALS(rootCoordinates, rootData.hoverEvent.GetLocalPosition(0), 0.1f, TEST_LOCATION);
420 DALI_TEST_CHECK(actor == data.hoverEvent.GetHitActor(0));
421 DALI_TEST_CHECK(actor == rootData.hoverEvent.GetHitActor(0));
425 // Emit a finished signal
426 screenCoordinates.x = screenCoordinates.y = 12.0f;
427 actor.ScreenToLocal(actorCoordinates.x, actorCoordinates.y, screenCoordinates.x, screenCoordinates.y);
428 rootActor.ScreenToLocal(rootCoordinates.x, rootCoordinates.y, screenCoordinates.x, screenCoordinates.y);
429 application.ProcessEvent(GenerateSingleHover(PointState::FINISHED, screenCoordinates));
430 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
431 DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
432 DALI_TEST_EQUALS(1u, data.hoverEvent.GetPointCount(), TEST_LOCATION);
433 DALI_TEST_EQUALS(1u, rootData.hoverEvent.GetPointCount(), TEST_LOCATION);
434 DALI_TEST_EQUALS(PointState::FINISHED, data.hoverEvent.GetState(0), TEST_LOCATION);
435 DALI_TEST_EQUALS(PointState::FINISHED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
436 DALI_TEST_EQUALS(screenCoordinates, data.hoverEvent.GetScreenPosition(0), TEST_LOCATION);
437 DALI_TEST_EQUALS(screenCoordinates, rootData.hoverEvent.GetScreenPosition(0), TEST_LOCATION);
438 DALI_TEST_EQUALS(actorCoordinates, data.hoverEvent.GetLocalPosition(0), 0.1f, TEST_LOCATION);
439 DALI_TEST_EQUALS(rootCoordinates, rootData.hoverEvent.GetLocalPosition(0), 0.1f, TEST_LOCATION);
440 DALI_TEST_CHECK(actor == data.hoverEvent.GetHitActor(0));
441 DALI_TEST_CHECK(actor == rootData.hoverEvent.GetHitActor(0));
445 // Emit a started signal where the actor is not present, will hit the root actor though
446 screenCoordinates.x = screenCoordinates.y = 200.0f;
447 rootActor.ScreenToLocal(rootCoordinates.x, rootCoordinates.y, screenCoordinates.x, screenCoordinates.y);
448 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, screenCoordinates));
449 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
450 DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
451 DALI_TEST_EQUALS(1u, rootData.hoverEvent.GetPointCount(), TEST_LOCATION);
452 DALI_TEST_EQUALS(PointState::STARTED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
453 DALI_TEST_EQUALS(screenCoordinates, rootData.hoverEvent.GetScreenPosition(0), TEST_LOCATION);
454 DALI_TEST_EQUALS(rootCoordinates, rootData.hoverEvent.GetLocalPosition(0), 0.1f, TEST_LOCATION);
455 DALI_TEST_CHECK(rootActor == rootData.hoverEvent.GetHitActor(0));
459 int UtcDaliHoverInterruptedParentConsumer(void)
461 TestApplication application;
462 Actor rootActor(application.GetScene().GetRootLayer());
464 Actor actor = Actor::New();
465 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
466 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
467 application.GetScene().Add(actor);
470 application.SendNotification();
471 application.Render();
473 // Connect to actor's hovered signal
475 HoverEventFunctor functor(data, false);
476 actor.HoveredSignal().Connect(&application, functor);
478 // Connect to root actor's hovered signal
480 HoverEventFunctor rootFunctor(rootData); // Consumes signal
481 rootActor.HoveredSignal().Connect(&application, rootFunctor);
483 // Emit a started signal
484 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
485 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
486 DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
487 DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
488 DALI_TEST_EQUALS(PointState::STARTED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
489 DALI_TEST_CHECK(actor == data.hoverEvent.GetHitActor(0));
490 DALI_TEST_CHECK(actor == rootData.hoverEvent.GetHitActor(0));
494 // Emit an interrupted signal
495 application.ProcessEvent(GenerateSingleHover(PointState::INTERRUPTED, Vector2(200.0f, 200.0f)));
496 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
497 DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
498 DALI_TEST_EQUALS(PointState::INTERRUPTED, data.hoverEvent.GetState(0), TEST_LOCATION);
499 DALI_TEST_EQUALS(PointState::INTERRUPTED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
500 DALI_TEST_CHECK(actor == data.hoverEvent.GetHitActor(0));
501 DALI_TEST_CHECK(actor == rootData.hoverEvent.GetHitActor(0));
505 // Emit another started signal
506 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
507 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
508 DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
509 DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
510 DALI_TEST_EQUALS(PointState::STARTED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
514 // Remove actor from Stage
515 application.GetScene().Remove(actor);
520 application.SendNotification();
521 application.Render();
523 // Emit an interrupted signal, only root actor's signal should be called.
524 application.ProcessEvent(GenerateSingleHover(PointState::INTERRUPTED, Vector2(200.0f, 200.0f /* Outside actor */)));
525 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
526 DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
527 DALI_TEST_EQUALS(PointState::INTERRUPTED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
528 DALI_TEST_CHECK(rootActor == rootData.hoverEvent.GetHitActor(0));
532 // Emit another interrupted state, none of the signal's should be called.
533 application.ProcessEvent(GenerateSingleHover(PointState::INTERRUPTED, Vector2(200.0f, 200.0f)));
534 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
535 DALI_TEST_EQUALS(false, rootData.functorCalled, TEST_LOCATION);
539 int UtcDaliHoverLeave(void)
541 TestApplication application;
543 Actor actor = Actor::New();
544 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
545 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
546 application.GetScene().Add(actor);
549 application.SendNotification();
550 application.Render();
552 // Connect to actor's hovered signal
554 HoverEventFunctor functor(data);
555 actor.HoveredSignal().Connect(&application, functor);
557 // Set actor to require leave events
558 actor.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
560 // Emit a started signal
561 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
562 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
563 DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
566 // Emit a motion signal outside of actor, should be signalled with a Leave
567 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(200.0f, 200.0f)));
568 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
569 DALI_TEST_EQUALS(PointState::LEAVE, data.hoverEvent.GetState(0), TEST_LOCATION);
572 // Another motion outside of actor, no signalling
573 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(201.0f, 201.0f)));
574 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
577 // Another motion event inside actor, signalled with start. This is because a new hover event was started on that actor.
578 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(10.0f, 10.0f)));
579 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
580 DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
583 // We do not want to listen to leave events anymore
584 actor.SetProperty(Actor::Property::LEAVE_REQUIRED, false);
586 // Another motion event outside of actor, no signalling
587 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(200.0f, 200.0f)));
588 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
593 int UtcDaliHoverLeaveParentConsumer(void)
595 TestApplication application;
596 Actor rootActor(application.GetScene().GetRootLayer());
598 Actor actor = Actor::New();
599 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
600 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
601 application.GetScene().Add(actor);
604 application.SendNotification();
605 application.Render();
607 // Connect to actor's hovered signal
609 HoverEventFunctor functor(data, false);
610 actor.HoveredSignal().Connect(&application, functor);
612 // Connect to root actor's hovered signal
614 HoverEventFunctor rootFunctor(rootData); // Consumes signal
615 rootActor.HoveredSignal().Connect(&application, rootFunctor);
617 // Set actor to require leave events
618 actor.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
619 rootActor.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
621 // Emit a started signal
622 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
623 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
624 DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
625 DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
626 DALI_TEST_EQUALS(PointState::STARTED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
627 DALI_TEST_CHECK(actor == data.hoverEvent.GetHitActor(0));
628 DALI_TEST_CHECK(actor == rootData.hoverEvent.GetHitActor(0));
632 // Emit a motion signal outside of actor, should be signalled with a Leave
633 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(200.0f, 200.0f)));
634 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
635 DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
636 DALI_TEST_EQUALS(PointState::LEAVE, data.hoverEvent.GetState(0), TEST_LOCATION);
637 // rootActor receives "started" state because a new hover event entered in rootActor area.
638 DALI_TEST_EQUALS(PointState::STARTED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
639 DALI_TEST_CHECK(actor == data.hoverEvent.GetHitActor(0));
640 DALI_TEST_CHECK(rootActor == rootData.hoverEvent.GetHitActor(0));
644 // Another motion outside of actor, only rootActor signalled
645 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(201.0f, 201.0f)));
646 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
647 DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
648 DALI_TEST_EQUALS(PointState::MOTION, rootData.hoverEvent.GetState(0), TEST_LOCATION);
649 DALI_TEST_CHECK(rootActor == rootData.hoverEvent.GetHitActor(0));
653 // Another motion event inside actor, signalled with start. This is because a new hover event was started on that actor.
654 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(10.0f, 10.0f)));
655 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
656 DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
657 DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
658 DALI_TEST_EQUALS(PointState::STARTED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
659 DALI_TEST_CHECK(actor == data.hoverEvent.GetHitActor(0));
660 DALI_TEST_CHECK(actor == rootData.hoverEvent.GetHitActor(0));
664 // We do not want to listen to leave events of actor anymore
665 actor.SetProperty(Actor::Property::LEAVE_REQUIRED, false);
667 // Another motion event outside of root actor, only root signalled
668 Vector2 stageSize(application.GetScene().GetSize());
669 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(stageSize.width + 10.0f, stageSize.height + 10.0f)));
670 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
671 DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
672 DALI_TEST_EQUALS(PointState::LEAVE, rootData.hoverEvent.GetState(0), TEST_LOCATION);
676 int UtcDaliHoverActorBecomesInsensitive(void)
678 TestApplication application;
680 Actor actor = Actor::New();
681 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
682 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
683 application.GetScene().Add(actor);
686 application.SendNotification();
687 application.Render();
689 // Connect to actor's hovered signal
691 HoverEventFunctor functor(data);
692 actor.HoveredSignal().Connect(&application, functor);
694 // Emit a started signal
695 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
696 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
697 DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
700 // Change actor to insensitive
701 actor.SetProperty(Actor::Property::SENSITIVE, false);
703 // Emit a motion signal, signalled with an interrupted
704 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(200.0f, 200.0f)));
705 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
706 DALI_TEST_EQUALS(PointState::INTERRUPTED, data.hoverEvent.GetState(0), TEST_LOCATION);
711 int UtcDaliHoverActorBecomesInsensitiveParentConsumer(void)
713 TestApplication application;
714 Actor rootActor(application.GetScene().GetRootLayer());
716 Actor actor = Actor::New();
717 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
718 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
719 application.GetScene().Add(actor);
722 application.SendNotification();
723 application.Render();
725 // Connect to actor's hovered signal
727 HoverEventFunctor functor(data, false);
728 actor.HoveredSignal().Connect(&application, functor);
730 // Connect to root actor's hovered signal
732 HoverEventFunctor rootFunctor(rootData); // Consumes signal
733 rootActor.HoveredSignal().Connect(&application, rootFunctor);
735 // Emit a started signal
736 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
737 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
738 DALI_TEST_EQUALS(true, rootData.functorCalled, TEST_LOCATION);
739 DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
740 DALI_TEST_EQUALS(PointState::STARTED, rootData.hoverEvent.GetState(0), TEST_LOCATION);
741 DALI_TEST_CHECK(actor == data.hoverEvent.GetHitActor(0));
742 DALI_TEST_CHECK(actor == rootData.hoverEvent.GetHitActor(0));
746 // Remove actor from Stage
747 application.GetScene().Remove(actor);
749 // Because it was removed, it gets interrupted.
750 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
751 DALI_TEST_EQUALS(PointState::INTERRUPTED, data.hoverEvent.GetState(0), TEST_LOCATION);
756 application.SendNotification();
757 application.Render();
759 // Make root actor insensitive
760 rootActor.SetProperty(Actor::Property::SENSITIVE, false);
762 // Because it is insensitive, it does not receive the event.
763 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(200.0f, 200.0f)));
764 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
765 DALI_TEST_EQUALS(false, rootData.functorCalled, TEST_LOCATION);
772 int UtcDaliHoverActorBecomesUserInteractionDisabled(void)
774 TestApplication application;
776 Actor actor = Actor::New();
777 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
778 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
779 application.GetScene().Add(actor);
782 application.SendNotification();
783 application.Render();
785 // Connect to actor's hovered signal
787 HoverEventFunctor functor(data);
788 actor.HoveredSignal().Connect(&application, functor);
790 // Emit a started signal
791 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
792 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
793 DALI_TEST_EQUALS(PointState::STARTED, data.hoverEvent.GetState(0), TEST_LOCATION);
796 // Change actor to disable user interaction.
797 actor.SetProperty(DevelActor::Property::USER_INTERACTION_ENABLED, false);
799 // Emit a motion signal, signalled with an interrupted
800 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(200.0f, 200.0f)));
801 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
802 DALI_TEST_EQUALS(PointState::INTERRUPTED, data.hoverEvent.GetState(0), TEST_LOCATION);
807 int UtcDaliHoverMultipleLayers(void)
809 TestApplication application;
810 Actor rootActor(application.GetScene().GetRootLayer());
812 // Connect to actor's hovered signal
814 HoverEventFunctor functor(data);
816 Layer layer1(Layer::New());
817 layer1.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
818 layer1.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
819 application.GetScene().Add(layer1);
821 Actor actor1(Actor::New());
822 actor1.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
823 actor1.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
824 actor1.SetProperty(Actor::Property::POSITION_Z, 1.0f); // Should hit actor1 in this layer
828 application.SendNotification();
829 application.Render();
831 // Connect to layer1 and actor1
832 layer1.HoveredSignal().Connect(&application, functor);
833 actor1.HoveredSignal().Connect(&application, functor);
835 // Hit in hittable area, actor1 should be hit
836 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
837 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
838 DALI_TEST_CHECK(data.hoveredActor == actor1);
841 // Make layer1 insensitive, nothing should be hit
842 layer1.SetProperty(Actor::Property::SENSITIVE, false);
843 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
844 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
847 // Make layer1 sensitive again, again actor1 will be hit
848 layer1.SetProperty(Actor::Property::SENSITIVE, true);
849 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
850 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
851 DALI_TEST_CHECK(data.hoveredActor == actor1);
854 // Make rootActor insensitive, nothing should be hit
855 rootActor.SetProperty(Actor::Property::SENSITIVE, false);
856 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
857 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
860 // Make rootActor sensitive
861 rootActor.SetProperty(Actor::Property::SENSITIVE, true);
864 Layer layer2(Layer::New());
865 layer2.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
866 layer2.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
867 layer2.SetProperty(Actor::Property::POSITION_Z, 10.0f); // Should hit layer2 in this layer rather than actor2
868 application.GetScene().Add(layer2);
870 Actor actor2(Actor::New());
871 actor2.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
872 actor2.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
876 application.SendNotification();
877 application.Render();
879 // Connect to layer2 and actor2
880 layer2.HoveredSignal().Connect(&application, functor);
881 actor2.HoveredSignal().Connect(&application, functor);
883 // Emit an event, should hit layer2
884 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
885 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
886 //DALI_TEST_CHECK( data.hoveredActor == layer2 ); // TODO: Uncomment this after removing renderable hack!
889 // Make layer2 insensitive, should hit actor1
890 layer2.SetProperty(Actor::Property::SENSITIVE, false);
891 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
892 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
893 DALI_TEST_CHECK(data.hoveredActor == actor1);
896 // Make layer2 sensitive again, should hit layer2
897 layer2.SetProperty(Actor::Property::SENSITIVE, true);
898 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
899 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
900 //DALI_TEST_CHECK( data.hoveredActor == layer2 ); // TODO: Uncomment this after removing renderable hack!
903 // Make layer2 invisible, render and notify
904 layer2.SetProperty(Actor::Property::VISIBLE, false);
905 application.SendNotification();
906 application.Render();
909 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
910 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
911 DALI_TEST_CHECK(data.hoveredActor == actor1);
914 // Make rootActor invisible, render and notify
915 rootActor.SetProperty(Actor::Property::VISIBLE, false);
917 // Because visible became false, we receive interrupted
918 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
919 DALI_TEST_EQUALS(PointState::INTERRUPTED, data.hoverEvent.GetState(0), TEST_LOCATION);
922 application.SendNotification();
923 application.Render();
925 // Should not hit anything
926 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
927 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
932 int UtcDaliHoverMultipleRenderTasks(void)
934 TestApplication application;
935 Integration::Scene stage(application.GetScene());
936 Vector2 stageSize(stage.GetSize());
938 Actor actor = Actor::New();
939 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
940 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
943 // Create render task
944 Viewport viewport(stageSize.width * 0.5f, stageSize.height * 0.5f, stageSize.width * 0.5f, stageSize.height * 0.5f);
945 RenderTask renderTask(application.GetScene().GetRenderTaskList().CreateTask());
946 renderTask.SetViewport(viewport);
947 renderTask.SetInputEnabled(true);
950 application.SendNotification();
951 application.Render();
953 // Connect to actor's hovered signal
955 HoverEventFunctor functor(data);
956 actor.HoveredSignal().Connect(&application, functor);
958 // Emit a started signal
959 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
960 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
963 // Ensure renderTask actor can be hit too.
964 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(viewport.x + 5.0f, viewport.y + 5.0f)));
965 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
968 // Disable input on renderTask, should not be hittable
969 renderTask.SetInputEnabled(false);
970 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(viewport.x + 5.0f, viewport.y + 5.0f)));
971 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
976 int UtcDaliHoverMultipleRenderTasksWithChildLayer(void)
978 TestApplication application;
979 Integration::Scene stage(application.GetScene());
980 Vector2 stageSize(stage.GetSize());
982 Actor actor = Actor::New();
983 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
984 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
987 Layer layer = Layer::New();
988 layer.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
989 layer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
992 // Create render task
993 Viewport viewport(stageSize.width * 0.5f, stageSize.height * 0.5f, stageSize.width * 0.5f, stageSize.height * 0.5f);
994 RenderTask renderTask(application.GetScene().GetRenderTaskList().CreateTask());
995 renderTask.SetViewport(viewport);
996 renderTask.SetInputEnabled(true);
997 renderTask.SetSourceActor(actor);
1000 application.SendNotification();
1001 application.Render();
1003 // Connect to layer's hovered signal
1005 HoverEventFunctor functor(data);
1006 actor.HoveredSignal().Connect(&application, functor);
1007 layer.HoveredSignal().Connect(&application, functor);
1009 // Emit a started signal
1010 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1011 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1014 // Ensure renderTask actor can be hit too.
1015 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(viewport.x + 5.0f, viewport.y + 5.0f)));
1016 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1019 // Disable input on renderTask, should not be hittable
1020 renderTask.SetInputEnabled(false);
1021 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(viewport.x + 5.0f, viewport.y + 5.0f)));
1022 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1027 int UtcDaliHoverOffscreenRenderTasks(void)
1029 TestApplication application;
1030 Integration::Scene stage(application.GetScene());
1031 Vector2 stageSize(stage.GetSize());
1033 // FrameBufferImage for offscreen RenderTask
1034 FrameBuffer frameBuffer = FrameBuffer::New(stageSize.width, stageSize.height);
1036 // Create a renderable actor to display the FrameBufferImage
1037 Actor renderableActor = CreateRenderableActor(frameBuffer.GetColorTexture());
1038 renderableActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
1039 renderableActor.SetProperty(Actor::Property::SIZE, Vector2(stageSize.x, stageSize.y));
1040 renderableActor.ScaleBy(Vector3(1.0f, -1.0f, 1.0f)); // FIXME
1041 stage.Add(renderableActor);
1043 Actor actor = Actor::New();
1044 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1045 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1047 application.GetGlAbstraction().SetCheckFramebufferStatusResult(GL_FRAMEBUFFER_COMPLETE); // Ensure framebuffer connects
1049 stage.GetRenderTaskList().GetTask(0u).SetScreenToFrameBufferFunction(RenderTask::FULLSCREEN_FRAMEBUFFER_FUNCTION);
1051 // Create a RenderTask
1052 RenderTask renderTask = stage.GetRenderTaskList().CreateTask();
1053 renderTask.SetSourceActor(actor);
1054 renderTask.SetFrameBuffer(frameBuffer);
1055 renderTask.SetInputEnabled(true);
1057 // Create another RenderTask
1058 RenderTask renderTask2(stage.GetRenderTaskList().CreateTask());
1059 renderTask2.SetInputEnabled(true);
1061 // Render and notify
1062 application.SendNotification();
1063 application.Render();
1065 // Connect to actor's hovered signal
1067 HoverEventFunctor functor(data);
1068 actor.HoveredSignal().Connect(&application, functor);
1070 // Emit a started signal
1071 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1072 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1077 int UtcDaliHoverMultipleRenderableActors(void)
1079 TestApplication application;
1080 Integration::Scene stage(application.GetScene());
1081 Vector2 stageSize(stage.GetSize());
1083 Actor parent = CreateRenderableActor();
1084 parent.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1085 parent.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1088 Actor actor = CreateRenderableActor();
1089 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1090 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1093 // Render and notify
1094 application.SendNotification();
1095 application.Render();
1097 // Connect to layer's hovered signal
1099 HoverEventFunctor functor(data);
1100 parent.HoveredSignal().Connect(&application, functor);
1101 actor.HoveredSignal().Connect(&application, functor);
1103 // Emit a started signal
1104 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1105 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1106 DALI_TEST_CHECK(actor == data.hoveredActor);
1110 int UtcDaliHoverActorRemovedInSignal(void)
1112 TestApplication application;
1114 Actor actor = Actor::New();
1115 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1116 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1117 application.GetScene().Add(actor);
1119 // Render and notify
1120 application.SendNotification();
1121 application.Render();
1123 // Connect to actor's hovered signal
1125 RemoveActorFunctor functor(data);
1126 actor.HoveredSignal().Connect(&application, functor);
1128 // Register for leave events
1129 actor.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
1131 // Emit a started signal
1132 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1133 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1136 // Re-add, render and notify
1137 application.GetScene().Add(actor);
1138 application.SendNotification();
1139 application.Render();
1141 // Emit another signal outside of actor's area, should not get anything as the scene has changed.
1142 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(210.0f, 210.0f)));
1143 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1146 // Emit a started signal
1147 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1148 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1151 // Render and notify
1152 application.SendNotification();
1153 application.Render();
1155 // Emit another signal outside of actor's area, should not get anything as the scene has changed.
1156 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(210.0f, 210.0f)));
1157 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1160 // Re-add actor back to stage, render and notify
1161 application.GetScene().Add(actor);
1162 application.SendNotification();
1163 application.Render();
1165 // Emit another started event
1166 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1167 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1170 // Completely delete the actor
1173 // Emit event, should not crash and should not receive an event.
1174 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(210.0f, 210.0f)));
1175 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1179 int UtcDaliHoverActorSignalNotConsumed(void)
1181 TestApplication application;
1183 Actor actor = Actor::New();
1184 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1185 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1186 application.GetScene().Add(actor);
1188 // Render and notify
1189 application.SendNotification();
1190 application.Render();
1192 // Connect to actor's hovered signal
1194 HoverEventFunctor functor(data, false);
1195 actor.HoveredSignal().Connect(&application, functor);
1197 // Emit a started signal
1198 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1199 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1203 int UtcDaliHoverActorUnStaged(void)
1205 TestApplication application;
1207 Actor actor = Actor::New();
1208 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1209 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1210 application.GetScene().Add(actor);
1212 // Render and notify
1213 application.SendNotification();
1214 application.Render();
1216 // Connect to actor's hovered signal
1218 HoverEventFunctor functor(data);
1219 actor.HoveredSignal().Connect(&application, functor);
1221 // Emit a started signal
1222 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1223 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1226 // Remove actor from stage
1227 application.GetScene().Remove(actor);
1229 // Interrupted is received because the actor receiving the event removed.
1230 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1231 DALI_TEST_EQUALS(PointState::INTERRUPTED, data.hoverEvent.GetState(0), TEST_LOCATION);
1234 // Render and notify
1235 application.SendNotification();
1236 application.Render();
1238 // Emit a move at the same point, we should not be signalled.
1239 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(10.0f, 10.0f)));
1240 DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
1245 int UtcDaliHoverLeaveActorReadded(void)
1247 TestApplication application;
1248 Integration::Scene stage = application.GetScene();
1250 Actor actor = Actor::New();
1251 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1252 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1255 // Set actor to receive hover-events
1256 actor.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
1258 // Render and notify
1259 application.SendNotification();
1260 application.Render();
1262 // Connect to actor's hovered signal
1264 HoverEventFunctor functor(data);
1265 actor.HoveredSignal().Connect(&application, functor);
1267 // Emit a started and motion
1268 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1269 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(11.0f, 10.0f)));
1270 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1273 // Remove actor from stage and add again
1274 stage.Remove(actor);
1277 // Emit a motion within the actor's bounds
1278 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(12.0f, 10.0f)));
1279 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1282 // Emit a motion outside the actor's bounds
1283 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(200.0f, 200.0f)));
1284 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1285 DALI_TEST_EQUALS(PointState::LEAVE, data.hoverEvent.GetState(0), TEST_LOCATION);
1291 int UtcDaliHoverClippingActor(void)
1293 TestApplication application;
1294 Integration::Scene stage = application.GetScene();
1296 Actor actor = Actor::New();
1297 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1298 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1301 Actor clippingActor = Actor::New();
1302 clippingActor.SetProperty(Actor::Property::SIZE, Vector2(50.0f, 50.0f));
1303 clippingActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1304 clippingActor.SetProperty(Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN);
1305 stage.Add(clippingActor);
1307 // Add a child to the clipped region.
1308 Actor clippingChild = Actor::New();
1309 clippingChild.SetProperty(Actor::Property::SIZE, Vector2(50.0f, 50.0f));
1310 clippingChild.SetProperty(Actor::Property::POSITION, Vector2(25.0f, 25.0f));
1311 clippingChild.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1312 clippingActor.Add(clippingChild);
1314 // Render and notify.
1315 application.SendNotification();
1316 application.Render();
1318 // Connect to actor's hovered signal.
1320 HoverEventFunctor functor(data);
1321 actor.HoveredSignal().Connect(&application, functor);
1323 // Emit an event within clipped area - we should have a hit.
1324 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1325 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1328 // Emit an event outside the clipped area but within the actor area, we should have a hit.
1329 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(60.0f, 60.0f)));
1330 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1333 clippingChild.HoveredSignal().Connect(&application, functor);
1335 // Emit an event inside part of the child which is within the clipped area, we should have a hit.
1336 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(30.0f, 30.0f)));
1337 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1343 int UtcDaliHoverEventCreate(void)
1345 TestApplication application;
1347 Dali::HoverEvent hoverEvent = DevelHoverEvent::New(100);
1348 DALI_TEST_CHECK(hoverEvent);
1350 // Emit a started signal
1351 DALI_TEST_EQUALS(100, hoverEvent.GetTime(), TEST_LOCATION);
1352 DALI_TEST_EQUALS(0, hoverEvent.GetPointCount(), TEST_LOCATION);
1357 int UtcDaliHoverEventIntegNewHoverEvent(void)
1359 uint32_t timestamp = 92858u;
1360 TouchPoint tp(1, PointState::STARTED, 34.4f, 123.89f, 5.0f, 7.0f);
1361 Dali::HoverEvent hoverEvent = Integration::NewHoverEvent(timestamp, tp);
1363 DALI_TEST_EQUALS(hoverEvent.GetPointCount(), 1u, TEST_LOCATION);
1364 DALI_TEST_EQUALS(hoverEvent.GetState(0), PointState::STARTED, TEST_LOCATION);
1365 DALI_TEST_EQUALS(hoverEvent.GetLocalPosition(0), Vector2(5.0f, 7.0f), TEST_LOCATION);
1366 DALI_TEST_EQUALS(hoverEvent.GetScreenPosition(0), Vector2(34.4f, 123.89f), TEST_LOCATION);
1371 int UtcDaliHoverActorHide(void)
1373 TestApplication application;
1374 Integration::Scene stage = application.GetScene();
1376 Actor actor = Actor::New();
1377 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1378 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1381 // Render and notify
1382 application.SendNotification();
1383 application.Render();
1385 // Connect to actor's hovered signal
1387 HoverEventFunctor functor(data);
1388 actor.HoveredSignal().Connect(&application, functor);
1391 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1392 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1395 actor.SetProperty(Actor::Property::VISIBLE, false);
1397 // flush the queue and render once
1398 application.SendNotification();
1399 application.Render();
1401 // Interrupted is received because the actor receiving the event hides.
1402 DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
1403 DALI_TEST_EQUALS(PointState::INTERRUPTED, data.hoverEvent.GetState(0), TEST_LOCATION);
1409 int UtcDaliHoverStartConsumerDifferentAtEnd(void)
1411 // Start a hover in one actor, continue it in another actor
1412 // End hover in the second actor
1413 // First actor should still get a hover finished call
1414 TestApplication application;
1415 Integration::Scene scene = application.GetScene();
1417 Actor actor = Actor::New();
1418 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1419 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1422 Actor actor2 = Actor::New();
1423 actor2.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1424 actor2.SetProperty(Actor::Property::POSITION, Vector2(100.0f, 100.0f));
1425 actor2.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1428 // Render and notify
1429 application.SendNotification();
1430 application.Render();
1432 // Connect to hover start actor's hovered signal
1433 SignalData dataStartActor;
1434 HoverEventFunctor functorStartActor(dataStartActor);
1435 actor.HoveredSignal().Connect(&application, functorStartActor);
1437 // Connect to second actor's hovered signal
1438 SignalData dataSecondActor;
1439 HoverEventFunctor functorSecondActor(dataSecondActor);
1440 actor2.HoveredSignal().Connect(&application, functorSecondActor);
1442 auto resetData = [&]() { dataStartActor.Reset(); dataSecondActor.Reset(); };
1445 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1446 DALI_TEST_EQUALS(true, dataStartActor.functorCalled, TEST_LOCATION);
1447 DALI_TEST_EQUALS(false, dataSecondActor.functorCalled, TEST_LOCATION);
1450 // Emit a hover somewhere else
1451 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(110.0f, 110.0f)));
1452 DALI_TEST_EQUALS(false, dataStartActor.functorCalled, TEST_LOCATION);
1453 DALI_TEST_EQUALS(true, dataSecondActor.functorCalled, TEST_LOCATION);
1456 // Emit a hover end in the same point, the hover start actor should still be informed
1457 application.ProcessEvent(GenerateSingleHover(PointState::FINISHED, Vector2(110.0f, 110.0f)));
1458 DALI_TEST_EQUALS(true, dataStartActor.functorCalled, TEST_LOCATION);
1459 DALI_TEST_EQUALS(true, dataSecondActor.functorCalled, TEST_LOCATION);
1462 // Do it again with the geometry on
1464 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1465 DALI_TEST_EQUALS(true, dataStartActor.functorCalled, TEST_LOCATION);
1466 DALI_TEST_EQUALS(false, dataSecondActor.functorCalled, TEST_LOCATION);
1469 // Emit a hover somewhere else
1470 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(110.0f, 110.0f)));
1471 DALI_TEST_EQUALS(false, dataStartActor.functorCalled, TEST_LOCATION);
1472 DALI_TEST_EQUALS(true, dataSecondActor.functorCalled, TEST_LOCATION);
1475 scene.SetGeometryHittestEnabled(true);
1477 // Emit a hover end in the same point, the hover start actor should still be informed
1478 application.ProcessEvent(GenerateSingleHover(PointState::FINISHED, Vector2(110.0f, 110.0f)));
1479 DALI_TEST_EQUALS(true, dataStartActor.functorCalled, TEST_LOCATION);
1480 DALI_TEST_EQUALS(true, dataSecondActor.functorCalled, TEST_LOCATION);
1486 int UtcDaliHoverEnsureDifferentConsumerReceivesInterrupted(void)
1488 // Interrupted event with a different consumer to previous event
1490 TestApplication application;
1491 Integration::Scene scene = application.GetScene();
1493 Actor parent = Actor::New();
1494 parent.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1495 parent.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1498 Actor child = Actor::New();
1499 child.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1500 child.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1503 // Render and notify
1504 application.SendNotification();
1505 application.Render();
1507 // Connect to parent's hover signal
1508 SignalData dataParent;
1509 HoverEventFunctor functorParent(dataParent);
1510 parent.HoveredSignal().Connect(&application, functorParent);
1512 // Connect to child's hovered signal but do not consume
1513 SignalData dataChildNoConsume;
1514 HoverEventFunctor functorChildNoConsume(dataChildNoConsume, false);
1515 child.HoveredSignal().Connect(&application, functorChildNoConsume);
1517 // Create a functor to consume the event of the child, but don't connect just yet
1518 SignalData dataChildConsume;
1519 HoverEventFunctor functorChildConsume(dataChildConsume);
1521 auto resetData = [&]() { dataParent.Reset(); dataChildNoConsume.Reset(); dataChildConsume.Reset(); };
1524 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1525 DALI_TEST_EQUALS(true, dataParent.functorCalled, TEST_LOCATION);
1526 DALI_TEST_EQUALS(true, dataChildNoConsume.functorCalled, TEST_LOCATION);
1527 DALI_TEST_EQUALS(false, dataChildConsume.functorCalled, TEST_LOCATION);
1530 // Connect to child's hover event and consume so it's a different consumer on interrupted
1531 child.HoveredSignal().Connect(&application, functorChildConsume);
1533 // Emit interrupted, all three methods should be called
1534 application.ProcessEvent(GenerateSingleHover(PointState::INTERRUPTED, Vector2(10.0f, 10.0f)));
1535 DALI_TEST_EQUALS(true, dataParent.functorCalled, TEST_LOCATION);
1536 DALI_TEST_EQUALS(true, dataChildNoConsume.functorCalled, TEST_LOCATION);
1537 DALI_TEST_EQUALS(true, dataChildConsume.functorCalled, TEST_LOCATION);
1543 int UtcDaliHoverEnsureDifferentConsumerReceivesLeave(void)
1545 // Motion event outside previous hit actor
1546 // This event is consumed by a different actor
1547 // The previous consumer's listener should still get called
1549 TestApplication application;
1550 Integration::Scene scene = application.GetScene();
1552 Actor parent = Actor::New();
1553 parent.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1554 parent.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1557 Actor child = Actor::New();
1558 child.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
1559 child.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1562 // Render and notify
1563 application.SendNotification();
1564 application.Render();
1566 // Connect to parent's hover signal
1567 SignalData dataParent;
1568 HoverEventFunctor functorParent(dataParent);
1569 parent.HoveredSignal().Connect(&application, functorParent);
1571 // Connect to child's hovered signal but do not consume
1572 SignalData dataChildNoConsume;
1573 HoverEventFunctor functorChildNoConsume(dataChildNoConsume, false);
1574 child.HoveredSignal().Connect(&application, functorChildNoConsume);
1576 // Create a functor to consume the event of the child, but don't connect just yet
1577 SignalData dataChildConsume;
1578 HoverEventFunctor functorChildConsume(dataChildConsume);
1580 auto resetData = [&]() { dataParent.Reset(); dataChildNoConsume.Reset(); dataChildConsume.Reset(); };
1583 application.ProcessEvent(GenerateSingleHover(PointState::STARTED, Vector2(10.0f, 10.0f)));
1584 DALI_TEST_EQUALS(true, dataParent.functorCalled, TEST_LOCATION);
1585 DALI_TEST_EQUALS(true, dataChildNoConsume.functorCalled, TEST_LOCATION);
1586 DALI_TEST_EQUALS(false, dataChildConsume.functorCalled, TEST_LOCATION);
1589 // Connect to child's hover event and consume so it's a different consumer on interrupted
1590 child.HoveredSignal().Connect(&application, functorChildConsume);
1592 // Also make last consumer insensitive
1593 parent.SetProperty(Actor::Property::SENSITIVE, false);
1595 // Emit interrupted, all three methods should be called
1596 application.ProcessEvent(GenerateSingleHover(PointState::MOTION, Vector2(110.0f, 110.0f)));
1597 DALI_TEST_EQUALS(true, dataParent.functorCalled, TEST_LOCATION);
1598 DALI_TEST_EQUALS(true, dataChildNoConsume.functorCalled, TEST_LOCATION);
1599 DALI_TEST_EQUALS(true, dataChildConsume.functorCalled, TEST_LOCATION);