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