Fix possible error if negative grid columns set 44/187944/4
authorAgnelo Vaz <agnelo.vaz@samsung.com>
Wed, 29 Aug 2018 18:25:34 +0000 (19:25 +0100)
committerAgnelo Vaz <agnelo.vaz@samsung.com>
Mon, 3 Sep 2018 18:36:15 +0000 (19:36 +0100)
Change-Id: Icd20fe7968f1e77501e4593b2fa81d40aabacb55

automated-tests/src/dali-toolkit/custom-layout-impl.cpp
automated-tests/src/dali-toolkit/custom-layout-impl.h
automated-tests/src/dali-toolkit/custom-layout.cpp
automated-tests/src/dali-toolkit/custom-layout.h
automated-tests/src/dali-toolkit/utc-Dali-GridLayout.cpp
dali-toolkit/internal/layouting/grid-impl.cpp
dali-toolkit/internal/layouting/grid-locations.cpp

index 97ded95..115336a 100644 (file)
@@ -30,12 +30,40 @@ namespace Internal
 using Dali::Actor;
 using Dali::Toolkit::MeasuredSize;
 
+CustomLayout::CustomLayout()
+: mBehaviourFlags( 0 )
+{
+}
+
 CustomLayoutPtr CustomLayout::New()
 {
   CustomLayoutPtr layout( new CustomLayout() );
   return layout;
 }
 
+void CustomLayout::MeasureChildren( Dali::Toolkit::Internal::LayoutItemPtr childLayout, MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec, int resultingWidth, int resultingHeight )
+{
+  // Initially use the measure spec of the child's parent
+  auto childWidthMeasureSpec = widthMeasureSpec;
+  auto childHeightMeasureSpec = heightMeasureSpec;
+
+  if ( true == GetCustomBehaviourFlags( Test::CustomLayout::BEHAVIOUR_FLAG_UNCONSTRAINED_CHILD_WIDTH ) )
+  {
+    // Use unspecified width measure spec, child can be any width it desires
+    childWidthMeasureSpec = MeasureSpec( widthMeasureSpec.GetSize(), MeasureSpec::Mode::UNSPECIFIED );
+  }
+
+  if ( true == GetCustomBehaviourFlags( Test::CustomLayout::BEHAVIOUR_FLAG_UNCONSTRAINED_CHILD_HEIGHT) )
+  {
+    // Use unspecified height measure spec, child can be any height it desires
+    childHeightMeasureSpec = MeasureSpec( heightMeasureSpec.GetSize(), MeasureSpec::Mode::UNSPECIFIED );
+  }
+
+  MeasureChild( childLayout, childWidthMeasureSpec, childHeightMeasureSpec );
+  resultingWidth += childLayout->GetMeasuredWidth();
+  resultingHeight = std::max( childLayout->GetMeasuredHeight().mValue, resultingHeight );
+}
+
 void CustomLayout::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec )
 {
   auto accumulatedWidth = 0;
@@ -51,9 +79,7 @@ void CustomLayout::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMe
     auto childLayout = GetChildAt( i );
     if( childLayout )
     {
-      MeasureChild( childLayout, widthMeasureSpec, heightMeasureSpec );
-      accumulatedWidth += childLayout->GetMeasuredWidth();
-      maxHeight = std::max( childLayout->GetMeasuredHeight().mValue, maxHeight );
+        MeasureChildren( childLayout, widthMeasureSpec, heightMeasureSpec, accumulatedWidth, maxHeight );
     }
   }
 
@@ -100,6 +126,23 @@ void CustomLayout::OnLayout( bool changed, LayoutLength left, LayoutLength top,
   }
 }
 
+void CustomLayout::SetCustomBehaviourFlag( int flag )
+{
+  mBehaviourFlags |= flag;
+  RequestLayout();
+}
+
+bool CustomLayout::GetCustomBehaviourFlags( int flagToCheck )
+{
+  return ( mBehaviourFlags & flagToCheck ) != 0;
+}
+
+void CustomLayout::ClearPrivateFlag( int flag )
+{
+    mBehaviourFlags &= ~flag;
+    RequestLayout();
+}
+
 } // namespace Internal
 
 } // namespace Test
