Refactored more code into Actor::Relayouter
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / actor-impl.cpp
index 776c3f3..b201786 100644 (file)
 #include <dali/public-api/object/type-registry.h>
 
 #include <dali/devel-api/actors/actor-devel.h>
-#include <dali/devel-api/actors/layer-devel.h>
 #include <dali/devel-api/common/capabilities.h>
 
 #include <dali/integration-api/debug.h>
 
+#include <dali/internal/event/actors/actor-coords.h>
 #include <dali/internal/event/actors/actor-parent.h>
 #include <dali/internal/event/actors/actor-property-handler.h>
 #include <dali/internal/event/actors/actor-relayouter.h>
 #include <dali/internal/event/actors/camera-actor-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/scene-impl.h>
 #include <dali/internal/event/common/stage-impl.h>
@@ -148,6 +147,8 @@ DALI_PROPERTY("updateSizeHint", VECTOR2, true, false, false, Dali::DevelActor::P
 DALI_PROPERTY("captureAllTouchAfterStart", BOOLEAN, true, false, false, Dali::DevelActor::Property::CAPTURE_ALL_TOUCH_AFTER_START)
 DALI_PROPERTY("touchAreaOffset", RECTANGLE, true, false, false, Dali::DevelActor::Property::TOUCH_AREA_OFFSET)
 DALI_PROPERTY("blendEquation", INTEGER, true, false, false, Dali::DevelActor::Property::BLEND_EQUATION)
+DALI_PROPERTY("touchFocusable", BOOLEAN, true, false, false, Dali::DevelActor::Property::TOUCH_FOCUSABLE)
+DALI_PROPERTY("keyboardFocusableChildren", BOOLEAN, true, false, false, Dali::DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN)
 DALI_PROPERTY_TABLE_END(DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties)
 
 // Signals
@@ -173,61 +174,122 @@ BaseHandle CreateActor()
   return Dali::Actor::New();
 }
 
-TypeRegistration mType(typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties);
+/**
+ * Connects a callback function with the object's signals.
+ * @param[in] object The object providing the signal.
+ * @param[in] tracker Used to disconnect the signal.
+ * @param[in] signalName The signal to connect to.
+ * @param[in] functor A newly allocated FunctorDelegate.
+ * @return True if the signal was connected.
+ * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
+ */
+static bool DoConnectSignal(BaseObject*                 object,
+                            ConnectionTrackerInterface* tracker,
+                            const std::string&          signalName,
+                            FunctorDelegate*            functor)
+{
+  bool   connected(true);
+  Actor* actor = static_cast<Actor*>(object); // TypeRegistry guarantees that this is the correct type.
+
+  std::string_view name(signalName);
 
-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);
+  if(name == SIGNAL_HOVERED)
+  {
+    actor->HoveredSignal().Connect(tracker, functor);
+  }
+  else if(signalName == SIGNAL_WHEEL_EVENT)
+  {
+    actor->WheelEventSignal().Connect(tracker, functor);
+  }
+  else if(name == SIGNAL_ON_SCENE)
+  {
+    actor->OnSceneSignal().Connect(tracker, functor);
+  }
+  else if(name == SIGNAL_OFF_SCENE)
+  {
+    actor->OffSceneSignal().Connect(tracker, functor);
+  }
+  else if(name == SIGNAL_ON_RELAYOUT)
+  {
+    actor->OnRelayoutSignal().Connect(tracker, functor);
+  }
+  else if(name == SIGNAL_TOUCHED)
+  {
+    actor->TouchedSignal().Connect(tracker, functor);
+  }
+  else if(name == SIGNAL_VISIBILITY_CHANGED)
+  {
+    actor->VisibilityChangedSignal().Connect(tracker, functor);
+  }
+  else if(name == SIGNAL_LAYOUT_DIRECTION_CHANGED)
+  {
+    actor->LayoutDirectionChangedSignal().Connect(tracker, functor);
+  }
+  else if(name == SIGNAL_CHILD_ADDED)
+  {
+    actor->ChildAddedSignal().Connect(tracker, functor);
+  }
+  else if(name == SIGNAL_CHILD_REMOVED)
+  {
+    actor->ChildRemovedSignal().Connect(tracker, functor);
+  }
+  else
+  {
+    // signalName does not match any signal
+    connected = false;
+  }
 
-TypeAction a1(mType, std::string(ACTION_SHOW), &Actor::DoAction);
-TypeAction a2(mType, std::string(ACTION_HIDE), &Actor::DoAction);
+  return connected;
+}
 
 /**
- * @brief Extract a given dimension from a Vector2
- *
- * @param[in] values The values to extract from
- * @param[in] dimension The dimension to extract
- * @return Return the value for the dimension
+ * Performs actions as requested using the action name.
+ * @param[in] object The object on which to perform the action.
+ * @param[in] actionName The action to perform.
+ * @param[in] attributes The attributes with which to perfrom this action.
+ * @return true if the action was done.
  */
-constexpr float GetDimensionValue(const Vector2& values, Dimension::Type dimension)
+bool DoAction(BaseObject*          object,
+              const std::string&   actionName,
+              const Property::Map& attributes)
 {
-  switch(dimension)
+  bool   done  = false;
+  Actor* actor = dynamic_cast<Actor*>(object);
+
+  if(actor)
   {
-    case Dimension::WIDTH:
-    {
-      return values.width;
-    }
-    case Dimension::HEIGHT:
+    std::string_view name(actionName);
+    if(name == ACTION_SHOW)
     {
-      return values.height;
+      actor->SetVisible(true);
+      done = true;
     }
-    default:
+    else if(name == ACTION_HIDE)
     {
-      break;
+      actor->SetVisible(false);
+      done = true;
     }
   }
-  return 0.0f;
-}
 
-/**
- * @brief Extract a given dimension from a Vector3
- *
- * @param[in] values The values to extract from
- * @param[in] dimension The dimension to extract
- * @return Return the value for the dimension
- */
-float GetDimensionValue(const Vector3& values, Dimension::Type dimension)
-{
-  return GetDimensionValue(values.GetVectorXY(), dimension);
+  return done;
 }
 
