Revert "[Tizen] Not execute the remove callback"
[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("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_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     if(mLayer3DParentsCount == 0)
544     {
545       // We can assume that this actor is under 2d layer. Use faster, but imprecise algorithm
546       return CalculateActorScreenPosition(*this, bufferIndex);
547     }
548     else
549     {
550       return CalculateActorScreenPositionRenderTaskList(*this, bufferIndex);
551     }
552   }
553   return Vector2::ZERO;
554 }
555
556 void Actor::SetInheritPosition(bool inherit)
557 {
558   if(mInheritPosition != inherit)
559   {
560     // non animatable so keep local copy
561     mInheritPosition = inherit;
562     SetInheritPositionMessage(GetEventThreadServices(), GetNode(), inherit);
563   }
564 }
565
566 void Actor::SetOrientation(const Radian& angle, const Vector3& axis)
567 {
568   Vector3 normalizedAxis(axis.x, axis.y, axis.z);
569   normalizedAxis.Normalize();
570
571   Quaternion orientation(angle, normalizedAxis);
572
573   SetOrientation(orientation);
574 }
575
576 void Actor::SetOrientation(const Quaternion& orientation)
577 {
578   mTargetOrientation = orientation;
579
580   // node is being used in a separate thread; queue a message to set the value & base value
581   SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation);
582 }
583
584 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
585 {
586   RotateBy(Quaternion(angle, axis));
587 }
588
589 void Actor::RotateBy(const Quaternion& relativeRotation)
590 {
591   mTargetOrientation *= Quaternion(relativeRotation);
592
593   // node is being used in a separate thread; queue a message to set the value & base value
594   SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation);
595 }
596
597 const Quaternion& Actor::GetCurrentOrientation() const
598 {
599   // node is being used in a separate thread; copy the value from the previous update
600   return GetNode().GetOrientation(GetEventThreadServices().GetEventBufferIndex());
601 }
602
603 const Quaternion& Actor::GetCurrentWorldOrientation() const
604 {
605   // node is being used in a separate thread; copy the value from the previous update
606   return GetNode().GetWorldOrientation(GetEventThreadServices().GetEventBufferIndex());
607 }
608
609 void Actor::SetScale(float scale)
610 {
611   SetScale(Vector3(scale, scale, scale));
612 }
613
614 void Actor::SetScale(float x, float y, float z)
615 {
616   SetScale(Vector3(x, y, z));
617 }
618
619 void Actor::SetScale(const Vector3& scale)
620 {
621   mTargetScale = scale;
622
623   // node is being used in a separate thread; queue a message to set the value & base value
624   SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale);
625 }
626
627 void Actor::SetScaleX(float x)
628 {
629   mTargetScale.x = x;
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>::BakeX, x);
633 }
634
635 void Actor::SetScaleY(float y)
636 {
637   mTargetScale.y = y;
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>::BakeY, y);
641 }
642
643 void Actor::SetScaleZ(float z)
644 {
645   mTargetScale.z = z;
646
647   // node is being used in a separate thread; queue a message to set the value & base value
648   SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z);
649 }
650
651 void Actor::ScaleBy(const Vector3& relativeScale)
652 {
653   mTargetScale *= relativeScale;
654
655   // node is being used in a separate thread; queue a message to set the value & base value
656   SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale);
657 }
658
659 const Vector3& Actor::GetCurrentScale() const
660 {
661   // node is being used in a separate thread; copy the value from the previous update
662   return GetNode().GetScale(GetEventThreadServices().GetEventBufferIndex());
663 }
664
665 const Vector3& Actor::GetCurrentWorldScale() const
666 {
667   // node is being used in a separate thread; copy the value from the previous update
668   return GetNode().GetWorldScale(GetEventThreadServices().GetEventBufferIndex());
669 }
670
671 void Actor::SetInheritScale(bool inherit)
672 {
673   if(mInheritScale != inherit)
674   {
675     // non animatable so keep local copy
676     mInheritScale = inherit;
677     // node is being used in a separate thread; queue a message to set the value
678     SetInheritScaleMessage(GetEventThreadServices(), GetNode(), inherit);
679   }
680 }
681
682 Matrix Actor::GetCurrentWorldMatrix() const
683 {
684   return GetNode().GetWorldMatrix(0);
685 }
686
687 void Actor::SetVisible(bool visible)
688 {
689   SetVisibleInternal(visible, SendMessage::TRUE);
690 }
691
692 bool Actor::IsVisible() const
693 {
694   // node is being used in a separate thread; copy the value from the previous update
695   return GetNode().IsVisible(GetEventThreadServices().GetEventBufferIndex());
696 }
697
698 void Actor::SetOpacity(float opacity)
699 {
700   mTargetColor.a = opacity;
701
702   // node is being used in a separate thread; queue a message to set the value & base value
703   SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeW, opacity);
704
705   RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
706 }
707
708 float Actor::GetCurrentOpacity() const
709 {
710   // node is being used in a separate thread; copy the value from the previous update
711   return GetNode().GetOpacity(GetEventThreadServices().GetEventBufferIndex());
712 }
713
714 const Vector4& Actor::GetCurrentWorldColor() const
715 {
716   return GetNode().GetWorldColor(GetEventThreadServices().GetEventBufferIndex());
717 }
718
719 void Actor::SetColor(const Vector4& color)
720 {
721   mTargetColor = color;
722
723   // node is being used in a separate thread; queue a message to set the value & base value
724   SceneGraph::NodePropertyMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::Bake, color);
725
726   RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
727 }
728
729 void Actor::SetColorRed(float red)
730 {
731   mTargetColor.r = red;
732
733   // node is being used in a separate thread; queue a message to set the value & base value
734   SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeX, red);
735
736   RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
737 }
738
739 void Actor::SetColorGreen(float green)
740 {
741   mTargetColor.g = green;
742
743   // node is being used in a separate thread; queue a message to set the value & base value
744   SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeY, green);
745
746   RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
747 }
748
749 void Actor::SetColorBlue(float blue)
750 {
751   mTargetColor.b = blue;
752
753   // node is being used in a separate thread; queue a message to set the value & base value
754   SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeZ, blue);
755
756   RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
757 }
758
759 const Vector4& Actor::GetCurrentColor() const
760 {
761   // node is being used in a separate thread; copy the value from the previous update
762   return GetNode().GetColor(GetEventThreadServices().GetEventBufferIndex());
763 }
764
765 void Actor::SetInheritOrientation(bool inherit)
766 {
767   if(mInheritOrientation != inherit)
768   {
769     // non animatable so keep local copy
770     mInheritOrientation = inherit;
771     // node is being used in a separate thread; queue a message to set the value
772     SetInheritOrientationMessage(GetEventThreadServices(), GetNode(), inherit);
773   }
774 }
775
776 void Actor::SetSizeModeFactor(const Vector3& factor)
777 {
778   mSizer.SetSizeModeFactor(factor);
779 }
780
781 const Vector3& Actor::GetSizeModeFactor() const
782 {
783   return mSizer.GetSizeModeFactor();
784 }
785
786 void Actor::SetColorMode(ColorMode colorMode)
787 {
788   // non animatable so keep local copy
789   mColorMode = colorMode;
790   // node is being used in a separate thread; queue a message to set the value
791   SetColorModeMessage(GetEventThreadServices(), GetNode(), colorMode);
792 }
793
794 void Actor::SetSize(float width, float height)
795 {
796   SetSize(Vector2(width, height));
797 }
798
799 void Actor::SetSize(float width, float height, float depth)
800 {
801   SetSize(Vector3(width, height, depth));
802 }
803
804 void Actor::SetSize(const Vector2& size)
805 {
806   SetSize(Vector3(size.width, size.height, 0.f));
807 }
808
809 void Actor::SetSize(const Vector3& size)
810 {
811   mSizer.SetSize(size);
812 }
813
814 void Actor::SetWidth(float width)
815 {
816   mSizer.SetWidth(width);
817 }
818
819 void Actor::SetHeight(float height)
820 {
821   mSizer.SetHeight(height);
822 }
823
824 void Actor::SetDepth(float depth)
825 {
826   mSizer.SetDepth(depth);
827   // node is being used in a separate thread; queue a message to set the value & base value
828   SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth);
829 }
830
831 Vector3 Actor::GetTargetSize() const
832 {
833   return mSizer.GetTargetSize();
834 }
835
836 const Vector3& Actor::GetCurrentSize() const
837 {
838   // node is being used in a separate thread; copy the value from the previous update
839   return GetNode().GetSize(GetEventThreadServices().GetEventBufferIndex());
840 }
841
842 Vector3 Actor::GetNaturalSize() const
843 {
844   // It is up to deriving classes to return the appropriate natural size
845   return Vector3(0.0f, 0.0f, 0.0f);
846 }
847
848 void Actor::SetResizePolicy(ResizePolicy::Type policy, Dimension::Type dimension)
849 {
850   mSizer.SetResizePolicy(policy, dimension);
851 }
852
853 ResizePolicy::Type Actor::GetResizePolicy(Dimension::Type dimension) const
854 {
855   return mSizer.GetResizePolicy(dimension);
856 }
857
858 void Actor::SetRelayoutEnabled(bool relayoutEnabled)
859 {
860   mSizer.SetRelayoutEnabled(relayoutEnabled);
861 }
862
863 bool Actor::IsRelayoutEnabled() const
864 {
865   return mSizer.IsRelayoutEnabled();
866 }
867
868 void Actor::SetLayoutDirty(bool dirty, Dimension::Type dimension)
869 {
870   mSizer.SetLayoutDirty(dirty, dimension);
871 }
872
873 bool Actor::IsLayoutDirty(Dimension::Type dimension) const
874 {
875   return mSizer.IsLayoutDirty(dimension);
876 }
877
878 bool Actor::RelayoutPossible(Dimension::Type dimension) const
879 {
880   return mSizer.RelayoutPossible(dimension);
881 }
882
883 bool Actor::RelayoutRequired(Dimension::Type dimension) const
884 {
885   return mSizer.RelayoutRequired(dimension);
886 }
887
888 uint32_t Actor::AddRenderer(Renderer& renderer)
889 {
890   if(!mRenderers)
891   {
892     mRenderers = new RendererContainer(GetEventThreadServices());
893   }
894   return mRenderers->Add(GetNode(), renderer, mIsBlendEquationSet, mBlendEquation);
895 }
896
897 uint32_t Actor::GetRendererCount() const
898 {
899   return mRenderers ? mRenderers->GetCount() : 0u;
900 }
901
902 RendererPtr Actor::GetRendererAt(uint32_t index)
903 {
904   return mRenderers ? mRenderers->GetRendererAt(index) : nullptr;
905 }
906
907 void Actor::RemoveRenderer(Renderer& renderer)
908 {
909   if(mRenderers)
910   {
911     mRenderers->Remove(GetNode(), renderer);
912   }
913 }
914
915 void Actor::RemoveRenderer(uint32_t index)
916 {
917   if(mRenderers)
918   {
919     mRenderers->Remove(GetNode(), index);
920   }
921 }
922
923 void Actor::SetBlendEquation(DevelBlendEquation::Type blendEquation)
924 {
925   if(Dali::Capabilities::IsBlendEquationSupported(blendEquation))
926   {
927     if(mBlendEquation != blendEquation)
928     {
929       mBlendEquation = blendEquation;
930       if(mRenderers)
931       {
932         mRenderers->SetBlending(blendEquation);
933       }
934     }
935     mIsBlendEquationSet = true;
936   }
937   else
938   {
939     DALI_LOG_ERROR("Invalid blend equation is entered.\n");
940   }
941 }
942
943 DevelBlendEquation::Type Actor::GetBlendEquation() const
944 {
945   return mBlendEquation;
946 }
947
948 void Actor::SetTransparent(bool transparent)
949 {
950   SetTransparentMessage(GetEventThreadServices(), GetNode(), transparent);
951 }
952
953 bool Actor::IsTransparent() const
954 {
955   return GetNode().IsTransparent();
956 }
957
958 void Actor::SetDrawMode(DrawMode::Type drawMode)
959 {
960   // this flag is not animatable so keep the value
961   mDrawMode = drawMode;
962
963   // node is being used in a separate thread; queue a message to set the value
964   SetDrawModeMessage(GetEventThreadServices(), GetNode(), drawMode);
965 }
966
967 bool Actor::ScreenToLocal(float& localX, float& localY, float screenX, float screenY) const
968 {
969   return mScene && OnScene() && ConvertScreenToLocalRenderTaskList(mScene->GetRenderTaskList(), GetNode().GetWorldMatrix(0), GetCurrentSize(), localX, localY, screenX, screenY);
970 }
971
972 bool Actor::ScreenToLocal(const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY) const
973 {
974   return OnScene() && ConvertScreenToLocalRenderTask(renderTask, GetNode().GetWorldMatrix(0), GetCurrentSize(), localX, localY, screenX, screenY);
975 }
976
977 bool Actor::ScreenToLocal(const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY) const
978 {
979   return OnScene() && ConvertScreenToLocal(viewMatrix, projectionMatrix, GetNode().GetWorldMatrix(0), GetCurrentSize(), viewport, localX, localY, screenX, screenY);
980 }
981
982 ActorGestureData& Actor::GetGestureData()
983 {
984   // Likely scenario is that once gesture-data is created for this actor, the actor will require
985   // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
986   if(nullptr == mGestureData)
987   {
988     mGestureData = new ActorGestureData;
989   }
990   return *mGestureData;
991 }
992
993 bool Actor::IsGestureRequired(GestureType::Value type) const
994 {
995   return mGestureData && mGestureData->IsGestureRequired(type);
996 }
997
998 bool Actor::EmitInterceptTouchEventSignal(const Dali::TouchEvent& touch)
999 {
1000   return EmitConsumingSignal(*this, mInterceptTouchedSignal, touch);
1001 }
1002
1003 bool Actor::EmitTouchEventSignal(const Dali::TouchEvent& touch)
1004 {
1005   return EmitConsumingSignal(*this, mTouchedSignal, touch);
1006 }
1007
1008 bool Actor::EmitHoverEventSignal(const Dali::HoverEvent& event)
1009 {
1010   return EmitConsumingSignal(*this, mHoveredSignal, event);
1011 }
1012
1013 bool Actor::EmitWheelEventSignal(const Dali::WheelEvent& event)
1014 {
1015   return EmitConsumingSignal(*this, mWheelEventSignal, event);
1016 }
1017
1018 void Actor::EmitVisibilityChangedSignal(bool visible, DevelActor::VisibilityChange::Type type)
1019 {
1020   EmitSignal(*this, mVisibilityChangedSignal, visible, type);
1021 }
1022
1023 void Actor::EmitLayoutDirectionChangedSignal(LayoutDirection::Type type)
1024 {
1025   EmitSignal(*this, mLayoutDirectionChangedSignal, type);
1026 }
1027
1028 bool Actor::EmitHitTestResultSignal(Integration::Point point, Vector2 hitPointLocal, uint32_t timeStamp)
1029 {
1030   bool hit = true;
1031
1032   if(IsHitTestResultRequired())
1033   {
1034     Dali::Actor        handle(this);
1035     Integration::Point newPoint(point);
1036     newPoint.SetHitActor(handle);
1037     newPoint.SetLocalPosition(hitPointLocal);
1038     Dali::TouchEvent touchEvent = Dali::Integration::NewTouchEvent(timeStamp, newPoint);
1039     hit                         = mHitTestResultSignal.Emit(handle, touchEvent);
1040   }
1041   return hit;
1042 }
1043
1044 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
1045 {
1046   return mParentImpl.ChildAddedSignal();
1047 }
1048
1049 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
1050 {
1051   return mParentImpl.ChildRemovedSignal();
1052 }
1053
1054 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
1055 {
1056   return mParentImpl.ChildOrderChangedSignal();
1057 }
1058
1059 Actor::Actor(DerivedType derivedType, const SceneGraph::Node& node)
1060 : Object(&node),
1061   mParentImpl(*this),
1062   mSizer(*this),
1063   mParent(nullptr),
1064   mScene(nullptr),
1065   mRenderers(nullptr),
1066   mParentOrigin(nullptr),
1067   mAnchorPoint(nullptr),
1068   mGestureData(nullptr),
1069   mInterceptTouchedSignal(),
1070   mTouchedSignal(),
1071   mHoveredSignal(),
1072   mWheelEventSignal(),
1073   mOnSceneSignal(),
1074   mOffSceneSignal(),
1075   mOnRelayoutSignal(),
1076   mVisibilityChangedSignal(),
1077   mLayoutDirectionChangedSignal(),
1078   mHitTestResultSignal(),
1079   mTargetOrientation(Quaternion::IDENTITY),
1080   mTargetColor(Color::WHITE),
1081   mTargetPosition(Vector3::ZERO),
1082   mTargetScale(Vector3::ONE),
1083   mTouchAreaOffset(0, 0, 0, 0),
1084   mName(),
1085   mSortedDepth(0u),
1086   mDepth(0u),
1087   mLayer3DParentsCount(0),
1088   mIsRoot(ROOT_LAYER == derivedType),
1089   mIsLayer(LAYER == derivedType || ROOT_LAYER == derivedType),
1090   mIsOnScene(false),
1091   mSensitive(true),
1092   mLeaveRequired(false),
1093   mKeyboardFocusable(false),
1094   mKeyboardFocusableChildren(true),
1095   mTouchFocusable(false),
1096   mOnSceneSignalled(false),
1097   mInheritPosition(true),
1098   mInheritOrientation(true),
1099   mInheritScale(true),
1100   mPositionUsesAnchorPoint(true),
1101   mVisible(true),
1102   mInheritLayoutDirection(true),
1103   mCaptureAllTouchAfterStart(false),
1104   mIsBlendEquationSet(false),
1105   mNeedGesturePropagation(false),
1106   mUserInteractionEnabled(true),
1107   mAllowOnlyOwnTouch(false),
1108   mLayoutDirection(LayoutDirection::LEFT_TO_RIGHT),
1109   mDrawMode(DrawMode::NORMAL),
1110   mColorMode(Node::DEFAULT_COLOR_MODE),
1111   mClippingMode(ClippingMode::DISABLED),
1112   mBlendEquation(DevelBlendEquation::ADD)
1113 {
1114 }
1115
1116 void Actor::Initialize()
1117 {
1118   OnInitialize();
1119
1120   GetEventThreadServices().RegisterObject(this);
1121 }
1122
1123 Actor::~Actor()
1124 {
1125   // Remove mParent pointers from children even if we're destroying core,
1126   // to guard against GetParent() & Unparent() calls from CustomActor destructors.
1127   UnparentChildren();
1128   delete mRenderers;
1129
1130   // Guard to allow handle destruction after Core has been destroyed
1131   if(EventThreadServices::IsCoreRunning())
1132   {
1133     // Root layer will destroy its node in its own destructor
1134     if(!mIsRoot)
1135     {
1136       DestroyNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
1137
1138       GetEventThreadServices().UnregisterObject(this);
1139     }
1140   }
1141
1142   // Cleanup optional gesture data
1143   delete mGestureData;
1144
1145   // Cleanup optional parent origin and anchor
1146   delete mParentOrigin;
1147   delete mAnchorPoint;
1148 }
1149
1150 void Actor::Add(Actor& child, bool notify)
1151 {
1152   mParentImpl.Add(child, notify);
1153 }
1154
1155 void Actor::Remove(Actor& child, bool notify)
1156 {
1157   mParentImpl.Remove(child, notify);
1158 }
1159
1160 void Actor::SwitchParent(Actor& newParent)
1161 {
1162   if(this == &newParent)
1163   {
1164     DALI_LOG_ERROR("Cannot add actor to itself");
1165     return;
1166   }
1167
1168   if(!this->OnScene() || !newParent.OnScene())
1169   {
1170     DALI_LOG_ERROR("Both of current parent and new parent must be on Scene");
1171     return;
1172   }
1173
1174   newParent.Add(*this, false);
1175 }
1176
1177 uint32_t Actor::GetChildCount() const
1178 {
1179   return mParentImpl.GetChildCount();
1180 }
1181
1182 ActorPtr Actor::GetChildAt(uint32_t index) const
1183 {
1184   return mParentImpl.GetChildAt(index);
1185 }
1186
1187 ActorContainer& Actor::GetChildrenInternal()
1188 {
1189   return mParentImpl.GetChildrenInternal();
1190 }
1191
1192 ActorPtr Actor::FindChildByName(ConstString actorName)
1193 {
1194   return mParentImpl.FindChildByName(actorName);
1195 }
1196
1197 ActorPtr Actor::FindChildById(const uint32_t id)
1198 {
1199   return mParentImpl.FindChildById(id);
1200 }
1201
1202 void Actor::UnparentChildren()
1203 {
1204   mParentImpl.UnparentChildren();
1205 }
1206
1207 void Actor::ConnectToScene(uint32_t parentDepth, uint32_t layer3DParentsCount, bool notify)
1208 {
1209   // This container is used instead of walking the Actor hierarchy.
1210   // It protects us when the Actor hierarchy is modified during OnSceneConnectionExternal callbacks.
1211   ActorContainer connectionList;
1212
1213   if(mScene)
1214   {
1215     mScene->RequestRebuildDepthTree();
1216   }
1217
1218   // This stage is not interrupted by user callbacks.
1219   mParentImpl.RecursiveConnectToScene(connectionList, layer3DParentsCount, parentDepth + 1);
1220
1221   // Notify applications about the newly connected actors.
1222   for(const auto& actor : connectionList)
1223   {
1224     actor->NotifyStageConnection(notify);
1225   }
1226
1227   RelayoutRequest();
1228 }
1229
1230 /**
1231  * This method is called when the Actor is connected to the Stage.
1232  * The parent must have added its Node to the scene-graph.
1233  * The child must connect its Node to the parent's Node.
1234  * This is recursive; the child calls ConnectToScene() for its children.
1235  */
1236 void Actor::ConnectToSceneGraph()
1237 {
1238   DALI_ASSERT_DEBUG(mParent != NULL);
1239
1240   // Reparent Node in next Update
1241   ConnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetParent()->GetNode(), GetNode());
1242
1243   // Request relayout on all actors that are added to the scenegraph
1244   RelayoutRequest();
1245
1246   // Notification for Object::Observers
1247   OnSceneObjectAdd();
1248 }
1249
1250 void Actor::NotifyStageConnection(bool notify)
1251 {
1252   // Actors can be removed (in a callback), before the on-stage stage is reported.
1253   // The actor may also have been reparented, in which case mOnSceneSignalled will be true.
1254   if(OnScene() && !mOnSceneSignalled)
1255   {
1256     if(notify)
1257     {
1258       // Notification for external (CustomActor) derived classes
1259       OnSceneConnectionExternal(mDepth);
1260
1261       if(!mOnSceneSignal.Empty())
1262       {
1263         Dali::Actor handle(this);
1264         mOnSceneSignal.Emit(handle);
1265       }
1266     }
1267
1268     // Guard against Remove during callbacks
1269     if(OnScene())
1270     {
1271       mOnSceneSignalled = true; // signal required next time Actor is removed
1272     }
1273   }
1274 }
1275
1276 void Actor::DisconnectFromStage(bool notify)
1277 {
1278   // This container is used instead of walking the Actor hierachy.
1279   // It protects us when the Actor hierachy is modified during OnSceneDisconnectionExternal callbacks.
1280   ActorContainer disconnectionList;
1281
1282   if(mScene)
1283   {
1284     mScene->RequestRebuildDepthTree();
1285   }
1286
1287   // This stage is not interrupted by user callbacks
1288   mParentImpl.RecursiveDisconnectFromScene(disconnectionList);
1289
1290   // Notify applications about the newly disconnected actors.
1291   for(const auto& actor : disconnectionList)
1292   {
1293     actor->NotifyStageDisconnection(notify);
1294   }
1295 }
1296
1297 /**
1298  * This method is called by an actor or its parent, before a node removal message is sent.
1299  * This is recursive; the child calls DisconnectFromStage() for its children.
1300  */
1301 void Actor::DisconnectFromSceneGraph()
1302 {
1303   // Notification for Object::Observers
1304   OnSceneObjectRemove();
1305 }
1306
1307 void Actor::NotifyStageDisconnection(bool notify)
1308 {
1309   // Actors can be added (in a callback), before the off-stage state is reported.
1310   // Also if the actor was added & removed before mOnSceneSignalled was set, then we don't notify here.
1311   // only do this step if there is a stage, i.e. Core is not being shut down
1312   if(EventThreadServices::IsCoreRunning() && !OnScene() && mOnSceneSignalled)
1313   {
1314     if(notify)
1315     {
1316       // Notification for external (CustomeActor) derived classes
1317       OnSceneDisconnectionExternal();
1318
1319       if(!mOffSceneSignal.Empty())
1320       {
1321         Dali::Actor handle(this);
1322         mOffSceneSignal.Emit(handle);
1323       }
1324     }
1325
1326     // Guard against Add during callbacks
1327     if(!OnScene())
1328     {
1329       mOnSceneSignalled = false; // signal required next time Actor is added
1330     }
1331   }
1332 }
1333
1334 bool Actor::IsNodeConnected() const
1335 {
1336   return OnScene() && (IsRoot() || GetNode().GetParent());
1337 }
1338
1339 // This method initiates traversal of the actor tree using depth-first
1340 // traversal to set a depth index based on traversal order. It sends a
1341 // single message to update manager to update all the actor's nodes in
1342 // this tree with the depth index. The sceneGraphNodeDepths vector's
1343 // elements are ordered by depth, and could be used to reduce sorting
1344 // in the update thread.
1345 void Actor::RebuildDepthTree()
1346 {
1347   DALI_LOG_TIMER_START(depthTimer);
1348
1349   // Vector of scene-graph nodes and their depths to send to UpdateManager
1350   // in a single message
1351   OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths(new SceneGraph::NodeDepths());
1352
1353   int32_t depthIndex = 1;
1354   mParentImpl.DepthTraverseActorTree(sceneGraphNodeDepths, depthIndex);
1355
1356   SetDepthIndicesMessage(GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths);
1357   DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
1358 }
1359
1360 void Actor::SetDefaultProperty(Property::Index index, const Property::Value& property)
1361 {
1362   PropertyHandler::SetDefaultProperty(*this, index, property);
1363 }
1364
1365 // TODO: This method needs to be removed
1366 void Actor::SetSceneGraphProperty(Property::Index index, const PropertyMetadata& entry, const Property::Value& value)
1367 {
1368   PropertyHandler::SetSceneGraphProperty(index, entry, value, GetEventThreadServices(), GetNode());
1369 }
1370
1371 Property::Value Actor::GetDefaultProperty(Property::Index index) const
1372 {
1373   Property::Value value;
1374
1375   if(!GetCachedPropertyValue(index, value))
1376   {
1377     // If property value is not stored in the event-side, then it must be a scene-graph only property
1378     GetCurrentPropertyValue(index, value);
1379   }
1380
1381   return value;
1382 }
1383
1384 Property::Value Actor::GetDefaultPropertyCurrentValue(Property::Index index) const
1385 {
1386   Property::Value value;
1387
1388   if(!GetCurrentPropertyValue(index, value))
1389   {
1390     // If unable to retrieve scene-graph property value, then it must be an event-side only property
1391     GetCachedPropertyValue(index, value);
1392   }
1393
1394   return value;
1395 }
1396
1397 void Actor::OnNotifyDefaultPropertyAnimation(Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType)
1398 {
1399   PropertyHandler::OnNotifyDefaultPropertyAnimation(*this, animation, index, value, animationType);
1400 }
1401
1402 const PropertyBase* Actor::GetSceneObjectAnimatableProperty(Property::Index index) const
1403 {
1404   const PropertyBase* property = PropertyHandler::GetSceneObjectAnimatableProperty(index, GetNode());
1405   if(!property)
1406   {
1407     // not our property, ask base
1408     property = Object::GetSceneObjectAnimatableProperty(index);
1409   }
1410
1411   return property;
1412 }
1413
1414 const PropertyInputImpl* Actor::GetSceneObjectInputProperty(Property::Index index) const
1415 {
1416   const PropertyInputImpl* property = PropertyHandler::GetSceneObjectInputProperty(index, GetNode());
1417   if(!property)
1418   {
1419     // reuse animatable property getter as animatable properties are inputs as well
1420     // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
1421     property = GetSceneObjectAnimatableProperty(index);
1422   }
1423
1424   return property;
1425 }
1426
1427 int32_t Actor::GetPropertyComponentIndex(Property::Index index) const
1428 {
1429   int32_t componentIndex = PropertyHandler::GetPropertyComponentIndex(index);
1430   if(Property::INVALID_COMPONENT_INDEX == componentIndex)
1431   {
1432     // ask base
1433     componentIndex = Object::GetPropertyComponentIndex(index);
1434   }
1435
1436   return componentIndex;
1437 }
1438
1439 const SceneGraph::Node& Actor::GetNode() const
1440 {
1441   return *static_cast<const SceneGraph::Node*>(mUpdateObject);
1442 }
1443
1444 void Actor::Raise()
1445 {
1446   CheckParentAndCall(mParent, *this, &ActorParent::RaiseChild);
1447 }
1448
1449 void Actor::Lower()
1450 {
1451   CheckParentAndCall(mParent, *this, &ActorParent::LowerChild);
1452 }
1453
1454 void Actor::RaiseToTop()
1455 {
1456   CheckParentAndCall(mParent, *this, &ActorParent::RaiseChildToTop);
1457 }
1458
1459 void Actor::LowerToBottom()
1460 {
1461   CheckParentAndCall(mParent, *this, &ActorParent::LowerChildToBottom);
1462 }
1463
1464 void Actor::RaiseAbove(Internal::Actor& target)
1465 {
1466   CheckParentAndCall(mParent, *this, target, &ActorParent::RaiseChildAbove);
1467 }
1468
1469 void Actor::LowerBelow(Internal::Actor& target)
1470 {
1471   CheckParentAndCall(mParent, *this, target, &ActorParent::LowerChildBelow);
1472 }
1473
1474 void Actor::SetParent(ActorParent* parent, bool notify)
1475 {
1476   if(parent)
1477   {
1478     DALI_ASSERT_ALWAYS(!mParent && "Actor cannot have 2 parents");
1479
1480     mParent            = parent;
1481     Actor* parentActor = static_cast<Actor*>(parent);
1482     mScene             = parentActor->mScene;
1483
1484     if(EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
1485        parentActor->OnScene())
1486     {
1487       // Instruct each actor to create a corresponding node in the scene graph
1488       ConnectToScene(parentActor->GetHierarchyDepth(), parentActor->GetLayer3DParentCount(), notify);
1489     }
1490
1491     // Resolve the name and index for the child properties if any
1492     ResolveChildProperties();
1493   }
1494   else // parent being set to NULL
1495   {
1496     DALI_ASSERT_ALWAYS(mParent != nullptr && "Actor should have a parent");
1497
1498     mParent = nullptr;
1499
1500     if(EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
1501        OnScene())
1502     {
1503       // Disconnect the Node & its children from the scene-graph.
1504       DisconnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
1505
1506       // Instruct each actor to discard pointers to the scene-graph
1507       DisconnectFromStage(notify);
1508     }
1509
1510     mScene = nullptr;
1511   }
1512 }
1513
1514 Rect<> Actor::CalculateScreenExtents() const
1515 {
1516   if(mLayer3DParentsCount == 0)
1517   {
1518     // We can assume that this actor is under 2d layer. Use faster, but imprecise algorithm
1519     auto        screenPosition = GetCurrentScreenPosition();
1520     BufferIndex bufferIndex    = GetEventThreadServices().GetEventBufferIndex();
1521     return CalculateActorScreenExtents(*this, screenPosition, bufferIndex);
1522   }
1523   else
1524   {
1525     BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
1526     return CalculateActorScreenExtentsRenderTaskList(*this, bufferIndex);
1527   }
1528 }
1529
1530 Vector3 Actor::GetAnchorPointForPosition() const
1531 {
1532   return (mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT);
1533 }
1534
1535 bool Actor::GetCachedPropertyValue(Property::Index index, Property::Value& value) const
1536 {
1537   return PropertyHandler::GetCachedPropertyValue(*this, index, value);
1538 }
1539
1540 bool Actor::GetCurrentPropertyValue(Property::Index index, Property::Value& value) const
1541 {
1542   return PropertyHandler::GetCurrentPropertyValue(*this, index, value);
1543 }
1544
1545 bool Actor::RelayoutDependentOnParent(Dimension::Type dimension)
1546 {
1547   return mSizer.RelayoutDependentOnParent(dimension);
1548 }
1549
1550 bool Actor::RelayoutDependentOnChildren(Dimension::Type dimension)
1551 {
1552   return mSizer.RelayoutDependentOnChildrenBase(dimension);
1553 }
1554
1555 bool Actor::RelayoutDependentOnDimension(Dimension::Type dimension, Dimension::Type dependentDimension)
1556 {
1557   return mSizer.RelayoutDependentOnDimension(dimension, dependentDimension);
1558 }
1559
1560 void Actor::SetPadding(const Vector2& padding, Dimension::Type dimension)
1561 {
1562   mSizer.SetPadding(padding, dimension);
1563 }
1564
1565 Vector2 Actor::GetPadding(Dimension::Type dimension) const
1566 {
1567   return mSizer.GetPadding(dimension);
1568 }
1569
1570 void Actor::SetLayoutNegotiated(bool negotiated, Dimension::Type dimension)
1571 {
1572   mSizer.SetLayoutNegotiated(negotiated, dimension);
1573 }
1574
1575 bool Actor::IsLayoutNegotiated(Dimension::Type dimension) const
1576 {
1577   return mSizer.IsLayoutNegotiated(dimension);
1578 }
1579
1580 float Actor::GetHeightForWidthBase(float width)
1581 {
1582   // Can be overridden in derived class
1583   return mSizer.GetHeightForWidthBase(width);
1584 }
1585
1586 float Actor::GetWidthForHeightBase(float height)
1587 {
1588   // Can be overridden in derived class
1589   return mSizer.GetWidthForHeightBase(height);
1590 }
1591
1592 float Actor::CalculateChildSizeBase(const Dali::Actor& child, Dimension::Type dimension)
1593 {
1594   // Can be overridden in derived class
1595   return mSizer.CalculateChildSizeBase(child, dimension);
1596 }
1597
1598 bool Actor::RelayoutDependentOnChildrenBase(Dimension::Type dimension)
1599 {
1600   return mSizer.RelayoutDependentOnChildrenBase(dimension);
1601 }
1602
1603 float Actor::CalculateChildSize(const Dali::Actor& child, Dimension::Type dimension)
1604 {
1605   // Can be overridden in derived class
1606   return mSizer.CalculateChildSizeBase(child, dimension);
1607 }
1608
1609 float Actor::GetHeightForWidth(float width)
1610 {
1611   // Can be overridden in derived class
1612   return mSizer.GetHeightForWidthBase(width);
1613 }
1614
1615 float Actor::GetWidthForHeight(float height)
1616 {
1617   // Can be overridden in derived class
1618   return mSizer.GetWidthForHeightBase(height);
1619 }
1620
1621 float Actor::GetRelayoutSize(Dimension::Type dimension) const
1622 {
1623   return mSizer.GetRelayoutSize(dimension);
1624 }
1625
1626 void Actor::NegotiateSize(const Vector2& allocatedSize, RelayoutContainer& container)
1627 {
1628   mSizer.NegotiateSize(allocatedSize, container);
1629 }
1630
1631 void Actor::RelayoutRequest(Dimension::Type dimension)
1632 {
1633   mSizer.RelayoutRequest(dimension);
1634 }
1635
1636 void Actor::SetMinimumSize(float size, Dimension::Type dimension)
1637 {
1638   mSizer.SetMinimumSize(size, dimension);
1639 }
1640
1641 float Actor::GetMinimumSize(Dimension::Type dimension) const
1642 {
1643   return mSizer.GetMinimumSize(dimension);
1644 }
1645
1646 void Actor::SetMaximumSize(float size, Dimension::Type dimension)
1647 {
1648   mSizer.SetMaximumSize(size, dimension);
1649 }
1650
1651 float Actor::GetMaximumSize(Dimension::Type dimension) const
1652 {
1653   return mSizer.GetMaximumSize(dimension);
1654 }
1655
1656 void Actor::SetVisibleInternal(bool visible, SendMessage::Type sendMessage)
1657 {
1658   if(mVisible != visible)
1659   {
1660     if(sendMessage == SendMessage::TRUE)
1661     {
1662       // node is being used in a separate thread; queue a message to set the value & base value
1663       SceneGraph::NodePropertyMessage<bool>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible);
1664
1665       RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
1666     }
1667
1668     mVisible = visible;
1669
1670     // Emit the signal on this actor and all its children
1671     mParentImpl.EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::SELF);
1672   }
1673 }
1674
1675 void Actor::SetSiblingOrderOfChild(Actor& child, uint32_t order)
1676 {
1677   mParentImpl.SetSiblingOrderOfChild(child, order);
1678 }
1679
1680 uint32_t Actor::GetSiblingOrderOfChild(const Actor& child) const
1681 {
1682   return mParentImpl.GetSiblingOrderOfChild(child);
1683 }
1684
1685 void Actor::RaiseChild(Actor& child)
1686 {
1687   mParentImpl.RaiseChild(child);
1688 }
1689
1690 void Actor::LowerChild(Actor& child)
1691 {
1692   mParentImpl.LowerChild(child);
1693 }
1694
1695 void Actor::RaiseChildToTop(Actor& child)
1696 {
1697   mParentImpl.RaiseChildToTop(child);
1698 }
1699
1700 void Actor::LowerChildToBottom(Actor& child)
1701 {
1702   mParentImpl.LowerChildToBottom(child);
1703 }
1704
1705 void Actor::RaiseChildAbove(Actor& child, Actor& target)
1706 {
1707   mParentImpl.RaiseChildAbove(child, target);
1708 }
1709
1710 void Actor::LowerChildBelow(Actor& child, Actor& target)
1711 {
1712   mParentImpl.LowerChildBelow(child, target);
1713 }
1714
1715 void Actor::SetInheritLayoutDirection(bool inherit)
1716 {
1717   if(mInheritLayoutDirection != inherit)
1718   {
1719     mInheritLayoutDirection = inherit;
1720
1721     if(inherit && mParent)
1722     {
1723       mParentImpl.InheritLayoutDirectionRecursively(GetParent()->mLayoutDirection);
1724     }
1725   }
1726 }
1727
1728 void Actor::SetUpdateAreaHint(const Vector4& updateAreaHint)
1729 {
1730   // node is being used in a separate thread; queue a message to set the value & base value
1731   SceneGraph::NodePropertyMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mUpdateAreaHint, &AnimatableProperty<Vector4>::Bake, updateAreaHint);
1732 }
1733
1734 } // namespace Internal
1735
1736 } // namespace Dali