e62406a977a868216218388d17ad7f49932a5f78
[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.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));
219
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);
228
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);
234
235   // Add the actors to the view
236   stage.Add(blue);
237   stage.Add(green);
238
239   // Render and notify
240   application.SendNotification();
241   application.Render(0);
242   application.Render(10);
243
244   {
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);
249   }
250
251   {
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);
256   }
257
258   {
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);
263   }
264
265   // Just inside green
266   {
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);
271   }
272
273   END_TEST;
274 }
275
276 int UtcDaliHitTestAlgorithmClippingActor(void)
277 {
278   TestApplication application;
279   tet_infoline("Testing Dali::HitTestAlgorithm with a stencil");
280
281   Stage stage     = Stage::GetCurrent();
282   Actor rootLayer = stage.GetRootLayer();
283   rootLayer.SetProperty(Actor::Property::NAME, "RootLayer");
284
285   // Create a layer
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");
290   stage.Add(layer);
291
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);
300
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);
308
309   // Render and notify
310   application.SendNotification();
311   application.Render();
312
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"));
318
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"));
323
324   END_TEST;
325 }
326
327 int UtcDaliHitTestAlgorithmClippingActorStress(void)
328 {
329   TestApplication application;
330   tet_infoline("Testing Dali::HitTestAlgorithm with many many stencil");
331
332   Stage stage     = Stage::GetCurrent();
333   Actor rootLayer = stage.GetRootLayer();
334   rootLayer.SetProperty(Actor::Property::NAME, "RootLayer");
335
336   // Create a layer
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");
341   stage.Add(layer);
342
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);
351
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++)
356   {
357     char tmp[29];
358     sprintf(tmp, "depth%03d", i);
359
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);
367
368     latestActor.Add(childActor);
369     latestActor = childActor;
370   }
371   // NOTE : latestActor's TOP_LEFT position become 200.f, 200.0f
372
373   // Render and notify
374   application.SendNotification();
375   application.Render();
376
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);
382
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);
387
388   END_TEST;
389 }
390
391 int UtcDaliHitTestAlgorithmOverlay(void)
392 {
393   TestApplication application;
394   tet_infoline("Testing Dali::HitTestAlgorithm with overlay actors");
395
396   Stage             stage             = Stage::GetCurrent();
397   RenderTaskList    renderTaskList    = stage.GetRenderTaskList();
398   RenderTask        defaultRenderTask = renderTaskList.GetTask(0u);
399   Dali::CameraActor cameraActor       = defaultRenderTask.GetCameraActor();
400
401   Vector2 stageSize(stage.GetSize());
402   cameraActor.SetOrthographicProjection(stageSize);
403   cameraActor.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, 1600.0f));
404
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);
414
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);
420
421   // Add the actors to the view
422   stage.Add(blue);
423   stage.Add(green);
424
425   // Render and notify
426   application.SendNotification();
427   application.Render(0);
428   application.Render(10);
429
430   HitTestAlgorithm::Results results;
431
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);
436
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);
441
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);
446
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);
454
455   blue.Add(red);
456
457   // Render and notify
458   application.SendNotification();
459   application.Render(0);
460   application.Render(10);
461
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);
467
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);
473
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);
479
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);
485
486   // Change blue's draw mode as normal. now blue < red < green
487   blue.SetProperty(Actor::Property::DRAW_MODE, DrawMode::NORMAL);
488
489   // Render and notify
490   application.SendNotification();
491   application.Render(0);
492   application.Render(10);
493
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);
499
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);
505
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);
511
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);
517   END_TEST;
518 }
519
520 int UtcDaliHitTestAlgorithmDoesWantedHitTest(void)
521 {
522   TestApplication application;
523   tet_infoline("Testing Dali::HitTestAlgorithm with does wanted to HitTest");
524
525   Stage             stage             = Stage::GetCurrent();
526   RenderTaskList    renderTaskList    = stage.GetRenderTaskList();
527   RenderTask        defaultRenderTask = renderTaskList.GetTask(0u);
528   Dali::CameraActor cameraActor       = defaultRenderTask.GetCameraActor();
529
530   Vector2 stageSize(stage.GetSize());
531   cameraActor.SetOrthographicProjection(stageSize);
532   cameraActor.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, 1600.0f));
533
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);
541
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);
547
548   // Add the actors to the view
549   stage.Add(blue);
550   stage.Add(green);
551
552   // connect to its hit-test signal
553   Dali::DevelActor::HitTestResultSignal(green).Connect(TestHitTestTouchCallback);
554
555   // Render and notify
556   application.SendNotification();
557   application.Render(0);
558   application.Render(10);
559
560   gHitTestTouchCallBackCalled = false;
561
562   HitTestAlgorithm::Results results;
563   HitTest(stage, stageSize / 2.0f, results, &DefaultIsActorTouchableFunction);
564
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);
570
571   END_TEST;
572 }
573
574 int UtcDaliHitTestAlgorithmOrder(void)
575 {
576   TestApplication application;
577   tet_infoline("Testing Dali::HitTestAlgorithm between On/Off render task");
578
579   Stage   stage = Stage::GetCurrent();
580   Vector2 stageSize(stage.GetSize());
581
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;
588
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;
595
596   stage.Add(blue);
597   stage.Add(green);
598
599   RenderTaskList renderTaskList = stage.GetRenderTaskList();
600   RenderTask     offRenderTask  = renderTaskList.CreateTask();
601
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);
606
607   offRenderTask.SetExclusive(true);
608   offRenderTask.SetInputEnabled(true);
609   offRenderTask.SetCameraActor(cameraActor);
610   offRenderTask.SetSourceActor(green);
611   offRenderTask.SetScreenToFrameBufferMappingActor(green);
612
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);
617
618   // Render and notify
619   application.SendNotification();
620   application.Render(10);
621
622   HitTestAlgorithm::Results results;
623   HitTest(stage, stageSize / 2.0f, results, &DefaultIsActorTouchableFunction);
624   DALI_TEST_CHECK(results.actor == green);
625
626   END_TEST;
627 }