+TypeRegistration mType(typeid(Dali::Actor), typeid(Dali::Handle), CreateActor, ActorDefaultProperties);
+
+SignalConnectorType signalConnector2(mType, std::string(SIGNAL_HOVERED), &DoConnectSignal);
+SignalConnectorType signalConnector3(mType, std::string(SIGNAL_WHEEL_EVENT), &DoConnectSignal);
+SignalConnectorType signalConnector4(mType, std::string(SIGNAL_ON_SCENE), &DoConnectSignal);
+SignalConnectorType signalConnector5(mType, std::string(SIGNAL_OFF_SCENE), &DoConnectSignal);
+SignalConnectorType signalConnector6(mType, std::string(SIGNAL_ON_RELAYOUT), &DoConnectSignal);
+SignalConnectorType signalConnector7(mType, std::string(SIGNAL_TOUCHED), &DoConnectSignal);
+SignalConnectorType signalConnector8(mType, std::string(SIGNAL_VISIBILITY_CHANGED), &DoConnectSignal);
+SignalConnectorType signalConnector9(mType, std::string(SIGNAL_LAYOUT_DIRECTION_CHANGED), &DoConnectSignal);
+SignalConnectorType signalConnector10(mType, std::string(SIGNAL_CHILD_ADDED), &DoConnectSignal);
+SignalConnectorType signalConnector11(mType, std::string(SIGNAL_CHILD_REMOVED), &DoConnectSignal);
+
+TypeAction a1(mType, std::string(ACTION_SHOW), &DoAction);
+TypeAction a2(mType, std::string(ACTION_HIDE), &DoAction);
+
 /// Helper for emitting a signal
 template<typename Signal, typename Event>
 bool EmitConsumingSignal(Actor& actor, Signal& signal, const Event& event)
@@ -254,58 +316,33 @@ void EmitSignal(Actor& actor, Signal& signal, Param... params)
   }
 }
 
-bool ScreenToLocalInternal(
-  const Matrix&   viewMatrix,
-  const Matrix&   projectionMatrix,
-  const Matrix&   worldMatrix,
-  const Viewport& viewport,
-  const Vector3&  currentSize,
-  float&          localX,
-  float&          localY,
-  float           screenX,
-  float           screenY)
-{
-  // Get the ModelView matrix
-  Matrix modelView;
-  Matrix::Multiply(modelView, worldMatrix, viewMatrix);
-
-  // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
-  Matrix invertedMvp(false /*don't init*/);
-  Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
-  bool success = invertedMvp.Invert();
+using ActorParentSiblingOrderMethod           = void (ActorParent::*)(Actor&);
+using ActorParentSiblingOrderMethodWithTarget = void (ActorParent::*)(Actor&, Actor&);
 
-  // Convert to GL coordinates
-  Vector4 screenPos(screenX - static_cast<float>(viewport.x), static_cast<float>(viewport.height) - screenY - static_cast<float>(viewport.y), 0.f, 1.f);
-
-  Vector4 nearPos;
-  if(success)
+/// Helper to check and call actor sibling methods in ActorParent
+void CheckParentAndCall(ActorParent* parent, Actor& actor, ActorParentSiblingOrderMethod memberFunction)
+{
+  if(parent)
   {
-    success = Unproject(screenPos, invertedMvp, static_cast<float>(viewport.width), static_cast<float>(viewport.height), nearPos);
+    (parent->*memberFunction)(actor);
   }
-
-  Vector4 farPos;
-  if(success)
+  else
   {
-    screenPos.z = 1.0f;
-    success     = Unproject(screenPos, invertedMvp, static_cast<float>(viewport.width), static_cast<float>(viewport.height), farPos);
+    DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
   }
+}
 
-  if(success)
+/// Helper to check and call actor sibling methods with a target parameter in ActorParent
+void CheckParentAndCall(ActorParent* parent, Actor& actor, Actor& target, ActorParentSiblingOrderMethodWithTarget memberFunction)
+{
+  if(parent)
   {
-    Vector4 local;
-    if(XyPlaneIntersect(nearPos, farPos, local))
-    {
-      Vector3 size = currentSize;
-      localX       = local.x + size.x * 0.5f;
-      localY       = local.y + size.y * 0.5f;
-    }
-    else
-    {
-      success = false;
-    }
+    (parent->*memberFunction)(actor, target);
+  }
+  else
+  {
+    DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
   }
-
-  return success;
 }
 
 } // unnamed namespace
@@ -499,21 +536,11 @@ const Vector3& Actor::GetCurrentWorldPosition() const
 
 const Vector2 Actor::GetCurrentScreenPosition() const
 {
-  if(mScene && OnScene())
+  if(mScene)
   {
-    Vector3 worldPosition  = GetNode().GetWorldPosition(GetEventThreadServices().GetEventBufferIndex());
-    Vector3 cameraPosition = mScene->GetDefaultCameraActor().GetNode().GetWorldPosition(GetEventThreadServices().GetEventBufferIndex());
-    worldPosition -= cameraPosition;
-
-    Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale();
-    Vector2 halfSceneSize(mScene->GetSize() * 0.5f); // World position origin is center of scene
-    Vector3 halfActorSize(actorSize * 0.5f);
-    Vector3 anchorPointOffSet = halfActorSize - actorSize * (mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT);
-
-    return Vector2(halfSceneSize.width + worldPosition.x - anchorPointOffSet.x,
-                   halfSceneSize.height + worldPosition.y - anchorPointOffSet.y);
+    BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
+    return CalculateActorScreenPosition(*this, bufferIndex);
   }
-
   return Vector2::ZERO;
 }
 
@@ -746,12 +773,7 @@ void Actor::SetSizeModeFactor(const Vector3& factor)
 
 const Vector3& Actor::GetSizeModeFactor() const
 {
-  if(mRelayoutData)
-  {
-    return mRelayoutData->sizeModeFactor;
-  }
-
-  return Relayouter::DEFAULT_SIZE_MODE_FACTOR;
+  return mRelayoutData ? mRelayoutData->sizeModeFactor : Relayouter::DEFAULT_SIZE_MODE_FACTOR;
 }
 
 void Actor::SetColorMode(ColorMode colorMode)
@@ -811,6 +833,18 @@ void Actor::SetSizeInternal(const Vector3& size)
   {
     mTargetSize = size;
 
+    // Update the preferred size after relayoutting
+    // It should be used in the next relayoutting
+    if(mUseAnimatedSize & AnimatedSizeFlag::WIDTH && mRelayoutData)
+    {
+      mRelayoutData->preferredSize.width = mAnimatedSize.width;
+    }
+
+    if(mUseAnimatedSize & AnimatedSizeFlag::HEIGHT && mRelayoutData)
+    {
+      mRelayoutData->preferredSize.height = mAnimatedSize.height;
+    }
+
     // node is being used in a separate thread; queue a message to set the value & base value
     SceneGraph::NodeTransformPropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mSize, &SceneGraph::TransformManagerPropertyHandler<Vector3>::Bake, mTargetSize);
 
