Fix bound checks for FirstColumn in Dimension and FreeSpot method helpers of UniformGrid.

This commit is contained in:
mhawker 2018-04-11 23:10:55 -07:00
Родитель 9afec2059c
Коммит 4b7624c6cb
3 изменённых файлов: 147 добавлений и 13 удалений

Просмотреть файл

@ -32,12 +32,14 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
{
if (topdown)
{
var rows = arrayref.SpotsTaken.GetLength(0);
// Layout spots from Top-Bottom, Left-Right (right-left handled automatically by Grid with Flow-Direction).
// Effectively transpose the Grid Layout.
for (int c = 0; c < arrayref.SpotsTaken.GetLength(1); c++)
{
int start = (c == 0 && firstcolumn > 0) ? firstcolumn : 0;
for (int r = start; r < arrayref.SpotsTaken.GetLength(0); r++)
int start = (c == 0 && firstcolumn > 0 && firstcolumn < rows) ? firstcolumn : 0;
for (int r = start; r < rows; r++)
{
// TODO: Do we want/need to worry about size here, what is our expectation?
if (!arrayref.SpotsTaken[r, c])
@ -49,13 +51,15 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
}
else
{
var columns = arrayref.SpotsTaken.GetLength(1);
// Layout spots as normal from Left-Right.
// (right-left handled automatically by Grid with Flow-Direction
// during its layout, internal model is always left-right).
for (int r = 0; r < arrayref.SpotsTaken.GetLength(0); r++)
{
int start = (r == 0 && firstcolumn > 0) ? firstcolumn : 0;
for (int c = start; c < arrayref.SpotsTaken.GetLength(1); c++)
int start = (r == 0 && firstcolumn > 0 && firstcolumn < columns) ? firstcolumn : 0;
for (int c = start; c < columns; c++)
{
// TODO: Do we want/need to worry about size here, what is our expectation?
if (!arrayref.SpotsTaken[r, c])
@ -86,21 +90,24 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
{
if (cols > 0)
{
var first = Math.Min(firstColumn, cols - 1); // Bound check
// Bound check
var first = (firstColumn >= cols || firstColumn < 0) ? 0 : firstColumn;
// If we have columns but no rows, calculate rows based on column offset and number of children.
rows = (count + first + (cols - 1)) / cols;
return (rows, cols);
}
else
{
// Otherwise, determine square layout if both are zero.
var size = (int)Math.Ceiling(Math.Sqrt(count));
// Otherwise, determine square layout if both are zero.
var size = (int)Math.Ceiling(Math.Sqrt(count));
// Figure out if firstColumn is in bounds
var first = (firstColumn >= size || firstColumn < 0) ? 0 : firstColumn;
// Figure out if firstColumn in bounds
var first2 = Math.Min(firstColumn, size - 1); // Bound check
rows = (int)Math.Ceiling(Math.Sqrt(count + first2));
return (rows, rows);
rows = (int)Math.Ceiling(Math.Sqrt(count + first));
return (rows, rows);
}
}
else if (cols == 0)
{
@ -108,7 +115,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
cols = (count + (rows - 1)) / rows;
// Now that we know a rough size of our shape, see if the FirstColumn effects that:
var first = Math.Min(firstColumn, cols - 1); // Bound check
var first = (firstColumn >= cols || firstColumn < 0) ? 0 : firstColumn;
cols = (count + first + (rows - 1)) / rows;
}

Просмотреть файл

@ -205,6 +205,43 @@ namespace UnitTests.UI.Controls
Assert.AreEqual(4, dimensions.rows);
Assert.AreEqual(4, dimensions.columns);
}
[TestCategory("UniformGrid")]
[UITestMethod]
public void Test_UniformGrid_GetDimensions_FirstColumnEqualsColumns()
{
var treeroot = XamlReader.Load(@"<Page
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
xmlns:controls=""using:Microsoft.Toolkit.Uwp.UI.Controls"">
<controls:UniformGrid x:Name=""UniformGrid"">
<Border/>
<Border/>
<Border/>
<Border/>
<Border/>
<Border/>
<Border/>
</controls:UniformGrid>
</Page>") as FrameworkElement;
Assert.IsNotNull(treeroot, "Could not load XAML tree.");
var grid = treeroot.FindChildByName("UniformGrid") as UniformGrid;
Assert.IsNotNull(grid, "Could not find UniformGrid in tree.");
var children = grid.Children.Select(item => item as FrameworkElement);
Assert.AreEqual(7, grid.Children.Count());
// columns == first column
// In WPF, First Column is ignored and we have a 1x7 layout.
var dimensions = UniformGrid.GetDimensions(ref children, 0, 7, 7);
Assert.AreEqual(1, dimensions.rows, "Expected single row.");
Assert.AreEqual(7, dimensions.columns, "Expected seven columns.");
}
}
#pragma warning restore SA1008 // Opening parenthesis must be spaced correctly
}

Просмотреть файл

@ -93,6 +93,96 @@ namespace UnitTests.UI.Controls
results.ToArrayString());
}
[TestCategory("UniformGrid")]
[UITestMethod]
public void Test_UniformGrid_GetFreeSpots_FirstColumnEndBoundMinusOne()
{
var grid = new UniformGrid();
var testref = new TakenSpotsReferenceHolder(new bool[3, 3]
{
{ false, false, false },
{ false, false, false },
{ false, false, false },
});
var results = UniformGrid.GetFreeSpot(testref, 2, false).ToArray();
var expected = new(int row, int column)[]
{
(0, 2),
(1, 0),(1, 1),(1, 2),
(2, 0),(2, 1),(2, 2),
};
CollectionAssert.AreEqual(
expected,
results,
"GetFreeSpot failed FirstColumn. Expected:\n{0}.\nActual:\n{1}",
expected.ToArrayString(),
results.ToArrayString());
}
[TestCategory("UniformGrid")]
[UITestMethod]
public void Test_UniformGrid_GetFreeSpots_FirstColumnEndBound()
{
var grid = new UniformGrid();
var testref = new TakenSpotsReferenceHolder(new bool[3, 3]
{
{ false, false, false },
{ false, false, false },
{ false, false, false },
});
var results = UniformGrid.GetFreeSpot(testref, 3, false).ToArray();
var expected = new(int row, int column)[]
{
(0, 0),(0, 1),(0, 2),
(1, 0),(1, 1),(1, 2),
(2, 0),(2, 1),(2, 2),
};
CollectionAssert.AreEqual(
expected,
results,
"GetFreeSpot failed FirstColumn. Expected:\n{0}.\nActual:\n{1}",
expected.ToArrayString(),
results.ToArrayString());
}
[TestCategory("UniformGrid")]
[UITestMethod]
public void Test_UniformGrid_GetFreeSpots_FirstColumnEndBound_TopDown()
{
var grid = new UniformGrid();
var testref = new TakenSpotsReferenceHolder(new bool[3, 3]
{
{ false, false, false },
{ false, false, false },
{ false, false, false },
});
var results = UniformGrid.GetFreeSpot(testref, 3, true).ToArray();
var expected = new(int row, int column)[]
{
(0, 0),(1, 0),(2, 0),
(0, 1),(1, 1),(2, 1),
(0, 2),(1, 2),(2, 2),
};
CollectionAssert.AreEqual(
expected,
results,
"GetFreeSpot failed FirstColumn. Expected:\n{0}.\nActual:\n{1}",
expected.ToArrayString(),
results.ToArrayString());
}
[TestCategory("UniformGrid")]
[UITestMethod]
public void Test_UniformGrid_GetFreeSpots_VerticalOrientation()