2 * Copyright (c) 2021 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>
27 #include <dali/public-api/common/constants.h>
28 #include <dali/public-api/common/dali-common.h>
29 #include <dali/public-api/math/radian.h>
30 #include <dali/public-api/math/vector2.h>
31 #include <dali/public-api/math/vector3.h>
32 #include <dali/public-api/object/type-registry.h>
34 #include <dali/devel-api/actors/actor-devel.h>
35 #include <dali/devel-api/actors/layer-devel.h>
36 #include <dali/devel-api/common/capabilities.h>
38 #include <dali/integration-api/debug.h>
40 #include <dali/internal/event/actors/actor-coords.h>
41 #include <dali/internal/event/actors/actor-parent.h>
42 #include <dali/internal/event/actors/actor-property-handler.h>
43 #include <dali/internal/event/actors/actor-relayouter.h>
44 #include <dali/internal/event/actors/camera-actor-impl.h>
45 #include <dali/internal/event/common/event-thread-services.h>
46 #include <dali/internal/event/common/property-helper.h>
47 #include <dali/internal/event/common/scene-impl.h>
48 #include <dali/internal/event/common/stage-impl.h>
49 #include <dali/internal/event/common/thread-local-storage.h>
50 #include <dali/internal/event/common/type-info-impl.h>
51 #include <dali/internal/event/events/actor-gesture-data.h>
52 #include <dali/internal/event/render-tasks/render-task-impl.h>
53 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
54 #include <dali/internal/event/rendering/renderer-impl.h>
55 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
56 #include <dali/internal/update/manager/update-manager.h>
57 #include <dali/internal/update/nodes/node-messages.h>
59 using Dali::Internal::SceneGraph::AnimatableProperty;
60 using Dali::Internal::SceneGraph::Node;
61 using Dali::Internal::SceneGraph::PropertyBase;
63 #if defined(DEBUG_ENABLED)
64 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER");
71 namespace // unnamed namespace
76 * We want to discourage the use of property strings (minimize string comparisons),
77 * particularly for the default properties.
78 * Name Type writable animatable constraint-input enum for index-checking
80 DALI_PROPERTY_TABLE_BEGIN
81 DALI_PROPERTY("parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN)
82 DALI_PROPERTY("parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X)
83 DALI_PROPERTY("parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y)
84 DALI_PROPERTY("parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z)
85 DALI_PROPERTY("anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT)
86 DALI_PROPERTY("anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X)
87 DALI_PROPERTY("anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y)
88 DALI_PROPERTY("anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z)
89 DALI_PROPERTY("size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE)
90 DALI_PROPERTY("sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH)
91 DALI_PROPERTY("sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT)
92 DALI_PROPERTY("sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH)
93 DALI_PROPERTY("position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION)
94 DALI_PROPERTY("positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X)
95 DALI_PROPERTY("positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y)
96 DALI_PROPERTY("positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z)
97 DALI_PROPERTY("worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION)
98 DALI_PROPERTY("worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X)
99 DALI_PROPERTY("worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y)
100 DALI_PROPERTY("worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z)
101 DALI_PROPERTY("orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION)
102 DALI_PROPERTY("worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION)
103 DALI_PROPERTY("scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE)
104 DALI_PROPERTY("scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X)
105 DALI_PROPERTY("scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y)
106 DALI_PROPERTY("scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z)
107 DALI_PROPERTY("worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE)
108 DALI_PROPERTY("visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE)
109 DALI_PROPERTY("color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR)
110 DALI_PROPERTY("colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED)
111 DALI_PROPERTY("colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN)
112 DALI_PROPERTY("colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE)
113 DALI_PROPERTY("colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA)
114 DALI_PROPERTY("worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR)
115 DALI_PROPERTY("worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX)
116 DALI_PROPERTY("name", STRING, true, false, false, Dali::Actor::Property::NAME)
117 DALI_PROPERTY("sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE)
118 DALI_PROPERTY("leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED)
119 DALI_PROPERTY("inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION)
120 DALI_PROPERTY("inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE)
121 DALI_PROPERTY("colorMode", INTEGER, true, false, false, Dali::Actor::Property::COLOR_MODE)
122 DALI_PROPERTY("drawMode", INTEGER, true, false, false, Dali::Actor::Property::DRAW_MODE)
123 DALI_PROPERTY("sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR)
124 DALI_PROPERTY("widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY)
125 DALI_PROPERTY("heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY)
126 DALI_PROPERTY("sizeScalePolicy", INTEGER, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY)
127 DALI_PROPERTY("widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT)
128 DALI_PROPERTY("heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH)
129 DALI_PROPERTY("padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING)
130 DALI_PROPERTY("minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE)
131 DALI_PROPERTY("maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE)
132 DALI_PROPERTY("inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION)
133 DALI_PROPERTY("clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE)
134 DALI_PROPERTY("layoutDirection", STRING, true, false, false, Dali::Actor::Property::LAYOUT_DIRECTION)
135 DALI_PROPERTY("inheritLayoutDirection", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION)
136 DALI_PROPERTY("opacity", FLOAT, true, true, true, Dali::Actor::Property::OPACITY)
137 DALI_PROPERTY("screenPosition", VECTOR2, false, false, false, Dali::Actor::Property::SCREEN_POSITION)
138 DALI_PROPERTY("positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::Actor::Property::POSITION_USES_ANCHOR_POINT)
139 DALI_PROPERTY("culled", BOOLEAN, false, false, true, Dali::Actor::Property::CULLED)
140 DALI_PROPERTY("id", INTEGER, false, false, false, Dali::Actor::Property::ID)
141 DALI_PROPERTY("hierarchyDepth", INTEGER, false, false, false, Dali::Actor::Property::HIERARCHY_DEPTH)
142 DALI_PROPERTY("isRoot", BOOLEAN, false, false, false, Dali::Actor::Property::IS_ROOT)
143 DALI_PROPERTY("isLayer", BOOLEAN, false, false, false, Dali::Actor::Property::IS_LAYER)
144 DALI_PROPERTY("connectedToScene", BOOLEAN, false, false, false, Dali::Actor::Property::CONNECTED_TO_SCENE)
145 DALI_PROPERTY("keyboardFocusable", BOOLEAN, true, false, false, Dali::Actor::Property::KEYBOARD_FOCUSABLE)
146 DALI_PROPERTY("siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER)
147 DALI_PROPERTY("updateSizeHint", VECTOR2, true, false, false, Dali::DevelActor::Property::UPDATE_SIZE_HINT)
148 DALI_PROPERTY("captureAllTouchAfterStart", BOOLEAN, true, false, false, Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START)
149 DALI_PROPERTY("touchAreaOffset", RECTANGLE, true, false, false, Dali::DevelActor::Property::TOUCH_AREA_OFFSET)
150 DALI_PROPERTY("blendEquation", INTEGER, true, false, false, Dali::DevelActor::Property::BLEND_EQUATION)
151 DALI_PROPERTY("touchFocusable", BOOLEAN, true, false, false, Dali::DevelActor::Property::TOUCH_FOCUSABLE)
152 DALI_PROPERTY("keyboardFocusableChildren", BOOLEAN, true, false, false, Dali::DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN)
153 DALI_PROPERTY_TABLE_END(DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties)
157 static constexpr std::string_view SIGNAL_HOVERED = "hovered";
158 static constexpr std::string_view SIGNAL_WHEEL_EVENT = "wheelEvent";
159 static constexpr std::string_view SIGNAL_ON_SCENE = "onScene";
160 static constexpr std::string_view SIGNAL_OFF_SCENE = "offScene";
161 static constexpr std::string_view SIGNAL_ON_RELAYOUT = "onRelayout";
162 static constexpr std::string_view SIGNAL_TOUCHED = "touched";
163 static constexpr std::string_view SIGNAL_VISIBILITY_CHANGED = "visibilityChanged";
164 static constexpr std::string_view SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
165 static constexpr std::string_view SIGNAL_CHILD_ADDED = "childAdded";
166 static constexpr std::string_view SIGNAL_CHILD_REMOVED = "childRemoved";
170 static constexpr std::string_view ACTION_SHOW = "show";
171 static constexpr std::string_view ACTION_HIDE = "hide";
173 BaseHandle CreateActor()
175 return Dali::Actor::New();
178 TypeRegistration mType(typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties);
180 SignalConnectorType signalConnector2(mType, std::string(SIGNAL_HOVERED), &Actor::DoConnectSignal);
181 SignalConnectorType signalConnector3(mType, std::string(SIGNAL_WHEEL_EVENT), &Actor::DoConnectSignal);
182 SignalConnectorType signalConnector4(mType, std::string(SIGNAL_ON_SCENE), &Actor::DoConnectSignal);
183 SignalConnectorType signalConnector5(mType, std::string(SIGNAL_OFF_SCENE), &Actor::DoConnectSignal);
184 SignalConnectorType signalConnector6(mType, std::string(SIGNAL_ON_RELAYOUT), &Actor::DoConnectSignal);
185 SignalConnectorType signalConnector7(mType, std::string(SIGNAL_TOUCHED), &Actor::DoConnectSignal);
186 SignalConnectorType signalConnector8(mType, std::string(SIGNAL_VISIBILITY_CHANGED), &Actor::DoConnectSignal);
187 SignalConnectorType signalConnector9(mType, std::string(SIGNAL_LAYOUT_DIRECTION_CHANGED), &Actor::DoConnectSignal);
188 SignalConnectorType signalConnector10(mType, std::string(SIGNAL_CHILD_ADDED), &Actor::DoConnectSignal);
189 SignalConnectorType signalConnector11(mType, std::string(SIGNAL_CHILD_REMOVED), &Actor::DoConnectSignal);
191 TypeAction a1(mType, std::string(ACTION_SHOW), &Actor::DoAction);
192 TypeAction a2(mType, std::string(ACTION_HIDE), &Actor::DoAction);
195 * @brief Extract a given dimension from a Vector2
197 * @param[in] values The values to extract from
198 * @param[in] dimension The dimension to extract
199 * @return Return the value for the dimension
201 constexpr float GetDimensionValue(const Vector2& values, Dimension::Type dimension)
205 case Dimension::WIDTH:
209 case Dimension::HEIGHT:
211 return values.height;
222 * @brief Extract a given dimension from a Vector3
224 * @param[in] values The values to extract from
225 * @param[in] dimension The dimension to extract
226 * @return Return the value for the dimension
228 float GetDimensionValue(const Vector3& values, Dimension::Type dimension)
230 return GetDimensionValue(values.GetVectorXY(), dimension);
233 /// Helper for emitting a signal
234 template<typename Signal, typename Event>
235 bool EmitConsumingSignal(Actor& actor, Signal& signal, const Event& event)
237 bool consumed = false;
241 Dali::Actor handle(&actor);
242 consumed = signal.Emit(handle, event);
248 /// Helper for emitting signals with multiple parameters
249 template<typename Signal, typename... Param>
250 void EmitSignal(Actor& actor, Signal& signal, Param... params)
254 Dali::Actor handle(&actor);
255 signal.Emit(handle, params...);
259 } // unnamed namespace
261 ActorPtr Actor::New()
263 // pass a reference to actor, actor does not own its node
264 ActorPtr actor(new Actor(BASIC, *CreateNode()));
266 // Second-phase construction
272 const SceneGraph::Node* Actor::CreateNode()
274 // create node. Nodes are owned by the update manager
275 SceneGraph::Node* node = SceneGraph::Node::New();
276 OwnerPointer<SceneGraph::Node> transferOwnership(node);
277 Internal::ThreadLocalStorage* tls = Internal::ThreadLocalStorage::GetInternal();
279 DALI_ASSERT_ALWAYS(tls && "ThreadLocalStorage is null");
281 AddNodeMessage(tls->GetUpdateManager(), transferOwnership);
286 void Actor::SetName(std::string_view name)
288 mName = ConstString(name);
290 // ATTENTION: string for debug purposes is not thread safe.
291 DALI_LOG_SET_OBJECT_STRING(const_cast<SceneGraph::Node*>(&GetNode()), mName.GetCString());
294 uint32_t Actor::GetId() const
296 return GetNode().GetId();
299 Dali::Layer Actor::GetLayer()
303 // Short-circuit for Layer derived actors
306 layer = Dali::Layer(static_cast<Dali::Internal::Layer*>(this)); // static cast as we trust the flag
309 // Find the immediate Layer parent
310 for(Actor* parent = GetParent(); !layer && parent != nullptr; parent = parent->GetParent())
312 if(parent->IsLayer())
314 layer = Dali::Layer(static_cast<Dali::Internal::Layer*>(parent)); // static cast as we trust the flag
321 void Actor::Unparent()
325 // Remove this actor from the parent. The remove will put a relayout request in for
326 // the parent if required
327 mParent->Remove(*this);
328 // mParent is now NULL!
332 void Actor::SetParentOrigin(const Vector3& origin)
334 // node is being used in a separate thread; queue a message to set the value & base value
335 SetParentOriginMessage(GetEventThreadServices(), GetNode(), origin);
337 // Cache for event-thread access
340 // not allocated, check if different from default
341 if(ParentOrigin::DEFAULT != origin)
343 mParentOrigin = new Vector3(origin);
348 // check if different from current costs more than just set
349 *mParentOrigin = origin;
353 const Vector3& Actor::GetCurrentParentOrigin() const
355 // Cached for event-thread access
356 return (mParentOrigin) ? *mParentOrigin : ParentOrigin::DEFAULT;
359 void Actor::SetAnchorPoint(const Vector3& anchor)
361 // node is being used in a separate thread; queue a message to set the value & base value
362 SetAnchorPointMessage(GetEventThreadServices(), GetNode(), anchor);
364 // Cache for event-thread access
367 // not allocated, check if different from default
368 if(AnchorPoint::DEFAULT != anchor)
370 mAnchorPoint = new Vector3(anchor);
375 // check if different from current costs more than just set
376 *mAnchorPoint = anchor;
380 const Vector3& Actor::GetCurrentAnchorPoint() const
382 // Cached for event-thread access
383 return (mAnchorPoint) ? *mAnchorPoint : AnchorPoint::DEFAULT;
386 void Actor::SetPosition(float x, float y)
388 SetPosition(Vector3(x, y, 0.0f));
391 void Actor::SetPosition(float x, float y, float z)
393 SetPosition(Vector3(x, y, z));
396 void Actor::SetPosition(const Vector3& position)
398 mTargetPosition = position;
400 // node is being used in a separate thread; queue a message to set the value & base value
401 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position);
404 void Actor::SetX(float x)
406 mTargetPosition.x = x;
408 // node is being used in a separate thread; queue a message to set the value & base value
409 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x);
412 void Actor::SetY(float y)
414 mTargetPosition.y = y;
416 // node is being used in a separate thread; queue a message to set the value & base value
417 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y);
420 void Actor::SetZ(float z)
422 mTargetPosition.z = z;
424 // node is being used in a separate thread; queue a message to set the value & base value
425 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z);
428 void Actor::TranslateBy(const Vector3& distance)
430 mTargetPosition += distance;
432 // node is being used in a separate thread; queue a message to set the value & base value
433 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance);
436 const Vector3& Actor::GetCurrentPosition() const
438 // node is being used in a separate thread; copy the value from the previous update
439 return GetNode().GetPosition(GetEventThreadServices().GetEventBufferIndex());
442 const Vector3& Actor::GetCurrentWorldPosition() const
444 // node is being used in a separate thread; copy the value from the previous update
445 return GetNode().GetWorldPosition(GetEventThreadServices().GetEventBufferIndex());
448 const Vector2 Actor::GetCurrentScreenPosition() const
450 if(mScene && OnScene())
452 Vector3 worldPosition = GetNode().GetWorldPosition(GetEventThreadServices().GetEventBufferIndex());
453 Vector3 cameraPosition = mScene->GetDefaultCameraActor().GetNode().GetWorldPosition(GetEventThreadServices().GetEventBufferIndex());
454 worldPosition -= cameraPosition;
456 Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale();
457 Vector2 halfSceneSize(mScene->GetSize() * 0.5f); // World position origin is center of scene
458 Vector3 halfActorSize(actorSize * 0.5f);
459 Vector3 anchorPointOffSet = halfActorSize - actorSize * (mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT);
461 return Vector2(halfSceneSize.width + worldPosition.x - anchorPointOffSet.x,
462 halfSceneSize.height + worldPosition.y - anchorPointOffSet.y);
465 return Vector2::ZERO;
468 void Actor::SetInheritPosition(bool inherit)
470 if(mInheritPosition != inherit)
472 // non animatable so keep local copy
473 mInheritPosition = inherit;
474 SetInheritPositionMessage(GetEventThreadServices(), GetNode(), inherit);
478 void Actor::SetOrientation(const Radian& angle, const Vector3& axis)
480 Vector3 normalizedAxis(axis.x, axis.y, axis.z);
481 normalizedAxis.Normalize();
483 Quaternion orientation(angle, normalizedAxis);
485 SetOrientation(orientation);
488 void Actor::SetOrientation(const Quaternion& orientation)
490 mTargetOrientation = orientation;
492 // node is being used in a separate thread; queue a message to set the value & base value
493 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation);
496 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
498 RotateBy(Quaternion(angle, axis));
501 void Actor::RotateBy(const Quaternion& relativeRotation)
503 mTargetOrientation *= Quaternion(relativeRotation);
505 // node is being used in a separate thread; queue a message to set the value & base value
506 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation);
509 const Quaternion& Actor::GetCurrentOrientation() const
511 // node is being used in a separate thread; copy the value from the previous update
512 return GetNode().GetOrientation(GetEventThreadServices().GetEventBufferIndex());
515 const Quaternion& Actor::GetCurrentWorldOrientation() const
517 // node is being used in a separate thread; copy the value from the previous update
518 return GetNode().GetWorldOrientation(GetEventThreadServices().GetEventBufferIndex());
521 void Actor::SetScale(float scale)
523 SetScale(Vector3(scale, scale, scale));
526 void Actor::SetScale(float x, float y, float z)
528 SetScale(Vector3(x, y, z));
531 void Actor::SetScale(const Vector3& scale)
533 mTargetScale = scale;
535 // node is being used in a separate thread; queue a message to set the value & base value
536 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale);
539 void Actor::SetScaleX(float x)
543 // node is being used in a separate thread; queue a message to set the value & base value
544 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x);
547 void Actor::SetScaleY(float y)
551 // node is being used in a separate thread; queue a message to set the value & base value
552 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y);
555 void Actor::SetScaleZ(float z)
559 // node is being used in a separate thread; queue a message to set the value & base value
560 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z);
563 void Actor::ScaleBy(const Vector3& relativeScale)
565 mTargetScale *= relativeScale;
567 // node is being used in a separate thread; queue a message to set the value & base value
568 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale);
571 const Vector3& Actor::GetCurrentScale() const
573 // node is being used in a separate thread; copy the value from the previous update
574 return GetNode().GetScale(GetEventThreadServices().GetEventBufferIndex());
577 const Vector3& Actor::GetCurrentWorldScale() const
579 // node is being used in a separate thread; copy the value from the previous update
580 return GetNode().GetWorldScale(GetEventThreadServices().GetEventBufferIndex());
583 void Actor::SetInheritScale(bool inherit)
585 if(mInheritScale != inherit)
587 // non animatable so keep local copy
588 mInheritScale = inherit;
589 // node is being used in a separate thread; queue a message to set the value
590 SetInheritScaleMessage(GetEventThreadServices(), GetNode(), inherit);
594 Matrix Actor::GetCurrentWorldMatrix() const
596 return GetNode().GetWorldMatrix(0);
599 void Actor::SetVisible(bool visible)
601 SetVisibleInternal(visible, SendMessage::TRUE);
604 bool Actor::IsVisible() const
606 // node is being used in a separate thread; copy the value from the previous update
607 return GetNode().IsVisible(GetEventThreadServices().GetEventBufferIndex());
610 void Actor::SetOpacity(float opacity)
612 mTargetColor.a = opacity;
614 // node is being used in a separate thread; queue a message to set the value & base value
615 SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeW, opacity);
617 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
620 float Actor::GetCurrentOpacity() const
622 // node is being used in a separate thread; copy the value from the previous update
623 return GetNode().GetOpacity(GetEventThreadServices().GetEventBufferIndex());
626 const Vector4& Actor::GetCurrentWorldColor() const
628 return GetNode().GetWorldColor(GetEventThreadServices().GetEventBufferIndex());
631 void Actor::SetColor(const Vector4& color)
633 mTargetColor = color;
635 // node is being used in a separate thread; queue a message to set the value & base value
636 SceneGraph::NodePropertyMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::Bake, color);
638 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
641 void Actor::SetColorRed(float red)
643 mTargetColor.r = red;
645 // node is being used in a separate thread; queue a message to set the value & base value
646 SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeX, red);
648 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
651 void Actor::SetColorGreen(float green)
653 mTargetColor.g = green;
655 // node is being used in a separate thread; queue a message to set the value & base value
656 SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeY, green);
658 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
661 void Actor::SetColorBlue(float blue)
663 mTargetColor.b = blue;
665 // node is being used in a separate thread; queue a message to set the value & base value
666 SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeZ, blue);
668 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
671 const Vector4& Actor::GetCurrentColor() const
673 // node is being used in a separate thread; copy the value from the previous update
674 return GetNode().GetColor(GetEventThreadServices().GetEventBufferIndex());
677 void Actor::SetInheritOrientation(bool inherit)
679 if(mInheritOrientation != inherit)
681 // non animatable so keep local copy
682 mInheritOrientation = inherit;
683 // node is being used in a separate thread; queue a message to set the value
684 SetInheritOrientationMessage(GetEventThreadServices(), GetNode(), inherit);
688 void Actor::SetSizeModeFactor(const Vector3& factor)
692 mRelayoutData->sizeModeFactor = factor;
695 const Vector3& Actor::GetSizeModeFactor() const
699 return mRelayoutData->sizeModeFactor;
702 return Relayouter::DEFAULT_SIZE_MODE_FACTOR;
705 void Actor::SetColorMode(ColorMode colorMode)
707 // non animatable so keep local copy
708 mColorMode = colorMode;
709 // node is being used in a separate thread; queue a message to set the value
710 SetColorModeMessage(GetEventThreadServices(), GetNode(), colorMode);
713 void Actor::SetSize(float width, float height)
715 SetSize(Vector2(width, height));
718 void Actor::SetSize(float width, float height, float depth)
720 SetSize(Vector3(width, height, depth));
723 void Actor::SetSize(const Vector2& size)
725 SetSize(Vector3(size.width, size.height, 0.f));
728 void Actor::SetSizeInternal(const Vector2& size)
730 SetSizeInternal(Vector3(size.width, size.height, 0.f));
733 void Actor::SetSize(const Vector3& size)
735 if(IsRelayoutEnabled() && !mRelayoutData->insideRelayout)
737 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
738 SetPreferredSize(size.GetVectorXY());
742 SetSizeInternal(size);
746 void Actor::SetSizeInternal(const Vector3& size)
748 // dont allow recursive loop
749 DALI_ASSERT_ALWAYS(!mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet");
750 // check that we have a node AND the new size width, height or depth is at least a little bit different from the old one
751 Vector3 currentSize = GetCurrentSize();
753 if((fabsf(mTargetSize.width - size.width) > Math::MACHINE_EPSILON_1) ||
754 (fabsf(mTargetSize.height - size.height) > Math::MACHINE_EPSILON_1) ||
755 (fabsf(mTargetSize.depth - size.depth) > Math::MACHINE_EPSILON_1) ||
756 (fabsf(mTargetSize.width - currentSize.width) > Math::MACHINE_EPSILON_1) ||
757 (fabsf(mTargetSize.height - currentSize.height) > Math::MACHINE_EPSILON_1) ||
758 (fabsf(mTargetSize.depth - currentSize.depth) > Math::MACHINE_EPSILON_1))
762 // node is being used in a separate thread; queue a message to set the value & base value
763 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize);
765 // Notification for derived classes
766 mInsideOnSizeSet = true;
767 OnSizeSet(mTargetSize);
768 mInsideOnSizeSet = false;
770 // Raise a relayout request if the flag is not locked
771 if(mRelayoutData && !mRelayoutData->insideRelayout)
778 void Actor::SetWidth(float width)
780 if(IsRelayoutEnabled() && !mRelayoutData->insideRelayout)
782 SetResizePolicy(ResizePolicy::FIXED, Dimension::WIDTH);
783 mRelayoutData->preferredSize.width = width;
787 mTargetSize.width = width;
789 // node is being used in a separate thread; queue a message to set the value & base value
790 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width);
793 mUseAnimatedSize &= ~AnimatedSizeFlag::WIDTH;
798 void Actor::SetHeight(float height)
800 if(IsRelayoutEnabled() && !mRelayoutData->insideRelayout)
802 SetResizePolicy(ResizePolicy::FIXED, Dimension::HEIGHT);
803 mRelayoutData->preferredSize.height = height;
807 mTargetSize.height = height;
809 // node is being used in a separate thread; queue a message to set the value & base value
810 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height);
813 mUseAnimatedSize &= ~AnimatedSizeFlag::HEIGHT;
818 void Actor::SetDepth(float depth)
820 mTargetSize.depth = depth;
822 mUseAnimatedSize &= ~AnimatedSizeFlag::DEPTH;
824 // node is being used in a separate thread; queue a message to set the value & base value
825 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth);
828 Vector3 Actor::GetTargetSize() const
830 Vector3 size = mTargetSize;
832 if(mUseAnimatedSize & AnimatedSizeFlag::WIDTH)
834 // Should return animated size if size is animated
835 size.width = mAnimatedSize.width;
839 // Should return preferred size if size is fixed as set by SetSize
840 if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::FIXED)
842 size.width = GetPreferredSize().width;
846 if(mUseAnimatedSize & AnimatedSizeFlag::HEIGHT)
848 size.height = mAnimatedSize.height;
852 if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::FIXED)
854 size.height = GetPreferredSize().height;
858 if(mUseAnimatedSize & AnimatedSizeFlag::DEPTH)
860 size.depth = mAnimatedSize.depth;
866 const Vector3& Actor::GetCurrentSize() const
868 // node is being used in a separate thread; copy the value from the previous update
869 return GetNode().GetSize(GetEventThreadServices().GetEventBufferIndex());
872 Vector3 Actor::GetNaturalSize() const
874 // It is up to deriving classes to return the appropriate natural size
875 return Vector3(0.0f, 0.0f, 0.0f);
878 void Actor::SetResizePolicy(ResizePolicy::Type policy, Dimension::Type dimension)
880 EnsureRelayouter().SetResizePolicy(policy, dimension, mTargetSize);
882 OnSetResizePolicy(policy, dimension);
884 // Trigger relayout on this control
888 ResizePolicy::Type Actor::GetResizePolicy(Dimension::Type dimension) const
892 return mRelayoutData->GetResizePolicy(dimension);
895 return ResizePolicy::DEFAULT;
898 void Actor::SetSizeScalePolicy(SizeScalePolicy::Type policy)
902 mRelayoutData->sizeSetPolicy = policy;
904 // Trigger relayout on this control
908 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
912 return mRelayoutData->sizeSetPolicy;
915 return Relayouter::DEFAULT_SIZE_SCALE_POLICY;
918 void Actor::SetDimensionDependency(Dimension::Type dimension, Dimension::Type dependency)
920 EnsureRelayouter().SetDimensionDependency(dimension, dependency);
923 Dimension::Type Actor::GetDimensionDependency(Dimension::Type dimension) const
927 return mRelayoutData->GetDimensionDependency(dimension);
930 return Dimension::ALL_DIMENSIONS; // Default
933 void Actor::SetRelayoutEnabled(bool relayoutEnabled)
935 // If relayout data has not been allocated yet and the client is requesting
936 // to disable it, do nothing
937 if(mRelayoutData || relayoutEnabled)
941 DALI_ASSERT_DEBUG(mRelayoutData && "mRelayoutData not created");
943 mRelayoutData->relayoutEnabled = relayoutEnabled;
947 bool Actor::IsRelayoutEnabled() const
949 // Assume that if relayout data has not been allocated yet then
950 // relayout is disabled
951 return mRelayoutData && mRelayoutData->relayoutEnabled;
954 void Actor::SetLayoutDirty(bool dirty, Dimension::Type dimension)
956 EnsureRelayouter().SetLayoutDirty(dirty, dimension);
959 bool Actor::IsLayoutDirty(Dimension::Type dimension) const
961 return mRelayoutData && mRelayoutData->IsLayoutDirty(dimension);
964 bool Actor::RelayoutPossible(Dimension::Type dimension) const
966 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty(dimension);
969 bool Actor::RelayoutRequired(Dimension::Type dimension) const
971 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty(dimension);
974 uint32_t Actor::AddRenderer(Renderer& renderer)
978 mRenderers = new RendererContainer(GetEventThreadServices());
980 return mRenderers->Add(GetNode(), renderer, mIsBlendEquationSet, mBlendEquation);
983 uint32_t Actor::GetRendererCount() const
985 return mRenderers ? mRenderers->GetCount() : 0u;
988 RendererPtr Actor::GetRendererAt(uint32_t index)
990 return mRenderers ? mRenderers->GetRendererAt(index) : nullptr;
993 void Actor::RemoveRenderer(Renderer& renderer)
997 mRenderers->Remove(GetNode(), renderer);
1001 void Actor::RemoveRenderer(uint32_t index)
1005 mRenderers->Remove(GetNode(), index);
1009 void Actor::SetBlendEquation(DevelBlendEquation::Type blendEquation)
1011 if(Dali::Capabilities::IsBlendEquationSupported(blendEquation))
1013 if(mBlendEquation != blendEquation)
1015 mBlendEquation = blendEquation;
1018 mRenderers->SetBlending(blendEquation);
1021 mIsBlendEquationSet = true;
1025 DALI_LOG_ERROR("Invalid blend equation is entered.\n");
1029 DevelBlendEquation::Type Actor::GetBlendEquation() const
1031 return mBlendEquation;
1034 void Actor::SetTransparent(bool transparent)
1036 SetTransparentMessage(GetEventThreadServices(), GetNode(), transparent);
1039 bool Actor::IsTransparent() const
1041 return GetNode().IsTransparent();
1044 void Actor::SetDrawMode(DrawMode::Type drawMode)
1046 // this flag is not animatable so keep the value
1047 mDrawMode = drawMode;
1049 // node is being used in a separate thread; queue a message to set the value
1050 SetDrawModeMessage(GetEventThreadServices(), GetNode(), drawMode);
1053 bool Actor::ScreenToLocal(float& localX, float& localY, float screenX, float screenY) const
1055 return mScene && OnScene() && ConvertScreenToLocalRenderTaskList(mScene->GetRenderTaskList(), GetNode().GetWorldMatrix(0), GetCurrentSize(), localX, localY, screenX, screenY);
1058 bool Actor::ScreenToLocal(const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY) const
1060 return OnScene() && ConvertScreenToLocalRenderTask(renderTask, GetNode().GetWorldMatrix(0), GetCurrentSize(), localX, localY, screenX, screenY);
1063 bool Actor::ScreenToLocal(const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY) const
1065 return OnScene() && ConvertScreenToLocal(viewMatrix, projectionMatrix, GetNode().GetWorldMatrix(0), GetCurrentSize(), viewport, localX, localY, screenX, screenY);
1068 ActorGestureData& Actor::GetGestureData()
1070 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1071 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1072 if(nullptr == mGestureData)
1074 mGestureData = new ActorGestureData;
1076 return *mGestureData;
1079 bool Actor::IsGestureRequired(GestureType::Value type) const
1081 return mGestureData && mGestureData->IsGestureRequired(type);
1084 bool Actor::EmitInterceptTouchEventSignal(const Dali::TouchEvent& touch)
1086 return EmitConsumingSignal(*this, mInterceptTouchedSignal, touch);
1089 bool Actor::EmitTouchEventSignal(const Dali::TouchEvent& touch)
1091 return EmitConsumingSignal(*this, mTouchedSignal, touch);
1094 bool Actor::EmitHoverEventSignal(const Dali::HoverEvent& event)
1096 return EmitConsumingSignal(*this, mHoveredSignal, event);
1099 bool Actor::EmitWheelEventSignal(const Dali::WheelEvent& event)
1101 return EmitConsumingSignal(*this, mWheelEventSignal, event);
1104 void Actor::EmitVisibilityChangedSignal(bool visible, DevelActor::VisibilityChange::Type type)
1106 EmitSignal(*this, mVisibilityChangedSignal, visible, type);
1109 void Actor::EmitLayoutDirectionChangedSignal(LayoutDirection::Type type)
1111 EmitSignal(*this, mLayoutDirectionChangedSignal, type);
1114 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
1116 return mParentImpl.ChildAddedSignal();
1119 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
1121 return mParentImpl.ChildRemovedSignal();
1124 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
1126 return mParentImpl.ChildOrderChangedSignal();
1129 bool Actor::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
1131 bool connected(true);
1132 Actor* actor = static_cast<Actor*>(object); // TypeRegistry guarantees that this is the correct type.
1134 std::string_view name(signalName);
1136 if(name == SIGNAL_HOVERED)
1138 actor->HoveredSignal().Connect(tracker, functor);
1140 else if(signalName == SIGNAL_WHEEL_EVENT)
1142 actor->WheelEventSignal().Connect(tracker, functor);
1144 else if(name == SIGNAL_ON_SCENE)
1146 actor->OnSceneSignal().Connect(tracker, functor);
1148 else if(name == SIGNAL_OFF_SCENE)
1150 actor->OffSceneSignal().Connect(tracker, functor);
1152 else if(name == SIGNAL_ON_RELAYOUT)
1154 actor->OnRelayoutSignal().Connect(tracker, functor);
1156 else if(name == SIGNAL_TOUCHED)
1158 actor->TouchedSignal().Connect(tracker, functor);
1160 else if(name == SIGNAL_VISIBILITY_CHANGED)
1162 actor->VisibilityChangedSignal().Connect(tracker, functor);
1164 else if(name == SIGNAL_LAYOUT_DIRECTION_CHANGED)
1166 actor->LayoutDirectionChangedSignal().Connect(tracker, functor);
1168 else if(name == SIGNAL_CHILD_ADDED)
1170 actor->ChildAddedSignal().Connect(tracker, functor);
1172 else if(name == SIGNAL_CHILD_REMOVED)
1174 actor->ChildRemovedSignal().Connect(tracker, functor);
1178 // signalName does not match any signal
1185 Actor::Actor(DerivedType derivedType, const SceneGraph::Node& node)
1190 mRenderers(nullptr),
1191 mParentOrigin(nullptr),
1192 mAnchorPoint(nullptr),
1193 mRelayoutData(nullptr),
1194 mGestureData(nullptr),
1195 mInterceptTouchedSignal(),
1198 mWheelEventSignal(),
1201 mOnRelayoutSignal(),
1202 mVisibilityChangedSignal(),
1203 mLayoutDirectionChangedSignal(),
1204 mTargetOrientation(Quaternion::IDENTITY),
1205 mTargetColor(Color::WHITE),
1206 mTargetSize(Vector3::ZERO),
1207 mTargetPosition(Vector3::ZERO),
1208 mTargetScale(Vector3::ONE),
1209 mAnimatedSize(Vector3::ZERO),
1210 mTouchAreaOffset(0, 0, 0, 0),
1214 mUseAnimatedSize(AnimatedSizeFlag::CLEAR),
1215 mIsRoot(ROOT_LAYER == derivedType),
1216 mIsLayer(LAYER == derivedType || ROOT_LAYER == derivedType),
1219 mLeaveRequired(false),
1220 mKeyboardFocusable(false),
1221 mKeyboardFocusableChildren(true),
1222 mTouchFocusable(false),
1223 mOnSceneSignalled(false),
1224 mInsideOnSizeSet(false),
1225 mInheritPosition(true),
1226 mInheritOrientation(true),
1227 mInheritScale(true),
1228 mPositionUsesAnchorPoint(true),
1230 mInheritLayoutDirection(true),
1231 mCaptureAllTouchAfterStart(false),
1232 mIsBlendEquationSet(false),
1233 mNeedGesturePropagation(false),
1234 mLayoutDirection(LayoutDirection::LEFT_TO_RIGHT),
1235 mDrawMode(DrawMode::NORMAL),
1236 mColorMode(Node::DEFAULT_COLOR_MODE),
1237 mClippingMode(ClippingMode::DISABLED),
1238 mBlendEquation(DevelBlendEquation::ADD)
1242 void Actor::Initialize()
1246 GetEventThreadServices().RegisterObject(this);
1251 // Remove mParent pointers from children even if we're destroying core,
1252 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
1256 // Guard to allow handle destruction after Core has been destroyed
1257 if(EventThreadServices::IsCoreRunning())
1259 // Root layer will destroy its node in its own destructor
1262 DestroyNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
1264 GetEventThreadServices().UnregisterObject(this);
1268 // Cleanup optional gesture data
1269 delete mGestureData;
1271 // Cleanup optional parent origin and anchor
1272 delete mParentOrigin;
1273 delete mAnchorPoint;
1275 // Delete optional relayout data
1276 delete mRelayoutData;
1279 void Actor::Add(Actor& child, bool notify)
1281 mParentImpl.Add(child, notify);
1284 void Actor::Remove(Actor& child, bool notify)
1286 mParentImpl.Remove(child, notify);
1289 void Actor::SwitchParent(Actor& newParent)
1291 if(this == &newParent)
1293 DALI_LOG_ERROR("Cannot add actor to itself");
1297 if(!this->OnScene() || !newParent.OnScene())
1299 DALI_LOG_ERROR("Both of current parent and new parent must be on Scene");
1303 newParent.Add(*this, false);
1306 uint32_t Actor::GetChildCount() const
1308 return mParentImpl.GetChildCount();
1311 ActorPtr Actor::GetChildAt(uint32_t index) const
1313 return mParentImpl.GetChildAt(index);
1316 ActorContainer& Actor::GetChildrenInternal()
1318 return mParentImpl.GetChildrenInternal();
1321 ActorPtr Actor::FindChildByName(ConstString actorName)
1323 return mParentImpl.FindChildByName(actorName);
1326 ActorPtr Actor::FindChildById(const uint32_t id)
1328 return mParentImpl.FindChildById(id);
1331 void Actor::UnparentChildren()
1333 mParentImpl.UnparentChildren();
1336 void Actor::ConnectToScene(uint32_t parentDepth, bool notify)
1338 // This container is used instead of walking the Actor hierarchy.
1339 // It protects us when the Actor hierarchy is modified during OnSceneConnectionExternal callbacks.
1340 ActorContainer connectionList;
1344 mScene->RequestRebuildDepthTree();
1347 // This stage is atomic i.e. not interrupted by user callbacks.
1348 RecursiveConnectToScene(connectionList, parentDepth + 1);
1350 // Notify applications about the newly connected actors.
1351 for(const auto& actor : connectionList)
1353 actor->NotifyStageConnection(notify);
1359 void Actor::RecursiveConnectToScene(ActorContainer& connectionList, uint32_t depth)
1361 DALI_ASSERT_ALWAYS(!OnScene());
1364 mDepth = static_cast<uint16_t>(depth); // overflow ignored, not expected in practice
1366 ConnectToSceneGraph();
1368 // Notification for internal derived classes
1369 OnSceneConnectionInternal();
1371 // This stage is atomic; avoid emitting callbacks until all Actors are connected
1372 connectionList.push_back(ActorPtr(this));
1374 // Recursively connect children
1375 if(GetChildCount() > 0)
1377 for(const auto& child : mParentImpl.GetChildrenInternal())
1379 child->SetScene(*mScene);
1380 child->RecursiveConnectToScene(connectionList, depth + 1);
1386 * This method is called when the Actor is connected to the Stage.
1387 * The parent must have added its Node to the scene-graph.
1388 * The child must connect its Node to the parent's Node.
1389 * This is recursive; the child calls ConnectToScene() for its children.
1391 void Actor::ConnectToSceneGraph()
1393 DALI_ASSERT_DEBUG(mParent != NULL);
1395 // Reparent Node in next Update
1396 ConnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetParent()->GetNode(), GetNode());
1398 // Request relayout on all actors that are added to the scenegraph
1401 // Notification for Object::Observers
1405 void Actor::NotifyStageConnection(bool notify)
1407 // Actors can be removed (in a callback), before the on-stage stage is reported.
1408 // The actor may also have been reparented, in which case mOnSceneSignalled will be true.
1409 if(OnScene() && !mOnSceneSignalled)
1413 // Notification for external (CustomActor) derived classes
1414 OnSceneConnectionExternal(mDepth);
1416 if(!mOnSceneSignal.Empty())
1418 Dali::Actor handle(this);
1419 mOnSceneSignal.Emit(handle);
1423 // Guard against Remove during callbacks
1426 mOnSceneSignalled = true; // signal required next time Actor is removed
1431 void Actor::DisconnectFromStage(bool notify)
1433 // This container is used instead of walking the Actor hierachy.
1434 // It protects us when the Actor hierachy is modified during OnSceneDisconnectionExternal callbacks.
1435 ActorContainer disconnectionList;
1439 mScene->RequestRebuildDepthTree();
1442 // This stage is atomic i.e. not interrupted by user callbacks
1443 RecursiveDisconnectFromStage(disconnectionList);
1445 // Notify applications about the newly disconnected actors.
1446 for(const auto& actor : disconnectionList)
1448 actor->NotifyStageDisconnection(notify);
1452 void Actor::RecursiveDisconnectFromStage(ActorContainer& disconnectionList)
1454 // need to change state first so that internals relying on IsOnScene() inside OnSceneDisconnectionInternal() get the correct value
1457 // Recursively disconnect children
1458 if(GetChildCount() > 0)
1460 for(const auto& child : mParentImpl.GetChildrenInternal())
1462 child->RecursiveDisconnectFromStage(disconnectionList);
1466 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
1467 disconnectionList.push_back(ActorPtr(this));
1469 // Notification for internal derived classes
1470 OnSceneDisconnectionInternal();
1472 DisconnectFromSceneGraph();
1476 * This method is called by an actor or its parent, before a node removal message is sent.
1477 * This is recursive; the child calls DisconnectFromStage() for its children.
1479 void Actor::DisconnectFromSceneGraph()
1481 // Notification for Object::Observers
1482 OnSceneObjectRemove();
1485 void Actor::NotifyStageDisconnection(bool notify)
1487 // Actors can be added (in a callback), before the off-stage state is reported.
1488 // Also if the actor was added & removed before mOnSceneSignalled was set, then we don't notify here.
1489 // only do this step if there is a stage, i.e. Core is not being shut down
1490 if(EventThreadServices::IsCoreRunning() && !OnScene() && mOnSceneSignalled)
1494 // Notification for external (CustomeActor) derived classes
1495 OnSceneDisconnectionExternal();
1497 if(!mOffSceneSignal.Empty())
1499 Dali::Actor handle(this);
1500 mOffSceneSignal.Emit(handle);
1504 // Guard against Add during callbacks
1507 mOnSceneSignalled = false; // signal required next time Actor is added
1512 bool Actor::IsNodeConnected() const
1514 bool connected(false);
1518 if(IsRoot() || GetNode().GetParent())
1527 // This method initiates traversal of the actor tree using depth-first
1528 // traversal to set a depth index based on traversal order. It sends a
1529 // single message to update manager to update all the actor's nodes in
1530 // this tree with the depth index. The sceneGraphNodeDepths vector's
1531 // elements are ordered by depth, and could be used to reduce sorting
1532 // in the update thread.
1533 void Actor::RebuildDepthTree()
1535 DALI_LOG_TIMER_START(depthTimer);
1537 // Vector of scene-graph nodes and their depths to send to UpdateManager
1538 // in a single message
1539 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths(new SceneGraph::NodeDepths());
1541 int32_t depthIndex = 1;
1542 DepthTraverseActorTree(sceneGraphNodeDepths, depthIndex);
1544 SetDepthIndicesMessage(GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths);
1545 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
1548 void Actor::DepthTraverseActorTree(OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int32_t& depthIndex)
1550 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
1551 sceneGraphNodeDepths->Add(const_cast<SceneGraph::Node*>(&GetNode()), mSortedDepth);
1553 // Create/add to children of this node
1554 if(GetChildCount() > 0)
1556 for(const auto& child : mParentImpl.GetChildrenInternal())
1558 Actor* childActor = child.Get();
1560 childActor->DepthTraverseActorTree(sceneGraphNodeDepths, depthIndex);
1565 void Actor::SetDefaultProperty(Property::Index index, const Property::Value& property)
1567 PropertyHandler::SetDefaultProperty(*this, index, property);
1570 // TODO: This method needs to be removed
1571 void Actor::SetSceneGraphProperty(Property::Index index, const PropertyMetadata& entry, const Property::Value& value)
1573 PropertyHandler::SetSceneGraphProperty(index, entry, value, GetEventThreadServices(), GetNode());
1576 Property::Value Actor::GetDefaultProperty(Property::Index index) const
1578 Property::Value value;
1580 if(!GetCachedPropertyValue(index, value))
1582 // If property value is not stored in the event-side, then it must be a scene-graph only property
1583 GetCurrentPropertyValue(index, value);
1589 Property::Value Actor::GetDefaultPropertyCurrentValue(Property::Index index) const
1591 Property::Value value;
1593 if(!GetCurrentPropertyValue(index, value))
1595 // If unable to retrieve scene-graph property value, then it must be an event-side only property
1596 GetCachedPropertyValue(index, value);
1602 void Actor::OnNotifyDefaultPropertyAnimation(Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType)
1604 PropertyHandler::OnNotifyDefaultPropertyAnimation(*this, animation, index, value, animationType);
1607 const PropertyBase* Actor::GetSceneObjectAnimatableProperty(Property::Index index) const
1609 const PropertyBase* property = PropertyHandler::GetSceneObjectAnimatableProperty(index, GetNode());
1612 // not our property, ask base
1613 property = Object::GetSceneObjectAnimatableProperty(index);
1619 const PropertyInputImpl* Actor::GetSceneObjectInputProperty(Property::Index index) const
1621 const PropertyInputImpl* property = PropertyHandler::GetSceneObjectInputProperty(index, GetNode());
1624 // reuse animatable property getter as animatable properties are inputs as well
1625 // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
1626 property = GetSceneObjectAnimatableProperty(index);
1632 int32_t Actor::GetPropertyComponentIndex(Property::Index index) const
1634 int32_t componentIndex = PropertyHandler::GetPropertyComponentIndex(index);
1635 if(Property::INVALID_COMPONENT_INDEX == componentIndex)
1638 componentIndex = Object::GetPropertyComponentIndex(index);
1641 return componentIndex;
1644 const SceneGraph::Node& Actor::GetNode() const
1646 return *static_cast<const SceneGraph::Node*>(mUpdateObject);
1653 mParent->RaiseChild(*this);
1657 DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1665 mParent->LowerChild(*this);
1669 DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1673 void Actor::RaiseToTop()
1677 mParent->RaiseChildToTop(*this);
1681 DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1685 void Actor::LowerToBottom()
1689 mParent->LowerChildToBottom(*this);
1693 DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1697 void Actor::RaiseAbove(Internal::Actor& target)
1701 mParent->RaiseChildAbove(*this, target);
1705 DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1709 void Actor::LowerBelow(Internal::Actor& target)
1713 mParent->LowerChildBelow(*this, target);
1717 DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1721 void Actor::SetParent(ActorParent* parent, bool notify)
1725 DALI_ASSERT_ALWAYS(!mParent && "Actor cannot have 2 parents");
1728 Actor* parentActor = static_cast<Actor*>(parent);
1729 mScene = parentActor->mScene;
1731 if(EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
1732 parentActor->OnScene())
1734 // Instruct each actor to create a corresponding node in the scene graph
1735 ConnectToScene(parentActor->GetHierarchyDepth(), notify);
1738 // Resolve the name and index for the child properties if any
1739 ResolveChildProperties();
1741 else // parent being set to NULL
1743 DALI_ASSERT_ALWAYS(mParent != nullptr && "Actor should have a parent");
1747 if(EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
1750 // Disconnect the Node & its children from the scene-graph.
1751 DisconnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
1753 // Instruct each actor to discard pointers to the scene-graph
1754 DisconnectFromStage(notify);
1761 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */)
1764 Actor* actor = dynamic_cast<Actor*>(object);
1768 std::string_view name(actionName);
1769 if(name == ACTION_SHOW)
1771 actor->SetVisible(true);
1774 else if(name == ACTION_HIDE)
1776 actor->SetVisible(false);
1784 Rect<> Actor::CalculateScreenExtents() const
1786 auto screenPosition = GetCurrentScreenPosition();
1787 Vector3 size = GetCurrentSize() * GetCurrentWorldScale();
1788 Vector3 anchorPointOffSet = size * (mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT);
1789 Vector2 position = Vector2(screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y);
1790 return {position.x, position.y, size.x, size.y};
1793 void Actor::SetNeedGesturePropagation(bool propagation)
1795 mNeedGesturePropagation = propagation;
1798 bool Actor::NeedGesturePropagation()
1800 return mNeedGesturePropagation;
1803 bool Actor::GetCachedPropertyValue(Property::Index index, Property::Value& value) const
1805 return PropertyHandler::GetCachedPropertyValue(*this, index, value);
1808 bool Actor::GetCurrentPropertyValue(Property::Index index, Property::Value& value) const
1810 return PropertyHandler::GetCurrentPropertyValue(*this, index, value);
1813 Actor::Relayouter& Actor::EnsureRelayouter()
1815 // Assign relayouter
1818 mRelayoutData = new Relayouter();
1821 return *mRelayoutData;
1824 bool Actor::RelayoutDependentOnParent(Dimension::Type dimension)
1826 // Check if actor is dependent on parent
1827 for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
1829 if((dimension & (1 << i)))
1831 const ResizePolicy::Type resizePolicy = GetResizePolicy(static_cast<Dimension::Type>(1 << i));
1832 if(resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT)
1842 bool Actor::RelayoutDependentOnChildren(Dimension::Type dimension)
1844 // Check if actor is dependent on children
1845 for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
1847 if((dimension & (1 << i)))
1849 const ResizePolicy::Type resizePolicy = GetResizePolicy(static_cast<Dimension::Type>(1 << i));
1850 switch(resizePolicy)
1852 case ResizePolicy::FIT_TO_CHILDREN:
1853 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
1869 bool Actor::RelayoutDependentOnChildrenBase(Dimension::Type dimension)
1871 return Actor::RelayoutDependentOnChildren(dimension);
1874 bool Actor::RelayoutDependentOnDimension(Dimension::Type dimension, Dimension::Type dependentDimension)
1876 // Check each possible dimension and see if it is dependent on the input one
1877 for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
1879 if(dimension & (1 << i))
1881 return mRelayoutData->resizePolicies[i] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[i] == dependentDimension;
1888 void Actor::SetNegotiatedDimension(float negotiatedDimension, Dimension::Type dimension)
1890 for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
1892 if(dimension & (1 << i))
1894 mRelayoutData->negotiatedDimensions[i] = negotiatedDimension;
1899 float Actor::GetNegotiatedDimension(Dimension::Type dimension) const
1901 // If more than one dimension is requested, just return the first one found
1902 for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
1904 if((dimension & (1 << i)))
1906 return mRelayoutData->negotiatedDimensions[i];
1910 return 0.0f; // Default
1913 void Actor::SetPadding(const Vector2& padding, Dimension::Type dimension)
1915 EnsureRelayouter().SetPadding(padding, dimension);
1918 Vector2 Actor::GetPadding(Dimension::Type dimension) const
1922 // If more than one dimension is requested, just return the first one found
1923 for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
1925 if((dimension & (1 << i)))
1927 return mRelayoutData->dimensionPadding[i];
1932 return Relayouter::DEFAULT_DIMENSION_PADDING;
1935 void Actor::SetLayoutNegotiated(bool negotiated, Dimension::Type dimension)
1937 EnsureRelayouter().SetLayoutNegotiated(negotiated, dimension);
1940 bool Actor::IsLayoutNegotiated(Dimension::Type dimension) const
1942 return mRelayoutData && mRelayoutData->IsLayoutNegotiated(dimension);
1945 float Actor::GetHeightForWidthBase(float width)
1947 float height = 0.0f;
1949 const Vector3 naturalSize = GetNaturalSize();
1950 if(naturalSize.width > 0.0f)
1952 height = naturalSize.height * width / naturalSize.width;
1954 else // we treat 0 as 1:1 aspect ratio
1962 float Actor::GetWidthForHeightBase(float height)
1966 const Vector3 naturalSize = GetNaturalSize();
1967 if(naturalSize.height > 0.0f)
1969 width = naturalSize.width * height / naturalSize.height;
1971 else // we treat 0 as 1:1 aspect ratio
1979 float Actor::CalculateChildSizeBase(const Dali::Actor& child, Dimension::Type dimension)
1981 // Fill to parent, taking size mode factor into account
1982 switch(child.GetResizePolicy(dimension))
1984 case ResizePolicy::FILL_TO_PARENT:
1986 return GetLatestSize(dimension);
1989 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
1991 return GetLatestSize(dimension) * GetDimensionValue(child.GetProperty<Vector3>(Dali::Actor::Property::SIZE_MODE_FACTOR), dimension);
1994 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
1996 return GetLatestSize(dimension) + GetDimensionValue(child.GetProperty<Vector3>(Dali::Actor::Property::SIZE_MODE_FACTOR), dimension);
2001 return GetLatestSize(dimension);
2006 float Actor::CalculateChildSize(const Dali::Actor& child, Dimension::Type dimension)
2008 // Can be overridden in derived class
2009 return CalculateChildSizeBase(child, dimension);
2012 float Actor::GetHeightForWidth(float width)
2014 // Can be overridden in derived class
2015 return GetHeightForWidthBase(width);
2018 float Actor::GetWidthForHeight(float height)
2020 // Can be overridden in derived class
2021 return GetWidthForHeightBase(height);
2024 float Actor::GetLatestSize(Dimension::Type dimension) const
2026 return IsLayoutNegotiated(dimension) ? GetNegotiatedDimension(dimension) : GetSize(dimension);
2029 float Actor::GetRelayoutSize(Dimension::Type dimension) const
2031 Vector2 padding = GetPadding(dimension);
2033 return GetLatestSize(dimension) + padding.x + padding.y;
2036 float Actor::NegotiateFromParent(Dimension::Type dimension)
2038 Actor* parent = GetParent();
2041 Vector2 padding(GetPadding(dimension));
2042 Vector2 parentPadding(parent->GetPadding(dimension));
2043 return parent->CalculateChildSize(Dali::Actor(this), dimension) - parentPadding.x - parentPadding.y - padding.x - padding.y;
2049 float Actor::NegotiateFromChildren(Dimension::Type dimension)
2051 float maxDimensionPoint = 0.0f;
2053 for(uint32_t i = 0, count = GetChildCount(); i < count; ++i)
2055 ActorPtr child = GetChildAt(i);
2057 if(!child->RelayoutDependentOnParent(dimension))
2059 // Calculate the min and max points that the children range across
2060 float childPosition = GetDimensionValue(child->GetTargetPosition(), dimension);
2061 float dimensionSize = child->GetRelayoutSize(dimension);
2062 maxDimensionPoint = std::max(maxDimensionPoint, childPosition + dimensionSize);
2066 return maxDimensionPoint;
2069 float Actor::GetSize(Dimension::Type dimension) const
2071 return GetDimensionValue(mTargetSize, dimension);
2074 float Actor::GetNaturalSize(Dimension::Type dimension) const
2076 return GetDimensionValue(GetNaturalSize(), dimension);
2079 float Actor::CalculateSize(Dimension::Type dimension, const Vector2& maximumSize)
2081 switch(GetResizePolicy(dimension))
2083 case ResizePolicy::USE_NATURAL_SIZE:
2085 return GetNaturalSize(dimension);
2088 case ResizePolicy::FIXED:
2090 return GetDimensionValue(GetPreferredSize(), dimension);
2093 case ResizePolicy::USE_ASSIGNED_SIZE:
2095 return GetDimensionValue(maximumSize, dimension);
2098 case ResizePolicy::FILL_TO_PARENT:
2099 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
2100 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
2102 return NegotiateFromParent(dimension);
2105 case ResizePolicy::FIT_TO_CHILDREN:
2107 return NegotiateFromChildren(dimension);
2110 case ResizePolicy::DIMENSION_DEPENDENCY:
2112 const Dimension::Type dimensionDependency = GetDimensionDependency(dimension);
2115 if(dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT)
2117 return GetWidthForHeight(GetNegotiatedDimension(Dimension::HEIGHT));
2120 if(dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH)
2122 return GetHeightForWidth(GetNegotiatedDimension(Dimension::WIDTH));
2134 return 0.0f; // Default
2137 Vector2 Actor::ApplySizeSetPolicy(const Vector2& size)
2139 return mRelayoutData->ApplySizeSetPolicy(*this, size);
2142 void Actor::SetNegotiatedSize(RelayoutContainer& container)
2144 // Do the set actor size
2145 Vector2 negotiatedSize(GetLatestSize(Dimension::WIDTH), GetLatestSize(Dimension::HEIGHT));
2147 // Adjust for size set policy
2148 negotiatedSize = ApplySizeSetPolicy(negotiatedSize);
2150 // Lock the flag to stop recursive relayouts on set size
2151 mRelayoutData->insideRelayout = true;
2152 SetSize(negotiatedSize);
2153 mRelayoutData->insideRelayout = false;
2155 // Clear flags for all dimensions
2156 SetLayoutDirty(false);
2158 // Give deriving classes a chance to respond
2159 OnRelayout(negotiatedSize, container);
2161 if(!mOnRelayoutSignal.Empty())
2163 Dali::Actor handle(this);
2164 mOnRelayoutSignal.Emit(handle);
2168 void Actor::NegotiateSize(const Vector2& allocatedSize, RelayoutContainer& container)
2170 Relayouter::NegotiateSize(*this, allocatedSize, container);
2173 void Actor::SetUseAssignedSize(bool use, Dimension::Type dimension)
2177 mRelayoutData->SetUseAssignedSize(use, dimension);
2181 bool Actor::GetUseAssignedSize(Dimension::Type dimension) const
2183 return mRelayoutData && mRelayoutData->GetUseAssignedSize(dimension);
2186 void Actor::RelayoutRequest(Dimension::Type dimension)
2188 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
2189 if(relayoutController)
2191 Dali::Actor self(this);
2192 relayoutController->RequestRelayout(self, dimension);
2196 void Actor::SetPreferredSize(const Vector2& size)
2198 EnsureRelayouter().SetPreferredSize(*this, size);
2201 Vector2 Actor::GetPreferredSize() const
2205 return Vector2(mRelayoutData->preferredSize);
2208 return Relayouter::DEFAULT_PREFERRED_SIZE;
2211 void Actor::SetMinimumSize(float size, Dimension::Type dimension)
2213 EnsureRelayouter().SetMinimumSize(size, dimension);
2217 float Actor::GetMinimumSize(Dimension::Type dimension) const
2221 return mRelayoutData->GetMinimumSize(dimension);
2224 return 0.0f; // Default
2227 void Actor::SetMaximumSize(float size, Dimension::Type dimension)
2229 EnsureRelayouter().SetMaximumSize(size, dimension);
2233 float Actor::GetMaximumSize(Dimension::Type dimension) const
2237 return mRelayoutData->GetMaximumSize(dimension);
2240 return FLT_MAX; // Default
2243 void Actor::SetVisibleInternal(bool visible, SendMessage::Type sendMessage)
2245 if(mVisible != visible)
2247 if(sendMessage == SendMessage::TRUE)
2249 // node is being used in a separate thread; queue a message to set the value & base value
2250 SceneGraph::NodePropertyMessage<bool>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible);
2252 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
2257 // Emit the signal on this actor and all its children
2258 EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::SELF);
2262 void Actor::SetSiblingOrderOfChild(Actor& child, uint32_t order)
2264 mParentImpl.SetSiblingOrderOfChild(child, order);
2267 uint32_t Actor::GetSiblingOrderOfChild(const Actor& child) const
2269 return mParentImpl.GetSiblingOrderOfChild(child);
2272 void Actor::RaiseChild(Actor& child)
2274 mParentImpl.RaiseChild(child);
2277 void Actor::LowerChild(Actor& child)
2279 mParentImpl.LowerChild(child);
2282 void Actor::RaiseChildToTop(Actor& child)
2284 mParentImpl.RaiseChildToTop(child);
2287 void Actor::LowerChildToBottom(Actor& child)
2289 mParentImpl.LowerChildToBottom(child);
2292 void Actor::RaiseChildAbove(Actor& child, Actor& target)
2294 mParentImpl.RaiseChildAbove(child, target);
2297 void Actor::LowerChildBelow(Actor& child, Actor& target)
2299 mParentImpl.LowerChildBelow(child, target);
2302 void Actor::SetInheritLayoutDirection(bool inherit)
2304 if(mInheritLayoutDirection != inherit)
2306 mInheritLayoutDirection = inherit;
2308 if(inherit && mParent)
2310 InheritLayoutDirectionRecursively(GetParent()->mLayoutDirection);
2315 void Actor::InheritLayoutDirectionRecursively(Dali::LayoutDirection::Type direction, bool set)
2317 if(mInheritLayoutDirection || set)
2319 if(mLayoutDirection != direction)
2321 mLayoutDirection = direction;
2322 EmitLayoutDirectionChangedSignal(direction);
2326 if(GetChildCount() > 0)
2328 for(const auto& child : mParentImpl.GetChildrenInternal())
2330 child->InheritLayoutDirectionRecursively(direction);
2336 void Actor::SetUpdateSizeHint(const Vector2& updateSizeHint)
2338 // node is being used in a separate thread; queue a message to set the value & base value
2339 SceneGraph::NodePropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mUpdateSizeHint, &AnimatableProperty<Vector3>::Bake, Vector3(updateSizeHint.width, updateSizeHint.height, 0.f));
2342 void Actor::EmitVisibilityChangedSignalRecursively(bool visible,
2343 DevelActor::VisibilityChange::Type type)
2345 EmitVisibilityChangedSignal(visible, type);
2347 if(GetChildCount() > 0)
2349 for(auto& child : mParentImpl.GetChildrenInternal())
2351 child->EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::PARENT);
2356 } // namespace Internal