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) 2021 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
38 #include <dali/internal/event/actors/actor-coords.h>
39 #include <dali/internal/event/actors/actor-parent.h>
40 #include <dali/internal/event/actors/actor-property-handler.h>
41 #include <dali/internal/event/actors/camera-actor-impl.h>
42 #include <dali/internal/event/common/event-thread-services.h>
43 #include <dali/internal/event/common/property-helper.h>
44 #include <dali/internal/event/common/scene-impl.h>
45 #include <dali/internal/event/common/stage-impl.h>
46 #include <dali/internal/event/common/thread-local-storage.h>
47 #include <dali/internal/event/common/type-info-impl.h>
48 #include <dali/internal/event/events/actor-gesture-data.h>
49 #include <dali/internal/event/render-tasks/render-task-impl.h>
50 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
51 #include <dali/internal/event/rendering/renderer-impl.h>
52 #include <dali/internal/update/manager/update-manager.h>
53 #include <dali/internal/update/nodes/node-messages.h>
54 #include <dali/public-api/size-negotiation/relayout-container.h>
55
56 using Dali::Internal::SceneGraph::AnimatableProperty;
57 using Dali::Internal::SceneGraph::Node;
58 using Dali::Internal::SceneGraph::PropertyBase;
59
60 #if defined(DEBUG_ENABLED)
61 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER");
62 #endif
63
64 namespace Dali
65 {
66 namespace Internal
67 {
68 namespace // unnamed namespace
69 {
70 // Properties
71
72 /**
73  * We want to discourage the use of property strings (minimize string comparisons),
74  * particularly for the default properties.
75  *              Name                  Type   writable animatable constraint-input  enum for index-checking
76  */
77 DALI_PROPERTY_TABLE_BEGIN
78 DALI_PROPERTY("parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN)
79 DALI_PROPERTY("parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X)
80 DALI_PROPERTY("parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y)
81 DALI_PROPERTY("parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z)
82 DALI_PROPERTY("anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT)
83 DALI_PROPERTY("anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X)
84 DALI_PROPERTY("anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y)
85 DALI_PROPERTY("anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z)
86 DALI_PROPERTY("size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE)
87 DALI_PROPERTY("sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH)
88 DALI_PROPERTY("sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT)
89 DALI_PROPERTY("sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH)
90 DALI_PROPERTY("position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION)
91 DALI_PROPERTY("positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X)
92 DALI_PROPERTY("positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y)
93 DALI_PROPERTY("positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z)
94 DALI_PROPERTY("worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION)
95 DALI_PROPERTY("worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X)
96 DALI_PROPERTY("worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y)
97 DALI_PROPERTY("worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z)
98 DALI_PROPERTY("orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION)
99 DALI_PROPERTY("worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION)
100 DALI_PROPERTY("scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE)
101 DALI_PROPERTY("scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X)
102 DALI_PROPERTY("scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y)
103 DALI_PROPERTY("scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z)
104 DALI_PROPERTY("worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE)
105 DALI_PROPERTY("visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE)
106 DALI_PROPERTY("color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR)
107 DALI_PROPERTY("colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED)
108 DALI_PROPERTY("colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN)
109 DALI_PROPERTY("colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE)
110 DALI_PROPERTY("colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA)
111 DALI_PROPERTY("worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR)
112 DALI_PROPERTY("worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX)
113 DALI_PROPERTY("name", STRING, true, false, false, Dali::Actor::Property::NAME)
114 DALI_PROPERTY("sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE)
115 DALI_PROPERTY("leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED)
116 DALI_PROPERTY("inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION)
117 DALI_PROPERTY("inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE)
118 DALI_PROPERTY("colorMode", INTEGER, true, false, false, Dali::Actor::Property::COLOR_MODE)
119 DALI_PROPERTY("drawMode", INTEGER, true, false, false, Dali::Actor::Property::DRAW_MODE)
120 DALI_PROPERTY("sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR)
121 DALI_PROPERTY("widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY)
122 DALI_PROPERTY("heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY)
123 DALI_PROPERTY("sizeScalePolicy", INTEGER, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY)
124 DALI_PROPERTY("widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT)
125 DALI_PROPERTY("heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH)
126 DALI_PROPERTY("padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING)
127 DALI_PROPERTY("minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE)
128 DALI_PROPERTY("maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE)
129 DALI_PROPERTY("inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION)
130 DALI_PROPERTY("clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE)
131 DALI_PROPERTY("layoutDirection", STRING, true, false, false, Dali::Actor::Property::LAYOUT_DIRECTION)
132 DALI_PROPERTY("inheritLayoutDirection", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION)
133 DALI_PROPERTY("opacity", FLOAT, true, true, true, Dali::Actor::Property::OPACITY)
134 DALI_PROPERTY("screenPosition", VECTOR2, false, false, false, Dali::Actor::Property::SCREEN_POSITION)
135 DALI_PROPERTY("positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::Actor::Property::POSITION_USES_ANCHOR_POINT)
136 DALI_PROPERTY("culled", BOOLEAN, false, false, true, Dali::Actor::Property::CULLED)
137 DALI_PROPERTY("id", INTEGER, false, false, false, Dali::Actor::Property::ID)
138 DALI_PROPERTY("hierarchyDepth", INTEGER, false, false, false, Dali::Actor::Property::HIERARCHY_DEPTH)
139 DALI_PROPERTY("isRoot", BOOLEAN, false, false, false, Dali::Actor::Property::IS_ROOT)
140 DALI_PROPERTY("isLayer", BOOLEAN, false, false, false, Dali::Actor::Property::IS_LAYER)
141 DALI_PROPERTY("connectedToScene", BOOLEAN, false, false, false, Dali::Actor::Property::CONNECTED_TO_SCENE)
142 DALI_PROPERTY("keyboardFocusable", BOOLEAN, true, false, false, Dali::Actor::Property::KEYBOARD_FOCUSABLE)
143 DALI_PROPERTY("siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER)
144 DALI_PROPERTY("updateSizeHint", VECTOR2, true, false, false, Dali::DevelActor::Property::UPDATE_SIZE_HINT)
145 DALI_PROPERTY("captureAllTouchAfterStart", BOOLEAN, true, false, false, Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START)
146 DALI_PROPERTY("touchAreaOffset", RECTANGLE, true, false, false, Dali::DevelActor::Property::TOUCH_AREA_OFFSET)
147 DALI_PROPERTY("blendEquation", INTEGER, true, false, false, Dali::DevelActor::Property::BLEND_EQUATION)
148 DALI_PROPERTY("touchFocusable", BOOLEAN, true, false, false, Dali::DevelActor::Property::TOUCH_FOCUSABLE)
149 DALI_PROPERTY("keyboardFocusableChildren", BOOLEAN, true, false, false, Dali::DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN)
150 DALI_PROPERTY("userInteractionEnabled", BOOLEAN, true, false, false, Dali::DevelActor::Property::USER_INTERACTION_ENABLED)
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 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
1019 {
1020   return mParentImpl.ChildAddedSignal();
1021 }
1022
1023 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
1024 {
1025   return mParentImpl.ChildRemovedSignal();
1026 }
1027
1028 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
1029 {
1030   return mParentImpl.ChildOrderChangedSignal();
1031 }
1032
1033 Actor::Actor(DerivedType derivedType, const SceneGraph::Node& node)
1034 : Object(&node),
1035   mParentImpl(*this),
1036   mSizer(*this),
1037   mParent(nullptr),
1038   mScene(nullptr),
1039   mRenderers(nullptr),
1040   mParentOrigin(nullptr),
1041   mAnchorPoint(nullptr),
1042   mGestureData(nullptr),
1043   mInterceptTouchedSignal(),
1044   mTouchedSignal(),
1045   mHoveredSignal(),
1046   mWheelEventSignal(),
1047   mOnSceneSignal(),
1048   mOffSceneSignal(),
1049   mOnRelayoutSignal(),
1050   mVisibilityChangedSignal(),
1051   mLayoutDirectionChangedSignal(),
1052   mTargetOrientation(Quaternion::IDENTITY),
1053   mTargetColor(Color::WHITE),
1054   mTargetPosition(Vector3::ZERO),
1055   mTargetScale(Vector3::ONE),
1056   mTouchAreaOffset(0, 0, 0, 0),
1057   mName(),
1058   mSortedDepth(0u),
1059   mDepth(0u),
1060   mIsRoot(ROOT_LAYER == derivedType),
1061   mIsLayer(LAYER == derivedType || ROOT_LAYER == derivedType),
1062   mIsOnScene(false),
1063   mSensitive(true),
1064   mLeaveRequired(false),
1065   mKeyboardFocusable(false),
1066   mKeyboardFocusableChildren(true),
1067   mTouchFocusable(false),
1068   mOnSceneSignalled(false),
1069   mInheritPosition(true),
1070   mInheritOrientation(true),
1071   mInheritScale(true),
1072   mPositionUsesAnchorPoint(true),
1073   mVisible(true),
1074   mInheritLayoutDirection(true),
1075   mCaptureAllTouchAfterStart(false),
1076   mIsBlendEquationSet(false),
1077   mNeedGesturePropagation(false),
1078   mUserInteractionEnabled(true),
1079   mLayoutDirection(LayoutDirection::LEFT_TO_RIGHT),
1080   mDrawMode(DrawMode::NORMAL),
1081   mColorMode(Node::DEFAULT_COLOR_MODE),
1082   mClippingMode(ClippingMode::DISABLED),
1083   mBlendEquation(DevelBlendEquation::ADD)
1084 {
1085 }
1086
1087 void Actor::Initialize()
1088 {
1089   OnInitialize();
1090
1091   GetEventThreadServices().RegisterObject(this);
1092 }
1093
1094 Actor::~Actor()
1095 {
1096   // Remove mParent pointers from children even if we're destroying core,
1097   // to guard against GetParent() & Unparent() calls from CustomActor destructors.
1098   UnparentChildren();
1099   delete mRenderers;
1100
1101   // Guard to allow handle destruction after Core has been destroyed
1102   if(EventThreadServices::IsCoreRunning())
1103   {
1104     // Root layer will destroy its node in its own destructor
1105     if(!mIsRoot)
1106     {
1107       DestroyNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
1108
1109       GetEventThreadServices().UnregisterObject(this);
1110     }
1111   }
1112
1113   // Cleanup optional gesture data
1114   delete mGestureData;
1115
1116   // Cleanup optional parent origin and anchor
1117   delete mParentOrigin;
1118   delete mAnchorPoint;
1119 }
1120
1121 void Actor::Add(Actor& child, bool notify)
1122 {
1123   mParentImpl.Add(child, notify);
1124 }
1125
1126 void Actor::Remove(Actor& child, bool notify)
1127 {
1128   mParentImpl.Remove(child, notify);
1129 }
1130
1131 void Actor::SwitchParent(Actor& newParent)
1132 {
1133   if(this == &newParent)
1134   {
1135     DALI_LOG_ERROR("Cannot add actor to itself");
1136     return;
1137   }
1138
1139   if(!this->OnScene() || !newParent.OnScene())
1140   {
1141     DALI_LOG_ERROR("Both of current parent and new parent must be on Scene");
1142     return;
1143   }
1144
1145   newParent.Add(*this, false);
1146 }
1147
1148 uint32_t Actor::GetChildCount() const
1149 {
1150   return mParentImpl.GetChildCount();
1151 }
1152
1153 ActorPtr Actor::GetChildAt(uint32_t index) const
1154 {
1155   return mParentImpl.GetChildAt(index);
1156 }
1157
1158 ActorContainer& Actor::GetChildrenInternal()
1159 {
1160   return mParentImpl.GetChildrenInternal();
1161 }
1162
1163 ActorPtr Actor::FindChildByName(ConstString actorName)
1164 {
1165   return mParentImpl.FindChildByName(actorName);
1166 }
1167
1168 ActorPtr Actor::FindChildById(const uint32_t id)
1169 {
1170   return mParentImpl.FindChildById(id);
1171 }
1172
1173 void Actor::UnparentChildren()
1174 {
1175   mParentImpl.UnparentChildren();
1176 }
1177
1178 void Actor::ConnectToScene(uint32_t parentDepth, bool notify)
1179 {
1180   // This container is used instead of walking the Actor hierarchy.
1181   // It protects us when the Actor hierarchy is modified during OnSceneConnectionExternal callbacks.
1182   ActorContainer connectionList;
1183
1184   if(mScene)
1185   {
1186     mScene->RequestRebuildDepthTree();
1187   }
1188
1189   // This stage is not interrupted by user callbacks.
1190   mParentImpl.RecursiveConnectToScene(connectionList, parentDepth + 1);
1191
1192   // Notify applications about the newly connected actors.
1193   for(const auto& actor : connectionList)
1194   {
1195     actor->NotifyStageConnection(notify);
1196   }
1197
1198   RelayoutRequest();
1199 }
1200
1201 /**
1202  * This method is called when the Actor is connected to the Stage.
1203  * The parent must have added its Node to the scene-graph.
1204  * The child must connect its Node to the parent's Node.
1205  * This is recursive; the child calls ConnectToScene() for its children.
1206  */
1207 void Actor::ConnectToSceneGraph()
1208 {
1209   DALI_ASSERT_DEBUG(mParent != NULL);
1210
1211   // Reparent Node in next Update
1212   ConnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetParent()->GetNode(), GetNode());
1213
1214   // Request relayout on all actors that are added to the scenegraph
1215   RelayoutRequest();
1216
1217   // Notification for Object::Observers
1218   OnSceneObjectAdd();
1219 }
1220
1221 void Actor::NotifyStageConnection(bool notify)
1222 {
1223   // Actors can be removed (in a callback), before the on-stage stage is reported.
1224   // The actor may also have been reparented, in which case mOnSceneSignalled will be true.
1225   if(OnScene() && !mOnSceneSignalled)
1226   {
1227     if(notify)
1228     {
1229       // Notification for external (CustomActor) derived classes
1230       OnSceneConnectionExternal(mDepth);
1231
1232       if(!mOnSceneSignal.Empty())
1233       {
1234         Dali::Actor handle(this);
1235         mOnSceneSignal.Emit(handle);
1236       }
1237     }
1238
1239     // Guard against Remove during callbacks
1240     if(OnScene())
1241     {
1242       mOnSceneSignalled = true; // signal required next time Actor is removed
1243     }
1244   }
1245 }
1246
1247 void Actor::DisconnectFromStage(bool notify)
1248 {
1249   // This container is used instead of walking the Actor hierachy.
1250   // It protects us when the Actor hierachy is modified during OnSceneDisconnectionExternal callbacks.
1251   ActorContainer disconnectionList;
1252
1253   if(mScene)
1254   {
1255     mScene->RequestRebuildDepthTree();
1256   }
1257
1258   // This stage is not interrupted by user callbacks
1259   mParentImpl.RecursiveDisconnectFromScene(disconnectionList);
1260
1261   // Notify applications about the newly disconnected actors.
1262   for(const auto& actor : disconnectionList)
1263   {
1264     actor->NotifyStageDisconnection(notify);
1265   }
1266 }
1267
1268 /**
1269  * This method is called by an actor or its parent, before a node removal message is sent.
1270  * This is recursive; the child calls DisconnectFromStage() for its children.
1271  */
1272 void Actor::DisconnectFromSceneGraph()
1273 {
1274   // Notification for Object::Observers
1275   OnSceneObjectRemove();
1276 }
1277
1278 void Actor::NotifyStageDisconnection(bool notify)
1279 {
1280   // Actors can be added (in a callback), before the off-stage state is reported.
1281   // Also if the actor was added & removed before mOnSceneSignalled was set, then we don't notify here.
1282   // only do this step if there is a stage, i.e. Core is not being shut down
1283   if(EventThreadServices::IsCoreRunning() && !OnScene() && mOnSceneSignalled)
1284   {
1285     if(notify)
1286     {
1287       // Notification for external (CustomeActor) derived classes
1288       OnSceneDisconnectionExternal();
1289
1290       if(!mOffSceneSignal.Empty())
1291       {
1292         Dali::Actor handle(this);
1293         mOffSceneSignal.Emit(handle);
1294       }
1295     }
1296
1297     // Guard against Add during callbacks
1298     if(!OnScene())
1299     {
1300       mOnSceneSignalled = false; // signal required next time Actor is added
1301     }
1302   }
1303 }
1304
1305 bool Actor::IsNodeConnected() const
1306 {
1307   return OnScene() && (IsRoot() || GetNode().GetParent());
1308 }
1309
1310 // This method initiates traversal of the actor tree using depth-first
1311 // traversal to set a depth index based on traversal order. It sends a
1312 // single message to update manager to update all the actor's nodes in
1313 // this tree with the depth index. The sceneGraphNodeDepths vector's
1314 // elements are ordered by depth, and could be used to reduce sorting
1315 // in the update thread.
1316 void Actor::RebuildDepthTree()
1317 {
1318   DALI_LOG_TIMER_START(depthTimer);
1319
1320   // Vector of scene-graph nodes and their depths to send to UpdateManager
1321   // in a single message
1322   OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths(new SceneGraph::NodeDepths());
1323
1324   int32_t depthIndex = 1;
1325   mParentImpl.DepthTraverseActorTree(sceneGraphNodeDepths, depthIndex);
1326
1327   SetDepthIndicesMessage(GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths);
1328   DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
1329 }
1330
1331 void Actor::SetDefaultProperty(Property::Index index, const Property::Value& property)
1332 {
1333   PropertyHandler::SetDefaultProperty(*this, index, property);
1334 }
1335
1336 // TODO: This method needs to be removed
1337 void Actor::SetSceneGraphProperty(Property::Index index, const PropertyMetadata& entry, const Property::Value& value)
1338 {
1339   PropertyHandler::SetSceneGraphProperty(index, entry, value, GetEventThreadServices(), GetNode());
1340 }
1341
1342 Property::Value Actor::GetDefaultProperty(Property::Index index) const
1343 {
1344   Property::Value value;
1345
1346   if(!GetCachedPropertyValue(index, value))
1347   {
1348     // If property value is not stored in the event-side, then it must be a scene-graph only property
1349     GetCurrentPropertyValue(index, value);
1350   }
1351
1352   return value;
1353 }
1354
1355 Property::Value Actor::GetDefaultPropertyCurrentValue(Property::Index index) const
1356 {
1357   Property::Value value;
1358
1359   if(!GetCurrentPropertyValue(index, value))
1360   {
1361     // If unable to retrieve scene-graph property value, then it must be an event-side only property
1362     GetCachedPropertyValue(index, value);
1363   }
1364
1365   return value;
1366 }
1367
1368 void Actor::OnNotifyDefaultPropertyAnimation(Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType)
1369 {
1370   PropertyHandler::OnNotifyDefaultPropertyAnimation(*this, animation, index, value, animationType);
1371 }
1372
1373 const PropertyBase* Actor::GetSceneObjectAnimatableProperty(Property::Index index) const
1374 {
1375   const PropertyBase* property = PropertyHandler::GetSceneObjectAnimatableProperty(index, GetNode());
1376   if(!property)
1377   {
1378     // not our property, ask base
1379     property = Object::GetSceneObjectAnimatableProperty(index);
1380   }
1381
1382   return property;
1383 }
1384
1385 const PropertyInputImpl* Actor::GetSceneObjectInputProperty(Property::Index index) const
1386 {
1387   const PropertyInputImpl* property = PropertyHandler::GetSceneObjectInputProperty(index, GetNode());
1388   if(!property)
1389   {
1390     // reuse animatable property getter as animatable properties are inputs as well
1391     // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
1392     property = GetSceneObjectAnimatableProperty(index);
1393   }
1394
1395   return property;
1396 }
1397
1398 int32_t Actor::GetPropertyComponentIndex(Property::Index index) const
1399 {
1400   int32_t componentIndex = PropertyHandler::GetPropertyComponentIndex(index);
1401   if(Property::INVALID_COMPONENT_INDEX == componentIndex)
1402   {
1403     // ask base
1404     componentIndex = Object::GetPropertyComponentIndex(index);
1405   }
1406
1407   return componentIndex;
1408 }
1409
1410 const SceneGraph::Node& Actor::GetNode() const
1411 {
1412   return *static_cast<const SceneGraph::Node*>(mUpdateObject);
1413 }
1414
1415 void Actor::Raise()
1416 {
1417   CheckParentAndCall(mParent, *this, &ActorParent::RaiseChild);
1418 }
1419
1420 void Actor::Lower()
1421 {
1422   CheckParentAndCall(mParent, *this, &ActorParent::LowerChild);
1423 }
1424
1425 void Actor::RaiseToTop()
1426 {
1427   CheckParentAndCall(mParent, *this, &ActorParent::RaiseChildToTop);
1428 }
1429
1430 void Actor::LowerToBottom()
1431 {
1432   CheckParentAndCall(mParent, *this, &ActorParent::LowerChildToBottom);
1433 }
1434
1435 void Actor::RaiseAbove(Internal::Actor& target)
1436 {
1437   CheckParentAndCall(mParent, *this, target, &ActorParent::RaiseChildAbove);
1438 }
1439
1440 void Actor::LowerBelow(Internal::Actor& target)
1441 {
1442   CheckParentAndCall(mParent, *this, target, &ActorParent::LowerChildBelow);
1443 }
1444
1445 void Actor::SetParent(ActorParent* parent, bool notify)
1446 {
1447   if(parent)
1448   {
1449     DALI_ASSERT_ALWAYS(!mParent && "Actor cannot have 2 parents");
1450
1451     mParent            = parent;
1452     Actor* parentActor = static_cast<Actor*>(parent);
1453     mScene             = parentActor->mScene;
1454
1455     if(EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
1456        parentActor->OnScene())
1457     {
1458       // Instruct each actor to create a corresponding node in the scene graph
1459       ConnectToScene(parentActor->GetHierarchyDepth(), notify);
1460     }
1461
1462     // Resolve the name and index for the child properties if any
1463     ResolveChildProperties();
1464   }
1465   else // parent being set to NULL
1466   {
1467     DALI_ASSERT_ALWAYS(mParent != nullptr && "Actor should have a parent");
1468
1469     mParent = nullptr;
1470
1471     if(EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
1472        OnScene())
1473     {
1474       // Disconnect the Node & its children from the scene-graph.
1475       DisconnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
1476
1477       // Instruct each actor to discard pointers to the scene-graph
1478       DisconnectFromStage(notify);
1479     }
1480
1481     mScene = nullptr;
1482   }
1483 }
1484
1485 Rect<> Actor::CalculateScreenExtents() const
1486 {
1487   auto        screenPosition = GetCurrentScreenPosition();
1488   BufferIndex bufferIndex    = GetEventThreadServices().GetEventBufferIndex();
1489   return CalculateActorScreenExtents(*this, screenPosition, bufferIndex);
1490 }
1491
1492 Vector3 Actor::GetAnchorPointForPosition() const
1493 {
1494   return (mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT);
1495 }
1496
1497 bool Actor::GetCachedPropertyValue(Property::Index index, Property::Value& value) const
1498 {
1499   return PropertyHandler::GetCachedPropertyValue(*this, index, value);
1500 }
1501
1502 bool Actor::GetCurrentPropertyValue(Property::Index index, Property::Value& value) const
1503 {
1504   return PropertyHandler::GetCurrentPropertyValue(*this, index, value);
1505 }
1506
1507 bool Actor::RelayoutDependentOnParent(Dimension::Type dimension)
1508 {
1509   return mSizer.RelayoutDependentOnParent(dimension);
1510 }
1511
1512 bool Actor::RelayoutDependentOnChildren(Dimension::Type dimension)
1513 {
1514   return mSizer.RelayoutDependentOnChildrenBase(dimension);
1515 }
1516
1517 bool Actor::RelayoutDependentOnDimension(Dimension::Type dimension, Dimension::Type dependentDimension)
1518 {
1519   return mSizer.RelayoutDependentOnDimension(dimension, dependentDimension);
1520 }
1521
1522 void Actor::SetPadding(const Vector2& padding, Dimension::Type dimension)
1523 {
1524   mSizer.SetPadding(padding, dimension);
1525 }
1526
1527 Vector2 Actor::GetPadding(Dimension::Type dimension) const
1528 {
1529   return mSizer.GetPadding(dimension);
1530 }
1531
1532 void Actor::SetLayoutNegotiated(bool negotiated, Dimension::Type dimension)
1533 {
1534   mSizer.SetLayoutNegotiated(negotiated, dimension);
1535 }
1536
1537 bool Actor::IsLayoutNegotiated(Dimension::Type dimension) const
1538 {
1539   return mSizer.IsLayoutNegotiated(dimension);
1540 }
1541
1542 float Actor::GetHeightForWidthBase(float width)
1543 {
1544   // Can be overridden in derived class
1545   return mSizer.GetHeightForWidthBase(width);
1546 }
1547
1548 float Actor::GetWidthForHeightBase(float height)
1549 {
1550   // Can be overridden in derived class
1551   return mSizer.GetWidthForHeightBase(height);
1552 }
1553
1554 float Actor::CalculateChildSizeBase(const Dali::Actor& child, Dimension::Type dimension)
1555 {
1556   // Can be overridden in derived class
1557   return mSizer.CalculateChildSizeBase(child, dimension);
1558 }
1559
1560 bool Actor::RelayoutDependentOnChildrenBase(Dimension::Type dimension)
1561 {
1562   return mSizer.RelayoutDependentOnChildrenBase(dimension);
1563 }
1564
1565 float Actor::CalculateChildSize(const Dali::Actor& child, Dimension::Type dimension)
1566 {
1567   // Can be overridden in derived class
1568   return mSizer.CalculateChildSizeBase(child, dimension);
1569 }
1570
1571 float Actor::GetHeightForWidth(float width)
1572 {
1573   // Can be overridden in derived class
1574   return mSizer.GetHeightForWidthBase(width);
1575 }
1576
1577 float Actor::GetWidthForHeight(float height)
1578 {
1579   // Can be overridden in derived class
1580   return mSizer.GetWidthForHeightBase(height);
1581 }
1582
1583 float Actor::GetRelayoutSize(Dimension::Type dimension) const
1584 {
1585   return mSizer.GetRelayoutSize(dimension);
1586 }
1587
1588 void Actor::NegotiateSize(const Vector2& allocatedSize, RelayoutContainer& container)
1589 {
1590   mSizer.NegotiateSize(allocatedSize, container);
1591 }
1592
1593 void Actor::RelayoutRequest(Dimension::Type dimension)
1594 {
1595   mSizer.RelayoutRequest(dimension);
1596 }
1597
1598 void Actor::SetMinimumSize(float size, Dimension::Type dimension)
1599 {
1600   mSizer.SetMinimumSize(size, dimension);
1601 }
1602
1603 float Actor::GetMinimumSize(Dimension::Type dimension) const
1604 {
1605   return mSizer.GetMinimumSize(dimension);
1606 }
1607
1608 void Actor::SetMaximumSize(float size, Dimension::Type dimension)
1609 {
1610   mSizer.SetMaximumSize(size, dimension);
1611 }
1612
1613 float Actor::GetMaximumSize(Dimension::Type dimension) const
1614 {
1615   return mSizer.GetMaximumSize(dimension);
1616 }
1617
1618 void Actor::SetVisibleInternal(bool visible, SendMessage::Type sendMessage)
1619 {
1620   if(mVisible != visible)
1621   {
1622     if(sendMessage == SendMessage::TRUE)
1623     {
1624       // node is being used in a separate thread; queue a message to set the value & base value
1625       SceneGraph::NodePropertyMessage<bool>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible);
1626
1627       RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
1628     }
1629
1630     mVisible = visible;
1631
1632     // Emit the signal on this actor and all its children
1633     mParentImpl.EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::SELF);
1634   }
1635 }
1636
1637 void Actor::SetSiblingOrderOfChild(Actor& child, uint32_t order)
1638 {
1639   mParentImpl.SetSiblingOrderOfChild(child, order);
1640 }
1641
1642 uint32_t Actor::GetSiblingOrderOfChild(const Actor& child) const
1643 {
1644   return mParentImpl.GetSiblingOrderOfChild(child);
1645 }
1646
1647 void Actor::RaiseChild(Actor& child)
1648 {
1649   mParentImpl.RaiseChild(child);
1650 }
1651
1652 void Actor::LowerChild(Actor& child)
1653 {
1654   mParentImpl.LowerChild(child);
1655 }
1656
1657 void Actor::RaiseChildToTop(Actor& child)
1658 {
1659   mParentImpl.RaiseChildToTop(child);
1660 }
1661
1662 void Actor::LowerChildToBottom(Actor& child)
1663 {
1664   mParentImpl.LowerChildToBottom(child);
1665 }
1666
1667 void Actor::RaiseChildAbove(Actor& child, Actor& target)
1668 {
1669   mParentImpl.RaiseChildAbove(child, target);
1670 }
1671
1672 void Actor::LowerChildBelow(Actor& child, Actor& target)
1673 {
1674   mParentImpl.LowerChildBelow(child, target);
1675 }
1676
1677 void Actor::SetInheritLayoutDirection(bool inherit)
1678 {
1679   if(mInheritLayoutDirection != inherit)
1680   {
1681     mInheritLayoutDirection = inherit;
1682
1683     if(inherit && mParent)
1684     {
1685       mParentImpl.InheritLayoutDirectionRecursively(GetParent()->mLayoutDirection);
1686     }
1687   }
1688 }
1689
1690 void Actor::SetUpdateSizeHint(const Vector2& updateSizeHint)
1691 {
1692   // node is being used in a separate thread; queue a message to set the value & base value
1693   SceneGraph::NodePropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mUpdateSizeHint, &AnimatableProperty<Vector3>::Bake, Vector3(updateSizeHint.width, updateSizeHint.height, 0.f));
1694 }
1695
1696 } // namespace Internal
1697
1698 } // namespace Dali