2 * Copyright (c) 2022 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/hit-test-algorithm.h>
21 #include <dali/integration-api/events/touch-event-integ.h>
22 #include <dali/public-api/dali-core.h>
31 bool gHitTestTouchCallBackCalled = false;
32 static bool TestHitTestTouchCallback(Actor, const TouchEvent&)
34 gHitTestTouchCallBackCalled = true;
40 * The functor to be used in the hit-test algorithm to check whether the actor is hittable.
42 bool IsActorHittableFunction(Actor actor, Dali::HitTestAlgorithm::TraverseType type)
44 bool hittable = false;
48 case Dali::HitTestAlgorithm::CHECK_ACTOR:
50 // Check whether the actor is visible and not fully transparent.
51 if(actor.GetCurrentProperty<bool>(Actor::Property::VISIBLE) && actor.GetCurrentProperty<Vector4>(Actor::Property::WORLD_COLOR).a > 0.01f) // not FULLY_TRANSPARENT
53 // Check whether the actor has the specific name "HittableActor"
54 if(actor.GetProperty<std::string>(Actor::Property::NAME) == "HittableActor")
61 case Dali::HitTestAlgorithm::DESCEND_ACTOR_TREE:
63 if(actor.GetCurrentProperty<bool>(Actor::Property::VISIBLE)) // Actor is visible, if not visible then none of its children are visible.
78 bool DefaultIsActorTouchableFunction(Dali::Actor actor, Dali::HitTestAlgorithm::TraverseType type)
80 bool hittable = false;
84 case Dali::HitTestAlgorithm::CHECK_ACTOR:
86 if(actor.GetCurrentProperty<bool>(Actor::Property::VISIBLE) &&
87 actor.GetProperty<bool>(Actor::Property::SENSITIVE) &&
88 actor.GetCurrentProperty<Vector4>(Actor::Property::WORLD_COLOR).a > 0.01f)
94 case Dali::HitTestAlgorithm::DESCEND_ACTOR_TREE:
96 if(actor.GetCurrentProperty<bool>(Actor::Property::VISIBLE) && // Actor is visible, if not visible then none of its children are visible.
97 actor.GetProperty<bool>(Actor::Property::SENSITIVE)) // Actor is sensitive, if insensitive none of its children should be hittable either.
112 } // anonymous namespace
114 // Positive test case for a method
115 int UtcDaliHitTestAlgorithmWithFunctor(void)
117 TestApplication application;
118 tet_infoline("Testing Dali::HitTestAlgorithm functor");
120 Stage stage = Stage::GetCurrent();
122 Actor actor = Actor::New();
123 actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
124 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
125 actor.SetProperty(Actor::Property::NAME, "NonHittableActor");
129 application.SendNotification();
130 application.Render();
132 Vector2 screenCoordinates(10.0f, 10.0f);
133 Vector2 localCoordinates;
134 actor.ScreenToLocal(localCoordinates.x, localCoordinates.y, screenCoordinates.x, screenCoordinates.y);
136 // Perform a hit-test at the given screen coordinates
137 Dali::HitTestAlgorithm::Results results;
138 Dali::HitTestAlgorithm::HitTest(stage, screenCoordinates, results, IsActorHittableFunction);
139 DALI_TEST_CHECK(results.actor != actor);
141 actor.SetProperty(Actor::Property::NAME, "HittableActor");
143 results.actor = Actor();
144 results.actorCoordinates = Vector2::ZERO;
146 // Perform a hit-test at the given screen coordinates
147 Dali::HitTestAlgorithm::HitTest(stage, screenCoordinates, results, IsActorHittableFunction);
148 DALI_TEST_CHECK(results.actor == actor);
149 DALI_TEST_EQUALS(localCoordinates, results.actorCoordinates, 0.1f, TEST_LOCATION);
153 int UtcDaliHitTestAlgorithmOrtho01(void)
155 TestApplication application;
156 tet_infoline("Testing Dali::HitTestAlgorithm with parallel Ortho camera()");
158 Stage stage = Stage::GetCurrent();
159 RenderTaskList renderTaskList = stage.GetRenderTaskList();
160 RenderTask defaultRenderTask = renderTaskList.GetTask(0u);
161 Dali::CameraActor cameraActor = defaultRenderTask.GetCameraActor();
163 Vector2 stageSize(stage.GetSize());
164 cameraActor.SetOrthographicProjection(stageSize);
165 cameraActor.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, 1600.0f));
167 Vector2 actorSize(stageSize * 0.5f);
168 // Create two actors with half the size of the stage and set them to be partially overlapping
169 Actor blue = Actor::New();
170 blue.SetProperty(Actor::Property::NAME, "Blue");
171 blue.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
172 blue.SetProperty(Actor::Property::PARENT_ORIGIN, Vector3(1.0f / 3.0f, 1.0f / 3.0f, 0.5f));
173 blue.SetProperty(Actor::Property::SIZE, actorSize);
174 blue.SetProperty(Actor::Property::POSITION_Z, 30.0f);
176 Actor green = Actor::New();
177 green.SetProperty(Actor::Property::NAME, "Green");
178 green.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
179 green.SetProperty(Actor::Property::PARENT_ORIGIN, Vector3(2.0f / 3.0f, 2.0f / 3.0f, 0.5f));
180 green.SetProperty(Actor::Property::SIZE, actorSize);
182 // Add the actors to the view
187 application.SendNotification();
188 application.Render(0);
189 application.Render(10);
191 HitTestAlgorithm::Results results;
192 HitTest(stage, stageSize / 2.0f, results, &DefaultIsActorTouchableFunction);
193 DALI_TEST_CHECK(results.actor == green);
194 DALI_TEST_EQUALS(results.actorCoordinates, actorSize * 1.0f / 6.0f, TEST_LOCATION);
196 HitTest(stage, stageSize / 3.0f, results, &DefaultIsActorTouchableFunction);
197 DALI_TEST_CHECK(results.actor == blue);
198 DALI_TEST_EQUALS(results.actorCoordinates, actorSize * 0.5f, TEST_LOCATION);
200 HitTest(stage, stageSize * 2.0f / 3.0f, results, &DefaultIsActorTouchableFunction);
201 DALI_TEST_CHECK(results.actor == green);
202 DALI_TEST_EQUALS(results.actorCoordinates, actorSize * 0.5f, TEST_LOCATION);
206 int UtcDaliHitTestAlgorithmOrtho02(void)
208 TestApplication application;
209 tet_infoline("Testing Dali::HitTestAlgorithm with offset Ortho camera()");
211 Stage stage = Stage::GetCurrent();
212 RenderTaskList renderTaskList = stage.GetRenderTaskList();
213 RenderTask defaultRenderTask = renderTaskList.GetTask(0u);
214 Dali::CameraActor cameraActor = defaultRenderTask.GetCameraActor();
216 Vector2 stageSize(stage.GetSize());
217 cameraActor.SetOrthographicProjection(-stageSize.x * 0.3f, stageSize.x * 0.7f, stageSize.y * 0.3f, -stageSize.y * 0.7f, 800.0f, 4895.0f);
218 cameraActor.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, 1600.0f));
220 Vector2 actorSize(stageSize * 0.5f);
221 // Create two actors with half the size of the stage and set them to be partially overlapping
222 Actor blue = Actor::New();
223 blue.SetProperty(Actor::Property::NAME, "Blue");
224 blue.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
225 blue.SetProperty(Actor::Property::PARENT_ORIGIN, Vector3(0.2f, 0.2f, 0.5f));
226 blue.SetProperty(Actor::Property::SIZE, actorSize);
227 blue.SetProperty(Actor::Property::POSITION_Z, 30.0f);
229 Actor green = Actor::New();
230 green.SetProperty(Actor::Property::NAME, "Green");
231 green.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
232 green.SetProperty(Actor::Property::PARENT_ORIGIN, Vector3(0.4f, 0.4f, 0.5f));
233 green.SetProperty(Actor::Property::SIZE, actorSize);
235 // Add the actors to the view
240 application.SendNotification();
241 application.Render(0);
242 application.Render(10);
245 HitTestAlgorithm::Results results;
246 HitTest(stage, Vector2(240.0f, 400.0f), results, &DefaultIsActorTouchableFunction);
247 DALI_TEST_CHECK(results.actor == green);
248 DALI_TEST_EQUALS(results.actorCoordinates, actorSize * 0.6f, 0.01f, TEST_LOCATION);
252 HitTestAlgorithm::Results results;
253 HitTest(stage, Vector2(0.001f, 0.001f), results, &DefaultIsActorTouchableFunction);
254 DALI_TEST_CHECK(results.actor == blue);
255 DALI_TEST_EQUALS(results.actorCoordinates, Vector2(0.001f, 0.001f), 0.001f, TEST_LOCATION);
259 HitTestAlgorithm::Results results;
260 HitTest(stage, stageSize, results, &DefaultIsActorTouchableFunction);
261 DALI_TEST_CHECK(!results.actor);
262 DALI_TEST_EQUALS(results.actorCoordinates, Vector2::ZERO, TEST_LOCATION);
267 HitTestAlgorithm::Results results;
268 HitTest(stage, stageSize * 0.69f, results, &DefaultIsActorTouchableFunction);
269 DALI_TEST_CHECK(results.actor == green);
270 DALI_TEST_EQUALS(results.actorCoordinates, actorSize * 0.98f, 0.01f, TEST_LOCATION);
276 int UtcDaliHitTestAlgorithmClippingActor(void)
278 TestApplication application;
279 tet_infoline("Testing Dali::HitTestAlgorithm with a stencil");
281 Stage stage = Stage::GetCurrent();
282 Actor rootLayer = stage.GetRootLayer();
283 rootLayer.SetProperty(Actor::Property::NAME, "RootLayer");
286 Layer layer = Layer::New();
287 layer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
288 layer.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
289 layer.SetProperty(Actor::Property::NAME, "layer");
292 // Create a clipping actor and add it to the layer.
293 Actor clippingActor = CreateRenderableActor();
294 clippingActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
295 clippingActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
296 clippingActor.SetProperty(Actor::Property::SIZE, Vector2(50.0f, 50.0f));
297 clippingActor.SetProperty(Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN);
298 clippingActor.SetProperty(Actor::Property::NAME, "clippingActor");
299 layer.Add(clippingActor);
301 // Create a renderable actor and add it to the clipping actor.
302 Actor childActor = CreateRenderableActor();
303 childActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
304 childActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
305 childActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
306 childActor.SetProperty(Actor::Property::NAME, "childActor");
307 clippingActor.Add(childActor);
310 application.SendNotification();
311 application.Render();
313 // Hit within clippingActor and childActor.
314 HitTestAlgorithm::Results results;
315 HitTest(stage, Vector2(10.0f, 10.0f), results, &DefaultIsActorTouchableFunction);
316 DALI_TEST_CHECK(results.actor == childActor);
317 tet_printf("Hit: %s\n", (results.actor ? results.actor.GetProperty<std::string>(Actor::Property::NAME).c_str() : "NULL"));
319 // Hit within childActor but outside of clippingActor, should hit the root-layer instead.
320 HitTest(stage, Vector2(60.0f, 60.0f), results, &DefaultIsActorTouchableFunction);
321 DALI_TEST_CHECK(results.actor == rootLayer);
322 tet_printf("Hit: %s\n", (results.actor ? results.actor.GetProperty<std::string>(Actor::Property::NAME).c_str() : "NULL"));
327 int UtcDaliHitTestAlgorithmClippingActorStress(void)
329 TestApplication application;
330 tet_infoline("Testing Dali::HitTestAlgorithm with many many stencil");
332 Stage stage = Stage::GetCurrent();
333 Actor rootLayer = stage.GetRootLayer();
334 rootLayer.SetProperty(Actor::Property::NAME, "RootLayer");
337 Layer layer = Layer::New();
338 layer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
339 layer.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
340 layer.SetProperty(Actor::Property::NAME, "layer");
343 // Create a clipping actor and add it to the layer.
344 Actor clippingActor = CreateRenderableActor();
345 clippingActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
346 clippingActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
347 clippingActor.SetProperty(Actor::Property::SIZE, Vector2(220.0f, 220.0f));
348 clippingActor.SetProperty(Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX);
349 clippingActor.SetProperty(Actor::Property::NAME, "clippingActor");
350 layer.Add(clippingActor);
352 // Create a renderable actor and add it to the clipping actor.
353 Actor latestActor = clippingActor;
354 const int depthMax = 100;
355 for(int i = 0; i < depthMax; i++)
358 sprintf(tmp, "depth%03d", i);
360 Actor childActor = CreateRenderableActor();
361 childActor.SetProperty(Actor::Property::SIZE, Vector2(220.0f, 220.0f));
362 childActor.SetProperty(Actor::Property::POSITION, Vector2(200.0f / depthMax, 200.0f / depthMax));
363 childActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
364 childActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
365 childActor.SetProperty(Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX);
366 childActor.SetProperty(Actor::Property::NAME, tmp);
368 latestActor.Add(childActor);
369 latestActor = childActor;
371 // NOTE : latestActor's TOP_LEFT position become 200.f, 200.0f
374 application.SendNotification();
375 application.Render();
377 // Hit within clippingActor and latestActor.
378 HitTestAlgorithm::Results results;
379 HitTest(stage, Vector2(201.0f, 201.0f), results, &DefaultIsActorTouchableFunction);
380 tet_printf("Hit: %s\n", (results.actor ? results.actor.GetProperty<std::string>(Actor::Property::NAME).c_str() : "NULL"));
381 DALI_TEST_CHECK(results.actor == latestActor);
383 // Hit within childActor but outside of clippingActor, should hit the root-layer instead.
384 HitTest(stage, Vector2(221.0f, 221.0f), results, &DefaultIsActorTouchableFunction);
385 tet_printf("Hit: %s\n", (results.actor ? results.actor.GetProperty<std::string>(Actor::Property::NAME).c_str() : "NULL"));
386 DALI_TEST_CHECK(results.actor == rootLayer);
391 int UtcDaliHitTestAlgorithmOverlay(void)
393 TestApplication application;
394 tet_infoline("Testing Dali::HitTestAlgorithm with overlay actors");
396 Stage stage = Stage::GetCurrent();
397 RenderTaskList renderTaskList = stage.GetRenderTaskList();
398 RenderTask defaultRenderTask = renderTaskList.GetTask(0u);
399 Dali::CameraActor cameraActor = defaultRenderTask.GetCameraActor();
401 Vector2 stageSize(stage.GetSize());
402 cameraActor.SetOrthographicProjection(stageSize);
403 cameraActor.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, 1600.0f));
405 Vector2 actorSize(stageSize * 0.5f);
406 // Create two actors with half the size of the stage and set them to be partially overlapping
407 Actor blue = Actor::New();
408 blue.SetProperty(Actor::Property::DRAW_MODE, DrawMode::OVERLAY_2D);
409 blue.SetProperty(Actor::Property::NAME, "Blue");
410 blue.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
411 blue.SetProperty(Actor::Property::PARENT_ORIGIN, Vector3(1.0f / 3.0f, 1.0f / 3.0f, 0.5f));
412 blue.SetProperty(Actor::Property::SIZE, actorSize);
413 blue.SetProperty(Actor::Property::POSITION_Z, 30.0f);
415 Actor green = Actor::New();
416 green.SetProperty(Actor::Property::NAME, "Green");
417 green.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
418 green.SetProperty(Actor::Property::PARENT_ORIGIN, Vector3(2.0f / 3.0f, 2.0f / 3.0f, 0.5f));
419 green.SetProperty(Actor::Property::SIZE, actorSize);
421 // Add the actors to the view
426 application.SendNotification();
427 application.Render(0);
428 application.Render(10);
430 HitTestAlgorithm::Results results;
432 //Hit in the intersection. Should pick the blue actor since it is an overlay.
433 HitTest(stage, stageSize / 2.0f, results, &DefaultIsActorTouchableFunction);
434 DALI_TEST_CHECK(results.actor == blue);
435 DALI_TEST_EQUALS(results.actorCoordinates, actorSize * 5.0f / 6.0f, TEST_LOCATION);
437 //Hit in the blue actor
438 HitTest(stage, stageSize / 3.0f, results, &DefaultIsActorTouchableFunction);
439 DALI_TEST_CHECK(results.actor == blue);
440 DALI_TEST_EQUALS(results.actorCoordinates, actorSize * 0.5f, TEST_LOCATION);
442 //Hit in the green actor
443 HitTest(stage, stageSize * 2.0f / 3.0f, results, &DefaultIsActorTouchableFunction);
444 DALI_TEST_CHECK(results.actor == green);
445 DALI_TEST_EQUALS(results.actorCoordinates, actorSize * 0.5f, TEST_LOCATION);
447 // Create new actor child as blue. It will be shown over the blue, and green.
448 Actor red = Actor::New();
449 red.SetProperty(Actor::Property::NAME, "Red");
450 red.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
451 red.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
452 red.SetProperty(Actor::Property::POSITION, Vector2(actorSize.x * 5.0f / 6.0f, -actorSize.y * 1.0f / 6.0f));
453 red.SetProperty(Actor::Property::SIZE, actorSize);
458 application.SendNotification();
459 application.Render(0);
460 application.Render(10);
462 //Hit in the intersection red, green, blue. Should pick the red actor since it is an child of overlay.
463 HitTest(stage, Vector2(stageSize.x * 13.0f / 24.0f, stageSize.y * 11.0f / 24.0f), results, &DefaultIsActorTouchableFunction);
464 tet_printf("%d %d %d , %f %f\n", results.actor == red ? 1 : 0, results.actor == green ? 1 : 0, results.actor == blue ? 1 : 0, results.actorCoordinates.x, results.actorCoordinates.y);
465 DALI_TEST_CHECK(results.actor == red);
466 DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 1.0f / 12.0f, actorSize.y * 11.0f / 12.0f), TEST_LOCATION);
468 //Hit in the intersection red, blue. Should pick the red actor since it is an child of blue.
469 HitTest(stage, Vector2(stageSize.x * 13.0f / 24.0f, stageSize.y * 9.0f / 24.0f), results, &DefaultIsActorTouchableFunction);
470 tet_printf("%d %d %d , %f %f\n", results.actor == red ? 1 : 0, results.actor == green ? 1 : 0, results.actor == blue ? 1 : 0, results.actorCoordinates.x, results.actorCoordinates.y);
471 DALI_TEST_CHECK(results.actor == red);
472 DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 1.0f / 12.0f, actorSize.y * 9.0f / 12.0f), TEST_LOCATION);
474 //Hit in the intersection red, green. Should pick the red actor since it is an child of overlay.
475 HitTest(stage, Vector2(stageSize.x * 15.0f / 24.0f, stageSize.y * 11.0f / 24.0f), results, &DefaultIsActorTouchableFunction);
476 tet_printf("%d %d %d , %f %f\n", results.actor == red ? 1 : 0, results.actor == green ? 1 : 0, results.actor == blue ? 1 : 0, results.actorCoordinates.x, results.actorCoordinates.y);
477 DALI_TEST_CHECK(results.actor == red);
478 DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 3.0f / 12.0f, actorSize.y * 11.0f / 12.0f), TEST_LOCATION);
480 //Hit in the intersection blue, green. Should pick the blue actor since it is an overlay.
481 HitTest(stage, Vector2(stageSize.x * 11.0f / 24.0f, stageSize.y * 13.0f / 24.0f), results, &DefaultIsActorTouchableFunction);
482 tet_printf("%d %d %d , %f %f\n", results.actor == red ? 1 : 0, results.actor == green ? 1 : 0, results.actor == blue ? 1 : 0, results.actorCoordinates.x, results.actorCoordinates.y);
483 DALI_TEST_CHECK(results.actor == blue);
484 DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 9.0f / 12.0f, actorSize.y * 11.0f / 12.0f), TEST_LOCATION);
486 // Change blue's draw mode as normal. now blue < red < green
487 blue.SetProperty(Actor::Property::DRAW_MODE, DrawMode::NORMAL);
490 application.SendNotification();
491 application.Render(0);
492 application.Render(10);
494 //Hit in the intersection red, green, blue. Should pick the green actor since it is latest ordered actor.
495 HitTest(stage, Vector2(stageSize.x * 13.0f / 24.0f, stageSize.y * 11.0f / 24.0f), results, &DefaultIsActorTouchableFunction);
496 tet_printf("%d %d %d , %f %f\n", results.actor == red ? 1 : 0, results.actor == green ? 1 : 0, results.actor == blue ? 1 : 0, results.actorCoordinates.x, results.actorCoordinates.y);
497 DALI_TEST_CHECK(results.actor == green);
498 DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 3.0f / 12.0f, actorSize.y * 1.0f / 12.0f), TEST_LOCATION);
500 //Hit in the intersection red, blue. Should pick the red actor since it is an child of blue.
501 HitTest(stage, Vector2(stageSize.x * 13.0f / 24.0f, stageSize.y * 9.0f / 24.0f), results, &DefaultIsActorTouchableFunction);
502 tet_printf("%d %d %d , %f %f\n", results.actor == red ? 1 : 0, results.actor == green ? 1 : 0, results.actor == blue ? 1 : 0, results.actorCoordinates.x, results.actorCoordinates.y);
503 DALI_TEST_CHECK(results.actor == red);
504 DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 1.0f / 12.0f, actorSize.y * 9.0f / 12.0f), TEST_LOCATION);
506 //Hit in the intersection red, green. Should pick the green actor since it is latest ordered actor.
507 HitTest(stage, Vector2(stageSize.x * 15.0f / 24.0f, stageSize.y * 11.0f / 24.0f), results, &DefaultIsActorTouchableFunction);
508 tet_printf("%d %d %d , %f %f\n", results.actor == red ? 1 : 0, results.actor == green ? 1 : 0, results.actor == blue ? 1 : 0, results.actorCoordinates.x, results.actorCoordinates.y);
509 DALI_TEST_CHECK(results.actor == green);
510 DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 5.0f / 12.0f, actorSize.y * 1.0f / 12.0f), TEST_LOCATION);
512 //Hit in the intersection blue, green. Should pick the green actor since it is latest ordered actor.
513 HitTest(stage, Vector2(stageSize.x * 11.0f / 24.0f, stageSize.y * 13.0f / 24.0f), results, &DefaultIsActorTouchableFunction);
514 tet_printf("%d %d %d , %f %f\n", results.actor == red ? 1 : 0, results.actor == green ? 1 : 0, results.actor == blue ? 1 : 0, results.actorCoordinates.x, results.actorCoordinates.y);
515 DALI_TEST_CHECK(results.actor == green);
516 DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 1.0f / 12.0f, actorSize.y * 3.0f / 12.0f), TEST_LOCATION);
520 int UtcDaliHitTestAlgorithmDoesWantedHitTest(void)
522 TestApplication application;
523 tet_infoline("Testing Dali::HitTestAlgorithm with does wanted to HitTest");
525 Stage stage = Stage::GetCurrent();
526 RenderTaskList renderTaskList = stage.GetRenderTaskList();
527 RenderTask defaultRenderTask = renderTaskList.GetTask(0u);
528 Dali::CameraActor cameraActor = defaultRenderTask.GetCameraActor();
530 Vector2 stageSize(stage.GetSize());
531 cameraActor.SetOrthographicProjection(stageSize);
532 cameraActor.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, 1600.0f));
534 Vector2 actorSize(stageSize * 0.5f);
535 // Create two actors with half the size of the stage and set them to be overlapping
536 Actor blue = Actor::New();
537 blue.SetProperty(Actor::Property::NAME, "Blue");
538 blue.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
539 blue.SetProperty(Actor::Property::PARENT_ORIGIN, AnchorPoint::CENTER);
540 blue.SetProperty(Actor::Property::SIZE, actorSize);
542 Actor green = Actor::New();
543 green.SetProperty(Actor::Property::NAME, "Green");
544 green.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
545 green.SetProperty(Actor::Property::PARENT_ORIGIN, AnchorPoint::CENTER);
546 green.SetProperty(Actor::Property::SIZE, actorSize);
548 // Add the actors to the view
552 // connect to its hit-test signal
553 Dali::DevelActor::HitTestResultSignal(green).Connect(TestHitTestTouchCallback);
556 application.SendNotification();
557 application.Render(0);
558 application.Render(10);
560 gHitTestTouchCallBackCalled = false;
562 HitTestAlgorithm::Results results;
563 HitTest(stage, stageSize / 2.0f, results, &DefaultIsActorTouchableFunction);
565 // check hit-test events
566 // The green actor received an event that the green actor was hit.
567 DALI_TEST_CHECK(gHitTestTouchCallBackCalled == true);
568 // The green actor passed the hit-test. So blue was the final hit.
569 DALI_TEST_CHECK(results.actor == blue);
574 int UtcDaliHitTestAlgorithmOrder(void)
576 TestApplication application;
577 tet_infoline("Testing Dali::HitTestAlgorithm between On/Off render task");
579 Stage stage = Stage::GetCurrent();
580 Vector2 stageSize(stage.GetSize());
582 Actor blue = Actor::New();
583 blue[Dali::Actor::Property::NAME] = "Blue";
584 blue[Dali::Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER;
585 blue[Dali::Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER;
586 blue[Dali::Actor::Property::WIDTH_RESIZE_POLICY] = ResizePolicy::FILL_TO_PARENT;
587 blue[Dali::Actor::Property::HEIGHT_RESIZE_POLICY] = ResizePolicy::FILL_TO_PARENT;
589 Actor green = Actor::New();
590 green[Dali::Actor::Property::NAME] = "Green";
591 green[Dali::Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER;
592 green[Dali::Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER;
593 green[Dali::Actor::Property::WIDTH_RESIZE_POLICY] = ResizePolicy::FILL_TO_PARENT;
594 green[Dali::Actor::Property::HEIGHT_RESIZE_POLICY] = ResizePolicy::FILL_TO_PARENT;
599 RenderTaskList renderTaskList = stage.GetRenderTaskList();
600 RenderTask offRenderTask = renderTaskList.CreateTask();
602 Dali::CameraActor cameraActor = Dali::CameraActor::New(stageSize);
603 cameraActor[Dali::Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER;
604 cameraActor[Dali::Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER;
605 stage.Add(cameraActor);
607 offRenderTask.SetExclusive(true);
608 offRenderTask.SetInputEnabled(true);
609 offRenderTask.SetCameraActor(cameraActor);
610 offRenderTask.SetSourceActor(green);
611 offRenderTask.SetScreenToFrameBufferMappingActor(green);
613 Dali::Texture texture = Dali::Texture::New(TextureType::TEXTURE_2D, Pixel::RGB888, unsigned(stageSize.width), unsigned(stageSize.height));
614 FrameBuffer renderTarget = FrameBuffer::New(stageSize.width, stageSize.height, FrameBuffer::Attachment::DEPTH);
615 renderTarget.AttachColorTexture(texture);
616 offRenderTask.SetFrameBuffer(renderTarget);
619 application.SendNotification();
620 application.Render(10);
622 HitTestAlgorithm::Results results;
623 HitTest(stage, stageSize / 2.0f, results, &DefaultIsActorTouchableFunction);
624 DALI_TEST_CHECK(results.actor == green);