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