New size negotiation 72/36272/13
authorKingsley Stephens <k.stephens@partner.samsung.com>
Thu, 20 Nov 2014 12:54:38 +0000 (12:54 +0000)
committerKingsley Stephens <k.stephens@samsung.com>
Mon, 30 Mar 2015 13:31:20 +0000 (14:31 +0100)
Change-Id: Ie58e896029fc35dfb4a41d63ea68af3b5d8de6e7

41 files changed:
automated-tests/src/dali-internal/CMakeLists.txt
automated-tests/src/dali-internal/utc-Dali-Internal-RelayoutController.cpp [new file with mode: 0644]
automated-tests/src/dali/dali-test-suite-utils/test-application.cpp
automated-tests/src/dali/utc-Dali-Actor.cpp
automated-tests/src/dali/utc-Dali-Animation.cpp
automated-tests/src/dali/utc-Dali-CustomActor.cpp
automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp
automated-tests/src/dali/utc-Dali-HoverProcessing.cpp
automated-tests/src/dali/utc-Dali-ImageActor.cpp
automated-tests/src/dali/utc-Dali-RenderTask.cpp
automated-tests/src/dali/utc-Dali-TouchProcessing.cpp
automated-tests/src/dali/utc-Dali-TypeRegistry.cpp
build/tizen/dali-core/Makefile.am
dali/internal/common/core-impl.cpp
dali/internal/common/core-impl.h
dali/internal/event/actors/actor-impl.cpp
dali/internal/event/actors/actor-impl.h
dali/internal/event/actors/custom-actor-internal.h
dali/internal/event/actors/image-actor-impl.cpp
dali/internal/event/actors/layer-impl.cpp
dali/internal/event/common/stage-impl.cpp
dali/internal/event/common/system-overlay-impl.cpp
dali/internal/event/common/thread-local-storage.cpp
dali/internal/event/common/thread-local-storage.h
dali/internal/event/size-negotiation/memory-pool-relayout-container.cpp [new file with mode: 0644]
dali/internal/event/size-negotiation/memory-pool-relayout-container.h [new file with mode: 0644]
dali/internal/event/size-negotiation/relayout-controller-impl.cpp [new file with mode: 0644]
dali/internal/event/size-negotiation/relayout-controller-impl.h [new file with mode: 0644]
dali/internal/file.list
dali/internal/update/manager/update-algorithms.cpp
dali/internal/update/nodes/node.cpp
dali/internal/update/nodes/node.h
dali/public-api/actors/actor-enumerations.h
dali/public-api/actors/actor.cpp
dali/public-api/actors/actor.h
dali/public-api/actors/custom-actor-impl.cpp
dali/public-api/actors/custom-actor-impl.h
dali/public-api/dali-core.h
dali/public-api/file.list
dali/public-api/math/rect.h
dali/public-api/size-negotiation/relayout-container.h [new file with mode: 0644]

index 26b6e8f..5eb1e41 100644 (file)
@@ -18,6 +18,7 @@ SET(TC_SOURCES
         utc-Dali-Internal-Constraint.cpp
         utc-Dali-Internal-FixedSizeMemoryPool.cpp
         utc-Dali-Internal-MemoryPoolObjectAllocator.cpp
+        utc-Dali-Internal-RelayoutController.cpp
 )
 
 LIST(APPEND TC_SOURCES
diff --git a/automated-tests/src/dali-internal/utc-Dali-Internal-RelayoutController.cpp b/automated-tests/src/dali-internal/utc-Dali-Internal-RelayoutController.cpp
new file mode 100644 (file)
index 0000000..46ac182
--- /dev/null
@@ -0,0 +1,490 @@
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <iostream>
+
+#include <stdlib.h>
+#include <dali/public-api/dali-core.h>
+#include <dali-test-suite-utils.h>
+
+#include <dali/internal/event/actors/actor-impl.h>
+#include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
+
+using namespace Dali;
+
+void utc_dali_internal_relayout_controller_startup(void)
+{
+  test_return_value = TET_UNDEF;
+}
+
+void utc_dali_internal_relayout_controller_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
+namespace
+{
+
+// Properties to attach to actors for testing
+const std::string REQUEST_WIDTH( "REQUEST_WIDTH" );
+const std::string REQUEST_HEIGHT( "REQUEST_HEIGHT" );
+const std::string EXPECTED_WIDTH_DIRTY( "EXPECTED_WIDTH_DIRTY" );
+const std::string EXPECTED_HEIGHT_DIRTY( "EXPECTED_HEIGHT_DIRTY" );
+
+/**
+ * Check to see that the desired test results were achieved
+ */
+void CheckResults( Actor root )
+{
+  const bool expectedWidthDirty = root.GetProperty( root.GetPropertyIndex( EXPECTED_WIDTH_DIRTY ) ).Get< bool >();
+  const bool expectedHeightDirty = root.GetProperty( root.GetPropertyIndex( EXPECTED_HEIGHT_DIRTY ) ).Get< bool >();
+
+  Internal::Actor& rootImpl = GetImplementation( root );
+
+  DALI_TEST_CHECK( rootImpl.IsLayoutDirty( WIDTH ) == expectedWidthDirty );
+  DALI_TEST_CHECK( rootImpl.IsLayoutDirty( HEIGHT ) == expectedHeightDirty );
+
+  for( unsigned int i = 0, numChildren = root.GetChildCount(); i < numChildren; ++i )
+  {
+    Actor child = root.GetChildAt( i );
+
+    CheckResults( child );
+  }
+}
+
+/**
+ * Create a new actor and enable relayout on it
+ *
+ * @return Return the new actor
+ */
+Actor NewRelayoutActor( bool expectedWidthDirty, bool expectedHeightDirty, ResizePolicy widthPolicy, ResizePolicy heightPolicy )
+{
+  Actor actor = Actor::New();
+
+  actor.SetRelayoutEnabled( true );
+
+  actor.SetResizePolicy( widthPolicy, WIDTH );
+  actor.SetResizePolicy( heightPolicy, HEIGHT );
+
+  // Expected results for this actor
+  actor.RegisterProperty( EXPECTED_WIDTH_DIRTY, expectedWidthDirty, Property::READ_WRITE );
+  actor.RegisterProperty( EXPECTED_HEIGHT_DIRTY, expectedHeightDirty, Property::READ_WRITE );
+
+  return actor;
+}
+
+/**
+ * Create a new root actor and enable relayout on it
+ *
+ * @return Return the new actor
+ */
+Actor NewRelayoutRootActor( bool requestWidth, bool requestHeight, bool expectedWidthDirty, bool expectedHeightDirty, ResizePolicy widthPolicy, ResizePolicy heightPolicy )
+{
+  Actor actor = NewRelayoutActor( expectedWidthDirty, expectedHeightDirty, widthPolicy, heightPolicy );
+
+  // Add properties to configure testing
+  actor.RegisterProperty( REQUEST_WIDTH, requestWidth, Property::READ_WRITE );
+  actor.RegisterProperty( REQUEST_HEIGHT, requestHeight, Property::READ_WRITE );
+
+  return actor;
+}
+
+void TestTree( TestApplication& application, Actor root, Actor entryPoint = Actor() )
+{
+  // Render and notify - clear the flags
+  application.SendNotification();
+  application.Render();
+
+  Internal::RelayoutController* controller = Internal::RelayoutController::Get();
+  controller->SetEnabled( true );
+
+  const bool widthRequest = root.GetProperty( root.GetPropertyIndex( REQUEST_WIDTH ) ).Get< bool >();
+  const bool heightRequest = root.GetProperty( root.GetPropertyIndex( REQUEST_HEIGHT ) ).Get< bool >();
+
+  const Dimension dimensions = Dimension( ( ( widthRequest ) ? WIDTH : 0 ) | ( ( heightRequest ) ? HEIGHT : 0 ) );
+
+  controller->RequestRelayout( ( entryPoint ) ? entryPoint : root, dimensions );
+
+  CheckResults( root );
+}
+
+} // anonymous namespace
+
+int UtcDaliRelayoutControllerGet(void)
+{
+  TestApplication application;
+
+  Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
+
+  DALI_TEST_CHECK( relayoutController );
+
+  END_TEST;
+}
+
+int UtcDaliRelayoutControllerRequestRelayout(void)
+{
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  actor.SetRelayoutEnabled( true );
+
+  Internal::Actor& actorImpl = GetImplementation( actor );
+
+  // Request default enable (false)
+  Internal::RelayoutController* controller = Internal::RelayoutController::Get();
+  controller->RequestRelayout( actor );
+
+  DALI_TEST_CHECK( actorImpl.IsLayoutDirty() );
+
+  END_TEST;
+}
+
+int UtcDaliRelayoutController_Relayout_SingleActor(void)
+{
+  TestApplication application;
+
+  // Construct scene
+  Actor parent = NewRelayoutRootActor( true, true, true, true, FIXED, FIXED );
+
+  TestTree( application, parent );
+
+  END_TEST;
+}
+
+int UtcDaliRelayoutController_Relayout_FixedParent(void)
+{
+  TestApplication application;
+
+  Internal::RelayoutController* controller = Internal::RelayoutController::Get();
+  controller->SetEnabled( false );
+
+  // Construct scene
+  Actor parent = NewRelayoutRootActor( true, true, true, true, FIXED, FIXED );
+
+  // Add a child
+  Actor child = NewRelayoutActor( false, false, FIXED, FIXED );
+  parent.Add( child );
+
+  TestTree( application, parent );
+
+  END_TEST;
+}
+
+int UtcDaliRelayoutController_Relayout_NaturalParent(void)
+{
+  TestApplication application;
+
+  Internal::RelayoutController* controller = Internal::RelayoutController::Get();
+  controller->SetEnabled( false );
+
+  // Construct scene
+  Actor parent = NewRelayoutRootActor( true, true, true, true, USE_NATURAL_SIZE, USE_NATURAL_SIZE );
+
+  // Add a child
+  Actor child = NewRelayoutActor( false, false, FIXED, FIXED );
+  parent.Add( child );
+
+  // Run the test
+  TestTree( application, parent );
+
+  END_TEST;
+}
+
+int UtcDaliRelayoutController_Relayout_FillParent(void)
+{
+  TestApplication application;
+
+  Internal::RelayoutController* controller = Internal::RelayoutController::Get();
+  controller->SetEnabled( false );
+
+  // Construct scene
+  Actor parent = NewRelayoutRootActor( true, true, true, true, FILL_TO_PARENT, FILL_TO_PARENT );
+
+  // Add a child
+  Actor child = NewRelayoutActor( false, false, FIXED, FIXED );
+  parent.Add( child );
+
+  // Run the test
+  TestTree( application, parent );
+
+  END_TEST;
+}
+
+int UtcDaliRelayoutController_Relayout_FitParent(void)
+{
+  TestApplication application;
+
+  Internal::RelayoutController* controller = Internal::RelayoutController::Get();
+  controller->SetEnabled( false );
+
+  // Construct scene
+  Actor parent = NewRelayoutRootActor( true, true, true, true, FIT_TO_CHILDREN, FIT_TO_CHILDREN );
+
+  // Add a child
+  Actor child = NewRelayoutActor( false, false, FIXED, FIXED );
+  parent.Add( child );
+
+  // Run the test
+  TestTree( application, parent );
+
+  END_TEST;
+}
+
+int UtcDaliRelayoutController_Relayout_DepParent1(void)
+{
+  TestApplication application;
+
+  Internal::RelayoutController* controller = Internal::RelayoutController::Get();
+  controller->SetEnabled( false );
+
+  // Construct scene
+  Actor parent = NewRelayoutRootActor( true, true, true, true, DIMENSION_DEPENDENCY, FIT_TO_CHILDREN );
+
+  // Add a child
+  Actor child = NewRelayoutActor( false, false, FIXED, FIXED );
+  parent.Add( child );
+
+  // Run the test
+  TestTree( application, parent );
+
+  END_TEST;
+}
+
+int UtcDaliRelayoutController_Relayout_DepParent2(void)
+{
+  TestApplication application;
+
+  Internal::RelayoutController* controller = Internal::RelayoutController::Get();
+  controller->SetEnabled( false );
+
+  // Construct scene
+  Actor parent = NewRelayoutRootActor( true, true, true, true, FIT_TO_CHILDREN, DIMENSION_DEPENDENCY );
+
+  Actor child = NewRelayoutActor( false, false, FIXED, FIXED );
+  parent.Add( child );
+
+
+  // Run the test
+  TestTree( application, parent );
+
+  END_TEST;
+}
+
+int UtcDaliRelayoutController_Relayout_Child1(void)
+{
+  TestApplication application;
+
+  Internal::RelayoutController* controller = Internal::RelayoutController::Get();
+  controller->SetEnabled( false );
+
+  // Construct scene
+  Actor parent = NewRelayoutRootActor( true, true, true, true, FIT_TO_CHILDREN, FIT_TO_CHILDREN );
+
+  // Add a child
+  Actor child = NewRelayoutActor( true, true, FIXED, FIXED );
+  parent.Add( child );
+
+  // Run the test
+  TestTree( application, parent, child );
+
+  END_TEST;
+}
+
+int UtcDaliRelayoutController_Relayout_Child2(void)
+{
+  TestApplication application;
+
+  Internal::RelayoutController* controller = Internal::RelayoutController::Get();
+  controller->SetEnabled( false );
+
+  // Construct scene
+  Actor parent = NewRelayoutRootActor( true, true, false, false, FIXED, FIXED );
+
+  // Add a child
+  Actor child = NewRelayoutActor( true, true, FIXED, FIXED );
+  parent.Add( child );
+
+  // Run the test
+  TestTree( application, parent, child );
+
+  END_TEST;
+}
+
+int UtcDaliRelayoutController_Relayout_Complex1(void)
+{
+  TestApplication application;
+
+  Internal::RelayoutController* controller = Internal::RelayoutController::Get();
+  controller->SetEnabled( false );
+
+  // Construct scene
+  Actor parent = NewRelayoutRootActor( true, true, true, true, FIXED, FIXED );
+
+  // Add children
+  Actor child1 = NewRelayoutActor( true, false, FILL_TO_PARENT, FIXED );
+  parent.Add( child1 );
+
+  Actor child2 = NewRelayoutActor( false, true, FIXED, FILL_TO_PARENT );
+  parent.Add( child2 );
+
+  Actor child3 = NewRelayoutActor( false, false, USE_NATURAL_SIZE, FIXED );
+  parent.Add( child3 );
+
+  // Grand children 1
+  Actor grandChild1_1 = NewRelayoutActor( true, false, FILL_TO_PARENT, FIXED );
+  child1.Add( grandChild1_1 );
+
+  Actor grandChild1_2 = NewRelayoutActor( false, false, FIXED, FILL_TO_PARENT );
+  child1.Add( grandChild1_2 );
+
+  // Grand children 2
+  Actor grandChild2_1 = NewRelayoutActor( false, false, FIXED, FIXED );
+  child2.Add( grandChild2_1 );
+
+  Actor grandChild2_2 = NewRelayoutActor( false, false, FIXED, FIXED );
+  child2.Add( grandChild2_2 );
+
+  // Run the test
+  TestTree( application, parent );
+
+  END_TEST;
+}
+
+int UtcDaliRelayoutController_Relayout_Complex2(void)
+{
+  TestApplication application;
+
+  Internal::RelayoutController* controller = Internal::RelayoutController::Get();
+  controller->SetEnabled( false );
+
+  // Construct scene
+  Actor parent = NewRelayoutRootActor( true, false, true, false, FIXED, FIXED );
+
+  // Add children
+  Actor child1 = NewRelayoutActor( true, false, FILL_TO_PARENT, FIXED );
+  parent.Add( child1 );
+
+  Actor child2 = NewRelayoutActor( false, false, FIXED, FILL_TO_PARENT );
+  parent.Add( child2 );
+
+  Actor child3 = NewRelayoutActor( false, false, USE_NATURAL_SIZE, FIXED );
+  parent.Add( child3 );
+
+  // Grand children 1
+  Actor grandChild1_1 = NewRelayoutActor( true, false, FILL_TO_PARENT, FIXED );
+  child1.Add( grandChild1_1 );
+
+  Actor grandChild1_2 = NewRelayoutActor( false, false, FIXED, FILL_TO_PARENT );
+  child1.Add( grandChild1_2 );
+
+  // Grand children 2
+  Actor grandChild2_1 = NewRelayoutActor( false, false, FIXED, FIXED );
+  child2.Add( grandChild2_1 );
+
+  Actor grandChild2_2 = NewRelayoutActor( false, false, FIXED, FIXED );
+  child2.Add( grandChild2_2 );
+
+  // Run the test
+  TestTree( application, parent );
+
+  END_TEST;
+}
+
+int UtcDaliRelayoutController_Relayout_Complex3(void)
+{
+  TestApplication application;
+
+  Internal::RelayoutController* controller = Internal::RelayoutController::Get();
+  controller->SetEnabled( false );
+
+  // Construct scene
+  Actor parent = NewRelayoutRootActor( false, true, false, true, FIXED, FIXED );
+
+  // Add children
+  Actor child1 = NewRelayoutActor( false, false, FILL_TO_PARENT, FIXED );
+  parent.Add( child1 );
+
+  Actor child2 = NewRelayoutActor( false, true, FIXED, FILL_TO_PARENT );
+  parent.Add( child2 );
+
+  Actor child3 = NewRelayoutActor( false, false, USE_NATURAL_SIZE, FIXED );
+  parent.Add( child3 );
+
+  // Grand children 1
+  Actor grandChild1_1 = NewRelayoutActor( false, false, FILL_TO_PARENT, FIXED );
+  child1.Add( grandChild1_1 );
+
+  Actor grandChild1_2 = NewRelayoutActor( false, false, FIXED, FILL_TO_PARENT );
+  child1.Add( grandChild1_2 );
+
+  // Grand children 2
+  Actor grandChild2_1 = NewRelayoutActor( false, false, FIXED, FIXED );
+  child2.Add( grandChild2_1 );
+
+  Actor grandChild2_2 = NewRelayoutActor( false, false, FIXED, FIXED );
+  child2.Add( grandChild2_2 );
+
+  // Run the test
+  TestTree( application, parent );
+
+  END_TEST;
+}
+
+int UtcDaliRelayoutController_Relayout_Dependency(void)
+{
+  TestApplication application;
+
+  Internal::RelayoutController* controller = Internal::RelayoutController::Get();
+  controller->SetEnabled( false );
+
+  // Construct scene
+  Actor parent = NewRelayoutRootActor( true, true, false, false, FIXED, FIXED );
+
+  // Add a child
+  Actor child = NewRelayoutActor( true, true, FILL_TO_PARENT, FIXED );
+  child.SetDimensionDependency( HEIGHT, WIDTH );
+  parent.Add( child );
+
+  // Run the test
+  TestTree( application, parent, child );
+
+  END_TEST;
+}
+
+int UtcDaliRelayoutControllerRequestRelayoutTree(void)
+{
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  actor.SetRelayoutEnabled( true );
+
+  Internal::Actor& actorImpl = GetImplementation( actor );
+
+  // Check if flag is set
+  DALI_TEST_CHECK( !actorImpl.IsLayoutDirty() );
+
+  Internal::RelayoutController* controller = Internal::RelayoutController::Get();
+  controller->SetEnabled( true );
+
+  // Request default enable (false)
+  controller->RequestRelayoutTree( actor );
+
+  DALI_TEST_CHECK( actorImpl.IsLayoutDirty() );
+
+  END_TEST;
+}
+
index ff8ec11..5d17a1d 100644 (file)
@@ -73,6 +73,8 @@ void TestApplication::Initialize()
 
   Dali::Integration::Log::LogFunction logFunction(&TestApplication::LogMessage);
   Dali::Integration::Log::InstallLogFunction(logFunction);
+
+  mCore->SceneCreated();
 }
 
 TestApplication::~TestApplication()
index ba07bb9..b5824b5 100644 (file)
@@ -44,7 +44,6 @@ namespace
 const Scripting::StringEnum< int > SIZE_MODE_VALUES[] =
 {
   { "USE_OWN_SIZE",                  USE_OWN_SIZE                  },
-  { "SIZE_EQUAL_TO_PARENT",          SIZE_EQUAL_TO_PARENT          },
   { "SIZE_RELATIVE_TO_PARENT",       SIZE_RELATIVE_TO_PARENT       },
   { "SIZE_FIXED_OFFSET_FROM_PARENT", SIZE_FIXED_OFFSET_FROM_PARENT },
 };
@@ -843,19 +842,19 @@ int UtcDaliActorGetCurrentSizeImmediate(void)
   Actor actor = Actor::New();
   Vector3 vector(100.0f, 100.0f, 20.0f);
 
-  DALI_TEST_CHECK(vector != actor.GetSize());
+  DALI_TEST_CHECK(vector != actor.GetTargetSize());
   DALI_TEST_CHECK(vector != actor.GetCurrentSize());
 
   actor.SetSize(vector);
 
-  DALI_TEST_CHECK(vector == actor.GetSize());
+  DALI_TEST_CHECK(vector == actor.GetTargetSize());
   DALI_TEST_CHECK(vector != actor.GetCurrentSize());
 
   // flush the queue and render once
   application.SendNotification();
   application.Render();
 
-  DALI_TEST_CHECK(vector == actor.GetSize());
+  DALI_TEST_CHECK(vector == actor.GetTargetSize());
   DALI_TEST_CHECK(vector == actor.GetCurrentSize());
 
   // Animation
@@ -865,7 +864,7 @@ int UtcDaliActorGetCurrentSizeImmediate(void)
   const Vector3 targetValue( 10.0f, 20.0f, 30.0f );
   animation.AnimateTo( Property( actor, Actor::Property::SIZE ), targetValue );
 
-  DALI_TEST_CHECK( actor.GetSize() == targetValue );
+  DALI_TEST_CHECK( actor.GetTargetSize() == targetValue );
 
   // Start the animation
   animation.Play();
@@ -873,7 +872,7 @@ int UtcDaliActorGetCurrentSizeImmediate(void)
   application.SendNotification();
   application.Render( static_cast<unsigned int>( durationSeconds * 1000.0f ) );
 
-  DALI_TEST_CHECK( actor.GetSize() == targetValue );
+  DALI_TEST_CHECK( actor.GetTargetSize() == targetValue );
 
   END_TEST;
 }
@@ -1174,213 +1173,6 @@ int UtcDaliActorInheritPosition(void)
   END_TEST;
 }
 