index b2dcb99..7fb7be2 100644 (file)
@@ -20,6 +20,7 @@
 // EXTERNAL INCLUDES
 #include <dali/public-api/common/intrusive-ptr.h>
 #include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
+#include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
 
 // INTERNAL INCLUDES
 #include "custom-layout.h"
@@ -57,12 +58,27 @@ public:
   CustomLayout( CustomLayout&& other ) = default;
   CustomLayout& operator=( CustomLayout&& other ) = default;
 
+  /**
+   * @copydoc CustomLayout::SetCustomBehaviourFlag
+   */
+  void SetCustomBehaviourFlag( int flag );
+
+  /**
+   * @copydoc CustomLayout::GetCustomBehaviourFlags
+   */
+  bool GetCustomBehaviourFlags( int flagToCheck );
+
+  /**
+   * @copydoc CustomLayout::ClearPrivateFlag
+   */
+  void ClearPrivateFlag( int flag );
+
 private:
 
   /**
    * @brief Default Constructor
    */
-  CustomLayout() = default;
+  CustomLayout();
 
   /**
    * Virtual Destructor
@@ -83,6 +99,20 @@ private:
    */
   virtual void OnLayout( bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom ) override;
 
+  /**
+   * Measure children with parent's measure spec unless BehaviourFlag set to use an unconstrained width or height.
+   * @param[in] childLayout child to measure
+   * @param[in] widthMeasureSpec default layout width measure spec
+   * @param[in] heightMeasureSpec default layout height measure spec
+   * @param[out] resultingWidth resulting width of layout after children are measured
+   * @param[out] resultingHeight resulting height of layout after children are measured
+   */
+  void MeasureChildren( Dali::Toolkit::Internal::LayoutItemPtr childLayout, MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec, int resultingWidth, int resultingHeight );
+
+  private:
+
+  int mBehaviourFlags; // flags to alter behaviour of this custom layout
+
 };
 
 } // namespace Internal
index 4a85014..8060840 100644 (file)
@@ -43,4 +43,20 @@ void CustomLayout::RequestLayout()
 {
   GetImplementation( *this ).RequestLayout();
 }
+
+void CustomLayout::SetCustomBehaviourFlag( int flag )
+{
+  GetImplementation(*this).SetCustomBehaviourFlag( flag );
+}
+
+bool CustomLayout::GetCustomBehaviourFlags( int flagToCheck )
+{
+  return GetImplementation(*this).GetCustomBehaviourFlags( flagToCheck );
+}
+
+void CustomLayout::ClearPrivateFlag( int flag )
+{
+  return GetImplementation(*this).ClearPrivateFlag( flag );
+}
+
 } // namespace Test
index fa977e7..df07d4f 100644 (file)
@@ -38,6 +38,10 @@ class CustomLayout : public Dali::Toolkit::LayoutGroup
 {
 public:
 
+  // Behaviour flags
+  static const int BEHAVIOUR_FLAG_UNCONSTRAINED_CHILD_WIDTH                = 0x00000001;  // Child width measured without constraint
+  static const int BEHAVIOUR_FLAG_UNCONSTRAINED_CHILD_HEIGHT               = 0x00000002;  // Child height measured without constraint
+
   /**
    * @brief Creates an uninitialized CustomLayout handle.
    *
@@ -90,8 +94,29 @@ public:
    */
   static CustomLayout DownCast( BaseHandle handle );
 
+  /**
+   * Request for a relayout of this layout
+   */
   void RequestLayout();
 
+  /**
+   * Enables setting of flags corresponding to particular behaviour of this layout
+   * @param[in] flag the flag to set
+   */
+  void SetCustomBehaviourFlag( int flag );
+
+  /**
+   * Returns true or false depending on whether flag is set
+   * @return bool returns true if flag set
+   */
+  bool GetCustomBehaviourFlags( int flagToCheck );
+
+  /**
+   * Clears the flag if already set.
+   * @param[in] flag the flag to clear
+   */
+  void ClearPrivateFlag( int flag );
+
 public: // Not intended for application developers
 
   /// @cond internal
index 4950241..224c6f4 100644 (file)
@@ -332,6 +332,287 @@ int UtcDaliLayouting_GridLayout04(void)
   END_TEST;
 }
 