@@ -939,12 +973,7 @@ void Actor::SetResizePolicy(ResizePolicy::Type policy, Dimension::Type dimension
 
 ResizePolicy::Type Actor::GetResizePolicy(Dimension::Type dimension) const
 {
-  if(mRelayoutData)
-  {
-    return mRelayoutData->GetResizePolicy(dimension);
-  }
-
-  return ResizePolicy::DEFAULT;
+  return mRelayoutData ? mRelayoutData->GetResizePolicy(dimension) : ResizePolicy::DEFAULT;
 }
 
 void Actor::SetSizeScalePolicy(SizeScalePolicy::Type policy)
@@ -959,12 +988,7 @@ void Actor::SetSizeScalePolicy(SizeScalePolicy::Type policy)
 
 SizeScalePolicy::Type Actor::GetSizeScalePolicy() const
 {
-  if(mRelayoutData)
-  {
-    return mRelayoutData->sizeSetPolicy;
-  }
-
-  return Relayouter::DEFAULT_SIZE_SCALE_POLICY;
+  return mRelayoutData ? mRelayoutData->sizeSetPolicy : Relayouter::DEFAULT_SIZE_SCALE_POLICY;
 }
 
 void Actor::SetDimensionDependency(Dimension::Type dimension, Dimension::Type dependency)
@@ -974,12 +998,7 @@ void Actor::SetDimensionDependency(Dimension::Type dimension, Dimension::Type de
 
 Dimension::Type Actor::GetDimensionDependency(Dimension::Type dimension) const
 {
-  if(mRelayoutData)
-  {
-    return mRelayoutData->GetDimensionDependency(dimension);
-  }
-
-  return Dimension::ALL_DIMENSIONS; // Default
+  return mRelayoutData ? mRelayoutData->GetDimensionDependency(dimension) : Dimension::ALL_DIMENSIONS;
 }
 
 void Actor::SetRelayoutEnabled(bool relayoutEnabled)
@@ -1027,67 +1046,34 @@ uint32_t Actor::AddRenderer(Renderer& renderer)
 {
   if(!mRenderers)
   {
-    mRenderers = new RendererContainer;
+    mRenderers = new RendererContainer(GetEventThreadServices());
   }
-
-  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);
-  AttachRendererMessage(GetEventThreadServices().GetUpdateManager(), GetNode(), renderer.GetRendererSceneObject());
-  return index;
+  return mRenderers->Add(GetNode(), renderer, mIsBlendEquationSet, mBlendEquation);
 }
 
 uint32_t Actor::GetRendererCount() const
 {
-  uint32_t rendererCount(0);
-  if(mRenderers)
-  {
-    rendererCount = static_cast<uint32_t>(mRenderers->size()); //  4,294,967,295 renderers per actor
-  }
-
-  return rendererCount;
+  return mRenderers ? mRenderers->GetCount() : 0u;
 }
 
 RendererPtr Actor::GetRendererAt(uint32_t index)
 {
-  RendererPtr renderer;
-  if(index < GetRendererCount())
-  {
-    renderer = (*mRenderers)[index];
-  }
-
-  return renderer;
+  return mRenderers ? mRenderers->GetRendererAt(index) : nullptr;
 }
 
 void Actor::RemoveRenderer(Renderer& renderer)
 {
   if(mRenderers)
   {
-    RendererIter end = mRenderers->end();
-    for(RendererIter iter = mRenderers->begin(); iter != end; ++iter)
-    {
-      if((*iter).Get() == &renderer)
-      {
-        mRenderers->erase(iter);
-        DetachRendererMessage(GetEventThreadServices(), GetNode(), renderer.GetRendererSceneObject());
-        break;
-      }
-    }
+    mRenderers->Remove(GetNode(), renderer);
   }
 }
 
 void Actor::RemoveRenderer(uint32_t index)
 {
-  if(index < GetRendererCount())
+  if(mRenderers)
   {
-    RendererPtr renderer = (*mRenderers)[index];
-    DetachRendererMessage(GetEventThreadServices(), GetNode(), renderer.Get()->GetRendererSceneObject());
-    mRenderers->erase(mRenderers->begin() + index);
+    mRenderers->Remove(GetNode(), index);
   }
 }
 
@@ -1097,12 +1083,10 @@ void Actor::SetBlendEquation(DevelBlendEquation::Type blendEquation)
   {
     if(mBlendEquation != blendEquation)
     {
-      mBlendEquation         = blendEquation;
-      uint32_t rendererCount = GetRendererCount();
-      for(uint32_t i = 0; i < rendererCount; ++i)
+      mBlendEquation = blendEquation;
+      if(mRenderers)
       {
-        RendererPtr renderer = GetRendererAt(i);
-        renderer->SetBlendEquation(static_cast<DevelBlendEquation::Type>(blendEquation));
+        mRenderers->SetBlending(blendEquation);
       }
     }
     mIsBlendEquationSet = true;
@@ -1118,6 +1102,16 @@ DevelBlendEquation::Type Actor::GetBlendEquation() const
   return mBlendEquation;
 }
 
+void Actor::SetTransparent(bool transparent)
+{
+  SetTransparentMessage(GetEventThreadServices(), GetNode(), transparent);
+}
+
+bool Actor::IsTransparent() const
+{
+  return GetNode().IsTransparent();
+}
+
 void Actor::SetDrawMode(DrawMode::Type drawMode)
 {
   // this flag is not animatable so keep the value
@@ -1129,54 +1123,17 @@ void Actor::SetDrawMode(DrawMode::Type drawMode)
 
 bool Actor::ScreenToLocal(float& localX, float& localY, float screenX, float screenY) const
 {
-  // only valid when on-stage
-  if(mScene && OnScene())
-  {
-    const RenderTaskList& taskList = mScene->GetRenderTaskList();
-
-    Vector2 converted(screenX, screenY);
-
-    // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
-    uint32_t taskCount = taskList.GetTaskCount();
-    for(uint32_t i = taskCount; i > 0; --i)
-    {
-      RenderTaskPtr task = taskList.GetTask(i - 1);
-      if(ScreenToLocal(*task, localX, localY, screenX, screenY))
-      {
-        // found a task where this conversion was ok so return
-        return true;
-      }
-    }
-  }
-  return false;
+  return mScene && OnScene() && ConvertScreenToLocalRenderTaskList(mScene->GetRenderTaskList(), GetNode().GetWorldMatrix(0), GetCurrentSize(), localX, localY, screenX, screenY);
 }
 
 bool Actor::ScreenToLocal(const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY) const
 {
-  bool retval = false;
-  // only valid when on-stage
-  if(OnScene())
-  {
-    CameraActor* camera = renderTask.GetCameraActor();
-    if(camera)
-    {
-      Viewport viewport;
-      renderTask.GetViewport(viewport);
-
-      // need to translate coordinates to render tasks coordinate space
-      Vector2 converted(screenX, screenY);
-      if(renderTask.TranslateCoordinates(converted))
-      {
-        retval = ScreenToLocal(camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y);
-      }
-    }
-  }
-  return retval;
+  return OnScene() && ConvertScreenToLocalRenderTask(renderTask, GetNode().GetWorldMatrix(0), GetCurrentSize(), localX, localY, screenX, screenY);
 }
 
 bool Actor::ScreenToLocal(const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY) const
 {
-  return OnScene() && ScreenToLocalInternal(viewMatrix, projectionMatrix, GetNode().GetWorldMatrix(0), viewport, GetCurrentSize(), localX, localY, screenX, screenY);
+  return OnScene() && ConvertScreenToLocal(viewMatrix, projectionMatrix, GetNode().GetWorldMatrix(0), GetCurrentSize(), viewport, localX, localY, screenX, screenY);
 }
 
 ActorGestureData& Actor::GetGestureData()
@@ -1240,62 +1197,6 @@ DevelActor::ChildOrderChangedSignalType& Actor::ChildOrderChangedSignal()
   return mParentImpl.ChildOrderChangedSignal();
 }
 
-bool Actor::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
-{
-  bool   connected(true);
-  Actor* actor = static_cast<Actor*>(object); // TypeRegistry guarantees that this is the correct type.
-
-  std::string_view name(signalName);
-
-  if(name == SIGNAL_HOVERED)
-  {
-    actor->HoveredSignal().Connect(tracker, functor);
-  }
-  else if(signalName == SIGNAL_WHEEL_EVENT)
-  {
-    actor->WheelEventSignal().Connect(tracker, functor);
-  }
-  else if(name == SIGNAL_ON_SCENE)
-  {
-    actor->OnSceneSignal().Connect(tracker, functor);
-  }
-  else if(name == SIGNAL_OFF_SCENE)
-  {
-    actor->OffSceneSignal().Connect(tracker, functor);
-  }
-  else if(name == SIGNAL_ON_RELAYOUT)
-  {
-    actor->OnRelayoutSignal().Connect(tracker, functor);
-  }
-  else if(name == SIGNAL_TOUCHED)
-  {
-    actor->TouchedSignal().Connect(tracker, functor);
-  }
-  else if(name == SIGNAL_VISIBILITY_CHANGED)
-  {
-    actor->VisibilityChangedSignal().Connect(tracker, functor);
-  }
-  else if(name == SIGNAL_LAYOUT_DIRECTION_CHANGED)
-  {
-    actor->LayoutDirectionChangedSignal().Connect(tracker, functor);
-  }
-  else if(name == SIGNAL_CHILD_ADDED)
-  {
-    actor->ChildAddedSignal().Connect(tracker, functor);
-  }
-  else if(name == SIGNAL_CHILD_REMOVED)
-  {
-    actor->ChildRemovedSignal().Connect(tracker, functor);
-  }
-  else
-  {
-    // signalName does not match any signal
-    connected = false;
-  }
-
-  return connected;
-}
-
 Actor::Actor(DerivedType derivedType, const SceneGraph::Node& node)
 : Object(&node),
   mParentImpl(*this),
@@ -1332,6 +1233,8 @@ Actor::Actor(DerivedType derivedType, const SceneGraph::Node& node)
   mSensitive(true),
   mLeaveRequired(false),
   mKeyboardFocusable(false),
+  mKeyboardFocusableChildren(true),
+  mTouchFocusable(false),
   mOnSceneSignalled(false),
   mInsideOnSizeSet(false),
   mInheritPosition(true),
@@ -1341,12 +1244,13 @@ Actor::Actor(DerivedType derivedType, const SceneGraph::Node& node)
   mVisible(true),
   mInheritLayoutDirection(true),
   mCaptureAllTouchAfterStart(false),
+  mIsBlendEquationSet(false),
+  mNeedGesturePropagation(false),
   mLayoutDirection(LayoutDirection::LEFT_TO_RIGHT),
   mDrawMode(DrawMode::NORMAL),
   mColorMode(Node::DEFAULT_COLOR_MODE),
   mClippingMode(ClippingMode::DISABLED),
-  mBlendEquation(DevelBlendEquation::ADD),
-  mIsBlendEquationSet(false)
+  mBlendEquation(DevelBlendEquation::ADD)
 {
 }
 
@@ -1387,14 +1291,31 @@ Actor::~Actor()
   delete mRelayoutData;
 }
 
