[dali_2.3.24] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / actor-impl.cpp
1 /*
2  * Copyright (c) 2023 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 <cmath>
24
25 // INTERNAL INCLUDES
26 #include <dali/public-api/common/constants.h>
27 #include <dali/public-api/common/dali-common.h>
28 #include <dali/public-api/math/radian.h>
29 #include <dali/public-api/math/vector2.h>
30 #include <dali/public-api/math/vector3.h>
31 #include <dali/public-api/object/type-registry.h>
32
33 #include <dali/devel-api/actors/actor-devel.h>
34 #include <dali/devel-api/common/capabilities.h>
35
36 #include <dali/integration-api/debug.h>
37 #include <dali/integration-api/events/touch-integ.h>
38
39 #include <dali/internal/event/actors/actor-coords.h>
40 #include <dali/internal/event/actors/actor-parent.h>
41 #include <dali/internal/event/actors/actor-property-handler.h>
42 #include <dali/internal/event/common/event-thread-services.h>
43 #include <dali/internal/event/common/property-helper.h>
44 #include <dali/internal/event/common/scene-impl.h>
45 #include <dali/internal/event/common/stage-impl.h>
46 #include <dali/internal/event/common/thread-local-storage.h>
47 #include <dali/internal/event/common/type-info-impl.h>
48 #include <dali/internal/event/events/actor-gesture-data.h>
49 #include <dali/internal/event/render-tasks/render-task-impl.h>
50 #include <dali/internal/event/rendering/renderer-impl.h>
51 #include <dali/internal/update/manager/update-manager.h>
52 #include <dali/internal/update/nodes/node-messages.h>
53 #include <dali/public-api/size-negotiation/relayout-container.h>
54
55 using Dali::Internal::SceneGraph::AnimatableProperty;
56 using Dali::Internal::SceneGraph::Node;
57 using Dali::Internal::SceneGraph::PropertyBase;
58
59 #if defined(DEBUG_ENABLED)
60 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER");
61 #endif
62
63 namespace Dali
64 {
65 namespace Internal
66 {
67 namespace // unnamed namespace
68 {
69 // Properties
70
71 /**
72  * We want to discourage the use of property strings (minimize string comparisons),
73  * particularly for the default properties.
74  *              Name                  Type   writable animatable constraint-input  enum for index-checking
75  */
76 DALI_PROPERTY_TABLE_BEGIN
77 DALI_PROPERTY("parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN)
78 DALI_PROPERTY("parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X)
79 DALI_PROPERTY("parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y)
80 DALI_PROPERTY("parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z)
81 DALI_PROPERTY("anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT)
82 DALI_PROPERTY("anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X)
83 DALI_PROPERTY("anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y)
84 DALI_PROPERTY("anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z)
85 DALI_PROPERTY("size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE)
86 DALI_PROPERTY("sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH)
87 DALI_PROPERTY("sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT)
88 DALI_PROPERTY("sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH)
89 DALI_PROPERTY("position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION)
90 DALI_PROPERTY("positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X)
91 DALI_PROPERTY("positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y)
92 DALI_PROPERTY("positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z)
93 DALI_PROPERTY("worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION)
94 DALI_PROPERTY("worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X)
95 DALI_PROPERTY("worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y)
96 DALI_PROPERTY("worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z)
97 DALI_PROPERTY("orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION)
98 DALI_PROPERTY("worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION)
99 DALI_PROPERTY("scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE)
100 DALI_PROPERTY("scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X)
101 DALI_PROPERTY("scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y)
102 DALI_PROPERTY("scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z)
103 DALI_PROPERTY("worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE)
104 DALI_PROPERTY("visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE)
105 DALI_PROPERTY("color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR)
106 DALI_PROPERTY("colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED)
107 DALI_PROPERTY("colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN)
108 DALI_PROPERTY("colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE)
109 DALI_PROPERTY("colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA)
110 DALI_PROPERTY("worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR)
111 DALI_PROPERTY("worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX)
112 DALI_PROPERTY("name", STRING, true, false, false, Dali::Actor::Property::NAME)
113 DALI_PROPERTY("sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE)
114 DALI_PROPERTY("leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED)
115 DALI_PROPERTY("inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION)
116 DALI_PROPERTY("inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE)
117 DALI_PROPERTY("colorMode", INTEGER, true, false, false, Dali::Actor::Property::COLOR_MODE)
118 DALI_PROPERTY("drawMode", INTEGER, true, false, false, Dali::Actor::Property::DRAW_MODE)
119 DALI_PROPERTY("sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR)
120 DALI_PROPERTY("widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY)
121 DALI_PROPERTY("heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY)
122 DALI_PROPERTY("sizeScalePolicy", INTEGER, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY)
123 DALI_PROPERTY("widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT)
124 DALI_PROPERTY("heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH)
125 DALI_PROPERTY("padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING)
126 DALI_PROPERTY("minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE)
127 DALI_PROPERTY("maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE)
128 DALI_PROPERTY("inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION)
129 DALI_PROPERTY("clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE)
130 DALI_PROPERTY("layoutDirection", STRING, true, false, false, Dali::Actor::Property::LAYOUT_DIRECTION)
131 DALI_PROPERTY("inheritLayoutDirection", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION)
132 DALI_PROPERTY("opacity", FLOAT, true, true, true, Dali::Actor::Property::OPACITY)
133 DALI_PROPERTY("screenPosition", VECTOR2, false, false, false, Dali::Actor::Property::SCREEN_POSITION)
134 DALI_PROPERTY("positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::Actor::Property::POSITION_USES_ANCHOR_POINT)
135 DALI_PROPERTY("culled", BOOLEAN, false, false, true, Dali::Actor::Property::CULLED)
136 DALI_PROPERTY("id", INTEGER, false, false, false, Dali::Actor::Property::ID)
137 DALI_PROPERTY("hierarchyDepth", INTEGER, false, false, false, Dali::Actor::Property::HIERARCHY_DEPTH)
138 DALI_PROPERTY("isRoot", BOOLEAN, false, false, false, Dali::Actor::Property::IS_ROOT)
139 DALI_PROPERTY("isLayer", BOOLEAN, false, false, false, Dali::Actor::Property::IS_LAYER)
140 DALI_PROPERTY("connectedToScene", BOOLEAN, false, false, false, Dali::Actor::Property::CONNECTED_TO_SCENE)
141 DALI_PROPERTY("keyboardFocusable", BOOLEAN, true, false, false, Dali::Actor::Property::KEYBOARD_FOCUSABLE)
142 DALI_PROPERTY("updateAreaHint", VECTOR4, true, false, false, Dali::Actor::Property::UPDATE_AREA_HINT)
143 DALI_PROPERTY("siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER)
144 DALI_PROPERTY("captureAllTouchAfterStart", BOOLEAN, true, false, false, Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START)
145 DALI_PROPERTY("touchAreaOffset", RECTANGLE, true, false, false, Dali::DevelActor::Property::TOUCH_AREA_OFFSET)
146 DALI_PROPERTY("blendEquation", INTEGER, true, false, false, Dali::DevelActor::Property::BLEND_EQUATION)
147 DALI_PROPERTY("touchFocusable", BOOLEAN, true, false, false, Dali::DevelActor::Property::TOUCH_FOCUSABLE)
148 DALI_PROPERTY("keyboardFocusableChildren", BOOLEAN, true, false, false, Dali::DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN)
149 DALI_PROPERTY("userInteractionEnabled", BOOLEAN, true, false, false, Dali::DevelActor::Property::USER_INTERACTION_ENABLED)
150 DALI_PROPERTY("allowOnlyOwnTouch", BOOLEAN, true, false, false, Dali::DevelActor::Property::ALLOW_ONLY_OWN_TOUCH)
151 DALI_PROPERTY("useTextureUpdateArea", BOOLEAN, true, false, false, Dali::DevelActor::Property::USE_TEXTURE_UPDATE_AREA)
152 DALI_PROPERTY("dispatchTouchMotion", BOOLEAN, true, false, false, Dali::DevelActor::Property::DISPATCH_TOUCH_MOTION)
153 DALI_PROPERTY("dispatchHoverMotion", BOOLEAN, true, false, false, Dali::DevelActor::Property::DISPATCH_HOVER_MOTION)
154 DALI_PROPERTY_TABLE_END(DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties)
155
156 // Signals
157
158 static constexpr std::string_view SIGNAL_HOVERED                      = "hovered";
159 static constexpr std::string_view SIGNAL_WHEEL_EVENT                  = "wheelEvent";
160 static constexpr std::string_view SIGNAL_ON_SCENE                     = "onScene";
161 static constexpr std::string_view SIGNAL_OFF_SCENE                    = "offScene";
162 static constexpr std::string_view SIGNAL_ON_RELAYOUT                  = "onRelayout";
163 static constexpr std::string_view SIGNAL_TOUCHED                      = "touched";
164 static constexpr std::string_view SIGNAL_VISIBILITY_CHANGED           = "visibilityChanged";
165 static constexpr std::string_view SIGNAL_INHERITED_VISIBILITY_CHANGED = "inheritedVisibilityChanged";
166 static constexpr std::string_view SIGNAL_LAYOUT_DIRECTION_CHANGED     = "layoutDirectionChanged";
167 static constexpr std::string_view SIGNAL_CHILD_ADDED                  = "childAdded";
168 static constexpr std::string_view SIGNAL_CHILD_REMOVED                = "childRemoved";
169
170 // Actions
171
172 static constexpr std::string_view ACTION_SHOW = "show";
173 static constexpr std::string_view ACTION_HIDE = "hide";
174
175 BaseHandle CreateActor()
176 {
177   return Dali::Actor::New();
178 }
179
180 /**
181  * Connects a callback function with the object's signals.
182  * @param[in] object The object providing the signal.
183  * @param[in] tracker Used to disconnect the signal.
184  * @param[in] signalName The signal to connect to.
185  * @param[in] functor A newly allocated FunctorDelegate.
186  * @return True if the signal was connected.
187  * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
188  */
189 static bool DoConnectSignal(BaseObject*                 object,
190                             ConnectionTrackerInterface* tracker,
191                             const std::string&          signalName,
192                             FunctorDelegate*            functor)
193 {
194   bool   connected(true);
195   Actor* actor = static_cast<Actor*>(object); // TypeRegistry guarantees that this is the correct type.
196
197   std::string_view name(signalName);
198
199   if(name == SIGNAL_HOVERED)
200   {
201     actor->HoveredSignal().Connect(tracker, functor);
202   }
203   else if(signalName == SIGNAL_WHEEL_EVENT)
204   {
205     actor->WheelEventSignal().Connect(tracker, functor);
206   }
207   else if(name == SIGNAL_ON_SCENE)
208   {
209     actor->OnSceneSignal().Connect(tracker, functor);
210   }
211   else if(name == SIGNAL_OFF_SCENE)
212   {
213     actor->OffSceneSignal().Connect(tracker, functor);
214   }
215   else if(name == SIGNAL_ON_RELAYOUT)
216   {
217     actor->OnRelayoutSignal().Connect(tracker, functor);
218   }
219   else if(name == SIGNAL_TOUCHED)
220   {
221     actor->TouchedSignal().Connect(tracker, functor);
222   }
223   else if(name == SIGNAL_VISIBILITY_CHANGED)
224   {
225     actor->VisibilityChangedSignal().Connect(tracker, functor);
226   }
227   else if(name == SIGNAL_INHERITED_VISIBILITY_CHANGED)
228   {
229     actor->InheritedVisibilityChangedSignal().Connect(tracker, functor);
230   }
231   else if(name == SIGNAL_LAYOUT_DIRECTION_CHANGED)
232   {
233     actor->LayoutDirectionChangedSignal().Connect(tracker, functor);
234   }
235   else if(name == SIGNAL_CHILD_ADDED)
236   {
237     actor->ChildAddedSignal().Connect(tracker, functor);
238   }
239   else if(name == SIGNAL_CHILD_REMOVED)
240   {
241     actor->ChildRemovedSignal().Connect(tracker, functor);
242   }
243   else
244   {
245     // signalName does not match any signal
246     connected = false;
247   }
248
249   return connected;
250 }
251
252 /**
253  * Performs actions as requested using the action name.
254  * @param[in] object The object on which to perform the action.
255  * @param[in] actionName The action to perform.
256  * @param[in] attributes The attributes with which to perfrom this action.
257  * @return true if the action was done.
258  */
259 bool DoAction(BaseObject*          object,
260               const std::string&   actionName,
261               const Property::Map& attributes)
262 {
263   bool   done  = false;
264   Actor* actor = dynamic_cast<Actor*>(object);
265
266   if(actor)
267   {
268     std::string_view name(actionName);
269     if(name == ACTION_SHOW)
270     {
271       actor->SetVisible(true);
272       done = true;
273     }
274     else if(name == ACTION_HIDE)
275     {
276       actor->SetVisible(false);
277       done = true;
278     }
279   }
280
281   return done;
282 }
283
284 TypeRegistration mType(typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties);
285
286 SignalConnectorType signalConnector2(mType, std::string(SIGNAL_HOVERED), &DoConnectSignal);
287 SignalConnectorType signalConnector3(mType, std::string(SIGNAL_WHEEL_EVENT), &DoConnectSignal);
288 SignalConnectorType signalConnector4(mType, std::string(SIGNAL_ON_SCENE), &DoConnectSignal);
289 SignalConnectorType signalConnector5(mType, std::string(SIGNAL_OFF_SCENE), &DoConnectSignal);
290 SignalConnectorType signalConnector6(mType, std::string(SIGNAL_ON_RELAYOUT), &DoConnectSignal);
291 SignalConnectorType signalConnector7(mType, std::string(SIGNAL_TOUCHED), &DoConnectSignal);
292 SignalConnectorType signalConnector8(mType, std::string(SIGNAL_VISIBILITY_CHANGED), &DoConnectSignal);
293 SignalConnectorType signalConnector9(mType, std::string(SIGNAL_INHERITED_VISIBILITY_CHANGED), &DoConnectSignal);
294 SignalConnectorType signalConnector10(mType, std::string(SIGNAL_LAYOUT_DIRECTION_CHANGED), &DoConnectSignal);
295 SignalConnectorType signalConnector11(mType, std::string(SIGNAL_CHILD_ADDED), &DoConnectSignal);
296 SignalConnectorType signalConnector12(mType, std::string(SIGNAL_CHILD_REMOVED), &DoConnectSignal);
297
298 TypeAction a1(mType, std::string(ACTION_SHOW), &DoAction);
299 TypeAction a2(mType, std::string(ACTION_HIDE), &DoAction);
300
301 /// Helper for emitting a signal
302 template<typename Signal, typename Event>
303 bool EmitConsumingSignal(Actor& actor, Signal& signal, const Event& event)
304 {
305   bool consumed = false;
306
307   if(!signal.Empty())
308   {
309     Dali::Actor handle(&actor);
310     consumed = signal.Emit(handle, event);
311   }
312
313   return consumed;
314 }
315
316 /// Helper for emitting signals with multiple parameters
317 template<typename Signal, typename... Param>
318 void EmitSignal(Actor& actor, Signal& signal, Param... params)
319 {
320   if(!signal.Empty())
321   {
322     Dali::Actor handle(&actor);
323     signal.Emit(handle, params...);
324   }
325 }
326
327 using ActorParentSiblingOrderMethod           = void (ActorParent::*)(Actor&);
328 using ActorParentSiblingOrderMethodWithTarget = void (ActorParent::*)(Actor&, Actor&);
329
330 /// Helper to check and call actor sibling methods in ActorParent
331 void CheckParentAndCall(ActorParent* parent, Actor& actor, ActorParentSiblingOrderMethod memberFunction)
332 {
333   if(parent)
334   {
335     (parent->*memberFunction)(actor);
336   }
337   else
338   {
339     DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
340   }
341 }
342
343 /// Helper to check and call actor sibling methods with a target parameter in ActorParent
344 void CheckParentAndCall(ActorParent* parent, Actor& actor, Actor& target, ActorParentSiblingOrderMethodWithTarget memberFunction)
345 {
346   if(parent)
347   {
348     (parent->*memberFunction)(actor, target);
349   }
350   else
351   {
352     DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
353   }
354 }
355
356 } // unnamed namespace
357
358 ActorPtr Actor::New()
359 {
360   // pass a reference to actor, actor does not own its node
361   ActorPtr actor(new Actor(BASIC, *CreateNode()));
362
363   // Second-phase construction
364   actor->Initialize();
365
366   return actor;
367 }
368
369 const SceneGraph::Node* Actor::CreateNode()
370 {
371   // create node. Nodes are owned by the update manager
372   SceneGraph::Node*              node = SceneGraph::Node::New();
373   OwnerPointer<SceneGraph::Node> transferOwnership(node);
374   Internal::ThreadLocalStorage*  tls = Internal::ThreadLocalStorage::GetInternal();
375
376   DALI_ASSERT_ALWAYS(tls && "ThreadLocalStorage is null");
377
378   AddNodeMessage(tls->GetUpdateManager(), transferOwnership);
379
380   return node;
381 }
382
383 void Actor::SetName(std::string_view name)
384 {
385   mName = ConstString(name);
386
387   // ATTENTION: string for debug purposes is not thread safe.
388   DALI_LOG_SET_OBJECT_STRING(const_cast<SceneGraph::Node*>(&GetNode()), mName.GetCString());
389 }
390
391 uint32_t Actor::GetId() const
392 {
393   return GetNode().GetId();
394 }
395
396 Dali::Layer Actor::GetLayer()
397 {
398   Dali::Layer layer;
399
400   // Short-circuit for Layer derived actors
401   if(mIsLayer)
402   {
403     layer = Dali::Layer(static_cast<Dali::Internal::Layer*>(this)); // static cast as we trust the flag
404   }
405
406   // Find the immediate Layer parent
407   for(Actor* parent = GetParent(); !layer && parent != nullptr; parent = parent->GetParent())
408   {
409     if(parent->IsLayer())
410     {
411       layer = Dali::Layer(static_cast<Dali::Internal::Layer*>(parent)); // static cast as we trust the flag
412     }
413   }
414
415   return layer;
416 }
417
418 void Actor::Unparent()
419 {
420   if(mParent)
421   {
422     // Remove this actor from the parent. The remove will put a relayout request in for
423     // the parent if required
424     mParent->Remove(*this);
425     // mParent is now NULL!
426   }
427 }
428
429 void Actor::SetParentOrigin(const Vector3& origin)
430 {
431   // node is being used in a separate thread; queue a message to set the value & base value
432   SetParentOriginMessage(GetEventThreadServices(), GetNode(), origin);
433
434   // Cache for event-thread access
435   if(!mParentOrigin)
436   {
437     // not allocated, check if different from default
438     if(ParentOrigin::DEFAULT != origin)
439     {
440       mParentOrigin = new Vector3(origin);
441     }
442   }
443   else
444   {
445     // check if different from current costs more than just set
446     *mParentOrigin = origin;
447   }
448 }
449
450 const Vector3& Actor::GetCurrentParentOrigin() const
451 {
452   // Cached for event-thread access
453   return (mParentOrigin) ? *mParentOrigin : ParentOrigin::DEFAULT;
454 }
455
456 void Actor::SetAnchorPoint(const Vector3& anchor)
457 {
458   // node is being used in a separate thread; queue a message to set the value & base value
459   SetAnchorPointMessage(GetEventThreadServices(), GetNode(), anchor);
460
461   // Cache for event-thread access
462   if(!mAnchorPoint)
463   {
464     // not allocated, check if different from default
465     if(AnchorPoint::DEFAULT != anchor)
466     {
467       mAnchorPoint = new Vector3(anchor);
468     }
469   }
470   else
471   {
472     // check if different from current costs more than just set
473     *mAnchorPoint = anchor;
474   }
475 }
476
477 const Vector3& Actor::GetCurrentAnchorPoint() const
478 {
479   // Cached for event-thread access
480   return (mAnchorPoint) ? *mAnchorPoint : AnchorPoint::DEFAULT;
481 }
482
483 void Actor::SetPosition(const Vector3& position)
484 {
485   mTargetPosition = position;
486
487   // node is being used in a separate thread; queue a message to set the value & base value
488   SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position);
489 }
490
491 void Actor::SetX(float x)
492 {
493   mTargetPosition.x = x;
494
495   // node is being used in a separate thread; queue a message to set the value & base value
496   SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x);
497 }
498
499 void Actor::SetY(float y)
500 {
501   mTargetPosition.y = y;
502
503   // node is being used in a separate thread; queue a message to set the value & base value
504   SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y);
505 }
506
507 void Actor::SetZ(float z)
508 {
509   mTargetPosition.z = z;
510
511   // node is being used in a separate thread; queue a message to set the value & base value
512   SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z);
513 }
514
515 void Actor::TranslateBy(const Vector3& distance)
516 {
517   mTargetPosition += distance;
518
519   // node is being used in a separate thread; queue a message to set the value & base value
520   SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance);
521 }
522
523 const Vector3& Actor::GetCurrentPosition() const
524 {
525   // node is being used in a separate thread; copy the value from the previous update
526   return GetNode().GetPosition(GetEventThreadServices().GetEventBufferIndex());
527 }
528
529 const Vector3& Actor::GetCurrentWorldPosition() const
530 {
531   // node is being used in a separate thread; copy the value from the previous update
532   return GetNode().GetWorldPosition(GetEventThreadServices().GetEventBufferIndex());
533 }
534
535 const Vector2 Actor::CalculateScreenPosition() const
536 {
537   if(mScene)
538   {
539     if(mLayer3DParentsCount == 0)
540     {
541       // We can assume that this actor is under 2d layer. Use faster, but imprecise algorithm
542       return CalculateActorScreenPosition(*this);
543     }
544     else
545     {
546       return CalculateActorScreenPositionRenderTaskList(*this);
547     }
548   }
549   return Vector2::ZERO;
550 }
551
552 const Vector2 Actor::GetCurrentScreenPosition() const
553 {
554   if(mScene)
555   {
556     BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
557     if(mLayer3DParentsCount == 0)
558     {
559       // We can assume that this actor is under 2d layer. Use faster, but imprecise algorithm
560       return CalculateCurrentActorScreenPosition(*this, bufferIndex);
561     }
562     else
563     {
564       return CalculateCurrentActorScreenPositionRenderTaskList(*this, bufferIndex);
565     }
566   }
567   return Vector2::ZERO;
568 }
569
570 void Actor::SetInheritPosition(bool inherit)
571 {
572   if(mInheritPosition != inherit)
573   {
574     // non animatable so keep local copy
575     mInheritPosition = inherit;
576     SetInheritPositionMessage(GetEventThreadServices(), GetNode(), inherit);
577   }
578 }
579
580 void Actor::SetOrientation(const Radian& angle, const Vector3& axis)
581 {
582   Vector3 normalizedAxis(axis.x, axis.y, axis.z);
583   normalizedAxis.Normalize();
584
585   Quaternion orientation(angle, normalizedAxis);
586
587   SetOrientation(orientation);
588 }
589
590 void Actor::SetOrientation(const Quaternion& orientation)
591 {
592   mTargetOrientation = orientation;
593
594   // node is being used in a separate thread; queue a message to set the value & base value
595   SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation);
596 }
597
598 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
599 {
600   RotateBy(Quaternion(angle, axis));
601 }
602
603 void Actor::RotateBy(const Quaternion& relativeRotation)
604 {
605   mTargetOrientation *= Quaternion(relativeRotation);
606
607   // node is being used in a separate thread; queue a message to set the value & base value
608   SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation);
609 }
610
611 const Quaternion& Actor::GetCurrentOrientation() const
612 {
613   // node is being used in a separate thread; copy the value from the previous update
614   return GetNode().GetOrientation(GetEventThreadServices().GetEventBufferIndex());
615 }
616
617 const Quaternion& Actor::GetCurrentWorldOrientation() const
618 {
619   // node is being used in a separate thread; copy the value from the previous update
620   return GetNode().GetWorldOrientation(GetEventThreadServices().GetEventBufferIndex());
621 }
622
623 void Actor::SetScale(const Vector3& scale)
624 {
625   mTargetScale = scale;
626
627   // node is being used in a separate thread; queue a message to set the value & base value
628   SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale);
629 }
630
631 void Actor::SetScaleX(float x)
632 {
633   mTargetScale.x = x;
634
635   // node is being used in a separate thread; queue a message to set the value & base value
636   SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x);
637 }
638
639 void Actor::SetScaleY(float y)
640 {
641   mTargetScale.y = y;
642
643   // node is being used in a separate thread; queue a message to set the value & base value
644   SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y);
645 }
646
647 void Actor::SetScaleZ(float z)
648 {
649   mTargetScale.z = z;
650
651   // node is being used in a separate thread; queue a message to set the value & base value
652   SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z);
653 }
654
655 void Actor::ScaleBy(const Vector3& relativeScale)
656 {
657   mTargetScale *= relativeScale;
658
659   // node is being used in a separate thread; queue a message to set the value & base value
660   SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale);
661 }
662
663 const Vector3& Actor::GetCurrentScale() const
664 {
665   // node is being used in a separate thread; copy the value from the previous update
666   return GetNode().GetScale(GetEventThreadServices().GetEventBufferIndex());
667 }
668
669 const Vector3& Actor::GetCurrentWorldScale() const
670 {
671   // node is being used in a separate thread; copy the value from the previous update
672   return GetNode().GetWorldScale(GetEventThreadServices().GetEventBufferIndex());
673 }
674
675 void Actor::SetInheritScale(bool inherit)
676 {
677   if(mInheritScale != inherit)
678   {
679     // non animatable so keep local copy
680     mInheritScale = inherit;
681     // node is being used in a separate thread; queue a message to set the value
682     SetInheritScaleMessage(GetEventThreadServices(), GetNode(), inherit);
683   }
684 }
685
686 Matrix Actor::GetCurrentWorldMatrix() const
687 {
688   return GetNode().GetWorldMatrix(0);
689 }
690
691 void Actor::SetVisible(bool visible)
692 {
693   SetVisibleInternal(visible, SendMessage::TRUE);
694 }
695
696 bool Actor::IsVisible() const
697 {
698   // node is being used in a separate thread; copy the value from the previous update
699   return GetNode().IsVisible(GetEventThreadServices().GetEventBufferIndex());
700 }
701
702 void Actor::SetOpacity(float opacity)
703 {
704   mTargetColor.a = opacity;
705
706   // node is being used in a separate thread; queue a message to set the value & base value
707   SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeW, opacity);
708
709   RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
710 }
711
712 float Actor::GetCurrentOpacity() const
713 {
714   // node is being used in a separate thread; copy the value from the previous update
715   return GetNode().GetOpacity(GetEventThreadServices().GetEventBufferIndex());
716 }
717
718 const Vector4& Actor::GetCurrentWorldColor() const
719 {
720   return GetNode().GetWorldColor(GetEventThreadServices().GetEventBufferIndex());
721 }
722
723 void Actor::SetColor(const Vector4& color)
724 {
725   mTargetColor = color;
726
727   // node is being used in a separate thread; queue a message to set the value & base value
728   SceneGraph::NodePropertyMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::Bake, color);
729
730   RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
731 }
732
733 void Actor::SetColorRed(float red)
734 {
735   mTargetColor.r = red;
736
737   // node is being used in a separate thread; queue a message to set the value & base value
738   SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeX, red);
739
740   RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
741 }
742
743 void Actor::SetColorGreen(float green)
744 {
745   mTargetColor.g = green;
746
747   // node is being used in a separate thread; queue a message to set the value & base value
748   SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeY, green);
749
750   RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
751 }
752
753 void Actor::SetColorBlue(float blue)
754 {
755   mTargetColor.b = blue;
756
757   // node is being used in a separate thread; queue a message to set the value & base value
758   SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeZ, blue);
759
760   RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
761 }
762
763 const Vector4& Actor::GetCurrentColor() const
764 {
765   // node is being used in a separate thread; copy the value from the previous update
766   return GetNode().GetColor(GetEventThreadServices().GetEventBufferIndex());
767 }
768
769 void Actor::SetInheritOrientation(bool inherit)
770 {
771   if(mInheritOrientation != inherit)
772   {
773     // non animatable so keep local copy
774     mInheritOrientation = inherit;
775     // node is being used in a separate thread; queue a message to set the value
776     SetInheritOrientationMessage(GetEventThreadServices(), GetNode(), inherit);
777   }
778 }
779
780 void Actor::SetSizeModeFactor(const Vector3& factor)
781 {
782   mSizer.SetSizeModeFactor(factor);
783 }
784
785 const Vector3& Actor::GetSizeModeFactor() const
786 {
787   return mSizer.GetSizeModeFactor();
788 }
789
790 void Actor::SetColorMode(ColorMode colorMode)
791 {
792   // non animatable so keep local copy
793   mColorMode = colorMode;
794   // node is being used in a separate thread; queue a message to set the value
795   SetColorModeMessage(GetEventThreadServices(), GetNode(), colorMode);
796 }
797
798 void Actor::SetSize(float width, float height)
799 {
800   SetSize(Vector2(width, height));
801 }
802
803 void Actor::SetSize(float width, float height, float depth)
804 {
805   SetSize(Vector3(width, height, depth));
806 }
807
808 void Actor::SetSize(const Vector2& size)
809 {
810   SetSize(Vector3(size.width, size.height, 0.f));
811 }
812
813 void Actor::SetSize(const Vector3& size)
814 {
815   mSizer.SetSize(size);
816 }
817
818 void Actor::SetWidth(float width)
819 {
820   mSizer.SetWidth(width);
821 }
822
823 void Actor::SetHeight(float height)
824 {
825   mSizer.SetHeight(height);
826 }
827
828 void Actor::SetDepth(float depth)
829 {
830   mSizer.SetDepth(depth);
831   // node is being used in a separate thread; queue a message to set the value & base value
832   SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth);
833 }
834
835 Vector3 Actor::GetTargetSize() const
836 {
837   return mSizer.GetTargetSize();
838 }
839
840 const Vector3& Actor::GetCurrentSize() const
841 {
842   // node is being used in a separate thread; copy the value from the previous update
843   return GetNode().GetSize(GetEventThreadServices().GetEventBufferIndex());
844 }
845
846 Vector3 Actor::GetNaturalSize() const
847 {
848   // It is up to deriving classes to return the appropriate natural size
849   return Vector3(0.0f, 0.0f, 0.0f);
850 }
851
852 void Actor::SetResizePolicy(ResizePolicy::Type policy, Dimension::Type dimension)
853 {
854   mSizer.SetResizePolicy(policy, dimension);
855 }
856
857 ResizePolicy::Type Actor::GetResizePolicy(Dimension::Type dimension) const
858 {
859   return mSizer.GetResizePolicy(dimension);
860 }
861
862 void Actor::SetRelayoutEnabled(bool relayoutEnabled)
863 {
864   mSizer.SetRelayoutEnabled(relayoutEnabled);
865 }
866
867 bool Actor::IsRelayoutEnabled() const
868 {
869   return mSizer.IsRelayoutEnabled();
870 }
871
872 void Actor::SetLayoutDirty(bool dirty, Dimension::Type dimension)
873 {
874   mSizer.SetLayoutDirty(dirty, dimension);
875 }
876
877 bool Actor::IsLayoutDirty(Dimension::Type dimension) const
878 {
879   return mSizer.IsLayoutDirty(dimension);
880 }
881
882 bool Actor::RelayoutPossible(Dimension::Type dimension) const
883 {
884   return mSizer.RelayoutPossible(dimension);
885 }
886
887 bool Actor::RelayoutRequired(Dimension::Type dimension) const
888 {
889   return mSizer.RelayoutRequired(dimension);
890 }
891
892 uint32_t Actor::AddRenderer(Renderer& renderer)
893 {
894   if(!mRenderers)
895   {
896     mRenderers = new RendererContainer(GetEventThreadServices());
897   }
898   return mRenderers->Add(GetNode(), renderer, mIsBlendEquationSet, mBlendEquation);
899 }
900
901 uint32_t Actor::GetRendererCount() const
902 {
903   return mRenderers ? mRenderers->GetCount() : 0u;
904 }
905
906 RendererPtr Actor::GetRendererAt(uint32_t index)
907 {
908   return mRenderers ? mRenderers->GetRendererAt(index) : nullptr;
909 }
910
911 void Actor::RemoveRenderer(Renderer& renderer)
912 {
913   if(mRenderers)
914   {
915     mRenderers->Remove(GetNode(), renderer);
916   }
917 }
918
919 void Actor::RemoveRenderer(uint32_t index)
920 {
921   if(mRenderers)
922   {
923     mRenderers->Remove(GetNode(), index);
924   }
925 }
926
927 void Actor::SetBlendEquation(DevelBlendEquation::Type blendEquation)
928 {
929   if(Dali::Capabilities::IsBlendEquationSupported(blendEquation))
930   {
931     if(mBlendEquation != blendEquation)
932     {
933       mBlendEquation = blendEquation;
934       if(mRenderers)
935       {
936         mRenderers->SetBlending(blendEquation);
937       }
938     }
939     mIsBlendEquationSet = true;
940   }
941   else
942   {
943     DALI_LOG_ERROR("Invalid blend equation is entered.\n");
944   }
945 }
946
947 DevelBlendEquation::Type Actor::GetBlendEquation() const
948 {
949   return mBlendEquation;
950 }
951
952 void Actor::SetTransparent(bool transparent)
953 {
954   SetTransparentMessage(GetEventThreadServices(), GetNode(), transparent);
955 }
956
957 bool Actor::IsTransparent() const
958 {
959   return GetNode().IsTransparent();
960 }
961
962 void Actor::SetDrawMode(DrawMode::Type drawMode)
963 {
964   // this flag is not animatable so keep the value
965   mDrawMode = drawMode;
966
967   // node is being used in a separate thread; queue a message to set the value
968   SetDrawModeMessage(GetEventThreadServices(), GetNode(), drawMode);
969 }
970
971 bool Actor::ScreenToLocal(float& localX, float& localY, float screenX, float screenY) const
972 {
973   return mScene && OnScene() && ConvertScreenToLocalRenderTaskList(mScene->GetRenderTaskList(), GetNode().GetWorldMatrix(0), GetCurrentSize(), localX, localY, screenX, screenY);
974 }
975
976 bool Actor::ScreenToLocal(const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY) const
977 {
978   return OnScene() && ConvertScreenToLocalRenderTask(renderTask, GetNode().GetWorldMatrix(0), GetCurrentSize(), localX, localY, screenX, screenY);
979 }
980
981 bool Actor::ScreenToLocal(const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY) const
982 {
983   return OnScene() && ConvertScreenToLocal(viewMatrix, projectionMatrix, GetNode().GetWorldMatrix(0), GetCurrentSize(), viewport, localX, localY, screenX, screenY);
984 }
985
986 ActorGestureData& Actor::GetGestureData()
987 {
988   // Likely scenario is that once gesture-data is created for this actor, the actor will require
989   // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
990   if(nullptr == mGestureData)
991   {
992     mGestureData = new ActorGestureData;
993   }
994   return *mGestureData;
995 }
996
997 bool Actor::IsGestureRequired(GestureType::Value type) const
998 {
999   return mGestureData && mGestureData->IsGestureRequired(type);
1000 }
1001
1002 bool Actor::EmitInterceptTouchEventSignal(const Dali::TouchEvent& touch)
1003 {
1004   return EmitConsumingSignal(*this, mInterceptTouchedSignal, touch);
1005 }
1006
1007 bool Actor::EmitTouchEventSignal(const Dali::TouchEvent& touch)
1008 {
1009   return EmitConsumingSignal(*this, mTouchedSignal, touch);
1010 }
1011
1012 bool Actor::EmitHoverEventSignal(const Dali::HoverEvent& event)
1013 {
1014   return EmitConsumingSignal(*this, mHoveredSignal, event);
1015 }
1016
1017 bool Actor::EmitInterceptWheelEventSignal(const Dali::WheelEvent& event)
1018 {
1019   return EmitConsumingSignal(*this, mInterceptWheelSignal, event);
1020 }
1021
1022 bool Actor::EmitWheelEventSignal(const Dali::WheelEvent& event)
1023 {
1024   return EmitConsumingSignal(*this, mWheelEventSignal, event);
1025 }
1026
1027 void Actor::EmitVisibilityChangedSignal(bool visible, DevelActor::VisibilityChange::Type type)
1028 {
1029   EmitSignal(*this, mVisibilityChangedSignal, visible, type);
1030 }
1031
1032 void Actor::EmitInheritedVisibilityChangedSignal(bool visible)
1033 {
1034   EmitSignal(*this, mInheritedVisibilityChangedSignal, visible);
1035 }
1036
1037 void Actor::EmitLayoutDirectionChangedSignal(LayoutDirection::Type type)
1038 {
1039   EmitSignal(*this, mLayoutDirectionChangedSignal, type);
1040 }
1041
1042 bool Actor::EmitHitTestResultSignal(Integration::Point point, Vector2 hitPointLocal, uint32_t timeStamp)
1043 {
1044   bool hit = true;
1045
1046   if(IsHitTestResultRequired())
1047   {
1048     Dali::Actor        handle(this);
1049     Integration::Point newPoint(point);
1050     newPoint.SetHitActor(handle);
1051     newPoint.SetLocalPosition(hitPointLocal);
1052     Dali::TouchEvent touchEvent = Dali::Integration::NewTouchEvent(timeStamp, newPoint);
1053     hit                         = mHitTestResultSignal.Emit(handle, touchEvent);
1054   }
1055   return hit;
1056 }
1057
1058 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
1059 {
1060   return mParentImpl.ChildAddedSignal();
1061 }
1062
1063 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
1064 {
1065   return mParentImpl.ChildRemovedSignal();
1066 }
1067
1068 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
1069 {
1070   return mParentImpl.ChildOrderChangedSignal();
1071 }
1072
1073 Actor::Actor(DerivedType derivedType, const SceneGraph::Node& node)
1074 : Object(&node),
1075   mParentImpl(*this),
1076   mSizer(*this),
1077   mParent(nullptr),
1078   mScene(nullptr),
1079   mRenderers(nullptr),
1080   mParentOrigin(nullptr),
1081   mAnchorPoint(nullptr),
1082   mGestureData(nullptr),
1083   mInterceptTouchedSignal(),
1084   mTouchedSignal(),
1085   mHoveredSignal(),
1086   mInterceptWheelSignal(),
1087   mWheelEventSignal(),
1088   mOnSceneSignal(),
1089   mOffSceneSignal(),
1090   mOnRelayoutSignal(),
1091   mVisibilityChangedSignal(),
1092   mInheritedVisibilityChangedSignal(),
1093   mLayoutDirectionChangedSignal(),
1094   mHitTestResultSignal(),
1095   mTargetOrientation(Quaternion::IDENTITY),
1096   mTargetColor(Color::WHITE),
1097   mTargetPosition(Vector3::ZERO),
1098   mTargetScale(Vector3::ONE),
1099   mTouchAreaOffset(0, 0, 0, 0),
1100   mName(),
1101   mSortedDepth(0u),
1102   mDepth(0u),
1103   mLayer3DParentsCount(0),
1104   mIsRoot(ROOT_LAYER == derivedType),
1105   mIsLayer(LAYER == derivedType || ROOT_LAYER == derivedType),
1106   mIsOnScene(false),
1107   mSensitive(true),
1108   mLeaveRequired(false),
1109   mKeyboardFocusable(false),
1110   mKeyboardFocusableChildren(true),
1111   mTouchFocusable(false),
1112   mOnSceneSignalled(false),
1113   mInheritPosition(true),
1114   mInheritOrientation(true),
1115   mInheritScale(true),
1116   mPositionUsesAnchorPoint(true),
1117   mVisible(true),
1118   mInheritLayoutDirection(true),
1119   mCaptureAllTouchAfterStart(false),
1120   mIsBlendEquationSet(false),
1121   mNeedGesturePropagation(false),
1122   mUserInteractionEnabled(true),
1123   mAllowOnlyOwnTouch(false),
1124   mUseTextureUpdateArea(false),
1125   mDispatchTouchMotion(true),
1126   mDispatchHoverMotion(true),
1127   mLayoutDirection(LayoutDirection::LEFT_TO_RIGHT),
1128   mDrawMode(DrawMode::NORMAL),
1129   mColorMode(Node::DEFAULT_COLOR_MODE),
1130   mClippingMode(ClippingMode::DISABLED),
1131   mHoverState(PointState::FINISHED),
1132   mBlendEquation(DevelBlendEquation::ADD)
1133 {
1134 }
1135
1136 void Actor::Initialize()
1137 {
1138   OnInitialize();
1139
1140   GetEventThreadServices().RegisterObject(this);
1141 }
1142
1143 Actor::~Actor()
1144 {
1145   // Remove mParent pointers from children even if we're destroying core,
1146   // to guard against GetParent() & Unparent() calls from CustomActor destructors.
1147   UnparentChildren();
1148
1149   // Guard to allow handle destruction after Core has been destroyed
1150   if(EventThreadServices::IsCoreRunning())
1151   {
1152     if(mRenderers)
1153     {
1154       // Detach all renderers before delete container.
1155       mRenderers->RemoveAll(GetNode());
1156     }
1157
1158     // Root layer will destroy its node in its own destructor
1159     if(!mIsRoot)
1160     {
1161       DestroyNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
1162
1163       GetEventThreadServices().UnregisterObject(this);
1164     }
1165   }
1166   // Cleanup renderer list
1167   delete mRenderers;
1168
1169   // Cleanup optional gesture data
1170   delete mGestureData;
1171
1172   // Cleanup optional parent origin and anchor
1173   delete mParentOrigin;
1174   delete mAnchorPoint;
1175 }
1176
1177 void Actor::Add(Actor& child, bool notify)
1178 {
1179   mParentImpl.Add(child, notify);
1180 }
1181
1182 void Actor::Remove(Actor& child, bool notify)
1183 {
1184   mParentImpl.Remove(child, notify);
1185 }
1186
1187 void Actor::SwitchParent(Actor& newParent)
1188 {
1189   if(this == &newParent)
1190   {
1191     DALI_LOG_ERROR("Cannot add actor to itself");
1192     return;
1193   }
1194
1195   if(!this->OnScene() || !newParent.OnScene())
1196   {
1197     DALI_LOG_ERROR("Both of current parent and new parent must be on Scene");
1198     return;
1199   }
1200
1201   newParent.Add(*this, false);
1202 }
1203
1204 uint32_t Actor::GetChildCount() const
1205 {
1206   return mParentImpl.GetChildCount();
1207 }
1208
1209 ActorPtr Actor::GetChildAt(uint32_t index) const
1210 {
1211   return mParentImpl.GetChildAt(index);
1212 }
1213
1214 ActorContainer& Actor::GetChildrenInternal()
1215 {
1216   return mParentImpl.GetChildrenInternal();
1217 }
1218
1219 ActorPtr Actor::FindChildByName(ConstString actorName)
1220 {
1221   return mParentImpl.FindChildByName(actorName);
1222 }
1223
1224 ActorPtr Actor::FindChildById(const uint32_t id)
1225 {
1226   return mParentImpl.FindChildById(id);
1227 }
1228
1229 void Actor::UnparentChildren()
1230 {
1231   mParentImpl.UnparentChildren();
1232 }
1233
1234 void Actor::ConnectToScene(uint32_t parentDepth, uint32_t layer3DParentsCount, bool notify)
1235 {
1236   // This container is used instead of walking the Actor hierarchy.
1237   // It protects us when the Actor hierarchy is modified during OnSceneConnectionExternal callbacks.
1238   ActorContainer connectionList;
1239
1240   if(mScene)
1241   {
1242     mScene->RequestRebuildDepthTree();
1243   }
1244
1245   // This stage is not interrupted by user callbacks.
1246   mParentImpl.RecursiveConnectToScene(connectionList, layer3DParentsCount, parentDepth + 1);
1247
1248   // Notify applications about the newly connected actors.
1249   for(const auto& actor : connectionList)
1250   {
1251     actor->NotifyStageConnection(notify);
1252   }
1253
1254   RelayoutRequest();
1255 }
1256
1257 /**
1258  * This method is called when the Actor is connected to the Stage.
1259  * The parent must have added its Node to the scene-graph.
1260  * The child must connect its Node to the parent's Node.
1261  * This is recursive; the child calls ConnectToScene() for its children.
1262  */
1263 void Actor::ConnectToSceneGraph()
1264 {
1265   DALI_ASSERT_DEBUG(mParent != NULL);
1266
1267   // Reparent Node in next Update
1268   ConnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetParent()->GetNode(), GetNode());
1269
1270   // Request relayout on all actors that are added to the scenegraph
1271   RelayoutRequest();
1272
1273   // Notification for Object::Observers
1274   OnSceneObjectAdd();
1275 }
1276
1277 void Actor::NotifyStageConnection(bool notify)
1278 {
1279   // Actors can be removed (in a callback), before the on-stage stage is reported.
1280   // The actor may also have been reparented, in which case mOnSceneSignalled will be true.
1281   if(OnScene() && !mOnSceneSignalled)
1282   {
1283     if(notify)
1284     {
1285       // Notification for external (CustomActor) derived classes
1286       OnSceneConnectionExternal(mDepth);
1287
1288       if(!mOnSceneSignal.Empty())
1289       {
1290         Dali::Actor handle(this);
1291         mOnSceneSignal.Emit(handle);
1292       }
1293     }
1294
1295     // Guard against Remove during callbacks
1296     if(OnScene())
1297     {
1298       mOnSceneSignalled = true; // signal required next time Actor is removed
1299     }
1300   }
1301 }
1302
1303 void Actor::DisconnectFromStage(bool notify)
1304 {
1305   // This container is used instead of walking the Actor hierachy.
1306   // It protects us when the Actor hierachy is modified during OnSceneDisconnectionExternal callbacks.
1307   ActorContainer disconnectionList;
1308
1309   if(mScene)
1310   {
1311     mScene->RequestRebuildDepthTree();
1312   }
1313
1314   // This stage is not interrupted by user callbacks
1315   mParentImpl.RecursiveDisconnectFromScene(disconnectionList);
1316
1317   // Notify applications about the newly disconnected actors.
1318   for(const auto& actor : disconnectionList)
1319   {
1320     actor->NotifyStageDisconnection(notify);
1321   }
1322 }
1323
1324 /**
1325  * This method is called by an actor or its parent, before a node removal message is sent.
1326  * This is recursive; the child calls DisconnectFromStage() for its children.
1327  */
1328 void Actor::DisconnectFromSceneGraph()
1329 {
1330   // Notification for Object::Observers
1331   OnSceneObjectRemove();
1332 }
1333
1334 void Actor::NotifyStageDisconnection(bool notify)
1335 {
1336   // Actors can be added (in a callback), before the off-stage state is reported.
1337   // Also if the actor was added & removed before mOnSceneSignalled was set, then we don't notify here.
1338   // only do this step if there is a stage, i.e. Core is not being shut down
1339   if(EventThreadServices::IsCoreRunning() && !OnScene() && mOnSceneSignalled)
1340   {
1341     if(notify)
1342     {
1343       // Notification for external (CustomeActor) derived classes
1344       OnSceneDisconnectionExternal();
1345
1346       if(!mOffSceneSignal.Empty())
1347       {
1348         Dali::Actor handle(this);
1349         mOffSceneSignal.Emit(handle);
1350       }
1351     }
1352
1353     // Guard against Add during callbacks
1354     if(!OnScene())
1355     {
1356       mOnSceneSignalled = false; // signal required next time Actor is added
1357     }
1358   }
1359 }
1360
1361 bool Actor::IsNodeConnected() const
1362 {
1363   return OnScene() && (IsRoot() || GetNode().GetParent());
1364 }
1365
1366 // This method initiates traversal of the actor tree using depth-first
1367 // traversal to set a depth index based on traversal order. It sends a
1368 // single message to update manager to update all the actor's nodes in
1369 // this tree with the depth index. The sceneGraphNodeDepths vector's
1370 // elements are ordered by depth, and could be used to reduce sorting
1371 // in the update thread.
1372 void Actor::RebuildDepthTree()
1373 {
1374   DALI_LOG_TIMER_START(depthTimer);
1375
1376   // Vector of scene-graph nodes and their depths to send to UpdateManager
1377   // in a single message
1378   OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths(new SceneGraph::NodeDepths());
1379
1380   int32_t depthIndex = 1;
1381   mParentImpl.DepthTraverseActorTree(sceneGraphNodeDepths, depthIndex);
1382
1383   SetDepthIndicesMessage(GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths);
1384   DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
1385 }
1386
1387 void Actor::SetDefaultProperty(Property::Index index, const Property::Value& property)
1388 {
1389   PropertyHandler::SetDefaultProperty(*this, index, property);
1390 }
1391
1392 // TODO: This method needs to be removed
1393 void Actor::SetSceneGraphProperty(Property::Index index, const PropertyMetadata& entry, const Property::Value& value)
1394 {
1395   PropertyHandler::SetSceneGraphProperty(index, entry, value, GetEventThreadServices(), GetNode());
1396 }
1397
1398 Property::Value Actor::GetDefaultProperty(Property::Index index) const
1399 {
1400   Property::Value value;
1401
1402   if(!GetCachedPropertyValue(index, value))
1403   {
1404     // If property value is not stored in the event-side, then it must be a scene-graph only property
1405     GetCurrentPropertyValue(index, value);
1406   }
1407
1408   return value;
1409 }
1410
1411 Property::Value Actor::GetDefaultPropertyCurrentValue(Property::Index index) const
1412 {
1413   Property::Value value;
1414
1415   if(!GetCurrentPropertyValue(index, value))
1416   {
1417     // If unable to retrieve scene-graph property value, then it must be an event-side only property
1418     GetCachedPropertyValue(index, value);
1419   }
1420
1421   return value;
1422 }
1423
1424 void Actor::OnNotifyDefaultPropertyAnimation(Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType)
1425 {
1426   PropertyHandler::OnNotifyDefaultPropertyAnimation(*this, animation, index, value, animationType);
1427 }
1428
1429 const PropertyBase* Actor::GetSceneObjectAnimatableProperty(Property::Index index) const
1430 {
1431   const PropertyBase* property = PropertyHandler::GetSceneObjectAnimatableProperty(index, GetNode());
1432   if(!property)
1433   {
1434     // not our property, ask base
1435     property = Object::GetSceneObjectAnimatableProperty(index);
1436   }
1437
1438   return property;
1439 }
1440
1441 const PropertyInputImpl* Actor::GetSceneObjectInputProperty(Property::Index index) const
1442 {
1443   const PropertyInputImpl* property = PropertyHandler::GetSceneObjectInputProperty(index, GetNode());
1444   if(!property)
1445   {
1446     // reuse animatable property getter as animatable properties are inputs as well
1447     // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
1448     property = GetSceneObjectAnimatableProperty(index);
1449   }
1450
1451   return property;
1452 }
1453
1454 int32_t Actor::GetPropertyComponentIndex(Property::Index index) const
1455 {
1456   int32_t componentIndex = PropertyHandler::GetPropertyComponentIndex(index);
1457   if(Property::INVALID_COMPONENT_INDEX == componentIndex)
1458   {
1459     // ask base
1460     componentIndex = Object::GetPropertyComponentIndex(index);
1461   }
1462
1463   return componentIndex;
1464 }
1465
1466 const SceneGraph::Node& Actor::GetNode() const
1467 {
1468   return *static_cast<const SceneGraph::Node*>(mUpdateObject);
1469 }
1470
1471 void Actor::Raise()
1472 {
1473   CheckParentAndCall(mParent, *this, &ActorParent::RaiseChild);
1474 }
1475
1476 void Actor::Lower()
1477 {
1478   CheckParentAndCall(mParent, *this, &ActorParent::LowerChild);
1479 }
1480
1481 void Actor::RaiseToTop()
1482 {
1483   CheckParentAndCall(mParent, *this, &ActorParent::RaiseChildToTop);
1484 }
1485
1486 void Actor::LowerToBottom()
1487 {
1488   CheckParentAndCall(mParent, *this, &ActorParent::LowerChildToBottom);
1489 }
1490
1491 void Actor::RaiseAbove(Internal::Actor& target)
1492 {
1493   CheckParentAndCall(mParent, *this, target, &ActorParent::RaiseChildAbove);
1494 }
1495
1496 void Actor::LowerBelow(Internal::Actor& target)
1497 {
1498   CheckParentAndCall(mParent, *this, target, &ActorParent::LowerChildBelow);
1499 }
1500
1501 void Actor::SetParent(ActorParent* parent, bool notify)
1502 {
1503   bool emitInheritedVisible = false;
1504   bool visiblility = true;
1505   if(parent)
1506   {
1507     DALI_ASSERT_ALWAYS(!mParent && "Actor cannot have 2 parents");
1508
1509     mParent            = parent;
1510     Actor* parentActor = static_cast<Actor*>(parent);
1511     mScene             = parentActor->mScene;
1512
1513     if(!EventThreadServices::IsShuttingDown() && // Don't emit signals or send messages during Core destruction
1514        parentActor->OnScene())
1515     {
1516       // Instruct each actor to create a corresponding node in the scene graph
1517       ConnectToScene(parentActor->GetHierarchyDepth(), parentActor->GetLayer3DParentCount(), notify);
1518
1519       Actor* actor         = this;
1520       emitInheritedVisible = true;
1521       while(emitInheritedVisible && actor)
1522       {
1523         emitInheritedVisible &= actor->GetProperty(Dali::Actor::Property::VISIBLE).Get<bool>();
1524         actor = actor->GetParent();
1525       }
1526     }
1527
1528     // Resolve the name and index for the child properties if any
1529     ResolveChildProperties();
1530   }
1531   else // parent being set to NULL
1532   {
1533     DALI_ASSERT_ALWAYS(mParent != nullptr && "Actor should have a parent");
1534
1535     if(!EventThreadServices::IsShuttingDown() && // Don't emit signals or send messages during Core destruction
1536        OnScene())
1537     {
1538       Actor* actor         = this;
1539       emitInheritedVisible = true;
1540       while(emitInheritedVisible && actor)
1541       {
1542         emitInheritedVisible &= actor->GetProperty(Dali::Actor::Property::VISIBLE).Get<bool>();
1543         actor = actor->GetParent();
1544       }
1545       visiblility = false;
1546     }
1547
1548     mParent = nullptr;
1549
1550     if(!EventThreadServices::IsShuttingDown() && // Don't emit signals or send messages during Core destruction
1551        OnScene())
1552     {
1553       // Disconnect the Node & its children from the scene-graph.
1554       DisconnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
1555
1556       // Instruct each actor to discard pointers to the scene-graph
1557       DisconnectFromStage(notify);
1558     }
1559
1560     mScene = nullptr;
1561   }
1562
1563   if(emitInheritedVisible)
1564   {
1565     EmitInheritedVisibilityChangedSignalRecursively(visiblility);
1566   }
1567 }
1568
1569 Rect<> Actor::CalculateScreenExtents() const
1570 {
1571   if(mLayer3DParentsCount == 0)
1572   {
1573     // We can assume that this actor is under 2d layer. Use faster, but imprecise algorithm
1574     return CalculateActorScreenExtents(*this);
1575   }
1576   else
1577   {
1578     return CalculateActorScreenExtentsRenderTaskList(*this);
1579   }
1580 }
1581
1582 Rect<> Actor::CalculateCurrentScreenExtents() const
1583 {
1584   BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
1585   if(mLayer3DParentsCount == 0)
1586   {
1587     // We can assume that this actor is under 2d layer. Use faster, but imprecise algorithm
1588     return CalculateCurrentActorScreenExtents(*this, bufferIndex);
1589   }
1590   else
1591   {
1592     return CalculateCurrentActorScreenExtentsRenderTaskList(*this, bufferIndex);
1593   }
1594 }
1595
1596 Vector3 Actor::GetAnchorPointForPosition() const
1597 {
1598   return (mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT);
1599 }
1600
1601 bool Actor::GetCachedPropertyValue(Property::Index index, Property::Value& value) const
1602 {
1603   return PropertyHandler::GetCachedPropertyValue(*this, index, value);
1604 }
1605
1606 bool Actor::GetCurrentPropertyValue(Property::Index index, Property::Value& value) const
1607 {
1608   return PropertyHandler::GetCurrentPropertyValue(*this, index, value);
1609 }
1610
1611 bool Actor::RelayoutDependentOnParent(Dimension::Type dimension)
1612 {
1613   return mSizer.RelayoutDependentOnParent(dimension);
1614 }
1615
1616 bool Actor::RelayoutDependentOnChildren(Dimension::Type dimension)
1617 {
1618   return mSizer.RelayoutDependentOnChildrenBase(dimension);
1619 }
1620
1621 bool Actor::RelayoutDependentOnDimension(Dimension::Type dimension, Dimension::Type dependentDimension)
1622 {
1623   return mSizer.RelayoutDependentOnDimension(dimension, dependentDimension);
1624 }
1625
1626 void Actor::SetPadding(const Vector2& padding, Dimension::Type dimension)
1627 {
1628   mSizer.SetPadding(padding, dimension);
1629 }
1630
1631 Vector2 Actor::GetPadding(Dimension::Type dimension) const
1632 {
1633   return mSizer.GetPadding(dimension);
1634 }
1635
1636 void Actor::SetLayoutNegotiated(bool negotiated, Dimension::Type dimension)
1637 {
1638   mSizer.SetLayoutNegotiated(negotiated, dimension);
1639 }
1640
1641 bool Actor::IsLayoutNegotiated(Dimension::Type dimension) const
1642 {
1643   return mSizer.IsLayoutNegotiated(dimension);
1644 }
1645
1646 float Actor::GetHeightForWidthBase(float width)
1647 {
1648   // Can be overridden in derived class
1649   return mSizer.GetHeightForWidthBase(width);
1650 }
1651
1652 float Actor::GetWidthForHeightBase(float height)
1653 {
1654   // Can be overridden in derived class
1655   return mSizer.GetWidthForHeightBase(height);
1656 }
1657
1658 float Actor::CalculateChildSizeBase(const Dali::Actor& child, Dimension::Type dimension)
1659 {
1660   // Can be overridden in derived class
1661   return mSizer.CalculateChildSizeBase(child, dimension);
1662 }
1663
1664 bool Actor::RelayoutDependentOnChildrenBase(Dimension::Type dimension)
1665 {
1666   return mSizer.RelayoutDependentOnChildrenBase(dimension);
1667 }
1668
1669 float Actor::CalculateChildSize(const Dali::Actor& child, Dimension::Type dimension)
1670 {
1671   // Can be overridden in derived class
1672   return mSizer.CalculateChildSizeBase(child, dimension);
1673 }
1674
1675 float Actor::GetHeightForWidth(float width)
1676 {
1677   // Can be overridden in derived class
1678   return mSizer.GetHeightForWidthBase(width);
1679 }
1680
1681 float Actor::GetWidthForHeight(float height)
1682 {
1683   // Can be overridden in derived class
1684   return mSizer.GetWidthForHeightBase(height);
1685 }
1686
1687 float Actor::GetRelayoutSize(Dimension::Type dimension) const
1688 {
1689   return mSizer.GetRelayoutSize(dimension);
1690 }
1691
1692 void Actor::NegotiateSize(const Vector2& allocatedSize, RelayoutContainer& container)
1693 {
1694   mSizer.NegotiateSize(allocatedSize, container);
1695 }
1696
1697 void Actor::RelayoutRequest(Dimension::Type dimension)
1698 {
1699   mSizer.RelayoutRequest(dimension);
1700 }
1701
1702 void Actor::SetMinimumSize(float size, Dimension::Type dimension)
1703 {
1704   mSizer.SetMinimumSize(size, dimension);
1705 }
1706
1707 float Actor::GetMinimumSize(Dimension::Type dimension) const
1708 {
1709   return mSizer.GetMinimumSize(dimension);
1710 }
1711
1712 void Actor::SetMaximumSize(float size, Dimension::Type dimension)
1713 {
1714   mSizer.SetMaximumSize(size, dimension);
1715 }
1716
1717 float Actor::GetMaximumSize(Dimension::Type dimension) const
1718 {
1719   return mSizer.GetMaximumSize(dimension);
1720 }
1721
1722 void Actor::SetVisibleInternal(bool visible, SendMessage::Type sendMessage)
1723 {
1724   if(mVisible != visible)
1725   {
1726     if(sendMessage == SendMessage::TRUE)
1727     {
1728       // node is being used in a separate thread; queue a message to set the value & base value
1729       SceneGraph::NodePropertyMessage<bool>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible);
1730
1731       RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
1732     }
1733
1734     Actor* actor = this->GetParent();
1735     bool emitInheritedVisible = OnScene();
1736     while(emitInheritedVisible && actor)
1737     {
1738       emitInheritedVisible &= actor->GetProperty(Dali::Actor::Property::VISIBLE).Get<bool>();
1739       actor = actor->GetParent();
1740     }
1741
1742     mVisible = visible;
1743
1744     // Emit the signal on this actor and all its children
1745     mParentImpl.EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::SELF);
1746     if(emitInheritedVisible)
1747     {
1748       EmitInheritedVisibilityChangedSignalRecursively(visible);
1749     }
1750   }
1751 }
1752
1753 void Actor::EmitInheritedVisibilityChangedSignalRecursively(bool visible)
1754 {
1755   ActorContainer inheritedVisibilityChangedList;
1756   mParentImpl.InheritVisibilityRecursively(inheritedVisibilityChangedList);
1757   // Notify applications about the newly connected actors.
1758   for(const auto& actor : inheritedVisibilityChangedList)
1759   {
1760     actor->EmitInheritedVisibilityChangedSignal(visible);
1761   }
1762 }
1763
1764 void Actor::SetSiblingOrderOfChild(Actor& child, uint32_t order)
1765 {
1766   mParentImpl.SetSiblingOrderOfChild(child, order);
1767 }
1768
1769 uint32_t Actor::GetSiblingOrderOfChild(const Actor& child) const
1770 {
1771   return mParentImpl.GetSiblingOrderOfChild(child);
1772 }
1773
1774 void Actor::RaiseChild(Actor& child)
1775 {
1776   mParentImpl.RaiseChild(child);
1777 }
1778
1779 void Actor::LowerChild(Actor& child)
1780 {
1781   mParentImpl.LowerChild(child);
1782 }
1783
1784 void Actor::RaiseChildToTop(Actor& child)
1785 {
1786   mParentImpl.RaiseChildToTop(child);
1787 }
1788
1789 void Actor::LowerChildToBottom(Actor& child)
1790 {
1791   mParentImpl.LowerChildToBottom(child);
1792 }
1793
1794 void Actor::RaiseChildAbove(Actor& child, Actor& target)
1795 {
1796   mParentImpl.RaiseChildAbove(child, target);
1797 }
1798
1799 void Actor::LowerChildBelow(Actor& child, Actor& target)
1800 {
1801   mParentImpl.LowerChildBelow(child, target);
1802 }
1803
1804 void Actor::SetInheritLayoutDirection(bool inherit)
1805 {
1806   if(mInheritLayoutDirection != inherit)
1807   {
1808     mInheritLayoutDirection = inherit;
1809
1810     if(inherit && mParent)
1811     {
1812       mParentImpl.InheritLayoutDirectionRecursively(GetParent()->mLayoutDirection);
1813     }
1814   }
1815 }
1816
1817 void Actor::SetUpdateAreaHint(const Vector4& updateAreaHint)
1818 {
1819   // node is being used in a separate thread; queue a message to set the value & base value
1820   SetUpdateAreaHintMessage(GetEventThreadServices(), GetNode(), updateAreaHint);
1821 }
1822
1823 } // namespace Internal
1824
1825 } // namespace Dali