+int UtcDaliLayouting_GridLayout05(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_GridLayout05 2 Column, 4 Items UNSPECIFIED width and height SPECIFICATIONS");
+
+  const auto NUMBER_OF_COLUMNS = 2;
+  const auto NUMBER_OF_ITEMS = 4;
+
+  tet_printf( "Testing %d columns with %d items\n", NUMBER_OF_COLUMNS, NUMBER_OF_ITEMS );
+
+  Stage stage = Stage::GetCurrent();
+
+  auto rootControl = Control::New();
+  auto absoluteLayout = AbsoluteLayout::New();
+  DevelControl::SetLayout( rootControl, absoluteLayout );
+  rootControl.SetName( "AbsoluteLayout" );
+  stage.Add( rootControl );
+
+  auto customLayout = Test::CustomLayout::New();
+  tet_printf( "Set Flag so child is measured with an unconstrained measure spec\n");
+  customLayout.SetCustomBehaviourFlag( Test::CustomLayout::BEHAVIOUR_FLAG_UNCONSTRAINED_CHILD_WIDTH );
+  customLayout.SetCustomBehaviourFlag( Test::CustomLayout::BEHAVIOUR_FLAG_UNCONSTRAINED_CHILD_HEIGHT );
+  auto customHBox = Control::New();
+  customHBox.SetName("CustomHBox");
+  DevelControl::SetLayout( customHBox, customLayout );
+  tet_printf( "Set width of custom layout to be smaller than child Grid wants to be\n");
+  customHBox.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, 150 );
+  customHBox.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, 150 );
+  rootControl.Add( customHBox );
+
+  auto gridContainer = Control::New();
+  auto gridLayout = Grid::New();
+  gridLayout.SetNumberOfColumns( NUMBER_OF_COLUMNS );
+  gridContainer.SetName( "GridLayout");
+  DevelControl::SetLayout( gridContainer, gridLayout );
+  tet_printf( "Grid SPEC set to MATCH_PARENT, this will be ignored if BEHAVIOUR_FLAG_UNCONSTRAINED_CHILD_WIDTH or BEHAVIOUR_FLAG_UNCONSTRAINED_CHILD_HEIGHT flags are set\n");
+  gridContainer.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  gridContainer.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+
+  std::vector< Control > controls;
+  for( auto i=0; i < NUMBER_OF_ITEMS; i++ )
+  {
+    controls.push_back( CreateLeafControl( 100, 100 ) );
+  }
+
+  for( auto&& iter : controls )
+  {
+    gridContainer.Add( iter );
+  }
+
+  customHBox.Add( gridContainer );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+ // Grid will layout first 2 items on first row then last 2 on second row.
+  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( 100.0f, 0.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( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  // Item sizes will not be changed
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.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_GridLayout06(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_GridLayout06 2 Column, 4 Items UNSPECIFIED width SPECIFICATION");
+
+  const auto NUMBER_OF_COLUMNS = 2;
+  const auto NUMBER_OF_ITEMS = 4;
+
+  tet_printf( "Testing %d columns with %d items\n", NUMBER_OF_COLUMNS, NUMBER_OF_ITEMS );
+
+  Stage stage = Stage::GetCurrent();
+
+  auto rootControl = Control::New();
+  auto absoluteLayout = AbsoluteLayout::New();
+  DevelControl::SetLayout( rootControl, absoluteLayout );
+  rootControl.SetName( "AbsoluteLayout" );
+  stage.Add( rootControl );
+
+  auto customLayout = Test::CustomLayout::New();
+  tet_printf( "Set Flag so child is measured with an unconstrained measure spec\n");
+  customLayout.SetCustomBehaviourFlag( Test::CustomLayout::BEHAVIOUR_FLAG_UNCONSTRAINED_CHILD_WIDTH );
+  auto customHBox = Control::New();
+  customHBox.SetName("CustomHBox");
+  DevelControl::SetLayout( customHBox, customLayout );
+  tet_printf( "Set width of custom layout to be smaller than child Grid wants to be\n");
+  customHBox.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, 150 );
+  customHBox.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, 150 );
+  rootControl.Add( customHBox );
+
+  auto gridContainer = Control::New();
+  auto gridLayout = Grid::New();
+  gridLayout.SetNumberOfColumns( NUMBER_OF_COLUMNS );
+  gridContainer.SetName( "GridLayout");
+  DevelControl::SetLayout( gridContainer, gridLayout );
+  tet_printf( "Grid SPEC set to MATCH_PARENT, this will be ignored if BEHAVIOUR_FLAG_UNCONSTRAINED_CHILD_WIDTH or BEHAVIOUR_FLAG_UNCONSTRAINED_CHILD_HEIGHT flags are set\n");
+  gridContainer.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  gridContainer.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+
+  std::vector< Control > controls;
+  for( auto i=0; i < NUMBER_OF_ITEMS; i++ )
+  {
+    controls.push_back( CreateLeafControl( 100, 100 ) );
+  }
+
+  for( auto&& iter : controls )
+  {
+    gridContainer.Add( iter );
+  }
+
+  customHBox.Add( gridContainer );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+ // Grid will layout first 2 items on first row then last 2 on second row.
+  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( 100.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 75.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f, 75.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  // Item sizes will not be changed
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 75.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 75.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 75.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 75.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliLayouting_GridLayout07(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_GridLayout07 2 Column, 4 Items UNSPECIFIED height SPECIFICATION");
+
+  const auto NUMBER_OF_COLUMNS = 2;
+  const auto NUMBER_OF_ITEMS = 4;
+
+  tet_printf( "Testing %d columns with %d items\n", NUMBER_OF_COLUMNS, NUMBER_OF_ITEMS );
+
+  Stage stage = Stage::GetCurrent();
+
+  auto rootControl = Control::New();
+  auto absoluteLayout = AbsoluteLayout::New();
+  DevelControl::SetLayout( rootControl, absoluteLayout );
+  rootControl.SetName( "AbsoluteLayout" );
+  stage.Add( rootControl );
+
+  auto customLayout = Test::CustomLayout::New();
+  tet_printf( "Set Flag so child is measured with an unconstrained measure spec\n");
+  customLayout.SetCustomBehaviourFlag( Test::CustomLayout::BEHAVIOUR_FLAG_UNCONSTRAINED_CHILD_HEIGHT );
+  auto customHBox = Control::New();
+  customHBox.SetName("CustomHBox");
+  DevelControl::SetLayout( customHBox, customLayout );
+  tet_printf( "Set width of custom layout to be smaller than child Grid wants to be\n");
+  customHBox.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, 150 );
+  customHBox.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, 150 );
+  rootControl.Add( customHBox );
+
+  auto gridContainer = Control::New();
+  auto gridLayout = Grid::New();
+  gridLayout.SetNumberOfColumns( NUMBER_OF_COLUMNS );
+  gridContainer.SetName( "GridLayout");
+  DevelControl::SetLayout( gridContainer, gridLayout );
+  tet_printf( "Grid SPEC set to MATCH_PARENT, this will be ignored if BEHAVIOUR_FLAG_UNCONSTRAINED_CHILD_WIDTH or BEHAVIOUR_FLAG_UNCONSTRAINED_CHILD_HEIGHT flags are set\n");
+  gridContainer.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  gridContainer.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+
+  std::vector< Control > controls;
+  for( auto i=0; i < NUMBER_OF_ITEMS; i++ )
+  {
+    controls.push_back( CreateLeafControl( 100, 100 ) );
+  }
+
+  for( auto&& iter : controls )
+  {
+    gridContainer.Add( iter );
+  }
+
+  customHBox.Add( gridContainer );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+ // Grid will layout first 2 items on first row then last 2 on second row.
+  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( 75.0f, 0.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( 75.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  // Item sizes will not be changed
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 75.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 75.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 75.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 75.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliLayouting_GridLayout08(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_GridLayout08 2 Column, 4 Items Grid with children too wide for parent spec");
+
+  const auto NUMBER_OF_COLUMNS = 2;
+  const auto NUMBER_OF_ITEMS = 4;
+
+  tet_printf( "Testing %d columns with %d items\n", NUMBER_OF_COLUMNS, NUMBER_OF_ITEMS );
+
+  Stage stage = Stage::GetCurrent();
+
+  auto rootControl = Control::New();
+  auto absoluteLayout = AbsoluteLayout::New();
+  DevelControl::SetLayout( rootControl, absoluteLayout );
+  rootControl.SetName( "AbsoluteLayout" );
+  stage.Add( rootControl );
+
+  auto customLayout = Test::CustomLayout::New();
+  auto customHBox = Control::New();
+  customHBox.SetName("CustomHBox");
+  DevelControl::SetLayout( customHBox, customLayout );
+  tet_printf( "Set width of custom layout to be smaller than child Grid wants to be\n");
+  customHBox.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, 150 );
+  customHBox.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, 200 );
+  rootControl.Add( customHBox );
+
+  auto gridContainer = Control::New();
+  auto gridLayout = Grid::New();
+  gridLayout.SetNumberOfColumns( NUMBER_OF_COLUMNS );
+  gridContainer.SetName( "GridLayout");
+  DevelControl::SetLayout( gridContainer, gridLayout );
+  gridContainer.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  gridContainer.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+
+  std::vector< Control > controls;
+  for( auto i=0; i < NUMBER_OF_ITEMS; i++ )
+  {
+    controls.push_back( CreateLeafControl( 100, 100 ) );
+  }
+
+  for( auto&& iter : controls )
+  {
+    gridContainer.Add( iter );
+  }
+
+  customHBox.Add( gridContainer );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  tet_printf( "Children width reduced from 100 to 75\n", NUMBER_OF_COLUMNS, NUMBER_OF_ITEMS );
+  // Grid will layout first 2 items on first row then last 2 on second row.
+  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( 75.0f, 0.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( 75.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  // Item sizes will be changed
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 75.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 75.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 75.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 75.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
+
 
 int UtcDaliLayouting_GridLayoutDownCast(void)
 {
index b8e2b22..af9b82e 100644 (file)
@@ -66,7 +66,7 @@ void Grid::SetNumberOfColumns( int columns )
   // Store value and Relayout if changed.
   if( columns != mNumColumns )
   {
-    mNumColumns = columns;
+    mNumColumns = std::max( 1, columns );
     RequestLayout();
   }
 }
@@ -186,11 +186,11 @@ void Grid::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpe
     // Grid expands to fit content
 
     // If number of columns AUTO_FIT then set to 1 column.
-
+    mNumColumns = ( mNumColumns > 0 ) ? mNumColumns : 1;
     // Calculate numbers of rows, round down result as later check for remainder.
-    mNumRows = childCount / ( ( mNumColumns ) ? mNumColumns : 1 );
+    mNumRows = childCount / mNumColumns;
     // If number of cells not cleanly dividable by colums, add another row to house remainder cells.
-    mNumRows += ( childCount %  ( ( mNumColumns ) ? mNumColumns : 1 ) ) ? 1 : 0;
+    mNumRows += ( childCount % mNumColumns ) ? 1 : 0;
 
     availableContentHeight = desiredChildHeight * mNumRows;
   }
index 8cb1cca..a4d3060 100644 (file)
@@ -59,6 +59,8 @@ void GridLocations::CalculateLocations( int numberOfColumns,
                                         unsigned int columnWidth,
                                         unsigned int rowHeight )
 {
+  DALI_ASSERT_DEBUG( numberOfColumns > 0 && "number of columns should be greater than 0" );
+  numberOfColumns = std::max ( numberOfColumns, 1 );
   mLocations.clear();
 
   // Calculate width and height of columns and rows.