X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fevent%2Factors%2Factor-impl.cpp;h=ee6089236446be1ce359bf71f5953cd1ad07f386;hb=3cfd6a240ea9eaa504d5237111170fa79768696d;hp=cb4b4f510708523ffc7a225c6e38ad237b32f59b;hpb=7e14935f42dc79f6b8239b0301078d004d3ebaba;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 cb4b4f5..ee60892 100644 --- a/dali/internal/event/actors/actor-impl.cpp +++ b/dali/internal/event/actors/actor-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 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. @@ -24,15 +24,16 @@ #include // INTERNAL INCLUDES - +#include #include #include +#include #include #include #include #include +#include #include - #include #include #include @@ -41,8 +42,6 @@ #include #include #include -#include -#include #include #include #include @@ -60,37 +59,6 @@ using Dali::Internal::SceneGraph::PropertyBase; namespace Dali { -namespace ResizePolicy -{ - -namespace -{ -DALI_ENUM_TO_STRING_TABLE_BEGIN( Type ) -DALI_ENUM_TO_STRING( FIXED ) -DALI_ENUM_TO_STRING( USE_NATURAL_SIZE ) -DALI_ENUM_TO_STRING( FILL_TO_PARENT ) -DALI_ENUM_TO_STRING( SIZE_RELATIVE_TO_PARENT ) -DALI_ENUM_TO_STRING( SIZE_FIXED_OFFSET_FROM_PARENT ) -DALI_ENUM_TO_STRING( FIT_TO_CHILDREN ) -DALI_ENUM_TO_STRING( DIMENSION_DEPENDENCY ) -DALI_ENUM_TO_STRING( USE_ASSIGNED_SIZE ) -DALI_ENUM_TO_STRING_TABLE_END( Type ) - -} // unnamed namespace -} // ResizePolicy - -namespace SizeScalePolicy -{ -namespace -{ -// Enumeration to / from string conversion tables -DALI_ENUM_TO_STRING_TABLE_BEGIN( Type ) -DALI_ENUM_TO_STRING( USE_SIZE_SET ) -DALI_ENUM_TO_STRING( FIT_WITH_ASPECT_RATIO ) -DALI_ENUM_TO_STRING( FILL_WITH_ASPECT_RATIO ) -DALI_ENUM_TO_STRING_TABLE_END( Type ) -} // unnamed namespace -} // SizeScalePolicy namespace Internal { @@ -119,6 +87,32 @@ inline const Vector2& GetDefaultDimensionPadding() const SizeScalePolicy::Type DEFAULT_SIZE_SCALE_POLICY = SizeScalePolicy::USE_SIZE_SET; +int GetSiblingOrder( ActorPtr actor ) +{ + Property::Value value = actor->GetProperty(Dali::DevelActor::Property::SIBLING_ORDER ); + int order; + value.Get( order ); + return order; +} + +bool ValidateActors( const Internal::Actor& actor, const Internal::Actor& target ) +{ + bool validTarget = true; + + if( &actor == &target ) + { + DALI_LOG_WARNING( "Source actor and target actor can not be the same, Sibling order not changed.\n" ); + validTarget = false; + } + else if( actor.GetParent() != target.GetParent() ) + { + DALI_LOG_WARNING( "Source actor and target actor need to have common parent, Sibling order not changed.\n" ); + validTarget = false; + } + + return validTarget; +} + } // unnamed namespace /** @@ -175,70 +169,78 @@ namespace // unnamed namespace /** * We want to discourage the use of property strings (minimize string comparisons), * particularly for the default properties. - * Name Type writable animatable constraint-input enum for index-checking + * Name Type writable animatable constraint-input enum for index-checking */ DALI_PROPERTY_TABLE_BEGIN -DALI_PROPERTY( "parent-origin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN ) -DALI_PROPERTY( "parent-origin-x", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X ) -DALI_PROPERTY( "parent-origin-y", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y ) -DALI_PROPERTY( "parent-origin-z", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z ) -DALI_PROPERTY( "anchor-point", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT ) -DALI_PROPERTY( "anchor-point-x", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X ) -DALI_PROPERTY( "anchor-point-y", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y ) -DALI_PROPERTY( "anchor-point-z", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z ) -DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE ) -DALI_PROPERTY( "size-width", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH ) -DALI_PROPERTY( "size-height", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT ) -DALI_PROPERTY( "size-depth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH ) -DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION ) -DALI_PROPERTY( "position-x", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X ) -DALI_PROPERTY( "position-y", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y ) -DALI_PROPERTY( "position-z", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z ) -DALI_PROPERTY( "world-position", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION ) -DALI_PROPERTY( "world-position-x", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X ) -DALI_PROPERTY( "world-position-y", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y ) -DALI_PROPERTY( "world-position-z", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z ) -DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION ) -DALI_PROPERTY( "world-orientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION ) -DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE ) -DALI_PROPERTY( "scale-x", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X ) -DALI_PROPERTY( "scale-y", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y ) -DALI_PROPERTY( "scale-z", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z ) -DALI_PROPERTY( "world-scale", 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( "color-red", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED ) -DALI_PROPERTY( "color-green", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN ) -DALI_PROPERTY( "color-blue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE ) -DALI_PROPERTY( "color-alpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA ) -DALI_PROPERTY( "world-color", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR ) -DALI_PROPERTY( "world-matrix", 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( "leave-required", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED ) -DALI_PROPERTY( "inherit-orientation",BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION ) -DALI_PROPERTY( "inherit-scale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE ) -DALI_PROPERTY( "color-mode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE ) -DALI_PROPERTY( "position-inheritance",STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE ) -DALI_PROPERTY( "draw-mode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE ) -DALI_PROPERTY( "size-mode-factor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR ) -DALI_PROPERTY( "width-resize-policy",STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY ) -DALI_PROPERTY( "height-resize-policy",STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY ) -DALI_PROPERTY( "size-scale-policy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY ) -DALI_PROPERTY( "width-for-height", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT ) -DALI_PROPERTY( "height-for-width", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH ) -DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING ) -DALI_PROPERTY( "minimum-size", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE ) -DALI_PROPERTY( "maximum-size", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE ) +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", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE ) +DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE ) +DALI_PROPERTY( "drawMode", STRING, 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", STRING, 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( "siblingOrder", INTEGER, true, false, false, Dali::DevelActor::Property::SIBLING_ORDER ) +DALI_PROPERTY( "opacity", FLOAT, true, true, true, Dali::DevelActor::Property::OPACITY ) +DALI_PROPERTY( "screenPosition", VECTOR2, false, false, false, Dali::DevelActor::Property::SCREEN_POSITION ) +DALI_PROPERTY( "positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT ) DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX ) // Signals const char* const SIGNAL_TOUCHED = "touched"; const char* const SIGNAL_HOVERED = "hovered"; -const char* const SIGNAL_WHEEL_EVENT = "wheel-event"; -const char* const SIGNAL_ON_STAGE = "on-stage"; -const char* const SIGNAL_OFF_STAGE = "off-stage"; +const char* const SIGNAL_WHEEL_EVENT = "wheelEvent"; +const char* const SIGNAL_ON_STAGE = "onStage"; +const char* const SIGNAL_OFF_STAGE = "offStage"; +const char* const SIGNAL_ON_RELAYOUT = "onRelayout"; +const char* const SIGNAL_TOUCH = "touch"; // Actions @@ -254,12 +256,96 @@ TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor ) SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal ); SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal ); -SignalConnectorType signalConnector3( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal ); -SignalConnectorType signalConnector4( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal ); +SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal ); +SignalConnectorType signalConnector4( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal ); +SignalConnectorType signalConnector5( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal ); +SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal ); +SignalConnectorType signalConnector7( mType, SIGNAL_TOUCH, &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( POSITION_INHERITANCE_MODE ) +DALI_ENUM_TO_STRING( INHERIT_PARENT_POSITION ) +DALI_ENUM_TO_STRING( USE_PARENT_POSITION ) +DALI_ENUM_TO_STRING( USE_PARENT_POSITION_PLUS_LOCAL_POSITION ) +DALI_ENUM_TO_STRING( DONT_INHERIT_POSITION ) +DALI_ENUM_TO_STRING_TABLE_END( POSITION_INHERITANCE_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_WITH_SCOPE( DrawMode, STENCIL ) +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 ) + + +bool GetAnchorPointConstant( const std::string& value, Vector3& anchor ) +{ + for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i ) + { + size_t sizeIgnored = 0; + if( CompareTokens( value.c_str(), ANCHOR_CONSTANT_TABLE[ i ].name, sizeIgnored ) ) + { + anchor = ANCHOR_CONSTANT_TABLE[ i ].value; + return true; + } + } + return false; +} + +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 ); +} + /** * @brief Extract a given dimension from a Vector2 * @@ -299,6 +385,33 @@ float GetDimensionValue( const Vector3& values, Dimension::Type dimension ) return GetDimensionValue( values.GetVectorXY(), dimension ); } +unsigned int GetDepthIndex( uint16_t depth, uint16_t siblingOrder ) +{ + return depth * Dali::DevelLayer::ACTOR_DEPTH_MULTIPLIER + siblingOrder * Dali::DevelLayer::SIBLING_ORDER_MULTIPLIER; +} + +/** + * @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 ) +{ + if( actor ) + { + actor->EmitVisibilityChangedSignal( visible, type ); + + 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 ); + } + } + } +} } // unnamed namespace @@ -333,23 +446,6 @@ unsigned int Actor::GetId() const return mId; } -void Actor::Attach( ActorAttachment& attachment ) -{ - DALI_ASSERT_DEBUG( !mAttachment && "An Actor can only have one attachment" ); - - if( OnStage() ) - { - attachment.Connect(); - } - - mAttachment = ActorAttachmentPtr( &attachment ); -} - -ActorAttachmentPtr Actor::GetAttachment() -{ - return mAttachment; -} - bool Actor::OnStage() const { return mIsOnStage; @@ -425,63 +521,6 @@ void Actor::Add( Actor& child ) } } -void Actor::Insert( unsigned int index, 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 ); - - // since an explicit position has been given, always insert, even if already a child - if( oldParent ) - { - oldParent->Remove( child ); // This causes OnChildRemove callback - - // 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 - if( index < GetChildCount() ) - { - ActorIter it = mChildren->begin(); - std::advance( it, index ); - mChildren->insert( it, ActorPtr( &child ) ); - } - else - { - mChildren->push_back( ActorPtr( &child ) ); - } - // SetParent asserts that child can be added - child.SetParent( this, index ); - - // Notification for derived classes - OnChildAdd( child ); - - // Only put in a relayout request if there is a suitable dependency - if( RelayoutDependentOnChildren() ) - { - RelayoutRequest(); - } - - if( child.RelayoutDependentOnParent() ) - { - child.RelayoutRequest(); - } - } -} - void Actor::Remove( Actor& child ) { if( (this == &child) || (!mChildren) ) @@ -515,15 +554,15 @@ void Actor::Remove( Actor& child ) if( removed ) { - // Notification for derived classes - OnChildRemove( *(removed.Get()) ); - // Only put in a relayout request if there is a suitable dependency if( RelayoutDependentOnChildren() ) { RelayoutRequest(); } } + + // Notification for derived classes + OnChildRemove( child ); } void Actor::Unparent() @@ -714,7 +753,7 @@ void Actor::SetPosition( const Vector3& position ) if( NULL != mNode ) { // mNode is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyMessage::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty::Bake, position ); + SceneGraph::NodeTransformPropertyMessage::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler::Bake, position ); } } @@ -725,7 +764,7 @@ void Actor::SetX( float x ) if( NULL != mNode ) { // mNode is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyComponentMessage::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty::BakeX, x ); + SceneGraph::NodeTransformComponentMessage::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler::BakeX, x ); } } @@ -736,7 +775,7 @@ void Actor::SetY( float y ) if( NULL != mNode ) { // mNode is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyComponentMessage::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty::BakeY, y ); + SceneGraph::NodeTransformComponentMessage::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler::BakeY, y ); } } @@ -747,7 +786,7 @@ void Actor::SetZ( float z ) if( NULL != mNode ) { // mNode is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyComponentMessage::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty::BakeZ, z ); + SceneGraph::NodeTransformComponentMessage::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler::BakeZ, z ); } } @@ -758,7 +797,7 @@ void Actor::TranslateBy( const Vector3& distance ) if( NULL != mNode ) { // mNode is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyMessage::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &AnimatableProperty::BakeRelative, distance ); + SceneGraph::NodeTransformPropertyMessage::Send( GetEventThreadServices(), mNode, &mNode->mPosition, &SceneGraph::TransformManagerPropertyHandler::BakeRelative, distance ); } } @@ -789,6 +828,24 @@ const Vector3& Actor::GetCurrentWorldPosition() const return Vector3::ZERO; } +const Vector2 Actor::GetCurrentScreenPosition() const +{ + if( OnStage() && NULL != mNode ) + { + StagePtr stage = Stage::GetCurrent(); + Vector3 worldPosition = mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() ); + Vector3 actorSize = GetCurrentSize() * GetCurrentScale(); + Vector2 halfStageSize( stage->GetSize() * 0.5f ); // World position origin is center of stage + Vector3 halfActorSize( actorSize * 0.5f ); + Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT ); + + return Vector2( halfStageSize.width + worldPosition.x - anchorPointOffSet.x, + halfStageSize.height + worldPosition.y - anchorPointOffSet.y ); + } + + return Vector2::ZERO; +} + void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode ) { // this flag is not animatable so keep the value @@ -796,7 +853,7 @@ void Actor::SetPositionInheritanceMode( PositionInheritanceMode mode ) if( NULL != mNode ) { // mNode is being used in a separate thread; queue a message to set the value - SetPositionInheritanceModeMessage( GetEventThreadServices(), *mNode, mode ); + SetInheritPositionMessage( GetEventThreadServices(), *mNode, mode == INHERIT_PARENT_POSITION ); } } @@ -806,6 +863,21 @@ PositionInheritanceMode Actor::GetPositionInheritanceMode() const return mPositionInheritanceMode; } +void Actor::SetInheritPosition( bool inherit ) +{ + if( mInheritPosition != inherit && NULL != mNode ) + { + // non animateable so keep local copy + mInheritPosition = inherit; + SetInheritPositionMessage( GetEventThreadServices(), *mNode, inherit ); + } +} + +bool Actor::IsPositionInherited() const +{ + return mInheritPosition; +} + void Actor::SetOrientation( const Radian& angle, const Vector3& axis ) { Vector3 normalizedAxis( axis.x, axis.y, axis.z ); @@ -818,28 +890,28 @@ void Actor::SetOrientation( const Radian& angle, const Vector3& axis ) void Actor::SetOrientation( const Quaternion& orientation ) { + mTargetOrientation = orientation; + if( NULL != mNode ) { // mNode is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyMessage::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &AnimatableProperty::Bake, orientation ); + SceneGraph::NodeTransformPropertyMessage::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler::Bake, orientation ); } } void Actor::RotateBy( const Radian& angle, const Vector3& axis ) { - if( NULL != mNode ) - { - // mNode is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyMessage::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &AnimatableProperty::BakeRelative, Quaternion(angle, axis) ); - } + RotateBy( Quaternion(angle, axis) ); } void Actor::RotateBy( const Quaternion& relativeRotation ) { + mTargetOrientation *= Quaternion( relativeRotation ); + if( NULL != mNode ) { // mNode is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyMessage::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &AnimatableProperty::BakeRelative, relativeRotation ); + SceneGraph::NodeTransformPropertyMessage::Send( GetEventThreadServices(), mNode, &mNode->mOrientation, &SceneGraph::TransformManagerPropertyHandler::BakeRelative, relativeRotation ); } } @@ -877,46 +949,56 @@ void Actor::SetScale( float x, float y, float z ) void Actor::SetScale( const Vector3& scale ) { + mTargetScale = scale; + if( NULL != mNode ) { // mNode is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyMessage::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty::Bake, scale ); + SceneGraph::NodeTransformPropertyMessage::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler::Bake, scale ); } } void Actor::SetScaleX( float x ) { + mTargetScale.x = x; + if( NULL != mNode ) { // mNode is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyComponentMessage::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty::BakeX, x ); + SceneGraph::NodeTransformComponentMessage::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler::BakeX, x ); } } void Actor::SetScaleY( float y ) { + mTargetScale.y = y; + if( NULL != mNode ) { // mNode is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyComponentMessage::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty::BakeY, y ); + SceneGraph::NodeTransformComponentMessage::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler::BakeY, y ); } } void Actor::SetScaleZ( float z ) { + mTargetScale.z = z; + if( NULL != mNode ) { // mNode is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyComponentMessage::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty::BakeZ, z ); + SceneGraph::NodeTransformComponentMessage::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler::BakeZ, z ); } } void Actor::ScaleBy(const Vector3& relativeScale) { + mTargetScale *= relativeScale; + if( NULL != mNode ) { // mNode is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyMessage::Send( GetEventThreadServices(), mNode, &mNode->mScale, &AnimatableProperty::BakeRelativeMultiply, relativeScale ); + SceneGraph::NodeTransformPropertyMessage::Send( GetEventThreadServices(), mNode, &mNode->mScale, &SceneGraph::TransformManagerPropertyHandler::BakeRelativeMultiply, relativeScale ); } } @@ -944,10 +1026,11 @@ const Vector3& Actor::GetCurrentWorldScale() const void Actor::SetInheritScale( bool inherit ) { - // non animateable so keep local copy - mInheritScale = inherit; - if( NULL != mNode ) + + if( mInheritScale != inherit && NULL != mNode ) { + // non animateable so keep local copy + mInheritScale = inherit; // mNode is being used in a separate thread; queue a message to set the value SetInheritScaleMessage( GetEventThreadServices(), *mNode, inherit ); } @@ -962,14 +1045,7 @@ Matrix Actor::GetCurrentWorldMatrix() const { if( NULL != mNode ) { - // World matrix is no longer updated unless there is something observing the node. - // Need to calculate it from node's world position, orientation and scale: - BufferIndex updateBufferIndex = GetEventThreadServices().GetEventBufferIndex(); - Matrix worldMatrix(false); - worldMatrix.SetTransformComponents( mNode->GetWorldScale( updateBufferIndex ), - mNode->GetWorldOrientation( updateBufferIndex ), - mNode->GetWorldPosition( updateBufferIndex ) ); - return worldMatrix; + return mNode->GetWorldMatrix(0); } return Matrix::IDENTITY; @@ -977,10 +1053,18 @@ Matrix Actor::GetCurrentWorldMatrix() const void Actor::SetVisible( bool visible ) { - if( NULL != mNode ) + if( mVisible != visible ) { - // mNode is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyMessage::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty::Bake, visible ); + if( NULL != mNode ) + { + // mNode is being used in a separate thread; queue a message to set the value & base value + SceneGraph::NodePropertyMessage::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty::Bake, visible ); + } + + mVisible = visible; + + // Emit the signal on this actor and all its children + EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF ); } } @@ -997,6 +1081,8 @@ bool Actor::IsVisible() const void Actor::SetOpacity( float opacity ) { + mTargetColor.a = opacity; + if( NULL != mNode ) { // mNode is being used in a separate thread; queue a message to set the value & base value @@ -1015,6 +1101,16 @@ float Actor::GetCurrentOpacity() const return 1.0f; } +ClippingMode::Type Actor::GetClippingMode() const +{ + return mClippingMode; +} + +unsigned int Actor::GetSortingDepth() +{ + return GetDepthIndex( mDepth, mSiblingOrder ); +} + const Vector4& Actor::GetCurrentWorldColor() const { if( NULL != mNode ) @@ -1027,6 +1123,8 @@ const Vector4& Actor::GetCurrentWorldColor() const void Actor::SetColor( const Vector4& color ) { + mTargetColor = color; + if( NULL != mNode ) { // mNode is being used in a separate thread; queue a message to set the value & base value @@ -1036,6 +1134,8 @@ void Actor::SetColor( const Vector4& color ) void Actor::SetColorRed( float red ) { + mTargetColor.r = red; + if( NULL != mNode ) { // mNode is being used in a separate thread; queue a message to set the value & base value @@ -1045,6 +1145,8 @@ void Actor::SetColorRed( float red ) void Actor::SetColorGreen( float green ) { + mTargetColor.g = green; + if( NULL != mNode ) { // mNode is being used in a separate thread; queue a message to set the value & base value @@ -1054,6 +1156,8 @@ void Actor::SetColorGreen( float green ) void Actor::SetColorBlue( float blue ) { + mTargetColor.b = blue; + if( NULL != mNode ) { // mNode is being used in a separate thread; queue a message to set the value & base value @@ -1074,10 +1178,10 @@ const Vector4& Actor::GetCurrentColor() const void Actor::SetInheritOrientation( bool inherit ) { - // non animateable so keep local copy - mInheritOrientation = inherit; - if( NULL != mNode ) + if( mInheritOrientation != inherit && NULL != mNode) { + // non animateable so keep local copy + mInheritOrientation = inherit; // mNode is being used in a separate thread; queue a message to set the value SetInheritOrientationMessage( GetEventThreadServices(), *mNode, inherit ); } @@ -1134,23 +1238,19 @@ void Actor::SetSize( float width, float height, float depth ) void Actor::SetSize( const Vector2& size ) { - SetSize( Vector3( size.width, size.height, CalculateSizeZ( size ) ) ); + SetSize( Vector3( size.width, size.height, 0.f ) ); } void Actor::SetSizeInternal( const Vector2& size ) { - SetSizeInternal( Vector3( size.width, size.height, CalculateSizeZ( size ) ) ); -} - -float Actor::CalculateSizeZ( const Vector2& size ) const -{ - return std::min( size.width, size.height ); + SetSizeInternal( Vector3( size.width, size.height, 0.f ) ); } void Actor::SetSize( const Vector3& size ) { if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout ) { + // TODO we cannot just ignore the given Z but that means rewrite the size negotiation!! SetPreferredSize( size.GetVectorXY() ); } else @@ -1172,7 +1272,7 @@ void Actor::SetSizeInternal( const Vector3& size ) mTargetSize = size; // mNode is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyMessage::Send( GetEventThreadServices(), mNode, &mNode->mSize, &AnimatableProperty::Bake, mTargetSize ); + SceneGraph::NodeTransformPropertyMessage::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler::Bake, mTargetSize ); // Notification for derived classes mInsideOnSizeSet = true; @@ -1205,34 +1305,85 @@ void Actor::NotifySizeAnimation( Animation& animation, float targetSize, Propert { mTargetSize.height = targetSize; } + else if ( Dali::Actor::Property::SIZE_DEPTH == property ) + { + mTargetSize.depth = targetSize; + } // Notify deriving classes OnSizeAnimation( animation, mTargetSize ); } +void Actor::NotifyPositionAnimation( Animation& animation, const Vector3& targetPosition ) +{ + mTargetPosition = targetPosition; +} + +void Actor::NotifyPositionAnimation( Animation& animation, float targetPosition, Property::Index property ) +{ + if ( Dali::Actor::Property::POSITION_X == property ) + { + mTargetPosition.x = targetPosition; + } + else if ( Dali::Actor::Property::POSITION_Y == property ) + { + mTargetPosition.y = targetPosition; + } + else if ( Dali::Actor::Property::POSITION_Z == property ) + { + mTargetPosition.z = targetPosition; + } +} + void Actor::SetWidth( float width ) { - if( NULL != mNode ) + if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout ) { - // mNode is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyComponentMessage::Send( GetEventThreadServices(), mNode, &mNode->mSize, &AnimatableProperty::BakeX, width ); + SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH ); + mRelayoutData->preferredSize.width = width; + } + else + { + mTargetSize.width = width; + + if( NULL != mNode ) + { + // mNode is being used in a separate thread; queue a message to set the value & base value + SceneGraph::NodeTransformComponentMessage::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler::BakeX, width ); + } } + + RelayoutRequest(); } void Actor::SetHeight( float height ) { - if( NULL != mNode ) + if( IsRelayoutEnabled() && !mRelayoutData->insideRelayout ) { - // mNode is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyComponentMessage::Send( GetEventThreadServices(), mNode, &mNode->mSize, &AnimatableProperty::BakeY, height ); + SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT ); + mRelayoutData->preferredSize.height = height; + } + else + { + mTargetSize.height = height; + + if( NULL != mNode ) + { + // mNode is being used in a separate thread; queue a message to set the value & base value + SceneGraph::NodeTransformComponentMessage::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler::BakeY, height ); + } } + + RelayoutRequest(); } void Actor::SetDepth( float depth ) { + mTargetSize.depth = depth; + if( NULL != mNode ) { // mNode is being used in a separate thread; queue a message to set the value & base value - SceneGraph::NodePropertyComponentMessage::Send( GetEventThreadServices(), mNode, &mNode->mSize, &AnimatableProperty::BakeZ, depth ); + SceneGraph::NodeTransformComponentMessage::Send( GetEventThreadServices(), mNode, &mNode->mSize, &SceneGraph::TransformManagerPropertyHandler::BakeZ, depth ); } } @@ -1262,6 +1413,9 @@ void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimensio { EnsureRelayoutData(); + ResizePolicy::Type originalWidthPolicy = GetResizePolicy(Dimension::WIDTH); + ResizePolicy::Type originalHeightPolicy = GetResizePolicy(Dimension::HEIGHT); + for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i ) { if( dimension & ( 1 << i ) ) @@ -1286,6 +1440,34 @@ void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimensio // If calling SetResizePolicy, assume we want relayout enabled SetRelayoutEnabled( true ); + // 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. + + if( dimension & Dimension::WIDTH ) + { + 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; + } + } + + 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 @@ -1364,6 +1546,8 @@ void Actor::SetRelayoutEnabled( bool relayoutEnabled ) { EnsureRelayoutData(); + DALI_ASSERT_DEBUG( mRelayoutData && "mRelayoutData not created" ); + mRelayoutData->relayoutEnabled = relayoutEnabled; } } @@ -1416,65 +1600,77 @@ bool Actor::RelayoutRequired( Dimension::Type dimension ) const unsigned int Actor::AddRenderer( Renderer& renderer ) { - //TODO: MESH_REWORK : Add support for multiple renderers - if ( ! mAttachment ) + if( !mRenderers ) { - mAttachment = RendererAttachment::New( GetEventThreadServices(), *mNode, renderer ); + mRenderers = new RendererContainer; } - return 0; + unsigned int index = mRenderers->size(); + RendererPtr rendererPtr = RendererPtr( &renderer ); + mRenderers->push_back( rendererPtr ); + AddRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() ); + return index; } unsigned int Actor::GetRendererCount() const { - //TODO: MESH_REWORK : Add support for multiple renderers - RendererAttachment* attachment = dynamic_cast(mAttachment.Get()); - return attachment ? 1u : 0u; + unsigned int rendererCount(0); + if( mRenderers ) + { + rendererCount = mRenderers->size(); + } + + return rendererCount; } -Renderer& Actor::GetRendererAt( unsigned int index ) +RendererPtr Actor::GetRendererAt( unsigned int index ) { - //TODO: MESH_REWORK : Add support for multiple renderers - DALI_ASSERT_DEBUG( index == 0 && "Only one renderer is supported." ); - - //TODO: MESH_REWORK : Temporary code - RendererAttachment* attachment = dynamic_cast(mAttachment.Get()); - DALI_ASSERT_ALWAYS( attachment && "Actor doesn't have a renderer" ); + RendererPtr renderer; + if( index < GetRendererCount() ) + { + renderer = ( *mRenderers )[ index ]; + } - return attachment->GetRenderer(); + return renderer; } void Actor::RemoveRenderer( Renderer& renderer ) { - //TODO: MESH_REWORK : Add support for multiple renderers - mAttachment = NULL; + if( mRenderers ) + { + RendererIter end = mRenderers->end(); + for( RendererIter iter = mRenderers->begin(); iter != end; ++iter ) + { + if( (*iter).Get() == &renderer ) + { + mRenderers->erase( iter ); + RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.GetRendererSceneObject() ); + break; + } + } + } } void Actor::RemoveRenderer( unsigned int index ) { - //TODO: MESH_REWORK : Add support for multiple renderers - mAttachment = NULL; -} - -void Actor::SetOverlay( bool enable ) -{ - // Setting STENCIL will override OVERLAY - if( DrawMode::STENCIL != mDrawMode ) + if( index < GetRendererCount() ) { - SetDrawMode( enable ? DrawMode::OVERLAY : DrawMode::NORMAL ); + RendererPtr renderer = ( *mRenderers )[ index ]; + RemoveRendererMessage( GetEventThreadServices(), *mNode, renderer.Get()->GetRendererSceneObject() ); + mRenderers->erase( mRenderers->begin()+index ); } } bool Actor::IsOverlay() const { - return ( DrawMode::OVERLAY == mDrawMode ); + return ( DrawMode::OVERLAY_2D == mDrawMode ); } void Actor::SetDrawMode( DrawMode::Type drawMode ) { // this flag is not animatable so keep the value mDrawMode = drawMode; - if( NULL != mNode ) + if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) ) { // mNode is being used in a separate thread; queue a message to set the value SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode ); @@ -1511,7 +1707,7 @@ bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float sc return false; } -bool Actor::ScreenToLocal( RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const +bool Actor::ScreenToLocal( const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const { bool retval = false; // only valid when on-stage @@ -1542,13 +1738,9 @@ bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMat return false; } - BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() ); - - // Calculate the ModelView matrix - Matrix modelView( false/*don't init*/); - // need to use the components as world matrix is only updated for actors that need it - modelView.SetTransformComponents( mNode->GetWorldScale( bufferIndex ), mNode->GetWorldOrientation( bufferIndex ), mNode->GetWorldPosition( bufferIndex ) ); - Matrix::Multiply( modelView, modelView, viewMatrix ); + // Get the ModelView matrix + Matrix modelView; + Matrix::Multiply( modelView, mNode->GetWorldMatrix(0), viewMatrix ); // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects Matrix invertedMvp( false/*don't init*/); @@ -1681,21 +1873,19 @@ bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) con return ( b2 * b2 - a * c ) >= 0.f; } -bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const +bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const { bool hit = false; - if( OnStage() && - NULL != mNode ) + if( OnStage() && NULL != mNode ) { - BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() ); - // Transforms the ray to the local reference system. - // Calculate the inverse of Model matrix Matrix invModelMatrix( false/*don't init*/); - // need to use the components as world matrix is only updated for actors that need it - invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale( bufferIndex ), mNode->GetWorldOrientation( bufferIndex ), mNode->GetWorldPosition( bufferIndex ) ); + + BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() ); + invModelMatrix = mNode->GetWorldMatrix(0); + invModelMatrix.Invert(); Vector4 rayOriginLocal( invModelMatrix * rayOrigin ); Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() ); @@ -1745,7 +1935,7 @@ bool Actor::IsKeyboardFocusable() const bool Actor::GetTouchRequired() const { - return !mTouchedSignal.Empty() || mDerivedRequiresTouch; + return !mTouchedSignal.Empty() || !mTouchSignal.Empty() || mDerivedRequiresTouch; } bool Actor::GetHoverRequired() const @@ -1779,20 +1969,26 @@ bool Actor::IsGestureRequred( Gesture::Type type ) const return mGestureData && mGestureData->IsGestureRequred( type ); } -bool Actor::EmitTouchEventSignal( const TouchEvent& event ) +bool Actor::EmitTouchEventSignal( const TouchEvent& event, const Dali::TouchData& touch ) { bool consumed = false; + if( !mTouchSignal.Empty() ) + { + Dali::Actor handle( this ); + consumed = mTouchSignal.Emit( handle, touch ); + } + if( !mTouchedSignal.Empty() ) { Dali::Actor handle( this ); - consumed = mTouchedSignal.Emit( handle, event ); + consumed |= mTouchedSignal.Emit( handle, event ); } if( !consumed ) { // Notification for derived classes - consumed = OnTouchEvent( event ); + consumed = OnTouchEvent( event ); // TODO } return consumed; @@ -1836,11 +2032,25 @@ bool Actor::EmitWheelEventSignal( const WheelEvent& event ) return consumed; } +void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityChange::Type type ) +{ + if( ! mVisibilityChangedSignal.Empty() ) + { + Dali::Actor handle( this ); + mVisibilityChangedSignal.Emit( handle, visible, type ); + } +} + Dali::Actor::TouchSignalType& Actor::TouchedSignal() { return mTouchedSignal; } +Dali::Actor::TouchDataSignalType& Actor::TouchSignal() +{ + return mTouchSignal; +} + Dali::Actor::HoverSignalType& Actor::HoveredSignal() { return mHoveredSignal; @@ -1866,10 +2076,15 @@ Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal() return mOnRelayoutSignal; } +DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal() +{ + return mVisibilityChangedSignal; +} + bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor ) { bool connected( true ); - Actor* actor = dynamic_cast< Actor* >( object ); + Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type. if( 0 == signalName.compare( SIGNAL_TOUCHED ) ) { @@ -1891,6 +2106,14 @@ bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tra { actor->OffStageSignal().Connect( tracker, functor ); } + else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) ) + { + actor->OnRelayoutSignal().Connect( tracker, functor ); + } + else if( 0 == signalName.compare( SIGNAL_TOUCH ) ) + { + actor->TouchSignal().Connect( tracker, functor ); + } else { // signalName does not match any signal @@ -1903,18 +2126,22 @@ bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tra Actor::Actor( DerivedType derivedType ) : mParent( NULL ), mChildren( NULL ), + mRenderers( NULL ), mNode( NULL ), mParentOrigin( NULL ), mAnchorPoint( NULL ), mRelayoutData( NULL ), mGestureData( NULL ), - mAttachment(), - mTargetSize( 0.0f, 0.0f, 0.0f ), + mTargetOrientation( Quaternion::IDENTITY ), + mTargetColor( Color::WHITE ), + mTargetSize( Vector3::ZERO ), + mTargetPosition( Vector3::ZERO ), + mTargetScale( Vector3::ONE ), mName(), mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved mDepth( 0u ), + mSiblingOrder(0u), mIsRoot( ROOT_LAYER == derivedType ), - mIsRenderable( RENDERABLE == derivedType ), mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ), mIsOnStage( false ), mSensitive( true ), @@ -1925,11 +2152,15 @@ Actor::Actor( DerivedType derivedType ) mDerivedRequiresWheelEvent( false ), mOnStageSignalled( false ), mInsideOnSizeSet( false ), + mInheritPosition( true ), mInheritOrientation( true ), mInheritScale( true ), + mPositionUsesAnchorPoint( true ), + mVisible( true ), mDrawMode( DrawMode::NORMAL ), mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ), - mColorMode( Node::DEFAULT_COLOR_MODE ) + mColorMode( Node::DEFAULT_COLOR_MODE ), + mClippingMode( ClippingMode::DISABLED ) { } @@ -1959,6 +2190,7 @@ Actor::~Actor() } } delete mChildren; + delete mRenderers; // Guard to allow handle destruction after Core has been destroyed if( EventThreadServices::IsCoreRunning() ) @@ -1986,15 +2218,14 @@ Actor::~Actor() } } -void Actor::ConnectToStage( unsigned int parentDepth, int index ) +void Actor::ConnectToStage( unsigned int parentDepth ) { - // This container is used instead of walking the Actor hierachy. - // It protects us when the Actor hierachy is modified during OnStageConnectionExternal callbacks. + // This container is used instead of walking the Actor hierarchy. + // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks. ActorContainer connectionList; - - // This stage is atomic i.e. not interrupted by user callbacks - RecursiveConnectToStage( connectionList, parentDepth+1, index ); + // This stage is atomic i.e. not interrupted by user callbacks. + RecursiveConnectToStage( connectionList, parentDepth + 1 ); // Notify applications about the newly connected actors. const ActorIter endIter = connectionList.end(); @@ -2006,14 +2237,15 @@ void Actor::ConnectToStage( unsigned int parentDepth, int index ) RelayoutRequest(); } -void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth, int index ) +void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned int depth ) { DALI_ASSERT_ALWAYS( !OnStage() ); mIsOnStage = true; mDepth = depth; + SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) ); - ConnectToSceneGraph( index ); + ConnectToSceneGraph(); // Notification for internal derived classes OnStageConnectionInternal(); @@ -2036,22 +2268,16 @@ void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned in * This method is called when the Actor is connected to the Stage. * The parent must have added its Node to the scene-graph. * The child must connect its Node to the parent's Node. - * This is resursive; the child calls ConnectToStage() for its children. + * This is recursive; the child calls ConnectToStage() for its children. */ -void Actor::ConnectToSceneGraph( int index ) +void Actor::ConnectToSceneGraph() { DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL ); if( NULL != mNode ) { // Reparent Node in next Update - ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode, index ); - } - - // Notify attachment - if( mAttachment ) - { - mAttachment->Connect(); + ConnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *(mParent->mNode), *mNode ); } // Request relayout on all actors that are added to the scenegraph @@ -2134,12 +2360,6 @@ void Actor::DisconnectFromSceneGraph() { // Notification for Object::Observers OnSceneObjectRemove(); - - // Notify attachment - if( mAttachment ) - { - mAttachment->Disconnect(); - } } void Actor::NotifyStageDisconnection() @@ -2170,10 +2390,9 @@ bool Actor::IsNodeConnected() const { bool connected( false ); - if( OnStage() && - NULL != mNode ) + if( OnStage() && ( NULL != mNode ) ) { - if( mNode->IsRoot() || mNode->GetParent() ) + if( IsRoot() || mNode->GetParent() ) { connected = true; } @@ -2272,7 +2491,21 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr { case Dali::Actor::Property::PARENT_ORIGIN: { - SetParentOrigin( property.Get< Vector3 >() ); + 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; } @@ -2296,7 +2529,21 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr case Dali::Actor::Property::ANCHOR_POINT: { - SetAnchorPoint( property.Get< Vector3 >() ); + 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; } @@ -2427,8 +2674,13 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr } case Dali::Actor::Property::COLOR_ALPHA: + case Dali::DevelActor::Property::OPACITY: { - SetOpacity( property.Get< float >() ); + float value; + if( property.Get( value ) ) + { + SetOpacity( value ); + } break; } @@ -2450,6 +2702,12 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr break; } + case Dali::Actor::Property::INHERIT_POSITION: + { + SetInheritPosition( property.Get< bool >() ); + break; + } + case Dali::Actor::Property::INHERIT_ORIENTATION: { SetInheritOrientation( property.Get< bool >() ); @@ -2464,19 +2722,31 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr case Dali::Actor::Property::COLOR_MODE: { - SetColorMode( Scripting::GetColorMode( property.Get< std::string >() ) ); + ColorMode mode = mColorMode; + if ( Scripting::GetEnumerationProperty< ColorMode >( property, COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT, mode ) ) + { + SetColorMode( mode ); + } break; } case Dali::Actor::Property::POSITION_INHERITANCE: { - SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get< std::string >() ) ); + PositionInheritanceMode mode = mPositionInheritanceMode; + if( Scripting::GetEnumerationProperty< PositionInheritanceMode >( property, POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT, mode ) ) + { + SetPositionInheritanceMode( mode ); + } break; } case Dali::Actor::Property::DRAW_MODE: { - SetDrawMode( Scripting::GetDrawMode( property.Get< std::string >() ) ); + DrawMode::Type mode = mDrawMode; + if( Scripting::GetEnumerationProperty< DrawMode::Type >( property, DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT, mode ) ) + { + SetDrawMode( mode ); + } break; } @@ -2488,8 +2758,8 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr case Dali::Actor::Property::WIDTH_RESIZE_POLICY: { - ResizePolicy::Type type; - if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), ResizePolicy::TypeTable, ResizePolicy::TypeTableCount, type ) ) + ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set. + if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) ) { SetResizePolicy( type, Dimension::WIDTH ); } @@ -2498,8 +2768,8 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr case Dali::Actor::Property::HEIGHT_RESIZE_POLICY: { - ResizePolicy::Type type; - if( Scripting::GetEnumeration< ResizePolicy::Type >( property.Get< std::string >().c_str(), ResizePolicy::TypeTable, ResizePolicy::TypeTableCount, type ) ) + ResizePolicy::Type type = static_cast< ResizePolicy::Type >( -1 ); // Set to invalid number so it definitely gets set. + if( Scripting::GetEnumerationProperty< ResizePolicy::Type >( property, RESIZE_POLICY_TABLE, RESIZE_POLICY_TABLE_COUNT, type ) ) { SetResizePolicy( type, Dimension::HEIGHT ); } @@ -2509,7 +2779,7 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr case Dali::Actor::Property::SIZE_SCALE_POLICY: { SizeScalePolicy::Type type; - if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SizeScalePolicy::TypeTable, SizeScalePolicy::TypeTableCount, type ) ) + if( Scripting::GetEnumeration< SizeScalePolicy::Type >( property.Get< std::string >().c_str(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT, type ) ) { SetSizeScalePolicy( type ); } @@ -2558,6 +2828,48 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr break; } + case Dali::DevelActor::Property::SIBLING_ORDER: + { + int value; + + if( property.Get( value ) ) + { + if( static_cast(value) != mSiblingOrder ) + { + 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; + if( NULL != mNode ) + { + SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode ); + } + } + break; + } + + case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT: + { + bool value = false; + if( property.Get( value ) && value != mPositionUsesAnchorPoint ) + { + mPositionUsesAnchorPoint = value; + if( NULL != mNode ) + { + SetPositionUsesAnchorPointMessage( GetEventThreadServices(), *mNode, mPositionUsesAnchorPoint ); + } + } + break; + } + default: { // this can happen in the case of a non-animatable default property so just do nothing @@ -2569,7 +2881,7 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr // TODO: This method needs to be removed void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value ) { - switch( entry.type ) + switch( entry.GetType() ) { case Property::BOOLEAN: { @@ -2717,358 +3029,167 @@ void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata default: { - DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here - break; + // nothing to do for other types } - } + } // entry.GetType } Property::Value Actor::GetDefaultProperty( Property::Index index ) const { Property::Value value; - switch( index ) + if( ! GetCachedPropertyValue( index, value ) ) { - case Dali::Actor::Property::PARENT_ORIGIN: - { - value = GetCurrentParentOrigin(); - 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: - { - value = GetCurrentParentOrigin().x; - break; - } + return value; +} - case Dali::Actor::Property::PARENT_ORIGIN_Y: - { - value = GetCurrentParentOrigin().y; - break; - } +Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) const +{ + Property::Value value; - case Dali::Actor::Property::PARENT_ORIGIN_Z: - { - value = GetCurrentParentOrigin().z; - 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: - { - value = GetCurrentAnchorPoint(); - break; - } + return value; +} - case Dali::Actor::Property::ANCHOR_POINT_X: - { - value = GetCurrentAnchorPoint().x; - break; - } +const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const +{ + return mNode; +} - case Dali::Actor::Property::ANCHOR_POINT_Y: - { - value = GetCurrentAnchorPoint().y; - break; - } +const SceneGraph::PropertyOwner* Actor::GetSceneObject() const +{ + // This method should only return an object connected to the scene-graph + return OnStage() ? mNode : NULL; +} - case Dali::Actor::Property::ANCHOR_POINT_Z: - { - value = GetCurrentAnchorPoint().z; - break; - } +const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const +{ + DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" ); - case Dali::Actor::Property::SIZE: - { - value = GetCurrentSize(); - break; - } + const PropertyBase* property( NULL ); - case Dali::Actor::Property::SIZE_WIDTH: - { - value = GetCurrentSize().width; - break; - } + // This method should only return a property of an object connected to the scene-graph + if( !OnStage() ) + { + return property; + } - case Dali::Actor::Property::SIZE_HEIGHT: - { - value = GetCurrentSize().height; - break; - } + if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) + { + AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index ); + DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" ); - case Dali::Actor::Property::SIZE_DEPTH: - { - value = GetCurrentSize().depth; - break; - } + property = animatable->GetSceneGraphProperty(); + } + else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties + ( index <= PROPERTY_CUSTOM_MAX_INDEX ) ) + { + CustomPropertyMetadata* custom = FindCustomProperty( index ); + DALI_ASSERT_ALWAYS( custom && "Property index is invalid" ); - case Dali::Actor::Property::POSITION: + property = custom->GetSceneGraphProperty(); + } + else if( NULL != mNode ) + { + switch( index ) { - value = GetCurrentPosition(); - break; - } + case Dali::Actor::Property::SIZE: + property = &mNode->mSize; + break; - case Dali::Actor::Property::POSITION_X: - { - value = GetCurrentPosition().x; - break; - } + case Dali::Actor::Property::SIZE_WIDTH: + property = &mNode->mSize; + break; - case Dali::Actor::Property::POSITION_Y: - { - value = GetCurrentPosition().y; - break; - } + case Dali::Actor::Property::SIZE_HEIGHT: + property = &mNode->mSize; + break; - case Dali::Actor::Property::POSITION_Z: - { - value = GetCurrentPosition().z; - break; - } + case Dali::Actor::Property::SIZE_DEPTH: + property = &mNode->mSize; + break; - case Dali::Actor::Property::WORLD_POSITION: - { - value = GetCurrentWorldPosition(); - break; - } + case Dali::Actor::Property::POSITION: + property = &mNode->mPosition; + break; - case Dali::Actor::Property::WORLD_POSITION_X: - { - value = GetCurrentWorldPosition().x; - break; - } + case Dali::Actor::Property::POSITION_X: + property = &mNode->mPosition; + break; - case Dali::Actor::Property::WORLD_POSITION_Y: - { - value = GetCurrentWorldPosition().y; - break; - } + case Dali::Actor::Property::POSITION_Y: + property = &mNode->mPosition; + break; - case Dali::Actor::Property::WORLD_POSITION_Z: - { - value = GetCurrentWorldPosition().z; - break; - } + case Dali::Actor::Property::POSITION_Z: + property = &mNode->mPosition; + break; - case Dali::Actor::Property::ORIENTATION: - { - value = GetCurrentOrientation(); - break; - } + case Dali::Actor::Property::ORIENTATION: + property = &mNode->mOrientation; + break; - case Dali::Actor::Property::WORLD_ORIENTATION: - { - value = GetCurrentWorldOrientation(); - break; - } + case Dali::Actor::Property::SCALE: + property = &mNode->mScale; + break; - case Dali::Actor::Property::SCALE: - { - value = GetCurrentScale(); - break; - } + case Dali::Actor::Property::SCALE_X: + property = &mNode->mScale; + 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::VISIBLE: - { - value = IsVisible(); - 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: - { - 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::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_ORIENTATION: - { - value = IsOrientationInherited(); - break; - } - - case Dali::Actor::Property::INHERIT_SCALE: - { - value = IsScaleInherited(); - break; - } - - case Dali::Actor::Property::COLOR_MODE: - { - value = Scripting::GetColorMode( GetColorMode() ); - break; - } - - case Dali::Actor::Property::POSITION_INHERITANCE: - { - value = Scripting::GetPositionInheritanceMode( GetPositionInheritanceMode() ); - break; - } - - case Dali::Actor::Property::DRAW_MODE: - { - value = Scripting::GetDrawMode( 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 ), ResizePolicy::TypeTable, ResizePolicy::TypeTableCount ); - break; - } + case Dali::Actor::Property::SCALE_Y: + property = &mNode->mScale; + break; - case Dali::Actor::Property::HEIGHT_RESIZE_POLICY: - { - value = Scripting::GetLinearEnumerationName< ResizePolicy::Type >( GetResizePolicy( Dimension::HEIGHT ), ResizePolicy::TypeTable, ResizePolicy::TypeTableCount ); - break; - } + case Dali::Actor::Property::SCALE_Z: + property = &mNode->mScale; + break; - case Dali::Actor::Property::SIZE_SCALE_POLICY: - { - value = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SizeScalePolicy::TypeTable, SizeScalePolicy::TypeTableCount ); - break; - } + case Dali::Actor::Property::VISIBLE: + property = &mNode->mVisible; + 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::COLOR: + property = &mNode->mColor; + 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::COLOR_RED: + property = &mNode->mColor; + 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::COLOR_GREEN: + property = &mNode->mColor; + break; - case Dali::Actor::Property::MINIMUM_SIZE: - { - value = Vector2( GetMinimumSize( Dimension::WIDTH ), GetMinimumSize( Dimension::HEIGHT ) ); - break; - } + case Dali::Actor::Property::COLOR_BLUE: + property = &mNode->mColor; + break; - case Dali::Actor::Property::MAXIMUM_SIZE: - { - value = Vector2( GetMaximumSize( Dimension::WIDTH ), GetMaximumSize( Dimension::HEIGHT ) ); - break; - } + case Dali::Actor::Property::COLOR_ALPHA: + case Dali::DevelActor::Property::OPACITY: + property = &mNode->mColor; + break; - default: - { - DALI_ASSERT_ALWAYS( false && "Actor Property index invalid" ); // should not come here - break; + default: + break; } } - return value; -} - -const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const -{ - return mNode; -} - -const SceneGraph::PropertyOwner* Actor::GetSceneObject() const -{ - // This method should only return an object connected to the scene-graph - return OnStage() ? mNode : NULL; + return property; } -const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const +const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const { - DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" ); - - const PropertyBase* property( NULL ); + const PropertyInputImpl* property( NULL ); // This method should only return a property of an object connected to the scene-graph if( !OnStage() ) @@ -3083,17 +3204,49 @@ const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index ind property = animatable->GetSceneGraphProperty(); } - else if ( index >= DEFAULT_PROPERTY_MAX_COUNT ) + else if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties + ( index <= PROPERTY_CUSTOM_MAX_INDEX ) ) { CustomPropertyMetadata* custom = FindCustomProperty( index ); DALI_ASSERT_ALWAYS( custom && "Property index is invalid" ); - property = custom->GetSceneGraphProperty(); } else if( NULL != mNode ) { switch( index ) { + case Dali::Actor::Property::PARENT_ORIGIN: + property = &mNode->mParentOrigin; + break; + + case Dali::Actor::Property::PARENT_ORIGIN_X: + property = &mNode->mParentOrigin; + break; + + case Dali::Actor::Property::PARENT_ORIGIN_Y: + property = &mNode->mParentOrigin; + break; + + case Dali::Actor::Property::PARENT_ORIGIN_Z: + property = &mNode->mParentOrigin; + break; + + case Dali::Actor::Property::ANCHOR_POINT: + property = &mNode->mAnchorPoint; + break; + + case Dali::Actor::Property::ANCHOR_POINT_X: + property = &mNode->mAnchorPoint; + break; + + case Dali::Actor::Property::ANCHOR_POINT_Y: + property = &mNode->mAnchorPoint; + break; + + case Dali::Actor::Property::ANCHOR_POINT_Z: + property = &mNode->mAnchorPoint; + break; + case Dali::Actor::Property::SIZE: property = &mNode->mSize; break; @@ -3126,163 +3279,20 @@ const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index ind property = &mNode->mPosition; break; - case Dali::Actor::Property::ORIENTATION: - property = &mNode->mOrientation; + case Dali::Actor::Property::WORLD_POSITION: + property = &mNode->mWorldPosition; break; - case Dali::Actor::Property::SCALE: - property = &mNode->mScale; + case Dali::Actor::Property::WORLD_POSITION_X: + property = &mNode->mWorldPosition; break; - case Dali::Actor::Property::SCALE_X: - property = &mNode->mScale; + case Dali::Actor::Property::WORLD_POSITION_Y: + property = &mNode->mWorldPosition; break; - case Dali::Actor::Property::SCALE_Y: - property = &mNode->mScale; - break; - - case Dali::Actor::Property::SCALE_Z: - property = &mNode->mScale; - break; - - case Dali::Actor::Property::VISIBLE: - property = &mNode->mVisible; - break; - - case Dali::Actor::Property::COLOR: - property = &mNode->mColor; - break; - - case Dali::Actor::Property::COLOR_RED: - property = &mNode->mColor; - break; - - case Dali::Actor::Property::COLOR_GREEN: - property = &mNode->mColor; - break; - - case Dali::Actor::Property::COLOR_BLUE: - property = &mNode->mColor; - break; - - case Dali::Actor::Property::COLOR_ALPHA: - property = &mNode->mColor; - break; - - default: - break; - } - } - - return property; -} - -const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index index ) const -{ - const PropertyInputImpl* property( NULL ); - - // This method should only return a property of an object connected to the scene-graph - if( !OnStage() ) - { - return property; - } - - if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) - { - AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index ); - DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" ); - - property = animatable->GetSceneGraphProperty(); - } - else if ( index >= DEFAULT_PROPERTY_MAX_COUNT ) - { - CustomPropertyMetadata* custom = FindCustomProperty( index ); - DALI_ASSERT_ALWAYS( custom && "Property index is invalid" ); - property = custom->GetSceneGraphProperty(); - } - else if( NULL != mNode ) - { - switch( index ) - { - case Dali::Actor::Property::PARENT_ORIGIN: - property = &mNode->mParentOrigin; - break; - - case Dali::Actor::Property::PARENT_ORIGIN_X: - property = &mNode->mParentOrigin; - break; - - case Dali::Actor::Property::PARENT_ORIGIN_Y: - property = &mNode->mParentOrigin; - break; - - case Dali::Actor::Property::PARENT_ORIGIN_Z: - property = &mNode->mParentOrigin; - break; - - case Dali::Actor::Property::ANCHOR_POINT: - property = &mNode->mAnchorPoint; - break; - - case Dali::Actor::Property::ANCHOR_POINT_X: - property = &mNode->mAnchorPoint; - break; - - case Dali::Actor::Property::ANCHOR_POINT_Y: - property = &mNode->mAnchorPoint; - break; - - case Dali::Actor::Property::ANCHOR_POINT_Z: - property = &mNode->mAnchorPoint; - break; - - case Dali::Actor::Property::SIZE: - property = &mNode->mSize; - break; - - case Dali::Actor::Property::SIZE_WIDTH: - property = &mNode->mSize; - break; - - case Dali::Actor::Property::SIZE_HEIGHT: - property = &mNode->mSize; - break; - - case Dali::Actor::Property::SIZE_DEPTH: - property = &mNode->mSize; - break; - - case Dali::Actor::Property::POSITION: - property = &mNode->mPosition; - break; - - case Dali::Actor::Property::POSITION_X: - property = &mNode->mPosition; - break; - - case Dali::Actor::Property::POSITION_Y: - property = &mNode->mPosition; - break; - - case Dali::Actor::Property::POSITION_Z: - property = &mNode->mPosition; - break; - - case Dali::Actor::Property::WORLD_POSITION: - property = &mNode->mWorldPosition; - break; - - case Dali::Actor::Property::WORLD_POSITION_X: - property = &mNode->mWorldPosition; - break; - - case Dali::Actor::Property::WORLD_POSITION_Y: - property = &mNode->mWorldPosition; - break; - - case Dali::Actor::Property::WORLD_POSITION_Z: - property = &mNode->mWorldPosition; + case Dali::Actor::Property::WORLD_POSITION_Z: + property = &mNode->mWorldPosition; break; case Dali::Actor::Property::ORIENTATION: @@ -3334,8 +3344,11 @@ const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index ind break; case Dali::Actor::Property::COLOR_ALPHA: + case Dali::DevelActor::Property::OPACITY: + { property = &mNode->mColor; break; + } case Dali::Actor::Property::WORLD_COLOR: property = &mNode->mWorldColor; @@ -3407,6 +3420,7 @@ int Actor::GetPropertyComponentIndex( Property::Index index ) const } case Dali::Actor::Property::COLOR_ALPHA: + case Dali::DevelActor::Property::OPACITY: { componentIndex = 3; break; @@ -3423,7 +3437,7 @@ int Actor::GetPropertyComponentIndex( Property::Index index ) const return componentIndex; } -void Actor::SetParent( Actor* parent, int index ) +void Actor::SetParent( Actor* parent ) { if( parent ) { @@ -3435,8 +3449,11 @@ void Actor::SetParent( Actor* parent, int index ) parent->OnStage() ) { // Instruct each actor to create a corresponding node in the scene graph - ConnectToStage( parent->GetHierarchyDepth(), index ); + ConnectToStage( parent->GetHierarchyDepth() ); } + + // Resolve the name and index for the child properties if any + ResolveChildProperties(); } else // parent being set to NULL { @@ -3444,48 +3461,565 @@ void Actor::SetParent( Actor* parent, int index ) mParent = NULL; - if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction - OnStage() ) + if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction + OnStage() ) + { + DALI_ASSERT_ALWAYS( mNode != NULL ); + + if( NULL != mNode ) + { + // Disconnect the Node & its children from the scene-graph. + DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode ); + } + + // Instruct each actor to discard pointers to the scene-graph + DisconnectFromStage(); + } + } +} + +SceneGraph::Node* Actor::CreateNode() const +{ + return Node::New(); +} + +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; +} + +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: + { + Vector3 size = GetTargetSize(); + + // Should return preferred size if size is fixed as set by SetSize + if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED ) + { + size.width = GetPreferredSize().width; + } + if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED ) + { + size.height = GetPreferredSize().height; + } + + value = size; + + break; + } + + case Dali::Actor::Property::SIZE_WIDTH: + { + if( GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::FIXED ) + { + // Should return preferred size if size is fixed as set by SetSize + value = GetPreferredSize().width; + } + else + { + value = GetTargetSize().width; + } + break; + } + + case Dali::Actor::Property::SIZE_HEIGHT: + { + if( GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::FIXED ) + { + // Should return preferred size if size is fixed as set by SetSize + value = GetPreferredSize().height; + } + else + { + 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::DevelActor::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 = Scripting::GetLinearEnumerationName< ColorMode >( GetColorMode(), COLOR_MODE_TABLE, COLOR_MODE_TABLE_COUNT ); + break; + } + + case Dali::Actor::Property::POSITION_INHERITANCE: + { + value = Scripting::GetLinearEnumerationName< PositionInheritanceMode >( GetPositionInheritanceMode(), POSITION_INHERITANCE_MODE_TABLE, POSITION_INHERITANCE_MODE_TABLE_COUNT ); + break; + } + + case Dali::Actor::Property::DRAW_MODE: + { + value = Scripting::GetEnumerationName< DrawMode::Type >( GetDrawMode(), DRAW_MODE_TABLE, DRAW_MODE_TABLE_COUNT ); + 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 = Scripting::GetLinearEnumerationName< SizeScalePolicy::Type >( GetSizeScalePolicy(), SIZE_SCALE_POLICY_TABLE, SIZE_SCALE_POLICY_TABLE_COUNT ); + 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(mSiblingOrder); + break; + } + + case Dali::DevelActor::Property::SCREEN_POSITION: + { + value = GetCurrentScreenPosition(); + break; + } + + case Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT: + { + value = mPositionUsesAnchorPoint; + 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: { - DALI_ASSERT_ALWAYS( mNode != NULL ); - - if( NULL != mNode ) - { - // Disconnect the Node & its children from the scene-graph. - DisconnectNodeMessage( GetEventThreadServices().GetUpdateManager(), *mNode ); - } + value = GetCurrentColor().g; + break; + } - // Instruct each actor to discard pointers to the scene-graph - DisconnectFromStage(); + case Dali::Actor::Property::COLOR_BLUE: + { + value = GetCurrentColor().b; + break; } - } -} -SceneGraph::Node* Actor::CreateNode() const -{ - return Node::New(); -} + case Dali::Actor::Property::COLOR_ALPHA: + case Dali::DevelActor::Property::OPACITY: + { + value = GetCurrentColor().a; + break; + } -bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ ) -{ - bool done = false; - Actor* actor = dynamic_cast< Actor* >( object ); + case Dali::Actor::Property::WORLD_COLOR: + { + value = GetCurrentWorldColor(); + break; + } - if( actor ) - { - if( 0 == actionName.compare( ACTION_SHOW ) ) + case Dali::Actor::Property::WORLD_MATRIX: { - actor->SetVisible( true ); - done = true; + value = GetCurrentWorldMatrix(); + break; } - else if( 0 == actionName.compare( ACTION_HIDE ) ) + + default: { - actor->SetVisible( false ); - done = true; + // Must be an event-side only property + valueSet = false; + break; } } - return done; + return valueSet; } void Actor::EnsureRelayoutData() @@ -3994,6 +4528,7 @@ Vector2 Actor::ApplySizeSetPolicy( const Vector2 size ) return size; } } + break; } default: @@ -4033,6 +4568,22 @@ void Actor::SetNegotiatedSize( RelayoutContainer& container ) 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. + if(GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE) + { + SetLayoutNegotiated(false, Dimension::WIDTH); + } + if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE) + { + SetLayoutNegotiated(false, Dimension::HEIGHT); + } + // Do the negotiation NegotiateDimensions( allocatedSize ); @@ -4046,6 +4597,19 @@ void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& cont { 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->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE) + { + child->SetLayoutNegotiated(false, Dimension::WIDTH); + child->SetLayoutDirty(true, Dimension::WIDTH); + } + if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE) + { + child->SetLayoutNegotiated(false, Dimension::HEIGHT); + child->SetLayoutDirty(true, Dimension::HEIGHT); + } + // Only relayout if required if( child->RelayoutRequired() ) { @@ -4095,7 +4659,7 @@ Vector2 Actor::GetPreferredSize() const { if ( mRelayoutData ) { - return mRelayoutData->preferredSize; + return Vector2( mRelayoutData->preferredSize ); } return GetDefaultPreferredSize(); @@ -4163,6 +4727,488 @@ float Actor::GetMaximumSize( Dimension::Type dimension ) const return FLT_MAX; // Default } +Object* Actor::GetParentObject() const +{ + return mParent; +} + +void Actor::SetSiblingOrder( unsigned int order ) +{ + mSiblingOrder = std::min( order, static_cast( DevelLayer::SIBLING_ORDER_MULTIPLIER ) ); + if( mIsOnStage ) + { + SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) ); + } +} + +void Actor::DefragmentSiblingIndexes( ActorContainer& siblings ) +{ + // Sibling index may not be in consecutive order as the sibling range is limited ( DevelLayer::SIBLING_ORDER_MULTIPLIER ) + // we need to remove the gaps and ensure the number start from 0 and consecutive hence have a full range. + + // Start at index 0, while index <= highest order + // Find next index higher than 0 + // if nextHigher > index+1 + // set all nextHigher orders to index+1 + + // Limitation: May reach the ceiling of DevelLayer::SIBLING_ORDER_MULTIPLIER with highest sibling. + + ActorIter end = siblings.end(); + int highestOrder = 0; + for( ActorIter iter = siblings.begin(); iter != end; ++iter ) + { + ActorPtr sibling = (*iter); + int siblingOrder = sibling->mSiblingOrder; + highestOrder = std::max( highestOrder, siblingOrder ); + } + + for ( int index = 0; index <= highestOrder; index++ ) + { + int nextHighest = -1; + + // Find Next highest + for( ActorIter iter = siblings.begin(); iter != end; ++iter ) + { + ActorPtr sibling = (*iter); + int siblingOrder = sibling->mSiblingOrder; + + if ( siblingOrder > index ) + { + if ( nextHighest == -1 ) + { + nextHighest = siblingOrder; + } + nextHighest = std::min( nextHighest, siblingOrder ); + } + } + + // Check if a gap exists between indexes, if so set next index to consecutive number + if ( ( nextHighest - index ) > 1 ) + { + for( ActorIter iter = siblings.begin(); iter != end; ++iter ) + { + ActorPtr sibling = (*iter); + int siblingOrder = sibling->mSiblingOrder; + if ( siblingOrder == nextHighest ) + { + sibling->mSiblingOrder = index + 1; + if ( sibling->mSiblingOrder >= Dali::DevelLayer::SIBLING_ORDER_MULTIPLIER ) + { + DALI_LOG_WARNING( "Reached max sibling order level for raising / lowering actors\n" ); + sibling->mSiblingOrder = Dali::DevelLayer::SIBLING_ORDER_MULTIPLIER; + } + sibling->SetSiblingOrder( sibling->mSiblingOrder ); + } + } + } + } +} + +bool Actor::ShiftSiblingsLevels( ActorContainer& siblings, int targetLevelToShiftFrom ) +{ + // Allows exclusive levels for an actor by shifting all sibling levels at the target and above by 1 + bool defragmentationRequired( false ); + ActorIter end = siblings.end(); + for( ActorIter iter = siblings.begin(); ( iter != end ) ; ++iter ) + { + // Move actors at nearest order and above up by 1 + ActorPtr sibling = (*iter); + if ( sibling != this ) + { + // Iterate through container of actors, any actor with a sibling order of the target or greater should + // be incremented by 1. + if ( sibling->mSiblingOrder >= targetLevelToShiftFrom ) + { + sibling->mSiblingOrder++; + if ( sibling->mSiblingOrder + 1 >= DevelLayer::SIBLING_ORDER_MULTIPLIER ) + { + // If a sibling order raises so that it is only 1 from the maximum allowed then set flag so + // can re-order all sibling orders. + defragmentationRequired = true; + } + sibling->SetSiblingOrder( sibling->mSiblingOrder ); + } + } + } + return defragmentationRequired; +} + +void Actor::Raise() +{ + /* + 1) Check if already at top and nothing to be done. + This Actor can have highest sibling order but if not exclusive then another actor at same sibling + order can be positioned above it due to insertion order of actors. + 2) Find nearest sibling level above, these are the siblings this actor needs to be above + 3) a) There may be other levels above this target level + b) Increment all sibling levels at the level above nearest(target) + c) Now have a vacant sibling level + 4) Set this actor's sibling level to nearest +1 as now vacated. + + Note May not just be sibling level + 1 as could be empty levels in-between + + Example: + + 1 ) Initial order + ActorC ( sibling level 4 ) + ActorB ( sibling level 3 ) + ActorA ( sibling level 1 ) + + 2 ) ACTION: Raise A above B + a) Find nearest level above A = Level 3 + b) Increment levels above Level 3 + + ActorC ( sibling level 5 ) + ActorB ( sibling level 3 ) NEAREST + ActorA ( sibling level 1 ) + + 3 ) Set Actor A sibling level to nearest +1 as vacant + + ActorC ( sibling level 5 ) + ActorA ( sibling level 4 ) + ActorB ( sibling level 3 ) + + 4 ) Sibling order levels have a maximum defined in DevelLayer::SIBLING_ORDER_MULTIPLIER + If shifting causes this ceiling to be reached. then a defragmentation can be performed to + remove any empty sibling order gaps and start from sibling level 0 again. + If the number of actors reaches this maximum and all using exclusive sibling order values then + defragmention will stop and new sibling orders will be set to same max value. + */ + if ( mParent ) + { + int nearestLevel = mSiblingOrder; + int shortestDistanceToNextLevel = DevelLayer::SIBLING_ORDER_MULTIPLIER; + bool defragmentationRequired( false ); + + ActorContainer* siblings = mParent->mChildren; + + // Find Nearest sibling level above this actor + ActorIter end = siblings->end(); + for( ActorIter iter = siblings->begin(); iter != end; ++iter ) + { + ActorPtr sibling = (*iter); + if ( sibling != this ) + { + int order = GetSiblingOrder( sibling ); + + if ( ( order >= mSiblingOrder ) ) + { + int distanceToNextLevel = order - mSiblingOrder; + if ( distanceToNextLevel < shortestDistanceToNextLevel ) + { + nearestLevel = order; + shortestDistanceToNextLevel = distanceToNextLevel; + } + } + } + } + + if ( nearestLevel < DevelLayer::SIBLING_ORDER_MULTIPLIER ) // Actor is not already exclusively at top + { + mSiblingOrder = nearestLevel + 1; // Set sibling level to that above the nearest level + defragmentationRequired = ShiftSiblingsLevels( *siblings, mSiblingOrder ); + // Move current actor to newly vacated order level + SetSiblingOrder( mSiblingOrder ); + if ( defragmentationRequired ) + { + DefragmentSiblingIndexes( *siblings ); + } + } + SetSiblingOrder( mSiblingOrder ); + } + else + { + DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" ); + } +} + +void Actor::Lower() +{ + /** + 1) Check if actor already at bottom and if nothing needs to be done + This Actor can have lowest sibling order but if not exclusive then another actor at same sibling + order can be positioned above it due to insertion order of actors so need to move this actor below it. + 2) Find nearest sibling level below, this Actor needs to be below it + 3) a) Need to vacate a sibling level below nearest for this actor to occupy + b) Shift up all sibling order values of actor at the nearest level and levels above it to vacate a level. + c) Set this actor's sibling level to this newly vacated level. + 4 ) Sibling order levels have a maximum defined in DevelLayer::SIBLING_ORDER_MULTIPLIER + If shifting causes this ceiling to be reached. then a defragmentation can be performed to + remove any empty sibling order gaps and start from sibling level 0 again. + If the number of actors reaches this maximum and all using exclusive sibling order values then + defragmention will stop and new sibling orders will be set to same max value. + */ + + if ( mParent ) + { + // 1) Find nearest level below + int nearestLevel = mSiblingOrder; + int shortestDistanceToNextLevel = DevelLayer::SIBLING_ORDER_MULTIPLIER; + + ActorContainer* siblings = mParent->mChildren; + + ActorIter end = siblings->end(); + for( ActorIter iter = siblings->begin(); iter != end; ++iter ) + { + ActorPtr sibling = (*iter); + if ( sibling != this ) + { + int order = GetSiblingOrder( sibling ); + + if ( order <= mSiblingOrder ) + { + int distanceToNextLevel = mSiblingOrder - order; + if ( distanceToNextLevel < shortestDistanceToNextLevel ) + { + nearestLevel = order; + shortestDistanceToNextLevel = distanceToNextLevel; + } + } + } + } + + bool defragmentationRequired ( false ); + + // 2) If actor already not at bottom, raise all actors at required level and above + if ( shortestDistanceToNextLevel < DevelLayer::SIBLING_ORDER_MULTIPLIER ) // Actor is not already exclusively at bottom + { + mSiblingOrder = nearestLevel; + defragmentationRequired = ShiftSiblingsLevels( *siblings, mSiblingOrder ); + // Move current actor to newly vacated order + SetSiblingOrder( mSiblingOrder ); + if ( defragmentationRequired ) + { + DefragmentSiblingIndexes( *siblings ); + } + } + } + else + { + DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" ); + } +} + +void Actor::RaiseToTop() +{ + /** + 1 ) Find highest sibling order actor + 2 ) If highest sibling level not itself then set sibling order to that + 1 + 3 ) highest sibling order can be same as itself so need to increment over that + 4 ) Sibling order levels have a maximum defined in DevelLayer::SIBLING_ORDER_MULTIPLIER + If shifting causes this ceiling to be reached. then a defragmentation can be performed to + remove any empty sibling order gaps and start from sibling level 0 again. + If the number of actors reaches this maximum and all using exclusive sibling order values then + defragmention will stop and new sibling orders will be set to same max value. + */ + + if ( mParent ) + { + int maxOrder = 0; + + ActorContainer* siblings = mParent->mChildren; + + ActorIter end = siblings->end(); + for( ActorIter iter = siblings->begin(); iter != end; ++iter ) + { + ActorPtr sibling = (*iter); + if ( sibling != this ) + { + maxOrder = std::max( GetSiblingOrder( sibling ), maxOrder ); + } + } + + bool defragmentationRequired( false ); + + if ( maxOrder >= mSiblingOrder ) + { + mSiblingOrder = maxOrder + 1; + if ( mSiblingOrder + 1 >= DevelLayer::SIBLING_ORDER_MULTIPLIER ) + { + defragmentationRequired = true; + } + } + + SetSiblingOrder( mSiblingOrder ); + + if ( defragmentationRequired ) + { + DefragmentSiblingIndexes( *siblings ); + } + } + else + { + DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" ); + } +} + +void Actor::LowerToBottom() +{ + /** + See Actor::LowerToBottom() + + 1 ) Check if this actor already at exclusively at the bottom, if so then no more to be done. + 2 ) a ) Check if the bottom position 0 is vacant. + b ) If 0 position is not vacant then shift up all sibling order values from 0 and above + c ) 0 sibling position is vacant. + 3 ) Set this actor to vacant sibling order 0; + 4 ) Sibling order levels have a maximum defined in DevelLayer::SIBLING_ORDER_MULTIPLIER + If shifting causes this ceiling to be reached. then a defragmentation can be performed to + remove any empty sibling order gaps and start from sibling level 0 again. + If the number of actors reaches this maximum and all using exclusive sibling order values then + defragmention will stop and new sibling orders will be set to same max value. + */ + + if ( mParent ) + { + bool defragmentationRequired( false ); + bool orderZeroFree ( true ); + + ActorContainer* siblings = mParent->mChildren; + + bool actorAtLowestOrder = true; + ActorIter end = siblings->end(); + for( ActorIter iter = siblings->begin(); ( iter != end ) ; ++iter ) + { + ActorPtr sibling = (*iter); + if ( sibling != this ) + { + int siblingOrder = GetSiblingOrder( sibling ); + if ( siblingOrder <= mSiblingOrder ) + { + actorAtLowestOrder = false; + } + + if ( siblingOrder == 0 ) + { + orderZeroFree = false; + } + } + } + + if ( ! actorAtLowestOrder ) + { + if ( ! orderZeroFree ) + { + defragmentationRequired = ShiftSiblingsLevels( *siblings, 0 ); + } + mSiblingOrder = 0; + SetSiblingOrder( mSiblingOrder ); + + if ( defragmentationRequired ) + { + DefragmentSiblingIndexes( *siblings ); + } + } + } + else + { + DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" ); + } +} + +void Actor::RaiseAbove( Internal::Actor& target ) +{ + /** + 1 ) a) Find target actor's sibling order + b) If sibling order of target is the same as this actor then need to this Actor's sibling order + needs to be above it or the insertion order will determine which is drawn on top. + 2 ) Shift up by 1 all sibling order greater than target sibling order + 3 ) Set this actor to the sibling order to target +1 as will be a newly vacated gap above + 4 ) Sibling order levels have a maximum defined in DevelLayer::SIBLING_ORDER_MULTIPLIER + If shifting causes this ceiling to be reached. then a defragmentation can be performed to + remove any empty sibling order gaps and start from sibling level 0 again. + If the number of actors reaches this maximum and all using exclusive sibling order values then + defragmention will stop and new sibling orders will be set to same max value. + */ + + if ( mParent ) + { + if ( ValidateActors( *this, target ) ) + { + // Find target's sibling order + // Set actor sibling order to this number +1 + int targetSiblingOrder = GetSiblingOrder( &target ); + ActorContainer* siblings = mParent->mChildren; + mSiblingOrder = targetSiblingOrder + 1; + bool defragmentationRequired = ShiftSiblingsLevels( *siblings, mSiblingOrder ); + + SetSiblingOrder( mSiblingOrder ); + + if ( defragmentationRequired ) + { + DefragmentSiblingIndexes( *(mParent->mChildren) ); + } + } + } + else + { + DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" ); + } +} + +void Actor::LowerBelow( Internal::Actor& target ) +{ + /** + 1 ) a) Find target actor's sibling order + b) If sibling order of target is the same as this actor then need to this Actor's sibling order + needs to be below it or the insertion order will determine which is drawn on top. + 2 ) Shift the target sibling order and all sibling orders at that level or above by 1 + 3 ) Set this actor to the sibling order of the target before it changed. + 4 ) Sibling order levels have a maximum defined in DevelLayer::SIBLING_ORDER_MULTIPLIER + If shifting causes this ceiling to be reached. then a defragmentation can be performed to + remove any empty sibling order gaps and start from sibling level 0 again. + If the number of actors reaches this maximum and all using exclusive sibling order values then + defragmention will stop and new sibling orders will be set to same max value. + */ + + if ( mParent ) + { + if ( ValidateActors( *this, target ) ) + { + bool defragmentationRequired ( false ); + // Find target's sibling order + // Set actor sibling order to target sibling order - 1 + int targetSiblingOrder = GetSiblingOrder( &target); + ActorContainer* siblings = mParent->mChildren; + if ( targetSiblingOrder == 0 ) + { + //lower to botton + ActorIter end = siblings->end(); + for( ActorIter iter = siblings->begin(); ( iter != end ) ; ++iter ) + { + ActorPtr sibling = (*iter); + if ( sibling != this ) + { + sibling->mSiblingOrder++; + if ( sibling->mSiblingOrder + 1 >= DevelLayer::SIBLING_ORDER_MULTIPLIER ) + { + defragmentationRequired = true; + } + sibling->SetSiblingOrder( sibling->mSiblingOrder ); + } + } + mSiblingOrder = 0; + } + else + { + defragmentationRequired = ShiftSiblingsLevels( *siblings, targetSiblingOrder ); + + mSiblingOrder = targetSiblingOrder; + } + SetSiblingOrder( mSiblingOrder ); + + if ( defragmentationRequired ) + { + DefragmentSiblingIndexes( *(mParent->mChildren) ); + } + } + } + else + { + DALI_LOG_WARNING( "Actor must have a parent, Sibling order not changed.\n" ); + } +} + } // namespace Internal } // namespace Dali