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