[Tizen] Add FlexLayout. 48/181448/1
authorAnton Obzhirov <a.obzhirov@samsung.com>
Thu, 24 May 2018 10:15:46 +0000 (11:15 +0100)
committerSeoyeon Kim <seoyeon2.kim@samsung.com>
Thu, 14 Jun 2018 04:59:41 +0000 (13:59 +0900)
Change-Id: Ib8aff13cf5b3ecc93eb0826b3c4ef47c39b6efb2

automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/layout-utils.cpp [new file with mode: 0755]
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/layout-utils.h [new file with mode: 0644]
automated-tests/src/dali-toolkit/utc-Dali-FlexLayout.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp
dali-toolkit/devel-api/file.list
dali-toolkit/devel-api/layouting/flex-layout.cpp [new file with mode: 0644]
dali-toolkit/devel-api/layouting/flex-layout.h [new file with mode: 0644]
dali-toolkit/internal/file.list
dali-toolkit/internal/layouting/flex-layout-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/layouting/flex-layout-impl.h [new file with mode: 0644]

index c32c8c2..881aec8 100755 (executable)
@@ -7,7 +7,6 @@ SET(CAPI_LIB "dali-toolkit")
 
 # List of test case sources (Only these get parsed for test cases)
 SET(TC_SOURCES
-  utc-Dali-Layouting.cpp
   utc-Dali-Alignment.cpp
   utc-Dali-AnimatedImageVisual.cpp
   utc-Dali-BloomView.cpp
@@ -18,11 +17,13 @@ SET(TC_SOURCES
   utc-Dali-CubeTransitionEffect.cpp
   utc-Dali-EffectsView.cpp
   utc-Dali-FlexContainer.cpp
+  utc-Dali-FlexLayout.cpp
   utc-Dali-GaussianBlurView.cpp
   utc-Dali-ImageView.cpp
   utc-Dali-ImageVisual.cpp
   utc-Dali-JsonParser.cpp
   utc-Dali-KeyInputFocusManager.cpp
+  utc-Dali-Layouting.cpp
   utc-Dali-PageTurnView.cpp
   utc-Dali-Script.cpp
   utc-Dali-ScrollBar.cpp
@@ -90,6 +91,7 @@ LIST(APPEND TC_SOURCES
   dali-toolkit-test-utils/toolkit-web-view-lite.cpp
   dali-toolkit-test-utils/dali-test-suite-utils.cpp
   dali-toolkit-test-utils/dummy-control.cpp
+  dali-toolkit-test-utils/layout-utils.cpp
   dali-toolkit-test-utils/mesh-builder.cpp
   dali-toolkit-test-utils/test-actor-utils.cpp
   dali-toolkit-test-utils/test-animation-data.cpp
diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/layout-utils.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/layout-utils.cpp
new file mode 100755 (executable)
index 0000000..54ff302
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2018 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 "layout-utils.h"
+
+// EXTERNAL INCLUDES
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
+#include <dali-toolkit/devel-api/image-loader/texture-manager.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/layouting/flex-layout.h>
+
+// INTERNAL INCLUDES
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+Control CreateLeafControl( int width, int height )
+{
+  auto control = Control::New();
+  control.SetName( "Leaf" );
+
+  auto pixelBuffer = Devel::PixelBuffer::New( 1, 1, Pixel::RGB888 );
+  unsigned char* pixels = pixelBuffer.GetBuffer();
+  pixels[0] = 0xff;
+  pixels[1] = 0x00;
+  pixels[2] = 0x00;
+  auto texture = Texture::New( TextureType::TEXTURE_2D, Pixel::RGB888, 1, 1 );
+  auto pixelData = Devel::PixelBuffer::Convert( pixelBuffer );
+  texture.Upload( pixelData );
+  std::string url = TextureManager::AddTexture( texture );
+
+  Property::Map map;
+  map[ Visual::Property::TYPE ] = Visual::IMAGE;
+  map[ ImageVisual::Property::URL ] = url;
+  map[ ImageVisual::Property::DESIRED_WIDTH ] = (float) width;
+  map[ ImageVisual::Property::DESIRED_HEIGHT ] = (float) height;
+  control.SetProperty( Control::Property::BACKGROUND, map );
+  return control;
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/layout-utils.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/layout-utils.h
new file mode 100644 (file)
index 0000000..c0ef58f
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef __DALI_TOOLKIT_LAYOUT_UTILS_H__
+#define __DALI_TOOLKIT_LAYOUT_UTILS_H__
+
+/*
+ * Copyright (c) 2018 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 <dali-toolkit/dali-toolkit.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+/**
+ * @brief Creates an empty leaf control filled with red color for layout tests
+ *
+ * @param[in] width The width of the control.
+ * @param[in] height The height of the control.
+ * @param[out] Control The control.
+ */
+Control CreateLeafControl( int width, int height );
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_LAYOUT_UTILS_H__
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-FlexLayout.cpp b/automated-tests/src/dali-toolkit/utc-Dali-FlexLayout.cpp
new file mode 100644 (file)
index 0000000..8317361
--- /dev/null
@@ -0,0 +1,718 @@
+/*
+ * Copyright (c) 2018 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-toolkit-test-suite-utils.h>
+
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/layouting/flex-layout.h>
+
+#include <layout-utils.h>
+
+using namespace Dali;
+using namespace Toolkit;
+
+void utc_dali_toolkit_flexlayout_startup(void)
+{
+  test_return_value = TET_UNDEF;
+}
+
+void utc_dali_toolkit_flexlayout_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
+int UtcDaliLayouting_FlexLayout01(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_FlexLayout01");
+
+  Stage stage = Stage::GetCurrent();
+  auto flexBox = Control::New();
+  auto flexLayout = FlexLayout::New();
+  flexLayout.SetFlexDirection( Dali::Toolkit::FlexLayout::FlexDirection::ROW );
+  flexLayout.SetFlexItemsAlignment( Dali::Toolkit::FlexLayout::Alignment::CENTER );
+  DevelControl::SetLayout( flexBox, flexLayout );
+  flexBox.SetName( "Flexbox");
+
+  std::vector< Control > controls;
+  controls.push_back( CreateLeafControl( 40, 40 ) );
+  controls.push_back( CreateLeafControl( 60, 60 ) );
+  controls.push_back( CreateLeafControl( 80, 80 ) );
+  controls.push_back( CreateLeafControl( 100, 100 ) );
+
+  const Extents CONTROL_MARGIN = Extents( 0, 10, 0, 0 );
+  for( auto&& iter : controls )
+  {
+    iter.SetProperty(Toolkit::Control::Property::MARGIN, CONTROL_MARGIN );
+    flexBox.Add( iter );
+  }
+  flexBox.SetParentOrigin( ParentOrigin::CENTER );
+  flexBox.SetAnchorPoint( AnchorPoint::CENTER );
+  stage.Add( flexBox );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  // To see goto https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjIsImFsaWduQ29udGVudCI6MSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfSwiZmxleFdyYXAiOjEsImNoaWxkcmVuIjpbeyJ3aWR0aCI6IjQwIiwiaGVpZ2h0IjoiNDAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsInBhZGRpbmciOnsidG9wIjoiIiwicmlnaHQiOiIiLCJib3R0b20iOiIiLCJsZWZ0IjoiIn0sIm1hcmdpbiI6eyJyaWdodCI6IjEwIn0sInBvc2l0aW9uIjp7InRvcCI6bnVsbCwicmlnaHQiOm51bGwsImJvdHRvbSI6bnVsbCwibGVmdCI6bnVsbH19LHsid2lkdGgiOiI2MCIsImhlaWdodCI6IjYwIiwibWluV2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1heEhlaWdodCI6bnVsbCwiYWxpZ25JdGVtcyI6MCwiYWxpZ25Db250ZW50IjowLCJwYWRkaW5nIjp7InRvcCI6IiIsInJpZ2h0IjoiIiwiYm90dG9tIjoiIiwibGVmdCI6IiJ9LCJtYXJnaW4iOnsicmlnaHQiOiIxMCJ9LCJwb3NpdGlvbiI6eyJ0b3AiOm51bGwsInJpZ2h0IjpudWxsLCJib3R0b20iOm51bGwsImxlZnQiOm51bGx9fSx7IndpZHRoIjoiODAiLCJoZWlnaHQiOiI4MCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjAsImFsaWduQ29udGVudCI6MCwicGFkZGluZyI6eyJ0b3AiOiIiLCJyaWdodCI6IiIsImJvdHRvbSI6IiIsImxlZnQiOiIifSwibWFyZ2luIjp7InJpZ2h0IjoiMTAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX0seyJ3aWR0aCI6MTAwLCJoZWlnaHQiOjEwMCwibWluV2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1heEhlaWdodCI6bnVsbCwiYWxpZ25JdGVtcyI6MCwiYWxpZ25Db250ZW50IjowLCJwYWRkaW5nIjp7InRvcCI6IiIsInJpZ2h0IjoiIiwiYm90dG9tIjoiIiwibGVmdCI6IiJ9LCJtYXJnaW4iOnsicmlnaHQiOiIxMCJ9LCJwb3NpdGlvbiI6eyJ0b3AiOm51bGwsInJpZ2h0IjpudWxsLCJib3R0b20iOm51bGwsImxlZnQiOm51bGx9fV19
+  DALI_TEST_EQUALS( flexBox.GetProperty<Vector3>(Actor::Property::POSITION), Vector3( 0, 0, 0 ),TEST_LOCATION);
+  DALI_TEST_EQUALS( flexBox.GetProperty<Vector3>(Actor::Property::SIZE), Vector3( 480, 800, 0 ),TEST_LOCATION);
+
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 50.0f, 370.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 120.0f, 360.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 210.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 80.0f, 80.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  const Extents CONTROL_PADDING = Extents( 5, 10, 15, 15 );
+  for( auto&& iter : controls )
+  {
+    iter.SetProperty(Toolkit::Control::Property::PADDING, CONTROL_PADDING );
+    flexBox.Add( iter );
+  }
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  // To see go to https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjIsImFsaWduQ29udGVudCI6MSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfSwiZmxleFdyYXAiOjEsImNoaWxkcmVuIjpbeyJ3aWR0aCI6IjQwIiwiaGVpZ2h0IjoiNDAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsInBhZGRpbmciOnsidG9wIjoiMTUiLCJyaWdodCI6IjEwIiwiYm90dG9tIjoiMTUiLCJsZWZ0IjoiNSJ9LCJtYXJnaW4iOnsicmlnaHQiOiIxMCJ9LCJwb3NpdGlvbiI6eyJ0b3AiOm51bGwsInJpZ2h0IjpudWxsLCJib3R0b20iOm51bGwsImxlZnQiOm51bGx9fSx7IndpZHRoIjoiNjAiLCJoZWlnaHQiOiI2MCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjAsImFsaWduQ29udGVudCI6MCwicGFkZGluZyI6eyJ0b3AiOiIxNSIsInJpZ2h0IjoiMTAiLCJib3R0b20iOiIxNSIsImxlZnQiOiI1In0sIm1hcmdpbiI6eyJyaWdodCI6IjEwIn0sInBvc2l0aW9uIjp7InRvcCI6bnVsbCwicmlnaHQiOm51bGwsImJvdHRvbSI6bnVsbCwibGVmdCI6bnVsbH19LHsid2lkdGgiOiI4MCIsImhlaWdodCI6IjgwIiwibWluV2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1heEhlaWdodCI6bnVsbCwiYWxpZ25JdGVtcyI6MCwiYWxpZ25Db250ZW50IjowLCJwYWRkaW5nIjp7InRvcCI6IjE1IiwicmlnaHQiOiIxMCIsImJvdHRvbSI6IjE1IiwibGVmdCI6IjUifSwibWFyZ2luIjp7InJpZ2h0IjoiMTAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX0seyJ3aWR0aCI6MTAwLCJoZWlnaHQiOjEwMCwibWluV2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1heEhlaWdodCI6bnVsbCwiYWxpZ25JdGVtcyI6MCwiYWxpZ25Db250ZW50IjowLCJwYWRkaW5nIjp7InRvcCI6IjE1IiwicmlnaHQiOiIxMCIsImJvdHRvbSI6IjE1IiwibGVmdCI6IjUifSwibWFyZ2luIjp7InJpZ2h0IjoiMTAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX1dfQ==
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 365.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 65.0f, 355.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 150.0f, 345.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 255.0f, 335.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 55.0f, 70.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 75.0f, 90.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 95.0f, 110.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 115.0f, 130.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  const Extents FLEXBOX_PADDING = Extents( 25, 25, 25, 25 );
+  flexBox.SetProperty(Toolkit::Control::Property::PADDING, FLEXBOX_PADDING );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  // To see go to https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjIsImFsaWduQ29udGVudCI6MSwicGFkZGluZyI6eyJ0b3AiOiIyNSIsInJpZ2h0IjoiMjUiLCJib3R0b20iOiIyNSIsImxlZnQiOiIyNSJ9LCJwb3NpdGlvbiI6eyJ0b3AiOm51bGwsInJpZ2h0IjpudWxsLCJib3R0b20iOm51bGwsImxlZnQiOm51bGx9LCJmbGV4V3JhcCI6MSwiY2hpbGRyZW4iOlt7IndpZHRoIjoiNDAiLCJoZWlnaHQiOiI0MCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjAsImFsaWduQ29udGVudCI6MCwicGFkZGluZyI6eyJ0b3AiOiIxNSIsInJpZ2h0IjoiMTAiLCJib3R0b20iOiIxNSIsImxlZnQiOiI1In0sIm1hcmdpbiI6eyJyaWdodCI6IjEwIn0sInBvc2l0aW9uIjp7InRvcCI6bnVsbCwicmlnaHQiOm51bGwsImJvdHRvbSI6bnVsbCwibGVmdCI6bnVsbH19LHsid2lkdGgiOiI2MCIsImhlaWdodCI6IjYwIiwibWluV2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1heEhlaWdodCI6bnVsbCwiYWxpZ25JdGVtcyI6MCwiYWxpZ25Db250ZW50IjowLCJwYWRkaW5nIjp7InRvcCI6IjE1IiwicmlnaHQiOiIxMCIsImJvdHRvbSI6IjE1IiwibGVmdCI6IjUifSwibWFyZ2luIjp7InJpZ2h0IjoiMTAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX0seyJ3aWR0aCI6IjgwIiwiaGVpZ2h0IjoiODAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsInBhZGRpbmciOnsidG9wIjoiMTUiLCJyaWdodCI6IjEwIiwiYm90dG9tIjoiMTUiLCJsZWZ0IjoiNSJ9LCJtYXJnaW4iOnsicmlnaHQiOiIxMCJ9LCJwb3NpdGlvbiI6eyJ0b3AiOm51bGwsInJpZ2h0IjpudWxsLCJib3R0b20iOm51bGwsImxlZnQiOm51bGx9fSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsInBhZGRpbmciOnsidG9wIjoiMTUiLCJyaWdodCI6IjEwIiwiYm90dG9tIjoiMTUiLCJsZWZ0IjoiNSJ9LCJtYXJnaW4iOnsicmlnaHQiOiIxMCJ9LCJwb3NpdGlvbiI6eyJ0b3AiOm51bGwsInJpZ2h0IjpudWxsLCJib3R0b20iOm51bGwsImxlZnQiOm51bGx9fV19
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 25.0f, 365.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 90.0f, 355.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 175.0f, 345.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 280.0f, 335.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 55.0f, 70.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 75.0f, 90.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 95.0f, 110.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 115.0f, 130.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliLayouting_FlexLayout02(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_FlexLayout02");
+
+  Stage stage = Stage::GetCurrent();
+  auto flexBox = Control::New();
+  auto flexLayout = FlexLayout::New();
+  flexLayout.SetFlexDirection( Dali::Toolkit::FlexLayout::FlexDirection::ROW );
+  flexLayout.SetFlexItemsAlignment( Dali::Toolkit::FlexLayout::Alignment::CENTER );
+
+  DevelControl::SetLayout( flexBox, flexLayout );
+  flexBox.SetName( "Flexbox");
+
+  std::vector< Control > controls;
+  controls.push_back( CreateLeafControl( 40, 40 ) );
+  controls.push_back( CreateLeafControl( 60, 60 ) );
+  controls.push_back( CreateLeafControl( 80, 80 ) );
+  controls.push_back( CreateLeafControl( 100, 100 ) );
+
+  const Extents CONTROL_MARGIN = Extents( 0, 10, 0, 0 );
+  for( auto&& iter : controls )
+  {
+    iter.SetProperty( Toolkit::Control::Property::MARGIN, CONTROL_MARGIN );
+    flexBox.Add( iter );
+  }
+
+  controls[1].SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+  controls[1].SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+
+  flexBox.SetParentOrigin( ParentOrigin::CENTER );
+  flexBox.SetAnchorPoint( AnchorPoint::CENTER );
+  stage.Add( flexBox );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  // flexbox centers elements vertically, it fills test harness stage, which is 480x800.
+  DALI_TEST_EQUALS( flexBox.GetProperty<Vector3>(Actor::Property::POSITION), Vector3( 0, 0, 0 ),TEST_LOCATION);
+  DALI_TEST_EQUALS( flexBox.GetProperty<Vector3>(Actor::Property::SIZE), Vector3( 480, 800, 0 ),TEST_LOCATION);
+
+  DALI_TEST_EQUALS( controls[1].GetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION ), Property::Value( ChildLayoutData::WRAP_CONTENT ), TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION ), Property::Value( ChildLayoutData::MATCH_PARENT ), TEST_LOCATION );
+
+  // left aligned elements with right margin 10
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 50.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 120.0f, 360.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 210.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 80.0f, 80.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliLayouting_FlexLayout03(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_FlexLayout03 Test nested flex boxes");
+
+  Stage stage = Stage::GetCurrent();
+
+  auto flexbox1 = Control::New();
+  auto flexLayout1 = FlexLayout::New();
+  DevelControl::SetLayout( flexbox1, flexLayout1 );
+  flexbox1.SetName( "Flexbox1");
+
+  std::vector< Control > controls;
+  controls.push_back( CreateLeafControl( 20, 20 ) );
+  controls.push_back( CreateLeafControl( 30, 30 ) );
+  flexbox1.Add( controls[0] );
+  flexbox1.Add( controls[1] );
+  flexbox1.SetParentOrigin( ParentOrigin::CENTER );
+  flexbox1.SetAnchorPoint( AnchorPoint::CENTER );
+
+  flexLayout1.SetFlexDirection( Dali::Toolkit::FlexLayout::FlexDirection::ROW );
+  flexLayout1.SetFlexWrap(Dali::Toolkit::FlexLayout::WrapType::NO_WRAP);
+  flexLayout1.SetFlexAlignment( Dali::Toolkit::FlexLayout::Alignment::FLEX_START );
+  flexLayout1.SetFlexItemsAlignment( Dali::Toolkit::FlexLayout::Alignment::FLEX_START );
+  flexLayout1.SetFlexJustification( Dali::Toolkit::FlexLayout::Justification::FLEX_START );
+
+  auto flexbox2 = Control::New();
+  auto flexLayout2 = FlexLayout::New();
+  DevelControl::SetLayout( flexbox2, flexLayout2 );
+  flexbox2.SetName( "Flexbox2");
+
+  controls.push_back( CreateLeafControl( 25, 25 ) );
+  controls.push_back( CreateLeafControl( 35, 35 ) );
+  flexbox2.Add( controls[2] );
+  flexbox2.Add( controls[3] );
+  flexbox2.SetParentOrigin( ParentOrigin::CENTER );
+  flexbox2.SetAnchorPoint( AnchorPoint::CENTER );
+
+  flexLayout2.SetFlexDirection( Dali::Toolkit::FlexLayout::FlexDirection::COLUMN );
+  flexLayout2.SetFlexWrap(Dali::Toolkit::FlexLayout::WrapType::NO_WRAP);
+  flexLayout2.SetFlexAlignment( Dali::Toolkit::FlexLayout::Alignment::FLEX_START );
+  flexLayout2.SetFlexItemsAlignment( Dali::Toolkit::FlexLayout::Alignment::FLEX_START );
+  flexLayout2.SetFlexJustification( Dali::Toolkit::FlexLayout::Justification::FLEX_START );
+
+  auto flexbox3 = Control::New();
+  auto flexLayout3 = FlexLayout::New();
+  DevelControl::SetLayout( flexbox3, flexLayout3 );
+  flexbox3.SetParentOrigin( ParentOrigin::CENTER );
+  flexbox3.SetName( "Flexbox3");
+  flexbox3.Add( flexbox1 );
+  flexbox3.Add( flexbox2 );
+  stage.Add( flexbox3 );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 20.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 30.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 55.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 20.0f, 20.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 30.0f, 30.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 25.0f, 25.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 35.0f, 35.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  // Test flexbox1,2 are sized to wrap their content
+  DALI_TEST_EQUALS( flexbox1.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 50.0f, 30.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( flexbox2.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 35.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( flexbox1.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( flexbox2.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 30.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  // Test flexbox3 matches parent (root layer)
+  DALI_TEST_EQUALS( flexbox3.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( flexbox3.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliLayouting_FlexLayout04(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_FlexLayout04");
+
+  Stage stage = Stage::GetCurrent();
+  auto flexBox = Control::New();
+  auto flexLayout = FlexLayout::New();
+  flexLayout.SetFlexAlignment( Dali::Toolkit::FlexLayout::Alignment::FLEX_START );
+  flexLayout.SetFlexItemsAlignment( Dali::Toolkit::FlexLayout::Alignment::FLEX_START );
+  flexLayout.SetFlexWrap(Dali::Toolkit::FlexLayout::WrapType::NO_WRAP);
+  flexLayout.SetFlexJustification( Dali::Toolkit::FlexLayout::Justification::FLEX_START );
+  flexLayout.SetFlexDirection( Dali::Toolkit::FlexLayout::FlexDirection::COLUMN );
+  DevelControl::SetLayout( flexBox, flexLayout );
+  flexBox.SetName( "Flexbox");
+
+  std::vector< Control > controls;
+  controls.push_back( CreateLeafControl( 40, 40 ) );
+  controls.push_back( CreateLeafControl( 60, 60 ) );
+  for( auto&& iter : controls )
+  {
+    flexBox.Add( iter );
+  }
+  flexBox.SetParentOrigin( ParentOrigin::CENTER );
+  flexBox.SetAnchorPoint( AnchorPoint::CENTER );
+  stage.Add( flexBox );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  // To see the test go to https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjEsImFsaWduQ29udGVudCI6MSwiZmxleERpcmVjdGlvbiI6MCwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfSwiZmxleFdyYXAiOjEsImNoaWxkcmVuIjpbeyJ3aWR0aCI6IjQwIiwiaGVpZ2h0IjoiNDAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJtYXJnaW4iOnsicmlnaHQiOiIwIn0sInBvc2l0aW9uIjp7InRvcCI6bnVsbCwicmlnaHQiOm51bGwsImJvdHRvbSI6bnVsbCwibGVmdCI6bnVsbH19LHsid2lkdGgiOiI2MCIsImhlaWdodCI6IjYwIiwibWluV2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1heEhlaWdodCI6bnVsbCwibWFyZ2luIjp7InJpZ2h0IjoiMTAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX1dfQ==
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  // Ensure layouting happens
+  flexLayout.SetFlexDirection( Dali::Toolkit::FlexLayout::FlexDirection::COLUMN_REVERSE );
+  application.SendNotification();
+  application.Render();
+
+  // To see the test go to https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjEsImFsaWduQ29udGVudCI6MSwiZmxleERpcmVjdGlvbiI6MSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfSwiZmxleFdyYXAiOjEsImNoaWxkcmVuIjpbeyJ3aWR0aCI6IjQwIiwiaGVpZ2h0IjoiNDAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJtYXJnaW4iOnsicmlnaHQiOiIwIn0sInBvc2l0aW9uIjp7InRvcCI6bnVsbCwicmlnaHQiOm51bGwsImJvdHRvbSI6bnVsbCwibGVmdCI6bnVsbH19LHsid2lkdGgiOiI2MCIsImhlaWdodCI6IjYwIiwibWluV2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1heEhlaWdodCI6bnVsbCwibWFyZ2luIjp7InJpZ2h0IjoiMTAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX1dfQ==
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 760.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 700.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  // Ensure layouting happens
+  flexLayout.SetFlexDirection( Dali::Toolkit::FlexLayout::FlexDirection::ROW );
+  application.SendNotification();
+  application.Render();
+
+  // To see the test go to https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjEsImFsaWduQ29udGVudCI6MSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfSwiZmxleFdyYXAiOjEsImNoaWxkcmVuIjpbeyJ3aWR0aCI6IjQwIiwiaGVpZ2h0IjoiNDAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJtYXJnaW4iOnsicmlnaHQiOiIwIn0sInBvc2l0aW9uIjp7InRvcCI6bnVsbCwicmlnaHQiOm51bGwsImJvdHRvbSI6bnVsbCwibGVmdCI6bnVsbH19LHsid2lkdGgiOiI2MCIsImhlaWdodCI6IjYwIiwibWluV2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1heEhlaWdodCI6bnVsbCwibWFyZ2luIjp7InJpZ2h0IjoiMTAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX1dfQ==
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 40.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  // Ensure layouting happens
+  flexLayout.SetFlexDirection( Dali::Toolkit::FlexLayout::FlexDirection::ROW_REVERSE );
+  application.SendNotification();
+  application.Render();
+
+  // To see the test go to https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjEsImFsaWduQ29udGVudCI6MSwiZmxleERpcmVjdGlvbiI6MywicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfSwiZmxleFdyYXAiOjEsImNoaWxkcmVuIjpbeyJ3aWR0aCI6IjQwIiwiaGVpZ2h0IjoiNDAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJtYXJnaW4iOnsicmlnaHQiOiIwIn0sInBvc2l0aW9uIjp7InRvcCI6bnVsbCwicmlnaHQiOm51bGwsImJvdHRvbSI6bnVsbCwibGVmdCI6bnVsbH19LHsid2lkdGgiOiI2MCIsImhlaWdodCI6IjYwIiwibWluV2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1heEhlaWdodCI6bnVsbCwibWFyZ2luIjp7InJpZ2h0IjoiMTAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX1dfQ==
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 440.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 380.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  // Ensure layouting happens
+  flexLayout.SetFlexDirection( Dali::Toolkit::FlexLayout::FlexDirection::ROW );
+  flexLayout.SetFlexItemsAlignment( Dali::Toolkit::FlexLayout::Alignment::CENTER );
+  application.SendNotification();
+  application.Render();
+
+  // To see the test go to https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjIsImFsaWduQ29udGVudCI6MSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfSwiY2hpbGRyZW4iOlt7IndpZHRoIjoiNDAiLCJoZWlnaHQiOiI0MCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX0seyJ3aWR0aCI6IjYwIiwiaGVpZ2h0IjoiNjAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJtYXJnaW4iOnsicmlnaHQiOiIxMCJ9LCJwb3NpdGlvbiI6eyJ0b3AiOm51bGwsInJpZ2h0IjpudWxsLCJib3R0b20iOm51bGwsImxlZnQiOm51bGx9fV19
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 40.0f, 370.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  // Ensure layouting happens
+  flexLayout.SetFlexItemsAlignment( Dali::Toolkit::FlexLayout::Alignment::FLEX_END );
+  application.SendNotification();
+  application.Render();
+
+  // To see the test go to https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjMsImFsaWduQ29udGVudCI6MSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfSwiY2hpbGRyZW4iOlt7IndpZHRoIjoiNDAiLCJoZWlnaHQiOiI0MCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX0seyJ3aWR0aCI6IjYwIiwiaGVpZ2h0IjoiNjAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJtYXJnaW4iOnsicmlnaHQiOiIxMCJ9LCJwb3NpdGlvbiI6eyJ0b3AiOm51bGwsInJpZ2h0IjpudWxsLCJib3R0b20iOm51bGwsImxlZnQiOm51bGx9fV19
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 760.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 40.0f, 740.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  // Ensure layouting happens
+  flexLayout.SetFlexItemsAlignment( Dali::Toolkit::FlexLayout::Alignment::STRETCH );
+  controls[0].SetProperty( Actor::Property::MAXIMUM_SIZE, Vector2(40.f, 40.f) );
+  controls[1].SetProperty( Actor::Property::MAXIMUM_SIZE, Vector2(60.f, 60.f) );
+  application.SendNotification();
+  application.Render();
+
+  // To see the test go to https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjEsImFsaWduQ29udGVudCI6MSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfSwiY2hpbGRyZW4iOlt7IndpZHRoIjoiNDAiLCJoZWlnaHQiOiI0MCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjAsImFsaWduQ29udGVudCI6MCwibWFyZ2luIjp7InJpZ2h0IjoiMCJ9LCJwb3NpdGlvbiI6eyJ0b3AiOm51bGwsInJpZ2h0IjpudWxsLCJib3R0b20iOm51bGwsImxlZnQiOm51bGx9fSx7IndpZHRoIjoiNjAiLCJoZWlnaHQiOiI2MCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjAsImFsaWduQ29udGVudCI6MCwibWFyZ2luIjp7InJpZ2h0IjoiMCJ9LCJwb3NpdGlvbiI6eyJ0b3AiOm51bGwsInJpZ2h0IjpudWxsLCJib3R0b20iOm51bGwsImxlZnQiOm51bGx9fV19
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 40.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  flexLayout.SetFlexItemsAlignment( Dali::Toolkit::FlexLayout::Alignment::FLEX_START );
+  flexLayout.SetFlexJustification( Dali::Toolkit::FlexLayout::Justification::FLEX_START );
+  application.SendNotification();
+  application.Render();
+
+  // To see the test go to https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjEsImFsaWduQ29udGVudCI6MSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfSwiY2hpbGRyZW4iOlt7IndpZHRoIjoiNDAiLCJoZWlnaHQiOiI0MCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjAsImFsaWduQ29udGVudCI6MCwibWFyZ2luIjp7InJpZ2h0IjoiMCJ9LCJwb3NpdGlvbiI6eyJ0b3AiOm51bGwsInJpZ2h0IjpudWxsLCJib3R0b20iOm51bGwsImxlZnQiOm51bGx9fSx7IndpZHRoIjoiNjAiLCJoZWlnaHQiOiI2MCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjAsImFsaWduQ29udGVudCI6MCwibWFyZ2luIjp7InJpZ2h0IjoiMCJ9LCJwb3NpdGlvbiI6eyJ0b3AiOm51bGwsInJpZ2h0IjpudWxsLCJib3R0b20iOm51bGwsImxlZnQiOm51bGx9fV19
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 40.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  flexLayout.SetFlexJustification( Dali::Toolkit::FlexLayout::Justification::CENTER );
+  application.SendNotification();
+  application.Render();
+
+  // To see the test go to https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImp1c3RpZnlDb250ZW50IjoxLCJhbGlnbkl0ZW1zIjoxLCJhbGlnbkNvbnRlbnQiOjEsInBvc2l0aW9uIjp7InRvcCI6bnVsbCwicmlnaHQiOm51bGwsImJvdHRvbSI6bnVsbCwibGVmdCI6bnVsbH0sImNoaWxkcmVuIjpbeyJ3aWR0aCI6IjQwIiwiaGVpZ2h0IjoiNDAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX0seyJ3aWR0aCI6IjYwIiwiaGVpZ2h0IjoiNjAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX1dfQ==
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 190.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 230.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  flexLayout.SetFlexJustification( Dali::Toolkit::FlexLayout::Justification::FLEX_END );
+  application.SendNotification();
+  application.Render();
+
+  // To see the test go to https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImp1c3RpZnlDb250ZW50IjoyLCJhbGlnbkl0ZW1zIjoxLCJhbGlnbkNvbnRlbnQiOjEsInBvc2l0aW9uIjp7InRvcCI6bnVsbCwicmlnaHQiOm51bGwsImJvdHRvbSI6bnVsbCwibGVmdCI6bnVsbH0sImNoaWxkcmVuIjpbeyJ3aWR0aCI6IjQwIiwiaGVpZ2h0IjoiNDAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX0seyJ3aWR0aCI6IjYwIiwiaGVpZ2h0IjoiNjAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX1dfQ==
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 380.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 420.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  flexLayout.SetFlexJustification( Dali::Toolkit::FlexLayout::Justification::SPACE_BETWEEN );
+  application.SendNotification();
+  application.Render();
+
+  // To see the test go to https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImp1c3RpZnlDb250ZW50IjozLCJhbGlnbkl0ZW1zIjoxLCJhbGlnbkNvbnRlbnQiOjEsInBvc2l0aW9uIjp7InRvcCI6bnVsbCwicmlnaHQiOm51bGwsImJvdHRvbSI6bnVsbCwibGVmdCI6bnVsbH0sImNoaWxkcmVuIjpbeyJ3aWR0aCI6IjQwIiwiaGVpZ2h0IjoiNDAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX0seyJ3aWR0aCI6IjYwIiwiaGVpZ2h0IjoiNjAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX1dfQ==
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 420.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  flexLayout.SetFlexJustification( Dali::Toolkit::FlexLayout::Justification::SPACE_AROUND );
+  application.SendNotification();
+  application.Render();
+
+  // To see the test go to https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImp1c3RpZnlDb250ZW50Ijo0LCJhbGlnbkl0ZW1zIjoxLCJhbGlnbkNvbnRlbnQiOjEsInBvc2l0aW9uIjp7InRvcCI6bnVsbCwicmlnaHQiOm51bGwsImJvdHRvbSI6bnVsbCwibGVmdCI6bnVsbH0sImNoaWxkcmVuIjpbeyJ3aWR0aCI6IjQwIiwiaGVpZ2h0IjoiNDAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX0seyJ3aWR0aCI6IjYwIiwiaGVpZ2h0IjoiNjAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX1dfQ==
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 95.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 325.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliLayouting_FlexLayout05(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_FlexLayout05");
+
+  Stage stage = Stage::GetCurrent();
+  auto flexBox = Control::New();
+  auto flexLayout = FlexLayout::New();
+  flexLayout.SetFlexAlignment( Dali::Toolkit::FlexLayout::Alignment::FLEX_START );
+  flexLayout.SetFlexItemsAlignment( Dali::Toolkit::FlexLayout::Alignment::FLEX_START );
+  flexLayout.SetFlexWrap(Dali::Toolkit::FlexLayout::WrapType::NO_WRAP);
+  flexLayout.SetFlexJustification( Dali::Toolkit::FlexLayout::Justification::FLEX_START );
+  flexLayout.SetFlexDirection( Dali::Toolkit::FlexLayout::FlexDirection::ROW );
+  DevelControl::SetLayout( flexBox, flexLayout );
+  flexBox.SetName( "Flexbox");
+
+  std::vector< Control > controls;
+  controls.push_back( CreateLeafControl( 200, 200 ) );
+  controls.push_back( CreateLeafControl( 400, 400 ) );
+  for( auto&& iter : controls )
+  {
+    flexBox.Add( iter );
+  }
+  flexBox.SetParentOrigin( ParentOrigin::CENTER );
+  flexBox.SetAnchorPoint( AnchorPoint::CENTER );
+  stage.Add( flexBox );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  // Shrink is off
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 200.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 200.0f, 200.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 400.0f, 400.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  flexLayout.SetFlexWrap(Dali::Toolkit::FlexLayout::WrapType::WRAP);
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  // To see the test go to https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjEsImFsaWduQ29udGVudCI6MSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfSwiZmxleFdyYXAiOjEsImNoaWxkcmVuIjpbeyJ3aWR0aCI6IjIwMCIsImhlaWdodCI6IjIwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjEsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX0seyJ3aWR0aCI6IjQwMCIsImhlaWdodCI6IjQwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjEsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX1dfQ==
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 200.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 200.0f, 200.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 400.0f, 400.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  flexLayout.SetFlexAlignment(Dali::Toolkit::FlexLayout::Alignment::CENTER);
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  // To see the test go to https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjEsImFsaWduQ29udGVudCI6MiwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfSwiZmxleFdyYXAiOjEsImNoaWxkcmVuIjpbeyJ3aWR0aCI6IjIwMCIsImhlaWdodCI6IjIwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjEsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX0seyJ3aWR0aCI6IjQwMCIsImhlaWdodCI6IjQwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjEsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX1dfQ==
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 300.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 200.0f, 200.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 400.0f, 400.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  flexLayout.SetFlexAlignment(Dali::Toolkit::FlexLayout::Alignment::FLEX_END);
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  // To see the test go to https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjEsImFsaWduQ29udGVudCI6MiwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfSwiZmxleFdyYXAiOjEsImNoaWxkcmVuIjpbeyJ3aWR0aCI6IjIwMCIsImhlaWdodCI6IjIwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjEsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX0seyJ3aWR0aCI6IjQwMCIsImhlaWdodCI6IjQwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjEsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX1dfQ==
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 200.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 400.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 200.0f, 200.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 400.0f, 400.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  flexLayout.SetFlexAlignment(Dali::Toolkit::FlexLayout::Alignment::STRETCH);
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  // To see the test go to https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjEsImFsaWduQ29udGVudCI6MiwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfSwiZmxleFdyYXAiOjEsImNoaWxkcmVuIjpbeyJ3aWR0aCI6IjIwMCIsImhlaWdodCI6IjIwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjEsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX0seyJ3aWR0aCI6IjQwMCIsImhlaWdodCI6IjQwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjEsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX1dfQ==
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 300.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 200.0f, 200.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 400.0f, 400.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliLayouting_FlexLayout06(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_FlexLayout06");
+
+  Stage stage = Stage::GetCurrent();
+  auto flexBox = Control::New();
+  auto flexLayout = FlexLayout::New();
+  flexLayout.SetFlexDirection( Dali::Toolkit::FlexLayout::FlexDirection::COLUMN );
+  flexLayout.SetFlexItemsAlignment( Dali::Toolkit::FlexLayout::Alignment::FLEX_START );
+  DevelControl::SetLayout( flexBox, flexLayout );
+  flexBox.SetName( "Flexbox");
+
+  std::vector< Control > controls;
+  controls.push_back( CreateLeafControl( 40, 40 ) );
+  controls.push_back( CreateLeafControl( 60, 60 ) );
+  controls.push_back( CreateLeafControl( 80, 80 ) );
+  controls.push_back( CreateLeafControl( 100, 100 ) );
+  for( auto&& iter : controls )
+  {
+    flexBox.Add( iter );
+  }
+  flexBox.SetParentOrigin( ParentOrigin::CENTER );
+  flexBox.SetAnchorPoint( AnchorPoint::CENTER );
+  stage.Add( flexBox );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  // flexbox centers elements vertically, it fills test harness stage, which is 480x800.
+  // left aligned elements with right margin 10
+  // To see goto https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjEsImFsaWduQ29udGVudCI6MSwiZmxleERpcmVjdGlvbiI6MCwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfSwiZmxleFdyYXAiOjEsImNoaWxkcmVuIjpbeyJ3aWR0aCI6IjQwIiwiaGVpZ2h0IjoiNDAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX0seyJ3aWR0aCI6IjYwIiwiaGVpZ2h0IjoiNjAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX0seyJ3aWR0aCI6IjgwIiwiaGVpZ2h0IjoiODAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX0seyJ3aWR0aCI6MTAwLCJoZWlnaHQiOjEwMCwibWluV2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1heEhlaWdodCI6bnVsbCwiYWxpZ25JdGVtcyI6MCwiYWxpZ25Db250ZW50IjowLCJwb3NpdGlvbiI6eyJ0b3AiOm51bGwsInJpZ2h0IjpudWxsLCJib3R0b20iOm51bGwsImxlZnQiOm51bGx9fV19
+  DALI_TEST_EQUALS( flexBox.GetProperty<Vector3>(Actor::Property::POSITION), Vector3(0, 0, 0),TEST_LOCATION);
+  DALI_TEST_EQUALS( flexBox.GetProperty<Vector3>(Actor::Property::SIZE), Vector3(480, 800, 0),TEST_LOCATION);
+
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 180.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 80.0f, 80.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  flexBox.Remove( controls[1] );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  // To see goto https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjEsImFsaWduQ29udGVudCI6MSwiZmxleERpcmVjdGlvbiI6MCwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfSwiZmxleFdyYXAiOjEsImNoaWxkcmVuIjpbeyJ3aWR0aCI6IjQwIiwiaGVpZ2h0IjoiNDAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX0seyJ3aWR0aCI6IjgwIiwiaGVpZ2h0IjoiODAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX0seyJ3aWR0aCI6MTAwLCJoZWlnaHQiOjEwMCwibWluV2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1heEhlaWdodCI6bnVsbCwiYWxpZ25JdGVtcyI6MCwiYWxpZ25Db250ZW50IjowLCJwb3NpdGlvbiI6eyJ0b3AiOm51bGwsInJpZ2h0IjpudWxsLCJib3R0b20iOm51bGwsImxlZnQiOm51bGx9fV19
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 120.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 80.0f, 80.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliLayouting_FlexLayout07(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_FlexLayout07");
+
+  Stage stage = Stage::GetCurrent();
+  auto flexBox = Control::New();
+  auto flexLayout = FlexLayout::New();
+  flexLayout.SetFlexDirection( Dali::Toolkit::FlexLayout::FlexDirection::ROW );
+  flexLayout.SetFlexItemsAlignment( Dali::Toolkit::FlexLayout::Alignment::CENTER );
+  DevelControl::SetLayout( flexBox, flexLayout );
+  flexBox.SetName( "Flexbox");
+
+  std::vector< Control > controls;
+  controls.push_back( CreateLeafControl( 40, 40 ) );
+  controls.push_back( CreateLeafControl( 60, 60 ) );
+  controls.push_back( CreateLeafControl( 80, 80 ) );
+  controls.push_back( CreateLeafControl( 100, 100 ) );
+
+  for( auto&& iter : controls )
+  {
+    iter.SetProperty( Toolkit::FlexLayout::ChildProperty::FLEX, 0.f );
+    iter.SetProperty( Toolkit::FlexLayout::ChildProperty::ALIGN_SELF, Dali::Toolkit::FlexLayout::Alignment::AUTO );
+    flexBox.Add( iter );
+  }
+  flexBox.SetParentOrigin( ParentOrigin::CENTER );
+  flexBox.SetAnchorPoint( AnchorPoint::CENTER );
+  stage.Add( flexBox );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  // To see goto https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjIsImFsaWduQ29udGVudCI6MSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfSwiZmxleFdyYXAiOjEsImNoaWxkcmVuIjpbeyJ3aWR0aCI6IjQwIiwiaGVpZ2h0IjoiNDAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX0seyJ3aWR0aCI6IjYwIiwiaGVpZ2h0IjoiNjAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX0seyJ3aWR0aCI6IjgwIiwiaGVpZ2h0IjoiODAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX0seyJ3aWR0aCI6MTAwLCJoZWlnaHQiOjEwMCwibWluV2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1heEhlaWdodCI6bnVsbCwiYWxpZ25JdGVtcyI6MCwiYWxpZ25Db250ZW50IjowLCJtYXJnaW4iOnsicmlnaHQiOiIwIn0sInBvc2l0aW9uIjp7InRvcCI6bnVsbCwicmlnaHQiOm51bGwsImJvdHRvbSI6bnVsbCwibGVmdCI6bnVsbH19XX0=
+  DALI_TEST_EQUALS( flexBox.GetProperty<Vector3>(Actor::Property::POSITION), Vector3( 0, 0, 0 ),TEST_LOCATION);
+  DALI_TEST_EQUALS( flexBox.GetProperty<Vector3>(Actor::Property::SIZE), Vector3( 480, 800, 0 ),TEST_LOCATION);
+
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 40.0f, 370.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f, 360.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 180.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 80.0f, 80.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  for( auto&& iter : controls )
+  {
+    iter.SetProperty( Toolkit::FlexLayout::ChildProperty::FLEX, 0.25f );
+    iter.SetProperty( Toolkit::FlexLayout::ChildProperty::ALIGN_SELF, Toolkit::FlexLayout::Alignment::AUTO );
+  }
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  // To see go to https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjIsImFsaWduQ29udGVudCI6MSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfSwiZmxleFdyYXAiOjEsImNoaWxkcmVuIjpbeyJ3aWR0aCI6IjQwIiwiaGVpZ2h0IjoiNDAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfSwiZmxleEdyb3ciOiIwLjI1In0seyJ3aWR0aCI6IjYwIiwiaGVpZ2h0IjoiNjAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfSwiZmxleEdyb3ciOiIwLjI1In0seyJ3aWR0aCI6IjgwIiwiaGVpZ2h0IjoiODAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfSwiZmxleEdyb3ciOiIwLjI1In0seyJ3aWR0aCI6MTAwLCJoZWlnaHQiOjEwMCwibWluV2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1heEhlaWdodCI6bnVsbCwiYWxpZ25JdGVtcyI6MCwiYWxpZ25Db250ZW50IjowLCJtYXJnaW4iOnsicmlnaHQiOiIwIn0sInBvc2l0aW9uIjp7InRvcCI6bnVsbCwicmlnaHQiOm51bGwsImJvdHRvbSI6bnVsbCwibGVmdCI6bnVsbH0sImZsZXhHcm93IjoiMC4yNSJ9XX0=
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 120.0f, 370.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 240.0f, 360.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 360.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 120.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 120.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 120.0f, 80.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 120.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  for( auto&& iter : controls )
+  {
+    iter.SetProperty( Toolkit::FlexLayout::ChildProperty::FLEX, 0.f );
+  }
+  controls[0].SetProperty( Toolkit::FlexLayout::ChildProperty::ALIGN_SELF, Toolkit::FlexLayout::Alignment::CENTER );
+  controls[1].SetProperty( Toolkit::FlexLayout::ChildProperty::ALIGN_SELF, Toolkit::FlexLayout::Alignment::FLEX_START );
+  controls[2].SetProperty( Toolkit::FlexLayout::ChildProperty::ALIGN_SELF, Toolkit::FlexLayout::Alignment::FLEX_END );
+  controls[3].SetProperty( Toolkit::FlexLayout::ChildProperty::ALIGN_SELF, Toolkit::FlexLayout::Alignment::STRETCH );
+  controls[3].SetProperty( Actor::Property::MAXIMUM_SIZE, Vector2(100.f, 100.f) );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  // To see go to https://yogalayout.com/playground/#eyJ3aWR0aCI6IjQ4MCIsImhlaWdodCI6IjgwMCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjIsImFsaWduQ29udGVudCI6MSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfSwiZmxleFdyYXAiOjEsImNoaWxkcmVuIjpbeyJ3aWR0aCI6IjQwIiwiaGVpZ2h0IjoiNDAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnbkNvbnRlbnQiOjAsIm1hcmdpbiI6eyJyaWdodCI6IjAifSwicG9zaXRpb24iOnsidG9wIjpudWxsLCJyaWdodCI6bnVsbCwiYm90dG9tIjpudWxsLCJsZWZ0IjpudWxsfX0seyJ3aWR0aCI6IjYwIiwiaGVpZ2h0IjoiNjAiLCJtaW5XaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsLCJhbGlnbkl0ZW1zIjowLCJhbGlnblNlbGYiOjEsImFsaWduQ29udGVudCI6MCwibWFyZ2luIjp7InJpZ2h0IjoiMCJ9LCJwb3NpdGlvbiI6eyJ0b3AiOm51bGwsInJpZ2h0IjpudWxsLCJib3R0b20iOm51bGwsImxlZnQiOm51bGx9fSx7IndpZHRoIjoiODAiLCJoZWlnaHQiOiI4MCIsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjAsImFsaWduU2VsZiI6MywiYWxpZ25Db250ZW50IjowLCJtYXJnaW4iOnsicmlnaHQiOiIwIn0sInBvc2l0aW9uIjp7InRvcCI6bnVsbCwicmlnaHQiOm51bGwsImJvdHRvbSI6bnVsbCwibGVmdCI6bnVsbH19LHsid2lkdGgiOjEwMCwiaGVpZ2h0IjoxMDAsIm1pbldpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtYXhIZWlnaHQiOm51bGwsImFsaWduSXRlbXMiOjAsImFsaWduU2VsZiI6NCwiYWxpZ25Db250ZW50IjowLCJtYXJnaW4iOnsicmlnaHQiOiIwIn0sInBvc2l0aW9uIjp7InRvcCI6bnVsbCwicmlnaHQiOm51bGwsImJvdHRvbSI6bnVsbCwibGVmdCI6bnVsbH19XX0=
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 380.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 40.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f, 720.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 180.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 60.0f, 60.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 80.0f, 80.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliLayouting_FlexLayout08(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_FlexLayout08");
+
+  Stage stage = Stage::GetCurrent();
+
+  auto flexbox1 = Control::New();
+  auto flexLayout1 = FlexLayout::New();
+  DevelControl::SetLayout( flexbox1, flexLayout1 );
+  flexbox1.SetName( "Flexbox1");
+
+  std::vector< Control > controls;
+  controls.push_back( CreateLeafControl( 20, 20 ) );
+  flexbox1.Add( controls[0] );
+  flexbox1.SetParentOrigin( ParentOrigin::CENTER );
+  flexbox1.SetAnchorPoint( AnchorPoint::CENTER );
+  const Extents CONTROL_MARGIN = Extents( 10, 10, 10, 10 );
+  const Extents CONTROL_PADDING = Extents( 5, 5, 5, 5 );
+  flexbox1.SetProperty( Toolkit::Control::Property::MARGIN, CONTROL_MARGIN );
+  flexbox1.SetProperty( Toolkit::Control::Property::PADDING, CONTROL_PADDING );
+  flexbox1.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+  flexbox1.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+
+  auto flexbox2 = Control::New();
+  auto flexLayout2 = FlexLayout::New();
+  DevelControl::SetLayout( flexbox2, flexLayout2 );
+  flexbox2.SetParentOrigin( ParentOrigin::CENTER );
+  flexbox2.SetName( "Flexbox2");
+  flexbox2.Add( flexbox1 );
+  stage.Add( flexbox2 );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 15.0f, 15.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 20.0f, 20.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( flexbox1.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 30.0f, 30.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( flexbox2.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( flexbox1.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 10.0f, 10.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( flexbox2.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
index deb8eb8..49bb007 100644 (file)
 #include <iostream>
 #include <stdlib.h>
 #include <dali-toolkit-test-suite-utils.h>
+
 #include <dali-toolkit/dali-toolkit.h>
-#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
-#include <dali-toolkit/devel-api/image-loader/texture-manager.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/layouting/hbox-layout.h>
 #include <dali-toolkit/devel-api/layouting/vbox-layout.h>
-//#include <dali-toolkit/internal/controls/control/control-data-impl-debug.h>
+
+#include <layout-utils.h>
 
 using namespace Dali;
 using namespace Toolkit;
@@ -39,31 +39,6 @@ void utc_dali_toolkit_layouting_cleanup(void)
   test_return_value = TET_PASS;
 }
 
-
-Control CreateLeafControl( int width, int height )
-{
-  auto control = Control::New();
-  control.SetName( "Leaf" );
-
-  auto pixelBuffer = Devel::PixelBuffer::New( 1, 1, Pixel::RGB888 );
-  unsigned char* pixels = pixelBuffer.GetBuffer();
-  pixels[0] = 0xff;
-  pixels[1] = 0x00;
-  pixels[2] = 0x00;
-  auto texture = Texture::New( TextureType::TEXTURE_2D, Pixel::RGB888, 1, 1 );
-  auto pixelData = Devel::PixelBuffer::Convert( pixelBuffer );
-  texture.Upload( pixelData );
-  std::string url = TextureManager::AddTexture( texture );
-
-  Property::Map map;
-  map[ Visual::Property::TYPE ] = Visual::IMAGE;
-  map[ ImageVisual::Property::URL ] = url;
-  map[ ImageVisual::Property::DESIRED_WIDTH ] = (float) width;
-  map[ ImageVisual::Property::DESIRED_HEIGHT ] = (float) height;
-  control.SetProperty( Control::Property::BACKGROUND, map );
-  return control;
-}
-
 int UtcDaliLayouting_HboxLayout01(void)
 {
   ToolkitTestApplication application;
index 2b667c0..829e4c6 100755 (executable)
@@ -32,6 +32,7 @@ devel_api_src_files = \
   $(devel_api_src_dir)/image-loader/atlas-upload-observer.cpp \
   $(devel_api_src_dir)/image-loader/image-atlas.cpp \
   $(devel_api_src_dir)/image-loader/texture-manager.cpp \
+  $(devel_api_src_dir)/layouting/flex-layout.cpp \
   $(devel_api_src_dir)/layouting/hbox-layout.cpp \
   $(devel_api_src_dir)/layouting/vbox-layout.cpp \
   $(devel_api_src_dir)/layouting/layout-item.cpp \
@@ -82,6 +83,7 @@ devel_api_effects_view_header_files = \
 
 devel_api_layouting_header_files = \
   $(devel_api_src_dir)/layouting/child-layout-data.h \
+  $(devel_api_src_dir)/layouting/flex-layout.h \
   $(devel_api_src_dir)/layouting/hbox-layout.h \
   $(devel_api_src_dir)/layouting/vbox-layout.h \
   $(devel_api_src_dir)/layouting/layout-item.h \
diff --git a/dali-toolkit/devel-api/layouting/flex-layout.cpp b/dali-toolkit/devel-api/layouting/flex-layout.cpp
new file mode 100644 (file)
index 0000000..084182b
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+//CLASS HEADER
+#include "flex-layout.h"
+
+//INTERNAL INCLUDES
+#include <dali-toolkit/internal/layouting/flex-layout-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+
+FlexLayout::FlexLayout()
+{
+}
+
+FlexLayout FlexLayout::New()
+{
+  Internal::FlexLayoutPtr internal = Internal::FlexLayout::New();
+  return FlexLayout( internal.Get() );
+}
+
+FlexLayout FlexLayout::DownCast( BaseHandle handle )
+{
+  return FlexLayout( dynamic_cast< Dali::Toolkit::Internal::FlexLayout*>( handle.GetObjectPtr() ) );
+}
+
+FlexLayout::FlexLayout( const FlexLayout& other )
+: LayoutGroup( other )
+{
+}
+
+FlexLayout& FlexLayout::operator=( const FlexLayout& other )
+{
+  if( &other != this )
+  {
+    LayoutGroup::operator=( other );
+  }
+  return *this;
+}
+
+void FlexLayout::SetFlexDirection( Dali::Toolkit::FlexLayout::FlexDirection flexDirection )
+{
+  if( GetImplementation(*this).GetFlexDirection() != flexDirection )
+  {
+    GetImplementation(*this).SetFlexDirection( flexDirection );
+    GetImplementation(*this).RequestLayout();
+  }
+}
+
+Dali::Toolkit::FlexLayout::FlexDirection FlexLayout::GetFlexDirection() const
+{
+  return GetImplementation(*this).GetFlexDirection();
+}
+
+void FlexLayout::SetFlexJustification( Dali::Toolkit::FlexLayout::Justification flexJustification )
+{
+  if( GetImplementation(*this).GetFlexJustification() != flexJustification )
+  {
+    GetImplementation(*this).SetFlexJustification( flexJustification );
+    GetImplementation(*this).RequestLayout();
+  }
+}
+
+Dali::Toolkit::FlexLayout::Justification FlexLayout::GetFlexJustification() const
+{
+  return GetImplementation(*this).GetFlexJustification();
+}
+
+void FlexLayout::SetFlexWrap( Dali::Toolkit::FlexLayout::WrapType flexWrap )
+{
+  if( GetImplementation(*this).GetFlexWrap() != flexWrap )
+  {
+    GetImplementation(*this).SetFlexWrap( flexWrap );
+    GetImplementation(*this).RequestLayout();
+  }
+}
+
+Dali::Toolkit::FlexLayout::WrapType FlexLayout::GetFlexWrap() const
+{
+  return GetImplementation(*this).GetFlexWrap();
+}
+
+void FlexLayout::SetFlexAlignment( Dali::Toolkit::FlexLayout::Alignment::Type flexAlignment )
+{
+  if( GetImplementation(*this).GetFlexAlignment() != flexAlignment )
+  {
+    GetImplementation(*this).SetFlexAlignment( flexAlignment );
+    GetImplementation(*this).RequestLayout();
+  }
+}
+
+Dali::Toolkit::FlexLayout::Alignment::Type FlexLayout::GetFlexAlignment() const
+{
+  return GetImplementation(*this).GetFlexAlignment();
+}
+
+void FlexLayout::SetFlexItemsAlignment( Dali::Toolkit::FlexLayout::Alignment::Type flexAlignment )
+{
+  if( GetImplementation(*this).GetFlexItemsAlignment() != flexAlignment )
+  {
+    GetImplementation(*this).SetFlexItemsAlignment( flexAlignment );
+    GetImplementation(*this).RequestLayout();
+  }
+}
+
+Dali::Toolkit::FlexLayout::Alignment::Type FlexLayout::GetFlexItemsAlignment() const
+{
+  return GetImplementation(*this).GetFlexItemsAlignment();
+}
+
+FlexLayout::FlexLayout( Dali::Toolkit::Internal::FlexLayout* object )
+: LayoutGroup( object )
+{
+}
+
+} // namespace Toolkit
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/layouting/flex-layout.h b/dali-toolkit/devel-api/layouting/flex-layout.h
new file mode 100644 (file)
index 0000000..881478b
--- /dev/null
@@ -0,0 +1,241 @@
+#ifndef DALI_TOOLKIT_LAYOUTING_FLEX_LAYOUT_H
+#define DALI_TOOLKIT_LAYOUTING_FLEX_LAYOUT_H
+
+/*
+ * Copyright (c) 2018 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 <dali/public-api/common/dali-common.h>
+#include <dali/public-api/object/base-handle.h>
+#include <dali-toolkit/public-api/dali-toolkit-common.h>
+#include <dali-toolkit/devel-api/layouting/layout-group.h>
+#include <dali-toolkit/devel-api/layouting/layout-size.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+
+namespace Internal DALI_INTERNAL
+{
+class FlexLayout;
+}
+
+/**
+ * This class implements a flex layout.
+ *
+ * The flex layout implementation is based on open source Facebook Yoga layout engine.
+ * For more information about the flex layout API and how to use it please refer to
+ * https://yogalayout.com/docs/
+ * We implement the subset of the API in the class below.
+ */
+class DALI_TOOLKIT_API FlexLayout : public LayoutGroup
+{
+public:
+
+  enum PropertyRange
+  {
+    CHILD_PROPERTY_START_INDEX = FLEX_LAYOUT_CHILD_PROPERTY_START_INDEX,
+    CHILD_PROPERTY_END_INDEX   = FLEX_LAYOUT_CHILD_PROPERTY_END_INDEX
+  };
+
+  /**
+   * @brief Enumeration for the direction of the main axis in the flex container. This determines
+   * the direction that flex items are laid out in the flex container.
+   */
+  enum class FlexDirection
+  {
+    COLUMN,                  ///< The flexible items are displayed vertically as a column
+    COLUMN_REVERSE,          ///< The flexible items are displayed vertically as a column, but in reverse order
+    ROW,                     ///< The flexible items are displayed horizontally as a row
+    ROW_REVERSE              ///< The flexible items are displayed horizontally as a row, but in reverse order
+  };
+
+  /**
+   * @brief Enumeration for the alignment of the flex items when the items do not use all available
+   * space on the main-axis.
+   */
+  enum class Justification
+  {
+    FLEX_START,              ///< Items are positioned at the beginning of the container
+    CENTER,                  ///< Items are positioned at the center of the container
+    FLEX_END,                ///< Items are positioned at the end of the container
+    SPACE_BETWEEN,           ///< Items are positioned with equal space between the lines
+    SPACE_AROUND             ///< Items are positioned with equal space before, between, and after the lines
+  };
+
+  /**
+   * @brief Enumeration for the alignment of the flex items or lines when the items or lines do not
+   * use all the available space on the cross-axis.
+   */
+  struct Alignment
+  {
+    enum Type
+    {
+      AUTO,                  ///< Inherits the same alignment from the parent (only valid for "alignSelf" property)
+      FLEX_START,            ///< At the beginning of the container
+      CENTER,                ///< At the center of the container
+      FLEX_END,              ///< At the end of the container
+      STRETCH                ///< Stretch to fit the container
+    };
+  };
+
+  /**
+   * @brief Enumeration for the wrap type of the flex container when there is no enough room for
+   * all the items on one flex line.
+   */
+  enum class WrapType
+  {
+    NO_WRAP,                 ///< Flex items laid out in single line (shrunk to fit the flex container along the main axis)
+    WRAP                     ///< Flex items laid out in multiple lines if needed
+  };
+
+  struct ChildProperty
+  {
+    enum
+    {
+      FLEX = CHILD_PROPERTY_START_INDEX, ///< name "flex",      The proportion of the free space in the container the flex item will receive. If all items in the container set this property, their sizes will be proportional to the specified flex factor,  type FLOAT
+      ALIGN_SELF                         ///< name "alignSelf", The alignment of the flex item along the cross axis, which, if set, overrides the default alignment for all items in the container, type INTEGER
+    };
+  };
+
+  /**
+   * @brief Creates an uninitialized FlexLayout handle.
+   *
+   * Initialize it using FlexLayout::New().
+   * Calling member functions with an uninitialized handle is not allowed.
+   */
+  FlexLayout();
+
+  /**
+   * @brief Creates a FlexLayout object.
+   */
+  static FlexLayout New();
+
+  /**
+   * @brief Downcasts a handle to a FlexLayout handle.
+   *
+   * If handle points to a FlexLayout, the downcast produces a valid handle.
+   * If not, the returned handle is left uninitialized.
+
+   * @param[in] handle to an object
+   * @return Handle to a FlexLayout or an uninitialized handle
+   */
+  static FlexLayout DownCast( BaseHandle handle );
+
+  /**
+   * @brief Copy constructor
+   */
+  FlexLayout( const FlexLayout& other );
+
+  /**
+   * @brief Assigment operator
+   */
+  FlexLayout& operator=( const FlexLayout& other );
+
+  /**
+   * @brief Default destructor.
+   *
+   * This is non-virtual, since derived Handle types must not contain data or virtual methods
+   */
+  ~FlexLayout()=default;
+
+  /**
+    * @brief Set the flex direction in the layout.
+    * The direction of the main-axis which determines the direction that flex items are laid out.
+    *
+    * @param[in] flexDirection The flex direction.
+    */
+  void SetFlexDirection( FlexDirection flexDirection );
+
+  /**
+    * @brief Get the flex direction in the layout.
+    *
+    * @return The flex direction.
+    */
+  FlexDirection GetFlexDirection() const;
+
+  /**
+    * @brief Set the justification in the layout.
+    *
+    * @param[in] flexJustification The flex justification.
+    */
+  void SetFlexJustification( Justification flexJustification );
+
+  /**
+    * @brief Get the flex justification in the layout.
+    *
+    * @return The flex justification.
+    */
+  Justification GetFlexJustification() const;
+
+  /**
+    * @brief Set the wrap in the layout.
+    *
+    * @param[in] flexWrap The flex wrap.
+    */
+  void SetFlexWrap( WrapType flexWrap );
+
+  /**
+    * @brief Get the flex wrap in the layout.
+    *
+    * @return The flex wrap.
+    */
+  WrapType GetFlexWrap() const;
+
+  /**
+    * @brief Set the alignment of the layout content.
+    *
+    * @param[in] flexAlignment The alignment of the content.
+    */
+  void SetFlexAlignment( Alignment::Type flexAlignment );
+
+  /**
+    * @brief Get the alignment of the layout content.
+    *
+    * @return The flex content alignment.
+    */
+  Alignment::Type GetFlexAlignment() const;
+
+  /**
+    * @brief Set the alignment of the layout items.
+    *
+    * @param[in] flexAlignment The alignment of the items.
+    */
+  void SetFlexItemsAlignment( Alignment::Type flexAlignment );
+
+  /**
+    * @brief Get the alignment of the layout items.
+    *
+    * @return The flex items alignment.
+    */
+  Alignment::Type GetFlexItemsAlignment() const;
+
+public: // Not intended for application developers
+
+  /// @cond internal
+  /**
+   * @brief This constructor is used by FlexLayout::New() methods.
+   *
+   * @param[in] actor A pointer to a newly allocated Dali resource
+   */
+  explicit DALI_INTERNAL FlexLayout( Internal::FlexLayout* body );
+  /// @endcond
+};
+
+} // namespace Toolkit
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_LAYOUTING_FLEX_LAYOUT_H
index 2104f2b..b92255e 100755 (executable)
@@ -11,6 +11,7 @@ toolkit_src_files = \
    $(toolkit_src_dir)/builder/style.cpp \
    $(toolkit_src_dir)/builder/tree-node-manipulator.cpp \
    $(toolkit_src_dir)/builder/replacement.cpp \
+   $(toolkit_src_dir)/layouting/flex-layout-impl.cpp \
    $(toolkit_src_dir)/layouting/hbox-layout-impl.cpp \
    $(toolkit_src_dir)/layouting/vbox-layout-impl.cpp \
    $(toolkit_src_dir)/layouting/layout-item-data-impl.cpp \
diff --git a/dali-toolkit/internal/layouting/flex-layout-impl.cpp b/dali-toolkit/internal/layouting/flex-layout-impl.cpp
new file mode 100644 (file)
index 0000000..ebbf330
--- /dev/null
@@ -0,0 +1,452 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+//CLASS HEADER
+#include "flex-layout-impl.h"
+
+//EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/common/extents.h>
+#include <dali/devel-api/actors/actor-devel.h>
+#include <dali/devel-api/object/handle-devel.h>
+
+//INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/layouting/layout-item.h>
+#include <dali-toolkit/public-api/controls/control-impl.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/third-party/yoga/YGNode.h>
+
+#if defined(DEBUG_ENABLED)
+static Debug::Filter* gLogFilter = Debug::Filter::New( Debug::Concise, false, "LOG_LAYOUT" );
+#endif
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+
+FlexLayoutPtr FlexLayout::New()
+{
+  FlexLayoutPtr layout( new FlexLayout() );
+  return layout;
+}
+
+void FlexLayout::SetFlexDirection( Dali::Toolkit::FlexLayout::FlexDirection flexDirection )
+{
+  YGNodeStyleSetFlexDirection( mRoot, static_cast<YGFlexDirection>(flexDirection) );
+}
+
+Dali::Toolkit::FlexLayout::FlexDirection FlexLayout::GetFlexDirection() const
+{
+  return static_cast<Dali::Toolkit::FlexLayout::FlexDirection>(YGNodeStyleGetFlexDirection( mRoot ));
+}
+
+void FlexLayout::SetFlexJustification( Dali::Toolkit::FlexLayout::Justification flexJustification )
+{
+  YGNodeStyleSetJustifyContent( mRoot, static_cast<YGJustify>(flexJustification) );
+}
+
+Dali::Toolkit::FlexLayout::Justification FlexLayout::GetFlexJustification() const
+{
+  return static_cast<Dali::Toolkit::FlexLayout::Justification>(YGNodeStyleGetJustifyContent( mRoot ));
+}
+
+void FlexLayout::SetFlexWrap( Dali::Toolkit::FlexLayout::WrapType wrapType )
+{
+  YGNodeStyleSetFlexWrap( mRoot, static_cast<YGWrap>(wrapType) );
+}
+
+Dali::Toolkit::FlexLayout::WrapType FlexLayout::GetFlexWrap() const
+{
+  return static_cast<Dali::Toolkit::FlexLayout::WrapType>(YGNodeStyleGetFlexWrap( mRoot ));
+}
+
+void FlexLayout::SetFlexAlignment( Dali::Toolkit::FlexLayout::Alignment::Type flexAlignment )
+{
+  YGNodeStyleSetAlignContent( mRoot, static_cast<YGAlign>(flexAlignment) );
+}
+
+Dali::Toolkit::FlexLayout::Alignment::Type FlexLayout::GetFlexAlignment() const
+{
+  return static_cast<Dali::Toolkit::FlexLayout::Alignment::Type>(YGNodeStyleGetAlignContent( mRoot ));
+}
+
+void FlexLayout::SetFlexItemsAlignment( Dali::Toolkit::FlexLayout::Alignment::Type flexAlignment )
+{
+  YGNodeStyleSetAlignItems( mRoot, static_cast<YGAlign>(flexAlignment) );
+}
+
+Dali::Toolkit::FlexLayout::Alignment::Type FlexLayout::GetFlexItemsAlignment() const
+{
+  return static_cast<Dali::Toolkit::FlexLayout::Alignment::Type>(YGNodeStyleGetAlignItems( mRoot ));
+}
+
+FlexLayout::FlexLayout()
+: LayoutGroup(),
+  mRoot( nullptr )
+{
+  mRoot = YGNodeNew();
+  YGNodeSetContext( mRoot, this );
+
+  // Set default style
+  YGNodeStyleSetFlexDirection( mRoot, YGFlexDirectionColumn );
+  YGNodeStyleSetFlexWrap( mRoot, YGWrapNoWrap );
+  YGNodeStyleSetJustifyContent( mRoot, YGJustifyFlexStart );
+  YGNodeStyleSetAlignContent( mRoot, YGAlignFlexStart );
+  YGNodeStyleSetAlignItems( mRoot, YGAlignFlexStart );
+}
+
+FlexLayout::~FlexLayout()
+{
+  if( mRoot )
+  {
+    YGNodeFreeRecursive( mRoot );
+  }
+}
+
+void FlexLayout::DoInitialize()
+{
+}
+
+void FlexLayout::DoRegisterChildProperties( const std::string& containerType )
+{
+  auto typeInfo = Dali::TypeRegistry::Get().GetTypeInfo( containerType );
+  if( typeInfo )
+  {
+    Property::IndexContainer indices;
+    typeInfo.GetChildPropertyIndices( indices );
+
+    if( std::find( indices.Begin(), indices.End(), Toolkit::FlexLayout::ChildProperty::FLEX ) ==
+        indices.End() )
+    {
+      ChildPropertyRegistration( typeInfo.GetName(), "flex", Toolkit::FlexLayout::ChildProperty::FLEX, Property::FLOAT );
+    }
+
+    if( std::find( indices.Begin(), indices.End(), Toolkit::FlexLayout::ChildProperty::ALIGN_SELF ) ==
+        indices.End() )
+    {
+      ChildPropertyRegistration( typeInfo.GetName(), "alignSelf", Toolkit::FlexLayout::ChildProperty::ALIGN_SELF, Property::INTEGER );
+    }
+  }
+}
+
+void FlexLayout::OnChildAdd( LayoutItem& child )
+{
+  auto owner = child.GetOwner();
+  if(!DevelHandle::DoesCustomPropertyExist(owner, Toolkit::FlexLayout::ChildProperty::FLEX ))
+  {
+    owner.SetProperty( Toolkit::FlexLayout::ChildProperty::FLEX, 0 );
+  }
+  if(!DevelHandle::DoesCustomPropertyExist(owner, Toolkit::FlexLayout::ChildProperty::ALIGN_SELF ))
+  {
+    owner.SetProperty( Toolkit::FlexLayout::ChildProperty::ALIGN_SELF, YGAlignAuto );
+  }
+
+  YGNodeRef node = YGNodeNew();
+  YGNodeSetContext( node, &child );
+  YGNodeSetMeasureFunc( node, OnChildMeasure );
+  YGNodeMarkDirty( node );
+  YGNodeInsertChild( mRoot, node, GetChildCount()-1 );
+}
+
+void FlexLayout::OnChildRemove( LayoutItem& child )
+{
+  auto count = GetChildCount();
+  for( unsigned int childIndex = 0; childIndex < count; childIndex++)
+  {
+    LayoutItemPtr childLayout = GetChildAt( childIndex );
+    if( &child == childLayout.Get() )
+    {
+      YGNodeRef node = YGNodeGetChild( mRoot, childIndex );
+      YGNodeRemoveChild( mRoot, node );
+      break;
+    }
+  }
+}
+
+void FlexLayout::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec )
+{
+  auto actor = Actor::DownCast(GetOwner());
+  bool isLayoutRtl = actor ? actor.GetProperty<int>( Actor::Property::LAYOUT_DIRECTION ) == LayoutDirection::RIGHT_TO_LEFT: false;
+  Extents padding = GetPadding();
+  Extents margin = GetMargin();
+
+#if defined(DEBUG_ENABLED)
+  std::ostringstream oss;
+  oss << "FlexLayout::OnMeasure  ";
+  if( actor )
+  {
+       oss << "Actor Id:" << actor.GetId() << " Name:" << actor.GetName() << " Layout direction:" << actor.GetProperty( Actor::Property::LAYOUT_DIRECTION ).Get<int>() << " ";
+  }
+  oss << "widthMeasureSpec:" << widthMeasureSpec << " heightMeasureSpec:" << heightMeasureSpec << std::endl;
+  DALI_LOG_INFO( gLogFilter, Debug::Concise, oss.str().c_str() );
+#endif
+
+  YGNodeStyleSetMargin( mRoot, YGEdgeLeft, margin.start );
+  YGNodeStyleSetMargin( mRoot, YGEdgeTop, margin.top );
+  YGNodeStyleSetMargin( mRoot, YGEdgeRight, margin.end );
+  YGNodeStyleSetMargin( mRoot, YGEdgeBottom, margin.bottom );
+  YGNodeStyleSetPadding( mRoot, YGEdgeLeft, padding.start );
+  YGNodeStyleSetPadding( mRoot, YGEdgeTop, padding.top );
+  YGNodeStyleSetPadding( mRoot, YGEdgeRight, padding.end );
+  YGNodeStyleSetPadding( mRoot, YGEdgeBottom, padding.bottom );
+
+  float width = YGUndefined;
+  float height = YGUndefined;
+
+  YGNodeStyleSetWidth( mRoot, YGUndefined );
+  YGNodeStyleSetHeight( mRoot, YGUndefined );
+  YGNodeStyleSetMinWidth( mRoot, YGUndefined );
+  YGNodeStyleSetMinHeight( mRoot, YGUndefined );
+  YGNodeStyleSetMaxWidth( mRoot, YGUndefined );
+  YGNodeStyleSetMaxHeight( mRoot, YGUndefined );
+
+  if( widthMeasureSpec.GetMode() == MeasureSpec::Mode::EXACTLY )
+  {
+    width = widthMeasureSpec.GetSize();
+    YGNodeStyleSetWidth( mRoot, width );
+  }
+  else if( widthMeasureSpec.GetMode() == MeasureSpec::Mode::AT_MOST )
+  {
+    width = widthMeasureSpec.GetSize();
+    YGNodeStyleSetMaxWidth( mRoot, width );
+  }
+
+  if (heightMeasureSpec.GetMode() == MeasureSpec::Mode::EXACTLY)
+  {
+    height = heightMeasureSpec.GetSize();
+    YGNodeStyleSetHeight( mRoot, height );
+  }
+  else if (widthMeasureSpec.GetMode() == MeasureSpec::Mode::AT_MOST)
+  {
+    height = heightMeasureSpec.GetSize();
+    YGNodeStyleSetMaxHeight( mRoot, height );
+  }
+
+  SetChildrenStyle();
+  YGNodeCalculateLayout( mRoot, width, height, isLayoutRtl ? YGDirectionRTL : YGDirectionLTR );
+  SetMeasuredDimensions( GetDefaultSize( YGNodeLayoutGetWidth(mRoot), widthMeasureSpec ),
+                         GetDefaultSize( YGNodeLayoutGetHeight(mRoot), heightMeasureSpec ) );
+}
+
+void FlexLayout::OnLayout( bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom )
+{
+  auto owner = GetOwner();
+  auto actor = Actor::DownCast(owner);
+  bool isLayoutRtl = actor ? actor.GetProperty( Actor::Property::LAYOUT_DIRECTION ).Get<int>() == LayoutDirection::RIGHT_TO_LEFT: false;
+  auto width = right - left;
+  auto height = bottom - top;
+
+#if defined(DEBUG_ENABLED)
+  std::ostringstream oss;
+  oss << "FlexLayout::OnLayout  ";
+  if( actor )
+  {
+    oss << "Actor Id:" << actor.GetId() << " Name:" << actor.GetName() << " Layout direction:" << actor.GetProperty( Actor::Property::LAYOUT_DIRECTION ).Get<int>() << " ";
+  }
+  oss << "changed:" << (int)changed << " left:" << left << " top:" << top << " right:" << right << " bottom:" << bottom << " isLayoutRtl:" << (int)isLayoutRtl << std::endl;
+  DALI_LOG_INFO( gLogFilter, Debug::Concise, oss.str().c_str() );
+#endif
+
+  YGNodeCalculateLayout( mRoot, width, height, isLayoutRtl ? YGDirectionRTL : YGDirectionLTR );
+
+  auto count = GetChildCount();
+  for( unsigned int childIndex = 0; childIndex < count; childIndex++)
+  {
+    LayoutItemPtr childLayout = GetChildAt( childIndex );
+    if( childLayout != nullptr )
+    {
+      YGNodeRef node = YGNodeGetChild(mRoot, childIndex);
+      auto childLeft = YGNodeLayoutGetLeft( node ) + left;
+      auto childTop = YGNodeLayoutGetTop( node ) + top;
+      auto childWidth = YGNodeLayoutGetWidth( node );
+      auto childHeight = YGNodeLayoutGetHeight( node );
+      childLayout->Layout( childLeft, childTop, childLeft + childWidth, childTop + childHeight );
+    }
+  }
+}
+
+YGSize FlexLayout::OnChildMeasure( YGNodeRef node,
+                              float innerWidth,
+                              YGMeasureMode widthMode,
+                              float innerHeight,
+                              YGMeasureMode heightMode ) {
+  LayoutItem* childLayout = static_cast<LayoutItem*>(node->getContext());
+  auto childOwner = childLayout->GetOwner();
+  auto desiredWidth = childOwner.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION );
+  auto desiredHeight = childOwner.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION );
+
+  MeasureSpec::Mode measureWidthMode = MeasureSpec::Mode::AT_MOST;
+  MeasureSpec::Mode measureHeightMode = MeasureSpec::Mode::AT_MOST;
+  if( desiredWidth == Toolkit::ChildLayoutData::MATCH_PARENT )
+  {
+    if( innerWidth != YGUndefined)
+    {
+      desiredWidth = innerWidth;
+    }
+    measureWidthMode = MeasureSpec::Mode::EXACTLY;
+  }
+
+  if( desiredHeight == Toolkit::ChildLayoutData::MATCH_PARENT )
+  {
+    if( innerWidth != YGUndefined)
+    {
+      desiredHeight = innerHeight;
+    }
+    measureHeightMode = MeasureSpec::Mode::EXACTLY;
+  }
+
+  if( desiredWidth == Toolkit::ChildLayoutData::WRAP_CONTENT )
+  {
+    measureWidthMode = MeasureSpec::Mode::UNSPECIFIED;
+  }
+
+  if( desiredHeight == Toolkit::ChildLayoutData::WRAP_CONTENT )
+  {
+    measureHeightMode = MeasureSpec::Mode::UNSPECIFIED;
+  }
+
+  MeasureSpec widthMeasureSpec = MeasureSpec( desiredWidth, measureWidthMode );
+  MeasureSpec heightMeasureSpec = MeasureSpec( desiredHeight, measureHeightMode );
+  if( measureWidthMode == MeasureSpec::Mode::UNSPECIFIED ||
+      measureHeightMode == MeasureSpec::Mode::UNSPECIFIED )
+  {
+    // A measure just to get the size if the wrapped content
+    childLayout->Measure( widthMeasureSpec, heightMeasureSpec );
+    desiredWidth = childLayout->GetMeasuredWidth();
+    desiredHeight = childLayout->GetMeasuredHeight();
+    // Remove padding here since the second measure will add it back
+    Extents padding = childLayout->GetPadding();
+    desiredWidth = desiredWidth - padding.end - padding.start;
+    desiredHeight = desiredHeight - padding.bottom - padding.top;
+  }
+
+  // Safety check to avoid going out of boundary
+  if( (innerWidth != YGUndefined && innerWidth != 0) && innerWidth < desiredWidth )
+  {
+    desiredWidth = innerWidth;
+  }
+
+  if( (innerHeight != YGUndefined && innerHeight != 0) && innerHeight < desiredHeight )
+  {
+    desiredHeight = innerHeight;
+  }
+
+  // Measure for Yoga
+  MeasureSpec ygWidthMeasureSpec = MeasureSpec( desiredWidth, static_cast<MeasureSpec::Mode>(widthMode) );
+  MeasureSpec ygHeightMeasureSpec = MeasureSpec( desiredHeight, static_cast<MeasureSpec::Mode>(heightMode) );
+#if defined(DEBUG_ENABLED)
+  auto actor = Actor::DownCast(childOwner);
+  std::ostringstream oss;
+  oss << "FlexLayout::OnChildMeasure  ";
+  if( actor )
+  {
+    oss << "Actor Id:" << actor.GetId() << " Name:" << actor.GetName() << " ";
+  }
+  oss << "innerWidth:" << ((innerWidth == YGUndefined) ? "YGUndefined " : "") << innerWidth <<
+         " innerHeight:" << ((innerHeight == YGUndefined) ? "YGUndefined " : "") << innerHeight <<
+         " desiredWidth:" << desiredWidth << " desiredHeight:" << desiredHeight <<
+         " widthMeasureSpec:" << widthMeasureSpec << " heightMeasureSpec:" << heightMeasureSpec <<
+         " ygWidthMeasureSpec:" << ygWidthMeasureSpec << " ygHeightMeasureSpec:" << ygHeightMeasureSpec << std::endl;
+  DALI_LOG_INFO( gLogFilter, Debug::Concise, oss.str().c_str() );
+#endif
+
+  if( measureWidthMode == MeasureSpec::Mode::UNSPECIFIED ||
+      measureHeightMode == MeasureSpec::Mode::UNSPECIFIED )
+  {
+    if( ygWidthMeasureSpec == widthMeasureSpec && ygHeightMeasureSpec == heightMeasureSpec )
+    {
+      return YGSize{
+        .width = childLayout->GetMeasuredWidth(),
+        .height = childLayout->GetMeasuredHeight(),
+      };
+    }
+  }
+
+  childLayout->Measure( ygWidthMeasureSpec, ygHeightMeasureSpec );
+  return YGSize{
+    .width = childLayout->GetMeasuredWidth(),
+    .height = childLayout->GetMeasuredHeight(),
+  };
+}
+
+void FlexLayout::SetChildrenStyle()
+{
+  if( mRoot )
+  {
+    auto count = GetChildCount();
+    for( unsigned int childIndex = 0; childIndex < count; childIndex++)
+    {
+      LayoutItemPtr childLayout = GetChildAt( childIndex );
+      if( childLayout != nullptr )
+      {
+        Extents padding = childLayout->GetPadding();
+        Extents margin = childLayout->GetMargin();
+        auto childOwner = childLayout->GetOwner();
+        auto childActor = Actor::DownCast(childOwner);
+        auto flex = childOwner.GetProperty<float>( Toolkit::FlexLayout::ChildProperty::FLEX );
+        auto alignSelf = static_cast<YGAlign>( childOwner.GetProperty<int>( Toolkit::FlexLayout::ChildProperty::ALIGN_SELF ));
+
+        YGNodeRef childNode = YGNodeGetChild( mRoot, childIndex );
+        // Initialise the style of the child.
+        YGNodeStyleSetMargin( childNode, YGEdgeLeft, margin.start );
+        YGNodeStyleSetMargin( childNode, YGEdgeTop, margin.top );
+        YGNodeStyleSetMargin( childNode, YGEdgeRight, margin.end );
+        YGNodeStyleSetMargin( childNode, YGEdgeBottom, margin.bottom );
+
+        YGNodeStyleSetPadding( childNode, YGEdgeLeft, padding.start );
+        YGNodeStyleSetPadding( childNode, YGEdgeTop, padding.top );
+        YGNodeStyleSetPadding( childNode, YGEdgeRight, padding.end );
+        YGNodeStyleSetPadding( childNode, YGEdgeBottom, padding.bottom );
+
+        YGNodeStyleSetWidth( childNode, YGUndefined );
+        YGNodeStyleSetHeight( childNode, YGUndefined );
+        // TODO: check if we are supposed to use actor properties here, max/min is needed for stretch
+        YGNodeStyleSetMinWidth( childNode, childActor.GetMinimumSize().x );
+        YGNodeStyleSetMinHeight( childNode, childActor.GetMinimumSize().y );
+        if( childActor.GetMaximumSize().x == FLT_MAX )
+        {
+          YGNodeStyleSetMaxWidth( childNode, YGUndefined );
+        }
+        else
+        {
+          YGNodeStyleSetMaxWidth( childNode, childActor.GetMaximumSize().x );
+        }
+        if( childActor.GetMaximumSize().y == FLT_MAX )
+        {
+          YGNodeStyleSetMaxHeight( childNode, YGUndefined );
+        }
+        else
+        {
+          YGNodeStyleSetMaxHeight( childNode, childActor.GetMaximumSize().y );
+        }
+
+        YGNodeStyleSetFlex( childNode, flex );
+        YGNodeStyleSetAlignSelf( childNode, alignSelf );
+
+        // Have to do manually for nodes with custom measure function
+        // TODO: check the style is changed before marking the node
+        YGNodeMarkDirty( childNode );
+      }
+    }
+  }
+}
+
+} // namespace Internal
+} // namespace Toolkit
+} // namespace Dali
diff --git a/dali-toolkit/internal/layouting/flex-layout-impl.h b/dali-toolkit/internal/layouting/flex-layout-impl.h
new file mode 100644 (file)
index 0000000..b2bd236
--- /dev/null
@@ -0,0 +1,165 @@
+#ifndef DALI_TOOLKIT_INTERNAL_LAYOUTING_FLEX_LAYOUT_H
+#define DALI_TOOLKIT_INTERNAL_LAYOUTING_FLEX_LAYOUT_H
+
+/*
+ * Copyright (c) 2018 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.
+ */
+
+//EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/object/base-object.h>
+
+//INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/layouting/flex-layout.h>
+#include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
+#include <dali-toolkit/third-party/yoga/Yoga.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+
+class FlexLayout;
+using FlexLayoutPtr = IntrusivePtr<FlexLayout>;
+
+class FlexLayout final : public LayoutGroup
+{
+public:
+  static FlexLayoutPtr New();
+
+public:
+  /**
+   * @copydoc FlexLayout::SetFlexDirection
+   */
+  void SetFlexDirection( Dali::Toolkit::FlexLayout::FlexDirection flexDirection );
+
+  /**
+   * @copydoc FlexLayout::GetFlexDirection
+   */
+  Dali::Toolkit::FlexLayout::FlexDirection GetFlexDirection() const;
+
+  /**
+   * @copydoc FlexLayout::SetFlexJustification
+   */
+  void SetFlexJustification( Dali::Toolkit::FlexLayout::Justification flexJustification );
+
+  /**
+   * @copydoc FlexLayout::GetFlexJustification
+   */
+  Dali::Toolkit::FlexLayout::Justification GetFlexJustification() const;
+
+  /**
+   * @copydoc FlexLayout::SetFlexWrap
+   */
+  void SetFlexWrap( Dali::Toolkit::FlexLayout::WrapType wrap );
+
+  /**
+   * @copydoc FlexLayout::GetFlexWrap
+   */
+  Dali::Toolkit::FlexLayout::WrapType GetFlexWrap() const;
+
+  /**
+   * @copydoc FlexLayout::SetFlexAlignment
+   */
+  void SetFlexAlignment( Dali::Toolkit::FlexLayout::Alignment::Type flexAlignment );
+  /**
+   * @copydoc FlexLayout::GetFlexAlignment
+   */
+  Dali::Toolkit::FlexLayout::Alignment::Type GetFlexAlignment() const;
+
+  /**
+   * @copydoc FlexLayout::SetFlexItemsAlignment
+   */
+  void SetFlexItemsAlignment( Dali::Toolkit::FlexLayout::Alignment::Type flexAlignment );
+
+  /**
+   * @copydoc FlexLayout::GetFlexItemsAlignment
+   */
+  Dali::Toolkit::FlexLayout::Alignment::Type GetFlexItemsAlignment() const;
+
+protected:
+  /**
+   * Constructor
+   */
+  FlexLayout();
+
+  /**
+   * Virtual destructor
+   */
+  virtual ~FlexLayout();
+
+  /**
+   * @copydoc LayoutItem::DoInitialize
+   */
+  virtual void DoInitialize() override;
+
+  /**
+   * @copydoc LayoutItem::DoRegisterChildProperties()
+   */
+  virtual void DoRegisterChildProperties( const std::string& containerType ) override;
+
+  /**
+   * @copydoc LayoutItem::OnChildAdd
+   */
+  virtual void OnChildAdd( LayoutItem& child ) override;
+
+  /**
+   * @copydoc LayoutItem::OnChildRemove
+   */
+  virtual void OnChildRemove( LayoutItem& child ) override;
+
+  /**
+   * @copydoc LayoutItem::OnMeasure
+   */
+  virtual void OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec ) override;
+
+  /**
+   * @copydoc LayoutItem::OnLayout
+   */
+  virtual void OnLayout( bool changed, LayoutLength l, LayoutLength t, LayoutLength r, LayoutLength b ) override;
+
+private:
+  FlexLayout( const FlexLayout& other ) = delete;
+  FlexLayout& operator=( const FlexLayout& other ) = delete;
+
+  static YGSize OnChildMeasure( YGNodeRef node, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode );
+  void SetChildrenStyle();
+
+private:
+  YGNodeRef mRoot;
+};
+
+} // namespace Internal
+
+inline Internal::FlexLayout& GetImplementation( Dali::Toolkit::FlexLayout& handle )
+{
+  DALI_ASSERT_ALWAYS( handle && "FboxLayout handle is empty" );
+  BaseObject& object = handle.GetBaseObject();
+  return static_cast<Internal::FlexLayout&>( object );
+}
+
+inline const Internal::FlexLayout& GetImplementation( const Dali::Toolkit::FlexLayout& handle )
+{
+  DALI_ASSERT_ALWAYS( handle && "FboxLayout handle is empty" );
+  const BaseObject& object = handle.GetBaseObject();
+  return static_cast<const Internal::FlexLayout&>( object );
+}
+
+} // namespace Toolkit
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_LAYOUTING_FLEX_LAYOUT_H