[Tizen] Adds transition effect
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / actor-impl.cpp
1 /*
2  * Copyright (c) 2021 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/actor-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <algorithm>
23 #include <cfloat>
24 #include <cmath>
25
26 // INTERNAL INCLUDES
27 #include <dali/public-api/common/constants.h>
28 #include <dali/public-api/common/dali-common.h>
29 #include <dali/public-api/math/radian.h>
30 #include <dali/public-api/math/vector2.h>
31 #include <dali/public-api/math/vector3.h>
32 #include <dali/public-api/object/type-registry.h>
33
34 #include <dali/devel-api/actors/actor-devel.h>
35 #include <dali/devel-api/actors/layer-devel.h>
36 #include <dali/devel-api/common/capabilities.h>
37
38 #include <dali/integration-api/debug.h>
39
40 #include <dali/internal/event/actors/actor-parent.h>
41 #include <dali/internal/event/actors/actor-property-handler.h>
42 #include <dali/internal/event/actors/actor-relayouter.h>
43 #include <dali/internal/event/actors/camera-actor-impl.h>
44 #include <dali/internal/event/common/event-thread-services.h>
45 #include <dali/internal/event/common/projection.h>
46 #include <dali/internal/event/common/property-helper.h>
47 #include <dali/internal/event/common/scene-impl.h>
48 #include <dali/internal/event/common/stage-impl.h>
49 #include <dali/internal/event/common/thread-local-storage.h>
50 #include <dali/internal/event/common/type-info-impl.h>
51 #include <dali/internal/event/events/actor-gesture-data.h>
52 #include <dali/internal/event/render-tasks/render-task-impl.h>
53 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
54 #include <dali/internal/event/rendering/renderer-impl.h>
55 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
56 #include <dali/internal/update/manager/update-manager.h>
57 #include <dali/internal/update/nodes/node-messages.h>
58
59 using Dali::Internal::SceneGraph::AnimatableProperty;
60 using Dali::Internal::SceneGraph::Node;
61 using Dali::Internal::SceneGraph::PropertyBase;
62
63 #if defined(DEBUG_ENABLED)
64 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER");
65 #endif
66
67 namespace Dali
68 {
69 namespace Internal
70 {
71 namespace // unnamed namespace
72 {
73 // Properties
74
75 /**
76  * We want to discourage the use of property strings (minimize string comparisons),
77  * particularly for the default properties.
78  *              Name                  Type   writable animatable constraint-input  enum for index-checking
79  */
80 DALI_PROPERTY_TABLE_BEGIN
81 DALI_PROPERTY("parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN)
82 DALI_PROPERTY("parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X)
83 DALI_PROPERTY("parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y)
84 DALI_PROPERTY("parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z)
85 DALI_PROPERTY("anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT)
86 DALI_PROPERTY("anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X)
87 DALI_PROPERTY("anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y)
88 DALI_PROPERTY("anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z)
89 DALI_PROPERTY("size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE)
90 DALI_PROPERTY("sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH)
91 DALI_PROPERTY("sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT)
92 DALI_PROPERTY("sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH)
93 DALI_PROPERTY("position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION)
94 DALI_PROPERTY("positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X)
95 DALI_PROPERTY("positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y)
96 DALI_PROPERTY("positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z)
97 DALI_PROPERTY("worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION)
98 DALI_PROPERTY("worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X)
99 DALI_PROPERTY("worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y)
100 DALI_PROPERTY("worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z)
101 DALI_PROPERTY("orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION)
102 DALI_PROPERTY("worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION)
103 DALI_PROPERTY("scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE)
104 DALI_PROPERTY("scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X)
105 DALI_PROPERTY("scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y)
106 DALI_PROPERTY("scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z)
107 DALI_PROPERTY("worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE)
108 DALI_PROPERTY("visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE)
109 DALI_PROPERTY("color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR)
110 DALI_PROPERTY("colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED)
111 DALI_PROPERTY("colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN)
112 DALI_PROPERTY("colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE)
113 DALI_PROPERTY("colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA)
114 DALI_PROPERTY("worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR)
115 DALI_PROPERTY("worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX)
116 DALI_PROPERTY("name", STRING, true, false, false, Dali::Actor::Property::NAME)
117 DALI_PROPERTY("sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE)
118 DALI_PROPERTY("leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED)
119 DALI_PROPERTY("inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION)
120 DALI_PROPERTY("inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE)
121 DALI_PROPERTY("colorMode", INTEGER, true, false, false, Dali::Actor::Property::COLOR_MODE)
122 DALI_PROPERTY("drawMode", INTEGER, true, false, false, Dali::Actor::Property::DRAW_MODE)
123 DALI_PROPERTY("sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR)
124 DALI_PROPERTY("widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY)
125 DALI_PROPERTY("heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY)
126 DALI_PROPERTY("sizeScalePolicy", INTEGER, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY)
127 DALI_PROPERTY("widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT)
128 DALI_PROPERTY("heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH)
129 DALI_PROPERTY("padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING)
130 DALI_PROPERTY("minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE)
131 DALI_PROPERTY("maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE)
132 DALI_PROPERTY("inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION)
133 DALI_PROPERTY("clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE)
134 DALI_PROPERTY("layoutDirection", STRING, true, false, false, Dali::Actor::Property::LAYOUT_DIRECTION)
135 DALI_PROPERTY("inheritLayoutDirection", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION)
136 DALI_PROPERTY("opacity", FLOAT, true, true, true, Dali::Actor::Property::OPACITY)
137 DALI_PROPERTY("screenPosition", VECTOR2, false, false, false, Dali::Actor::Property::SCREEN_POSITION)
138 DALI_PROPERTY("positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::Actor::Property::POSITION_USES_ANCHOR_POINT)
139 DALI_PROPERTY("culled", BOOLEAN, false, false, true, Dali::Actor::Property::CULLED)
140 DALI_PROPERTY("id", INTEGER, false, false, false, Dali::Actor::Property::ID)
141 DALI_PROPERTY("hierarchyDepth", INTEGER, false, false, false, Dali::Actor::Property::HIERARCHY_DEPTH)
142 DALI_PROPERTY("isRoot", BOOLEAN, false, false, false, Dali::Actor::Property::IS_ROOT)
143 DALI_PROPERTY("isLayer", BOOLEAN, false, false, false, Dali::Actor::Property::IS_LAYER)
144 DALI_PROPERTY("connectedToScene", BOOLEAN, false, false, false, Dali::Actor::Property::CONNECTED_TO_SCENE)
145 DALI_PROPERTY("keyboardFocusable", BOOLEAN, true, false, false, Dali::Actor::Property::KEYBOARD_FOCUSABLE)
146 DALI_PROPERTY("siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER)
147 DALI_PROPERTY("updateSizeHint", VECTOR2, true, false, false, Dali::DevelActor::Property::UPDATE_SIZE_HINT)
148 DALI_PROPERTY("captureAllTouchAfterStart", BOOLEAN, true, false, false, Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START)
149 DALI_PROPERTY("touchAreaOffset", RECTANGLE, true, false, false, Dali::DevelActor::Property::TOUCH_AREA_OFFSET)
150 DALI_PROPERTY("blendEquation", INTEGER, true, false, false, Dali::DevelActor::Property::BLEND_EQUATION)
151 DALI_PROPERTY_TABLE_END(DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties)
152
153 // Signals
154
155 static constexpr std::string_view SIGNAL_HOVERED                  = "hovered";
156 static constexpr std::string_view SIGNAL_WHEEL_EVENT              = "wheelEvent";
157 static constexpr std::string_view SIGNAL_ON_SCENE                 = "onScene";
158 static constexpr std::string_view SIGNAL_OFF_SCENE                = "offScene";
159 static constexpr std::string_view SIGNAL_ON_RELAYOUT              = "onRelayout";
160 static constexpr std::string_view SIGNAL_TOUCHED                  = "touched";
161 static constexpr std::string_view SIGNAL_VISIBILITY_CHANGED       = "visibilityChanged";
162 static constexpr std::string_view SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
163 static constexpr std::string_view SIGNAL_CHILD_ADDED              = "childAdded";
164 static constexpr std::string_view SIGNAL_CHILD_REMOVED            = "childRemoved";
165
166 // Actions
167
168 static constexpr std::string_view ACTION_SHOW = "show";
169 static constexpr std::string_view ACTION_HIDE = "hide";
170
171 BaseHandle CreateActor()
172 {
173   return Dali::Actor::New();
174 }
175
176 TypeRegistration mType(typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties);
177
178 SignalConnectorType signalConnector2(mType, std::string(SIGNAL_HOVERED), &Actor::DoConnectSignal);
179 SignalConnectorType signalConnector3(mType, std::string(SIGNAL_WHEEL_EVENT), &Actor::DoConnectSignal);
180 SignalConnectorType signalConnector4(mType, std::string(SIGNAL_ON_SCENE), &Actor::DoConnectSignal);
181 SignalConnectorType signalConnector5(mType, std::string(SIGNAL_OFF_SCENE), &Actor::DoConnectSignal);
182 SignalConnectorType signalConnector6(mType, std::string(SIGNAL_ON_RELAYOUT), &Actor::DoConnectSignal);
183 SignalConnectorType signalConnector7(mType, std::string(SIGNAL_TOUCHED), &Actor::DoConnectSignal);
184 SignalConnectorType signalConnector8(mType, std::string(SIGNAL_VISIBILITY_CHANGED), &Actor::DoConnectSignal);
185 SignalConnectorType signalConnector9(mType, std::string(SIGNAL_LAYOUT_DIRECTION_CHANGED), &Actor::DoConnectSignal);
186 SignalConnectorType signalConnector10(mType, std::string(SIGNAL_CHILD_ADDED), &Actor::DoConnectSignal);
187 SignalConnectorType signalConnector11(mType, std::string(SIGNAL_CHILD_REMOVED), &Actor::DoConnectSignal);
188
189 TypeAction a1(mType, std::string(ACTION_SHOW), &Actor::DoAction);
190 TypeAction a2(mType, std::string(ACTION_HIDE), &Actor::DoAction);
191
192 /**
193  * @brief Extract a given dimension from a Vector2
194  *
195  * @param[in] values The values to extract from
196  * @param[in] dimension The dimension to extract
197  * @return Return the value for the dimension
198  */
199 constexpr float GetDimensionValue(const Vector2& values, Dimension::Type dimension)
200 {
201   switch(dimension)
202   {
203     case Dimension::WIDTH:
204     {
205       return values.width;
206     }
207     case Dimension::HEIGHT:
208     {
209       return values.height;
210     }
211     default:
212     {
213       break;
214     }
215   }
216   return 0.0f;
217 }
218
219 /**
220  * @brief Extract a given dimension from a Vector3
221  *
222  * @param[in] values The values to extract from
223  * @param[in] dimension The dimension to extract
224  * @return Return the value for the dimension
225  */
226 float GetDimensionValue(const Vector3& values, Dimension::Type dimension)
227 {
228   return GetDimensionValue(values.GetVectorXY(), dimension);
229 }
230
231 /// Helper for emitting a signal
232 template<typename Signal, typename Event>
233 bool EmitConsumingSignal(Actor& actor, Signal& signal, const Event& event)
234 {
235   bool consumed = false;
236
237   if(!signal.Empty())
238   {
239     Dali::Actor handle(&actor);
240     consumed = signal.Emit(handle, event);
241   }
242
243   return consumed;
244 }
245
246 /// Helper for emitting signals with multiple parameters
247 template<typename Signal, typename... Param>
248 void EmitSignal(Actor& actor, Signal& signal, Param... params)
249 {
250   if(!signal.Empty())
251   {
252     Dali::Actor handle(&actor);
253     signal.Emit(handle, params...);
254   }
255 }
256
257 bool ScreenToLocalInternal(
258   const Matrix&   viewMatrix,
259   const Matrix&   projectionMatrix,
260   const Matrix&   worldMatrix,
261   const Viewport& viewport,
262   const Vector3&  currentSize,
263   float&          localX,
264   float&          localY,
265   float           screenX,
266   float           screenY)
267 {
268   // Get the ModelView matrix
269   Matrix modelView;
270   Matrix::Multiply(modelView, worldMatrix, viewMatrix);
271
272   // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
273   Matrix invertedMvp(false /*don't init*/);
274   Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
275   bool success = invertedMvp.Invert();
276
277   // Convert to GL coordinates
278   Vector4 screenPos(screenX - static_cast<float>(viewport.x), static_cast<float>(viewport.height) - screenY - static_cast<float>(viewport.y), 0.f, 1.f);
279
280   Vector4 nearPos;
281   if(success)
282   {
283     success = Unproject(screenPos, invertedMvp, static_cast<float>(viewport.width), static_cast<float>(viewport.height), nearPos);
284   }
285
286   Vector4 farPos;
287   if(success)
288   {
289     screenPos.z = 1.0f;
290     success     = Unproject(screenPos, invertedMvp, static_cast<float>(viewport.width), static_cast<float>(viewport.height), farPos);
291   }
292
293   if(success)
294   {
295     Vector4 local;
296     if(XyPlaneIntersect(nearPos, farPos, local))
297     {
298       Vector3 size = currentSize;
299       localX       = local.x + size.x * 0.5f;
300       localY       = local.y + size.y * 0.5f;
301     }
302     else
303     {
304       success = false;
305     }
306   }
307
308   return success;
309 }
310
311 } // unnamed namespace
312
313 ActorPtr Actor::New()
314 {
315   // pass a reference to actor, actor does not own its node
316   ActorPtr actor(new Actor(BASIC, *CreateNode()));
317
318   // Second-phase construction
319   actor->Initialize();
320
321   return actor;
322 }
323
324 const SceneGraph::Node* Actor::CreateNode()
325 {
326   // create node. Nodes are owned by the update manager
327   SceneGraph::Node*              node = SceneGraph::Node::New();
328   OwnerPointer<SceneGraph::Node> transferOwnership(node);
329   Internal::ThreadLocalStorage*  tls = Internal::ThreadLocalStorage::GetInternal();
330
331   DALI_ASSERT_ALWAYS(tls && "ThreadLocalStorage is null");
332
333   AddNodeMessage(tls->GetUpdateManager(), transferOwnership);
334
335   return node;
336 }
337
338 void Actor::SetName(std::string_view name)
339 {
340   mName = ConstString(name);
341
342   // ATTENTION: string for debug purposes is not thread safe.
343   DALI_LOG_SET_OBJECT_STRING(const_cast<SceneGraph::Node*>(&GetNode()), mName.GetCString());
344 }
345
346 uint32_t Actor::GetId() const
347 {
348   return GetNode().GetId();
349 }
350
351 Dali::Layer Actor::GetLayer()
352 {
353   Dali::Layer layer;
354
355   // Short-circuit for Layer derived actors
356   if(mIsLayer)
357   {
358     layer = Dali::Layer(static_cast<Dali::Internal::Layer*>(this)); // static cast as we trust the flag
359   }
360
361   // Find the immediate Layer parent
362   for(Actor* parent = GetParent(); !layer && parent != nullptr; parent = parent->GetParent())
363   {
364     if(parent->IsLayer())
365     {
366       layer = Dali::Layer(static_cast<Dali::Internal::Layer*>(parent)); // static cast as we trust the flag
367     }
368   }
369
370   return layer;
371 }
372
373 void Actor::Unparent()
374 {
375   if(mParent)
376   {
377     // Remove this actor from the parent. The remove will put a relayout request in for
378     // the parent if required
379     mParent->Remove(*this);
380     // mParent is now NULL!
381   }
382 }
383
384 void Actor::SetParentOrigin(const Vector3& origin)
385 {
386   // node is being used in a separate thread; queue a message to set the value & base value
387   SetParentOriginMessage(GetEventThreadServices(), GetNode(), origin);
388
389   // Cache for event-thread access
390   if(!mParentOrigin)
391   {
392     // not allocated, check if different from default
393     if(ParentOrigin::DEFAULT != origin)
394     {
395       mParentOrigin = new Vector3(origin);
396     }
397   }
398   else
399   {
400     // check if different from current costs more than just set
401     *mParentOrigin = origin;
402   }
403 }
404
405 const Vector3& Actor::GetCurrentParentOrigin() const
406 {
407   // Cached for event-thread access
408   return (mParentOrigin) ? *mParentOrigin : ParentOrigin::DEFAULT;
409 }
410
411 void Actor::SetAnchorPoint(const Vector3& anchor)
412 {
413   // node is being used in a separate thread; queue a message to set the value & base value
414   SetAnchorPointMessage(GetEventThreadServices(), GetNode(), anchor);
415
416   // Cache for event-thread access
417   if(!mAnchorPoint)
418   {
419     // not allocated, check if different from default
420     if(AnchorPoint::DEFAULT != anchor)
421     {
422       mAnchorPoint = new Vector3(anchor);
423     }
424   }
425   else
426   {
427     // check if different from current costs more than just set
428     *mAnchorPoint = anchor;
429   }
430 }
431
432 const Vector3& Actor::GetCurrentAnchorPoint() const
433 {
434   // Cached for event-thread access
435   return (mAnchorPoint) ? *mAnchorPoint : AnchorPoint::DEFAULT;
436 }
437
438 void Actor::SetPosition(float x, float y)
439 {
440   SetPosition(Vector3(x, y, 0.0f));
441 }
442
443 void Actor::SetPosition(float x, float y, float z)
444 {
445   SetPosition(Vector3(x, y, z));
446 }
447
448 void Actor::SetPosition(const Vector3& position)
449 {
450   mTargetPosition = position;
451
452   // node is being used in a separate thread; queue a message to set the value & base value
453   SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position);
454 }
455
456 void Actor::SetX(float x)
457 {
458   mTargetPosition.x = x;
459
460   // node is being used in a separate thread; queue a message to set the value & base value
461   SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x);
462 }
463
464 void Actor::SetY(float y)
465 {
466   mTargetPosition.y = y;
467
468   // node is being used in a separate thread; queue a message to set the value & base value
469   SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y);
470 }
471
472 void Actor::SetZ(float z)
473 {
474   mTargetPosition.z = z;
475
476   // node is being used in a separate thread; queue a message to set the value & base value
477   SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z);
478 }
479
480 void Actor::TranslateBy(const Vector3& distance)
481 {
482   mTargetPosition += distance;
483
484   // node is being used in a separate thread; queue a message to set the value & base value
485   SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance);
486 }
487
488 const Vector3& Actor::GetCurrentPosition() const
489 {
490   // node is being used in a separate thread; copy the value from the previous update
491   return GetNode().GetPosition(GetEventThreadServices().GetEventBufferIndex());
492 }
493
494 const Vector3& Actor::GetCurrentWorldPosition() const
495 {
496   // node is being used in a separate thread; copy the value from the previous update
497   return GetNode().GetWorldPosition(GetEventThreadServices().GetEventBufferIndex());
498 }
499
500 const Vector2 Actor::GetCurrentScreenPosition() const
501 {
502   if(mScene && OnScene())
503   {
504     Vector3 worldPosition  = GetNode().GetWorldPosition(GetEventThreadServices().GetEventBufferIndex());
505     Vector3 cameraPosition = mScene->GetDefaultCameraActor().GetNode().GetWorldPosition(GetEventThreadServices().GetEventBufferIndex());
506     worldPosition -= cameraPosition;
507
508     Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale();
509     Vector2 halfSceneSize(mScene->GetSize() * 0.5f); // World position origin is center of scene
510     Vector3 halfActorSize(actorSize * 0.5f);
511     Vector3 anchorPointOffSet = halfActorSize - actorSize * (mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT);
512
513     return Vector2(halfSceneSize.width + worldPosition.x - anchorPointOffSet.x,
514                    halfSceneSize.height + worldPosition.y - anchorPointOffSet.y);
515   }
516
517   return Vector2::ZERO;
518 }
519
520 void Actor::SetInheritPosition(bool inherit)
521 {
522   if(mInheritPosition != inherit)
523   {
524     // non animatable so keep local copy
525     mInheritPosition = inherit;
526     SetInheritPositionMessage(GetEventThreadServices(), GetNode(), inherit);
527   }
528 }
529
530 void Actor::SetOrientation(const Radian& angle, const Vector3& axis)
531 {
532   Vector3 normalizedAxis(axis.x, axis.y, axis.z);
533   normalizedAxis.Normalize();
534
535   Quaternion orientation(angle, normalizedAxis);
536
537   SetOrientation(orientation);
538 }
539
540 void Actor::SetOrientation(const Quaternion& orientation)
541 {
542   mTargetOrientation = orientation;
543
544   // node is being used in a separate thread; queue a message to set the value & base value
545   SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation);
546 }
547
548 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
549 {
550   RotateBy(Quaternion(angle, axis));
551 }
552
553 void Actor::RotateBy(const Quaternion& relativeRotation)
554 {
555   mTargetOrientation *= Quaternion(relativeRotation);
556
557   // node is being used in a separate thread; queue a message to set the value & base value
558   SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation);
559 }
560
561 const Quaternion& Actor::GetCurrentOrientation() const
562 {
563   // node is being used in a separate thread; copy the value from the previous update
564   return GetNode().GetOrientation(GetEventThreadServices().GetEventBufferIndex());
565 }
566
567 const Quaternion& Actor::GetCurrentWorldOrientation() const
568 {
569   // node is being used in a separate thread; copy the value from the previous update
570   return GetNode().GetWorldOrientation(GetEventThreadServices().GetEventBufferIndex());
571 }
572
573 void Actor::SetScale(float scale)
574 {
575   SetScale(Vector3(scale, scale, scale));
576 }
577
578 void Actor::SetScale(float x, float y, float z)
579 {
580   SetScale(Vector3(x, y, z));
581 }
582
583 void Actor::SetScale(const Vector3& scale)
584 {
585   mTargetScale = scale;
586
587   // node is being used in a separate thread; queue a message to set the value & base value
588   SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale);
589 }
590
591 void Actor::SetScaleX(float x)
592 {
593   mTargetScale.x = x;
594
595   // node is being used in a separate thread; queue a message to set the value & base value
596   SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x);
597 }
598
599 void Actor::SetScaleY(float y)
600 {
601   mTargetScale.y = y;
602
603   // node is being used in a separate thread; queue a message to set the value & base value
604   SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y);
605 }
606
607 void Actor::SetScaleZ(float z)
608 {
609   mTargetScale.z = z;
610
611   // node is being used in a separate thread; queue a message to set the value & base value
612   SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z);
613 }
614
615 void Actor::ScaleBy(const Vector3& relativeScale)
616 {
617   mTargetScale *= relativeScale;
618
619   // node is being used in a separate thread; queue a message to set the value & base value
620   SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale);
621 }
622
623 const Vector3& Actor::GetCurrentScale() const
624 {
625   // node is being used in a separate thread; copy the value from the previous update
626   return GetNode().GetScale(GetEventThreadServices().GetEventBufferIndex());
627 }
628
629 const Vector3& Actor::GetCurrentWorldScale() const
630 {
631   // node is being used in a separate thread; copy the value from the previous update
632   return GetNode().GetWorldScale(GetEventThreadServices().GetEventBufferIndex());
633 }
634
635 void Actor::SetInheritScale(bool inherit)
636 {
637   if(mInheritScale != inherit)
638   {
639     // non animatable so keep local copy
640     mInheritScale = inherit;
641     // node is being used in a separate thread; queue a message to set the value
642     SetInheritScaleMessage(GetEventThreadServices(), GetNode(), inherit);
643   }
644 }
645
646 Matrix Actor::GetCurrentWorldMatrix() const
647 {
648   return GetNode().GetWorldMatrix(0);
649 }
650
651 void Actor::SetVisible(bool visible)
652 {
653   SetVisibleInternal(visible, SendMessage::TRUE);
654 }
655
656 bool Actor::IsVisible() const
657 {
658   // node is being used in a separate thread; copy the value from the previous update
659   return GetNode().IsVisible(GetEventThreadServices().GetEventBufferIndex());
660 }
661
662 void Actor::SetOpacity(float opacity)
663 {
664   mTargetColor.a = opacity;
665
666   // node is being used in a separate thread; queue a message to set the value & base value
667   SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeW, opacity);
668
669   RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
670 }
671
672 float Actor::GetCurrentOpacity() const
673 {
674   // node is being used in a separate thread; copy the value from the previous update
675   return GetNode().GetOpacity(GetEventThreadServices().GetEventBufferIndex());
676 }
677
678 const Vector4& Actor::GetCurrentWorldColor() const
679 {
680   return GetNode().GetWorldColor(GetEventThreadServices().GetEventBufferIndex());
681 }
682
683 void Actor::SetColor(const Vector4& color)
684 {
685   mTargetColor = color;
686
687   // node is being used in a separate thread; queue a message to set the value & base value
688   SceneGraph::NodePropertyMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::Bake, color);
689
690   RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
691 }
692
693 void Actor::SetColorRed(float red)
694 {
695   mTargetColor.r = red;
696
697   // node is being used in a separate thread; queue a message to set the value & base value
698   SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeX, red);
699
700   RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
701 }
702
703 void Actor::SetColorGreen(float green)
704 {
705   mTargetColor.g = green;
706
707   // node is being used in a separate thread; queue a message to set the value & base value
708   SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeY, green);
709
710   RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
711 }
712
713 void Actor::SetColorBlue(float blue)
714 {
715   mTargetColor.b = blue;
716
717   // node is being used in a separate thread; queue a message to set the value & base value
718   SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeZ, blue);
719
720   RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
721 }
722
723 const Vector4& Actor::GetCurrentColor() const
724 {
725   // node is being used in a separate thread; copy the value from the previous update
726   return GetNode().GetColor(GetEventThreadServices().GetEventBufferIndex());
727 }
728
729 void Actor::SetInheritOrientation(bool inherit)
730 {
731   if(mInheritOrientation != inherit)
732   {
733     // non animatable so keep local copy
734     mInheritOrientation = inherit;
735     // node is being used in a separate thread; queue a message to set the value
736     SetInheritOrientationMessage(GetEventThreadServices(), GetNode(), inherit);
737   }
738 }
739
740 void Actor::SetSizeModeFactor(const Vector3& factor)
741 {
742   EnsureRelayouter();
743
744   mRelayoutData->sizeModeFactor = factor;
745 }
746
747 const Vector3& Actor::GetSizeModeFactor() const
748 {
749   if(mRelayoutData)
750   {
751     return mRelayoutData->sizeModeFactor;
752   }
753
754   return Relayouter::DEFAULT_SIZE_MODE_FACTOR;
755 }
756
757 void Actor::SetColorMode(ColorMode colorMode)
758 {
759   // non animatable so keep local copy
760   mColorMode = colorMode;
761   // node is being used in a separate thread; queue a message to set the value
762   SetColorModeMessage(GetEventThreadServices(), GetNode(), colorMode);
763 }
764
765 void Actor::SetSize(float width, float height)
766 {
767   SetSize(Vector2(width, height));
768 }
769
770 void Actor::SetSize(float width, float height, float depth)
771 {
772   SetSize(Vector3(width, height, depth));
773 }
774
775 void Actor::SetSize(const Vector2& size)
776 {
777   SetSize(Vector3(size.width, size.height, 0.f));
778 }
779
780 void Actor::SetSizeInternal(const Vector2& size)
781 {
782   SetSizeInternal(Vector3(size.width, size.height, 0.f));
783 }
784
785 void Actor::SetSize(const Vector3& size)
786 {
787   if(IsRelayoutEnabled() && !mRelayoutData->insideRelayout)
788   {
789     // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
790     SetPreferredSize(size.GetVectorXY());
791   }
792   else
793   {
794     SetSizeInternal(size);
795   }
796 }
797
798 void Actor::SetSizeInternal(const Vector3& size)
799 {
800   // dont allow recursive loop
801   DALI_ASSERT_ALWAYS(!mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet");
802   // check that we have a node AND the new size width, height or depth is at least a little bit different from the old one
803   Vector3 currentSize = GetCurrentSize();
804
805   if((fabsf(mTargetSize.width - size.width) > Math::MACHINE_EPSILON_1) ||
806      (fabsf(mTargetSize.height - size.height) > Math::MACHINE_EPSILON_1) ||
807      (fabsf(mTargetSize.depth - size.depth) > Math::MACHINE_EPSILON_1) ||
808      (fabsf(mTargetSize.width - currentSize.width) > Math::MACHINE_EPSILON_1) ||
809      (fabsf(mTargetSize.height - currentSize.height) > Math::MACHINE_EPSILON_1) ||
810      (fabsf(mTargetSize.depth - currentSize.depth) > Math::MACHINE_EPSILON_1))
811   {
812     mTargetSize = size;
813
814     // node is being used in a separate thread; queue a message to set the value & base value
815     SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize);
816
817     // Notification for derived classes
818     mInsideOnSizeSet = true;
819     OnSizeSet(mTargetSize);
820     mInsideOnSizeSet = false;
821
822     // Raise a relayout request if the flag is not locked
823     if(mRelayoutData && !mRelayoutData->insideRelayout)
824     {
825       RelayoutRequest();
826     }
827   }
828 }
829
830 void Actor::SetWidth(float width)
831 {
832   if(IsRelayoutEnabled() && !mRelayoutData->insideRelayout)
833   {
834     SetResizePolicy(ResizePolicy::FIXED, Dimension::WIDTH);
835     mRelayoutData->preferredSize.width = width;
836   }
837   else
838   {
839     mTargetSize.width = width;
840
841     // node is being used in a separate thread; queue a message to set the value & base value
842     SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width);
843   }
844
845   mUseAnimatedSize &= ~AnimatedSizeFlag::WIDTH;
846
847   RelayoutRequest();
848 }
849
850 void Actor::SetHeight(float height)
851 {
852   if(IsRelayoutEnabled() && !mRelayoutData->insideRelayout)
853   {
854     SetResizePolicy(ResizePolicy::FIXED, Dimension::HEIGHT);
855     mRelayoutData->preferredSize.height = height;
856   }
857   else
858   {
859     mTargetSize.height = height;
860
861     // node is being used in a separate thread; queue a message to set the value & base value
862     SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height);
863   }
864
865   mUseAnimatedSize &= ~AnimatedSizeFlag::HEIGHT;
866
867   RelayoutRequest();
868 }
869
870 void Actor::SetDepth(float depth)
871 {
872   mTargetSize.depth = depth;
873
874   mUseAnimatedSize &= ~AnimatedSizeFlag::DEPTH;
875
876   // node is being used in a separate thread; queue a message to set the value & base value
877   SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth);
878 }
879
880 Vector3 Actor::GetTargetSize() const
881 {
882   Vector3 size = mTargetSize;
883
884   if(mUseAnimatedSize & AnimatedSizeFlag::WIDTH)
885   {
886     // Should return animated size if size is animated
887     size.width = mAnimatedSize.width;
888   }
889   else
890   {
891     // Should return preferred size if size is fixed as set by SetSize
892     if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::FIXED)
893     {
894       size.width = GetPreferredSize().width;
895     }
896   }
897
898   if(mUseAnimatedSize & AnimatedSizeFlag::HEIGHT)
899   {
900     size.height = mAnimatedSize.height;
901   }
902   else
903   {
904     if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::FIXED)
905     {
906       size.height = GetPreferredSize().height;
907     }
908   }
909
910   if(mUseAnimatedSize & AnimatedSizeFlag::DEPTH)
911   {
912     size.depth = mAnimatedSize.depth;
913   }
914
915   return size;
916 }
917
918 const Vector3& Actor::GetCurrentSize() const
919 {
920   // node is being used in a separate thread; copy the value from the previous update
921   return GetNode().GetSize(GetEventThreadServices().GetEventBufferIndex());
922 }
923
924 Vector3 Actor::GetNaturalSize() const
925 {
926   // It is up to deriving classes to return the appropriate natural size
927   return Vector3(0.0f, 0.0f, 0.0f);
928 }
929
930 void Actor::SetResizePolicy(ResizePolicy::Type policy, Dimension::Type dimension)
931 {
932   EnsureRelayouter().SetResizePolicy(policy, dimension, mTargetSize);
933
934   OnSetResizePolicy(policy, dimension);
935
936   // Trigger relayout on this control
937   RelayoutRequest();
938 }
939
940 ResizePolicy::Type Actor::GetResizePolicy(Dimension::Type dimension) const
941 {
942   if(mRelayoutData)
943   {
944     return mRelayoutData->GetResizePolicy(dimension);
945   }
946
947   return ResizePolicy::DEFAULT;
948 }
949
950 void Actor::SetSizeScalePolicy(SizeScalePolicy::Type policy)
951 {
952   EnsureRelayouter();
953
954   mRelayoutData->sizeSetPolicy = policy;
955
956   // Trigger relayout on this control
957   RelayoutRequest();
958 }
959
960 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
961 {
962   if(mRelayoutData)
963   {
964     return mRelayoutData->sizeSetPolicy;
965   }
966
967   return Relayouter::DEFAULT_SIZE_SCALE_POLICY;
968 }
969
970 void Actor::SetDimensionDependency(Dimension::Type dimension, Dimension::Type dependency)
971 {
972   EnsureRelayouter().SetDimensionDependency(dimension, dependency);
973 }
974
975 Dimension::Type Actor::GetDimensionDependency(Dimension::Type dimension) const
976 {
977   if(mRelayoutData)
978   {
979     return mRelayoutData->GetDimensionDependency(dimension);
980   }
981
982   return Dimension::ALL_DIMENSIONS; // Default
983 }
984
985 void Actor::SetRelayoutEnabled(bool relayoutEnabled)
986 {
987   // If relayout data has not been allocated yet and the client is requesting
988   // to disable it, do nothing
989   if(mRelayoutData || relayoutEnabled)
990   {
991     EnsureRelayouter();
992
993     DALI_ASSERT_DEBUG(mRelayoutData && "mRelayoutData not created");
994
995     mRelayoutData->relayoutEnabled = relayoutEnabled;
996   }
997 }
998
999 bool Actor::IsRelayoutEnabled() const
1000 {
1001   // Assume that if relayout data has not been allocated yet then
1002   // relayout is disabled
1003   return mRelayoutData && mRelayoutData->relayoutEnabled;
1004 }
1005
1006 void Actor::SetLayoutDirty(bool dirty, Dimension::Type dimension)
1007 {
1008   EnsureRelayouter().SetLayoutDirty(dirty, dimension);
1009 }
1010
1011 bool Actor::IsLayoutDirty(Dimension::Type dimension) const
1012 {
1013   return mRelayoutData && mRelayoutData->IsLayoutDirty(dimension);
1014 }
1015
1016 bool Actor::RelayoutPossible(Dimension::Type dimension) const
1017 {
1018   return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty(dimension);
1019 }
1020
1021 bool Actor::RelayoutRequired(Dimension::Type dimension) const
1022 {
1023   return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty(dimension);
1024 }
1025
1026 uint32_t Actor::AddRenderer(Renderer& renderer)
1027 {
1028   if(!mRenderers)
1029   {
1030     mRenderers = new RendererContainer;
1031   }
1032
1033   if(mIsBlendEquationSet)
1034   {
1035     renderer.SetBlendEquation(static_cast<DevelBlendEquation::Type>(mBlendEquation));
1036   }
1037
1038   uint32_t    index       = static_cast<uint32_t>(mRenderers->size()); //  4,294,967,295 renderers per actor
1039   RendererPtr rendererPtr = RendererPtr(&renderer);
1040   mRenderers->push_back(rendererPtr);
1041   AttachRendererMessage(GetEventThreadServices().GetUpdateManager(), GetNode(), renderer.GetRendererSceneObject());
1042   return index;
1043 }
1044
1045 uint32_t Actor::GetRendererCount() const
1046 {
1047   uint32_t rendererCount(0);
1048   if(mRenderers)
1049   {
1050     rendererCount = static_cast<uint32_t>(mRenderers->size()); //  4,294,967,295 renderers per actor
1051   }
1052
1053   return rendererCount;
1054 }
1055
1056 RendererPtr Actor::GetRendererAt(uint32_t index)
1057 {
1058   RendererPtr renderer;
1059   if(index < GetRendererCount())
1060   {
1061     renderer = (*mRenderers)[index];
1062   }
1063
1064   return renderer;
1065 }
1066
1067 void Actor::RemoveRenderer(Renderer& renderer)
1068 {
1069   if(mRenderers)
1070   {
1071     RendererIter end = mRenderers->end();
1072     for(RendererIter iter = mRenderers->begin(); iter != end; ++iter)
1073     {
1074       if((*iter).Get() == &renderer)
1075       {
1076         mRenderers->erase(iter);
1077         DetachRendererMessage(GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject());
1078         break;
1079       }
1080     }
1081   }
1082 }
1083
1084 void Actor::RemoveRenderer(uint32_t index)
1085 {
1086   if(index < GetRendererCount())
1087   {
1088     RendererPtr renderer = (*mRenderers)[index];
1089     DetachRendererMessage(GetEventThreadServices(), GetNode(), renderer.Get()->GetRendererSceneObject());
1090     mRenderers->erase(mRenderers->begin() + index);
1091   }
1092 }
1093
1094 void Actor::SetBlendEquation(DevelBlendEquation::Type blendEquation)
1095 {
1096   if(Dali::Capabilities::IsBlendEquationSupported(blendEquation))
1097   {
1098     if(mBlendEquation != blendEquation)
1099     {
1100       mBlendEquation         = blendEquation;
1101       uint32_t rendererCount = GetRendererCount();
1102       for(uint32_t i = 0; i < rendererCount; ++i)
1103       {
1104         RendererPtr renderer = GetRendererAt(i);
1105         renderer->SetBlendEquation(static_cast<DevelBlendEquation::Type>(blendEquation));
1106       }
1107     }
1108     mIsBlendEquationSet = true;
1109   }
1110   else
1111   {
1112     DALI_LOG_ERROR("Invalid blend equation is entered.\n");
1113   }
1114 }
1115
1116 DevelBlendEquation::Type Actor::GetBlendEquation() const
1117 {
1118   return mBlendEquation;
1119 }
1120
1121 void Actor::SetTransparent(bool transparent)
1122 {
1123   SetTransparentMessage(GetEventThreadServices(), GetNode(), transparent);
1124 }
1125
1126 bool Actor::GetTransparent() const
1127 {
1128   return GetNode().GetTransparent();
1129 }
1130
1131 void Actor::SetDrawMode(DrawMode::Type drawMode)
1132 {
1133   // this flag is not animatable so keep the value
1134   mDrawMode = drawMode;
1135
1136   // node is being used in a separate thread; queue a message to set the value
1137   SetDrawModeMessage(GetEventThreadServices(), GetNode(), drawMode);
1138 }
1139
1140 bool Actor::ScreenToLocal(float& localX, float& localY, float screenX, float screenY) const
1141 {
1142   // only valid when on-stage
1143   if(mScene && OnScene())
1144   {
1145     const RenderTaskList& taskList = mScene->GetRenderTaskList();
1146
1147     Vector2 converted(screenX, screenY);
1148
1149     // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1150     uint32_t taskCount = taskList.GetTaskCount();
1151     for(uint32_t i = taskCount; i > 0; --i)
1152     {
1153       RenderTaskPtr task = taskList.GetTask(i - 1);
1154       if(ScreenToLocal(*task, localX, localY, screenX, screenY))
1155       {
1156         // found a task where this conversion was ok so return
1157         return true;
1158       }
1159     }
1160   }
1161   return false;
1162 }
1163
1164 bool Actor::ScreenToLocal(const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY) const
1165 {
1166   bool retval = false;
1167   // only valid when on-stage
1168   if(OnScene())
1169   {
1170     CameraActor* camera = renderTask.GetCameraActor();
1171     if(camera)
1172     {
1173       Viewport viewport;
1174       renderTask.GetViewport(viewport);
1175
1176       // need to translate coordinates to render tasks coordinate space
1177       Vector2 converted(screenX, screenY);
1178       if(renderTask.TranslateCoordinates(converted))
1179       {
1180         retval = ScreenToLocal(camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y);
1181       }
1182     }
1183   }
1184   return retval;
1185 }
1186
1187 bool Actor::ScreenToLocal(const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY) const
1188 {
1189   return OnScene() && ScreenToLocalInternal(viewMatrix, projectionMatrix, GetNode().GetWorldMatrix(0), viewport, GetCurrentSize(), localX, localY, screenX, screenY);
1190 }
1191
1192 ActorGestureData& Actor::GetGestureData()
1193 {
1194   // Likely scenario is that once gesture-data is created for this actor, the actor will require
1195   // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1196   if(nullptr == mGestureData)
1197   {
1198     mGestureData = new ActorGestureData;
1199   }
1200   return *mGestureData;
1201 }
1202
1203 bool Actor::IsGestureRequired(GestureType::Value type) const
1204 {
1205   return mGestureData && mGestureData->IsGestureRequired(type);
1206 }
1207
1208 bool Actor::EmitInterceptTouchEventSignal(const Dali::TouchEvent& touch)
1209 {
1210   return EmitConsumingSignal(*this, mInterceptTouchedSignal, touch);
1211 }
1212
1213 bool Actor::EmitTouchEventSignal(const Dali::TouchEvent& touch)
1214 {
1215   return EmitConsumingSignal(*this, mTouchedSignal, touch);
1216 }
1217
1218 bool Actor::EmitHoverEventSignal(const Dali::HoverEvent& event)
1219 {
1220   return EmitConsumingSignal(*this, mHoveredSignal, event);
1221 }
1222
1223 bool Actor::EmitWheelEventSignal(const Dali::WheelEvent& event)
1224 {
1225   return EmitConsumingSignal(*this, mWheelEventSignal, event);
1226 }
1227
1228 void Actor::EmitVisibilityChangedSignal(bool visible, DevelActor::VisibilityChange::Type type)
1229 {
1230   EmitSignal(*this, mVisibilityChangedSignal, visible, type);
1231 }
1232
1233 void Actor::EmitLayoutDirectionChangedSignal(LayoutDirection::Type type)
1234 {
1235   EmitSignal(*this, mLayoutDirectionChangedSignal, type);
1236 }
1237
1238 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
1239 {
1240   return mParentImpl.ChildAddedSignal();
1241 }
1242
1243 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
1244 {
1245   return mParentImpl.ChildRemovedSignal();
1246 }
1247
1248 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
1249 {
1250   return mParentImpl.ChildOrderChangedSignal();
1251 }
1252
1253 bool Actor::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
1254 {
1255   bool   connected(true);
1256   Actor* actor = static_cast<Actor*>(object); // TypeRegistry guarantees that this is the correct type.
1257
1258   std::string_view name(signalName);
1259
1260   if(name == SIGNAL_HOVERED)
1261   {
1262     actor->HoveredSignal().Connect(tracker, functor);
1263   }
1264   else if(signalName == SIGNAL_WHEEL_EVENT)
1265   {
1266     actor->WheelEventSignal().Connect(tracker, functor);
1267   }
1268   else if(name == SIGNAL_ON_SCENE)
1269   {
1270     actor->OnSceneSignal().Connect(tracker, functor);
1271   }
1272   else if(name == SIGNAL_OFF_SCENE)
1273   {
1274     actor->OffSceneSignal().Connect(tracker, functor);
1275   }
1276   else if(name == SIGNAL_ON_RELAYOUT)
1277   {
1278     actor->OnRelayoutSignal().Connect(tracker, functor);
1279   }
1280   else if(name == SIGNAL_TOUCHED)
1281   {
1282     actor->TouchedSignal().Connect(tracker, functor);
1283   }
1284   else if(name == SIGNAL_VISIBILITY_CHANGED)
1285   {
1286     actor->VisibilityChangedSignal().Connect(tracker, functor);
1287   }
1288   else if(name == SIGNAL_LAYOUT_DIRECTION_CHANGED)
1289   {
1290     actor->LayoutDirectionChangedSignal().Connect(tracker, functor);
1291   }
1292   else if(name == SIGNAL_CHILD_ADDED)
1293   {
1294     actor->ChildAddedSignal().Connect(tracker, functor);
1295   }
1296   else if(name == SIGNAL_CHILD_REMOVED)
1297   {
1298     actor->ChildRemovedSignal().Connect(tracker, functor);
1299   }
1300   else
1301   {
1302     // signalName does not match any signal
1303     connected = false;
1304   }
1305
1306   return connected;
1307 }
1308
1309 Actor::Actor(DerivedType derivedType, const SceneGraph::Node& node)
1310 : Object(&node),
1311   mParentImpl(*this),
1312   mParent(nullptr),
1313   mScene(nullptr),
1314   mRenderers(nullptr),
1315   mParentOrigin(nullptr),
1316   mAnchorPoint(nullptr),
1317   mRelayoutData(nullptr),
1318   mGestureData(nullptr),
1319   mInterceptTouchedSignal(),
1320   mTouchedSignal(),
1321   mHoveredSignal(),
1322   mWheelEventSignal(),
1323   mOnSceneSignal(),
1324   mOffSceneSignal(),
1325   mOnRelayoutSignal(),
1326   mVisibilityChangedSignal(),
1327   mLayoutDirectionChangedSignal(),
1328   mTargetOrientation(Quaternion::IDENTITY),
1329   mTargetColor(Color::WHITE),
1330   mTargetSize(Vector3::ZERO),
1331   mTargetPosition(Vector3::ZERO),
1332   mTargetScale(Vector3::ONE),
1333   mAnimatedSize(Vector3::ZERO),
1334   mTouchAreaOffset(0, 0, 0, 0),
1335   mName(),
1336   mSortedDepth(0u),
1337   mDepth(0u),
1338   mUseAnimatedSize(AnimatedSizeFlag::CLEAR),
1339   mIsRoot(ROOT_LAYER == derivedType),
1340   mIsLayer(LAYER == derivedType || ROOT_LAYER == derivedType),
1341   mIsOnScene(false),
1342   mSensitive(true),
1343   mLeaveRequired(false),
1344   mKeyboardFocusable(false),
1345   mOnSceneSignalled(false),
1346   mInsideOnSizeSet(false),
1347   mInheritPosition(true),
1348   mInheritOrientation(true),
1349   mInheritScale(true),
1350   mPositionUsesAnchorPoint(true),
1351   mVisible(true),
1352   mInheritLayoutDirection(true),
1353   mCaptureAllTouchAfterStart(false),
1354   mIsBlendEquationSet(false),
1355   mNeedGesturePropagation(false),
1356   mLayoutDirection(LayoutDirection::LEFT_TO_RIGHT),
1357   mDrawMode(DrawMode::NORMAL),
1358   mColorMode(Node::DEFAULT_COLOR_MODE),
1359   mClippingMode(ClippingMode::DISABLED),
1360   mBlendEquation(DevelBlendEquation::ADD)
1361 {
1362 }
1363
1364 void Actor::Initialize()
1365 {
1366   OnInitialize();
1367
1368   GetEventThreadServices().RegisterObject(this);
1369 }
1370
1371 Actor::~Actor()
1372 {
1373   // Remove mParent pointers from children even if we're destroying core,
1374   // to guard against GetParent() & Unparent() calls from CustomActor destructors.
1375   UnparentChildren();
1376   delete mRenderers;
1377
1378   // Guard to allow handle destruction after Core has been destroyed
1379   if(EventThreadServices::IsCoreRunning())
1380   {
1381     // Root layer will destroy its node in its own destructor
1382     if(!mIsRoot)
1383     {
1384       DestroyNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
1385
1386       GetEventThreadServices().UnregisterObject(this);
1387     }
1388   }
1389
1390   // Cleanup optional gesture data
1391   delete mGestureData;
1392
1393   // Cleanup optional parent origin and anchor
1394   delete mParentOrigin;
1395   delete mAnchorPoint;
1396
1397   // Delete optional relayout data
1398   delete mRelayoutData;
1399 }
1400
1401 void Actor::Add(Actor& child)
1402 {
1403   mParentImpl.Add(child);
1404 }
1405
1406 void Actor::Remove(Actor& child)
1407 {
1408   mParentImpl.Remove(child);
1409 }
1410
1411 void Actor::SwitchParent(Actor& newParent)
1412 {
1413   DALI_ASSERT_ALWAYS(this != &newParent && "Cannot add actor to itself");
1414
1415   DALI_ASSERT_ALWAYS((this->OnScene() && newParent.OnScene()) && "Both of current parent and new parent must be on Scene");
1416
1417   Actor* oldParent = this->GetParent();
1418   if(oldParent->RemoveWithoutNotify(*this))
1419   {
1420     // Only put in a relayout request if there is a suitable dependency
1421     if(oldParent->RelayoutDependentOnChildren())
1422     {
1423       oldParent->RelayoutRequest();
1424     }
1425   }
1426
1427   newParent.AddWithoutNotify(*this);
1428   mParent            = &newParent;
1429   Actor* parentActor = static_cast<Actor*>(&newParent);
1430   mScene             = parentActor->mScene;
1431
1432   // Resolve the name and index for the child properties if any
1433   ResolveChildProperties();
1434
1435   this->InheritLayoutDirectionRecursively(newParent.GetLayoutDirection());
1436   // Only put in a relayout request if there is a suitable dependency
1437   if(newParent.RelayoutDependentOnChildren())
1438   {
1439     newParent.RelayoutRequest();
1440   }
1441 }
1442
1443 void Actor::AddWithoutNotify(Actor& child)
1444 {
1445   mParentImpl.AddWithoutNotify(child);
1446 }
1447
1448 bool Actor::RemoveWithoutNotify(Actor& child)
1449 {
1450   return mParentImpl.RemoveWithoutNotify(child);
1451 }
1452
1453 uint32_t Actor::GetChildCount() const
1454 {
1455   return mParentImpl.GetChildCount();
1456 }
1457
1458 ActorPtr Actor::GetChildAt(uint32_t index) const
1459 {
1460   return mParentImpl.GetChildAt(index);
1461 }
1462
1463 ActorContainer& Actor::GetChildrenInternal()
1464 {
1465   return mParentImpl.GetChildrenInternal();
1466 }
1467
1468 ActorPtr Actor::FindChildByName(ConstString actorName)
1469 {
1470   return mParentImpl.FindChildByName(actorName);
1471 }
1472
1473 ActorPtr Actor::FindChildById(const uint32_t id)
1474 {
1475   return mParentImpl.FindChildById(id);
1476 }
1477
1478 void Actor::UnparentChildren()
1479 {
1480   mParentImpl.UnparentChildren();
1481 }
1482
1483 void Actor::ConnectToScene(uint32_t parentDepth)
1484 {
1485   // This container is used instead of walking the Actor hierarchy.
1486   // It protects us when the Actor hierarchy is modified during OnSceneConnectionExternal callbacks.
1487   ActorContainer connectionList;
1488
1489   if(mScene)
1490   {
1491     mScene->RequestRebuildDepthTree();
1492   }
1493
1494   // This stage is atomic i.e. not interrupted by user callbacks.
1495   RecursiveConnectToScene(connectionList, parentDepth + 1);
1496
1497   // Notify applications about the newly connected actors.
1498   for(const auto& actor : connectionList)
1499   {
1500     actor->NotifyStageConnection();
1501   }
1502
1503   RelayoutRequest();
1504 }
1505
1506 void Actor::RecursiveConnectToScene(ActorContainer& connectionList, uint32_t depth)
1507 {
1508   DALI_ASSERT_ALWAYS(!OnScene());
1509
1510   mIsOnScene = true;
1511   mDepth     = static_cast<uint16_t>(depth); // overflow ignored, not expected in practice
1512
1513   ConnectToSceneGraph();
1514
1515   // Notification for internal derived classes
1516   OnSceneConnectionInternal();
1517
1518   // This stage is atomic; avoid emitting callbacks until all Actors are connected
1519   connectionList.push_back(ActorPtr(this));
1520
1521   // Recursively connect children
1522   if(GetChildCount() > 0)
1523   {
1524     for(const auto& child : mParentImpl.GetChildrenInternal())
1525     {
1526       child->SetScene(*mScene);
1527       child->RecursiveConnectToScene(connectionList, depth + 1);
1528     }
1529   }
1530 }
1531
1532 /**
1533  * This method is called when the Actor is connected to the Stage.
1534  * The parent must have added its Node to the scene-graph.
1535  * The child must connect its Node to the parent's Node.
1536  * This is recursive; the child calls ConnectToScene() for its children.
1537  */
1538 void Actor::ConnectToSceneGraph()
1539 {
1540   DALI_ASSERT_DEBUG(mParent != NULL);
1541
1542   // Reparent Node in next Update
1543   ConnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetParent()->GetNode(), GetNode());
1544
1545   // Request relayout on all actors that are added to the scenegraph
1546   RelayoutRequest();
1547
1548   // Notification for Object::Observers
1549   OnSceneObjectAdd();
1550 }
1551
1552 void Actor::NotifyStageConnection()
1553 {
1554   // Actors can be removed (in a callback), before the on-stage stage is reported.
1555   // The actor may also have been reparented, in which case mOnSceneSignalled will be true.
1556   if(OnScene() && !mOnSceneSignalled)
1557   {
1558     // Notification for external (CustomActor) derived classes
1559     OnSceneConnectionExternal(mDepth);
1560
1561     if(!mOnSceneSignal.Empty())
1562     {
1563       Dali::Actor handle(this);
1564       mOnSceneSignal.Emit(handle);
1565     }
1566
1567     // Guard against Remove during callbacks
1568     if(OnScene())
1569     {
1570       mOnSceneSignalled = true; // signal required next time Actor is removed
1571     }
1572   }
1573 }
1574
1575 void Actor::DisconnectFromStage()
1576 {
1577   // This container is used instead of walking the Actor hierachy.
1578   // It protects us when the Actor hierachy is modified during OnSceneDisconnectionExternal callbacks.
1579   ActorContainer disconnectionList;
1580
1581   if(mScene)
1582   {
1583     mScene->RequestRebuildDepthTree();
1584   }
1585
1586   // This stage is atomic i.e. not interrupted by user callbacks
1587   RecursiveDisconnectFromStage(disconnectionList);
1588
1589   // Notify applications about the newly disconnected actors.
1590   for(const auto& actor : disconnectionList)
1591   {
1592     actor->NotifyStageDisconnection();
1593   }
1594 }
1595
1596 void Actor::RecursiveDisconnectFromStage(ActorContainer& disconnectionList)
1597 {
1598   // need to change state first so that internals relying on IsOnScene() inside OnSceneDisconnectionInternal() get the correct value
1599   mIsOnScene = false;
1600
1601   // Recursively disconnect children
1602   if(GetChildCount() > 0)
1603   {
1604     for(const auto& child : mParentImpl.GetChildrenInternal())
1605     {
1606       child->RecursiveDisconnectFromStage(disconnectionList);
1607     }
1608   }
1609
1610   // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
1611   disconnectionList.push_back(ActorPtr(this));
1612
1613   // Notification for internal derived classes
1614   OnSceneDisconnectionInternal();
1615
1616   DisconnectFromSceneGraph();
1617 }
1618
1619 /**
1620  * This method is called by an actor or its parent, before a node removal message is sent.
1621  * This is recursive; the child calls DisconnectFromStage() for its children.
1622  */
1623 void Actor::DisconnectFromSceneGraph()
1624 {
1625   // Notification for Object::Observers
1626   OnSceneObjectRemove();
1627 }
1628
1629 void Actor::NotifyStageDisconnection()
1630 {
1631   // Actors can be added (in a callback), before the off-stage state is reported.
1632   // Also if the actor was added & removed before mOnSceneSignalled was set, then we don't notify here.
1633   // only do this step if there is a stage, i.e. Core is not being shut down
1634   if(EventThreadServices::IsCoreRunning() && !OnScene() && mOnSceneSignalled)
1635   {
1636     // Notification for external (CustomeActor) derived classes
1637     OnSceneDisconnectionExternal();
1638
1639     if(!mOffSceneSignal.Empty())
1640     {
1641       Dali::Actor handle(this);
1642       mOffSceneSignal.Emit(handle);
1643     }
1644
1645     // Guard against Add during callbacks
1646     if(!OnScene())
1647     {
1648       mOnSceneSignalled = false; // signal required next time Actor is added
1649     }
1650
1651     SetTransparent(false);
1652   }
1653 }
1654
1655 bool Actor::IsNodeConnected() const
1656 {
1657   bool connected(false);
1658
1659   if(OnScene())
1660   {
1661     if(IsRoot() || GetNode().GetParent())
1662     {
1663       connected = true;
1664     }
1665   }
1666
1667   return connected;
1668 }
1669
1670 // This method initiates traversal of the actor tree using depth-first
1671 // traversal to set a depth index based on traversal order. It sends a
1672 // single message to update manager to update all the actor's nodes in
1673 // this tree with the depth index. The sceneGraphNodeDepths vector's
1674 // elements are ordered by depth, and could be used to reduce sorting
1675 // in the update thread.
1676 void Actor::RebuildDepthTree()
1677 {
1678   DALI_LOG_TIMER_START(depthTimer);
1679
1680   // Vector of scene-graph nodes and their depths to send to UpdateManager
1681   // in a single message
1682   OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths(new SceneGraph::NodeDepths());
1683
1684   int32_t depthIndex = 1;
1685   DepthTraverseActorTree(sceneGraphNodeDepths, depthIndex);
1686
1687   SetDepthIndicesMessage(GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths);
1688   DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
1689 }
1690
1691 void Actor::DepthTraverseActorTree(OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int32_t& depthIndex)
1692 {
1693   mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
1694   sceneGraphNodeDepths->Add(const_cast<SceneGraph::Node*>(&GetNode()), mSortedDepth);
1695
1696   // Create/add to children of this node
1697   if(GetChildCount() > 0)
1698   {
1699     for(const auto& child : mParentImpl.GetChildrenInternal())
1700     {
1701       Actor* childActor = child.Get();
1702       ++depthIndex;
1703       childActor->DepthTraverseActorTree(sceneGraphNodeDepths, depthIndex);
1704     }
1705   }
1706 }
1707
1708 void Actor::SetDefaultProperty(Property::Index index, const Property::Value& property)
1709 {
1710   PropertyHandler::SetDefaultProperty(*this, index, property);
1711 }
1712
1713 // TODO: This method needs to be removed
1714 void Actor::SetSceneGraphProperty(Property::Index index, const PropertyMetadata& entry, const Property::Value& value)
1715 {
1716   PropertyHandler::SetSceneGraphProperty(index, entry, value, GetEventThreadServices(), GetNode());
1717 }
1718
1719 Property::Value Actor::GetDefaultProperty(Property::Index index) const
1720 {
1721   Property::Value value;
1722
1723   if(!GetCachedPropertyValue(index, value))
1724   {
1725     // If property value is not stored in the event-side, then it must be a scene-graph only property
1726     GetCurrentPropertyValue(index, value);
1727   }
1728
1729   return value;
1730 }
1731
1732 Property::Value Actor::GetDefaultPropertyCurrentValue(Property::Index index) const
1733 {
1734   Property::Value value;
1735
1736   if(!GetCurrentPropertyValue(index, value))
1737   {
1738     // If unable to retrieve scene-graph property value, then it must be an event-side only property
1739     GetCachedPropertyValue(index, value);
1740   }
1741
1742   return value;
1743 }
1744
1745 void Actor::OnNotifyDefaultPropertyAnimation(Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType)
1746 {
1747   PropertyHandler::OnNotifyDefaultPropertyAnimation(*this, animation, index, value, animationType);
1748 }
1749
1750 const PropertyBase* Actor::GetSceneObjectAnimatableProperty(Property::Index index) const
1751 {
1752   const PropertyBase* property = PropertyHandler::GetSceneObjectAnimatableProperty(index, GetNode());
1753   if(!property)
1754   {
1755     // not our property, ask base
1756     property = Object::GetSceneObjectAnimatableProperty(index);
1757   }
1758
1759   return property;
1760 }
1761
1762 const PropertyInputImpl* Actor::GetSceneObjectInputProperty(Property::Index index) const
1763 {
1764   const PropertyInputImpl* property = PropertyHandler::GetSceneObjectInputProperty(index, GetNode());
1765   if(!property)
1766   {
1767     // reuse animatable property getter as animatable properties are inputs as well
1768     // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
1769     property = GetSceneObjectAnimatableProperty(index);
1770   }
1771
1772   return property;
1773 }
1774
1775 int32_t Actor::GetPropertyComponentIndex(Property::Index index) const
1776 {
1777   int32_t componentIndex = PropertyHandler::GetPropertyComponentIndex(index);
1778   if(Property::INVALID_COMPONENT_INDEX == componentIndex)
1779   {
1780     // ask base
1781     componentIndex = Object::GetPropertyComponentIndex(index);
1782   }
1783
1784   return componentIndex;
1785 }
1786
1787 const SceneGraph::Node& Actor::GetNode() const
1788 {
1789   return *static_cast<const SceneGraph::Node*>(mUpdateObject);
1790 }
1791
1792 void Actor::Raise()
1793 {
1794   if(mParent)
1795   {
1796     mParent->RaiseChild(*this);
1797   }
1798   else
1799   {
1800     DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1801   }
1802 }
1803
1804 void Actor::Lower()
1805 {
1806   if(mParent)
1807   {
1808     mParent->LowerChild(*this);
1809   }
1810   else
1811   {
1812     DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1813   }
1814 }
1815
1816 void Actor::RaiseToTop()
1817 {
1818   if(mParent)
1819   {
1820     mParent->RaiseChildToTop(*this);
1821   }
1822   else
1823   {
1824     DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1825   }
1826 }
1827
1828 void Actor::LowerToBottom()
1829 {
1830   if(mParent)
1831   {
1832     mParent->LowerChildToBottom(*this);
1833   }
1834   else
1835   {
1836     DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1837   }
1838 }
1839
1840 void Actor::RaiseAbove(Internal::Actor& target)
1841 {
1842   if(mParent)
1843   {
1844     mParent->RaiseChildAbove(*this, target);
1845   }
1846   else
1847   {
1848     DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1849   }
1850 }
1851
1852 void Actor::LowerBelow(Internal::Actor& target)
1853 {
1854   if(mParent)
1855   {
1856     mParent->LowerChildBelow(*this, target);
1857   }
1858   else
1859   {
1860     DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1861   }
1862 }
1863
1864 void Actor::SetParent(ActorParent* parent)
1865 {
1866   if(parent)
1867   {
1868     DALI_ASSERT_ALWAYS(!mParent && "Actor cannot have 2 parents");
1869
1870     mParent            = parent;
1871     Actor* parentActor = static_cast<Actor*>(parent);
1872     mScene             = parentActor->mScene;
1873
1874     if(EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
1875        parentActor->OnScene())
1876     {
1877       // Instruct each actor to create a corresponding node in the scene graph
1878       ConnectToScene(parentActor->GetHierarchyDepth());
1879     }
1880
1881     // Resolve the name and index for the child properties if any
1882     ResolveChildProperties();
1883   }
1884   else // parent being set to NULL
1885   {
1886     DALI_ASSERT_ALWAYS(mParent != nullptr && "Actor should have a parent");
1887
1888     mParent = nullptr;
1889
1890     if(EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
1891        OnScene())
1892     {
1893       // Disconnect the Node & its children from the scene-graph.
1894       DisconnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
1895
1896       // Instruct each actor to discard pointers to the scene-graph
1897       DisconnectFromStage();
1898     }
1899
1900     mScene = nullptr;
1901   }
1902 }
1903
1904 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */)
1905 {
1906   bool   done  = false;
1907   Actor* actor = dynamic_cast<Actor*>(object);
1908
1909   if(actor)
1910   {
1911     std::string_view name(actionName);
1912     if(name == ACTION_SHOW)
1913     {
1914       actor->SetVisible(true);
1915       done = true;
1916     }
1917     else if(name == ACTION_HIDE)
1918     {
1919       actor->SetVisible(false);
1920       done = true;
1921     }
1922   }
1923
1924   return done;
1925 }
1926
1927 Rect<> Actor::CalculateScreenExtents() const
1928 {
1929   auto    screenPosition    = GetCurrentScreenPosition();
1930   Vector3 size              = GetCurrentSize() * GetCurrentWorldScale();
1931   Vector3 anchorPointOffSet = size * (mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT);
1932   Vector2 position          = Vector2(screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y);
1933   return {position.x, position.y, size.x, size.y};
1934 }
1935
1936 void Actor::SetNeedGesturePropagation(bool propagation)
1937 {
1938   mNeedGesturePropagation = propagation;
1939 }
1940
1941 bool Actor::NeedGesturePropagation()
1942 {
1943   return mNeedGesturePropagation;
1944 }
1945
1946 bool Actor::GetCachedPropertyValue(Property::Index index, Property::Value& value) const
1947 {
1948   return PropertyHandler::GetCachedPropertyValue(*this, index, value);
1949 }
1950
1951 bool Actor::GetCurrentPropertyValue(Property::Index index, Property::Value& value) const
1952 {
1953   return PropertyHandler::GetCurrentPropertyValue(*this, index, value);
1954 }
1955
1956 Actor::Relayouter& Actor::EnsureRelayouter()
1957 {
1958   // Assign relayouter
1959   if(!mRelayoutData)
1960   {
1961     mRelayoutData = new Relayouter();
1962   }
1963
1964   return *mRelayoutData;
1965 }
1966
1967 bool Actor::RelayoutDependentOnParent(Dimension::Type dimension)
1968 {
1969   // Check if actor is dependent on parent
1970   for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
1971   {
1972     if((dimension & (1 << i)))
1973     {
1974       const ResizePolicy::Type resizePolicy = GetResizePolicy(static_cast<Dimension::Type>(1 << i));
1975       if(resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT)
1976       {
1977         return true;
1978       }
1979     }
1980   }
1981
1982   return false;
1983 }
1984
1985 bool Actor::RelayoutDependentOnChildren(Dimension::Type dimension)
1986 {
1987   // Check if actor is dependent on children
1988   for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
1989   {
1990     if((dimension & (1 << i)))
1991     {
1992       const ResizePolicy::Type resizePolicy = GetResizePolicy(static_cast<Dimension::Type>(1 << i));
1993       switch(resizePolicy)
1994       {
1995         case ResizePolicy::FIT_TO_CHILDREN:
1996         case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
1997         {
1998           return true;
1999         }
2000
2001         default:
2002         {
2003           break;
2004         }
2005       }
2006     }
2007   }
2008
2009   return false;
2010 }
2011
2012 bool Actor::RelayoutDependentOnChildrenBase(Dimension::Type dimension)
2013 {
2014   return Actor::RelayoutDependentOnChildren(dimension);
2015 }
2016
2017 bool Actor::RelayoutDependentOnDimension(Dimension::Type dimension, Dimension::Type dependentDimension)
2018 {
2019   // Check each possible dimension and see if it is dependent on the input one
2020   for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
2021   {
2022     if(dimension & (1 << i))
2023     {
2024       return mRelayoutData->resizePolicies[i] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[i] == dependentDimension;
2025     }
2026   }
2027
2028   return false;
2029 }
2030
2031 void Actor::SetNegotiatedDimension(float negotiatedDimension, Dimension::Type dimension)
2032 {
2033   for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
2034   {
2035     if(dimension & (1 << i))
2036     {
2037       mRelayoutData->negotiatedDimensions[i] = negotiatedDimension;
2038     }
2039   }
2040 }
2041
2042 float Actor::GetNegotiatedDimension(Dimension::Type dimension) const
2043 {
2044   // If more than one dimension is requested, just return the first one found
2045   for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
2046   {
2047     if((dimension & (1 << i)))
2048     {
2049       return mRelayoutData->negotiatedDimensions[i];
2050     }
2051   }
2052
2053   return 0.0f; // Default
2054 }
2055
2056 void Actor::SetPadding(const Vector2& padding, Dimension::Type dimension)
2057 {
2058   EnsureRelayouter().SetPadding(padding, dimension);
2059 }
2060
2061 Vector2 Actor::GetPadding(Dimension::Type dimension) const
2062 {
2063   if(mRelayoutData)
2064   {
2065     // If more than one dimension is requested, just return the first one found
2066     for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
2067     {
2068       if((dimension & (1 << i)))
2069       {
2070         return mRelayoutData->dimensionPadding[i];
2071       }
2072     }
2073   }
2074
2075   return Relayouter::DEFAULT_DIMENSION_PADDING;
2076 }
2077
2078 void Actor::SetLayoutNegotiated(bool negotiated, Dimension::Type dimension)
2079 {
2080   EnsureRelayouter().SetLayoutNegotiated(negotiated, dimension);
2081 }
2082
2083 bool Actor::IsLayoutNegotiated(Dimension::Type dimension) const
2084 {
2085   return mRelayoutData && mRelayoutData->IsLayoutNegotiated(dimension);
2086 }
2087
2088 float Actor::GetHeightForWidthBase(float width)
2089 {
2090   float height = 0.0f;
2091
2092   const Vector3 naturalSize = GetNaturalSize();
2093   if(naturalSize.width > 0.0f)
2094   {
2095     height = naturalSize.height * width / naturalSize.width;
2096   }
2097   else // we treat 0 as 1:1 aspect ratio
2098   {
2099     height = width;
2100   }
2101
2102   return height;
2103 }
2104
2105 float Actor::GetWidthForHeightBase(float height)
2106 {
2107   float width = 0.0f;
2108
2109   const Vector3 naturalSize = GetNaturalSize();
2110   if(naturalSize.height > 0.0f)
2111   {
2112     width = naturalSize.width * height / naturalSize.height;
2113   }
2114   else // we treat 0 as 1:1 aspect ratio
2115   {
2116     width = height;
2117   }
2118
2119   return width;
2120 }
2121
2122 float Actor::CalculateChildSizeBase(const Dali::Actor& child, Dimension::Type dimension)
2123 {
2124   // Fill to parent, taking size mode factor into account
2125   switch(child.GetResizePolicy(dimension))
2126   {
2127     case ResizePolicy::FILL_TO_PARENT:
2128     {
2129       return GetLatestSize(dimension);
2130     }
2131
2132     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
2133     {
2134       return GetLatestSize(dimension) * GetDimensionValue(child.GetProperty<Vector3>(Dali::Actor::Property::SIZE_MODE_FACTOR), dimension);
2135     }
2136
2137     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
2138     {
2139       return GetLatestSize(dimension) + GetDimensionValue(child.GetProperty<Vector3>(Dali::Actor::Property::SIZE_MODE_FACTOR), dimension);
2140     }
2141
2142     default:
2143     {
2144       return GetLatestSize(dimension);
2145     }
2146   }
2147 }
2148
2149 float Actor::CalculateChildSize(const Dali::Actor& child, Dimension::Type dimension)
2150 {
2151   // Can be overridden in derived class
2152   return CalculateChildSizeBase(child, dimension);
2153 }
2154
2155 float Actor::GetHeightForWidth(float width)
2156 {
2157   // Can be overridden in derived class
2158   return GetHeightForWidthBase(width);
2159 }
2160
2161 float Actor::GetWidthForHeight(float height)
2162 {
2163   // Can be overridden in derived class
2164   return GetWidthForHeightBase(height);
2165 }
2166
2167 float Actor::GetLatestSize(Dimension::Type dimension) const
2168 {
2169   return IsLayoutNegotiated(dimension) ? GetNegotiatedDimension(dimension) : GetSize(dimension);
2170 }
2171
2172 float Actor::GetRelayoutSize(Dimension::Type dimension) const
2173 {
2174   Vector2 padding = GetPadding(dimension);
2175
2176   return GetLatestSize(dimension) + padding.x + padding.y;
2177 }
2178
2179 float Actor::NegotiateFromParent(Dimension::Type dimension)
2180 {
2181   Actor* parent = GetParent();
2182   if(parent)
2183   {
2184     Vector2 padding(GetPadding(dimension));
2185     Vector2 parentPadding(parent->GetPadding(dimension));
2186     return parent->CalculateChildSize(Dali::Actor(this), dimension) - parentPadding.x - parentPadding.y - padding.x - padding.y;
2187   }
2188
2189   return 0.0f;
2190 }
2191
2192 float Actor::NegotiateFromChildren(Dimension::Type dimension)
2193 {
2194   float maxDimensionPoint = 0.0f;
2195
2196   for(uint32_t i = 0, count = GetChildCount(); i < count; ++i)
2197   {
2198     ActorPtr child = GetChildAt(i);
2199
2200     if(!child->RelayoutDependentOnParent(dimension))
2201     {
2202       // Calculate the min and max points that the children range across
2203       float childPosition = GetDimensionValue(child->GetTargetPosition(), dimension);
2204       float dimensionSize = child->GetRelayoutSize(dimension);
2205       maxDimensionPoint   = std::max(maxDimensionPoint, childPosition + dimensionSize);
2206     }
2207   }
2208
2209   return maxDimensionPoint;
2210 }
2211
2212 float Actor::GetSize(Dimension::Type dimension) const
2213 {
2214   return GetDimensionValue(mTargetSize, dimension);
2215 }
2216
2217 float Actor::GetNaturalSize(Dimension::Type dimension) const
2218 {
2219   return GetDimensionValue(GetNaturalSize(), dimension);
2220 }
2221
2222 float Actor::CalculateSize(Dimension::Type dimension, const Vector2& maximumSize)
2223 {
2224   switch(GetResizePolicy(dimension))
2225   {
2226     case ResizePolicy::USE_NATURAL_SIZE:
2227     {
2228       return GetNaturalSize(dimension);
2229     }
2230
2231     case ResizePolicy::FIXED:
2232     {
2233       return GetDimensionValue(GetPreferredSize(), dimension);
2234     }
2235
2236     case ResizePolicy::USE_ASSIGNED_SIZE:
2237     {
2238       return GetDimensionValue(maximumSize, dimension);
2239     }
2240
2241     case ResizePolicy::FILL_TO_PARENT:
2242     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
2243     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
2244     {
2245       return NegotiateFromParent(dimension);
2246     }
2247
2248     case ResizePolicy::FIT_TO_CHILDREN:
2249     {
2250       return NegotiateFromChildren(dimension);
2251     }
2252
2253     case ResizePolicy::DIMENSION_DEPENDENCY:
2254     {
2255       const Dimension::Type dimensionDependency = GetDimensionDependency(dimension);
2256
2257       // Custom rules
2258       if(dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT)
2259       {
2260         return GetWidthForHeight(GetNegotiatedDimension(Dimension::HEIGHT));
2261       }
2262
2263       if(dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH)
2264       {
2265         return GetHeightForWidth(GetNegotiatedDimension(Dimension::WIDTH));
2266       }
2267
2268       break;
2269     }
2270
2271     default:
2272     {
2273       break;
2274     }
2275   }
2276
2277   return 0.0f; // Default
2278 }
2279
2280 Vector2 Actor::ApplySizeSetPolicy(const Vector2& size)
2281 {
2282   return mRelayoutData->ApplySizeSetPolicy(*this, size);
2283 }
2284
2285 void Actor::SetNegotiatedSize(RelayoutContainer& container)
2286 {
2287   // Do the set actor size
2288   Vector2 negotiatedSize(GetLatestSize(Dimension::WIDTH), GetLatestSize(Dimension::HEIGHT));
2289
2290   // Adjust for size set policy
2291   negotiatedSize = ApplySizeSetPolicy(negotiatedSize);
2292
2293   // Lock the flag to stop recursive relayouts on set size
2294   mRelayoutData->insideRelayout = true;
2295   SetSize(negotiatedSize);
2296   mRelayoutData->insideRelayout = false;
2297
2298   // Clear flags for all dimensions
2299   SetLayoutDirty(false);
2300
2301   // Give deriving classes a chance to respond
2302   OnRelayout(negotiatedSize, container);
2303
2304   if(!mOnRelayoutSignal.Empty())
2305   {
2306     Dali::Actor handle(this);
2307     mOnRelayoutSignal.Emit(handle);
2308   }
2309 }
2310
2311 void Actor::NegotiateSize(const Vector2& allocatedSize, RelayoutContainer& container)
2312 {
2313   Relayouter::NegotiateSize(*this, allocatedSize, container);
2314 }
2315
2316 void Actor::SetUseAssignedSize(bool use, Dimension::Type dimension)
2317 {
2318   if(mRelayoutData)
2319   {
2320     mRelayoutData->SetUseAssignedSize(use, dimension);
2321   }
2322 }
2323
2324 bool Actor::GetUseAssignedSize(Dimension::Type dimension) const
2325 {
2326   return mRelayoutData && mRelayoutData->GetUseAssignedSize(dimension);
2327 }
2328
2329 void Actor::RelayoutRequest(Dimension::Type dimension)
2330 {
2331   Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
2332   if(relayoutController)
2333   {
2334     Dali::Actor self(this);
2335     relayoutController->RequestRelayout(self, dimension);
2336   }
2337 }
2338
2339 void Actor::SetPreferredSize(const Vector2& size)
2340 {
2341   EnsureRelayouter().SetPreferredSize(*this, size);
2342 }
2343
2344 Vector2 Actor::GetPreferredSize() const
2345 {
2346   if(mRelayoutData)
2347   {
2348     return Vector2(mRelayoutData->preferredSize);
2349   }
2350
2351   return Relayouter::DEFAULT_PREFERRED_SIZE;
2352 }
2353
2354 void Actor::SetMinimumSize(float size, Dimension::Type dimension)
2355 {
2356   EnsureRelayouter().SetMinimumSize(size, dimension);
2357   RelayoutRequest();
2358 }
2359
2360 float Actor::GetMinimumSize(Dimension::Type dimension) const
2361 {
2362   if(mRelayoutData)
2363   {
2364     return mRelayoutData->GetMinimumSize(dimension);
2365   }
2366
2367   return 0.0f; // Default
2368 }
2369
2370 void Actor::SetMaximumSize(float size, Dimension::Type dimension)
2371 {
2372   EnsureRelayouter().SetMaximumSize(size, dimension);
2373   RelayoutRequest();
2374 }
2375
2376 float Actor::GetMaximumSize(Dimension::Type dimension) const
2377 {
2378   if(mRelayoutData)
2379   {
2380     return mRelayoutData->GetMaximumSize(dimension);
2381   }
2382
2383   return FLT_MAX; // Default
2384 }
2385
2386 void Actor::SetVisibleInternal(bool visible, SendMessage::Type sendMessage)
2387 {
2388   if(mVisible != visible)
2389   {
2390     if(sendMessage == SendMessage::TRUE)
2391     {
2392       // node is being used in a separate thread; queue a message to set the value & base value
2393       SceneGraph::NodePropertyMessage<bool>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible);
2394
2395       RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
2396     }
2397
2398     mVisible = visible;
2399
2400     // Emit the signal on this actor and all its children
2401     EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::SELF);
2402   }
2403 }
2404
2405 void Actor::SetSiblingOrderOfChild(Actor& child, uint32_t order)
2406 {
2407   mParentImpl.SetSiblingOrderOfChild(child, order);
2408 }
2409
2410 uint32_t Actor::GetSiblingOrderOfChild(const Actor& child) const
2411 {
2412   return mParentImpl.GetSiblingOrderOfChild(child);
2413 }
2414
2415 void Actor::RaiseChild(Actor& child)
2416 {
2417   mParentImpl.RaiseChild(child);
2418 }
2419
2420 void Actor::LowerChild(Actor& child)
2421 {
2422   mParentImpl.LowerChild(child);
2423 }
2424
2425 void Actor::RaiseChildToTop(Actor& child)
2426 {
2427   mParentImpl.RaiseChildToTop(child);
2428 }
2429
2430 void Actor::LowerChildToBottom(Actor& child)
2431 {
2432   mParentImpl.LowerChildToBottom(child);
2433 }
2434
2435 void Actor::RaiseChildAbove(Actor& child, Actor& target)
2436 {
2437   mParentImpl.RaiseChildAbove(child, target);
2438 }
2439
2440 void Actor::LowerChildBelow(Actor& child, Actor& target)
2441 {
2442   mParentImpl.LowerChildBelow(child, target);
2443 }
2444
2445 void Actor::SetInheritLayoutDirection(bool inherit)
2446 {
2447   if(mInheritLayoutDirection != inherit)
2448   {
2449     mInheritLayoutDirection = inherit;
2450
2451     if(inherit && mParent)
2452     {
2453       InheritLayoutDirectionRecursively(GetParent()->mLayoutDirection);
2454     }
2455   }
2456 }
2457
2458 void Actor::InheritLayoutDirectionRecursively(Dali::LayoutDirection::Type direction, bool set)
2459 {
2460   if(mInheritLayoutDirection || set)
2461   {
2462     if(mLayoutDirection != direction)
2463     {
2464       mLayoutDirection = direction;
2465       EmitLayoutDirectionChangedSignal(direction);
2466       RelayoutRequest();
2467     }
2468
2469     if(GetChildCount() > 0)
2470     {
2471       for(const auto& child : mParentImpl.GetChildrenInternal())
2472       {
2473         child->InheritLayoutDirectionRecursively(direction);
2474       }
2475     }
2476   }
2477 }
2478
2479 void Actor::SetUpdateSizeHint(const Vector2& updateSizeHint)
2480 {
2481   // node is being used in a separate thread; queue a message to set the value & base value
2482   SceneGraph::NodePropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mUpdateSizeHint, &AnimatableProperty<Vector3>::Bake, Vector3(updateSizeHint.width, updateSizeHint.height, 0.f));
2483 }
2484
2485 void Actor::EmitVisibilityChangedSignalRecursively(bool                               visible,
2486                                                    DevelActor::VisibilityChange::Type type)
2487 {
2488   EmitVisibilityChangedSignal(visible, type);
2489
2490   if(GetChildCount() > 0)
2491   {
2492     for(auto& child : mParentImpl.GetChildrenInternal())
2493     {
2494       child->EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::PARENT);
2495     }
2496   }
2497 }
2498
2499 } // namespace Internal
2500
2501 } // namespace Dali