[Tizen] Calculrate screen position with RenderTask
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / layer-impl.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 // CLASS HEADER
19 #include <dali/internal/event/actors/layer-impl.h>
20
21 // EXTERNAL INCLUDES
22
23 // INTERNAL INCLUDES
24 #include <dali/public-api/actors/layer.h>
25 #include <dali/public-api/common/dali-common.h>
26 #include <dali/public-api/object/type-registry.h>
27
28 #include <dali/internal/event/actors/layer-list.h>
29 #include <dali/internal/event/common/event-thread-services.h>
30 #include <dali/internal/event/common/property-helper.h>
31 #include <dali/internal/event/common/scene-impl.h>
32
33 #include <dali/internal/update/manager/update-manager.h>
34 #include <dali/internal/update/nodes/scene-graph-layer.h>
35
36 using Dali::Internal::SceneGraph::UpdateManager;
37
38 namespace Dali
39 {
40 namespace
41 {
42 typedef Layer::Behavior Behavior;
43
44 DALI_ENUM_TO_STRING_TABLE_BEGIN(BEHAVIOR)
45   DALI_ENUM_TO_STRING_WITH_SCOPE(Layer, LAYER_UI)
46   DALI_ENUM_TO_STRING_WITH_SCOPE(Layer, LAYER_3D)
47 DALI_ENUM_TO_STRING_TABLE_END(BEHAVIOR)
48
49 } // namespace
50
51 namespace Internal
52 {
53 namespace
54 {
55 // Properties
56
57 //              Name                Type      writable animatable constraint-input  enum for index-checking
58 DALI_PROPERTY_TABLE_BEGIN
59 DALI_PROPERTY("clippingEnable", BOOLEAN, true, false, true, Dali::Layer::Property::CLIPPING_ENABLE)
60 DALI_PROPERTY("clippingBox", RECTANGLE, true, false, true, Dali::Layer::Property::CLIPPING_BOX)
61 DALI_PROPERTY("behavior", INTEGER, true, false, false, Dali::Layer::Property::BEHAVIOR)
62 DALI_PROPERTY("depth", INTEGER, false, false, false, Dali::Layer::Property::DEPTH)
63 DALI_PROPERTY("depthTest", BOOLEAN, true, false, false, Dali::Layer::Property::DEPTH_TEST)
64 DALI_PROPERTY("consumesTouch", BOOLEAN, true, false, false, Dali::Layer::Property::CONSUMES_TOUCH)
65 DALI_PROPERTY("consumesHover", BOOLEAN, true, false, false, Dali::Layer::Property::CONSUMES_HOVER)
66 DALI_PROPERTY_TABLE_END(DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX, LayerDefaultProperties)
67
68 // Actions
69
70 static constexpr std::string_view ACTION_RAISE           = "raise";
71 static constexpr std::string_view ACTION_LOWER           = "lower";
72 static constexpr std::string_view ACTION_RAISE_TO_TOP    = "raiseToTop";
73 static constexpr std::string_view ACTION_LOWER_TO_BOTTOM = "lowerToBottom";
74
75 BaseHandle Create()
76 {
77   return Dali::Layer::New();
78 }
79
80 TypeRegistration mType(typeid(Dali::Layer), typeid(Dali::Actor), Create, LayerDefaultProperties);
81
82 TypeAction a1(mType, std::string(ACTION_RAISE), &Layer::DoAction);
83 TypeAction a2(mType, std::string(ACTION_LOWER), &Layer::DoAction);
84 TypeAction a3(mType, std::string(ACTION_RAISE_TO_TOP), &Layer::DoAction);
85 TypeAction a4(mType, std::string(ACTION_LOWER_TO_BOTTOM), &Layer::DoAction);
86
87 } // unnamed namespace
88
89 LayerPtr Layer::New()
90 {
91   // create node, nodes are owned by UpdateManager
92   SceneGraph::Layer*             layerNode = SceneGraph::Layer::New();
93   OwnerPointer<SceneGraph::Node> transferOwnership(layerNode);
94   AddNodeMessage(EventThreadServices::Get().GetUpdateManager(), transferOwnership);
95   LayerPtr layer(new Layer(Actor::LAYER, *layerNode));
96
97   // Second-phase construction
98   layer->Initialize();
99
100   return layer;
101 }
102
103 LayerPtr Layer::NewRoot(LayerList& layerList)
104 {
105   // create node, nodes are owned by UpdateManager
106   SceneGraph::Layer*              rootLayer = SceneGraph::Layer::New();
107   OwnerPointer<SceneGraph::Layer> transferOwnership(rootLayer);
108   InstallRootMessage(EventThreadServices::Get().GetUpdateManager(), transferOwnership);
109
110   LayerPtr root(new Layer(Actor::ROOT_LAYER, *rootLayer));
111
112   // root actor is immediately considered to be on-stage
113   root->mIsOnScene = true;
114
115   // The root actor will not emit a stage connection signal so set the signalled flag here as well
116   root->mOnSceneSignalled = true;
117
118   // layer-list must be set for the root layer
119   root->mLayerList = &layerList;
120   layerList.SetRootLayer(&(*root));
121   layerList.RegisterLayer(*root);
122
123   return root;
124 }
125
126 Layer::Layer(Actor::DerivedType type, const SceneGraph::Layer& layer)
127 : Actor(type, layer),
128   mLayerList(nullptr),
129   mClippingBox(0, 0, 0, 0),
130   mSortFunction(Layer::ZValue),
131   mBehavior(Dali::Layer::LAYER_UI),
132   mIsClipping(false),
133   mDepthTestDisabled(true),
134   mTouchConsumed(false),
135   mHoverConsumed(false)
136 {
137 }
138
139 void Layer::OnInitialize()
140 {
141 }
142
143 Layer::~Layer()
144 {
145   if(mIsRoot)
146   {
147     // Guard to allow handle destruction after Core has been destroyed
148     if(EventThreadServices::IsCoreRunning())
149     {
150       UninstallRootMessage(GetEventThreadServices().GetUpdateManager(), &GetSceneGraphLayer());
151
152       GetEventThreadServices().UnregisterObject(this);
153     }
154   }
155 }
156
157 unsigned int Layer::GetDepth() const
158 {
159   return mLayerList ? mLayerList->GetDepth(this) : 0u;
160 }
161
162 void Layer::Raise()
163 {
164   if(mLayerList)
165   {
166     mLayerList->RaiseLayer(*this);
167   }
168 }
169
170 void Layer::Lower()
171 {
172   if(mLayerList)
173   {
174     mLayerList->LowerLayer(*this);
175   }
176 }
177
178 void Layer::RaiseAbove(const Internal::Layer& target)
179 {
180   // cannot raise above ourself, both have to be on the scene
181   if((this != &target) && OnScene() && target.OnScene())
182   {
183     // get parameters depth
184     const uint32_t targetDepth = target.GetDepth();
185     if(GetDepth() < targetDepth)
186     {
187       MoveAbove(target);
188     }
189   }
190 }
191
192 void Layer::LowerBelow(const Internal::Layer& target)
193 {
194   // cannot lower below ourself, both have to be on the scene
195   if((this != &target) && OnScene() && target.OnScene())
196   {
197     // get parameters depth
198     const uint32_t targetDepth = target.GetDepth();
199     if(GetDepth() > targetDepth)
200     {
201       MoveBelow(target);
202     }
203   }
204 }
205
206 void Layer::RaiseToTop()
207 {
208   if(mLayerList)
209   {
210     mLayerList->RaiseLayerToTop(*this);
211   }
212 }
213
214 void Layer::LowerToBottom()
215 {
216   if(mLayerList)
217   {
218     mLayerList->LowerLayerToBottom(*this);
219   }
220 }
221
222 void Layer::MoveAbove(const Internal::Layer& target)
223 {
224   // cannot raise above ourself, both have to be on the scene
225   if((this != &target) && mLayerList && target.OnScene())
226   {
227     mLayerList->MoveLayerAbove(*this, target);
228   }
229 }
230
231 void Layer::MoveBelow(const Internal::Layer& target)
232 {
233   // cannot lower below ourself, both have to be on the scene
234   if((this != &target) && mLayerList && target.OnScene())
235   {
236     mLayerList->MoveLayerBelow(*this, target);
237   }
238 }
239
240 void Layer::SetBehavior(Dali::Layer::Behavior behavior)
241 {
242   if(mBehavior != behavior)
243   {
244     mBehavior = behavior;
245
246     if(mIsOnScene)
247     {
248       // If current layer is on scene, and it's behavior changed,
249       // Change the mLayer3DParentsCount value recursively.
250       mParentImpl.RecursiveChangeLayer3dCount(mBehavior == Dali::Layer::LAYER_3D ? 1 : -1);
251     }
252
253     // Notify update side object.
254     SetBehaviorMessage(GetEventThreadServices(), GetSceneGraphLayer(), behavior);
255     // By default, disable depth test for LAYER_UI, and enable for LAYER_3D.
256     SetDepthTestDisabled(mBehavior == Dali::Layer::LAYER_UI);
257   }
258 }
259
260 void Layer::SetClipping(bool enabled)
261 {
262   if(enabled != mIsClipping)
263   {
264     mIsClipping = enabled;
265
266     // layerNode is being used in a separate thread; queue a message to set the value
267     SetClippingMessage(GetEventThreadServices(), GetSceneGraphLayer(), mIsClipping);
268   }
269 }
270
271 void Layer::SetClippingBox(int x, int y, int width, int height)
272 {
273   if((x != mClippingBox.x) ||
274      (y != mClippingBox.y) ||
275      (width != mClippingBox.width) ||
276      (height != mClippingBox.height))
277   {
278     // Clipping box is not animatable; this is the most up-to-date value
279     mClippingBox.Set(x, y, width, height);
280
281     // Convert mClippingBox to GL based coordinates (from bottom-left)
282     ClippingBox clippingBox(mClippingBox);
283
284     if(mScene)
285     {
286       clippingBox.y = static_cast<int32_t>(mScene->GetSize().height) - clippingBox.y - clippingBox.height;
287
288       // layerNode is being used in a separate thread; queue a message to set the value
289       SetClippingBoxMessage(GetEventThreadServices(), GetSceneGraphLayer(), clippingBox);
290     }
291   }
292 }
293
294 void Layer::SetDepthTestDisabled(bool disable)
295 {
296   if(disable != mDepthTestDisabled)
297   {
298     mDepthTestDisabled = disable;
299
300     // Send message.
301     // layerNode is being used in a separate thread; queue a message to set the value
302     SetDepthTestDisabledMessage(GetEventThreadServices(), GetSceneGraphLayer(), mDepthTestDisabled);
303   }
304 }
305
306 bool Layer::IsDepthTestDisabled() const
307 {
308   return mDepthTestDisabled;
309 }
310
311 void Layer::SetSortFunction(Dali::Layer::SortFunctionType function)
312 {
313   if(function != mSortFunction)
314   {
315     mSortFunction = function;
316
317     // layerNode is being used in a separate thread; queue a message to set the value
318     SetSortFunctionMessage(GetEventThreadServices(), GetSceneGraphLayer(), mSortFunction);
319   }
320 }
321
322 void Layer::SetTouchConsumed(bool consume)
323 {
324   mTouchConsumed = consume;
325 }
326
327 bool Layer::IsTouchConsumed() const
328 {
329   return mTouchConsumed;
330 }
331
332 void Layer::SetHoverConsumed(bool consume)
333 {
334   mHoverConsumed = consume;
335 }
336
337 bool Layer::IsHoverConsumed() const
338 {
339   return mHoverConsumed;
340 }
341
342 void Layer::OnSceneConnectionInternal()
343 {
344   if(!mIsRoot)
345   {
346     DALI_ASSERT_DEBUG(NULL == mLayerList);
347
348     // Find the ordered layer-list
349     for(Actor* parent = GetParent(); parent != nullptr; parent = parent->GetParent())
350     {
351       if(parent->IsLayer())
352       {
353         Layer* parentLayer = static_cast<Layer*>(parent); // cheaper than dynamic_cast
354         mLayerList         = parentLayer->mLayerList;
355       }
356     }
357   }
358
359   DALI_ASSERT_DEBUG(NULL != mLayerList);
360   mLayerList->RegisterLayer(*this);
361 }
362
363 void Layer::OnSceneDisconnectionInternal()
364 {
365   mLayerList->UnregisterLayer(*this);
366
367   // mLayerList is only valid when on-stage
368   mLayerList = nullptr;
369 }
370
371 const SceneGraph::Layer& Layer::GetSceneGraphLayer() const
372 {
373   return static_cast<const SceneGraph::Layer&>(GetNode()); // we know our node is a layer node
374 }
375
376 void Layer::SetDefaultProperty(Property::Index index, const Property::Value& propertyValue)
377 {
378   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
379   {
380     Actor::SetDefaultProperty(index, propertyValue);
381   }
382   else
383   {
384     switch(index)
385     {
386       case Dali::Layer::Property::CLIPPING_ENABLE:
387       {
388         SetClipping(propertyValue.Get<bool>());
389         break;
390       }
391       case Dali::Layer::Property::CLIPPING_BOX:
392       {
393         Rect<int32_t> clippingBox(propertyValue.Get<Rect<int32_t> >());
394         SetClippingBox(clippingBox.x, clippingBox.y, clippingBox.width, clippingBox.height);
395         break;
396       }
397       case Dali::Layer::Property::BEHAVIOR:
398       {
399         Behavior behavior = mBehavior;
400
401         Property::Type type = propertyValue.GetType();
402         if(type == Property::STRING)
403         {
404           if(Scripting::GetEnumeration<Behavior>(propertyValue.Get<std::string>().c_str(), BEHAVIOR_TABLE, BEHAVIOR_TABLE_COUNT, behavior))
405           {
406             SetBehavior(behavior);
407           }
408         }
409         else if(type == Property::INTEGER)
410         {
411           SetBehavior(propertyValue.Get<Dali::Layer::Behavior>());
412         }
413         break;
414       }
415       case Dali::Layer::Property::DEPTH_TEST:
416       {
417         SetDepthTestDisabled(!propertyValue.Get<bool>());
418         break;
419       }
420       case Dali::Layer::Property::CONSUMES_TOUCH:
421       {
422         SetTouchConsumed(propertyValue.Get<bool>());
423         break;
424       }
425       case Dali::Layer::Property::CONSUMES_HOVER:
426       {
427         SetHoverConsumed(propertyValue.Get<bool>());
428         break;
429       }
430       default:
431       {
432         DALI_LOG_WARNING("Unknown property (%d)\n", index);
433         break;
434       }
435     } // switch(index)
436
437   } // else
438 }
439
440 Property::Value Layer::GetDefaultProperty(Property::Index index) const
441 {
442   Property::Value ret;
443   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
444   {
445     ret = Actor::GetDefaultProperty(index);
446   }
447   else
448   {
449     switch(index)
450     {
451       case Dali::Layer::Property::CLIPPING_ENABLE:
452       {
453         ret = mIsClipping;
454         break;
455       }
456       case Dali::Layer::Property::CLIPPING_BOX:
457       {
458         ret = mClippingBox;
459         break;
460       }
461       case Dali::Layer::Property::BEHAVIOR:
462       {
463         ret = mBehavior;
464         break;
465       }
466       case Dali::Layer::Property::DEPTH:
467       {
468         ret = static_cast<int>(GetDepth());
469         break;
470       }
471       case Dali::Layer::Property::DEPTH_TEST:
472       {
473         ret = !mDepthTestDisabled;
474         break;
475       }
476       case Dali::Layer::Property::CONSUMES_TOUCH:
477       {
478         ret = mTouchConsumed;
479         break;
480       }
481       case Dali::Layer::Property::CONSUMES_HOVER:
482       {
483         ret = mHoverConsumed;
484         break;
485       }
486       default:
487       {
488         DALI_LOG_WARNING("Unknown property (%d)\n", index);
489         break;
490       }
491     } // switch(index)
492   }
493
494   return ret;
495 }
496
497 Property::Value Layer::GetDefaultPropertyCurrentValue(Property::Index index) const
498 {
499   Property::Value ret;
500   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
501   {
502     ret = Actor::GetDefaultPropertyCurrentValue(index);
503   }
504   else
505   {
506     ret = GetDefaultProperty(index); // Layer only has event-side properties
507   }
508
509   return ret;
510 }
511
512 bool Layer::DoAction(BaseObject* object, const std::string& actionName, const Property::Map& /*attributes*/)
513 {
514   bool   done  = false;
515   Layer* layer = dynamic_cast<Layer*>(object);
516
517   if(layer)
518   {
519     std::string_view name(actionName);
520
521     if(name == ACTION_RAISE)
522     {
523       layer->Raise();
524       done = true;
525     }
526     else if(name == ACTION_LOWER)
527     {
528       layer->Lower();
529       done = true;
530     }
531     else if(name == ACTION_RAISE_TO_TOP)
532     {
533       layer->RaiseToTop();
534       done = true;
535     }
536     else if(name == ACTION_LOWER_TO_BOTTOM)
537     {
538       layer->LowerToBottom();
539       done = true;
540     }
541   }
542
543   return done;
544 }
545
546 } // namespace Internal
547
548 } // namespace Dali