-void Actor::Add(Actor& child)
+void Actor::Add(Actor& child, bool notify)
 {
-  mParentImpl.Add(child);
+  mParentImpl.Add(child, notify);
 }
 
-void Actor::Remove(Actor& child)
+void Actor::Remove(Actor& child, bool notify)
 {
-  mParentImpl.Remove(child);
+  mParentImpl.Remove(child, notify);
+}
+
+void Actor::SwitchParent(Actor& newParent)
+{
+  if(this == &newParent)
+  {
+    DALI_LOG_ERROR("Cannot add actor to itself");
+    return;
+  }
+
+  if(!this->OnScene() || !newParent.OnScene())
+  {
+    DALI_LOG_ERROR("Both of current parent and new parent must be on Scene");
+    return;
+  }
+
+  newParent.Add(*this, false);
 }
 
 uint32_t Actor::GetChildCount() const
@@ -1427,7 +1348,7 @@ void Actor::UnparentChildren()
   mParentImpl.UnparentChildren();
 }
 
-void Actor::ConnectToScene(uint32_t parentDepth)
+void Actor::ConnectToScene(uint32_t parentDepth, bool notify)
 {
   // This container is used instead of walking the Actor hierarchy.
   // It protects us when the Actor hierarchy is modified during OnSceneConnectionExternal callbacks.
@@ -1438,44 +1359,18 @@ void Actor::ConnectToScene(uint32_t parentDepth)
     mScene->RequestRebuildDepthTree();
   }
 