-int UtcDaliActorSizeMode(void)
-{
-  tet_infoline("Testing Actor::SetSizeMode");
-  TestApplication application;
-
-  // Create a parent and a child.
-  Actor parent = Actor::New();
-  parent.SetParentOrigin( ParentOrigin::CENTER );
-  parent.SetAnchorPoint( AnchorPoint::CENTER );
-  Vector3 parentPosition( 0.0f, 0.0f, 0.0f );
-  parent.SetPosition( parentPosition );
-  parent.SetSize( 10.0f, 20.0f, 40.0f );
-  parent.SetSizeMode( USE_OWN_SIZE );
-  Stage::GetCurrent().Add( parent );
-
-  Actor child = Actor::New();
-  child.SetParentOrigin( ParentOrigin::CENTER );
-  child.SetAnchorPoint( AnchorPoint::CENTER );
-  Vector3 childPosition( 0.0f, 0.0f, 0.0f );
-  child.SetPosition( childPosition );
-  child.SetSize( 1.0f, 2.0f, 4.0f );
-  child.SetSizeMode( USE_OWN_SIZE );
-  parent.Add( child );
-
-  // Flush the queue and render once.
-  application.SendNotification();
-  application.Render();
-
-  // Test USE_OWN_SIZE uses the user-set size value.
-  DALI_TEST_EQUALS( child.GetCurrentSize(), Vector3( 1.0f, 2.0f, 4.0f ), TEST_LOCATION );
-  // Render and check again to ensure double-buffering does not cause old value to reappear.
-  application.Render();
-  DALI_TEST_EQUALS( child.GetCurrentSize(), Vector3( 1.0f, 2.0f, 4.0f ), TEST_LOCATION );
-
-  // Test SIZE_EQUAL_TO_PARENT overrides size with the parents size.
-  child.SetSizeMode( SIZE_EQUAL_TO_PARENT );
-
-  application.SendNotification();
-  application.Render();
-  DALI_TEST_EQUALS( child.GetCurrentSize(), Vector3( 10.0f, 20.0f, 40.0f ), TEST_LOCATION );
-  // Render and check again to ensure double-buffering does not cause old value to reappear.
-  application.Render();
-  DALI_TEST_EQUALS( child.GetCurrentSize(), Vector3( 10.0f, 20.0f, 40.0f ), TEST_LOCATION );
-
-  // Test SIZE_RELATIVE_TO_PARENT overrides size with parents size * SizeModeFactor.
-  child.SetSizeMode( SIZE_RELATIVE_TO_PARENT );
-
-  application.SendNotification();
-  application.Render();
-  // First check without setting a relative factor, to confirm that the default factor (of 1.0f) is used.
-  DALI_TEST_EQUALS( child.GetCurrentSize(), Vector3( 10.0f, 20.0f, 40.0f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-  // Render and check again to ensure double-buffering does not cause old value to reappear.
-  application.Render();
-  DALI_TEST_EQUALS( child.GetCurrentSize(), Vector3( 10.0f, 20.0f, 40.0f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-
-  // Set an arbitary relative factor to check against.
-  child.SetSizeModeFactor( Vector3( 2.0f, 3.0f, 4.0f ) );
-
-  application.SendNotification();
-  application.Render();
-  // Check with a valid relative factor.
-  DALI_TEST_EQUALS( child.GetCurrentSize(), Vector3( 20.0f, 60.0f, 160.0f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-  // Render and check again to ensure double-buffering does not cause old value to reappear.
-  application.Render();
-  DALI_TEST_EQUALS( child.GetCurrentSize(), Vector3( 20.0f, 60.0f, 160.0f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-
-  // Test SIZE_FIXED_OFFSET_FROM_PARENT overrides size with parents size + SizeModeFactor.
-  child.SetSizeMode( SIZE_FIXED_OFFSET_FROM_PARENT );
-
-  application.SendNotification();
-  application.Render();
-  // Check with a valid relative factor.
-  DALI_TEST_EQUALS( child.GetCurrentSize(), Vector3( 12.0f, 23.0f, 44.0f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-  // Render and check again to ensure double-buffering does not cause old value to reappear.
-  application.Render();
-  DALI_TEST_EQUALS( child.GetCurrentSize(), Vector3( 12.0f, 23.0f, 44.0f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-
-  application.SendNotification();
-
-  // Test the calculation order in update by having a parent with a size-relative
-  // factor and a rotation rotate a child anchored to one of the parents corners.
-  //       .---. c
-  //   .-----. |          .-----.    The new child is parented from the top-left of its parent.
-  //   |   '-|-'  ----->  |     |    We rotate the parent to confirm that the relative size calculation is
-  //   |  p  |    Rotate  |   .-|-.  done before rotation. If it wasn't, the childs resultant
-  //   '-----'    parent  '-----' |  world-position would be incorrect.
-  //                90°       '---'
-  //
-  // Create a new parent and child, and a root parent which the parent can grab relative size from.
-  Actor rootParent = Actor::New();
-  rootParent.SetParentOrigin( ParentOrigin::CENTER );
-  rootParent.SetAnchorPoint( AnchorPoint::CENTER );
-  rootParent.SetPosition( Vector3( 0.0f, 0.0f, 0.0f ) );
-  rootParent.SetSize( 10.0f, 10.0f, 10.0f );
-  rootParent.SetSizeMode( USE_OWN_SIZE );
-  Stage::GetCurrent().Add( rootParent );
-
-  Actor newParent = Actor::New();
-  newParent.SetParentOrigin( ParentOrigin::CENTER );
-  newParent.SetAnchorPoint( AnchorPoint::CENTER );
-  newParent.SetPosition( Vector3( 0.0f, 0.0f, 0.0f ) );
-  newParent.SetSize( 10.0f, 10.0f, 10.0f );
-  newParent.SetSizeMode( SIZE_RELATIVE_TO_PARENT );
-  newParent.SetSizeModeFactor( Vector3( 0.5f, 0.5f, 0.5f ) );
-  rootParent.Add( newParent );
-
-  Actor newChild = Actor::New();
-  newChild.SetParentOrigin( ParentOrigin::TOP_RIGHT );
-  newChild.SetAnchorPoint( AnchorPoint::CENTER );
-  newChild.SetPosition( Vector3( 0.0f, 0.0f, 0.0f ) );
-  newChild.SetSize( 1.0f, 1.0f, 1.0f );
-  newChild.SetSizeMode( USE_OWN_SIZE );
-  newParent.Add( newChild );
-
-  // Set up the rotation by 90 degrees on Z.
-  newParent.RotateBy( Radian( M_PI * 0.5f ), Vector3::ZAXIS );
-
-  application.SendNotification();
-  application.Render();
-  DALI_TEST_EQUALS( newParent.GetCurrentSize(), Vector3( 5.0f, 5.0f, 5.0f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-  DALI_TEST_EQUALS( newParent.GetCurrentWorldPosition(), Vector3( 0.0f, 0.0f, 0.0f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-  DALI_TEST_EQUALS( newChild.GetCurrentWorldPosition(), Vector3( 2.5f, 2.5f, 0.0f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-
-  // Test changing the parents size to check the child's size is updated.
-  Actor newParent2 = Actor::New();
-  newParent2.SetParentOrigin( ParentOrigin::CENTER );
-  newParent2.SetAnchorPoint( AnchorPoint::CENTER );
-  newParent2.SetPosition( Vector3( 0.0f, 0.0f, 0.0f ) );
-  newParent2.SetSize( 10.0f, 10.0f, 10.0f );
-  newParent2.SetSizeMode( USE_OWN_SIZE );
-  rootParent.Add( newParent2 );
-
-  Actor newChild2 = Actor::New();
-  newChild2.SetParentOrigin( ParentOrigin::TOP_RIGHT );
-  newChild2.SetAnchorPoint( AnchorPoint::CENTER );
-  newChild2.SetPosition( Vector3( 0.0f, 0.0f, 0.0f ) );
-  newChild2.SetSize( Vector3::ONE );
-  newChild2.SetSizeMode( SIZE_RELATIVE_TO_PARENT );
-  newChild2.SetSizeModeFactor( Vector3( 0.5f, 0.5f, 0.5f ) );
-  newParent2.Add( newChild2 );
-
-  // Check the child has no size yet.
-  DALI_TEST_EQUALS( newChild2.GetCurrentSize(), Vector3::ZERO, TEST_LOCATION );
-
-  // Check the child now has a relative size to the parent.
-  application.SendNotification();
-  application.Render();
-  DALI_TEST_EQUALS( newChild2.GetCurrentSize(), Vector3( 5.0f, 5.0f, 5.0f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-
-  // Change the parent's size and check the child's size changes also.
-  newParent2.SetSize( 100.0f, 100.0f, 100.0f );
-  application.SendNotification();
-  application.Render();
-  DALI_TEST_EQUALS( newChild2.GetCurrentSize(), Vector3( 50.0f, 50.0f, 50.0f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-  // Confirm the child's size is still correct on the next frame.
-  application.Render();
-  DALI_TEST_EQUALS( newChild2.GetCurrentSize(), Vector3( 50.0f, 50.0f, 50.0f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-
-  // Text that reparenting a child causes its size to update relative to its new parent.
-  Actor newParent3 = Actor::New();
-  newParent3.SetParentOrigin( ParentOrigin::CENTER );
-  newParent3.SetAnchorPoint( AnchorPoint::CENTER );
-  newParent3.SetPosition( Vector3( 0.0f, 0.0f, 0.0f ) );
-  newParent3.SetSize( 400.0f, 400.0f, 400.0f );
-  newParent3.SetSizeMode( USE_OWN_SIZE );
-  rootParent.Add( newParent3 );
-
-  // Reparent the child but don't update yet. Check it still has its old size.
-  newParent3.Add( newChild2 );
-  DALI_TEST_EQUALS( newChild2.GetCurrentSize(), Vector3( 50.0f, 50.0f, 50.0f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-
-  // Check the child's size has updated based on the new parent.
-  application.SendNotification();
-  application.Render();
-  DALI_TEST_EQUALS( newChild2.GetCurrentSize(), Vector3( 200.0f, 200.0f, 200.0f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-  // Confirm the child's size is still correct on the next frame.
-  application.Render();
-  DALI_TEST_EQUALS( newChild2.GetCurrentSize(), Vector3( 200.0f, 200.0f, 200.0f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
-
-  // Properties:
-  // Test setting and getting the SizeMode property (by string).
-  Actor propertyActor = Actor::New();
-  propertyActor.SetParentOrigin( ParentOrigin::CENTER );
-  propertyActor.SetAnchorPoint( AnchorPoint::CENTER );
-  propertyActor.SetPosition( Vector3::ZERO );
-  propertyActor.SetSize( Vector3::ONE );
-  propertyActor.SetSizeMode( USE_OWN_SIZE );
-
-  // Loop through each SizeMode enumeration.
-  for( unsigned int propertyIndex = 0; propertyIndex < SIZE_MODE_VALUES_COUNT; ++propertyIndex )
-  {
-    Property::Value inValue = SIZE_MODE_VALUES[ propertyIndex ].string;
-    propertyActor.SetProperty( Actor::Property::SIZE_MODE, inValue );
-    std::string outString = propertyActor.GetProperty( Actor::Property::SIZE_MODE ).Get< std::string >();
-    DALI_TEST_EQUALS( inValue.Get< std::string >(), outString, TEST_LOCATION );
-  }
-
-  // Test setting and getting the SizeModeFactor property.
-  Vector3 testPropertySizeModeFactor( 1.0f, 2.0f, 3.0f );
-  Property::Value inValueFactor = testPropertySizeModeFactor;
-  propertyActor.SetProperty( Actor::Property::SIZE_MODE_FACTOR, inValueFactor );
-  Vector3 outValueFactor = propertyActor.GetProperty( Actor::Property::SIZE_MODE_FACTOR ).Get< Vector3 >();
-  DALI_TEST_EQUALS( testPropertySizeModeFactor, outValueFactor, TEST_LOCATION );
-
-  END_TEST;
-}
-
 // SetOrientation(float angleRadians, Vector3 axis)
 int UtcDaliActorSetOrientation01(void)
 {
@@ -2117,9 +1909,9 @@ int UtcDaliActorApplyConstraintAppliedCallback(void)
   activeConstraint3.AppliedSignal().Connect( TestConstraintCallback3 );
 
   // Check event-side size
-  DALI_TEST_EQUALS( child1.GetSize(), Vector3::ZERO, TEST_LOCATION );
-  DALI_TEST_EQUALS( child2.GetSize(), Vector3::ZERO, TEST_LOCATION );
-  DALI_TEST_EQUALS( child3.GetSize(), Vector3::ZERO, TEST_LOCATION );
+  DALI_TEST_EQUALS( child1.GetTargetSize(), Vector3::ZERO, TEST_LOCATION );
+  DALI_TEST_EQUALS( child2.GetTargetSize(), Vector3::ZERO, TEST_LOCATION );
+  DALI_TEST_EQUALS( child3.GetTargetSize(), Vector3::ZERO, TEST_LOCATION );
 
   DALI_TEST_EQUALS( child1.GetCurrentSize(), Vector3::ZERO, TEST_LOCATION );
   DALI_TEST_EQUALS( child2.GetCurrentSize(), Vector3::ZERO, TEST_LOCATION );
@@ -2841,8 +2633,10 @@ int UtcDaliActorSetDrawModeOverlayHitTest(void)
   Stage::GetCurrent().Add(a);
   Stage::GetCurrent().Add(b);
 
-  a.SetSize(Vector2(100.0f, 100.0f));
-  b.SetSize(Vector2(100.0f, 100.0f));
+  a.SetResizePolicy( FIXED, ALL_DIMENSIONS );
+  a.SetPreferredSize(Vector2(100.0f, 100.0f));
+  b.SetResizePolicy( FIXED, ALL_DIMENSIONS );
+  b.SetPreferredSize(Vector2(100.0f, 100.0f));
 
   // position b overlapping a. (regular non-overlays)
   // hit test at point 'x'
@@ -3159,6 +2953,16 @@ const PropertyStringIndex PROPERTY_TABLE[] =
   { "draw-mode",                Actor::Property::DRAW_MODE,                Property::STRING      },
   { "size-mode",                Actor::Property::SIZE_MODE,                Property::STRING      },
   { "size-mode-factor",         Actor::Property::SIZE_MODE_FACTOR,         Property::VECTOR3     },
+  { "relayout-enabled",         Actor::Property::RELAYOUT_ENABLED,         Property::BOOLEAN     },
+  { "width-resize-policy",      Actor::Property::WIDTH_RESIZE_POLICY,      Property::STRING      },
+  { "height-resize-policy",     Actor::Property::HEIGHT_RESIZE_POLICY,     Property::STRING      },
+  { "size-scale-policy",        Actor::Property::SIZE_SCALE_POLICY,        Property::STRING      },
+  { "width-for-height",         Actor::Property::WIDTH_FOR_HEIGHT,         Property::BOOLEAN     },
+  { "height-for-width",         Actor::Property::HEIGHT_FOR_WIDTH,         Property::BOOLEAN     },
+  { "padding",                  Actor::Property::PADDING,                  Property::VECTOR4     },
+  { "minimum-size",             Actor::Property::MINIMUM_SIZE,             Property::VECTOR2     },
+  { "maximum-size",             Actor::Property::MAXIMUM_SIZE,             Property::VECTOR2     },
+  { "preferred-size",           Actor::Property::PREFERRED_SIZE,           Property::VECTOR2     },
 };
 const unsigned int PROPERTY_TABLE_COUNT = sizeof( PROPERTY_TABLE ) / sizeof( PROPERTY_TABLE[0] );
 } // unnamed namespace
@@ -3178,3 +2982,143 @@ int UtcDaliActorProperties(void)
   }
   END_TEST;
 }
+
+int UtcDaliRelayoutProperties_RelayoutEnabled(void)
+{
+  TestApplication app;
+
+  Actor actor = Actor::New();
+
+  // Defaults
+  DALI_TEST_EQUALS( actor.GetProperty( Actor::Property::RELAYOUT_ENABLED ).Get< bool >(), false, TEST_LOCATION );
+
+  // Set relayout disabled
+  actor.SetProperty( Actor::Property::RELAYOUT_ENABLED, false );
+
+  DALI_TEST_EQUALS( actor.GetProperty( Actor::Property::RELAYOUT_ENABLED ).Get< bool >(), false, TEST_LOCATION );
+
+  // Set relayout enabled
+  actor.SetProperty( Actor::Property::RELAYOUT_ENABLED, true );
+
+  DALI_TEST_EQUALS( actor.GetProperty( Actor::Property::RELAYOUT_ENABLED ).Get< bool >(), true, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliRelayoutProperties_ResizePolicies(void)
+{
+  TestApplication app;
+
+  Actor actor = Actor::New();
+
+  // Defaults
+  DALI_TEST_EQUALS( actor.GetProperty( Actor::Property::WIDTH_RESIZE_POLICY ).Get< std::string >(), "FIXED", TEST_LOCATION );
+  DALI_TEST_EQUALS( actor.GetProperty( Actor::Property::HEIGHT_RESIZE_POLICY ).Get< std::string >(), "FIXED", TEST_LOCATION );
+
+  // Set resize policy for all dimensions
+  actor.SetResizePolicy( USE_NATURAL_SIZE, ALL_DIMENSIONS );
+  for( unsigned int i = 0; i < DIMENSION_COUNT; ++i)
+  {
+    DALI_TEST_EQUALS( actor.GetResizePolicy( static_cast< Dimension >( 1 << i ) ), USE_NATURAL_SIZE, TEST_LOCATION );
+  }
+
+  // Set individual dimensions
+  const char* const widthPolicy = "FILL_TO_PARENT";
+  const char* const heightPolicy = "FIXED";
+
+  actor.SetProperty( Actor::Property::WIDTH_RESIZE_POLICY, widthPolicy );
+  actor.SetProperty( Actor::Property::HEIGHT_RESIZE_POLICY, heightPolicy );
+
+  DALI_TEST_EQUALS( actor.GetProperty( Actor::Property::WIDTH_RESIZE_POLICY ).Get< std::string >(), widthPolicy, TEST_LOCATION );
+  DALI_TEST_EQUALS( actor.GetProperty( Actor::Property::HEIGHT_RESIZE_POLICY ).Get< std::string >(), heightPolicy, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliRelayoutProperties_SizeScalePolicy(void)
+{
+  TestApplication app;
+
+  Actor actor = Actor::New();
+
+  // Defaults
+  DALI_TEST_EQUALS( actor.GetProperty( Actor::Property::SIZE_SCALE_POLICY ).Get< std::string >(), "USE_SIZE_SET", TEST_LOCATION );
+
+  // Set
+  const char* const policy1 = "FIT_WITH_ASPECT_RATIO";
+  const char* const policy2 = "FILL_WITH_ASPECT_RATIO";
+
+  actor.SetProperty( Actor::Property::SIZE_SCALE_POLICY, policy1 );
+  DALI_TEST_EQUALS( actor.GetProperty( Actor::Property::SIZE_SCALE_POLICY ).Get< std::string >(), policy1, TEST_LOCATION );
+
+  actor.SetProperty( Actor::Property::SIZE_SCALE_POLICY, policy2 );
+  DALI_TEST_EQUALS( actor.GetProperty( Actor::Property::SIZE_SCALE_POLICY ).Get< std::string >(), policy2, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliRelayoutProperties_DimensionDependency(void)
+{
+  TestApplication app;
+
+  Actor actor = Actor::New();
+
+  // Defaults
+  DALI_TEST_EQUALS( actor.GetProperty( Actor::Property::WIDTH_FOR_HEIGHT ).Get< bool >(), false, TEST_LOCATION );
+  DALI_TEST_EQUALS( actor.GetProperty( Actor::Property::HEIGHT_FOR_WIDTH ).Get< bool >(), false, TEST_LOCATION );
+
+  // Set
+  actor.SetProperty( Actor::Property::WIDTH_FOR_HEIGHT, true );
+  DALI_TEST_EQUALS( actor.GetProperty( Actor::Property::WIDTH_FOR_HEIGHT ).Get< bool >(), true, TEST_LOCATION );
+
+  actor.SetProperty( Actor::Property::HEIGHT_FOR_WIDTH, true );
+  DALI_TEST_EQUALS( actor.GetProperty( Actor::Property::HEIGHT_FOR_WIDTH ).Get< bool >(), true, TEST_LOCATION );
+
+  // Test setting another resize policy
+  actor.SetProperty( Actor::Property::WIDTH_RESIZE_POLICY, "FIXED" );
+  DALI_TEST_EQUALS( actor.GetProperty( Actor::Property::WIDTH_FOR_HEIGHT ).Get< bool >(), false, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliRelayoutProperties_Padding(void)
+{
+  TestApplication app;
+
+  Actor actor = Actor::New();
+
+  // Data
+  Vector4 padding( 1.0f, 2.0f, 3.0f, 4.0f );
+
+  // PADDING
+  actor.SetProperty( Actor::Property::PADDING, padding );
+  Vector4 paddingResult = actor.GetProperty( Actor::Property::PADDING ).Get< Vector4 >();
+
+  DALI_TEST_EQUALS( paddingResult, padding, Math::MACHINE_EPSILON_0, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliRelayoutProperties_MinimumMaximumSize(void)
+{
+  TestApplication app;
+
+  Actor actor = Actor::New();
+
+  // Data
+  Vector2 minSize( 1.0f, 2.0f );
+
+  actor.SetProperty( Actor::Property::MINIMUM_SIZE, minSize );
+  Vector2 resultMin = actor.GetProperty( Actor::Property::MINIMUM_SIZE ).Get< Vector2 >();
+
+  DALI_TEST_EQUALS( resultMin, minSize, Math::MACHINE_EPSILON_0, TEST_LOCATION );
+
+  Vector2 maxSize( 3.0f, 4.0f );
+
+  actor.SetProperty( Actor::Property::MAXIMUM_SIZE, maxSize );
+  Vector2 resultMax = actor.GetProperty( Actor::Property::MAXIMUM_SIZE ).Get< Vector2 >();
+
+  DALI_TEST_EQUALS( resultMax, maxSize, Math::MACHINE_EPSILON_0, TEST_LOCATION );
+
+  END_TEST;
+}
index e313153..7296d7b 100644 (file)
@@ -4643,7 +4643,7 @@ int UtcDaliAnimationAnimateToActorParentOrigin(void)
   catch (Dali::DaliException& e)
   {
     DALI_TEST_PRINT_ASSERT( e );
-    DALI_TEST_ASSERT(e, "IsPropertyAnimatable(index)", TEST_LOCATION);
+    DALI_TEST_ASSERT(e, "IsPropertyAnimatable( index )", TEST_LOCATION);
   }
   END_TEST;
 }
@@ -4670,7 +4670,7 @@ int UtcDaliAnimationAnimateToActorParentOriginX(void)
   catch (Dali::DaliException& e)
   {
     DALI_TEST_PRINT_ASSERT( e );
-    DALI_TEST_ASSERT(e, "IsPropertyAnimatable(index)", TEST_LOCATION);
+    DALI_TEST_ASSERT(e, "IsPropertyAnimatable( index )", TEST_LOCATION);
   }
   END_TEST;
 }
@@ -4697,7 +4697,7 @@ int UtcDaliAnimationAnimateToActorParentOriginY(void)
   catch (Dali::DaliException& e)
   {
     DALI_TEST_PRINT_ASSERT( e );
-    DALI_TEST_ASSERT(e, "IsPropertyAnimatable(index)", TEST_LOCATION);
+    DALI_TEST_ASSERT(e, "IsPropertyAnimatable( index )", TEST_LOCATION);
   }
   END_TEST;
 }
@@ -4724,7 +4724,7 @@ int UtcDaliAnimationAnimateToActorParentOriginZ(void)
   catch (Dali::DaliException& e)
   {
     DALI_TEST_PRINT_ASSERT( e );
-    DALI_TEST_ASSERT(e, "IsPropertyAnimatable(index)", TEST_LOCATION);
+    DALI_TEST_ASSERT(e, "IsPropertyAnimatable( index )", TEST_LOCATION);
   }
   END_TEST;
 }
@@ -4749,7 +4749,7 @@ int UtcDaliAnimationAnimateToActorAnchorPoint(void)
   catch (Dali::DaliException& e)
   {
     DALI_TEST_PRINT_ASSERT( e );
-    DALI_TEST_ASSERT(e, "IsPropertyAnimatable(index)", TEST_LOCATION);
+    DALI_TEST_ASSERT(e, "IsPropertyAnimatable( index )", TEST_LOCATION);
   }
   END_TEST;
 }
@@ -4776,7 +4776,7 @@ int UtcDaliAnimationAnimateToActorAnchorPointX(void)
   catch (Dali::DaliException& e)
   {
     DALI_TEST_PRINT_ASSERT( e );
-    DALI_TEST_ASSERT(e, "IsPropertyAnimatable(index)", TEST_LOCATION);
+    DALI_TEST_ASSERT(e, "IsPropertyAnimatable( index )", TEST_LOCATION);
   }
   END_TEST;
 }
@@ -4803,7 +4803,7 @@ int UtcDaliAnimationAnimateToActorAnchorPointY(void)
   catch (Dali::DaliException& e)
   {
     DALI_TEST_PRINT_ASSERT( e );
-    DALI_TEST_ASSERT(e, "IsPropertyAnimatable(index)", TEST_LOCATION);
+    DALI_TEST_ASSERT(e, "IsPropertyAnimatable( index )", TEST_LOCATION);
   }
   END_TEST;
 }
@@ -4830,7 +4830,7 @@ int UtcDaliAnimationAnimateToActorAnchorPointZ(void)
   catch (Dali::DaliException& e)
   {
     DALI_TEST_PRINT_ASSERT( e );
-    DALI_TEST_ASSERT(e, "IsPropertyAnimatable(index)", TEST_LOCATION);
+    DALI_TEST_ASSERT(e, "IsPropertyAnimatable( index )", TEST_LOCATION);
   }
   END_TEST;
 }
index 4eca0f7..8d08607 100644 (file)
@@ -174,6 +174,42 @@ struct TestCustomActor : public CustomActorImpl
     return Vector3( 0.0f, 0.0f, 0.0f );
   }
 
+  virtual float GetHeightForWidth( float width )
+  {
+    return 0.0f;
+  }
+
+  virtual float GetWidthForHeight( float height )
+  {
+    return 0.0f;
+  }
+
+  virtual void OnRelayout( const Vector2& size, RelayoutContainer& container )
+  {
+  }
+
+  virtual void OnSetResizePolicy( ResizePolicy policy, Dimension dimension )
+  {
+  }
+
+  virtual void OnCalculateRelayoutSize( Dimension dimension )
+  {
+  }
+
+  virtual float CalculateChildSize( const Dali::Actor& child, Dimension dimension )
+  {
+    return 0.0f;
+  }
+
+  virtual void OnLayoutNegotiated( float size, Dimension dimension )
+  {
+  }
+
+  virtual bool RelayoutDependentOnChildren( Dimension dimension = ALL_DIMENSIONS )
+  {
+    return false;
+  }
+
   void SetDaliProperty(std::string s)
   {
     Self().SetProperty(mDaliProperty, s) ;
@@ -472,6 +508,42 @@ public:
   {
     return Vector3( 0.0f, 0.0f, 0.0f );
   }
+
+  virtual float GetHeightForWidth( float width )
+  {
+    return 0.0f;
+  }
+
+  virtual float GetWidthForHeight( float height )
+  {
+    return 0.0f;
+  }
+
+  virtual void OnRelayout( const Vector2& size, RelayoutContainer& container )
+  {
+  }
+
+  virtual void OnSetResizePolicy( ResizePolicy policy, Dimension dimension )
+  {
+  }
+
+  virtual void OnCalculateRelayoutSize( Dimension dimension )
+  {
+  }
+
+  virtual float CalculateChildSize( const Dali::Actor& child, Dimension dimension )
+  {
+    return 0.0f;
+  }
+
+  virtual void OnLayoutNegotiated( float size, Dimension dimension )
+  {
+  }
+
+  virtual bool RelayoutDependentOnChildren( Dimension dimension = ALL_DIMENSIONS )
+  {
+    return false;
+  }
 };
 
 } ; // namespace Impl
@@ -616,6 +688,28 @@ public:
     return Vector3( 0.0f, 0.0f, 0.0f );
   }
 
+  virtual float GetHeightForWidth( float width )
+  {
+    return 0.0f;
+  }
+
+  virtual float GetWidthForHeight( float height )
+  {
+    return 0.0f;
+  }
+
+  virtual void OnRelayout( const Vector2& size, RelayoutContainer& container )
+  {
+  }
+
+  virtual void OnLayoutNegotiated( float size, Dimension dimension )
+  {
+  }
+
+  virtual void OnCalculateRelayoutSize( Dimension dimension )
+  {
+  }
+
 private:
 
   TestCustomActor( Impl::TestCustomActor& impl ) : CustomActor( impl )
index 0e0461f..689286d 100644 (file)
@@ -381,6 +381,7 @@ int UtcDaliHitTestAlgorithmStencil(void)
   Actor stencil = ImageActor::New(Dali::BufferImage::WHITE() );
   stencil.SetAnchorPoint( AnchorPoint::TOP_LEFT );
   stencil.SetParentOrigin( ParentOrigin::TOP_LEFT );
+  stencil.SetRelayoutEnabled( false );
   stencil.SetSize( 50.0f, 50.0f );
   stencil.SetDrawMode( DrawMode::STENCIL );
   stencil.SetName( "stencil" );
@@ -388,6 +389,7 @@ int UtcDaliHitTestAlgorithmStencil(void)
 
   // Create a renderable actor and add that to the layer
   Actor layerHitActor = TextActor::New();
+  layerHitActor.SetRelayoutEnabled( false );
   layerHitActor.SetSize( 100.0f, 100.0f );
   layerHitActor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
   layerHitActor.SetParentOrigin( ParentOrigin::TOP_LEFT );
index efd4e34..4462bd8 100644 (file)
@@ -1001,12 +1001,14 @@ int UtcDaliHoverMultipleRenderableActors(void)
   Vector2 stageSize ( stage.GetSize() );
 
   Actor parent = ImageActor::New();
-  parent.SetSize(100.0f, 100.0f);
+  parent.SetRelayoutEnabled( false );
+  parent.SetSize( 100.0f, 100.0f );
   parent.SetAnchorPoint(AnchorPoint::TOP_LEFT);
   stage.Add(parent);
 
   Actor actor = ImageActor::New();
-  actor.SetSize(100.0f, 100.0f);
+  actor.SetRelayoutEnabled( false );
+  actor.SetSize( 100.0f, 100.0f );
   actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
   parent.Add(actor);
 
index 45a53b5..8c65eee 100644 (file)
@@ -181,6 +181,7 @@ int UtcDaliImageActorSetSize01(void)
 
   BufferImage img = BufferImage::New( 1,1 );
   ImageActor actor = ImageActor::New( img );
+  actor.SetRelayoutEnabled( false );
 
   ShaderEffect effect = ShaderEffect::New( " ", " ", " ", " ", ShaderEffect::HINT_GRID );
   actor.SetShaderEffect( effect );
@@ -209,6 +210,7 @@ int UtcDaliImageActorGetCurrentSize01(void)
   Vector2 initialImageSize(100, 50);
   BufferImage image = BufferImage::New( initialImageSize.width, initialImageSize.height );
   ImageActor actor = ImageActor::New( image );
+  actor.SetRelayoutEnabled( false );
   Stage::GetCurrent().Add(actor);
 
   application.SendNotification();
@@ -256,6 +258,7 @@ int UtcDaliImageActorGetCurrentSize02(void)
 
   Image image = ResourceImage::New("image.jpg");
   ImageActor actor = ImageActor::New( image );
+  actor.SetRelayoutEnabled( false );
   Stage::GetCurrent().Add(actor);
 
   application.SendNotification(); // Flush update messages
@@ -308,6 +311,7 @@ int UtcDaliImageActorGetCurrentSize03(void)
   attrs.SetSize( requestedSize.width, requestedSize.height );
   Image image = ResourceImage::New("image.jpg", attrs);
   ImageActor actor = ImageActor::New( image );
+  actor.SetRelayoutEnabled( false );
   Stage::GetCurrent().Add(actor);
 
   application.SendNotification(); // Flush update messages
@@ -361,6 +365,7 @@ int UtcDaliImageActorGetCurrentSize04(void)
   attrs.SetSize( requestedSize.width, requestedSize.height );
   Image image = ResourceImage::New("image.jpg", attrs);
   ImageActor actor = ImageActor::New( image );
+  actor.SetRelayoutEnabled( false );
   Stage::GetCurrent().Add(actor);
 
   application.SendNotification(); // Flush update messages
@@ -445,6 +450,7 @@ int UtcDaliImageActorGetCurrentSize05(void)
   attrs.SetSize( requestedSize.width, requestedSize.height );
   Image image = ResourceImage::New("image.jpg", attrs);
   ImageActor actor = ImageActor::New( image );
+  actor.SetRelayoutEnabled( false );
   Stage::GetCurrent().Add(actor);
 
   application.SendNotification(); // Flush update messages
@@ -524,6 +530,7 @@ int UtcDaliImageActorNaturalPixelAreaSize01(void)
   attrs.SetSize( requestedSize.width, requestedSize.height );
   Image image = ResourceImage::New("image.jpg", attrs);
   ImageActor actor = ImageActor::New( image );
+  actor.SetRelayoutEnabled( false );
   Stage::GetCurrent().Add(actor);
 
   application.SendNotification(); // Flush update messages
@@ -587,6 +594,7 @@ int UtcDaliImageActorNaturalPixelAreaSize02(void)
   attrs.SetSize( requestedSize.width, requestedSize.height );
   Image image = ResourceImage::New("image.jpg", attrs);
   ImageActor actor = ImageActor::New( image );
+  actor.SetRelayoutEnabled( false );
   Stage::GetCurrent().Add(actor);
 
   application.SendNotification(); // Flush update messages
index 0bfc035..81845ec 100644 (file)
@@ -138,7 +138,8 @@ ImageActor CreateLoadingImage(TestApplication& application, std::string filename
   application.Render(16);
   DALI_TEST_CHECK( application.GetPlatform().WasCalled(TestPlatformAbstraction::LoadResourceFunc) );
   ImageActor actor = ImageActor::New(image);
-  actor.SetSize( 80, 80 );
+  actor.SetPreferredSize( Vector2( 80, 80 ) );
+  actor.SetResizePolicy( FIXED, ALL_DIMENSIONS );
   application.SendNotification();
   application.Render(16);
   return actor;
index 9c72554..26496bc 100644 (file)
@@ -1001,11 +1001,13 @@ int UtcDaliTouchMultipleRenderableActors(void)
   Vector2 stageSize ( stage.GetSize() );
 
   Actor parent = ImageActor::New();
+  parent.SetRelayoutEnabled( false );
   parent.SetSize(100.0f, 100.0f);
   parent.SetAnchorPoint(AnchorPoint::TOP_LEFT);
   stage.Add(parent);
 
   Actor actor = ImageActor::New();
+  actor.SetRelayoutEnabled( false );
   actor.SetSize(100.0f, 100.0f);
   actor.SetAnchorPoint(AnchorPoint::TOP_LEFT);
   parent.Add(actor);
index 8120663..5f696de 100644 (file)
@@ -247,6 +247,42 @@ struct MyTestCustomActor : public CustomActorImpl
     return Vector3( 0.0f, 0.0f, 0.0f );
   }
 
+  virtual float GetHeightForWidth( float width )
+  {
+    return 0.0f;
+  }
+
+  virtual float GetWidthForHeight( float height )
+  {
+    return 0.0f;
+  }
+
+  virtual void OnRelayout( const Vector2& size, RelayoutContainer& container )
+  {
+  }
+
+  virtual void OnSetResizePolicy( ResizePolicy policy, Dimension dimension )
+  {
+  }
+
+  virtual void OnCalculateRelayoutSize( Dimension dimension )
+  {
+  }
+
+  virtual float CalculateChildSize( const Dali::Actor& child, Dimension dimension )
+  {
+    return 0.0f;
+  }
+
+  virtual void OnLayoutNegotiated( float size, Dimension dimension )
+  {
+  }
+
+  virtual bool RelayoutDependentOnChildren( Dimension dimension = ALL_DIMENSIONS )
+  {
+    return false;
+  }
+
 public:
 
   SignalType mSignal;
index 880e60d..17be9ca 100644 (file)
@@ -97,6 +97,7 @@ publicapishadereffectsdir = $(publicapidir)/shader-effects
 publicapisignalsdir = $(publicapidir)/signals
 publicapitextdir = $(publicapidir)/text
 publicapiscriptingdir = $(publicapidir)/scripting
+publicapisizenegotiationdir = $(publicapidir)/size-negotiation
 
 publicapi_HEADERS = $(public_api_header_files)
 publicapiactors_HEADERS = $(public_api_core_actors_header_files)
@@ -111,6 +112,7 @@ publicapimodeling_HEADERS = $(public_api_core_modeling_header_files)
 publicapirendertasks_HEADERS = $(public_api_core_render_tasks_header_files)
 publicapiobject_HEADERS = $(public_api_core_object_header_files)
 publicapiscripting_HEADERS = $(public_api_core_scripting_header_files)
+publicapisizenegotiation_HEADERS = $(public_api_core_size_negotiation_header_files)
 publicapishadereffects_HEADERS = $(public_api_core_shader_effects_header_files)
 publicapisignals_HEADERS = $(public_api_core_signals_header_files)
 publicapitext_HEADERS = $(public_api_core_text_header_files)
index 6a13411..982f7d3 100644 (file)
@@ -46,6 +46,7 @@
 #include <dali/internal/update/touch/touch-resampler.h>
 #include <dali/internal/event/common/type-registry-impl.h>
 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
+#include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
 
 #include <dali/internal/render/gl-resources/texture-cache.h>
 #include <dali/internal/render/gl-resources/context.h>
@@ -152,6 +153,10 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform,
                                       *mTouchResampler );
 
   mStage = IntrusivePtr<Stage>( Stage::New( *mAnimationPlaylist, *mPropertyNotificationManager, *mUpdateManager, *mNotificationManager ) );
+
+  // This must be called after stage is created but before stage initialization
+  mRelayoutController = IntrusivePtr< RelayoutController >( new RelayoutController() );
+
   mStage->Initialize();
 
   mResourceClient = new ResourceClient( *mResourceManager, *mStage, dataRetentionPolicy );
@@ -185,6 +190,9 @@ Core::~Core()
   // Do this before mStage.Reset() so Stage::IsInstalled() returns false
   ThreadLocalStorage::Get().Remove();
 
+  // Stop relayout requests being raised on stage destruction
+  mRelayoutController.Reset();
+
   // Clean-up stage - remove default camera and root layer
   mStage->Uninitialize();
 
@@ -295,6 +303,8 @@ void Core::Resume()
 void Core::SceneCreated()
 {
   mStage->EmitSceneCreatedSignal();
+
+  mRelayoutController->OnApplicationSceneCreated();
 }
 
 void Core::QueueEvent( const Integration::Event& event )
@@ -327,6 +337,9 @@ void Core::ProcessEvents()
     // Emit signal here to start size negotiation and control relayout.
     mStage->EmitEventProcessingFinishedSignal();
 
+    // Run the size negotiation after event processing finished signal
+    mRelayoutController->Relayout();
+
     // Flush discard queue for image factory
     mImageFactory->FlushReleaseQueue();
 
@@ -446,6 +459,11 @@ EmojiFactory& Core::GetEmojiFactory()
   return *mEmojiFactory;
 }
 
+RelayoutController& Core::GetRelayoutController()
+{
+  return *(mRelayoutController.Get());
+}
+
 void Core::CreateThreadLocalStorage()
 {
   // a pointer to the ThreadLocalStorage object will be stored in TLS
index 071282a..353f50e 100644 (file)
@@ -61,6 +61,7 @@ class ImageFactory;
 class ShaderFactory;
 class TouchResampler;
 class EmojiFactory;
+class RelayoutController;
 
 namespace SceneGraph
 {
@@ -272,6 +273,12 @@ private:  // for use by ThreadLocalStorage
    */
   EmojiFactory& GetEmojiFactory();
 
+  /**
+   * Return the relayout controller
+   * @Return Return a reference to the relayout controller
+   */
+  RelayoutController& GetRelayoutController();
+
 private:
 
   /**
@@ -307,6 +314,7 @@ private:
   ResourceManager*                          mResourceManager;             ///< Asynchronous Resource Loading
   TouchResampler*                           mTouchResampler;              ///< Resamples touches to correct frame rate.
   EmojiFactory*                             mEmojiFactory;                ///< Emoji resource factory.
+  IntrusivePtr< RelayoutController >        mRelayoutController;          ///< Size negotiation relayout controller
 
   bool                                      mIsActive         : 1;        ///< Whether Core is active or suspended
   bool                                      mProcessingEvent  : 1;        ///< True during ProcessEvents()
index e5b33ce..6a1efd9 100644 (file)
@@ -21,6 +21,7 @@
 // EXTERNAL INCLUDES
 #include <cmath>
 #include <algorithm>
+#include <cfloat>
 
 // INTERNAL INCLUDES
 
@@ -42,6 +43,7 @@
 #include <dali/internal/event/actor-attachments/actor-attachment-impl.h>
 #include <dali/internal/event/animation/constraint-impl.h>
 #include <dali/internal/event/common/projection.h>
+#include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
 #include <dali/internal/update/common/animatable-property.h>
 #include <dali/internal/update/nodes/node-messages.h>
 #include <dali/internal/update/nodes/node-declarations.h>
@@ -70,6 +72,53 @@ namespace Internal
 unsigned int Actor::mActorCounter = 0;
 ActorContainer Actor::mNullChildren;
 
+/**
+ * Struct to collect relayout variables
+ */
+struct Actor::RelayoutData
+{
+  RelayoutData()
+      : sizeModeFactor( Vector3::ONE ), preferredSize( Vector2::ZERO ), sizeSetPolicy( USE_SIZE_SET ), sizeMode( USE_OWN_SIZE ), relayoutEnabled( false ), insideRelayout( false )
+  {
+    // Set size negotiation defaults
+    for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+    {
+      resizePolicies[ i ] = FIXED;
+      negotiatedDimensions[ i ] = 0.0f;
+      dimensionNegotiated[ i ] = false;
+      dimensionDirty[ i ] = false;
+      dimensionDependencies[ i ] = ALL_DIMENSIONS;
+      dimensionPadding[ i ] = Vector2( 0.0f, 0.0f );
+      minimumSize[ i ] = 0.0f;
+      maximumSize[ i ] = FLT_MAX;
+    }
+  }
+
+  ResizePolicy resizePolicies[ DIMENSION_COUNT ];      ///< Resize policies
+
+  Dimension dimensionDependencies[ DIMENSION_COUNT ];  ///< A list of dimension dependencies
+
+  Vector2 dimensionPadding[ DIMENSION_COUNT ];         ///< Padding for each dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
+
+  float negotiatedDimensions[ DIMENSION_COUNT ];       ///< Storage for when a dimension is negotiated but before set on actor
+
+  float minimumSize[ DIMENSION_COUNT ];                ///< The minimum size an actor can be
+  float maximumSize[ DIMENSION_COUNT ];                ///< The maximum size an actor can be
+
+  bool dimensionNegotiated[ DIMENSION_COUNT ];         ///< Has the dimension been negotiated
+  bool dimensionDirty[ 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 sizeSetPolicy :3;            ///< Policy to apply when setting size. Enough room for the enum
+  SizeMode sizeMode :2;                        ///< Determines how the actors parent affects the actors size
+
+  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
+};
+
 #ifdef DYNAMICS_SUPPORT
 
 // Encapsulate actor related dynamics data
@@ -81,10 +130,10 @@ struct DynamicsData
   }
 
   typedef std::map<Actor*, DynamicsJointPtr> JointContainer;
-  typedef std::vector<DynamicsJointPtr>      ReferencedJointContainer;
+  typedef std::vector<DynamicsJointPtr> ReferencedJointContainer;
 
-  DynamicsBodyPtr          body;
-  JointContainer           joints;
+  DynamicsBodyPtr body;
+  JointContainer joints;
   ReferencedJointContainer referencedJoints;
 
   SlotDelegate< Actor > slotDelegate;
@@ -103,51 +152,61 @@ namespace // unnamed namespace
  *              Name                   Type   writable animatable constraint-input  enum for index-checking
  */
 DALI_PROPERTY_TABLE_BEGIN
-DALI_PROPERTY( "parent-origin",        VECTOR3,  true,    false,   true,   Dali::Actor::Property::PARENT_ORIGIN        )
-DALI_PROPERTY( "parent-origin-x",      FLOAT,    true,    false,   true,   Dali::Actor::Property::PARENT_ORIGIN_X      )
-DALI_PROPERTY( "parent-origin-y",      FLOAT,    true,    false,   true,   Dali::Actor::Property::PARENT_ORIGIN_Y      )
-DALI_PROPERTY( "parent-origin-z",      FLOAT,    true,    false,   true,   Dali::Actor::Property::PARENT_ORIGIN_Z      )
-DALI_PROPERTY( "anchor-point",         VECTOR3,  true,    false,   true,   Dali::Actor::Property::ANCHOR_POINT         )
-DALI_PROPERTY( "anchor-point-x",       FLOAT,    true,    false,   true,   Dali::Actor::Property::ANCHOR_POINT_X       )
-DALI_PROPERTY( "anchor-point-y",       FLOAT,    true,    false,   true,   Dali::Actor::Property::ANCHOR_POINT_Y       )
-DALI_PROPERTY( "anchor-point-z",       FLOAT,    true,    false,   true,   Dali::Actor::Property::ANCHOR_POINT_Z       )
-DALI_PROPERTY( "size",                 VECTOR3,  true,    true,    true,   Dali::Actor::Property::SIZE                 )
-DALI_PROPERTY( "size-width",           FLOAT,    true,    true,    true,   Dali::Actor::Property::SIZE_WIDTH           )
-DALI_PROPERTY( "size-height",          FLOAT,    true,    true,    true,   Dali::Actor::Property::SIZE_HEIGHT          )
-DALI_PROPERTY( "size-depth",           FLOAT,    true,    true,    true,   Dali::Actor::Property::SIZE_DEPTH           )
-DALI_PROPERTY( "position",             VECTOR3,  true,    true,    true,   Dali::Actor::Property::POSITION             )
-DALI_PROPERTY( "position-x",           FLOAT,    true,    true,    true,   Dali::Actor::Property::POSITION_X           )
-DALI_PROPERTY( "position-y",           FLOAT,    true,    true,    true,   Dali::Actor::Property::POSITION_Y           )
-DALI_PROPERTY( "position-z",           FLOAT,    true,    true,    true,   Dali::Actor::Property::POSITION_Z           )
-DALI_PROPERTY( "world-position",       VECTOR3,  false,   false,   true,   Dali::Actor::Property::WORLD_POSITION       )
-DALI_PROPERTY( "world-position-x",     FLOAT,    false,   false,   true,   Dali::Actor::Property::WORLD_POSITION_X     )
-DALI_PROPERTY( "world-position-y",     FLOAT,    false,   false,   true,   Dali::Actor::Property::WORLD_POSITION_Y     )
-DALI_PROPERTY( "world-position-z",     FLOAT,    false,   false,   true,   Dali::Actor::Property::WORLD_POSITION_Z     )
-DALI_PROPERTY( "orientation",          ROTATION, true,    true,    true,   Dali::Actor::Property::ORIENTATION          )
-DALI_PROPERTY( "world-orientation",    ROTATION, false,   false,   true,   Dali::Actor::Property::WORLD_ORIENTATION    )
-DALI_PROPERTY( "scale",                VECTOR3,  true,    true,    true,   Dali::Actor::Property::SCALE                )
-DALI_PROPERTY( "scale-x",              FLOAT,    true,    true,    true,   Dali::Actor::Property::SCALE_X              )
-DALI_PROPERTY( "scale-y",              FLOAT,    true,    true,    true,   Dali::Actor::Property::SCALE_Y              )
-DALI_PROPERTY( "scale-z",              FLOAT,    true,    true,    true,   Dali::Actor::Property::SCALE_Z              )
-DALI_PROPERTY( "world-scale",          VECTOR3,  false,   false,   true,   Dali::Actor::Property::WORLD_SCALE          )
-DALI_PROPERTY( "visible",              BOOLEAN,  true,    true,    true,   Dali::Actor::Property::VISIBLE              )
-DALI_PROPERTY( "color",                VECTOR4,  true,    true,    true,   Dali::Actor::Property::COLOR                )
-DALI_PROPERTY( "color-red",            FLOAT,    true,    true,    true,   Dali::Actor::Property::COLOR_RED            )
-DALI_PROPERTY( "color-green",          FLOAT,    true,    true,    true,   Dali::Actor::Property::COLOR_GREEN          )
-DALI_PROPERTY( "color-blue",           FLOAT,    true,    true,    true,   Dali::Actor::Property::COLOR_BLUE           )
-DALI_PROPERTY( "color-alpha",          FLOAT,    true,    true,    true,   Dali::Actor::Property::COLOR_ALPHA          )
-DALI_PROPERTY( "world-color",          VECTOR4,  false,   false,   true,   Dali::Actor::Property::WORLD_COLOR          )
-DALI_PROPERTY( "world-matrix",         MATRIX,   false,   false,   true,   Dali::Actor::Property::WORLD_MATRIX         )
-DALI_PROPERTY( "name",                 STRING,   true,    false,   false,  Dali::Actor::Property::NAME                 )
-DALI_PROPERTY( "sensitive",            BOOLEAN,  true,    false,   false,  Dali::Actor::Property::SENSITIVE            )
-DALI_PROPERTY( "leave-required",       BOOLEAN,  true,    false,   false,  Dali::Actor::Property::LEAVE_REQUIRED       )
-DALI_PROPERTY( "inherit-orientation",  BOOLEAN,  true,    false,   false,  Dali::Actor::Property::INHERIT_ORIENTATION  )
-DALI_PROPERTY( "inherit-scale",        BOOLEAN,  true,    false,   false,  Dali::Actor::Property::INHERIT_SCALE        )
-DALI_PROPERTY( "color-mode",           STRING,   true,    false,   false,  Dali::Actor::Property::COLOR_MODE           )
-DALI_PROPERTY( "position-inheritance", STRING,   true,    false,   false,  Dali::Actor::Property::POSITION_INHERITANCE )
-DALI_PROPERTY( "draw-mode",            STRING,   true,    false,   false,  Dali::Actor::Property::DRAW_MODE            )
-DALI_PROPERTY( "size-mode",            STRING,   true,    false,   false,  Dali::Actor::Property::SIZE_MODE            )
-DALI_PROPERTY( "size-mode-factor",     VECTOR3,  true,    false,   false,  Dali::Actor::Property::SIZE_MODE_FACTOR     )
+DALI_PROPERTY( "parent-origin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN )
+DALI_PROPERTY( "parent-origin-x", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X )
+DALI_PROPERTY( "parent-origin-y", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y )
+DALI_PROPERTY( "parent-origin-z", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z )
+DALI_PROPERTY( "anchor-point", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT )
+DALI_PROPERTY( "anchor-point-x", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X )
+DALI_PROPERTY( "anchor-point-y", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y )
+DALI_PROPERTY( "anchor-point-z", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z )
+DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE )
+DALI_PROPERTY( "size-width", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH )
+DALI_PROPERTY( "size-height", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT )
+DALI_PROPERTY( "size-depth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH )
+DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION )
+DALI_PROPERTY( "position-x", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X )
+DALI_PROPERTY( "position-y", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y )
+DALI_PROPERTY( "position-z", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z )
+DALI_PROPERTY( "world-position", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION )
+DALI_PROPERTY( "world-position-x", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X )
+DALI_PROPERTY( "world-position-y", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y )
+DALI_PROPERTY( "world-position-z", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z )
+DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION )
+DALI_PROPERTY( "world-orientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION )
+DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE )
+DALI_PROPERTY( "scale-x", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X )
+DALI_PROPERTY( "scale-y", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y )
+DALI_PROPERTY( "scale-z", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z )
+DALI_PROPERTY( "world-scale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE )
+DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE )
+DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR )
+DALI_PROPERTY( "color-red", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED )
+DALI_PROPERTY( "color-green", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN )
+DALI_PROPERTY( "color-blue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE )
+DALI_PROPERTY( "color-alpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA )
+DALI_PROPERTY( "world-color", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR )
+DALI_PROPERTY( "world-matrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX )
+DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME )
+DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE )
+DALI_PROPERTY( "leave-required", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED )
+DALI_PROPERTY( "inherit-orientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION )
+DALI_PROPERTY( "inherit-scale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE )
+DALI_PROPERTY( "color-mode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE )
+DALI_PROPERTY( "position-inheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE )
+DALI_PROPERTY( "draw-mode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE )
+DALI_PROPERTY( "size-mode", STRING, true, false, false, Dali::Actor::Property::SIZE_MODE )
+DALI_PROPERTY( "size-mode-factor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR )
+DALI_PROPERTY( "relayout-enabled", BOOLEAN, true, false, false, Dali::Actor::Property::RELAYOUT_ENABLED )
+DALI_PROPERTY( "width-resize-policy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY )
+DALI_PROPERTY( "height-resize-policy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY )
+DALI_PROPERTY( "size-scale-policy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY )
+DALI_PROPERTY( "width-for-height", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT )
+DALI_PROPERTY( "height-for-width", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH )
+DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING )
+DALI_PROPERTY( "minimum-size", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE )
+DALI_PROPERTY( "maximum-size", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE )
+DALI_PROPERTY( "preferred-size", VECTOR2, true, false, false, Dali::Actor::Property::PREFERRED_SIZE )
 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
 
 // Signals
@@ -165,28 +224,81 @@ const char* const ACTION_HIDE = "hide";
 
 // Enumeration to / from string conversion tables
 
-DALI_ENUM_TO_STRING_TABLE_BEGIN( SizeMode )
-DALI_ENUM_TO_STRING( USE_OWN_SIZE )
-DALI_ENUM_TO_STRING( SIZE_EQUAL_TO_PARENT )
+DALI_ENUM_TO_STRING_TABLE_BEGIN( SizeMode )DALI_ENUM_TO_STRING( USE_OWN_SIZE )
 DALI_ENUM_TO_STRING( SIZE_RELATIVE_TO_PARENT )
 DALI_ENUM_TO_STRING( SIZE_FIXED_OFFSET_FROM_PARENT )
 DALI_ENUM_TO_STRING_TABLE_END( SizeMode )
 
+DALI_ENUM_TO_STRING_TABLE_BEGIN( ResizePolicy )DALI_ENUM_TO_STRING( FIXED )
+DALI_ENUM_TO_STRING( USE_NATURAL_SIZE )
+DALI_ENUM_TO_STRING( USE_ASSIGNED_SIZE )
+DALI_ENUM_TO_STRING( FILL_TO_PARENT )
+DALI_ENUM_TO_STRING( FIT_TO_CHILDREN )
+DALI_ENUM_TO_STRING( DIMENSION_DEPENDENCY )
+DALI_ENUM_TO_STRING_TABLE_END( ResizePolicy )
+
+DALI_ENUM_TO_STRING_TABLE_BEGIN( SizeScalePolicy )DALI_ENUM_TO_STRING( USE_SIZE_SET )
+DALI_ENUM_TO_STRING( FIT_WITH_ASPECT_RATIO )
+DALI_ENUM_TO_STRING( FILL_WITH_ASPECT_RATIO )
+DALI_ENUM_TO_STRING_TABLE_END( SizeScalePolicy )
+
 BaseHandle CreateActor()
 {
   return Dali::Actor::New();
 }
 
-TypeRegistration mType( typeid( Dali::Actor ), typeid( Dali::Handle ), CreateActor );
+TypeRegistration mType( typeid(Dali::Actor), typeid(Dali::Handle), CreateActor );
 
-SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED,    &Actor::DoConnectSignal );
-SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED,    &Actor::DoConnectSignal );
-SignalConnectorType signalConnector3( mType, SIGNAL_ON_STAGE,   &Actor::DoConnectSignal );
-SignalConnectorType signalConnector4( mType, SIGNAL_OFF_STAGE,  &Actor::DoConnectSignal );
+SignalConnectorType signalConnector1( mType, SIGNAL_TOUCHED, &Actor::DoConnectSignal );
+SignalConnectorType signalConnector2( mType, SIGNAL_HOVERED, &Actor::DoConnectSignal );
+SignalConnectorType signalConnector3( mType, SIGNAL_ON_STAGE, &Actor::DoConnectSignal );
+SignalConnectorType signalConnector4( mType, SIGNAL_OFF_STAGE, &Actor::DoConnectSignal );
 
 TypeAction a1( mType, ACTION_SHOW, &Actor::DoAction );
 TypeAction a2( mType, ACTION_HIDE, &Actor::DoAction );
 
+/**
+ * @brief Extract a given dimension from a Vector2
+ *
+ * @param[in] values The values to extract from
+ * @param[in] dimension The dimension to extract
+ * @return Return the value for the dimension
+ */
+float GetDimensionValue( const Vector2& values, Dimension dimension )
+{
+  switch( dimension )
+  {
+    case WIDTH:
+    {
+      return values.width;
+    }
+
+    case HEIGHT:
+    {
+      return values.height;
+    }
+
+    default:
+    {
+      break;
+    }
+  }
+
+  return 0.0f;
+}
+
+/**
+ * @brief Extract a given dimension from a Vector3
+ *
+ * @param[in] values The values to extract from
+ * @param[in] dimension The dimension to extract
+ * @return Return the value for the dimension
+ */
+float GetDimensionValue( const Vector3& values, Dimension dimension )
+{
+  return GetDimensionValue( values.GetVectorXY(), dimension );
+}
+
 } // unnamed namespace
 
 ActorPtr Actor::New()
@@ -204,7 +316,7 @@ const std::string& Actor::GetName() const
   return mName;
 }
 
-void Actor::SetName(const std::string& name)
+void Actor::SetName( const std::string& name )
 {
   mName = name;
 
@@ -229,7 +341,7 @@ void Actor::Attach( ActorAttachment& attachment )
     attachment.Connect();
   }
 
-  mAttachment = ActorAttachmentPtr(&attachment);
+  mAttachment = ActorAttachmentPtr( &attachment );
 }
 
 ActorAttachmentPtr Actor::GetAttachment()
@@ -253,7 +365,7 @@ Dali::Layer Actor::GetLayer()
   }
 
   // Find the immediate Layer parent
-  for (Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent())
+  for( Actor* parent = mParent; !layer && parent != NULL; parent = parent->GetParent() )
   {
     if( parent->IsLayer() )
     {
@@ -264,7 +376,7 @@ Dali::Layer Actor::GetLayer()
   return layer;
 }
 
-void Actor::Add(Actor& child)
+void Actor::Add( Actor& child )
 {
   DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
   DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
@@ -283,24 +395,41 @@ void Actor::Add(Actor& child)
     if( oldParent )
     {
       oldParent->Remove( child ); // This causes OnChildRemove callback
+
+      // Old parent may need to readjust to missing child
+      if( oldParent->RelayoutDependentOnChildren() )
+      {
+        oldParent->RelayoutRequest();
+      }
     }
 
     // Guard against Add() during previous OnChildRemove callback
-    if ( !child.mParent )
+    if( !child.mParent )
     {
       // Do this first, since user callbacks from within SetParent() may need to remove child
-      mChildren->push_back(Dali::Actor(&child));
+      mChildren->push_back( Dali::Actor( &child ) );
 
       // SetParent asserts that child can be added
-      child.SetParent(this);
+      child.SetParent( this );
 
       // Notification for derived classes
-      OnChildAdd(child);
+      OnChildAdd( child );
+
+      // Only put in a relayout request if there is a suitable dependency
+      if( RelayoutDependentOnChildren() )
+      {
+        RelayoutRequest();
+      }
+
+      if( child.RelayoutDependentOnParent() )
+      {
+        child.RelayoutRequest();
+      }
     }
   }
 }
 
-void Actor::Insert(unsigned int index, Actor& child)
+void Actor::Insert( unsigned int index, Actor& child )
 {
   DALI_ASSERT_ALWAYS( this != &child && "Cannot add actor to itself" );
   DALI_ASSERT_ALWAYS( !child.IsRoot() && "Cannot add root actor" );
@@ -316,31 +445,48 @@ void Actor::Insert(unsigned int index, Actor& child)
   if( oldParent )
   {
     oldParent->Remove( child ); // This causes OnChildRemove callback
+
+    // Old parent may need to readjust to missing child
+    if( oldParent->RelayoutDependentOnChildren() )
+    {
+      oldParent->RelayoutRequest();
+    }
   }
 
   // Guard against Add() during previous OnChildRemove callback
-  if ( !child.mParent )
+  if( !child.mParent )
   {
     // Do this first, since user callbacks from within SetParent() may need to remove child
-    if (index < GetChildCount())
+    if( index < GetChildCount() )
     {
       ActorIter it = mChildren->begin();
-      std::advance(it, index);
-      mChildren->insert(it, Dali::Actor(&child));
+      std::advance( it, index );
+      mChildren->insert( it, Dali::Actor( &child ) );
     }
     else
     {
-      mChildren->push_back(Dali::Actor(&child));
+      mChildren->push_back( Dali::Actor( &child ) );
     }
     // SetParent asserts that child can be added
-    child.SetParent(this, index);
+    child.SetParent( this, index );
 
     // Notification for derived classes
-    OnChildAdd(child);
+    OnChildAdd( child );
+
+    // Only put in a relayout request if there is a suitable dependency
+    if( RelayoutDependentOnChildren() )
+    {
+      RelayoutRequest();
+    }
+
+    if( child.RelayoutDependentOnParent() )
+    {
+      child.RelayoutRequest();
+    }
   }
 }
 
-void Actor::Remove(Actor& child)
+void Actor::Remove( Actor& child )
 {
   DALI_ASSERT_ALWAYS( this != &child && "Cannot remove actor from itself" );
 
@@ -356,7 +502,7 @@ void Actor::Remove(Actor& child)
   ActorIter end = mChildren->end();
   for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
   {
-    Actor& actor = GetImplementation(*iter);
+    Actor& actor = GetImplementation( *iter );
 
     if( &actor == &child )
     {
@@ -364,7 +510,7 @@ void Actor::Remove(Actor& child)
       removed = Dali::Actor( &actor );
 
       // Do this first, since user callbacks from within SetParent() may need to add the child
-      mChildren->erase(iter);
+      mChildren->erase( iter );
 
       DALI_ASSERT_DEBUG( actor.GetParent() == this );
       actor.SetParent( NULL );
@@ -373,10 +519,16 @@ void Actor::Remove(Actor& child)
     }
   }
 
-  if ( removed )
+  if( removed )
   {
     // Notification for derived classes
-    OnChildRemove( GetImplementation(removed) );
+    OnChildRemove( GetImplementation( removed ) );
+
+    // Only put in a relayout request if there is a suitable dependency
+    if( RelayoutDependentOnChildren() )
+    {
+      RelayoutRequest();
+    }
   }
 }
 
@@ -384,7 +536,10 @@ void Actor::Unparent()
 {
   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 is now NULL!
   }
 }
 
@@ -393,11 +548,11 @@ unsigned int Actor::GetChildCount() const
   return ( NULL != mChildren ) ? mChildren->size() : 0;
 }
 
-Dali::Actor Actor::GetChildAt(unsigned int index) const
+Dali::Actor Actor::GetChildAt( unsigned int index ) const
 {
   DALI_ASSERT_ALWAYS( index < GetChildCount() );
 
-  return ( ( mChildren ) ? (*mChildren)[index] : Dali::Actor() );
+  return ( ( mChildren ) ? ( *mChildren )[ index ] : Dali::Actor() );
 }
 
 ActorContainer Actor::GetChildren()
@@ -422,10 +577,10 @@ const ActorContainer& Actor::GetChildren() const
   return mNullChildren;
 }
 
-ActorPtr Actor::FindChildByName(const std::string& actorName)
+ActorPtr Actor::FindChildByName( const std::string& actorName )
 {
-  ActorPtr child=0;
-  if (actorName == mName)
+  ActorPtr child = 0;
+  if( actorName == mName )
   {
     child = this;
   }
@@ -434,9 +589,9 @@ ActorPtr Actor::FindChildByName(const std::string& actorName)
     ActorIter end = mChildren->end();
     for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
     {
-      child = GetImplementation(*iter).FindChildByName(actorName);
+      child = GetImplementation( *iter ).FindChildByName( actorName );
 
-      if (child)
+      if( child )
       {
         break;
       }
@@ -445,10 +600,10 @@ ActorPtr Actor::FindChildByName(const std::string& actorName)
   return child;
 }
 
-ActorPtr Actor::FindChildById(const unsigned int id)
+ActorPtr Actor::FindChildById( const unsigned int id )
 {
   ActorPtr child = 0;
-  if (id == mId)
+  if( id == mId )
   {
     child = this;
   }
@@ -457,9 +612,9 @@ ActorPtr Actor::FindChildById(const unsigned int id)
     ActorIter end = mChildren->end();
     for( ActorIter iter = mChildren->begin(); iter != end; ++iter )
     {
-      child = GetImplementation(*iter).FindChildById(id);
+      child = GetImplementation( *iter ).FindChildById( id );
 
-      if (child)
+      if( child )
       {
         break;
       }
@@ -519,7 +674,7 @@ const Vector3& Actor::GetCurrentParentOrigin() const
   return ( mParentOrigin ) ? *mParentOrigin : ParentOrigin::DEFAULT;
 }
 
-void Actor::SetAnchorPoint(const Vector3& anchor)
+void Actor::SetAnchorPoint( const Vector3& anchor )
 {
   if( NULL != mNode )
   {
@@ -570,17 +725,17 @@ const Vector3& Actor::GetCurrentAnchorPoint() const
   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 )
 {
   if( NULL != mNode )
   {
@@ -589,7 +744,7 @@ void Actor::SetPosition(const Vector3& position)
   }
 }
 
-void Actor::SetX(float x)
+void Actor::SetX( float x )
 {
   if( NULL != mNode )
   {
@@ -598,7 +753,7 @@ void Actor::SetX(float x)
   }
 }
 
-void Actor::SetY(float y)
+void Actor::SetY( float y )
 {
   if( NULL != mNode )
   {
@@ -607,7 +762,7 @@ void Actor::SetY(float y)
   }
 }
 
-void Actor::SetZ(float z)
+void Actor::SetZ( float z )
 {
   if( NULL != mNode )
   {
@@ -616,7 +771,7 @@ void Actor::SetZ(float z)
   }
 }
 
-void Actor::TranslateBy(const Vector3& distance)
+void Actor::TranslateBy( const Vector3& distance )
 {
   if( NULL != mNode )
   {
@@ -664,17 +819,17 @@ PositionInheritanceMode Actor::GetPositionInheritanceMode() const
   return mPositionInheritanceMode;
 }
 
-void Actor::SetOrientation(const Radian& angle, const Vector3& axis)
+void Actor::SetOrientation( const Radian& angle, const Vector3& axis )
 {
-  Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
+  Vector4 normalizedAxis( axis.x, axis.y, axis.z, 0.0f );
   normalizedAxis.Normalize();
 
-  Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
+  Quaternion orientation( Quaternion::FromAxisAngle( normalizedAxis, angle ) );
 
-  SetOrientation(orientation);
+  SetOrientation( orientation );
 }
 
-void Actor::SetOrientation(const Quaternion& orientation)
+void Actor::SetOrientation( const Quaternion& orientation )
 {
   if( NULL != mNode )
   {
@@ -683,7 +838,7 @@ void Actor::SetOrientation(const Quaternion& orientation)
   }
 }
 
-void Actor::RotateBy(const Radian& angle, const Vector3& axis)
+void Actor::RotateBy( const Radian& angle, const Vector3& axis )
 {
   if( NULL != mNode )
   {
@@ -692,7 +847,7 @@ void Actor::RotateBy(const Radian& angle, const Vector3& axis)
   }
 }
 
-void Actor::RotateBy(const Quaternion& relativeRotation)
+void Actor::RotateBy( const Quaternion& relativeRotation )
 {
   if( NULL != mNode )
   {
@@ -723,17 +878,17 @@ const Quaternion& Actor::GetCurrentWorldOrientation() const
   return Quaternion::IDENTITY;
 }
 
-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 )
 {
   if( NULL != mNode )
   {
@@ -769,7 +924,7 @@ void Actor::SetScaleZ( float z )
   }
 }
 
-void Actor::SetInitialVolume(const Vector3& volume)
+void Actor::SetInitialVolume( const Vector3& volume )
 {
   if( NULL != mNode )
   {
@@ -778,7 +933,7 @@ void Actor::SetInitialVolume(const Vector3& volume)
   }
 }
 
-void Actor::SetTransmitGeometryScaling(bool transmitGeometryScaling)
+void Actor::SetTransmitGeometryScaling( bool transmitGeometryScaling )
 {
   if( NULL != mNode )
   {
@@ -798,7 +953,7 @@ bool Actor::GetTransmitGeometryScaling() const
   return false;
 }
 
-void Actor::ScaleBy(const Vector3& relativeScale)
+void Actor::ScaleBy( const Vector3& relativeScale )
 {
   if( NULL != mNode )
   {
@@ -862,7 +1017,7 @@ Matrix Actor::GetCurrentWorldMatrix() const
   return Matrix::IDENTITY;
 }
 
-void Actor::SetVisible(bool visible)
+void Actor::SetVisible( bool visible )
 {
   if( NULL != mNode )
   {
@@ -882,7 +1037,7 @@ bool Actor::IsVisible() const
   return true;
 }
 
-void Actor::SetOpacity(float opacity)
+void Actor::SetOpacity( float opacity )
 {
   if( NULL != mNode )
   {
@@ -912,7 +1067,7 @@ const Vector4& Actor::GetCurrentWorldColor() const
   return Color::WHITE;
 }
 
-void Actor::SetColor(const Vector4& color)
+void Actor::SetColor( const Vector4& color )
 {
   if( NULL != mNode )
   {
@@ -959,7 +1114,7 @@ const Vector4& Actor::GetCurrentColor() const
   return Color::WHITE;
 }
 
-void Actor::SetInheritOrientation(bool inherit)
+void Actor::SetInheritOrientation( bool inherit )
 {
   // non animateable so keep local copy
   mInheritOrientation = inherit;
@@ -975,39 +1130,35 @@ bool Actor::IsOrientationInherited() const
   return mInheritOrientation;
 }
 
-void Actor::SetSizeMode(SizeMode mode)
+void Actor::SetSizeMode( SizeMode mode )
 {
-  // non animateable so keep local copy
-  mSizeMode = mode;
-  if( NULL != mNode )
-  {
-    // mNode is being used in a separate thread; queue a message to set the value
-    SetSizeModeMessage( GetEventThreadServices(), *mNode, mode );
-  }
+  EnsureRelayoutData();
+
+  mRelayoutData->sizeMode = mode;
 }
 
-void Actor::SetSizeModeFactor(const Vector3& factor)
+void Actor::SetSizeModeFactor( const Vector3& factor )
 {
-  // non animateable so keep local copy
-  mSizeModeFactor = factor;
-  if( NULL != mNode )
-  {
-    // mNode is being used in a separate thread; queue a message to set the value
-    SetSizeModeFactorMessage( GetEventThreadServices(), *mNode, factor );
-  }
+  EnsureRelayoutData();
+
+  mRelayoutData->sizeModeFactor = factor;
 }
 
 SizeMode Actor::GetSizeMode() const
 {
-  return mSizeMode;
+  EnsureRelayoutData();
+
+  return mRelayoutData->sizeMode;
 }
 
 const Vector3& Actor::GetSizeModeFactor() const
 {
-  return mSizeModeFactor;
+  EnsureRelayoutData();
+
+  return mRelayoutData->sizeModeFactor;
 }
 
-void Actor::SetColorMode(ColorMode colorMode)
+void Actor::SetColorMode( ColorMode colorMode )
 {
   // non animateable so keep local copy
   mColorMode = colorMode;
@@ -1024,17 +1175,17 @@ ColorMode Actor::GetColorMode() const
   return mColorMode;
 }
 
-void Actor::SetSize(float width, float height)
+void Actor::SetSize( float width, float 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 ) );
 }
 
-void Actor::SetSize(const Vector2& size)
+void Actor::SetSize( const Vector2& size )
 {
   SetSize( Vector3( size.width, size.height, CalculateSizeZ( size ) ) );
 }
@@ -1044,23 +1195,29 @@ float Actor::CalculateSizeZ( const Vector2& size ) const
   return std::min( size.width, size.height );
 }
 
-void Actor::SetSize(const Vector3& size)
+void Actor::SetSize( const Vector3& size )
 {
   if( NULL != mNode )
   {
-    mSize = size;
+    mTargetSize = size;
 
     // mNode is being used in a separate thread; queue a message to set the value & base value
-    SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, mSize );
+    SceneGraph::NodePropertyMessage<Vector3>::Send( GetEventThreadServices(), mNode, &mNode->mSize, &AnimatableProperty<Vector3>::Bake, mTargetSize );
 
     // Notification for derived classes
-    OnSizeSet( mSize );
+    OnSizeSet( mTargetSize );
+
+    // Raise a relayout request if the flag is not locked
+    if( mRelayoutData && !mRelayoutData->insideRelayout )
+    {
+      RelayoutRequest();
+    }
   }
 }
 
-void Actor::NotifySizeAnimation(Animation& animation, const Vector3& targetSize)
+void Actor::NotifySizeAnimation( Animation& animation, const Vector3& targetSize )
 {
-  mSize = targetSize;
+  mTargetSize = targetSize;
 
   // Notify deriving classes
   OnSizeAnimation( animation, targetSize );
@@ -1093,9 +1250,9 @@ void Actor::SetDepth( float depth )
   }
 }
 
-const Vector3& Actor::GetSize() const
+const Vector3& Actor::GetTargetSize() const
 {
-  return mSize;
+  return mTargetSize;
 }
 
 const Vector3& Actor::GetCurrentSize() const
@@ -1115,6 +1272,144 @@ Vector3 Actor::GetNaturalSize() const
   return Vector3( 0.0f, 0.0f, 0.0f );
 }
 
+void Actor::SetResizePolicy( ResizePolicy policy, Dimension dimension )
+{
+  EnsureRelayoutData();
+
+  for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+  {
+    if( dimension & ( 1 << i ) )
+    {
+      mRelayoutData->resizePolicies[ i ] = policy;
+    }
+  }
+
+  OnSetResizePolicy( policy, dimension );
+
+  // Trigger relayout on this control
+  RelayoutRequest();
+}
+
+ResizePolicy Actor::GetResizePolicy( Dimension dimension ) const
+{
+  EnsureRelayoutData();
+
+  // If more than one dimension is requested, just return the first one found
+  for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+  {
+    if( ( dimension & ( 1 << i ) ) )
+    {
+      return mRelayoutData->resizePolicies[ i ];
+    }
+  }
+
+  return FIXED;   // Default
+}
+
+void Actor::SetSizeScalePolicy( SizeScalePolicy policy )
+{
+  EnsureRelayoutData();
+
+  mRelayoutData->sizeSetPolicy = policy;
+}
+
+SizeScalePolicy Actor::GetSizeScalePolicy() const
+{
+  EnsureRelayoutData();
+
+  return mRelayoutData->sizeSetPolicy;
+}
+
+void Actor::SetDimensionDependency( Dimension dimension, Dimension dependency )
+{
+  EnsureRelayoutData();
+
+  for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+  {
+    if( dimension & ( 1 << i ) )
+    {
+      mRelayoutData->dimensionDependencies[ i ] = dependency;
+      mRelayoutData->resizePolicies[ i ] = DIMENSION_DEPENDENCY;
+    }
+  }
+}
+
+Dimension Actor::GetDimensionDependency( Dimension dimension ) const
+{
+  EnsureRelayoutData();
+
+  // If more than one dimension is requested, just return the first one found
+  for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+  {
+    if( ( dimension & ( 1 << i ) ) )
+    {
+      return mRelayoutData->dimensionDependencies[ i ];
+    }
+  }
+
+  return ALL_DIMENSIONS;   // Default
+}
+
+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 )
+  {
+    EnsureRelayoutData();
+
+    mRelayoutData->relayoutEnabled = relayoutEnabled;
+  }
+}
+
+bool Actor::IsRelayoutEnabled() const
+{
+  // Assume that if relayout data has not been allocated yet then
+  // relayout is disabled
+  return mRelayoutData && mRelayoutData->relayoutEnabled;
+}
+
+void Actor::SetLayoutDirty( bool dirty, Dimension dimension )
+{
+  EnsureRelayoutData();
+
+  for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+  {
+    if( dimension & ( 1 << i ) )
+    {
+      mRelayoutData->dimensionDirty[ i ] = dirty;
+    }
+  }
+}
+
+bool Actor::IsLayoutDirty( Dimension dimension ) const
+{
+  EnsureRelayoutData();
+
+  for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+  {
+    if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionDirty[ i ] )
+    {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+bool Actor::RelayoutPossible( Dimension dimension ) const
+{
+  EnsureRelayoutData();
+
+  return mRelayoutData->relayoutEnabled && !IsLayoutDirty( dimension );
+}
+
+bool Actor::RelayoutRequired( Dimension dimension ) const
+{
+  EnsureRelayoutData();
+
+  return mRelayoutData->relayoutEnabled && IsLayoutDirty( dimension );
+}
 
 #ifdef DYNAMICS_SUPPORT
 
@@ -1274,7 +1569,7 @@ DynamicsJointPtr Actor::GetDynamicsJointByIndex( const int index ) const
     {
       DynamicsData::JointContainer::const_iterator it( mDynamicsData->joints.begin() );
 
-      for( int i = 0; i < index; ++i  )
+      for( int i = 0; i < index; ++i )
       {
         ++it;
       }
@@ -1311,7 +1606,7 @@ void Actor::RemoveDynamicsJoint( DynamicsJointPtr joint )
     DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
     DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
 
-    for( ; it != endIt; ++it )
+    for(; it != endIt; ++it )
     {
       if( it->second == joint.Get() )
       {
@@ -1407,7 +1702,7 @@ void Actor::AttachedActorOnStage( Dali::Actor actor )
     DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
     if( NULL != mDynamicsData )
     {
-      DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find(  attachedActor.Get() ) );
+      DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
       if( mDynamicsData->joints.end() != it )
       {
         DynamicsJointPtr joint( it->second );
@@ -1428,7 +1723,7 @@ void Actor::AttachedActorOffStage( Dali::Actor actor )
     DALI_ASSERT_DEBUG( NULL != mDynamicsData && "Dynamics not enabled on this actor!" );
     if( NULL != mDynamicsData )
     {
-      DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find(  attachedActor.Get() ) );
+      DynamicsData::JointContainer::iterator it( mDynamicsData->joints.find( attachedActor.Get() ) );
       if( mDynamicsData->joints.end() != it )
       {
         DynamicsJointPtr joint( it->second );
@@ -1452,7 +1747,7 @@ void Actor::ConnectDynamics()
         DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
         DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
 
-        for( ; it != endIt; ++it )
+        for(; it != endIt; ++it )
         {
           Actor* attachedActor( it->first );
           if( NULL != attachedActor && attachedActor->OnStage() )
@@ -1481,7 +1776,7 @@ void Actor::DisconnectDynamics()
         DynamicsData::JointContainer::iterator it( mDynamicsData->joints.begin() );
         DynamicsData::JointContainer::iterator endIt( mDynamicsData->joints.end() );
 
-        for( ; it != endIt; ++it )
+        for(; it != endIt; ++it )
         {
           DynamicsJointPtr joint( it->second );
 
@@ -1494,7 +1789,7 @@ void Actor::DisconnectDynamics()
 
 #endif // DYNAMICS_SUPPORT
 
-void Actor::SetOverlay(bool enable)
+void Actor::SetOverlay( bool enable )
 {
   // Setting STENCIL will override OVERLAY
   if( DrawMode::STENCIL != mDrawMode )
@@ -1524,13 +1819,10 @@ DrawMode::Type Actor::GetDrawMode() const
   return mDrawMode;
 }
 
-bool Actor::ScreenToLocal( float& localX,
-                           float& localY,
-                           float screenX,
-                           float screenY ) const
+bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const
 {
   // only valid when on-stage
-  if ( OnStage() )
+  if( OnStage() )
   {
     const RenderTaskList& taskList = Stage::GetCurrent()->GetRenderTaskList();
 
@@ -1551,15 +1843,11 @@ bool Actor::ScreenToLocal( float& localX,
   return false;
 }
 
-bool Actor::ScreenToLocal( RenderTask& renderTask,
-                           float& localX,
-                           float& localY,
-                           float screenX,
-                           float screenY ) const
+bool Actor::ScreenToLocal( RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const
 {
   bool retval = false;
   // only valid when on-stage
-  if ( OnStage() )
+  if( OnStage() )
   {
     CameraActor* camera = renderTask.GetCameraActor();
     if( camera )
@@ -1578,13 +1866,7 @@ bool Actor::ScreenToLocal( RenderTask& renderTask,
   return retval;
 }
 
-bool Actor::ScreenToLocal( const Matrix& viewMatrix,
-                           const Matrix& projectionMatrix,
-                           const Viewport& viewport,
-                           float& localX,
-                           float& localY,
-                           float screenX,
-                           float screenY ) const
+bool Actor::ScreenToLocal( const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY ) const
 {
   // Early-out if mNode is NULL
   if( !OnStage() )
@@ -1595,36 +1877,36 @@ bool Actor::ScreenToLocal( const Matrix& viewMatrix,
   BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
 
   // Calculate the ModelView matrix
-  Matrix modelView(false/*don't init*/);
+  Matrix modelView( false/*don't init*/);
   // need to use the components as world matrix is only updated for actors that need it
-  modelView.SetTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldOrientation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
-  Matrix::Multiply(modelView, modelView, viewMatrix);
+  modelView.SetTransformComponents( mNode->GetWorldScale( bufferIndex ), mNode->GetWorldOrientation( bufferIndex ), mNode->GetWorldPosition( bufferIndex ) );
+  Matrix::Multiply( modelView, modelView, viewMatrix );
 
   // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
-  Matrix invertedMvp(false/*don't init*/);
-  Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
+  Matrix invertedMvp( false/*don't init*/);
+  Matrix::Multiply( invertedMvp, modelView, projectionMatrix );
   bool success = invertedMvp.Invert();
 
   // Convert to GL coordinates
-  Vector4 screenPos( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
+  Vector4 screenPos( screenX - viewport.x, viewport.height - ( screenY - viewport.y ), 0.f, 1.f );
 
   Vector4 nearPos;
-  if (success)
+  if( success )
   {
-    success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, nearPos);
+    success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, nearPos );
   }
 
   Vector4 farPos;
-  if (success)
+  if( success )
   {
     screenPos.z = 1.0f;
-    success = Unproject(screenPos, invertedMvp, viewport.width, viewport.height, farPos);
+    success = Unproject( screenPos, invertedMvp, viewport.width, viewport.height, farPos );
   }
 
-  if (success)
+  if( success )
   {
     Vector4 local;
-    if (XyPlaneIntersect(nearPos, farPos, local))
+    if( XyPlaneIntersect( nearPos, farPos, local ) )
     {
       Vector3 size = GetCurrentSize();
       localX = local.x + size.x * 0.5f;
@@ -1642,63 +1924,63 @@ bool Actor::ScreenToLocal( const Matrix& viewMatrix,
 bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) const
 {
   /*
-    http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
+   http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
 
-    Mathematical Formulation
+   Mathematical Formulation
 
-    Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
+   Given the above mentioned sphere, a point 'p' lies on the surface of the sphere if
 
-    ( p - c ) dot ( p - c ) = r^2
+   ( p - c ) dot ( p - c ) = r^2
 
-    Given a ray with a point of origin 'o', and a direction vector 'd':
+   Given a ray with a point of origin 'o', and a direction vector 'd':
 
-    ray(t) = o + td, t >= 0
+   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'
+   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
+   (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
+   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
+   ( d dot d )t^2 + 2( o - c ) dot dt + ( o - c ) dot ( o - c ) - r^2 = 0
 
-    or
+   or
 
-    At2 + Bt + C = 0
+   At2 + Bt + C = 0
 
-    where
+   where
 
-    A = d dot d
-    B = 2( o - c ) dot d
-    C = ( o - c ) dot ( o - c ) - r^2
+   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.
+   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.
+   Note that in the absence of positive, real, roots, the ray does not intersect the sphere.
 
-    Practical Simplification
+   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.
+   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
+   If a sphere is centred at origin, a point 'p' lies on a sphere of radius r2 if
 
-    p dot p = r^2
+   p dot p = r^2
 
-    and we can find the t at which the (transformed) ray intersects the sphere by
+   and we can find the t at which the (transformed) ray intersects the sphere by
 
-    ( o + td ) dot ( o + td ) = r^2
+   ( o + td ) dot ( o + td ) = r^2
 
-    According to the reasoning above, we expand the above quadratic equation into the general form
+   According to the reasoning above, we expand the above quadratic equation into the general form
 
-    At2 + Bt + C = 0
+   At2 + Bt + C = 0
 
-    which now has coefficients:
+   which now has coefficients:
 
-    A = d dot d
-    B = 2( d dot o )
-    C = o dot o - r^2
+   A = d dot d
+   B = 2( d dot o )
+   C = o dot o - r^2
    */
 
   // Early out if mNode is NULL
@@ -1711,9 +1993,7 @@ bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) con
 
   // 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( mNode->GetWorldPosition( bufferIndex ) );
-  Vector3 rayOriginLocal(rayOrigin.x - translation.x,
-                         rayOrigin.y - translation.y,
-                         rayOrigin.z - translation.z);
+  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( mNode->GetSize( bufferIndex ) );
@@ -1730,7 +2010,7 @@ bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) con
   float b2 = rayDir.Dot( rayOriginLocal );                              // b/2
   float c = rayOriginLocal.Dot( rayOriginLocal ) - squareSphereRadius;  // c
 
-  return ( b2*b2 - a*c ) >= 0.f;
+  return ( b2 * b2 - a * c ) >= 0.f;
 }
 
 bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const
@@ -1738,19 +2018,19 @@ bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vecto
   bool hit = false;
 
   if( OnStage() &&
-      NULL != mNode )
+  NULL != mNode )
   {
     BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
 
     // Transforms the ray to the local reference system.
 
     // Calculate the inverse of Model matrix
-    Matrix invModelMatrix(false/*don't init*/);
+    Matrix invModelMatrix( false/*don't init*/);
     // need to use the components as world matrix is only updated for actors that need it
-    invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale(bufferIndex), mNode->GetWorldOrientation(bufferIndex), mNode->GetWorldPosition(bufferIndex) );
+    invModelMatrix.SetInverseTransformComponents( mNode->GetWorldScale( bufferIndex ), mNode->GetWorldOrientation( bufferIndex ), mNode->GetWorldPosition( bufferIndex ) );
 
-    Vector4 rayOriginLocal(invModelMatrix * rayOrigin);
-    Vector4 rayDirLocal(invModelMatrix * rayDir - invModelMatrix.GetTranslation());
+    Vector4 rayOriginLocal( invModelMatrix * rayOrigin );
+    Vector4 rayDirLocal( invModelMatrix * rayDir - invModelMatrix.GetTranslation() );
 
     // Test with the actor's XY plane (Normal = 0 0 1 1).
 
@@ -1775,7 +2055,7 @@ bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vecto
   return hit;
 }
 
-void Actor::SetLeaveRequired(bool required)
+void Actor::SetLeaveRequired( bool required )
 {
   mLeaveRequired = required;
 }
@@ -1812,17 +2092,14 @@ bool Actor::GetMouseWheelEventRequired() const
 
 bool Actor::IsHittable() const
 {
-  return IsSensitive() &&
-         IsVisible() &&
-         ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) &&
-         IsNodeConnected();
+  return IsSensitive() && IsVisible() && ( GetCurrentWorldColor().a > FULLY_TRANSPARENT ) && IsNodeConnected();
 }
 
 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 ( NULL == mGestureData )
+  if( NULL == mGestureData )
   {
     mGestureData = new ActorGestureData;
   }
@@ -1834,17 +2111,17 @@ bool Actor::IsGestureRequred( Gesture::Type type ) const
   return mGestureData && mGestureData->IsGestureRequred( type );
 }
 
-bool Actor::EmitTouchEventSignal(const TouchEvent& event)
+bool Actor::EmitTouchEventSignal( const TouchEvent& event )
 {
   bool consumed = false;
 
-  if ( !mTouchedSignal.Empty() )
+  if( !mTouchedSignal.Empty() )
   {
     Dali::Actor handle( this );
     consumed = mTouchedSignal.Emit( handle, event );
   }
 
-  if (!consumed)
+  if( !consumed )
   {
     // Notification for derived classes
     consumed = OnTouchEvent( event );
@@ -1853,17 +2130,17 @@ bool Actor::EmitTouchEventSignal(const TouchEvent& event)
   return consumed;
 }
 
-bool Actor::EmitHoverEventSignal(const HoverEvent& event)
+bool Actor::EmitHoverEventSignal( const HoverEvent& event )
 {
   bool consumed = false;
 
-  if ( !mHoveredSignal.Empty() )
+  if( !mHoveredSignal.Empty() )
   {
     Dali::Actor handle( this );
     consumed = mHoveredSignal.Emit( handle, event );
   }
 
-  if (!consumed)
+  if( !consumed )
   {
     // Notification for derived classes
     consumed = OnHoverEvent( event );
@@ -1872,20 +2149,20 @@ bool Actor::EmitHoverEventSignal(const HoverEvent& event)
   return consumed;
 }
 
-bool Actor::EmitMouseWheelEventSignal(const MouseWheelEvent& event)
+bool Actor::EmitMouseWheelEventSignal( const MouseWheelEvent& event )
 {
   bool consumed = false;
 
-  if ( !mMouseWheelEventSignal.Empty() )
+  if( !mMouseWheelEventSignal.Empty() )
   {
     Dali::Actor handle( this );
     consumed = mMouseWheelEventSignal.Emit( handle, event );
   }
 
-  if (!consumed)
+  if( !consumed )
   {
     // Notification for derived classes
-    consumed = OnMouseWheelEvent(event);
+    consumed = OnMouseWheelEvent( event );
   }
 
   return consumed;
@@ -1916,10 +2193,15 @@ Dali::Actor::OffStageSignalType& Actor::OffStageSignal()
   return mOffStageSignal;
 }
 
+Dali::Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
+{
+  return mOnRelayoutSignal;
+}
+
 bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
 {
   bool connected( true );
-  Actor* actor = dynamic_cast<Actor*>( object );
+  Actor* actor = dynamic_cast< Actor* >( object );
 
   if( 0 == strcmp( signalName.c_str(), SIGNAL_TOUCHED ) ) // don't want to convert char* to string
   {
@@ -1933,7 +2215,7 @@ bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tra
   {
     actor->MouseWheelEventSignal().Connect( tracker, functor );
   }
-  else if( 0 == strcmp( signalName.c_str(), SIGNAL_ON_STAGE  ) )
+  else if( 0 == strcmp( signalName.c_str(), SIGNAL_ON_STAGE ) )
   {
     actor->OnStageSignal().Connect( tracker, functor );
   }
@@ -1956,33 +2238,12 @@ Actor::Actor( DerivedType derivedType )
   mNode( NULL ),
   mParentOrigin( NULL ),
   mAnchorPoint( NULL ),
+  mRelayoutData( NULL ),
 #ifdef DYNAMICS_SUPPORT
-  mDynamicsData( NULL ),
+        mDynamicsData( NULL ),
 #endif
-  mGestureData( NULL ),
-  mAttachment(),
-  mSize( 0.0f, 0.0f, 0.0f ),
-  mSizeModeFactor( Vector3::ONE ),
-  mName(),
-  mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
-  mIsRoot( ROOT_LAYER == derivedType ),
-  mIsRenderable( RENDERABLE == derivedType ),
-  mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ),
-  mIsOnStage( false ),
-  mIsDynamicsRoot(false),
-  mSensitive( true ),
-  mLeaveRequired( false ),
-  mKeyboardFocusable( false ),
-  mDerivedRequiresTouch( false ),
-  mDerivedRequiresHover( false ),
-  mDerivedRequiresMouseWheelEvent( false ),
-  mOnStageSignalled( false ),
-  mInheritOrientation( true ),
-  mInheritScale( true ),
-  mDrawMode( DrawMode::NORMAL ),
-  mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ),
-  mColorMode( Node::DEFAULT_COLOR_MODE ),
-  mSizeMode( Node::DEFAULT_SIZE_MODE )
+        mGestureData( NULL ), mAttachment(), mTargetSize( 0.0f, 0.0f, 0.0f ), mName(), mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
+        mIsRoot( ROOT_LAYER == derivedType ), mIsRenderable( RENDERABLE == derivedType ), mIsLayer( LAYER == derivedType || ROOT_LAYER == derivedType ), mIsOnStage( false ), mIsDynamicsRoot( false ), mSensitive( true ), mLeaveRequired( false ), mKeyboardFocusable( false ), mDerivedRequiresTouch( false ), mDerivedRequiresHover( false ), mDerivedRequiresMouseWheelEvent( false ), mOnStageSignalled( false ), mInheritOrientation( true ), mInheritScale( true ), mDrawMode( DrawMode::NORMAL ), mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ), mColorMode( Node::DEFAULT_COLOR_MODE )
 {
 }
 
@@ -2037,6 +2298,12 @@ Actor::~Actor()
   // Cleanup optional parent origin and anchor
   delete mParentOrigin;
   delete mAnchorPoint;
+
+  // Delete optional relayout data
+  if( mRelayoutData )
+  {
+    delete mRelayoutData;
+  }
 }
 
 void Actor::ConnectToStage( int index )
@@ -2052,9 +2319,11 @@ void Actor::ConnectToStage( int index )
   const ActorIter endIter = connectionList.end();
   for( ActorIter iter = connectionList.begin(); iter != endIter; ++iter )
   {
-    Actor& actor = GetImplementation(*iter);
+    Actor& actor = GetImplementation( *iter );
     actor.NotifyStageConnection();
   }
+
+  RelayoutRequest();
 }
 
 void Actor::RecursiveConnectToStage( ActorContainer& connectionList, int index )
@@ -2063,13 +2332,13 @@ void Actor::RecursiveConnectToStage( ActorContainer& connectionList, int index )
 
   mIsOnStage = true;
 
-  ConnectToSceneGraph(index);
+  ConnectToSceneGraph( index );
 
   // Notification for internal derived classes
   OnStageConnectionInternal();
 
   // This stage is atomic; avoid emitting callbacks until all Actors are connected
-  connectionList.push_back( Dali::Actor(this) );
+  connectionList.push_back( Dali::Actor( this ) );
 
   // Recursively connect children
   if( mChildren )
@@ -2089,11 +2358,9 @@ void Actor::RecursiveConnectToStage( ActorContainer& connectionList, int index )
  * The child must connect its Node to the parent's Node.
  * This is resursive; the child calls ConnectToStage() for its children.
  */
-void Actor::ConnectToSceneGraph(int index)
+void Actor::ConnectToSceneGraph( int index )
 {
-  DALI_ASSERT_DEBUG( mNode != NULL);
-  DALI_ASSERT_DEBUG( mParent != NULL);
-  DALI_ASSERT_DEBUG( mParent->mNode != NULL );
+  DALI_ASSERT_DEBUG( mNode != NULL); DALI_ASSERT_DEBUG( mParent != NULL); DALI_ASSERT_DEBUG( mParent->mNode != NULL );
 
   if( NULL != mNode )
   {
@@ -2102,7 +2369,7 @@ void Actor::ConnectToSceneGraph(int index)
   }
 
   // Notify attachment
-  if (mAttachment)
+  if( mAttachment )
   {
     mAttachment->Connect();
   }
@@ -2123,19 +2390,19 @@ void Actor::NotifyStageConnection()
 {
   // Actors can be removed (in a callback), before the on-stage stage is reported.
   // The actor may also have been reparented, in which case mOnStageSignalled will be true.
-  if ( OnStage() && !mOnStageSignalled )
+  if( OnStage() && !mOnStageSignalled )
   {
     // Notification for external (CustomActor) derived classes
     OnStageConnectionExternal();
 
-    if ( !mOnStageSignal.Empty() )
+    if( !mOnStageSignal.Empty() )
     {
       Dali::Actor handle( this );
       mOnStageSignal.Emit( handle );
     }
 
     // Guard against Remove during callbacks
-    if ( OnStage()  )
+    if( OnStage() )
     {
       mOnStageSignalled = true; // signal required next time Actor is removed
     }
@@ -2155,7 +2422,7 @@ void Actor::DisconnectFromStage()
   const ActorIter endIter = disconnectionList.end();
   for( ActorIter iter = disconnectionList.begin(); iter != endIter; ++iter )
   {
-    Actor& actor = GetImplementation(*iter);
+    Actor& actor = GetImplementation( *iter );
     actor.NotifyStageDisconnection();
   }
 }
@@ -2176,7 +2443,7 @@ void Actor::RecursiveDisconnectFromStage( ActorContainer& disconnectionList )
   }
 
   // This stage is atomic; avoid emitting callbacks until all Actors are disconnected
-  disconnectionList.push_back( Dali::Actor(this) );
+  disconnectionList.push_back( Dali::Actor( this ) );
 
   // Notification for internal derived classes
   OnStageDisconnectionInternal();
@@ -2196,7 +2463,7 @@ void Actor::DisconnectFromSceneGraph()
   OnSceneObjectRemove();
 
   // Notify attachment
-  if (mAttachment)
+  if( mAttachment )
   {
     mAttachment->Disconnect();
   }
@@ -2227,7 +2494,7 @@ void Actor::NotifyStageDisconnection()
     }
 
     // Guard against Add during callbacks
-    if ( !OnStage()  )
+    if( !OnStage() )
     {
       mOnStageSignalled = false; // signal required next time Actor is added
     }
@@ -2239,7 +2506,7 @@ bool Actor::IsNodeConnected() const
   bool connected( false );
 
   if( OnStage() &&
-      NULL != mNode )
+  NULL != mNode )
   {
     if( mNode->IsRoot() || mNode->GetParent() )
     {
@@ -2259,7 +2526,7 @@ void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
 {
   indices.reserve( DEFAULT_PROPERTY_COUNT );
 
-  for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
+  for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
   {
     indices.push_back( i );
   }
@@ -2269,13 +2536,13 @@ const char* Actor::GetDefaultPropertyName( Property::Index index ) const
 {
   if( index < DEFAULT_PROPERTY_COUNT )
   {
-    return DEFAULT_PROPERTY_DETAILS[index].name;
+    return DEFAULT_PROPERTY_DETAILS[ index ].name;
   }
 
   return NULL;
 }
 
-Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
+Property::Index Actor::GetDefaultPropertyIndex( const std::string& name ) const
 {
   Property::Index index = Property::INVALID_INDEX;
 
@@ -2293,21 +2560,21 @@ Property::Index Actor::GetDefaultPropertyIndex(const std::string& name) const
   return index;
 }
 
-bool Actor::IsDefaultPropertyWritable(Property::Index index) const
+bool Actor::IsDefaultPropertyWritable( Property::Index index ) const
 {
   if( index < DEFAULT_PROPERTY_COUNT )
   {
-    return DEFAULT_PROPERTY_DETAILS[index].writable;
+    return DEFAULT_PROPERTY_DETAILS[ index ].writable;
   }
 
   return false;
 }
 
-bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
+bool Actor::IsDefaultPropertyAnimatable( Property::Index index ) const
 {
   if( index < DEFAULT_PROPERTY_COUNT )
   {
-    return DEFAULT_PROPERTY_DETAILS[index].animatable;
+    return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
   }
 
   return false;
@@ -2317,17 +2584,17 @@ bool Actor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
 {
   if( index < DEFAULT_PROPERTY_COUNT )
   {
-    return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
+    return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
   }
 
   return false;
 }
 
-Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
+Property::Type Actor::GetDefaultPropertyType( Property::Index index ) const
 {
   if( index < DEFAULT_PROPERTY_COUNT )
   {
-    return DEFAULT_PROPERTY_DETAILS[index].type;
+    return DEFAULT_PROPERTY_DETAILS[ index ].type;
   }
 
   // index out of range...return Property::NONE
@@ -2336,227 +2603,300 @@ Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
 
 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
 {
-  switch ( index )
+  switch( index )
   {
     case Dali::Actor::Property::PARENT_ORIGIN:
     {
-      SetParentOrigin( property.Get<Vector3>() );
+      SetParentOrigin( property.Get< Vector3 >() );
       break;
     }
 
     case Dali::Actor::Property::PARENT_ORIGIN_X:
     {
-      SetParentOriginX( property.Get<float>() );
+      SetParentOriginX( property.Get< float >() );
       break;
     }
 
     case Dali::Actor::Property::PARENT_ORIGIN_Y:
     {
-      SetParentOriginY( property.Get<float>() );
+      SetParentOriginY( property.Get< float >() );
       break;
     }
 
     case Dali::Actor::Property::PARENT_ORIGIN_Z:
     {
-      SetParentOriginZ( property.Get<float>() );
+      SetParentOriginZ( property.Get< float >() );
       break;
     }
 
     case Dali::Actor::Property::ANCHOR_POINT:
     {
-      SetAnchorPoint( property.Get<Vector3>() );
+      SetAnchorPoint( property.Get< Vector3 >() );
       break;
     }
 
     case Dali::Actor::Property::ANCHOR_POINT_X:
     {
-      SetAnchorPointX( property.Get<float>() );
+      SetAnchorPointX( property.Get< float >() );
       break;
     }
 
     case Dali::Actor::Property::ANCHOR_POINT_Y:
     {
-      SetAnchorPointY( property.Get<float>() );
+      SetAnchorPointY( property.Get< float >() );
       break;
     }
 
     case Dali::Actor::Property::ANCHOR_POINT_Z:
     {
-      SetAnchorPointZ( property.Get<float>() );
+      SetAnchorPointZ( property.Get< float >() );
       break;
     }
 
     case Dali::Actor::Property::SIZE:
     {
-      SetSize( property.Get<Vector3>() );
+      SetSize( property.Get< Vector3 >() );
       break;
     }
 
     case Dali::Actor::Property::SIZE_WIDTH:
     {
-      SetWidth( property.Get<float>() );
+      SetWidth( property.Get< float >() );
       break;
     }
 
     case Dali::Actor::Property::SIZE_HEIGHT:
     {
-      SetHeight( property.Get<float>() );
+      SetHeight( property.Get< float >() );
       break;
     }
 
     case Dali::Actor::Property::SIZE_DEPTH:
     {
-      SetDepth( property.Get<float>() );
+      SetDepth( property.Get< float >() );
       break;
     }
 
     case Dali::Actor::Property::POSITION:
     {
-      SetPosition( property.Get<Vector3>() );
+      SetPosition( property.Get< Vector3 >() );
       break;
     }
 
     case Dali::Actor::Property::POSITION_X:
     {
-      SetX( property.Get<float>() );
+      SetX( property.Get< float >() );
       break;
     }
 
     case Dali::Actor::Property::POSITION_Y:
     {
-      SetY( property.Get<float>() );
+      SetY( property.Get< float >() );
       break;
     }
 
     case Dali::Actor::Property::POSITION_Z:
     {
-      SetZ( property.Get<float>() );
+      SetZ( property.Get< float >() );
       break;
     }
 
     case Dali::Actor::Property::ORIENTATION:
     {
-      SetOrientation( property.Get<Quaternion>() );
+      SetOrientation( property.Get< Quaternion >() );
       break;
     }
 
     case Dali::Actor::Property::SCALE:
     {
-      SetScale( property.Get<Vector3>() );
+      SetScale( property.Get< Vector3 >() );
       break;
     }
 
     case Dali::Actor::Property::SCALE_X:
     {
-      SetScaleX( property.Get<float>() );
+      SetScaleX( property.Get< float >() );
       break;
     }
 
     case Dali::Actor::Property::SCALE_Y:
     {
-      SetScaleY( property.Get<float>() );
+      SetScaleY( property.Get< float >() );
       break;
     }
 
     case Dali::Actor::Property::SCALE_Z:
     {
-      SetScaleZ( property.Get<float>() );
+      SetScaleZ( property.Get< float >() );
       break;
     }
 
     case Dali::Actor::Property::VISIBLE:
     {
-      SetVisible( property.Get<bool>() );
+      SetVisible( property.Get< bool >() );
       break;
     }
 
     case Dali::Actor::Property::COLOR:
     {
-      SetColor( property.Get<Vector4>() );
+      SetColor( property.Get< Vector4 >() );
       break;
     }
 
     case Dali::Actor::Property::COLOR_RED:
     {
-      SetColorRed( property.Get<float>() );
+      SetColorRed( property.Get< float >() );
       break;
     }
 
     case Dali::Actor::Property::COLOR_GREEN:
     {
-      SetColorGreen( property.Get<float>() );
+      SetColorGreen( property.Get< float >() );
       break;
     }
 
     case Dali::Actor::Property::COLOR_BLUE:
     {
-      SetColorBlue( property.Get<float>() );
+      SetColorBlue( property.Get< float >() );
       break;
     }
 
     case Dali::Actor::Property::COLOR_ALPHA:
     {
-      SetOpacity( property.Get<float>() );
+      SetOpacity( property.Get< float >() );
       break;
     }
 
     case Dali::Actor::Property::NAME:
     {
-      SetName( property.Get<std::string>() );
+      SetName( property.Get< std::string >() );
       break;
     }
 
     case Dali::Actor::Property::SENSITIVE:
     {
-      SetSensitive( property.Get<bool>() );
+      SetSensitive( property.Get< bool >() );
       break;
     }
 
     case Dali::Actor::Property::LEAVE_REQUIRED:
     {
-      SetLeaveRequired( property.Get<bool>() );
+      SetLeaveRequired( property.Get< bool >() );
       break;
     }
 
     case Dali::Actor::Property::INHERIT_ORIENTATION:
     {
-      SetInheritOrientation( property.Get<bool>() );
+      SetInheritOrientation( property.Get< bool >() );
       break;
     }
 
     case Dali::Actor::Property::INHERIT_SCALE:
     {
-      SetInheritScale( property.Get<bool>() );
+      SetInheritScale( property.Get< bool >() );
       break;
     }
 
     case Dali::Actor::Property::COLOR_MODE:
     {
-      SetColorMode( Scripting::GetColorMode( property.Get<std::string>() ) );
+      SetColorMode( Scripting::GetColorMode( property.Get< std::string >() ) );
       break;
     }
 
     case Dali::Actor::Property::POSITION_INHERITANCE:
     {
-      SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get<std::string>() ) );
+      SetPositionInheritanceMode( Scripting::GetPositionInheritanceMode( property.Get< std::string >() ) );
       break;
     }
 
     case Dali::Actor::Property::DRAW_MODE:
     {
-      SetDrawMode( Scripting::GetDrawMode( property.Get<std::string>() ) );
+      SetDrawMode( Scripting::GetDrawMode( property.Get< std::string >() ) );
       break;
     }
 
     case Dali::Actor::Property::SIZE_MODE:
     {
-      SetSizeMode( Scripting::GetEnumeration< SizeMode >( property.Get<std::string>().c_str(), SizeModeTable, SizeModeTableCount ) );
+      SetSizeMode( Scripting::GetEnumeration< SizeMode >( property.Get< std::string >().c_str(), SizeModeTable, SizeModeTableCount ) );
       break;
     }
 
     case Dali::Actor::Property::SIZE_MODE_FACTOR:
     {
-      SetSizeModeFactor( property.Get<Vector3>() );
+      SetSizeModeFactor( property.Get< Vector3 >() );
+      break;
+    }
+
+    case Dali::Actor::Property::RELAYOUT_ENABLED:
+    {
+      SetRelayoutEnabled( property.Get< bool >() );
+      break;
+    }
+
+    case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
+    {
+      SetResizePolicy( Scripting::GetEnumeration< ResizePolicy >( property.Get< std::string >().c_str(), ResizePolicyTable, ResizePolicyTableCount ), WIDTH );
+      break;
+    }
+
+    case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
+    {
+      SetResizePolicy( Scripting::GetEnumeration< ResizePolicy >( property.Get< std::string >().c_str(), ResizePolicyTable, ResizePolicyTableCount ), HEIGHT );
+      break;
+    }
+
+    case Dali::Actor::Property::SIZE_SCALE_POLICY:
+    {
+      SetSizeScalePolicy( Scripting::GetEnumeration< SizeScalePolicy >( property.Get< std::string >().c_str(), SizeScalePolicyTable, SizeScalePolicyTableCount ) );
+      break;
+    }
+
+    case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
+    {
+      if( property.Get< bool >() )
+      {
+        SetDimensionDependency( WIDTH, HEIGHT );
+      }
+      break;
+    }
+
+    case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
+    {
+      if( property.Get< bool >() )
+      {
+        SetDimensionDependency( HEIGHT, WIDTH );
+      }
+      break;
+    }
+
+    case Dali::Actor::Property::PADDING:
+    {
+      Vector4 padding = property.Get< Vector4 >();
+      SetPadding( Vector2( padding.x, padding.y ), WIDTH );
+      SetPadding( Vector2( padding.z, padding.w ), HEIGHT );
+      break;
+    }
+
+    case Dali::Actor::Property::MINIMUM_SIZE:
+    {
+      Vector2 size = property.Get< Vector2 >();
+      SetMinimumSize( size.x, WIDTH );
+      SetMinimumSize( size.y, HEIGHT );
+      break;
+    }
+
+    case Dali::Actor::Property::MAXIMUM_SIZE:
+    {
+      Vector2 size = property.Get< Vector2 >();
+      SetMaximumSize( size.x, WIDTH );
+      SetMaximumSize( size.y, HEIGHT );
+      break;
+    }
+
+    case Dali::Actor::Property::PREFERRED_SIZE:
+    {
+      Vector2 size = property.Get< Vector2 >();
+      SetPreferredSize( size );
       break;
     }
 
@@ -2571,13 +2911,13 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr
 // TODO: This method needs to be removed
 void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
 {
-  OnPropertySet(index, value);
+  OnPropertySet( index, value );
 
-  switch ( entry.type )
+  switch( entry.type )
   {
     case Property::BOOLEAN:
     {
-      const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
+      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
@@ -2588,7 +2928,7 @@ void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata
 
     case Property::FLOAT:
     {
-      const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
+      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
@@ -2599,7 +2939,7 @@ void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata
 
     case Property::INTEGER:
     {
-      const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
+      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
@@ -2610,7 +2950,7 @@ void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata
 
     case Property::VECTOR2:
     {
-      const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
+      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
@@ -2621,7 +2961,7 @@ void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata
 
     case Property::VECTOR3:
     {
-      const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
+      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
@@ -2632,7 +2972,7 @@ void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata
 
     case Property::VECTOR4:
     {
-      const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
+      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
@@ -2643,7 +2983,7 @@ void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata
 
     case Property::ROTATION:
     {
-      const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
+      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
@@ -2654,7 +2994,7 @@ void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata
 
     case Property::MATRIX:
     {
-      const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( entry.GetSceneGraphProperty() );
+      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
@@ -2665,7 +3005,7 @@ void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata
 
     case Property::MATRIX3:
     {
-      const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( entry.GetSceneGraphProperty() );
+      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
@@ -2686,7 +3026,7 @@ Property::Value Actor::GetDefaultProperty( Property::Index index ) const
 {
   Property::Value value;
 
-  switch ( index )
+  switch( index )
   {
     case Dali::Actor::Property::PARENT_ORIGIN:
     {
@@ -2958,38 +3298,100 @@ Property::Value Actor::GetDefaultProperty( Property::Index index ) const
       break;
     }
 
-    default:
+    case Dali::Actor::Property::RELAYOUT_ENABLED:
     {
-      DALI_ASSERT_ALWAYS(false && "Actor Property index invalid" ); // should not come here
+      value = IsRelayoutEnabled();
       break;
     }
-  }
 
-  return value;
-}
+    case Dali::Actor::Property::WIDTH_RESIZE_POLICY:
+    {
+      value = Scripting::GetLinearEnumerationName< ResizePolicy >( GetResizePolicy( WIDTH ), ResizePolicyTable, ResizePolicyTableCount );
+      break;
+    }
 
-const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
-{
-  return mNode;
-}
+    case Dali::Actor::Property::HEIGHT_RESIZE_POLICY:
+    {
+      value = Scripting::GetLinearEnumerationName< ResizePolicy >( GetResizePolicy( HEIGHT ), ResizePolicyTable, ResizePolicyTableCount );
+      break;
+    }
 
-const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
-{
-  // This method should only return an object connected to the scene-graph
-  return OnStage() ? mNode : NULL;
-}
+    case Dali::Actor::Property::SIZE_SCALE_POLICY:
+    {
+      value = Scripting::GetLinearEnumerationName< SizeScalePolicy >( GetSizeScalePolicy(), SizeScalePolicyTable, SizeScalePolicyTableCount );
+      break;
+    }
 
-const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
-{
-  DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
+    case Dali::Actor::Property::WIDTH_FOR_HEIGHT:
+    {
+      value = ( GetResizePolicy( WIDTH ) == DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( WIDTH ) == HEIGHT );
+      break;
+    }
 
-  const PropertyBase* property( NULL );
+    case Dali::Actor::Property::HEIGHT_FOR_WIDTH:
+    {
+      value = ( GetResizePolicy( HEIGHT ) == DIMENSION_DEPENDENCY ) && ( GetDimensionDependency( HEIGHT ) == WIDTH );
+      break;
+    }
 
-  // This method should only return a property of an object connected to the scene-graph
-  if ( !OnStage() )
-  {
-    return property;
-  }
+    case Dali::Actor::Property::PADDING:
+    {
+      Vector2 widthPadding = GetPadding( WIDTH );
+      Vector2 heightPadding = GetPadding( HEIGHT );
+      value = Vector4( widthPadding.x, widthPadding.y, heightPadding.x, heightPadding.y );
+      break;
+    }
+
+    case Dali::Actor::Property::MINIMUM_SIZE:
+    {
+      value = Vector2( GetMinimumSize( WIDTH ), GetMinimumSize( HEIGHT ) );
+      break;
+    }
+
+    case Dali::Actor::Property::MAXIMUM_SIZE:
+    {
+      value = Vector2( GetMaximumSize( WIDTH ), GetMaximumSize( HEIGHT ) );
+      break;
+    }
+
+    case Dali::Actor::Property::PREFERRED_SIZE:
+    {
+      value = GetPreferredSize();
+      break;
+    }
+
+    default:
+    {
+      DALI_ASSERT_ALWAYS( false && "Actor Property index invalid" ); // should not come here
+      break;
+    }
+  }
+
+  return value;
+}
+
+const SceneGraph::PropertyOwner* Actor::GetPropertyOwner() const
+{
+  return mNode;
+}
+
+const SceneGraph::PropertyOwner* Actor::GetSceneObject() const
+{
+  // This method should only return an object connected to the scene-graph
+  return OnStage() ? mNode : NULL;
+}
+
+const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index index ) const
+{
+  DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
+
+  const PropertyBase* property( NULL );
+
+  // This method should only return a property of an object connected to the scene-graph
+  if( !OnStage() )
+  {
+    return property;
+  }
 
   if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
   {
@@ -3006,7 +3408,7 @@ const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index ind
   }
   else if( NULL != mNode )
   {
-    switch ( index )
+    switch( index )
     {
       case Dali::Actor::Property::SIZE:
         property = &mNode->mSize;
@@ -3097,7 +3499,7 @@ const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index ind
   const PropertyInputImpl* property( NULL );
 
   // This method should only return a property of an object connected to the scene-graph
-  if ( !OnStage() )
+  if( !OnStage() )
   {
     return property;
   }
@@ -3116,7 +3518,7 @@ const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index ind
   }
   else if( NULL != mNode )
   {
-    switch ( index )
+    switch( index )
     {
       case Dali::Actor::Property::PARENT_ORIGIN:
         property = &mNode->mParentOrigin;
@@ -3270,7 +3672,7 @@ int Actor::GetPropertyComponentIndex( Property::Index index ) const
 {
   int componentIndex( Property::INVALID_COMPONENT_INDEX );
 
-  switch ( index )
+  switch( index )
   {
     case Dali::Actor::Property::PARENT_ORIGIN_X:
     case Dali::Actor::Property::ANCHOR_POINT_X:
@@ -3324,7 +3726,7 @@ int Actor::GetPropertyComponentIndex( Property::Index index ) const
   return componentIndex;
 }
 
-void Actor::SetParent(Actor* parent, int index)
+void Actor::SetParent( Actor* parent, int index )
 {
   if( parent )
   {
@@ -3348,7 +3750,7 @@ void Actor::SetParent(Actor* parent, int index)
     if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction
          OnStage() )
     {
-      DALI_ASSERT_ALWAYS(mNode != NULL);
+      DALI_ASSERT_ALWAYS( mNode != NULL );
 
       if( NULL != mNode )
       {
@@ -3367,21 +3769,21 @@ SceneGraph::Node* Actor::CreateNode() const
   return Node::New();
 }
 
-bool Actor::DoAction( BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes )
+bool Actor::DoAction( BaseObject* object, const std::string& actionName, const std::vector< Property::Value >& attributes )
 {
   bool done = false;
-  Actor* actor = dynamic_cast<Actor*>( object );
+  Actor* actor = dynamic_cast< Actor* >( object );
 
   if( actor )
   {
     if( 0 == strcmp( actionName.c_str(), ACTION_SHOW ) ) // dont want to convert char* to string
     {
-      actor->SetVisible(true);
+      actor->SetVisible( true );
       done = true;
     }
     else if( 0 == strcmp( actionName.c_str(), ACTION_HIDE ) )
     {
-      actor->SetVisible(false);
+      actor->SetVisible( false );
       done = true;
     }
   }
@@ -3389,6 +3791,664 @@ bool Actor::DoAction( BaseObject* object, const std::string& actionName, const s
   return done;
 }
 
+void Actor::EnsureRelayoutData() const
+{
+  // Assign relayout data.
+  if( !mRelayoutData )
+  {
+    mRelayoutData = new RelayoutData();
+  }
+}
+
+bool Actor::RelayoutDependentOnParent( Dimension dimension )
+{
+  // Check if actor is dependent on parent
+  for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+  {
+    if( ( dimension & ( 1 << i ) ) )
+    {
+      const ResizePolicy resizePolicy = GetResizePolicy( static_cast< Dimension >( 1 << i ) );
+      if( resizePolicy == FILL_TO_PARENT )
+      {
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+bool Actor::RelayoutDependentOnChildren( Dimension dimension )
+{
+  // Check if actor is dependent on children
+  for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+  {
+    if( ( dimension & ( 1 << i ) ) )
+    {
+      const ResizePolicy resizePolicy = GetResizePolicy( static_cast< Dimension >( 1 << i ) );
+      switch( resizePolicy )
+      {
+        case FIT_TO_CHILDREN:
+        case USE_NATURAL_SIZE:      // i.e. For things that calculate their size based on children
+        {
+          return true;
+        }
+
+        default:
+        {
+          break;
+        }
+      }
+    }
+  }
+
+  return false;
+}
+
+bool Actor::RelayoutDependentOnChildrenBase( Dimension dimension )
+{
+  return Actor::RelayoutDependentOnChildren( dimension );
+}
+
+bool Actor::RelayoutDependentOnDimension( Dimension dimension, Dimension dependentDimension )
+{
+  // Check each possible dimension and see if it is dependent on the input one
+  for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+  {
+    if( dimension & ( 1 << i ) )
+    {
+      return mRelayoutData->resizePolicies[ i ] == DIMENSION_DEPENDENCY && mRelayoutData->dimensionDependencies[ i ] == dependentDimension;
+    }
+  }
+
+  return false;
+}
+
+void Actor::SetNegotiatedDimension( float negotiatedDimension, Dimension dimension )
+{
+  for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+  {
+    if( dimension & ( 1 << i ) )
+    {
+      mRelayoutData->negotiatedDimensions[ i ] = negotiatedDimension;
+    }
+  }
+}
+
+float Actor::GetNegotiatedDimension( Dimension dimension ) const
+{
+  // If more than one dimension is requested, just return the first one found
+  for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+  {
+    if( ( dimension & ( 1 << i ) ) )
+    {
+      return mRelayoutData->negotiatedDimensions[ i ];
+    }
+  }
+
+  return 0.0f;   // Default
+}
+
+void Actor::SetPadding( const Vector2& padding, Dimension dimension )
+{
+  EnsureRelayoutData();
+
+  for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+  {
+    if( dimension & ( 1 << i ) )
+    {
+      mRelayoutData->dimensionPadding[ i ] = padding;
+    }
+  }
+}
+
+Vector2 Actor::GetPadding( Dimension dimension ) const
+{
+  EnsureRelayoutData();
+
+  // If more than one dimension is requested, just return the first one found
+  for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+  {
+    if( ( dimension & ( 1 << i ) ) )
+    {
+      return mRelayoutData->dimensionPadding[ i ];
+    }
+  }
+
+  return Vector2( 0.0f, 0.0f );   // Default
+}
+
+void Actor::SetLayoutNegotiated( bool negotiated, Dimension dimension )
+{
+  for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+  {
+    if( dimension & ( 1 << i ) )
+    {
+      mRelayoutData->dimensionNegotiated[ i ] = negotiated;
+    }
+  }
+}
+
+bool Actor::IsLayoutNegotiated( Dimension dimension ) const
+{
+  for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+  {
+    if( ( dimension & ( 1 << i ) ) && mRelayoutData->dimensionNegotiated[ i ] )
+    {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+float Actor::CalculateChildSize( const Dali::Actor& child, Dimension dimension )
+{
+  // Could be overridden in derived classes.
+  return CalculateChildSizeBase( child, dimension );
+}
+
+float Actor::CalculateChildSizeBase( const Dali::Actor& child, Dimension dimension )
+{
+  // Fill to parent, taking size mode factor into account
+  switch( child.GetSizeMode() )
+  {
+    case USE_OWN_SIZE:
+    {
+      return GetLatestSize( dimension );
+    }
+
+    case SIZE_RELATIVE_TO_PARENT:
+    {
+      return GetLatestSize( dimension ) * GetDimensionValue( child.GetSizeModeFactor(), dimension );
+    }
+
+    case SIZE_FIXED_OFFSET_FROM_PARENT:
+    {
+      return GetLatestSize( dimension ) + GetDimensionValue( child.GetSizeModeFactor(), dimension );
+    }
+
+    default:
+    {
+      return GetLatestSize( dimension );
+    }
+  }
+}
+
+float Actor::GetHeightForWidth( float width )
+{
+  // Could be overridden in derived classes.
+  float height = 0.0f;
+
+  const Vector3 naturalSize = GetNaturalSize();
+  if( naturalSize.width > 0.0f )
+  {
+    height = naturalSize.height * width / naturalSize.width;
+  }
+
+  return height;
+}
+
+float Actor::GetWidthForHeight( float height )
+{
+  // Could be overridden in derived classes.
+  float width = 0.0f;
+
+  const Vector3 naturalSize = GetNaturalSize();
+  if( naturalSize.height > 0.0f )
+  {
+    width = naturalSize.width * height / naturalSize.height;
+  }
+
+  return width;
+}
+
+float Actor::GetLatestSize( Dimension dimension ) const
+{
+  return IsLayoutNegotiated( dimension ) ? GetNegotiatedDimension( dimension ) : GetSize( dimension );
+}
+
+float Actor::GetRelayoutSize( Dimension dimension ) const
+{
+  Vector2 padding = GetPadding( dimension );
+
+  return GetLatestSize( dimension ) + padding.x + padding.y;
+}
+
+float Actor::NegotiateFromParent( Dimension dimension )
+{
+  Actor* parent = GetParent();
+  if( parent )
+  {
+    Vector2 padding( GetPadding( dimension ) );
+    Vector2 parentPadding( parent->GetPadding( dimension ) );
+    return parent->CalculateChildSize( Dali::Actor( this ), dimension ) - parentPadding.x - parentPadding.y - padding.x - padding.y;
+  }
+
+  return 0.0f;
+}
+
+float Actor::NegotiateFromChildren( Dimension dimension )
+{
+  float minDimensionPoint = 0.0f;
+  float maxDimensionPoint = 0.0f;
+
+  for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
+  {
+    Dali::Actor child = GetChildAt( i );
+    Actor& childImpl = GetImplementation( child );
+
+    if( !childImpl.RelayoutDependentOnParent( dimension ) )
+    {
+      // Calculate the min and max points that the children range across
+      float childPosition = GetDimensionValue( childImpl.GetCurrentPosition(), dimension );
+      float dimensionSize = childImpl.GetRelayoutSize( dimension );
+      minDimensionPoint = std::min( minDimensionPoint, childPosition - dimensionSize * 0.5f );
+      maxDimensionPoint = std::max( maxDimensionPoint, childPosition + dimensionSize * 0.5f );
+    }
+  }
+
+  return maxDimensionPoint - minDimensionPoint;
+}
+
+float Actor::GetSize( Dimension dimension ) const
+{
+  return GetDimensionValue( GetTargetSize(), dimension );
+}
+
+float Actor::GetNaturalSize( Dimension dimension ) const
+{
+  return GetDimensionValue( GetNaturalSize(), dimension );
+}
+
+float Actor::CalculateSize( Dimension dimension, const Vector2& maximumSize )
+{
+  switch( GetResizePolicy( dimension ) )
+  {
+    case USE_NATURAL_SIZE:
+    {
+      return GetNaturalSize( dimension );
+    }
+
+    case FIXED:
+    {
+      return GetDimensionValue( GetPreferredSize(), dimension );
+    }
+
+    case USE_ASSIGNED_SIZE:
+    {
+      return GetDimensionValue( maximumSize, dimension );
+    }
+
+    case FILL_TO_PARENT:
+    {
+      return NegotiateFromParent( dimension );
+    }
+
+    case FIT_TO_CHILDREN:
+    {
+      return NegotiateFromChildren( dimension );
+    }
+
+    case DIMENSION_DEPENDENCY:
+    {
+      const Dimension dimensionDependency = GetDimensionDependency( dimension );
+
+      // Custom rules
+      if( dimension == WIDTH && dimensionDependency == HEIGHT )
+      {
+        return GetWidthForHeight( GetNegotiatedDimension( HEIGHT ) );
+      }
+
+      if( dimension == HEIGHT && dimensionDependency == WIDTH )
+      {
+        return GetHeightForWidth( GetNegotiatedDimension( WIDTH ) );
+      }
+
+      break;
+    }
+
+    default:
+    {
+      break;
+    }
+  }
+
+  return 0.0f;  // Default
+}
+
+float Actor::ConstrainDimension( float size, Dimension dimension )
+{
+  const float minSize = GetMinimumSize( dimension );
+  const float maxSize = GetMaximumSize( dimension );
+
+  return std::max( minSize, std::min( size, maxSize ) );
+}
+
+void Actor::NegotiateDimension( Dimension dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack )
+{
+  // Check if it needs to be negotiated
+  if( IsLayoutDirty( dimension ) && !IsLayoutNegotiated( dimension ) )
+  {
+    // Check that we havn't gotten into an infinite loop
+    ActorDimensionPair searchActor = ActorDimensionPair( this, dimension );
+    bool recursionFound = false;
+    for( ActorDimensionStack::iterator it = recursionStack.begin(), itEnd = recursionStack.end(); it != itEnd; ++it )
+    {
+      if( *it == searchActor )
+      {
+        recursionFound = true;
+        break;
+      }
+    }
+
+    if( !recursionFound )
+    {
+      // Record the path that we have taken
+      recursionStack.push_back( ActorDimensionPair( this, dimension ) );
+
+      // Dimension dependency check
+      for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+      {
+        Dimension dimensionToCheck = static_cast< Dimension >( 1 << i );
+
+        if( RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
+        {
+          NegotiateDimension( dimensionToCheck, allocatedSize, recursionStack );
+        }
+      }
+
+      // Parent dependency check
+      Actor* parent = GetParent();
+      if( parent && RelayoutDependentOnParent( dimension ) )
+      {
+        parent->NegotiateDimension( dimension, allocatedSize, recursionStack );
+      }
+
+      // Children dependency check
+      if( RelayoutDependentOnChildren( dimension ) )
+      {
+        for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
+        {
+          Dali::Actor child = GetChildAt( i );
+          Actor& childImpl = GetImplementation( child );
+
+          // Only relayout child first if it is not dependent on this actor
+          if( !childImpl.RelayoutDependentOnParent( dimension ) )
+          {
+            childImpl.NegotiateDimension( dimension, allocatedSize, recursionStack );
+          }
+        }
+      }
+
+      // For deriving classes
+      OnCalculateRelayoutSize( dimension );
+
+      // All dependencies checked, calculate the size and set negotiated flag
+      const float newSize = ConstrainDimension( 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( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+  {
+    const Dimension dimension = static_cast< Dimension >( 1 << i );
+
+    // Negotiate
+    NegotiateDimension( dimension, allocatedSize, recursionStack );
+  }
+}
+
+Vector2 Actor::ApplySizeSetPolicy( const Vector2 size )
+{
+  switch( mRelayoutData->sizeSetPolicy )
+  {
+    case USE_SIZE_SET:
+    {
+      return size;
+    }
+
+    case 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 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
+        {
+          return size;
+        }
+      }
+
+      break;
+    }
+
+    case 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
+        {
+          return size;
+        }
+      }
+    }
+
+    default:
+    {
+      break;
+    }
+  }
+
+  return size;
+}
+
+void Actor::SetNegotiatedSize( RelayoutContainer& container )
+{
+  // Do the set actor size
+  Vector2 negotiatedSize( GetLatestSize( WIDTH ), GetLatestSize( 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 );
+  }
+}
+
+void Actor::NegotiateSize( const Vector2& allocatedSize, RelayoutContainer& container )
+{
+  // Do the negotiation
+  NegotiateDimensions( allocatedSize );
+
+  // Set the actor size
+  SetNegotiatedSize( container );
+
+  // Negotiate down to children
+  const Vector2 newBounds = GetTargetSize().GetVectorXY();
+
+  for( unsigned int i = 0, count = GetChildCount(); i < count; ++i )
+  {
+    Dali::Actor child = GetChildAt( i );
+
+    // Only relayout if required
+    if( GetImplementation( child ).RelayoutRequired() )
+    {
+      container.Add( child, newBounds );
+    }
+  }
+}
+
+void Actor::RelayoutRequest( Dimension dimension )
+{
+  Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
+  if( relayoutController )
+  {
+    Dali::Actor self( this );
+    relayoutController->RequestRelayout( self, dimension );
+  }
+}
+
+void Actor::RelayoutRequestTree()
+{
+  Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
+  if( relayoutController )
+  {
+    Dali::Actor self( this );
+    relayoutController->RequestRelayoutTree( self );
+  }
+}
+
+void Actor::PropagateRelayoutFlags()
+{
+  Internal::RelayoutController* relayoutController = Internal::RelayoutController::Get();
+  if( relayoutController )
+  {
+    Dali::Actor self( this );
+    relayoutController->PropagateFlags( self );
+  }
+}
+
+void Actor::OnCalculateRelayoutSize( Dimension dimension )
+{
+}
+
+void Actor::OnLayoutNegotiated( float size, Dimension dimension )
+{
+}
+
+void Actor::SetPreferredSize( const Vector2& size )
+{
+  EnsureRelayoutData();
+
+  mRelayoutData->preferredSize = size;
+
+  RelayoutRequest();
+}
+
+Vector2 Actor::GetPreferredSize() const
+{
+  EnsureRelayoutData();
+
+  return mRelayoutData->preferredSize;
+}
+
+void Actor::SetMinimumSize( float size, Dimension dimension )
+{
+  EnsureRelayoutData();
+
+  for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+  {
+    if( dimension & ( 1 << i ) )
+    {
+      mRelayoutData->minimumSize[ i ] = size;
+    }
+  }
+
+  RelayoutRequest();
+}
+
+float Actor::GetMinimumSize( Dimension dimension ) const
+{
+  EnsureRelayoutData();
+
+  for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+  {
+    if( dimension & ( 1 << i ) )
+    {
+      return mRelayoutData->minimumSize[ i ];
+    }
+  }
+
+  return 0.0f;  // Default
+}
+
+void Actor::SetMaximumSize( float size, Dimension dimension )
+{
+  EnsureRelayoutData();
+
+  for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+  {
+    if( dimension & ( 1 << i ) )
+    {
+      mRelayoutData->maximumSize[ i ] = size;
+    }
+  }
+
+  RelayoutRequest();
+}
+
+float Actor::GetMaximumSize( Dimension dimension ) const
+{
+  EnsureRelayoutData();
+
+  for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+  {
+    if( dimension & ( 1 << i ) )
+    {
+      return mRelayoutData->maximumSize[ i ];
+    }
+  }
+
+  return 0.0f;  // Default
+}
+
 } // namespace Internal
 
 } // namespace Dali
index 6cf654c..73105e6 100644 (file)
@@ -29,6 +29,7 @@
 #include <dali/public-api/events/gesture.h>
 #include <dali/public-api/math/viewport.h>
 #include <dali/internal/event/common/object-impl.h>
+#include <dali/public-api/size-negotiation/relayout-container.h>
 #include <dali/internal/event/common/stage-def.h>
 #include <dali/internal/event/actors/actor-declarations.h>
 #include <dali/internal/event/actor-attachments/actor-attachment-declarations.h>
@@ -55,10 +56,10 @@ class Animation;
 class RenderTask;
 struct DynamicsData;
 
-typedef IntrusivePtr<Actor>                   ActorPtr;
-typedef Dali::ActorContainer                  ActorContainer; // Store handles to return via public-api
-typedef ActorContainer::iterator              ActorIter;
-typedef ActorContainer::const_iterator        ActorConstIter;
+typedef IntrusivePtr< Actor > ActorPtr;
+typedef Dali::ActorContainer ActorContainer; // Store handles to return via public-api
+typedef ActorContainer::iterator ActorIter;
+typedef ActorContainer::const_iterator ActorConstIter;
 
 /**
  * Actor is the primary object which Dali applications interact with.
@@ -75,6 +76,42 @@ class Actor : public Object
 public:
 
   /**
+   * @brief Struct to hold an actor and a dimension
+   */
+  struct ActorDimensionPair
+  {
+    /**
+     * @brief Constructor
+     *
+     * @param[in] newActor The actor to assign
+     * @param[in] newDimension The dimension to assign
+     */
+    ActorDimensionPair( Actor* newActor, Dimension newDimension )
+    : actor( newActor ),
+      dimension( newDimension )
+    {
+    }
+
+    /**
+     * @brief Equality operator
+     *
+     * @param[in] lhs The left hand side argument
+     * @param[in] rhs The right hand side argument
+     */
+    bool operator== ( const ActorDimensionPair& rhs )
+    {
+      return ( actor == rhs.actor ) && ( dimension == rhs.dimension );
+    }
+
+    Actor* actor;           ///< The actor to hold
+    Dimension dimension;    ///< The dimension to hold
+  };
+
+  typedef std::vector< ActorDimensionPair > ActorDimensionStack;
+
+public:
+
+  /**
    * Create a new actor.
    * @return A smart-pointer to the newly allocated Actor.
    */
@@ -90,7 +127,7 @@ public:
    * Set the name of the actor.
    * @param[in] name The new name.
    */
-  void SetName(const std::string& name);
+  void SetName( const std::string& name );
 
   /**
    * @copydoc Dali::Actor::GetId
@@ -104,7 +141,7 @@ public:
    * @pre The actor does not already have an attachment.
    * @param[in] attachment The object to attach.
    */
-  void Attach(ActorAttachment& attachment);
+  void Attach( ActorAttachment& attachment );
 
   /**
    * Retreive the object attached to an actor.
@@ -161,7 +198,7 @@ public:
    * @param [in] child The child.
    * @post The child will be referenced by its parent.
    */
-  void Add(Actor& child);
+  void Add( Actor& child );
 
   /**
    * Inserts a child Actor to this Actor's child list
@@ -171,14 +208,14 @@ public:
    * @param [in] child The child.
    * @post The child will be referenced by its parent.
    */
-  void Insert(unsigned int index, Actor& child);
+  void Insert( unsigned int index, Actor& child );
 
   /**
    * Removes a child Actor from this Actor.
    * @param [in] child The child.
    * @post The child will be unreferenced.
    */
-  void Remove(Actor& child);
+  void Remove( Actor& child );
 
   /**
    * @copydoc Dali::Actor::Unparent
@@ -194,7 +231,7 @@ public:
   /**
    * @copydoc Dali::Actor::GetChildAt
    */
-  Dali::Actor GetChildAt(unsigned int index) const;
+  Dali::Actor GetChildAt( unsigned int index ) const;
 
   /**
    * Retrieve the Actor's children.
@@ -221,12 +258,12 @@ public:
   /**
    * @copydoc Dali::Actor::FindChildByName
    */
-  ActorPtr FindChildByName(const std::string& actorName);
+  ActorPtr FindChildByName( const std::string& actorName );
 
   /**
    * @copydoc Dali::Actor::FindChildById
    */
-  ActorPtr FindChildById(const unsigned int id);
+  ActorPtr FindChildById( const unsigned int id );
 
   /**
    * Retrieve the parent of an Actor.
@@ -244,7 +281,7 @@ public:
    * @param [in] width  The new width.
    * @param [in] height The new height.
    */
-  void SetSize(float width, float height);
+  void SetSize( float width, float height );
 
   /**
    * Sets the size of an actor.
@@ -254,7 +291,7 @@ public:
    * @param [in] height The size of the actor along the y-axis.
    * @param [in] depth The size of the actor along the z-axis.
    */
-  void SetSize(float width, float height, float depth);
+  void SetSize( float width, float height, float depth );
 
   /**
    * Sets the size of an actor.
@@ -262,7 +299,7 @@ public:
    * This does not interfere with the actors scale factor.
    * @param [in] size The new size.
    */
-  void SetSize(const Vector2& size);
+  void SetSize( const Vector2& size );
 
   /**
    * Sets the size of an actor.
@@ -270,7 +307,7 @@ public:
    * This does not interfere with the actors scale factor.
    * @param [in] size The new size.
    */
-  void SetSize(const Vector3& size);
+  void SetSize( const Vector3& size );
 
   /**
    * Set the width component of the Actor's size.
@@ -295,7 +332,7 @@ public:
    * This size will be the size set or if animating then the target size.
    * @return The Actor's size.
    */
-  const Vector3& GetSize() const;
+  const Vector3& GetTargetSize() const;
 
   /**
    * Retrieve the Actor's size from update side.
@@ -319,7 +356,7 @@ public:
    * An actor position is the distance between this origin, and the actors anchor-point.
    * @param [in] origin The new parent-origin.
    */
-  void SetParentOrigin(const Vector3& origin);
+  void SetParentOrigin( const Vector3& origin );
 
   /**
    * Set the x component of the parent-origin
@@ -353,7 +390,7 @@ public:
    * An actor's rotation is centered around its anchor-point.
    * @param [in] anchorPoint The new anchor-point.
    */
-  void SetAnchorPoint(const Vector3& anchorPoint);
+  void SetAnchorPoint( const Vector3& anchorPoint );
 
   /**
    * Set the x component of the anchor-point.
@@ -386,7 +423,7 @@ public:
    * @param [in] x The new x position
    * @param [in] y The new y position
    */
-  void SetPosition(float x, float y);
+  void SetPosition( float x, float y );
 
   /**
    * Sets the position of the Actor.
@@ -395,38 +432,38 @@ public:
    * @param [in] y The new y position
    * @param [in] z The new z position
    */
-  void SetPosition(float x, float y, float z);
+  void SetPosition( float x, float y, float z );
 
   /**
    * Sets the position of the Actor.
    * The coordinates are relative to the Actor's parent.
    * @param [in] position The new position.
    */
-  void SetPosition(const Vector3& position);
+  void SetPosition( const Vector3& position );
 
   /**
    * Set the position of an actor along the X-axis.
    * @param [in] x The new x position
    */
-  void SetX(float x);
+  void SetX( float x );
 
   /**
    * Set the position of an actor along the Y-axis.
    * @param [in] y The new y position.
    */
-  void SetY(float y);
+  void SetY( float y );
 
   /**
    * Set the position of an actor along the Z-axis.
    * @param [in] z The new z position
    */
-  void SetZ(float z);
+  void SetZ( float z );
 
   /**
    * Translate an actor relative to its existing position.
    * @param[in] distance The actor will move by this distance.
    */
-  void TranslateBy(const Vector3& distance);
+  void TranslateBy( const Vector3& distance );
 
   /**
    * Retrieve the position of the Actor.
@@ -455,26 +492,26 @@ public:
    * @param [in] angleRadians The new orientation angle in radians.
    * @param [in] axis The new axis of orientation.
    */
-  void SetOrientation(const Radian& angleRadians, const Vector3& axis);
+  void SetOrientation( const Radian& angleRadians, const Vector3& axis );
 
   /**
    * Sets the orientation of the Actor.
    * @param [in] orientation The new orientation.
    */
-  void SetOrientation(const Quaternion& orientation);
+  void SetOrientation( const Quaternion& orientation );
 
   /**
    * Rotate an actor around its existing rotation axis.
    * @param[in] angleRadians The angle to the rotation to combine with the existing rotation.
    * @param[in] axis The axis of the rotation to combine with the existing rotation.
    */
-  void RotateBy(const Radian& angleRadians, const Vector3& axis);
+  void RotateBy( const Radian& angleRadians, const Vector3& axis );
 
   /**
    * Apply a relative rotation to an actor.
    * @param[in] relativeRotation The rotation to combine with the actors existing rotation.
    */
-  void RotateBy(const Quaternion& relativeRotation);
+  void RotateBy( const Quaternion& relativeRotation );
 
   /**
    * Retreive the Actor's orientation.
@@ -487,7 +524,7 @@ public:
    * Switching this off means that using SetOrientation() sets the actor's world orientation.
    * @param[in] inherit - true if the actor should inherit orientation, false otherwise.
    */
-  void SetInheritOrientation(bool inherit);
+  void SetInheritOrientation( bool inherit );
 
   /**
    * Returns whether the actor inherit's it's parent's orientation.
@@ -499,7 +536,7 @@ public:
    * @brief Defines how a child actors size is affected by its parents size.
    * @param[in] mode The size relative to parent mode to use.
    */
-  void SetSizeMode(SizeMode mode);
+  void SetSizeMode( SizeMode mode );
 
   /**
    * Query how the child actors size is affected by its parents size.
@@ -512,7 +549,7 @@ public:
    * Note: Only used if SizeMode is SIZE_RELATIVE_TO_PARENT or SIZE_FIXED_OFFSET_FROM_PARENT.
    * @param[in] factor The vector to multiply the parents size by to get the childs size.
    */
-  void SetSizeModeFactor(const Vector3& factor);
+  void SetSizeModeFactor( const Vector3& factor );
 
   /**
    * Gets the factor of the parents size used for the child actor.
@@ -530,7 +567,7 @@ public:
    * Sets a scale factor applied to an actor.
    * @param [in] scale The scale factor applied on all axes.
    */
-  void SetScale(float scale);
+  void SetScale( float scale );
 
   /**
    * Sets a scale factor applied to an actor.
@@ -538,13 +575,13 @@ public:
    * @param [in] scaleY The scale factor applied along the y-axis.
    * @param [in] scaleZ The scale factor applied along the z-axis.
    */
-  void SetScale(float scaleX, float scaleY, float scaleZ);
+  void SetScale( float scaleX, float scaleY, float scaleZ );
 
   /**
    * Sets a scale factor applied to an actor.
    * @param [in] scale A vector representing the scale factor for each axis.
    */
-  void SetScale(const Vector3& scale);
+  void SetScale( const Vector3& scale );
 
   /**
    * Set the x component of the scale factor.
@@ -568,7 +605,7 @@ public:
    * Apply a relative scale to an actor.
    * @param[in] relativeScale The scale to combine with the actors existing scale.
    */
-  void ScaleBy(const Vector3& relativeScale);
+  void ScaleBy( const Vector3& relativeScale );
 
   /**
    * Retrieve the scale factor applied to an actor.
@@ -602,7 +639,7 @@ public:
    * Sets the visibility flag of an actor.
    * @param [in] visible The new visibility flag.
    */
-  void SetVisible(bool visible);
+  void SetVisible( bool visible );
 
   /**
    * Retrieve the visibility flag of an actor.
@@ -614,7 +651,7 @@ public:
    * Sets the opacity of an actor.
    * @param [in] opacity The new opacity.
    */
-  void SetOpacity(float opacity);
+  void SetOpacity( float opacity );
 
   /**
    * Retrieve the actor's opacity.
@@ -642,7 +679,7 @@ public:
    * @note If an actor's sensitivity is set to false, then it's children will not emit a touch or hover event signal either.
    * @param[in]  sensitive  true to enable emission of the touch or hover event signals, false otherwise.
    */
-  void SetSensitive(bool sensitive)
+  void SetSensitive( bool sensitive )
   {
     mSensitive = sensitive;
   }
@@ -670,7 +707,7 @@ public:
   /**
    * @copydoc Dali::Actor::SetOverlay
    */
-  void SetOverlay(bool enable);
+  void SetOverlay( bool enable );
 
   /**
    * @copydoc Dali::Actor::IsOverlay
@@ -682,7 +719,7 @@ public:
    * The default value is for it not to transmit scaling.
    * @param[in] transmitGeometryScaling True to transmit scaling.
    */
-  void SetTransmitGeometryScaling(bool transmitGeometryScaling);
+  void SetTransmitGeometryScaling( bool transmitGeometryScaling );
 
   /**
    * Get the TransmitGeometryScaling property for this actor.
@@ -697,14 +734,14 @@ public:
    *
    * @param[in] volume the volume of the model and it's children
    */
-  void SetInitialVolume(const Vector3& volume);
+  void SetInitialVolume( const Vector3& volume );
 
   /**
    * Sets the actor's color.  The final color of actor depends on its color mode.
    * This final color is applied to the drawable elements of an actor.
    * @param [in] color The new color.
    */
-  void SetColor(const Vector4& color);
+  void SetColor( const Vector4& color );
 
   /**
    * Set the red component of the color.
@@ -735,7 +772,7 @@ public:
    * Color mode specifies whether Actor uses its own color or inherits its parent color
    * @param [in] colorMode to use.
    */
-  void SetColorMode(ColorMode colorMode);
+  void SetColorMode( ColorMode colorMode );
 
   /**
    * Returns the actor's color mode.
@@ -748,6 +785,436 @@ public:
    */
   const Vector4& GetCurrentWorldColor() const;
 
+public:
+
+  // Size negotiation virtual functions
+
+  /**
+   * @brief Called after the size negotiation has been finished for this control.
+   *
+   * The control is expected to assign this given size to itself/its children.
+   *
+   * Should be overridden by derived classes if they need to layout
+   * actors differently after certain operations like add or remove
+   * actors, resize or after changing specific properties.
+   *
+   * Note! As this function is called from inside the size negotiation algorithm, you cannot
+   * call RequestRelayout (the call would just be ignored)
+   *
+   * @param[in]      size       The allocated size.
+   * @param[in,out]  container  The control should add actors to this container that it is not able
+   *                            to allocate a size for.
+   */
+  virtual void OnRelayout( const Vector2& size, RelayoutContainer& container )
+  {
+  }
+
+  /**
+   * @brief Notification for deriving classes when the resize policy is set
+   *
+   * @param[in] policy The policy being set
+   * @param[in] dimension The dimension the policy is being set for
+   */
+  virtual void OnSetResizePolicy( ResizePolicy policy, Dimension dimension ) {}
+
+  /**
+   * @brief Virtual method to notify deriving classes that relayout dependencies have been
+   * met and the size for this object is about to be calculated for the given dimension
+   *
+   * @param dimension The dimension that is about to be calculated
+   */
+  virtual void OnCalculateRelayoutSize( Dimension dimension );
+
+  /**
+   * @brief Virtual method to notify deriving classes that the size for a dimension
+   * has just been negotiated
+   *
+   * @param[in] size The new size for the given dimension
+   * @param[in] dimension The dimension that was just negotiated
+   */
+  virtual void OnLayoutNegotiated( float size, Dimension dimension );
+
+  /**
+   * @brief Determine if this actor is dependent on it's children for relayout
+   *
+   * @param dimension The dimension(s) to check for
+   * @return Return if the actor is dependent on it's children
+   */
+  virtual bool RelayoutDependentOnChildren( Dimension dimension = ALL_DIMENSIONS );
+
+  /**
+   * @brief Determine if this actor is dependent on it's children for relayout.
+   *
+   * Called from deriving classes
+   *
+   * @param dimension The dimension(s) to check for
+   * @return Return if the actor is dependent on it's children
+   */
+  virtual bool RelayoutDependentOnChildrenBase( Dimension dimension = ALL_DIMENSIONS );
+
+  /**
+   * @brief Calculate the size for a child
+   *
+   * @param[in] child The child actor to calculate the size for
+   * @param[in] dimension The dimension to calculate the size for. E.g. width or height.
+   * @return Return the calculated size for the given dimension
+   */
+  virtual float CalculateChildSize( const Dali::Actor& child, Dimension dimension );
+
+  /**
+   * @brief This method is called during size negotiation when a height is required for a given width.
+   *
+   * Derived classes should override this if they wish to customize the height returned.
+   *
+   * @param width to use.
+   * @return the height based on the width.
+   */
+  virtual float GetHeightForWidth( float width );
+
+  /**
+   * @brief This method is called during size negotiation when a width is required for a given height.
+   *
+   * Derived classes should override this if they wish to customize the width returned.
+   *
+   * @param height to use.
+   * @return the width based on the width.
+   */
+  virtual float GetWidthForHeight( float height );
+
+public:
+
+  // Size negotiation
+
+  /**
+   * @brief Called by the RelayoutController to negotiate the size of an actor.
+   *
+   * The size allocated by the the algorithm is passed in which the
+   * actor must adhere to.  A container is passed in as well which
+   * the actor should populate with actors it has not / or does not
+   * need to handle in its size negotiation.
+   *
+   * @param[in]      size       The allocated size.
+   * @param[in,out]  container  The container that holds actors that are fed back into the
+   *                            RelayoutController algorithm.
+   */
+  void NegotiateSize( const Vector2& size, RelayoutContainer& container );
+
+  /**
+   * @copydoc Dali::Actor::SetResizePolicy()
+   */
+  void SetResizePolicy( ResizePolicy policy, Dimension dimension = ALL_DIMENSIONS );
+
+  /**
+   * @copydoc Dali::Actor::GetResizePolicy()
+   */
+  ResizePolicy GetResizePolicy( Dimension dimension ) const;
+
+  /**
+   * @copydoc Dali::Actor::SetSizeScalePolicy()
+   */
+  void SetSizeScalePolicy( SizeScalePolicy policy );
+
+  /**
+   * @copydoc Dali::Actor::GetSizeScalePolicy()
+   */
+  SizeScalePolicy GetSizeScalePolicy() const;
+
+  /**
+   * @copydoc Dali::Actor::SetDimensionDependency()
+   */
+  void SetDimensionDependency( Dimension dimension, Dimension dependency );
+
+  /**
+   * @copydoc Dali::Actor::GetDimensionDependency()
+   */
+  Dimension GetDimensionDependency( Dimension dimension ) const;
+
+  /**
+   * @copydoc Dali::Actor::SetRelayoutEnabled()
+   */
+  void SetRelayoutEnabled( bool relayoutEnabled );
+
+  /**
+   * @copydoc Dali::Actor::IsRelayoutEnabled()
+   */
+  bool IsRelayoutEnabled() const;
+
+  /**
+   * @brief Mark an actor as having it's layout dirty
+   *
+   * @param dirty Whether to mark actor as dirty or not
+   * @param dimension The dimension(s) to mark as dirty
+   */
+  void SetLayoutDirty( bool dirty, Dimension dimension = ALL_DIMENSIONS );
+
+  /**
+   * @brief Return if any of an actor's dimensions are marked as dirty
+   *
+   * @param dimension The dimension(s) to check
+   * @return Return if any of the requested dimensions are dirty
+   */
+  bool IsLayoutDirty( Dimension dimension = ALL_DIMENSIONS ) const;
+
+  /**
+   * @brief Returns if relayout is enabled and the actor is not dirty
+   *
+   * @return Return if it is possible to relayout the actor
+   */
+  bool RelayoutPossible( Dimension dimension = ALL_DIMENSIONS ) const;
+
+  /**
+   * @brief Returns if relayout is enabled and the actor is dirty
+   *
+   * @return Return if it is required to relayout the actor
+   */
+  bool RelayoutRequired( Dimension dimension = ALL_DIMENSIONS ) const;
+
+  /**
+   * @brief Request a relayout, which means performing a size negotiation on this actor, its parent and children (and potentially whole scene)
+   *
+   * This method is automatically called from OnStageConnection(), OnChildAdd(),
+   * OnChildRemove(), SetSizePolicy(), SetMinimumSize() and SetMaximumSize().
+   *
+   * This method can also be called from a derived class every time it needs a different size.
+   * At the end of event processing, the relayout process starts and
+   * all controls which requested Relayout will have their sizes (re)negotiated.
+   *
+   * @note RelayoutRequest() can be called multiple times; the size negotiation is still
+   * only performed once, i.e. there is no need to keep track of this in the calling side.
+   */
+  void RelayoutRequest( Dimension dimension = ALL_DIMENSIONS );
+
+  /**
+   * @brief Request to relayout of all actors in the sub-tree below the given actor.
+   *
+   * This flags the actor and all actors below it for relayout. The actual
+   * relayout is performed at the end of the frame. This means that multiple calls to relayout
+   * will not cause multiple relayouts to occur.
+   */
+  void RelayoutRequestTree();
+
+  /*
+   * @copydoc Dali::Actor::PropagateRelayoutFlags
+   */
+  void PropagateRelayoutFlags();
+
+  /**
+   * @brief Determine if this actor is dependent on it's parent for relayout
+   *
+   * @param dimension The dimension(s) to check for
+   * @return Return if the actor is dependent on it's parent
+   */
+  bool RelayoutDependentOnParent( Dimension dimension = ALL_DIMENSIONS );
+
+  /**
+   * @brief Determine if this actor has another dimension depedent on the specified one
+   *
+   * @param dimension The dimension to check for
+   * @param dependentDimension The dimension to check for dependency with
+   * @return Return if the actor is dependent on this dimension
+   */
+  bool RelayoutDependentOnDimension( Dimension dimension, Dimension dependentDimension );
+
+  /**
+   * Negotiate sizes for a control in all dimensions
+   *
+   * @param[in] allocatedSize The size constraint that the control must respect
+   */
+  void NegotiateDimensions( const Vector2& allocatedSize );
+
+  /**
+   * Negotiate size for a specific dimension
+   *
+   * The algorithm adopts a recursive dependency checking approach. Meaning, that wherever dependencies
+   * are found, e.g. an actor dependent on its parent, the dependency will be calculated first with NegotiatedDimension and
+   * LayoutDimensionNegotiated flags being filled in on the actor.
+   *
+   * @post All actors that exist in the dependency chain connected to the given actor will have had their NegotiatedDimensions
+   * calculated and set as well as the LayoutDimensionNegotiated flags.
+   *
+   * @param[in] dimension The dimension to negotiate on
+   * @param[in] allocatedSize The size constraint that the actor must respect
+   */
+  void NegotiateDimension( Dimension dimension, const Vector2& allocatedSize, ActorDimensionStack& recursionStack );
+
+  /**
+   * @brief Calculate the size of a dimension
+   *
+   * @param[in] dimension The dimension to calculate the size for
+   * @param[in] maximumSize The upper bounds on the size
+   * @return Return the calculated size for the dimension
+   */
+  float CalculateSize( Dimension dimension, const Vector2& maximumSize );
+
+  /**
+   * @brief Constain a dimension given the relayout constraints on this actor
+   *
+   * @param[in] size The size to constrain
+   * @param[in] dimension The dimension the size exists in
+   * @return Return the constrained size
+   */
+  float ConstrainDimension( float size, Dimension dimension );
+
+  /**
+   * Negotiate a dimension based on the size of the parent
+   *
+   * @param[in] dimension The dimension to negotiate on
+   * @return Return the negotiated size
+   */
+  float NegotiateFromParent( Dimension dimension );
+
+  /**
+   * Negotiate a dimension based on the size of the parent. Fitting inside.
+   *
+   * @param[in] dimension The dimension to negotiate on
+   * @return Return the negotiated size
+   */
+  float NegotiateFromParentFit( Dimension dimension );
+
+  /**
+   * Negotiate a dimension based on the size of the parent. Flooding the whole space.
+   *
+   * @param[in] dimension The dimension to negotiate on
+   * @return Return the negotiated size
+   */
+  float NegotiateFromParentFlood( Dimension dimension );
+
+  /**
+   * @brief Negotiate a dimension based on the size of the children
+   *
+   * @param[in] dimension The dimension to negotiate on
+   * @return Return the negotiated size
+   */
+  float NegotiateFromChildren( Dimension dimension );
+
+  /**
+   * Set the negotiated dimension value for the given dimension(s)
+   *
+   * @param negotiatedDimension The value to set
+   * @param dimension The dimension(s) to set the value for
+   */
+  void SetNegotiatedDimension( float negotiatedDimension, Dimension dimension = ALL_DIMENSIONS );
+
+  /**
+   * Return the value of negotiated dimension for the given dimension
+   *
+   * @param dimension The dimension to retrieve
+   * @return Return the value of the negotiated dimension
+   */
+  float GetNegotiatedDimension( Dimension dimension ) const;
+
+  /**
+   * @brief Set the padding for a dimension
+   *
+   * @param[in] padding Padding for the dimension. X = start (e.g. left, bottom), y = end (e.g. right, top)
+   * @param[in] dimension The dimension to set
+   */
+  void SetPadding( const Vector2& padding, Dimension dimension );
+
+  /**
+   * Return the value of padding for the given dimension
+   *
+   * @param dimension The dimension to retrieve
+   * @return Return the value of padding for the dimension
+   */
+  Vector2 GetPadding( Dimension dimension ) const;
+
+  /**
+   * Return the actor size for a given dimension
+   *
+   * @param[in] dimension The dimension to retrieve the size for
+   * @return Return the size for the given dimension
+   */
+  float GetSize( Dimension dimension ) const;
+
+  /**
+   * Return the natural size of the actor for a given dimension
+   *
+   * @param[in] dimension The dimension to retrieve the size for
+   * @return Return the natural size for the given dimension
+   */
+  float GetNaturalSize( Dimension dimension ) const;
+
+  /**
+   * @brief Return the amount of size allocated for relayout
+   *
+   * May include padding
+   *
+   * @param[in] dimension The dimension to retrieve
+   * @return Return the size
+   */
+  float GetRelayoutSize( Dimension dimension ) const;
+
+  /**
+   * @brief If the size has been negotiated return that else return normal size
+   *
+   * @param[in] dimension The dimension to retrieve
+   * @return Return the size
+   */
+  float GetLatestSize( Dimension dimension ) const;
+
+  /**
+   * Apply the negotiated size to the actor
+   *
+   * @param[in] container The container to fill with actors that require further relayout
+   */
+  void SetNegotiatedSize( RelayoutContainer& container );
+
+  /**
+   * @brief Flag the actor as having it's layout dimension negotiated.
+   *
+   * @param[in] negotiated The status of the flag to set.
+   * @param[in] dimension The dimension to set the flag for
+   */
+  void SetLayoutNegotiated( bool negotiated, Dimension dimension = ALL_DIMENSIONS );
+
+  /**
+   * @brief Test whether the layout dimension for this actor has been negotiated or not.
+   *
+   * @param[in] dimension The dimension to determine the value of the flag for
+   * @return Return if the layout dimension is negotiated or not.
+   */
+  bool IsLayoutNegotiated( Dimension dimension = ALL_DIMENSIONS ) const;
+
+  /**
+   * @brief Calculate the size for a child
+   *
+   * @param[in] child The child actor to calculate the size for
+   * @param[in] dimension The dimension to calculate the size for. E.g. width or height.
+   * @return Return the calculated size for the given dimension
+   */
+  float CalculateChildSizeBase( const Dali::Actor& child, Dimension dimension );
+
+  /**
+   * @copydoc Dali::Actor::SetPreferredSize
+   */
+  void SetPreferredSize( const Vector2& size );
+
+  /**
+   * @copydoc Dali::Actor::GetPreferredSize
+   */
+  Vector2 GetPreferredSize() const;
+
+  /**
+   * @copydoc Dali::Actor::SetMinimumSize
+   */
+  void SetMinimumSize( float size, Dimension dimension = ALL_DIMENSIONS );
+
+  /**
+   * @copydoc Dali::Actor::GetMinimumSize
+   */
+  float GetMinimumSize( Dimension dimension ) const;
+
+  /**
+   * @copydoc Dali::Actor::SetMaximumSize
+   */
+  void SetMaximumSize( float size, Dimension dimension = ALL_DIMENSIONS );
+
+  /**
+   * @copydoc Dali::Actor::GetMaximumSize
+   */
+  float GetMaximumSize( Dimension dimension ) const;
+
 #ifdef DYNAMICS_SUPPORT
 
   // Dynamics
@@ -756,7 +1223,7 @@ public:
   void DisableDynamics();
 
   /// @copydoc Dali::Actor::EnableDynamics(Dali::DynamicsBodyConfig)
-  DynamicsBodyPtr  EnableDynamics(DynamicsBodyConfigPtr bodyConfig);
+  DynamicsBodyPtr EnableDynamics(DynamicsBodyConfigPtr bodyConfig);
 
   /// @copydoc Dali::Actor::GetDynamicsBody
   DynamicsBodyPtr GetDynamicsBody() const;
@@ -844,7 +1311,7 @@ public:
    * @param[in] screenY The screen Y-coordinate.
    * @return True if the conversion succeeded.
    */
-  bool ScreenToLocal(float& localX, float& localY, float screenX, float screenY) const;
+  bool ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const;
 
   /**
    * Converts screen coordinates into the actor's coordinate system.
@@ -856,7 +1323,7 @@ public:
    * @param[in] screenY The screen Y-coordinate.
    * @return True if the conversion succeeded.
    */
-  bool ScreenToLocal(RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY) const;
+  bool ScreenToLocal( RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY ) const;
 
   /**
    * Converts from the actor's coordinate system to screen coordinates.
@@ -896,7 +1363,10 @@ public:
    * @param[out] distance The distance from the hit point to the camera.
    * @return True if the ray intersects the actor's geometry.
    */
-  bool RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const;
+  bool RayActorTest( const Vector4& rayOrigin,
+                     const Vector4& rayDir,
+                     Vector4& hitPointLocal,
+                     float& distance ) const;
 
   /**
    * Sets whether the actor should receive a notification when touch or hover motion events leave
@@ -907,7 +1377,7 @@ public:
    *
    * @param[in]  required  Should be set to true if a Leave event is required
    */
-  void SetLeaveRequired(bool required);
+  void SetLeaveRequired( bool required );
 
   /**
    * This returns whether the actor requires touch or hover events whenever touch or hover motion events leave
@@ -976,21 +1446,21 @@ public:
    * @param[in] event The touch event.
    * @return True if the event was consumed.
    */
-  bool EmitTouchEventSignal(const TouchEvent& event);
+  bool EmitTouchEventSignal( const TouchEvent& event );
 
   /**
    * Used by the EventProcessor to emit hover event signals.
    * @param[in] event The hover event.
    * @return True if the event was consumed.
    */
-  bool EmitHoverEventSignal(const HoverEvent& event);
+  bool EmitHoverEventSignal( const HoverEvent& event );
 
   /**
    * Used by the EventProcessor to emit mouse wheel event signals.
    * @param[in] event The mouse wheel event.
    * @return True if the event was consumed.
    */
-  bool EmitMouseWheelEventSignal(const MouseWheelEvent& event);
+  bool EmitMouseWheelEventSignal( const MouseWheelEvent& event );
 
   /**
    * @copydoc Dali::Actor::TouchedSignal()
@@ -1018,6 +1488,11 @@ public:
   Dali::Actor::OffStageSignalType& OffStageSignal();
 
   /**
+   * @copydoc Dali::Actor::OnRelayoutSignal()
+   */
+  Dali::Actor::OnRelayoutSignalType& OnRelayoutSignal();
+
+  /**
    * Connects a callback function with the object's signals.
    * @param[in] object The object providing the signal.
    * @param[in] tracker Used to disconnect the signal.
@@ -1026,7 +1501,10 @@ public:
    * @return True if the signal was connected.
    * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
    */
-  static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor );
+  static bool DoConnectSignal( BaseObject* object,
+                               ConnectionTrackerInterface* tracker,
+                               const std::string& signalName,
+                               FunctorDelegate* functor );
 
   /**
    * Performs actions as requested using the action name.
@@ -1035,9 +1513,12 @@ public:
    * @param[in] attributes The attributes with which to perfrom this action.
    * @return true if the action was done.
    */
-  static bool DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes);
+  static bool DoAction( BaseObject* object,
+                        const std::string& actionName,
+                        const std::vector< Property::Value >& attributes );
 
-public:  // For Animation
+public:
+  // For Animation
 
   /**
    * This should only be called by Animation, when the actor is resized using Animation::Resize().
@@ -1045,22 +1526,21 @@ public:  // For Animation
    * @param[in] animation The animation that resized the actor
    * @param[in] targetSize The new target size of the actor
    */
-  void NotifySizeAnimation( Animation& animation, const Vector3& targetSize);
+  void NotifySizeAnimation( Animation& animation, const Vector3& targetSize );
 
   /**
    * For use in derived classes.
    * This should only be called by Animation, when the actor is resized using Animation::Resize().
    */
-  virtual void OnSizeAnimation( Animation& animation, const Vector3& targetSize) {}
+  virtual void OnSizeAnimation( Animation& animation, const Vector3& targetSize )
+  {
+  }
 
 protected:
 
   enum DerivedType
   {
-    BASIC,
-    RENDERABLE,
-    LAYER,
-    ROOT_LAYER
+    BASIC, RENDERABLE, LAYER, ROOT_LAYER
   };
 
   /**
@@ -1073,7 +1553,7 @@ protected:
   /**
    * Second-phase constructor. Must be called immediately after creating a new Actor;
    */
-  void Initialize(void);
+  void Initialize( void );
 
   /**
    * A reference counted object may only be deleted by calling Unreference()
@@ -1099,7 +1579,7 @@ protected:
    * Connect the Node associated with this Actor to the scene-graph.
    * @param[in] index If set, it is only used for positioning the actor within the parent's child list.
    */
-  void ConnectToSceneGraph(int index = -1);
+  void ConnectToSceneGraph( int index = -1 );
 
   /**
    * Helper for ConnectToStage, to notify a connected actor through the public API.
@@ -1143,7 +1623,8 @@ protected:
    */
   float CalculateSizeZ( const Vector2& size ) const;
 
-public: // Default property extensions from Object
+public:
+  // Default property extensions from Object
 
   /**
    * @copydoc Dali::Internal::Object::GetDefaultPropertyCount()
@@ -1158,22 +1639,22 @@ public: // Default property extensions from Object
   /**
    * @copydoc Dali::Internal::Object::GetDefaultPropertyName()
    */
-  virtual const char* GetDefaultPropertyName(Property::Index index) const;
+  virtual const char* GetDefaultPropertyName( Property::Index index ) const;
 
   /**
    * @copydoc Dali::Internal::Object::GetDefaultPropertyIndex()
    */
-  virtual Property::Index GetDefaultPropertyIndex(const std::string& name) const;
+  virtual Property::Index GetDefaultPropertyIndex( const std::string& name ) const;
 
   /**
    * @copydoc Dali::Internal::Object::IsDefaultPropertyWritable()
    */
-  virtual bool IsDefaultPropertyWritable(Property::Index index) const;
+  virtual bool IsDefaultPropertyWritable( Property::Index index ) const;
 
   /**
    * @copydoc Dali::Internal::Object::IsDefaultPropertyAnimatable()
    */
-  virtual bool IsDefaultPropertyAnimatable(Property::Index index) const;
+  virtual bool IsDefaultPropertyAnimatable( Property::Index index ) const;
 
   /**
    * @copydoc Dali::Internal::Object::IsDefaultPropertyAConstraintInput()
@@ -1183,12 +1664,12 @@ public: // Default property extensions from Object
   /**
    * @copydoc Dali::Internal::Object::GetDefaultPropertyType()
    */
-  virtual Property::Type GetDefaultPropertyType(Property::Index index) const;
+  virtual Property::Type GetDefaultPropertyType( Property::Index index ) const;
 
   /**
    * @copydoc Dali::Internal::Object::SetDefaultProperty()
    */
-  virtual void SetDefaultProperty(Property::Index index, const Property::Value& propertyValue);
+  virtual void SetDefaultProperty( Property::Index index, const Property::Value& propertyValue );
 
   /**
    * @copydoc Dali::Internal::Object::SetSceneGraphProperty()
@@ -1231,17 +1712,17 @@ private:
   Actor();
 
   // Undefined
-  Actor(const Actor&);
+  Actor( const Actor& );
 
   // Undefined
-  Actor& operator=(const Actor& rhs);
+  Actor& operator=( const Actor& rhs );
 
   /**
    * Set the actors parent.
    * @param[in] parent The new parent.
    * @param[in] index If set, it is only used for positioning the actor within the parent's child list.
    */
-  void SetParent(Actor* parent, int index = -1);
+  void SetParent( Actor* parent, int index = -1 );
 
   /**
    * Helper to create a Node for this Actor.
@@ -1253,51 +1734,67 @@ private:
   /**
    * For use in derived classes, called after Initialize()
    */
-  virtual void OnInitialize() {}
+  virtual void OnInitialize()
+  {
+  }
 
   /**
    * For use in internal derived classes.
    * This is called during ConnectToStage(), after the actor has finished adding its node to the scene-graph.
    * The derived class must not modify the actor hierachy (Add/Remove children) during this callback.
    */
-  virtual void OnStageConnectionInternal() {}
+  virtual void OnStageConnectionInternal()
+  {
+  }
 
   /**
    * For use in internal derived classes.
    * This is called during DisconnectFromStage(), before the actor removes its node from the scene-graph.
    * The derived class must not modify the actor hierachy (Add/Remove children) during this callback.
    */
-  virtual void OnStageDisconnectionInternal() {}
+  virtual void OnStageDisconnectionInternal()
+  {
+  }
 
   /**
    * For use in external (CustomActor) derived classes.
    * This is called after the atomic ConnectToStage() traversal has been completed.
    */
-  virtual void OnStageConnectionExternal() {}
+  virtual void OnStageConnectionExternal()
+  {
+  }
 
   /**
    * For use in external (CustomActor) derived classes.
    * This is called after the atomic DisconnectFromStage() traversal has been completed.
    */
-  virtual void OnStageDisconnectionExternal() {}
+  virtual void OnStageDisconnectionExternal()
+  {
+  }
 
   /**
    * For use in derived classes; this is called after Add() has added a child.
    * @param[in] child The child that was added.
    */
-  virtual void OnChildAdd( Actor& child ) {}
+  virtual void OnChildAdd( Actor& child )
+  {
+  }
 
   /**
    * For use in derived classes; this is called after Remove() has removed a child.
    * @param[in] child The child that was removed.
    */
-  virtual void OnChildRemove( Actor& child ) {}
+  virtual void OnChildRemove( Actor& child )
+  {
+  }
 
   /**
    * For use in derived classes.
    * This is called after SizeSet() has been called.
    */
-  virtual void OnSizeSet(const Vector3& targetSize) {}
+  virtual void OnSizeSet( const Vector3& targetSize )
+  {
+  }
 
   /**
    * For use in derived classes.
@@ -1305,7 +1802,10 @@ private:
    * @param[in] event The touch event.
    * @return True if the event should be consumed.
    */
-  virtual bool OnTouchEvent(const TouchEvent& event) { return false; }
+  virtual bool OnTouchEvent( const TouchEvent& event )
+  {
+    return false;
+  }
 
   /**
    * For use in derived classes.
@@ -1313,7 +1813,10 @@ private:
    * @param[in] event The hover event.
    * @return True if the event should be consumed.
    */
-  virtual bool OnHoverEvent(const HoverEvent& event) { return false; }
+  virtual bool OnHoverEvent( const HoverEvent& event )
+  {
+    return false;
+  }
 
   /**
    * For use in derived classes.
@@ -1321,24 +1824,43 @@ private:
    * @param[in] event The mouse event.
    * @return True if the event should be consumed.
    */
-  virtual bool OnMouseWheelEvent(const MouseWheelEvent& event) { return false; }
+  virtual bool OnMouseWheelEvent( const MouseWheelEvent& event )
+  {
+    return false;
+  }
+
+  /**
+   * @brief Ensure the relayout data is allocated
+   */
+  void EnsureRelayoutData() const;
+
+  /**
+   * @brief Apply the size set policy to the input size
+   *
+   * @param[in] size The size to apply the policy to
+   * @return Return the adjusted size
+   */
+  Vector2 ApplySizeSetPolicy( const Vector2 size );
 
 protected:
 
-  StagePtr                mStage;        ///< Used to send messages to Node; valid until Core destruction
-  Actor*                  mParent;       ///< Each actor (except the root) can have one parent
-  ActorContainer*         mChildren;     ///< Container of referenced actors
-  const SceneGraph::Node* mNode;         ///< Not owned
-  Vector3*                mParentOrigin; ///< NULL means ParentOrigin::DEFAULT. ParentOrigin is non-animatable
-  Vector3*                mAnchorPoint;  ///< NULL means AnchorPoint::DEFAULT. AnchorPoint is non-animatable
+  StagePtr mStage;                ///< Used to send messages to Node; valid until Core destruction
+  Actor* mParent;                 ///< Each actor (except the root) can have one parent
+  ActorContainer* mChildren;      ///< Container of referenced actors
+  const SceneGraph::Node* mNode;  ///< Not owned
+  Vector3* mParentOrigin;         ///< NULL means ParentOrigin::DEFAULT. ParentOrigin is non-animatable
+  Vector3* mAnchorPoint;          ///< NULL means AnchorPoint::DEFAULT. AnchorPoint is non-animatable
+
+  struct RelayoutData;
+  mutable RelayoutData* mRelayoutData; ///< Struct to hold optional collection of relayout variables
 
 #ifdef DYNAMICS_SUPPORT
-  DynamicsData*           mDynamicsData; ///< optional physics data
+  DynamicsData* mDynamicsData; ///< optional physics data
 #endif
 
-  ActorGestureData*       mGestureData;  ///< Optional Gesture data. Only created when actor requires gestures
+  ActorGestureData* mGestureData;   ///< Optional Gesture data. Only created when actor requires gestures
 
-  ActorAttachmentPtr      mAttachment;   ///< Optional referenced attachment
+  ActorAttachmentPtr mAttachment;   ///< Optional referenced attachment
 
   // Signals
   Dali::Actor::TouchSignalType             mTouchedSignal;
@@ -1346,9 +1868,9 @@ protected:
   Dali::Actor::MouseWheelEventSignalType   mMouseWheelEventSignal;
   Dali::Actor::OnStageSignalType           mOnStageSignal;
   Dali::Actor::OffStageSignalType          mOffStageSignal;
+  Dali::Actor::OnRelayoutSignalType        mOnRelayoutSignal;
 
-  Vector3         mSize;      ///< Event-side storage for size (not a pointer as most actors will have a size)
-  Vector3         mSizeModeFactor; ///< Factor of parent size used for certain SizeModes.
+  Vector3         mTargetSize;      ///< Event-side storage for size (not a pointer as most actors will have a size)
 
   std::string     mName;      ///< Name of the actor
   unsigned int    mId;        ///< A unique ID to identify the actor starting from 1, and 0 is reserved
@@ -1370,12 +1892,11 @@ protected:
   DrawMode::Type mDrawMode                         : 2; ///< Cached: How the actor and its children should be drawn
   PositionInheritanceMode mPositionInheritanceMode : 2; ///< Cached: Determines how position is inherited
   ColorMode mColorMode                             : 2; ///< Cached: Determines whether mWorldColor is inherited
-  SizeMode mSizeMode                               : 2; ///< Cached: Determines how the actors parent affects the actors size.
 
 private:
 
-  static ActorContainer mNullChildren; ///< Empty container (shared by all actors, returned by GetChildren() const)
-  static unsigned int   mActorCounter; ///< A counter to track the actor instance creation
+  static ActorContainer mNullChildren;  ///< Empty container (shared by all actors, returned by GetChildren() const)
+  static unsigned int mActorCounter;    ///< A counter to track the actor instance creation
 
 };
 
@@ -1383,22 +1904,22 @@ private:
 
 // Helpers for public-api forwarding methods
 
-inline Internal::Actor& GetImplementation(Dali::Actor& actor)
+inline Internal::Actor& GetImplementation( Dali::Actor& actor )
 {
-  DALI_ASSERT_ALWAYS(actor && "Actor handle is empty");
+  DALI_ASSERT_ALWAYS( actor && "Actor handle is empty" );
 
   BaseObject& handle = actor.GetBaseObject();
 
-  return static_cast<Internal::Actor&>(handle);
+  return static_cast< Internal::Actor& >( handle );
 }
 
-inline const Internal::Actor& GetImplementation(const Dali::Actor& actor)
+inline const Internal::Actor& GetImplementation( const Dali::Actor& actor )
 {
-  DALI_ASSERT_ALWAYS(actor && "Actor handle is empty");
+  DALI_ASSERT_ALWAYS( actor && "Actor handle is empty" );
 
   const BaseObject& handle = actor.GetBaseObject();
 
-  return static_cast<const Internal::Actor&>(handle);
+  return static_cast< const Internal::Actor& >( handle );
 }
 
 } // namespace Dali
index deed407..377e297 100644 (file)
@@ -159,6 +159,22 @@ private:
   }
 
   /**
+   * @copydoc Internal::Actor::OnRelayout
+   */
+  virtual void OnRelayout( const Vector2& size, RelayoutContainer& container )
+  {
+    mImpl->OnRelayout( size, container );
+  }
+
+  /**
+   * @copydoc Internal::Actor::OnSetResizePolicy
+   */
+  virtual void OnSetResizePolicy( ResizePolicy policy, Dimension dimension )
+  {
+    mImpl->OnSetResizePolicy( policy, dimension );
+  }
+
+  /**
    * @copydoc Internal::Actor::GetNaturalSize
    */
   virtual Vector3 GetNaturalSize() const
@@ -167,6 +183,54 @@ private:
   }
 
   /**
+   * @copydoc Internal::Actor::CalculateChildSize
+   */
+  virtual float CalculateChildSize( const Dali::Actor& child, Dimension dimension )
+  {
+    return mImpl->CalculateChildSize( child, dimension );
+  }
+
+  /**
+   * @copydoc Internal::Actor::GetHeightForWidth
+   */
+  virtual float GetHeightForWidth( float width )
+  {
+    return mImpl->GetHeightForWidth( width );
+  }
+
+  /**
+   * @copydoc Internal::Actor::GetWidthForHeight
+   */
+  virtual float GetWidthForHeight( float height )
+  {
+    return mImpl->GetWidthForHeight( height );
+  }
+
+  /**
+   * @copydoc Internal::Actor::RelayoutDependentOnChildren
+   */
+  virtual bool RelayoutDependentOnChildren( Dimension dimension = ALL_DIMENSIONS )
+  {
+    return mImpl->RelayoutDependentOnChildren( dimension );
+  }
+
+  /**
+   * @copydoc Internal::Actor::OnCalculateRelayoutSize
+   */
+  virtual void OnCalculateRelayoutSize( Dimension dimension )
+  {
+    return mImpl->OnCalculateRelayoutSize( dimension );
+  }
+
+  /**
+   * @copydoc Internal::Actor::OnLayoutNegotiated
+   */
+  virtual void OnLayoutNegotiated( float size, Dimension dimension )
+  {
+    return mImpl->OnLayoutNegotiated( size, dimension );
+  }
+
+  /**
    * Private constructor; see also CustomActor::New()
    */
   CustomActor(CustomActorImpl& extension);
index 1e48202..a31e532 100644 (file)
@@ -100,6 +100,7 @@ ImageActorPtr ImageActor::New()
 
 void ImageActor::OnInitialize()
 {
+  SetResizePolicy( USE_NATURAL_SIZE, ALL_DIMENSIONS );
 }
 
 void ImageActor::SetImage( ImagePtr& image )
@@ -170,6 +171,7 @@ void ImageActor::ClearPixelArea()
     {
       mInternalSetSize = true;
       SetSize( image->GetNaturalSize() );
+      SetPreferredSize( GetTargetSize().GetVectorXY() );
       mInternalSetSize = false;
     }
   }
@@ -211,6 +213,8 @@ ImageActor::ImageActor()
   mUsingNaturalSize(true),
   mInternalSetSize(false)
 {
+  // Size negotiate disabled by default, so turn it on for this actor
+  SetRelayoutEnabled( true );
 }
 
 ImageActor::~ImageActor()
@@ -223,6 +227,7 @@ void ImageActor::SetNaturalSize()
   {
     mInternalSetSize = true;
     SetSize( CalculateNaturalSize() );
+    SetPreferredSize( GetTargetSize().GetVectorXY() );
     mInternalSetSize = false;
   }
 }
index 2021941..9b64444 100644 (file)
@@ -109,6 +109,8 @@ Layer::Layer( Actor::DerivedType type )
   mTouchConsumed(false),
   mHoverConsumed(false)
 {
+  // Size negotiate disabled by default, so turn it on for this actor
+  SetRelayoutEnabled( true );
 }
 
 void Layer::OnInitialize()
index 990fb52..775c319 100644 (file)
@@ -97,6 +97,7 @@ void Stage::Initialize()
   // The stage owns the default layer
   mRootLayer = Layer::NewRoot( *mLayerList, mUpdateManager, false/*not system-level*/ );
   mRootLayer->SetName("RootLayer");
+  mRootLayer->SetRelayoutEnabled( false );   // Exclude from size negotiation
 
   // Create the default camera actor first; this is needed by the RenderTaskList
   CreateDefaultCameraActor();
index 2733568..2ab705c 100644 (file)
@@ -130,6 +130,7 @@ void SystemOverlay::CreateRootLayer()
   {
     mRootLayer = Layer::NewRoot( *mLayerList, mEventThreadServices.GetUpdateManager(), true/*system layer*/ );
     mRootLayer->SetName("SystemOverlayRoot");
+    mRootLayer->SetRelayoutEnabled( false );   // Exclude from size negotiation
     mRootLayer->SetSize( mSize.width, mSize.height );
   }
 }
index 72cf2b7..5bf87ae 100644 (file)
@@ -124,6 +124,11 @@ EmojiFactory& ThreadLocalStorage::GetEmojiFactory()
   return mCore->GetEmojiFactory();
 }
 
+RelayoutController& ThreadLocalStorage::GetRelayoutController()
+{
+  return mCore->GetRelayoutController();
+}
+
 } // namespace Internal
 
 } // namespace Dali
index bdeb0eb..956211e 100644 (file)
@@ -43,6 +43,7 @@ class FontFactory;
 class ShaderFactory;
 class GestureEventProcessor;
 class EmojiFactory;
+class RelayoutController;
 
 namespace SceneGraph
 {
@@ -159,6 +160,12 @@ public:
    */
   EmojiFactory& GetEmojiFactory();
 
+  /**
+   * Return the relayout controller
+   * @Return Return a reference to the relayout controller
+   */
+  RelayoutController& GetRelayoutController();
+
 private:
 
   Core* mCore;                            ///< reference to core
diff --git a/dali/internal/event/size-negotiation/memory-pool-relayout-container.cpp b/dali/internal/event/size-negotiation/memory-pool-relayout-container.cpp
new file mode 100644 (file)
index 0000000..617f801
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+#include "memory-pool-relayout-container.h"
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+MemoryPoolRelayoutContainer::MemoryPoolRelayoutContainer( MemoryPoolObjectAllocator< RelayoutInfo >& objectAllocator )
+: mAllocator( objectAllocator )
+{
+}
+
+MemoryPoolRelayoutContainer::~MemoryPoolRelayoutContainer()
+{
+}
+
+bool MemoryPoolRelayoutContainer::Contains( const Dali::Actor& actor )
+{
+  for( RelayoutInfoContainer::Iterator it = mRelayoutInfos.Begin(), itEnd = mRelayoutInfos.End(); it != itEnd; ++it )
+  {
+    RelayoutInfo* info = *it;
+
+    if( info->actor == actor )
+    {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+void MemoryPoolRelayoutContainer::Add( const Dali::Actor& actor, const Vector2& size )
+{
+  if( !Contains( actor ) )
+  {
+    RelayoutInfo* info = mAllocator.Allocate();
+    info->actor = actor;
+    info->size = size;
+
+    mRelayoutInfos.PushBack( info );
+  }
+}
+
+void MemoryPoolRelayoutContainer::PopBack()
+{
+  if( mRelayoutInfos.Size() > 0 )
+  {
+    RelayoutInfoContainer::Iterator back = mRelayoutInfos.End();
+    back--;
+    RelayoutInfo* info = *back;
+    mAllocator.Free( info );
+    mRelayoutInfos.Erase( back );
+  }
+}
+
+void MemoryPoolRelayoutContainer::Get( size_t index, Dali::Actor& actorOut, Vector2& sizeOut  ) const
+{
+  DALI_ASSERT_DEBUG( index < Size() );
+
+  RelayoutInfo* info = mRelayoutInfos[ index ];
+  actorOut = info->actor;
+  sizeOut = info->size;
+}
+
+size_t MemoryPoolRelayoutContainer::Size() const
+{
+  return mRelayoutInfos.Size();
+}
+
+void MemoryPoolRelayoutContainer::Reserve( size_t capacity )
+{
+  mRelayoutInfos.Reserve( capacity );
+}
+
+void MemoryPoolRelayoutContainer::Clear()
+{
+  for( size_t i = 0; i < Size(); ++i )
+  {
+    RelayoutInfo* info = mRelayoutInfos[ i ];
+    mAllocator.Free( info );
+  }
+
+  mRelayoutInfos.Clear();
+}
+
+} // namespace Internal
+
+} // namespace Dali
diff --git a/dali/internal/event/size-negotiation/memory-pool-relayout-container.h b/dali/internal/event/size-negotiation/memory-pool-relayout-container.h
new file mode 100644 (file)
index 0000000..02eda8f
--- /dev/null
@@ -0,0 +1,123 @@
+#ifndef __DALI_INTERNAL_MEMORY_POOL_RELAYOUT_CONTAINER_H__
+#define __DALI_INTERNAL_MEMORY_POOL_RELAYOUT_CONTAINER_H__
+
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+// INTERNAL INCLUDES
+#include <dali/public-api/size-negotiation/relayout-container.h>
+#include <dali/public-api/common/dali-vector.h>
+#include <dali/public-api/actors/actor.h>
+
+#include <dali/internal/common/memory-pool-object-allocator.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+/**
+ * @brief Container to encapsulate information required for relayout.
+ *
+ * Uses a memory pool to manage data allocations.
+ */
+class MemoryPoolRelayoutContainer : public RelayoutContainer
+{
+public:
+
+  /**
+   * Struct to store the relayout information
+   */
+  struct RelayoutInfo
+  {
+    Dali::Actor actor;            ///< The actor to relayout
+    Vector2 size;           ///< The desired size of the actor
+  };
+
+  /**
+   * @brief Default constructor
+   *
+   * @param objectAllocator A memory pool that can allocate memory for RelayoutInfos
+   */
+  MemoryPoolRelayoutContainer( MemoryPoolObjectAllocator< RelayoutInfo >& objectAllocator );
+
+  /**
+   * Virtual destructor
+   */
+  virtual ~MemoryPoolRelayoutContainer();
+
+  /**
+   * @brief Add relayout information to the container if it does'nt already exist
+   *
+   * @param actor The actor to relayout
+   * @param size The size to relayout
+   */
+  virtual void Add( const Dali::Actor& actor, const Vector2& size );
+
+  /**
+   * @brief Remove information from the container
+   */
+  void PopBack();
+
+  /**
+   * @brief Retrieve relayout information for the given index
+   *
+   * @param index The index of the information to retrieve
+   */
+  void Get( size_t index, Dali::Actor& actorOut, Vector2& sizeOut  ) const;
+
+  /**
+   * @brief The count of information in the container
+   */
+  size_t Size() const;
+
+  /**
+   * @brief Set the capacity of the container
+   *
+   * @param capacity The new capacity for the container
+   */
+  void Reserve( size_t capacity );
+
+  /**
+   * @brief Reset the container, freeing all memory
+   */
+  void Clear();
+
+  /**
+   * @brief Returns if the container contains the actor or not
+   *
+   * @param actor The actor to search for
+   * @return Return if the actor was found or not
+   */
+  bool Contains( const Dali::Actor& actor );
+
+private:
+
+  typedef Vector< RelayoutInfo* > RelayoutInfoContainer;
+
+  RelayoutInfoContainer mRelayoutInfos;     ///< The list of relayout infos
+
+  MemoryPoolObjectAllocator< RelayoutInfo >& mAllocator;         ///< The memory pool from which the infos are allocated
+};
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // __DALI_INTERNAL_MEMORY_POOL_RELAYOUT_CONTAINER_H__
diff --git a/dali/internal/event/size-negotiation/relayout-controller-impl.cpp b/dali/internal/event/size-negotiation/relayout-controller-impl.cpp
new file mode 100644 (file)
index 0000000..3deb9e1
--- /dev/null
@@ -0,0 +1,498 @@
+/*
+ * Copyright (c) 2014 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+
+#include "relayout-controller-impl.h"
+
+// EXTERNAL INCLUDES
+#if defined(DEBUG_ENABLED)
+#include <sstream>
+#include <dali/internal/event/common/system-overlay-impl.h>
+#endif // defined(DEBUG_ENABLED)
+
+// INTERNAL INCLUDES
+#include <dali/public-api/actors/layer.h>
+#include <dali/public-api/common/stage.h>
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/object/type-registry.h>
+#include <dali/public-api/object/object-registry.h>
+#include <dali/internal/event/actors/actor-impl.h>
+#include <dali/internal/event/common/thread-local-storage.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace
+{
+#if defined(DEBUG_ENABLED)
+
+Integration::Log::Filter* gLogFilter( Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_RELAYOUT_CONTROLLER") );
+
+/**
+ * Prints out all the children of the given actor when debug is enabled.
+ *
+ * @param[in]  actor  The actor whose children to print.
+ * @param[in]  level  The number of " | " to put in front of the children.
+ */
+void PrintChildren( Dali::Actor actor, int level )
+{
+  std::ostringstream output;
+
+  for ( int t = 0; t < level; ++t )
+  {
+    output << " | ";
+  }
+
+  output << actor.GetTypeName();
+
+  output << ", " << actor.GetName();
+
+  output << " - Pos: " << actor.GetCurrentPosition() << " Size: " << actor.GetTargetSize();
+
+  output << ", Dirty: (" << ( GetImplementation( actor ).IsLayoutDirty( WIDTH ) ? "TRUE" : "FALSE" ) << "," << ( GetImplementation( actor ).IsLayoutDirty( HEIGHT ) ? "TRUE" : "FALSE" ) << ")";
+  output << ", Negotiated: (" << ( GetImplementation( actor ).IsLayoutNegotiated( WIDTH ) ? "TRUE" : "FALSE" ) << "," << ( GetImplementation( actor ).IsLayoutNegotiated( HEIGHT ) ? "TRUE" : "FALSE" ) << ")";
+  output << ", Enabled: " << ( actor.IsRelayoutEnabled() ? "TRUE" : "FALSE" );
+
+  output << ", (" << actor.GetObjectPtr() << ")" << std::endl;
+
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, output.str().c_str() );
+
+  ++level;
+  unsigned int numChildren = actor.GetChildCount();
+  for( unsigned int i=0; i<numChildren; ++i )
+  {
+    PrintChildren( actor.GetChildAt(i), level );
+  }
+  --level;
+}
+
+/**
+ * Prints the entire hierarchy of the scene.
+ */
+void PrintHierarchy()
+{
+  if ( gLogFilter->IsEnabledFor( Debug::Verbose ) )
+  {
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "---------- ROOT LAYER ----------\n" );
+    PrintChildren( Dali::Stage().GetCurrent().GetRootLayer(), 0 );
+  }
+}
+
+#define PRINT_HIERARCHY PrintHierarchy()
+
+#else // defined(DEBUG_ENABLED)
+
+#define PRINT_HIERARCHY
+
+#endif // defined(DEBUG_ENABLED)
+
+} // unnamed namespace
+
+RelayoutController* RelayoutController::Get()
+{
+  return &ThreadLocalStorage::Get().GetRelayoutController();
+}
+
+RelayoutController::RelayoutController()
+: mRelayoutInfoAllocator(),
+  mSlotDelegate( this ),
+  mRelayoutStack( new MemoryPoolRelayoutContainer( mRelayoutInfoAllocator ) ),
+  mRelayoutConnection( false ),
+  mRelayoutFlag( false ),
+  mEnabled( false )
+{
+  // Make space for 32 controls to avoid having to copy construct a lot in the beginning
+  mRelayoutStack->Reserve( 32 );
+}
+
+RelayoutController::~RelayoutController()
+{
+  delete mRelayoutStack;
+}
+
+void RelayoutController::QueueActor( Dali::Actor& actor, RelayoutContainer& actors, Vector2 size )
+{
+  if( GetImplementation( actor ).RelayoutRequired() )
+  {
+    actors.Add( actor, size );
+  }
+}
+
+void RelayoutController::RequestRelayout( Dali::Actor& actor, Dimension dimension )
+{
+  if( !mEnabled )
+  {
+    return;
+  }
+
+  Dali::ActorContainer potentialRedundantSubRoots;
+  Dali::ActorContainer topOfSubTreeStack;
+
+  topOfSubTreeStack.push_back( actor );
+
+  // Propagate on all dimensions
+  for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+  {
+    if( dimension & ( 1 << i ) )
+    {
+      // Do the propagation
+      PropagateAll( actor, static_cast< Dimension >( 1 << i ), topOfSubTreeStack, potentialRedundantSubRoots );
+    }
+  }
+
+  // Request this actor as head of sub-tree if it is not dependent on a parent that is dirty
+  Dali::Actor subTreeActor = topOfSubTreeStack.back();
+  Dali::Actor parent = subTreeActor.GetParent();
+  if( !parent || !( GetImplementation( subTreeActor ).RelayoutDependentOnParent() && GetImplementation( parent ).RelayoutRequired() ) )
+  {
+    // Add sub tree root to relayout list
+    AddRequest( subTreeActor );
+
+    // Flag request for end of frame
+    Request();
+  }
+  else
+  {
+    potentialRedundantSubRoots.push_back( subTreeActor );
+  }
+
+  // Remove any redundant sub-tree heads
+  for( ActorContainer::iterator it = potentialRedundantSubRoots.begin(), itEnd = potentialRedundantSubRoots.end(); it != itEnd; ++it )
+  {
+    Dali::Actor subRoot = *it;
+
+    RemoveRequest( subRoot );
+  }
+}
+
+void RelayoutController::OnApplicationSceneCreated()
+{
+  DALI_LOG_INFO( gLogFilter, Debug::General, "[Internal::RelayoutController::OnApplicationSceneCreated]\n" );
+
+  // Open relayout controller to receive relayout requests
+  mEnabled = true;
+
+  // Spread the dirty flag through whole tree - don't need to explicity
+  // add request on rootLayer as it will automatically be added below.
+  Dali::Actor rootLayer = Dali::Stage::GetCurrent().GetRootLayer();
+  RequestRelayoutTree( rootLayer );
+
+  // Flag request for end of frame
+  Request();
+}
+
+void RelayoutController::RequestRelayoutTree( Dali::Actor& actor )
+{
+  if( !mEnabled )
+  {
+    return;
+  }
+
+  // Only set dirty flag if doing relayout and not already marked as dirty
+  Actor& actorImpl = GetImplementation( actor );
+  if( actorImpl.RelayoutPossible() )
+  {
+    // If parent is not in relayout we are at the top of a new sub-tree
+    Dali::Actor parent = actor.GetParent();
+    if( !parent || !parent.IsRelayoutEnabled() )
+    {
+      AddRequest( actor );
+    }
+
+    // Set dirty flag on actors that are enabled
+    actorImpl.SetLayoutDirty( true );
+    actorImpl.SetLayoutNegotiated( false );    // Reset this flag ready for next relayout
+  }
+
+  // Propagate down to children
+  for( unsigned int i = 0; i < actor.GetChildCount(); ++i )
+  {
+    Dali::Actor child = actor.GetChildAt( i );
+
+    RequestRelayoutTree( child );
+  }
+}
+
+void RelayoutController::PropagateAll( Dali::Actor& actor, Dimension dimension, Dali::ActorContainer& topOfSubTreeStack, Dali::ActorContainer& potentialRedundantSubRoots )
+{
+  // Only set dirty flag if doing relayout and not already marked as dirty
+  Actor& actorImpl = GetImplementation( actor );
+  if( actorImpl.RelayoutPossible( dimension ) )
+  {
+    // Set dirty and negotiated flags
+    actorImpl.SetLayoutDirty( true, dimension );
+    actorImpl.SetLayoutNegotiated( false, dimension );    // Reset this flag ready for next relayout
+
+    // Check for dimension dependecy: width for height/height for width etc
+    // Check each possible dimension and see if it is dependent on the input one
+    for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+    {
+      Dimension dimensionToCheck = static_cast< Dimension >( 1 << i );
+
+      if( actorImpl.RelayoutDependentOnDimension( dimension, dimensionToCheck ) &&
+          !actorImpl.IsLayoutDirty( dimensionToCheck ) )
+      {
+        PropagateAll( actor, dimensionToCheck, topOfSubTreeStack, potentialRedundantSubRoots );
+      }
+    }
+
+    // Propagate up to parent
+    Dali::Actor parent = actor.GetParent();
+    if( parent )
+    {
+      Actor& parentImpl = GetImplementation( parent );
+      if( parentImpl.RelayoutDependentOnChildren( dimension ) && !parentImpl.IsLayoutDirty( dimension ) )
+      {
+        // Store the highest parent reached
+        bool found = false;
+        for( unsigned int i = 0, count = topOfSubTreeStack.size(); i < count; ++i )
+        {
+          if( topOfSubTreeStack[ i ] == parent )
+          {
+            found = true;
+            break;
+          }
+        }
+
+        if( !found )
+        {
+          topOfSubTreeStack.push_back( parent );
+        }
+
+        // Propagate up
+        PropagateAll( parent, dimension, topOfSubTreeStack, potentialRedundantSubRoots );
+      }
+    }
+
+    // Propagate down to children
+    for( unsigned int i = 0, childCount = actor.GetChildCount(); i < childCount; ++i )
+    {
+      Dali::Actor child = actor.GetChildAt( i );
+      Actor& childImpl = GetImplementation( child );
+
+      if( childImpl.IsRelayoutEnabled() && childImpl.RelayoutDependentOnParent( dimension ) )
+      {
+        if( childImpl.IsLayoutDirty( dimension ) )
+        {
+          // We have found a child that could potentially have already been collected for relayout
+          potentialRedundantSubRoots.push_back( child );
+        }
+        else
+        {
+          PropagateAll( child, dimension, topOfSubTreeStack, potentialRedundantSubRoots );
+        }
+      }
+    }
+  }
+}
+
+
+void RelayoutController::PropagateFlags( Dali::Actor& actor, Dimension dimension )
+{
+  // Only set dirty flag if doing relayout and not already marked as dirty
+  Actor& actorImpl = GetImplementation( actor );
+  if( actorImpl.IsRelayoutEnabled() )
+  {
+    // Set dirty and negotiated flags
+    actorImpl.SetLayoutDirty( true, dimension );
+    actorImpl.SetLayoutNegotiated( false, dimension );    // Reset this flag ready for next relayout
+
+    // Check for dimension dependecy: width for height/height for width etc
+    // Check each possible dimension and see if it is dependent on the input one
+    for( unsigned int i = 0; i < DIMENSION_COUNT; ++i )
+    {
+      Dimension dimensionToCheck = static_cast< Dimension >( 1 << i );
+
+      if( actorImpl.RelayoutDependentOnDimension( dimension, dimensionToCheck ) )
+      {
+        PropagateFlags( actor, dimensionToCheck );
+      }
+    }
+
+    // Propagate up to parent
+    Dali::Actor parent = actor.GetParent();
+    if( parent )
+    {
+      Actor& parentImpl = GetImplementation( parent );
+      if( parentImpl.RelayoutDependentOnChildren( dimension ) )
+      {
+        // Propagate up
+        PropagateFlags( parent, dimension );
+      }
+    }
+
+    // Propagate down to children
+    for( unsigned int i = 0, childCount = actor.GetChildCount(); i < childCount; ++i )
+    {
+      Dali::Actor child = actor.GetChildAt( i );
+      Actor& childImpl = GetImplementation( child );
+
+      if( childImpl.RelayoutDependentOnParent( dimension ) )
+      {
+        PropagateFlags( child, dimension );
+      }
+    }
+  }
+}
+
+void RelayoutController::AddRequest( Dali::Actor& actor )
+{
+  BaseObject* actorPtr = &GetImplementation( actor );
+
+  // Only add the rootActor if it is not already recorded
+  bool found = false;
+  for( unsigned int i = 0, count = mDirtyLayoutSubTrees.Size(); i < count; ++i )
+  {
+    if( mDirtyLayoutSubTrees[ i ] == actorPtr )
+    {
+      found = true;
+      break;
+    }
+  }
+
+  if( !found )
+  {
+    mDirtyLayoutSubTrees.PushBack( actorPtr );
+  }
+}
+
+void RelayoutController::RemoveRequest( Dali::Actor& actor )
+{
+  BaseObject* actorPtr = &GetImplementation( actor );
+
+  // Remove actor from dirty sub trees
+  for( RawActorList::Iterator it = mDirtyLayoutSubTrees.Begin(), itEnd = mDirtyLayoutSubTrees.End(); it != itEnd; ++it )
+  {
+    if( *it == actorPtr )
+    {
+      mDirtyLayoutSubTrees.Erase( it );
+      break;
+    }
+  }
+}
+
+void RelayoutController::Request()
+{
+  mRelayoutFlag = true;
+
+  if( !mRelayoutConnection )
+  {
+    Dali::Stage stage = Dali::Stage::GetCurrent();
+    stage.GetObjectRegistry().ObjectDestroyedSignal().Connect( mSlotDelegate, &RelayoutController::OnObjectDestroyed );
+
+    mRelayoutConnection = true;
+  }
+}
+
+void RelayoutController::OnObjectDestroyed( const Dali::RefObject* object )
+{
+  // Search for and null the object if found in the following lists
+  FindAndZero( mDirtyLayoutSubTrees, object );
+}
+
+void RelayoutController::Relayout()
+{
+  // Only do something when requested
+  if( mRelayoutFlag )
+  {
+    // Clear the flag as we're now doing the relayout
+    mRelayoutFlag = false;
+
+    // 1. Finds all top-level controls from the dirty list and allocate them the size of the stage
+    //    These controls are paired with the parent/stage size and added to the stack.
+    const Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
+
+    for( RawActorList::Iterator it = mDirtyLayoutSubTrees.Begin(), itEnd = mDirtyLayoutSubTrees.End(); it != itEnd; ++it )
+    {
+      BaseObject* dirtyActor = *it;
+
+      // Need to test if actor is valid (could have been deleted and had the pointer cleared)
+      if( dirtyActor )
+      {
+        // We know that BaseObject is a base class of Internal::Actor but need to instruct the compiler to do the cast
+        Dali::Actor actor = Dali::Actor( reinterpret_cast<Dali::Internal::Actor*>( dirtyActor ) );
+
+        // Only negotiate actors that are on stage
+        if( actor.OnStage() )
+        {
+          Dali::Actor parent = actor.GetParent();
+          QueueActor( actor, *mRelayoutStack, ( parent ) ? Vector2( parent.GetTargetSize() ) : stageSize );
+        }
+      }
+    }
+
+    mDirtyLayoutSubTrees.Clear();
+
+    // 2. Iterate through the stack until it's empty.
+    if( mRelayoutStack->Size() > 0 )
+    {
+      PRINT_HIERARCHY;
+
+      while( mRelayoutStack->Size() > 0 )
+      {
+        Dali::Actor actor;
+        Vector2 size;
+        mRelayoutStack->Get( mRelayoutStack->Size() - 1, actor, size );
+        Actor& actorImpl = GetImplementation( actor );
+        mRelayoutStack->PopBack();
+
+        if( actorImpl.RelayoutRequired() )
+        {
+          DALI_LOG_INFO( gLogFilter, Debug::General, "[Internal::RelayoutController::Relayout] Negotiating %p %s %s (%.2f, %.2f)\n", &actorImpl, actor.GetTypeName().c_str(), actor.GetName().c_str(), size.width, size.height );
+
+          // 3. Negotiate the size with the current actor. Pass it an empty container which the actor
+          //    has to fill with all the actors it has not done any size negotiation for.
+          actorImpl.NegotiateSize( size, *mRelayoutStack );
+        }
+      }
+
+      // We are done with the RelayoutInfos now so delete the pool
+      mRelayoutInfoAllocator.ResetMemoryPool();
+
+      PRINT_HIERARCHY;
+    }
+  }
+  // should not disconnect the signal as that causes some control size negotiations to not work correctly
+  // this algorithm needs more optimization as well
+}
+
+void RelayoutController::SetEnabled( bool enabled )
+{
+  mEnabled = enabled;
+}
+
+void RelayoutController::FindAndZero( const RawActorList& list, const Dali::RefObject* object )
+{
+  // Object has been destroyed so clear it from this list
+  for( RawActorList::Iterator it = list.Begin(), itEnd = list.End(); it != itEnd; ++it )
+  {
+    BaseObject* actor = *it;
+
+    if( actor && ( actor == object ) )
+    {
+      *it = NULL;    // Reset the pointer in the list. We don't want to remove it in case something is iterating over the list.
+    }
+  }
+}
+
+} // namespace Internal
+
+} // namespace Dali
diff --git a/dali/internal/event/size-negotiation/relayout-controller-impl.h b/dali/internal/event/size-negotiation/relayout-controller-impl.h
new file mode 100644 (file)
index 0000000..81b8dd2
--- /dev/null
@@ -0,0 +1,200 @@
+#ifndef __DALI_INTERNAL_RELAYOUT_CONTROLLER_IMPL_H__
+#define __DALI_INTERNAL_RELAYOUT_CONTROLLER_IMPL_H__
+
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/public-api/object/base-object.h>
+#include <dali/public-api/size-negotiation/relayout-container.h>
+
+#include <dali/internal/common/memory-pool-object-allocator.h>
+#include <dali/internal/event/size-negotiation/memory-pool-relayout-container.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+/**
+ * @brief The relayout controller is responsible for taking request from actors to relayout their sizes.
+ * The requests are actioned on at the end of the frame where all actors that have made a request are
+ * resized.
+ */
+class RelayoutController : public Dali::BaseObject
+{
+public:
+
+  /**
+   * @brief Constructor.
+   * We should only create a unique instance.
+   */
+  RelayoutController();
+
+  /**
+   * Destructor
+   */
+  virtual ~RelayoutController();
+
+  /**
+   * @brief Get the singleton of RelayoutController object.
+   *
+   * @return A handle to the RelayoutController control.
+   */
+  static RelayoutController* Get();
+
+  /**
+   * @brief Request to relayout the given actor and all sub-actors of it.
+   *
+   * This flags the actor and all actors dependent on it for relayout. The actual
+   * relayout is performed at the end of the frame. This means that multiple calls to relayout
+   * will not cause multiple relayouts to occur.
+   *
+   * @param[in] actor The actor to request relayout on
+   * @param[in] dimension The dimension(s) to request the relayout on. Defaults to all dimensions
+   */
+  void RequestRelayout( Dali::Actor& actor, Dimension dimension = ALL_DIMENSIONS );
+
+  /**
+   * @brief Request to relayout of all actors in the sub-tree below the given actor.
+   *
+   * This flags the actor and all actors below it for relayout. The actual
+   * relayout is performed at the end of the frame. This means that multiple calls to relayout
+   * will not cause multiple relayouts to occur.
+   *
+   * @param[in] actor The actor to request relayout on
+   */
+  void RequestRelayoutTree( Dali::Actor& actor );
+
+  /**
+   * @brief Force propagate relayout flags through the tree. This is similiar to Request Relayout
+   * except all dependencies have their flags reset in spite of whether they are all ready set.
+   *
+   * This is useful for resetting layout flags during the layout process.
+   *
+   * @param[in] actor The actor to propagate from
+   * @param[in] dimension The dimension to propagate on
+   */
+  void PropagateFlags( Dali::Actor& actor, Dimension dimension = ALL_DIMENSIONS );
+
+  /**
+   * @brief Relayouts all actors that have been marked as dirty
+   */
+  void Relayout();
+
+  /**
+   * @brief Enable/disable the controller
+   *
+   * @param[in] enabled Flag to indicate whether the controller should be enabled or disabled
+   */
+  void SetEnabled( bool enabled );
+
+public: // CALLBACKS
+
+  /**
+   * @brief Callback raised after the application creates the scene
+   */
+  void OnApplicationSceneCreated();
+
+  /**
+   * @brief Callback for when an object is destroyed
+   *
+   * @param[in] object The object being destroyed
+   */
+  void OnObjectDestroyed( const Dali::RefObject* object );
+
+private:
+
+  typedef Dali::Vector< BaseObject* > RawActorList;
+
+  /**
+   * @brief Request for relayout. Relays out whole scene.
+   */
+  void Request();
+
+  /**
+   * @brief Add actor to request list
+   *
+   * @param[in] actor The root of the sub tree to add
+   */
+  void AddRequest( Dali::Actor& actor );
+
+  /**
+   * @brief Remove actor from request list
+   *
+   * @param[in] actor The root of the sub tree to remove
+   */
+  void RemoveRequest( Dali::Actor& actor );
+
+  /**
+   * @brief Disconnect the Relayout() method from the Stage::EventProcessingFinishedSignal().
+   */
+  void Disconnect();
+
+  /**
+   * @brief Propagate dirty layout flags to actor and all sub-actors. This will stop propagating when a dirty actor
+   * is found.
+   *
+   * @param[in] actor The actor to propagate on
+   * @param[in] dimension The dimension to propagate on
+   * @param[in] topOfSubTreeStack The top of the sub tree that this actor is in
+   * @param[in] potentialRedundantSubRoots Actors collected as potentially already being included in relayout
+   */
+  void PropagateAll( Dali::Actor& actor, Dimension dimension, Dali::ActorContainer& topOfSubTreeStack, Dali::ActorContainer& potentialRedundantSubRoots );
+
+  /**
+   * Queue an actor on the relayout container
+   *
+   * @param[in] actor The actor to be queued
+   * @param[in] actors The container to add the actor to
+   * @param[in] size The size that this actor should be
+   */
+  void QueueActor( Dali::Actor& actor, RelayoutContainer& actors, Vector2 size );
+
+  /**
+   * @brief Find the given object in the list and null it out
+   *
+   * @param[in] list The list to search
+   * @param[in] object The object to search for
+   */
+  void FindAndZero( const RawActorList& list, const Dali::RefObject* object );
+
+  // Undefined
+  RelayoutController(const RelayoutController&);
+  RelayoutController& operator=(const RelayoutController&);
+
+private:
+
+  MemoryPoolObjectAllocator< MemoryPoolRelayoutContainer::RelayoutInfo > mRelayoutInfoAllocator;
+
+  SlotDelegate< RelayoutController > mSlotDelegate;
+
+  RawActorList mDirtyLayoutSubTrees;    ///< List of roots of sub trees that are dirty
+  MemoryPoolRelayoutContainer* mRelayoutStack;  ///< Stack for relayouting
+  bool mRelayoutConnection : 1;         ///< Whether EventProcessingFinishedSignal signal is connected.
+  bool mRelayoutFlag : 1;               ///< Relayout flag to avoid unnecessary calls
+  bool mEnabled : 1;                    ///< Initially disabled. Must be enabled at some point.
+
+};
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // __DALI_INTERNAL_RELAYOUT_CONTROLLER_IMPL_H__
index 215beaf..8204242 100644 (file)
@@ -95,6 +95,8 @@ internal_src_files = \
   $(internal_src_dir)/event/resources/resource-client.cpp \
   $(internal_src_dir)/event/resources/resource-ticket.cpp \
   $(internal_src_dir)/event/resources/resource-type-path.cpp \
+  $(internal_src_dir)/event/size-negotiation/memory-pool-relayout-container.cpp \
+  $(internal_src_dir)/event/size-negotiation/relayout-controller-impl.cpp \
   $(internal_src_dir)/event/text/character-impl.cpp \
   $(internal_src_dir)/event/text/glyph-metric.cpp \
   $(internal_src_dir)/event/text/font-layout.cpp \
index ee4a4af..bd0295f 100644 (file)
@@ -186,44 +186,6 @@ inline void UpdateNodeTransformValues( Node& node, int& nodeDirtyFlags, BufferIn
   // If the transform values need to be reinherited
   if( nodeDirtyFlags & TransformFlag )
   {
-    // Handle size relative to parent modes.
-    // This must be delt with before rotation/translation as otherwise anything
-    // anchored to a corner of this child would appear at the wrong position.
-    // The size dirty flag is modified if the size is being overridden.
-    // Note: Switch is in order of use-case commonality.
-    switch( node.GetSizeMode() )
-    {
-      case USE_OWN_SIZE:
-      {
-        // Completely ignore the parents size.
-        break;
-      }
-
-      case SIZE_EQUAL_TO_PARENT:
-      {
-        // Set the nodes size to that of the parent.
-        node.SetSize( updateBufferIndex, node.GetParent()->GetSize( updateBufferIndex ) );
-        nodeDirtyFlags |= SizeFlag;
-        break;
-      }
-
-      case SIZE_RELATIVE_TO_PARENT:
-      {
-        // Set the nodes size to the parents multiplied by a user defined value.
-        node.SetSize( updateBufferIndex, node.GetSizeModeFactor() * node.GetParent()->GetSize( updateBufferIndex ) );
-        nodeDirtyFlags |= SizeFlag;
-        break;
-      }
-
-      case SIZE_FIXED_OFFSET_FROM_PARENT:
-      {
-        // Set the nodes size to the parents plus a user defined value.
-        node.SetSize( updateBufferIndex, node.GetSizeModeFactor() + node.GetParent()->GetSize( updateBufferIndex ) );
-        nodeDirtyFlags |= SizeFlag;
-        break;
-      }
-    }
-
     // With a non-central anchor-point, the world rotation and scale affects the world position.
     // Therefore the world rotation & scale must be updated before the world position.
     if( node.IsOrientationInherited() )
index 6c2f437..c7a6ea2 100644 (file)
@@ -35,7 +35,6 @@ namespace SceneGraph
 
 const PositionInheritanceMode Node::DEFAULT_POSITION_INHERITANCE_MODE( INHERIT_PARENT_POSITION );
 const ColorMode Node::DEFAULT_COLOR_MODE( USE_OWN_MULTIPLY_PARENT_ALPHA );
-const SizeMode Node::DEFAULT_SIZE_MODE( USE_OWN_SIZE );
 
 Node* Node::New()
 {
@@ -62,7 +61,6 @@ Node::Node()
   mChildren(),
   mGeometryScale( Vector3::ONE ),
   mInitialVolume( Vector3::ONE ),
-  mSizeModeFactor( Vector3::ONE ),
   mDirtyFlags(AllFlags),
   mIsRoot( false ),
   mInheritOrientation( true ),
@@ -72,8 +70,7 @@ Node::Node()
   mIsActive( true ),
   mDrawMode( DrawMode::NORMAL ),
   mPositionInheritanceMode( DEFAULT_POSITION_INHERITANCE_MODE ),
-  mColorMode( DEFAULT_COLOR_MODE ),
-  mSizeMode( DEFAULT_SIZE_MODE )
+  mColorMode( DEFAULT_COLOR_MODE )
 {
 }
 
index 0102877..2b5bcf6 100644 (file)
@@ -95,7 +95,6 @@ public:
   // Defaults
   static const PositionInheritanceMode DEFAULT_POSITION_INHERITANCE_MODE;
   static const ColorMode DEFAULT_COLOR_MODE;
-  static const SizeMode DEFAULT_SIZE_MODE;
 
   // Creation methods
 
@@ -593,51 +592,6 @@ public:
   }
 
   /**
-   * @brief Defines how a child actor's size is affected by its parent's size.
-   * @param[in] mode The size relative to parent mode to use.
-   */
-  void SetSizeMode( SizeMode mode )
-  {
-    if ( mode != mSizeMode )
-    {
-      mSizeMode = mode;
-
-      SetDirtyFlag( TransformFlag );
-    }
-  }
-
-  /**
-   * Query how the child actor's size is affected by its parent's size.
-   * @return The size relative to parent mode in use.
-   */
-  SizeMode GetSizeMode() const
-  {
-    return mSizeMode;
-  }
-
-  /**
-   * Sets the factor of the parents size used for the child actor.
-   * Note: Only used for certain SizeModes.
-   * @param[in] factor The vector to multiply the parents size by to get the childs size.
-   */
-  void SetSizeModeFactor( const Vector3& factor )
-  {
-    mSizeModeFactor = factor;
-
-    SetDirtyFlag( TransformFlag );
-  }
-
-  /**
-   * Gets the factor of the parents size used for the child actor.
-   * Note: Only used for certain SizeModes.
-   * @return The vector being used to multiply the parents size by to get the childs size.
-   */
-  const Vector3& GetSizeModeFactor() const
-  {
-    return mSizeModeFactor;
-  }
-
-  /**
    * Set the initial volume of the node. Used for calculating geometry scaling
    * as the node size is changed  when transmitGeometryScaling is set to true.
    *
@@ -1124,7 +1078,6 @@ protected:
 
   Vector3             mGeometryScale;                ///< Applied before calculating world transform.
   Vector3             mInitialVolume;                ///< Initial volume... TODO - need a better name.
-  Vector3             mSizeModeFactor;               ///< Factor of parent size. Used for certain SizeModes.
 
   // flags, compressed to bitfield
   int  mDirtyFlags:10;                               ///< A composite set of flags for each of the Node properties
@@ -1139,7 +1092,6 @@ protected:
   DrawMode::Type          mDrawMode:2;               ///< How the Node and its children should be drawn
   PositionInheritanceMode mPositionInheritanceMode:2;///< Determines how position is inherited, 2 bits is enough
   ColorMode               mColorMode:2;              ///< Determines whether mWorldColor is inherited, 2 bits is enough
-  SizeMode                mSizeMode:2;               ///< Determines how the actors parent affects the actors size.
 
   // Changes scope, should be at end of class
   DALI_LOG_OBJECT_STRING_DECLARATION;
@@ -1158,28 +1110,6 @@ inline void SetInheritOrientationMessage( EventThreadServices& eventThreadServic
   new (slot) LocalType( &node, &Node::SetInheritOrientation, inherit );
 }
 
-inline void SetSizeModeMessage( EventThreadServices& eventThreadServices, const Node& node, SizeMode mode )
-{
-  typedef MessageValue1< Node, SizeMode > LocalType;
-
-  // Reserve some memory inside the message queue
-  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
-
-  // Construct message in the message queue memory; note that delete should not be called on the return value
-  new (slot) LocalType( &node, &Node::SetSizeMode, mode );
-}
-
-inline void SetSizeModeFactorMessage( EventThreadServices& eventThreadServices, const Node& node, const Vector3& factor )
-{
-  typedef MessageValue1< Node, Vector3 > LocalType;
-
-  // Reserve some memory inside the message queue
-  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
-
-  // Construct message in the message queue memory; note that delete should not be called on the return value
-  new (slot) LocalType( &node, &Node::SetSizeModeFactor, factor );
-}
-
 inline void SetInitialVolumeMessage( EventThreadServices& eventThreadServices, const Node& node, const Vector3& initialVolume )
 {
   typedef MessageValue1< Node, Vector3 > LocalType;
index 9cf5de1..77fd3a1 100644 (file)
@@ -52,11 +52,68 @@ enum PositionInheritanceMode
 enum SizeMode
 {
   USE_OWN_SIZE,                            ///< The mode is bypassed. The size Vector3 will be used as normal.
-  SIZE_EQUAL_TO_PARENT,                    ///< The actor will have the exact same size as the parent.
   SIZE_RELATIVE_TO_PARENT,                 ///< The actors size will be ( ParentSize * SizeRelativeToParentFactor ).
   SIZE_FIXED_OFFSET_FROM_PARENT            ///< The actors size will be ( ParentSize + SizeRelativeToParentFactor ).
 };
 
+/**
+ * @brief Dimensions for layout
+ */
+enum Dimension
+{
+  WIDTH  = 0x1,       ///< Width dimension
+  HEIGHT = 0x2,       ///< Height dimension
+
+  DIMENSION_COUNT = 2,  ///< Number of dimensions - update this if adding new dimension
+  ALL_DIMENSIONS = 0x3  ///< Mask to cover all flags
+};
+
+/**
+ * @brief Size negotiation resize policies
+ */
+enum ResizePolicy
+{
+  FIXED,                 ///< Size is fixed as set by SetSize
+  USE_NATURAL_SIZE,      ///< Size is to use the actor's natural size
+  USE_ASSIGNED_SIZE,     ///< The size will be assigned to the actor
+  FILL_TO_PARENT,        ///< Size is to fill up to the actor's parent's bounds. Aspect ratio not maintained.
+  FIT_TO_CHILDREN,       ///< Size will adjust to wrap around all children
+  DIMENSION_DEPENDENCY   ///< One dimension is dependent on the other
+};
+
+/**
+ * @brief Policies to determine how an actor should resize itself when having its size set in size negotiation
+ */
+enum SizeScalePolicy
+{
+  USE_SIZE_SET,                ///< Use the size that was set
+  FIT_WITH_ASPECT_RATIO,       ///< Fit within the size set maintaining natural size aspect ratio
+  FILL_WITH_ASPECT_RATIO       ///< Fill up the size set maintaining natural size aspect ratio. May exceed size bounds in one dimension.
+};
+
+/**
+ * @brief Different types of alignment.
+ */
+namespace HorizontalAlignment
+{
+enum Type
+{
+  LEFT,         ///< Align horizontally left
+  CENTER,       ///< Align horizontally center
+  RIGHT         ///< Align horiztonally right
+};
+}
+
+namespace VerticalAlignment
+{
+enum Type
+{
+  TOP,          ///< Align vertically top
+  CENTER,       ///< Align vertically center
+  BOTTOM        ///< Align vertically bottom
+};
+}
+
 } // namespace Dali
 
 #endif // __DALI_ACTOR_ENUMERATIONS_H__
index 38c93b0..51e84ae 100644 (file)
@@ -189,9 +189,9 @@ void Actor::SetSize(const Vector3& size)
   GetImplementation(*this).SetSize(size);
 }
 
-Vector3 Actor::GetSize() const
+Vector3 Actor::GetTargetSize() const
 {
-  return GetImplementation(*this).GetSize();
+  return GetImplementation(*this).GetTargetSize();
 }
 
 Vector3 Actor::GetCurrentSize() const
@@ -464,6 +464,135 @@ bool Actor::IsKeyboardFocusable() const
   return GetImplementation(*this).IsKeyboardFocusable();
 }
 
+void Actor::SetRelayoutEnabled( bool enabled )
+{
+  GetImplementation(*this).SetRelayoutEnabled( enabled );
+}
+
+bool Actor::IsRelayoutEnabled() const
+{
+  return GetImplementation(*this).IsRelayoutEnabled();
+}
+
+void Actor::SetResizePolicy( ResizePolicy policy, Dimension dimension )
+{
+  GetImplementation(*this).SetResizePolicy( policy, dimension );
+}
+
+ResizePolicy Actor::GetResizePolicy( Dimension dimension ) const
+{
+  return GetImplementation(*this).GetResizePolicy( dimension );
+}
+
+void Actor::SetSizeScalePolicy( SizeScalePolicy policy )
+{
+  GetImplementation(*this).SetSizeScalePolicy( policy );
+}
+
+SizeScalePolicy Actor::GetSizeScalePolicy() const
+{
+  return GetImplementation(*this).GetSizeScalePolicy();
+}
+
+void Actor::SetDimensionDependency( Dimension dimension, Dimension dependency )
+{
+  GetImplementation(*this).SetDimensionDependency( dimension, dependency );
+}
+
+Dimension Actor::GetDimensionDependency( Dimension dimension )
+{
+  return GetImplementation(*this).GetDimensionDependency( dimension );
+}
+
+float Actor::GetHeightForWidth( float width )
+{
+  return GetImplementation(*this).GetHeightForWidth( width );
+}
+
+float Actor::GetWidthForHeight( float height )
+{
+  return GetImplementation(*this).GetWidthForHeight( height );
+}
+
+float Actor::GetRelayoutSize( Dimension dimension ) const
+{
+  return GetImplementation(*this).GetRelayoutSize( dimension );
+}
+
+void Actor::RelayoutRequestTree()
+{
+  GetImplementation(*this).RelayoutRequestTree();
+}
+
+void Actor::PropagateRelayoutFlags()
+{
+  GetImplementation(*this).PropagateRelayoutFlags();
+}
+
+void Actor::SetPadding( const Padding& padding )
+{
+  Internal::Actor& impl = GetImplementation(*this);
+
+  Vector2 widthPadding( padding.left, padding.right );
+  impl.SetPadding( widthPadding, WIDTH );
+
+  Vector2 heightPadding( padding.bottom, padding.top );
+  impl.SetPadding( heightPadding, HEIGHT );
+}
+
+void Actor::GetPadding( Padding& paddingOut ) const
+{
+  const Internal::Actor& impl = GetImplementation(*this);
+
+  Vector2 widthPadding = impl.GetPadding( WIDTH );
+  Vector2 heightPadding = impl.GetPadding( HEIGHT );
+
+  paddingOut.left = widthPadding.x;
+  paddingOut.right = widthPadding.y;
+  paddingOut.bottom = heightPadding.x;
+  paddingOut.top = heightPadding.y;
+}
+
+void Actor::SetPreferredSize( const Vector2& size )
+{
+  GetImplementation(*this).SetPreferredSize( size );
+}
+
+Vector2 Actor::GetPreferredSize() const
+{
+  return GetImplementation(*this).GetPreferredSize();
+}
+
+void Actor::SetMinimumSize( const Vector2& size )
+{
+  Internal::Actor& impl = GetImplementation(*this);
+
+  impl.SetMinimumSize( size.x, WIDTH );
+  impl.SetMinimumSize( size.y, HEIGHT );
+}
+
+Vector2 Actor::GetMinimumSize()
+{
+  Internal::Actor& impl = GetImplementation(*this);
+
+  return Vector2( impl.GetMinimumSize( WIDTH ), impl.GetMinimumSize( HEIGHT ) );
+}
+
+void Actor::SetMaximumSize( const Vector2& size )
+{
+  Internal::Actor& impl = GetImplementation(*this);
+
+  impl.SetMaximumSize( size.x, WIDTH );
+  impl.SetMaximumSize( size.y, HEIGHT );
+}
+
+Vector2 Actor::GetMaximumSize()
+{
+  Internal::Actor& impl = GetImplementation(*this);
+
+  return Vector2( impl.GetMaximumSize( WIDTH ), impl.GetMaximumSize( HEIGHT ) );
+}
+
 Actor::TouchSignalType& Actor::TouchedSignal()
 {
   return GetImplementation(*this).TouchedSignal();
@@ -489,6 +618,11 @@ Actor::OffStageSignalType& Actor::OffStageSignal()
   return GetImplementation(*this).OffStageSignal();
 }
 
+Actor::OnRelayoutSignalType& Actor::OnRelayoutSignal()
+{
+  return GetImplementation(*this).OnRelayoutSignal();
+}
+
 Actor::Actor(Internal::Actor* internal)
 : Handle(internal)
 {
index 94640f4..4cc752d 100644 (file)
@@ -60,6 +60,7 @@ typedef std::vector<Actor> ActorContainer;
 typedef ActorContainer::iterator ActorIter; ///< Iterator for Dali::ActorContainer
 typedef ActorContainer::const_iterator ActorConstIter; ///< Const iterator for Dali::ActorContainer
 
+typedef Rect<float> Padding;      ///< Padding definition
 
 /**
  * @brief Actor is the primary object with which Dali applications interact.
@@ -295,6 +296,16 @@ public:
       DRAW_MODE,                                          ///< name "draw-mode",             type std::string
       SIZE_MODE,                                          ///< name "size-mode",             type std::string
       SIZE_MODE_FACTOR,                                   ///< name "size-mode-factor",      type Vector3
+      RELAYOUT_ENABLED,                                   ///< name "relayout-enabled",      type Boolean
+      WIDTH_RESIZE_POLICY,                                ///< name "width-resize-policy",   type String
+      HEIGHT_RESIZE_POLICY,                               ///< name "height-resize-policy",  type String
+      SIZE_SCALE_POLICY,                                  ///< name "size-scale-policy",     type String
+      WIDTH_FOR_HEIGHT,                                   ///< name "width-for-height",      type Boolean
+      HEIGHT_FOR_WIDTH,                                   ///< name "height-for-width",      type Boolean
+      PADDING,                                            ///< name "padding",               type Vector4
+      MINIMUM_SIZE,                                       ///< name "minimum-size",          type Vector2
+      MAXIMUM_SIZE,                                       ///< name "maximum-size",          type Vector2
+      PREFERRED_SIZE                                      ///< name "preferred-size",        type Vector2
     };
   };
 
@@ -305,6 +316,7 @@ public:
   typedef Signal< bool (Actor, const MouseWheelEvent&) > MouseWheelEventSignalType; ///< Mousewheel signal type
   typedef Signal< void (Actor) > OnStageSignalType;  ///< Stage connection signal type
   typedef Signal< void (Actor) > OffStageSignalType; ///< Stage disconnection signal type
+  typedef Signal< void (Actor) > OnRelayoutSignalType; ///< Called when the actor is relaid out
 
   // Creation
 
@@ -621,7 +633,7 @@ public:
    * @note This return is the value that was set using SetSize or the target size of an animation
    * @return The actor's current size.
    */
-  Vector3 GetSize() const;
+  Vector3 GetTargetSize() const;
 
   /**
    * @brief Retrieve the actor's size.
@@ -912,58 +924,6 @@ public:
   bool IsScaleInherited() const;
 
   /**
-   * @brief Defines how a child actor's size is affected by its parent's size.
-   *
-   * The default is to ignore the parent's size and use the size property of this actor.
-   *
-   * If USE_OWN_SIZE is used, this option is bypassed and the actor's size
-   *     property is used.
-   *
-   * If SIZE_EQUAL_TO_PARENT is used, this actor's size will be equal to that
-   *     of its parent. The actor's size property is ignored.
-   *
-   * If SIZE_RELATIVE_TO_PARENT is used, this actor's size will be based on
-   *     its parent's size by multiplying the parent size by
-   *     SizeModeFactor.
-   *
-   * If SIZE_FIXED_OFFSET_FROM_PARENT is used, this actor's size will be based on
-   *     its parent's size plus SizeModeFactor.
-   *
-   * @pre The Actor has been initialized.
-   * @param[in] mode The size relative to parent mode to use.
-   */
-  void SetSizeMode(const SizeMode mode);
-
-  /**
-   * @brief Returns the actor's mode for modifying its size relative to its parent.
-   *
-   * @pre The Actor has been initialized.
-   * @return The mode used.
-   */
-  SizeMode GetSizeMode() const;
-
-  /**
-   * @brief Sets the relative to parent size factor of the actor.
-   *
-   * This factor is only used when SizeMode is set to either:
-   * SIZE_RELATIVE_TO_PARENT or SIZE_FIXED_OFFSET_FROM_PARENT.
-   * This actor's size is set to the actor's parent size multipled by or added to this factor,
-   * depending on SideMode (See SetSizeMode).
-   *
-   * @pre The Actor has been initialized.
-   * @param [in] factor A Vector3 representing the relative factor to be applied to each axis.
-   */
-  void SetSizeModeFactor(const Vector3& factor);
-
-  /**
-   * @brief Retrieve the relative to parent size factor of the actor.
-   *
-   * @pre The Actor has been initialized.
-   * @return The Actor's current relative size factor.
-   */
-  Vector3 GetSizeModeFactor() const;
-
-  /**
    * @brief Retrieves the world-matrix of the actor.
    *
    * @note The actor will not have a world-matrix, unless it has previously been added to the stage.
@@ -1183,6 +1143,215 @@ public:
    */
   bool IsKeyboardFocusable() const;
 
+  // SIZE NEGOTIATION
+
+  /**
+   * @brief Set if the actor should do relayout in size negotiation or not.
+   *
+   * @param[in] enabled Flag to specify if actor should do relayout or not.
+   */
+  void SetRelayoutEnabled( bool enabled );
+
+  /**
+   * @brief Is the actor included in relayout or not.
+   *
+   * @return Return if the actor is involved in size negotiation or not.
+   */
+  bool IsRelayoutEnabled() const;
+
+  /**
+   * Set the resize policy to be used for the given dimension(s)
+   *
+   * @param[in] policy The resize policy to use
+   * @param[in] dimension The dimension(s) to set policy for. Can be a bitfield of multiple dimensions.
+   */
+  void SetResizePolicy( ResizePolicy policy, Dimension dimension );
+
+  /**
+   * Return the resize policy used for a single dimension
+   *
+   * @param[in] dimension The dimension to get policy for
+   * @return Return the dimension resize policy
+   */
+  ResizePolicy GetResizePolicy( Dimension dimension ) const;
+
+  /**
+   * @brief Set the policy to use when setting size with size negotiation. Defaults to USE_SIZE_SET.
+   *
+   * @param[in] policy The policy to use for when the size is set
+   */
+  void SetSizeScalePolicy( SizeScalePolicy policy );
+
+  /**
+   * @brief Return the size set policy in use
+   *
+   * @return Return the size set policy
+   */
+  SizeScalePolicy GetSizeScalePolicy() const;
+
+  /**
+   * @brief Defines how a child actor's size is affected by its parent's size.
+   *
+   * The default is to ignore the parent's size and use the size property of this actor.
+   *
+   * If USE_OWN_SIZE is used, this option is bypassed and the actor's size
+   *     property is used.
+   *
+   * If SIZE_RELATIVE_TO_PARENT is used, this actor's size will be based on
+   *     its parent's size by multiplying the parent size by
+   *     SizeModeFactor.
+   *
+   * If SIZE_FIXED_OFFSET_FROM_PARENT is used, this actor's size will be based on
+   *     its parent's size plus SizeModeFactor.
+   *
+   * @pre The Actor has been initialized.
+   * @param[in] mode The size relative to parent mode to use.
+   */
+  void SetSizeMode( const SizeMode mode );
+
+  /**
+   * @brief Returns the actor's mode for modifying its size relative to its parent.
+   *
+   * @pre The Actor has been initialized.
+   * @return The mode used.
+   */
+  SizeMode GetSizeMode() const;
+
+  /**
+   * @brief Sets the relative to parent size factor of the actor.
+   *
+   * This factor is only used when SizeMode is set to either:
+   * SIZE_RELATIVE or SIZE_FIXED_OFFSET.
+   * This actor's size is set to the actor's size multipled by or added to this factor,
+   * depending on SideMode (See SetSizeMode).
+   *
+   * @pre The Actor has been initialized.
+   * @param [in] factor A Vector3 representing the relative factor to be applied to each axis.
+   */
+  void SetSizeModeFactor( const Vector3& factor );
+
+  /**
+   * @brief Retrieve the relative to parent size factor of the actor.
+   *
+   * @pre The Actor has been initialized.
+   * @return The Actor's current relative size factor.
+   */
+  Vector3 GetSizeModeFactor() const;
+
+  /**
+   * @brief This method specifies a dependency between dimensions. Will set resize policy on the actor for
+   * the given dimension to be DIMENSION_DEPENDENCY.
+   *
+   * @param[in] dimension The dimension to set the dependency on
+   * @param[in] dependency The dependency to set on the dimension
+   */
+  void SetDimensionDependency( Dimension dimension, Dimension dependency );
+
+  /**
+   * @brief Return the dependecy for a dimension
+   *
+   * @param[in] dimension The dimension to return the dependency for
+   * @return Return the dependency
+   */
+  Dimension GetDimensionDependency( Dimension dimension );
+
+  /**
+   * @brief Calculate the height of the actor given a width
+   *
+   * @param width Width to use
+   * @return Return the height based on the width
+   */
+  float GetHeightForWidth( float width );
+
+  /**
+   * @brief Calculate the width of the actor given a height
+   *
+   * @param height Height to use
+   * @return Return the width based on the height
+   */
+  float GetWidthForHeight( float height );
+
+  /**
+   * Return the value of negotiated dimension for the given dimension
+   *
+   * @param dimension The dimension to retrieve
+   * @return Return the value of the negotiated dimension
+   */
+  float GetRelayoutSize( Dimension dimension ) const;
+
+  /**
+   * @brief Request to relayout of all actors in the sub-tree below the given actor.
+   *
+   * This flags the actor and all actors below it for relayout. The actual
+   * relayout is performed at the end of the frame. This means that multiple calls to relayout
+   * will not cause multiple relayouts to occur.
+   */
+  void RelayoutRequestTree();
+
+  /**
+   * @brief Force propagate relayout flags through the tree. This actor and all actors
+   * dependent on it will have their relayout flags reset.
+   *
+   * This is useful for resetting layout flags during the layout process.
+   */
+  void PropagateRelayoutFlags();
+
+  /**
+   * @brief Set the padding for use in layout
+   *
+   * @param[in] padding Padding for the actor
+   */
+  void SetPadding( const Padding& padding );
+
+  /**
+   * Return the value of the padding
+   *
+   * @param paddingOut The returned padding data
+   */
+  void GetPadding( Padding& paddingOut ) const;
+
+  /**
+   * @brief Set the preferred size for size negotiation
+   *
+   * @param[in] size The preferred size to set
+   */
+  void SetPreferredSize( const Vector2& size );
+
+  /**
+   * @brief Return the preferred size used for size negotiation
+   *
+   * @return Return the preferred size
+   */
+  Vector2 GetPreferredSize() const;
+
+  /**
+   * @brief Set the minimum size an actor can be assigned in size negotiation
+   *
+   * @param[in] size The minimum size
+   */
+  void SetMinimumSize( const Vector2& size );
+
+  /**
+   * @brief Return the minimum relayout size
+   *
+   * @return Return the mininmum size
+   */
+  Vector2 GetMinimumSize();
+
+  /**
+   * @brief Set the maximum size an actor can be assigned in size negotiation
+   *
+   * @param[in] size The maximum size
+   */
+  void SetMaximumSize( const Vector2& size );
+
+  /**
+   * @brief Return the maximum relayout size
+   *
+   * @return Return the maximum size
+   */
+  Vector2 GetMaximumSize();
+
 public: // Signals
 
   /**
@@ -1268,6 +1437,13 @@ public: // Signals
    */
   OffStageSignalType& OffStageSignal();
 
+  /**
+   * @brief This signal is emitted after the size has been set on the actor during relayout
+   *
+   * @return Return the signal
+   */
+  OnRelayoutSignalType& OnRelayoutSignal();
+
 public: // Not intended for application developers
 
   /**
index d27d22f..557d94e 100644 (file)
@@ -83,4 +83,19 @@ void CustomActorImpl::SetRequiresMouseWheelEvents(bool requiresMouseWheelEvents)
   mRequiresMouseWheelEvents = requiresMouseWheelEvents;
 }
 
+void CustomActorImpl::RelayoutRequest()
+{
+  mOwner->RelayoutRequest();
+}
+
+float CustomActorImpl::CalculateChildSizeBase( const Dali::Actor& child, Dimension dimension )
+{
+  return mOwner->CalculateChildSizeBase( child, dimension );
+}
+
+bool CustomActorImpl::RelayoutDependentOnChildrenBase( Dimension dimension )
+{
+  return mOwner->RelayoutDependentOnChildrenBase( dimension );
+}
+
 } // namespace Dali
index aa88262..654f557 100644 (file)
@@ -22,6 +22,7 @@
 #include <dali/public-api/common/vector-wrapper.h>
 #include <dali/public-api/object/property.h>
 #include <dali/public-api/object/ref-object.h>
+#include <dali/public-api/actors/actor-enumerations.h>
 
 namespace Dali
 {
@@ -35,12 +36,15 @@ class Actor;
 class Animation;
 class CustomActor;
 class CustomActorImpl;
+class RelayoutContainer;
 struct KeyEvent;
 struct TouchEvent;
 struct HoverEvent;
 struct MouseWheelEvent;
+struct Vector2;
 struct Vector3;
 
+
 /**
  * @brief Pointer to Dali::CustomActorImpl object.
  */
@@ -178,12 +182,92 @@ public:
   virtual bool OnMouseWheelEvent(const MouseWheelEvent& event) = 0;
 
   /**
+   * @brief Called after the size negotiation has been finished for this control.
+   *
+   * The control is expected to assign this given size to itself/its children.
+   *
+   * Should be overridden by derived classes if they need to layout
+   * actors differently after certain operations like add or remove
+   * actors, resize or after changing specific properties.
+   *
+   * Note! As this function is called from inside the size negotiation algorithm, you cannot
+   * call RequestRelayout (the call would just be ignored)
+   *
+   * @param[in]      size       The allocated size.
+   * @param[in,out]  container  The control should add actors to this container that it is not able
+   *                            to allocate a size for.
+   */
+  virtual void OnRelayout( const Vector2& size, RelayoutContainer& container ) = 0;
+
+  /**
+   * @brief Notification for deriving classes
+   *
+   * @param[in] policy The policy being set
+   * @param[in] dimension The dimension the policy is being set for
+   */
+  virtual void OnSetResizePolicy( ResizePolicy policy, Dimension dimension ) = 0;
+
+  /**
    * Return the natural size of the actor
    *
    * @return The actor's natural size
    */
   virtual Vector3 GetNaturalSize() = 0;
 
+  /**
+   * @brief Calculate the size for a child
+   *
+   * @param[in] child The child actor to calculate the size for
+   * @param[in] dimension The dimension to calculate the size for. E.g. width or height.
+   * @return Return the calculated size for the given dimension
+   */
+  virtual float CalculateChildSize( const Dali::Actor& child, Dimension dimension ) = 0;
+
+  /**
+   * @brief This method is called during size negotiation when a height is required for a given width.
+   *
+   * Derived classes should override this if they wish to customize the height returned.
+   *
+   * @param width to use.
+   * @return the height based on the width.
+   */
+  virtual float GetHeightForWidth( float width ) = 0;
+
+  /**
+   * @brief This method is called during size negotiation when a width is required for a given height.
+   *
+   * Derived classes should override this if they wish to customize the width returned.
+   *
+   * @param height to use.
+   * @return the width based on the width.
+   */
+  virtual float GetWidthForHeight( float height ) = 0;
+
+  /**
+   * @brief Determine if this actor is dependent on it's children for relayout
+   *
+   * @param dimension The dimension(s) to check for
+   * @return Return if the actor is dependent on it's children
+   */
+  virtual bool RelayoutDependentOnChildren( Dimension dimension = ALL_DIMENSIONS ) = 0;
+
+  /**
+   * @brief Virtual method to notify deriving classes that relayout dependencies have been
+   * met and the size for this object is about to be calculated for the given dimension
+   *
+   * @param dimension The dimension that is about to be calculated
+   */
+  virtual void OnCalculateRelayoutSize( Dimension dimension ) = 0;
+
+  /**
+   * @brief Virtual method to notify deriving classes that the size for a dimension
+   * has just been negotiated
+   *
+   * @param[in] size The new size for the given dimension
+   * @param[in] dimension The dimension that was just negotiated
+   */
+  virtual void OnLayoutNegotiated( float size, Dimension dimension ) = 0;
+
 protected: // For derived classes
 
   /**
@@ -204,6 +288,35 @@ protected: // For derived classes
    */
   void SetRequiresMouseWheelEvents(bool requiresMouseWheelEvents);
 
+  /**
+   * @brief Request a relayout, which means performing a size negotiation on this actor, its parent and children (and potentially whole scene)
+   *
+   * This method can also be called from a derived class every time it needs a different size.
+   * At the end of event processing, the relayout process starts and
+   * all controls which requested Relayout will have their sizes (re)negotiated.
+   *
+   * @note RelayoutRequest() can be called multiple times; the size negotiation is still
+   * only performed once, i.e. there is no need to keep track of this in the calling side.
+   */
+  void RelayoutRequest();
+
+  /**
+   * @brief Calculate the size for a child using the base actor object
+   *
+   * @param[in] child The child actor to calculate the size for
+   * @param[in] dimension The dimension to calculate the size for. E.g. width or height.
+   * @return Return the calculated size for the given dimension
+   */
+  float CalculateChildSizeBase( const Dali::Actor& child, Dimension dimension );
+
+  /**
+   * @brief Determine if this actor is dependent on it's children for relayout from the base class
+   *
+   * @param dimension The dimension(s) to check for
+   * @return Return if the actor is dependent on it's children
+   */
+  bool RelayoutDependentOnChildrenBase( Dimension dimension = ALL_DIMENSIONS );
+
 public: // Not intended for application developers
 
   /**
index b148eaa..032e4bc 100644 (file)
 
 #include <dali/public-api/shader-effects/shader-effect.h>
 
+#include <dali/public-api/size-negotiation/relayout-container.h>
+
 #include <dali/public-api/text/font-parameters.h>
 #include <dali/public-api/text/font.h>
 #include <dali/public-api/text/text-actor-parameters.h>
index 956123f..d7a7721 100644 (file)
@@ -264,6 +264,9 @@ public_api_core_shader_effects_header_files = \
 public_api_core_scripting_header_files = \
   $(public_api_src_dir)/scripting/scripting.h
 
+public_api_core_size_negotiation_header_files = \
+  $(public_api_src_dir)/size-negotiation/relayout-container.h
+
 public_api_core_signals_header_files = \
   $(public_api_src_dir)/signals/base-signal.h \
   $(public_api_src_dir)/signals/callback.h \
index 89e815c..e51fd88 100644 (file)
@@ -50,10 +50,10 @@ struct Rect
   /**
    * @brief Constructor.
    *
-   * @param [in] x       x coordinate
-   * @param [in] y       y coordinate
-   * @param [in] width   width
-   * @param [in] height  height
+   * @param [in] x       x coordinate (or left)
+   * @param [in] y       y coordinate (or right)
+   * @param [in] width   width (or bottom)
+   * @param [in] height  height (or top)
    */
   Rect(T x, T y, T width, T height)
   : x(x),
@@ -201,10 +201,29 @@ struct Rect
 
 public:   // Data
 
-  T x;      ///< X position of the rectangle
-  T y;      ///< Y position of the rectangle
-  T width;  ///< width of the rectangle
-  T height; ///< height of the rectangle
+  union
+  {
+    T x;      ///< X position of the rectangle
+    T left;   ///< The left value
+  };
+
+  union
+  {
+    T y;      ///< Y position of the rectangle
+    T right;  ///< The right value
+  };
+
+  union
+  {
+    T width;  ///< width of the rectangle
+    T bottom; ///< The bottom value
+  };
+
+  union
+  {
+    T height; ///< height of the rectangle
+    T top;    ///< The top value
+  };
 };
 
 /**
diff --git a/dali/public-api/size-negotiation/relayout-container.h b/dali/public-api/size-negotiation/relayout-container.h
new file mode 100644 (file)
index 0000000..4017ac3
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef __DALI_RELAYOUT_CONTAINER_H__
+#define __DALI_RELAYOUT_CONTAINER_H__
+
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/actors/actor.h>
+#include <dali/public-api/math/vector2.h>
+
+namespace Dali
+{
+
+class RelayoutContainer;
+typedef RelayoutContainer* RelayoutContainerPtr;
+
+
+/**
+ * @brief Interface to encapsulate information required for relayout
+ */
+class RelayoutContainer
+{
+public:
+
+  /**
+   * @brief Default constructor
+   *
+   */
+  RelayoutContainer() {}
+
+  /**
+   * @brief Virtual destructor
+   */
+  virtual ~RelayoutContainer() {}
+
+  /**
+   * @brief Add relayout information to the container if it does'nt already exist
+   *
+   * @param actor The actor to relayout
+   * @param size The size to relayout
+   */
+  virtual void Add( const Actor& actor, const Vector2& size ) = 0;
+
+};
+
+} // namespace Dali
+
+#endif // __DALI_RELAYOUT_CONTAINER_H__