diff --git a/src/Avalonia.Controls/DefinitionBase.cs b/src/Avalonia.Controls/Grid/DefinitionBase.cs
similarity index 94%
rename from src/Avalonia.Controls/DefinitionBase.cs
rename to src/Avalonia.Controls/Grid/DefinitionBase.cs
index 3dd4819ca7..ad2f33a18a 100644
--- a/src/Avalonia.Controls/DefinitionBase.cs
+++ b/src/Avalonia.Controls/Grid/DefinitionBase.cs
@@ -47,7 +47,7 @@ namespace Avalonia.Controls
///
/// Layout-time user size type.
///
- internal Grid.LayoutTimeSizeType SizeType { get; set; }
+ internal LayoutTimeSizeType SizeType { get; set; }
///
/// Returns or sets measure size for the definition.
@@ -65,12 +65,12 @@ namespace Avalonia.Controls
get
{
double preferredSize = MinSize;
- if (SizeType != Grid.LayoutTimeSizeType.Auto
+ if (SizeType != LayoutTimeSizeType.Auto
&& preferredSize < MeasureSize)
{
preferredSize = MeasureSize;
}
- return (preferredSize);
+ return (preferredSize);
}
}
diff --git a/src/Avalonia.Controls/Grid.cs b/src/Avalonia.Controls/Grid/Grid.cs
similarity index 85%
rename from src/Avalonia.Controls/Grid.cs
rename to src/Avalonia.Controls/Grid/Grid.cs
index 5b7b4b2afa..a14e3f0d01 100644
--- a/src/Avalonia.Controls/Grid.cs
+++ b/src/Avalonia.Controls/Grid/Grid.cs
@@ -9,11 +9,9 @@ using System.Reactive.Linq;
using System.Runtime.CompilerServices;
using Avalonia.Collections;
using Avalonia.Controls.Utils;
-using Avalonia.VisualTree;
using System.Threading;
using JetBrains.Annotations;
using Avalonia.Controls;
-using Avalonia.Media;
using Avalonia;
using System.Collections;
using Avalonia.Utilities;
@@ -21,9 +19,6 @@ using Avalonia.Layout;
namespace Avalonia.Controls
{
- ///
- /// Grid
- ///
public class Grid : Panel
{
internal bool CellsStructureDirty = true;
@@ -55,8 +50,7 @@ namespace Avalonia.Controls
// Keeps track of definition indices.
private int[] _definitionIndices;
- private CellCache[] _cellCache;
-
+ private GridCellCache[] _cellCache;
// Stores unrounded values and rounding errors during layout rounding.
private double[] _roundingErrors;
@@ -309,7 +303,7 @@ namespace Avalonia.Controls
}
}
- private bool IsTrivialGrid => (_definitionsU?.Length <= 1) &&
+ internal bool IsTrivialGrid => (_definitionsU?.Length <= 1) &&
(_definitionsV?.Length <= 1);
///
@@ -607,7 +601,7 @@ namespace Avalonia.Controls
{
if (!CellsStructureDirty) return;
- _cellCache = new CellCache[Children.Count];
+ _cellCache = new GridCellCache[Children.Count];
CellGroup1 = int.MaxValue;
CellGroup2 = int.MaxValue;
CellGroup3 = int.MaxValue;
@@ -626,7 +620,7 @@ namespace Avalonia.Controls
continue;
}
- var cell = new CellCache();
+ var cell = new GridCellCache();
// read indices from the corresponding properties
// clamp to value < number_of_columns
@@ -895,7 +889,7 @@ namespace Avalonia.Controls
{
foreach (DictionaryEntry e in spanStore)
{
- SpanKey key = (SpanKey)e.Key;
+ GridSpanKey key = (GridSpanKey)e.Key;
double requestedSize = (double)e.Value;
EnsureMinSizeInDefinitionRange(
@@ -928,7 +922,7 @@ namespace Avalonia.Controls
store = new Hashtable();
}
- SpanKey key = new SpanKey(start, count, u);
+ GridSpanKey key = new GridSpanKey(start, count, u);
object o = store[key];
if (o == null
@@ -2127,7 +2121,6 @@ namespace Avalonia.Controls
}
}
-
///
/// Synchronized ShowGridLines property with the state of the grid's visual collection
/// by adding / removing GridLinesRenderer visual.
@@ -2213,7 +2206,7 @@ namespace Avalonia.Controls
/// true if one or both of x and y are null, in which case result holds
/// the relative sort order.
///
- private static bool CompareNullRefs(object x, object y, out int result)
+ internal static bool CompareNullRefs(object x, object y, out int result)
{
result = 2;
@@ -2328,497 +2321,5 @@ namespace Avalonia.Controls
return def.UserSize.Value * scale;
}
}
-
- ///
- /// LayoutTimeSizeType is used internally and reflects layout-time size type.
- ///
- [System.Flags]
- internal enum LayoutTimeSizeType : byte
- {
- None = 0x00,
- Pixel = 0x01,
- Auto = 0x02,
- Star = 0x04,
- }
-
- ///
- /// CellCache stored calculated values of
- /// 1. attached cell positioning properties;
- /// 2. size type;
- /// 3. index of a next cell in the group;
- ///
- private struct CellCache
- {
- internal int ColumnIndex;
- internal int RowIndex;
- internal int ColumnSpan;
- internal int RowSpan;
- internal LayoutTimeSizeType SizeTypeU;
- internal LayoutTimeSizeType SizeTypeV;
- internal int Next;
- internal bool IsStarU { get { return ((SizeTypeU & LayoutTimeSizeType.Star) != 0); } }
- internal bool IsAutoU { get { return ((SizeTypeU & LayoutTimeSizeType.Auto) != 0); } }
- internal bool IsStarV { get { return ((SizeTypeV & LayoutTimeSizeType.Star) != 0); } }
- internal bool IsAutoV { get { return ((SizeTypeV & LayoutTimeSizeType.Auto) != 0); } }
- }
-
- ///
- /// Helper class for representing a key for a span in hashtable.
- ///
- private class SpanKey
- {
- ///
- /// Constructor.
- ///
- /// Starting index of the span.
- /// Span count.
- /// true for columns; false for rows.
- internal SpanKey(int start, int count, bool u)
- {
- _start = start;
- _count = count;
- _u = u;
- }
-
- ///
- ///
- ///
- public override int GetHashCode()
- {
- int hash = (_start ^ (_count << 2));
-
- if (_u) hash &= 0x7ffffff;
- else hash |= 0x8000000;
-
- return (hash);
- }
-
- ///
- ///
- ///
- public override bool Equals(object obj)
- {
- SpanKey sk = obj as SpanKey;
- return (sk != null
- && sk._start == _start
- && sk._count == _count
- && sk._u == _u);
- }
-
- ///
- /// Returns start index of the span.
- ///
- internal int Start { get { return (_start); } }
-
- ///
- /// Returns span count.
- ///
- internal int Count { get { return (_count); } }
-
- ///
- /// Returns true if this is a column span.
- /// false if this is a row span.
- ///
- internal bool U { get { return (_u); } }
-
- private int _start;
- private int _count;
- private bool _u;
- }
-
- ///
- /// SpanPreferredDistributionOrderComparer.
- ///
- private class SpanPreferredDistributionOrderComparer : IComparer
- {
- public int Compare(object x, object y)
- {
- DefinitionBase definitionX = x as DefinitionBase;
- DefinitionBase definitionY = y as DefinitionBase;
-
- int result;
-
- if (!CompareNullRefs(definitionX, definitionY, out result))
- {
- if (definitionX.UserSize.IsAuto)
- {
- if (definitionY.UserSize.IsAuto)
- {
- result = definitionX.MinSize.CompareTo(definitionY.MinSize);
- }
- else
- {
- result = -1;
- }
- }
- else
- {
- if (definitionY.UserSize.IsAuto)
- {
- result = +1;
- }
- else
- {
- result = definitionX.PreferredSize.CompareTo(definitionY.PreferredSize);
- }
- }
- }
-
- return result;
- }
- }
-
- ///
- /// SpanMaxDistributionOrderComparer.
- ///
- private class SpanMaxDistributionOrderComparer : IComparer
- {
- public int Compare(object x, object y)
- {
- DefinitionBase definitionX = x as DefinitionBase;
- DefinitionBase definitionY = y as DefinitionBase;
-
- int result;
-
- if (!CompareNullRefs(definitionX, definitionY, out result))
- {
- if (definitionX.UserSize.IsAuto)
- {
- if (definitionY.UserSize.IsAuto)
- {
- result = definitionX.SizeCache.CompareTo(definitionY.SizeCache);
- }
- else
- {
- result = +1;
- }
- }
- else
- {
- if (definitionY.UserSize.IsAuto)
- {
- result = -1;
- }
- else
- {
- result = definitionX.SizeCache.CompareTo(definitionY.SizeCache);
- }
- }
- }
-
- return result;
- }
- }
-
- ///
- /// RoundingErrorIndexComparer.
- ///
- private class RoundingErrorIndexComparer : IComparer
- {
- private readonly double[] errors;
-
- internal RoundingErrorIndexComparer(double[] errors)
- {
- Contract.Requires(errors != null);
- this.errors = errors;
- }
-
- public int Compare(object x, object y)
- {
- int? indexX = x as int?;
- int? indexY = y as int?;
-
- int result;
-
- if (!CompareNullRefs(indexX, indexY, out result))
- {
- double errorX = errors[indexX.Value];
- double errorY = errors[indexY.Value];
- result = errorX.CompareTo(errorY);
- }
-
- return result;
- }
- }
-
- ///
- /// MinRatioComparer.
- /// Sort by w/min (stored in MeasureSize), descending.
- /// We query the list from the back, i.e. in ascending order of w/min.
- ///
- private class MinRatioComparer : IComparer
- {
- public int Compare(object x, object y)
- {
- DefinitionBase definitionX = x as DefinitionBase;
- DefinitionBase definitionY = y as DefinitionBase;
-
- int result;
-
- if (!CompareNullRefs(definitionY, definitionX, out result))
- {
- result = definitionY.MeasureSize.CompareTo(definitionX.MeasureSize);
- }
-
- return result;
- }
- }
-
- ///
- /// MaxRatioComparer.
- /// Sort by w/max (stored in SizeCache), ascending.
- /// We query the list from the back, i.e. in descending order of w/max.
- ///
- private class MaxRatioComparer : IComparer
- {
- public int Compare(object x, object y)
- {
- DefinitionBase definitionX = x as DefinitionBase;
- DefinitionBase definitionY = y as DefinitionBase;
-
- int result;
-
- if (!CompareNullRefs(definitionX, definitionY, out result))
- {
- result = definitionX.SizeCache.CompareTo(definitionY.SizeCache);
- }
-
- return result;
- }
- }
-
- ///
- /// StarWeightComparer.
- /// Sort by *-weight (stored in MeasureSize), ascending.
- ///
- private class StarWeightComparer : IComparer
- {
- public int Compare(object x, object y)
- {
- DefinitionBase definitionX = x as DefinitionBase;
- DefinitionBase definitionY = y as DefinitionBase;
-
- int result;
-
- if (!CompareNullRefs(definitionX, definitionY, out result))
- {
- result = definitionX.MeasureSize.CompareTo(definitionY.MeasureSize);
- }
-
- return result;
- }
- }
-
- ///
- /// MinRatioIndexComparer.
- ///
- private class MinRatioIndexComparer : IComparer
- {
- private readonly DefinitionBase[] definitions;
-
- internal MinRatioIndexComparer(DefinitionBase[] definitions)
- {
- Contract.Requires(definitions != null);
- this.definitions = definitions;
- }
-
- public int Compare(object x, object y)
- {
- int? indexX = x as int?;
- int? indexY = y as int?;
-
- DefinitionBase definitionX = null;
- DefinitionBase definitionY = null;
-
- if (indexX != null)
- {
- definitionX = definitions[indexX.Value];
- }
- if (indexY != null)
- {
- definitionY = definitions[indexY.Value];
- }
-
- int result;
-
- if (!CompareNullRefs(definitionY, definitionX, out result))
- {
- result = definitionY.MeasureSize.CompareTo(definitionX.MeasureSize);
- }
-
- return result;
- }
- }
-
- ///
- /// MaxRatioIndexComparer.
- ///
- private class MaxRatioIndexComparer : IComparer
- {
- private readonly DefinitionBase[] definitions;
-
- internal MaxRatioIndexComparer(DefinitionBase[] definitions)
- {
- Contract.Requires(definitions != null);
- this.definitions = definitions;
- }
-
- public int Compare(object x, object y)
- {
- int? indexX = x as int?;
- int? indexY = y as int?;
-
- DefinitionBase definitionX = null;
- DefinitionBase definitionY = null;
-
- if (indexX != null)
- {
- definitionX = definitions[indexX.Value];
- }
- if (indexY != null)
- {
- definitionY = definitions[indexY.Value];
- }
-
- int result;
-
- if (!CompareNullRefs(definitionX, definitionY, out result))
- {
- result = definitionX.SizeCache.CompareTo(definitionY.SizeCache);
- }
-
- return result;
- }
- }
-
- ///
- /// MaxRatioIndexComparer.
- ///
- private class StarWeightIndexComparer : IComparer
- {
- private readonly DefinitionBase[] definitions;
-
- internal StarWeightIndexComparer(DefinitionBase[] definitions)
- {
- Contract.Requires(definitions != null);
- this.definitions = definitions;
- }
-
- public int Compare(object x, object y)
- {
- int? indexX = x as int?;
- int? indexY = y as int?;
-
- DefinitionBase definitionX = null;
- DefinitionBase definitionY = null;
-
- if (indexX != null)
- {
- definitionX = definitions[indexX.Value];
- }
- if (indexY != null)
- {
- definitionY = definitions[indexY.Value];
- }
-
- int result;
-
- if (!CompareNullRefs(definitionX, definitionY, out result))
- {
- result = definitionX.MeasureSize.CompareTo(definitionY.MeasureSize);
- }
-
- return result;
- }
- }
-
- ///
- /// Helper to render grid lines.
- ///
- private class GridLinesRenderer : Control
- {
- ///
- /// Static initialization
- ///
- static GridLinesRenderer()
- {
- var oddDashArray = new List();
- oddDashArray.Add(_dashLength);
- oddDashArray.Add(_dashLength);
- var ds1 = new DashStyle(oddDashArray, 0);
- _oddDashPen = new Pen(Brushes.Blue,
- _penWidth,
- lineCap: PenLineCap.Flat,
- dashStyle: ds1);
-
- var evenDashArray = new List();
- evenDashArray.Add(_dashLength);
- evenDashArray.Add(_dashLength);
- var ds2 = new DashStyle(evenDashArray, 0);
- _evenDashPen = new Pen(Brushes.Yellow,
- _penWidth,
- lineCap: PenLineCap.Flat,
- dashStyle: ds2);
- }
-
- ///
- /// UpdateRenderBounds.
- ///
- public override void Render(DrawingContext drawingContext)
- {
- var grid = this.GetVisualParent();
-
- if (grid == null
- || !grid.ShowGridLines
- || grid.IsTrivialGrid)
- {
- return;
- }
-
- for (int i = 1; i < grid.ColumnDefinitions.Count; ++i)
- {
- DrawGridLine(
- drawingContext,
- grid.ColumnDefinitions[i].FinalOffset, 0.0,
- grid.ColumnDefinitions[i].FinalOffset, _lastArrangeSize.Height);
- }
-
- for (int i = 1; i < grid.RowDefinitions.Count; ++i)
- {
- DrawGridLine(
- drawingContext,
- 0.0, grid.RowDefinitions[i].FinalOffset,
- _lastArrangeSize.Width, grid.RowDefinitions[i].FinalOffset);
- }
- }
-
- ///
- /// Draw single hi-contrast line.
- ///
- private static void DrawGridLine(
- DrawingContext drawingContext,
- double startX,
- double startY,
- double endX,
- double endY)
- {
- var start = new Point(startX, startY);
- var end = new Point(endX, endY);
- drawingContext.DrawLine(_oddDashPen, start, end);
- drawingContext.DrawLine(_evenDashPen, start, end);
- }
-
- internal void UpdateRenderBounds(Size arrangeSize)
- {
- _lastArrangeSize = arrangeSize;
- this.InvalidateVisual();
- }
-
- private static Size _lastArrangeSize;
- private const double _dashLength = 4.0; //
- private const double _penWidth = 1.0; //
- private static readonly Pen _oddDashPen; // first pen to draw dash
- private static readonly Pen _evenDashPen; // second pen to draw dash
- }
}
}
\ No newline at end of file
diff --git a/src/Avalonia.Controls/Grid/GridCellCache.cs b/src/Avalonia.Controls/Grid/GridCellCache.cs
new file mode 100644
index 0000000000..81edf72ca5
--- /dev/null
+++ b/src/Avalonia.Controls/Grid/GridCellCache.cs
@@ -0,0 +1,26 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Avalonia.Controls
+{
+ ///
+ /// CellCache stored calculated values of
+ /// 1. attached cell positioning properties;
+ /// 2. size type;
+ /// 3. index of a next cell in the group;
+ ///
+ internal struct GridCellCache
+ {
+ internal int ColumnIndex;
+ internal int RowIndex;
+ internal int ColumnSpan;
+ internal int RowSpan;
+ internal LayoutTimeSizeType SizeTypeU;
+ internal LayoutTimeSizeType SizeTypeV;
+ internal int Next;
+ internal bool IsStarU { get { return ((SizeTypeU & LayoutTimeSizeType.Star) != 0); } }
+ internal bool IsAutoU { get { return ((SizeTypeU & LayoutTimeSizeType.Auto) != 0); } }
+ internal bool IsStarV { get { return ((SizeTypeV & LayoutTimeSizeType.Star) != 0); } }
+ internal bool IsAutoV { get { return ((SizeTypeV & LayoutTimeSizeType.Auto) != 0); } }
+ }
+}
\ No newline at end of file
diff --git a/src/Avalonia.Controls/GridLength.cs b/src/Avalonia.Controls/Grid/GridLength.cs
similarity index 100%
rename from src/Avalonia.Controls/GridLength.cs
rename to src/Avalonia.Controls/Grid/GridLength.cs
diff --git a/src/Avalonia.Controls/Grid/GridLinesRenderer.cs b/src/Avalonia.Controls/Grid/GridLinesRenderer.cs
new file mode 100644
index 0000000000..338b8c40c1
--- /dev/null
+++ b/src/Avalonia.Controls/Grid/GridLinesRenderer.cs
@@ -0,0 +1,95 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections.Generic;
+using Avalonia.VisualTree;
+using Avalonia.Media;
+
+namespace Avalonia.Controls
+{
+ internal class GridLinesRenderer : Control
+ {
+ ///
+ /// Static initialization
+ ///
+ static GridLinesRenderer()
+ {
+ var oddDashArray = new List();
+ oddDashArray.Add(_dashLength);
+ oddDashArray.Add(_dashLength);
+ var ds1 = new DashStyle(oddDashArray, 0);
+ _oddDashPen = new Pen(Brushes.Blue,
+ _penWidth,
+ lineCap: PenLineCap.Flat,
+ dashStyle: ds1);
+
+ var evenDashArray = new List();
+ evenDashArray.Add(_dashLength);
+ evenDashArray.Add(_dashLength);
+ var ds2 = new DashStyle(evenDashArray, 0);
+ _evenDashPen = new Pen(Brushes.Yellow,
+ _penWidth,
+ lineCap: PenLineCap.Flat,
+ dashStyle: ds2);
+ }
+
+ ///
+ /// UpdateRenderBounds.
+ ///
+ public override void Render(DrawingContext drawingContext)
+ {
+ var grid = this.GetVisualParent();
+
+ if (grid == null
+ || !grid.ShowGridLines
+ || grid.IsTrivialGrid)
+ {
+ return;
+ }
+
+ for (int i = 1; i < grid.ColumnDefinitions.Count; ++i)
+ {
+ DrawGridLine(
+ drawingContext,
+ grid.ColumnDefinitions[i].FinalOffset, 0.0,
+ grid.ColumnDefinitions[i].FinalOffset, _lastArrangeSize.Height);
+ }
+
+ for (int i = 1; i < grid.RowDefinitions.Count; ++i)
+ {
+ DrawGridLine(
+ drawingContext,
+ 0.0, grid.RowDefinitions[i].FinalOffset,
+ _lastArrangeSize.Width, grid.RowDefinitions[i].FinalOffset);
+ }
+ }
+
+ ///
+ /// Draw single hi-contrast line.
+ ///
+ private static void DrawGridLine(
+ DrawingContext drawingContext,
+ double startX,
+ double startY,
+ double endX,
+ double endY)
+ {
+ var start = new Point(startX, startY);
+ var end = new Point(endX, endY);
+ drawingContext.DrawLine(_oddDashPen, start, end);
+ drawingContext.DrawLine(_evenDashPen, start, end);
+ }
+
+ internal void UpdateRenderBounds(Size arrangeSize)
+ {
+ _lastArrangeSize = arrangeSize;
+ this.InvalidateVisual();
+ }
+
+ private static Size _lastArrangeSize;
+ private const double _dashLength = 4.0; //
+ private const double _penWidth = 1.0; //
+ private static readonly Pen _oddDashPen; // first pen to draw dash
+ private static readonly Pen _evenDashPen; // second pen to draw dash
+ }
+}
\ No newline at end of file
diff --git a/src/Avalonia.Controls/Grid/GridSpanKey.cs b/src/Avalonia.Controls/Grid/GridSpanKey.cs
new file mode 100644
index 0000000000..cd48bc1265
--- /dev/null
+++ b/src/Avalonia.Controls/Grid/GridSpanKey.cs
@@ -0,0 +1,69 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Avalonia.Controls
+{
+ ///
+ /// Helper class for representing a key for a span in hashtable.
+ ///
+ internal class GridSpanKey
+ {
+ ///
+ /// Constructor.
+ ///
+ /// Starting index of the span.
+ /// Span count.
+ /// true for columns; false for rows.
+ internal GridSpanKey(int start, int count, bool u)
+ {
+ _start = start;
+ _count = count;
+ _u = u;
+ }
+
+ ///
+ ///
+ ///
+ public override int GetHashCode()
+ {
+ int hash = (_start ^ (_count << 2));
+
+ if (_u) hash &= 0x7ffffff;
+ else hash |= 0x8000000;
+
+ return (hash);
+ }
+
+ ///
+ ///
+ ///
+ public override bool Equals(object obj)
+ {
+ GridSpanKey sk = obj as GridSpanKey;
+ return (sk != null
+ && sk._start == _start
+ && sk._count == _count
+ && sk._u == _u);
+ }
+
+ ///
+ /// Returns start index of the span.
+ ///
+ internal int Start { get { return (_start); } }
+
+ ///
+ /// Returns span count.
+ ///
+ internal int Count { get { return (_count); } }
+
+ ///
+ /// Returns true if this is a column span.
+ /// false if this is a row span.
+ ///
+ internal bool U { get { return (_u); } }
+
+ private int _start;
+ private int _count;
+ private bool _u;
+ }
+}
\ No newline at end of file
diff --git a/src/Avalonia.Controls/GridSplitter.cs b/src/Avalonia.Controls/Grid/GridSplitter.cs
similarity index 100%
rename from src/Avalonia.Controls/GridSplitter.cs
rename to src/Avalonia.Controls/Grid/GridSplitter.cs
diff --git a/src/Avalonia.Controls/Grid/LayoutTimeSizeType.cs b/src/Avalonia.Controls/Grid/LayoutTimeSizeType.cs
new file mode 100644
index 0000000000..1432c29ae5
--- /dev/null
+++ b/src/Avalonia.Controls/Grid/LayoutTimeSizeType.cs
@@ -0,0 +1,17 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Avalonia.Controls
+{
+ ///
+ /// LayoutTimeSizeType is used internally and reflects layout-time size type.
+ ///
+ [System.Flags]
+ internal enum LayoutTimeSizeType : byte
+ {
+ None = 0x00,
+ Pixel = 0x01,
+ Auto = 0x02,
+ Star = 0x04,
+ }
+}
\ No newline at end of file
diff --git a/src/Avalonia.Controls/Grid/MaxRatioComparer.cs b/src/Avalonia.Controls/Grid/MaxRatioComparer.cs
new file mode 100644
index 0000000000..fe7eb356ec
--- /dev/null
+++ b/src/Avalonia.Controls/Grid/MaxRatioComparer.cs
@@ -0,0 +1,31 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections;
+
+namespace Avalonia.Controls
+{
+
+ ///
+ /// MaxRatioComparer.
+ /// Sort by w/max (stored in SizeCache), ascending.
+ /// We query the list from the back, i.e. in descending order of w/max.
+ ///
+ internal class MaxRatioComparer : IComparer
+ {
+ public int Compare(object x, object y)
+ {
+ DefinitionBase definitionX = x as DefinitionBase;
+ DefinitionBase definitionY = y as DefinitionBase;
+
+ int result;
+
+ if (!Grid.CompareNullRefs(definitionX, definitionY, out result))
+ {
+ result = definitionX.SizeCache.CompareTo(definitionY.SizeCache);
+ }
+
+ return result;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Avalonia.Controls/Grid/MaxRatioIndexComparer.cs b/src/Avalonia.Controls/Grid/MaxRatioIndexComparer.cs
new file mode 100644
index 0000000000..01bcf85b27
--- /dev/null
+++ b/src/Avalonia.Controls/Grid/MaxRatioIndexComparer.cs
@@ -0,0 +1,46 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections;
+
+namespace Avalonia.Controls
+{
+ internal class MaxRatioIndexComparer : IComparer
+ {
+ private readonly DefinitionBase[] definitions;
+
+ internal MaxRatioIndexComparer(DefinitionBase[] definitions)
+ {
+ Contract.Requires(definitions != null);
+ this.definitions = definitions;
+ }
+
+ public int Compare(object x, object y)
+ {
+ int? indexX = x as int?;
+ int? indexY = y as int?;
+
+ DefinitionBase definitionX = null;
+ DefinitionBase definitionY = null;
+
+ if (indexX != null)
+ {
+ definitionX = definitions[indexX.Value];
+ }
+ if (indexY != null)
+ {
+ definitionY = definitions[indexY.Value];
+ }
+
+ int result;
+
+ if (!Grid.CompareNullRefs(definitionX, definitionY, out result))
+ {
+ result = definitionX.SizeCache.CompareTo(definitionY.SizeCache);
+ }
+
+ return result;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Avalonia.Controls/Grid/MinRatioComparer.cs b/src/Avalonia.Controls/Grid/MinRatioComparer.cs
new file mode 100644
index 0000000000..8e0fa0a282
--- /dev/null
+++ b/src/Avalonia.Controls/Grid/MinRatioComparer.cs
@@ -0,0 +1,30 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections;
+
+namespace Avalonia.Controls
+{
+ ///
+ /// MinRatioComparer.
+ /// Sort by w/min (stored in MeasureSize), descending.
+ /// We query the list from the back, i.e. in ascending order of w/min.
+ ///
+ internal class MinRatioComparer : IComparer
+ {
+ public int Compare(object x, object y)
+ {
+ DefinitionBase definitionX = x as DefinitionBase;
+ DefinitionBase definitionY = y as DefinitionBase;
+
+ int result;
+
+ if (!Grid.CompareNullRefs(definitionY, definitionX, out result))
+ {
+ result = definitionY.MeasureSize.CompareTo(definitionX.MeasureSize);
+ }
+
+ return result;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Avalonia.Controls/Grid/MinRatioIndexComparer.cs b/src/Avalonia.Controls/Grid/MinRatioIndexComparer.cs
new file mode 100644
index 0000000000..01add324c1
--- /dev/null
+++ b/src/Avalonia.Controls/Grid/MinRatioIndexComparer.cs
@@ -0,0 +1,46 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections;
+
+namespace Avalonia.Controls
+{
+ internal class MinRatioIndexComparer : IComparer
+ {
+ private readonly DefinitionBase[] definitions;
+
+ internal MinRatioIndexComparer(DefinitionBase[] definitions)
+ {
+ Contract.Requires(definitions != null);
+ this.definitions = definitions;
+ }
+
+ public int Compare(object x, object y)
+ {
+ int? indexX = x as int?;
+ int? indexY = y as int?;
+
+ DefinitionBase definitionX = null;
+ DefinitionBase definitionY = null;
+
+ if (indexX != null)
+ {
+ definitionX = definitions[indexX.Value];
+ }
+ if (indexY != null)
+ {
+ definitionY = definitions[indexY.Value];
+ }
+
+ int result;
+
+ if (!Grid.CompareNullRefs(definitionY, definitionX, out result))
+ {
+ result = definitionY.MeasureSize.CompareTo(definitionX.MeasureSize);
+ }
+
+ return result;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Avalonia.Controls/Grid/RoundingErrorIndexComparer.cs b/src/Avalonia.Controls/Grid/RoundingErrorIndexComparer.cs
new file mode 100644
index 0000000000..a0a9035384
--- /dev/null
+++ b/src/Avalonia.Controls/Grid/RoundingErrorIndexComparer.cs
@@ -0,0 +1,36 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections;
+
+namespace Avalonia.Controls
+{
+ internal class RoundingErrorIndexComparer : IComparer
+ {
+ private readonly double[] errors;
+
+ internal RoundingErrorIndexComparer(double[] errors)
+ {
+ Contract.Requires(errors != null);
+ this.errors = errors;
+ }
+
+ public int Compare(object x, object y)
+ {
+ int? indexX = x as int?;
+ int? indexY = y as int?;
+
+ int result;
+
+ if (!Grid.CompareNullRefs(indexX, indexY, out result))
+ {
+ double errorX = errors[indexX.Value];
+ double errorY = errors[indexY.Value];
+ result = errorX.CompareTo(errorY);
+ }
+
+ return result;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Avalonia.Controls/Grid/SpanMaxDistributionOrderComparer.cs b/src/Avalonia.Controls/Grid/SpanMaxDistributionOrderComparer.cs
new file mode 100644
index 0000000000..f6fbf4d2bb
--- /dev/null
+++ b/src/Avalonia.Controls/Grid/SpanMaxDistributionOrderComparer.cs
@@ -0,0 +1,46 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections;
+
+namespace Avalonia.Controls
+{
+ internal class SpanMaxDistributionOrderComparer : IComparer
+ {
+ public int Compare(object x, object y)
+ {
+ DefinitionBase definitionX = x as DefinitionBase;
+ DefinitionBase definitionY = y as DefinitionBase;
+
+ int result;
+
+ if (!Grid.CompareNullRefs(definitionX, definitionY, out result))
+ {
+ if (definitionX.UserSize.IsAuto)
+ {
+ if (definitionY.UserSize.IsAuto)
+ {
+ result = definitionX.SizeCache.CompareTo(definitionY.SizeCache);
+ }
+ else
+ {
+ result = +1;
+ }
+ }
+ else
+ {
+ if (definitionY.UserSize.IsAuto)
+ {
+ result = -1;
+ }
+ else
+ {
+ result = definitionX.SizeCache.CompareTo(definitionY.SizeCache);
+ }
+ }
+ }
+
+ return result;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Avalonia.Controls/Grid/SpanPreferredDistributionOrderComparer.cs b/src/Avalonia.Controls/Grid/SpanPreferredDistributionOrderComparer.cs
new file mode 100644
index 0000000000..1adb62590c
--- /dev/null
+++ b/src/Avalonia.Controls/Grid/SpanPreferredDistributionOrderComparer.cs
@@ -0,0 +1,46 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections;
+
+namespace Avalonia.Controls
+{
+ internal class SpanPreferredDistributionOrderComparer : IComparer
+ {
+ public int Compare(object x, object y)
+ {
+ DefinitionBase definitionX = x as DefinitionBase;
+ DefinitionBase definitionY = y as DefinitionBase;
+
+ int result;
+
+ if (!Grid.CompareNullRefs(definitionX, definitionY, out result))
+ {
+ if (definitionX.UserSize.IsAuto)
+ {
+ if (definitionY.UserSize.IsAuto)
+ {
+ result = definitionX.MinSize.CompareTo(definitionY.MinSize);
+ }
+ else
+ {
+ result = -1;
+ }
+ }
+ else
+ {
+ if (definitionY.UserSize.IsAuto)
+ {
+ result = +1;
+ }
+ else
+ {
+ result = definitionX.PreferredSize.CompareTo(definitionY.PreferredSize);
+ }
+ }
+ }
+
+ return result;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Avalonia.Controls/Grid/StarWeightComparer.cs b/src/Avalonia.Controls/Grid/StarWeightComparer.cs
new file mode 100644
index 0000000000..216f97f2c1
--- /dev/null
+++ b/src/Avalonia.Controls/Grid/StarWeightComparer.cs
@@ -0,0 +1,29 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections;
+
+namespace Avalonia.Controls
+{
+ ///
+ /// StarWeightComparer.
+ /// Sort by *-weight (stored in MeasureSize), ascending.
+ ///
+ internal class StarWeightComparer : IComparer
+ {
+ public int Compare(object x, object y)
+ {
+ DefinitionBase definitionX = x as DefinitionBase;
+ DefinitionBase definitionY = y as DefinitionBase;
+
+ int result;
+
+ if (!Grid.CompareNullRefs(definitionX, definitionY, out result))
+ {
+ result = definitionX.MeasureSize.CompareTo(definitionY.MeasureSize);
+ }
+
+ return result;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Avalonia.Controls/Grid/StarWeightIndexComparer.cs b/src/Avalonia.Controls/Grid/StarWeightIndexComparer.cs
new file mode 100644
index 0000000000..da5148e9a5
--- /dev/null
+++ b/src/Avalonia.Controls/Grid/StarWeightIndexComparer.cs
@@ -0,0 +1,47 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections;
+
+namespace Avalonia.Controls
+{
+
+ internal class StarWeightIndexComparer : IComparer
+ {
+ private readonly DefinitionBase[] definitions;
+
+ internal StarWeightIndexComparer(DefinitionBase[] definitions)
+ {
+ Contract.Requires(definitions != null);
+ this.definitions = definitions;
+ }
+
+ public int Compare(object x, object y)
+ {
+ int? indexX = x as int?;
+ int? indexY = y as int?;
+
+ DefinitionBase definitionX = null;
+ DefinitionBase definitionY = null;
+
+ if (indexX != null)
+ {
+ definitionX = definitions[indexX.Value];
+ }
+ if (indexY != null)
+ {
+ definitionY = definitions[indexY.Value];
+ }
+
+ int result;
+
+ if (!Grid.CompareNullRefs(definitionX, definitionY, out result))
+ {
+ result = definitionX.MeasureSize.CompareTo(definitionY.MeasureSize);
+ }
+
+ return result;
+ }
+ }
+}
\ No newline at end of file