2 * Copyright (c) 2020 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-parent.h>
41 #include <dali/internal/event/actors/actor-property-handler.h>
42 #include <dali/internal/event/actors/actor-relayouter.h>
43 #include <dali/internal/event/actors/camera-actor-impl.h>
44 #include <dali/internal/event/common/event-thread-services.h>
45 #include <dali/internal/event/common/projection.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/size-negotiation/relayout-controller-impl.h>
55 #include <dali/internal/update/nodes/node-messages.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("siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER)
145 DALI_PROPERTY("updateSizeHint", VECTOR2, true, false, false, Dali::DevelActor::Property::UPDATE_SIZE_HINT)
146 DALI_PROPERTY("captureAllTouchAfterStart", BOOLEAN, true, false, false, Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START)
147 DALI_PROPERTY("touchArea", VECTOR2, true, false, false, Dali::DevelActor::Property::TOUCH_AREA)
148 DALI_PROPERTY("blendEquation", INTEGER, true, false, false, Dali::DevelActor::Property::BLEND_EQUATION)
149 DALI_PROPERTY_TABLE_END(DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties)
153 static constexpr std::string_view SIGNAL_HOVERED = "hovered";
154 static constexpr std::string_view SIGNAL_WHEEL_EVENT = "wheelEvent";
155 static constexpr std::string_view SIGNAL_ON_SCENE = "onScene";
156 static constexpr std::string_view SIGNAL_OFF_SCENE = "offScene";
157 static constexpr std::string_view SIGNAL_ON_RELAYOUT = "onRelayout";
158 static constexpr std::string_view SIGNAL_TOUCHED = "touched";
159 static constexpr std::string_view SIGNAL_VISIBILITY_CHANGED = "visibilityChanged";
160 static constexpr std::string_view SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
161 static constexpr std::string_view SIGNAL_CHILD_ADDED = "childAdded";
162 static constexpr std::string_view SIGNAL_CHILD_REMOVED = "childRemoved";
166 static constexpr std::string_view ACTION_SHOW = "show";
167 static constexpr std::string_view ACTION_HIDE = "hide";
169 BaseHandle CreateActor()
171 return Dali::Actor::New();
174 TypeRegistration mType(typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties);
176 SignalConnectorType signalConnector2(mType, std::string(SIGNAL_HOVERED), &Actor::DoConnectSignal);
177 SignalConnectorType signalConnector3(mType, std::string(SIGNAL_WHEEL_EVENT), &Actor::DoConnectSignal);
178 SignalConnectorType signalConnector4(mType, std::string(SIGNAL_ON_SCENE), &Actor::DoConnectSignal);
179 SignalConnectorType signalConnector5(mType, std::string(SIGNAL_OFF_SCENE), &Actor::DoConnectSignal);
180 SignalConnectorType signalConnector6(mType, std::string(SIGNAL_ON_RELAYOUT), &Actor::DoConnectSignal);
181 SignalConnectorType signalConnector7(mType, std::string(SIGNAL_TOUCHED), &Actor::DoConnectSignal);
182 SignalConnectorType signalConnector8(mType, std::string(SIGNAL_VISIBILITY_CHANGED), &Actor::DoConnectSignal);
183 SignalConnectorType signalConnector9(mType, std::string(SIGNAL_LAYOUT_DIRECTION_CHANGED), &Actor::DoConnectSignal);
184 SignalConnectorType signalConnector10(mType, std::string(SIGNAL_CHILD_ADDED), &Actor::DoConnectSignal);
185 SignalConnectorType signalConnector11(mType, std::string(SIGNAL_CHILD_REMOVED), &Actor::DoConnectSignal);
187 TypeAction a1(mType, std::string(ACTION_SHOW), &Actor::DoAction);
188 TypeAction a2(mType, std::string(ACTION_HIDE), &Actor::DoAction);
191 * @brief Extract a given dimension from a Vector2
193 * @param[in] values The values to extract from
194 * @param[in] dimension The dimension to extract
195 * @return Return the value for the dimension
197 constexpr float GetDimensionValue(const Vector2& values, Dimension::Type dimension)
201 case Dimension::WIDTH:
205 case Dimension::HEIGHT:
207 return values.height;
218 * @brief Extract a given dimension from a Vector3
220 * @param[in] values The values to extract from
221 * @param[in] dimension The dimension to extract
222 * @return Return the value for the dimension
224 float GetDimensionValue(const Vector3& values, Dimension::Type dimension)
226 return GetDimensionValue(values.GetVectorXY(), dimension);
229 /// Helper for emitting a signal
230 template<typename Signal, typename Event>
231 bool EmitConsumingSignal(Actor& actor, Signal& signal, const Event& event)
233 bool consumed = false;
237 Dali::Actor handle(&actor);
238 consumed = signal.Emit(handle, event);
244 /// Helper for emitting signals with multiple parameters
245 template<typename Signal, typename... Param>
246 void EmitSignal(Actor& actor, Signal& signal, Param... params)
250 Dali::Actor handle(&actor);
251 signal.Emit(handle, params...);
255 bool ScreenToLocalInternal(
256 const Matrix& viewMatrix,
257 const Matrix& projectionMatrix,
258 const Matrix& worldMatrix,
259 const Viewport& viewport,
260 const Vector3& currentSize,
266 // Get the ModelView matrix
268 Matrix::Multiply(modelView, worldMatrix, viewMatrix);
270 // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
271 Matrix invertedMvp(false /*don't init*/);
272 Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
273 bool success = invertedMvp.Invert();
275 // Convert to GL coordinates
276 Vector4 screenPos(screenX - static_cast<float>(viewport.x), static_cast<float>(viewport.height) - screenY - static_cast<float>(viewport.y), 0.f, 1.f);
281 success = Unproject(screenPos, invertedMvp, static_cast<float>(viewport.width), static_cast<float>(viewport.height), nearPos);
288 success = Unproject(screenPos, invertedMvp, static_cast<float>(viewport.width), static_cast<float>(viewport.height), farPos);
294 if(XyPlaneIntersect(nearPos, farPos, local))
296 Vector3 size = currentSize;
297 localX = local.x + size.x * 0.5f;
298 localY = local.y + size.y * 0.5f;
309 } // unnamed namespace
311 ActorPtr Actor::New()
313 // pass a reference to actor, actor does not own its node
314 ActorPtr actor(new Actor(BASIC, *CreateNode()));
316 // Second-phase construction
322 const SceneGraph::Node* Actor::CreateNode()
324 // create node. Nodes are owned by the update manager
325 SceneGraph::Node* node = SceneGraph::Node::New();
326 OwnerPointer<SceneGraph::Node> transferOwnership(node);
327 Internal::ThreadLocalStorage* tls = Internal::ThreadLocalStorage::GetInternal();
329 DALI_ASSERT_ALWAYS(tls && "ThreadLocalStorage is null");
331 AddNodeMessage(tls->GetUpdateManager(), transferOwnership);
337 void Actor::SetName( std::string_view name )
339 mName = ConstString(name);
341 // ATTENTION: string for debug purposes is not thread safe.
342 DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( &GetNode() ), mName.GetCString() );
345 uint32_t Actor::GetId() const
347 return GetNode().GetId();
350 Dali::Layer Actor::GetLayer()
354 // Short-circuit for Layer derived actors
357 layer = Dali::Layer(static_cast<Dali::Internal::Layer*>(this)); // static cast as we trust the flag
360 // Find the immediate Layer parent
361 for(Actor* parent = GetParent(); !layer && parent != nullptr; parent = parent->GetParent())
363 if(parent->IsLayer())
365 layer = Dali::Layer(static_cast<Dali::Internal::Layer*>(parent)); // static cast as we trust the flag
372 void Actor::Unparent()
376 // Remove this actor from the parent. The remove will put a relayout request in for
377 // the parent if required
378 mParent->Remove(*this);
379 // mParent is now NULL!
383 void Actor::SetParentOrigin(const Vector3& origin)
385 // node is being used in a separate thread; queue a message to set the value & base value
386 SetParentOriginMessage(GetEventThreadServices(), GetNode(), origin);
388 // Cache for event-thread access
391 // not allocated, check if different from default
392 if(ParentOrigin::DEFAULT != origin)
394 mParentOrigin = new Vector3(origin);
399 // check if different from current costs more than just set
400 *mParentOrigin = origin;
404 const Vector3& Actor::GetCurrentParentOrigin() const
406 // Cached for event-thread access
407 return (mParentOrigin) ? *mParentOrigin : ParentOrigin::DEFAULT;
410 void Actor::SetAnchorPoint(const Vector3& anchor)
412 // node is being used in a separate thread; queue a message to set the value & base value
413 SetAnchorPointMessage(GetEventThreadServices(), GetNode(), anchor);
415 // Cache for event-thread access
418 // not allocated, check if different from default
419 if(AnchorPoint::DEFAULT != anchor)
421 mAnchorPoint = new Vector3(anchor);
426 // check if different from current costs more than just set
427 *mAnchorPoint = anchor;
431 const Vector3& Actor::GetCurrentAnchorPoint() const
433 // Cached for event-thread access
434 return (mAnchorPoint) ? *mAnchorPoint : AnchorPoint::DEFAULT;
437 void Actor::SetPosition(float x, float y)
439 SetPosition(Vector3(x, y, 0.0f));
442 void Actor::SetPosition(float x, float y, float z)
444 SetPosition(Vector3(x, y, z));
447 void Actor::SetPosition(const Vector3& position)
449 mTargetPosition = position;
451 // node is being used in a separate thread; queue a message to set the value & base value
452 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, position);
455 void Actor::SetX(float x)
457 mTargetPosition.x = x;
459 // node is being used in a separate thread; queue a message to set the value & base value
460 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x);
463 void Actor::SetY(float y)
465 mTargetPosition.y = y;
467 // node is being used in a separate thread; queue a message to set the value & base value
468 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y);
471 void Actor::SetZ(float z)
473 mTargetPosition.z = z;
475 // node is being used in a separate thread; queue a message to set the value & base value
476 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z);
479 void Actor::TranslateBy(const Vector3& distance)
481 mTargetPosition += distance;
483 // node is being used in a separate thread; queue a message to set the value & base value
484 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelative, distance);
487 const Vector3& Actor::GetCurrentPosition() const
489 // node is being used in a separate thread; copy the value from the previous update
490 return GetNode().GetPosition(GetEventThreadServices().GetEventBufferIndex());
493 const Vector3& Actor::GetCurrentWorldPosition() const
495 // node is being used in a separate thread; copy the value from the previous update
496 return GetNode().GetWorldPosition(GetEventThreadServices().GetEventBufferIndex());
499 const Vector2 Actor::GetCurrentScreenPosition() const
501 if(mScene && OnScene())
503 Vector3 worldPosition = GetNode().GetWorldPosition(GetEventThreadServices().GetEventBufferIndex());
504 Vector3 cameraPosition = mScene->GetDefaultCameraActor().GetNode().GetWorldPosition(GetEventThreadServices().GetEventBufferIndex());
505 worldPosition -= cameraPosition;
507 Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale();
508 Vector2 halfSceneSize(mScene->GetSize() * 0.5f); // World position origin is center of scene
509 Vector3 halfActorSize(actorSize * 0.5f);
510 Vector3 anchorPointOffSet = halfActorSize - actorSize * (mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT);
512 return Vector2(halfSceneSize.width + worldPosition.x - anchorPointOffSet.x,
513 halfSceneSize.height + worldPosition.y - anchorPointOffSet.y);
516 return Vector2::ZERO;
519 void Actor::SetInheritPosition(bool inherit)
521 if(mInheritPosition != inherit)
523 // non animatable so keep local copy
524 mInheritPosition = inherit;
525 SetInheritPositionMessage(GetEventThreadServices(), GetNode(), inherit);
529 void Actor::SetOrientation(const Radian& angle, const Vector3& axis)
531 Vector3 normalizedAxis(axis.x, axis.y, axis.z);
532 normalizedAxis.Normalize();
534 Quaternion orientation(angle, normalizedAxis);
536 SetOrientation(orientation);
539 void Actor::SetOrientation(const Quaternion& orientation)
541 mTargetOrientation = orientation;
543 // node is being used in a separate thread; queue a message to set the value & base value
544 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::Bake, orientation);
547 void Actor::RotateBy(const Radian& angle, const Vector3& axis)
549 RotateBy(Quaternion(angle, axis));
552 void Actor::RotateBy(const Quaternion& relativeRotation)
554 mTargetOrientation *= Quaternion(relativeRotation);
556 // node is being used in a separate thread; queue a message to set the value & base value
557 SceneGraph::NodeTransformPropertyMessage<Quaternion>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler<Quaternion>::BakeRelative, relativeRotation);
560 const Quaternion& Actor::GetCurrentOrientation() const
562 // node is being used in a separate thread; copy the value from the previous update
563 return GetNode().GetOrientation(GetEventThreadServices().GetEventBufferIndex());
566 const Quaternion& Actor::GetCurrentWorldOrientation() const
568 // node is being used in a separate thread; copy the value from the previous update
569 return GetNode().GetWorldOrientation(GetEventThreadServices().GetEventBufferIndex());
572 void Actor::SetScale(float scale)
574 SetScale(Vector3(scale, scale, scale));
577 void Actor::SetScale(float x, float y, float z)
579 SetScale(Vector3(x, y, z));
582 void Actor::SetScale(const Vector3& scale)
584 mTargetScale = scale;
586 // node is being used in a separate thread; queue a message to set the value & base value
587 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, scale);
590 void Actor::SetScaleX(float x)
594 // node is being used in a separate thread; queue a message to set the value & base value
595 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, x);
598 void Actor::SetScaleY(float y)
602 // node is being used in a separate thread; queue a message to set the value & base value
603 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, y);
606 void Actor::SetScaleZ(float z)
610 // node is being used in a separate thread; queue a message to set the value & base value
611 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, z);
614 void Actor::ScaleBy(const Vector3& relativeScale)
616 mTargetScale *= relativeScale;
618 // node is being used in a separate thread; queue a message to set the value & base value
619 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeRelativeMultiply, relativeScale);
622 const Vector3& Actor::GetCurrentScale() const
624 // node is being used in a separate thread; copy the value from the previous update
625 return GetNode().GetScale(GetEventThreadServices().GetEventBufferIndex());
628 const Vector3& Actor::GetCurrentWorldScale() const
630 // node is being used in a separate thread; copy the value from the previous update
631 return GetNode().GetWorldScale(GetEventThreadServices().GetEventBufferIndex());
634 void Actor::SetInheritScale(bool inherit)
636 if(mInheritScale != inherit)
638 // non animatable so keep local copy
639 mInheritScale = inherit;
640 // node is being used in a separate thread; queue a message to set the value
641 SetInheritScaleMessage(GetEventThreadServices(), GetNode(), inherit);
645 Matrix Actor::GetCurrentWorldMatrix() const
647 return GetNode().GetWorldMatrix(0);
650 void Actor::SetVisible(bool visible)
652 SetVisibleInternal(visible, SendMessage::TRUE);
655 bool Actor::IsVisible() const
657 // node is being used in a separate thread; copy the value from the previous update
658 return GetNode().IsVisible(GetEventThreadServices().GetEventBufferIndex());
661 void Actor::SetOpacity(float opacity)
663 mTargetColor.a = opacity;
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>::BakeW, opacity);
668 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
671 float Actor::GetCurrentOpacity() const
673 // node is being used in a separate thread; copy the value from the previous update
674 return GetNode().GetOpacity(GetEventThreadServices().GetEventBufferIndex());
677 const Vector4& Actor::GetCurrentWorldColor() const
679 return GetNode().GetWorldColor(GetEventThreadServices().GetEventBufferIndex());
682 void Actor::SetColor(const Vector4& color)
684 mTargetColor = color;
686 // node is being used in a separate thread; queue a message to set the value & base value
687 SceneGraph::NodePropertyMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::Bake, color);
689 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
692 void Actor::SetColorRed(float red)
694 mTargetColor.r = red;
696 // node is being used in a separate thread; queue a message to set the value & base value
697 SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeX, red);
699 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
702 void Actor::SetColorGreen(float green)
704 mTargetColor.g = green;
706 // node is being used in a separate thread; queue a message to set the value & base value
707 SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeY, green);
709 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
712 void Actor::SetColorBlue(float blue)
714 mTargetColor.b = blue;
716 // node is being used in a separate thread; queue a message to set the value & base value
717 SceneGraph::NodePropertyComponentMessage<Vector4>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty<Vector4>::BakeZ, blue);
719 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
722 const Vector4& Actor::GetCurrentColor() const
724 // node is being used in a separate thread; copy the value from the previous update
725 return GetNode().GetColor(GetEventThreadServices().GetEventBufferIndex());
728 void Actor::SetInheritOrientation(bool inherit)
730 if(mInheritOrientation != inherit)
732 // non animatable so keep local copy
733 mInheritOrientation = inherit;
734 // node is being used in a separate thread; queue a message to set the value
735 SetInheritOrientationMessage(GetEventThreadServices(), GetNode(), inherit);
739 void Actor::SetSizeModeFactor(const Vector3& factor)
743 mRelayoutData->sizeModeFactor = factor;
746 const Vector3& Actor::GetSizeModeFactor() const
750 return mRelayoutData->sizeModeFactor;
753 return Relayouter::DEFAULT_SIZE_MODE_FACTOR;
756 void Actor::SetColorMode(ColorMode colorMode)
758 // non animatable so keep local copy
759 mColorMode = colorMode;
760 // node is being used in a separate thread; queue a message to set the value
761 SetColorModeMessage(GetEventThreadServices(), GetNode(), colorMode);
764 void Actor::SetSize(float width, float height)
766 SetSize(Vector2(width, height));
769 void Actor::SetSize(float width, float height, float depth)
771 SetSize(Vector3(width, height, depth));
774 void Actor::SetSize(const Vector2& size)
776 SetSize(Vector3(size.width, size.height, 0.f));
779 void Actor::SetSizeInternal(const Vector2& size)
781 SetSizeInternal(Vector3(size.width, size.height, 0.f));
784 void Actor::SetSize(const Vector3& size)
786 if(IsRelayoutEnabled() && !mRelayoutData->insideRelayout)
788 // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!!
789 SetPreferredSize(size.GetVectorXY());
793 SetSizeInternal(size);
797 void Actor::SetSizeInternal(const Vector3& size)
799 // dont allow recursive loop
800 DALI_ASSERT_ALWAYS(!mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet");
801 // 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
802 Vector3 currentSize = GetCurrentSize();
804 if( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )||
805 ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )||
806 ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 )||
807 ( fabsf( mTargetSize.width - currentSize.width ) > Math::MACHINE_EPSILON_1 )||
808 ( fabsf( mTargetSize.height- currentSize.height ) > Math::MACHINE_EPSILON_1 )||
809 ( fabsf( mTargetSize.depth - currentSize.depth ) > Math::MACHINE_EPSILON_1 ) )
813 // node is being used in a separate thread; queue a message to set the value & base value
814 SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize);
816 // Notification for derived classes
817 mInsideOnSizeSet = true;
818 OnSizeSet(mTargetSize);
819 mInsideOnSizeSet = false;
821 // Raise a relayout request if the flag is not locked
822 if(mRelayoutData && !mRelayoutData->insideRelayout)
829 void Actor::SetWidth(float width)
831 if(IsRelayoutEnabled() && !mRelayoutData->insideRelayout)
833 SetResizePolicy(ResizePolicy::FIXED, Dimension::WIDTH);
834 mRelayoutData->preferredSize.width = width;
838 mTargetSize.width = width;
840 // node is being used in a separate thread; queue a message to set the value & base value
841 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeX, width);
844 mUseAnimatedSize &= ~AnimatedSizeFlag::WIDTH;
849 void Actor::SetHeight(float height)
851 if(IsRelayoutEnabled() && !mRelayoutData->insideRelayout)
853 SetResizePolicy(ResizePolicy::FIXED, Dimension::HEIGHT);
854 mRelayoutData->preferredSize.height = height;
858 mTargetSize.height = height;
860 // node is being used in a separate thread; queue a message to set the value & base value
861 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeY, height);
864 mUseAnimatedSize &= ~AnimatedSizeFlag::HEIGHT;
869 void Actor::SetDepth(float depth)
871 mTargetSize.depth = depth;
873 mUseAnimatedSize &= ~AnimatedSizeFlag::DEPTH;
875 // node is being used in a separate thread; queue a message to set the value & base value
876 SceneGraph::NodeTransformComponentMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::BakeZ, depth);
879 Vector3 Actor::GetTargetSize() const
881 Vector3 size = mTargetSize;
883 if(mUseAnimatedSize & AnimatedSizeFlag::WIDTH)
885 // Should return animated size if size is animated
886 size.width = mAnimatedSize.width;
890 // Should return preferred size if size is fixed as set by SetSize
891 if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::FIXED)
893 size.width = GetPreferredSize().width;
897 if(mUseAnimatedSize & AnimatedSizeFlag::HEIGHT)
899 size.height = mAnimatedSize.height;
903 if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::FIXED)
905 size.height = GetPreferredSize().height;
909 if(mUseAnimatedSize & AnimatedSizeFlag::DEPTH)
911 size.depth = mAnimatedSize.depth;
917 const Vector3& Actor::GetCurrentSize() const
919 // node is being used in a separate thread; copy the value from the previous update
920 return GetNode().GetSize(GetEventThreadServices().GetEventBufferIndex());
923 Vector3 Actor::GetNaturalSize() const
925 // It is up to deriving classes to return the appropriate natural size
926 return Vector3(0.0f, 0.0f, 0.0f);
929 void Actor::SetResizePolicy(ResizePolicy::Type policy, Dimension::Type dimension)
931 EnsureRelayouter().SetResizePolicy(policy, dimension, mTargetSize);
933 OnSetResizePolicy(policy, dimension);
935 // Trigger relayout on this control
939 ResizePolicy::Type Actor::GetResizePolicy(Dimension::Type dimension) const
943 return mRelayoutData->GetResizePolicy(dimension);
946 return ResizePolicy::DEFAULT;
949 void Actor::SetSizeScalePolicy(SizeScalePolicy::Type policy)
953 mRelayoutData->sizeSetPolicy = policy;
955 // Trigger relayout on this control
959 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
963 return mRelayoutData->sizeSetPolicy;
966 return Relayouter::DEFAULT_SIZE_SCALE_POLICY;
969 void Actor::SetDimensionDependency(Dimension::Type dimension, Dimension::Type dependency)
971 EnsureRelayouter().SetDimensionDependency(dimension, dependency);
974 Dimension::Type Actor::GetDimensionDependency(Dimension::Type dimension) const
978 return mRelayoutData->GetDimensionDependency(dimension);
981 return Dimension::ALL_DIMENSIONS; // Default
984 void Actor::SetRelayoutEnabled(bool relayoutEnabled)
986 // If relayout data has not been allocated yet and the client is requesting
987 // to disable it, do nothing
988 if(mRelayoutData || relayoutEnabled)
992 DALI_ASSERT_DEBUG(mRelayoutData && "mRelayoutData not created");
994 mRelayoutData->relayoutEnabled = relayoutEnabled;
998 bool Actor::IsRelayoutEnabled() const
1000 // Assume that if relayout data has not been allocated yet then
1001 // relayout is disabled
1002 return mRelayoutData && mRelayoutData->relayoutEnabled;
1005 void Actor::SetLayoutDirty(bool dirty, Dimension::Type dimension)
1007 EnsureRelayouter().SetLayoutDirty(dirty, dimension);
1010 bool Actor::IsLayoutDirty(Dimension::Type dimension) const
1012 return mRelayoutData && mRelayoutData->IsLayoutDirty(dimension);
1015 bool Actor::RelayoutPossible(Dimension::Type dimension) const
1017 return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty(dimension);
1020 bool Actor::RelayoutRequired(Dimension::Type dimension) const
1022 return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty(dimension);
1025 uint32_t Actor::AddRenderer(Renderer& renderer)
1029 mRenderers = new RendererContainer;
1032 if(mIsBlendEquationSet)
1034 renderer.SetBlendEquation(static_cast<DevelBlendEquation::Type>(mBlendEquation));
1037 uint32_t index = static_cast<uint32_t>(mRenderers->size()); // 4,294,967,295 renderers per actor
1038 RendererPtr rendererPtr = RendererPtr(&renderer);
1039 mRenderers->push_back(rendererPtr);
1040 AttachRendererMessage(GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject());
1044 uint32_t Actor::GetRendererCount() const
1046 uint32_t rendererCount(0);
1049 rendererCount = static_cast<uint32_t>(mRenderers->size()); // 4,294,967,295 renderers per actor
1052 return rendererCount;
1055 RendererPtr Actor::GetRendererAt(uint32_t index)
1057 RendererPtr renderer;
1058 if(index < GetRendererCount())
1060 renderer = (*mRenderers)[index];
1066 void Actor::RemoveRenderer(Renderer& renderer)
1070 RendererIter end = mRenderers->end();
1071 for(RendererIter iter = mRenderers->begin(); iter != end; ++iter)
1073 if((*iter).Get() == &renderer)
1075 mRenderers->erase(iter);
1076 DetachRendererMessage(GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject());
1083 void Actor::RemoveRenderer(uint32_t index)
1085 if(index < GetRendererCount())
1087 RendererPtr renderer = (*mRenderers)[index];
1088 DetachRendererMessage(GetEventThreadServices(), GetNode(), renderer.Get()->GetRendererSceneObject());
1089 mRenderers->erase(mRenderers->begin() + index);
1093 void Actor::SetBlendEquation(DevelBlendEquation::Type blendEquation)
1095 if(Dali::Capabilities::IsBlendEquationSupported(blendEquation))
1097 if(mBlendEquation != blendEquation)
1099 mBlendEquation = blendEquation;
1100 uint32_t rendererCount = GetRendererCount();
1101 for(uint32_t i = 0; i < rendererCount; ++i)
1103 RendererPtr renderer = GetRendererAt(i);
1104 renderer->SetBlendEquation(static_cast<DevelBlendEquation::Type>(blendEquation));
1107 mIsBlendEquationSet = true;
1111 DALI_LOG_ERROR("Invalid blend equation is entered.\n");
1115 DevelBlendEquation::Type Actor::GetBlendEquation() const
1117 return mBlendEquation;
1120 void Actor::SetDrawMode(DrawMode::Type drawMode)
1122 // this flag is not animatable so keep the value
1123 mDrawMode = drawMode;
1125 // node is being used in a separate thread; queue a message to set the value
1126 SetDrawModeMessage(GetEventThreadServices(), GetNode(), drawMode);
1129 bool Actor::ScreenToLocal(float& localX, float& localY, float screenX, float screenY) const
1131 // only valid when on-stage
1132 if(mScene && OnScene())
1134 const RenderTaskList& taskList = mScene->GetRenderTaskList();
1136 Vector2 converted(screenX, screenY);
1138 // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
1139 uint32_t taskCount = taskList.GetTaskCount();
1140 for(uint32_t i = taskCount; i > 0; --i)
1142 RenderTaskPtr task = taskList.GetTask(i - 1);
1143 if(ScreenToLocal(*task, localX, localY, screenX, screenY))
1145 // found a task where this conversion was ok so return
1153 bool Actor::ScreenToLocal(const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY) const
1155 bool retval = false;
1156 // only valid when on-stage
1159 CameraActor* camera = renderTask.GetCameraActor();
1163 renderTask.GetViewport(viewport);
1165 // need to translate coordinates to render tasks coordinate space
1166 Vector2 converted(screenX, screenY);
1167 if(renderTask.TranslateCoordinates(converted))
1169 retval = ScreenToLocal(camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y);
1176 bool Actor::ScreenToLocal(const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY) const
1178 return OnScene() && ScreenToLocalInternal(viewMatrix, projectionMatrix, GetNode().GetWorldMatrix(0), viewport, GetCurrentSize(), localX, localY, screenX, screenY);
1181 ActorGestureData& Actor::GetGestureData()
1183 // Likely scenario is that once gesture-data is created for this actor, the actor will require
1184 // that gesture for its entire life-time so no need to destroy it until the actor is destroyed
1185 if(nullptr == mGestureData)
1187 mGestureData = new ActorGestureData;
1189 return *mGestureData;
1192 bool Actor::IsGestureRequired(GestureType::Value type) const
1194 return mGestureData && mGestureData->IsGestureRequired(type);
1197 bool Actor::EmitInterceptTouchEventSignal(const Dali::TouchEvent& touch)
1199 return EmitConsumingSignal(*this, mInterceptTouchedSignal, touch);
1202 bool Actor::EmitTouchEventSignal(const Dali::TouchEvent& touch)
1204 return EmitConsumingSignal(*this, mTouchedSignal, touch);
1207 bool Actor::EmitHoverEventSignal(const Dali::HoverEvent& event)
1209 return EmitConsumingSignal(*this, mHoveredSignal, event);
1212 bool Actor::EmitWheelEventSignal(const Dali::WheelEvent& event)
1214 return EmitConsumingSignal(*this, mWheelEventSignal, event);
1217 void Actor::EmitVisibilityChangedSignal(bool visible, DevelActor::VisibilityChange::Type type)
1219 EmitSignal(*this, mVisibilityChangedSignal, visible, type);
1222 void Actor::EmitLayoutDirectionChangedSignal(LayoutDirection::Type type)
1224 EmitSignal(*this, mLayoutDirectionChangedSignal, type);
1227 DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
1229 return mParentImpl.ChildAddedSignal();
1232 DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal()
1234 return mParentImpl.ChildRemovedSignal();
1237 DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
1239 return mParentImpl.ChildOrderChangedSignal();
1242 bool Actor::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
1244 bool connected(true);
1245 Actor* actor = static_cast<Actor*>(object); // TypeRegistry guarantees that this is the correct type.
1247 std::string_view name(signalName);
1249 if(name == SIGNAL_HOVERED)
1251 actor->HoveredSignal().Connect(tracker, functor);
1253 else if(signalName == SIGNAL_WHEEL_EVENT)
1255 actor->WheelEventSignal().Connect(tracker, functor);
1257 else if(name == SIGNAL_ON_SCENE)
1259 actor->OnSceneSignal().Connect(tracker, functor);
1261 else if(name == SIGNAL_OFF_SCENE)
1263 actor->OffSceneSignal().Connect(tracker, functor);
1265 else if(name == SIGNAL_ON_RELAYOUT)
1267 actor->OnRelayoutSignal().Connect(tracker, functor);
1269 else if(name == SIGNAL_TOUCHED)
1271 actor->TouchedSignal().Connect(tracker, functor);
1273 else if(name == SIGNAL_VISIBILITY_CHANGED)
1275 actor->VisibilityChangedSignal().Connect(tracker, functor);
1277 else if(name == SIGNAL_LAYOUT_DIRECTION_CHANGED)
1279 actor->LayoutDirectionChangedSignal().Connect(tracker, functor);
1281 else if(name == SIGNAL_CHILD_ADDED)
1283 actor->ChildAddedSignal().Connect(tracker, functor);
1285 else if(name == SIGNAL_CHILD_REMOVED)
1287 actor->ChildRemovedSignal().Connect(tracker, functor);
1291 // signalName does not match any signal
1298 Actor::Actor(DerivedType derivedType, const SceneGraph::Node& node)
1303 mRenderers(nullptr),
1304 mParentOrigin(nullptr),
1305 mAnchorPoint(nullptr),
1306 mRelayoutData(nullptr),
1307 mGestureData(nullptr),
1308 mInterceptTouchedSignal(),
1311 mWheelEventSignal(),
1314 mOnRelayoutSignal(),
1315 mVisibilityChangedSignal(),
1316 mLayoutDirectionChangedSignal(),
1317 mTargetOrientation(Quaternion::IDENTITY),
1318 mTargetColor(Color::WHITE),
1319 mTargetSize(Vector3::ZERO),
1320 mTargetPosition(Vector3::ZERO),
1321 mTargetScale(Vector3::ONE),
1322 mAnimatedSize(Vector3::ZERO),
1323 mTouchArea(Vector2::ZERO),
1327 mUseAnimatedSize(AnimatedSizeFlag::CLEAR),
1328 mIsRoot(ROOT_LAYER == derivedType),
1329 mIsLayer(LAYER == derivedType || ROOT_LAYER == derivedType),
1332 mLeaveRequired(false),
1333 mKeyboardFocusable(false),
1334 mOnSceneSignalled(false),
1335 mInsideOnSizeSet(false),
1336 mInheritPosition(true),
1337 mInheritOrientation(true),
1338 mInheritScale(true),
1339 mPositionUsesAnchorPoint(true),
1341 mInheritLayoutDirection(true),
1342 mCaptureAllTouchAfterStart(false),
1343 mLayoutDirection(LayoutDirection::LEFT_TO_RIGHT),
1344 mDrawMode(DrawMode::NORMAL),
1345 mColorMode(Node::DEFAULT_COLOR_MODE),
1346 mClippingMode(ClippingMode::DISABLED),
1347 mBlendEquation(DevelBlendEquation::ADD),
1348 mIsBlendEquationSet(false)
1352 void Actor::Initialize()
1356 GetEventThreadServices().RegisterObject(this);
1361 // Remove mParent pointers from children even if we're destroying core,
1362 // to guard against GetParent() & Unparent() calls from CustomActor destructors.
1366 // Guard to allow handle destruction after Core has been destroyed
1367 if(EventThreadServices::IsCoreRunning())
1369 // Root layer will destroy its node in its own destructor
1372 DestroyNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
1374 GetEventThreadServices().UnregisterObject(this);
1378 // Cleanup optional gesture data
1379 delete mGestureData;
1381 // Cleanup optional parent origin and anchor
1382 delete mParentOrigin;
1383 delete mAnchorPoint;
1385 // Delete optional relayout data
1386 delete mRelayoutData;
1389 void Actor::Add(Actor& child)
1391 mParentImpl.Add(child);
1394 void Actor::Remove(Actor& child)
1396 mParentImpl.Remove(child);
1399 uint32_t Actor::GetChildCount() const
1401 return mParentImpl.GetChildCount();
1404 ActorPtr Actor::GetChildAt(uint32_t index) const
1406 return mParentImpl.GetChildAt(index);
1409 ActorContainer& Actor::GetChildrenInternal()
1411 return mParentImpl.GetChildrenInternal();
1414 ActorPtr Actor::FindChildByName(ConstString actorName)
1416 return mParentImpl.FindChildByName(actorName);
1419 ActorPtr Actor::FindChildById(const uint32_t id)
1421 return mParentImpl.FindChildById(id);
1424 void Actor::UnparentChildren()
1426 mParentImpl.UnparentChildren();
1429 void Actor::ConnectToScene(uint32_t parentDepth)
1431 // This container is used instead of walking the Actor hierarchy.
1432 // It protects us when the Actor hierarchy is modified during OnSceneConnectionExternal callbacks.
1433 ActorContainer connectionList;
1437 mScene->RequestRebuildDepthTree();
1440 // This stage is atomic i.e. not interrupted by user callbacks.
1441 RecursiveConnectToScene(connectionList, parentDepth + 1);
1443 // Notify applications about the newly connected actors.
1444 for(const auto& actor : connectionList)
1446 actor->NotifyStageConnection();
1452 void Actor::RecursiveConnectToScene(ActorContainer& connectionList, uint32_t depth)
1454 DALI_ASSERT_ALWAYS(!OnScene());
1457 mDepth = static_cast<uint16_t>(depth); // overflow ignored, not expected in practice
1459 ConnectToSceneGraph();
1461 // Notification for internal derived classes
1462 OnSceneConnectionInternal();
1464 // This stage is atomic; avoid emitting callbacks until all Actors are connected
1465 connectionList.push_back(ActorPtr(this));
1467 // Recursively connect children
1468 if(GetChildCount() > 0)
1470 for(const auto& child : mParentImpl.GetChildrenInternal())
1472 child->SetScene(*mScene);
1473 child->RecursiveConnectToScene(connectionList, depth + 1);
1479 * This method is called when the Actor is connected to the Stage.
1480 * The parent must have added its Node to the scene-graph.
1481 * The child must connect its Node to the parent's Node.
1482 * This is recursive; the child calls ConnectToScene() for its children.
1484 void Actor::ConnectToSceneGraph()
1486 DALI_ASSERT_DEBUG(mParent != NULL);
1488 // Reparent Node in next Update
1489 ConnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetParent()->GetNode(), GetNode());
1491 // Request relayout on all actors that are added to the scenegraph
1494 // Notification for Object::Observers
1498 void Actor::NotifyStageConnection()
1500 // Actors can be removed (in a callback), before the on-stage stage is reported.
1501 // The actor may also have been reparented, in which case mOnSceneSignalled will be true.
1502 if(OnScene() && !mOnSceneSignalled)
1504 // Notification for external (CustomActor) derived classes
1505 OnSceneConnectionExternal(mDepth);
1507 if(!mOnSceneSignal.Empty())
1509 Dali::Actor handle(this);
1510 mOnSceneSignal.Emit(handle);
1513 // Guard against Remove during callbacks
1516 mOnSceneSignalled = true; // signal required next time Actor is removed
1521 void Actor::DisconnectFromStage()
1523 // This container is used instead of walking the Actor hierachy.
1524 // It protects us when the Actor hierachy is modified during OnSceneDisconnectionExternal callbacks.
1525 ActorContainer disconnectionList;
1529 mScene->RequestRebuildDepthTree();
1532 // This stage is atomic i.e. not interrupted by user callbacks
1533 RecursiveDisconnectFromStage(disconnectionList);
1535 // Notify applications about the newly disconnected actors.
1536 for(const auto& actor : disconnectionList)
1538 actor->NotifyStageDisconnection();
1542 void Actor::RecursiveDisconnectFromStage(ActorContainer& disconnectionList)
1544 // need to change state first so that internals relying on IsOnScene() inside OnSceneDisconnectionInternal() get the correct value
1547 // Recursively disconnect children
1548 if(GetChildCount() > 0)
1550 for(const auto& child : mParentImpl.GetChildrenInternal())
1552 child->RecursiveDisconnectFromStage(disconnectionList);
1556 // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
1557 disconnectionList.push_back(ActorPtr(this));
1559 // Notification for internal derived classes
1560 OnSceneDisconnectionInternal();
1562 DisconnectFromSceneGraph();
1566 * This method is called by an actor or its parent, before a node removal message is sent.
1567 * This is recursive; the child calls DisconnectFromStage() for its children.
1569 void Actor::DisconnectFromSceneGraph()
1571 // Notification for Object::Observers
1572 OnSceneObjectRemove();
1575 void Actor::NotifyStageDisconnection()
1577 // Actors can be added (in a callback), before the off-stage state is reported.
1578 // Also if the actor was added & removed before mOnSceneSignalled was set, then we don't notify here.
1579 // only do this step if there is a stage, i.e. Core is not being shut down
1580 if(EventThreadServices::IsCoreRunning() && !OnScene() && mOnSceneSignalled)
1582 // Notification for external (CustomeActor) derived classes
1583 OnSceneDisconnectionExternal();
1585 if(!mOffSceneSignal.Empty())
1587 Dali::Actor handle(this);
1588 mOffSceneSignal.Emit(handle);
1591 // Guard against Add during callbacks
1594 mOnSceneSignalled = false; // signal required next time Actor is added
1599 bool Actor::IsNodeConnected() const
1601 bool connected(false);
1605 if(IsRoot() || GetNode().GetParent())
1614 // This method initiates traversal of the actor tree using depth-first
1615 // traversal to set a depth index based on traversal order. It sends a
1616 // single message to update manager to update all the actor's nodes in
1617 // this tree with the depth index. The sceneGraphNodeDepths vector's
1618 // elements are ordered by depth, and could be used to reduce sorting
1619 // in the update thread.
1620 void Actor::RebuildDepthTree()
1622 DALI_LOG_TIMER_START(depthTimer);
1624 // Vector of scene-graph nodes and their depths to send to UpdateManager
1625 // in a single message
1626 OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths(new SceneGraph::NodeDepths());
1628 int32_t depthIndex = 1;
1629 DepthTraverseActorTree(sceneGraphNodeDepths, depthIndex);
1631 SetDepthIndicesMessage(GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths);
1632 DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
1635 void Actor::DepthTraverseActorTree(OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int32_t& depthIndex)
1637 mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
1638 sceneGraphNodeDepths->Add(const_cast<SceneGraph::Node*>(&GetNode()), mSortedDepth);
1640 // Create/add to children of this node
1641 if(GetChildCount() > 0)
1643 for(const auto& child : mParentImpl.GetChildrenInternal())
1645 Actor* childActor = child.Get();
1647 childActor->DepthTraverseActorTree(sceneGraphNodeDepths, depthIndex);
1652 void Actor::SetDefaultProperty(Property::Index index, const Property::Value& property)
1654 PropertyHandler::SetDefaultProperty(*this, index, property);
1657 // TODO: This method needs to be removed
1658 void Actor::SetSceneGraphProperty(Property::Index index, const PropertyMetadata& entry, const Property::Value& value)
1660 PropertyHandler::SetSceneGraphProperty(index, entry, value, GetEventThreadServices(), GetNode());
1663 Property::Value Actor::GetDefaultProperty(Property::Index index) const
1665 Property::Value value;
1667 if(!GetCachedPropertyValue(index, value))
1669 // If property value is not stored in the event-side, then it must be a scene-graph only property
1670 GetCurrentPropertyValue(index, value);
1676 Property::Value Actor::GetDefaultPropertyCurrentValue(Property::Index index) const
1678 Property::Value value;
1680 if(!GetCurrentPropertyValue(index, value))
1682 // If unable to retrieve scene-graph property value, then it must be an event-side only property
1683 GetCachedPropertyValue(index, value);
1689 void Actor::OnNotifyDefaultPropertyAnimation(Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType)
1691 PropertyHandler::OnNotifyDefaultPropertyAnimation(*this, animation, index, value, animationType);
1694 const PropertyBase* Actor::GetSceneObjectAnimatableProperty(Property::Index index) const
1696 const PropertyBase* property = PropertyHandler::GetSceneObjectAnimatableProperty(index, GetNode());
1699 // not our property, ask base
1700 property = Object::GetSceneObjectAnimatableProperty(index);
1706 const PropertyInputImpl* Actor::GetSceneObjectInputProperty(Property::Index index) const
1708 const PropertyInputImpl* property = PropertyHandler::GetSceneObjectInputProperty(index, GetNode());
1711 // reuse animatable property getter as animatable properties are inputs as well
1712 // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered
1713 property = GetSceneObjectAnimatableProperty(index);
1719 int32_t Actor::GetPropertyComponentIndex(Property::Index index) const
1721 int32_t componentIndex = PropertyHandler::GetPropertyComponentIndex(index);
1722 if(Property::INVALID_COMPONENT_INDEX == componentIndex)
1725 componentIndex = Object::GetPropertyComponentIndex(index);
1728 return componentIndex;
1735 mParent->RaiseChild(*this);
1739 DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1747 mParent->LowerChild(*this);
1751 DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1755 void Actor::RaiseToTop()
1759 mParent->RaiseChildToTop(*this);
1763 DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1767 void Actor::LowerToBottom()
1771 mParent->LowerChildToBottom(*this);
1775 DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1779 void Actor::RaiseAbove(Internal::Actor& target)
1783 mParent->RaiseChildAbove(*this, target);
1787 DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1791 void Actor::LowerBelow(Internal::Actor& target)
1795 mParent->LowerChildBelow(*this, target);
1799 DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
1803 void Actor::SetParent(ActorParent* parent)
1807 DALI_ASSERT_ALWAYS(!mParent && "Actor cannot have 2 parents");
1810 Actor* parentActor = static_cast<Actor*>(parent);
1811 mScene = parentActor->mScene;
1813 if(EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
1814 parentActor->OnScene())
1816 // Instruct each actor to create a corresponding node in the scene graph
1817 ConnectToScene(parentActor->GetHierarchyDepth());
1820 // Resolve the name and index for the child properties if any
1821 ResolveChildProperties();
1823 else // parent being set to NULL
1825 DALI_ASSERT_ALWAYS(mParent != nullptr && "Actor should have a parent");
1829 if(EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
1832 // Disconnect the Node & its children from the scene-graph.
1833 DisconnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
1835 // Instruct each actor to discard pointers to the scene-graph
1836 DisconnectFromStage();
1843 bool Actor::DoAction(BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */)
1846 Actor* actor = dynamic_cast<Actor*>(object);
1850 std::string_view name(actionName);
1851 if(name == ACTION_SHOW)
1853 actor->SetVisible(true);
1856 else if(name == ACTION_HIDE)
1858 actor->SetVisible(false);
1866 Rect<> Actor::CalculateScreenExtents() const
1868 auto screenPosition = GetCurrentScreenPosition();
1869 Vector3 size = GetCurrentSize() * GetCurrentWorldScale();
1870 Vector3 anchorPointOffSet = size * (mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT);
1871 Vector2 position = Vector2(screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y);
1872 return {position.x, position.y, size.x, size.y};
1875 bool Actor::GetCachedPropertyValue(Property::Index index, Property::Value& value) const
1877 return PropertyHandler::GetCachedPropertyValue(*this, index, value);
1880 bool Actor::GetCurrentPropertyValue(Property::Index index, Property::Value& value) const
1882 return PropertyHandler::GetCurrentPropertyValue(*this, index, value);
1885 Actor::Relayouter& Actor::EnsureRelayouter()
1887 // Assign relayouter
1890 mRelayoutData = new Relayouter();
1893 return *mRelayoutData;
1896 bool Actor::RelayoutDependentOnParent(Dimension::Type dimension)
1898 // Check if actor is dependent on parent
1899 for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
1901 if((dimension & (1 << i)))
1903 const ResizePolicy::Type resizePolicy = GetResizePolicy(static_cast<Dimension::Type>(1 << i));
1904 if(resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT)
1914 bool Actor::RelayoutDependentOnChildren(Dimension::Type dimension)
1916 // Check if actor is dependent on children
1917 for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
1919 if((dimension & (1 << i)))
1921 const ResizePolicy::Type resizePolicy = GetResizePolicy(static_cast<Dimension::Type>(1 << i));
1922 switch(resizePolicy)
1924 case ResizePolicy::FIT_TO_CHILDREN:
1925 case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
1941 bool Actor::RelayoutDependentOnChildrenBase(Dimension::Type dimension)
1943 return Actor::RelayoutDependentOnChildren(dimension);
1946 bool Actor::RelayoutDependentOnDimension(Dimension::Type dimension, Dimension::Type dependentDimension)
1948 // Check each possible dimension and see if it is dependent on the input one
1949 for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
1951 if(dimension & (1 << i))
1953 return mRelayoutData->resizePolicies[i] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[i] == dependentDimension;
1960 void Actor::SetNegotiatedDimension(float negotiatedDimension, Dimension::Type dimension)
1962 for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
1964 if(dimension & (1 << i))
1966 mRelayoutData->negotiatedDimensions[i] = negotiatedDimension;
1971 float Actor::GetNegotiatedDimension(Dimension::Type dimension) const
1973 // If more than one dimension is requested, just return the first one found
1974 for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
1976 if((dimension & (1 << i)))
1978 return mRelayoutData->negotiatedDimensions[i];
1982 return 0.0f; // Default
1985 void Actor::SetPadding(const Vector2& padding, Dimension::Type dimension)
1987 EnsureRelayouter().SetPadding(padding, dimension);
1990 Vector2 Actor::GetPadding(Dimension::Type dimension) const
1994 // If more than one dimension is requested, just return the first one found
1995 for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
1997 if((dimension & (1 << i)))
1999 return mRelayoutData->dimensionPadding[i];
2004 return Relayouter::DEFAULT_DIMENSION_PADDING;
2007 void Actor::SetLayoutNegotiated(bool negotiated, Dimension::Type dimension)
2009 EnsureRelayouter().SetLayoutNegotiated(negotiated, dimension);
2012 bool Actor::IsLayoutNegotiated(Dimension::Type dimension) const
2014 return mRelayoutData && mRelayoutData->IsLayoutNegotiated(dimension);
2017 float Actor::GetHeightForWidthBase(float width)
2019 float height = 0.0f;
2021 const Vector3 naturalSize = GetNaturalSize();
2022 if(naturalSize.width > 0.0f)
2024 height = naturalSize.height * width / naturalSize.width;
2026 else // we treat 0 as 1:1 aspect ratio
2034 float Actor::GetWidthForHeightBase(float height)
2038 const Vector3 naturalSize = GetNaturalSize();
2039 if(naturalSize.height > 0.0f)
2041 width = naturalSize.width * height / naturalSize.height;
2043 else // we treat 0 as 1:1 aspect ratio
2051 float Actor::CalculateChildSizeBase(const Dali::Actor& child, Dimension::Type dimension)
2053 // Fill to parent, taking size mode factor into account
2054 switch(child.GetResizePolicy(dimension))
2056 case ResizePolicy::FILL_TO_PARENT:
2058 return GetLatestSize(dimension);
2061 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
2063 return GetLatestSize(dimension) * GetDimensionValue(child.GetProperty<Vector3>(Dali::Actor::Property::SIZE_MODE_FACTOR), dimension);
2066 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
2068 return GetLatestSize(dimension) + GetDimensionValue(child.GetProperty<Vector3>(Dali::Actor::Property::SIZE_MODE_FACTOR), dimension);
2073 return GetLatestSize(dimension);
2078 float Actor::CalculateChildSize(const Dali::Actor& child, Dimension::Type dimension)
2080 // Can be overridden in derived class
2081 return CalculateChildSizeBase(child, dimension);
2084 float Actor::GetHeightForWidth(float width)
2086 // Can be overridden in derived class
2087 return GetHeightForWidthBase(width);
2090 float Actor::GetWidthForHeight(float height)
2092 // Can be overridden in derived class
2093 return GetWidthForHeightBase(height);
2096 float Actor::GetLatestSize(Dimension::Type dimension) const
2098 return IsLayoutNegotiated(dimension) ? GetNegotiatedDimension(dimension) : GetSize(dimension);
2101 float Actor::GetRelayoutSize(Dimension::Type dimension) const
2103 Vector2 padding = GetPadding(dimension);
2105 return GetLatestSize(dimension) + padding.x + padding.y;
2108 float Actor::NegotiateFromParent(Dimension::Type dimension)
2110 Actor* parent = GetParent();
2113 Vector2 padding(GetPadding(dimension));
2114 Vector2 parentPadding(parent->GetPadding(dimension));
2115 return parent->CalculateChildSize(Dali::Actor(this), dimension) - parentPadding.x - parentPadding.y - padding.x - padding.y;
2121 float Actor::NegotiateFromChildren(Dimension::Type dimension)
2123 float maxDimensionPoint = 0.0f;
2125 for(uint32_t i = 0, count = GetChildCount(); i < count; ++i)
2127 ActorPtr child = GetChildAt(i);
2129 if(!child->RelayoutDependentOnParent(dimension))
2131 // Calculate the min and max points that the children range across
2132 float childPosition = GetDimensionValue(child->GetTargetPosition(), dimension);
2133 float dimensionSize = child->GetRelayoutSize(dimension);
2134 maxDimensionPoint = std::max(maxDimensionPoint, childPosition + dimensionSize);
2138 return maxDimensionPoint;
2141 float Actor::GetSize(Dimension::Type dimension) const
2143 return GetDimensionValue(mTargetSize, dimension);
2146 float Actor::GetNaturalSize(Dimension::Type dimension) const
2148 return GetDimensionValue(GetNaturalSize(), dimension);
2151 float Actor::CalculateSize(Dimension::Type dimension, const Vector2& maximumSize)
2153 switch(GetResizePolicy(dimension))
2155 case ResizePolicy::USE_NATURAL_SIZE:
2157 return GetNaturalSize(dimension);
2160 case ResizePolicy::FIXED:
2162 return GetDimensionValue(GetPreferredSize(), dimension);
2165 case ResizePolicy::USE_ASSIGNED_SIZE:
2167 return GetDimensionValue(maximumSize, dimension);
2170 case ResizePolicy::FILL_TO_PARENT:
2171 case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
2172 case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
2174 return NegotiateFromParent(dimension);
2177 case ResizePolicy::FIT_TO_CHILDREN:
2179 return NegotiateFromChildren(dimension);
2182 case ResizePolicy::DIMENSION_DEPENDENCY:
2184 const Dimension::Type dimensionDependency = GetDimensionDependency(dimension);
2187 if(dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT)
2189 return GetWidthForHeight(GetNegotiatedDimension(Dimension::HEIGHT));
2192 if(dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH)
2194 return GetHeightForWidth(GetNegotiatedDimension(Dimension::WIDTH));
2206 return 0.0f; // Default
2209 Vector2 Actor::ApplySizeSetPolicy(const Vector2& size)
2211 return mRelayoutData->ApplySizeSetPolicy(*this, size);
2214 void Actor::SetNegotiatedSize(RelayoutContainer& container)
2216 // Do the set actor size
2217 Vector2 negotiatedSize(GetLatestSize(Dimension::WIDTH), GetLatestSize(Dimension::HEIGHT));
2219 // Adjust for size set policy
2220 negotiatedSize = ApplySizeSetPolicy(negotiatedSize);
2222 // Lock the flag to stop recursive relayouts on set size
2223 mRelayoutData->insideRelayout = true;
2224 SetSize(negotiatedSize);
2225 mRelayoutData->insideRelayout = false;
2227 // Clear flags for all dimensions
2228 SetLayoutDirty(false);
2230 // Give deriving classes a chance to respond
2231 OnRelayout(negotiatedSize, container);
2233 if(!mOnRelayoutSignal.Empty())
2235 Dali::Actor handle(this);
2236 mOnRelayoutSignal.Emit(handle);
2240 void Actor::NegotiateSize(const Vector2& allocatedSize, RelayoutContainer& container)
2242 Relayouter::NegotiateSize(*this, allocatedSize, container);
2245 void Actor::SetUseAssignedSize(bool use, Dimension::Type dimension)
2249 mRelayoutData->SetUseAssignedSize(use, dimension);
2253 bool Actor::GetUseAssignedSize(Dimension::Type dimension) const
2255 return mRelayoutData && mRelayoutData->GetUseAssignedSize(dimension);
2258 void Actor::RelayoutRequest(Dimension::Type dimension)
2260 Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
2261 if(relayoutController)
2263 Dali::Actor self(this);
2264 relayoutController->RequestRelayout(self, dimension);
2268 void Actor::SetPreferredSize(const Vector2& size)
2270 EnsureRelayouter().SetPreferredSize(*this, size);
2273 Vector2 Actor::GetPreferredSize() const
2277 return Vector2(mRelayoutData->preferredSize);
2280 return Relayouter::DEFAULT_PREFERRED_SIZE;
2283 void Actor::SetMinimumSize(float size, Dimension::Type dimension)
2285 EnsureRelayouter().SetMinimumSize(size, dimension);
2289 float Actor::GetMinimumSize(Dimension::Type dimension) const
2293 return mRelayoutData->GetMinimumSize(dimension);
2296 return 0.0f; // Default
2299 void Actor::SetMaximumSize(float size, Dimension::Type dimension)
2301 EnsureRelayouter().SetMaximumSize(size, dimension);
2305 float Actor::GetMaximumSize(Dimension::Type dimension) const
2309 return mRelayoutData->GetMaximumSize(dimension);
2312 return FLT_MAX; // Default
2315 void Actor::SetVisibleInternal(bool visible, SendMessage::Type sendMessage)
2317 if(mVisible != visible)
2319 if(sendMessage == SendMessage::TRUE)
2321 // node is being used in a separate thread; queue a message to set the value & base value
2322 SceneGraph::NodePropertyMessage<bool>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty<bool>::Bake, visible);
2324 RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
2329 // Emit the signal on this actor and all its children
2330 EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::SELF);
2334 void Actor::SetSiblingOrderOfChild(Actor& child, uint32_t order)
2336 mParentImpl.SetSiblingOrderOfChild(child, order);
2339 uint32_t Actor::GetSiblingOrderOfChild(const Actor& child) const
2341 return mParentImpl.GetSiblingOrderOfChild(child);
2344 void Actor::RaiseChild(Actor& child)
2346 mParentImpl.RaiseChild(child);
2349 void Actor::LowerChild(Actor& child)
2351 mParentImpl.LowerChild(child);
2354 void Actor::RaiseChildToTop(Actor& child)
2356 mParentImpl.RaiseChildToTop(child);
2359 void Actor::LowerChildToBottom(Actor& child)
2361 mParentImpl.LowerChildToBottom(child);
2364 void Actor::RaiseChildAbove(Actor& child, Actor& target)
2366 mParentImpl.RaiseChildAbove(child, target);
2369 void Actor::LowerChildBelow(Actor& child, Actor& target)
2371 mParentImpl.LowerChildBelow(child, target);
2374 void Actor::SetInheritLayoutDirection(bool inherit)
2376 if(mInheritLayoutDirection != inherit)
2378 mInheritLayoutDirection = inherit;
2380 if(inherit && mParent)
2382 InheritLayoutDirectionRecursively(GetParent()->mLayoutDirection);
2387 void Actor::InheritLayoutDirectionRecursively(Dali::LayoutDirection::Type direction, bool set)
2389 if(mInheritLayoutDirection || set)
2391 if(mLayoutDirection != direction)
2393 mLayoutDirection = direction;
2394 EmitLayoutDirectionChangedSignal(direction);
2398 if(GetChildCount() > 0)
2400 for(const auto& child : mParentImpl.GetChildrenInternal())
2402 child->InheritLayoutDirectionRecursively(direction);
2408 void Actor::SetUpdateSizeHint(const Vector2& updateSizeHint)
2410 // node is being used in a separate thread; queue a message to set the value & base value
2411 SceneGraph::NodePropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mUpdateSizeHint, &AnimatableProperty<Vector3>::Bake, Vector3(updateSizeHint.width, updateSizeHint.height, 0.f));
2414 void Actor::EmitVisibilityChangedSignalRecursively(bool visible,
2415 DevelActor::VisibilityChange::Type type)
2417 EmitVisibilityChangedSignal(visible, type);
2419 if(GetChildCount() > 0)
2421 for(auto& child : mParentImpl.GetChildrenInternal())
2423 child->EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::PARENT);
2428 } // namespace Internal