-  // This stage is atomic i.e. not interrupted by user callbacks.
-  RecursiveConnectToScene(connectionList, parentDepth + 1);
+  // This stage is not interrupted by user callbacks.
+  mParentImpl.RecursiveConnectToScene(connectionList, parentDepth + 1);
 
   // Notify applications about the newly connected actors.
   for(const auto& actor : connectionList)
   {
-    actor->NotifyStageConnection();
+    actor->NotifyStageConnection(notify);
   }
 
   RelayoutRequest();
 }
 
-void Actor::RecursiveConnectToScene(ActorContainer& connectionList, uint32_t depth)
-{
-  DALI_ASSERT_ALWAYS(!OnScene());
-
-  mIsOnScene = true;
-  mDepth     = static_cast<uint16_t>(depth); // overflow ignored, not expected in practice
-
-  ConnectToSceneGraph();
-
-  // Notification for internal derived classes
-  OnSceneConnectionInternal();
-
-  // This stage is atomic; avoid emitting callbacks until all Actors are connected
-  connectionList.push_back(ActorPtr(this));
-
-  // Recursively connect children
-  if(GetChildCount() > 0)
-  {
-    for(const auto& child : mParentImpl.GetChildrenInternal())
-    {
-      child->SetScene(*mScene);
-      child->RecursiveConnectToScene(connectionList, depth + 1);
-    }
-  }
-}
-
 /**
  * This method is called when the Actor is connected to the Stage.
  * The parent must have added its Node to the scene-graph.
@@ -1496,19 +1391,22 @@ void Actor::ConnectToSceneGraph()
   OnSceneObjectAdd();
 }
 
-void Actor::NotifyStageConnection()
+void Actor::NotifyStageConnection(bool notify)
 {
   // Actors can be removed (in a callback), before the on-stage stage is reported.
   // The actor may also have been reparented, in which case mOnSceneSignalled will be true.
   if(OnScene() && !mOnSceneSignalled)
   {
-    // Notification for external (CustomActor) derived classes
-    OnSceneConnectionExternal(mDepth);
-
-    if(!mOnSceneSignal.Empty())
+    if(notify)
     {
-      Dali::Actor handle(this);
-      mOnSceneSignal.Emit(handle);
+      // Notification for external (CustomActor) derived classes
+      OnSceneConnectionExternal(mDepth);
+
+      if(!mOnSceneSignal.Empty())
+      {
+        Dali::Actor handle(this);
+        mOnSceneSignal.Emit(handle);
+      }
     }
 
     // Guard against Remove during callbacks
@@ -1519,7 +1417,7 @@ void Actor::NotifyStageConnection()
   }
 }
 
-void Actor::DisconnectFromStage()
+void Actor::DisconnectFromStage(bool notify)
 {
   // This container is used instead of walking the Actor hierachy.
   // It protects us when the Actor hierachy is modified during OnSceneDisconnectionExternal callbacks.
@@ -1530,39 +1428,16 @@ void Actor::DisconnectFromStage()
     mScene->RequestRebuildDepthTree();
   }
 
-  // This stage is atomic i.e. not interrupted by user callbacks
-  RecursiveDisconnectFromStage(disconnectionList);
+  // This stage is not interrupted by user callbacks
+  mParentImpl.RecursiveDisconnectFromScene(disconnectionList);
 
   // Notify applications about the newly disconnected actors.
   for(const auto& actor : disconnectionList)
   {
-    actor->NotifyStageDisconnection();
+    actor->NotifyStageDisconnection(notify);
   }
 }
 
-void Actor::RecursiveDisconnectFromStage(ActorContainer& disconnectionList)
-{
-  // need to change state first so that internals relying on IsOnScene() inside OnSceneDisconnectionInternal() get the correct value
-  mIsOnScene = false;
-
-  // Recursively disconnect children
-  if(GetChildCount() > 0)
-  {
-    for(const auto& child : mParentImpl.GetChildrenInternal())
-    {
-      child->RecursiveDisconnectFromStage(disconnectionList);
-    }
-  }
-
-  // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
-  disconnectionList.push_back(ActorPtr(this));
-
-  // Notification for internal derived classes
-  OnSceneDisconnectionInternal();
-
-  DisconnectFromSceneGraph();
-}
-
 /**
  * This method is called by an actor or its parent, before a node removal message is sent.
  * This is recursive; the child calls DisconnectFromStage() for its children.
@@ -1573,20 +1448,23 @@ void Actor::DisconnectFromSceneGraph()
   OnSceneObjectRemove();
 }
 
-void Actor::NotifyStageDisconnection()
+void Actor::NotifyStageDisconnection(bool notify)
 {
   // Actors can be added (in a callback), before the off-stage state is reported.
   // Also if the actor was added & removed before mOnSceneSignalled was set, then we don't notify here.
   // only do this step if there is a stage, i.e. Core is not being shut down
   if(EventThreadServices::IsCoreRunning() && !OnScene() && mOnSceneSignalled)
   {
-    // Notification for external (CustomeActor) derived classes
-    OnSceneDisconnectionExternal();
-
-    if(!mOffSceneSignal.Empty())
+    if(notify)
     {
-      Dali::Actor handle(this);
-      mOffSceneSignal.Emit(handle);
+      // Notification for external (CustomeActor) derived classes
+      OnSceneDisconnectionExternal();
+
+      if(!mOffSceneSignal.Empty())
+      {
+        Dali::Actor handle(this);
+        mOffSceneSignal.Emit(handle);
+      }
     }
 
     // Guard against Add during callbacks
@@ -1599,17 +1477,7 @@ void Actor::NotifyStageDisconnection()
 
 bool Actor::IsNodeConnected() const
 {
-  bool connected(false);
-
-  if(OnScene())
-  {
-    if(IsRoot() || GetNode().GetParent())
-    {
-      connected = true;
-    }
-  }
-
-  return connected;
+  return OnScene() && (IsRoot() || GetNode().GetParent());
 }
 
 // This method initiates traversal of the actor tree using depth-first
@@ -1627,29 +1495,12 @@ void Actor::RebuildDepthTree()
   OwnerPointer<SceneGraph::NodeDepths> sceneGraphNodeDepths(new SceneGraph::NodeDepths());
 
   int32_t depthIndex = 1;
-  DepthTraverseActorTree(sceneGraphNodeDepths, depthIndex);
+  mParentImpl.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, int32_t& depthIndex)
-{
-  mSortedDepth = depthIndex * DevelLayer::SIBLING_ORDER_MULTIPLIER;
-  sceneGraphNodeDepths->Add(const_cast<SceneGraph::Node*>(&GetNode()), mSortedDepth);
-
-  // Create/add to children of this node
-  if(GetChildCount() > 0)
-  {
-    for(const auto& child : mParentImpl.GetChildrenInternal())
-    {
-      Actor* childActor = child.Get();
-      ++depthIndex;
-      childActor->DepthTraverseActorTree(sceneGraphNodeDepths, depthIndex);
-    }
-  }
-}
-
 void Actor::SetDefaultProperty(Property::Index index, const Property::Value& property)
 {
   PropertyHandler::SetDefaultProperty(*this, index, property);
@@ -1736,77 +1587,35 @@ const SceneGraph::Node& Actor::GetNode() const
 
 void Actor::Raise()
 {
-  if(mParent)
-  {
-    mParent->RaiseChild(*this);
-  }
-  else
-  {
-    DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
-  }
+  CheckParentAndCall(mParent, *this, &ActorParent::RaiseChild);
 }
 
 void Actor::Lower()
 {
-  if(mParent)
-  {
-    mParent->LowerChild(*this);
-  }
-  else
-  {
-    DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
-  }
+  CheckParentAndCall(mParent, *this, &ActorParent::LowerChild);
 }
 
 void Actor::RaiseToTop()
 {
-  if(mParent)
-  {
-    mParent->RaiseChildToTop(*this);
-  }
-  else
-  {
-    DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
-  }
+  CheckParentAndCall(mParent, *this, &ActorParent::RaiseChildToTop);
 }
 
 void Actor::LowerToBottom()
 {
-  if(mParent)
-  {
-    mParent->LowerChildToBottom(*this);
-  }
-  else
-  {
-    DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
-  }
+  CheckParentAndCall(mParent, *this, &ActorParent::LowerChildToBottom);
 }
 
 void Actor::RaiseAbove(Internal::Actor& target)
 {
-  if(mParent)
-  {
-    mParent->RaiseChildAbove(*this, target);
-  }
-  else
-  {
-    DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
-  }
+  CheckParentAndCall(mParent, *this, target, &ActorParent::RaiseChildAbove);
 }
 
 void Actor::LowerBelow(Internal::Actor& target)
 {
-  if(mParent)
-  {
-    mParent->LowerChildBelow(*this, target);
-  }
-  else
-  {
-    DALI_LOG_WARNING("Actor must have a parent, Sibling order not changed.\n");
-  }
+  CheckParentAndCall(mParent, *this, target, &ActorParent::LowerChildBelow);
 }
 
-void Actor::SetParent(ActorParent* parent)
+void Actor::SetParent(ActorParent* parent, bool notify)
 {
   if(parent)
   {
@@ -1820,7 +1629,7 @@ void Actor::SetParent(ActorParent* parent)
        parentActor->OnScene())
     {
       // Instruct each actor to create a corresponding node in the scene graph
-      ConnectToScene(parentActor->GetHierarchyDepth());
+      ConnectToScene(parentActor->GetHierarchyDepth(), notify);
     }
 
     // Resolve the name and index for the child properties if any
@@ -1839,43 +1648,23 @@ void Actor::SetParent(ActorParent* parent)
       DisconnectNodeMessage(GetEventThreadServices().GetUpdateManager(), GetNode());
 
       // Instruct each actor to discard pointers to the scene-graph
-      DisconnectFromStage();
+      DisconnectFromStage(notify);
     }
 
     mScene = nullptr;
   }
 }
 
-bool Actor::DoAction(BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */)
+Rect<> Actor::CalculateScreenExtents() const
 {
-  bool   done  = false;
-  Actor* actor = dynamic_cast<Actor*>(object);
-
-  if(actor)
-  {
-    std::string_view name(actionName);
-    if(name == ACTION_SHOW)
-    {
-      actor->SetVisible(true);
-      done = true;
-    }
-    else if(name == ACTION_HIDE)
-    {
-      actor->SetVisible(false);
-      done = true;
-    }
-  }
-
-  return done;
+  auto        screenPosition = GetCurrentScreenPosition();
+  BufferIndex bufferIndex    = GetEventThreadServices().GetEventBufferIndex();
+  return CalculateActorScreenExtents(*this, screenPosition, bufferIndex);
 }
 
