Fix SCREEN_POSITION error
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / actor-impl.cpp
index ee60892..d36e103 100644 (file)
@@ -57,6 +57,11 @@ using Dali::Internal::SceneGraph::Node;
 using Dali::Internal::SceneGraph::AnimatableProperty;
 using Dali::Internal::SceneGraph::PropertyBase;
 
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER" );
+Debug::Filter* gLogRelayoutFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RELAYOUT_TIMER" );
+#endif
+
 namespace Dali
 {
 
@@ -87,32 +92,6 @@ 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
 
 /**
@@ -127,6 +106,7 @@ struct Actor::RelayoutData
     for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
     {
       resizePolicies[ i ] = ResizePolicy::DEFAULT;
+      useAssignedSize[ i ] = false;
       negotiatedDimensions[ i ] = 0.0f;
       dimensionNegotiated[ i ] = false;
       dimensionDirty[ i ] = false;
@@ -138,6 +118,7 @@ struct Actor::RelayoutData
   }
 
   ResizePolicy::Type resizePolicies[ Dimension::DIMENSION_COUNT ];      ///< Resize policies
+  bool useAssignedSize[ Dimension::DIMENSION_COUNT ];                   ///< The flag to specify whether the size should be assigned to the actor
 
   Dimension::Type dimensionDependencies[ Dimension::DIMENSION_COUNT ];  ///< A list of dimension dependencies
 
@@ -226,6 +207,8 @@ DALI_PROPERTY( "minimumSize",               VECTOR2,  true,  false, false, Dali:
 DALI_PROPERTY( "maximumSize",               VECTOR2,  true,  false, false, Dali::Actor::Property::MAXIMUM_SIZE )
 DALI_PROPERTY( "inheritPosition",           BOOLEAN,  true,  false, false, Dali::Actor::Property::INHERIT_POSITION )
 DALI_PROPERTY( "clippingMode",              STRING,   true,  false, false, Dali::Actor::Property::CLIPPING_MODE )
+DALI_PROPERTY( "layoutDirection",           STRING,   true,  false, false, Dali::Actor::Property::LAYOUT_DIRECTION )
+DALI_PROPERTY( "inheritLayoutDirection",    BOOLEAN,  true,  false, false, Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION )
 DALI_PROPERTY( "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 )
@@ -325,6 +308,10 @@ DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
 
+DALI_ENUM_TO_STRING_TABLE_BEGIN( LAYOUT_DIRECTION )
+DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, LEFT_TO_RIGHT )
+DALI_ENUM_TO_STRING_WITH_SCOPE( LayoutDirection, RIGHT_TO_LEFT )
+DALI_ENUM_TO_STRING_TABLE_END( LAYOUT_DIRECTION )
 
 bool GetAnchorPointConstant( const std::string& value, Vector3& anchor )
 {
@@ -385,11 +372,6 @@ 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
@@ -512,6 +494,8 @@ void Actor::Add( Actor& child )
       // Notification for derived classes
       OnChildAdd( child );
 
+      InheritLayoutDirectionRecursively( ActorPtr( &child ), mLayoutDirection );
+
       // Only put in a relayout request if there is a suitable dependency
       if( RelayoutDependentOnChildren() )
       {
@@ -834,7 +818,7 @@ const Vector2 Actor::GetCurrentScreenPosition() const
   {
     StagePtr stage = Stage::GetCurrent();
     Vector3 worldPosition =  mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
-    Vector3 actorSize = GetCurrentSize() * GetCurrentScale();
+    Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale();
     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 );
@@ -1053,19 +1037,7 @@ Matrix Actor::GetCurrentWorldMatrix() const
 
 void Actor::SetVisible( bool visible )
 {
-  if( mVisible != visible )
-  {
-    if( NULL != mNode )
-    {
-      // mNode is being used in a separate thread; queue a message to set the value & base value
-      SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
-    }
-
-    mVisible = visible;
-
-    // Emit the signal on this actor and all its children
-    EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
-  }
+  SetVisibleInternal( visible, SendMessage::TRUE );
 }
 
 bool Actor::IsVisible() const
@@ -1108,7 +1080,7 @@ ClippingMode::Type Actor::GetClippingMode() const
 
 unsigned int Actor::GetSortingDepth()
 {
-  return GetDepthIndex( mDepth, mSiblingOrder );
+  return mSortedDepth;
 }
 
 const Vector4& Actor::GetCurrentWorldColor() const
@@ -1287,53 +1259,6 @@ void Actor::SetSizeInternal( const Vector3& size )
   }
 }
 
-void Actor::NotifySizeAnimation( Animation& animation, const Vector3& targetSize )
-{
-  mTargetSize = targetSize;
-
-  // Notify deriving classes
-  OnSizeAnimation( animation, mTargetSize );
-}
-
-void Actor::NotifySizeAnimation( Animation& animation, float targetSize, Property::Index property )
-{
-  if ( Dali::Actor::Property::SIZE_WIDTH == property )
-  {
-    mTargetSize.width = targetSize;
-  }
-  else if ( Dali::Actor::Property::SIZE_HEIGHT == property )
-  {
-    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( IsRelayoutEnabled() && !mRelayoutData->insideRelayout )
@@ -1387,9 +1312,21 @@ void Actor::SetDepth( float depth )
   }
 }
 
-const Vector3& Actor::GetTargetSize() const
+Vector3 Actor::GetTargetSize() const
 {
-  return mTargetSize;
+  Vector3 size = mTargetSize;
+
+  // 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;
+  }
+
+  return size;
 }
 
 const Vector3& Actor::GetCurrentSize() const
@@ -1420,7 +1357,15 @@ void Actor::SetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimensio
   {
     if( dimension & ( 1 << i ) )
     {
-      mRelayoutData->resizePolicies[ i ] = policy;
+      if ( policy == ResizePolicy::USE_ASSIGNED_SIZE )
+      {
+        mRelayoutData->useAssignedSize[ i ] = true;
+      }
+      else
+      {
+        mRelayoutData->resizePolicies[ i ] = policy;
+        mRelayoutData->useAssignedSize[ i ] = false;
+      }
     }
   }
 
@@ -1483,7 +1428,14 @@ ResizePolicy::Type Actor::GetResizePolicy( Dimension::Type dimension ) const
     {
       if( ( dimension & ( 1 << i ) ) )
       {
-        return mRelayoutData->resizePolicies[ i ];
+        if( mRelayoutData->useAssignedSize[ i ] )
+        {
+          return ResizePolicy::USE_ASSIGNED_SIZE;
+        }
+        else
+        {
+          return mRelayoutData->resizePolicies[ i ];
+        }
       }
     }
   }
@@ -2041,6 +1993,15 @@ void Actor::EmitVisibilityChangedSignal( bool visible, DevelActor::VisibilityCha
   }
 }
 
+void Actor::EmitLayoutDirectionChangedSignal( LayoutDirection::Type type )
+{
+  if( ! mLayoutDirectionChangedSignal.Empty() )
+  {
+    Dali::Actor handle( this );
+    mLayoutDirectionChangedSignal.Emit( handle, type );
+  }
+}
+
 Dali::Actor::TouchSignalType& Actor::TouchedSignal()
 {
   return mTouchedSignal;
@@ -2081,6 +2042,11 @@ DevelActor::VisibilityChangedSignalType& Actor::VisibilityChangedSignal()
   return mVisibilityChangedSignal;
 }
 
+Dali::Actor::LayoutDirectionChangedSignalType& Actor::LayoutDirectionChangedSignal()
+{
+  return mLayoutDirectionChangedSignal;
+}
+
 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
 {
   bool connected( true );
@@ -2139,8 +2105,8 @@ Actor::Actor( DerivedType derivedType )
   mTargetScale( Vector3::ONE ),
   mName(),
   mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
+  mSortedDepth( 0u ),
   mDepth( 0u ),
-  mSiblingOrder(0u),
   mIsRoot( ROOT_LAYER == derivedType ),
   mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
   mIsOnStage( false ),
@@ -2157,6 +2123,8 @@ Actor::Actor( DerivedType derivedType )
   mInheritScale( true ),
   mPositionUsesAnchorPoint( true ),
   mVisible( true ),
+  mInheritLayoutDirection( true ),
+  mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
   mDrawMode( DrawMode::NORMAL ),
   mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
   mColorMode( Node::DEFAULT_COLOR_MODE ),
@@ -2166,11 +2134,10 @@ Actor::Actor( DerivedType derivedType )
 
 void Actor::Initialize()
 {
-  // Node creation
-  SceneGraph::Node* node = CreateNode();
-
-  AddNodeMessage( GetEventThreadServices().GetUpdateManager(), *node ); // Pass ownership to scene-graph
-  mNode = node; // Keep raw-pointer to Node
+  // Node creation, keep raw-pointer to Node for messaging
+  mNode = CreateNode();
+  OwnerPointer< SceneGraph::Node > transferOwnership( const_cast< SceneGraph::Node* >( mNode ) );
+  AddNodeMessage( GetEventThreadServices().GetUpdateManager(), transferOwnership );
 
   OnInitialize();
 
@@ -2224,6 +2191,12 @@ void Actor::ConnectToStage( unsigned int parentDepth )
   // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks.
   ActorContainer connectionList;
 
+  StagePtr stage = Stage::GetCurrent();
+  if( stage )
+  {
+    stage->RequestRebuildDepthTree();
+  }
+
   // This stage is atomic i.e. not interrupted by user callbacks.
   RecursiveConnectToStage( connectionList, parentDepth + 1 );
 
@@ -2243,7 +2216,6 @@ void Actor::RecursiveConnectToStage( ActorContainer& connectionList, unsigned in
 
   mIsOnStage = true;
   mDepth = depth;
-  SetDepthIndexMessage( GetEventThreadServices(), *mNode, GetDepthIndex( mDepth, mSiblingOrder ) );
 
   ConnectToSceneGraph();
 
@@ -2316,6 +2288,12 @@ void Actor::DisconnectFromStage()
   // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks.
   ActorContainer disconnectionList;
 
+  StagePtr stage = Stage::GetCurrent();
+  if( stage )
+  {
+    stage->RequestRebuildDepthTree();
+  }
+
   // This stage is atomic i.e. not interrupted by user callbacks
   RecursiveDisconnectFromStage( disconnectionList );
 
@@ -2401,6 +2379,44 @@ bool Actor::IsNodeConnected() const
   return connected;
 }
 
+// This method initiates traversal of the actor tree using depth-first
+// traversal to set a depth index based on traversal order. It sends a
+// single message to update manager to update all the actor's nodes in
+// this tree with the depth index. The sceneGraphNodeDepths vector's
+// elements are ordered by depth, and could be used to reduce sorting
+// in the update thread.
+void Actor::RebuildDepthTree()
+{
+  DALI_LOG_TIMER_START(depthTimer);
+
+  // Vector of scene-graph nodes and their depths to send to UpdateManager
+  // in a single message
+  OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths( new SceneGraph::NodeDepths() );
+
+  int depthIndex = 1;
+  DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
+
+  SetDepthIndicesMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphNodeDepths );
+  DALI_LOG_TIMER_END(depthTimer, gLogFilter, Debug::Concise, "Depth tree traversal time: ");
+}
+
+void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneGraphNodeDepths, int& depthIndex )
+{
+  mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
+  sceneGraphNodeDepths->Add( const_cast<SceneGraph::Node*>( mNode ), mSortedDepth );
+
+  // Create/add to children of this node
+  if( mChildren )
+  {
+    for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
+    {
+      Actor* childActor = (*it).Get();
+      ++depthIndex;
+      childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
+    }
+  }
+}
+
 unsigned int Actor::GetDefaultPropertyCount() const
 {
   return DEFAULT_PROPERTY_COUNT;
@@ -2834,10 +2850,7 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr
 
       if( property.Get( value ) )
       {
-        if( static_cast<unsigned int>(value) != mSiblingOrder )
-        {
-          SetSiblingOrder( value );
-        }
+        SetSiblingOrder( value );
       }
       break;
     }
@@ -2870,6 +2883,28 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr
       break;
     }
 
+    case Dali::Actor::Property::LAYOUT_DIRECTION:
+    {
+      Dali::LayoutDirection::Type direction = mLayoutDirection;
+      mInheritLayoutDirection = false;
+
+      if( Scripting::GetEnumerationProperty< LayoutDirection::Type >( property, LAYOUT_DIRECTION_TABLE, LAYOUT_DIRECTION_TABLE_COUNT, direction ) )
+      {
+        InheritLayoutDirectionRecursively( this, direction, true );
+      }
+      break;
+    }
+
+    case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
+    {
+      bool value = false;
+      if( property.Get( value ) )
+      {
+        SetInheritLayoutDirection( value );
+      }
+      break;
+    }
+
     default:
     {
       // this can happen in the case of a non-animatable default property so just do nothing
@@ -3060,93 +3095,397 @@ Property::Value Actor::GetDefaultPropertyCurrentValue( Property::Index index ) c
   return value;
 }
 
-const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
+void Actor::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
 {
-  return mNode;
-}
+  switch( animationType )
+  {
+    case Animation::TO:
+    case Animation::BETWEEN:
+    {
+      switch( index )
+      {
+        case Dali::Actor::Property::SIZE:
+        {
+          if( value.Get( mTargetSize ) )
+          {
+            // Notify deriving classes
+            OnSizeAnimation( animation, mTargetSize );
+          }
+          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::SIZE_WIDTH:
+        {
+          if( value.Get( mTargetSize.width ) )
+          {
+            // Notify deriving classes
+            OnSizeAnimation( animation, mTargetSize );
+          }
+          break;
+        }
 
-const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
-{
-  DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
+        case Dali::Actor::Property::SIZE_HEIGHT:
+        {
+          if( value.Get( mTargetSize.height ) )
+          {
+            // Notify deriving classes
+            OnSizeAnimation( animation, mTargetSize );
+          }
+          break;
+        }
 
-  const PropertyBase* property( NULL );
+        case Dali::Actor::Property::SIZE_DEPTH:
+        {
+          if( value.Get( mTargetSize.depth ) )
+          {
+            // Notify deriving classes
+            OnSizeAnimation( animation, mTargetSize );
+          }
+          break;
+        }
 
-  // This method should only return a property of an object connected to the scene-graph
-  if( !OnStage() )
-  {
-    return property;
-  }
+        case Dali::Actor::Property::POSITION:
+        {
+          value.Get( mTargetPosition );
+          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::POSITION_X:
+        {
+          value.Get( mTargetPosition.x );
+          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_Y:
+        {
+          value.Get( mTargetPosition.y );
+          break;
+        }
 
-    property = custom->GetSceneGraphProperty();
-  }
-  else if( NULL != mNode )
-  {
-    switch( index )
-    {
-      case Dali::Actor::Property::SIZE:
-        property = &mNode->mSize;
-        break;
+        case Dali::Actor::Property::POSITION_Z:
+        {
+          value.Get( mTargetPosition.z );
+          break;
+        }
 
-      case Dali::Actor::Property::SIZE_WIDTH:
-        property = &mNode->mSize;
-        break;
+        case Dali::Actor::Property::ORIENTATION:
+        {
+          value.Get( mTargetOrientation );
+          break;
+        }
 
-      case Dali::Actor::Property::SIZE_HEIGHT:
-        property = &mNode->mSize;
-        break;
+        case Dali::Actor::Property::SCALE:
+        {
+          value.Get( mTargetScale );
+          break;
+        }
 
-      case Dali::Actor::Property::SIZE_DEPTH:
-        property = &mNode->mSize;
-        break;
+        case Dali::Actor::Property::SCALE_X:
+        {
+          value.Get( mTargetScale.x );
+          break;
+        }
 
-      case Dali::Actor::Property::POSITION:
-        property = &mNode->mPosition;
-        break;
+        case Dali::Actor::Property::SCALE_Y:
+        {
+          value.Get( mTargetScale.y );
+          break;
+        }
 
-      case Dali::Actor::Property::POSITION_X:
-        property = &mNode->mPosition;
-        break;
+        case Dali::Actor::Property::SCALE_Z:
+        {
+          value.Get( mTargetScale.z );
+          break;
+        }
 
-      case Dali::Actor::Property::POSITION_Y:
-        property = &mNode->mPosition;
-        break;
+        case Dali::Actor::Property::VISIBLE:
+        {
+          SetVisibleInternal( value.Get< bool >(), SendMessage::FALSE );
+          break;
+        }
 
-      case Dali::Actor::Property::POSITION_Z:
-        property = &mNode->mPosition;
-        break;
+        case Dali::Actor::Property::COLOR:
+        {
+          value.Get( mTargetColor );
+          break;
+        }
 
-      case Dali::Actor::Property::ORIENTATION:
-        property = &mNode->mOrientation;
-        break;
+        case Dali::Actor::Property::COLOR_RED:
+        {
+          value.Get( mTargetColor.r );
+          break;
+        }
 
-      case Dali::Actor::Property::SCALE:
-        property = &mNode->mScale;
-        break;
+        case Dali::Actor::Property::COLOR_GREEN:
+        {
+          value.Get( mTargetColor.g );
+          break;
+        }
 
-      case Dali::Actor::Property::SCALE_X:
-        property = &mNode->mScale;
-        break;
+        case Dali::Actor::Property::COLOR_BLUE:
+        {
+          value.Get( mTargetColor.b );
+          break;
+        }
 
-      case Dali::Actor::Property::SCALE_Y:
+        case Dali::Actor::Property::COLOR_ALPHA:
+        case Dali::DevelActor::Property::OPACITY:
+        {
+          value.Get( mTargetColor.a );
+          break;
+        }
+
+        default:
+        {
+          // Not an animatable property. Do nothing.
+          break;
+        }
+      }
+      break;
+    }
+
+    case Animation::BY:
+    {
+      switch( index )
+      {
+        case Dali::Actor::Property::SIZE:
+        {
+          if( AdjustValue< Vector3 >( mTargetSize, value ) )
+          {
+            // Notify deriving classes
+            OnSizeAnimation( animation, mTargetSize );
+          }
+          break;
+        }
+
+        case Dali::Actor::Property::SIZE_WIDTH:
+        {
+          if( AdjustValue< float >( mTargetSize.width, value ) )
+          {
+            // Notify deriving classes
+            OnSizeAnimation( animation, mTargetSize );
+          }
+          break;
+        }
+
+        case Dali::Actor::Property::SIZE_HEIGHT:
+        {
+          if( AdjustValue< float >( mTargetSize.height, value ) )
+          {
+            // Notify deriving classes
+            OnSizeAnimation( animation, mTargetSize );
+          }
+          break;
+        }
+
+        case Dali::Actor::Property::SIZE_DEPTH:
+        {
+          if( AdjustValue< float >( mTargetSize.depth, value ) )
+          {
+            // Notify deriving classes
+            OnSizeAnimation( animation, mTargetSize );
+          }
+          break;
+        }
+
+        case Dali::Actor::Property::POSITION:
+        {
+          AdjustValue< Vector3 >( mTargetPosition, value );
+          break;
+        }
+
+        case Dali::Actor::Property::POSITION_X:
+        {
+          AdjustValue< float >( mTargetPosition.x, value );
+          break;
+        }
+
+        case Dali::Actor::Property::POSITION_Y:
+        {
+          AdjustValue< float >( mTargetPosition.y, value );
+          break;
+        }
+
+        case Dali::Actor::Property::POSITION_Z:
+        {
+          AdjustValue< float >( mTargetPosition.z, value );
+          break;
+        }
+
+        case Dali::Actor::Property::ORIENTATION:
+        {
+          Quaternion relativeValue;
+          if( value.Get( relativeValue ) )
+          {
+            mTargetOrientation *= relativeValue;
+          }
+          break;
+        }
+
+        case Dali::Actor::Property::SCALE:
+        {
+          AdjustValue< Vector3 >( mTargetScale, value );
+          break;
+        }
+
+        case Dali::Actor::Property::SCALE_X:
+        {
+          AdjustValue< float >( mTargetScale.x, value );
+          break;
+        }
+
+        case Dali::Actor::Property::SCALE_Y:
+        {
+          AdjustValue< float >( mTargetScale.y, value );
+          break;
+        }
+
+        case Dali::Actor::Property::SCALE_Z:
+        {
+          AdjustValue< float >( mTargetScale.z, value );
+          break;
+        }
+
+        case Dali::Actor::Property::VISIBLE:
+        {
+          bool relativeValue = false;
+          if( value.Get( relativeValue ) )
+          {
+            bool visible = mVisible || relativeValue;
+            SetVisibleInternal( visible, SendMessage::FALSE );
+          }
+          break;
+        }
+
+        case Dali::Actor::Property::COLOR:
+        {
+          AdjustValue< Vector4 >( mTargetColor, value );
+          break;
+        }
+
+        case Dali::Actor::Property::COLOR_RED:
+        {
+          AdjustValue< float >( mTargetColor.r, value );
+          break;
+        }
+
+        case Dali::Actor::Property::COLOR_GREEN:
+        {
+          AdjustValue< float >( mTargetColor.g, value );
+          break;
+        }
+
+        case Dali::Actor::Property::COLOR_BLUE:
+        {
+          AdjustValue< float >( mTargetColor.b, value );
+          break;
+        }
+
+        case Dali::Actor::Property::COLOR_ALPHA:
+        case Dali::DevelActor::Property::OPACITY:
+        {
+          AdjustValue< float >( mTargetColor.a, value );
+          break;
+        }
+
+        default:
+        {
+          // Not an animatable property. Do nothing.
+          break;
+        }
+      }
+      break;
+    }
+  }
+}
+
+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;
+}
+
+const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
+{
+  DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
+
+  const PropertyBase* 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 >= 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::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::ORIENTATION:
+        property = &mNode->mOrientation;
+        break;
+
+      case Dali::Actor::Property::SCALE:
+        property = &mNode->mScale;
+        break;
+
+      case Dali::Actor::Property::SCALE_X:
+        property = &mNode->mScale;
+        break;
+
+      case Dali::Actor::Property::SCALE_Y:
         property = &mNode->mScale;
         break;
 
@@ -3561,48 +3900,19 @@ bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& valu
 
     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;
-
+      value = GetTargetSize();
       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;
-      }
+      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;
-      }
+      value = GetTargetSize().height;
       break;
     }
 
@@ -3821,7 +4131,7 @@ bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& valu
 
     case Dali::DevelActor::Property::SIBLING_ORDER:
     {
-      value = static_cast<int>(mSiblingOrder);
+      value = static_cast<int>( GetSiblingOrder() );
       break;
     }
 
@@ -3837,6 +4147,18 @@ bool Actor::GetCachedPropertyValue( Property::Index index, Property::Value& valu
       break;
     }
 
+    case Dali::Actor::Property::LAYOUT_DIRECTION:
+    {
+      value = mLayoutDirection;
+      break;
+    }
+
+    case Dali::Actor::Property::INHERIT_LAYOUT_DIRECTION:
+    {
+      value = IsLayoutDirectionInherited();
+      break;
+    }
+
     default:
     {
       // Must be a scene-graph only property
@@ -4011,6 +4333,12 @@ bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& val
       break;
     }
 
+    case Dali::Actor::Property::VISIBLE:
+    {
+      value = IsVisible();
+      break;
+    }
+
     default:
     {
       // Must be an event-side only property
@@ -4305,7 +4633,7 @@ float Actor::NegotiateFromChildren( Dimension::Type dimension )
 
 float Actor::GetSize( Dimension::Type dimension ) const
 {
-  return GetDimensionValue( GetTargetSize(), dimension );
+  return GetDimensionValue( mTargetSize, dimension );
 }
 
 float Actor::GetNaturalSize( Dimension::Type dimension ) const
@@ -4471,7 +4799,7 @@ void Actor::NegotiateDimensions( const Vector2& allocatedSize )
   }
 }
 
-Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
+Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
 {
   switch( mRelayoutData->sizeSetPolicy )
   {
@@ -4575,13 +4903,15 @@ void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& cont
   // 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)
+  DALI_LOG_TIMER_START( NegSizeTimer1 );
+
+  if( GetUseAssignedSize(Dimension::WIDTH ) )
   {
-    SetLayoutNegotiated(false, Dimension::WIDTH);
+    SetLayoutNegotiated( false, Dimension::WIDTH );
   }
-  if(GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
+  if( GetUseAssignedSize( Dimension::HEIGHT ) )
   {
-    SetLayoutNegotiated(false, Dimension::HEIGHT);
+    SetLayoutNegotiated( false, Dimension::HEIGHT );
   }
 
   // Do the negotiation
@@ -4591,20 +4921,19 @@ void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& cont
   SetNegotiatedSize( container );
 
   // Negotiate down to children
-  const Vector2 newBounds = GetTargetSize().GetVectorXY();
-
   for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
   {
     ActorPtr child = GetChildAt( i );
 
     // Forces children that have already been laid out to be relayed out
     // if they have assigned size during relayout.
-    if(child->GetResizePolicy(Dimension::WIDTH) == ResizePolicy::USE_ASSIGNED_SIZE)
+    if( child->GetUseAssignedSize(Dimension::WIDTH) )
     {
       child->SetLayoutNegotiated(false, Dimension::WIDTH);
       child->SetLayoutDirty(true, Dimension::WIDTH);
     }
-    if(child->GetResizePolicy(Dimension::HEIGHT) == ResizePolicy::USE_ASSIGNED_SIZE)
+
+    if( child->GetUseAssignedSize(Dimension::HEIGHT) )
     {
       child->SetLayoutNegotiated(false, Dimension::HEIGHT);
       child->SetLayoutDirty(true, Dimension::HEIGHT);
@@ -4613,9 +4942,41 @@ void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& cont
     // Only relayout if required
     if( child->RelayoutRequired() )
     {
-      container.Add( Dali::Actor( child.Get() ), newBounds );
+      container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
     }
   }
+  DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
+}
+
+void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
+{
+  if( mRelayoutData )
+  {
+    for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
+    {
+      if( dimension & ( 1 << i ) )
+      {
+        mRelayoutData->useAssignedSize[ i ] = use;
+      }
+    }
+  }
+}
+
+bool Actor::GetUseAssignedSize( Dimension::Type dimension ) const
+{
+  if ( mRelayoutData )
+  {
+    // If more than one dimension is requested, just return the first one found
+    for( unsigned int i = 0; i < Dimension::DIMENSION_COUNT; ++i )
+    {
+      if( dimension & ( 1 << i ) )
+      {
+        return mRelayoutData->useAssignedSize[ i ];
+      }
+    }
+  }
+
+  return false;
 }
 
 void Actor::RelayoutRequest( Dimension::Type dimension )
@@ -4732,189 +5093,107 @@ Object* Actor::GetParentObject() const
   return mParent;
 }
 
-void Actor::SetSiblingOrder( unsigned int order )
+void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
 {
-  mSiblingOrder = std::min( order, static_cast<unsigned int>( DevelLayer::SIBLING_ORDER_MULTIPLIER ) );
-  if( mIsOnStage )
+  if( mVisible != visible )
   {
-    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
+    if( sendMessage == SendMessage::TRUE && NULL != mNode )
+    {
+      // mNode is being used in a separate thread; queue a message to set the value & base value
+      SceneGraph::NodePropertyMessage<bool>::Send( GetEventThreadServices(), mNode, &mNode->mVisible, &AnimatableProperty<bool>::Bake, visible );
+    }
 
-  // Limitation: May reach the ceiling of DevelLayer::SIBLING_ORDER_MULTIPLIER with highest sibling.
+    mVisible = visible;
 
-  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 );
+    // Emit the signal on this actor and all its children
+    EmitVisibilityChangedSignalRecursively( this, visible, DevelActor::VisibilityChange::SELF );
   }
+}
 
-  for ( int index = 0; index <= highestOrder; index++ )
+void Actor::SetSiblingOrder( unsigned int order )
+{
+  if ( mParent )
   {
-    int nextHighest = -1;
+    ActorContainer& siblings = *(mParent->mChildren);
+    unsigned int currentOrder = GetSiblingOrder();
 
-    // Find Next highest
-    for( ActorIter iter = siblings.begin(); iter != end; ++iter )
+    if( order != currentOrder )
     {
-      ActorPtr sibling = (*iter);
-      int siblingOrder = sibling->mSiblingOrder;
-
-      if ( siblingOrder > index )
+      if( order == 0 )
       {
-        if ( nextHighest == -1 )
+        LowerToBottom();
+      }
+      else if( order < siblings.size() -1 )
+      {
+        if( order > currentOrder )
         {
-          nextHighest = siblingOrder;
+          RaiseAbove( *siblings[order] );
         }
-        nextHighest = std::min( nextHighest, siblingOrder );
+        else
+        {
+          LowerBelow( *siblings[order] );
+        }
+      }
+      else
+      {
+        RaiseToTop();
       }
     }
+  }
+}
 
-    // Check if a gap exists between indexes, if so set next index to consecutive number
-    if ( ( nextHighest - index ) > 1 )
+unsigned int Actor::GetSiblingOrder() const
+{
+  unsigned int order = 0;
+
+  if ( mParent )
+  {
+    ActorContainer& siblings = *(mParent->mChildren);
+    for( size_t i=0; i<siblings.size(); ++i )
     {
-      for( ActorIter iter = siblings.begin(); iter != end; ++iter )
+      if( siblings[i] == this )
       {
-        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 );
-        }
+        order = i;
+        break;
       }
     }
   }
+
+  return order;
 }
 
-bool Actor::ShiftSiblingsLevels( ActorContainer& siblings, int targetLevelToShiftFrom )
+void Actor::RequestRebuildDepthTree()
 {
-  // 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 )
+  if( mIsOnStage )
   {
-    // Move actors at nearest order and above up by 1
-    ActorPtr sibling = (*iter);
-    if ( sibling != this )
+    StagePtr stage = Stage::GetCurrent();
+    if( stage )
     {
-      // 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 );
-      }
+      stage->RequestRebuildDepthTree();
     }
   }
-  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 )
+    ActorContainer& siblings = *(mParent->mChildren);
+    if( siblings.back() != this ) // If not already at end
     {
-      ActorPtr sibling = (*iter);
-      if ( sibling != this )
+      for( size_t i=0; i<siblings.size(); ++i )
       {
-        int order = GetSiblingOrder( sibling );
-
-        if ( ( order >= mSiblingOrder ) )
+        if( siblings[i] == this )
         {
-          int distanceToNextLevel =  order - mSiblingOrder;
-          if ( distanceToNextLevel < shortestDistanceToNextLevel )
-          {
-            nearestLevel = order;
-            shortestDistanceToNextLevel = distanceToNextLevel;
-          }
+          // Swap with next
+          ActorPtr next = siblings[i+1];
+          siblings[i+1] = this;
+          siblings[i] = next;
+          break;
         }
       }
     }
-
-    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 );
+    RequestRebuildDepthTree();
   }
   else
   {
@@ -4924,63 +5203,24 @@ void Actor::Raise()
 
 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 )
+    ActorContainer& siblings = *(mParent->mChildren);
+    if( siblings.front() != this ) // If not already at beginning
     {
-      ActorPtr sibling = (*iter);
-      if ( sibling != this )
+      for( size_t i=1; i<siblings.size(); ++i )
       {
-        int order = GetSiblingOrder( sibling );
-
-        if ( order <= mSiblingOrder )
+        if( siblings[i] == this )
         {
-          int distanceToNextLevel =  mSiblingOrder - order;
-          if ( distanceToNextLevel < shortestDistanceToNextLevel )
-          {
-            nearestLevel = order;
-            shortestDistanceToNextLevel = distanceToNextLevel;
-          }
+          // Swap with previous
+          ActorPtr previous = siblings[i-1];
+          siblings[i-1] = this;
+          siblings[i] = previous;
+          break;
         }
       }
     }
-
-    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 );
-      }
-    }
+    RequestRebuildDepthTree();
   }
   else
   {
@@ -4990,50 +5230,19 @@ void Actor::Lower()
 
 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 )
+    ActorContainer& siblings = *(mParent->mChildren);
+    if( siblings.back() != this ) // If not already at end
     {
-      ActorPtr sibling = (*iter);
-      if ( sibling != this )
+      ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
+      if( iter != siblings.end() )
       {
-        maxOrder = std::max( GetSiblingOrder( sibling ), maxOrder );
+        siblings.erase(iter);
+        siblings.push_back(ActorPtr(this));
       }
     }
-
-    bool defragmentationRequired( false );
-
-    if ( maxOrder >= mSiblingOrder )
-    {
-      mSiblingOrder = maxOrder + 1;
-      if ( mSiblingOrder + 1 >= DevelLayer::SIBLING_ORDER_MULTIPLIER )
-      {
-        defragmentationRequired = true;
-      }
-    }
-
-    SetSiblingOrder( mSiblingOrder );
-
-    if ( defragmentationRequired )
-    {
-      DefragmentSiblingIndexes( *siblings );
-    }
+    RequestRebuildDepthTree();
   }
   else
   {
@@ -5043,62 +5252,21 @@ void Actor::RaiseToTop()
 
 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  )
+    ActorContainer& siblings = *(mParent->mChildren);
+    if( siblings.front() != this ) // If not already at bottom,
     {
-      if ( ! orderZeroFree )
-      {
-        defragmentationRequired = ShiftSiblingsLevels( *siblings, 0 );
-      }
-      mSiblingOrder = 0;
-      SetSiblingOrder( mSiblingOrder );
+      ActorPtr thisPtr(this); // ensure this actor remains referenced.
 
-      if ( defragmentationRequired )
+      ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
+      if( iter != siblings.end() )
       {
-        DefragmentSiblingIndexes( *siblings );
+        siblings.erase(iter);
+        siblings.insert(siblings.begin(), thisPtr);
       }
     }
+    RequestRebuildDepthTree();
   }
   else
   {
@@ -5108,36 +5276,25 @@ void Actor::LowerToBottom()
 
 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 ) )
+    ActorContainer& siblings = *(mParent->mChildren);
+    if( siblings.back() != this && target.mParent == mParent ) // If not already at top
     {
-       // 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 );
+      ActorPtr thisPtr(this); // ensure this actor remains referenced.
 
-      if ( defragmentationRequired )
+      ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
+      ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
+      if( thisIter < targetIter )
       {
-        DefragmentSiblingIndexes( *(mParent->mChildren) );
+        siblings.erase(thisIter);
+        // Erasing early invalidates the targetIter. (Conversely, inserting first may also
+        // invalidate thisIter)
+        targetIter = std::find( siblings.begin(), siblings.end(), &target );
+        ++targetIter;
+        siblings.insert(targetIter, thisPtr);
       }
+      RequestRebuildDepthTree();
     }
   }
   else
@@ -5148,59 +5305,22 @@ void Actor::RaiseAbove( Internal::Actor& target )
 
 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 )  )
+    ActorContainer& siblings = *(mParent->mChildren);
+    if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
     {
-      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 );
+      ActorPtr thisPtr(this); // ensure this actor remains referenced.
 
-        mSiblingOrder = targetSiblingOrder;
-      }
-      SetSiblingOrder( mSiblingOrder );
+      ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
+      ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
 
-      if ( defragmentationRequired )
+      if( thisIter > targetIter )
       {
-        DefragmentSiblingIndexes( *(mParent->mChildren) );
+        siblings.erase(thisIter); // this only invalidates iterators at or after this point.
+        siblings.insert(targetIter, thisPtr);
       }
+      RequestRebuildDepthTree();
     }
   }
   else
@@ -5209,6 +5329,46 @@ void Actor::LowerBelow( Internal::Actor& target )
   }
 }
 
+void Actor::SetInheritLayoutDirection( bool inherit )
+{
+  if( mInheritLayoutDirection != inherit )
+  {
+    mInheritLayoutDirection = inherit;
+
+    if( inherit && mParent )
+    {
+      InheritLayoutDirectionRecursively( this, mParent->mLayoutDirection );
+    }
+  }
+}
+
+bool Actor::IsLayoutDirectionInherited() const
+{
+  return mInheritLayoutDirection;
+}
+
+void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirection::Type direction, bool set )
+{
+  if( actor && ( actor->mInheritLayoutDirection || set ) )
+  {
+    if( actor->mLayoutDirection != direction)
+    {
+      actor->mLayoutDirection = direction;
+      actor->EmitLayoutDirectionChangedSignal( direction );
+      actor->RelayoutRequest();
+    }
+
+    if( actor->GetChildCount() > 0 )
+    {
+      ActorContainer& children = actor->GetChildrenInternal();
+      for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
+      {
+        InheritLayoutDirectionRecursively( *iter, direction );
+      }
+    }
+  }
+}
+
 } // namespace Internal
 
 } // namespace Dali