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