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