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_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_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
166 static constexpr std::string_view SIGNAL_CHILD_ADDED = "childAdded";
167 static constexpr std::string_view SIGNAL_CHILD_REMOVED = "childRemoved";
171 static constexpr std::string_view ACTION_SHOW = "show";
172 static constexpr std::string_view ACTION_HIDE = "hide";
174 BaseHandle CreateActor()
176 return Dali::Actor::New();
180 * Connects a callback function with the object's signals.
181 * @param[in] object The object providing the signal.
182 * @param[in] tracker Used to disconnect the signal.
183 * @param[in] signalName The signal to connect to.
184 * @param[in] functor A newly allocated FunctorDelegate.
185 * @return True if the signal was connected.
186 * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
188 static bool DoConnectSignal(BaseObject* object,
189 ConnectionTrackerInterface* tracker,
190 const std::string& signalName,
191 FunctorDelegate* functor)
193 bool connected(true);
194 Actor* actor = static_cast<Actor*>(object); // TypeRegistry guarantees that this is the correct type.
196 std::string_view name(signalName);
198 if(name == SIGNAL_HOVERED)
200 actor->HoveredSignal().Connect(tracker, functor);
202 else if(signalName == SIGNAL_WHEEL_EVENT)
204 actor->WheelEventSignal().Connect(tracker, functor);
206 else if(name == SIGNAL_ON_SCENE)
208 actor->OnSceneSignal().Connect(tracker, functor);
210 else if(name == SIGNAL_OFF_SCENE)
212 actor->OffSceneSignal().Connect(tracker, functor);
214 else if(name == SIGNAL_ON_RELAYOUT)
216 actor->OnRelayoutSignal().Connect(tracker, functor);
218 else if(name == SIGNAL_TOUCHED)
220 actor->TouchedSignal().Connect(tracker, functor);
222 else if(name == SIGNAL_VISIBILITY_CHANGED)
224 actor->VisibilityChangedSignal().Connect(tracker, functor);
226 else if(name == SIGNAL_LAYOUT_DIRECTION_CHANGED)
228 actor->LayoutDirectionChangedSignal().Connect(tracker, functor);
230 else if(name == SIGNAL_CHILD_ADDED)
232 actor->ChildAddedSignal().Connect(tracker, functor);
234 else if(name == SIGNAL_CHILD_REMOVED)
236 actor->ChildRemovedSignal().Connect(tracker, functor);
240 // signalName does not match any signal
248 * Performs actions as requested using the action name.
249 * @param[in] object The object on which to perform the action.
250 * @param[in] actionName The action to perform.
251 * @param[in] attributes The attributes with which to perfrom this action.
252 * @return true if the action was done.
254 bool DoAction(BaseObject* object,
255 const std::string& actionName,
256 const Property::Map& attributes)
259 Actor* actor = dynamic_cast<Actor*>(object);
263 std::string_view name(actionName);
264 if(name == ACTION_SHOW)
266 actor->SetVisible(true);
269 else if(name == ACTION_HIDE)
271 actor->SetVisible(false);
279 TypeRegistration mType(typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties);
281 SignalConnectorType signalConnector2(mType, std::string(SIGNAL_HOVERED), &DoConnectSignal);
282 SignalConnectorType signalConnector3(mType, std::string(SIGNAL_WHEEL_EVENT), &DoConnectSignal);
283 SignalConnectorType signalConnector4(mType, std::string(SIGNAL_ON_SCENE), &DoConnectSignal);
284 SignalConnectorType signalConnector5(mType, std::string(SIGNAL_OFF_SCENE), &DoConnectSignal);
285 SignalConnectorType signalConnector6(mType, std::string(SIGNAL_ON_RELAYOUT), &DoConnectSignal);
286 SignalConnectorType signalConnector7(mType, std::string(SIGNAL_TOUCHED), &DoConnectSignal);
287 SignalConnectorType signalConnector8(mType, std::string(SIGNAL_VISIBILITY_CHANGED), &DoConnectSignal);
288 SignalConnectorType signalConnector9(mType, std::string(SIGNAL_LAYOUT_DIRECTION_CHANGED), &DoConnectSignal);
289 SignalConnectorType signalConnector10(mType, std::string(SIGNAL_CHILD_ADDED), &DoConnectSignal);
290 SignalConnectorType signalConnector11(mType, std::string(SIGNAL_CHILD_REMOVED), &DoConnectSignal);
292 TypeAction a1(mType, std::string(ACTION_SHOW), &DoAction);
293 TypeAction a2(mType, std::string(ACTION_HIDE), &DoAction);
295 /// Helper for emitting a signal
296 template<typename Signal, typename Event>
297 bool EmitConsumingSignal(Actor& actor, Signal& signal, const Event& event)
299 bool consumed = false;
303 Dali::Actor handle(&actor);
304 consumed = signal.Emit(handle, event);
310 /// Helper for emitting signals with multiple parameters
311 template<typename Signal, typename... Param>
312 void EmitSignal(Actor& actor, Signal& signal, Param... params)
316 Dali::Actor handle(&actor);
317 signal.Emit(handle, params...);
321 using ActorParentSiblingOrderMethod = void (ActorParent::*)(Actor&);
322 using ActorParentSiblingOrderMethodWithTarget = void (ActorParent::*)(Actor&, Actor&);
324 /// Helper to check and call actor sibling methods in ActorParent
325 void CheckParentAndCall(ActorParent* parent, Actor& actor, ActorParentSiblingOrderMethod memberFunction)
329 (parent->*memberFunction)(actor);
333 DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
337 /// Helper to check and call actor sibling methods with a target parameter in ActorParent
338 void CheckParentAndCall(ActorParent* parent, Actor& actor, Actor& target, ActorParentSiblingOrderMethodWithTarget memberFunction)
342 (parent->*memberFunction)(actor, target);
346 DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
350 } // unnamed namespace
352 ActorPtr Actor::New()
354 // pass a reference to actor, actor does not own its node
355 ActorPtr actor(new Actor(BASIC, *CreateNode()));
357 // Second-phase construction
363 const SceneGraph::Node* Actor::CreateNode()
365 // create node. Nodes are owned by the update manager
366 SceneGraph::Node* node = SceneGraph::Node::New();
367 OwnerPointer<SceneGraph::Node> transferOwnership(node);
368 Internal::ThreadLocalStorage* tls = Internal::ThreadLocalStorage::GetInternal();
370 DALI_ASSERT_ALWAYS(tls && "ThreadLocalStorage is null");
372 AddNodeMessage(tls->GetUpdateManager(), transferOwnership);
377 void Actor::SetName(std::string_view name)
379 mName = ConstString(name);
381 // ATTENTION: string for debug purposes is not thread safe.
382 DALI_LOG_SET_OBJECT_STRING(const_cast<SceneGraph::Node*>(&GetNode()), mName.GetCString());
385 uint32_t Actor::GetId() const
387 return GetNode().GetId();
390 Dali::Layer Actor::GetLayer()
394 // Short-circuit for Layer derived actors
397 layer = Dali::Layer(static_cast<Dali::Internal::Layer*>(this)); // static cast as we trust the flag
400 // Find the immediate Layer parent
401 for(Actor* parent = GetParent(); !layer && parent != nullptr; parent = parent->GetParent())
403 if(parent->IsLayer())
405 layer = Dali::Layer(static_cast<Dali::Internal::Layer*>(parent)); // static cast as we trust the flag
412 void Actor::Unparent()
416 // Remove this actor from the parent. The remove will put a relayout request in for
417 // the parent if required
418 mParent->Remove(*this);
419 // mParent is now NULL!
423 void Actor::SetParentOrigin(const Vector3& origin)
425 // node is being used in a separate thread; queue a message to set the value & base value
426 SetParentOriginMessage(GetEventThreadServices(), GetNode(), origin);
428 // Cache for event-thread access
431 // not allocated, check if different from default
432 if(ParentOrigin::DEFAULT != origin)
434 mParentOrigin = new Vector3(origin);
439 // check if different from current costs more than just set
440 *mParentOrigin = origin;
444 const Vector3& Actor::GetCurrentParentOrigin() const
446 // Cached for event-thread access
447 return (mParentOrigin) ? *mParentOrigin : ParentOrigin::DEFAULT;
450 void Actor::SetAnchorPoint(const Vector3& anchor)
452 // node is being used in a separate thread; queue a message to set the value & base value
453 SetAnchorPointMessage(GetEventThreadServices(), GetNode(), anchor);
455 // Cache for event-thread access
458 // not allocated, check if different from default
459 if(AnchorPoint::DEFAULT != anchor)
461 mAnchorPoint = new Vector3(anchor);
466 // check if different from current costs more than just set
467 *mAnchorPoint = anchor;
471 const Vector3& Actor::GetCurrentAnchorPoint() const
473 // Cached for event-thread access
474 return (mAnchorPoint) ? *mAnchorPoint : AnchorPoint::DEFAULT;
477 void Actor::SetPosition(float x, float y)
479 SetPosition(Vector3(x, y, 0.0f));
482 void Actor::SetPosition(float x, float y, float z)
484 SetPosition(Vector3(x, y, z));
487 void Actor::SetPosition(const Vector3& position)
489 mTargetPosition = position;
491 // node is being used in a separate thread; queue a message to set the value & base value
492 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position);
495 void Actor::SetX(float x)
497 mTargetPosition.x = x;
499 // node is being used in a separate thread; queue a message to set the value & base value
500 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x);
503 void Actor::SetY(float y)
505 mTargetPosition.y = y;
507 // node is being used in a separate thread; queue a message to set the value & base value
508 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y);
511 void Actor::SetZ(float z)
513 mTargetPosition.z = z;
515 // node is being used in a separate thread; queue a message to set the value & base value
516 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z);
519 void Actor::TranslateBy(const Vector3& distance)
521 mTargetPosition += distance;
523 // node is being used in a separate thread; queue a message to set the value & base value
524 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance);
527 const Vector3& Actor::GetCurrentPosition() const
529 // node is being used in a separate thread; copy the value from the previous update
530 return GetNode().GetPosition(GetEventThreadServices().GetEventBufferIndex());
533 const Vector3& Actor::GetCurrentWorldPosition() const
535 // node is being used in a separate thread; copy the value from the previous update
536 return GetNode().GetWorldPosition(GetEventThreadServices().GetEventBufferIndex());
539 const Vector2 Actor::CalculateScreenPosition() const
543 if(mLayer3DParentsCount == 0)
545 // We can assume that this actor is under 2d layer. Use faster, but imprecise algorithm
546 return CalculateActorScreenPosition(*this);
550 return CalculateActorScreenPositionRenderTaskList(*this);
553 return Vector2::ZERO;
556 const Vector2 Actor::GetCurrentScreenPosition() const
560 BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
561 if(mLayer3DParentsCount == 0)
563 // We can assume that this actor is under 2d layer. Use faster, but imprecise algorithm
564 return CalculateCurrentActorScreenPosition(*this, bufferIndex);
568 return CalculateCurrentActorScreenPositionRenderTaskList(*this, bufferIndex);
571 return Vector2::ZERO;
574 void Actor::SetInheritPosition(bool inherit)
576 if(mInheritPosition != inherit)
578 // non animatable so keep local copy
579 mInheritPosition = inherit;
580 SetInheritPositionMessage(GetEventThreadServices(), GetNode(), inherit);
584 void Actor::SetOrientation(const Radian& angle, const Vector3& axis)
586 Vector3 normalizedAxis(axis.x, axis.y, axis.z);
587 normalizedAxis.Normalize();
589 Quaternion orientation(angle, normalizedAxis);
591 SetOrientation(orientation);
594 void Actor::SetOrientation(const Quaternion& orientation)
596 mTargetOrientation = orientation;
598 // node is being used in a separate thread; queue a message to set the value & base value
599 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation);
602 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
604 RotateBy(Quaternion(angle, axis));
607 void Actor::RotateBy(const Quaternion& relativeRotation)
609 mTargetOrientation *= Quaternion(relativeRotation);
611 // node is being used in a separate thread; queue a message to set the value & base value
612 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation);
615 const Quaternion& Actor::GetCurrentOrientation() const
617 // node is being used in a separate thread; copy the value from the previous update
618 return GetNode().GetOrientation(GetEventThreadServices().GetEventBufferIndex());
621 const Quaternion& Actor::GetCurrentWorldOrientation() const
623 // node is being used in a separate thread; copy the value from the previous update
624 return GetNode().GetWorldOrientation(GetEventThreadServices().GetEventBufferIndex());
627 void Actor::SetScale(float scale)
629 SetScale(Vector3(scale, scale, scale));
632 void Actor::SetScale(float x, float y, float z)
634 SetScale(Vector3(x, y, z));
637 void Actor::SetScale(const Vector3& scale)
639 mTargetScale = scale;
641 // node is being used in a separate thread; queue a message to set the value & base value
642 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale);
645 void Actor::SetScaleX(float x)
649 // node is being used in a separate thread; queue a message to set the value & base value
650 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x);
653 void Actor::SetScaleY(float y)
657 // node is being used in a separate thread; queue a message to set the value & base value
658 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y);
661 void Actor::SetScaleZ(float z)
665 // node is being used in a separate thread; queue a message to set the value & base value
666 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z);
669 void Actor::ScaleBy(const Vector3& relativeScale)
671 mTargetScale *= relativeScale;
673 // node is being used in a separate thread; queue a message to set the value & base value
674 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale);
677 const Vector3& Actor::GetCurrentScale() const
679 // node is being used in a separate thread; copy the value from the previous update
680 return GetNode().GetScale(GetEventThreadServices().GetEventBufferIndex());
683 const Vector3& Actor::GetCurrentWorldScale() const
685 // node is being used in a separate thread; copy the value from the previous update
686 return GetNode().GetWorldScale(GetEventThreadServices().GetEventBufferIndex());
689 void Actor::SetInheritScale(bool inherit)
691 if(mInheritScale != inherit)
693 // non animatable so keep local copy
694 mInheritScale = inherit;
695 // node is being used in a separate thread; queue a message to set the value
696 SetInheritScaleMessage(GetEventThreadServices(), GetNode(), inherit);
700 Matrix Actor::GetCurrentWorldMatrix() const
702 return GetNode().GetWorldMatrix(0);
705 void Actor::SetVisible(bool visible)
707 SetVisibleInternal(visible, SendMessage::TRUE);
710 bool Actor::IsVisible() const
712 // node is being used in a separate thread; copy the value from the previous update
713 return GetNode().IsVisible(GetEventThreadServices().GetEventBufferIndex());
716 void Actor::SetOpacity(float opacity)
718 mTargetColor.a = opacity;
720 // node is being used in a separate thread; queue a message to set the value & base value
721 SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeW, opacity);
723 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
726 float Actor::GetCurrentOpacity() const
728 // node is being used in a separate thread; copy the value from the previous update
729 return GetNode().GetOpacity(GetEventThreadServices().GetEventBufferIndex());
732 const Vector4& Actor::GetCurrentWorldColor() const
734 return GetNode().GetWorldColor(GetEventThreadServices().GetEventBufferIndex());
737 void Actor::SetColor(const Vector4& color)
739 mTargetColor = color;
741 // node is being used in a separate thread; queue a message to set the value & base value
742 SceneGraph::NodePropertyMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::Bake, color);
744 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
747 void Actor::SetColorRed(float red)
749 mTargetColor.r = red;
751 // node is being used in a separate thread; queue a message to set the value & base value
752 SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeX, red);
754 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
757 void Actor::SetColorGreen(float green)
759 mTargetColor.g = green;
761 // node is being used in a separate thread; queue a message to set the value & base value
762 SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeY, green);
764 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
767 void Actor::SetColorBlue(float blue)
769 mTargetColor.b = blue;
771 // node is being used in a separate thread; queue a message to set the value & base value
772 SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeZ, blue);
774 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
777 const Vector4& Actor::GetCurrentColor() const
779 // node is being used in a separate thread; copy the value from the previous update
780 return GetNode().GetColor(GetEventThreadServices().GetEventBufferIndex());
783 void Actor::SetInheritOrientation(bool inherit)
785 if(mInheritOrientation != inherit)
787 // non animatable so keep local copy
788 mInheritOrientation = inherit;
789 // node is being used in a separate thread; queue a message to set the value
790 SetInheritOrientationMessage(GetEventThreadServices(), GetNode(), inherit);
794 void Actor::SetSizeModeFactor(const Vector3& factor)
796 mSizer.SetSizeModeFactor(factor);
799 const Vector3& Actor::GetSizeModeFactor() const
801 return mSizer.GetSizeModeFactor();
804 void Actor::SetColorMode(ColorMode colorMode)
806 // non animatable so keep local copy
807 mColorMode = colorMode;
808 // node is being used in a separate thread; queue a message to set the value
809 SetColorModeMessage(GetEventThreadServices(), GetNode(), colorMode);
812 void Actor::SetSize(float width, float height)
814 SetSize(Vector2(width, height));
817 void Actor::SetSize(float width, float height, float depth)
819 SetSize(Vector3(width, height, depth));
822 void Actor::SetSize(const Vector2& size)
824 SetSize(Vector3(size.width, size.height, 0.f));
827 void Actor::SetSize(const Vector3& size)
829 mSizer.SetSize(size);
832 void Actor::SetWidth(float width)
834 mSizer.SetWidth(width);
837 void Actor::SetHeight(float height)
839 mSizer.SetHeight(height);
842 void Actor::SetDepth(float depth)
844 mSizer.SetDepth(depth);
845 // node is being used in a separate thread; queue a message to set the value & base value
846 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth);
849 Vector3 Actor::GetTargetSize() const
851 return mSizer.GetTargetSize();
854 const Vector3& Actor::GetCurrentSize() const
856 // node is being used in a separate thread; copy the value from the previous update
857 return GetNode().GetSize(GetEventThreadServices().GetEventBufferIndex());
860 Vector3 Actor::GetNaturalSize() const
862 // It is up to deriving classes to return the appropriate natural size
863 return Vector3(0.0f, 0.0f, 0.0f);
866 void Actor::SetResizePolicy(ResizePolicy::Type policy, Dimension::Type dimension)
868 mSizer.SetResizePolicy(policy, dimension);
871 ResizePolicy::Type Actor::GetResizePolicy(Dimension::Type dimension) const
873 return mSizer.GetResizePolicy(dimension);
876 void Actor::SetRelayoutEnabled(bool relayoutEnabled)
878 mSizer.SetRelayoutEnabled(relayoutEnabled);
881 bool Actor::IsRelayoutEnabled() const
883 return mSizer.IsRelayoutEnabled();
886 void Actor::SetLayoutDirty(bool dirty, Dimension::Type dimension)
888 mSizer.SetLayoutDirty(dirty, dimension);
891 bool Actor::IsLayoutDirty(Dimension::Type dimension) const
893 return mSizer.IsLayoutDirty(dimension);
896 bool Actor::RelayoutPossible(Dimension::Type dimension) const
898 return mSizer.RelayoutPossible(dimension);
901 bool Actor::RelayoutRequired(Dimension::Type dimension) const
903 return mSizer.RelayoutRequired(dimension);
906 uint32_t Actor::AddRenderer(Renderer& renderer)
910 mRenderers = new RendererContainer(GetEventThreadServices());
912 return mRenderers->Add(GetNode(), renderer, mIsBlendEquationSet, mBlendEquation);
915 uint32_t Actor::GetRendererCount() const
917 return mRenderers ? mRenderers->GetCount() : 0u;
920 RendererPtr Actor::GetRendererAt(uint32_t index)
922 return mRenderers ? mRenderers->GetRendererAt(index) : nullptr;
925 void Actor::RemoveRenderer(Renderer& renderer)
929 mRenderers->Remove(GetNode(), renderer);
933 void Actor::RemoveRenderer(uint32_t index)
937 mRenderers->Remove(GetNode(), index);
941 void Actor::SetBlendEquation(DevelBlendEquation::Type blendEquation)
943 if(Dali::Capabilities::IsBlendEquationSupported(blendEquation))
945 if(mBlendEquation != blendEquation)
947 mBlendEquation = blendEquation;
950 mRenderers->SetBlending(blendEquation);
953 mIsBlendEquationSet = true;
957 DALI_LOG_ERROR("Invalid blend equation is entered.\n");
961 DevelBlendEquation::Type Actor::GetBlendEquation() const
963 return mBlendEquation;
966 void Actor::SetTransparent(bool transparent)
968 SetTransparentMessage(GetEventThreadServices(), GetNode(), transparent);
971 bool Actor::IsTransparent() const
973 return GetNode().IsTransparent();
976 void Actor::SetDrawMode(DrawMode::Type drawMode)
978 // this flag is not animatable so keep the value
979 mDrawMode = drawMode;
981 // node is being used in a separate thread; queue a message to set the value
982 SetDrawModeMessage(GetEventThreadServices(), GetNode(), drawMode);
985 bool Actor::ScreenToLocal(float& localX, float& localY, float screenX, float screenY) const
987 return mScene && OnScene() && ConvertScreenToLocalRenderTaskList(mScene->GetRenderTaskList(), GetNode().GetWorldMatrix(0), GetCurrentSize(), localX, localY, screenX, screenY);
990 bool Actor::ScreenToLocal(const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY) const
992 return OnScene() && ConvertScreenToLocalRenderTask(renderTask, GetNode().GetWorldMatrix(0), GetCurrentSize(), localX, localY, screenX, screenY);
995 bool Actor::ScreenToLocal(const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY) const
997 return OnScene() && ConvertScreenToLocal(viewMatrix, projectionMatrix, GetNode().GetWorldMatrix(0), GetCurrentSize(), viewport, localX, localY, screenX, screenY);
1000 ActorGestureData& Actor::GetGestureData()
1002 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1003 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1004 if(nullptr == mGestureData)
1006 mGestureData = new ActorGestureData;
1008 return *mGestureData;
1011 bool Actor::IsGestureRequired(GestureType::Value type) const
1013 return mGestureData && mGestureData->IsGestureRequired(type);
1016 bool Actor::EmitInterceptTouchEventSignal(const Dali::TouchEvent& touch)
1018 return EmitConsumingSignal(*this, mInterceptTouchedSignal, touch);
1021 bool Actor::EmitTouchEventSignal(const Dali::TouchEvent& touch)
1023 return EmitConsumingSignal(*this, mTouchedSignal, touch);
1026 bool Actor::EmitHoverEventSignal(const Dali::HoverEvent& event)
1028 return EmitConsumingSignal(*this, mHoveredSignal, event);
1031 bool Actor::EmitInterceptWheelEventSignal(const Dali::WheelEvent& event)
1033 return EmitConsumingSignal(*this, mInterceptWheelSignal, event);
1036 bool Actor::EmitWheelEventSignal(const Dali::WheelEvent& event)
1038 return EmitConsumingSignal(*this, mWheelEventSignal, event);
1041 void Actor::EmitVisibilityChangedSignal(bool visible, DevelActor::VisibilityChange::Type type)
1043 EmitSignal(*this, mVisibilityChangedSignal, visible, type);
1046 void Actor::EmitLayoutDirectionChangedSignal(LayoutDirection::Type type)
1048 EmitSignal(*this, mLayoutDirectionChangedSignal, type);
1051 bool Actor::EmitHitTestResultSignal(Integration::Point point, Vector2 hitPointLocal, uint32_t timeStamp)
1055 if(IsHitTestResultRequired())
1057 Dali::Actor handle(this);
1058 Integration::Point newPoint(point);
1059 newPoint.SetHitActor(handle);
1060 newPoint.SetLocalPosition(hitPointLocal);
1061 Dali::TouchEvent touchEvent = Dali::Integration::NewTouchEvent(timeStamp, newPoint);
1062 hit = mHitTestResultSignal.Emit(handle, touchEvent);
1067 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
1069 return mParentImpl.ChildAddedSignal();
1072 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
1074 return mParentImpl.ChildRemovedSignal();
1077 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
1079 return mParentImpl.ChildOrderChangedSignal();
1082 Actor::Actor(DerivedType derivedType, const SceneGraph::Node& node)
1088 mRenderers(nullptr),
1089 mParentOrigin(nullptr),
1090 mAnchorPoint(nullptr),
1091 mGestureData(nullptr),
1092 mInterceptTouchedSignal(),
1095 mInterceptWheelSignal(),
1096 mWheelEventSignal(),
1099 mOnRelayoutSignal(),
1100 mVisibilityChangedSignal(),
1101 mLayoutDirectionChangedSignal(),
1102 mHitTestResultSignal(),
1103 mTargetOrientation(Quaternion::IDENTITY),
1104 mTargetColor(Color::WHITE),
1105 mTargetPosition(Vector3::ZERO),
1106 mTargetScale(Vector3::ONE),
1107 mTouchAreaOffset(0, 0, 0, 0),
1111 mLayer3DParentsCount(0),
1112 mIsRoot(ROOT_LAYER == derivedType),
1113 mIsLayer(LAYER == derivedType || ROOT_LAYER == derivedType),
1116 mLeaveRequired(false),
1117 mKeyboardFocusable(false),
1118 mKeyboardFocusableChildren(true),
1119 mTouchFocusable(false),
1120 mOnSceneSignalled(false),
1121 mInheritPosition(true),
1122 mInheritOrientation(true),
1123 mInheritScale(true),
1124 mPositionUsesAnchorPoint(true),
1126 mInheritLayoutDirection(true),
1127 mCaptureAllTouchAfterStart(false),
1128 mIsBlendEquationSet(false),
1129 mNeedGesturePropagation(false),
1130 mUserInteractionEnabled(true),
1131 mAllowOnlyOwnTouch(false),
1132 mUseTextureUpdateArea(false),
1133 mLayoutDirection(LayoutDirection::LEFT_TO_RIGHT),
1134 mDrawMode(DrawMode::NORMAL),
1135 mColorMode(Node::DEFAULT_COLOR_MODE),
1136 mClippingMode(ClippingMode::DISABLED),
1137 mBlendEquation(DevelBlendEquation::ADD)
1141 void Actor::Initialize()
1145 GetEventThreadServices().RegisterObject(this);
1150 // Remove mParent pointers from children even if we're destroying core,
1151 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
1154 // Guard to allow handle destruction after Core has been destroyed
1155 if(EventThreadServices::IsCoreRunning())
1159 // Detach all renderers before delete container.
1160 mRenderers->RemoveAll(GetNode());
1163 // Root layer will destroy its node in its own destructor
1166 DestroyNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
1168 GetEventThreadServices().UnregisterObject(this);
1171 // Cleanup renderer list
1174 // Cleanup optional gesture data
1175 delete mGestureData;
1177 // Cleanup optional parent origin and anchor
1178 delete mParentOrigin;
1179 delete mAnchorPoint;
1182 void Actor::Add(Actor& child, bool notify)
1184 mParentImpl.Add(child, notify);
1187 void Actor::Remove(Actor& child, bool notify)
1189 mParentImpl.Remove(child, notify);
1192 void Actor::SwitchParent(Actor& newParent)
1194 if(this == &newParent)
1196 DALI_LOG_ERROR("Cannot add actor to itself");
1200 if(!this->OnScene() || !newParent.OnScene())
1202 DALI_LOG_ERROR("Both of current parent and new parent must be on Scene");
1206 newParent.Add(*this, false);
1209 uint32_t Actor::GetChildCount() const
1211 return mParentImpl.GetChildCount();
1214 ActorPtr Actor::GetChildAt(uint32_t index) const
1216 return mParentImpl.GetChildAt(index);
1219 ActorContainer& Actor::GetChildrenInternal()
1221 return mParentImpl.GetChildrenInternal();
1224 ActorPtr Actor::FindChildByName(ConstString actorName)
1226 return mParentImpl.FindChildByName(actorName);
1229 ActorPtr Actor::FindChildById(const uint32_t id)
1231 return mParentImpl.FindChildById(id);
1234 void Actor::UnparentChildren()
1236 mParentImpl.UnparentChildren();
1239 void Actor::ConnectToScene(uint32_t parentDepth, uint32_t layer3DParentsCount, bool notify)
1241 // This container is used instead of walking the Actor hierarchy.
1242 // It protects us when the Actor hierarchy is modified during OnSceneConnectionExternal callbacks.
1243 ActorContainer connectionList;
1247 mScene->RequestRebuildDepthTree();
1250 // This stage is not interrupted by user callbacks.
1251 mParentImpl.RecursiveConnectToScene(connectionList, layer3DParentsCount, parentDepth + 1);
1253 // Notify applications about the newly connected actors.
1254 for(const auto& actor : connectionList)
1256 actor->NotifyStageConnection(notify);
1263 * This method is called when the Actor is connected to the Stage.
1264 * The parent must have added its Node to the scene-graph.
1265 * The child must connect its Node to the parent's Node.
1266 * This is recursive; the child calls ConnectToScene() for its children.
1268 void Actor::ConnectToSceneGraph()
1270 DALI_ASSERT_DEBUG(mParent != NULL);
1272 // Reparent Node in next Update
1273 ConnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetParent()->GetNode(), GetNode());
1275 // Request relayout on all actors that are added to the scenegraph
1278 // Notification for Object::Observers
1282 void Actor::NotifyStageConnection(bool notify)
1284 // Actors can be removed (in a callback), before the on-stage stage is reported.
1285 // The actor may also have been reparented, in which case mOnSceneSignalled will be true.
1286 if(OnScene() && !mOnSceneSignalled)
1290 // Notification for external (CustomActor) derived classes
1291 OnSceneConnectionExternal(mDepth);
1293 if(!mOnSceneSignal.Empty())
1295 Dali::Actor handle(this);
1296 mOnSceneSignal.Emit(handle);
1300 // Guard against Remove during callbacks
1303 mOnSceneSignalled = true; // signal required next time Actor is removed
1308 void Actor::DisconnectFromStage(bool notify)
1310 // This container is used instead of walking the Actor hierachy.
1311 // It protects us when the Actor hierachy is modified during OnSceneDisconnectionExternal callbacks.
1312 ActorContainer disconnectionList;
1316 mScene->RequestRebuildDepthTree();
1319 // This stage is not interrupted by user callbacks
1320 mParentImpl.RecursiveDisconnectFromScene(disconnectionList);
1322 // Notify applications about the newly disconnected actors.
1323 for(const auto& actor : disconnectionList)
1325 actor->NotifyStageDisconnection(notify);
1330 * This method is called by an actor or its parent, before a node removal message is sent.
1331 * This is recursive; the child calls DisconnectFromStage() for its children.
1333 void Actor::DisconnectFromSceneGraph()
1335 // Notification for Object::Observers
1336 OnSceneObjectRemove();
1339 void Actor::NotifyStageDisconnection(bool notify)
1341 // Actors can be added (in a callback), before the off-stage state is reported.
1342 // Also if the actor was added & removed before mOnSceneSignalled was set, then we don't notify here.
1343 // only do this step if there is a stage, i.e. Core is not being shut down
1344 if(EventThreadServices::IsCoreRunning() && !OnScene() && mOnSceneSignalled)
1348 // Notification for external (CustomeActor) derived classes
1349 OnSceneDisconnectionExternal();
1351 if(!mOffSceneSignal.Empty())
1353 Dali::Actor handle(this);
1354 mOffSceneSignal.Emit(handle);
1358 // Guard against Add during callbacks
1361 mOnSceneSignalled = false; // signal required next time Actor is added
1366 bool Actor::IsNodeConnected() const
1368 return OnScene() && (IsRoot() || GetNode().GetParent());
1371 // This method initiates traversal of the actor tree using depth-first
1372 // traversal to set a depth index based on traversal order. It sends a
1373 // single message to update manager to update all the actor's nodes in
1374 // this tree with the depth index. The sceneGraphNodeDepths vector's
1375 // elements are ordered by depth, and could be used to reduce sorting
1376 // in the update thread.
1377 void Actor::RebuildDepthTree()
1379 DALI_LOG_TIMER_START(depthTimer);
1381 // Vector of scene-graph nodes and their depths to send to UpdateManager
1382 // in a single message
1383 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths(new SceneGraph::NodeDepths());
1385 int32_t depthIndex = 1;
1386 mParentImpl.DepthTraverseActorTree(sceneGraphNodeDepths, depthIndex);
1388 SetDepthIndicesMessage(GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths);
1389 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
1392 void Actor::SetDefaultProperty(Property::Index index, const Property::Value& property)
1394 PropertyHandler::SetDefaultProperty(*this, index, property);
1397 // TODO: This method needs to be removed
1398 void Actor::SetSceneGraphProperty(Property::Index index, const PropertyMetadata& entry, const Property::Value& value)
1400 PropertyHandler::SetSceneGraphProperty(index, entry, value, GetEventThreadServices(), GetNode());
1403 Property::Value Actor::GetDefaultProperty(Property::Index index) const
1405 Property::Value value;
1407 if(!GetCachedPropertyValue(index, value))
1409 // If property value is not stored in the event-side, then it must be a scene-graph only property
1410 GetCurrentPropertyValue(index, value);
1416 Property::Value Actor::GetDefaultPropertyCurrentValue(Property::Index index) const
1418 Property::Value value;
1420 if(!GetCurrentPropertyValue(index, value))
1422 // If unable to retrieve scene-graph property value, then it must be an event-side only property
1423 GetCachedPropertyValue(index, value);
1429 void Actor::OnNotifyDefaultPropertyAnimation(Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType)
1431 PropertyHandler::OnNotifyDefaultPropertyAnimation(*this, animation, index, value, animationType);
1434 const PropertyBase* Actor::GetSceneObjectAnimatableProperty(Property::Index index) const
1436 const PropertyBase* property = PropertyHandler::GetSceneObjectAnimatableProperty(index, GetNode());
1439 // not our property, ask base
1440 property = Object::GetSceneObjectAnimatableProperty(index);
1446 const PropertyInputImpl* Actor::GetSceneObjectInputProperty(Property::Index index) const
1448 const PropertyInputImpl* property = PropertyHandler::GetSceneObjectInputProperty(index, GetNode());
1451 // reuse animatable property getter as animatable properties are inputs as well
1452 // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
1453 property = GetSceneObjectAnimatableProperty(index);
1459 int32_t Actor::GetPropertyComponentIndex(Property::Index index) const
1461 int32_t componentIndex = PropertyHandler::GetPropertyComponentIndex(index);
1462 if(Property::INVALID_COMPONENT_INDEX == componentIndex)
1465 componentIndex = Object::GetPropertyComponentIndex(index);
1468 return componentIndex;
1471 const SceneGraph::Node& Actor::GetNode() const
1473 return *static_cast<const SceneGraph::Node*>(mUpdateObject);
1478 CheckParentAndCall(mParent, *this, &ActorParent::RaiseChild);
1483 CheckParentAndCall(mParent, *this, &ActorParent::LowerChild);
1486 void Actor::RaiseToTop()
1488 CheckParentAndCall(mParent, *this, &ActorParent::RaiseChildToTop);
1491 void Actor::LowerToBottom()
1493 CheckParentAndCall(mParent, *this, &ActorParent::LowerChildToBottom);
1496 void Actor::RaiseAbove(Internal::Actor& target)
1498 CheckParentAndCall(mParent, *this, target, &ActorParent::RaiseChildAbove);
1501 void Actor::LowerBelow(Internal::Actor& target)
1503 CheckParentAndCall(mParent, *this, target, &ActorParent::LowerChildBelow);
1506 void Actor::SetParent(ActorParent* parent, bool notify)
1510 DALI_ASSERT_ALWAYS(!mParent && "Actor cannot have 2 parents");
1513 Actor* parentActor = static_cast<Actor*>(parent);
1514 mScene = parentActor->mScene;
1516 if(!EventThreadServices::IsShuttingDown() && // Don't emit signals or send messages during Core destruction
1517 parentActor->OnScene())
1519 // Instruct each actor to create a corresponding node in the scene graph
1520 ConnectToScene(parentActor->GetHierarchyDepth(), parentActor->GetLayer3DParentCount(), notify);
1523 // Resolve the name and index for the child properties if any
1524 ResolveChildProperties();
1526 else // parent being set to NULL
1528 DALI_ASSERT_ALWAYS(mParent != nullptr && "Actor should have a parent");
1532 if(!EventThreadServices::IsShuttingDown() && // Don't emit signals or send messages during Core destruction
1535 // Disconnect the Node & its children from the scene-graph.
1536 DisconnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
1538 // Instruct each actor to discard pointers to the scene-graph
1539 DisconnectFromStage(notify);
1546 Rect<> Actor::CalculateScreenExtents() const
1548 if(mLayer3DParentsCount == 0)
1550 // We can assume that this actor is under 2d layer. Use faster, but imprecise algorithm
1551 return CalculateActorScreenExtents(*this);
1555 return CalculateActorScreenExtentsRenderTaskList(*this);
1559 Rect<> Actor::CalculateCurrentScreenExtents() const
1561 if(mLayer3DParentsCount == 0)
1563 // We can assume that this actor is under 2d layer. Use faster, but imprecise algorithm
1564 BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
1565 return CalculateCurrentActorScreenExtents(*this, bufferIndex);
1569 BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
1570 return CalculateCurrentActorScreenExtentsRenderTaskList(*this, bufferIndex);
1574 Vector3 Actor::GetAnchorPointForPosition() const
1576 return (mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT);
1579 bool Actor::GetCachedPropertyValue(Property::Index index, Property::Value& value) const
1581 return PropertyHandler::GetCachedPropertyValue(*this, index, value);
1584 bool Actor::GetCurrentPropertyValue(Property::Index index, Property::Value& value) const
1586 return PropertyHandler::GetCurrentPropertyValue(*this, index, value);
1589 bool Actor::RelayoutDependentOnParent(Dimension::Type dimension)
1591 return mSizer.RelayoutDependentOnParent(dimension);
1594 bool Actor::RelayoutDependentOnChildren(Dimension::Type dimension)
1596 return mSizer.RelayoutDependentOnChildrenBase(dimension);
1599 bool Actor::RelayoutDependentOnDimension(Dimension::Type dimension, Dimension::Type dependentDimension)
1601 return mSizer.RelayoutDependentOnDimension(dimension, dependentDimension);
1604 void Actor::SetPadding(const Vector2& padding, Dimension::Type dimension)
1606 mSizer.SetPadding(padding, dimension);
1609 Vector2 Actor::GetPadding(Dimension::Type dimension) const
1611 return mSizer.GetPadding(dimension);
1614 void Actor::SetLayoutNegotiated(bool negotiated, Dimension::Type dimension)
1616 mSizer.SetLayoutNegotiated(negotiated, dimension);
1619 bool Actor::IsLayoutNegotiated(Dimension::Type dimension) const
1621 return mSizer.IsLayoutNegotiated(dimension);
1624 float Actor::GetHeightForWidthBase(float width)
1626 // Can be overridden in derived class
1627 return mSizer.GetHeightForWidthBase(width);
1630 float Actor::GetWidthForHeightBase(float height)
1632 // Can be overridden in derived class
1633 return mSizer.GetWidthForHeightBase(height);
1636 float Actor::CalculateChildSizeBase(const Dali::Actor& child, Dimension::Type dimension)
1638 // Can be overridden in derived class
1639 return mSizer.CalculateChildSizeBase(child, dimension);
1642 bool Actor::RelayoutDependentOnChildrenBase(Dimension::Type dimension)
1644 return mSizer.RelayoutDependentOnChildrenBase(dimension);
1647 float Actor::CalculateChildSize(const Dali::Actor& child, Dimension::Type dimension)
1649 // Can be overridden in derived class
1650 return mSizer.CalculateChildSizeBase(child, dimension);
1653 float Actor::GetHeightForWidth(float width)
1655 // Can be overridden in derived class
1656 return mSizer.GetHeightForWidthBase(width);
1659 float Actor::GetWidthForHeight(float height)
1661 // Can be overridden in derived class
1662 return mSizer.GetWidthForHeightBase(height);
1665 float Actor::GetRelayoutSize(Dimension::Type dimension) const
1667 return mSizer.GetRelayoutSize(dimension);
1670 void Actor::NegotiateSize(const Vector2& allocatedSize, RelayoutContainer& container)
1672 mSizer.NegotiateSize(allocatedSize, container);
1675 void Actor::RelayoutRequest(Dimension::Type dimension)
1677 mSizer.RelayoutRequest(dimension);
1680 void Actor::SetMinimumSize(float size, Dimension::Type dimension)
1682 mSizer.SetMinimumSize(size, dimension);
1685 float Actor::GetMinimumSize(Dimension::Type dimension) const
1687 return mSizer.GetMinimumSize(dimension);
1690 void Actor::SetMaximumSize(float size, Dimension::Type dimension)
1692 mSizer.SetMaximumSize(size, dimension);
1695 float Actor::GetMaximumSize(Dimension::Type dimension) const
1697 return mSizer.GetMaximumSize(dimension);
1700 void Actor::SetVisibleInternal(bool visible, SendMessage::Type sendMessage)
1702 if(mVisible != visible)
1704 if(sendMessage == SendMessage::TRUE)
1706 // node is being used in a separate thread; queue a message to set the value & base value
1707 SceneGraph::NodePropertyMessage<bool>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible);
1709 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
1714 // Emit the signal on this actor and all its children
1715 mParentImpl.EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::SELF);
1719 void Actor::SetSiblingOrderOfChild(Actor& child, uint32_t order)
1721 mParentImpl.SetSiblingOrderOfChild(child, order);
1724 uint32_t Actor::GetSiblingOrderOfChild(const Actor& child) const
1726 return mParentImpl.GetSiblingOrderOfChild(child);
1729 void Actor::RaiseChild(Actor& child)
1731 mParentImpl.RaiseChild(child);
1734 void Actor::LowerChild(Actor& child)
1736 mParentImpl.LowerChild(child);
1739 void Actor::RaiseChildToTop(Actor& child)
1741 mParentImpl.RaiseChildToTop(child);
1744 void Actor::LowerChildToBottom(Actor& child)
1746 mParentImpl.LowerChildToBottom(child);
1749 void Actor::RaiseChildAbove(Actor& child, Actor& target)
1751 mParentImpl.RaiseChildAbove(child, target);
1754 void Actor::LowerChildBelow(Actor& child, Actor& target)
1756 mParentImpl.LowerChildBelow(child, target);
1759 void Actor::SetInheritLayoutDirection(bool inherit)
1761 if(mInheritLayoutDirection != inherit)
1763 mInheritLayoutDirection = inherit;
1765 if(inherit && mParent)
1767 mParentImpl.InheritLayoutDirectionRecursively(GetParent()->mLayoutDirection);
1772 void Actor::SetUpdateAreaHint(const Vector4& updateAreaHint)
1774 // node is being used in a separate thread; queue a message to set the value & base value
1775 SetUpdateAreaHintMessage(GetEventThreadServices(), GetNode(), updateAreaHint);
1778 } // namespace Internal