2 * Copyright (c) 2023 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("useTextureUpdateArea", BOOLEAN, true, false, false, Dali::DevelActor::Property::USE_TEXTURE_UPDATE_AREA)
154 DALI_PROPERTY("dispatchTouchMotion", BOOLEAN, true, false, false, Dali::DevelActor::Property::DISPATCH_TOUCH_MOTION)
155 DALI_PROPERTY("dispatchHoverMotion", BOOLEAN, true, false, false, Dali::DevelActor::Property::DISPATCH_HOVER_MOTION)
156 DALI_PROPERTY_TABLE_END(DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties)
160 static constexpr std::string_view SIGNAL_HOVERED = "hovered";
161 static constexpr std::string_view SIGNAL_WHEEL_EVENT = "wheelEvent";
162 static constexpr std::string_view SIGNAL_ON_SCENE = "onScene";
163 static constexpr std::string_view SIGNAL_OFF_SCENE = "offScene";
164 static constexpr std::string_view SIGNAL_ON_RELAYOUT = "onRelayout";
165 static constexpr std::string_view SIGNAL_TOUCHED = "touched";
166 static constexpr std::string_view SIGNAL_VISIBILITY_CHANGED = "visibilityChanged";
167 static constexpr std::string_view SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
168 static constexpr std::string_view SIGNAL_CHILD_ADDED = "childAdded";
169 static constexpr std::string_view SIGNAL_CHILD_REMOVED = "childRemoved";
173 static constexpr std::string_view ACTION_SHOW = "show";
174 static constexpr std::string_view ACTION_HIDE = "hide";
176 BaseHandle CreateActor()
178 return Dali::Actor::New();
182 * Connects a callback function with the object's signals.
183 * @param[in] object The object providing the signal.
184 * @param[in] tracker Used to disconnect the signal.
185 * @param[in] signalName The signal to connect to.
186 * @param[in] functor A newly allocated FunctorDelegate.
187 * @return True if the signal was connected.
188 * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
190 static bool DoConnectSignal(BaseObject* object,
191 ConnectionTrackerInterface* tracker,
192 const std::string& signalName,
193 FunctorDelegate* functor)
195 bool connected(true);
196 Actor* actor = static_cast<Actor*>(object); // TypeRegistry guarantees that this is the correct type.
198 std::string_view name(signalName);
200 if(name == SIGNAL_HOVERED)
202 actor->HoveredSignal().Connect(tracker, functor);
204 else if(signalName == SIGNAL_WHEEL_EVENT)
206 actor->WheelEventSignal().Connect(tracker, functor);
208 else if(name == SIGNAL_ON_SCENE)
210 actor->OnSceneSignal().Connect(tracker, functor);
212 else if(name == SIGNAL_OFF_SCENE)
214 actor->OffSceneSignal().Connect(tracker, functor);
216 else if(name == SIGNAL_ON_RELAYOUT)
218 actor->OnRelayoutSignal().Connect(tracker, functor);
220 else if(name == SIGNAL_TOUCHED)
222 actor->TouchedSignal().Connect(tracker, functor);
224 else if(name == SIGNAL_VISIBILITY_CHANGED)
226 actor->VisibilityChangedSignal().Connect(tracker, functor);
228 else if(name == SIGNAL_LAYOUT_DIRECTION_CHANGED)
230 actor->LayoutDirectionChangedSignal().Connect(tracker, functor);
232 else if(name == SIGNAL_CHILD_ADDED)
234 actor->ChildAddedSignal().Connect(tracker, functor);
236 else if(name == SIGNAL_CHILD_REMOVED)
238 actor->ChildRemovedSignal().Connect(tracker, functor);
242 // signalName does not match any signal
250 * Performs actions as requested using the action name.
251 * @param[in] object The object on which to perform the action.
252 * @param[in] actionName The action to perform.
253 * @param[in] attributes The attributes with which to perfrom this action.
254 * @return true if the action was done.
256 bool DoAction(BaseObject* object,
257 const std::string& actionName,
258 const Property::Map& attributes)
261 Actor* actor = dynamic_cast<Actor*>(object);
265 std::string_view name(actionName);
266 if(name == ACTION_SHOW)
268 actor->SetVisible(true);
271 else if(name == ACTION_HIDE)
273 actor->SetVisible(false);
281 TypeRegistration mType(typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties);
283 SignalConnectorType signalConnector2(mType, std::string(SIGNAL_HOVERED), &DoConnectSignal);
284 SignalConnectorType signalConnector3(mType, std::string(SIGNAL_WHEEL_EVENT), &DoConnectSignal);
285 SignalConnectorType signalConnector4(mType, std::string(SIGNAL_ON_SCENE), &DoConnectSignal);
286 SignalConnectorType signalConnector5(mType, std::string(SIGNAL_OFF_SCENE), &DoConnectSignal);
287 SignalConnectorType signalConnector6(mType, std::string(SIGNAL_ON_RELAYOUT), &DoConnectSignal);
288 SignalConnectorType signalConnector7(mType, std::string(SIGNAL_TOUCHED), &DoConnectSignal);
289 SignalConnectorType signalConnector8(mType, std::string(SIGNAL_VISIBILITY_CHANGED), &DoConnectSignal);
290 SignalConnectorType signalConnector9(mType, std::string(SIGNAL_LAYOUT_DIRECTION_CHANGED), &DoConnectSignal);
291 SignalConnectorType signalConnector10(mType, std::string(SIGNAL_CHILD_ADDED), &DoConnectSignal);
292 SignalConnectorType signalConnector11(mType, std::string(SIGNAL_CHILD_REMOVED), &DoConnectSignal);
294 TypeAction a1(mType, std::string(ACTION_SHOW), &DoAction);
295 TypeAction a2(mType, std::string(ACTION_HIDE), &DoAction);
297 /// Helper for emitting a signal
298 template<typename Signal, typename Event>
299 bool EmitConsumingSignal(Actor& actor, Signal& signal, const Event& event)
301 bool consumed = false;
305 Dali::Actor handle(&actor);
306 consumed = signal.Emit(handle, event);
312 /// Helper for emitting signals with multiple parameters
313 template<typename Signal, typename... Param>
314 void EmitSignal(Actor& actor, Signal& signal, Param... params)
318 Dali::Actor handle(&actor);
319 signal.Emit(handle, params...);
323 using ActorParentSiblingOrderMethod = void (ActorParent::*)(Actor&);
324 using ActorParentSiblingOrderMethodWithTarget = void (ActorParent::*)(Actor&, Actor&);
326 /// Helper to check and call actor sibling methods in ActorParent
327 void CheckParentAndCall(ActorParent* parent, Actor& actor, ActorParentSiblingOrderMethod memberFunction)
331 (parent->*memberFunction)(actor);
335 DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
339 /// Helper to check and call actor sibling methods with a target parameter in ActorParent
340 void CheckParentAndCall(ActorParent* parent, Actor& actor, Actor& target, ActorParentSiblingOrderMethodWithTarget memberFunction)
344 (parent->*memberFunction)(actor, target);
348 DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
352 } // unnamed namespace
354 ActorPtr Actor::New()
356 // pass a reference to actor, actor does not own its node
357 ActorPtr actor(new Actor(BASIC, *CreateNode()));
359 // Second-phase construction
365 const SceneGraph::Node* Actor::CreateNode()
367 // create node. Nodes are owned by the update manager
368 SceneGraph::Node* node = SceneGraph::Node::New();
369 OwnerPointer<SceneGraph::Node> transferOwnership(node);
370 Internal::ThreadLocalStorage* tls = Internal::ThreadLocalStorage::GetInternal();
372 DALI_ASSERT_ALWAYS(tls && "ThreadLocalStorage is null");
374 AddNodeMessage(tls->GetUpdateManager(), transferOwnership);
379 void Actor::SetName(std::string_view name)
381 mName = ConstString(name);
383 // ATTENTION: string for debug purposes is not thread safe.
384 DALI_LOG_SET_OBJECT_STRING(const_cast<SceneGraph::Node*>(&GetNode()), mName.GetCString());
387 uint32_t Actor::GetId() const
389 return GetNode().GetId();
392 Dali::Layer Actor::GetLayer()
396 // Short-circuit for Layer derived actors
399 layer = Dali::Layer(static_cast<Dali::Internal::Layer*>(this)); // static cast as we trust the flag
402 // Find the immediate Layer parent
403 for(Actor* parent = GetParent(); !layer && parent != nullptr; parent = parent->GetParent())
405 if(parent->IsLayer())
407 layer = Dali::Layer(static_cast<Dali::Internal::Layer*>(parent)); // static cast as we trust the flag
414 void Actor::Unparent()
418 // Remove this actor from the parent. The remove will put a relayout request in for
419 // the parent if required
420 mParent->Remove(*this);
421 // mParent is now NULL!
425 void Actor::SetParentOrigin(const Vector3& origin)
427 // node is being used in a separate thread; queue a message to set the value & base value
428 SetParentOriginMessage(GetEventThreadServices(), GetNode(), origin);
430 // Cache for event-thread access
433 // not allocated, check if different from default
434 if(ParentOrigin::DEFAULT != origin)
436 mParentOrigin = new Vector3(origin);
441 // check if different from current costs more than just set
442 *mParentOrigin = origin;
446 const Vector3& Actor::GetCurrentParentOrigin() const
448 // Cached for event-thread access
449 return (mParentOrigin) ? *mParentOrigin : ParentOrigin::DEFAULT;
452 void Actor::SetAnchorPoint(const Vector3& anchor)
454 // node is being used in a separate thread; queue a message to set the value & base value
455 SetAnchorPointMessage(GetEventThreadServices(), GetNode(), anchor);
457 // Cache for event-thread access
460 // not allocated, check if different from default
461 if(AnchorPoint::DEFAULT != anchor)
463 mAnchorPoint = new Vector3(anchor);
468 // check if different from current costs more than just set
469 *mAnchorPoint = anchor;
473 const Vector3& Actor::GetCurrentAnchorPoint() const
475 // Cached for event-thread access
476 return (mAnchorPoint) ? *mAnchorPoint : AnchorPoint::DEFAULT;
479 void Actor::SetPosition(float x, float y)
481 SetPosition(Vector3(x, y, 0.0f));
484 void Actor::SetPosition(float x, float y, float z)
486 SetPosition(Vector3(x, y, z));
489 void Actor::SetPosition(const Vector3& position)
491 mTargetPosition = position;
493 // node is being used in a separate thread; queue a message to set the value & base value
494 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position);
497 void Actor::SetX(float x)
499 mTargetPosition.x = x;
501 // node is being used in a separate thread; queue a message to set the value & base value
502 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x);
505 void Actor::SetY(float y)
507 mTargetPosition.y = y;
509 // node is being used in a separate thread; queue a message to set the value & base value
510 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y);
513 void Actor::SetZ(float z)
515 mTargetPosition.z = z;
517 // node is being used in a separate thread; queue a message to set the value & base value
518 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z);
521 void Actor::TranslateBy(const Vector3& distance)
523 mTargetPosition += distance;
525 // node is being used in a separate thread; queue a message to set the value & base value
526 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance);
529 const Vector3& Actor::GetCurrentPosition() const
531 // node is being used in a separate thread; copy the value from the previous update
532 return GetNode().GetPosition(GetEventThreadServices().GetEventBufferIndex());
535 const Vector3& Actor::GetCurrentWorldPosition() const
537 // node is being used in a separate thread; copy the value from the previous update
538 return GetNode().GetWorldPosition(GetEventThreadServices().GetEventBufferIndex());
541 const Vector2 Actor::CalculateScreenPosition() const
545 if(mLayer3DParentsCount == 0)
547 // We can assume that this actor is under 2d layer. Use faster, but imprecise algorithm
548 return CalculateActorScreenPosition(*this);
552 return CalculateActorScreenPositionRenderTaskList(*this);
555 return Vector2::ZERO;
558 const Vector2 Actor::GetCurrentScreenPosition() const
562 BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
563 if(mLayer3DParentsCount == 0)
565 // We can assume that this actor is under 2d layer. Use faster, but imprecise algorithm
566 return CalculateCurrentActorScreenPosition(*this, bufferIndex);
570 return CalculateCurrentActorScreenPositionRenderTaskList(*this, bufferIndex);
573 return Vector2::ZERO;
576 void Actor::SetInheritPosition(bool inherit)
578 if(mInheritPosition != inherit)
580 // non animatable so keep local copy
581 mInheritPosition = inherit;
582 SetInheritPositionMessage(GetEventThreadServices(), GetNode(), inherit);
586 void Actor::SetOrientation(const Radian& angle, const Vector3& axis)
588 Vector3 normalizedAxis(axis.x, axis.y, axis.z);
589 normalizedAxis.Normalize();
591 Quaternion orientation(angle, normalizedAxis);
593 SetOrientation(orientation);
596 void Actor::SetOrientation(const Quaternion& orientation)
598 mTargetOrientation = orientation;
600 // node is being used in a separate thread; queue a message to set the value & base value
601 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation);
604 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
606 RotateBy(Quaternion(angle, axis));
609 void Actor::RotateBy(const Quaternion& relativeRotation)
611 mTargetOrientation *= Quaternion(relativeRotation);
613 // node is being used in a separate thread; queue a message to set the value & base value
614 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation);
617 const Quaternion& Actor::GetCurrentOrientation() const
619 // node is being used in a separate thread; copy the value from the previous update
620 return GetNode().GetOrientation(GetEventThreadServices().GetEventBufferIndex());
623 const Quaternion& Actor::GetCurrentWorldOrientation() const
625 // node is being used in a separate thread; copy the value from the previous update
626 return GetNode().GetWorldOrientation(GetEventThreadServices().GetEventBufferIndex());
629 void Actor::SetScale(float scale)
631 SetScale(Vector3(scale, scale, scale));
634 void Actor::SetScale(float x, float y, float z)
636 SetScale(Vector3(x, y, z));
639 void Actor::SetScale(const Vector3& scale)
641 mTargetScale = scale;
643 // node is being used in a separate thread; queue a message to set the value & base value
644 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale);
647 void Actor::SetScaleX(float x)
651 // node is being used in a separate thread; queue a message to set the value & base value
652 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x);
655 void Actor::SetScaleY(float y)
659 // node is being used in a separate thread; queue a message to set the value & base value
660 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y);
663 void Actor::SetScaleZ(float z)
667 // node is being used in a separate thread; queue a message to set the value & base value
668 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z);
671 void Actor::ScaleBy(const Vector3& relativeScale)
673 mTargetScale *= relativeScale;
675 // node is being used in a separate thread; queue a message to set the value & base value
676 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale);
679 const Vector3& Actor::GetCurrentScale() const
681 // node is being used in a separate thread; copy the value from the previous update
682 return GetNode().GetScale(GetEventThreadServices().GetEventBufferIndex());
685 const Vector3& Actor::GetCurrentWorldScale() const
687 // node is being used in a separate thread; copy the value from the previous update
688 return GetNode().GetWorldScale(GetEventThreadServices().GetEventBufferIndex());
691 void Actor::SetInheritScale(bool inherit)
693 if(mInheritScale != inherit)
695 // non animatable so keep local copy
696 mInheritScale = inherit;
697 // node is being used in a separate thread; queue a message to set the value
698 SetInheritScaleMessage(GetEventThreadServices(), GetNode(), inherit);
702 Matrix Actor::GetCurrentWorldMatrix() const
704 return GetNode().GetWorldMatrix(0);
707 void Actor::SetVisible(bool visible)
709 SetVisibleInternal(visible, SendMessage::TRUE);
712 bool Actor::IsVisible() const
714 // node is being used in a separate thread; copy the value from the previous update
715 return GetNode().IsVisible(GetEventThreadServices().GetEventBufferIndex());
718 void Actor::SetOpacity(float opacity)
720 mTargetColor.a = opacity;
722 // node is being used in a separate thread; queue a message to set the value & base value
723 SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeW, opacity);
725 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
728 float Actor::GetCurrentOpacity() const
730 // node is being used in a separate thread; copy the value from the previous update
731 return GetNode().GetOpacity(GetEventThreadServices().GetEventBufferIndex());
734 const Vector4& Actor::GetCurrentWorldColor() const
736 return GetNode().GetWorldColor(GetEventThreadServices().GetEventBufferIndex());
739 void Actor::SetColor(const Vector4& color)
741 mTargetColor = color;
743 // node is being used in a separate thread; queue a message to set the value & base value
744 SceneGraph::NodePropertyMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::Bake, color);
746 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
749 void Actor::SetColorRed(float red)
751 mTargetColor.r = red;
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>::BakeX, red);
756 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
759 void Actor::SetColorGreen(float green)
761 mTargetColor.g = green;
763 // node is being used in a separate thread; queue a message to set the value & base value
764 SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeY, green);
766 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
769 void Actor::SetColorBlue(float blue)
771 mTargetColor.b = blue;
773 // node is being used in a separate thread; queue a message to set the value & base value
774 SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeZ, blue);
776 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
779 const Vector4& Actor::GetCurrentColor() const
781 // node is being used in a separate thread; copy the value from the previous update
782 return GetNode().GetColor(GetEventThreadServices().GetEventBufferIndex());
785 void Actor::SetInheritOrientation(bool inherit)
787 if(mInheritOrientation != inherit)
789 // non animatable so keep local copy
790 mInheritOrientation = inherit;
791 // node is being used in a separate thread; queue a message to set the value
792 SetInheritOrientationMessage(GetEventThreadServices(), GetNode(), inherit);
796 void Actor::SetSizeModeFactor(const Vector3& factor)
798 mSizer.SetSizeModeFactor(factor);
801 const Vector3& Actor::GetSizeModeFactor() const
803 return mSizer.GetSizeModeFactor();
806 void Actor::SetColorMode(ColorMode colorMode)
808 // non animatable so keep local copy
809 mColorMode = colorMode;
810 // node is being used in a separate thread; queue a message to set the value
811 SetColorModeMessage(GetEventThreadServices(), GetNode(), colorMode);
814 void Actor::SetSize(float width, float height)
816 SetSize(Vector2(width, height));
819 void Actor::SetSize(float width, float height, float depth)
821 SetSize(Vector3(width, height, depth));
824 void Actor::SetSize(const Vector2& size)
826 SetSize(Vector3(size.width, size.height, 0.f));
829 void Actor::SetSize(const Vector3& size)
831 mSizer.SetSize(size);
834 void Actor::SetWidth(float width)
836 mSizer.SetWidth(width);
839 void Actor::SetHeight(float height)
841 mSizer.SetHeight(height);
844 void Actor::SetDepth(float depth)
846 mSizer.SetDepth(depth);
847 // node is being used in a separate thread; queue a message to set the value & base value
848 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth);
851 Vector3 Actor::GetTargetSize() const
853 return mSizer.GetTargetSize();
856 const Vector3& Actor::GetCurrentSize() const
858 // node is being used in a separate thread; copy the value from the previous update
859 return GetNode().GetSize(GetEventThreadServices().GetEventBufferIndex());
862 Vector3 Actor::GetNaturalSize() const
864 // It is up to deriving classes to return the appropriate natural size
865 return Vector3(0.0f, 0.0f, 0.0f);
868 void Actor::SetResizePolicy(ResizePolicy::Type policy, Dimension::Type dimension)
870 mSizer.SetResizePolicy(policy, dimension);
873 ResizePolicy::Type Actor::GetResizePolicy(Dimension::Type dimension) const
875 return mSizer.GetResizePolicy(dimension);
878 void Actor::SetRelayoutEnabled(bool relayoutEnabled)
880 mSizer.SetRelayoutEnabled(relayoutEnabled);
883 bool Actor::IsRelayoutEnabled() const
885 return mSizer.IsRelayoutEnabled();
888 void Actor::SetLayoutDirty(bool dirty, Dimension::Type dimension)
890 mSizer.SetLayoutDirty(dirty, dimension);
893 bool Actor::IsLayoutDirty(Dimension::Type dimension) const
895 return mSizer.IsLayoutDirty(dimension);
898 bool Actor::RelayoutPossible(Dimension::Type dimension) const
900 return mSizer.RelayoutPossible(dimension);
903 bool Actor::RelayoutRequired(Dimension::Type dimension) const
905 return mSizer.RelayoutRequired(dimension);
908 uint32_t Actor::AddRenderer(Renderer& renderer)
912 mRenderers = new RendererContainer(GetEventThreadServices());
914 return mRenderers->Add(GetNode(), renderer, mIsBlendEquationSet, mBlendEquation);
917 uint32_t Actor::GetRendererCount() const
919 return mRenderers ? mRenderers->GetCount() : 0u;
922 RendererPtr Actor::GetRendererAt(uint32_t index)
924 return mRenderers ? mRenderers->GetRendererAt(index) : nullptr;
927 void Actor::RemoveRenderer(Renderer& renderer)
931 mRenderers->Remove(GetNode(), renderer);
935 void Actor::RemoveRenderer(uint32_t index)
939 mRenderers->Remove(GetNode(), index);
943 void Actor::SetBlendEquation(DevelBlendEquation::Type blendEquation)
945 if(Dali::Capabilities::IsBlendEquationSupported(blendEquation))
947 if(mBlendEquation != blendEquation)
949 mBlendEquation = blendEquation;
952 mRenderers->SetBlending(blendEquation);
955 mIsBlendEquationSet = true;
959 DALI_LOG_ERROR("Invalid blend equation is entered.\n");
963 DevelBlendEquation::Type Actor::GetBlendEquation() const
965 return mBlendEquation;
968 void Actor::SetTransparent(bool transparent)
970 SetTransparentMessage(GetEventThreadServices(), GetNode(), transparent);
973 bool Actor::IsTransparent() const
975 return GetNode().IsTransparent();
978 void Actor::SetDrawMode(DrawMode::Type drawMode)
980 // this flag is not animatable so keep the value
981 mDrawMode = drawMode;
983 // node is being used in a separate thread; queue a message to set the value
984 SetDrawModeMessage(GetEventThreadServices(), GetNode(), drawMode);
987 bool Actor::ScreenToLocal(float& localX, float& localY, float screenX, float screenY) const
989 return mScene && OnScene() && ConvertScreenToLocalRenderTaskList(mScene->GetRenderTaskList(), GetNode().GetWorldMatrix(0), GetCurrentSize(), localX, localY, screenX, screenY);
992 bool Actor::ScreenToLocal(const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY) const
994 return OnScene() && ConvertScreenToLocalRenderTask(renderTask, GetNode().GetWorldMatrix(0), GetCurrentSize(), localX, localY, screenX, screenY);
997 bool Actor::ScreenToLocal(const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY) const
999 return OnScene() && ConvertScreenToLocal(viewMatrix, projectionMatrix, GetNode().GetWorldMatrix(0), GetCurrentSize(), viewport, localX, localY, screenX, screenY);
1002 ActorGestureData& Actor::GetGestureData()
1004 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1005 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1006 if(nullptr == mGestureData)
1008 mGestureData = new ActorGestureData;
1010 return *mGestureData;
1013 bool Actor::IsGestureRequired(GestureType::Value type) const
1015 return mGestureData && mGestureData->IsGestureRequired(type);
1018 bool Actor::EmitInterceptTouchEventSignal(const Dali::TouchEvent& touch)
1020 return EmitConsumingSignal(*this, mInterceptTouchedSignal, touch);
1023 bool Actor::EmitTouchEventSignal(const Dali::TouchEvent& touch)
1025 return EmitConsumingSignal(*this, mTouchedSignal, touch);
1028 bool Actor::EmitHoverEventSignal(const Dali::HoverEvent& event)
1030 return EmitConsumingSignal(*this, mHoveredSignal, event);
1033 bool Actor::EmitInterceptWheelEventSignal(const Dali::WheelEvent& event)
1035 return EmitConsumingSignal(*this, mInterceptWheelSignal, event);
1038 bool Actor::EmitWheelEventSignal(const Dali::WheelEvent& event)
1040 return EmitConsumingSignal(*this, mWheelEventSignal, event);
1043 void Actor::EmitVisibilityChangedSignal(bool visible, DevelActor::VisibilityChange::Type type)
1045 EmitSignal(*this, mVisibilityChangedSignal, visible, type);
1048 void Actor::EmitLayoutDirectionChangedSignal(LayoutDirection::Type type)
1050 EmitSignal(*this, mLayoutDirectionChangedSignal, type);
1053 bool Actor::EmitHitTestResultSignal(Integration::Point point, Vector2 hitPointLocal, uint32_t timeStamp)
1057 if(IsHitTestResultRequired())
1059 Dali::Actor handle(this);
1060 Integration::Point newPoint(point);
1061 newPoint.SetHitActor(handle);
1062 newPoint.SetLocalPosition(hitPointLocal);
1063 Dali::TouchEvent touchEvent = Dali::Integration::NewTouchEvent(timeStamp, newPoint);
1064 hit = mHitTestResultSignal.Emit(handle, touchEvent);
1069 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
1071 return mParentImpl.ChildAddedSignal();
1074 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
1076 return mParentImpl.ChildRemovedSignal();
1079 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
1081 return mParentImpl.ChildOrderChangedSignal();
1084 Actor::Actor(DerivedType derivedType, const SceneGraph::Node& node)
1090 mRenderers(nullptr),
1091 mParentOrigin(nullptr),
1092 mAnchorPoint(nullptr),
1093 mGestureData(nullptr),
1094 mInterceptTouchedSignal(),
1097 mInterceptWheelSignal(),
1098 mWheelEventSignal(),
1101 mOnRelayoutSignal(),
1102 mVisibilityChangedSignal(),
1103 mLayoutDirectionChangedSignal(),
1104 mHitTestResultSignal(),
1105 mTargetOrientation(Quaternion::IDENTITY),
1106 mTargetColor(Color::WHITE),
1107 mTargetPosition(Vector3::ZERO),
1108 mTargetScale(Vector3::ONE),
1109 mTouchAreaOffset(0, 0, 0, 0),
1113 mLayer3DParentsCount(0),
1114 mIsRoot(ROOT_LAYER == derivedType),
1115 mIsLayer(LAYER == derivedType || ROOT_LAYER == derivedType),
1118 mLeaveRequired(false),
1119 mKeyboardFocusable(false),
1120 mKeyboardFocusableChildren(true),
1121 mTouchFocusable(false),
1122 mOnSceneSignalled(false),
1123 mInheritPosition(true),
1124 mInheritOrientation(true),
1125 mInheritScale(true),
1126 mPositionUsesAnchorPoint(true),
1128 mInheritLayoutDirection(true),
1129 mCaptureAllTouchAfterStart(false),
1130 mIsBlendEquationSet(false),
1131 mNeedGesturePropagation(false),
1132 mUserInteractionEnabled(true),
1133 mAllowOnlyOwnTouch(false),
1134 mUseTextureUpdateArea(false),
1135 mDispatchTouchMotion(true),
1136 mDispatchHoverMotion(true),
1137 mLayoutDirection(LayoutDirection::LEFT_TO_RIGHT),
1138 mDrawMode(DrawMode::NORMAL),
1139 mColorMode(Node::DEFAULT_COLOR_MODE),
1140 mClippingMode(ClippingMode::DISABLED),
1141 mBlendEquation(DevelBlendEquation::ADD)
1145 void Actor::Initialize()
1149 GetEventThreadServices().RegisterObject(this);
1154 // Remove mParent pointers from children even if we're destroying core,
1155 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
1158 // Guard to allow handle destruction after Core has been destroyed
1159 if(EventThreadServices::IsCoreRunning())
1163 // Detach all renderers before delete container.
1164 mRenderers->RemoveAll(GetNode());
1167 // Root layer will destroy its node in its own destructor
1170 DestroyNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
1172 GetEventThreadServices().UnregisterObject(this);
1175 // Cleanup renderer list
1178 // Cleanup optional gesture data
1179 delete mGestureData;
1181 // Cleanup optional parent origin and anchor
1182 delete mParentOrigin;
1183 delete mAnchorPoint;
1186 void Actor::Add(Actor& child, bool notify)
1188 mParentImpl.Add(child, notify);
1191 void Actor::Remove(Actor& child, bool notify)
1193 mParentImpl.Remove(child, notify);
1196 void Actor::SwitchParent(Actor& newParent)
1198 if(this == &newParent)
1200 DALI_LOG_ERROR("Cannot add actor to itself");
1204 if(!this->OnScene() || !newParent.OnScene())
1206 DALI_LOG_ERROR("Both of current parent and new parent must be on Scene");
1210 newParent.Add(*this, false);
1213 uint32_t Actor::GetChildCount() const
1215 return mParentImpl.GetChildCount();
1218 ActorPtr Actor::GetChildAt(uint32_t index) const
1220 return mParentImpl.GetChildAt(index);
1223 ActorContainer& Actor::GetChildrenInternal()
1225 return mParentImpl.GetChildrenInternal();
1228 ActorPtr Actor::FindChildByName(ConstString actorName)
1230 return mParentImpl.FindChildByName(actorName);
1233 ActorPtr Actor::FindChildById(const uint32_t id)
1235 return mParentImpl.FindChildById(id);
1238 void Actor::UnparentChildren()
1240 mParentImpl.UnparentChildren();
1243 void Actor::ConnectToScene(uint32_t parentDepth, uint32_t layer3DParentsCount, bool notify)
1245 // This container is used instead of walking the Actor hierarchy.
1246 // It protects us when the Actor hierarchy is modified during OnSceneConnectionExternal callbacks.
1247 ActorContainer connectionList;
1251 mScene->RequestRebuildDepthTree();
1254 // This stage is not interrupted by user callbacks.
1255 mParentImpl.RecursiveConnectToScene(connectionList, layer3DParentsCount, parentDepth + 1);
1257 // Notify applications about the newly connected actors.
1258 for(const auto& actor : connectionList)
1260 actor->NotifyStageConnection(notify);
1267 * This method is called when the Actor is connected to the Stage.
1268 * The parent must have added its Node to the scene-graph.
1269 * The child must connect its Node to the parent's Node.
1270 * This is recursive; the child calls ConnectToScene() for its children.
1272 void Actor::ConnectToSceneGraph()
1274 DALI_ASSERT_DEBUG(mParent != NULL);
1276 // Reparent Node in next Update
1277 ConnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetParent()->GetNode(), GetNode());
1279 // Request relayout on all actors that are added to the scenegraph
1282 // Notification for Object::Observers
1286 void Actor::NotifyStageConnection(bool notify)
1288 // Actors can be removed (in a callback), before the on-stage stage is reported.
1289 // The actor may also have been reparented, in which case mOnSceneSignalled will be true.
1290 if(OnScene() && !mOnSceneSignalled)
1294 // Notification for external (CustomActor) derived classes
1295 OnSceneConnectionExternal(mDepth);
1297 if(!mOnSceneSignal.Empty())
1299 Dali::Actor handle(this);
1300 mOnSceneSignal.Emit(handle);
1304 // Guard against Remove during callbacks
1307 mOnSceneSignalled = true; // signal required next time Actor is removed
1312 void Actor::DisconnectFromStage(bool notify)
1314 // This container is used instead of walking the Actor hierachy.
1315 // It protects us when the Actor hierachy is modified during OnSceneDisconnectionExternal callbacks.
1316 ActorContainer disconnectionList;
1320 mScene->RequestRebuildDepthTree();
1323 // This stage is not interrupted by user callbacks
1324 mParentImpl.RecursiveDisconnectFromScene(disconnectionList);
1326 // Notify applications about the newly disconnected actors.
1327 for(const auto& actor : disconnectionList)
1329 actor->NotifyStageDisconnection(notify);
1334 * This method is called by an actor or its parent, before a node removal message is sent.
1335 * This is recursive; the child calls DisconnectFromStage() for its children.
1337 void Actor::DisconnectFromSceneGraph()
1339 // Notification for Object::Observers
1340 OnSceneObjectRemove();
1343 void Actor::NotifyStageDisconnection(bool notify)
1345 // Actors can be added (in a callback), before the off-stage state is reported.
1346 // Also if the actor was added & removed before mOnSceneSignalled was set, then we don't notify here.
1347 // only do this step if there is a stage, i.e. Core is not being shut down
1348 if(EventThreadServices::IsCoreRunning() && !OnScene() && mOnSceneSignalled)
1352 // Notification for external (CustomeActor) derived classes
1353 OnSceneDisconnectionExternal();
1355 if(!mOffSceneSignal.Empty())
1357 Dali::Actor handle(this);
1358 mOffSceneSignal.Emit(handle);
1362 // Guard against Add during callbacks
1365 mOnSceneSignalled = false; // signal required next time Actor is added
1370 bool Actor::IsNodeConnected() const
1372 return OnScene() && (IsRoot() || GetNode().GetParent());
1375 // This method initiates traversal of the actor tree using depth-first
1376 // traversal to set a depth index based on traversal order. It sends a
1377 // single message to update manager to update all the actor's nodes in
1378 // this tree with the depth index. The sceneGraphNodeDepths vector's
1379 // elements are ordered by depth, and could be used to reduce sorting
1380 // in the update thread.
1381 void Actor::RebuildDepthTree()
1383 DALI_LOG_TIMER_START(depthTimer);
1385 // Vector of scene-graph nodes and their depths to send to UpdateManager
1386 // in a single message
1387 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths(new SceneGraph::NodeDepths());
1389 int32_t depthIndex = 1;
1390 mParentImpl.DepthTraverseActorTree(sceneGraphNodeDepths, depthIndex);
1392 SetDepthIndicesMessage(GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths);
1393 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
1396 void Actor::SetDefaultProperty(Property::Index index, const Property::Value& property)
1398 PropertyHandler::SetDefaultProperty(*this, index, property);
1401 // TODO: This method needs to be removed
1402 void Actor::SetSceneGraphProperty(Property::Index index, const PropertyMetadata& entry, const Property::Value& value)
1404 PropertyHandler::SetSceneGraphProperty(index, entry, value, GetEventThreadServices(), GetNode());
1407 Property::Value Actor::GetDefaultProperty(Property::Index index) const
1409 Property::Value value;
1411 if(!GetCachedPropertyValue(index, value))
1413 // If property value is not stored in the event-side, then it must be a scene-graph only property
1414 GetCurrentPropertyValue(index, value);
1420 Property::Value Actor::GetDefaultPropertyCurrentValue(Property::Index index) const
1422 Property::Value value;
1424 if(!GetCurrentPropertyValue(index, value))
1426 // If unable to retrieve scene-graph property value, then it must be an event-side only property
1427 GetCachedPropertyValue(index, value);
1433 void Actor::OnNotifyDefaultPropertyAnimation(Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType)
1435 PropertyHandler::OnNotifyDefaultPropertyAnimation(*this, animation, index, value, animationType);
1438 const PropertyBase* Actor::GetSceneObjectAnimatableProperty(Property::Index index) const
1440 const PropertyBase* property = PropertyHandler::GetSceneObjectAnimatableProperty(index, GetNode());
1443 // not our property, ask base
1444 property = Object::GetSceneObjectAnimatableProperty(index);
1450 const PropertyInputImpl* Actor::GetSceneObjectInputProperty(Property::Index index) const
1452 const PropertyInputImpl* property = PropertyHandler::GetSceneObjectInputProperty(index, GetNode());
1455 // reuse animatable property getter as animatable properties are inputs as well
1456 // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
1457 property = GetSceneObjectAnimatableProperty(index);
1463 int32_t Actor::GetPropertyComponentIndex(Property::Index index) const
1465 int32_t componentIndex = PropertyHandler::GetPropertyComponentIndex(index);
1466 if(Property::INVALID_COMPONENT_INDEX == componentIndex)
1469 componentIndex = Object::GetPropertyComponentIndex(index);
1472 return componentIndex;
1475 const SceneGraph::Node& Actor::GetNode() const
1477 return *static_cast<const SceneGraph::Node*>(mUpdateObject);
1482 CheckParentAndCall(mParent, *this, &ActorParent::RaiseChild);
1487 CheckParentAndCall(mParent, *this, &ActorParent::LowerChild);
1490 void Actor::RaiseToTop()
1492 CheckParentAndCall(mParent, *this, &ActorParent::RaiseChildToTop);
1495 void Actor::LowerToBottom()
1497 CheckParentAndCall(mParent, *this, &ActorParent::LowerChildToBottom);
1500 void Actor::RaiseAbove(Internal::Actor& target)
1502 CheckParentAndCall(mParent, *this, target, &ActorParent::RaiseChildAbove);
1505 void Actor::LowerBelow(Internal::Actor& target)
1507 CheckParentAndCall(mParent, *this, target, &ActorParent::LowerChildBelow);
1510 void Actor::SetParent(ActorParent* parent, bool notify)
1514 DALI_ASSERT_ALWAYS(!mParent && "Actor cannot have 2 parents");
1517 Actor* parentActor = static_cast<Actor*>(parent);
1518 mScene = parentActor->mScene;
1520 if(!EventThreadServices::IsShuttingDown() && // Don't emit signals or send messages during Core destruction
1521 parentActor->OnScene())
1523 // Instruct each actor to create a corresponding node in the scene graph
1524 ConnectToScene(parentActor->GetHierarchyDepth(), parentActor->GetLayer3DParentCount(), notify);
1527 // Resolve the name and index for the child properties if any
1528 ResolveChildProperties();
1530 else // parent being set to NULL
1532 DALI_ASSERT_ALWAYS(mParent != nullptr && "Actor should have a parent");
1536 if(!EventThreadServices::IsShuttingDown() && // Don't emit signals or send messages during Core destruction
1539 // Disconnect the Node & its children from the scene-graph.
1540 DisconnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
1542 // Instruct each actor to discard pointers to the scene-graph
1543 DisconnectFromStage(notify);
1550 Rect<> Actor::CalculateScreenExtents() const
1552 if(mLayer3DParentsCount == 0)
1554 // We can assume that this actor is under 2d layer. Use faster, but imprecise algorithm
1555 return CalculateActorScreenExtents(*this);
1559 return CalculateActorScreenExtentsRenderTaskList(*this);
1563 Rect<> Actor::CalculateCurrentScreenExtents() const
1565 if(mLayer3DParentsCount == 0)
1567 // We can assume that this actor is under 2d layer. Use faster, but imprecise algorithm
1568 BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
1569 return CalculateCurrentActorScreenExtents(*this, bufferIndex);
1573 BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
1574 return CalculateCurrentActorScreenExtentsRenderTaskList(*this, bufferIndex);
1578 Vector3 Actor::GetAnchorPointForPosition() const
1580 return (mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT);
1583 bool Actor::GetCachedPropertyValue(Property::Index index, Property::Value& value) const
1585 return PropertyHandler::GetCachedPropertyValue(*this, index, value);
1588 bool Actor::GetCurrentPropertyValue(Property::Index index, Property::Value& value) const
1590 return PropertyHandler::GetCurrentPropertyValue(*this, index, value);
1593 bool Actor::RelayoutDependentOnParent(Dimension::Type dimension)
1595 return mSizer.RelayoutDependentOnParent(dimension);
1598 bool Actor::RelayoutDependentOnChildren(Dimension::Type dimension)
1600 return mSizer.RelayoutDependentOnChildrenBase(dimension);
1603 bool Actor::RelayoutDependentOnDimension(Dimension::Type dimension, Dimension::Type dependentDimension)
1605 return mSizer.RelayoutDependentOnDimension(dimension, dependentDimension);
1608 void Actor::SetPadding(const Vector2& padding, Dimension::Type dimension)
1610 mSizer.SetPadding(padding, dimension);
1613 Vector2 Actor::GetPadding(Dimension::Type dimension) const
1615 return mSizer.GetPadding(dimension);
1618 void Actor::SetLayoutNegotiated(bool negotiated, Dimension::Type dimension)
1620 mSizer.SetLayoutNegotiated(negotiated, dimension);
1623 bool Actor::IsLayoutNegotiated(Dimension::Type dimension) const
1625 return mSizer.IsLayoutNegotiated(dimension);
1628 float Actor::GetHeightForWidthBase(float width)
1630 // Can be overridden in derived class
1631 return mSizer.GetHeightForWidthBase(width);
1634 float Actor::GetWidthForHeightBase(float height)
1636 // Can be overridden in derived class
1637 return mSizer.GetWidthForHeightBase(height);
1640 float Actor::CalculateChildSizeBase(const Dali::Actor& child, Dimension::Type dimension)
1642 // Can be overridden in derived class
1643 return mSizer.CalculateChildSizeBase(child, dimension);
1646 bool Actor::RelayoutDependentOnChildrenBase(Dimension::Type dimension)
1648 return mSizer.RelayoutDependentOnChildrenBase(dimension);
1651 float Actor::CalculateChildSize(const Dali::Actor& child, Dimension::Type dimension)
1653 // Can be overridden in derived class
1654 return mSizer.CalculateChildSizeBase(child, dimension);
1657 float Actor::GetHeightForWidth(float width)
1659 // Can be overridden in derived class
1660 return mSizer.GetHeightForWidthBase(width);
1663 float Actor::GetWidthForHeight(float height)
1665 // Can be overridden in derived class
1666 return mSizer.GetWidthForHeightBase(height);
1669 float Actor::GetRelayoutSize(Dimension::Type dimension) const
1671 return mSizer.GetRelayoutSize(dimension);
1674 void Actor::NegotiateSize(const Vector2& allocatedSize, RelayoutContainer& container)
1676 mSizer.NegotiateSize(allocatedSize, container);
1679 void Actor::RelayoutRequest(Dimension::Type dimension)
1681 mSizer.RelayoutRequest(dimension);
1684 void Actor::SetMinimumSize(float size, Dimension::Type dimension)
1686 mSizer.SetMinimumSize(size, dimension);
1689 float Actor::GetMinimumSize(Dimension::Type dimension) const
1691 return mSizer.GetMinimumSize(dimension);
1694 void Actor::SetMaximumSize(float size, Dimension::Type dimension)
1696 mSizer.SetMaximumSize(size, dimension);
1699 float Actor::GetMaximumSize(Dimension::Type dimension) const
1701 return mSizer.GetMaximumSize(dimension);
1704 void Actor::SetVisibleInternal(bool visible, SendMessage::Type sendMessage)
1706 if(mVisible != visible)
1708 if(sendMessage == SendMessage::TRUE)
1710 // node is being used in a separate thread; queue a message to set the value & base value
1711 SceneGraph::NodePropertyMessage<bool>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible);
1713 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
1718 // Emit the signal on this actor and all its children
1719 mParentImpl.EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::SELF);
1723 void Actor::SetSiblingOrderOfChild(Actor& child, uint32_t order)
1725 mParentImpl.SetSiblingOrderOfChild(child, order);
1728 uint32_t Actor::GetSiblingOrderOfChild(const Actor& child) const
1730 return mParentImpl.GetSiblingOrderOfChild(child);
1733 void Actor::RaiseChild(Actor& child)
1735 mParentImpl.RaiseChild(child);
1738 void Actor::LowerChild(Actor& child)
1740 mParentImpl.LowerChild(child);
1743 void Actor::RaiseChildToTop(Actor& child)
1745 mParentImpl.RaiseChildToTop(child);
1748 void Actor::LowerChildToBottom(Actor& child)
1750 mParentImpl.LowerChildToBottom(child);
1753 void Actor::RaiseChildAbove(Actor& child, Actor& target)
1755 mParentImpl.RaiseChildAbove(child, target);
1758 void Actor::LowerChildBelow(Actor& child, Actor& target)
1760 mParentImpl.LowerChildBelow(child, target);
1763 void Actor::SetInheritLayoutDirection(bool inherit)
1765 if(mInheritLayoutDirection != inherit)
1767 mInheritLayoutDirection = inherit;
1769 if(inherit && mParent)
1771 mParentImpl.InheritLayoutDirectionRecursively(GetParent()->mLayoutDirection);
1776 void Actor::SetUpdateAreaHint(const Vector4& updateAreaHint)
1778 // node is being used in a separate thread; queue a message to set the value & base value
1779 SetUpdateAreaHintMessage(GetEventThreadServices(), GetNode(), updateAreaHint);
1782 } // namespace Internal