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