4d17b65d0b147e1f5605ce67f403282a120d5e45
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-HitTestAlgorithm.cpp
1 /*
2  * Copyright (c) 2022 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 <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>
23 #include <stdlib.h>
24
25 #include <iostream>
26
27 using namespace Dali;
28
29 namespace
30 {
31 bool        gHitTestTouchCallBackCalled = false;
32 static bool TestHitTestTouchCallback(Actor, const TouchEvent&)
33 {
34   gHitTestTouchCallBackCalled = true;
35   return false;
36   END_TEST;
37 }
38
39 /**
40  * The functor to be used in the hit-test algorithm to check whether the actor is hittable.
41  */
42 bool IsActorHittableFunction(Actor actor, Dali::HitTestAlgorithm::TraverseType type)
43 {
44   bool hittable = false;
45
46   switch(type)
47   {
48     case Dali::HitTestAlgorithm::CHECK_ACTOR:
49     {
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
52       {
53         // Check whether the actor has the specific name "HittableActor"
54         if(actor.GetProperty<std::string>(Actor::Property::NAME) == "HittableActor")
55         {
56           hittable = true;
57         }
58       }
59       break;
60     }
61     case Dali::HitTestAlgorithm::DESCEND_ACTOR_TREE:
62     {
63       if(actor.GetCurrentProperty<bool>(Actor::Property::VISIBLE)) // Actor is visible, if not visible then none of its children are visible.
64       {
65         hittable = true;
66       }
67       break;
68     }
69     default:
70     {
71       break;
72     }
73   }
74
75   return hittable;
76 };
77
78 bool DefaultIsActorTouchableFunction(Dali::Actor actor, Dali::HitTestAlgorithm::TraverseType type)
79 {
80   bool hittable = false;
81
82   switch(type)
83   {
84     case Dali::HitTestAlgorithm::CHECK_ACTOR:
85     {
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)
89       {
90         hittable = true;
91       }
92       break;
93     }
94     case Dali::HitTestAlgorithm::DESCEND_ACTOR_TREE:
95     {
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.
98       {
99         hittable = true;
100       }
101       break;
102     }
103     default:
104     {
105       break;
106     }
107   }
108
109   return hittable;
110 };
111
112 } // anonymous namespace
113
114 // Positive test case for a method
115 int UtcDaliHitTestAlgorithmWithFunctor(void)
116 {
117   TestApplication application;
118   tet_infoline("Testing Dali::HitTestAlgorithm functor");
119
120   Stage stage = Stage::GetCurrent();
121
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");
126   stage.Add(actor);
127
128   // Render and notify
129   application.SendNotification();
130   application.Render();
131
132   Vector2 screenCoordinates(10.0f, 10.0f);
133   Vector2 localCoordinates;
134   actor.ScreenToLocal(localCoordinates.x, localCoordinates.y, screenCoordinates.x, screenCoordinates.y);
135
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);
140
141   actor.SetProperty(Actor::Property::NAME, "HittableActor");
142
143   results.actor            = Actor();
144   results.actorCoordinates = Vector2::ZERO;
145
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);
150   END_TEST;
151 }
152
153 int UtcDaliHitTestAlgorithmOrtho01(void)
154 {
155   TestApplication application;
156   tet_infoline("Testing Dali::HitTestAlgorithm with parallel Ortho camera()");
157
158   Stage             stage             = Stage::GetCurrent();
159   RenderTaskList    renderTaskList    = stage.GetRenderTaskList();
160   RenderTask        defaultRenderTask = renderTaskList.GetTask(0u);
161   Dali::CameraActor cameraActor       = defaultRenderTask.GetCameraActor();
162
163   Vector2 stageSize(stage.GetSize());
164   cameraActor.SetOrthographicProjection(stageSize);
165   cameraActor.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, 1600.0f));
166
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);
175
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);
181
182   // Add the actors to the view
183   stage.Add(blue);
184   stage.Add(green);
185
186   // Render and notify
187   application.SendNotification();
188   application.Render(0);
189   application.Render(10);
190
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);
195
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);
199
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);
203   END_TEST;
204 }
205
206 int UtcDaliHitTestAlgorithmOrtho02(void)
207 {
208   TestApplication application;
209   tet_infoline("Testing Dali::HitTestAlgorithm with offset Ortho camera()");
210
211   Stage             stage             = Stage::GetCurrent();
212   RenderTaskList    renderTaskList    = stage.GetRenderTaskList();
213   RenderTask        defaultRenderTask = renderTaskList.GetTask(0u);
214   Dali::CameraActor cameraActor       = defaultRenderTask.GetCameraActor();
215
216   Vector2 stageSize(stage.GetSize());
217   cameraActor.SetOrthographicProjection(stageSize);
218   cameraActor.SetNearClippingPlane(800.0f);
219   cameraActor.SetFarClippingPlane(4895.0f);
220
221   // Move camera not centered position.
222   cameraActor.SetProperty(Actor::Property::POSITION, Vector3(stageSize.x * 0.2f, stageSize.y * 0.2f, 1600.0f));
223
224   Vector2 actorSize(stageSize * 0.5f);
225   // Create two actors with half the size of the stage and set them to be partially overlapping
226   Actor blue = Actor::New();
227   blue.SetProperty(Actor::Property::NAME, "Blue");
228   blue.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
229   blue.SetProperty(Actor::Property::PARENT_ORIGIN, Vector3(0.2f, 0.2f, 0.5f));
230   blue.SetProperty(Actor::Property::SIZE, actorSize);
231   blue.SetProperty(Actor::Property::POSITION_Z, 30.0f);
232
233   Actor green = Actor::New();
234   green.SetProperty(Actor::Property::NAME, "Green");
235   green.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
236   green.SetProperty(Actor::Property::PARENT_ORIGIN, Vector3(0.4f, 0.4f, 0.5f));
237   green.SetProperty(Actor::Property::SIZE, actorSize);
238
239   // Add the actors to the view
240   stage.Add(blue);
241   stage.Add(green);
242
243   // Render and notify
244   application.SendNotification();
245   application.Render(0);
246   application.Render(10);
247
248   {
249     HitTestAlgorithm::Results results;
250     HitTest(stage, Vector2(240.0f, 400.0f), results, &DefaultIsActorTouchableFunction);
251     DALI_TEST_CHECK(results.actor == green);
252     DALI_TEST_EQUALS(results.actorCoordinates, actorSize * 0.6f, 0.01f, TEST_LOCATION);
253   }
254
255   {
256     HitTestAlgorithm::Results results;
257     HitTest(stage, Vector2(0.001f, 0.001f), results, &DefaultIsActorTouchableFunction);
258     DALI_TEST_CHECK(results.actor == blue);
259     DALI_TEST_EQUALS(results.actorCoordinates, Vector2(0.001f, 0.001f), 0.001f, TEST_LOCATION);
260   }
261
262   {
263     HitTestAlgorithm::Results results;
264     HitTest(stage, stageSize, results, &DefaultIsActorTouchableFunction);
265     DALI_TEST_CHECK(!results.actor);
266     DALI_TEST_EQUALS(results.actorCoordinates, Vector2::ZERO, TEST_LOCATION);
267   }
268
269   // Just inside green
270   {
271     HitTestAlgorithm::Results results;
272     HitTest(stage, stageSize * 0.69f, results, &DefaultIsActorTouchableFunction);
273     DALI_TEST_CHECK(results.actor == green);
274     DALI_TEST_EQUALS(results.actorCoordinates, actorSize * 0.98f, 0.01f, TEST_LOCATION);
275   }
276
277   END_TEST;
278 }
279
280 int UtcDaliHitTestAlgorithmClippingActor(void)
281 {
282   TestApplication application;
283   tet_infoline("Testing Dali::HitTestAlgorithm with a stencil");
284
285   Stage stage     = Stage::GetCurrent();
286   Actor rootLayer = stage.GetRootLayer();
287   rootLayer.SetProperty(Actor::Property::NAME, "RootLayer");
288
289   // Create a layer
290   Layer layer = Layer::New();
291   layer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
292   layer.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
293   layer.SetProperty(Actor::Property::NAME, "layer");
294   stage.Add(layer);
295
296   // Create a clipping actor and add it to the layer.
297   Actor clippingActor = CreateRenderableActor();
298   clippingActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
299   clippingActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
300   clippingActor.SetProperty(Actor::Property::SIZE, Vector2(50.0f, 50.0f));
301   clippingActor.SetProperty(Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN);
302   clippingActor.SetProperty(Actor::Property::NAME, "clippingActor");
303   layer.Add(clippingActor);
304
305   // Create a renderable actor and add it to the clipping actor.
306   Actor childActor = CreateRenderableActor();
307   childActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
308   childActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
309   childActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
310   childActor.SetProperty(Actor::Property::NAME, "childActor");
311   clippingActor.Add(childActor);
312
313   // Render and notify
314   application.SendNotification();
315   application.Render();
316
317   // Hit within clippingActor and childActor.
318   HitTestAlgorithm::Results results;
319   HitTest(stage, Vector2(10.0f, 10.0f), results, &DefaultIsActorTouchableFunction);
320   DALI_TEST_CHECK(results.actor == childActor);
321   tet_printf("Hit: %s\n", (results.actor ? results.actor.GetProperty<std::string>(Actor::Property::NAME).c_str() : "NULL"));
322
323   // Hit within childActor but outside of clippingActor, should hit the root-layer instead.
324   HitTest(stage, Vector2(60.0f, 60.0f), results, &DefaultIsActorTouchableFunction);
325   DALI_TEST_CHECK(results.actor == rootLayer);
326   tet_printf("Hit: %s\n", (results.actor ? results.actor.GetProperty<std::string>(Actor::Property::NAME).c_str() : "NULL"));
327
328   END_TEST;
329 }
330
331 int UtcDaliHitTestAlgorithmClippingActorStress(void)
332 {
333   TestApplication application;
334   tet_infoline("Testing Dali::HitTestAlgorithm with many many stencil");
335
336   Stage stage     = Stage::GetCurrent();
337   Actor rootLayer = stage.GetRootLayer();
338   rootLayer.SetProperty(Actor::Property::NAME, "RootLayer");
339
340   // Create a layer
341   Layer layer = Layer::New();
342   layer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
343   layer.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
344   layer.SetProperty(Actor::Property::NAME, "layer");
345   stage.Add(layer);
346
347   // Create a clipping actor and add it to the layer.
348   Actor clippingActor = CreateRenderableActor();
349   clippingActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
350   clippingActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
351   clippingActor.SetProperty(Actor::Property::SIZE, Vector2(220.0f, 220.0f));
352   clippingActor.SetProperty(Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX);
353   clippingActor.SetProperty(Actor::Property::NAME, "clippingActor");
354   layer.Add(clippingActor);
355
356   // Create a renderable actor and add it to the clipping actor.
357   Actor     latestActor = clippingActor;
358   const int depthMax    = 100;
359   for(int i = 0; i < depthMax; i++)
360   {
361     char tmp[29];
362     sprintf(tmp, "depth%03d", i);
363
364     Actor childActor = CreateRenderableActor();
365     childActor.SetProperty(Actor::Property::SIZE, Vector2(220.0f, 220.0f));
366     childActor.SetProperty(Actor::Property::POSITION, Vector2(200.0f / depthMax, 200.0f / depthMax));
367     childActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
368     childActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
369     childActor.SetProperty(Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX);
370     childActor.SetProperty(Actor::Property::NAME, tmp);
371
372     latestActor.Add(childActor);
373     latestActor = childActor;
374   }
375   // NOTE : latestActor's TOP_LEFT position become 200.f, 200.0f
376
377   // Render and notify
378   application.SendNotification();
379   application.Render();
380
381   // Hit within clippingActor and latestActor.
382   HitTestAlgorithm::Results results;
383   HitTest(stage, Vector2(201.0f, 201.0f), results, &DefaultIsActorTouchableFunction);
384   tet_printf("Hit: %s\n", (results.actor ? results.actor.GetProperty<std::string>(Actor::Property::NAME).c_str() : "NULL"));
385   DALI_TEST_CHECK(results.actor == latestActor);
386
387   // Hit within childActor but outside of clippingActor, should hit the root-layer instead.
388   HitTest(stage, Vector2(221.0f, 221.0f), results, &DefaultIsActorTouchableFunction);
389   tet_printf("Hit: %s\n", (results.actor ? results.actor.GetProperty<std::string>(Actor::Property::NAME).c_str() : "NULL"));
390   DALI_TEST_CHECK(results.actor == rootLayer);
391
392   END_TEST;
393 }
394
395 int UtcDaliHitTestAlgorithmOverlay(void)
396 {
397   TestApplication application;
398   tet_infoline("Testing Dali::HitTestAlgorithm with overlay actors");
399
400   Stage             stage             = Stage::GetCurrent();
401   RenderTaskList    renderTaskList    = stage.GetRenderTaskList();
402   RenderTask        defaultRenderTask = renderTaskList.GetTask(0u);
403   Dali::CameraActor cameraActor       = defaultRenderTask.GetCameraActor();
404
405   Vector2 stageSize(stage.GetSize());
406   cameraActor.SetOrthographicProjection(stageSize);
407   cameraActor.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, 1600.0f));
408
409   Vector2 actorSize(stageSize * 0.5f);
410   // Create two actors with half the size of the stage and set them to be partially overlapping
411   Actor blue = Actor::New();
412   blue.SetProperty(Actor::Property::DRAW_MODE, DrawMode::OVERLAY_2D);
413   blue.SetProperty(Actor::Property::NAME, "Blue");
414   blue.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
415   blue.SetProperty(Actor::Property::PARENT_ORIGIN, Vector3(1.0f / 3.0f, 1.0f / 3.0f, 0.5f));
416   blue.SetProperty(Actor::Property::SIZE, actorSize);
417   blue.SetProperty(Actor::Property::POSITION_Z, 30.0f);
418
419   Actor green = Actor::New();
420   green.SetProperty(Actor::Property::NAME, "Green");
421   green.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
422   green.SetProperty(Actor::Property::PARENT_ORIGIN, Vector3(2.0f / 3.0f, 2.0f / 3.0f, 0.5f));
423   green.SetProperty(Actor::Property::SIZE, actorSize);
424
425   // Add the actors to the view
426   stage.Add(blue);
427   stage.Add(green);
428
429   // Render and notify
430   application.SendNotification();
431   application.Render(0);
432   application.Render(10);
433
434   HitTestAlgorithm::Results results;
435
436   //Hit in the intersection. Should pick the blue actor since it is an overlay.
437   HitTest(stage, stageSize / 2.0f, results, &DefaultIsActorTouchableFunction);
438   DALI_TEST_CHECK(results.actor == blue);
439   DALI_TEST_EQUALS(results.actorCoordinates, actorSize * 5.0f / 6.0f, TEST_LOCATION);
440
441   //Hit in the blue actor
442   HitTest(stage, stageSize / 3.0f, results, &DefaultIsActorTouchableFunction);
443   DALI_TEST_CHECK(results.actor == blue);
444   DALI_TEST_EQUALS(results.actorCoordinates, actorSize * 0.5f, TEST_LOCATION);
445
446   //Hit in the green actor
447   HitTest(stage, stageSize * 2.0f / 3.0f, results, &DefaultIsActorTouchableFunction);
448   DALI_TEST_CHECK(results.actor == green);
449   DALI_TEST_EQUALS(results.actorCoordinates, actorSize * 0.5f, TEST_LOCATION);
450
451   // Create new actor child as blue. It will be shown over the blue, and green.
452   Actor red = Actor::New();
453   red.SetProperty(Actor::Property::NAME, "Red");
454   red.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
455   red.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
456   red.SetProperty(Actor::Property::POSITION, Vector2(actorSize.x * 5.0f / 6.0f, -actorSize.y * 1.0f / 6.0f));
457   red.SetProperty(Actor::Property::SIZE, actorSize);
458
459   blue.Add(red);
460
461   // Render and notify
462   application.SendNotification();
463   application.Render(0);
464   application.Render(10);
465
466   //Hit in the intersection red, green, blue. Should pick the red actor since it is an child of overlay.
467   HitTest(stage, Vector2(stageSize.x * 13.0f / 24.0f, stageSize.y * 11.0f / 24.0f), results, &DefaultIsActorTouchableFunction);
468   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);
469   DALI_TEST_CHECK(results.actor == red);
470   DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 1.0f / 12.0f, actorSize.y * 11.0f / 12.0f), TEST_LOCATION);
471
472   //Hit in the intersection red, blue. Should pick the red actor since it is an child of blue.
473   HitTest(stage, Vector2(stageSize.x * 13.0f / 24.0f, stageSize.y * 9.0f / 24.0f), results, &DefaultIsActorTouchableFunction);
474   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);
475   DALI_TEST_CHECK(results.actor == red);
476   DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 1.0f / 12.0f, actorSize.y * 9.0f / 12.0f), TEST_LOCATION);
477
478   //Hit in the intersection red, green. Should pick the red actor since it is an child of overlay.
479   HitTest(stage, Vector2(stageSize.x * 15.0f / 24.0f, stageSize.y * 11.0f / 24.0f), results, &DefaultIsActorTouchableFunction);
480   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);
481   DALI_TEST_CHECK(results.actor == red);
482   DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 3.0f / 12.0f, actorSize.y * 11.0f / 12.0f), TEST_LOCATION);
483
484   //Hit in the intersection blue, green. Should pick the blue actor since it is an overlay.
485   HitTest(stage, Vector2(stageSize.x * 11.0f / 24.0f, stageSize.y * 13.0f / 24.0f), results, &DefaultIsActorTouchableFunction);
486   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);
487   DALI_TEST_CHECK(results.actor == blue);
488   DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 9.0f / 12.0f, actorSize.y * 11.0f / 12.0f), TEST_LOCATION);
489
490   // Change blue's draw mode as normal. now blue < red < green
491   blue.SetProperty(Actor::Property::DRAW_MODE, DrawMode::NORMAL);
492
493   // Render and notify
494   application.SendNotification();
495   application.Render(0);
496   application.Render(10);
497
498   //Hit in the intersection red, green, blue. Should pick the green actor since it is latest ordered actor.
499   HitTest(stage, Vector2(stageSize.x * 13.0f / 24.0f, stageSize.y * 11.0f / 24.0f), results, &DefaultIsActorTouchableFunction);
500   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);
501   DALI_TEST_CHECK(results.actor == green);
502   DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 3.0f / 12.0f, actorSize.y * 1.0f / 12.0f), TEST_LOCATION);
503
504   //Hit in the intersection red, blue. Should pick the red actor since it is an child of blue.
505   HitTest(stage, Vector2(stageSize.x * 13.0f / 24.0f, stageSize.y * 9.0f / 24.0f), results, &DefaultIsActorTouchableFunction);
506   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);
507   DALI_TEST_CHECK(results.actor == red);
508   DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 1.0f / 12.0f, actorSize.y * 9.0f / 12.0f), TEST_LOCATION);
509
510   //Hit in the intersection red, green. Should pick the green actor since it is latest ordered actor.
511   HitTest(stage, Vector2(stageSize.x * 15.0f / 24.0f, stageSize.y * 11.0f / 24.0f), results, &DefaultIsActorTouchableFunction);
512   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);
513   DALI_TEST_CHECK(results.actor == green);
514   DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 5.0f / 12.0f, actorSize.y * 1.0f / 12.0f), TEST_LOCATION);
515
516   //Hit in the intersection blue, green. Should pick the green actor since it is latest ordered actor.
517   HitTest(stage, Vector2(stageSize.x * 11.0f / 24.0f, stageSize.y * 13.0f / 24.0f), results, &DefaultIsActorTouchableFunction);
518   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);
519   DALI_TEST_CHECK(results.actor == green);
520   DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 1.0f / 12.0f, actorSize.y * 3.0f / 12.0f), TEST_LOCATION);
521   END_TEST;
522 }
523
524 int UtcDaliHitTestAlgorithmDoesWantedHitTest(void)
525 {
526   TestApplication application;
527   tet_infoline("Testing Dali::HitTestAlgorithm with does wanted to HitTest");
528
529   Stage             stage             = Stage::GetCurrent();
530   RenderTaskList    renderTaskList    = stage.GetRenderTaskList();
531   RenderTask        defaultRenderTask = renderTaskList.GetTask(0u);
532   Dali::CameraActor cameraActor       = defaultRenderTask.GetCameraActor();
533
534   Vector2 stageSize(stage.GetSize());
535   cameraActor.SetOrthographicProjection(stageSize);
536   cameraActor.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, 1600.0f));
537
538   Vector2 actorSize(stageSize * 0.5f);
539   // Create two actors with half the size of the stage and set them to be overlapping
540   Actor blue = Actor::New();
541   blue.SetProperty(Actor::Property::NAME, "Blue");
542   blue.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
543   blue.SetProperty(Actor::Property::PARENT_ORIGIN, AnchorPoint::CENTER);
544   blue.SetProperty(Actor::Property::SIZE, actorSize);
545
546   Actor green = Actor::New();
547   green.SetProperty(Actor::Property::NAME, "Green");
548   green.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
549   green.SetProperty(Actor::Property::PARENT_ORIGIN, AnchorPoint::CENTER);
550   green.SetProperty(Actor::Property::SIZE, actorSize);
551
552   // Add the actors to the view
553   stage.Add(blue);
554   stage.Add(green);
555
556   // connect to its hit-test signal
557   Dali::DevelActor::HitTestResultSignal(green).Connect(TestHitTestTouchCallback);
558
559   // Render and notify
560   application.SendNotification();
561   application.Render(0);
562   application.Render(10);
563
564   gHitTestTouchCallBackCalled = false;
565
566   HitTestAlgorithm::Results results;
567   HitTest(stage, stageSize / 2.0f, results, &DefaultIsActorTouchableFunction);
568
569   // check hit-test events
570   // The green actor received an event that the green actor was hit.
571   DALI_TEST_CHECK(gHitTestTouchCallBackCalled == true);
572   // The green actor passed the hit-test. So blue was the final hit.
573   DALI_TEST_CHECK(results.actor == blue);
574
575   END_TEST;
576 }
577
578 int UtcDaliHitTestAlgorithmOrder(void)
579 {
580   TestApplication application;
581   tet_infoline("Testing Dali::HitTestAlgorithm between On/Off render task");
582
583   Stage   stage = Stage::GetCurrent();
584   Vector2 stageSize(stage.GetSize());
585
586   Actor blue                                        = Actor::New();
587   blue[Dali::Actor::Property::NAME]                 = "Blue";
588   blue[Dali::Actor::Property::ANCHOR_POINT]         = AnchorPoint::CENTER;
589   blue[Dali::Actor::Property::PARENT_ORIGIN]        = ParentOrigin::CENTER;
590   blue[Dali::Actor::Property::WIDTH_RESIZE_POLICY]  = ResizePolicy::FILL_TO_PARENT;
591   blue[Dali::Actor::Property::HEIGHT_RESIZE_POLICY] = ResizePolicy::FILL_TO_PARENT;
592
593   Actor green                                        = Actor::New();
594   green[Dali::Actor::Property::NAME]                 = "Green";
595   green[Dali::Actor::Property::ANCHOR_POINT]         = AnchorPoint::CENTER;
596   green[Dali::Actor::Property::PARENT_ORIGIN]        = ParentOrigin::CENTER;
597   green[Dali::Actor::Property::WIDTH_RESIZE_POLICY]  = ResizePolicy::FILL_TO_PARENT;
598   green[Dali::Actor::Property::HEIGHT_RESIZE_POLICY] = ResizePolicy::FILL_TO_PARENT;
599
600   stage.Add(blue);
601   stage.Add(green);
602
603   RenderTaskList renderTaskList = stage.GetRenderTaskList();
604   RenderTask     offRenderTask  = renderTaskList.CreateTask();
605
606   Dali::CameraActor cameraActor                     = Dali::CameraActor::New(stageSize);
607   cameraActor[Dali::Actor::Property::ANCHOR_POINT]  = AnchorPoint::CENTER;
608   cameraActor[Dali::Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER;
609   stage.Add(cameraActor);
610
611   offRenderTask.SetExclusive(true);
612   offRenderTask.SetInputEnabled(true);
613   offRenderTask.SetCameraActor(cameraActor);
614   offRenderTask.SetSourceActor(green);
615   offRenderTask.SetScreenToFrameBufferMappingActor(green);
616
617   Dali::Texture texture      = Dali::Texture::New(TextureType::TEXTURE_2D, Pixel::RGB888, unsigned(stageSize.width), unsigned(stageSize.height));
618   FrameBuffer   renderTarget = FrameBuffer::New(stageSize.width, stageSize.height, FrameBuffer::Attachment::DEPTH);
619   renderTarget.AttachColorTexture(texture);
620   offRenderTask.SetFrameBuffer(renderTarget);
621
622   // Render and notify
623   application.SendNotification();
624   application.Render(10);
625
626   HitTestAlgorithm::Results results;
627   HitTest(stage, stageSize / 2.0f, results, &DefaultIsActorTouchableFunction);
628   DALI_TEST_CHECK(results.actor == green);
629
630   END_TEST;
631 }