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