X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fevent%2Factors%2Factor-impl.cpp;h=decf85af6970808b9a01422c51a37bea3b2803da;hb=a42d8f30cafd2c74a3146607f13ab6aa7ca0c3f6;hp=70fce3634af9a8308a9c8f2f07b17fd9fc5adfc0;hpb=5f200f16a783b85be40da73ce02ac98bb6a60096;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/event/actors/actor-impl.cpp b/dali/internal/event/actors/actor-impl.cpp index 70fce36..decf85a 100644 --- a/dali/internal/event/actors/actor-impl.cpp +++ b/dali/internal/event/actors/actor-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,132 +19,57 @@ #include // EXTERNAL INCLUDES -#include #include #include +#include // INTERNAL INCLUDES -#include -#include #include -#include +#include +#include #include #include -#include #include + #include -#include -#include -#include -#include +#include +#include + +#include + +#include +#include +#include +#include #include -#include +#include #include -#include -#include #include +#include #include -#include -#include +#include +#include +#include +#include +#include #include -#include +#include #include -#include -#include -#include -#include -#include -using Dali::Internal::SceneGraph::Node; using Dali::Internal::SceneGraph::AnimatableProperty; +using Dali::Internal::SceneGraph::Node; using Dali::Internal::SceneGraph::PropertyBase; #if defined(DEBUG_ENABLED) -Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER" ); -Debug::Filter* gLogRelayoutFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RELAYOUT_TIMER" ); +Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER"); #endif namespace Dali { - namespace Internal { - -namespace -{ -/// Using a function because of library initialisation order. Vector3::ONE may not have been initialised yet. -inline const Vector3& GetDefaultSizeModeFactor() -{ - return Vector3::ONE; -} - -/// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet. -inline const Vector2& GetDefaultPreferredSize() -{ - return Vector2::ZERO; -} - -/// Using a function because of library initialisation order. Vector2::ZERO may not have been initialised yet. -inline const Vector2& GetDefaultDimensionPadding() -{ - return Vector2::ZERO; -} - -const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET; - -} // unnamed namespace - -/** - * Struct to collect relayout variables - */ -struct Actor::RelayoutData -{ - RelayoutData() - : sizeModeFactor( GetDefaultSizeModeFactor() ), preferredSize( GetDefaultPreferredSize() ), sizeSetPolicy( DEFAULT_SIZE_SCALE_POLICY ), relayoutEnabled( false ), insideRelayout( false ) - { - // Set size negotiation defaults - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) - { - resizePolicies[ i ] = ResizePolicy::DEFAULT; - useAssignedSize[ i ] = false; - negotiatedDimensions[ i ] = 0.0f; - dimensionNegotiated[ i ] = false; - dimensionDirty[ i ] = false; - dimensionDependencies[ i ] = Dimension::ALL_DIMENSIONS; - dimensionPadding[ i ] = GetDefaultDimensionPadding(); - minimumSize[ i ] = 0.0f; - maximumSize[ i ] = FLT_MAX; - } - } - - ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ]; ///< Resize policies - bool useAssignedSize[ Dimension::DIMENSION_COUNT ]; ///< The flag to specify whether the size should be assigned to the actor - - Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ]; ///< A list of dimension dependencies - - Vector2 dimensionPadding[ Dimension::DIMENSION_COUNT ]; ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top) - - float negotiatedDimensions[ Dimension::DIMENSION_COUNT ]; ///< Storage for when a dimension is negotiated but before set on actor - - float minimumSize[ Dimension::DIMENSION_COUNT ]; ///< The minimum size an actor can be - float maximumSize[ Dimension::DIMENSION_COUNT ]; ///< The maximum size an actor can be - - bool dimensionNegotiated[ Dimension::DIMENSION_COUNT ]; ///< Has the dimension been negotiated - bool dimensionDirty[ Dimension::DIMENSION_COUNT ]; ///< Flags indicating whether the layout dimension is dirty or not - - Vector3 sizeModeFactor; ///< Factor of size used for certain SizeModes - - Vector2 preferredSize; ///< The preferred size of the actor - - SizeScalePolicy::Type sizeSetPolicy :3; ///< Policy to apply when setting size. Enough room for the enum - - bool relayoutEnabled :1; ///< Flag to specify if this actor should be included in size negotiation or not (defaults to true) - bool insideRelayout :1; ///< Locking flag to prevent recursive relayouts on size set -}; - namespace // unnamed namespace { - // Properties /** @@ -153,191 +78,118 @@ namespace // unnamed namespace * Name Type writable animatable constraint-input enum for index-checking */ DALI_PROPERTY_TABLE_BEGIN -DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN ) -DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X ) -DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y ) -DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z ) -DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT ) -DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X ) -DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y ) -DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z ) -DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE ) -DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH ) -DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT ) -DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH ) -DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION ) -DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X ) -DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y ) -DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z ) -DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION ) -DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X ) -DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y ) -DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z ) -DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION ) -DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION ) -DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE ) -DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X ) -DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y ) -DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z ) -DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE ) -DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE ) -DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR ) -DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED ) -DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN ) -DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE ) -DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA ) -DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR ) -DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX ) -DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME ) -DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE ) -DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED ) -DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION ) -DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE ) -DALI_PROPERTY( "colorMode", INTEGER, true, false, false, Dali::Actor::Property::COLOR_MODE ) -DALI_PROPERTY( "drawMode", INTEGER, true, false, false, Dali::Actor::Property::DRAW_MODE ) -DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR ) -DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY ) -DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY ) -DALI_PROPERTY( "sizeScalePolicy", INTEGER, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY ) -DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT ) -DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH ) -DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING ) -DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE ) -DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE ) -DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION ) -DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE ) -DALI_PROPERTY( "layoutDirection", STRING, true, false, false, Dali::Actor::Property::LAYOUT_DIRECTION ) -DALI_PROPERTY( "inheritLayoutDirection", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION ) -DALI_PROPERTY( "opacity", FLOAT, true, true, true, Dali::Actor::Property::OPACITY ) -DALI_PROPERTY( "screenPosition", VECTOR2, false, false, false, Dali::Actor::Property::SCREEN_POSITION ) -DALI_PROPERTY( "positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::Actor::Property::POSITION_USES_ANCHOR_POINT ) -DALI_PROPERTY( "culled", BOOLEAN, false, false, true, Dali::Actor::Property::CULLED ) -DALI_PROPERTY( "id", INTEGER, false, false, false, Dali::Actor::Property::ID ) -DALI_PROPERTY( "hierarchyDepth", INTEGER, false, false, false, Dali::Actor::Property::HIERARCHY_DEPTH ) -DALI_PROPERTY( "isRoot", BOOLEAN, false, false, false, Dali::Actor::Property::IS_ROOT ) -DALI_PROPERTY( "isLayer", BOOLEAN, false, false, false, Dali::Actor::Property::IS_LAYER ) -DALI_PROPERTY( "connectedToScene", BOOLEAN, false, false, false, Dali::Actor::Property::CONNECTED_TO_SCENE ) -DALI_PROPERTY( "keyboardFocusable", BOOLEAN, true, false, false, Dali::Actor::Property::KEYBOARD_FOCUSABLE ) -DALI_PROPERTY( "siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER ) -DALI_PROPERTY( "updateSizeHint", VECTOR2, true, false, false, Dali::DevelActor::Property::UPDATE_SIZE_HINT ) -DALI_PROPERTY( "captureAllTouchAfterStart", BOOLEAN, true, false, false, Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START ) -DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties ) +DALI_PROPERTY("parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN) +DALI_PROPERTY("parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X) +DALI_PROPERTY("parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y) +DALI_PROPERTY("parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z) +DALI_PROPERTY("anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT) +DALI_PROPERTY("anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X) +DALI_PROPERTY("anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y) +DALI_PROPERTY("anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z) +DALI_PROPERTY("size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE) +DALI_PROPERTY("sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH) +DALI_PROPERTY("sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT) +DALI_PROPERTY("sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH) +DALI_PROPERTY("position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION) +DALI_PROPERTY("positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X) +DALI_PROPERTY("positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y) +DALI_PROPERTY("positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z) +DALI_PROPERTY("worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION) +DALI_PROPERTY("worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X) +DALI_PROPERTY("worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y) +DALI_PROPERTY("worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z) +DALI_PROPERTY("orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION) +DALI_PROPERTY("worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION) +DALI_PROPERTY("scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE) +DALI_PROPERTY("scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X) +DALI_PROPERTY("scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y) +DALI_PROPERTY("scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z) +DALI_PROPERTY("worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE) +DALI_PROPERTY("visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE) +DALI_PROPERTY("color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR) +DALI_PROPERTY("colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED) +DALI_PROPERTY("colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN) +DALI_PROPERTY("colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE) +DALI_PROPERTY("colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA) +DALI_PROPERTY("worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR) +DALI_PROPERTY("worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX) +DALI_PROPERTY("name", STRING, true, false, false, Dali::Actor::Property::NAME) +DALI_PROPERTY("sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE) +DALI_PROPERTY("leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED) +DALI_PROPERTY("inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION) +DALI_PROPERTY("inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE) +DALI_PROPERTY("colorMode", INTEGER, true, false, false, Dali::Actor::Property::COLOR_MODE) +DALI_PROPERTY("drawMode", INTEGER, true, false, false, Dali::Actor::Property::DRAW_MODE) +DALI_PROPERTY("sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR) +DALI_PROPERTY("widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY) +DALI_PROPERTY("heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY) +DALI_PROPERTY("sizeScalePolicy", INTEGER, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY) +DALI_PROPERTY("widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT) +DALI_PROPERTY("heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH) +DALI_PROPERTY("padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING) +DALI_PROPERTY("minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE) +DALI_PROPERTY("maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE) +DALI_PROPERTY("inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION) +DALI_PROPERTY("clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE) +DALI_PROPERTY("layoutDirection", STRING, true, false, false, Dali::Actor::Property::LAYOUT_DIRECTION) +DALI_PROPERTY("inheritLayoutDirection", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION) +DALI_PROPERTY("opacity", FLOAT, true, true, true, Dali::Actor::Property::OPACITY) +DALI_PROPERTY("screenPosition", VECTOR2, false, false, false, Dali::Actor::Property::SCREEN_POSITION) +DALI_PROPERTY("positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::Actor::Property::POSITION_USES_ANCHOR_POINT) +DALI_PROPERTY("culled", BOOLEAN, false, false, true, Dali::Actor::Property::CULLED) +DALI_PROPERTY("id", INTEGER, false, false, false, Dali::Actor::Property::ID) +DALI_PROPERTY("hierarchyDepth", INTEGER, false, false, false, Dali::Actor::Property::HIERARCHY_DEPTH) +DALI_PROPERTY("isRoot", BOOLEAN, false, false, false, Dali::Actor::Property::IS_ROOT) +DALI_PROPERTY("isLayer", BOOLEAN, false, false, false, Dali::Actor::Property::IS_LAYER) +DALI_PROPERTY("connectedToScene", BOOLEAN, false, false, false, Dali::Actor::Property::CONNECTED_TO_SCENE) +DALI_PROPERTY("keyboardFocusable", BOOLEAN, true, false, false, Dali::Actor::Property::KEYBOARD_FOCUSABLE) +DALI_PROPERTY("siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER) +DALI_PROPERTY("updateSizeHint", VECTOR2, true, false, false, Dali::DevelActor::Property::UPDATE_SIZE_HINT) +DALI_PROPERTY("captureAllTouchAfterStart", BOOLEAN, true, false, false, Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START) +DALI_PROPERTY("touchAreaOffset", RECTANGLE, true, false, false, Dali::DevelActor::Property::TOUCH_AREA_OFFSET) +DALI_PROPERTY("blendEquation", INTEGER, true, false, false, Dali::DevelActor::Property::BLEND_EQUATION) +DALI_PROPERTY("touchFocusable", BOOLEAN, true, false, false, Dali::DevelActor::Property::TOUCH_FOCUSABLE) +DALI_PROPERTY("keyboardFocusableChildren", BOOLEAN, true, false, false, Dali::DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN) +DALI_PROPERTY_TABLE_END(DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties) // Signals -const char* const SIGNAL_HOVERED = "hovered"; -const char* const SIGNAL_WHEEL_EVENT = "wheelEvent"; -const char* const SIGNAL_ON_SCENE = "onScene"; -const char* const SIGNAL_OFF_SCENE = "offScene"; -const char* const SIGNAL_ON_RELAYOUT = "onRelayout"; -const char* const SIGNAL_TOUCHED = "touched"; -const char* const SIGNAL_VISIBILITY_CHANGED = "visibilityChanged"; -const char* const SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged"; -const char* const SIGNAL_CHILD_ADDED = "childAdded"; -const char* const SIGNAL_CHILD_REMOVED = "childRemoved"; +static constexpr std::string_view SIGNAL_HOVERED = "hovered"; +static constexpr std::string_view SIGNAL_WHEEL_EVENT = "wheelEvent"; +static constexpr std::string_view SIGNAL_ON_SCENE = "onScene"; +static constexpr std::string_view SIGNAL_OFF_SCENE = "offScene"; +static constexpr std::string_view SIGNAL_ON_RELAYOUT = "onRelayout"; +static constexpr std::string_view SIGNAL_TOUCHED = "touched"; +static constexpr std::string_view SIGNAL_VISIBILITY_CHANGED = "visibilityChanged"; +static constexpr std::string_view SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged"; +static constexpr std::string_view SIGNAL_CHILD_ADDED = "childAdded"; +static constexpr std::string_view SIGNAL_CHILD_REMOVED = "childRemoved"; // Actions -const char* const ACTION_SHOW = "show"; -const char* const ACTION_HIDE = "hide"; +static constexpr std::string_view ACTION_SHOW = "show"; +static constexpr std::string_view ACTION_HIDE = "hide"; BaseHandle CreateActor() { return Dali::Actor::New(); } -TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties ); - -SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal ); -SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal ); -SignalConnectorType signalConnector4( mType, SIGNAL_ON_SCENE, &Actor::DoConnectSignal ); -SignalConnectorType signalConnector5( mType, SIGNAL_OFF_SCENE, &Actor::DoConnectSignal ); -SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal ); -SignalConnectorType signalConnector7( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal ); -SignalConnectorType signalConnector8( mType, SIGNAL_VISIBILITY_CHANGED, &Actor::DoConnectSignal ); -SignalConnectorType signalConnector9( mType, SIGNAL_LAYOUT_DIRECTION_CHANGED, &Actor::DoConnectSignal ); -SignalConnectorType signalConnector10( mType, SIGNAL_CHILD_ADDED, &Actor::DoConnectSignal ); -SignalConnectorType signalConnector11( mType, SIGNAL_CHILD_REMOVED, &Actor::DoConnectSignal ); - -TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction ); -TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction ); - -struct AnchorValue -{ - const char* name; - const Vector3& value; -}; - -DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( AnchorValue, ANCHOR_CONSTANT ) -DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_LEFT ) -DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_CENTER ) -DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, TOP_RIGHT ) -DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_LEFT ) -DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER ) -DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, CENTER_RIGHT ) -DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_LEFT ) -DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_CENTER ) -DALI_ENUM_TO_STRING_WITH_SCOPE( AnchorPoint, BOTTOM_RIGHT ) -DALI_ENUM_TO_STRING_TABLE_END( ANCHOR_CONSTANT ) - -DALI_ENUM_TO_STRING_TABLE_BEGIN( COLOR_MODE ) -DALI_ENUM_TO_STRING( USE_OWN_COLOR ) -DALI_ENUM_TO_STRING( USE_PARENT_COLOR ) -DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_COLOR ) -DALI_ENUM_TO_STRING( USE_OWN_MULTIPLY_PARENT_ALPHA ) -DALI_ENUM_TO_STRING_TABLE_END( COLOR_MODE ) - -DALI_ENUM_TO_STRING_TABLE_BEGIN( DRAW_MODE ) -DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, NORMAL ) -DALI_ENUM_TO_STRING_WITH_SCOPE( DrawMode, OVERLAY_2D ) -DALI_ENUM_TO_STRING_TABLE_END( DRAW_MODE ) - -DALI_ENUM_TO_STRING_TABLE_BEGIN( RESIZE_POLICY ) -DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIXED ) -DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_NATURAL_SIZE ) -DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FILL_TO_PARENT ) -DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_RELATIVE_TO_PARENT ) -DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, SIZE_FIXED_OFFSET_FROM_PARENT ) -DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, FIT_TO_CHILDREN ) -DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, DIMENSION_DEPENDENCY ) -DALI_ENUM_TO_STRING_WITH_SCOPE( ResizePolicy, USE_ASSIGNED_SIZE ) -DALI_ENUM_TO_STRING_TABLE_END( RESIZE_POLICY ) - -DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_SCALE_POLICY ) -DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, USE_SIZE_SET ) -DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO ) -DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO ) -DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY ) - -DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE ) -DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED ) -DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN ) -DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE ) - -DALI_ENUM_TO_STRING_TABLE_BEGIN( LAYOUT_DIRECTION ) -DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, LEFT_TO_RIGHT ) -DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, RIGHT_TO_LEFT ) -DALI_ENUM_TO_STRING_TABLE_END( LAYOUT_DIRECTION ) - -bool GetAnchorPointConstant( const std::string& value, Vector3& anchor ) -{ - for( uint32_t i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i ) - { - uint32_t sizeIgnored = 0; - if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) ) - { - anchor = ANCHOR_CONSTANT_TABLE[ i ].value; - return true; - } - } - return false; -} +TypeRegistration mType(typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties); -inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOrigin ) -{ - // Values are the same so just use the same table as anchor-point - return GetAnchorPointConstant( value, parentOrigin ); -} +SignalConnectorType signalConnector2(mType, std::string(SIGNAL_HOVERED), &Actor::DoConnectSignal); +SignalConnectorType signalConnector3(mType, std::string(SIGNAL_WHEEL_EVENT), &Actor::DoConnectSignal); +SignalConnectorType signalConnector4(mType, std::string(SIGNAL_ON_SCENE), &Actor::DoConnectSignal); +SignalConnectorType signalConnector5(mType, std::string(SIGNAL_OFF_SCENE), &Actor::DoConnectSignal); +SignalConnectorType signalConnector6(mType, std::string(SIGNAL_ON_RELAYOUT), &Actor::DoConnectSignal); +SignalConnectorType signalConnector7(mType, std::string(SIGNAL_TOUCHED), &Actor::DoConnectSignal); +SignalConnectorType signalConnector8(mType, std::string(SIGNAL_VISIBILITY_CHANGED), &Actor::DoConnectSignal); +SignalConnectorType signalConnector9(mType, std::string(SIGNAL_LAYOUT_DIRECTION_CHANGED), &Actor::DoConnectSignal); +SignalConnectorType signalConnector10(mType, std::string(SIGNAL_CHILD_ADDED), &Actor::DoConnectSignal); +SignalConnectorType signalConnector11(mType, std::string(SIGNAL_CHILD_REMOVED), &Actor::DoConnectSignal); + +TypeAction a1(mType, std::string(ACTION_SHOW), &Actor::DoAction); +TypeAction a2(mType, std::string(ACTION_HIDE), &Actor::DoAction); /** * @brief Extract a given dimension from a Vector2 @@ -346,9 +198,9 @@ inline bool GetParentOriginConstant( const std::string& value, Vector3& parentOr * @param[in] dimension The dimension to extract * @return Return the value for the dimension */ -float GetDimensionValue( const Vector2& values, Dimension::Type dimension ) +constexpr float GetDimensionValue(const Vector2& values, Dimension::Type dimension) { - switch( dimension ) + switch(dimension) { case Dimension::WIDTH: { @@ -373,31 +225,34 @@ float GetDimensionValue( const Vector2& values, Dimension::Type dimension ) * @param[in] dimension The dimension to extract * @return Return the value for the dimension */ -float GetDimensionValue( const Vector3& values, Dimension::Type dimension ) +float GetDimensionValue(const Vector3& values, Dimension::Type dimension) { - return GetDimensionValue( values.GetVectorXY(), dimension ); + return GetDimensionValue(values.GetVectorXY(), dimension); } -/** - * @brief Recursively emits the visibility-changed-signal on the actor tree. - * @param[in] actor The actor to emit the signal on - * @param[in] visible The new visibility of the actor - * @param[in] type Whether the actor's visible property has changed or a parent's - */ -void EmitVisibilityChangedSignalRecursively( ActorPtr actor, bool visible, DevelActor::VisibilityChange::Type type ) +/// Helper for emitting a signal +template +bool EmitConsumingSignal(Actor& actor, Signal& signal, const Event& event) { - if( actor ) + bool consumed = false; + + if(!signal.Empty()) { - actor->EmitVisibilityChangedSignal( visible, type ); + Dali::Actor handle(&actor); + consumed = signal.Emit(handle, event); + } - if( actor->GetChildCount() > 0 ) - { - ActorContainer& children = actor->GetChildrenInternal(); - for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter ) - { - EmitVisibilityChangedSignalRecursively( *iter, visible, DevelActor::VisibilityChange::PARENT ); - } - } + return consumed; +} + +/// Helper for emitting signals with multiple parameters +template +void EmitSignal(Actor& actor, Signal& signal, Param... params) +{ + if(!signal.Empty()) + { + Dali::Actor handle(&actor); + signal.Emit(handle, params...); } } @@ -406,7 +261,7 @@ void EmitVisibilityChangedSignalRecursively( ActorPtr actor, bool visible, Devel ActorPtr Actor::New() { // pass a reference to actor, actor does not own its node - ActorPtr actor( new Actor( BASIC, *CreateNode() ) ); + ActorPtr actor(new Actor(BASIC, *CreateNode())); // Second-phase construction actor->Initialize(); @@ -417,28 +272,23 @@ ActorPtr Actor::New() const SceneGraph::Node* Actor::CreateNode() { // create node. Nodes are owned by the update manager - SceneGraph::Node* node = SceneGraph::Node::New(); - OwnerPointer< SceneGraph::Node > transferOwnership( node ); - Internal::ThreadLocalStorage* tls = Internal::ThreadLocalStorage::GetInternal(); + SceneGraph::Node* node = SceneGraph::Node::New(); + OwnerPointer transferOwnership(node); + Internal::ThreadLocalStorage* tls = Internal::ThreadLocalStorage::GetInternal(); - DALI_ASSERT_ALWAYS( tls && "ThreadLocalStorage is null" ); + DALI_ASSERT_ALWAYS(tls && "ThreadLocalStorage is null"); - AddNodeMessage( tls->GetUpdateManager(), transferOwnership ); + AddNodeMessage(tls->GetUpdateManager(), transferOwnership); return node; } -const std::string& Actor::GetName() const -{ - return mName; -} - -void Actor::SetName( const std::string& name ) +void Actor::SetName(std::string_view name) { - mName = name; + mName = ConstString(name); // ATTENTION: string for debug purposes is not thread safe. - DALI_LOG_SET_OBJECT_STRING( const_cast< SceneGraph::Node* >( &GetNode() ), name ); + DALI_LOG_SET_OBJECT_STRING(const_cast(&GetNode()), mName.GetCString()); } uint32_t Actor::GetId() const @@ -446,210 +296,51 @@ uint32_t Actor::GetId() const return GetNode().GetId(); } -bool Actor::OnScene() const -{ - return mIsOnScene; -} - Dali::Layer Actor::GetLayer() { Dali::Layer layer; // Short-circuit for Layer derived actors - if( mIsLayer ) + if(mIsLayer) { - layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( this ) ); // static cast as we trust the flag + layer = Dali::Layer(static_cast(this)); // static cast as we trust the flag } // Find the immediate Layer parent - for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() ) + for(Actor* parent = GetParent(); !layer && parent != nullptr; parent = parent->GetParent()) { - if( parent->IsLayer() ) + if(parent->IsLayer()) { - layer = Dali::Layer( static_cast< Dali::Internal::Layer* >( parent ) ); // static cast as we trust the flag + layer = Dali::Layer(static_cast(parent)); // static cast as we trust the flag } } return layer; } -void Actor::Add( Actor& child ) -{ - DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" ); - DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" ); - - if( !mChildren ) - { - mChildren = new ActorContainer; - } - - Actor* const oldParent( child.mParent ); - - // child might already be ours - if( this != oldParent ) - { - // if we already have parent, unparent us first - if( oldParent ) - { - oldParent->Remove( child ); // This causes OnChildRemove callback & ChildRemoved signal - - // Old parent may need to readjust to missing child - if( oldParent->RelayoutDependentOnChildren() ) - { - oldParent->RelayoutRequest(); - } - } - - // Guard against Add() during previous OnChildRemove callback - if( !child.mParent ) - { - // Do this first, since user callbacks from within SetParent() may need to remove child - mChildren->push_back( ActorPtr( &child ) ); - - // SetParent asserts that child can be added - child.SetParent( this ); - - // Notification for derived classes - OnChildAdd( child ); - EmitChildAddedSignal( child ); - - InheritLayoutDirectionRecursively( ActorPtr( &child ), mLayoutDirection ); - - // Only put in a relayout request if there is a suitable dependency - if( RelayoutDependentOnChildren() ) - { - RelayoutRequest(); - } - } - } -} - -void Actor::Remove( Actor& child ) -{ - if( (this == &child) || (!mChildren) ) - { - // no children or removing itself - return; - } - - ActorPtr removed; - - // Find the child in mChildren, and unparent it - ActorIter end = mChildren->end(); - for( ActorIter iter = mChildren->begin(); iter != end; ++iter ) - { - ActorPtr actor = (*iter); - - if( actor.Get() == &child ) - { - // Keep handle for OnChildRemove notification - removed = actor; - - // Do this first, since user callbacks from within SetParent() may need to add the child - mChildren->erase( iter ); - - DALI_ASSERT_DEBUG( actor->GetParent() == this ); - actor->SetParent( NULL ); - - break; - } - } - - if( removed ) - { - // Only put in a relayout request if there is a suitable dependency - if( RelayoutDependentOnChildren() ) - { - RelayoutRequest(); - } - } - - // Notification for derived classes - OnChildRemove( child ); - EmitChildRemovedSignal( child ); -} - void Actor::Unparent() { - if( mParent ) + if(mParent) { // Remove this actor from the parent. The remove will put a relayout request in for // the parent if required - mParent->Remove( *this ); + mParent->Remove(*this); // mParent is now NULL! } } -uint32_t Actor::GetChildCount() const -{ - return ( NULL != mChildren ) ? static_cast( mChildren->size() ) : 0; // only 4,294,967,295 children per actor -} - -ActorPtr Actor::GetChildAt( uint32_t index ) const -{ - DALI_ASSERT_ALWAYS( index < GetChildCount() ); - - return ( ( mChildren ) ? ( *mChildren )[ index ] : ActorPtr() ); -} - -ActorPtr Actor::FindChildByName( const std::string& actorName ) -{ - ActorPtr child = 0; - if( actorName == mName ) - { - child = this; - } - else if( mChildren ) - { - ActorIter end = mChildren->end(); - for( ActorIter iter = mChildren->begin(); iter != end; ++iter ) - { - child = (*iter)->FindChildByName( actorName ); - - if( child ) - { - break; - } - } - } - return child; -} - -ActorPtr Actor::FindChildById( const uint32_t id ) -{ - ActorPtr child = 0; - if( id == GetId() ) - { - child = this; - } - else if( mChildren ) - { - ActorIter end = mChildren->end(); - for( ActorIter iter = mChildren->begin(); iter != end; ++iter ) - { - child = (*iter)->FindChildById( id ); - - if( child ) - { - break; - } - } - } - return child; -} - -void Actor::SetParentOrigin( const Vector3& origin ) +void Actor::SetParentOrigin(const Vector3& origin) { // node is being used in a separate thread; queue a message to set the value & base value - SetParentOriginMessage( GetEventThreadServices(), GetNode(), origin ); + SetParentOriginMessage(GetEventThreadServices(), GetNode(), origin); // Cache for event-thread access - if( !mParentOrigin ) + if(!mParentOrigin) { // not allocated, check if different from default - if( ParentOrigin::DEFAULT != origin ) + if(ParentOrigin::DEFAULT != origin) { - mParentOrigin = new Vector3( origin ); + mParentOrigin = new Vector3(origin); } } else @@ -659,45 +350,24 @@ void Actor::SetParentOrigin( const Vector3& origin ) } } -void Actor::SetParentOriginX( float x ) -{ - const Vector3& current = GetCurrentParentOrigin(); - - SetParentOrigin( Vector3( x, current.y, current.z ) ); -} - -void Actor::SetParentOriginY( float y ) -{ - const Vector3& current = GetCurrentParentOrigin(); - - SetParentOrigin( Vector3( current.x, y, current.z ) ); -} - -void Actor::SetParentOriginZ( float z ) -{ - const Vector3& current = GetCurrentParentOrigin(); - - SetParentOrigin( Vector3( current.x, current.y, z ) ); -} - const Vector3& Actor::GetCurrentParentOrigin() const { // Cached for event-thread access - return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT; + return (mParentOrigin) ? *mParentOrigin : ParentOrigin::DEFAULT; } -void Actor::SetAnchorPoint( const Vector3& anchor ) +void Actor::SetAnchorPoint(const Vector3& anchor) { // node is being used in a separate thread; queue a message to set the value & base value - SetAnchorPointMessage( GetEventThreadServices(), GetNode(), anchor ); + SetAnchorPointMessage(GetEventThreadServices(), GetNode(), anchor); // Cache for event-thread access - if( !mAnchorPoint ) + if(!mAnchorPoint) { // not allocated, check if different from default - if( AnchorPoint::DEFAULT != anchor ) + if(AnchorPoint::DEFAULT != anchor) { - mAnchorPoint = new Vector3( anchor ); + mAnchorPoint = new Vector3(anchor); } } else @@ -707,81 +377,60 @@ void Actor::SetAnchorPoint( const Vector3& anchor ) } } -void Actor::SetAnchorPointX( float x ) -{ - const Vector3& current = GetCurrentAnchorPoint(); - - SetAnchorPoint( Vector3( x, current.y, current.z ) ); -} - -void Actor::SetAnchorPointY( float y ) -{ - const Vector3& current = GetCurrentAnchorPoint(); - - SetAnchorPoint( Vector3( current.x, y, current.z ) ); -} - -void Actor::SetAnchorPointZ( float z ) -{ - const Vector3& current = GetCurrentAnchorPoint(); - - SetAnchorPoint( Vector3( current.x, current.y, z ) ); -} - const Vector3& Actor::GetCurrentAnchorPoint() const { // Cached for event-thread access - return ( mAnchorPoint ) ? *mAnchorPoint : AnchorPoint::DEFAULT; + return (mAnchorPoint) ? *mAnchorPoint : AnchorPoint::DEFAULT; } -void Actor::SetPosition( float x, float y ) +void Actor::SetPosition(float x, float y) { - SetPosition( Vector3( x, y, 0.0f ) ); + SetPosition(Vector3(x, y, 0.0f)); } -void Actor::SetPosition( float x, float y, float z ) +void Actor::SetPosition(float x, float y, float z) { - SetPosition( Vector3( x, y, z ) ); + SetPosition(Vector3(x, y, z)); } -void Actor::SetPosition( const Vector3& position ) +void Actor::SetPosition(const Vector3& position) { mTargetPosition = position; // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodeTransformPropertyMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler::Bake, position ); + SceneGraph::NodeTransformPropertyMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler::Bake, position); } -void Actor::SetX( float x ) +void Actor::SetX(float x) { mTargetPosition.x = x; // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodeTransformComponentMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler::BakeX, x ); + SceneGraph::NodeTransformComponentMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler::BakeX, x); } -void Actor::SetY( float y ) +void Actor::SetY(float y) { mTargetPosition.y = y; // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodeTransformComponentMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler::BakeY, y ); + SceneGraph::NodeTransformComponentMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler::BakeY, y); } -void Actor::SetZ( float z ) +void Actor::SetZ(float z) { mTargetPosition.z = z; // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodeTransformComponentMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler::BakeZ, z ); + SceneGraph::NodeTransformComponentMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler::BakeZ, z); } -void Actor::TranslateBy( const Vector3& distance ) +void Actor::TranslateBy(const Vector3& distance) { mTargetPosition += distance; // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodeTransformPropertyMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler::BakeRelative, distance ); + SceneGraph::NodeTransformPropertyMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mPosition, &SceneGraph::TransformManagerPropertyHandler::BakeRelative, distance); } const Vector3& Actor::GetCurrentPosition() const @@ -790,81 +439,71 @@ const Vector3& Actor::GetCurrentPosition() const return GetNode().GetPosition(GetEventThreadServices().GetEventBufferIndex()); } -const Vector3& Actor::GetTargetPosition() const -{ - return mTargetPosition; -} - const Vector3& Actor::GetCurrentWorldPosition() const { // node is being used in a separate thread; copy the value from the previous update - return GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() ); + return GetNode().GetWorldPosition(GetEventThreadServices().GetEventBufferIndex()); } const Vector2 Actor::GetCurrentScreenPosition() const { - if( mScene && OnScene() ) + if(mScene && OnScene()) { - Vector3 worldPosition = GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() ); - Vector3 cameraPosition = mScene->GetDefaultCameraActor().GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() ); + Vector3 worldPosition = GetNode().GetWorldPosition(GetEventThreadServices().GetEventBufferIndex()); + Vector3 cameraPosition = mScene->GetDefaultCameraActor().GetNode().GetWorldPosition(GetEventThreadServices().GetEventBufferIndex()); worldPosition -= cameraPosition; Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale(); - Vector2 halfSceneSize( mScene->GetSize() * 0.5f ); // World position origin is center of scene - Vector3 halfActorSize( actorSize * 0.5f ); - Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT ); + Vector2 halfSceneSize(mScene->GetSize() * 0.5f); // World position origin is center of scene + Vector3 halfActorSize(actorSize * 0.5f); + Vector3 anchorPointOffSet = halfActorSize - actorSize * (mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT); - return Vector2( halfSceneSize.width + worldPosition.x - anchorPointOffSet.x, - halfSceneSize.height + worldPosition.y - anchorPointOffSet.y ); + return Vector2(halfSceneSize.width + worldPosition.x - anchorPointOffSet.x, + halfSceneSize.height + worldPosition.y - anchorPointOffSet.y); } return Vector2::ZERO; } -void Actor::SetInheritPosition( bool inherit ) +void Actor::SetInheritPosition(bool inherit) { - if( mInheritPosition != inherit ) + if(mInheritPosition != inherit) { // non animatable so keep local copy mInheritPosition = inherit; - SetInheritPositionMessage( GetEventThreadServices(), GetNode(), inherit ); + SetInheritPositionMessage(GetEventThreadServices(), GetNode(), inherit); } } -bool Actor::IsPositionInherited() const -{ - return mInheritPosition; -} - -void Actor::SetOrientation( const Radian& angle, const Vector3& axis ) +void Actor::SetOrientation(const Radian& angle, const Vector3& axis) { - Vector3 normalizedAxis( axis.x, axis.y, axis.z ); + Vector3 normalizedAxis(axis.x, axis.y, axis.z); normalizedAxis.Normalize(); - Quaternion orientation( angle, normalizedAxis ); + Quaternion orientation(angle, normalizedAxis); - SetOrientation( orientation ); + SetOrientation(orientation); } -void Actor::SetOrientation( const Quaternion& orientation ) +void Actor::SetOrientation(const Quaternion& orientation) { mTargetOrientation = orientation; // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodeTransformPropertyMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler::Bake, orientation ); + SceneGraph::NodeTransformPropertyMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler::Bake, orientation); } -void Actor::RotateBy( const Radian& angle, const Vector3& axis ) +void Actor::RotateBy(const Radian& angle, const Vector3& axis) { - RotateBy( Quaternion(angle, axis) ); + RotateBy(Quaternion(angle, axis)); } -void Actor::RotateBy( const Quaternion& relativeRotation ) +void Actor::RotateBy(const Quaternion& relativeRotation) { - mTargetOrientation *= Quaternion( relativeRotation ); + mTargetOrientation *= Quaternion(relativeRotation); // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodeTransformPropertyMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler::BakeRelative, relativeRotation ); + SceneGraph::NodeTransformPropertyMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mOrientation, &SceneGraph::TransformManagerPropertyHandler::BakeRelative, relativeRotation); } const Quaternion& Actor::GetCurrentOrientation() const @@ -876,49 +515,49 @@ const Quaternion& Actor::GetCurrentOrientation() const const Quaternion& Actor::GetCurrentWorldOrientation() const { // node is being used in a separate thread; copy the value from the previous update - return GetNode().GetWorldOrientation( GetEventThreadServices().GetEventBufferIndex() ); + return GetNode().GetWorldOrientation(GetEventThreadServices().GetEventBufferIndex()); } -void Actor::SetScale( float scale ) +void Actor::SetScale(float scale) { - SetScale( Vector3( scale, scale, scale ) ); + SetScale(Vector3(scale, scale, scale)); } -void Actor::SetScale( float x, float y, float z ) +void Actor::SetScale(float x, float y, float z) { - SetScale( Vector3( x, y, z ) ); + SetScale(Vector3(x, y, z)); } -void Actor::SetScale( const Vector3& scale ) +void Actor::SetScale(const Vector3& scale) { mTargetScale = scale; // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodeTransformPropertyMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler::Bake, scale ); + SceneGraph::NodeTransformPropertyMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler::Bake, scale); } -void Actor::SetScaleX( float x ) +void Actor::SetScaleX(float x) { mTargetScale.x = x; // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodeTransformComponentMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler::BakeX, x ); + SceneGraph::NodeTransformComponentMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler::BakeX, x); } -void Actor::SetScaleY( float y ) +void Actor::SetScaleY(float y) { mTargetScale.y = y; // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodeTransformComponentMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler::BakeY, y ); + SceneGraph::NodeTransformComponentMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler::BakeY, y); } -void Actor::SetScaleZ( float z ) +void Actor::SetScaleZ(float z) { mTargetScale.z = z; // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodeTransformComponentMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler::BakeZ, z ); + SceneGraph::NodeTransformComponentMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler::BakeZ, z); } void Actor::ScaleBy(const Vector3& relativeScale) @@ -926,7 +565,7 @@ void Actor::ScaleBy(const Vector3& relativeScale) mTargetScale *= relativeScale; // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodeTransformPropertyMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler::BakeRelativeMultiply, relativeScale ); + SceneGraph::NodeTransformPropertyMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mScale, &SceneGraph::TransformManagerPropertyHandler::BakeRelativeMultiply, relativeScale); } const Vector3& Actor::GetCurrentScale() const @@ -938,47 +577,44 @@ const Vector3& Actor::GetCurrentScale() const const Vector3& Actor::GetCurrentWorldScale() const { // node is being used in a separate thread; copy the value from the previous update - return GetNode().GetWorldScale( GetEventThreadServices().GetEventBufferIndex() ); + return GetNode().GetWorldScale(GetEventThreadServices().GetEventBufferIndex()); } -void Actor::SetInheritScale( bool inherit ) +void Actor::SetInheritScale(bool inherit) { - if( mInheritScale != inherit ) + if(mInheritScale != inherit) { // non animatable so keep local copy mInheritScale = inherit; // node is being used in a separate thread; queue a message to set the value - SetInheritScaleMessage( GetEventThreadServices(), GetNode(), inherit ); + SetInheritScaleMessage(GetEventThreadServices(), GetNode(), inherit); } } -bool Actor::IsScaleInherited() const -{ - return mInheritScale; -} - Matrix Actor::GetCurrentWorldMatrix() const { return GetNode().GetWorldMatrix(0); } -void Actor::SetVisible( bool visible ) +void Actor::SetVisible(bool visible) { - SetVisibleInternal( visible, SendMessage::TRUE ); + SetVisibleInternal(visible, SendMessage::TRUE); } bool Actor::IsVisible() const { // node is being used in a separate thread; copy the value from the previous update - return GetNode().IsVisible( GetEventThreadServices().GetEventBufferIndex() ); + return GetNode().IsVisible(GetEventThreadServices().GetEventBufferIndex()); } -void Actor::SetOpacity( float opacity ) +void Actor::SetOpacity(float opacity) { mTargetColor.a = opacity; // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyComponentMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty::BakeW, opacity ); + SceneGraph::NodePropertyComponentMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty::BakeW, opacity); + + RequestRenderingMessage(GetEventThreadServices().GetUpdateManager()); } float Actor::GetCurrentOpacity() const @@ -987,51 +623,49 @@ float Actor::GetCurrentOpacity() const return GetNode().GetOpacity(GetEventThreadServices().GetEventBufferIndex()); } -ClippingMode::Type Actor::GetClippingMode() const -{ - return mClippingMode; -} - -uint32_t Actor::GetSortingDepth() -{ - return mSortedDepth; -} - const Vector4& Actor::GetCurrentWorldColor() const { - return GetNode().GetWorldColor( GetEventThreadServices().GetEventBufferIndex() ); + return GetNode().GetWorldColor(GetEventThreadServices().GetEventBufferIndex()); } -void Actor::SetColor( const Vector4& color ) +void Actor::SetColor(const Vector4& color) { mTargetColor = color; // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty::Bake, color ); + SceneGraph::NodePropertyMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty::Bake, color); + + RequestRenderingMessage(GetEventThreadServices().GetUpdateManager()); } -void Actor::SetColorRed( float red ) +void Actor::SetColorRed(float red) { mTargetColor.r = red; // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyComponentMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty::BakeX, red ); + SceneGraph::NodePropertyComponentMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty::BakeX, red); + + RequestRenderingMessage(GetEventThreadServices().GetUpdateManager()); } -void Actor::SetColorGreen( float green ) +void Actor::SetColorGreen(float green) { mTargetColor.g = green; // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyComponentMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty::BakeY, green ); + SceneGraph::NodePropertyComponentMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty::BakeY, green); + + RequestRenderingMessage(GetEventThreadServices().GetUpdateManager()); } -void Actor::SetColorBlue( float blue ) +void Actor::SetColorBlue(float blue) { mTargetColor.b = blue; // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyComponentMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty::BakeZ, blue ); + SceneGraph::NodePropertyComponentMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mColor, &AnimatableProperty::BakeZ, blue); + + RequestRenderingMessage(GetEventThreadServices().GetUpdateManager()); } const Vector4& Actor::GetCurrentColor() const @@ -1040,118 +674,112 @@ const Vector4& Actor::GetCurrentColor() const return GetNode().GetColor(GetEventThreadServices().GetEventBufferIndex()); } -void Actor::SetInheritOrientation( bool inherit ) +void Actor::SetInheritOrientation(bool inherit) { - if( mInheritOrientation != inherit ) + if(mInheritOrientation != inherit) { // non animatable so keep local copy mInheritOrientation = inherit; // node is being used in a separate thread; queue a message to set the value - SetInheritOrientationMessage( GetEventThreadServices(), GetNode(), inherit ); + SetInheritOrientationMessage(GetEventThreadServices(), GetNode(), inherit); } } -bool Actor::IsOrientationInherited() const -{ - return mInheritOrientation; -} - -void Actor::SetSizeModeFactor( const Vector3& factor ) +void Actor::SetSizeModeFactor(const Vector3& factor) { - EnsureRelayoutData(); + EnsureRelayouter(); mRelayoutData->sizeModeFactor = factor; } const Vector3& Actor::GetSizeModeFactor() const { - if ( mRelayoutData ) + if(mRelayoutData) { return mRelayoutData->sizeModeFactor; } - return GetDefaultSizeModeFactor(); + return Relayouter::DEFAULT_SIZE_MODE_FACTOR; } -void Actor::SetColorMode( ColorMode colorMode ) +void Actor::SetColorMode(ColorMode colorMode) { // non animatable so keep local copy mColorMode = colorMode; // node is being used in a separate thread; queue a message to set the value - SetColorModeMessage( GetEventThreadServices(), GetNode(), colorMode ); -} - -ColorMode Actor::GetColorMode() const -{ - // we have cached copy - return mColorMode; + SetColorModeMessage(GetEventThreadServices(), GetNode(), colorMode); } -void Actor::SetSize( float width, float height ) +void Actor::SetSize(float width, float height) { - SetSize( Vector2( width, height ) ); + SetSize(Vector2(width, height)); } -void Actor::SetSize( float width, float height, float depth ) +void Actor::SetSize(float width, float height, float depth) { - SetSize( Vector3( width, height, depth ) ); + SetSize(Vector3(width, height, depth)); } -void Actor::SetSize( const Vector2& size ) +void Actor::SetSize(const Vector2& size) { - SetSize( Vector3( size.width, size.height, 0.f ) ); + SetSize(Vector3(size.width, size.height, 0.f)); } -void Actor::SetSizeInternal( const Vector2& size ) +void Actor::SetSizeInternal(const Vector2& size) { - SetSizeInternal( Vector3( size.width, size.height, 0.f ) ); + SetSizeInternal(Vector3(size.width, size.height, 0.f)); } -void Actor::SetSize( const Vector3& size ) +void Actor::SetSize(const Vector3& size) { - if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout ) + if(IsRelayoutEnabled() && !mRelayoutData->insideRelayout) { // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!! - SetPreferredSize( size.GetVectorXY() ); + SetPreferredSize(size.GetVectorXY()); } else { - SetSizeInternal( size ); + SetSizeInternal(size); } } -void Actor::SetSizeInternal( const Vector3& size ) +void Actor::SetSizeInternal(const Vector3& size) { // dont allow recursive loop - DALI_ASSERT_ALWAYS( !mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet" ); + DALI_ASSERT_ALWAYS(!mInsideOnSizeSet && "Cannot call SetSize from OnSizeSet"); // 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 - if( ( fabsf( mTargetSize.width - size.width ) > Math::MACHINE_EPSILON_1 )|| - ( fabsf( mTargetSize.height- size.height ) > Math::MACHINE_EPSILON_1 )|| - ( fabsf( mTargetSize.depth - size.depth ) > Math::MACHINE_EPSILON_1 ) ) + Vector3 currentSize = GetCurrentSize(); + + if((fabsf(mTargetSize.width - size.width) > Math::MACHINE_EPSILON_1) || + (fabsf(mTargetSize.height - size.height) > Math::MACHINE_EPSILON_1) || + (fabsf(mTargetSize.depth - size.depth) > Math::MACHINE_EPSILON_1) || + (fabsf(mTargetSize.width - currentSize.width) > Math::MACHINE_EPSILON_1) || + (fabsf(mTargetSize.height - currentSize.height) > Math::MACHINE_EPSILON_1) || + (fabsf(mTargetSize.depth - currentSize.depth) > Math::MACHINE_EPSILON_1)) { mTargetSize = size; // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodeTransformPropertyMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler::Bake, mTargetSize ); + SceneGraph::NodeTransformPropertyMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler::Bake, mTargetSize); // Notification for derived classes mInsideOnSizeSet = true; - OnSizeSet( mTargetSize ); + OnSizeSet(mTargetSize); mInsideOnSizeSet = false; // Raise a relayout request if the flag is not locked - if( mRelayoutData && !mRelayoutData->insideRelayout ) + if(mRelayoutData && !mRelayoutData->insideRelayout) { RelayoutRequest(); } } } -void Actor::SetWidth( float width ) +void Actor::SetWidth(float width) { - if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout ) + if(IsRelayoutEnabled() && !mRelayoutData->insideRelayout) { - SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH ); + SetResizePolicy(ResizePolicy::FIXED, Dimension::WIDTH); mRelayoutData->preferredSize.width = width; } else @@ -1159,7 +787,7 @@ void Actor::SetWidth( float width ) mTargetSize.width = width; // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodeTransformComponentMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler::BakeX, width ); + SceneGraph::NodeTransformComponentMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler::BakeX, width); } mUseAnimatedSize &= ~AnimatedSizeFlag::WIDTH; @@ -1167,11 +795,11 @@ void Actor::SetWidth( float width ) RelayoutRequest(); } -void Actor::SetHeight( float height ) +void Actor::SetHeight(float height) { - if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout ) + if(IsRelayoutEnabled() && !mRelayoutData->insideRelayout) { - SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT ); + SetResizePolicy(ResizePolicy::FIXED, Dimension::HEIGHT); mRelayoutData->preferredSize.height = height; } else @@ -1179,7 +807,7 @@ void Actor::SetHeight( float height ) mTargetSize.height = height; // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodeTransformComponentMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler::BakeY, height ); + SceneGraph::NodeTransformComponentMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler::BakeY, height); } mUseAnimatedSize &= ~AnimatedSizeFlag::HEIGHT; @@ -1187,21 +815,21 @@ void Actor::SetHeight( float height ) RelayoutRequest(); } -void Actor::SetDepth( float depth ) +void Actor::SetDepth(float depth) { mTargetSize.depth = depth; mUseAnimatedSize &= ~AnimatedSizeFlag::DEPTH; // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodeTransformComponentMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler::BakeZ, depth ); + SceneGraph::NodeTransformComponentMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler::BakeZ, depth); } Vector3 Actor::GetTargetSize() const { Vector3 size = mTargetSize; - if( mUseAnimatedSize & AnimatedSizeFlag::WIDTH ) + if(mUseAnimatedSize & AnimatedSizeFlag::WIDTH) { // Should return animated size if size is animated size.width = mAnimatedSize.width; @@ -1209,25 +837,25 @@ Vector3 Actor::GetTargetSize() const else { // Should return preferred size if size is fixed as set by SetSize - if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED ) + if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::FIXED) { size.width = GetPreferredSize().width; } } - if( mUseAnimatedSize & AnimatedSizeFlag::HEIGHT ) + if(mUseAnimatedSize & AnimatedSizeFlag::HEIGHT) { size.height = mAnimatedSize.height; } else { - if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED ) + if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::FIXED) { size.height = GetPreferredSize().height; } } - if( mUseAnimatedSize & AnimatedSizeFlag::DEPTH ) + if(mUseAnimatedSize & AnimatedSizeFlag::DEPTH) { size.depth = mAnimatedSize.depth; } @@ -1238,171 +866,79 @@ Vector3 Actor::GetTargetSize() const const Vector3& Actor::GetCurrentSize() const { // node is being used in a separate thread; copy the value from the previous update - return GetNode().GetSize( GetEventThreadServices().GetEventBufferIndex() ); + return GetNode().GetSize(GetEventThreadServices().GetEventBufferIndex()); } Vector3 Actor::GetNaturalSize() const { // It is up to deriving classes to return the appropriate natural size - return Vector3( 0.0f, 0.0f, 0.0f ); + return Vector3(0.0f, 0.0f, 0.0f); } -void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension ) +void Actor::SetResizePolicy(ResizePolicy::Type policy, Dimension::Type dimension) { - EnsureRelayoutData(); + EnsureRelayouter().SetResizePolicy(policy, dimension, mTargetSize); + + OnSetResizePolicy(policy, dimension); - ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH); - ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT); + // Trigger relayout on this control + RelayoutRequest(); +} - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) +ResizePolicy::Type Actor::GetResizePolicy(Dimension::Type dimension) const +{ + if(mRelayoutData) { - if( dimension & ( 1 << i ) ) - { - if ( policy == ResizePolicy::USE_ASSIGNED_SIZE ) - { - mRelayoutData->useAssignedSize[ i ] = true; - } - else - { - mRelayoutData->resizePolicies[ i ] = policy; - mRelayoutData->useAssignedSize[ i ] = false; - } - } + return mRelayoutData->GetResizePolicy(dimension); } - if( policy == ResizePolicy::DIMENSION_DEPENDENCY ) - { - if( dimension & Dimension::WIDTH ) - { - SetDimensionDependency( Dimension::WIDTH, Dimension::HEIGHT ); - } + return ResizePolicy::DEFAULT; +} - if( dimension & Dimension::HEIGHT ) - { - SetDimensionDependency( Dimension::HEIGHT, Dimension::WIDTH ); - } - } +void Actor::SetSizeScalePolicy(SizeScalePolicy::Type policy) +{ + EnsureRelayouter(); - // If calling SetResizePolicy, assume we want relayout enabled - SetRelayoutEnabled( true ); + mRelayoutData->sizeSetPolicy = policy; - // If the resize policy is set to be FIXED, the preferred size - // should be overrided by the target size. Otherwise the target - // size should be overrided by the preferred size. + // Trigger relayout on this control + RelayoutRequest(); +} - if( dimension & Dimension::WIDTH ) +SizeScalePolicy::Type Actor::GetSizeScalePolicy() const +{ + if(mRelayoutData) { - if( originalWidthPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED ) - { - mRelayoutData->preferredSize.width = mTargetSize.width; - } - else if( originalWidthPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED ) - { - mTargetSize.width = mRelayoutData->preferredSize.width; - } + return mRelayoutData->sizeSetPolicy; } - if( dimension & Dimension::HEIGHT ) - { - if( originalHeightPolicy != ResizePolicy::FIXED && policy == ResizePolicy::FIXED ) - { - mRelayoutData->preferredSize.height = mTargetSize.height; - } - else if( originalHeightPolicy == ResizePolicy::FIXED && policy != ResizePolicy::FIXED ) - { - mTargetSize.height = mRelayoutData->preferredSize.height; - } - } - - OnSetResizePolicy( policy, dimension ); - - // Trigger relayout on this control - RelayoutRequest(); -} - -ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const -{ - if ( mRelayoutData ) - { - // If more than one dimension is requested, just return the first one found - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) - { - if( ( dimension & ( 1 << i ) ) ) - { - if( mRelayoutData->useAssignedSize[ i ] ) - { - return ResizePolicy::USE_ASSIGNED_SIZE; - } - else - { - return mRelayoutData->resizePolicies[ i ]; - } - } - } - } - - return ResizePolicy::DEFAULT; -} - -void Actor::SetSizeScalePolicy( SizeScalePolicy::Type policy ) -{ - EnsureRelayoutData(); - - mRelayoutData->sizeSetPolicy = policy; - - // Trigger relayout on this control - RelayoutRequest(); -} - -SizeScalePolicy::Type Actor::GetSizeScalePolicy() const -{ - if ( mRelayoutData ) - { - return mRelayoutData->sizeSetPolicy; - } - - return DEFAULT_SIZE_SCALE_POLICY; + return Relayouter::DEFAULT_SIZE_SCALE_POLICY; } -void Actor::SetDimensionDependency( Dimension::Type dimension, Dimension::Type dependency ) +void Actor::SetDimensionDependency(Dimension::Type dimension, Dimension::Type dependency) { - EnsureRelayoutData(); - - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) - { - if( dimension & ( 1 << i ) ) - { - mRelayoutData->dimensionDependencies[ i ] = dependency; - } - } + EnsureRelayouter().SetDimensionDependency(dimension, dependency); } -Dimension::Type Actor::GetDimensionDependency( Dimension::Type dimension ) const +Dimension::Type Actor::GetDimensionDependency(Dimension::Type dimension) const { - if ( mRelayoutData ) + if(mRelayoutData) { - // If more than one dimension is requested, just return the first one found - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) - { - if( ( dimension & ( 1 << i ) ) ) - { - return mRelayoutData->dimensionDependencies[ i ]; - } - } + return mRelayoutData->GetDimensionDependency(dimension); } - return Dimension::ALL_DIMENSIONS; // Default + return Dimension::ALL_DIMENSIONS; // Default } -void Actor::SetRelayoutEnabled( bool relayoutEnabled ) +void Actor::SetRelayoutEnabled(bool relayoutEnabled) { // If relayout data has not been allocated yet and the client is requesting // to disable it, do nothing - if( mRelayoutData || relayoutEnabled ) + if(mRelayoutData || relayoutEnabled) { - EnsureRelayoutData(); + EnsureRelayouter(); - DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" ); + DALI_ASSERT_DEBUG(mRelayoutData && "mRelayoutData not created"); mRelayoutData->relayoutEnabled = relayoutEnabled; } @@ -1415,587 +951,262 @@ bool Actor::IsRelayoutEnabled() const return mRelayoutData && mRelayoutData->relayoutEnabled; } -void Actor::SetLayoutDirty( bool dirty, Dimension::Type dimension ) +void Actor::SetLayoutDirty(bool dirty, Dimension::Type dimension) { - EnsureRelayoutData(); - - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) - { - if( dimension & ( 1 << i ) ) - { - mRelayoutData->dimensionDirty[ i ] = dirty; - } - } + EnsureRelayouter().SetLayoutDirty(dirty, dimension); } -bool Actor::IsLayoutDirty( Dimension::Type dimension ) const +bool Actor::IsLayoutDirty(Dimension::Type dimension) const { - if ( mRelayoutData ) - { - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) - { - if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] ) - { - return true; - } - } - } - - return false; + return mRelayoutData && mRelayoutData->IsLayoutDirty(dimension); } -bool Actor::RelayoutPossible( Dimension::Type dimension ) const +bool Actor::RelayoutPossible(Dimension::Type dimension) const { - return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension ); + return mRelayoutData && mRelayoutData->relayoutEnabled && !IsLayoutDirty(dimension); } -bool Actor::RelayoutRequired( Dimension::Type dimension ) const +bool Actor::RelayoutRequired(Dimension::Type dimension) const { - return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension ); + return mRelayoutData && mRelayoutData->relayoutEnabled && IsLayoutDirty(dimension); } -uint32_t Actor::AddRenderer( Renderer& renderer ) +uint32_t Actor::AddRenderer(Renderer& renderer) { - if( !mRenderers ) + if(!mRenderers) { mRenderers = new RendererContainer; } - uint32_t index = static_cast( mRenderers->size() ); // 4,294,967,295 renderers per actor - RendererPtr rendererPtr = RendererPtr( &renderer ); - mRenderers->push_back( rendererPtr ); - AttachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() ); + if(mIsBlendEquationSet) + { + renderer.SetBlendEquation(static_cast(mBlendEquation)); + } + + uint32_t index = static_cast(mRenderers->size()); // 4,294,967,295 renderers per actor + RendererPtr rendererPtr = RendererPtr(&renderer); + mRenderers->push_back(rendererPtr); + AttachRendererMessage(GetEventThreadServices().GetUpdateManager(), GetNode(), renderer.GetRendererSceneObject()); return index; } uint32_t Actor::GetRendererCount() const { uint32_t rendererCount(0); - if( mRenderers ) + if(mRenderers) { - rendererCount = static_cast( mRenderers->size() ); // 4,294,967,295 renderers per actor + rendererCount = static_cast(mRenderers->size()); // 4,294,967,295 renderers per actor } return rendererCount; } -RendererPtr Actor::GetRendererAt( uint32_t index ) +RendererPtr Actor::GetRendererAt(uint32_t index) { RendererPtr renderer; - if( index < GetRendererCount() ) + if(index < GetRendererCount()) { - renderer = ( *mRenderers )[ index ]; + renderer = (*mRenderers)[index]; } return renderer; } -void Actor::RemoveRenderer( Renderer& renderer ) +void Actor::RemoveRenderer(Renderer& renderer) { - if( mRenderers ) + if(mRenderers) { RendererIter end = mRenderers->end(); - for( RendererIter iter = mRenderers->begin(); iter != end; ++iter ) + for(RendererIter iter = mRenderers->begin(); iter != end; ++iter) { - if( (*iter).Get() == &renderer ) + if((*iter).Get() == &renderer) { - mRenderers->erase( iter ); - DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject() ); + mRenderers->erase(iter); + DetachRendererMessage(GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject()); break; } } } } -void Actor::RemoveRenderer( uint32_t index ) -{ - if( index < GetRendererCount() ) - { - RendererPtr renderer = ( *mRenderers )[ index ]; - DetachRendererMessage( GetEventThreadServices(), GetNode(), renderer.Get()->GetRendererSceneObject() ); - mRenderers->erase( mRenderers->begin()+index ); - } -} - -bool Actor::IsOverlay() const -{ - return ( DrawMode::OVERLAY_2D == mDrawMode ); -} - -void Actor::SetDrawMode( DrawMode::Type drawMode ) -{ - // this flag is not animatable so keep the value - mDrawMode = drawMode; - - // node is being used in a separate thread; queue a message to set the value - SetDrawModeMessage( GetEventThreadServices(), GetNode(), drawMode ); -} - -DrawMode::Type Actor::GetDrawMode() const +void Actor::RemoveRenderer(uint32_t index) { - return mDrawMode; -} - -bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const -{ - // only valid when on-stage - if( mScene && OnScene() ) + if(index < GetRendererCount()) { - const RenderTaskList& taskList = mScene->GetRenderTaskList(); - - Vector2 converted( screenX, screenY ); - - // do a reverse traversal of all lists (as the default onscreen one is typically the last one) - uint32_t taskCount = taskList.GetTaskCount(); - for( uint32_t i = taskCount; i > 0; --i ) - { - RenderTaskPtr task = taskList.GetTask( i - 1 ); - if( ScreenToLocal( *task, localX, localY, screenX, screenY ) ) - { - // found a task where this conversion was ok so return - return true; - } - } + RendererPtr renderer = (*mRenderers)[index]; + DetachRendererMessage(GetEventThreadServices(), GetNode(), renderer.Get()->GetRendererSceneObject()); + mRenderers->erase(mRenderers->begin() + index); } - return false; } -bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const +void Actor::SetBlendEquation(DevelBlendEquation::Type blendEquation) { - bool retval = false; - // only valid when on-stage - if( OnScene() ) + if(Dali::Capabilities::IsBlendEquationSupported(blendEquation)) { - CameraActor* camera = renderTask.GetCameraActor(); - if( camera ) + if(mBlendEquation != blendEquation) { - Viewport viewport; - renderTask.GetViewport( viewport ); - - // need to translate coordinates to render tasks coordinate space - Vector2 converted( screenX, screenY ); - if( renderTask.TranslateCoordinates( converted ) ) + mBlendEquation = blendEquation; + uint32_t rendererCount = GetRendererCount(); + for(uint32_t i = 0; i < rendererCount; ++i) { - retval = ScreenToLocal( camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y ); + RendererPtr renderer = GetRendererAt(i); + renderer->SetBlendEquation(static_cast(blendEquation)); } } + mIsBlendEquationSet = true; } - return retval; -} - -bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const -{ - // Early-out if not on stage - if( !OnScene() ) - { - return false; - } - - // Get the ModelView matrix - Matrix modelView; - Matrix::Multiply( modelView, GetNode().GetWorldMatrix(0), viewMatrix ); - - // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects - Matrix invertedMvp( false/*don't init*/); - Matrix::Multiply( invertedMvp, modelView, projectionMatrix ); - bool success = invertedMvp.Invert(); - - // Convert to GL coordinates - Vector4 screenPos( screenX - static_cast( viewport.x ), static_cast( viewport.height ) - screenY - static_cast( viewport.y ), 0.f, 1.f ); - - Vector4 nearPos; - if( success ) - { - success = Unproject( screenPos, invertedMvp, static_cast( viewport.width ), static_cast( viewport.height ), nearPos ); - } - - Vector4 farPos; - if( success ) - { - screenPos.z = 1.0f; - success = Unproject( screenPos, invertedMvp, static_cast( viewport.width ), static_cast( viewport.height ), farPos ); - } - - if( success ) - { - Vector4 local; - if( XyPlaneIntersect( nearPos, farPos, local ) ) - { - Vector3 size = GetCurrentSize(); - localX = local.x + size.x * 0.5f; - localY = local.y + size.y * 0.5f; - } - else - { - success = false; - } - } - - return success; -} - -bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const -{ - /* - http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection - - Mathematical Formulation - - Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if - - ( p - c ) dot ( p - c ) = r^2 - - Given a ray with a point of origin 'o', and a direction vector 'd': - - ray(t) = o + td, t >= 0 - - we can find the t at which the ray intersects the sphere by setting ray(t) equal to 'p' - - (o + td - c ) dot ( o + td - c ) = r^2 - - To solve for t we first expand the above into a more recognisable quadratic equation form - - ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0 - - or - - At2 + Bt + C = 0 - - where - - A = d dot d - B = 2( o - c ) dot d - C = ( o - c ) dot ( o - c ) - r^2 - - which can be solved using a standard quadratic formula. - - Note that in the absence of positive, real, roots, the ray does not intersect the sphere. - - Practical Simplification - - In a renderer, we often differentiate between world space and object space. In the object space - of a sphere it is centred at origin, meaning that if we first transform the ray from world space - into object space, the mathematical solution presented above can be simplified significantly. - - If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if - - p dot p = r^2 - - and we can find the t at which the (transformed) ray intersects the sphere by - - ( o + td ) dot ( o + td ) = r^2 - - According to the reasoning above, we expand the above quadratic equation into the general form - - At2 + Bt + C = 0 - - which now has coefficients: - - A = d dot d - B = 2( d dot o ) - C = o dot o - r^2 - */ - - // Early-out if not on stage - if( !OnScene() ) - { - return false; - } - - BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() ); - - // Transforms the ray to the local reference system. As the test is against a sphere, only the translation and scale are needed. - const Vector3& translation( GetNode().GetWorldPosition( bufferIndex ) ); - Vector3 rayOriginLocal( rayOrigin.x - translation.x, rayOrigin.y - translation.y, rayOrigin.z - translation.z ); - - // Compute the radius is not needed, square radius it's enough. - const Vector3& size( GetNode().GetSize( bufferIndex ) ); - - // Scale the sphere. - const Vector3& scale( GetNode().GetWorldScale( bufferIndex ) ); - - const float width = size.width * scale.width; - const float height = size.height * scale.height; - - float squareSphereRadius = 0.5f * ( width * width + height * height ); - - float a = rayDir.Dot( rayDir ); // a - float b2 = rayDir.Dot( rayOriginLocal ); // b/2 - float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius; // c - - return ( b2 * b2 - a * c ) >= 0.f; -} - -bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const -{ - bool hit = false; - - if( OnScene() ) + else { - // Transforms the ray to the local reference system. - // Calculate the inverse of Model matrix - Matrix invModelMatrix( false/*don't init*/); - - BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() ); - invModelMatrix = GetNode().GetWorldMatrix(0); - invModelMatrix.Invert(); - - Vector4 rayOriginLocal( invModelMatrix * rayOrigin ); - Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() ); - - // Test with the actor's XY plane (Normal = 0 0 1 1). - - float a = -rayOriginLocal.z; - float b = rayDirLocal.z; - - if( fabsf( b ) > Math::MACHINE_EPSILON_1 ) - { - // Ray travels distance * rayDirLocal to intersect with plane. - distance = a / b; - - const Vector3& size = GetNode().GetSize( bufferIndex ); - - hitPointLocal.x = rayOriginLocal.x + rayDirLocal.x * distance + size.x * 0.5f; - hitPointLocal.y = rayOriginLocal.y + rayDirLocal.y * distance + size.y * 0.5f; - - // Test with the actor's geometry. - hit = ( hitPointLocal.x >= 0.f ) && ( hitPointLocal.x <= size.x ) && ( hitPointLocal.y >= 0.f ) && ( hitPointLocal.y <= size.y ); - } + DALI_LOG_ERROR("Invalid blend equation is entered.\n"); } - - return hit; } -void Actor::SetLeaveRequired( bool required ) +DevelBlendEquation::Type Actor::GetBlendEquation() const { - mLeaveRequired = required; + return mBlendEquation; } -bool Actor::GetLeaveRequired() const +void Actor::SetTransparent(bool transparent) { - return mLeaveRequired; + SetTransparentMessage(GetEventThreadServices(), GetNode(), transparent); } -void Actor::SetKeyboardFocusable( bool focusable ) +bool Actor::IsTransparent() const { - mKeyboardFocusable = focusable; + return GetNode().IsTransparent(); } -bool Actor::IsKeyboardFocusable() const +void Actor::SetDrawMode(DrawMode::Type drawMode) { - return mKeyboardFocusable; -} + // this flag is not animatable so keep the value + mDrawMode = drawMode; -bool Actor::GetTouchRequired() const -{ - return !mTouchedSignal.Empty(); + // node is being used in a separate thread; queue a message to set the value + SetDrawModeMessage(GetEventThreadServices(), GetNode(), drawMode); } -bool Actor::GetHoverRequired() const +bool Actor::ScreenToLocal(float& localX, float& localY, float screenX, float screenY) const { - return !mHoveredSignal.Empty(); + return mScene && OnScene() && ConvertScreenToLocalRenderTaskList(mScene->GetRenderTaskList(), GetNode().GetWorldMatrix(0), GetCurrentSize(), localX, localY, screenX, screenY); } -bool Actor::GetWheelEventRequired() const +bool Actor::ScreenToLocal(const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY) const { - return !mWheelEventSignal.Empty(); + return OnScene() && ConvertScreenToLocalRenderTask(renderTask, GetNode().GetWorldMatrix(0), GetCurrentSize(), localX, localY, screenX, screenY); } -bool Actor::IsHittable() const +bool Actor::ScreenToLocal(const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY) const { - return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected(); + return OnScene() && ConvertScreenToLocal(viewMatrix, projectionMatrix, GetNode().GetWorldMatrix(0), GetCurrentSize(), viewport, localX, localY, screenX, screenY); } ActorGestureData& Actor::GetGestureData() { // Likely scenario is that once gesture-data is created for this actor, the actor will require // that gesture for its entire life-time so no need to destroy it until the actor is destroyed - if( NULL == mGestureData ) + if(nullptr == mGestureData) { mGestureData = new ActorGestureData; } return *mGestureData; } -bool Actor::IsGestureRequired( GestureType::Value type ) const -{ - return mGestureData && mGestureData->IsGestureRequired( type ); -} - -bool Actor::EmitTouchEventSignal( const Dali::TouchEvent& touch ) -{ - bool consumed = false; - - if( !mTouchedSignal.Empty() ) - { - Dali::Actor handle( this ); - consumed = mTouchedSignal.Emit( handle, touch ); - } - - return consumed; -} - -bool Actor::EmitHoverEventSignal( const Dali::HoverEvent& event ) -{ - bool consumed = false; - - if( !mHoveredSignal.Empty() ) - { - Dali::Actor handle( this ); - consumed = mHoveredSignal.Emit( handle, event ); - } - - return consumed; -} - -bool Actor::EmitWheelEventSignal( const Dali::WheelEvent& event ) -{ - bool consumed = false; - - if( !mWheelEventSignal.Empty() ) - { - Dali::Actor handle( this ); - consumed = mWheelEventSignal.Emit( handle, event ); - } - - return consumed; -} - -void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type ) -{ - if( ! mVisibilityChangedSignal.Empty() ) - { - Dali::Actor handle( this ); - mVisibilityChangedSignal.Emit( handle, visible, type ); - } -} - -void Actor::EmitLayoutDirectionChangedSignal( LayoutDirection::Type type ) -{ - if( ! mLayoutDirectionChangedSignal.Empty() ) - { - Dali::Actor handle( this ); - mLayoutDirectionChangedSignal.Emit( handle, type ); - } -} - -void Actor::EmitChildAddedSignal( Actor& child ) -{ - if( ! mChildAddedSignal.Empty() ) - { - Dali::Actor handle( &child ); - mChildAddedSignal.Emit( handle ); - } -} - -void Actor::EmitChildRemovedSignal( Actor& child ) -{ - if( ! mChildRemovedSignal.Empty() ) - { - Dali::Actor handle( &child ); - mChildRemovedSignal.Emit( handle ); - } -} - -Dali::Actor::TouchEventSignalType& Actor::TouchedSignal() +bool Actor::IsGestureRequired(GestureType::Value type) const { - return mTouchedSignal; + return mGestureData && mGestureData->IsGestureRequired(type); } -Dali::Actor::HoverSignalType& Actor::HoveredSignal() +bool Actor::EmitInterceptTouchEventSignal(const Dali::TouchEvent& touch) { - return mHoveredSignal; + return EmitConsumingSignal(*this, mInterceptTouchedSignal, touch); } -Dali::Actor::WheelEventSignalType& Actor::WheelEventSignal() +bool Actor::EmitTouchEventSignal(const Dali::TouchEvent& touch) { - return mWheelEventSignal; + return EmitConsumingSignal(*this, mTouchedSignal, touch); } -Dali::Actor::OnSceneSignalType& Actor::OnSceneSignal() +bool Actor::EmitHoverEventSignal(const Dali::HoverEvent& event) { - return mOnSceneSignal; + return EmitConsumingSignal(*this, mHoveredSignal, event); } -Dali::Actor::OffSceneSignalType& Actor::OffSceneSignal() +bool Actor::EmitWheelEventSignal(const Dali::WheelEvent& event) { - return mOffSceneSignal; + return EmitConsumingSignal(*this, mWheelEventSignal, event); } -Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal() +void Actor::EmitVisibilityChangedSignal(bool visible, DevelActor::VisibilityChange::Type type) { - return mOnRelayoutSignal; + EmitSignal(*this, mVisibilityChangedSignal, visible, type); } -DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal() +void Actor::EmitLayoutDirectionChangedSignal(LayoutDirection::Type type) { - return mVisibilityChangedSignal; -} - -Dali::Actor::LayoutDirectionChangedSignalType& Actor::LayoutDirectionChangedSignal() -{ - return mLayoutDirectionChangedSignal; + EmitSignal(*this, mLayoutDirectionChangedSignal, type); } DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal() { - return mChildAddedSignal; + return mParentImpl.ChildAddedSignal(); } DevelActor::ChildChangedSignalType& Actor::ChildRemovedSignal() { - return mChildRemovedSignal; + return mParentImpl.ChildRemovedSignal(); } DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal() { - return mChildOrderChangedSignal; + return mParentImpl.ChildOrderChangedSignal(); } -bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor ) +bool Actor::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor) { - bool connected( true ); - Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type. + bool connected(true); + Actor* actor = static_cast(object); // TypeRegistry guarantees that this is the correct type. + + std::string_view name(signalName); - if( 0 == signalName.compare( SIGNAL_HOVERED ) ) + if(name == SIGNAL_HOVERED) { - actor->HoveredSignal().Connect( tracker, functor ); + actor->HoveredSignal().Connect(tracker, functor); } - else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) ) + else if(signalName == SIGNAL_WHEEL_EVENT) { - actor->WheelEventSignal().Connect( tracker, functor ); + actor->WheelEventSignal().Connect(tracker, functor); } - else if( 0 == signalName.compare( SIGNAL_ON_SCENE ) ) + else if(name == SIGNAL_ON_SCENE) { - actor->OnSceneSignal().Connect( tracker, functor ); + actor->OnSceneSignal().Connect(tracker, functor); } - else if( 0 == signalName.compare( SIGNAL_OFF_SCENE ) ) + else if(name == SIGNAL_OFF_SCENE) { - actor->OffSceneSignal().Connect( tracker, functor ); + actor->OffSceneSignal().Connect(tracker, functor); } - else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) ) + else if(name == SIGNAL_ON_RELAYOUT) { - actor->OnRelayoutSignal().Connect( tracker, functor ); + actor->OnRelayoutSignal().Connect(tracker, functor); } - else if( 0 == signalName.compare( SIGNAL_TOUCHED ) ) + else if(name == SIGNAL_TOUCHED) { - actor->TouchedSignal().Connect( tracker, functor ); + actor->TouchedSignal().Connect(tracker, functor); } - else if( 0 == signalName.compare( SIGNAL_VISIBILITY_CHANGED ) ) + else if(name == SIGNAL_VISIBILITY_CHANGED) { - actor->VisibilityChangedSignal().Connect( tracker, functor ); + actor->VisibilityChangedSignal().Connect(tracker, functor); } - else if( 0 == signalName.compare( SIGNAL_LAYOUT_DIRECTION_CHANGED ) ) + else if(name == SIGNAL_LAYOUT_DIRECTION_CHANGED) { - actor->LayoutDirectionChangedSignal().Connect( tracker, functor ); + actor->LayoutDirectionChangedSignal().Connect(tracker, functor); } - else if( 0 == signalName.compare( SIGNAL_CHILD_ADDED ) ) + else if(name == SIGNAL_CHILD_ADDED) { - actor->ChildAddedSignal().Connect( tracker, functor ); + actor->ChildAddedSignal().Connect(tracker, functor); } - else if( 0 == signalName.compare( SIGNAL_CHILD_REMOVED ) ) + else if(name == SIGNAL_CHILD_REMOVED) { - actor->ChildRemovedSignal().Connect( tracker, functor ); + actor->ChildRemovedSignal().Connect(tracker, functor); } else { @@ -2006,16 +1217,17 @@ bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tra return connected; } -Actor::Actor( DerivedType derivedType, const SceneGraph::Node& node ) -: Object( &node ), - mScene( nullptr ), - mParent( NULL ), - mChildren( NULL ), - mRenderers( NULL ), - mParentOrigin( NULL ), - mAnchorPoint( NULL ), - mRelayoutData( NULL ), - mGestureData( NULL ), +Actor::Actor(DerivedType derivedType, const SceneGraph::Node& node) +: Object(&node), + mParentImpl(*this), + mParent(nullptr), + mScene(nullptr), + mRenderers(nullptr), + mParentOrigin(nullptr), + mAnchorPoint(nullptr), + mRelayoutData(nullptr), + mGestureData(nullptr), + mInterceptTouchedSignal(), mTouchedSignal(), mHoveredSignal(), mWheelEventSignal(), @@ -2024,38 +1236,41 @@ Actor::Actor( DerivedType derivedType, const SceneGraph::Node& node ) mOnRelayoutSignal(), mVisibilityChangedSignal(), mLayoutDirectionChangedSignal(), - mChildAddedSignal(), - mChildRemovedSignal(), - mChildOrderChangedSignal(), - mTargetOrientation( Quaternion::IDENTITY ), - mTargetColor( Color::WHITE ), - mTargetSize( Vector3::ZERO ), - mTargetPosition( Vector3::ZERO ), - mTargetScale( Vector3::ONE ), - mAnimatedSize( Vector3::ZERO ), + mTargetOrientation(Quaternion::IDENTITY), + mTargetColor(Color::WHITE), + mTargetSize(Vector3::ZERO), + mTargetPosition(Vector3::ZERO), + mTargetScale(Vector3::ONE), + mAnimatedSize(Vector3::ZERO), + mTouchAreaOffset(0, 0, 0, 0), mName(), - mSortedDepth( 0u ), - mDepth( 0u ), - mUseAnimatedSize( AnimatedSizeFlag::CLEAR ), - mIsRoot( ROOT_LAYER == derivedType ), - mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ), - mIsOnScene( false ), - mSensitive( true ), - mLeaveRequired( false ), - mKeyboardFocusable( false ), - mOnSceneSignalled( false ), - mInsideOnSizeSet( false ), - mInheritPosition( true ), - mInheritOrientation( true ), - mInheritScale( true ), - mPositionUsesAnchorPoint( true ), - mVisible( true ), - mInheritLayoutDirection( true ), - mCaptureAllTouchAfterStart( false ), - mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ), - mDrawMode( DrawMode::NORMAL ), - mColorMode( Node::DEFAULT_COLOR_MODE ), - mClippingMode( ClippingMode::DISABLED ) + mSortedDepth(0u), + mDepth(0u), + mUseAnimatedSize(AnimatedSizeFlag::CLEAR), + mIsRoot(ROOT_LAYER == derivedType), + mIsLayer(LAYER == derivedType || ROOT_LAYER == derivedType), + mIsOnScene(false), + mSensitive(true), + mLeaveRequired(false), + mKeyboardFocusable(false), + mKeyboardFocusableChildren(true), + mTouchFocusable(false), + mOnSceneSignalled(false), + mInsideOnSizeSet(false), + mInheritPosition(true), + mInheritOrientation(true), + mInheritScale(true), + mPositionUsesAnchorPoint(true), + mVisible(true), + mInheritLayoutDirection(true), + mCaptureAllTouchAfterStart(false), + mIsBlendEquationSet(false), + mNeedGesturePropagation(false), + mLayoutDirection(LayoutDirection::LEFT_TO_RIGHT), + mDrawMode(DrawMode::NORMAL), + mColorMode(Node::DEFAULT_COLOR_MODE), + mClippingMode(ClippingMode::DISABLED), + mBlendEquation(DevelBlendEquation::ADD) { } @@ -2063,33 +1278,25 @@ void Actor::Initialize() { OnInitialize(); - GetEventThreadServices().RegisterObject( this ); + GetEventThreadServices().RegisterObject(this); } Actor::~Actor() { // Remove mParent pointers from children even if we're destroying core, // to guard against GetParent() & Unparent() calls from CustomActor destructors. - if( mChildren ) - { - ActorConstIter endIter = mChildren->end(); - for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter ) - { - (*iter)->SetParent( NULL ); - } - } - delete mChildren; + UnparentChildren(); delete mRenderers; // Guard to allow handle destruction after Core has been destroyed - if( EventThreadServices::IsCoreRunning() ) + if(EventThreadServices::IsCoreRunning()) { // Root layer will destroy its node in its own destructor - if ( !mIsRoot ) + if(!mIsRoot) { - DestroyNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() ); + DestroyNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode()); - GetEventThreadServices().UnregisterObject( this ); + GetEventThreadServices().UnregisterObject(this); } } @@ -2104,36 +1311,92 @@ Actor::~Actor() delete mRelayoutData; } -void Actor::ConnectToScene( uint32_t parentDepth ) +void Actor::Add(Actor& child, bool notify) { - // This container is used instead of walking the Actor hierarchy. - // It protects us when the Actor hierarchy is modified during OnSceneConnectionExternal callbacks. - ActorContainer connectionList; + mParentImpl.Add(child, notify); +} - if( mScene ) +void Actor::Remove(Actor& child, bool notify) +{ + mParentImpl.Remove(child, notify); +} + +void Actor::SwitchParent(Actor& newParent) +{ + if(this == &newParent) { - mScene->RequestRebuildDepthTree(); + DALI_LOG_ERROR("Cannot add actor to itself"); + return; } - // This stage is atomic i.e. not interrupted by user callbacks. - RecursiveConnectToScene( connectionList, parentDepth + 1 ); - - // Notify applications about the newly connected actors. - const ActorIter endIter = connectionList.end(); - for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter ) + if(!this->OnScene() || !newParent.OnScene()) { - (*iter)->NotifyStageConnection(); + DALI_LOG_ERROR("Both of current parent and new parent must be on Scene"); + return; } - RelayoutRequest(); + newParent.Add(*this, false); } -void Actor::RecursiveConnectToScene( ActorContainer& connectionList, uint32_t depth ) +uint32_t Actor::GetChildCount() const { - DALI_ASSERT_ALWAYS( !OnScene() ); + return mParentImpl.GetChildCount(); +} - mIsOnScene = true; - mDepth = static_cast< uint16_t >( depth ); // overflow ignored, not expected in practice +ActorPtr Actor::GetChildAt(uint32_t index) const +{ + return mParentImpl.GetChildAt(index); +} + +ActorContainer& Actor::GetChildrenInternal() +{ + return mParentImpl.GetChildrenInternal(); +} + +ActorPtr Actor::FindChildByName(ConstString actorName) +{ + return mParentImpl.FindChildByName(actorName); +} + +ActorPtr Actor::FindChildById(const uint32_t id) +{ + return mParentImpl.FindChildById(id); +} + +void Actor::UnparentChildren() +{ + mParentImpl.UnparentChildren(); +} + +void Actor::ConnectToScene(uint32_t parentDepth, bool notify) +{ + // This container is used instead of walking the Actor hierarchy. + // It protects us when the Actor hierarchy is modified during OnSceneConnectionExternal callbacks. + ActorContainer connectionList; + + if(mScene) + { + mScene->RequestRebuildDepthTree(); + } + + // This stage is atomic i.e. not interrupted by user callbacks. + RecursiveConnectToScene(connectionList, parentDepth + 1); + + // Notify applications about the newly connected actors. + for(const auto& actor : connectionList) + { + actor->NotifyStageConnection(notify); + } + + RelayoutRequest(); +} + +void Actor::RecursiveConnectToScene(ActorContainer& connectionList, uint32_t depth) +{ + DALI_ASSERT_ALWAYS(!OnScene()); + + mIsOnScene = true; + mDepth = static_cast(depth); // overflow ignored, not expected in practice ConnectToSceneGraph(); @@ -2141,16 +1404,15 @@ void Actor::RecursiveConnectToScene( ActorContainer& connectionList, uint32_t de OnSceneConnectionInternal(); // This stage is atomic; avoid emitting callbacks until all Actors are connected - connectionList.push_back( ActorPtr( this ) ); + connectionList.push_back(ActorPtr(this)); // Recursively connect children - if( mChildren ) + if(GetChildCount() > 0) { - ActorConstIter endIter = mChildren->end(); - for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter ) + for(const auto& child : mParentImpl.GetChildrenInternal()) { - (*iter)->SetScene( *mScene ); - (*iter)->RecursiveConnectToScene( connectionList, depth + 1 ); + child->SetScene(*mScene); + child->RecursiveConnectToScene(connectionList, depth + 1); } } } @@ -2163,10 +1425,10 @@ void Actor::RecursiveConnectToScene( ActorContainer& connectionList, uint32_t de */ void Actor::ConnectToSceneGraph() { - DALI_ASSERT_DEBUG( mParent != NULL); + DALI_ASSERT_DEBUG(mParent != NULL); // Reparent Node in next Update - ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), mParent->GetNode(), GetNode() ); + ConnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetParent()->GetNode(), GetNode()); // Request relayout on all actors that are added to the scenegraph RelayoutRequest(); @@ -2175,68 +1437,69 @@ void Actor::ConnectToSceneGraph() OnSceneObjectAdd(); } -void Actor::NotifyStageConnection() +void Actor::NotifyStageConnection(bool notify) { // Actors can be removed (in a callback), before the on-stage stage is reported. // The actor may also have been reparented, in which case mOnSceneSignalled will be true. - if( OnScene() && !mOnSceneSignalled ) + if(OnScene() && !mOnSceneSignalled) { - // Notification for external (CustomActor) derived classes - OnSceneConnectionExternal( mDepth ); - - if( !mOnSceneSignal.Empty() ) + if(notify) { - Dali::Actor handle( this ); - mOnSceneSignal.Emit( handle ); + // Notification for external (CustomActor) derived classes + OnSceneConnectionExternal(mDepth); + + if(!mOnSceneSignal.Empty()) + { + Dali::Actor handle(this); + mOnSceneSignal.Emit(handle); + } } // Guard against Remove during callbacks - if( OnScene() ) + if(OnScene()) { mOnSceneSignalled = true; // signal required next time Actor is removed } } } -void Actor::DisconnectFromStage() +void Actor::DisconnectFromStage(bool notify) { // This container is used instead of walking the Actor hierachy. // It protects us when the Actor hierachy is modified during OnSceneDisconnectionExternal callbacks. ActorContainer disconnectionList; - if( mScene ) + if(mScene) { mScene->RequestRebuildDepthTree(); } // This stage is atomic i.e. not interrupted by user callbacks - RecursiveDisconnectFromStage( disconnectionList ); + RecursiveDisconnectFromStage(disconnectionList); // Notify applications about the newly disconnected actors. - const ActorIter endIter = disconnectionList.end(); - for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter ) + for(const auto& actor : disconnectionList) { - (*iter)->NotifyStageDisconnection(); + actor->NotifyStageDisconnection(notify); } } -void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList ) +void Actor::RecursiveDisconnectFromStage(ActorContainer& disconnectionList) { // need to change state first so that internals relying on IsOnScene() inside OnSceneDisconnectionInternal() get the correct value mIsOnScene = false; // Recursively disconnect children - if( mChildren ) + if(GetChildCount() > 0) { - ActorConstIter endIter = mChildren->end(); - for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter ) + for(const auto& child : mParentImpl.GetChildrenInternal()) { - (*iter)->RecursiveDisconnectFromStage( disconnectionList ); + child->RecursiveDisconnectFromStage(disconnectionList); } } // This stage is atomic; avoid emitting callbacks until all Actors are disconnected - disconnectionList.push_back( ActorPtr( this ) ); + disconnectionList.push_back(ActorPtr(this)); // Notification for internal derived classes OnSceneDisconnectionInternal(); @@ -2254,24 +1517,27 @@ void Actor::DisconnectFromSceneGraph() OnSceneObjectRemove(); } -void Actor::NotifyStageDisconnection() +void Actor::NotifyStageDisconnection(bool notify) { // Actors can be added (in a callback), before the off-stage state is reported. // Also if the actor was added & removed before mOnSceneSignalled was set, then we don't notify here. // only do this step if there is a stage, i.e. Core is not being shut down - if ( EventThreadServices::IsCoreRunning() && !OnScene() && mOnSceneSignalled ) + if(EventThreadServices::IsCoreRunning() && !OnScene() && mOnSceneSignalled) { - // Notification for external (CustomeActor) derived classes - OnSceneDisconnectionExternal(); - - if( !mOffSceneSignal.Empty() ) + if(notify) { - Dali::Actor handle( this ); - mOffSceneSignal.Emit( handle ); + // Notification for external (CustomeActor) derived classes + OnSceneDisconnectionExternal(); + + if(!mOffSceneSignal.Empty()) + { + Dali::Actor handle(this); + mOffSceneSignal.Emit(handle); + } } // Guard against Add during callbacks - if( !OnScene() ) + if(!OnScene()) { mOnSceneSignalled = false; // signal required next time Actor is added } @@ -2280,11 +1546,11 @@ void Actor::NotifyStageDisconnection() bool Actor::IsNodeConnected() const { - bool connected( false ); + bool connected(false); - if( OnScene() ) + if(OnScene()) { - if( IsRoot() || GetNode().GetParent() ) + if(IsRoot() || GetNode().GetParent()) { connected = true; } @@ -2305,2891 +1571,821 @@ void Actor::RebuildDepthTree() // Vector of scene-graph nodes and their depths to send to UpdateManager // in a single message - OwnerPointer sceneGraphNodeDepths( new SceneGraph::NodeDepths() ); + OwnerPointer sceneGraphNodeDepths(new SceneGraph::NodeDepths()); int32_t depthIndex = 1; - DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex ); + DepthTraverseActorTree(sceneGraphNodeDepths, depthIndex); - SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths ); + SetDepthIndicesMessage(GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths); DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: "); } -void Actor::DepthTraverseActorTree( OwnerPointer& sceneGraphNodeDepths, int32_t& depthIndex ) +void Actor::DepthTraverseActorTree(OwnerPointer& sceneGraphNodeDepths, int32_t& depthIndex) { mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER; - sceneGraphNodeDepths->Add( const_cast( &GetNode() ), mSortedDepth ); + sceneGraphNodeDepths->Add(const_cast(&GetNode()), mSortedDepth); // Create/add to children of this node - if( mChildren ) + if(GetChildCount() > 0) { - for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it ) + for(const auto& child : mParentImpl.GetChildrenInternal()) { - Actor* childActor = (*it).Get(); + Actor* childActor = child.Get(); ++depthIndex; - childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex ); + childActor->DepthTraverseActorTree(sceneGraphNodeDepths, depthIndex); } } } -void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property ) +void Actor::SetDefaultProperty(Property::Index index, const Property::Value& property) +{ + PropertyHandler::SetDefaultProperty(*this, index, property); +} + +// TODO: This method needs to be removed +void Actor::SetSceneGraphProperty(Property::Index index, const PropertyMetadata& entry, const Property::Value& value) +{ + PropertyHandler::SetSceneGraphProperty(index, entry, value, GetEventThreadServices(), GetNode()); +} + +Property::Value Actor::GetDefaultProperty(Property::Index index) const { - switch( index ) + Property::Value value; + + if(!GetCachedPropertyValue(index, value)) { - case Dali::Actor::Property::PARENT_ORIGIN: - { - Property::Type type = property.GetType(); - if( type == Property::VECTOR3 ) - { - SetParentOrigin( property.Get< Vector3 >() ); - } - else if ( type == Property::STRING ) - { - std::string parentOriginString; - property.Get( parentOriginString ); - Vector3 parentOrigin; - if( GetParentOriginConstant( parentOriginString, parentOrigin ) ) - { - SetParentOrigin( parentOrigin ); - } - } - break; - } + // If property value is not stored in the event-side, then it must be a scene-graph only property + GetCurrentPropertyValue(index, value); + } - case Dali::Actor::Property::PARENT_ORIGIN_X: - { - SetParentOriginX( property.Get< float >() ); - break; - } + return value; +} - case Dali::Actor::Property::PARENT_ORIGIN_Y: - { - SetParentOriginY( property.Get< float >() ); - break; - } +Property::Value Actor::GetDefaultPropertyCurrentValue(Property::Index index) const +{ + Property::Value value; - case Dali::Actor::Property::PARENT_ORIGIN_Z: - { - SetParentOriginZ( property.Get< float >() ); - break; - } + if(!GetCurrentPropertyValue(index, value)) + { + // If unable to retrieve scene-graph property value, then it must be an event-side only property + GetCachedPropertyValue(index, value); + } - case Dali::Actor::Property::ANCHOR_POINT: - { - Property::Type type = property.GetType(); - if( type == Property::VECTOR3 ) - { - SetAnchorPoint( property.Get< Vector3 >() ); - } - else if ( type == Property::STRING ) - { - std::string anchorPointString; - property.Get( anchorPointString ); - Vector3 anchor; - if( GetAnchorPointConstant( anchorPointString, anchor ) ) - { - SetAnchorPoint( anchor ); - } - } - break; - } + return value; +} - case Dali::Actor::Property::ANCHOR_POINT_X: - { - SetAnchorPointX( property.Get< float >() ); - break; - } +void Actor::OnNotifyDefaultPropertyAnimation(Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType) +{ + PropertyHandler::OnNotifyDefaultPropertyAnimation(*this, animation, index, value, animationType); +} - case Dali::Actor::Property::ANCHOR_POINT_Y: - { - SetAnchorPointY( property.Get< float >() ); - break; - } +const PropertyBase* Actor::GetSceneObjectAnimatableProperty(Property::Index index) const +{ + const PropertyBase* property = PropertyHandler::GetSceneObjectAnimatableProperty(index, GetNode()); + if(!property) + { + // not our property, ask base + property = Object::GetSceneObjectAnimatableProperty(index); + } - case Dali::Actor::Property::ANCHOR_POINT_Z: - { - SetAnchorPointZ( property.Get< float >() ); - break; - } + return property; +} - case Dali::Actor::Property::SIZE: - { - Property::Type type = property.GetType(); - if( type == Property::VECTOR2 ) - { - SetSize( property.Get< Vector2 >() ); - } - else if ( type == Property::VECTOR3 ) - { - SetSize( property.Get< Vector3 >() ); - } - break; - } +const PropertyInputImpl* Actor::GetSceneObjectInputProperty(Property::Index index) const +{ + const PropertyInputImpl* property = PropertyHandler::GetSceneObjectInputProperty(index, GetNode()); + if(!property) + { + // reuse animatable property getter as animatable properties are inputs as well + // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered + property = GetSceneObjectAnimatableProperty(index); + } - case Dali::Actor::Property::SIZE_WIDTH: - { - SetWidth( property.Get< float >() ); - break; - } + return property; +} - case Dali::Actor::Property::SIZE_HEIGHT: - { - SetHeight( property.Get< float >() ); - break; - } +int32_t Actor::GetPropertyComponentIndex(Property::Index index) const +{ + int32_t componentIndex = PropertyHandler::GetPropertyComponentIndex(index); + if(Property::INVALID_COMPONENT_INDEX == componentIndex) + { + // ask base + componentIndex = Object::GetPropertyComponentIndex(index); + } - case Dali::Actor::Property::SIZE_DEPTH: - { - SetDepth( property.Get< float >() ); - break; - } + return componentIndex; +} - case Dali::Actor::Property::POSITION: - { - Property::Type type = property.GetType(); - if( type == Property::VECTOR2 ) - { - Vector2 position = property.Get< Vector2 >(); - SetPosition( Vector3( position.x, position.y, 0.0f ) ); - } - else if ( type == Property::VECTOR3 ) - { - SetPosition( property.Get< Vector3 >() ); - } - break; - } +const SceneGraph::Node& Actor::GetNode() const +{ + return *static_cast(mUpdateObject); +} - case Dali::Actor::Property::POSITION_X: - { - SetX( property.Get< float >() ); - break; - } +void Actor::Raise() +{ + if(mParent) + { + mParent->RaiseChild(*this); + } + else + { + DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n"); + } +} - case Dali::Actor::Property::POSITION_Y: - { - SetY( property.Get< float >() ); - break; - } +void Actor::Lower() +{ + if(mParent) + { + mParent->LowerChild(*this); + } + else + { + DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n"); + } +} - case Dali::Actor::Property::POSITION_Z: - { - SetZ( property.Get< float >() ); - break; - } +void Actor::RaiseToTop() +{ + if(mParent) + { + mParent->RaiseChildToTop(*this); + } + else + { + DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n"); + } +} - case Dali::Actor::Property::ORIENTATION: - { - SetOrientation( property.Get< Quaternion >() ); - break; - } +void Actor::LowerToBottom() +{ + if(mParent) + { + mParent->LowerChildToBottom(*this); + } + else + { + DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n"); + } +} - case Dali::Actor::Property::SCALE: - { - Property::Type type = property.GetType(); - if( type == Property::FLOAT ) - { - float scale = property.Get< float >(); - SetScale( scale, scale, scale ); - } - else if ( type == Property::VECTOR3 ) - { - SetScale( property.Get< Vector3 >() ); - } - break; - } +void Actor::RaiseAbove(Internal::Actor& target) +{ + if(mParent) + { + mParent->RaiseChildAbove(*this, target); + } + else + { + DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n"); + } +} - case Dali::Actor::Property::SCALE_X: - { - SetScaleX( property.Get< float >() ); - break; - } +void Actor::LowerBelow(Internal::Actor& target) +{ + if(mParent) + { + mParent->LowerChildBelow(*this, target); + } + else + { + DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n"); + } +} - case Dali::Actor::Property::SCALE_Y: - { - SetScaleY( property.Get< float >() ); - break; - } +void Actor::SetParent(ActorParent* parent, bool notify) +{ + if(parent) + { + DALI_ASSERT_ALWAYS(!mParent && "Actor cannot have 2 parents"); - case Dali::Actor::Property::SCALE_Z: - { - SetScaleZ( property.Get< float >() ); - break; - } + mParent = parent; + Actor* parentActor = static_cast(parent); + mScene = parentActor->mScene; - case Dali::Actor::Property::VISIBLE: + if(EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction + parentActor->OnScene()) { - SetVisible( property.Get< bool >() ); - break; + // Instruct each actor to create a corresponding node in the scene graph + ConnectToScene(parentActor->GetHierarchyDepth(), notify); } - case Dali::Actor::Property::COLOR: - { - Property::Type type = property.GetType(); - if( type == Property::VECTOR3 ) - { - Vector3 color = property.Get< Vector3 >(); - SetColor( Vector4( color.r, color.g, color.b, 1.0f ) ); - } - else if( type == Property::VECTOR4 ) - { - SetColor( property.Get< Vector4 >() ); - } - break; - } + // Resolve the name and index for the child properties if any + ResolveChildProperties(); + } + else // parent being set to NULL + { + DALI_ASSERT_ALWAYS(mParent != nullptr && "Actor should have a parent"); - case Dali::Actor::Property::COLOR_RED: - { - SetColorRed( property.Get< float >() ); - break; - } + mParent = nullptr; - case Dali::Actor::Property::COLOR_GREEN: + if(EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction + OnScene()) { - SetColorGreen( property.Get< float >() ); - break; + // Disconnect the Node & its children from the scene-graph. + DisconnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode()); + + // Instruct each actor to discard pointers to the scene-graph + DisconnectFromStage(notify); } - case Dali::Actor::Property::COLOR_BLUE: + mScene = nullptr; + } +} + +bool Actor::DoAction(BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */) +{ + bool done = false; + Actor* actor = dynamic_cast(object); + + if(actor) + { + std::string_view name(actionName); + if(name == ACTION_SHOW) { - SetColorBlue( property.Get< float >() ); - break; + actor->SetVisible(true); + done = true; } - - case Dali::Actor::Property::COLOR_ALPHA: - case Dali::Actor::Property::OPACITY: + else if(name == ACTION_HIDE) { - float value; - if( property.Get( value ) ) - { - SetOpacity( value ); - } - break; + actor->SetVisible(false); + done = true; } + } - case Dali::Actor::Property::NAME: - { - SetName( property.Get< std::string >() ); - break; - } - - case Dali::Actor::Property::SENSITIVE: - { - SetSensitive( property.Get< bool >() ); - break; - } - - case Dali::Actor::Property::LEAVE_REQUIRED: - { - SetLeaveRequired( property.Get< bool >() ); - break; - } - - case Dali::Actor::Property::INHERIT_POSITION: - { - SetInheritPosition( property.Get< bool >() ); - break; - } - - case Dali::Actor::Property::INHERIT_ORIENTATION: - { - SetInheritOrientation( property.Get< bool >() ); - break; - } - - case Dali::Actor::Property::INHERIT_SCALE: - { - SetInheritScale( property.Get< bool >() ); - break; - } - - case Dali::Actor::Property::COLOR_MODE: - { - ColorMode mode = mColorMode; - if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) ) - { - SetColorMode( mode ); - } - break; - } - - case Dali::Actor::Property::DRAW_MODE: - { - DrawMode::Type mode = mDrawMode; - if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) ) - { - SetDrawMode( mode ); - } - break; - } - - case Dali::Actor::Property::SIZE_MODE_FACTOR: - { - SetSizeModeFactor( property.Get< Vector3 >() ); - break; - } - - case Dali::Actor::Property::WIDTH_RESIZE_POLICY: - { - ResizePolicy::Type type = GetResizePolicy( Dimension::WIDTH ); - if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) ) - { - SetResizePolicy( type, Dimension::WIDTH ); - } - break; - } - - case Dali::Actor::Property::HEIGHT_RESIZE_POLICY: - { - ResizePolicy::Type type = GetResizePolicy( Dimension::HEIGHT ); - if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) ) - { - SetResizePolicy( type, Dimension::HEIGHT ); - } - break; - } - - case Dali::Actor::Property::SIZE_SCALE_POLICY: - { - SizeScalePolicy::Type type = GetSizeScalePolicy(); - if( Scripting::GetEnumerationProperty< SizeScalePolicy::Type >( property, SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) ) - { - SetSizeScalePolicy( type ); - } - break; - } - - case Dali::Actor::Property::WIDTH_FOR_HEIGHT: - { - if( property.Get< bool >() ) - { - SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::WIDTH ); - } - break; - } - - case Dali::Actor::Property::HEIGHT_FOR_WIDTH: - { - if( property.Get< bool >() ) - { - SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT ); - } - break; - } - - case Dali::Actor::Property::PADDING: - { - Vector4 padding = property.Get< Vector4 >(); - SetPadding( Vector2( padding.x, padding.y ), Dimension::WIDTH ); - SetPadding( Vector2( padding.z, padding.w ), Dimension::HEIGHT ); - break; - } - - case Dali::Actor::Property::MINIMUM_SIZE: - { - Vector2 size = property.Get< Vector2 >(); - SetMinimumSize( size.x, Dimension::WIDTH ); - SetMinimumSize( size.y, Dimension::HEIGHT ); - break; - } - - case Dali::Actor::Property::MAXIMUM_SIZE: - { - Vector2 size = property.Get< Vector2 >(); - SetMaximumSize( size.x, Dimension::WIDTH ); - SetMaximumSize( size.y, Dimension::HEIGHT ); - break; - } - - case Dali::DevelActor::Property::SIBLING_ORDER: - { - int value; - - if( property.Get( value ) ) - { - SetSiblingOrder( value ); - } - break; - } - - case Dali::Actor::Property::CLIPPING_MODE: - { - ClippingMode::Type convertedValue = mClippingMode; - if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) ) - { - mClippingMode = convertedValue; - SetClippingModeMessage( GetEventThreadServices(), GetNode(), mClippingMode ); - } - break; - } - - case Dali::Actor::Property::POSITION_USES_ANCHOR_POINT: - { - bool value = false; - if( property.Get( value ) && value != mPositionUsesAnchorPoint ) - { - mPositionUsesAnchorPoint = value; - SetPositionUsesAnchorPointMessage( GetEventThreadServices(), GetNode(), mPositionUsesAnchorPoint ); - } - break; - } - - case Dali::Actor::Property::LAYOUT_DIRECTION: - { - Dali::LayoutDirection::Type direction = mLayoutDirection; - mInheritLayoutDirection = false; - - if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) ) - { - InheritLayoutDirectionRecursively( this, direction, true ); - } - break; - } - - case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION: - { - bool value = false; - if( property.Get( value ) ) - { - SetInheritLayoutDirection( value ); - } - break; - } - - case Dali::Actor::Property::KEYBOARD_FOCUSABLE: - { - bool value = false; - if( property.Get( value ) ) - { - SetKeyboardFocusable( value ); - } - break; - } - - case Dali::DevelActor::Property::UPDATE_SIZE_HINT: - { - SetUpdateSizeHint( property.Get< Vector2 >() ); - break; - } - - case Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START: - { - bool boolValue = false; - if ( property.Get( boolValue ) ) - { - mCaptureAllTouchAfterStart = boolValue; - } - break; - } - - default: - { - // this can happen in the case of a non-animatable default property so just do nothing - break; - } - } -} - -// TODO: This method needs to be removed -void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value ) -{ - switch( entry.GetType() ) - { - case Property::BOOLEAN: - { - const AnimatableProperty< bool >* property = dynamic_cast< const AnimatableProperty< bool >* >( entry.GetSceneGraphProperty() ); - DALI_ASSERT_DEBUG( NULL != property ); - - // property is being used in a separate thread; queue a message to set the property - SceneGraph::NodePropertyMessage::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty::Bake, value.Get() ); - - break; - } - - case Property::INTEGER: - { - const AnimatableProperty< int >* property = dynamic_cast< const AnimatableProperty< int >* >( entry.GetSceneGraphProperty() ); - DALI_ASSERT_DEBUG( NULL != property ); - - // property is being used in a separate thread; queue a message to set the property - SceneGraph::NodePropertyMessage::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty::Bake, value.Get() ); - - break; - } - - case Property::FLOAT: - { - const AnimatableProperty< float >* property = dynamic_cast< const AnimatableProperty< float >* >( entry.GetSceneGraphProperty() ); - DALI_ASSERT_DEBUG( NULL != property ); - - // property is being used in a separate thread; queue a message to set the property - SceneGraph::NodePropertyMessage::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty::Bake, value.Get() ); - - break; - } - - case Property::VECTOR2: - { - const AnimatableProperty< Vector2 >* property = dynamic_cast< const AnimatableProperty< Vector2 >* >( entry.GetSceneGraphProperty() ); - DALI_ASSERT_DEBUG( NULL != property ); - - // property is being used in a separate thread; queue a message to set the property - if(entry.componentIndex == 0) - { - SceneGraph::NodePropertyComponentMessage::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty::BakeX, value.Get() ); - } - else if(entry.componentIndex == 1) - { - SceneGraph::NodePropertyComponentMessage::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty::BakeY, value.Get() ); - } - else - { - SceneGraph::NodePropertyMessage::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty::Bake, value.Get() ); - } - - break; - } - - case Property::VECTOR3: - { - const AnimatableProperty< Vector3 >* property = dynamic_cast< const AnimatableProperty< Vector3 >* >( entry.GetSceneGraphProperty() ); - DALI_ASSERT_DEBUG( NULL != property ); - - // property is being used in a separate thread; queue a message to set the property - if(entry.componentIndex == 0) - { - SceneGraph::NodePropertyComponentMessage::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty::BakeX, value.Get() ); - } - else if(entry.componentIndex == 1) - { - SceneGraph::NodePropertyComponentMessage::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty::BakeY, value.Get() ); - } - else if(entry.componentIndex == 2) - { - SceneGraph::NodePropertyComponentMessage::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty::BakeZ, value.Get() ); - } - else - { - SceneGraph::NodePropertyMessage::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty::Bake, value.Get() ); - } - - break; - } - - case Property::VECTOR4: - { - const AnimatableProperty< Vector4 >* property = dynamic_cast< const AnimatableProperty< Vector4 >* >( entry.GetSceneGraphProperty() ); - DALI_ASSERT_DEBUG( NULL != property ); - - // property is being used in a separate thread; queue a message to set the property - if(entry.componentIndex == 0) - { - SceneGraph::NodePropertyComponentMessage::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty::BakeX, value.Get() ); - } - else if(entry.componentIndex == 1) - { - SceneGraph::NodePropertyComponentMessage::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty::BakeY, value.Get() ); - } - else if(entry.componentIndex == 2) - { - SceneGraph::NodePropertyComponentMessage::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty::BakeZ, value.Get() ); - } - else if(entry.componentIndex == 3) - { - SceneGraph::NodePropertyComponentMessage::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty::BakeW, value.Get() ); - } - else - { - SceneGraph::NodePropertyMessage::Send( GetEventThreadServices(), &GetNode(), property, &AnimatableProperty::Bake, value.Get() ); - } - - break; - } - - case Property::ROTATION: - { - const AnimatableProperty< Quaternion >* property = dynamic_cast< const AnimatableProperty< Quaternion >* >( entry.GetSceneGraphProperty() ); - DALI_ASSERT_DEBUG( NULL != property ); - - // property is being used in a separate thread; queue a message to set the property - SceneGraph::NodePropertyMessage::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty::Bake, value.Get() ); - - break; - } - - case Property::MATRIX: - { - const AnimatableProperty< Matrix >* property = dynamic_cast< const AnimatableProperty< Matrix >* >( entry.GetSceneGraphProperty() ); - DALI_ASSERT_DEBUG( NULL != property ); - - // property is being used in a separate thread; queue a message to set the property - SceneGraph::NodePropertyMessage::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty::Bake, value.Get() ); - - break; - } - - case Property::MATRIX3: - { - const AnimatableProperty< Matrix3 >* property = dynamic_cast< const AnimatableProperty< Matrix3 >* >( entry.GetSceneGraphProperty() ); - DALI_ASSERT_DEBUG( NULL != property ); - - // property is being used in a separate thread; queue a message to set the property - SceneGraph::NodePropertyMessage::Send( GetEventThreadServices(), &GetNode(), property,&AnimatableProperty::Bake, value.Get() ); - - break; - } - - default: - { - // nothing to do for other types - } - } // entry.GetType -} - -Property::Value Actor::GetDefaultProperty( Property::Index index ) const -{ - Property::Value value; - - if( ! GetCachedPropertyValue( index, value ) ) - { - // If property value is not stored in the event-side, then it must be a scene-graph only property - GetCurrentPropertyValue( index, value ); - } - - return value; -} - -Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const -{ - Property::Value value; - - if( ! GetCurrentPropertyValue( index, value ) ) - { - // If unable to retrieve scene-graph property value, then it must be an event-side only property - GetCachedPropertyValue( index, value ); - } - - return value; -} - -void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType ) -{ - switch( animationType ) - { - case Animation::TO: - case Animation::BETWEEN: - { - switch( index ) - { - case Dali::Actor::Property::SIZE: - { - if( value.Get( mTargetSize ) ) - { - mAnimatedSize = mTargetSize; - mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH; - - // Notify deriving classes - OnSizeAnimation( animation, mTargetSize ); - } - break; - } - - case Dali::Actor::Property::SIZE_WIDTH: - { - if( value.Get( mTargetSize.width ) ) - { - mAnimatedSize.width = mTargetSize.width; - mUseAnimatedSize |= AnimatedSizeFlag::WIDTH; - - // Notify deriving classes - OnSizeAnimation( animation, mTargetSize ); - } - break; - } - - case Dali::Actor::Property::SIZE_HEIGHT: - { - if( value.Get( mTargetSize.height ) ) - { - mAnimatedSize.height = mTargetSize.height; - mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT; - - // Notify deriving classes - OnSizeAnimation( animation, mTargetSize ); - } - break; - } - - case Dali::Actor::Property::SIZE_DEPTH: - { - if( value.Get( mTargetSize.depth ) ) - { - mAnimatedSize.depth = mTargetSize.depth; - mUseAnimatedSize |= AnimatedSizeFlag::DEPTH; - - // Notify deriving classes - OnSizeAnimation( animation, mTargetSize ); - } - break; - } - - case Dali::Actor::Property::POSITION: - { - value.Get( mTargetPosition ); - break; - } - - case Dali::Actor::Property::POSITION_X: - { - value.Get( mTargetPosition.x ); - break; - } - - case Dali::Actor::Property::POSITION_Y: - { - value.Get( mTargetPosition.y ); - break; - } - - case Dali::Actor::Property::POSITION_Z: - { - value.Get( mTargetPosition.z ); - break; - } - - case Dali::Actor::Property::ORIENTATION: - { - value.Get( mTargetOrientation ); - break; - } - - case Dali::Actor::Property::SCALE: - { - value.Get( mTargetScale ); - break; - } - - case Dali::Actor::Property::SCALE_X: - { - value.Get( mTargetScale.x ); - break; - } - - case Dali::Actor::Property::SCALE_Y: - { - value.Get( mTargetScale.y ); - break; - } - - case Dali::Actor::Property::SCALE_Z: - { - value.Get( mTargetScale.z ); - break; - } - - case Dali::Actor::Property::VISIBLE: - { - SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE ); - break; - } - - case Dali::Actor::Property::COLOR: - { - value.Get( mTargetColor ); - break; - } - - case Dali::Actor::Property::COLOR_RED: - { - value.Get( mTargetColor.r ); - break; - } - - case Dali::Actor::Property::COLOR_GREEN: - { - value.Get( mTargetColor.g ); - break; - } - - case Dali::Actor::Property::COLOR_BLUE: - { - value.Get( mTargetColor.b ); - break; - } - - case Dali::Actor::Property::COLOR_ALPHA: - case Dali::Actor::Property::OPACITY: - { - value.Get( mTargetColor.a ); - break; - } - - default: - { - // Not an animatable property. Do nothing. - break; - } - } - break; - } - - case Animation::BY: - { - switch( index ) - { - case Dali::Actor::Property::SIZE: - { - if( AdjustValue< Vector3 >( mTargetSize, value ) ) - { - mAnimatedSize = mTargetSize; - mUseAnimatedSize = AnimatedSizeFlag::WIDTH | AnimatedSizeFlag::HEIGHT | AnimatedSizeFlag::DEPTH; - - // Notify deriving classes - OnSizeAnimation( animation, mTargetSize ); - } - break; - } - - case Dali::Actor::Property::SIZE_WIDTH: - { - if( AdjustValue< float >( mTargetSize.width, value ) ) - { - mAnimatedSize.width = mTargetSize.width; - mUseAnimatedSize |= AnimatedSizeFlag::WIDTH; - - // Notify deriving classes - OnSizeAnimation( animation, mTargetSize ); - } - break; - } - - case Dali::Actor::Property::SIZE_HEIGHT: - { - if( AdjustValue< float >( mTargetSize.height, value ) ) - { - mAnimatedSize.height = mTargetSize.height; - mUseAnimatedSize |= AnimatedSizeFlag::HEIGHT; - - // Notify deriving classes - OnSizeAnimation( animation, mTargetSize ); - } - break; - } - - case Dali::Actor::Property::SIZE_DEPTH: - { - if( AdjustValue< float >( mTargetSize.depth, value ) ) - { - mAnimatedSize.depth = mTargetSize.depth; - mUseAnimatedSize |= AnimatedSizeFlag::DEPTH; - - // Notify deriving classes - OnSizeAnimation( animation, mTargetSize ); - } - break; - } - - case Dali::Actor::Property::POSITION: - { - AdjustValue< Vector3 >( mTargetPosition, value ); - break; - } - - case Dali::Actor::Property::POSITION_X: - { - AdjustValue< float >( mTargetPosition.x, value ); - break; - } - - case Dali::Actor::Property::POSITION_Y: - { - AdjustValue< float >( mTargetPosition.y, value ); - break; - } - - case Dali::Actor::Property::POSITION_Z: - { - AdjustValue< float >( mTargetPosition.z, value ); - break; - } - - case Dali::Actor::Property::ORIENTATION: - { - Quaternion relativeValue; - if( value.Get( relativeValue ) ) - { - mTargetOrientation *= relativeValue; - } - break; - } - - case Dali::Actor::Property::SCALE: - { - AdjustValue< Vector3 >( mTargetScale, value ); - break; - } - - case Dali::Actor::Property::SCALE_X: - { - AdjustValue< float >( mTargetScale.x, value ); - break; - } - - case Dali::Actor::Property::SCALE_Y: - { - AdjustValue< float >( mTargetScale.y, value ); - break; - } - - case Dali::Actor::Property::SCALE_Z: - { - AdjustValue< float >( mTargetScale.z, value ); - break; - } - - case Dali::Actor::Property::VISIBLE: - { - bool relativeValue = false; - if( value.Get( relativeValue ) ) - { - bool visible = mVisible || relativeValue; - SetVisibleInternal( visible, SendMessage::FALSE ); - } - break; - } - - case Dali::Actor::Property::COLOR: - { - AdjustValue< Vector4 >( mTargetColor, value ); - break; - } - - case Dali::Actor::Property::COLOR_RED: - { - AdjustValue< float >( mTargetColor.r, value ); - break; - } - - case Dali::Actor::Property::COLOR_GREEN: - { - AdjustValue< float >( mTargetColor.g, value ); - break; - } - - case Dali::Actor::Property::COLOR_BLUE: - { - AdjustValue< float >( mTargetColor.b, value ); - break; - } - - case Dali::Actor::Property::COLOR_ALPHA: - case Dali::Actor::Property::OPACITY: - { - AdjustValue< float >( mTargetColor.a, value ); - break; - } - - default: - { - // Not an animatable property. Do nothing. - break; - } - } - break; - } - } -} - -const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const -{ - const PropertyBase* property( NULL ); - - switch( index ) - { - case Dali::Actor::Property::SIZE: // FALLTHROUGH - case Dali::Actor::Property::SIZE_WIDTH: // FALLTHROUGH - case Dali::Actor::Property::SIZE_HEIGHT: // FALLTHROUGH - case Dali::Actor::Property::SIZE_DEPTH: - { - property = &GetNode().mSize; - break; - } - case Dali::Actor::Property::POSITION: // FALLTHROUGH - case Dali::Actor::Property::POSITION_X: // FALLTHROUGH - case Dali::Actor::Property::POSITION_Y: // FALLTHROUGH - case Dali::Actor::Property::POSITION_Z: - { - property = &GetNode().mPosition; - break; - } - case Dali::Actor::Property::ORIENTATION: - { - property = &GetNode().mOrientation; - break; - } - case Dali::Actor::Property::SCALE: // FALLTHROUGH - case Dali::Actor::Property::SCALE_X: // FALLTHROUGH - case Dali::Actor::Property::SCALE_Y: // FALLTHROUGH - case Dali::Actor::Property::SCALE_Z: - { - property = &GetNode().mScale; - break; - } - case Dali::Actor::Property::VISIBLE: - { - property = &GetNode().mVisible; - break; - } - case Dali::Actor::Property::COLOR: // FALLTHROUGH - case Dali::Actor::Property::COLOR_RED: // FALLTHROUGH - case Dali::Actor::Property::COLOR_GREEN: // FALLTHROUGH - case Dali::Actor::Property::COLOR_BLUE: // FALLTHROUGH - case Dali::Actor::Property::COLOR_ALPHA: // FALLTHROUGH - case Dali::Actor::Property::OPACITY: - { - property = &GetNode().mColor; - break; - } - default: - { - break; - } - } - if( !property ) - { - // not our property, ask base - property = Object::GetSceneObjectAnimatableProperty( index ); - } - - return property; -} - -const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const -{ - const PropertyInputImpl* property( NULL ); - - switch( index ) - { - case Dali::Actor::Property::PARENT_ORIGIN: // FALLTHROUGH - case Dali::Actor::Property::PARENT_ORIGIN_X: // FALLTHROUGH - case Dali::Actor::Property::PARENT_ORIGIN_Y: // FALLTHROUGH - case Dali::Actor::Property::PARENT_ORIGIN_Z: - { - property = &GetNode().mParentOrigin; - break; - } - case Dali::Actor::Property::ANCHOR_POINT: // FALLTHROUGH - case Dali::Actor::Property::ANCHOR_POINT_X: // FALLTHROUGH - case Dali::Actor::Property::ANCHOR_POINT_Y: // FALLTHROUGH - case Dali::Actor::Property::ANCHOR_POINT_Z: - { - property = &GetNode().mAnchorPoint; - break; - } - case Dali::Actor::Property::WORLD_POSITION: // FALLTHROUGH - case Dali::Actor::Property::WORLD_POSITION_X: // FALLTHROUGH - case Dali::Actor::Property::WORLD_POSITION_Y: // FALLTHROUGH - case Dali::Actor::Property::WORLD_POSITION_Z: - { - property = &GetNode().mWorldPosition; - break; - } - case Dali::Actor::Property::WORLD_ORIENTATION: - { - property = &GetNode().mWorldOrientation; - break; - } - case Dali::Actor::Property::WORLD_SCALE: - { - property = &GetNode().mWorldScale; - break; - } - case Dali::Actor::Property::WORLD_COLOR: - { - property = &GetNode().mWorldColor; - break; - } - case Dali::Actor::Property::WORLD_MATRIX: - { - property = &GetNode().mWorldMatrix; - break; - } - case Dali::Actor::Property::CULLED: - { - property = &GetNode().mCulled; - break; - } - default: - { - break; - } - } - if( !property ) - { - // reuse animatable property getter as animatable properties are inputs as well - // animatable property chains back to Object::GetSceneObjectInputProperty() so all properties get covered - property = GetSceneObjectAnimatableProperty( index ); - } - - return property; -} - -int32_t Actor::GetPropertyComponentIndex( Property::Index index ) const -{ - int32_t componentIndex = Property::INVALID_COMPONENT_INDEX; - - switch( index ) - { - case Dali::Actor::Property::PARENT_ORIGIN_X: - case Dali::Actor::Property::ANCHOR_POINT_X: - case Dali::Actor::Property::SIZE_WIDTH: - case Dali::Actor::Property::POSITION_X: - case Dali::Actor::Property::WORLD_POSITION_X: - case Dali::Actor::Property::SCALE_X: - case Dali::Actor::Property::COLOR_RED: - { - componentIndex = 0; - break; - } - - case Dali::Actor::Property::PARENT_ORIGIN_Y: - case Dali::Actor::Property::ANCHOR_POINT_Y: - case Dali::Actor::Property::SIZE_HEIGHT: - case Dali::Actor::Property::POSITION_Y: - case Dali::Actor::Property::WORLD_POSITION_Y: - case Dali::Actor::Property::SCALE_Y: - case Dali::Actor::Property::COLOR_GREEN: - { - componentIndex = 1; - break; - } - - case Dali::Actor::Property::PARENT_ORIGIN_Z: - case Dali::Actor::Property::ANCHOR_POINT_Z: - case Dali::Actor::Property::SIZE_DEPTH: - case Dali::Actor::Property::POSITION_Z: - case Dali::Actor::Property::WORLD_POSITION_Z: - case Dali::Actor::Property::SCALE_Z: - case Dali::Actor::Property::COLOR_BLUE: - { - componentIndex = 2; - break; - } - - case Dali::Actor::Property::COLOR_ALPHA: - case Dali::Actor::Property::OPACITY: - { - componentIndex = 3; - break; - } - - default: - { - // Do nothing - break; - } - } - if( Property::INVALID_COMPONENT_INDEX == componentIndex ) - { - // ask base - componentIndex = Object::GetPropertyComponentIndex( index ); - } - - return componentIndex; -} - -void Actor::SetParent( Actor* parent ) -{ - if( parent ) - { - DALI_ASSERT_ALWAYS( !mParent && "Actor cannot have 2 parents" ); - - mParent = parent; - - mScene = parent->mScene; - - if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction - parent->OnScene() ) - { - // Instruct each actor to create a corresponding node in the scene graph - ConnectToScene( parent->GetHierarchyDepth() ); - } - - // Resolve the name and index for the child properties if any - ResolveChildProperties(); - } - else // parent being set to NULL - { - DALI_ASSERT_ALWAYS( mParent != NULL && "Actor should have a parent" ); - - mParent = NULL; - - if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction - OnScene() ) - { - // Disconnect the Node & its children from the scene-graph. - DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), GetNode() ); - - // Instruct each actor to discard pointers to the scene-graph - DisconnectFromStage(); - } - - mScene = nullptr; - } -} - -bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ ) -{ - bool done = false; - Actor* actor = dynamic_cast< Actor* >( object ); - - if( actor ) - { - if( 0 == actionName.compare( ACTION_SHOW ) ) - { - actor->SetVisible( true ); - done = true; - } - else if( 0 == actionName.compare( ACTION_HIDE ) ) - { - actor->SetVisible( false ); - done = true; - } - } - - return done; -} - -Rect<> Actor::CalculateScreenExtents( ) const -{ - auto screenPosition = GetCurrentScreenPosition(); - Vector3 size = GetCurrentSize() * GetCurrentWorldScale(); - Vector3 anchorPointOffSet = size * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT ); - Vector2 position = Vector2( screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y ); - return { position.x, position.y, size.x, size.y }; -} - -bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const -{ - bool valueSet = true; - - switch( index ) - { - case Dali::Actor::Property::PARENT_ORIGIN: - { - value = GetCurrentParentOrigin(); - break; - } - - case Dali::Actor::Property::PARENT_ORIGIN_X: - { - value = GetCurrentParentOrigin().x; - break; - } - - case Dali::Actor::Property::PARENT_ORIGIN_Y: - { - value = GetCurrentParentOrigin().y; - break; - } - - case Dali::Actor::Property::PARENT_ORIGIN_Z: - { - value = GetCurrentParentOrigin().z; - break; - } - - case Dali::Actor::Property::ANCHOR_POINT: - { - value = GetCurrentAnchorPoint(); - break; - } - - case Dali::Actor::Property::ANCHOR_POINT_X: - { - value = GetCurrentAnchorPoint().x; - break; - } - - case Dali::Actor::Property::ANCHOR_POINT_Y: - { - value = GetCurrentAnchorPoint().y; - break; - } - - case Dali::Actor::Property::ANCHOR_POINT_Z: - { - value = GetCurrentAnchorPoint().z; - break; - } - - case Dali::Actor::Property::SIZE: - { - value = GetTargetSize(); - break; - } - - case Dali::Actor::Property::SIZE_WIDTH: - { - value = GetTargetSize().width; - break; - } - - case Dali::Actor::Property::SIZE_HEIGHT: - { - value = GetTargetSize().height; - break; - } - - case Dali::Actor::Property::SIZE_DEPTH: - { - value = GetTargetSize().depth; - break; - } - - case Dali::Actor::Property::POSITION: - { - value = GetTargetPosition(); - break; - } - - case Dali::Actor::Property::POSITION_X: - { - value = GetTargetPosition().x; - break; - } - - case Dali::Actor::Property::POSITION_Y: - { - value = GetTargetPosition().y; - break; - } - - case Dali::Actor::Property::POSITION_Z: - { - value = GetTargetPosition().z; - break; - } - - case Dali::Actor::Property::ORIENTATION: - { - value = mTargetOrientation; - break; - } - - case Dali::Actor::Property::SCALE: - { - value = mTargetScale; - break; - } - - case Dali::Actor::Property::SCALE_X: - { - value = mTargetScale.x; - break; - } - - case Dali::Actor::Property::SCALE_Y: - { - value = mTargetScale.y; - break; - } - - case Dali::Actor::Property::SCALE_Z: - { - value = mTargetScale.z; - break; - } - - case Dali::Actor::Property::VISIBLE: - { - value = mVisible; - break; - } - - case Dali::Actor::Property::COLOR: - { - value = mTargetColor; - break; - } - - case Dali::Actor::Property::COLOR_RED: - { - value = mTargetColor.r; - break; - } - - case Dali::Actor::Property::COLOR_GREEN: - { - value = mTargetColor.g; - break; - } - - case Dali::Actor::Property::COLOR_BLUE: - { - value = mTargetColor.b; - break; - } - - case Dali::Actor::Property::COLOR_ALPHA: - case Dali::Actor::Property::OPACITY: - { - value = mTargetColor.a; - break; - } - - case Dali::Actor::Property::NAME: - { - value = GetName(); - break; - } - - case Dali::Actor::Property::SENSITIVE: - { - value = IsSensitive(); - break; - } - - case Dali::Actor::Property::LEAVE_REQUIRED: - { - value = GetLeaveRequired(); - break; - } - - case Dali::Actor::Property::INHERIT_POSITION: - { - value = IsPositionInherited(); - break; - } - - case Dali::Actor::Property::INHERIT_ORIENTATION: - { - value = IsOrientationInherited(); - break; - } - - case Dali::Actor::Property::INHERIT_SCALE: - { - value = IsScaleInherited(); - break; - } - - case Dali::Actor::Property::COLOR_MODE: - { - value = GetColorMode(); - break; - } - - case Dali::Actor::Property::DRAW_MODE: - { - value = GetDrawMode(); - break; - } - - case Dali::Actor::Property::SIZE_MODE_FACTOR: - { - value = GetSizeModeFactor(); - break; - } - - case Dali::Actor::Property::WIDTH_RESIZE_POLICY: - { - value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::WIDTH ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT ); - break; - } - - case Dali::Actor::Property::HEIGHT_RESIZE_POLICY: - { - value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT ); - break; - } - - case Dali::Actor::Property::SIZE_SCALE_POLICY: - { - value = GetSizeScalePolicy(); - break; - } - - case Dali::Actor::Property::WIDTH_FOR_HEIGHT: - { - value = ( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::WIDTH ) == Dimension::HEIGHT ); - break; - } - - case Dali::Actor::Property::HEIGHT_FOR_WIDTH: - { - value = ( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( Dimension::HEIGHT ) == Dimension::WIDTH ); - break; - } - - case Dali::Actor::Property::PADDING: - { - Vector2 widthPadding = GetPadding( Dimension::WIDTH ); - Vector2 heightPadding = GetPadding( Dimension::HEIGHT ); - value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y ); - break; - } - - case Dali::Actor::Property::MINIMUM_SIZE: - { - value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) ); - break; - } - - case Dali::Actor::Property::MAXIMUM_SIZE: - { - value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) ); - break; - } - - case Dali::Actor::Property::CLIPPING_MODE: - { - value = mClippingMode; - break; - } - - case Dali::DevelActor::Property::SIBLING_ORDER: - { - value = static_cast( GetSiblingOrder() ); - break; - } - - case Dali::Actor::Property::SCREEN_POSITION: - { - value = GetCurrentScreenPosition(); - break; - } - - case Dali::Actor::Property::POSITION_USES_ANCHOR_POINT: - { - value = mPositionUsesAnchorPoint; - break; - } - - case Dali::Actor::Property::LAYOUT_DIRECTION: - { - value = mLayoutDirection; - break; - } - - case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION: - { - value = IsLayoutDirectionInherited(); - break; - } - - case Dali::Actor::Property::ID: - { - value = static_cast( GetId() ); - break; - } - - case Dali::Actor::Property::HIERARCHY_DEPTH: - { - value = GetHierarchyDepth(); - break; - } - - case Dali::Actor::Property::IS_ROOT: - { - value = IsRoot(); - break; - } - - case Dali::Actor::Property::IS_LAYER: - { - value = IsLayer(); - break; - } - - case Dali::Actor::Property::CONNECTED_TO_SCENE: - { - value = OnScene(); - break; - } - - case Dali::Actor::Property::KEYBOARD_FOCUSABLE: - { - value = IsKeyboardFocusable(); - break; - } - - case Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START: - { - value = mCaptureAllTouchAfterStart; - break; - } - - default: - { - // Must be a scene-graph only property - valueSet = false; - break; - } - } - - return valueSet; -} - -bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& value ) const -{ - bool valueSet = true; - - switch( index ) - { - case Dali::Actor::Property::SIZE: - { - value = GetCurrentSize(); - break; - } - - case Dali::Actor::Property::SIZE_WIDTH: - { - value = GetCurrentSize().width; - break; - } - - case Dali::Actor::Property::SIZE_HEIGHT: - { - value = GetCurrentSize().height; - break; - } - - case Dali::Actor::Property::SIZE_DEPTH: - { - value = GetCurrentSize().depth; - break; - } - - case Dali::Actor::Property::POSITION: - { - value = GetCurrentPosition(); - break; - } - - case Dali::Actor::Property::POSITION_X: - { - value = GetCurrentPosition().x; - break; - } - - case Dali::Actor::Property::POSITION_Y: - { - value = GetCurrentPosition().y; - break; - } - - case Dali::Actor::Property::POSITION_Z: - { - value = GetCurrentPosition().z; - break; - } - - case Dali::Actor::Property::WORLD_POSITION: - { - value = GetCurrentWorldPosition(); - break; - } - - case Dali::Actor::Property::WORLD_POSITION_X: - { - value = GetCurrentWorldPosition().x; - break; - } - - case Dali::Actor::Property::WORLD_POSITION_Y: - { - value = GetCurrentWorldPosition().y; - break; - } - - case Dali::Actor::Property::WORLD_POSITION_Z: - { - value = GetCurrentWorldPosition().z; - break; - } - - case Dali::Actor::Property::ORIENTATION: - { - value = GetCurrentOrientation(); - break; - } - - case Dali::Actor::Property::WORLD_ORIENTATION: - { - value = GetCurrentWorldOrientation(); - break; - } - - case Dali::Actor::Property::SCALE: - { - value = GetCurrentScale(); - break; - } - - case Dali::Actor::Property::SCALE_X: - { - value = GetCurrentScale().x; - break; - } - - case Dali::Actor::Property::SCALE_Y: - { - value = GetCurrentScale().y; - break; - } - - case Dali::Actor::Property::SCALE_Z: - { - value = GetCurrentScale().z; - break; - } - - case Dali::Actor::Property::WORLD_SCALE: - { - value = GetCurrentWorldScale(); - break; - } - - case Dali::Actor::Property::COLOR: - { - value = GetCurrentColor(); - break; - } - - case Dali::Actor::Property::COLOR_RED: - { - value = GetCurrentColor().r; - break; - } - - case Dali::Actor::Property::COLOR_GREEN: - { - value = GetCurrentColor().g; - break; - } - - case Dali::Actor::Property::COLOR_BLUE: - { - value = GetCurrentColor().b; - break; - } - - case Dali::Actor::Property::COLOR_ALPHA: - case Dali::Actor::Property::OPACITY: - { - value = GetCurrentColor().a; - break; - } - - case Dali::Actor::Property::WORLD_COLOR: - { - value = GetCurrentWorldColor(); - break; - } - - case Dali::Actor::Property::WORLD_MATRIX: - { - value = GetCurrentWorldMatrix(); - break; - } - - case Dali::Actor::Property::VISIBLE: - { - value = IsVisible(); - break; - } - - case Dali::Actor::Property::CULLED: - { - value = GetNode().IsCulled( GetEventThreadServices().GetEventBufferIndex() ); - break; - } - - case Dali::DevelActor::Property::UPDATE_SIZE_HINT: - { - value = GetUpdateSizeHint(); - break; - } - - default: - { - // Must be an event-side only property - valueSet = false; - break; - } - } - - return valueSet; -} - -void Actor::EnsureRelayoutData() -{ - // Assign relayout data. - if( !mRelayoutData ) - { - mRelayoutData = new RelayoutData(); - } -} - -bool Actor::RelayoutDependentOnParent( Dimension::Type dimension ) -{ - // Check if actor is dependent on parent - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) - { - if( ( dimension & ( 1 << i ) ) ) - { - const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) ); - if( resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT ) - { - return true; - } - } - } - - return false; -} - -bool Actor::RelayoutDependentOnChildren( Dimension::Type dimension ) -{ - // Check if actor is dependent on children - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) - { - if( ( dimension & ( 1 << i ) ) ) - { - const ResizePolicy::Type resizePolicy = GetResizePolicy( static_cast< Dimension::Type >( 1 << i ) ); - switch( resizePolicy ) - { - case ResizePolicy::FIT_TO_CHILDREN: - case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children - { - return true; - } - - default: - { - break; - } - } - } - } - - return false; -} - -bool Actor::RelayoutDependentOnChildrenBase( Dimension::Type dimension ) -{ - return Actor::RelayoutDependentOnChildren( dimension ); -} - -bool Actor::RelayoutDependentOnDimension( Dimension::Type dimension, Dimension::Type dependentDimension ) -{ - // Check each possible dimension and see if it is dependent on the input one - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) - { - if( dimension & ( 1 << i ) ) - { - return mRelayoutData->resizePolicies[ i ] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension; - } - } - - return false; -} - -void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension::Type dimension ) -{ - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) - { - if( dimension & ( 1 << i ) ) - { - mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension; - } - } -} - -float Actor::GetNegotiatedDimension( Dimension::Type dimension ) const -{ - // If more than one dimension is requested, just return the first one found - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) - { - if( ( dimension & ( 1 << i ) ) ) - { - return mRelayoutData->negotiatedDimensions[ i ]; - } - } - - return 0.0f; // Default -} - -void Actor::SetPadding( const Vector2& padding, Dimension::Type dimension ) -{ - EnsureRelayoutData(); - - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) - { - if( dimension & ( 1 << i ) ) - { - mRelayoutData->dimensionPadding[ i ] = padding; - } - } -} - -Vector2 Actor::GetPadding( Dimension::Type dimension ) const -{ - if ( mRelayoutData ) - { - // If more than one dimension is requested, just return the first one found - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) - { - if( ( dimension & ( 1 << i ) ) ) - { - return mRelayoutData->dimensionPadding[ i ]; - } - } - } - - return GetDefaultDimensionPadding(); -} - -void Actor::SetLayoutNegotiated( bool negotiated, Dimension::Type dimension ) -{ - EnsureRelayoutData(); - - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) - { - if( dimension & ( 1 << i ) ) - { - mRelayoutData->dimensionNegotiated[ i ] = negotiated; - } - } -} - -bool Actor::IsLayoutNegotiated( Dimension::Type dimension ) const -{ - if ( mRelayoutData ) - { - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) - { - if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] ) - { - return true; - } - } - } - - return false; -} - -float Actor::GetHeightForWidthBase( float width ) -{ - float height = 0.0f; - - const Vector3 naturalSize = GetNaturalSize(); - if( naturalSize.width > 0.0f ) - { - height = naturalSize.height * width / naturalSize.width; - } - else // we treat 0 as 1:1 aspect ratio - { - height = width; - } - - return height; -} - -float Actor::GetWidthForHeightBase( float height ) -{ - float width = 0.0f; - - const Vector3 naturalSize = GetNaturalSize(); - if( naturalSize.height > 0.0f ) - { - width = naturalSize.width * height / naturalSize.height; - } - else // we treat 0 as 1:1 aspect ratio - { - width = height; - } - - return width; -} - -float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension ) -{ - // Fill to parent, taking size mode factor into account - switch( child.GetResizePolicy( dimension ) ) - { - case ResizePolicy::FILL_TO_PARENT: - { - return GetLatestSize( dimension ); - } - - case ResizePolicy::SIZE_RELATIVE_TO_PARENT: - { - return GetLatestSize( dimension ) * GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension ); - } - - case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT: - { - return GetLatestSize( dimension ) + GetDimensionValue( child.GetProperty< Vector3 >( Dali::Actor::Property::SIZE_MODE_FACTOR ), dimension ); - } - - default: - { - return GetLatestSize( dimension ); - } - } -} - -float Actor::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension ) -{ - // Can be overridden in derived class - return CalculateChildSizeBase( child, dimension ); -} - -float Actor::GetHeightForWidth( float width ) -{ - // Can be overridden in derived class - return GetHeightForWidthBase( width ); -} - -float Actor::GetWidthForHeight( float height ) -{ - // Can be overridden in derived class - return GetWidthForHeightBase( height ); -} - -float Actor::GetLatestSize( Dimension::Type dimension ) const -{ - return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension ); + return done; } -float Actor::GetRelayoutSize( Dimension::Type dimension ) const +Rect<> Actor::CalculateScreenExtents() const { - Vector2 padding = GetPadding( dimension ); - - return GetLatestSize( dimension ) + padding.x + padding.y; + auto screenPosition = GetCurrentScreenPosition(); + Vector3 size = GetCurrentSize() * GetCurrentWorldScale(); + Vector3 anchorPointOffSet = size * (mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT); + Vector2 position = Vector2(screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y); + return {position.x, position.y, size.x, size.y}; } -float Actor::NegotiateFromParent( Dimension::Type dimension ) +void Actor::SetNeedGesturePropagation(bool propagation) { - Actor* parent = GetParent(); - if( parent ) - { - Vector2 padding( GetPadding( dimension ) ); - Vector2 parentPadding( parent->GetPadding( dimension ) ); - return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y; - } - - return 0.0f; + mNeedGesturePropagation = propagation; } -float Actor::NegotiateFromChildren( Dimension::Type dimension ) +bool Actor::NeedGesturePropagation() { - float maxDimensionPoint = 0.0f; - - for( uint32_t i = 0, count = GetChildCount(); i < count; ++i ) - { - ActorPtr child = GetChildAt( i ); - - if( !child->RelayoutDependentOnParent( dimension ) ) - { - // Calculate the min and max points that the children range across - float childPosition = GetDimensionValue( child->GetTargetPosition(), dimension ); - float dimensionSize = child->GetRelayoutSize( dimension ); - maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize ); - } - } - - return maxDimensionPoint; + return mNeedGesturePropagation; } -float Actor::GetSize( Dimension::Type dimension ) const +bool Actor::GetCachedPropertyValue(Property::Index index, Property::Value& value) const { - return GetDimensionValue( mTargetSize, dimension ); + return PropertyHandler::GetCachedPropertyValue(*this, index, value); } -float Actor::GetNaturalSize( Dimension::Type dimension ) const +bool Actor::GetCurrentPropertyValue(Property::Index index, Property::Value& value) const { - return GetDimensionValue( GetNaturalSize(), dimension ); + return PropertyHandler::GetCurrentPropertyValue(*this, index, value); } -float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSize ) +Actor::Relayouter& Actor::EnsureRelayouter() { - switch( GetResizePolicy( dimension ) ) + // Assign relayouter + if(!mRelayoutData) { - case ResizePolicy::USE_NATURAL_SIZE: - { - return GetNaturalSize( dimension ); - } - - case ResizePolicy::FIXED: - { - return GetDimensionValue( GetPreferredSize(), dimension ); - } - - case ResizePolicy::USE_ASSIGNED_SIZE: - { - return GetDimensionValue( maximumSize, dimension ); - } - - case ResizePolicy::FILL_TO_PARENT: - case ResizePolicy::SIZE_RELATIVE_TO_PARENT: - case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT: - { - return NegotiateFromParent( dimension ); - } - - case ResizePolicy::FIT_TO_CHILDREN: - { - return NegotiateFromChildren( dimension ); - } - - case ResizePolicy::DIMENSION_DEPENDENCY: - { - const Dimension::Type dimensionDependency = GetDimensionDependency( dimension ); - - // Custom rules - if( dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT ) - { - return GetWidthForHeight( GetNegotiatedDimension( Dimension::HEIGHT ) ); - } - - if( dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH ) - { - return GetHeightForWidth( GetNegotiatedDimension( Dimension::WIDTH ) ); - } - - break; - } - - default: - { - break; - } + mRelayoutData = new Relayouter(); } - return 0.0f; // Default + return *mRelayoutData; } -float Actor::ClampDimension( float size, Dimension::Type dimension ) +bool Actor::RelayoutDependentOnParent(Dimension::Type dimension) { - const float minSize = GetMinimumSize( dimension ); - const float maxSize = GetMaximumSize( dimension ); - - return std::max( minSize, std::min( size, maxSize ) ); -} - -void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack ) -{ - // Check if it needs to be negotiated - if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) ) + // Check if actor is dependent on parent + for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i) { - // Check that we havn't gotten into an infinite loop - ActorDimensionPair searchActor = ActorDimensionPair( this, dimension ); - bool recursionFound = false; - for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it ) - { - if( *it == searchActor ) - { - recursionFound = true; - break; - } - } - - if( !recursionFound ) + if((dimension & (1 << i))) { - // Record the path that we have taken - recursionStack.push_back( ActorDimensionPair( this, dimension ) ); - - // Dimension dependency check - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) - { - Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i ); - - if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) ) - { - NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack ); - } - } - - // Parent dependency check - Actor* parent = GetParent(); - if( parent && RelayoutDependentOnParent( dimension ) ) - { - parent->NegotiateDimension( dimension, allocatedSize, recursionStack ); - } - - // Children dependency check - if( RelayoutDependentOnChildren( dimension ) ) + const ResizePolicy::Type resizePolicy = GetResizePolicy(static_cast(1 << i)); + if(resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT) { - for( uint32_t i = 0, count = GetChildCount(); i < count; ++i ) - { - ActorPtr child = GetChildAt( i ); - - // Only relayout child first if it is not dependent on this actor - if( !child->RelayoutDependentOnParent( dimension ) ) - { - child->NegotiateDimension( dimension, allocatedSize, recursionStack ); - } - } + return true; } - - // For deriving classes - OnCalculateRelayoutSize( dimension ); - - // All dependencies checked, calculate the size and set negotiated flag - const float newSize = ClampDimension( CalculateSize( dimension, allocatedSize ), dimension ); - - SetNegotiatedDimension( newSize, dimension ); - SetLayoutNegotiated( true, dimension ); - - // For deriving classes - OnLayoutNegotiated( newSize, dimension ); - - // This actor has been successfully processed, pop it off the recursion stack - recursionStack.pop_back(); - } - else - { - // TODO: Break infinite loop - SetLayoutNegotiated( true, dimension ); } } -} - -void Actor::NegotiateDimensions( const Vector2& allocatedSize ) -{ - // Negotiate all dimensions that require it - ActorDimensionStack recursionStack; - - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) - { - const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i ); - // Negotiate - NegotiateDimension( dimension, allocatedSize, recursionStack ); - } + return false; } -Vector2 Actor::ApplySizeSetPolicy( const Vector2& size ) +bool Actor::RelayoutDependentOnChildren(Dimension::Type dimension) { - switch( mRelayoutData->sizeSetPolicy ) + // Check if actor is dependent on children + for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i) { - case SizeScalePolicy::USE_SIZE_SET: + if((dimension & (1 << i))) { - return size; - } - - case SizeScalePolicy::FIT_WITH_ASPECT_RATIO: - { - // Scale size to fit within the original size bounds, keeping the natural size aspect ratio - const Vector3 naturalSize = GetNaturalSize(); - if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f ) + const ResizePolicy::Type resizePolicy = GetResizePolicy(static_cast(1 << i)); + switch(resizePolicy) { - const float sizeRatio = size.width / size.height; - const float naturalSizeRatio = naturalSize.width / naturalSize.height; - - if( naturalSizeRatio < sizeRatio ) - { - return Vector2( naturalSizeRatio * size.height, size.height ); - } - else if( naturalSizeRatio > sizeRatio ) - { - return Vector2( size.width, size.width / naturalSizeRatio ); - } - else + case ResizePolicy::FIT_TO_CHILDREN: + case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children { - return size; + return true; } - } - - break; - } - - case SizeScalePolicy::FILL_WITH_ASPECT_RATIO: - { - // Scale size to fill the original size bounds, keeping the natural size aspect ratio. Potentially exceeding the original bounds. - const Vector3 naturalSize = GetNaturalSize(); - if( naturalSize.width > 0.0f && naturalSize.height > 0.0f && size.width > 0.0f && size.height > 0.0f ) - { - const float sizeRatio = size.width / size.height; - const float naturalSizeRatio = naturalSize.width / naturalSize.height; - if( naturalSizeRatio < sizeRatio ) - { - return Vector2( size.width, size.width / naturalSizeRatio ); - } - else if( naturalSizeRatio > sizeRatio ) - { - return Vector2( naturalSizeRatio * size.height, size.height ); - } - else + default: { - return size; + break; } } - break; - } - - default: - { - break; } } - return size; -} - -void Actor::SetNegotiatedSize( RelayoutContainer& container ) -{ - // Do the set actor size - Vector2 negotiatedSize( GetLatestSize( Dimension::WIDTH ), GetLatestSize( Dimension::HEIGHT ) ); - - // Adjust for size set policy - negotiatedSize = ApplySizeSetPolicy( negotiatedSize ); - - // Lock the flag to stop recursive relayouts on set size - mRelayoutData->insideRelayout = true; - SetSize( negotiatedSize ); - mRelayoutData->insideRelayout = false; - - // Clear flags for all dimensions - SetLayoutDirty( false ); - - // Give deriving classes a chance to respond - OnRelayout( negotiatedSize, container ); - - if( !mOnRelayoutSignal.Empty() ) - { - Dali::Actor handle( this ); - mOnRelayoutSignal.Emit( handle ); - } + return false; } -void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container ) -{ - // Force a size negotiation for actors that has assigned size during relayout - // This is required as otherwise the flags that force a relayout will not - // necessarilly be set. This will occur if the actor has already been laid out. - // The dirty flags are then cleared. Then if the actor is added back into the - // relayout container afterwards, the dirty flags would still be clear... - // causing a relayout to be skipped. Here we force any actors added to the - // container to be relayed out. - DALI_LOG_TIMER_START( NegSizeTimer1 ); - - if( GetUseAssignedSize(Dimension::WIDTH ) ) - { - SetLayoutNegotiated( false, Dimension::WIDTH ); - } - if( GetUseAssignedSize( Dimension::HEIGHT ) ) - { - SetLayoutNegotiated( false, Dimension::HEIGHT ); - } - - // Do the negotiation - NegotiateDimensions( allocatedSize ); - - // Set the actor size - SetNegotiatedSize( container ); +bool Actor::RelayoutDependentOnChildrenBase(Dimension::Type dimension) +{ + return Actor::RelayoutDependentOnChildren(dimension); +} - // Negotiate down to children - for( uint32_t i = 0, count = GetChildCount(); i < count; ++i ) +bool Actor::RelayoutDependentOnDimension(Dimension::Type dimension, Dimension::Type dependentDimension) +{ + // Check each possible dimension and see if it is dependent on the input one + for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i) { - ActorPtr child = GetChildAt( i ); - - // Forces children that have already been laid out to be relayed out - // if they have assigned size during relayout. - if( child->GetUseAssignedSize(Dimension::WIDTH) ) + if(dimension & (1 << i)) { - child->SetLayoutNegotiated(false, Dimension::WIDTH); - child->SetLayoutDirty(true, Dimension::WIDTH); + return mRelayoutData->resizePolicies[i] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[i] == dependentDimension; } + } - if( child->GetUseAssignedSize(Dimension::HEIGHT) ) - { - child->SetLayoutNegotiated(false, Dimension::HEIGHT); - child->SetLayoutDirty(true, Dimension::HEIGHT); - } + return false; +} - // Only relayout if required - if( child->RelayoutRequired() ) +void Actor::SetNegotiatedDimension(float negotiatedDimension, Dimension::Type dimension) +{ + for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i) + { + if(dimension & (1 << i)) { - container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() ); + mRelayoutData->negotiatedDimensions[i] = negotiatedDimension; } } - DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: "); } -void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension ) +float Actor::GetNegotiatedDimension(Dimension::Type dimension) const { - if( mRelayoutData ) + // If more than one dimension is requested, just return the first one found + for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i) { - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) + if((dimension & (1 << i))) { - if( dimension & ( 1 << i ) ) - { - mRelayoutData->useAssignedSize[ i ] = use; - } + return mRelayoutData->negotiatedDimensions[i]; } } + + return 0.0f; // Default } -bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const +void Actor::SetPadding(const Vector2& padding, Dimension::Type dimension) { - if ( mRelayoutData ) + EnsureRelayouter().SetPadding(padding, dimension); +} + +Vector2 Actor::GetPadding(Dimension::Type dimension) const +{ + if(mRelayoutData) { // If more than one dimension is requested, just return the first one found - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) + for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i) { - if( dimension & ( 1 << i ) ) + if((dimension & (1 << i))) { - return mRelayoutData->useAssignedSize[ i ]; + return mRelayoutData->dimensionPadding[i]; } } } - return false; -} - -void Actor::RelayoutRequest( Dimension::Type dimension ) -{ - Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get(); - if( relayoutController ) - { - Dali::Actor self( this ); - relayoutController->RequestRelayout( self, dimension ); - } + return Relayouter::DEFAULT_DIMENSION_PADDING; } -void Actor::OnCalculateRelayoutSize( Dimension::Type dimension ) +void Actor::SetLayoutNegotiated(bool negotiated, Dimension::Type dimension) { + EnsureRelayouter().SetLayoutNegotiated(negotiated, dimension); } -void Actor::OnLayoutNegotiated( float size, Dimension::Type dimension ) +bool Actor::IsLayoutNegotiated(Dimension::Type dimension) const { + return mRelayoutData && mRelayoutData->IsLayoutNegotiated(dimension); } -void Actor::SetPreferredSize( const Vector2& size ) +float Actor::GetHeightForWidthBase(float width) { - EnsureRelayoutData(); - - // If valid width or height, then set the resize policy to FIXED - // A 0 width or height may also be required so if the resize policy has not been changed, i.e. is still set to DEFAULT, - // then change to FIXED as well + float height = 0.0f; - if( size.width > 0.0f || GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DEFAULT ) + const Vector3 naturalSize = GetNaturalSize(); + if(naturalSize.width > 0.0f) { - SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH ); + height = naturalSize.height * width / naturalSize.width; } - - if( size.height > 0.0f || GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DEFAULT ) + else // we treat 0 as 1:1 aspect ratio { - SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT ); + height = width; } - mRelayoutData->preferredSize = size; - - mUseAnimatedSize = AnimatedSizeFlag::CLEAR; - - RelayoutRequest(); + return height; } -Vector2 Actor::GetPreferredSize() const +float Actor::GetWidthForHeightBase(float height) { - if ( mRelayoutData ) + float width = 0.0f; + + const Vector3 naturalSize = GetNaturalSize(); + if(naturalSize.height > 0.0f) + { + width = naturalSize.width * height / naturalSize.height; + } + else // we treat 0 as 1:1 aspect ratio { - return Vector2( mRelayoutData->preferredSize ); + width = height; } - return GetDefaultPreferredSize(); + return width; } -void Actor::SetMinimumSize( float size, Dimension::Type dimension ) +float Actor::CalculateChildSizeBase(const Dali::Actor& child, Dimension::Type dimension) { - EnsureRelayoutData(); - - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) + // Fill to parent, taking size mode factor into account + switch(child.GetResizePolicy(dimension)) { - if( dimension & ( 1 << i ) ) + case ResizePolicy::FILL_TO_PARENT: { - mRelayoutData->minimumSize[ i ] = size; + return GetLatestSize(dimension); } - } - RelayoutRequest(); -} + case ResizePolicy::SIZE_RELATIVE_TO_PARENT: + { + return GetLatestSize(dimension) * GetDimensionValue(child.GetProperty(Dali::Actor::Property::SIZE_MODE_FACTOR), dimension); + } -float Actor::GetMinimumSize( Dimension::Type dimension ) const -{ - if ( mRelayoutData ) - { - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) + case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT: { - if( dimension & ( 1 << i ) ) - { - return mRelayoutData->minimumSize[ i ]; - } + return GetLatestSize(dimension) + GetDimensionValue(child.GetProperty(Dali::Actor::Property::SIZE_MODE_FACTOR), dimension); + } + + default: + { + return GetLatestSize(dimension); } } +} + +float Actor::CalculateChildSize(const Dali::Actor& child, Dimension::Type dimension) +{ + // Can be overridden in derived class + return CalculateChildSizeBase(child, dimension); +} + +float Actor::GetHeightForWidth(float width) +{ + // Can be overridden in derived class + return GetHeightForWidthBase(width); +} + +float Actor::GetWidthForHeight(float height) +{ + // Can be overridden in derived class + return GetWidthForHeightBase(height); +} - return 0.0f; // Default +float Actor::GetLatestSize(Dimension::Type dimension) const +{ + return IsLayoutNegotiated(dimension) ? GetNegotiatedDimension(dimension) : GetSize(dimension); } -void Actor::SetMaximumSize( float size, Dimension::Type dimension ) +float Actor::GetRelayoutSize(Dimension::Type dimension) const { - EnsureRelayoutData(); + Vector2 padding = GetPadding(dimension); + + return GetLatestSize(dimension) + padding.x + padding.y; +} - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) +float Actor::NegotiateFromParent(Dimension::Type dimension) +{ + Actor* parent = GetParent(); + if(parent) { - if( dimension & ( 1 << i ) ) - { - mRelayoutData->maximumSize[ i ] = size; - } + Vector2 padding(GetPadding(dimension)); + Vector2 parentPadding(parent->GetPadding(dimension)); + return parent->CalculateChildSize(Dali::Actor(this), dimension) - parentPadding.x - parentPadding.y - padding.x - padding.y; } - RelayoutRequest(); + return 0.0f; } -float Actor::GetMaximumSize( Dimension::Type dimension ) const +float Actor::NegotiateFromChildren(Dimension::Type dimension) { - if ( mRelayoutData ) + float maxDimensionPoint = 0.0f; + + for(uint32_t i = 0, count = GetChildCount(); i < count; ++i) { - for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i ) + ActorPtr child = GetChildAt(i); + + if(!child->RelayoutDependentOnParent(dimension)) { - if( dimension & ( 1 << i ) ) - { - return mRelayoutData->maximumSize[ i ]; - } + // Calculate the min and max points that the children range across + float childPosition = GetDimensionValue(child->GetTargetPosition(), dimension); + float dimensionSize = child->GetRelayoutSize(dimension); + maxDimensionPoint = std::max(maxDimensionPoint, childPosition + dimensionSize); } } - return FLT_MAX; // Default + return maxDimensionPoint; +} + +float Actor::GetSize(Dimension::Type dimension) const +{ + return GetDimensionValue(mTargetSize, dimension); } -Object* Actor::GetParentObject() const +float Actor::GetNaturalSize(Dimension::Type dimension) const { - return mParent; + return GetDimensionValue(GetNaturalSize(), dimension); } -void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage ) +float Actor::CalculateSize(Dimension::Type dimension, const Vector2& maximumSize) { - if( mVisible != visible ) + switch(GetResizePolicy(dimension)) { - if( sendMessage == SendMessage::TRUE ) + case ResizePolicy::USE_NATURAL_SIZE: { - // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty::Bake, visible ); + return GetNaturalSize(dimension); } - mVisible = visible; + case ResizePolicy::FIXED: + { + return GetDimensionValue(GetPreferredSize(), dimension); + } - // Emit the signal on this actor and all its children - EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF ); - } -} + case ResizePolicy::USE_ASSIGNED_SIZE: + { + return GetDimensionValue(maximumSize, dimension); + } -void Actor::SetSiblingOrder( uint32_t order ) -{ - if ( mParent ) - { - ActorContainer& siblings = *(mParent->mChildren); - uint32_t currentOrder = GetSiblingOrder(); + case ResizePolicy::FILL_TO_PARENT: + case ResizePolicy::SIZE_RELATIVE_TO_PARENT: + case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT: + { + return NegotiateFromParent(dimension); + } - if( order != currentOrder ) + case ResizePolicy::FIT_TO_CHILDREN: { - if( order == 0 ) - { - LowerToBottom(); - } - else if( order < siblings.size() -1 ) + return NegotiateFromChildren(dimension); + } + + case ResizePolicy::DIMENSION_DEPENDENCY: + { + const Dimension::Type dimensionDependency = GetDimensionDependency(dimension); + + // Custom rules + if(dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT) { - if( order > currentOrder ) - { - RaiseAbove( *siblings[order] ); - } - else - { - LowerBelow( *siblings[order] ); - } + return GetWidthForHeight(GetNegotiatedDimension(Dimension::HEIGHT)); } - else + + if(dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH) { - RaiseToTop(); + return GetHeightForWidth(GetNegotiatedDimension(Dimension::WIDTH)); } - } - } -} -uint32_t Actor::GetSiblingOrder() const -{ - uint32_t order = 0; + break; + } - if ( mParent ) - { - ActorContainer& siblings = *(mParent->mChildren); - for( std::size_t i = 0; i < siblings.size(); ++i ) + default: { - if( siblings[i] == this ) - { - order = static_cast( i ); - break; - } + break; } } - return order; + return 0.0f; // Default } -void Actor::RequestRebuildDepthTree() +Vector2 Actor::ApplySizeSetPolicy(const Vector2& size) { - if( mIsOnScene ) - { - if( mScene ) - { - mScene->RequestRebuildDepthTree(); - } - } + return mRelayoutData->ApplySizeSetPolicy(*this, size); } -void Actor::Raise() +void Actor::SetNegotiatedSize(RelayoutContainer& container) { - if ( mParent ) - { - ActorContainer& siblings = *(mParent->mChildren); - if( siblings.back() != this ) // If not already at end - { - for( std::size_t i=0; imChildOrderChangedSignal.Emit( handle ); + // Adjust for size set policy + negotiatedSize = ApplySizeSetPolicy(negotiatedSize); - RequestRebuildDepthTree(); - } - else + // Lock the flag to stop recursive relayouts on set size + mRelayoutData->insideRelayout = true; + SetSize(negotiatedSize); + mRelayoutData->insideRelayout = false; + + // Clear flags for all dimensions + SetLayoutDirty(false); + + // Give deriving classes a chance to respond + OnRelayout(negotiatedSize, container); + + if(!mOnRelayoutSignal.Empty()) { - DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" ); + Dali::Actor handle(this); + mOnRelayoutSignal.Emit(handle); } } -void Actor::Lower() +void Actor::NegotiateSize(const Vector2& allocatedSize, RelayoutContainer& container) { - if ( mParent ) - { - ActorContainer& siblings = *(mParent->mChildren); - if( siblings.front() != this ) // If not already at beginning - { - for( std::size_t i=1; imChildOrderChangedSignal.Emit( handle ); + Relayouter::NegotiateSize(*this, allocatedSize, container); +} - RequestRebuildDepthTree(); - } - else +void Actor::SetUseAssignedSize(bool use, Dimension::Type dimension) +{ + if(mRelayoutData) { - DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" ); + mRelayoutData->SetUseAssignedSize(use, dimension); } } -void Actor::RaiseToTop() +bool Actor::GetUseAssignedSize(Dimension::Type dimension) const +{ + return mRelayoutData && mRelayoutData->GetUseAssignedSize(dimension); +} + +void Actor::RelayoutRequest(Dimension::Type dimension) { - if ( mParent ) + Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get(); + if(relayoutController) { - ActorContainer& siblings = *(mParent->mChildren); - if( siblings.back() != this ) // If not already at end - { - ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this ); - if( iter != siblings.end() ) - { - siblings.erase(iter); - siblings.push_back(ActorPtr(this)); - } - } + Dali::Actor self(this); + relayoutController->RequestRelayout(self, dimension); + } +} - Dali::Actor handle( this ); - mParent->mChildOrderChangedSignal.Emit( handle ); +void Actor::SetPreferredSize(const Vector2& size) +{ + EnsureRelayouter().SetPreferredSize(*this, size); +} - RequestRebuildDepthTree(); - } - else +Vector2 Actor::GetPreferredSize() const +{ + if(mRelayoutData) { - DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" ); + return Vector2(mRelayoutData->preferredSize); } + + return Relayouter::DEFAULT_PREFERRED_SIZE; } -void Actor::LowerToBottom() +void Actor::SetMinimumSize(float size, Dimension::Type dimension) { - if ( mParent ) + EnsureRelayouter().SetMinimumSize(size, dimension); + RelayoutRequest(); +} + +float Actor::GetMinimumSize(Dimension::Type dimension) const +{ + if(mRelayoutData) { - ActorContainer& siblings = *(mParent->mChildren); - if( siblings.front() != this ) // If not already at bottom, - { - ActorPtr thisPtr(this); // ensure this actor remains referenced. + return mRelayoutData->GetMinimumSize(dimension); + } - ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this ); - if( iter != siblings.end() ) - { - siblings.erase(iter); - siblings.insert(siblings.begin(), thisPtr); - } - } + return 0.0f; // Default +} - Dali::Actor handle( this ); - mParent->mChildOrderChangedSignal.Emit( handle ); +void Actor::SetMaximumSize(float size, Dimension::Type dimension) +{ + EnsureRelayouter().SetMaximumSize(size, dimension); + RelayoutRequest(); +} - RequestRebuildDepthTree(); - } - else +float Actor::GetMaximumSize(Dimension::Type dimension) const +{ + if(mRelayoutData) { - DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" ); + return mRelayoutData->GetMaximumSize(dimension); } + + return FLT_MAX; // Default } -void Actor::RaiseAbove( Internal::Actor& target ) +void Actor::SetVisibleInternal(bool visible, SendMessage::Type sendMessage) { - if ( mParent ) + if(mVisible != visible) { - ActorContainer& siblings = *(mParent->mChildren); - if( siblings.back() != this && target.mParent == mParent ) // If not already at top + if(sendMessage == SendMessage::TRUE) { - ActorPtr thisPtr(this); // ensure this actor remains referenced. + // node is being used in a separate thread; queue a message to set the value & base value + SceneGraph::NodePropertyMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mVisible, &AnimatableProperty::Bake, visible); - ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target ); - ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this ); - if( thisIter < targetIter ) - { - siblings.erase(thisIter); - // Erasing early invalidates the targetIter. (Conversely, inserting first may also - // invalidate thisIter) - targetIter = std::find( siblings.begin(), siblings.end(), &target ); - ++targetIter; - siblings.insert(targetIter, thisPtr); - } + RequestRenderingMessage(GetEventThreadServices().GetUpdateManager()); + } - Dali::Actor handle( this ); - mParent->mChildOrderChangedSignal.Emit( handle ); + mVisible = visible; - RequestRebuildDepthTree(); - } - } - else - { - DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" ); + // Emit the signal on this actor and all its children + EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::SELF); } } -void Actor::LowerBelow( Internal::Actor& target ) +void Actor::SetSiblingOrderOfChild(Actor& child, uint32_t order) { - if ( mParent ) - { - ActorContainer& siblings = *(mParent->mChildren); - if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom - { - ActorPtr thisPtr(this); // ensure this actor remains referenced. + mParentImpl.SetSiblingOrderOfChild(child, order); +} - ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target ); - ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this ); +uint32_t Actor::GetSiblingOrderOfChild(const Actor& child) const +{ + return mParentImpl.GetSiblingOrderOfChild(child); +} - if( thisIter > targetIter ) - { - siblings.erase(thisIter); // this only invalidates iterators at or after this point. - siblings.insert(targetIter, thisPtr); - } +void Actor::RaiseChild(Actor& child) +{ + mParentImpl.RaiseChild(child); +} - Dali::Actor handle( this ); - mParent->mChildOrderChangedSignal.Emit( handle ); +void Actor::LowerChild(Actor& child) +{ + mParentImpl.LowerChild(child); +} - RequestRebuildDepthTree(); - } - } - else - { - DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" ); - } +void Actor::RaiseChildToTop(Actor& child) +{ + mParentImpl.RaiseChildToTop(child); } -void Actor::SetScene( Scene& scene ) +void Actor::LowerChildToBottom(Actor& child) { - mScene = &scene; + mParentImpl.LowerChildToBottom(child); } -Scene& Actor::GetScene() const +void Actor::RaiseChildAbove(Actor& child, Actor& target) { - return *mScene; + mParentImpl.RaiseChildAbove(child, target); } -void Actor::SetInheritLayoutDirection( bool inherit ) +void Actor::LowerChildBelow(Actor& child, Actor& target) { - if( mInheritLayoutDirection != inherit ) + mParentImpl.LowerChildBelow(child, target); +} + +void Actor::SetInheritLayoutDirection(bool inherit) +{ + if(mInheritLayoutDirection != inherit) { mInheritLayoutDirection = inherit; - if( inherit && mParent ) + if(inherit && mParent) { - InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection ); + InheritLayoutDirectionRecursively(GetParent()->mLayoutDirection); } } } -bool Actor::IsLayoutDirectionInherited() const -{ - return mInheritLayoutDirection; -} - -void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set ) +void Actor::InheritLayoutDirectionRecursively(Dali::LayoutDirection::Type direction, bool set) { - if( actor && ( actor->mInheritLayoutDirection || set ) ) + if(mInheritLayoutDirection || set) { - if( actor->mLayoutDirection != direction ) + if(mLayoutDirection != direction) { - actor->mLayoutDirection = direction; - actor->EmitLayoutDirectionChangedSignal( direction ); - actor->RelayoutRequest(); + mLayoutDirection = direction; + EmitLayoutDirectionChangedSignal(direction); + RelayoutRequest(); } - if( actor->GetChildCount() > 0 ) + if(GetChildCount() > 0) { - ActorContainer& children = actor->GetChildrenInternal(); - for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter ) + for(const auto& child : mParentImpl.GetChildrenInternal()) { - InheritLayoutDirectionRecursively( *iter, direction ); + child->InheritLayoutDirectionRecursively(direction); } } } } -void Actor::SetUpdateSizeHint( const Vector2& updateSizeHint ) +void Actor::SetUpdateSizeHint(const Vector2& updateSizeHint) { // node is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mUpdateSizeHint, &AnimatableProperty::Bake, Vector3(updateSizeHint.width, updateSizeHint.height, 0.f ) ); + SceneGraph::NodePropertyMessage::Send(GetEventThreadServices(), &GetNode(), &GetNode().mUpdateSizeHint, &AnimatableProperty::Bake, Vector3(updateSizeHint.width, updateSizeHint.height, 0.f)); } -Vector2 Actor::GetUpdateSizeHint() const +void Actor::EmitVisibilityChangedSignalRecursively(bool visible, + DevelActor::VisibilityChange::Type type) { - // node is being used in a separate thread, the value from the previous update is the same, set by user - Vector3 updateSizeHint = GetNode().GetUpdateSizeHint(); - return Vector2( updateSizeHint.width, updateSizeHint.height ); + EmitVisibilityChangedSignal(visible, type); + + if(GetChildCount() > 0) + { + for(auto& child : mParentImpl.GetChildrenInternal()) + { + child->EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::PARENT); + } + } } } // namespace Internal