-Rect<> Actor::CalculateScreenExtents() const
+Vector3 Actor::GetAnchorPointForPosition() const
 {
-  auto    screenPosition    = GetCurrentScreenPosition();
-  Vector3 size              = GetCurrentSize() * GetCurrentWorldScale();
-  Vector3 anchorPointOffSet = size * (mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT);
-  Vector2 position          = Vector2(screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y);
-  return {position.x, position.y, size.x, size.y};
+  return (mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT);
 }
 
 bool Actor::GetCachedPropertyValue(Property::Index index, Property::Value& value) const
@@ -1901,47 +1690,12 @@ Actor::Relayouter& Actor::EnsureRelayouter()
 
 bool Actor::RelayoutDependentOnParent(Dimension::Type dimension)
 {
-  // Check if actor is dependent on parent
-  for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
-  {
-    if((dimension & (1 << i)))
-    {
-      const ResizePolicy::Type resizePolicy = GetResizePolicy(static_cast<Dimension::Type>(1 << i));
-      if(resizePolicy == ResizePolicy::FILL_TO_PARENT || resizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT || resizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT)
-      {
-        return true;
-      }
-    }
-  }
-
-  return false;
+  return mRelayoutData && mRelayoutData->GetRelayoutDependentOnParent(dimension);
 }
 
 bool Actor::RelayoutDependentOnChildren(Dimension::Type dimension)
 {
-  // Check if actor is dependent on children
-  for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
-  {
-    if((dimension & (1 << i)))
-    {
-      const ResizePolicy::Type resizePolicy = GetResizePolicy(static_cast<Dimension::Type>(1 << i));
-      switch(resizePolicy)
-      {
-        case ResizePolicy::FIT_TO_CHILDREN:
-        case ResizePolicy::USE_NATURAL_SIZE: // i.e. For things that calculate their size based on children
-        {
-          return true;
-        }
-
-        default:
-        {
-          break;
-        }
-      }
-    }
-  }
-
-  return false;
+  return mRelayoutData && mRelayoutData->GetRelayoutDependentOnChildren(dimension);
 }
 
 bool Actor::RelayoutDependentOnChildrenBase(Dimension::Type dimension)
