Refactored Internal::Actor by moving some methods into the Relayouter
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / actor-impl.cpp
index 4fdf0c2..96e5a67 100755 (executable)
 #include <dali/public-api/math/vector3.h>
 #include <dali/public-api/math/radian.h>
 #include <dali/public-api/object/type-registry.h>
+#include <dali/devel-api/common/capabilities.h>
 #include <dali/devel-api/actors/actor-devel.h>
+#include <dali/internal/event/events/actor-gesture-data.h>
 #include <dali/internal/event/actors/actor-property-handler.h>
 #include <dali/internal/event/actors/actor-relayouter.h>
-#include <dali/internal/event/common/event-thread-services.h>
-#include <dali/internal/event/render-tasks/render-task-impl.h>
+#include <dali/internal/event/actors/actor-siblings.h>
 #include <dali/internal/event/actors/camera-actor-impl.h>
-#include <dali/internal/event/render-tasks/render-task-list-impl.h>
+#include <dali/internal/event/common/event-thread-services.h>
+#include <dali/internal/event/common/projection.h>
 #include <dali/internal/event/common/property-helper.h>
-#include <dali/internal/event/common/stage-impl.h>
-#include <dali/internal/event/common/type-info-impl.h>
 #include <dali/internal/event/common/scene-impl.h>
+#include <dali/internal/event/common/stage-impl.h>
 #include <dali/internal/event/common/thread-local-storage.h>
-#include <dali/internal/event/common/projection.h>
+#include <dali/internal/event/common/type-info-impl.h>
+#include <dali/internal/event/render-tasks/render-task-impl.h>
+#include <dali/internal/event/render-tasks/render-task-list-impl.h>
 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
 #include <dali/internal/update/nodes/node-messages.h>
-#include <dali/internal/event/events/actor-gesture-data.h>
 #include <dali/integration-api/debug.h>
 
 using Dali::Internal::SceneGraph::Node;
@@ -55,7 +57,6 @@ 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
@@ -143,25 +144,27 @@ DALI_PROPERTY( "keyboardFocusable",         BOOLEAN,  true,  false, false, Dali:
 DALI_PROPERTY( "siblingOrder",              INTEGER,  true,  false, false, Dali::DevelActor::Property::SIBLING_ORDER )
 DALI_PROPERTY( "updateSizeHint",            VECTOR2,  true,  false, false, Dali::DevelActor::Property::UPDATE_SIZE_HINT )
 DALI_PROPERTY( "captureAllTouchAfterStart", BOOLEAN,  true,  false, false, Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START )
+DALI_PROPERTY( "touchArea",                 VECTOR2,  true,  false, false, Dali::DevelActor::Property::TOUCH_AREA )
+DALI_PROPERTY( "blendEquation",             INTEGER,  true,  false, false, Dali::DevelActor::Property::BLEND_EQUATION )
 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties )
 
 // Signals
 
-const char* const SIGNAL_HOVERED = "hovered";
-const char* const SIGNAL_WHEEL_EVENT = "wheelEvent";
-const char* const SIGNAL_ON_SCENE = "onScene";
-const char* const SIGNAL_OFF_SCENE = "offScene";
-const char* const SIGNAL_ON_RELAYOUT = "onRelayout";
-const char* const SIGNAL_TOUCHED = "touched";
-const char* const SIGNAL_VISIBILITY_CHANGED = "visibilityChanged";
-const char* const SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
-const char* const SIGNAL_CHILD_ADDED = "childAdded";
-const char* const SIGNAL_CHILD_REMOVED = "childRemoved";
+static constexpr std::string_view SIGNAL_HOVERED                  = "hovered";
+static constexpr std::string_view SIGNAL_WHEEL_EVENT              = "wheelEvent";
+static constexpr std::string_view SIGNAL_ON_SCENE                 = "onScene";
+static constexpr std::string_view SIGNAL_OFF_SCENE                = "offScene";
+static constexpr std::string_view SIGNAL_ON_RELAYOUT              = "onRelayout";
+static constexpr std::string_view SIGNAL_TOUCHED                  = "touched";
+static constexpr std::string_view SIGNAL_VISIBILITY_CHANGED       = "visibilityChanged";
+static constexpr std::string_view SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
+static constexpr std::string_view SIGNAL_CHILD_ADDED              = "childAdded";
+static constexpr std::string_view SIGNAL_CHILD_REMOVED            = "childRemoved";
 
 // Actions
 
