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