From 689ca63c7ac90c81d3eecbdcec6816f0c8bc7a6a Mon Sep 17 00:00:00 2001 From: Jumar Macato Date: Mon, 27 May 2019 10:51:07 +0800 Subject: [PATCH] Fix DPI fallback value on LayoutRounding; Rename `rowColDefsEmpty` to `IsTrivialGrid`; --- src/Avalonia.Controls/GridWPF.cs | 66 +++++++++++++++++++------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/src/Avalonia.Controls/GridWPF.cs b/src/Avalonia.Controls/GridWPF.cs index 0549c7f20a..119c94c6e0 100644 --- a/src/Avalonia.Controls/GridWPF.cs +++ b/src/Avalonia.Controls/GridWPF.cs @@ -33,6 +33,11 @@ namespace Avalonia.Controls internal bool HasStarCellsU; internal bool HasStarCellsV; internal bool HasGroup3CellsInAutoRows; + internal bool MeasureOverrideInProgress; + internal bool ArrangeOverrideInProgress; + internal bool ColumnDefinitionsDirty; + internal bool RowDefinitionsDirty; + // index of the first cell in first cell group internal int CellGroup1; @@ -44,7 +49,6 @@ namespace Avalonia.Controls internal int CellGroup3; // index of the first cell in fourth cell group - internal int CellGroup4; // temporary array used during layout for various purposes @@ -60,9 +64,9 @@ namespace Avalonia.Controls // Stores unrounded values and rounding errors during layout rounding. private double[] _roundingErrors; - private DefinitionBase[] DefinitionsU = new DefinitionBase[1] { new ColumnDefinition() }; - private DefinitionBase[] DefinitionsV = new DefinitionBase[1] { new RowDefinition() }; - private const int c_layoutLoopMaxCount = 5; // 5 is an arbitrary constant chosen to end the measure loop + private DefinitionBase[] DefinitionsU; + private DefinitionBase[] DefinitionsV; + private const int layoutLoopMaxCount = 5; // 5 is an arbitrary constant chosen to end the measure loop private static readonly LocalDataStoreSlot s_tempDefinitionsDataSlot = Thread.AllocateDataSlot(); private static readonly IComparer s_spanPreferredDistributionOrderComparer = new SpanPreferredDistributionOrderComparer(); private static readonly IComparer s_spanMaxDistributionOrderComparer = new SpanMaxDistributionOrderComparer(); @@ -73,6 +77,7 @@ namespace Avalonia.Controls static Grid() { ShowGridLinesProperty.Changed.AddClassHandler(OnShowGridLinesPropertyChanged); + ColumnProperty.Changed.AddClassHandler(OnCellAttachedPropertyChanged); ColumnSpanProperty.Changed.AddClassHandler(OnCellAttachedPropertyChanged); RowProperty.Changed.AddClassHandler(OnCellAttachedPropertyChanged); @@ -167,7 +172,6 @@ namespace Avalonia.Controls return element.GetValue(RowSpanProperty); } - /// /// Gets the value of the IsSharedSizeScope attached property for a control. /// @@ -243,6 +247,8 @@ namespace Avalonia.Controls if (_columnDefinitions.Count > 0) DefinitionsU = _columnDefinitions.Cast().ToArray(); + else + DefinitionsU = new DefinitionBase[1] { new ColumnDefinition() }; _columnDefinitions.CollectionChanged += (_, e) => { @@ -283,6 +289,8 @@ namespace Avalonia.Controls if (_rowDefinitions.Count > 0) DefinitionsV = _rowDefinitions.Cast().ToArray(); + else + DefinitionsV = new DefinitionBase[1] { new ColumnDefinition() }; _rowDefinitions.CollectionChanged += (_, e) => { @@ -300,8 +308,8 @@ namespace Avalonia.Controls } } - private bool rowColDefsEmpty => (DefinitionsU.Length == 0) && - (DefinitionsV.Length == 0); + private bool IsTrivialGrid => (DefinitionsU?.Length <= 1) && + (DefinitionsV?.Length <= 1); /// /// Content measurement. @@ -317,7 +325,7 @@ namespace Avalonia.Controls ListenToNotifications = true; MeasureOverrideInProgress = true; - if (rowColDefsEmpty) + if (IsTrivialGrid) { gridDesiredSize = new Size(); @@ -358,10 +366,10 @@ namespace Avalonia.Controls } } - // ValidateColumnDefinitionsStructure(); + ValidateColumnDefinitionsStructure(); ValidateDefinitionsLayout(DefinitionsU, sizeToContentU); - // ValidateRowDefinitionsStructure(); + ValidateRowDefinitionsStructure(); ValidateDefinitionsLayout(DefinitionsV, sizeToContentV); CellsStructureDirty |= (SizeToContentU != sizeToContentU) || (SizeToContentV != sizeToContentV); @@ -429,9 +437,9 @@ namespace Avalonia.Controls ApplyCachedMinSizes(group2MinSizes, false); if (HasStarCellsV) { ResolveStar(DefinitionsV, constraint.Height); } - MeasureCellsGroup(CellGroup2, constraint, cnt == c_layoutLoopMaxCount, false, out hasDesiredSizeUChanged); + MeasureCellsGroup(CellGroup2, constraint, cnt == layoutLoopMaxCount, false, out hasDesiredSizeUChanged); } - while (hasDesiredSizeUChanged && ++cnt <= c_layoutLoopMaxCount); + while (hasDesiredSizeUChanged && ++cnt <= layoutLoopMaxCount); } } } @@ -451,6 +459,18 @@ namespace Avalonia.Controls return (gridDesiredSize); } + private void ValidateColumnDefinitionsStructure() + { + if (DefinitionsU == null || DefinitionsU?.Count() == 0) + DefinitionsU = new DefinitionBase[1] { new ColumnDefinition() }; + } + + private void ValidateRowDefinitionsStructure() + { + if (DefinitionsV == null || DefinitionsV?.Count() == 0) + DefinitionsV = new DefinitionBase[1] { new RowDefinition() }; + } + /// /// Content arrangement. /// @@ -459,10 +479,9 @@ namespace Avalonia.Controls { try { - ArrangeOverrideInProgress = true; - if (rowColDefsEmpty) + if (IsTrivialGrid) { for (int i = 0, count = Children.Count; i < count; ++i) { @@ -527,11 +546,6 @@ namespace Avalonia.Controls InvalidateMeasure(); } - internal bool MeasureOverrideInProgress; - internal bool ArrangeOverrideInProgress; - internal bool ColumnDefinitionsDirty; - internal bool RowDefinitionsDirty; - /// /// Lays out cells according to rows and columns, and creates lookup grids. /// @@ -1638,9 +1652,9 @@ namespace Avalonia.Controls double remainingAvailableSize = finalSize - takenSize; double remainingStarWeight = totalStarWeight - takenStarWeight; - MinRatioIndexComparer minRatioIndexComparer = new MinRatioIndexComparer((DefinitionBase[])definitions); + MinRatioIndexComparer minRatioIndexComparer = new MinRatioIndexComparer(definitions); Array.Sort(definitionIndices, 0, minCount, minRatioIndexComparer); - MaxRatioIndexComparer maxRatioIndexComparer = new MaxRatioIndexComparer((DefinitionBase[])definitions); + MaxRatioIndexComparer maxRatioIndexComparer = new MaxRatioIndexComparer(definitions); Array.Sort(definitionIndices, defCount, maxCount, maxRatioIndexComparer); while (minCount + maxCount > 0 && remainingAvailableSize > 0.0) @@ -1835,7 +1849,7 @@ namespace Avalonia.Controls // unrounded sizes, to avoid breaking assumptions in the previous phases if (UseLayoutRounding) { - var dpi = (VisualRoot as ILayoutRoot)?.LayoutScaling ?? 96; + var dpi = (VisualRoot as ILayoutRoot)?.LayoutScaling ?? 1.0; double[] roundingErrors = RoundingErrors; double roundedTakenSize = 0.0; @@ -2043,7 +2057,7 @@ namespace Avalonia.Controls /// private void SetValid() { - if (rowColDefsEmpty) + if (IsTrivialGrid) { if (_tempDefinitions != null) { @@ -2127,7 +2141,7 @@ namespace Avalonia.Controls private static void OnShowGridLinesPropertyChanged(Grid grid, AvaloniaPropertyChangedEventArgs e) { - if (grid.rowColDefsEmpty // trivial grid is 1 by 1. there is no grid lines anyway + if (!grid.IsTrivialGrid // trivial grid is 1 by 1. there is no grid lines anyway && grid.ListenToNotifications) { grid.InvalidateVisual(); @@ -2140,7 +2154,7 @@ namespace Avalonia.Controls { var grid = child.GetVisualParent() as Grid; if (grid != null - && grid.rowColDefsEmpty + && !grid.IsTrivialGrid && grid.ListenToNotifications) { grid.CellsStructureDirty = true; @@ -2153,7 +2167,7 @@ namespace Avalonia.Controls /// Helper for Comparer methods. /// /// - /// true iff one or both of x and y are null, in which case result holds + /// 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)