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/common/event-thread-services.h>
43 #include <dali/internal/event/common/property-helper.h>
44 #include <dali/internal/event/common/scene-impl.h>
45 #include <dali/internal/event/common/stage-impl.h>
46 #include <dali/internal/event/common/thread-local-storage.h>
47 #include <dali/internal/event/common/type-info-impl.h>
48 #include <dali/internal/event/events/actor-gesture-data.h>
49 #include <dali/internal/event/render-tasks/render-task-impl.h>
50 #include <dali/internal/event/rendering/renderer-impl.h>
51 #include <dali/internal/update/manager/update-manager.h>
52 #include <dali/internal/update/nodes/node-messages.h>
53 #include <dali/public-api/size-negotiation/relayout-container.h>
55 using Dali::Internal::SceneGraph::AnimatableProperty;
56 using Dali::Internal::SceneGraph::Node;
57 using Dali::Internal::SceneGraph::PropertyBase;
59 #if defined(DEBUG_ENABLED)
60 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER");
67 namespace // unnamed namespace
72 * We want to discourage the use of property strings (minimize string comparisons),
73 * particularly for the default properties.
74 * Name Type writable animatable constraint-input enum for index-checking
76 DALI_PROPERTY_TABLE_BEGIN
77 DALI_PROPERTY("parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN)
78 DALI_PROPERTY("parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X)
79 DALI_PROPERTY("parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y)
80 DALI_PROPERTY("parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z)
81 DALI_PROPERTY("anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT)
82 DALI_PROPERTY("anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X)
83 DALI_PROPERTY("anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y)
84 DALI_PROPERTY("anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z)
85 DALI_PROPERTY("size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE)
86 DALI_PROPERTY("sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH)
87 DALI_PROPERTY("sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT)
88 DALI_PROPERTY("sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH)
89 DALI_PROPERTY("position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION)
90 DALI_PROPERTY("positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X)
91 DALI_PROPERTY("positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y)
92 DALI_PROPERTY("positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z)
93 DALI_PROPERTY("worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION)
94 DALI_PROPERTY("worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X)
95 DALI_PROPERTY("worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y)
96 DALI_PROPERTY("worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z)
97 DALI_PROPERTY("orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION)
98 DALI_PROPERTY("worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION)
99 DALI_PROPERTY("scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE)
100 DALI_PROPERTY("scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X)
101 DALI_PROPERTY("scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y)
102 DALI_PROPERTY("scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z)
103 DALI_PROPERTY("worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE)
104 DALI_PROPERTY("visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE)
105 DALI_PROPERTY("color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR)
106 DALI_PROPERTY("colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED)
107 DALI_PROPERTY("colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN)
108 DALI_PROPERTY("colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE)
109 DALI_PROPERTY("colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA)
110 DALI_PROPERTY("worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR)
111 DALI_PROPERTY("worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX)
112 DALI_PROPERTY("name", STRING, true, false, false, Dali::Actor::Property::NAME)
113 DALI_PROPERTY("sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE)
114 DALI_PROPERTY("leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED)
115 DALI_PROPERTY("inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION)
116 DALI_PROPERTY("inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE)
117 DALI_PROPERTY("colorMode", INTEGER, true, false, false, Dali::Actor::Property::COLOR_MODE)
118 DALI_PROPERTY("drawMode", INTEGER, true, false, false, Dali::Actor::Property::DRAW_MODE)
119 DALI_PROPERTY("sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR)
120 DALI_PROPERTY("widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY)
121 DALI_PROPERTY("heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY)
122 DALI_PROPERTY("sizeScalePolicy", INTEGER, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY)
123 DALI_PROPERTY("widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT)
124 DALI_PROPERTY("heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH)
125 DALI_PROPERTY("padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING)
126 DALI_PROPERTY("minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE)
127 DALI_PROPERTY("maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE)
128 DALI_PROPERTY("inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION)
129 DALI_PROPERTY("clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE)
130 DALI_PROPERTY("layoutDirection", STRING, true, false, false, Dali::Actor::Property::LAYOUT_DIRECTION)
131 DALI_PROPERTY("inheritLayoutDirection", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION)
132 DALI_PROPERTY("opacity", FLOAT, true, true, true, Dali::Actor::Property::OPACITY)
133 DALI_PROPERTY("screenPosition", VECTOR2, false, false, false, Dali::Actor::Property::SCREEN_POSITION)
134 DALI_PROPERTY("positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::Actor::Property::POSITION_USES_ANCHOR_POINT)
135 DALI_PROPERTY("culled", BOOLEAN, false, false, true, Dali::Actor::Property::CULLED)
136 DALI_PROPERTY("id", INTEGER, false, false, false, Dali::Actor::Property::ID)
137 DALI_PROPERTY("hierarchyDepth", INTEGER, false, false, false, Dali::Actor::Property::HIERARCHY_DEPTH)
138 DALI_PROPERTY("isRoot", BOOLEAN, false, false, false, Dali::Actor::Property::IS_ROOT)
139 DALI_PROPERTY("isLayer", BOOLEAN, false, false, false, Dali::Actor::Property::IS_LAYER)
140 DALI_PROPERTY("connectedToScene", BOOLEAN, false, false, false, Dali::Actor::Property::CONNECTED_TO_SCENE)
141 DALI_PROPERTY("keyboardFocusable", BOOLEAN, true, false, false, Dali::Actor::Property::KEYBOARD_FOCUSABLE)
142 DALI_PROPERTY("updateAreaHint", VECTOR4, true, false, false, Dali::Actor::Property::UPDATE_AREA_HINT)
143 DALI_PROPERTY("siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER)
144 DALI_PROPERTY("captureAllTouchAfterStart", BOOLEAN, true, false, false, Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START)
145 DALI_PROPERTY("touchAreaOffset", RECTANGLE, true, false, false, Dali::DevelActor::Property::TOUCH_AREA_OFFSET)
146 DALI_PROPERTY("blendEquation", INTEGER, true, false, false, Dali::DevelActor::Property::BLEND_EQUATION)
147 DALI_PROPERTY("touchFocusable", BOOLEAN, true, false, false, Dali::DevelActor::Property::TOUCH_FOCUSABLE)
148 DALI_PROPERTY("keyboardFocusableChildren", BOOLEAN, true, false, false, Dali::DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN)
149 DALI_PROPERTY("userInteractionEnabled", BOOLEAN, true, false, false, Dali::DevelActor::Property::USER_INTERACTION_ENABLED)
150 DALI_PROPERTY("allowOnlyOwnTouch", BOOLEAN, true, false, false, Dali::DevelActor::Property::ALLOW_ONLY_OWN_TOUCH)
151 DALI_PROPERTY("useTextureUpdateArea", BOOLEAN, true, false, false, Dali::DevelActor::Property::USE_TEXTURE_UPDATE_AREA)
152 DALI_PROPERTY("dispatchTouchMotion", BOOLEAN, true, false, false, Dali::DevelActor::Property::DISPATCH_TOUCH_MOTION)
153 DALI_PROPERTY("dispatchHoverMotion", BOOLEAN, true, false, false, Dali::DevelActor::Property::DISPATCH_HOVER_MOTION)
154 DALI_PROPERTY_TABLE_END(DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties)
158 static constexpr std::string_view SIGNAL_HOVERED = "hovered";
159 static constexpr std::string_view SIGNAL_WHEEL_EVENT = "wheelEvent";
160 static constexpr std::string_view SIGNAL_ON_SCENE = "onScene";
161 static constexpr std::string_view SIGNAL_OFF_SCENE = "offScene";
162 static constexpr std::string_view SIGNAL_ON_RELAYOUT = "onRelayout";
163 static constexpr std::string_view SIGNAL_TOUCHED = "touched";
164 static constexpr std::string_view SIGNAL_VISIBILITY_CHANGED = "visibilityChanged";
165 static constexpr std::string_view SIGNAL_INHERITED_VISIBILITY_CHANGED = "inheritedVisibilityChanged";
166 static constexpr std::string_view SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
167 static constexpr std::string_view SIGNAL_CHILD_ADDED = "childAdded";
168 static constexpr std::string_view SIGNAL_CHILD_REMOVED = "childRemoved";
172 static constexpr std::string_view ACTION_SHOW = "show";
173 static constexpr std::string_view ACTION_HIDE = "hide";
175 BaseHandle CreateActor()
177 return Dali::Actor::New();
181 * Connects a callback function with the object's signals.
182 * @param[in] object The object providing the signal.
183 * @param[in] tracker Used to disconnect the signal.
184 * @param[in] signalName The signal to connect to.
185 * @param[in] functor A newly allocated FunctorDelegate.
186 * @return True if the signal was connected.
187 * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
189 static bool DoConnectSignal(BaseObject* object,
190 ConnectionTrackerInterface* tracker,
191 const std::string& signalName,
192 FunctorDelegate* functor)
194 bool connected(true);
195 Actor* actor = static_cast<Actor*>(object); // TypeRegistry guarantees that this is the correct type.
197 std::string_view name(signalName);
199 if(name == SIGNAL_HOVERED)
201 actor->HoveredSignal().Connect(tracker, functor);
203 else if(signalName == SIGNAL_WHEEL_EVENT)
205 actor->WheelEventSignal().Connect(tracker, functor);
207 else if(name == SIGNAL_ON_SCENE)
209 actor->OnSceneSignal().Connect(tracker, functor);
211 else if(name == SIGNAL_OFF_SCENE)
213 actor->OffSceneSignal().Connect(tracker, functor);
215 else if(name == SIGNAL_ON_RELAYOUT)
217 actor->OnRelayoutSignal().Connect(tracker, functor);
219 else if(name == SIGNAL_TOUCHED)
221 actor->TouchedSignal().Connect(tracker, functor);
223 else if(name == SIGNAL_VISIBILITY_CHANGED)
225 actor->VisibilityChangedSignal().Connect(tracker, functor);
227 else if(name == SIGNAL_INHERITED_VISIBILITY_CHANGED)
229 actor->InheritedVisibilityChangedSignal().Connect(tracker, functor);
231 else if(name == SIGNAL_LAYOUT_DIRECTION_CHANGED)
233 actor->LayoutDirectionChangedSignal().Connect(tracker, functor);
235 else if(name == SIGNAL_CHILD_ADDED)
237 actor->ChildAddedSignal().Connect(tracker, functor);
239 else if(name == SIGNAL_CHILD_REMOVED)
241 actor->ChildRemovedSignal().Connect(tracker, functor);
245 // signalName does not match any signal
253 * Performs actions as requested using the action name.
254 * @param[in] object The object on which to perform the action.
255 * @param[in] actionName The action to perform.
256 * @param[in] attributes The attributes with which to perfrom this action.
257 * @return true if the action was done.
259 bool DoAction(BaseObject* object,
260 const std::string& actionName,
261 const Property::Map& attributes)
264 Actor* actor = dynamic_cast<Actor*>(object);
268 std::string_view name(actionName);
269 if(name == ACTION_SHOW)
271 actor->SetVisible(true);
274 else if(name == ACTION_HIDE)
276 actor->SetVisible(false);
284 TypeRegistration mType(typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties);
286 SignalConnectorType signalConnector2(mType, std::string(SIGNAL_HOVERED), &DoConnectSignal);
287 SignalConnectorType signalConnector3(mType, std::string(SIGNAL_WHEEL_EVENT), &DoConnectSignal);
288 SignalConnectorType signalConnector4(mType, std::string(SIGNAL_ON_SCENE), &DoConnectSignal);
289 SignalConnectorType signalConnector5(mType, std::string(SIGNAL_OFF_SCENE), &DoConnectSignal);
290 SignalConnectorType signalConnector6(mType, std::string(SIGNAL_ON_RELAYOUT), &DoConnectSignal);
291 SignalConnectorType signalConnector7(mType, std::string(SIGNAL_TOUCHED), &DoConnectSignal);
292 SignalConnectorType signalConnector8(mType, std::string(SIGNAL_VISIBILITY_CHANGED), &DoConnectSignal);
293 SignalConnectorType signalConnector9(mType, std::string(SIGNAL_INHERITED_VISIBILITY_CHANGED), &DoConnectSignal);
294 SignalConnectorType signalConnector10(mType, std::string(SIGNAL_LAYOUT_DIRECTION_CHANGED), &DoConnectSignal);
295 SignalConnectorType signalConnector11(mType, std::string(SIGNAL_CHILD_ADDED), &DoConnectSignal);
296 SignalConnectorType signalConnector12(mType, std::string(SIGNAL_CHILD_REMOVED), &DoConnectSignal);
298 TypeAction a1(mType, std::string(ACTION_SHOW), &DoAction);
299 TypeAction a2(mType, std::string(ACTION_HIDE), &DoAction);
301 /// Helper for emitting a signal
302 template<typename Signal, typename Event>
303 bool EmitConsumingSignal(Actor& actor, Signal& signal, const Event& event)
305 bool consumed = false;
309 Dali::Actor handle(&actor);
310 consumed = signal.Emit(handle, event);
316 /// Helper for emitting signals with multiple parameters
317 template<typename Signal, typename... Param>
318 void EmitSignal(Actor& actor, Signal& signal, Param... params)
322 Dali::Actor handle(&actor);
323 signal.Emit(handle, params...);
327 using ActorParentSiblingOrderMethod = void (ActorParent::*)(Actor&);
328 using ActorParentSiblingOrderMethodWithTarget = void (ActorParent::*)(Actor&, Actor&);
330 /// Helper to check and call actor sibling methods in ActorParent
331 void CheckParentAndCall(ActorParent* parent, Actor& actor, ActorParentSiblingOrderMethod memberFunction)
335 (parent->*memberFunction)(actor);
339 DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
343 /// Helper to check and call actor sibling methods with a target parameter in ActorParent
344 void CheckParentAndCall(ActorParent* parent, Actor& actor, Actor& target, ActorParentSiblingOrderMethodWithTarget memberFunction)
348 (parent->*memberFunction)(actor, target);
352 DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
356 } // unnamed namespace
358 ActorPtr Actor::New()
360 // pass a reference to actor, actor does not own its node
361 ActorPtr actor(new Actor(BASIC, *CreateNode()));
363 // Second-phase construction
369 const SceneGraph::Node* Actor::CreateNode()
371 // create node. Nodes are owned by the update manager
372 SceneGraph::Node* node = SceneGraph::Node::New();
373 OwnerPointer<SceneGraph::Node> transferOwnership(node);
374 Internal::ThreadLocalStorage* tls = Internal::ThreadLocalStorage::GetInternal();
376 DALI_ASSERT_ALWAYS(tls && "ThreadLocalStorage is null");
378 AddNodeMessage(tls->GetUpdateManager(), transferOwnership);
383 void Actor::SetName(std::string_view name)
385 mName = ConstString(name);
387 // ATTENTION: string for debug purposes is not thread safe.
388 DALI_LOG_SET_OBJECT_STRING(const_cast<SceneGraph::Node*>(&GetNode()), mName.GetCString());
391 uint32_t Actor::GetId() const
393 return GetNode().GetId();
396 Dali::Layer Actor::GetLayer()
400 // Short-circuit for Layer derived actors
403 layer = Dali::Layer(static_cast<Dali::Internal::Layer*>(this)); // static cast as we trust the flag
406 // Find the immediate Layer parent
407 for(Actor* parent = GetParent(); !layer && parent != nullptr; parent = parent->GetParent())
409 if(parent->IsLayer())
411 layer = Dali::Layer(static_cast<Dali::Internal::Layer*>(parent)); // static cast as we trust the flag
418 void Actor::Unparent()
422 // Remove this actor from the parent. The remove will put a relayout request in for
423 // the parent if required
424 mParent->Remove(*this);
425 // mParent is now NULL!
429 void Actor::SetParentOrigin(const Vector3& origin)
431 // node is being used in a separate thread; queue a message to set the value & base value
432 SetParentOriginMessage(GetEventThreadServices(), GetNode(), origin);
434 // Cache for event-thread access
437 // not allocated, check if different from default
438 if(ParentOrigin::DEFAULT != origin)
440 mParentOrigin = new Vector3(origin);
445 // check if different from current costs more than just set
446 *mParentOrigin = origin;
450 const Vector3& Actor::GetCurrentParentOrigin() const
452 // Cached for event-thread access
453 return (mParentOrigin) ? *mParentOrigin : ParentOrigin::DEFAULT;
456 void Actor::SetAnchorPoint(const Vector3& anchor)
458 // node is being used in a separate thread; queue a message to set the value & base value
459 SetAnchorPointMessage(GetEventThreadServices(), GetNode(), anchor);
461 // Cache for event-thread access
464 // not allocated, check if different from default
465 if(AnchorPoint::DEFAULT != anchor)
467 mAnchorPoint = new Vector3(anchor);
472 // check if different from current costs more than just set
473 *mAnchorPoint = anchor;
477 const Vector3& Actor::GetCurrentAnchorPoint() const
479 // Cached for event-thread access
480 return (mAnchorPoint) ? *mAnchorPoint : AnchorPoint::DEFAULT;
483 void Actor::SetPosition(const Vector3& position)
485 mTargetPosition = position;
487 // node is being used in a separate thread; queue a message to set the value & base value
488 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position);
491 void Actor::SetX(float x)
493 mTargetPosition.x = x;
495 // node is being used in a separate thread; queue a message to set the value & base value
496 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x);
499 void Actor::SetY(float y)
501 mTargetPosition.y = y;
503 // node is being used in a separate thread; queue a message to set the value & base value
504 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y);
507 void Actor::SetZ(float z)
509 mTargetPosition.z = z;
511 // node is being used in a separate thread; queue a message to set the value & base value
512 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z);
515 void Actor::TranslateBy(const Vector3& distance)
517 mTargetPosition += distance;
519 // node is being used in a separate thread; queue a message to set the value & base value
520 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance);
523 const Vector3& Actor::GetCurrentPosition() const
525 // node is being used in a separate thread; copy the value from the previous update
526 return GetNode().GetPosition(GetEventThreadServices().GetEventBufferIndex());
529 const Vector3& Actor::GetCurrentWorldPosition() const
531 // node is being used in a separate thread; copy the value from the previous update
532 return GetNode().GetWorldPosition(GetEventThreadServices().GetEventBufferIndex());
535 const Vector2 Actor::CalculateScreenPosition() const
539 if(mLayer3DParentsCount == 0)
541 // We can assume that this actor is under 2d layer. Use faster, but imprecise algorithm
542 return CalculateActorScreenPosition(*this);
546 return CalculateActorScreenPositionRenderTaskList(*this);
549 return Vector2::ZERO;
552 const Vector2 Actor::GetCurrentScreenPosition() const
556 BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
557 if(mLayer3DParentsCount == 0)
559 // We can assume that this actor is under 2d layer. Use faster, but imprecise algorithm
560 return CalculateCurrentActorScreenPosition(*this, bufferIndex);
564 return CalculateCurrentActorScreenPositionRenderTaskList(*this, bufferIndex);
567 return Vector2::ZERO;
570 void Actor::SetInheritPosition(bool inherit)
572 if(mInheritPosition != inherit)
574 // non animatable so keep local copy
575 mInheritPosition = inherit;
576 SetInheritPositionMessage(GetEventThreadServices(), GetNode(), inherit);
580 void Actor::SetOrientation(const Radian& angle, const Vector3& axis)
582 Vector3 normalizedAxis(axis.x, axis.y, axis.z);
583 normalizedAxis.Normalize();
585 Quaternion orientation(angle, normalizedAxis);
587 SetOrientation(orientation);
590 void Actor::SetOrientation(const Quaternion& orientation)
592 mTargetOrientation = orientation;
594 // node is being used in a separate thread; queue a message to set the value & base value
595 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation);
598 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
600 RotateBy(Quaternion(angle, axis));
603 void Actor::RotateBy(const Quaternion& relativeRotation)
605 mTargetOrientation *= Quaternion(relativeRotation);
607 // node is being used in a separate thread; queue a message to set the value & base value
608 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation);
611 const Quaternion& Actor::GetCurrentOrientation() const
613 // node is being used in a separate thread; copy the value from the previous update
614 return GetNode().GetOrientation(GetEventThreadServices().GetEventBufferIndex());
617 const Quaternion& Actor::GetCurrentWorldOrientation() const
619 // node is being used in a separate thread; copy the value from the previous update
620 return GetNode().GetWorldOrientation(GetEventThreadServices().GetEventBufferIndex());
623 void Actor::SetScale(const Vector3& scale)
625 mTargetScale = scale;
627 // node is being used in a separate thread; queue a message to set the value & base value
628 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale);
631 void Actor::SetScaleX(float x)
635 // node is being used in a separate thread; queue a message to set the value & base value
636 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x);
639 void Actor::SetScaleY(float y)
643 // node is being used in a separate thread; queue a message to set the value & base value
644 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y);
647 void Actor::SetScaleZ(float z)
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>::BakeZ, z);
655 void Actor::ScaleBy(const Vector3& relativeScale)
657 mTargetScale *= relativeScale;
659 // node is being used in a separate thread; queue a message to set the value & base value
660 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale);
663 const Vector3& Actor::GetCurrentScale() const
665 // node is being used in a separate thread; copy the value from the previous update
666 return GetNode().GetScale(GetEventThreadServices().GetEventBufferIndex());
669 const Vector3& Actor::GetCurrentWorldScale() const
671 // node is being used in a separate thread; copy the value from the previous update
672 return GetNode().GetWorldScale(GetEventThreadServices().GetEventBufferIndex());
675 void Actor::SetInheritScale(bool inherit)
677 if(mInheritScale != inherit)
679 // non animatable so keep local copy
680 mInheritScale = inherit;
681 // node is being used in a separate thread; queue a message to set the value
682 SetInheritScaleMessage(GetEventThreadServices(), GetNode(), inherit);
686 Matrix Actor::GetCurrentWorldMatrix() const
688 return GetNode().GetWorldMatrix(0);
691 void Actor::SetVisible(bool visible)
693 SetVisibleInternal(visible, SendMessage::TRUE);
696 bool Actor::IsVisible() const
698 // node is being used in a separate thread; copy the value from the previous update
699 return GetNode().IsVisible(GetEventThreadServices().GetEventBufferIndex());
702 void Actor::SetOpacity(float opacity)
704 mTargetColor.a = opacity;
706 // node is being used in a separate thread; queue a message to set the value & base value
707 SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeW, opacity);
709 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
712 float Actor::GetCurrentOpacity() const
714 // node is being used in a separate thread; copy the value from the previous update
715 return GetNode().GetOpacity(GetEventThreadServices().GetEventBufferIndex());
718 const Vector4& Actor::GetCurrentWorldColor() const
720 return GetNode().GetWorldColor(GetEventThreadServices().GetEventBufferIndex());
723 void Actor::SetColor(const Vector4& color)
725 mTargetColor = color;
727 // node is being used in a separate thread; queue a message to set the value & base value
728 SceneGraph::NodePropertyMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::Bake, color);
730 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
733 void Actor::SetColorRed(float red)
735 mTargetColor.r = red;
737 // node is being used in a separate thread; queue a message to set the value & base value
738 SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeX, red);
740 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
743 void Actor::SetColorGreen(float green)
745 mTargetColor.g = green;
747 // node is being used in a separate thread; queue a message to set the value & base value
748 SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeY, green);
750 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
753 void Actor::SetColorBlue(float blue)
755 mTargetColor.b = blue;
757 // node is being used in a separate thread; queue a message to set the value & base value
758 SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeZ, blue);
760 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
763 const Vector4& Actor::GetCurrentColor() const
765 // node is being used in a separate thread; copy the value from the previous update
766 return GetNode().GetColor(GetEventThreadServices().GetEventBufferIndex());
769 void Actor::SetInheritOrientation(bool inherit)
771 if(mInheritOrientation != inherit)
773 // non animatable so keep local copy
774 mInheritOrientation = inherit;
775 // node is being used in a separate thread; queue a message to set the value
776 SetInheritOrientationMessage(GetEventThreadServices(), GetNode(), inherit);
780 void Actor::SetSizeModeFactor(const Vector3& factor)
782 mSizer.SetSizeModeFactor(factor);
785 const Vector3& Actor::GetSizeModeFactor() const
787 return mSizer.GetSizeModeFactor();
790 void Actor::SetColorMode(ColorMode colorMode)
792 // non animatable so keep local copy
793 mColorMode = colorMode;
794 // node is being used in a separate thread; queue a message to set the value
795 SetColorModeMessage(GetEventThreadServices(), GetNode(), colorMode);
798 void Actor::SetSize(float width, float height)
800 SetSize(Vector2(width, height));
803 void Actor::SetSize(float width, float height, float depth)
805 SetSize(Vector3(width, height, depth));
808 void Actor::SetSize(const Vector2& size)
810 SetSize(Vector3(size.width, size.height, 0.f));
813 void Actor::SetSize(const Vector3& size)
815 mSizer.SetSize(size);
818 void Actor::SetWidth(float width)
820 mSizer.SetWidth(width);
823 void Actor::SetHeight(float height)
825 mSizer.SetHeight(height);
828 void Actor::SetDepth(float depth)
830 mSizer.SetDepth(depth);
831 // node is being used in a separate thread; queue a message to set the value & base value
832 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth);
835 Vector3 Actor::GetTargetSize() const
837 return mSizer.GetTargetSize();
840 const Vector3& Actor::GetCurrentSize() const
842 // node is being used in a separate thread; copy the value from the previous update
843 return GetNode().GetSize(GetEventThreadServices().GetEventBufferIndex());
846 Vector3 Actor::GetNaturalSize() const
848 // It is up to deriving classes to return the appropriate natural size
849 return Vector3(0.0f, 0.0f, 0.0f);
852 void Actor::SetResizePolicy(ResizePolicy::Type policy, Dimension::Type dimension)
854 mSizer.SetResizePolicy(policy, dimension);
857 ResizePolicy::Type Actor::GetResizePolicy(Dimension::Type dimension) const
859 return mSizer.GetResizePolicy(dimension);
862 void Actor::SetRelayoutEnabled(bool relayoutEnabled)
864 mSizer.SetRelayoutEnabled(relayoutEnabled);
867 bool Actor::IsRelayoutEnabled() const
869 return mSizer.IsRelayoutEnabled();
872 void Actor::SetLayoutDirty(bool dirty, Dimension::Type dimension)
874 mSizer.SetLayoutDirty(dirty, dimension);
877 bool Actor::IsLayoutDirty(Dimension::Type dimension) const
879 return mSizer.IsLayoutDirty(dimension);
882 bool Actor::RelayoutPossible(Dimension::Type dimension) const
884 return mSizer.RelayoutPossible(dimension);
887 bool Actor::RelayoutRequired(Dimension::Type dimension) const
889 return mSizer.RelayoutRequired(dimension);
892 uint32_t Actor::AddRenderer(Renderer& renderer)
896 mRenderers = new RendererContainer(GetEventThreadServices());
898 return mRenderers->Add(GetNode(), renderer, mIsBlendEquationSet, mBlendEquation);
901 uint32_t Actor::GetRendererCount() const
903 return mRenderers ? mRenderers->GetCount() : 0u;
906 RendererPtr Actor::GetRendererAt(uint32_t index)
908 return mRenderers ? mRenderers->GetRendererAt(index) : nullptr;
911 void Actor::RemoveRenderer(Renderer& renderer)
915 mRenderers->Remove(GetNode(), renderer);
919 void Actor::RemoveRenderer(uint32_t index)
923 mRenderers->Remove(GetNode(), index);
927 void Actor::SetBlendEquation(DevelBlendEquation::Type blendEquation)
929 if(Dali::Capabilities::IsBlendEquationSupported(blendEquation))
931 if(mBlendEquation != blendEquation)
933 mBlendEquation = blendEquation;
936 mRenderers->SetBlending(blendEquation);
939 mIsBlendEquationSet = true;
943 DALI_LOG_ERROR("Invalid blend equation is entered.\n");
947 DevelBlendEquation::Type Actor::GetBlendEquation() const
949 return mBlendEquation;
952 void Actor::SetTransparent(bool transparent)
954 SetTransparentMessage(GetEventThreadServices(), GetNode(), transparent);
957 bool Actor::IsTransparent() const
959 return GetNode().IsTransparent();
962 void Actor::SetDrawMode(DrawMode::Type drawMode)
964 // this flag is not animatable so keep the value
965 mDrawMode = drawMode;
967 // node is being used in a separate thread; queue a message to set the value
968 SetDrawModeMessage(GetEventThreadServices(), GetNode(), drawMode);
971 bool Actor::ScreenToLocal(float& localX, float& localY, float screenX, float screenY) const
973 return mScene && OnScene() && ConvertScreenToLocalRenderTaskList(mScene->GetRenderTaskList(), GetNode().GetWorldMatrix(0), GetCurrentSize(), localX, localY, screenX, screenY);
976 bool Actor::ScreenToLocal(const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY) const
978 return OnScene() && ConvertScreenToLocalRenderTask(renderTask, GetNode().GetWorldMatrix(0), GetCurrentSize(), localX, localY, screenX, screenY);
981 bool Actor::ScreenToLocal(const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY) const
983 return OnScene() && ConvertScreenToLocal(viewMatrix, projectionMatrix, GetNode().GetWorldMatrix(0), GetCurrentSize(), viewport, localX, localY, screenX, screenY);
986 ActorGestureData& Actor::GetGestureData()
988 // Likely scenario is that once gesture-data is created for this actor, the actor will require
989 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
990 if(nullptr == mGestureData)
992 mGestureData = new ActorGestureData;
994 return *mGestureData;
997 bool Actor::IsGestureRequired(GestureType::Value type) const
999 return mGestureData && mGestureData->IsGestureRequired(type);
1002 bool Actor::EmitInterceptTouchEventSignal(const Dali::TouchEvent& touch)
1004 return EmitConsumingSignal(*this, mInterceptTouchedSignal, touch);
1007 bool Actor::EmitTouchEventSignal(const Dali::TouchEvent& touch)
1009 return EmitConsumingSignal(*this, mTouchedSignal, touch);
1012 bool Actor::EmitHoverEventSignal(const Dali::HoverEvent& event)
1014 return EmitConsumingSignal(*this, mHoveredSignal, event);
1017 bool Actor::EmitInterceptWheelEventSignal(const Dali::WheelEvent& event)
1019 return EmitConsumingSignal(*this, mInterceptWheelSignal, event);
1022 bool Actor::EmitWheelEventSignal(const Dali::WheelEvent& event)
1024 return EmitConsumingSignal(*this, mWheelEventSignal, event);
1027 void Actor::EmitVisibilityChangedSignal(bool visible, DevelActor::VisibilityChange::Type type)
1029 EmitSignal(*this, mVisibilityChangedSignal, visible, type);
1032 void Actor::EmitInheritedVisibilityChangedSignal(bool visible)
1034 EmitSignal(*this, mInheritedVisibilityChangedSignal, visible);
1037 void Actor::EmitLayoutDirectionChangedSignal(LayoutDirection::Type type)
1039 EmitSignal(*this, mLayoutDirectionChangedSignal, type);
1042 bool Actor::EmitHitTestResultSignal(Integration::Point point, Vector2 hitPointLocal, uint32_t timeStamp)
1046 if(IsHitTestResultRequired())
1048 Dali::Actor handle(this);
1049 Integration::Point newPoint(point);
1050 newPoint.SetHitActor(handle);
1051 newPoint.SetLocalPosition(hitPointLocal);
1052 Dali::TouchEvent touchEvent = Dali::Integration::NewTouchEvent(timeStamp, newPoint);
1053 hit = mHitTestResultSignal.Emit(handle, touchEvent);
1058 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
1060 return mParentImpl.ChildAddedSignal();
1063 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
1065 return mParentImpl.ChildRemovedSignal();
1068 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
1070 return mParentImpl.ChildOrderChangedSignal();
1073 Actor::Actor(DerivedType derivedType, const SceneGraph::Node& node)
1079 mRenderers(nullptr),
1080 mParentOrigin(nullptr),
1081 mAnchorPoint(nullptr),
1082 mGestureData(nullptr),
1083 mInterceptTouchedSignal(),
1086 mInterceptWheelSignal(),
1087 mWheelEventSignal(),
1090 mOnRelayoutSignal(),
1091 mVisibilityChangedSignal(),
1092 mInheritedVisibilityChangedSignal(),
1093 mLayoutDirectionChangedSignal(),
1094 mHitTestResultSignal(),
1095 mTargetOrientation(Quaternion::IDENTITY),
1096 mTargetColor(Color::WHITE),
1097 mTargetPosition(Vector3::ZERO),
1098 mTargetScale(Vector3::ONE),
1099 mTouchAreaOffset(0, 0, 0, 0),
1103 mLayer3DParentsCount(0),
1104 mIsRoot(ROOT_LAYER == derivedType),
1105 mIsLayer(LAYER == derivedType || ROOT_LAYER == derivedType),
1108 mLeaveRequired(false),
1109 mKeyboardFocusable(false),
1110 mKeyboardFocusableChildren(true),
1111 mTouchFocusable(false),
1112 mOnSceneSignalled(false),
1113 mInheritPosition(true),
1114 mInheritOrientation(true),
1115 mInheritScale(true),
1116 mPositionUsesAnchorPoint(true),
1118 mInheritLayoutDirection(true),
1119 mCaptureAllTouchAfterStart(false),
1120 mIsBlendEquationSet(false),
1121 mNeedGesturePropagation(false),
1122 mUserInteractionEnabled(true),
1123 mAllowOnlyOwnTouch(false),
1124 mUseTextureUpdateArea(false),
1125 mDispatchTouchMotion(true),
1126 mDispatchHoverMotion(true),
1127 mLayoutDirection(LayoutDirection::LEFT_TO_RIGHT),
1128 mDrawMode(DrawMode::NORMAL),
1129 mColorMode(Node::DEFAULT_COLOR_MODE),
1130 mClippingMode(ClippingMode::DISABLED),
1131 mHoverState(PointState::FINISHED),
1132 mBlendEquation(DevelBlendEquation::ADD)
1136 void Actor::Initialize()
1140 GetEventThreadServices().RegisterObject(this);
1145 // Remove mParent pointers from children even if we're destroying core,
1146 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
1149 // Guard to allow handle destruction after Core has been destroyed
1150 if(EventThreadServices::IsCoreRunning())
1154 // Detach all renderers before delete container.
1155 mRenderers->RemoveAll(GetNode());
1158 // Root layer will destroy its node in its own destructor
1161 DestroyNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
1163 GetEventThreadServices().UnregisterObject(this);
1166 // Cleanup renderer list
1169 // Cleanup optional gesture data
1170 delete mGestureData;
1172 // Cleanup optional parent origin and anchor
1173 delete mParentOrigin;
1174 delete mAnchorPoint;
1177 void Actor::Add(Actor& child, bool notify)
1179 mParentImpl.Add(child, notify);
1182 void Actor::Remove(Actor& child, bool notify)
1184 mParentImpl.Remove(child, notify);
1187 void Actor::SwitchParent(Actor& newParent)
1189 if(this == &newParent)
1191 DALI_LOG_ERROR("Cannot add actor to itself");
1195 if(!this->OnScene() || !newParent.OnScene())
1197 DALI_LOG_ERROR("Both of current parent and new parent must be on Scene");
1201 newParent.Add(*this, false);
1204 uint32_t Actor::GetChildCount() const
1206 return mParentImpl.GetChildCount();
1209 ActorPtr Actor::GetChildAt(uint32_t index) const
1211 return mParentImpl.GetChildAt(index);
1214 ActorContainer& Actor::GetChildrenInternal()
1216 return mParentImpl.GetChildrenInternal();
1219 ActorPtr Actor::FindChildByName(ConstString actorName)
1221 return mParentImpl.FindChildByName(actorName);
1224 ActorPtr Actor::FindChildById(const uint32_t id)
1226 return mParentImpl.FindChildById(id);
1229 void Actor::UnparentChildren()
1231 mParentImpl.UnparentChildren();
1234 void Actor::ConnectToScene(uint32_t parentDepth, uint32_t layer3DParentsCount, bool notify)
1236 // This container is used instead of walking the Actor hierarchy.
1237 // It protects us when the Actor hierarchy is modified during OnSceneConnectionExternal callbacks.
1238 ActorContainer connectionList;
1242 mScene->RequestRebuildDepthTree();
1245 // This stage is not interrupted by user callbacks.
1246 mParentImpl.RecursiveConnectToScene(connectionList, layer3DParentsCount, parentDepth + 1);
1248 // Notify applications about the newly connected actors.
1249 for(const auto& actor : connectionList)
1251 actor->NotifyStageConnection(notify);
1258 * This method is called when the Actor is connected to the Stage.
1259 * The parent must have added its Node to the scene-graph.
1260 * The child must connect its Node to the parent's Node.
1261 * This is recursive; the child calls ConnectToScene() for its children.
1263 void Actor::ConnectToSceneGraph()
1265 DALI_ASSERT_DEBUG(mParent != NULL);
1267 // Reparent Node in next Update
1268 ConnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetParent()->GetNode(), GetNode());
1270 // Request relayout on all actors that are added to the scenegraph
1273 // Notification for Object::Observers
1277 void Actor::NotifyStageConnection(bool notify)
1279 // Actors can be removed (in a callback), before the on-stage stage is reported.
1280 // The actor may also have been reparented, in which case mOnSceneSignalled will be true.
1281 if(OnScene() && !mOnSceneSignalled)
1285 // Notification for external (CustomActor) derived classes
1286 OnSceneConnectionExternal(mDepth);
1288 if(!mOnSceneSignal.Empty())
1290 Dali::Actor handle(this);
1291 mOnSceneSignal.Emit(handle);
1295 // Guard against Remove during callbacks
1298 mOnSceneSignalled = true; // signal required next time Actor is removed
1303 void Actor::DisconnectFromStage(bool notify)
1305 // This container is used instead of walking the Actor hierachy.
1306 // It protects us when the Actor hierachy is modified during OnSceneDisconnectionExternal callbacks.
1307 ActorContainer disconnectionList;
1311 mScene->RequestRebuildDepthTree();
1314 // This stage is not interrupted by user callbacks
1315 mParentImpl.RecursiveDisconnectFromScene(disconnectionList);
1317 // Notify applications about the newly disconnected actors.
1318 for(const auto& actor : disconnectionList)
1320 actor->NotifyStageDisconnection(notify);
1325 * This method is called by an actor or its parent, before a node removal message is sent.
1326 * This is recursive; the child calls DisconnectFromStage() for its children.
1328 void Actor::DisconnectFromSceneGraph()
1330 // Notification for Object::Observers
1331 OnSceneObjectRemove();
1334 void Actor::NotifyStageDisconnection(bool notify)
1336 // Actors can be added (in a callback), before the off-stage state is reported.
1337 // Also if the actor was added & removed before mOnSceneSignalled was set, then we don't notify here.
1338 // only do this step if there is a stage, i.e. Core is not being shut down
1339 if(EventThreadServices::IsCoreRunning() && !OnScene() && mOnSceneSignalled)
1343 // Notification for external (CustomeActor) derived classes
1344 OnSceneDisconnectionExternal();
1346 if(!mOffSceneSignal.Empty())
1348 Dali::Actor handle(this);
1349 mOffSceneSignal.Emit(handle);
1353 // Guard against Add during callbacks
1356 mOnSceneSignalled = false; // signal required next time Actor is added
1361 bool Actor::IsNodeConnected() const
1363 return OnScene() && (IsRoot() || GetNode().GetParent());
1366 // This method initiates traversal of the actor tree using depth-first
1367 // traversal to set a depth index based on traversal order. It sends a
1368 // single message to update manager to update all the actor's nodes in
1369 // this tree with the depth index. The sceneGraphNodeDepths vector's
1370 // elements are ordered by depth, and could be used to reduce sorting
1371 // in the update thread.
1372 void Actor::RebuildDepthTree()
1374 DALI_LOG_TIMER_START(depthTimer);
1376 // Vector of scene-graph nodes and their depths to send to UpdateManager
1377 // in a single message
1378 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths(new SceneGraph::NodeDepths());
1380 int32_t depthIndex = 1;
1381 mParentImpl.DepthTraverseActorTree(sceneGraphNodeDepths, depthIndex);
1383 SetDepthIndicesMessage(GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths);
1384 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
1387 void Actor::SetDefaultProperty(Property::Index index, const Property::Value& property)
1389 PropertyHandler::SetDefaultProperty(*this, index, property);
1392 // TODO: This method needs to be removed
1393 void Actor::SetSceneGraphProperty(Property::Index index, const PropertyMetadata& entry, const Property::Value& value)
1395 PropertyHandler::SetSceneGraphProperty(index, entry, value, GetEventThreadServices(), GetNode());
1398 Property::Value Actor::GetDefaultProperty(Property::Index index) const
1400 Property::Value value;
1402 if(!GetCachedPropertyValue(index, value))
1404 // If property value is not stored in the event-side, then it must be a scene-graph only property
1405 GetCurrentPropertyValue(index, value);
1411 Property::Value Actor::GetDefaultPropertyCurrentValue(Property::Index index) const
1413 Property::Value value;
1415 if(!GetCurrentPropertyValue(index, value))
1417 // If unable to retrieve scene-graph property value, then it must be an event-side only property
1418 GetCachedPropertyValue(index, value);
1424 void Actor::OnNotifyDefaultPropertyAnimation(Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType)
1426 PropertyHandler::OnNotifyDefaultPropertyAnimation(*this, animation, index, value, animationType);
1429 const PropertyBase* Actor::GetSceneObjectAnimatableProperty(Property::Index index) const
1431 const PropertyBase* property = PropertyHandler::GetSceneObjectAnimatableProperty(index, GetNode());
1434 // not our property, ask base
1435 property = Object::GetSceneObjectAnimatableProperty(index);
1441 const PropertyInputImpl* Actor::GetSceneObjectInputProperty(Property::Index index) const
1443 const PropertyInputImpl* property = PropertyHandler::GetSceneObjectInputProperty(index, GetNode());
1446 // reuse animatable property getter as animatable properties are inputs as well
1447 // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
1448 property = GetSceneObjectAnimatableProperty(index);
1454 int32_t Actor::GetPropertyComponentIndex(Property::Index index) const
1456 int32_t componentIndex = PropertyHandler::GetPropertyComponentIndex(index);
1457 if(Property::INVALID_COMPONENT_INDEX == componentIndex)
1460 componentIndex = Object::GetPropertyComponentIndex(index);
1463 return componentIndex;
1466 const SceneGraph::Node& Actor::GetNode() const
1468 return *static_cast<const SceneGraph::Node*>(mUpdateObject);
1473 CheckParentAndCall(mParent, *this, &ActorParent::RaiseChild);
1478 CheckParentAndCall(mParent, *this, &ActorParent::LowerChild);
1481 void Actor::RaiseToTop()
1483 CheckParentAndCall(mParent, *this, &ActorParent::RaiseChildToTop);
1486 void Actor::LowerToBottom()
1488 CheckParentAndCall(mParent, *this, &ActorParent::LowerChildToBottom);
1491 void Actor::RaiseAbove(Internal::Actor& target)
1493 CheckParentAndCall(mParent, *this, target, &ActorParent::RaiseChildAbove);
1496 void Actor::LowerBelow(Internal::Actor& target)
1498 CheckParentAndCall(mParent, *this, target, &ActorParent::LowerChildBelow);
1501 void Actor::SetParent(ActorParent* parent, bool notify)
1503 bool emitInheritedVisible = false;
1504 bool visiblility = true;
1507 DALI_ASSERT_ALWAYS(!mParent && "Actor cannot have 2 parents");
1510 Actor* parentActor = static_cast<Actor*>(parent);
1511 mScene = parentActor->mScene;
1513 if(!EventThreadServices::IsShuttingDown() && // Don't emit signals or send messages during Core destruction
1514 parentActor->OnScene())
1516 // Instruct each actor to create a corresponding node in the scene graph
1517 ConnectToScene(parentActor->GetHierarchyDepth(), parentActor->GetLayer3DParentCount(), notify);
1519 Actor* actor = this;
1520 emitInheritedVisible = true;
1521 while(emitInheritedVisible && actor)
1523 emitInheritedVisible &= actor->GetProperty(Dali::Actor::Property::VISIBLE).Get<bool>();
1524 actor = actor->GetParent();
1528 // Resolve the name and index for the child properties if any
1529 ResolveChildProperties();
1531 else // parent being set to NULL
1533 DALI_ASSERT_ALWAYS(mParent != nullptr && "Actor should have a parent");
1535 if(!EventThreadServices::IsShuttingDown() && // Don't emit signals or send messages during Core destruction
1538 Actor* actor = this;
1539 emitInheritedVisible = true;
1540 while(emitInheritedVisible && actor)
1542 emitInheritedVisible &= actor->GetProperty(Dali::Actor::Property::VISIBLE).Get<bool>();
1543 actor = actor->GetParent();
1545 visiblility = false;
1550 if(!EventThreadServices::IsShuttingDown() && // Don't emit signals or send messages during Core destruction
1553 // Disconnect the Node & its children from the scene-graph.
1554 DisconnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
1556 // Instruct each actor to discard pointers to the scene-graph
1557 DisconnectFromStage(notify);
1563 if(emitInheritedVisible)
1565 EmitInheritedVisibilityChangedSignalRecursively(visiblility);
1569 Rect<> Actor::CalculateScreenExtents() const
1571 if(mLayer3DParentsCount == 0)
1573 // We can assume that this actor is under 2d layer. Use faster, but imprecise algorithm
1574 return CalculateActorScreenExtents(*this);
1578 return CalculateActorScreenExtentsRenderTaskList(*this);
1582 Rect<> Actor::CalculateCurrentScreenExtents() const
1584 BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
1585 if(mLayer3DParentsCount == 0)
1587 // We can assume that this actor is under 2d layer. Use faster, but imprecise algorithm
1588 return CalculateCurrentActorScreenExtents(*this, bufferIndex);
1592 return CalculateCurrentActorScreenExtentsRenderTaskList(*this, bufferIndex);
1596 Vector3 Actor::GetAnchorPointForPosition() const
1598 return (mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT);
1601 bool Actor::GetCachedPropertyValue(Property::Index index, Property::Value& value) const
1603 return PropertyHandler::GetCachedPropertyValue(*this, index, value);
1606 bool Actor::GetCurrentPropertyValue(Property::Index index, Property::Value& value) const
1608 return PropertyHandler::GetCurrentPropertyValue(*this, index, value);
1611 bool Actor::RelayoutDependentOnParent(Dimension::Type dimension)
1613 return mSizer.RelayoutDependentOnParent(dimension);
1616 bool Actor::RelayoutDependentOnChildren(Dimension::Type dimension)
1618 return mSizer.RelayoutDependentOnChildrenBase(dimension);
1621 bool Actor::RelayoutDependentOnDimension(Dimension::Type dimension, Dimension::Type dependentDimension)
1623 return mSizer.RelayoutDependentOnDimension(dimension, dependentDimension);
1626 void Actor::SetPadding(const Vector2& padding, Dimension::Type dimension)
1628 mSizer.SetPadding(padding, dimension);
1631 Vector2 Actor::GetPadding(Dimension::Type dimension) const
1633 return mSizer.GetPadding(dimension);
1636 void Actor::SetLayoutNegotiated(bool negotiated, Dimension::Type dimension)
1638 mSizer.SetLayoutNegotiated(negotiated, dimension);
1641 bool Actor::IsLayoutNegotiated(Dimension::Type dimension) const
1643 return mSizer.IsLayoutNegotiated(dimension);
1646 float Actor::GetHeightForWidthBase(float width)
1648 // Can be overridden in derived class
1649 return mSizer.GetHeightForWidthBase(width);
1652 float Actor::GetWidthForHeightBase(float height)
1654 // Can be overridden in derived class
1655 return mSizer.GetWidthForHeightBase(height);
1658 float Actor::CalculateChildSizeBase(const Dali::Actor& child, Dimension::Type dimension)
1660 // Can be overridden in derived class
1661 return mSizer.CalculateChildSizeBase(child, dimension);
1664 bool Actor::RelayoutDependentOnChildrenBase(Dimension::Type dimension)
1666 return mSizer.RelayoutDependentOnChildrenBase(dimension);
1669 float Actor::CalculateChildSize(const Dali::Actor& child, Dimension::Type dimension)
1671 // Can be overridden in derived class
1672 return mSizer.CalculateChildSizeBase(child, dimension);
1675 float Actor::GetHeightForWidth(float width)
1677 // Can be overridden in derived class
1678 return mSizer.GetHeightForWidthBase(width);
1681 float Actor::GetWidthForHeight(float height)
1683 // Can be overridden in derived class
1684 return mSizer.GetWidthForHeightBase(height);
1687 float Actor::GetRelayoutSize(Dimension::Type dimension) const
1689 return mSizer.GetRelayoutSize(dimension);
1692 void Actor::NegotiateSize(const Vector2& allocatedSize, RelayoutContainer& container)
1694 mSizer.NegotiateSize(allocatedSize, container);
1697 void Actor::RelayoutRequest(Dimension::Type dimension)
1699 mSizer.RelayoutRequest(dimension);
1702 void Actor::SetMinimumSize(float size, Dimension::Type dimension)
1704 mSizer.SetMinimumSize(size, dimension);
1707 float Actor::GetMinimumSize(Dimension::Type dimension) const
1709 return mSizer.GetMinimumSize(dimension);
1712 void Actor::SetMaximumSize(float size, Dimension::Type dimension)
1714 mSizer.SetMaximumSize(size, dimension);
1717 float Actor::GetMaximumSize(Dimension::Type dimension) const
1719 return mSizer.GetMaximumSize(dimension);
1722 void Actor::SetVisibleInternal(bool visible, SendMessage::Type sendMessage)
1724 if(mVisible != visible)
1726 if(sendMessage == SendMessage::TRUE)
1728 // node is being used in a separate thread; queue a message to set the value & base value
1729 SceneGraph::NodePropertyMessage<bool>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible);
1731 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
1734 Actor* actor = this->GetParent();
1735 bool emitInheritedVisible = OnScene();
1736 while(emitInheritedVisible && actor)
1738 emitInheritedVisible &= actor->GetProperty(Dali::Actor::Property::VISIBLE).Get<bool>();
1739 actor = actor->GetParent();
1744 // Emit the signal on this actor and all its children
1745 mParentImpl.EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::SELF);
1746 if(emitInheritedVisible)
1748 EmitInheritedVisibilityChangedSignalRecursively(visible);
1753 void Actor::EmitInheritedVisibilityChangedSignalRecursively(bool visible)
1755 ActorContainer inheritedVisibilityChangedList;
1756 mParentImpl.InheritVisibilityRecursively(inheritedVisibilityChangedList);
1757 // Notify applications about the newly connected actors.
1758 for(const auto& actor : inheritedVisibilityChangedList)
1760 actor->EmitInheritedVisibilityChangedSignal(visible);
1764 void Actor::SetSiblingOrderOfChild(Actor& child, uint32_t order)
1766 mParentImpl.SetSiblingOrderOfChild(child, order);
1769 uint32_t Actor::GetSiblingOrderOfChild(const Actor& child) const
1771 return mParentImpl.GetSiblingOrderOfChild(child);
1774 void Actor::RaiseChild(Actor& child)
1776 mParentImpl.RaiseChild(child);
1779 void Actor::LowerChild(Actor& child)
1781 mParentImpl.LowerChild(child);
1784 void Actor::RaiseChildToTop(Actor& child)
1786 mParentImpl.RaiseChildToTop(child);
1789 void Actor::LowerChildToBottom(Actor& child)
1791 mParentImpl.LowerChildToBottom(child);
1794 void Actor::RaiseChildAbove(Actor& child, Actor& target)
1796 mParentImpl.RaiseChildAbove(child, target);
1799 void Actor::LowerChildBelow(Actor& child, Actor& target)
1801 mParentImpl.LowerChildBelow(child, target);
1804 void Actor::SetInheritLayoutDirection(bool inherit)
1806 if(mInheritLayoutDirection != inherit)
1808 mInheritLayoutDirection = inherit;
1810 if(inherit && mParent)
1812 mParentImpl.InheritLayoutDirectionRecursively(GetParent()->mLayoutDirection);
1817 void Actor::SetUpdateAreaHint(const Vector4& updateAreaHint)
1819 // node is being used in a separate thread; queue a message to set the value & base value
1820 SetUpdateAreaHintMessage(GetEventThreadServices(), GetNode(), updateAreaHint);
1823 } // namespace Internal