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