diff --git a/dev/RadioButtons/ColumnMajorUniformToLargestGridLayout.cpp b/dev/RadioButtons/ColumnMajorUniformToLargestGridLayout.cpp index b6ae136a31..61edaee219 100644 --- a/dev/RadioButtons/ColumnMajorUniformToLargestGridLayout.cpp +++ b/dev/RadioButtons/ColumnMajorUniformToLargestGridLayout.cpp @@ -15,10 +15,6 @@ winrt::Size ColumnMajorUniformToLargestGridLayout::MeasureOverride( { if (auto const children = context.Children()) { - auto const maxColumns = std::max(1, MaxColumns()); - MUX_ASSERT(maxColumns > 0); - auto const maxItemsPerColumn = static_cast(std::ceil(static_cast(children.Size()) / static_cast(maxColumns))); - m_largestChildSize = [children, availableSize]() { auto largestChildWidth = 0.0f; @@ -39,12 +35,11 @@ winrt::Size ColumnMajorUniformToLargestGridLayout::MeasureOverride( return winrt::Size(largestChildWidth, largestChildHeight); }(); - auto const actualColumnCount = std::min( - static_cast(maxColumns), - static_cast(children.Size())); + m_actualColumnCount = CalculateColumns(children.Size(), m_largestChildSize.Width, availableSize.Width); + auto const maxItemsPerColumn = static_cast(std::ceil(static_cast(children.Size()) / static_cast(m_actualColumnCount))); return winrt::Size( - (m_largestChildSize.Width * actualColumnCount) + - (static_cast(ColumnSpacing()) * (actualColumnCount - 1)), + (m_largestChildSize.Width * m_actualColumnCount) + + (static_cast(ColumnSpacing()) * (m_actualColumnCount - 1)), (m_largestChildSize.Height * maxItemsPerColumn) + (static_cast(RowSpacing()) * (maxItemsPerColumn - 1)) ); @@ -58,11 +53,9 @@ winrt::Size ColumnMajorUniformToLargestGridLayout::ArrangeOverride( { if (auto const children = context.Children()) { - auto const maxColumns = std::max(1, MaxColumns()); - MUX_ASSERT(maxColumns > 0); auto const itemCount = children.Size(); - auto const minitemsPerColumn = static_cast(std::floor(static_cast(itemCount) / static_cast(maxColumns))); - auto const numberOfColumnsWithExtraElements = static_cast(itemCount % maxColumns); + auto const minitemsPerColumn = static_cast(std::floor(static_cast(itemCount) / m_actualColumnCount)); + auto const numberOfColumnsWithExtraElements = static_cast(itemCount % static_cast(m_actualColumnCount)); auto const columnSpacing = static_cast(ColumnSpacing()); auto const rowSpacing = static_cast(RowSpacing()); @@ -138,6 +131,39 @@ void ColumnMajorUniformToLargestGridLayout::OnMaxColumnsPropertyChanged(const wi InvalidateMeasure(); } +int ColumnMajorUniformToLargestGridLayout::CalculateColumns(int childCount, float maxItemWidth, float availableWidth) +{ + /* + -------------------------------------------------------------- + | |-----------|-----------| | widthNeededForExtraColumn | + | | | + | |------| |------| | ColumnSpacing | + | |----| |----| |----| | maxItemWidth | + | O RB O RB O RB | | + -------------------------------------------------------------- + */ + + // Every column execpt the first takes this ammount of space to fit on screen. + auto const widthNeededForExtraColumn = ColumnSpacing() + maxItemWidth; + // The number of columns from data and api ignoring available space + auto const requestedColumnCount = std::min(MaxColumns(), childCount); + + // If columns can be added with effectively 0 extra space return as many columns as needed. + if (widthNeededForExtraColumn < std::numeric_limits::epsilon()) + { + return requestedColumnCount; + } + + auto const extraWidthAfterFirstColumn = availableWidth - maxItemWidth; + auto const maxExtraColumns = std::max(0.0, std::floor(extraWidthAfterFirstColumn / widthNeededForExtraColumn)); + + // The smaller of number of columns from data and api and + // the number of columns the available space can support + auto const effectiveColumnCount = std::min(static_cast(requestedColumnCount), maxExtraColumns + 1); + // return 1 even if there isn't any data + return std::max(1, static_cast(effectiveColumnCount)); +} + void ColumnMajorUniformToLargestGridLayout::ValidateGreaterThanZero(int value) { if (value <= 0) @@ -147,7 +173,6 @@ void ColumnMajorUniformToLargestGridLayout::ValidateGreaterThanZero(int value) } //Testhooks helpers, only function while m_testHooksEnabled == true - void ColumnMajorUniformToLargestGridLayout::SetTestHooksEnabled(bool enabled) { m_testHooksEnabled = enabled; diff --git a/dev/RadioButtons/ColumnMajorUniformToLargestGridLayout.h b/dev/RadioButtons/ColumnMajorUniformToLargestGridLayout.h index a92eebd7d3..78ff3ec9d3 100644 --- a/dev/RadioButtons/ColumnMajorUniformToLargestGridLayout.h +++ b/dev/RadioButtons/ColumnMajorUniformToLargestGridLayout.h @@ -37,6 +37,8 @@ class ColumnMajorUniformToLargestGridLayout : void LayoutChanged(winrt::event_token const& token); private: + int CalculateColumns(int childCount, float maxItemWidth, float availableWidth); + int m_actualColumnCount{ 1 }; winrt::Size m_largestChildSize{ 0,0 }; //Testhooks helpers, only function while m_testHooksEnabled == true diff --git a/dev/RadioButtons/InteractionTests/RadioButtonsTestPageElements.cs b/dev/RadioButtons/InteractionTests/RadioButtonsTestPageElements.cs index 75e7641434..dd1d392895 100644 --- a/dev/RadioButtons/InteractionTests/RadioButtonsTestPageElements.cs +++ b/dev/RadioButtons/InteractionTests/RadioButtonsTestPageElements.cs @@ -184,6 +184,18 @@ public ComboBox GetSourceComboBox() } private ComboBox SourceComboBox; + public Edit GetBorderWidthTextBox() + { + return GetElement(ref BorderWidthTextBox, "BorderWidthTextBox"); + } + private Edit BorderWidthTextBox; + + public Button GetSetBorderWidthButton() + { + return GetElement(ref SetBorderWidthButton, "SetBorderWidthButton"); + } + private Button SetBorderWidthButton; + public Button GetFocusSelectedItemButton() { return GetElement(ref FocusSelectedItemButton, "FocusSelectedItemButton"); diff --git a/dev/RadioButtons/InteractionTests/RadioButtonsTests.cs b/dev/RadioButtons/InteractionTests/RadioButtonsTests.cs index 0e7debb002..b4772472ba 100644 --- a/dev/RadioButtons/InteractionTests/RadioButtonsTests.cs +++ b/dev/RadioButtons/InteractionTests/RadioButtonsTests.cs @@ -527,6 +527,7 @@ public void ColumnsTest() SetItemType(type); SetNumberOfColumns(1); SetNumberOfItems(10); + SetBorderWidthToInf(); VerifyLayoutData(10, 1, 0); SetNumberOfColumns(3); @@ -538,10 +539,21 @@ public void ColumnsTest() SetNumberOfColumns(10); VerifyLayoutData(1, 10, 0); SetNumberOfColumns(20); - VerifyLayoutData(0, 10, 10); + VerifyLayoutData(1, 10, 0); SetNumberOfItems(77); VerifyLayoutData(3, 20, 17); + + SetBorderWidth(100); + VerifyLayoutData(77, 1, 0); + SetBorderWidth(200); + VerifyLayoutData(77, 1, 0); + SetBorderWidth(300); + VerifyLayoutData(38, 2, 1); + SetBorderWidth(500); + VerifyLayoutData(25, 3, 2); + SetBorderWidth(550); + VerifyLayoutData(19, 4, 1); } } } @@ -651,6 +663,18 @@ void SetNumberOfItems(int items) elements.GetSetNumberOfItemsButton().Click(); } + void SetBorderWidth(float width) + { + elements.GetBorderWidthTextBox().SetValue(width.ToString()); + elements.GetSetBorderWidthButton().Click(); + } + + void SetBorderWidthToInf() + { + elements.GetBorderWidthTextBox().SetValue("inf"); + elements.GetSetBorderWidthButton().Click(); + } + void SetSource(RadioButtonsSourceLocation location) { switch(location) diff --git a/dev/RadioButtons/TestUI/RadioButtonsPage.xaml b/dev/RadioButtons/TestUI/RadioButtonsPage.xaml index 19a3150690..26c28966bb 100644 --- a/dev/RadioButtons/TestUI/RadioButtonsPage.xaml +++ b/dev/RadioButtons/TestUI/RadioButtonsPage.xaml @@ -22,7 +22,9 @@ - + + + "I'm really a Radio Button" I'm just a string @@ -68,6 +70,7 @@ + @@ -111,9 +114,11 @@ -