2 * Copyright (c) 2022 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/event/actors/actor-impl.h>
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>
33 #include <dali/devel-api/actors/actor-devel.h>
34 #include <dali/devel-api/common/capabilities.h>
36 #include <dali/integration-api/debug.h>
37 #include <dali/integration-api/events/touch-integ.h>
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>
57 using Dali::Internal::SceneGraph::AnimatableProperty;
58 using Dali::Internal::SceneGraph::Node;
59 using Dali::Internal::SceneGraph::PropertyBase;
61 #if defined(DEBUG_ENABLED)
62 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER");
69 namespace // unnamed namespace
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
78 DALI_PROPERTY_TABLE_BEGIN
79 DALI_PROPERTY("parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN)
80 DALI_PROPERTY("parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X)
81 DALI_PROPERTY("parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y)
82 DALI_PROPERTY("parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z)
83 DALI_PROPERTY("anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT)
84 DALI_PROPERTY("anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X)
85 DALI_PROPERTY("anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y)
86 DALI_PROPERTY("anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z)
87 DALI_PROPERTY("size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE)
88 DALI_PROPERTY("sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH)
89 DALI_PROPERTY("sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT)
90 DALI_PROPERTY("sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH)
91 DALI_PROPERTY("position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION)
92 DALI_PROPERTY("positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X)
93 DALI_PROPERTY("positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y)
94 DALI_PROPERTY("positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z)
95 DALI_PROPERTY("worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION)
96 DALI_PROPERTY("worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X)
97 DALI_PROPERTY("worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y)
98 DALI_PROPERTY("worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z)
99 DALI_PROPERTY("orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION)
100 DALI_PROPERTY("worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION)
101 DALI_PROPERTY("scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE)
102 DALI_PROPERTY("scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X)
103 DALI_PROPERTY("scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y)
104 DALI_PROPERTY("scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z)
105 DALI_PROPERTY("worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE)
106 DALI_PROPERTY("visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE)
107 DALI_PROPERTY("color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR)
108 DALI_PROPERTY("colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED)
109 DALI_PROPERTY("colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN)
110 DALI_PROPERTY("colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE)
111 DALI_PROPERTY("colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA)
112 DALI_PROPERTY("worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR)
113 DALI_PROPERTY("worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX)
114 DALI_PROPERTY("name", STRING, true, false, false, Dali::Actor::Property::NAME)
115 DALI_PROPERTY("sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE)
116 DALI_PROPERTY("leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED)
117 DALI_PROPERTY("inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION)
118 DALI_PROPERTY("inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE)
119 DALI_PROPERTY("colorMode", INTEGER, true, false, false, Dali::Actor::Property::COLOR_MODE)
120 DALI_PROPERTY("drawMode", INTEGER, true, false, false, Dali::Actor::Property::DRAW_MODE)
121 DALI_PROPERTY("sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR)
122 DALI_PROPERTY("widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY)
123 DALI_PROPERTY("heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY)
124 DALI_PROPERTY("sizeScalePolicy", INTEGER, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY)
125 DALI_PROPERTY("widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT)
126 DALI_PROPERTY("heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH)
127 DALI_PROPERTY("padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING)
128 DALI_PROPERTY("minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE)
129 DALI_PROPERTY("maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE)
130 DALI_PROPERTY("inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION)
131 DALI_PROPERTY("clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE)
132 DALI_PROPERTY("layoutDirection", STRING, true, false, false, Dali::Actor::Property::LAYOUT_DIRECTION)
133 DALI_PROPERTY("inheritLayoutDirection", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION)
134 DALI_PROPERTY("opacity", FLOAT, true, true, true, Dali::Actor::Property::OPACITY)
135 DALI_PROPERTY("screenPosition", VECTOR2, false, false, false, Dali::Actor::Property::SCREEN_POSITION)
136 DALI_PROPERTY("positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::Actor::Property::POSITION_USES_ANCHOR_POINT)
137 DALI_PROPERTY("culled", BOOLEAN, false, false, true, Dali::Actor::Property::CULLED)
138 DALI_PROPERTY("id", INTEGER, false, false, false, Dali::Actor::Property::ID)
139 DALI_PROPERTY("hierarchyDepth", INTEGER, false, false, false, Dali::Actor::Property::HIERARCHY_DEPTH)
140 DALI_PROPERTY("isRoot", BOOLEAN, false, false, false, Dali::Actor::Property::IS_ROOT)
141 DALI_PROPERTY("isLayer", BOOLEAN, false, false, false, Dali::Actor::Property::IS_LAYER)
142 DALI_PROPERTY("connectedToScene", BOOLEAN, false, false, false, Dali::Actor::Property::CONNECTED_TO_SCENE)
143 DALI_PROPERTY("keyboardFocusable", BOOLEAN, true, false, false, Dali::Actor::Property::KEYBOARD_FOCUSABLE)
144 DALI_PROPERTY("updateAreaHint", VECTOR4, true, false, false, Dali::Actor::Property::UPDATE_AREA_HINT)
145 DALI_PROPERTY("siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER)
146 DALI_PROPERTY("captureAllTouchAfterStart", BOOLEAN, true, false, false, Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START)
147 DALI_PROPERTY("touchAreaOffset", RECTANGLE, true, false, false, Dali::DevelActor::Property::TOUCH_AREA_OFFSET)
148 DALI_PROPERTY("blendEquation", INTEGER, true, false, false, Dali::DevelActor::Property::BLEND_EQUATION)
149 DALI_PROPERTY("touchFocusable", BOOLEAN, true, false, false, Dali::DevelActor::Property::TOUCH_FOCUSABLE)
150 DALI_PROPERTY("keyboardFocusableChildren", BOOLEAN, true, false, false, Dali::DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN)
151 DALI_PROPERTY("userInteractionEnabled", BOOLEAN, true, false, false, Dali::DevelActor::Property::USER_INTERACTION_ENABLED)
152 DALI_PROPERTY("allowOnlyOwnTouch", BOOLEAN, true, false, false, Dali::DevelActor::Property::ALLOW_ONLY_OWN_TOUCH)
153 DALI_PROPERTY_TABLE_END(DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties)
157 static constexpr std::string_view SIGNAL_HOVERED = "hovered";
158 static constexpr std::string_view SIGNAL_WHEEL_EVENT = "wheelEvent";
159 static constexpr std::string_view SIGNAL_ON_SCENE = "onScene";
160 static constexpr std::string_view SIGNAL_OFF_SCENE = "offScene";
161 static constexpr std::string_view SIGNAL_ON_RELAYOUT = "onRelayout";
162 static constexpr std::string_view SIGNAL_TOUCHED = "touched";
163 static constexpr std::string_view SIGNAL_VISIBILITY_CHANGED = "visibilityChanged";
164 static constexpr std::string_view SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
165 static constexpr std::string_view SIGNAL_CHILD_ADDED = "childAdded";
166 static constexpr std::string_view SIGNAL_CHILD_REMOVED = "childRemoved";
170 static constexpr std::string_view ACTION_SHOW = "show";
171 static constexpr std::string_view ACTION_HIDE = "hide";
173 BaseHandle CreateActor()
175 return Dali::Actor::New();
179 * Connects a callback function with the object's signals.
180 * @param[in] object The object providing the signal.
181 * @param[in] tracker Used to disconnect the signal.
182 * @param[in] signalName The signal to connect to.
183 * @param[in] functor A newly allocated FunctorDelegate.
184 * @return True if the signal was connected.
185 * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
187 static bool DoConnectSignal(BaseObject* object,
188 ConnectionTrackerInterface* tracker,
189 const std::string& signalName,
190 FunctorDelegate* functor)
192 bool connected(true);
193 Actor* actor = static_cast<Actor*>(object); // TypeRegistry guarantees that this is the correct type.
195 std::string_view name(signalName);
197 if(name == SIGNAL_HOVERED)
199 actor->HoveredSignal().Connect(tracker, functor);
201 else if(signalName == SIGNAL_WHEEL_EVENT)
203 actor->WheelEventSignal().Connect(tracker, functor);
205 else if(name == SIGNAL_ON_SCENE)
207 actor->OnSceneSignal().Connect(tracker, functor);
209 else if(name == SIGNAL_OFF_SCENE)
211 actor->OffSceneSignal().Connect(tracker, functor);
213 else if(name == SIGNAL_ON_RELAYOUT)
215 actor->OnRelayoutSignal().Connect(tracker, functor);
217 else if(name == SIGNAL_TOUCHED)
219 actor->TouchedSignal().Connect(tracker, functor);
221 else if(name == SIGNAL_VISIBILITY_CHANGED)
223 actor->VisibilityChangedSignal().Connect(tracker, functor);
225 else if(name == SIGNAL_LAYOUT_DIRECTION_CHANGED)
227 actor->LayoutDirectionChangedSignal().Connect(tracker, functor);
229 else if(name == SIGNAL_CHILD_ADDED)
231 actor->ChildAddedSignal().Connect(tracker, functor);
233 else if(name == SIGNAL_CHILD_REMOVED)
235 actor->ChildRemovedSignal().Connect(tracker, functor);
239 // signalName does not match any signal
247 * Performs actions as requested using the action name.
248 * @param[in] object The object on which to perform the action.
249 * @param[in] actionName The action to perform.
250 * @param[in] attributes The attributes with which to perfrom this action.
251 * @return true if the action was done.
253 bool DoAction(BaseObject* object,
254 const std::string& actionName,
255 const Property::Map& attributes)
258 Actor* actor = dynamic_cast<Actor*>(object);
262 std::string_view name(actionName);
263 if(name == ACTION_SHOW)
265 actor->SetVisible(true);
268 else if(name == ACTION_HIDE)
270 actor->SetVisible(false);
278 TypeRegistration mType(typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties);
280 SignalConnectorType signalConnector2(mType, std::string(SIGNAL_HOVERED), &DoConnectSignal);
281 SignalConnectorType signalConnector3(mType, std::string(SIGNAL_WHEEL_EVENT), &DoConnectSignal);
282 SignalConnectorType signalConnector4(mType, std::string(SIGNAL_ON_SCENE), &DoConnectSignal);
283 SignalConnectorType signalConnector5(mType, std::string(SIGNAL_OFF_SCENE), &DoConnectSignal);
284 SignalConnectorType signalConnector6(mType, std::string(SIGNAL_ON_RELAYOUT), &DoConnectSignal);
285 SignalConnectorType signalConnector7(mType, std::string(SIGNAL_TOUCHED), &DoConnectSignal);
286 SignalConnectorType signalConnector8(mType, std::string(SIGNAL_VISIBILITY_CHANGED), &DoConnectSignal);
287 SignalConnectorType signalConnector9(mType, std::string(SIGNAL_LAYOUT_DIRECTION_CHANGED), &DoConnectSignal);
288 SignalConnectorType signalConnector10(mType, std::string(SIGNAL_CHILD_ADDED), &DoConnectSignal);
289 SignalConnectorType signalConnector11(mType, std::string(SIGNAL_CHILD_REMOVED), &DoConnectSignal);
291 TypeAction a1(mType, std::string(ACTION_SHOW), &DoAction);
292 TypeAction a2(mType, std::string(ACTION_HIDE), &DoAction);
294 /// Helper for emitting a signal
295 template<typename Signal, typename Event>
296 bool EmitConsumingSignal(Actor& actor, Signal& signal, const Event& event)
298 bool consumed = false;
302 Dali::Actor handle(&actor);
303 consumed = signal.Emit(handle, event);
309 /// Helper for emitting signals with multiple parameters
310 template<typename Signal, typename... Param>
311 void EmitSignal(Actor& actor, Signal& signal, Param... params)
315 Dali::Actor handle(&actor);
316 signal.Emit(handle, params...);
320 using ActorParentSiblingOrderMethod = void (ActorParent::*)(Actor&);
321 using ActorParentSiblingOrderMethodWithTarget = void (ActorParent::*)(Actor&, Actor&);
323 /// Helper to check and call actor sibling methods in ActorParent
324 void CheckParentAndCall(ActorParent* parent, Actor& actor, ActorParentSiblingOrderMethod memberFunction)
328 (parent->*memberFunction)(actor);
332 DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
336 /// Helper to check and call actor sibling methods with a target parameter in ActorParent
337 void CheckParentAndCall(ActorParent* parent, Actor& actor, Actor& target, ActorParentSiblingOrderMethodWithTarget memberFunction)
341 (parent->*memberFunction)(actor, target);
345 DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
349 } // unnamed namespace
351 ActorPtr Actor::New()
353 // pass a reference to actor, actor does not own its node
354 ActorPtr actor(new Actor(BASIC, *CreateNode()));
356 // Second-phase construction
362 const SceneGraph::Node* Actor::CreateNode()
364 // create node. Nodes are owned by the update manager
365 SceneGraph::Node* node = SceneGraph::Node::New();
366 OwnerPointer<SceneGraph::Node> transferOwnership(node);
367 Internal::ThreadLocalStorage* tls = Internal::ThreadLocalStorage::GetInternal();
369 DALI_ASSERT_ALWAYS(tls && "ThreadLocalStorage is null");
371 AddNodeMessage(tls->GetUpdateManager(), transferOwnership);
376 void Actor::SetName(std::string_view name)
378 mName = ConstString(name);
380 // ATTENTION: string for debug purposes is not thread safe.
381 DALI_LOG_SET_OBJECT_STRING(const_cast<SceneGraph::Node*>(&GetNode()), mName.GetCString());
384 uint32_t Actor::GetId() const
386 return GetNode().GetId();
389 Dali::Layer Actor::GetLayer()
393 // Short-circuit for Layer derived actors
396 layer = Dali::Layer(static_cast<Dali::Internal::Layer*>(this)); // static cast as we trust the flag
399 // Find the immediate Layer parent
400 for(Actor* parent = GetParent(); !layer && parent != nullptr; parent = parent->GetParent())
402 if(parent->IsLayer())
404 layer = Dali::Layer(static_cast<Dali::Internal::Layer*>(parent)); // static cast as we trust the flag
411 void Actor::Unparent()
415 // Remove this actor from the parent. The remove will put a relayout request in for
416 // the parent if required
417 mParent->Remove(*this);
418 // mParent is now NULL!
422 void Actor::SetParentOrigin(const Vector3& origin)
424 // node is being used in a separate thread; queue a message to set the value & base value
425 SetParentOriginMessage(GetEventThreadServices(), GetNode(), origin);
427 // Cache for event-thread access
430 // not allocated, check if different from default
431 if(ParentOrigin::DEFAULT != origin)
433 mParentOrigin = new Vector3(origin);
438 // check if different from current costs more than just set
439 *mParentOrigin = origin;
443 const Vector3& Actor::GetCurrentParentOrigin() const
445 // Cached for event-thread access
446 return (mParentOrigin) ? *mParentOrigin : ParentOrigin::DEFAULT;
449 void Actor::SetAnchorPoint(const Vector3& anchor)
451 // node is being used in a separate thread; queue a message to set the value & base value
452 SetAnchorPointMessage(GetEventThreadServices(), GetNode(), anchor);
454 // Cache for event-thread access
457 // not allocated, check if different from default
458 if(AnchorPoint::DEFAULT != anchor)
460 mAnchorPoint = new Vector3(anchor);
465 // check if different from current costs more than just set
466 *mAnchorPoint = anchor;
470 const Vector3& Actor::GetCurrentAnchorPoint() const
472 // Cached for event-thread access
473 return (mAnchorPoint) ? *mAnchorPoint : AnchorPoint::DEFAULT;
476 void Actor::SetPosition(float x, float y)
478 SetPosition(Vector3(x, y, 0.0f));
481 void Actor::SetPosition(float x, float y, float z)
483 SetPosition(Vector3(x, y, z));
486 void Actor::SetPosition(const Vector3& position)
488 mTargetPosition = position;
490 // node is being used in a separate thread; queue a message to set the value & base value
491 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position);
494 void Actor::SetX(float x)
496 mTargetPosition.x = x;
498 // node is being used in a separate thread; queue a message to set the value & base value
499 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x);
502 void Actor::SetY(float y)
504 mTargetPosition.y = y;
506 // node is being used in a separate thread; queue a message to set the value & base value
507 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y);
510 void Actor::SetZ(float z)
512 mTargetPosition.z = z;
514 // node is being used in a separate thread; queue a message to set the value & base value
515 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z);
518 void Actor::TranslateBy(const Vector3& distance)
520 mTargetPosition += distance;
522 // node is being used in a separate thread; queue a message to set the value & base value
523 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance);
526 const Vector3& Actor::GetCurrentPosition() const
528 // node is being used in a separate thread; copy the value from the previous update
529 return GetNode().GetPosition(GetEventThreadServices().GetEventBufferIndex());
532 const Vector3& Actor::GetCurrentWorldPosition() const
534 // node is being used in a separate thread; copy the value from the previous update
535 return GetNode().GetWorldPosition(GetEventThreadServices().GetEventBufferIndex());
538 const Vector2 Actor::GetCurrentScreenPosition() const
542 BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
543 if(mLayer3DParentsCount == 0)
545 // We can assume that this actor is under 2d layer. Use faster, but imprecise algorithm
546 return CalculateActorScreenPosition(*this, bufferIndex);
550 return CalculateActorScreenPositionRenderTaskList(*this, bufferIndex);
553 return Vector2::ZERO;
556 void Actor::SetInheritPosition(bool inherit)
558 if(mInheritPosition != inherit)
560 // non animatable so keep local copy
561 mInheritPosition = inherit;
562 SetInheritPositionMessage(GetEventThreadServices(), GetNode(), inherit);
566 void Actor::SetOrientation(const Radian& angle, const Vector3& axis)
568 Vector3 normalizedAxis(axis.x, axis.y, axis.z);
569 normalizedAxis.Normalize();
571 Quaternion orientation(angle, normalizedAxis);
573 SetOrientation(orientation);
576 void Actor::SetOrientation(const Quaternion& orientation)
578 mTargetOrientation = orientation;
580 // node is being used in a separate thread; queue a message to set the value & base value
581 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation);
584 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
586 RotateBy(Quaternion(angle, axis));
589 void Actor::RotateBy(const Quaternion& relativeRotation)
591 mTargetOrientation *= Quaternion(relativeRotation);
593 // node is being used in a separate thread; queue a message to set the value & base value
594 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation);
597 const Quaternion& Actor::GetCurrentOrientation() const
599 // node is being used in a separate thread; copy the value from the previous update
600 return GetNode().GetOrientation(GetEventThreadServices().GetEventBufferIndex());
603 const Quaternion& Actor::GetCurrentWorldOrientation() const
605 // node is being used in a separate thread; copy the value from the previous update
606 return GetNode().GetWorldOrientation(GetEventThreadServices().GetEventBufferIndex());
609 void Actor::SetScale(float scale)
611 SetScale(Vector3(scale, scale, scale));
614 void Actor::SetScale(float x, float y, float z)
616 SetScale(Vector3(x, y, z));
619 void Actor::SetScale(const Vector3& scale)
621 mTargetScale = scale;
623 // node is being used in a separate thread; queue a message to set the value & base value
624 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale);
627 void Actor::SetScaleX(float x)
631 // node is being used in a separate thread; queue a message to set the value & base value
632 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x);
635 void Actor::SetScaleY(float y)
639 // node is being used in a separate thread; queue a message to set the value & base value
640 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y);
643 void Actor::SetScaleZ(float z)
647 // node is being used in a separate thread; queue a message to set the value & base value
648 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z);
651 void Actor::ScaleBy(const Vector3& relativeScale)
653 mTargetScale *= relativeScale;
655 // node is being used in a separate thread; queue a message to set the value & base value
656 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale);
659 const Vector3& Actor::GetCurrentScale() const
661 // node is being used in a separate thread; copy the value from the previous update
662 return GetNode().GetScale(GetEventThreadServices().GetEventBufferIndex());
665 const Vector3& Actor::GetCurrentWorldScale() const
667 // node is being used in a separate thread; copy the value from the previous update
668 return GetNode().GetWorldScale(GetEventThreadServices().GetEventBufferIndex());
671 void Actor::SetInheritScale(bool inherit)
673 if(mInheritScale != inherit)
675 // non animatable so keep local copy
676 mInheritScale = inherit;
677 // node is being used in a separate thread; queue a message to set the value
678 SetInheritScaleMessage(GetEventThreadServices(), GetNode(), inherit);
682 Matrix Actor::GetCurrentWorldMatrix() const
684 return GetNode().GetWorldMatrix(0);
687 void Actor::SetVisible(bool visible)
689 SetVisibleInternal(visible, SendMessage::TRUE);
692 bool Actor::IsVisible() const
694 // node is being used in a separate thread; copy the value from the previous update
695 return GetNode().IsVisible(GetEventThreadServices().GetEventBufferIndex());
698 void Actor::SetOpacity(float opacity)
700 mTargetColor.a = opacity;
702 // node is being used in a separate thread; queue a message to set the value & base value
703 SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeW, opacity);
705 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
708 float Actor::GetCurrentOpacity() const
710 // node is being used in a separate thread; copy the value from the previous update
711 return GetNode().GetOpacity(GetEventThreadServices().GetEventBufferIndex());
714 const Vector4& Actor::GetCurrentWorldColor() const
716 return GetNode().GetWorldColor(GetEventThreadServices().GetEventBufferIndex());
719 void Actor::SetColor(const Vector4& color)
721 mTargetColor = color;
723 // node is being used in a separate thread; queue a message to set the value & base value
724 SceneGraph::NodePropertyMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::Bake, color);
726 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
729 void Actor::SetColorRed(float red)
731 mTargetColor.r = red;
733 // node is being used in a separate thread; queue a message to set the value & base value
734 SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeX, red);
736 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
739 void Actor::SetColorGreen(float green)
741 mTargetColor.g = green;
743 // node is being used in a separate thread; queue a message to set the value & base value
744 SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeY, green);
746 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
749 void Actor::SetColorBlue(float blue)
751 mTargetColor.b = blue;
753 // node is being used in a separate thread; queue a message to set the value & base value
754 SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeZ, blue);
756 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
759 const Vector4& Actor::GetCurrentColor() const
761 // node is being used in a separate thread; copy the value from the previous update
762 return GetNode().GetColor(GetEventThreadServices().GetEventBufferIndex());
765 void Actor::SetInheritOrientation(bool inherit)
767 if(mInheritOrientation != inherit)
769 // non animatable so keep local copy
770 mInheritOrientation = inherit;
771 // node is being used in a separate thread; queue a message to set the value
772 SetInheritOrientationMessage(GetEventThreadServices(), GetNode(), inherit);
776 void Actor::SetSizeModeFactor(const Vector3& factor)
778 mSizer.SetSizeModeFactor(factor);
781 const Vector3& Actor::GetSizeModeFactor() const
783 return mSizer.GetSizeModeFactor();
786 void Actor::SetColorMode(ColorMode colorMode)
788 // non animatable so keep local copy
789 mColorMode = colorMode;
790 // node is being used in a separate thread; queue a message to set the value
791 SetColorModeMessage(GetEventThreadServices(), GetNode(), colorMode);
794 void Actor::SetSize(float width, float height)
796 SetSize(Vector2(width, height));
799 void Actor::SetSize(float width, float height, float depth)
801 SetSize(Vector3(width, height, depth));
804 void Actor::SetSize(const Vector2& size)
806 SetSize(Vector3(size.width, size.height, 0.f));
809 void Actor::SetSize(const Vector3& size)
811 mSizer.SetSize(size);
814 void Actor::SetWidth(float width)
816 mSizer.SetWidth(width);
819 void Actor::SetHeight(float height)
821 mSizer.SetHeight(height);
824 void Actor::SetDepth(float depth)
826 mSizer.SetDepth(depth);
827 // node is being used in a separate thread; queue a message to set the value & base value
828 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth);
831 Vector3 Actor::GetTargetSize() const
833 return mSizer.GetTargetSize();
836 const Vector3& Actor::GetCurrentSize() const
838 // node is being used in a separate thread; copy the value from the previous update
839 return GetNode().GetSize(GetEventThreadServices().GetEventBufferIndex());
842 Vector3 Actor::GetNaturalSize() const
844 // It is up to deriving classes to return the appropriate natural size
845 return Vector3(0.0f, 0.0f, 0.0f);
848 void Actor::SetResizePolicy(ResizePolicy::Type policy, Dimension::Type dimension)
850 mSizer.SetResizePolicy(policy, dimension);
853 ResizePolicy::Type Actor::GetResizePolicy(Dimension::Type dimension) const
855 return mSizer.GetResizePolicy(dimension);
858 void Actor::SetRelayoutEnabled(bool relayoutEnabled)
860 mSizer.SetRelayoutEnabled(relayoutEnabled);
863 bool Actor::IsRelayoutEnabled() const
865 return mSizer.IsRelayoutEnabled();
868 void Actor::SetLayoutDirty(bool dirty, Dimension::Type dimension)
870 mSizer.SetLayoutDirty(dirty, dimension);
873 bool Actor::IsLayoutDirty(Dimension::Type dimension) const
875 return mSizer.IsLayoutDirty(dimension);
878 bool Actor::RelayoutPossible(Dimension::Type dimension) const
880 return mSizer.RelayoutPossible(dimension);
883 bool Actor::RelayoutRequired(Dimension::Type dimension) const
885 return mSizer.RelayoutRequired(dimension);
888 uint32_t Actor::AddRenderer(Renderer& renderer)
892 mRenderers = new RendererContainer(GetEventThreadServices());
894 return mRenderers->Add(GetNode(), renderer, mIsBlendEquationSet, mBlendEquation);
897 uint32_t Actor::GetRendererCount() const
899 return mRenderers ? mRenderers->GetCount() : 0u;
902 RendererPtr Actor::GetRendererAt(uint32_t index)
904 return mRenderers ? mRenderers->GetRendererAt(index) : nullptr;
907 void Actor::RemoveRenderer(Renderer& renderer)
911 mRenderers->Remove(GetNode(), renderer);
915 void Actor::RemoveRenderer(uint32_t index)
919 mRenderers->Remove(GetNode(), index);
923 void Actor::SetBlendEquation(DevelBlendEquation::Type blendEquation)
925 if(Dali::Capabilities::IsBlendEquationSupported(blendEquation))
927 if(mBlendEquation != blendEquation)
929 mBlendEquation = blendEquation;
932 mRenderers->SetBlending(blendEquation);
935 mIsBlendEquationSet = true;
939 DALI_LOG_ERROR("Invalid blend equation is entered.\n");
943 DevelBlendEquation::Type Actor::GetBlendEquation() const
945 return mBlendEquation;
948 void Actor::SetTransparent(bool transparent)
950 SetTransparentMessage(GetEventThreadServices(), GetNode(), transparent);
953 bool Actor::IsTransparent() const
955 return GetNode().IsTransparent();
958 void Actor::SetDrawMode(DrawMode::Type drawMode)
960 // this flag is not animatable so keep the value
961 mDrawMode = drawMode;
963 // node is being used in a separate thread; queue a message to set the value
964 SetDrawModeMessage(GetEventThreadServices(), GetNode(), drawMode);
967 bool Actor::ScreenToLocal(float& localX, float& localY, float screenX, float screenY) const
969 return mScene && OnScene() && ConvertScreenToLocalRenderTaskList(mScene->GetRenderTaskList(), GetNode().GetWorldMatrix(0), GetCurrentSize(), localX, localY, screenX, screenY);
972 bool Actor::ScreenToLocal(const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY) const
974 return OnScene() && ConvertScreenToLocalRenderTask(renderTask, GetNode().GetWorldMatrix(0), GetCurrentSize(), localX, localY, screenX, screenY);
977 bool Actor::ScreenToLocal(const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY) const
979 return OnScene() && ConvertScreenToLocal(viewMatrix, projectionMatrix, GetNode().GetWorldMatrix(0), GetCurrentSize(), viewport, localX, localY, screenX, screenY);
982 ActorGestureData& Actor::GetGestureData()
984 // Likely scenario is that once gesture-data is created for this actor, the actor will require
985 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
986 if(nullptr == mGestureData)
988 mGestureData = new ActorGestureData;
990 return *mGestureData;
993 bool Actor::IsGestureRequired(GestureType::Value type) const
995 return mGestureData && mGestureData->IsGestureRequired(type);
998 bool Actor::EmitInterceptTouchEventSignal(const Dali::TouchEvent& touch)
1000 return EmitConsumingSignal(*this, mInterceptTouchedSignal, touch);
1003 bool Actor::EmitTouchEventSignal(const Dali::TouchEvent& touch)
1005 return EmitConsumingSignal(*this, mTouchedSignal, touch);
1008 bool Actor::EmitHoverEventSignal(const Dali::HoverEvent& event)
1010 return EmitConsumingSignal(*this, mHoveredSignal, event);
1013 bool Actor::EmitWheelEventSignal(const Dali::WheelEvent& event)
1015 return EmitConsumingSignal(*this, mWheelEventSignal, event);
1018 void Actor::EmitVisibilityChangedSignal(bool visible, DevelActor::VisibilityChange::Type type)
1020 EmitSignal(*this, mVisibilityChangedSignal, visible, type);
1023 void Actor::EmitLayoutDirectionChangedSignal(LayoutDirection::Type type)
1025 EmitSignal(*this, mLayoutDirectionChangedSignal, type);
1028 bool Actor::EmitHitTestResultSignal(Integration::Point point, Vector2 hitPointLocal, uint32_t timeStamp)
1032 if(IsHitTestResultRequired())
1034 Dali::Actor handle(this);
1035 Integration::Point newPoint(point);
1036 newPoint.SetHitActor(handle);
1037 newPoint.SetLocalPosition(hitPointLocal);
1038 Dali::TouchEvent touchEvent = Dali::Integration::NewTouchEvent(timeStamp, newPoint);
1039 hit = mHitTestResultSignal.Emit(handle, touchEvent);
1044 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
1046 return mParentImpl.ChildAddedSignal();
1049 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
1051 return mParentImpl.ChildRemovedSignal();
1054 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
1056 return mParentImpl.ChildOrderChangedSignal();
1059 Actor::Actor(DerivedType derivedType, const SceneGraph::Node& node)
1065 mRenderers(nullptr),
1066 mParentOrigin(nullptr),
1067 mAnchorPoint(nullptr),
1068 mGestureData(nullptr),
1069 mInterceptTouchedSignal(),
1072 mWheelEventSignal(),
1075 mOnRelayoutSignal(),
1076 mVisibilityChangedSignal(),
1077 mLayoutDirectionChangedSignal(),
1078 mHitTestResultSignal(),
1079 mTargetOrientation(Quaternion::IDENTITY),
1080 mTargetColor(Color::WHITE),
1081 mTargetPosition(Vector3::ZERO),
1082 mTargetScale(Vector3::ONE),
1083 mTouchAreaOffset(0, 0, 0, 0),
1087 mLayer3DParentsCount(0),
1088 mIsRoot(ROOT_LAYER == derivedType),
1089 mIsLayer(LAYER == derivedType || ROOT_LAYER == derivedType),
1092 mLeaveRequired(false),
1093 mKeyboardFocusable(false),
1094 mKeyboardFocusableChildren(true),
1095 mTouchFocusable(false),
1096 mOnSceneSignalled(false),
1097 mInheritPosition(true),
1098 mInheritOrientation(true),
1099 mInheritScale(true),
1100 mPositionUsesAnchorPoint(true),
1102 mInheritLayoutDirection(true),
1103 mCaptureAllTouchAfterStart(false),
1104 mIsBlendEquationSet(false),
1105 mNeedGesturePropagation(false),
1106 mUserInteractionEnabled(true),
1107 mAllowOnlyOwnTouch(false),
1108 mLayoutDirection(LayoutDirection::LEFT_TO_RIGHT),
1109 mDrawMode(DrawMode::NORMAL),
1110 mColorMode(Node::DEFAULT_COLOR_MODE),
1111 mClippingMode(ClippingMode::DISABLED),
1112 mBlendEquation(DevelBlendEquation::ADD)
1116 void Actor::Initialize()
1120 GetEventThreadServices().RegisterObject(this);
1125 // Remove mParent pointers from children even if we're destroying core,
1126 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
1130 // Guard to allow handle destruction after Core has been destroyed
1131 if(EventThreadServices::IsCoreRunning())
1133 // Root layer will destroy its node in its own destructor
1136 DestroyNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
1138 GetEventThreadServices().UnregisterObject(this);
1142 // Cleanup optional gesture data
1143 delete mGestureData;
1145 // Cleanup optional parent origin and anchor
1146 delete mParentOrigin;
1147 delete mAnchorPoint;
1150 void Actor::Add(Actor& child, bool notify)
1152 mParentImpl.Add(child, notify);
1155 void Actor::Remove(Actor& child, bool notify)
1157 mParentImpl.Remove(child, notify);
1160 void Actor::SwitchParent(Actor& newParent)
1162 if(this == &newParent)
1164 DALI_LOG_ERROR("Cannot add actor to itself");
1168 if(!this->OnScene() || !newParent.OnScene())
1170 DALI_LOG_ERROR("Both of current parent and new parent must be on Scene");
1174 newParent.Add(*this, false);
1177 uint32_t Actor::GetChildCount() const
1179 return mParentImpl.GetChildCount();
1182 ActorPtr Actor::GetChildAt(uint32_t index) const
1184 return mParentImpl.GetChildAt(index);
1187 ActorContainer& Actor::GetChildrenInternal()
1189 return mParentImpl.GetChildrenInternal();
1192 ActorPtr Actor::FindChildByName(ConstString actorName)
1194 return mParentImpl.FindChildByName(actorName);
1197 ActorPtr Actor::FindChildById(const uint32_t id)
1199 return mParentImpl.FindChildById(id);
1202 void Actor::UnparentChildren()
1204 mParentImpl.UnparentChildren();
1207 void Actor::ConnectToScene(uint32_t parentDepth, uint32_t layer3DParentsCount, bool notify)
1209 // This container is used instead of walking the Actor hierarchy.
1210 // It protects us when the Actor hierarchy is modified during OnSceneConnectionExternal callbacks.
1211 ActorContainer connectionList;
1215 mScene->RequestRebuildDepthTree();
1218 // This stage is not interrupted by user callbacks.
1219 mParentImpl.RecursiveConnectToScene(connectionList, layer3DParentsCount, parentDepth + 1);
1221 // Notify applications about the newly connected actors.
1222 for(const auto& actor : connectionList)
1224 actor->NotifyStageConnection(notify);
1231 * This method is called when the Actor is connected to the Stage.
1232 * The parent must have added its Node to the scene-graph.
1233 * The child must connect its Node to the parent's Node.
1234 * This is recursive; the child calls ConnectToScene() for its children.
1236 void Actor::ConnectToSceneGraph()
1238 DALI_ASSERT_DEBUG(mParent != NULL);
1240 // Reparent Node in next Update
1241 ConnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetParent()->GetNode(), GetNode());
1243 // Request relayout on all actors that are added to the scenegraph
1246 // Notification for Object::Observers
1250 void Actor::NotifyStageConnection(bool notify)
1252 // Actors can be removed (in a callback), before the on-stage stage is reported.
1253 // The actor may also have been reparented, in which case mOnSceneSignalled will be true.
1254 if(OnScene() && !mOnSceneSignalled)
1258 // Notification for external (CustomActor) derived classes
1259 OnSceneConnectionExternal(mDepth);
1261 if(!mOnSceneSignal.Empty())
1263 Dali::Actor handle(this);
1264 mOnSceneSignal.Emit(handle);
1268 // Guard against Remove during callbacks
1271 mOnSceneSignalled = true; // signal required next time Actor is removed
1276 void Actor::DisconnectFromStage(bool notify)
1278 // This container is used instead of walking the Actor hierachy.
1279 // It protects us when the Actor hierachy is modified during OnSceneDisconnectionExternal callbacks.
1280 ActorContainer disconnectionList;
1284 mScene->RequestRebuildDepthTree();
1287 // This stage is not interrupted by user callbacks
1288 mParentImpl.RecursiveDisconnectFromScene(disconnectionList);
1290 // Notify applications about the newly disconnected actors.
1291 for(const auto& actor : disconnectionList)
1293 actor->NotifyStageDisconnection(notify);
1298 * This method is called by an actor or its parent, before a node removal message is sent.
1299 * This is recursive; the child calls DisconnectFromStage() for its children.
1301 void Actor::DisconnectFromSceneGraph()
1303 // Notification for Object::Observers
1304 OnSceneObjectRemove();
1307 void Actor::NotifyStageDisconnection(bool notify)
1309 // Actors can be added (in a callback), before the off-stage state is reported.
1310 // Also if the actor was added & removed before mOnSceneSignalled was set, then we don't notify here.
1311 // only do this step if there is a stage, i.e. Core is not being shut down
1312 if(EventThreadServices::IsCoreRunning() && !OnScene() && mOnSceneSignalled)
1316 // Notification for external (CustomeActor) derived classes
1317 OnSceneDisconnectionExternal();
1319 if(!mOffSceneSignal.Empty())
1321 Dali::Actor handle(this);
1322 mOffSceneSignal.Emit(handle);
1326 // Guard against Add during callbacks
1329 mOnSceneSignalled = false; // signal required next time Actor is added
1334 bool Actor::IsNodeConnected() const
1336 return OnScene() && (IsRoot() || GetNode().GetParent());
1339 // This method initiates traversal of the actor tree using depth-first
1340 // traversal to set a depth index based on traversal order. It sends a
1341 // single message to update manager to update all the actor's nodes in
1342 // this tree with the depth index. The sceneGraphNodeDepths vector's
1343 // elements are ordered by depth, and could be used to reduce sorting
1344 // in the update thread.
1345 void Actor::RebuildDepthTree()
1347 DALI_LOG_TIMER_START(depthTimer);
1349 // Vector of scene-graph nodes and their depths to send to UpdateManager
1350 // in a single message
1351 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths(new SceneGraph::NodeDepths());
1353 int32_t depthIndex = 1;
1354 mParentImpl.DepthTraverseActorTree(sceneGraphNodeDepths, depthIndex);
1356 SetDepthIndicesMessage(GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths);
1357 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
1360 void Actor::SetDefaultProperty(Property::Index index, const Property::Value& property)
1362 PropertyHandler::SetDefaultProperty(*this, index, property);
1365 // TODO: This method needs to be removed
1366 void Actor::SetSceneGraphProperty(Property::Index index, const PropertyMetadata& entry, const Property::Value& value)
1368 PropertyHandler::SetSceneGraphProperty(index, entry, value, GetEventThreadServices(), GetNode());
1371 Property::Value Actor::GetDefaultProperty(Property::Index index) const
1373 Property::Value value;
1375 if(!GetCachedPropertyValue(index, value))
1377 // If property value is not stored in the event-side, then it must be a scene-graph only property
1378 GetCurrentPropertyValue(index, value);
1384 Property::Value Actor::GetDefaultPropertyCurrentValue(Property::Index index) const
1386 Property::Value value;
1388 if(!GetCurrentPropertyValue(index, value))
1390 // If unable to retrieve scene-graph property value, then it must be an event-side only property
1391 GetCachedPropertyValue(index, value);
1397 void Actor::OnNotifyDefaultPropertyAnimation(Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType)
1399 PropertyHandler::OnNotifyDefaultPropertyAnimation(*this, animation, index, value, animationType);
1402 const PropertyBase* Actor::GetSceneObjectAnimatableProperty(Property::Index index) const
1404 const PropertyBase* property = PropertyHandler::GetSceneObjectAnimatableProperty(index, GetNode());
1407 // not our property, ask base
1408 property = Object::GetSceneObjectAnimatableProperty(index);
1414 const PropertyInputImpl* Actor::GetSceneObjectInputProperty(Property::Index index) const
1416 const PropertyInputImpl* property = PropertyHandler::GetSceneObjectInputProperty(index, GetNode());
1419 // reuse animatable property getter as animatable properties are inputs as well
1420 // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
1421 property = GetSceneObjectAnimatableProperty(index);
1427 int32_t Actor::GetPropertyComponentIndex(Property::Index index) const
1429 int32_t componentIndex = PropertyHandler::GetPropertyComponentIndex(index);
1430 if(Property::INVALID_COMPONENT_INDEX == componentIndex)
1433 componentIndex = Object::GetPropertyComponentIndex(index);
1436 return componentIndex;
1439 const SceneGraph::Node& Actor::GetNode() const
1441 return *static_cast<const SceneGraph::Node*>(mUpdateObject);
1446 CheckParentAndCall(mParent, *this, &ActorParent::RaiseChild);
1451 CheckParentAndCall(mParent, *this, &ActorParent::LowerChild);
1454 void Actor::RaiseToTop()
1456 CheckParentAndCall(mParent, *this, &ActorParent::RaiseChildToTop);
1459 void Actor::LowerToBottom()
1461 CheckParentAndCall(mParent, *this, &ActorParent::LowerChildToBottom);
1464 void Actor::RaiseAbove(Internal::Actor& target)
1466 CheckParentAndCall(mParent, *this, target, &ActorParent::RaiseChildAbove);
1469 void Actor::LowerBelow(Internal::Actor& target)
1471 CheckParentAndCall(mParent, *this, target, &ActorParent::LowerChildBelow);
1474 void Actor::SetParent(ActorParent* parent, bool notify)
1478 DALI_ASSERT_ALWAYS(!mParent && "Actor cannot have 2 parents");
1481 Actor* parentActor = static_cast<Actor*>(parent);
1482 mScene = parentActor->mScene;
1484 if(EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
1485 parentActor->OnScene())
1487 // Instruct each actor to create a corresponding node in the scene graph
1488 ConnectToScene(parentActor->GetHierarchyDepth(), parentActor->GetLayer3DParentCount(), notify);
1491 // Resolve the name and index for the child properties if any
1492 ResolveChildProperties();
1494 else // parent being set to NULL
1496 DALI_ASSERT_ALWAYS(mParent != nullptr && "Actor should have a parent");
1500 if(EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
1503 // Disconnect the Node & its children from the scene-graph.
1504 DisconnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
1506 // Instruct each actor to discard pointers to the scene-graph
1507 DisconnectFromStage(notify);
1514 Rect<> Actor::CalculateScreenExtents() const
1516 if(mLayer3DParentsCount == 0)
1518 // We can assume that this actor is under 2d layer. Use faster, but imprecise algorithm
1519 auto screenPosition = GetCurrentScreenPosition();
1520 BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
1521 return CalculateActorScreenExtents(*this, screenPosition, bufferIndex);
1525 BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
1526 return CalculateActorScreenExtentsRenderTaskList(*this, bufferIndex);
1530 Vector3 Actor::GetAnchorPointForPosition() const
1532 return (mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT);
1535 bool Actor::GetCachedPropertyValue(Property::Index index, Property::Value& value) const
1537 return PropertyHandler::GetCachedPropertyValue(*this, index, value);
1540 bool Actor::GetCurrentPropertyValue(Property::Index index, Property::Value& value) const
1542 return PropertyHandler::GetCurrentPropertyValue(*this, index, value);
1545 bool Actor::RelayoutDependentOnParent(Dimension::Type dimension)
1547 return mSizer.RelayoutDependentOnParent(dimension);
1550 bool Actor::RelayoutDependentOnChildren(Dimension::Type dimension)
1552 return mSizer.RelayoutDependentOnChildrenBase(dimension);
1555 bool Actor::RelayoutDependentOnDimension(Dimension::Type dimension, Dimension::Type dependentDimension)
1557 return mSizer.RelayoutDependentOnDimension(dimension, dependentDimension);
1560 void Actor::SetPadding(const Vector2& padding, Dimension::Type dimension)
1562 mSizer.SetPadding(padding, dimension);
1565 Vector2 Actor::GetPadding(Dimension::Type dimension) const
1567 return mSizer.GetPadding(dimension);
1570 void Actor::SetLayoutNegotiated(bool negotiated, Dimension::Type dimension)
1572 mSizer.SetLayoutNegotiated(negotiated, dimension);
1575 bool Actor::IsLayoutNegotiated(Dimension::Type dimension) const
1577 return mSizer.IsLayoutNegotiated(dimension);
1580 float Actor::GetHeightForWidthBase(float width)
1582 // Can be overridden in derived class
1583 return mSizer.GetHeightForWidthBase(width);
1586 float Actor::GetWidthForHeightBase(float height)
1588 // Can be overridden in derived class
1589 return mSizer.GetWidthForHeightBase(height);
1592 float Actor::CalculateChildSizeBase(const Dali::Actor& child, Dimension::Type dimension)
1594 // Can be overridden in derived class
1595 return mSizer.CalculateChildSizeBase(child, dimension);
1598 bool Actor::RelayoutDependentOnChildrenBase(Dimension::Type dimension)
1600 return mSizer.RelayoutDependentOnChildrenBase(dimension);
1603 float Actor::CalculateChildSize(const Dali::Actor& child, Dimension::Type dimension)
1605 // Can be overridden in derived class
1606 return mSizer.CalculateChildSizeBase(child, dimension);
1609 float Actor::GetHeightForWidth(float width)
1611 // Can be overridden in derived class
1612 return mSizer.GetHeightForWidthBase(width);
1615 float Actor::GetWidthForHeight(float height)
1617 // Can be overridden in derived class
1618 return mSizer.GetWidthForHeightBase(height);
1621 float Actor::GetRelayoutSize(Dimension::Type dimension) const
1623 return mSizer.GetRelayoutSize(dimension);
1626 void Actor::NegotiateSize(const Vector2& allocatedSize, RelayoutContainer& container)
1628 mSizer.NegotiateSize(allocatedSize, container);
1631 void Actor::RelayoutRequest(Dimension::Type dimension)
1633 mSizer.RelayoutRequest(dimension);
1636 void Actor::SetMinimumSize(float size, Dimension::Type dimension)
1638 mSizer.SetMinimumSize(size, dimension);
1641 float Actor::GetMinimumSize(Dimension::Type dimension) const
1643 return mSizer.GetMinimumSize(dimension);
1646 void Actor::SetMaximumSize(float size, Dimension::Type dimension)
1648 mSizer.SetMaximumSize(size, dimension);
1651 float Actor::GetMaximumSize(Dimension::Type dimension) const
1653 return mSizer.GetMaximumSize(dimension);
1656 void Actor::SetVisibleInternal(bool visible, SendMessage::Type sendMessage)
1658 if(mVisible != visible)
1660 if(sendMessage == SendMessage::TRUE)
1662 // node is being used in a separate thread; queue a message to set the value & base value
1663 SceneGraph::NodePropertyMessage<bool>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible);
1665 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
1670 // Emit the signal on this actor and all its children
1671 mParentImpl.EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::SELF);
1675 void Actor::SetSiblingOrderOfChild(Actor& child, uint32_t order)
1677 mParentImpl.SetSiblingOrderOfChild(child, order);
1680 uint32_t Actor::GetSiblingOrderOfChild(const Actor& child) const
1682 return mParentImpl.GetSiblingOrderOfChild(child);
1685 void Actor::RaiseChild(Actor& child)
1687 mParentImpl.RaiseChild(child);
1690 void Actor::LowerChild(Actor& child)
1692 mParentImpl.LowerChild(child);
1695 void Actor::RaiseChildToTop(Actor& child)
1697 mParentImpl.RaiseChildToTop(child);
1700 void Actor::LowerChildToBottom(Actor& child)
1702 mParentImpl.LowerChildToBottom(child);
1705 void Actor::RaiseChildAbove(Actor& child, Actor& target)
1707 mParentImpl.RaiseChildAbove(child, target);
1710 void Actor::LowerChildBelow(Actor& child, Actor& target)
1712 mParentImpl.LowerChildBelow(child, target);
1715 void Actor::SetInheritLayoutDirection(bool inherit)
1717 if(mInheritLayoutDirection != inherit)
1719 mInheritLayoutDirection = inherit;
1721 if(inherit && mParent)
1723 mParentImpl.InheritLayoutDirectionRecursively(GetParent()->mLayoutDirection);
1728 void Actor::SetUpdateAreaHint(const Vector4& updateAreaHint)
1730 // node is being used in a separate thread; queue a message to set the value & base value
1731 SceneGraph::NodePropertyMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mUpdateAreaHint, &AnimatableProperty<Vector4>::Bake, updateAreaHint);
1734 } // namespace Internal