@@ -1951,41 +1705,20 @@ bool Actor::RelayoutDependentOnChildrenBase(Dimension::Type dimension)
 
 bool Actor::RelayoutDependentOnDimension(Dimension::Type dimension, Dimension::Type dependentDimension)
 {
-  // Check each possible dimension and see if it is dependent on the input one
-  for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
-  {
-    if(dimension & (1 << i))
-    {
-      return mRelayoutData->resizePolicies[i] == ResizePolicy::DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[i] == dependentDimension;
-    }
-  }
-
-  return false;
+  return mRelayoutData && mRelayoutData->GetRelayoutDependentOnDimension(dimension, dependentDimension);
 }
 
 void Actor::SetNegotiatedDimension(float negotiatedDimension, Dimension::Type dimension)
 {
-  for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
+  if(mRelayoutData)
   {
-    if(dimension & (1 << i))
-    {
-      mRelayoutData->negotiatedDimensions[i] = negotiatedDimension;
-    }
+    mRelayoutData->SetNegotiatedDimension(negotiatedDimension, dimension);
   }
 }
 
 float Actor::GetNegotiatedDimension(Dimension::Type dimension) const
 {
-  // If more than one dimension is requested, just return the first one found
-  for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
-  {
-    if((dimension & (1 << i)))
-    {
-      return mRelayoutData->negotiatedDimensions[i];
-    }
-  }
-
-  return 0.0f; // Default
+  return mRelayoutData ? mRelayoutData->GetNegotiatedDimension(dimension) : 0.0f;
 }
 
 void Actor::SetPadding(const Vector2& padding, Dimension::Type dimension)
@@ -1995,19 +1728,7 @@ void Actor::SetPadding(const Vector2& padding, Dimension::Type dimension)
 
 Vector2 Actor::GetPadding(Dimension::Type dimension) const
 {
-  if(mRelayoutData)
-  {
-    // If more than one dimension is requested, just return the first one found
-    for(uint32_t i = 0; i < Dimension::DIMENSION_COUNT; ++i)
-    {
-      if((dimension & (1 << i)))
-      {
-        return mRelayoutData->dimensionPadding[i];
-      }
-    }
-  }
-
-  return Relayouter::DEFAULT_DIMENSION_PADDING;
+  return mRelayoutData ? mRelayoutData->GetPadding(dimension) : Relayouter::DEFAULT_DIMENSION_PADDING;
 }
 
 void Actor::SetLayoutNegotiated(bool negotiated, Dimension::Type dimension)
@@ -2022,63 +1743,19 @@ bool Actor::IsLayoutNegotiated(Dimension::Type dimension) const
 
 float Actor::GetHeightForWidthBase(float width)
 {
-  float height = 0.0f;
-
   const Vector3 naturalSize = GetNaturalSize();
-  if(naturalSize.width > 0.0f)
-  {
-    height = naturalSize.height * width / naturalSize.width;
-  }
-  else // we treat 0 as 1:1 aspect ratio
-  {
-    height = width;
-  }
-
-  return height;
+  return naturalSize.width > 0.0f ? naturalSize.height * width / naturalSize.width : width;
 }
 
 float Actor::GetWidthForHeightBase(float height)
 {
-  float width = 0.0f;
-
   const Vector3 naturalSize = GetNaturalSize();
-  if(naturalSize.height > 0.0f)
-  {
-    width = naturalSize.width * height / naturalSize.height;
-  }
-  else // we treat 0 as 1:1 aspect ratio
-  {
-    width = height;
-  }
-
-  return width;
+  return naturalSize.height > 0.0f ? naturalSize.width * height / naturalSize.height : height;
 }
 
 float Actor::CalculateChildSizeBase(const Dali::Actor& child, Dimension::Type dimension)
 {
-  // Fill to parent, taking size mode factor into account
-  switch(child.GetResizePolicy(dimension))
-  {
-    case ResizePolicy::FILL_TO_PARENT:
-    {
-      return GetLatestSize(dimension);
-    }
-
-    case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
-    {
-      return GetLatestSize(dimension) * GetDimensionValue(child.GetProperty<Vector3>(Dali::Actor::Property::SIZE_MODE_FACTOR), dimension);
-    }
-
-    case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
-    {
-      return GetLatestSize(dimension) + GetDimensionValue(child.GetProperty<Vector3>(Dali::Actor::Property::SIZE_MODE_FACTOR), dimension);
-    }
-
-    default:
-    {
-      return GetLatestSize(dimension);
-    }
-  }
+  return Actor::Relayouter::CalculateChildSize(*this, GetImplementation(child), dimension);
 }
 
 float Actor::CalculateChildSize(const Dali::Actor& child, Dimension::Type dimension)