-const char* const ACTION_SHOW = "show";
-const char* const ACTION_HIDE = "hide";
+static constexpr std::string_view ACTION_SHOW = "show";
+static constexpr std::string_view ACTION_HIDE = "hide";
 
 BaseHandle CreateActor()
 {
@@ -170,19 +173,19 @@ BaseHandle CreateActor()
 
 TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties );
 
-SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
-SignalConnectorType signalConnector3( mType, SIGNAL_WHEEL_EVENT, &Actor::DoConnectSignal );
-SignalConnectorType signalConnector4( mType, SIGNAL_ON_SCENE, &Actor::DoConnectSignal );
-SignalConnectorType signalConnector5( mType, SIGNAL_OFF_SCENE, &Actor::DoConnectSignal );
-SignalConnectorType signalConnector6( mType, SIGNAL_ON_RELAYOUT, &Actor::DoConnectSignal );
-SignalConnectorType signalConnector7( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
-SignalConnectorType signalConnector8( mType, SIGNAL_VISIBILITY_CHANGED, &Actor::DoConnectSignal );
-SignalConnectorType signalConnector9( mType, SIGNAL_LAYOUT_DIRECTION_CHANGED, &Actor::DoConnectSignal );
-SignalConnectorType signalConnector10( mType, SIGNAL_CHILD_ADDED, &Actor::DoConnectSignal );
-SignalConnectorType signalConnector11( mType, SIGNAL_CHILD_REMOVED, &Actor::DoConnectSignal );
+SignalConnectorType signalConnector2(mType, std::string(SIGNAL_HOVERED), &Actor::DoConnectSignal);
+SignalConnectorType signalConnector3(mType, std::string(SIGNAL_WHEEL_EVENT), &Actor::DoConnectSignal);
+SignalConnectorType signalConnector4(mType, std::string(SIGNAL_ON_SCENE), &Actor::DoConnectSignal);
+SignalConnectorType signalConnector5(mType, std::string(SIGNAL_OFF_SCENE), &Actor::DoConnectSignal);
+SignalConnectorType signalConnector6(mType, std::string(SIGNAL_ON_RELAYOUT), &Actor::DoConnectSignal);
+SignalConnectorType signalConnector7(mType, std::string(SIGNAL_TOUCHED), &Actor::DoConnectSignal);
+SignalConnectorType signalConnector8(mType, std::string(SIGNAL_VISIBILITY_CHANGED), &Actor::DoConnectSignal);
+SignalConnectorType signalConnector9(mType, std::string(SIGNAL_LAYOUT_DIRECTION_CHANGED), &Actor::DoConnectSignal);
+SignalConnectorType signalConnector10(mType, std::string(SIGNAL_CHILD_ADDED), &Actor::DoConnectSignal);
+SignalConnectorType signalConnector11(mType, std::string(SIGNAL_CHILD_REMOVED), &Actor::DoConnectSignal);
 
-TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
-TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
+TypeAction a1(mType, std::string(ACTION_SHOW), &Actor::DoAction);
+TypeAction a2(mType, std::string(ACTION_HIDE), &Actor::DoAction);
 
 /**
  * @brief Extract a given dimension from a Vector2
@@ -237,7 +240,7 @@ void EmitVisibilityChangedSignalRecursively( ActorPtr actor, bool visible, Devel
 
     if( actor->GetChildCount() > 0 )
     {
-      for( ActorPtr& child : actor->GetChildrenInternal() )
+      for( auto& child : actor->GetChildrenInternal() )
       {
         EmitVisibilityChangedSignalRecursively( child, visible, DevelActor::VisibilityChange::PARENT );
       }
@@ -515,10 +518,9 @@ ActorPtr Actor::FindChildByName( const std::string& actorName )
   }
   else if( mChildren )
   {
-    ActorIter end = mChildren->end();
-    for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
+    for( const auto& actor : *mChildren )
     {
-      child = (*iter)->FindChildByName( actorName );
+      child = actor->FindChildByName( actorName );
 
       if( child )
       {
@@ -538,10 +540,9 @@ ActorPtr Actor::FindChildById( const uint32_t id )
   }
   else if( mChildren )
   {
-    ActorIter end = mChildren->end();
-    for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
+    for( const auto& actor : *mChildren )
     {
-      child = (*iter)->FindChildById( id );
+      child = actor->FindChildById( id );
 
       if( child )
       {
@@ -1196,6 +1197,11 @@ uint32_t Actor::AddRenderer( Renderer& renderer )
     mRenderers = new RendererContainer;
   }
 
+  if(mIsBlendEquationSet)
+  {
+    renderer.SetBlendEquation(static_cast<DevelBlendEquation::Type>(mBlendEquation));
+  }
+
   uint32_t index = static_cast<uint32_t>( mRenderers->size() ); //  4,294,967,295 renderers per actor
   RendererPtr rendererPtr = RendererPtr( &renderer );
   mRenderers->push_back( rendererPtr );
@@ -1252,6 +1258,33 @@ void Actor::RemoveRenderer( uint32_t index )
   }
 }
 
+void Actor::SetBlendEquation(DevelBlendEquation::Type blendEquation)
+{
+  if(Dali::Capabilities::IsBlendEquationSupported(blendEquation))
+  {
+    if(mBlendEquation != blendEquation)
+    {
+      mBlendEquation         = blendEquation;
+      uint32_t rendererCount = GetRendererCount();
+      for(uint32_t i = 0; i < rendererCount; ++i)
+      {
+        RendererPtr renderer = GetRendererAt(i);
+        renderer->SetBlendEquation(static_cast<DevelBlendEquation::Type>(blendEquation));
+      }
+    }
+    mIsBlendEquationSet = true;
+  }
+  else
+  {
+    DALI_LOG_ERROR("Invalid blend equation is entered.\n");
+  }
+}
+
+DevelBlendEquation::Type Actor::GetBlendEquation() const
+{
+  return mBlendEquation;
+}
+
 void Actor::SetDrawMode( DrawMode::Type drawMode )
 {
   // this flag is not animatable so keep the value
@@ -1374,43 +1407,45 @@ bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tra
   bool connected( true );
   Actor* actor = static_cast< Actor* >( object ); // TypeRegistry guarantees that this is the correct type.
 
-  if( 0 == signalName.compare( SIGNAL_HOVERED ) )
+  std::string_view name(signalName);
+
+  if(name == SIGNAL_HOVERED)
   {
     actor->HoveredSignal().Connect( tracker, functor );
   }
-  else if( 0 == signalName.compare( SIGNAL_WHEEL_EVENT ) )
+  else if(signalName == SIGNAL_WHEEL_EVENT)
   {
     actor->WheelEventSignal().Connect( tracker, functor );
   }
-  else if( 0 == signalName.compare( SIGNAL_ON_SCENE ) )
+  else if(name == SIGNAL_ON_SCENE)
   {
     actor->OnSceneSignal().Connect( tracker, functor );
   }
-  else if( 0 == signalName.compare( SIGNAL_OFF_SCENE ) )
+  else if(name == SIGNAL_OFF_SCENE)
   {
     actor->OffSceneSignal().Connect( tracker, functor );
   }
-  else if( 0 == signalName.compare( SIGNAL_ON_RELAYOUT ) )
+  else if(name == SIGNAL_ON_RELAYOUT)
   {
     actor->OnRelayoutSignal().Connect( tracker, functor );
   }
-  else if( 0 == signalName.compare( SIGNAL_TOUCHED ) )
+  else if(name == SIGNAL_TOUCHED)
   {
     actor->TouchedSignal().Connect( tracker, functor );
   }
-  else if( 0 == signalName.compare( SIGNAL_VISIBILITY_CHANGED ) )
+  else if(name == SIGNAL_VISIBILITY_CHANGED)
   {
     actor->VisibilityChangedSignal().Connect( tracker, functor );
   }
-  else if( 0 == signalName.compare( SIGNAL_LAYOUT_DIRECTION_CHANGED ) )
+  else if(name == SIGNAL_LAYOUT_DIRECTION_CHANGED)
   {
     actor->LayoutDirectionChangedSignal().Connect( tracker, functor );
   }
-  else if( 0 == signalName.compare( SIGNAL_CHILD_ADDED ) )
+  else if(name == SIGNAL_CHILD_ADDED)
   {
     actor->ChildAddedSignal().Connect( tracker, functor );
   }
-  else if( 0 == signalName.compare( SIGNAL_CHILD_REMOVED ) )
+  else if(name == SIGNAL_CHILD_REMOVED)
   {
     actor->ChildRemovedSignal().Connect( tracker, functor );
   }
@@ -1451,6 +1486,7 @@ Actor::Actor( DerivedType derivedType, const SceneGraph::Node& node )
   mTargetPosition( Vector3::ZERO ),
   mTargetScale( Vector3::ONE ),
   mAnimatedSize( Vector3::ZERO ),
+  mTouchArea( Vector2::ZERO ),
   mName(),
   mSortedDepth( 0u ),
   mDepth( 0u ),
@@ -1473,7 +1509,9 @@ Actor::Actor( DerivedType derivedType, const SceneGraph::Node& node )
   mLayoutDirection( LayoutDirection::LEFT_TO_RIGHT ),
   mDrawMode( DrawMode::NORMAL ),
   mColorMode( Node::DEFAULT_COLOR_MODE ),
-  mClippingMode( ClippingMode::DISABLED )
+  mClippingMode( ClippingMode::DISABLED ),
+  mBlendEquation( DevelBlendEquation::ADD ),
+  mIsBlendEquationSet( false )
 {
 }
 
@@ -1490,10 +1528,9 @@ Actor::~Actor()
   // to guard against GetParent() & Unparent() calls from CustomActor destructors.
   if( mChildren )
   {
-    ActorConstIter endIter = mChildren->end();
-    for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
+    for( const auto& actor : *mChildren )
     {
-      (*iter)->SetParent( nullptr );
+      actor->SetParent( nullptr );
     }
   }
   delete mChildren;
@@ -1537,10 +1574,9 @@ void Actor::ConnectToScene( uint32_t parentDepth )
   RecursiveConnectToScene( connectionList, parentDepth + 1 );
 
   // Notify applications about the newly connected actors.
-  const ActorIter endIter = connectionList.end();
-  for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
+  for( const auto& actor : connectionList )
   {
-    (*iter)->NotifyStageConnection();
+    actor->NotifyStageConnection();
   }
 
   RelayoutRequest();
@@ -1564,11 +1600,10 @@ void Actor::RecursiveConnectToScene( ActorContainer& connectionList, uint32_t de
   // Recursively connect children
   if( mChildren )
   {
-    ActorConstIter endIter = mChildren->end();
-    for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
+    for( const auto& actor : *mChildren )
     {
-      (*iter)->SetScene( *mScene );
-      (*iter)->RecursiveConnectToScene( connectionList, depth + 1 );
+      actor->SetScene( *mScene );
+      actor->RecursiveConnectToScene( connectionList, depth + 1 );
     }
   }
 }
@@ -1631,10 +1666,9 @@ void Actor::DisconnectFromStage()
   RecursiveDisconnectFromStage( disconnectionList );
 
   // Notify applications about the newly disconnected actors.
-  const ActorIter endIter = disconnectionList.end();
-  for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
+  for( const auto& actor : disconnectionList )
   {
-    (*iter)->NotifyStageDisconnection();
+    actor->NotifyStageDisconnection();
   }
 }
 
@@ -1646,10 +1680,9 @@ void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
   // Recursively disconnect children
   if( mChildren )
   {
-    ActorConstIter endIter = mChildren->end();
-    for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter )
+    for( const auto& child : *mChildren )
     {
-      (*iter)->RecursiveDisconnectFromStage( disconnectionList );
+      child->RecursiveDisconnectFromStage( disconnectionList );
     }
   }
 
@@ -1740,9 +1773,9 @@ void Actor::DepthTraverseActorTree( OwnerPointer<SceneGraph::NodeDepths>& sceneG
   // Create/add to children of this node
   if( mChildren )
   {
-    for( ActorContainer::iterator it = mChildren->begin(); it != mChildren->end(); ++it )
+    for( const auto& child : *mChildren )
     {
-      Actor* childActor = (*it).Get();
+      Actor* childActor = child.Get();
       ++depthIndex;
       childActor->DepthTraverseActorTree( sceneGraphNodeDepths, depthIndex );
     }
@@ -1875,12 +1908,13 @@ bool Actor::DoAction( BaseObject* object, const std::string& actionName, const P
 
   if( actor )
   {
-    if( 0 == actionName.compare( ACTION_SHOW ) )
+    std::string_view name(actionName);
+    if(name == ACTION_SHOW)
     {
       actor->SetVisible( true );
       done = true;
     }
-    else if( 0 == actionName.compare( ACTION_HIDE ) )
+    else if(name == ACTION_HIDE)
     {
       actor->SetVisible( false );
       done = true;
@@ -2233,98 +2267,6 @@ float Actor::CalculateSize( Dimension::Type dimension, const Vector2& maximumSiz
   return 0.0f;  // Default
 }
 
-void Actor::NegotiateDimension( Dimension::Type dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
-{
-  // Check if it needs to be negotiated
-  if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
-  {
-    // Check that we havn't gotten into an infinite loop
-    ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
-    bool recursionFound = false;
-    for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
-    {
-      if( *it == searchActor )
-      {
-        recursionFound = true;
-        break;
-      }
-    }
-
-    if( !recursionFound )
-    {
-      // Record the path that we have taken
-      recursionStack.push_back( ActorDimensionPair( this, dimension ) );
-
-      // Dimension dependency check
-      for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
-      {
-        Dimension::Type dimensionToCheck = static_cast< Dimension::Type >( 1 << i );
-
-        if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
-        {
-          NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
-        }
-      }
-
-      // Parent dependency check
-      Actor* parent = GetParent();
-      if( parent && RelayoutDependentOnParent( dimension ) )
-      {
-        parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
-      }
-
-      // Children dependency check
-      if( RelayoutDependentOnChildren( dimension ) )
-      {
-        for( uint32_t i = 0, count = GetChildCount(); i < count; ++i )
-        {
-          ActorPtr child = GetChildAt( i );
-
-          // Only relayout child first if it is not dependent on this actor
-          if( !child->RelayoutDependentOnParent( dimension ) )
-          {
-            child->NegotiateDimension( dimension, allocatedSize, recursionStack );
-          }
-        }
-      }
-
-      // For deriving classes
-      OnCalculateRelayoutSize( dimension );
-
-      // All dependencies checked, calculate the size and set negotiated flag
-      const float newSize = Relayouter::ClampDimension( *this, CalculateSize( dimension, allocatedSize ), dimension );
-
-      SetNegotiatedDimension( newSize, dimension );
-      SetLayoutNegotiated( true, dimension );
-
-      // For deriving classes
-      OnLayoutNegotiated( newSize, dimension );
-
-      // This actor has been successfully processed, pop it off the recursion stack
-      recursionStack.pop_back();
-    }
-    else
-    {
-      // TODO: Break infinite loop
-      SetLayoutNegotiated( true, dimension );
-    }
-  }
-}
-
-void Actor::NegotiateDimensions( const Vector2& allocatedSize )
-{
-  // Negotiate all dimensions that require it
-  ActorDimensionStack recursionStack;
-
-  for( uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i )
-  {
-    const Dimension::Type dimension = static_cast< Dimension::Type >( 1 << i );
-
-    // Negotiate
-    NegotiateDimension( dimension, allocatedSize, recursionStack );
-  }
-}
-
 Vector2 Actor::ApplySizeSetPolicy( const Vector2& size )
 {
   return mRelayoutData->ApplySizeSetPolicy(*this, size);
@@ -2358,56 +2300,7 @@ 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.
-  DALI_LOG_TIMER_START( NegSizeTimer1 );
-
-  if( GetUseAssignedSize(Dimension::WIDTH ) )
-  {
-    SetLayoutNegotiated( false, Dimension::WIDTH );
-  }
-  if( GetUseAssignedSize( Dimension::HEIGHT ) )
-  {
-    SetLayoutNegotiated( false, Dimension::HEIGHT );
-  }
-
-  // Do the negotiation
-  NegotiateDimensions( allocatedSize );
-
-  // Set the actor size
-  SetNegotiatedSize( container );
-
-  // Negotiate down to children
-  for( uint32_t 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->GetUseAssignedSize(Dimension::WIDTH) )
-    {
-      child->SetLayoutNegotiated(false, Dimension::WIDTH);
-      child->SetLayoutDirty(true, Dimension::WIDTH);
-    }
-
-    if( child->GetUseAssignedSize(Dimension::HEIGHT) )
-    {
-      child->SetLayoutNegotiated(false, Dimension::HEIGHT);
-      child->SetLayoutDirty(true, Dimension::HEIGHT);
-    }
-
-    // Only relayout if required
-    if( child->RelayoutRequired() )
-    {
-      container.Add( Dali::Actor( child.Get() ), mTargetSize.GetVectorXY() );
-    }
-  }
-  DALI_LOG_TIMER_END( NegSizeTimer1, gLogRelayoutFilter, Debug::Concise, "NegotiateSize() took: ");
+  Relayouter::NegotiateSize(*this, allocatedSize, container);
 }
 
 void Actor::SetUseAssignedSize( bool use, Dimension::Type dimension )
@@ -2435,27 +2328,7 @@ void Actor::RelayoutRequest( Dimension::Type dimension )
 
 void Actor::SetPreferredSize( const Vector2& size )
 {
-  EnsureRelayouter();
-
-  // If valid width or height, then set the resize policy to FIXED
-  // A 0 width or height may also be required so if the resize policy has not been changed, i.e. is still set to DEFAULT,
-  // then change to FIXED as well
-
-  if( size.width > 0.0f || GetResizePolicy( Dimension::WIDTH ) == ResizePolicy::DEFAULT )
-  {
-    SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
-  }
-
-  if( size.height > 0.0f || GetResizePolicy( Dimension::HEIGHT ) == ResizePolicy::DEFAULT )
-  {
-    SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
-  }
-
-  mRelayoutData->preferredSize = size;
-
-  mUseAnimatedSize = AnimatedSizeFlag::CLEAR;
-
-  RelayoutRequest();
+  EnsureRelayouter().SetPreferredSize(*this, size);
 }
 
 Vector2 Actor::GetPreferredSize() const
@@ -2519,93 +2392,39 @@ void Actor::SetVisibleInternal( bool visible, SendMessage::Type sendMessage )
   }
 }
 
-void Actor::SetSiblingOrder( uint32_t order )
+void Actor::EmitOrderChangedAndRebuild()
 {
-  if ( mParent )
+  Dali::Actor handle( this );
+  mParent->mChildOrderChangedSignal.Emit( handle );
+  if( mIsOnScene && mScene )
   {
-    ActorContainer& siblings = *(mParent->mChildren);
-    uint32_t currentOrder = GetSiblingOrder();
-
-    if( order != currentOrder )
-    {
-      if( order == 0 )
-      {
-        LowerToBottom();
-      }
-      else if( order < siblings.size() -1 )
-      {
-        if( order > currentOrder )
-        {
-          RaiseAbove( *siblings[order] );
-        }
-        else
-        {
-          LowerBelow( *siblings[order] );
-        }
-      }
-      else
-      {
-        RaiseToTop();
-      }
-    }
+    mScene->RequestRebuildDepthTree();
   }
 }
 
-uint32_t Actor::GetSiblingOrder() const
+void Actor::SetSiblingOrder( uint32_t order )
 {
-  uint32_t order = 0;
-
-  if ( mParent )
+  if( mParent && SiblingHandler::SetSiblingOrder(*(mParent->mChildren), *this, order))
   {
-    ActorContainer& siblings = *(mParent->mChildren);
-    for( std::size_t i = 0; i < siblings.size(); ++i )
-    {
-      if( siblings[i] == this )
-      {
-        order = static_cast<uint32_t>( i );
-        break;
-      }
-    }
+    EmitOrderChangedAndRebuild();
   }
-
-  return order;
 }
 
-void Actor::RequestRebuildDepthTree()
+uint32_t Actor::GetSiblingOrder() const
 {
-  if( mIsOnScene )
+  uint32_t order = 0;
+  if( mParent )
   {
-    if( mScene )
-    {
-      mScene->RequestRebuildDepthTree();
-    }
+    order = SiblingHandler::GetSiblingOrder(*(mParent->mChildren), *this);
   }
+  return order;
 }
 
 void Actor::Raise()
 {
-  if ( mParent )
+  if( mParent && SiblingHandler::Raise(*(mParent->mChildren), *this) )
   {
-    ActorContainer& siblings = *(mParent->mChildren);
-    if( siblings.back() != this ) // If not already at end
-    {
-      for( std::size_t i=0; i<siblings.size(); ++i )
-      {
-        if( siblings[i] == this )
-        {
-          // Swap with next
-          ActorPtr next = siblings[i+1];
-          siblings[i+1] = this;
-          siblings[i] = next;
-          break;
-        }
-      }
-    }
-
-    Dali::Actor handle( this );
-    mParent->mChildOrderChangedSignal.Emit( handle );
-
-    RequestRebuildDepthTree();
+    EmitOrderChangedAndRebuild();
   }
   else
   {
@@ -2615,28 +2434,9 @@ void Actor::Raise()
 
 void Actor::Lower()
 {
-  if ( mParent )
+  if( mParent && SiblingHandler::Lower(*(mParent->mChildren), *this) )
   {
-    ActorContainer& siblings = *(mParent->mChildren);
-    if( siblings.front() != this ) // If not already at beginning
-    {
-      for( std::size_t i=1; i<siblings.size(); ++i )
-      {
-        if( siblings[i] == this )
-        {
-          // Swap with previous
-          ActorPtr previous = siblings[i-1];
-          siblings[i-1] = this;
-          siblings[i] = previous;
-          break;
-        }
-      }
-    }
-
-    Dali::Actor handle( this );
-    mParent->mChildOrderChangedSignal.Emit( handle );
-
-    RequestRebuildDepthTree();
+    EmitOrderChangedAndRebuild();
   }
   else
   {
@@ -2646,23 +2446,9 @@ void Actor::Lower()
 
 void Actor::RaiseToTop()
 {
-  if ( mParent )
+  if( mParent && SiblingHandler::RaiseToTop(*(mParent->mChildren), *this) )
   {
-    ActorContainer& siblings = *(mParent->mChildren);
-    if( siblings.back() != this ) // If not already at end
-    {
-      ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
-      if( iter != siblings.end() )
-      {
-        siblings.erase(iter);
-        siblings.push_back(ActorPtr(this));
-      }
-    }
-
-    Dali::Actor handle( this );
-    mParent->mChildOrderChangedSignal.Emit( handle );
-
-    RequestRebuildDepthTree();
+    EmitOrderChangedAndRebuild();
   }
   else
   {
@@ -2672,25 +2458,9 @@ void Actor::RaiseToTop()
 
 void Actor::LowerToBottom()
 {
-  if ( mParent )
+  if( mParent && SiblingHandler::LowerToBottom(*(mParent->mChildren), *this) )
   {
-    ActorContainer& siblings = *(mParent->mChildren);
-    if( siblings.front() != this ) // If not already at bottom,
-    {
-      ActorPtr thisPtr(this); // ensure this actor remains referenced.
-
-      ActorContainer::iterator iter = std::find( siblings.begin(), siblings.end(), this );
-      if( iter != siblings.end() )
-      {
-        siblings.erase(iter);
-        siblings.insert(siblings.begin(), thisPtr);
-      }
-    }
-
-    Dali::Actor handle( this );
-    mParent->mChildOrderChangedSignal.Emit( handle );
-
-    RequestRebuildDepthTree();
+    EmitOrderChangedAndRebuild();
   }
   else
   {
@@ -2700,30 +2470,9 @@ void Actor::LowerToBottom()
 
 void Actor::RaiseAbove( Internal::Actor& target )
 {
-  if ( mParent )
+  if( mParent && SiblingHandler::RaiseAbove( *(mParent->mChildren), *this, target ))
   {
-    ActorContainer& siblings = *(mParent->mChildren);
-    if( siblings.back() != this && target.mParent == mParent ) // If not already at top
-    {
-      ActorPtr thisPtr(this); // ensure this actor remains referenced.
-
-      ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
-      ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
-      if( thisIter < targetIter )
-      {
-        siblings.erase(thisIter);
-        // Erasing early invalidates the targetIter. (Conversely, inserting first may also
-        // invalidate thisIter)
-        targetIter = std::find( siblings.begin(), siblings.end(), &target );
-        ++targetIter;
-        siblings.insert(targetIter, thisPtr);
-      }
-
-      Dali::Actor handle( this );
-      mParent->mChildOrderChangedSignal.Emit( handle );
-
-      RequestRebuildDepthTree();
-    }
+    EmitOrderChangedAndRebuild();
   }
   else
   {
@@ -2733,27 +2482,9 @@ void Actor::RaiseAbove( Internal::Actor& target )
 
 void Actor::LowerBelow( Internal::Actor& target )
 {
-  if ( mParent )
+  if( mParent && SiblingHandler::LowerBelow(*(mParent->mChildren), *this, target ) )
   {
-    ActorContainer& siblings = *(mParent->mChildren);
-    if( siblings.front() != this && target.mParent == mParent ) // If not already at bottom
-    {
-      ActorPtr thisPtr(this); // ensure this actor remains referenced.
-
-      ActorContainer::iterator targetIter = std::find( siblings.begin(), siblings.end(), &target );
-      ActorContainer::iterator thisIter = std::find( siblings.begin(), siblings.end(), this );
-
-      if( thisIter > targetIter )
-      {
-        siblings.erase(thisIter); // this only invalidates iterators at or after this point.
-        siblings.insert(targetIter, thisPtr);
-      }
-
-      Dali::Actor handle( this );
-      mParent->mChildOrderChangedSignal.Emit( handle );
-
-      RequestRebuildDepthTree();
-    }
+    EmitOrderChangedAndRebuild();
   }
   else
   {
@@ -2787,7 +2518,7 @@ void Actor::InheritLayoutDirectionRecursively( ActorPtr actor, Dali::LayoutDirec
 
     if( actor->GetChildCount() > 0 )
     {
-      for( ActorPtr& child : actor->GetChildrenInternal() )
+      for( const auto& child : actor->GetChildrenInternal() )
       {
         InheritLayoutDirectionRecursively( child, direction );
       }