From 5434c2607f3806204be8d7f192d3be53584d9ad6 Mon Sep 17 00:00:00 2001 From: Agnelo Vaz Date: Wed, 29 Aug 2018 19:25:34 +0100 Subject: [PATCH] Fix possible error if negative grid columns set Change-Id: Icd20fe7968f1e77501e4593b2fa81d40aabacb55 --- .../src/dali-toolkit/custom-layout-impl.cpp | 49 +++- .../src/dali-toolkit/custom-layout-impl.h | 32 ++- automated-tests/src/dali-toolkit/custom-layout.cpp | 16 ++ automated-tests/src/dali-toolkit/custom-layout.h | 25 ++ .../src/dali-toolkit/utc-Dali-GridLayout.cpp | 281 +++++++++++++++++++++ dali-toolkit/internal/layouting/grid-impl.cpp | 8 +- dali-toolkit/internal/layouting/grid-locations.cpp | 2 + 7 files changed, 405 insertions(+), 8 deletions(-) diff --git a/automated-tests/src/dali-toolkit/custom-layout-impl.cpp b/automated-tests/src/dali-toolkit/custom-layout-impl.cpp index 97ded95..115336a 100644 --- a/automated-tests/src/dali-toolkit/custom-layout-impl.cpp +++ b/automated-tests/src/dali-toolkit/custom-layout-impl.cpp @@ -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 diff --git a/automated-tests/src/dali-toolkit/custom-layout-impl.h b/automated-tests/src/dali-toolkit/custom-layout-impl.h index b2dcb99..7fb7be2 100644 --- a/automated-tests/src/dali-toolkit/custom-layout-impl.h +++ b/automated-tests/src/dali-toolkit/custom-layout-impl.h @@ -20,6 +20,7 @@ // EXTERNAL INCLUDES #include #include +#include // 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 diff --git a/automated-tests/src/dali-toolkit/custom-layout.cpp b/automated-tests/src/dali-toolkit/custom-layout.cpp index 4a85014..8060840 100644 --- a/automated-tests/src/dali-toolkit/custom-layout.cpp +++ b/automated-tests/src/dali-toolkit/custom-layout.cpp @@ -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 diff --git a/automated-tests/src/dali-toolkit/custom-layout.h b/automated-tests/src/dali-toolkit/custom-layout.h index fa977e7..df07d4f 100644 --- a/automated-tests/src/dali-toolkit/custom-layout.h +++ b/automated-tests/src/dali-toolkit/custom-layout.h @@ -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 diff --git a/automated-tests/src/dali-toolkit/utc-Dali-GridLayout.cpp b/automated-tests/src/dali-toolkit/utc-Dali-GridLayout.cpp index 4950241..224c6f4 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-GridLayout.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-GridLayout.cpp @@ -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( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::POSITION ), Vector3( 100.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[2].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[3].GetProperty( 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( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[2].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[3].GetProperty( 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( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::POSITION ), Vector3( 100.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[2].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 75.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[3].GetProperty( 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( Actor::Property::SIZE ), Vector3( 100.0f, 75.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 75.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[2].GetProperty( Actor::Property::SIZE ), Vector3( 100.0f, 75.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[3].GetProperty( 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( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::POSITION ), Vector3( 75.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[2].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[3].GetProperty( 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( Actor::Property::SIZE ), Vector3( 75.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::SIZE ), Vector3( 75.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[2].GetProperty( Actor::Property::SIZE ), Vector3( 75.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[3].GetProperty( 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( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::POSITION ), Vector3( 75.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[2].GetProperty( Actor::Property::POSITION ), Vector3( 0.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[3].GetProperty( 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( Actor::Property::SIZE ), Vector3( 75.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[1].GetProperty( Actor::Property::SIZE ), Vector3( 75.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[2].GetProperty( Actor::Property::SIZE ), Vector3( 75.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + DALI_TEST_EQUALS( controls[3].GetProperty( Actor::Property::SIZE ), Vector3( 75.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION ); + + END_TEST; +} + int UtcDaliLayouting_GridLayoutDownCast(void) { diff --git a/dali-toolkit/internal/layouting/grid-impl.cpp b/dali-toolkit/internal/layouting/grid-impl.cpp index b8e2b22..af9b82e 100644 --- a/dali-toolkit/internal/layouting/grid-impl.cpp +++ b/dali-toolkit/internal/layouting/grid-impl.cpp @@ -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; } diff --git a/dali-toolkit/internal/layouting/grid-locations.cpp b/dali-toolkit/internal/layouting/grid-locations.cpp index 8cb1cca..a4d3060 100644 --- a/dali-toolkit/internal/layouting/grid-locations.cpp +++ b/dali-toolkit/internal/layouting/grid-locations.cpp @@ -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. -- 2.7.4