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