@@ -2113,103 +1790,27 @@ float Actor::GetRelayoutSize(Dimension::Type dimension) const
 
 float Actor::NegotiateFromParent(Dimension::Type dimension)
 {
-  Actor* parent = GetParent();
-  if(parent)
-  {
-    Vector2 padding(GetPadding(dimension));
-    Vector2 parentPadding(parent->GetPadding(dimension));
-    return parent->CalculateChildSize(Dali::Actor(this), dimension) - parentPadding.x - parentPadding.y - padding.x - padding.y;
-  }
-
-  return 0.0f;
+  return Relayouter::NegotiateDimensionFromParent(*this, dimension);
 }
 
 float Actor::NegotiateFromChildren(Dimension::Type dimension)
 {
-  float maxDimensionPoint = 0.0f;
-
-  for(uint32_t i = 0, count = GetChildCount(); i < count; ++i)
-  {
-    ActorPtr child = GetChildAt(i);
-
-    if(!child->RelayoutDependentOnParent(dimension))
-    {
-      // Calculate the min and max points that the children range across
-      float childPosition = GetDimensionValue(child->GetTargetPosition(), dimension);
-      float dimensionSize = child->GetRelayoutSize(dimension);
-      maxDimensionPoint   = std::max(maxDimensionPoint, childPosition + dimensionSize);
-    }
-  }
-
-  return maxDimensionPoint;
+  return Relayouter::NegotiateDimensionFromChildren(*this, dimension);
 }
 
 float Actor::GetSize(Dimension::Type dimension) const
 {
-  return GetDimensionValue(mTargetSize, dimension);
+  return Relayouter::GetDimensionValue(mTargetSize, dimension);
 }
 
 float Actor::GetNaturalSize(Dimension::Type dimension) const
 {
-  return GetDimensionValue(GetNaturalSize(), dimension);
+  return Relayouter::GetDimensionValue(GetNaturalSize(), dimension);
 }
 
 float Actor::CalculateSize(Dimension::Type dimension, const Vector2& maximumSize)
 {
-  switch(GetResizePolicy(dimension))
-  {
-    case ResizePolicy::USE_NATURAL_SIZE:
-    {
-      return GetNaturalSize(dimension);
-    }
-
-    case ResizePolicy::FIXED:
-    {
-      return GetDimensionValue(GetPreferredSize(), dimension);
-    }
-
-    case ResizePolicy::USE_ASSIGNED_SIZE:
-    {
-      return GetDimensionValue(maximumSize, dimension);
-    }
-
-    case ResizePolicy::FILL_TO_PARENT:
-    case ResizePolicy::SIZE_RELATIVE_TO_PARENT:
-    case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT:
-    {
-      return NegotiateFromParent(dimension);
-    }
-
-    case ResizePolicy::FIT_TO_CHILDREN:
-    {
-      return NegotiateFromChildren(dimension);
-    }
-
-    case ResizePolicy::DIMENSION_DEPENDENCY:
-    {
-      const Dimension::Type dimensionDependency = GetDimensionDependency(dimension);
-
-      // Custom rules
-      if(dimension == Dimension::WIDTH && dimensionDependency == Dimension::HEIGHT)
-      {
-        return GetWidthForHeight(GetNegotiatedDimension(Dimension::HEIGHT));
-      }
-
-      if(dimension == Dimension::HEIGHT && dimensionDependency == Dimension::WIDTH)
-      {
-        return GetHeightForWidth(GetNegotiatedDimension(Dimension::WIDTH));
-      }
-
-      break;
-    }
-
-    default:
-    {
-      break;
-    }
-  }
-
-  return 0.0f; // Default
+  return Relayouter::CalculateSize(*this, dimension, maximumSize);
 }
 
 Vector2 Actor::ApplySizeSetPolicy(const Vector2& size)
@@ -2241,6 +1842,8 @@ void Actor::SetNegotiatedSize(RelayoutContainer& container)
     Dali::Actor handle(this);
     mOnRelayoutSignal.Emit(handle);
   }
+
+  mRelayoutData->relayoutRequested = false;
 }
 
 void Actor::NegotiateSize(const Vector2& allocatedSize, RelayoutContainer& container)
@@ -2268,6 +1871,11 @@ void Actor::RelayoutRequest(Dimension::Type dimension)
   {
     Dali::Actor self(this);
     relayoutController->RequestRelayout(self, dimension);
+
+    if(mRelayoutData)
+    {
+      mRelayoutData->relayoutRequested = true;
+    }
   }
 }
 
@@ -2278,12 +1886,7 @@ void Actor::SetPreferredSize(const Vector2& size)
 
 Vector2 Actor::GetPreferredSize() const
 {
-  if(mRelayoutData)
-  {
-    return Vector2(mRelayoutData->preferredSize);
-  }
-
-  return Relayouter::DEFAULT_PREFERRED_SIZE;
+  return mRelayoutData ? Vector2(mRelayoutData->preferredSize) : Relayouter::DEFAULT_PREFERRED_SIZE;
 }
 
 void Actor::SetMinimumSize(float size, Dimension::Type dimension)
@@ -2294,12 +1897,7 @@ void Actor::SetMinimumSize(float size, Dimension::Type dimension)
 
 float Actor::GetMinimumSize(Dimension::Type dimension) const
 {
-  if(mRelayoutData)
-  {
-    return mRelayoutData->GetMinimumSize(dimension);
-  }
-
-  return 0.0f; // Default
+  return mRelayoutData ? mRelayoutData->GetMinimumSize(dimension) : 0.0f;
 }
 
 void Actor::SetMaximumSize(float size, Dimension::Type dimension)
@@ -2310,12 +1908,7 @@ void Actor::SetMaximumSize(float size, Dimension::Type dimension)
 
 float Actor::GetMaximumSize(Dimension::Type dimension) const
 {
-  if(mRelayoutData)
-  {
-    return mRelayoutData->GetMaximumSize(dimension);
-  }
-
-  return FLT_MAX; // Default
+  return mRelayoutData ? mRelayoutData->GetMaximumSize(dimension) : FLT_MAX;
 }
 
 void Actor::SetVisibleInternal(bool visible, SendMessage::Type sendMessage)
@@ -2333,7 +1926,7 @@ void Actor::SetVisibleInternal(bool visible, SendMessage::Type sendMessage)
     mVisible = visible;
 
     // Emit the signal on this actor and all its children
-    EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::SELF);
+    mParentImpl.EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::SELF);
   }
 }
 
@@ -2385,28 +1978,7 @@ void Actor::SetInheritLayoutDirection(bool inherit)
 
     if(inherit && mParent)
     {
-      InheritLayoutDirectionRecursively(GetParent()->mLayoutDirection);
-    }
-  }
-}
-
-void Actor::InheritLayoutDirectionRecursively(Dali::LayoutDirection::Type direction, bool set)
-{
-  if(mInheritLayoutDirection || set)
-  {
-    if(mLayoutDirection != direction)
-    {
-      mLayoutDirection = direction;
-      EmitLayoutDirectionChangedSignal(direction);
-      RelayoutRequest();
-    }
-
-    if(GetChildCount() > 0)
-    {
-      for(const auto& child : mParentImpl.GetChildrenInternal())
-      {
-        child->InheritLayoutDirectionRecursively(direction);
-      }
+      mParentImpl.InheritLayoutDirectionRecursively(GetParent()->mLayoutDirection);
     }
   }
 }
@@ -2417,20 +1989,6 @@ void Actor::SetUpdateSizeHint(const Vector2& updateSizeHint)
   SceneGraph::NodePropertyMessage<Vector3>::Send(GetEventThreadServices(), &GetNode(), &GetNode().mUpdateSizeHint, &AnimatableProperty<Vector3>::Bake, Vector3(updateSizeHint.width, updateSizeHint.height, 0.f));
 }
 
-void Actor::EmitVisibilityChangedSignalRecursively(bool                               visible,
-                                                   DevelActor::VisibilityChange::Type type)
-{
-  EmitVisibilityChangedSignal(visible, type);
-
-  if(GetChildCount() > 0)
-  {
-    for(auto& child : mParentImpl.GetChildrenInternal())
-    {
-      child->EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::PARENT);
-    }
-  }
-}
-
 } // namespace Internal
 
 } // namespace Dali