[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   mLayoutDirection(LayoutDirection::LEFT_TO_RIGHT),
1355   mDrawMode(DrawMode::NORMAL),
1356   mColorMode(Node::DEFAULT_COLOR_MODE),
1357   mClippingMode(ClippingMode::DISABLED),
1358   mBlendEquation(DevelBlendEquation::ADD),
1359   mIsBlendEquationSet(false)
1360 {
1361 }
1362
1363 void Actor::Initialize()
1364 {
1365   OnInitialize();
1366
1367   GetEventThreadServices().RegisterObject(this);
1368 }
1369
1370 Actor::~Actor()
1371 {
1372   // Remove mParent pointers from children even if we're destroying core,
1373   // to guard against GetParent() & Unparent() calls from CustomActor destructors.
1374   UnparentChildren();
1375   delete mRenderers;
1376
1377   // Guard to allow handle destruction after Core has been destroyed
1378   if(EventThreadServices::IsCoreRunning())
1379   {
1380     // Root layer will destroy its node in its own destructor
1381     if(!mIsRoot)
1382     {
1383       DestroyNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
1384
1385       GetEventThreadServices().UnregisterObject(this);
1386     }
1387   }
1388
1389   // Cleanup optional gesture data
1390   delete mGestureData;
1391
1392   // Cleanup optional parent origin and anchor
1393   delete mParentOrigin;
1394   delete mAnchorPoint;
1395
1396   // Delete optional relayout data
1397   delete mRelayoutData;
1398 }
1399
1400 void Actor::Add(Actor& child)
1401 {
1402   mParentImpl.Add(child);
1403 }
1404
1405 void Actor::Remove(Actor& child)
1406 {
1407   mParentImpl.Remove(child);
1408 }
1409
1410 void Actor::SwitchParent(Actor& newParent)
1411 {
1412   DALI_ASSERT_ALWAYS(this != &newParent && "Cannot add actor to itself");
1413
1414   DALI_ASSERT_ALWAYS((this->OnScene() && newParent.OnScene()) && "Both of current parent and new parent must be on Scene");
1415
1416   Actor* oldParent = this->GetParent();
1417   if(oldParent->RemoveWithoutNotify(*this))
1418   {
1419     // Only put in a relayout request if there is a suitable dependency
1420     if(oldParent->RelayoutDependentOnChildren())
1421     {
1422       oldParent->RelayoutRequest();
1423     }
1424   }
1425
1426   newParent.AddWithoutNotify(*this);
1427   mParent            = &newParent;
1428   Actor* parentActor = static_cast<Actor*>(&newParent);
1429   mScene             = parentActor->mScene;
1430
1431   // Resolve the name and index for the child properties if any
1432   ResolveChildProperties();
1433
1434   this->InheritLayoutDirectionRecursively(newParent.GetLayoutDirection());
1435   // Only put in a relayout request if there is a suitable dependency
1436   if(newParent.RelayoutDependentOnChildren())
1437   {
1438     newParent.RelayoutRequest();
1439   }
1440 }
1441
1442 void Actor::AddWithoutNotify(Actor& child)
1443 {
1444   mParentImpl.AddWithoutNotify(child);
1445 }
1446
1447 bool Actor::RemoveWithoutNotify(Actor& child)
1448 {
1449   return mParentImpl.RemoveWithoutNotify(child);
1450 }
1451
1452 uint32_t Actor::GetChildCount() const
1453 {
1454   return mParentImpl.GetChildCount();
1455 }
1456
1457 ActorPtr Actor::GetChildAt(uint32_t index) const
1458 {
1459   return mParentImpl.GetChildAt(index);
1460 }
1461
1462 ActorContainer& Actor::GetChildrenInternal()
1463 {
1464   return mParentImpl.GetChildrenInternal();
1465 }
1466
1467 ActorPtr Actor::FindChildByName(ConstString actorName)
1468 {
1469   return mParentImpl.FindChildByName(actorName);
1470 }
1471
1472 ActorPtr Actor::FindChildById(const uint32_t id)
1473 {
1474   return mParentImpl.FindChildById(id);
1475 }
1476
1477 void Actor::UnparentChildren()
1478 {
1479   mParentImpl.UnparentChildren();
1480 }
1481
1482 void Actor::ConnectToScene(uint32_t parentDepth)
1483 {
1484   // This container is used instead of walking the Actor hierarchy.
1485   // It protects us when the Actor hierarchy is modified during OnSceneConnectionExternal callbacks.
1486   ActorContainer connectionList;
1487
1488   if(mScene)
1489   {
1490     mScene->RequestRebuildDepthTree();
1491   }
1492
1493   // This stage is atomic i.e. not interrupted by user callbacks.
1494   RecursiveConnectToScene(connectionList, parentDepth + 1);
1495
1496   // Notify applications about the newly connected actors.
1497   for(const auto& actor : connectionList)
1498   {
1499     actor->NotifyStageConnection();
1500   }
1501
1502   RelayoutRequest();
1503 }
1504
1505 void Actor::RecursiveConnectToScene(ActorContainer& connectionList, uint32_t depth)
1506 {
1507   DALI_ASSERT_ALWAYS(!OnScene());
1508
1509   mIsOnScene = true;
1510   mDepth     = static_cast<uint16_t>(depth); // overflow ignored, not expected in practice
1511
1512   ConnectToSceneGraph();
1513
1514   // Notification for internal derived classes
1515   OnSceneConnectionInternal();
1516
1517   // This stage is atomic; avoid emitting callbacks until all Actors are connected
1518   connectionList.push_back(ActorPtr(this));
1519
1520   // Recursively connect children
1521   if(GetChildCount() > 0)
1522   {
1523     for(const auto& child : mParentImpl.GetChildrenInternal())
1524     {
1525       child->SetScene(*mScene);
1526       child->RecursiveConnectToScene(connectionList, depth + 1);
1527     }
1528   }
1529 }
1530
1531 /**
1532  * This method is called when the Actor is connected to the Stage.
1533  * The parent must have added its Node to the scene-graph.
1534  * The child must connect its Node to the parent's Node.
1535  * This is recursive; the child calls ConnectToScene() for its children.
1536  */
1537 void Actor::ConnectToSceneGraph()
1538 {
1539   DALI_ASSERT_DEBUG(mParent != NULL);
1540
1541   // Reparent Node in next Update
1542   ConnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetParent()->GetNode(), GetNode());
1543
1544   // Request relayout on all actors that are added to the scenegraph
1545   RelayoutRequest();
1546
1547   // Notification for Object::Observers
1548   OnSceneObjectAdd();
1549 }
1550
1551 void Actor::NotifyStageConnection()
1552 {
1553   // Actors can be removed (in a callback), before the on-stage stage is reported.
1554   // The actor may also have been reparented, in which case mOnSceneSignalled will be true.
1555   if(OnScene() && !mOnSceneSignalled)
1556   {
1557     // Notification for external (CustomActor) derived classes
1558     OnSceneConnectionExternal(mDepth);
1559
1560     if(!mOnSceneSignal.Empty())
1561     {
1562       Dali::Actor handle(this);
1563       mOnSceneSignal.Emit(handle);
1564     }
1565
1566     // Guard against Remove during callbacks
1567     if(OnScene())
1568     {
1569       mOnSceneSignalled = true; // signal required next time Actor is removed
1570     }
1571   }
1572 }
1573
1574 void Actor::DisconnectFromStage()
1575 {
1576   // This container is used instead of walking the Actor hierachy.
1577   // It protects us when the Actor hierachy is modified during OnSceneDisconnectionExternal callbacks.
1578   ActorContainer disconnectionList;
1579
1580   if(mScene)
1581   {
1582     mScene->RequestRebuildDepthTree();
1583   }
1584
1585   // This stage is atomic i.e. not interrupted by user callbacks
1586   RecursiveDisconnectFromStage(disconnectionList);
1587
1588   // Notify applications about the newly disconnected actors.
1589   for(const auto& actor : disconnectionList)
1590   {
1591     actor->NotifyStageDisconnection();
1592   }
1593 }
1594
1595 void Actor::RecursiveDisconnectFromStage(ActorContainer& disconnectionList)
1596 {
1597   // need to change state first so that internals relying on IsOnScene() inside OnSceneDisconnectionInternal() get the correct value
1598   mIsOnScene = false;
1599
1600   // Recursively disconnect children
1601   if(GetChildCount() > 0)
1602   {
1603     for(const auto& child : mParentImpl.GetChildrenInternal())
1604     {
1605       child->RecursiveDisconnectFromStage(disconnectionList);
1606     }
1607   }
1608
1609   // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
1610   disconnectionList.push_back(ActorPtr(this));
1611
1612   // Notification for internal derived classes
1613   OnSceneDisconnectionInternal();
1614
1615   DisconnectFromSceneGraph();
1616 }
1617
1618 /**
1619  * This method is called by an actor or its parent, before a node removal message is sent.
1620  * This is recursive; the child calls DisconnectFromStage() for its children.
1621  */
1622 void Actor::DisconnectFromSceneGraph()
1623 {
1624   // Notification for Object::Observers
1625   OnSceneObjectRemove();
1626 }
1627
1628 void Actor::NotifyStageDisconnection()
1629 {
1630   // Actors can be added (in a callback), before the off-stage state is reported.
1631   // Also if the actor was added & removed before mOnSceneSignalled was set, then we don't notify here.
1632   // only do this step if there is a stage, i.e. Core is not being shut down
1633   if(EventThreadServices::IsCoreRunning() && !OnScene() && mOnSceneSignalled)
1634   {
1635     // Notification for external (CustomeActor) derived classes
1636     OnSceneDisconnectionExternal();
1637
1638     if(!mOffSceneSignal.Empty())
1639     {
1640       Dali::Actor handle(this);
1641       mOffSceneSignal.Emit(handle);
1642     }
1643
1644     // Guard against Add during callbacks
1645     if(!OnScene())
1646     {
1647       mOnSceneSignalled = false; // signal required next time Actor is added
1648     }
1649
1650     SetTransparent(false);
1651   }
1652 }
1653
1654 bool Actor::IsNodeConnected() const
1655 {
1656   bool connected(false);
1657
1658   if(OnScene())
1659   {
1660     if(IsRoot() || GetNode().GetParent())
1661     {
1662       connected = true;
1663     }
1664   }
1665
1666   return connected;
1667 }
1668
1669 // This method initiates traversal of the actor tree using depth-first
1670 // traversal to set a depth index based on traversal order. It sends a
1671 // single message to update manager to update all the actor's nodes in
1672 // this tree with the depth index. The sceneGraphNodeDepths vector's
1673 // elements are ordered by depth, and could be used to reduce sorting
1674 // in the update thread.
1675 void Actor::RebuildDepthTree()
1676 {
1677   DALI_LOG_TIMER_START(depthTimer);
1678
1679   // Vector of scene-graph nodes and their depths to send to UpdateManager
1680   // in a single message
1681   OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths(new SceneGraph::NodeDepths());
1682
1683   int32_t depthIndex = 1;
1684   DepthTraverseActorTree(sceneGraphNodeDepths, depthIndex);
1685
1686   SetDepthIndicesMessage(GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths);
1687   DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
1688 }
1689
1690 void Actor::DepthTraverseActorTree(OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int32_t& depthIndex)
1691 {
1692   mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
1693   sceneGraphNodeDepths->Add(const_cast<SceneGraph::Node*>(&GetNode()), mSortedDepth);
1694
1695   // Create/add to children of this node
1696   if(GetChildCount() > 0)
1697   {
1698     for(const auto& child : mParentImpl.GetChildrenInternal())
1699     {
1700       Actor* childActor = child.Get();
1701       ++depthIndex;
1702       childActor->DepthTraverseActorTree(sceneGraphNodeDepths, depthIndex);
1703     }
1704   }
1705 }
1706
1707 void Actor::SetDefaultProperty(Property::Index index, const Property::Value& property)
1708 {
1709   PropertyHandler::SetDefaultProperty(*this, index, property);
1710 }
1711
1712 // TODO: This method needs to be removed
1713 void Actor::SetSceneGraphProperty(Property::Index index, const PropertyMetadata& entry, const Property::Value& value)
1714 {
1715   PropertyHandler::SetSceneGraphProperty(index, entry, value, GetEventThreadServices(), GetNode());
1716 }
1717
1718 Property::Value Actor::GetDefaultProperty(Property::Index index) const
1719 {
1720   Property::Value value;
1721
1722   if(!GetCachedPropertyValue(index, value))
1723   {
1724     // If property value is not stored in the event-side, then it must be a scene-graph only property
1725     GetCurrentPropertyValue(index, value);
1726   }
1727
1728   return value;
1729 }
1730
1731 Property::Value Actor::GetDefaultPropertyCurrentValue(Property::Index index) const
1732 {
1733   Property::Value value;
1734
1735   if(!GetCurrentPropertyValue(index, value))
1736   {
1737     // If unable to retrieve scene-graph property value, then it must be an event-side only property
1738     GetCachedPropertyValue(index, value);
1739   }
1740
1741   return value;
1742 }
1743
1744 void Actor::OnNotifyDefaultPropertyAnimation(Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType)
1745 {
1746   PropertyHandler::OnNotifyDefaultPropertyAnimation(*this, animation, index, value, animationType);
1747 }
1748
1749 const PropertyBase* Actor::GetSceneObjectAnimatableProperty(Property::Index index) const
1750 {
1751   const PropertyBase* property = PropertyHandler::GetSceneObjectAnimatableProperty(index, GetNode());
1752   if(!property)
1753   {
1754     // not our property, ask base
1755     property = Object::GetSceneObjectAnimatableProperty(index);
1756   }
1757
1758   return property;
1759 }
1760
1761 const PropertyInputImpl* Actor::GetSceneObjectInputProperty(Property::Index index) const
1762 {
1763   const PropertyInputImpl* property = PropertyHandler::GetSceneObjectInputProperty(index, GetNode());
1764   if(!property)
1765   {
1766     // reuse animatable property getter as animatable properties are inputs as well
1767     // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
1768     property = GetSceneObjectAnimatableProperty(index);
1769   }
1770
1771   return property;
1772 }
1773
1774 int32_t Actor::GetPropertyComponentIndex(Property::Index index) const
1775 {
1776   int32_t componentIndex = PropertyHandler::GetPropertyComponentIndex(index);
1777   if(Property::INVALID_COMPONENT_INDEX == componentIndex)
1778   {
1779     // ask base
1780     componentIndex = Object::GetPropertyComponentIndex(index);
1781   }
1782
1783   return componentIndex;
1784 }
1785
1786 const SceneGraph::Node& Actor::GetNode() const
1787 {
1788   return *static_cast<const SceneGraph::Node*>(mUpdateObject);
1789 }
1790
1791 void Actor::Raise()
1792 {
1793   if(mParent)
1794   {
1795     mParent->RaiseChild(*this);
1796   }
1797   else
1798   {
1799     DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1800   }
1801 }
1802
1803 void Actor::Lower()
1804 {
1805   if(mParent)
1806   {
1807     mParent->LowerChild(*this);
1808   }
1809   else
1810   {
1811     DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1812   }
1813 }
1814
1815 void Actor::RaiseToTop()
1816 {
1817   if(mParent)
1818   {
1819     mParent->RaiseChildToTop(*this);
1820   }
1821   else
1822   {
1823     DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1824   }
1825 }
1826
1827 void Actor::LowerToBottom()
1828 {
1829   if(mParent)
1830   {
1831     mParent->LowerChildToBottom(*this);
1832   }
1833   else
1834   {
1835     DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1836   }
1837 }
1838
1839 void Actor::RaiseAbove(Internal::Actor& target)
1840 {
1841   if(mParent)
1842   {
1843     mParent->RaiseChildAbove(*this, target);
1844   }
1845   else
1846   {
1847     DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1848   }
1849 }
1850
1851 void Actor::LowerBelow(Internal::Actor& target)
1852 {
1853   if(mParent)
1854   {
1855     mParent->LowerChildBelow(*this, target);
1856   }
1857   else
1858   {
1859     DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1860   }
1861 }
1862
1863 void Actor::SetParent(ActorParent* parent)
1864 {
1865   if(parent)
1866   {
1867     DALI_ASSERT_ALWAYS(!mParent && "Actor cannot have 2 parents");
1868
1869     mParent            = parent;
1870     Actor* parentActor = static_cast<Actor*>(parent);
1871     mScene             = parentActor->mScene;
1872
1873     if(EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
1874        parentActor->OnScene())
1875     {
1876       // Instruct each actor to create a corresponding node in the scene graph
1877       ConnectToScene(parentActor->GetHierarchyDepth());
1878     }
1879
1880     // Resolve the name and index for the child properties if any
1881     ResolveChildProperties();
1882   }
1883   else // parent being set to NULL
1884   {
1885     DALI_ASSERT_ALWAYS(mParent != nullptr && "Actor should have a parent");
1886
1887     mParent = nullptr;
1888
1889     if(EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
1890        OnScene())
1891     {
1892       // Disconnect the Node & its children from the scene-graph.
1893       DisconnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
1894
1895       // Instruct each actor to discard pointers to the scene-graph
1896       DisconnectFromStage();
1897     }
1898
1899     mScene = nullptr;
1900   }
1901 }
1902
1903 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */)
1904 {
1905   bool   done  = false;
1906   Actor* actor = dynamic_cast<Actor*>(object);
1907
1908   if(actor)
1909   {
1910     std::string_view name(actionName);
1911     if(name == ACTION_SHOW)
1912     {
1913       actor->SetVisible(true);
1914       done = true;
1915     }
1916     else if(name == ACTION_HIDE)
1917     {
1918       actor->SetVisible(false);
1919       done = true;
1920     }
1921   }
1922
1923   return done;
1924 }
1925
1926 Rect<> Actor::CalculateScreenExtents() const
1927 {
1928   auto    screenPosition    = GetCurrentScreenPosition();
1929   Vector3 size              = GetCurrentSize() * GetCurrentWorldScale();
1930   Vector3 anchorPointOffSet = size * (mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT);
1931   Vector2 position          = Vector2(screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y);
1932   return {position.x, position.y, size.x, size.y};
1933 }
1934
1935 bool Actor::GetCachedPropertyValue(Property::Index index, Property::Value& value) const
1936 {
1937   return PropertyHandler::GetCachedPropertyValue(*this, index, value);
1938 }
1939
1940 bool Actor::GetCurrentPropertyValue(Property::Index index, Property::Value& value) const
1941 {
1942   return PropertyHandler::GetCurrentPropertyValue(*this, index, value);
1943 }
1944
1945 Actor::Relayouter& Actor::EnsureRelayouter()
1946 {
1947   // Assign relayouter
1948   if(!mRelayoutData)
1949   {
1950     mRelayoutData = new Relayouter();
1951   }
1952
1953   return *mRelayoutData;
1954 }
1955
1956 bool Actor::RelayoutDependentOnParent(Dimension::Type dimension)
1957 {
1958   // Check if actor is dependent on parent
1959   for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
1960   {
1961     if((dimension & (1 << i)))
1962     {
1963       const ResizePolicy::Type resizePolicy = GetResizePolicy(static_cast<Dimension::Type>(1 << i));
1964       if(resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT)
1965       {
1966         return true;
1967       }
1968     }
1969   }
1970
1971   return false;
1972 }
1973
1974 bool Actor::RelayoutDependentOnChildren(Dimension::Type dimension)
1975 {
1976   // Check if actor is dependent on children
1977   for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
1978   {
1979     if((dimension & (1 << i)))
1980     {
1981       const ResizePolicy::Type resizePolicy = GetResizePolicy(static_cast<Dimension::Type>(1 << i));
1982       switch(resizePolicy)
1983       {
1984         case ResizePolicy::FIT_TO_CHILDREN:
1985         case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
1986         {
1987           return true;
1988         }
1989
1990         default:
1991         {
1992           break;
1993         }
1994       }
1995     }
1996   }
1997
1998   return false;
1999 }
2000
2001 bool Actor::RelayoutDependentOnChildrenBase(Dimension::Type dimension)
2002 {
2003   return Actor::RelayoutDependentOnChildren(dimension);
2004 }
2005
2006 bool Actor::RelayoutDependentOnDimension(Dimension::Type dimension, Dimension::Type dependentDimension)
2007 {
2008   // Check each possible dimension and see if it is dependent on the input one
2009   for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
2010   {
2011     if(dimension & (1 << i))
2012     {
2013       return mRelayoutData->resizePolicies[i] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[i] == dependentDimension;
2014     }
2015   }
2016
2017   return false;
2018 }
2019
2020 void Actor::SetNegotiatedDimension(float negotiatedDimension, Dimension::Type dimension)
2021 {
2022   for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
2023   {
2024     if(dimension & (1 << i))
2025     {
2026       mRelayoutData->negotiatedDimensions[i] = negotiatedDimension;
2027     }
2028   }
2029 }
2030
2031 float Actor::GetNegotiatedDimension(Dimension::Type dimension) const
2032 {
2033   // If more than one dimension is requested, just return the first one found
2034   for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
2035   {
2036     if((dimension & (1 << i)))
2037     {
2038       return mRelayoutData->negotiatedDimensions[i];
2039     }
2040   }
2041
2042   return 0.0f; // Default
2043 }
2044
2045 void Actor::SetPadding(const Vector2& padding, Dimension::Type dimension)
2046 {
2047   EnsureRelayouter().SetPadding(padding, dimension);
2048 }
2049
2050 Vector2 Actor::GetPadding(Dimension::Type dimension) const
2051 {
2052   if(mRelayoutData)
2053   {
2054     // If more than one dimension is requested, just return the first one found
2055     for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
2056     {
2057       if((dimension & (1 << i)))
2058       {
2059         return mRelayoutData->dimensionPadding[i];
2060       }
2061     }
2062   }
2063
2064   return Relayouter::DEFAULT_DIMENSION_PADDING;
2065 }
2066
2067 void Actor::SetLayoutNegotiated(bool negotiated, Dimension::Type dimension)
2068 {
2069   EnsureRelayouter().SetLayoutNegotiated(negotiated, dimension);
2070 }
2071
2072 bool Actor::IsLayoutNegotiated(Dimension::Type dimension) const
2073 {
2074   return mRelayoutData && mRelayoutData->IsLayoutNegotiated(dimension);
2075 }
2076
2077 float Actor::GetHeightForWidthBase(float width)
2078 {
2079   float height = 0.0f;
2080
2081   const Vector3 naturalSize = GetNaturalSize();
2082   if(naturalSize.width > 0.0f)
2083   {
2084     height = naturalSize.height * width / naturalSize.width;
2085   }
2086   else // we treat 0 as 1:1 aspect ratio
2087   {
2088     height = width;
2089   }
2090
2091   return height;
2092 }
2093
2094 float Actor::GetWidthForHeightBase(float height)
2095 {
2096   float width = 0.0f;
2097
2098   const Vector3 naturalSize = GetNaturalSize();
2099   if(naturalSize.height > 0.0f)
2100   {
2101     width = naturalSize.width * height / naturalSize.height;
2102   }
2103   else // we treat 0 as 1:1 aspect ratio
2104   {
2105     width = height;
2106   }
2107
2108   return width;
2109 }
2110
2111 float Actor::CalculateChildSizeBase(const Dali::Actor& child, Dimension::Type dimension)
2112 {
2113   // Fill to parent, taking size mode factor into account
2114   switch(child.GetResizePolicy(dimension))
2115   {
2116     case ResizePolicy::FILL_TO_PARENT:
2117     {
2118       return GetLatestSize(dimension);
2119     }
2120
2121     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
2122     {
2123       return GetLatestSize(dimension) * GetDimensionValue(child.GetProperty<Vector3>(Dali::Actor::Property::SIZE_MODE_FACTOR), dimension);
2124     }
2125
2126     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
2127     {
2128       return GetLatestSize(dimension) + GetDimensionValue(child.GetProperty<Vector3>(Dali::Actor::Property::SIZE_MODE_FACTOR), dimension);
2129     }
2130
2131     default:
2132     {
2133       return GetLatestSize(dimension);
2134     }
2135   }
2136 }
2137
2138 float Actor::CalculateChildSize(const Dali::Actor& child, Dimension::Type dimension)
2139 {
2140   // Can be overridden in derived class
2141   return CalculateChildSizeBase(child, dimension);
2142 }
2143
2144 float Actor::GetHeightForWidth(float width)
2145 {
2146   // Can be overridden in derived class
2147   return GetHeightForWidthBase(width);
2148 }
2149
2150 float Actor::GetWidthForHeight(float height)
2151 {
2152   // Can be overridden in derived class
2153   return GetWidthForHeightBase(height);
2154 }
2155
2156 float Actor::GetLatestSize(Dimension::Type dimension) const
2157 {
2158   return IsLayoutNegotiated(dimension) ? GetNegotiatedDimension(dimension) : GetSize(dimension);
2159 }
2160
2161 float Actor::GetRelayoutSize(Dimension::Type dimension) const
2162 {
2163   Vector2 padding = GetPadding(dimension);
2164
2165   return GetLatestSize(dimension) + padding.x + padding.y;
2166 }
2167
2168 float Actor::NegotiateFromParent(Dimension::Type dimension)
2169 {
2170   Actor* parent = GetParent();
2171   if(parent)
2172   {
2173     Vector2 padding(GetPadding(dimension));
2174     Vector2 parentPadding(parent->GetPadding(dimension));
2175     return parent->CalculateChildSize(Dali::Actor(this), dimension) - parentPadding.x - parentPadding.y - padding.x - padding.y;
2176   }
2177
2178   return 0.0f;
2179 }
2180
2181 float Actor::NegotiateFromChildren(Dimension::Type dimension)
2182 {
2183   float maxDimensionPoint = 0.0f;
2184
2185   for(uint32_t i = 0, count = GetChildCount(); i < count; ++i)
2186   {
2187     ActorPtr child = GetChildAt(i);
2188
2189     if(!child->RelayoutDependentOnParent(dimension))
2190     {
2191       // Calculate the min and max points that the children range across
2192       float childPosition = GetDimensionValue(child->GetTargetPosition(), dimension);
2193       float dimensionSize = child->GetRelayoutSize(dimension);
2194       maxDimensionPoint   = std::max(maxDimensionPoint, childPosition + dimensionSize);
2195     }
2196   }
2197
2198   return maxDimensionPoint;
2199 }
2200
2201 float Actor::GetSize(Dimension::Type dimension) const
2202 {
2203   return GetDimensionValue(mTargetSize, dimension);
2204 }
2205
2206 float Actor::GetNaturalSize(Dimension::Type dimension) const
2207 {
2208   return GetDimensionValue(GetNaturalSize(), dimension);
2209 }
2210
2211 float Actor::CalculateSize(Dimension::Type dimension, const Vector2& maximumSize)
2212 {
2213   switch(GetResizePolicy(dimension))
2214   {
2215     case ResizePolicy::USE_NATURAL_SIZE:
2216     {
2217       return GetNaturalSize(dimension);
2218     }
2219
2220     case ResizePolicy::FIXED:
2221     {
2222       return GetDimensionValue(GetPreferredSize(), dimension);
2223     }
2224
2225     case ResizePolicy::USE_ASSIGNED_SIZE:
2226     {
2227       return GetDimensionValue(maximumSize, dimension);
2228     }
2229
2230     case ResizePolicy::FILL_TO_PARENT:
2231     case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
2232     case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
2233     {
2234       return NegotiateFromParent(dimension);
2235     }
2236
2237     case ResizePolicy::FIT_TO_CHILDREN:
2238     {
2239       return NegotiateFromChildren(dimension);
2240     }
2241
2242     case ResizePolicy::DIMENSION_DEPENDENCY:
2243     {
2244       const Dimension::Type dimensionDependency = GetDimensionDependency(dimension);
2245
2246       // Custom rules
2247       if(dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT)
2248       {
2249         return GetWidthForHeight(GetNegotiatedDimension(Dimension::HEIGHT));
2250       }
2251
2252       if(dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH)
2253       {
2254         return GetHeightForWidth(GetNegotiatedDimension(Dimension::WIDTH));
2255       }
2256
2257       break;
2258     }
2259
2260     default:
2261     {
2262       break;
2263     }
2264   }
2265
2266   return 0.0f; // Default
2267 }
2268
2269 Vector2 Actor::ApplySizeSetPolicy(const Vector2& size)
2270 {
2271   return mRelayoutData->ApplySizeSetPolicy(*this, size);
2272 }
2273
2274 void Actor::SetNegotiatedSize(RelayoutContainer& container)
2275 {
2276   // Do the set actor size
2277   Vector2 negotiatedSize(GetLatestSize(Dimension::WIDTH), GetLatestSize(Dimension::HEIGHT));
2278
2279   // Adjust for size set policy
2280   negotiatedSize = ApplySizeSetPolicy(negotiatedSize);
2281
2282   // Lock the flag to stop recursive relayouts on set size
2283   mRelayoutData->insideRelayout = true;
2284   SetSize(negotiatedSize);
2285   mRelayoutData->insideRelayout = false;
2286
2287   // Clear flags for all dimensions
2288   SetLayoutDirty(false);
2289
2290   // Give deriving classes a chance to respond
2291   OnRelayout(negotiatedSize, container);
2292
2293   if(!mOnRelayoutSignal.Empty())
2294   {
2295     Dali::Actor handle(this);
2296     mOnRelayoutSignal.Emit(handle);
2297   }
2298 }
2299
2300 void Actor::NegotiateSize(const Vector2& allocatedSize, RelayoutContainer& container)
2301 {
2302   Relayouter::NegotiateSize(*this, allocatedSize, container);
2303 }
2304
2305 void Actor::SetUseAssignedSize(bool use, Dimension::Type dimension)
2306 {
2307   if(mRelayoutData)
2308   {
2309     mRelayoutData->SetUseAssignedSize(use, dimension);
2310   }
2311 }
2312
2313 bool Actor::GetUseAssignedSize(Dimension::Type dimension) const
2314 {
2315   return mRelayoutData && mRelayoutData->GetUseAssignedSize(dimension);
2316 }
2317
2318 void Actor::RelayoutRequest(Dimension::Type dimension)
2319 {
2320   Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
2321   if(relayoutController)
2322   {
2323     Dali::Actor self(this);
2324     relayoutController->RequestRelayout(self, dimension);
2325   }
2326 }
2327
2328 void Actor::SetPreferredSize(const Vector2& size)
2329 {
2330   EnsureRelayouter().SetPreferredSize(*this, size);
2331 }
2332
2333 Vector2 Actor::GetPreferredSize() const
2334 {
2335   if(mRelayoutData)
2336   {
2337     return Vector2(mRelayoutData->preferredSize);
2338   }
2339
2340   return Relayouter::DEFAULT_PREFERRED_SIZE;
2341 }
2342
2343 void Actor::SetMinimumSize(float size, Dimension::Type dimension)
2344 {
2345   EnsureRelayouter().SetMinimumSize(size, dimension);
2346   RelayoutRequest();
2347 }
2348
2349 float Actor::GetMinimumSize(Dimension::Type dimension) const
2350 {
2351   if(mRelayoutData)
2352   {
2353     return mRelayoutData->GetMinimumSize(dimension);
2354   }
2355
2356   return 0.0f; // Default
2357 }
2358
2359 void Actor::SetMaximumSize(float size, Dimension::Type dimension)
2360 {
2361   EnsureRelayouter().SetMaximumSize(size, dimension);
2362   RelayoutRequest();
2363 }
2364
2365 float Actor::GetMaximumSize(Dimension::Type dimension) const
2366 {
2367   if(mRelayoutData)
2368   {
2369     return mRelayoutData->GetMaximumSize(dimension);
2370   }
2371
2372   return FLT_MAX; // Default
2373 }
2374
2375 void Actor::SetVisibleInternal(bool visible, SendMessage::Type sendMessage)
2376 {
2377   if(mVisible != visible)
2378   {
2379     if(sendMessage == SendMessage::TRUE)
2380     {
2381       // node is being used in a separate thread; queue a message to set the value & base value
2382       SceneGraph::NodePropertyMessage<bool>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible);
2383
2384       RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
2385     }
2386
2387     mVisible = visible;
2388
2389     // Emit the signal on this actor and all its children
2390     EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::SELF);
2391   }
2392 }
2393
2394 void Actor::SetSiblingOrderOfChild(Actor& child, uint32_t order)
2395 {
2396   mParentImpl.SetSiblingOrderOfChild(child, order);
2397 }
2398
2399 uint32_t Actor::GetSiblingOrderOfChild(const Actor& child) const
2400 {
2401   return mParentImpl.GetSiblingOrderOfChild(child);
2402 }
2403
2404 void Actor::RaiseChild(Actor& child)
2405 {
2406   mParentImpl.RaiseChild(child);
2407 }
2408
2409 void Actor::LowerChild(Actor& child)
2410 {
2411   mParentImpl.LowerChild(child);
2412 }
2413
2414 void Actor::RaiseChildToTop(Actor& child)
2415 {
2416   mParentImpl.RaiseChildToTop(child);
2417 }
2418
2419 void Actor::LowerChildToBottom(Actor& child)
2420 {
2421   mParentImpl.LowerChildToBottom(child);
2422 }
2423
2424 void Actor::RaiseChildAbove(Actor& child, Actor& target)
2425 {
2426   mParentImpl.RaiseChildAbove(child, target);
2427 }
2428
2429 void Actor::LowerChildBelow(Actor& child, Actor& target)
2430 {
2431   mParentImpl.LowerChildBelow(child, target);
2432 }
2433
2434 void Actor::SetInheritLayoutDirection(bool inherit)
2435 {
2436   if(mInheritLayoutDirection != inherit)
2437   {
2438     mInheritLayoutDirection = inherit;
2439
2440     if(inherit && mParent)
2441     {
2442       InheritLayoutDirectionRecursively(GetParent()->mLayoutDirection);
2443     }
2444   }
2445 }
2446
2447 void Actor::InheritLayoutDirectionRecursively(Dali::LayoutDirection::Type direction, bool set)
2448 {
2449   if(mInheritLayoutDirection || set)
2450   {
2451     if(mLayoutDirection != direction)
2452     {
2453       mLayoutDirection = direction;
2454       EmitLayoutDirectionChangedSignal(direction);
2455       RelayoutRequest();
2456     }
2457
2458     if(GetChildCount() > 0)
2459     {
2460       for(const auto& child : mParentImpl.GetChildrenInternal())
2461       {
2462         child->InheritLayoutDirectionRecursively(direction);
2463       }
2464     }
2465   }
2466 }
2467
2468 void Actor::SetUpdateSizeHint(const Vector2& updateSizeHint)
2469 {
2470   // node is being used in a separate thread; queue a message to set the value & base value
2471   SceneGraph::NodePropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mUpdateSizeHint, &AnimatableProperty<Vector3>::Bake, Vector3(updateSizeHint.width, updateSizeHint.height, 0.f));
2472 }
2473
2474 void Actor::EmitVisibilityChangedSignalRecursively(bool                               visible,
2475                                                    DevelActor::VisibilityChange::Type type)
2476 {
2477   EmitVisibilityChangedSignal(visible, type);
2478
2479   if(GetChildCount() > 0)
2480   {
2481     for(auto& child : mParentImpl.GetChildrenInternal())
2482     {
2483       child->EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::PARENT);
2484     }
2485   }
2486 }
2487
2488 } // namespace Internal
2489
2490 } // namespace Dali