Browse Source

Cleaning up redundant/unreferenced code.

pull/2563/head
Jumar Macato 7 years ago
parent
commit
0e15b3f972
No known key found for this signature in database GPG Key ID: B19884DAC3A5BF3F
  1. 653
      src/Avalonia.Controls/GridWPF.cs

653
src/Avalonia.Controls/GridWPF.cs

@ -26,6 +26,49 @@ namespace Avalonia.Controls
/// </summary>
public class Grid : Panel
{
internal bool CellsStructureDirty = true;
internal bool ListenToNotifications;
internal bool SizeToContentU;
internal bool SizeToContentV;
internal bool HasStarCellsU;
internal bool HasStarCellsV;
internal bool HasGroup3CellsInAutoRows;
// index of the first cell in first cell group
internal int CellGroup1;
// index of the first cell in second cell group
internal int CellGroup2;
// index of the first cell in third cell group
internal int CellGroup3;
// index of the first cell in fourth cell group
internal int CellGroup4;
// temporary array used during layout for various purposes
// TempDefinitions.Length == Max(DefinitionsU.Length, DefinitionsV.Length)
internal DefinitionBase[] _tempDefinitions;
private GridLinesRenderer _gridLinesRenderer;
// Keeps track of definition indices.
private int[] _definitionIndices;
private CellCache[] _cellCache;
// 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 static readonly LocalDataStoreSlot s_tempDefinitionsDataSlot = Thread.AllocateDataSlot();
private static readonly IComparer s_spanPreferredDistributionOrderComparer = new SpanPreferredDistributionOrderComparer();
private static readonly IComparer s_spanMaxDistributionOrderComparer = new SpanMaxDistributionOrderComparer();
private static readonly IComparer s_minRatioComparer = new MinRatioComparer();
private static readonly IComparer s_maxRatioComparer = new MaxRatioComparer();
private static readonly IComparer s_starWeightComparer = new StarWeightComparer();
static Grid()
{
@ -193,19 +236,27 @@ namespace Avalonia.Controls
return _columnDefinitions;
}
set
{
{
_columnDefinitions = value;
_columnDefinitions.TrackItemPropertyChanged(_ => InvalidateMeasure());
_columnDefinitions.TrackItemPropertyChanged(_ => Invalidate());
ColumnDefinitionsDirty = true;
DefinitionsU = _columnDefinitions.Cast<DefinitionBase>().ToArray();
if (_columnDefinitions.Count > 0)
DefinitionsU = _columnDefinitions.Cast<DefinitionBase>().ToArray();
_columnDefinitions.CollectionChanged += (_, e) =>
{
DefinitionsU = _columnDefinitions.Cast<DefinitionBase>().ToArray();
ColumnDefinitionsDirty = true;
InvalidateMeasure();
if (_columnDefinitions.Count == 0)
{
DefinitionsU = new DefinitionBase[1] { new ColumnDefinition() };
}
else
{
DefinitionsU = _columnDefinitions.Cast<DefinitionBase>().ToArray();
ColumnDefinitionsDirty = true;
}
Invalidate();
};
}
}
@ -226,17 +277,25 @@ namespace Avalonia.Controls
set
{
_rowDefinitions = value;
_rowDefinitions.TrackItemPropertyChanged(_ => InvalidateMeasure());
_rowDefinitions.TrackItemPropertyChanged(_ => Invalidate());
RowDefinitionsDirty = true;
DefinitionsV = _rowDefinitions.Cast<DefinitionBase>().ToArray();
if (_rowDefinitions.Count > 0)
DefinitionsV = _rowDefinitions.Cast<DefinitionBase>().ToArray();
_rowDefinitions.CollectionChanged += (_, e) =>
{
DefinitionsV = _rowDefinitions.Cast<DefinitionBase>().ToArray();
RowDefinitionsDirty = true;
InvalidateMeasure();
if (_rowDefinitions.Count == 0)
{
DefinitionsV = new DefinitionBase[1] { new ColumnDefinition() };
}
else
{
DefinitionsV = _rowDefinitions.Cast<DefinitionBase>().ToArray();
RowDefinitionsDirty = true;
}
Invalidate();
};
}
}
@ -252,7 +311,6 @@ namespace Avalonia.Controls
protected override Size MeasureOverride(Size constraint)
{
Size gridDesiredSize;
ExtendedData extData = ExtData;
try
{
@ -316,7 +374,7 @@ namespace Avalonia.Controls
Debug.Assert(DefinitionsU.Length > 0 && DefinitionsV.Length > 0);
MeasureCellsGroup(extData.CellGroup1, constraint, false, false);
MeasureCellsGroup(CellGroup1, constraint, false, false);
{
// after Group1 is measured, only Group3 may have cells belonging to Auto rows.
@ -325,19 +383,19 @@ namespace Avalonia.Controls
if (canResolveStarsV)
{
if (HasStarCellsV) { ResolveStar(DefinitionsV, constraint.Height); }
MeasureCellsGroup(extData.CellGroup2, constraint, false, false);
MeasureCellsGroup(CellGroup2, constraint, false, false);
if (HasStarCellsU) { ResolveStar(DefinitionsU, constraint.Width); }
MeasureCellsGroup(extData.CellGroup3, constraint, false, false);
MeasureCellsGroup(CellGroup3, constraint, false, false);
}
else
{
// if at least one cell exists in Group2, it must be measured before
// StarsU can be resolved.
bool canResolveStarsU = extData.CellGroup2 > PrivateCells.Length;
bool canResolveStarsU = CellGroup2 > _cellCache.Length;
if (canResolveStarsU)
{
if (HasStarCellsU) { ResolveStar(DefinitionsU, constraint.Width); }
MeasureCellsGroup(extData.CellGroup3, constraint, false, false);
MeasureCellsGroup(CellGroup3, constraint, false, false);
if (HasStarCellsV) { ResolveStar(DefinitionsV, constraint.Height); }
}
else
@ -351,10 +409,10 @@ namespace Avalonia.Controls
int cnt = 0;
// Cache Group2MinWidths & Group3MinHeights
double[] group2MinSizes = CacheMinSizes(extData.CellGroup2, false);
double[] group3MinSizes = CacheMinSizes(extData.CellGroup3, true);
double[] group2MinSizes = CacheMinSizes(CellGroup2, false);
double[] group3MinSizes = CacheMinSizes(CellGroup3, true);
MeasureCellsGroup(extData.CellGroup2, constraint, false, true);
MeasureCellsGroup(CellGroup2, constraint, false, true);
do
{
@ -365,20 +423,20 @@ namespace Avalonia.Controls
}
if (HasStarCellsU) { ResolveStar(DefinitionsU, constraint.Width); }
MeasureCellsGroup(extData.CellGroup3, constraint, false, false);
MeasureCellsGroup(CellGroup3, constraint, false, false);
// Reset cached Group2Widths
ApplyCachedMinSizes(group2MinSizes, false);
if (HasStarCellsV) { ResolveStar(DefinitionsV, constraint.Height); }
MeasureCellsGroup(extData.CellGroup2, constraint, cnt == c_layoutLoopMaxCount, false, out hasDesiredSizeUChanged);
MeasureCellsGroup(CellGroup2, constraint, cnt == c_layoutLoopMaxCount, false, out hasDesiredSizeUChanged);
}
while (hasDesiredSizeUChanged && ++cnt <= c_layoutLoopMaxCount);
}
}
}
MeasureCellsGroup(extData.CellGroup4, constraint, false, false);
MeasureCellsGroup(CellGroup4, constraint, false, false);
gridDesiredSize = new Size(
CalculateDesiredSize(DefinitionsU),
@ -422,7 +480,7 @@ namespace Avalonia.Controls
SetFinalSize(DefinitionsU, arrangeSize.Width, true);
SetFinalSize(DefinitionsV, arrangeSize.Height, false);
for (int currentCell = 0; currentCell < PrivateCells.Length; ++currentCell)
for (int currentCell = 0; currentCell < _cellCache.Length; ++currentCell)
{
IControl cell = Children[currentCell];
if (cell == null)
@ -430,10 +488,10 @@ namespace Avalonia.Controls
continue;
}
int columnIndex = PrivateCells[currentCell].ColumnIndex;
int rowIndex = PrivateCells[currentCell].RowIndex;
int columnSpan = PrivateCells[currentCell].ColumnSpan;
int rowSpan = PrivateCells[currentCell].RowSpan;
int columnIndex = _cellCache[currentCell].ColumnIndex;
int rowIndex = _cellCache[currentCell].RowIndex;
int columnSpan = _cellCache[currentCell].ColumnSpan;
int rowSpan = _cellCache[currentCell].RowSpan;
Rect cellRect = new Rect(
columnIndex == 0 ? 0.0 : DefinitionsU[columnIndex].FinalOffset,
@ -469,109 +527,38 @@ namespace Avalonia.Controls
InvalidateMeasure();
}
/// <summary>
/// Returns final width for a column.
/// </summary>
/// <remarks>
/// Used from public ColumnDefinition ActualWidth. Calculates final width using offset data.
/// </remarks>
internal double GetFinalColumnDefinitionWidth(int columnIndex)
{
double value = 0.0;
Contract.Requires<NullReferenceException>(_data != null);
// actual value calculations require structure to be up-to-date
if (!ColumnDefinitionsDirty)
{
var definitions = DefinitionsU;
value = definitions[(columnIndex + 1) % definitions.Length].FinalOffset;
if (columnIndex != 0) { value -= definitions[columnIndex].FinalOffset; }
}
return (value);
}
/// <summary>
/// Returns final height for a row.
/// </summary>
/// <remarks>
/// Used from public RowDefinition ActualHeight. Calculates final height using offset data.
/// </remarks>
internal double GetFinalRowDefinitionHeight(int rowIndex)
{
double value = 0.0;
Contract.Requires<NullReferenceException>(_data != null);
// actual value calculations require structure to be up-to-date
if (!RowDefinitionsDirty)
{
var definitions = DefinitionsV;
value = definitions[(rowIndex + 1) % definitions.Length].FinalOffset;
if (rowIndex != 0) { value -= definitions[rowIndex].FinalOffset; }
}
return (value);
}
/// <summary>
/// Convenience accessor to MeasureOverrideInProgress bit flag.
/// </summary>
internal bool MeasureOverrideInProgress { get; set; }
/// <summary>
/// Convenience accessor to ArrangeOverrideInProgress bit flag.
/// </summary>
internal bool ArrangeOverrideInProgress { get; set; }
/// <summary>
/// Convenience accessor to ValidColumnDefinitionsStructure bit flag.
/// </summary>
internal bool ColumnDefinitionsDirty { get; set; }
/// <summary>
/// Convenience accessor to ValidRowDefinitionsStructure bit flag.
/// </summary>
internal bool RowDefinitionsDirty { get; set; }
internal bool MeasureOverrideInProgress;
internal bool ArrangeOverrideInProgress;
internal bool ColumnDefinitionsDirty;
internal bool RowDefinitionsDirty;
/// <summary>
/// Lays out cells according to rows and columns, and creates lookup grids.
/// </summary>
private void ValidateCells()
{
if (CellsStructureDirty)
{
ValidateCellsCore();
CellsStructureDirty = false;
}
}
if (!CellsStructureDirty) return;
/// <summary>
/// ValidateCellsCore
/// </summary>
private void ValidateCellsCore()
{
ExtendedData extData = ExtData;
extData.CellCachesCollection = new CellCache[Children.Count];
extData.CellGroup1 = int.MaxValue;
extData.CellGroup2 = int.MaxValue;
extData.CellGroup3 = int.MaxValue;
extData.CellGroup4 = int.MaxValue;
_cellCache = new CellCache[Children.Count];
CellGroup1 = int.MaxValue;
CellGroup2 = int.MaxValue;
CellGroup3 = int.MaxValue;
CellGroup4 = int.MaxValue;
bool hasStarCellsU = false;
bool hasStarCellsV = false;
bool hasGroup3CellsInAutoRows = false;
for (int i = PrivateCells.Length - 1; i >= 0; --i)
for (int i = _cellCache.Length - 1; i >= 0; --i)
{
var child = Children[i] as Control;
if (child == null)
{
continue;
}
CellCache cell = new CellCache();
//
// read and cache child positioning properties
//
var cell = new CellCache();
// read indices from the corresponding properties
// clamp to value < number_of_columns
@ -611,13 +598,13 @@ namespace Avalonia.Controls
{
if (!cell.IsStarU)
{
cell.Next = extData.CellGroup1;
extData.CellGroup1 = i;
cell.Next = CellGroup1;
CellGroup1 = i;
}
else
{
cell.Next = extData.CellGroup3;
extData.CellGroup3 = i;
cell.Next = CellGroup3;
CellGroup3 = i;
// remember if this cell belongs to auto row
hasGroup3CellsInAutoRows |= cell.IsAutoV;
@ -629,22 +616,24 @@ namespace Avalonia.Controls
// note below: if spans through Star column it is NOT Auto
&& !cell.IsStarU)
{
cell.Next = extData.CellGroup2;
extData.CellGroup2 = i;
cell.Next = CellGroup2;
CellGroup2 = i;
}
else
{
cell.Next = extData.CellGroup4;
extData.CellGroup4 = i;
cell.Next = CellGroup4;
CellGroup4 = i;
}
}
PrivateCells[i] = cell;
_cellCache[i] = cell;
}
HasStarCellsU = hasStarCellsU;
HasStarCellsV = hasStarCellsV;
HasGroup3CellsInAutoRows = hasGroup3CellsInAutoRows;
CellsStructureDirty = false;
}
/// <summary>
@ -713,15 +702,15 @@ namespace Avalonia.Controls
{
if (isRows)
{
minSizes[PrivateCells[i].RowIndex] = DefinitionsV[PrivateCells[i].RowIndex].MinSize;
minSizes[_cellCache[i].RowIndex] = DefinitionsV[_cellCache[i].RowIndex].MinSize;
}
else
{
minSizes[PrivateCells[i].ColumnIndex] = DefinitionsU[PrivateCells[i].ColumnIndex].MinSize;
minSizes[_cellCache[i].ColumnIndex] = DefinitionsU[_cellCache[i].ColumnIndex].MinSize;
}
i = PrivateCells[i].Next;
} while (i < PrivateCells.Length);
i = _cellCache[i].Next;
} while (i < _cellCache.Length);
return minSizes;
}
@ -773,7 +762,7 @@ namespace Avalonia.Controls
{
hasDesiredSizeUChanged = false;
if (cellsHead >= PrivateCells.Length)
if (cellsHead >= _cellCache.Length)
{
return;
}
@ -792,16 +781,16 @@ namespace Avalonia.Controls
if (!ignoreDesiredSizeU)
{
if (PrivateCells[i].ColumnSpan == 1)
if (_cellCache[i].ColumnSpan == 1)
{
DefinitionsU[PrivateCells[i].ColumnIndex].UpdateMinSize(Math.Min(Children[i].DesiredSize.Width, DefinitionsU[PrivateCells[i].ColumnIndex].UserMaxSize));
DefinitionsU[_cellCache[i].ColumnIndex].UpdateMinSize(Math.Min(Children[i].DesiredSize.Width, DefinitionsU[_cellCache[i].ColumnIndex].UserMaxSize));
}
else
{
RegisterSpan(
ref spanStore,
PrivateCells[i].ColumnIndex,
PrivateCells[i].ColumnSpan,
_cellCache[i].ColumnIndex,
_cellCache[i].ColumnSpan,
true,
Children[i].DesiredSize.Width);
}
@ -809,23 +798,23 @@ namespace Avalonia.Controls
if (!ignoreDesiredSizeV)
{
if (PrivateCells[i].RowSpan == 1)
if (_cellCache[i].RowSpan == 1)
{
DefinitionsV[PrivateCells[i].RowIndex].UpdateMinSize(Math.Min(Children[i].DesiredSize.Height, DefinitionsV[PrivateCells[i].RowIndex].UserMaxSize));
DefinitionsV[_cellCache[i].RowIndex].UpdateMinSize(Math.Min(Children[i].DesiredSize.Height, DefinitionsV[_cellCache[i].RowIndex].UserMaxSize));
}
else
{
RegisterSpan(
ref spanStore,
PrivateCells[i].RowIndex,
PrivateCells[i].RowSpan,
_cellCache[i].RowIndex,
_cellCache[i].RowSpan,
false,
Children[i].DesiredSize.Height);
}
}
i = PrivateCells[i].Next;
} while (i < PrivateCells.Length);
i = _cellCache[i].Next;
} while (i < _cellCache.Length);
if (spanStore != null)
{
@ -887,8 +876,8 @@ namespace Avalonia.Controls
double cellMeasureWidth;
double cellMeasureHeight;
if (PrivateCells[cell].IsAutoU
&& !PrivateCells[cell].IsStarU)
if (_cellCache[cell].IsAutoU
&& !_cellCache[cell].IsStarU)
{
// if cell belongs to at least one Auto column and not a single Star column
// then it should be calculated "to content", thus it is possible to "shortcut"
@ -900,16 +889,16 @@ namespace Avalonia.Controls
// otherwise...
cellMeasureWidth = GetMeasureSizeForRange(
DefinitionsU,
PrivateCells[cell].ColumnIndex,
PrivateCells[cell].ColumnSpan);
_cellCache[cell].ColumnIndex,
_cellCache[cell].ColumnSpan);
}
if (forceInfinityV)
{
cellMeasureHeight = double.PositiveInfinity;
}
else if (PrivateCells[cell].IsAutoV
&& !PrivateCells[cell].IsStarV)
else if (_cellCache[cell].IsAutoV
&& !_cellCache[cell].IsStarV)
{
// if cell belongs to at least one Auto row and not a single Star row
// then it should be calculated "to content", thus it is possible to "shortcut"
@ -920,8 +909,8 @@ namespace Avalonia.Controls
{
cellMeasureHeight = GetMeasureSizeForRange(
DefinitionsV,
PrivateCells[cell].RowIndex,
PrivateCells[cell].RowSpan);
_cellCache[cell].RowIndex,
_cellCache[cell].RowSpan);
}
var child = Children[cell];
@ -1006,7 +995,7 @@ namespace Avalonia.Controls
Debug.Assert(1 < count && 0 <= start && (start + count) <= definitions.Length);
// avoid processing when asked to distribute "0"
if (!_IsZero(requestedSize))
if (!MathUtilities.IsZero(requestedSize))
{
DefinitionBase[] tempDefinitions = TempDefinitions; // temp array used to remember definitions for sorting
int end = start + count;
@ -1084,7 +1073,7 @@ namespace Avalonia.Controls
}
// sanity check: requested size must all be distributed
Debug.Assert(_IsZero(sizeToDistribute));
Debug.Assert(MathUtilities.IsZero(sizeToDistribute));
}
else if (requestedSize <= rangeMaxSize)
{
@ -1124,7 +1113,7 @@ namespace Avalonia.Controls
}
// sanity check: requested size must all be distributed
Debug.Assert(_IsZero(sizeToDistribute));
Debug.Assert(MathUtilities.IsZero(sizeToDistribute));
}
else
{
@ -1136,7 +1125,7 @@ namespace Avalonia.Controls
double equalSize = requestedSize / count;
if (equalSize < maxMaxSize
&& !_AreClose(equalSize, maxMaxSize))
&& !MathUtilities.AreClose(equalSize, maxMaxSize))
{
// equi-size is less than maximum of maxSizes.
// in this case distribute so that smaller definitions grow faster than
@ -1903,7 +1892,7 @@ namespace Avalonia.Controls
// and precision of floating-point computation. (However, the resulting
// display is subject to anti-aliasing problems. TANSTAAFL.)
if (!_AreClose(roundedTakenSize, finalSize))
if (!MathUtilities.AreClose(roundedTakenSize, finalSize))
{
// Compute deltas
for (int i = 0; i < definitions.Length; ++i)
@ -1920,7 +1909,7 @@ namespace Avalonia.Controls
if (roundedTakenSize > finalSize)
{
int i = definitions.Length - 1;
while ((adjustedSize > finalSize && !_AreClose(adjustedSize, finalSize)) && i >= 0)
while ((adjustedSize > finalSize && !MathUtilities.AreClose(adjustedSize, finalSize)) && i >= 0)
{
DefinitionBase definition = definitions[definitionIndices[i]];
double final = definition.SizeCache - dpiIncrement;
@ -1936,7 +1925,7 @@ namespace Avalonia.Controls
else if (roundedTakenSize < finalSize)
{
int i = 0;
while ((adjustedSize < finalSize && !_AreClose(adjustedSize, finalSize)) && i < definitions.Length)
while ((adjustedSize < finalSize && !MathUtilities.AreClose(adjustedSize, finalSize)) && i < definitions.Length)
{
DefinitionBase definition = definitions[definitionIndices[i]];
double final = definition.SizeCache + dpiIncrement;
@ -2054,14 +2043,13 @@ namespace Avalonia.Controls
/// </summary>
private void SetValid()
{
ExtendedData extData = ExtData;
if (extData != null)
if (rowColDefsEmpty)
{
if (extData.TempDefinitions != null)
if (_tempDefinitions != null)
{
// TempDefinitions has to be cleared to avoid "memory leaks"
Array.Clear(extData.TempDefinitions, 0, Math.Max(DefinitionsU.Length, DefinitionsV.Length));
extData.TempDefinitions = null;
Array.Clear(_tempDefinitions, 0, Math.Max(DefinitionsU.Length, DefinitionsV.Length));
_tempDefinitions = null;
}
}
}
@ -2092,15 +2080,6 @@ namespace Avalonia.Controls
return (_gridLinesRenderer);
}
/// <summary>
/// SetFlags is used to set or unset one or multiple
/// flags on the object.
/// </summary>
private void SetFlags(bool value, Flags flags)
{
_flags = value ? (_flags | flags) : (_flags & (~flags));
}
private double RoundLayoutValue(double value, double dpiScale)
{
double newValue;
@ -2125,28 +2104,6 @@ namespace Avalonia.Controls
return newValue;
}
/// <summary>
/// CheckFlagsAnd returns <c>true</c> if all the flags in the
/// given bitmask are set on the object.
/// </summary>
private bool CheckFlagsAnd(Flags flags)
{
return ((_flags & flags) == flags);
}
/// <summary>
/// CheckFlagsOr returns <c>true</c> if at least one flag in the
/// given bitmask is set.
/// </summary>
/// <remarks>
/// If no bits are set in the given bitmask, the method returns
/// <c>true</c>.
/// </remarks>
private bool CheckFlagsOr(Flags flags)
{
return (flags == 0 || (_flags & flags) != 0);
}
private static int ValidateColumn(AvaloniaObject o, int value)
{
@ -2170,7 +2127,7 @@ namespace Avalonia.Controls
private static void OnShowGridLinesPropertyChanged(Grid grid, AvaloniaPropertyChangedEventArgs e)
{
if (grid.ExtData != null // trivial grid is 1 by 1. there is no grid lines anyway
if (grid.rowColDefsEmpty // trivial grid is 1 by 1. there is no grid lines anyway
&& grid.ListenToNotifications)
{
grid.InvalidateVisual();
@ -2183,7 +2140,7 @@ namespace Avalonia.Controls
{
var grid = child.GetVisualParent() as Grid;
if (grid != null
&& grid.ExtData != null
&& grid.rowColDefsEmpty
&& grid.ListenToNotifications)
{
grid.CellsStructureDirty = true;
@ -2232,30 +2189,29 @@ namespace Avalonia.Controls
{
get
{
ExtendedData extData = ExtData;
int requiredLength = Math.Max(DefinitionsU.Length, DefinitionsV.Length) * 2;
if (extData.TempDefinitions == null
|| extData.TempDefinitions.Length < requiredLength)
if (_tempDefinitions == null
|| _tempDefinitions.Length < requiredLength)
{
WeakReference tempDefinitionsWeakRef = (WeakReference)Thread.GetData(s_tempDefinitionsDataSlot);
if (tempDefinitionsWeakRef == null)
{
extData.TempDefinitions = new DefinitionBase[requiredLength];
Thread.SetData(s_tempDefinitionsDataSlot, new WeakReference(extData.TempDefinitions));
_tempDefinitions = new DefinitionBase[requiredLength];
Thread.SetData(s_tempDefinitionsDataSlot, new WeakReference(_tempDefinitions));
}
else
{
extData.TempDefinitions = (DefinitionBase[])tempDefinitionsWeakRef.Target;
if (extData.TempDefinitions == null
|| extData.TempDefinitions.Length < requiredLength)
_tempDefinitions = (DefinitionBase[])tempDefinitionsWeakRef.Target;
if (_tempDefinitions == null
|| _tempDefinitions.Length < requiredLength)
{
extData.TempDefinitions = new DefinitionBase[requiredLength];
tempDefinitionsWeakRef.Target = extData.TempDefinitions;
_tempDefinitions = new DefinitionBase[requiredLength];
tempDefinitionsWeakRef.Target = _tempDefinitions;
}
}
}
return (extData.TempDefinitions);
return (_tempDefinitions);
}
}
@ -2298,106 +2254,6 @@ namespace Avalonia.Controls
}
}
/// <summary>
/// Private version returning array of cells.
/// </summary>
private CellCache[] PrivateCells
{
get { return (ExtData.CellCachesCollection); }
}
/// <summary>
/// Convenience accessor to ValidCellsStructure bit flag.
/// </summary>
private bool CellsStructureDirty
{
get { return (!CheckFlagsAnd(Flags.ValidCellsStructure)); }
set { SetFlags(!value, Flags.ValidCellsStructure); }
}
/// <summary>
/// Convenience accessor to ListenToNotifications bit flag.
/// </summary>
private bool ListenToNotifications
{
get { return (CheckFlagsAnd(Flags.ListenToNotifications)); }
set { SetFlags(value, Flags.ListenToNotifications); }
}
/// <summary>
/// Convenience accessor to SizeToContentU bit flag.
/// </summary>
private bool SizeToContentU
{
get { return (CheckFlagsAnd(Flags.SizeToContentU)); }
set { SetFlags(value, Flags.SizeToContentU); }
}
/// <summary>
/// Convenience accessor to SizeToContentV bit flag.
/// </summary>
private bool SizeToContentV
{
get { return (CheckFlagsAnd(Flags.SizeToContentV)); }
set { SetFlags(value, Flags.SizeToContentV); }
}
/// <summary>
/// Convenience accessor to HasStarCellsU bit flag.
/// </summary>
private bool HasStarCellsU
{
get { return (CheckFlagsAnd(Flags.HasStarCellsU)); }
set { SetFlags(value, Flags.HasStarCellsU); }
}
/// <summary>
/// Convenience accessor to HasStarCellsV bit flag.
/// </summary>
private bool HasStarCellsV
{
get { return (CheckFlagsAnd(Flags.HasStarCellsV)); }
set { SetFlags(value, Flags.HasStarCellsV); }
}
/// <summary>
/// Convenience accessor to HasGroup3CellsInAutoRows bit flag.
/// </summary>
private bool HasGroup3CellsInAutoRows
{
get { return (CheckFlagsAnd(Flags.HasGroup3CellsInAutoRows)); }
set { SetFlags(value, Flags.HasGroup3CellsInAutoRows); }
}
/// <summary>
/// fp version of <c>d == 0</c>.
/// </summary>
/// <param name="d">Value to check.</param>
/// <returns><c>true</c> if d == 0.</returns>
private static bool _IsZero(double d)
{
return (Math.Abs(d) < double.Epsilon);
}
/// <summary>
/// fp version of <c>d1 == d2</c>
/// </summary>
/// <param name="d1">First value to compare</param>
/// <param name="d2">Second value to compare</param>
/// <returns><c>true</c> if d1 == d2</returns>
private static bool _AreClose(double d1, double d2)
{
return (Math.Abs(d1 - d2) < double.Epsilon);
}
/// <summary>
/// Returns reference to extended data bag.
/// </summary>
private ExtendedData ExtData
{
get { return (_data); }
}
/// <summary>
/// Returns *-weight, adjusted for scale computed during Phase 1
/// </summary>
@ -2416,72 +2272,6 @@ namespace Avalonia.Controls
}
}
private ExtendedData _data = new ExtendedData(); // extended data instantiated on demand, for non-trivial case handling only
private Flags _flags; // grid validity / property caches dirtiness flags
private GridLinesRenderer _gridLinesRenderer;
// Keeps track of definition indices.
int[] _definitionIndices;
// Stores unrounded values and rounding errors during layout rounding.
double[] _roundingErrors;
private DefinitionBase[] DefinitionsU = new DefinitionBase[1] { new ColumnDefinition() };
private DefinitionBase[] DefinitionsV = new DefinitionBase[1] { new RowDefinition() };
private const double c_epsilon = 1e-5; // used in fp calculations
private const double c_starClip = 1e298; // used as maximum for clipping star values during normalization
private const int c_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();
private static readonly IComparer s_starDistributionOrderComparer = new StarDistributionOrderComparer();
private static readonly IComparer s_distributionOrderComparer = new DistributionOrderComparer();
private static readonly IComparer s_minRatioComparer = new MinRatioComparer();
private static readonly IComparer s_maxRatioComparer = new MaxRatioComparer();
private static readonly IComparer s_starWeightComparer = new StarWeightComparer();
/// <summary>
/// Extended data instantiated on demand, when grid handles non-trivial case.
/// </summary>
private class ExtendedData
{
internal CellCache[] CellCachesCollection; // backing store for logical Children
internal int CellGroup1; // index of the first cell in first cell group
internal int CellGroup2; // index of the first cell in second cell group
internal int CellGroup3; // index of the first cell in third cell group
internal int CellGroup4; // index of the first cell in forth cell group
internal DefinitionBase[] TempDefinitions; // temporary array used during layout for various purposes
// TempDefinitions.Length == Max(DefinitionsU.Length, DefinitionsV.Length)
}
/// <summary>
/// Grid validity / property caches dirtiness flags
/// </summary>
[System.Flags]
private enum Flags
{
//
// the foolowing flags let grid tracking dirtiness in more granular manner:
// * Valid???Structure flags indicate that elements were added or removed.
// * Valid???Layout flags indicate that layout time portion of the information
// stored on the objects should be updated.
//
ValidColumnDefinitionsStructure = 0x00000001,
ValidRowDefinitionsStructure = 0x00000002,
ValidCellsStructure = 0x00000004,
//
// boolean flags
//
ListenToNotifications = 0x00001000, // "0" when all notifications are ignored
SizeToContentU = 0x00002000, // "1" if calculating to content in U direction
SizeToContentV = 0x00004000, // "1" if calculating to content in V direction
HasStarCellsU = 0x00008000, // "1" if at least one cell belongs to a Star column
HasStarCellsV = 0x00010000, // "1" if at least one cell belongs to a Star row
HasGroup3CellsInAutoRows = 0x00020000, // "1" if at least one cell of group 3 belongs to an Auto row
MeasureOverrideInProgress = 0x00040000, // "1" while in the context of Grid.MeasureOverride
ArrangeOverrideInProgress = 0x00080000, // "1" while in the context of Grid.ArrangeOverride
}
/// <summary>
/// LayoutTimeSizeType is used internally and reflects layout-time size type.
/// </summary>
@ -2663,135 +2453,6 @@ namespace Avalonia.Controls
}
}
/// <summary>
/// StarDistributionOrderComparer.
/// </summary>
private class StarDistributionOrderComparer : 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;
}
}
/// <summary>
/// DistributionOrderComparer.
/// </summary>
private class DistributionOrderComparer : 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))
{
double xprime = definitionX.SizeCache - definitionX.MinSizeForArrange;
double yprime = definitionY.SizeCache - definitionY.MinSizeForArrange;
result = xprime.CompareTo(yprime);
}
return result;
}
}
/// <summary>
/// StarDistributionOrderIndexComparer.
/// </summary>
private class StarDistributionOrderIndexComparer : IComparer
{
private readonly DefinitionBase[] definitions;
internal StarDistributionOrderIndexComparer(DefinitionBase[] definitions)
{
Contract.Requires<NullReferenceException>(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;
}
}
/// <summary>
/// DistributionOrderComparer.
/// </summary>
private class DistributionOrderIndexComparer : IComparer
{
private readonly DefinitionBase[] definitions;
internal DistributionOrderIndexComparer(DefinitionBase[] definitions)
{
Contract.Requires<NullReferenceException>(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))
{
double xprime = definitionX.SizeCache - definitionX.MinSizeForArrange;
double yprime = definitionY.SizeCache - definitionY.MinSizeForArrange;
result = xprime.CompareTo(yprime);
}
return result;
}
}
/// <summary>
/// RoundingErrorIndexComparer.
/// </summary>

Loading…
Cancel
Save