From 5a8a9e7ce2006ea62c28fa466eee7ff4152abc1c Mon Sep 17 00:00:00 2001 From: Jumar Macato Date: Wed, 5 Jun 2019 22:13:46 +0800 Subject: [PATCH] Cleaning up --- src/Avalonia.Controls/ColumnDefinitions.cs | 4 +- src/Avalonia.Controls/DefinitionBase.cs | 273 ++---- src/Avalonia.Controls/DefinitionList.cs | 7 +- src/Avalonia.Controls/Grid.cs | 943 +++------------------ src/Avalonia.Controls/RowDefinitions.cs | 4 +- 5 files changed, 202 insertions(+), 1029 deletions(-) diff --git a/src/Avalonia.Controls/ColumnDefinitions.cs b/src/Avalonia.Controls/ColumnDefinitions.cs index 4f5bbf3bc3..d4fc2ee0a1 100644 --- a/src/Avalonia.Controls/ColumnDefinitions.cs +++ b/src/Avalonia.Controls/ColumnDefinitions.cs @@ -16,10 +16,8 @@ namespace Avalonia.Controls /// /// Initializes a new instance of the class. /// - public ColumnDefinitions() + public ColumnDefinitions() : base () { - ResetBehavior = ResetBehavior.Remove; - CollectionChanged += OnCollectionChanged; } /// diff --git a/src/Avalonia.Controls/DefinitionBase.cs b/src/Avalonia.Controls/DefinitionBase.cs index 8899c38bf9..d04578b371 100644 --- a/src/Avalonia.Controls/DefinitionBase.cs +++ b/src/Avalonia.Controls/DefinitionBase.cs @@ -20,49 +20,15 @@ namespace Avalonia.Controls /// public abstract class DefinitionBase : AvaloniaObject { - //------------------------------------------------------ - // - // Constructors - // - //------------------------------------------------------ - - #region Constructors - - /* internal DefinitionBase(bool isColumnDefinition) - { - _isColumnDefinition = isColumnDefinition; - _parentIndex = -1; - }*/ - - #endregion Constructors - - //------------------------------------------------------ - // - // Public Properties - // - //------------------------------------------------------ - - #region Public Properties - /// /// SharedSizeGroup property. /// public string SharedSizeGroup { - get { return (string) GetValue(SharedSizeGroupProperty); } + get { return (string)GetValue(SharedSizeGroupProperty); } set { SetValue(SharedSizeGroupProperty, value); } } - #endregion Public Properties - - //------------------------------------------------------ - // - // Internal Methods - // - //------------------------------------------------------ - - #region Internal Methods - /// /// Callback to notify about entering model tree. /// @@ -91,7 +57,7 @@ namespace Avalonia.Controls if (e.Property.PropertyType == typeof(GridLength) || e.Property.PropertyType == typeof(double)) OnUserSizePropertyChanged(e); - + base.OnPropertyChanged(e); } @@ -139,9 +105,6 @@ namespace Avalonia.Controls _minSize = minSize; } - /// - /// - /// /// /// This method needs to be internal to be accessable from derived classes. /// @@ -166,92 +129,29 @@ namespace Avalonia.Controls } } } - /// - /// - /// - /// - /// This method needs to be internal to be accessable from derived classes. - /// - internal static bool IsUserSizePropertyValueValid(object value) - { - return (((GridLength)value).Value >= 0); - } - /// - /// - /// /// /// This method needs to be internal to be accessable from derived classes. /// internal static void OnUserMinSizePropertyChanged(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e) { - DefinitionBase definition = (DefinitionBase) d; - - if (definition.InParentLogicalTree) - { - Grid parentGrid = (Grid) definition.Parent; - parentGrid.InvalidateMeasure(); - } - } - - /// - /// - /// - /// - /// This method needs to be internal to be accessable from derived classes. - /// - internal static bool IsUserMinSizePropertyValueValid(object value) - { - double v = (double)value; - return (!double.IsNaN(v) && v >= 0.0d && !Double.IsPositiveInfinity(v)); - } - - /// - /// - /// - /// - /// This method needs to be internal to be accessable from derived classes. - /// - internal static void OnUserMaxSizePropertyChanged(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e) - { - DefinitionBase definition = (DefinitionBase) d; + DefinitionBase definition = (DefinitionBase)d; if (definition.InParentLogicalTree) { - Grid parentGrid = (Grid) definition.Parent; + Grid parentGrid = (Grid)definition.Parent; parentGrid.InvalidateMeasure(); } } - /// - /// - /// - /// - /// This method needs to be internal to be accessable from derived classes. - /// - internal static bool IsUserMaxSizePropertyValueValid(object value) - { - double v = (double)value; - return (!double.IsNaN(v) && v >= 0.0d); - } - - /// - /// - /// /// /// This method reflects Grid.SharedScopeProperty state by setting / clearing /// dynamic property PrivateSharedSizeScopeProperty. Value of PrivateSharedSizeScopeProperty /// is a collection of SharedSizeState objects for the scope. - /// Also PrivateSharedSizeScopeProperty is FrameworkPropertyMetadataOptions.Inherits property. So that all children - /// elements belonging to a certain scope can easily access SharedSizeState collection. As well - /// as been norified about enter / exit a scope. /// internal static void OnIsSharedSizeScopePropertyChanged(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e) { - // is it possible to optimize here something like this: - // if ((bool)d.GetValue(Grid.IsSharedSizeScopeProperty) == (d.GetLocalValue(PrivateSharedSizeScopeProperty) != null) - // { /* do nothing */ } - if ((bool) e.NewValue) + if ((bool)e.NewValue) { SharedSizeScope sharedStatesCollection = new SharedSizeScope(); d.SetValue(PrivateSharedSizeScopeProperty, sharedStatesCollection); @@ -262,16 +162,6 @@ namespace Avalonia.Controls } } - #endregion Internal Methods - - //------------------------------------------------------ - // - // Internal Properties - // - //------------------------------------------------------ - - #region Internal Properties - /// /// Returns true if this definition is a part of shared group. /// @@ -349,8 +239,8 @@ namespace Avalonia.Controls get { double preferredSize = MinSize; - if ( _sizeType != Grid.LayoutTimeSizeType.Auto - && preferredSize < _measureSize ) + if (_sizeType != Grid.LayoutTimeSizeType.Auto + && preferredSize < _measureSize) { preferredSize = _measureSize; } @@ -375,9 +265,9 @@ namespace Avalonia.Controls get { double minSize = _minSize; - if ( UseSharedMinimum - && _sharedState != null - && minSize < _sharedState.MinSize ) + if (UseSharedMinimum + && _sharedState != null + && minSize < _sharedState.MinSize) { minSize = _sharedState.MinSize; } @@ -393,9 +283,9 @@ namespace Avalonia.Controls get { double minSize = _minSize; - if ( _sharedState != null - && (UseSharedMinimum || !LayoutWasUpdated) - && minSize < _sharedState.MinSize ) + if (_sharedState != null + && (UseSharedMinimum || !LayoutWasUpdated) + && minSize < _sharedState.MinSize) { minSize = _sharedState.MinSize; } @@ -426,7 +316,7 @@ namespace Avalonia.Controls /// Internal helper to access up-to-date UserMaxSize property value. /// internal abstract double UserMaxSizeValueCache { get; } - + /// /// Protected. Returns true if this DefinitionBase instance is in parent's logical tree. /// @@ -437,16 +327,6 @@ namespace Avalonia.Controls internal Grid Parent { get; set; } - #endregion Internal Properties - - //------------------------------------------------------ - // - // Private Methods - // - //------------------------------------------------------ - - #region Private Methods - /// /// SetFlags is used to set or unset one or multiple /// flags on the object. @@ -465,16 +345,13 @@ namespace Avalonia.Controls return ((_flags & flags) == flags); } - /// - /// - /// private static void OnSharedSizeGroupPropertyChanged(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e) { - DefinitionBase definition = (DefinitionBase) d; - + DefinitionBase definition = (DefinitionBase)d; + if (definition.InParentLogicalTree) { - string sharedSizeGroupId = (string) e.NewValue; + string sharedSizeGroupId = (string)e.NewValue; if (definition._sharedState != null) { @@ -483,7 +360,7 @@ namespace Avalonia.Controls definition._sharedState.RemoveMember(definition); definition._sharedState = null; } - + if ((definition._sharedState == null) && (sharedSizeGroupId != null)) { SharedSizeScope privateSharedSizeScope = definition.PrivateSharedSizeScope; @@ -498,9 +375,6 @@ namespace Avalonia.Controls } } - /// - /// - /// /// /// Verifies that Shared Size Group Property string /// a) not empty. @@ -520,10 +394,10 @@ namespace Avalonia.Controls { bool isDigit = Char.IsDigit(id[i]); - if ( (i == 0 && isDigit) - || !( isDigit - || Char.IsLetter(id[i]) - || '_' == id[i] ) ) + if ((i == 0 && isDigit) + || !(isDigit + || Char.IsLetter(id[i]) + || '_' == id[i])) { break; } @@ -535,12 +409,9 @@ namespace Avalonia.Controls } } - throw new ArgumentException("Invalid SharedSizeGroup string."); + throw new ArgumentException("Invalid SharedSizeGroup string."); } - /// - /// - /// /// /// OnPrivateSharedSizeScopePropertyChanged is called when new scope enters or /// existing scope just left. In both cases if the DefinitionBase object is already registered @@ -552,7 +423,7 @@ namespace Avalonia.Controls if (definition.InParentLogicalTree) { - SharedSizeScope privateSharedSizeScope = (SharedSizeScope) e.NewValue; + SharedSizeScope privateSharedSizeScope = (SharedSizeScope)e.NewValue; if (definition._sharedState != null) { @@ -576,22 +447,12 @@ namespace Avalonia.Controls } } - #endregion Private Methods - - //------------------------------------------------------ - // - // Private Properties - // - //------------------------------------------------------ - - #region Private Properties - /// /// Private getter of shared state collection dynamic property. /// private SharedSizeScope PrivateSharedSizeScope { - get { return (SharedSizeScope) GetValue(PrivateSharedSizeScopeProperty); } + get { return (SharedSizeScope)GetValue(PrivateSharedSizeScopeProperty); } } /// @@ -612,16 +473,6 @@ namespace Avalonia.Controls set { SetFlags(value, Flags.LayoutWasUpdated); } } - #endregion Private Properties - - //------------------------------------------------------ - // - // Private Fields - // - //------------------------------------------------------ - - #region Private Fields - private readonly bool _isColumnDefinition; // when "true", this is a ColumnDefinition; when "false" this is a RowDefinition (faster than a type check) private Flags _flags; // flags reflecting various aspects of internal state internal int _parentIndex = -1; // this instance's index in parent's children collection @@ -633,19 +484,6 @@ namespace Avalonia.Controls private double _offset; // offset of the DefinitionBase from left / top corner (assuming LTR case) private SharedSizeState _sharedState; // reference to shared state object this instance is registered with - - internal const bool ThisIsColumnDefinition = true; - internal const bool ThisIsRowDefinition = false; - - #endregion Private Fields - - //------------------------------------------------------ - // - // Private Structures / Classes - // - //------------------------------------------------------ - - #region Private Structures Classes [System.Flags] private enum Flags : byte @@ -653,8 +491,8 @@ namespace Avalonia.Controls // // bool flags // - UseSharedMinimum = 0x00000020, // when "1", definition will take into account shared state's minimum - LayoutWasUpdated = 0x00000040, // set to "1" every time the parent grid is measured + UseSharedMinimum = 0x00000020, // when "1", definition will take into account shared state's minimum + LayoutWasUpdated = 0x00000040, // set to "1" every time the parent grid is measured } /// @@ -799,8 +637,8 @@ namespace Avalonia.Controls for (int i = 0, count = _registry.Count; i < count; ++i) { - Debug.Assert( _userSize.GridUnitType == GridUnitType.Auto - || _userSize.GridUnitType == GridUnitType.Pixel ); + Debug.Assert(_userSize.GridUnitType == GridUnitType.Auto + || _userSize.GridUnitType == GridUnitType.Pixel); GridLength currentGridLength = _registry[i].UserSizeValueCache; if (currentGridLength.GridUnitType == GridUnitType.Pixel) @@ -845,7 +683,7 @@ namespace Avalonia.Controls { DefinitionBase definitionBase = _registry[i]; - if (sharedMinSizeChanged || definitionBase.LayoutWasUpdated) + if (sharedMinSizeChanged || definitionBase.LayoutWasUpdated) { // if definition's min size is different, then need to re-measure if (!MathUtilities.AreClose(sharedMinSize, definitionBase.MinSize)) @@ -857,7 +695,7 @@ namespace Avalonia.Controls else { definitionBase.UseSharedMinimum = false; - + // if measure is valid then also need to check arrange. // Note: definitionBase.SizeCache is volatile but at this point // it contains up-to-date final size @@ -879,27 +717,34 @@ namespace Avalonia.Controls _broadcastInvalidation = true; } - - private readonly SharedSizeScope _sharedSizeScope; // the scope this state belongs to - private readonly string _sharedSizeGroupId; // Id of the shared size group this object is servicing - private readonly List _registry; // registry of participating definitions - private readonly EventHandler _layoutUpdated; // instance event handler for layout updated event - private Control _layoutUpdatedHost; // Control for which layout updated event handler is registered - private bool _broadcastInvalidation; // "true" when broadcasting of invalidation is needed - private bool _userSizeValid; // "true" when _userSize is up to date - private GridLength _userSize; // shared state - private double _minSize; // shared state - } - #endregion Private Structures Classes + // the scope this state belongs to + private readonly SharedSizeScope _sharedSizeScope; + + // Id of the shared size group this object is servicing + private readonly string _sharedSizeGroupId; + + // Registry of participating definitions + private readonly List _registry; + + // Instance event handler for layout updated event + private readonly EventHandler _layoutUpdated; - //------------------------------------------------------ - // - // Properties - // - //------------------------------------------------------ + // Control for which layout updated event handler is registered + private Control _layoutUpdatedHost; - #region Properties + // "true" when broadcasting of invalidation is needed + private bool _broadcastInvalidation; + + // "true" when _userSize is up to date + private bool _userSizeValid; + + // shared state + private GridLength _userSize; + + // shared state + private double _minSize; + } /// /// Private shared size scope property holds a collection of shared state objects for the a given shared size scope. @@ -931,7 +776,7 @@ namespace Avalonia.Controls public static readonly AttachedProperty SharedSizeGroupProperty = AvaloniaProperty.RegisterAttached( "SharedSizeGroup", - validate:SharedSizeGroupPropertyValueValid); + validate: SharedSizeGroupPropertyValueValid); /// /// Static ctor. Used for static registration of properties. @@ -941,7 +786,5 @@ namespace Avalonia.Controls SharedSizeGroupProperty.Changed.AddClassHandler(OnSharedSizeGroupPropertyChanged); PrivateSharedSizeScopeProperty.Changed.AddClassHandler(OnPrivateSharedSizeScopePropertyChanged); } - - #endregion Properties } -} +} \ No newline at end of file diff --git a/src/Avalonia.Controls/DefinitionList.cs b/src/Avalonia.Controls/DefinitionList.cs index b36ca9ce8a..97d92bdcb7 100644 --- a/src/Avalonia.Controls/DefinitionList.cs +++ b/src/Avalonia.Controls/DefinitionList.cs @@ -10,6 +10,12 @@ namespace Avalonia.Controls { public abstract class DefinitionList : AvaloniaList where T : DefinitionBase { + public DefinitionList() + { + ResetBehavior = ResetBehavior.Remove; + CollectionChanged += OnCollectionChanged; + } + internal bool IsDirty = true; private Grid _parent; @@ -19,7 +25,6 @@ namespace Avalonia.Controls set => SetParent(value); } - private void SetParent(Grid value) { _parent = value; diff --git a/src/Avalonia.Controls/Grid.cs b/src/Avalonia.Controls/Grid.cs index fc61c409f0..5a44b93941 100644 --- a/src/Avalonia.Controls/Grid.cs +++ b/src/Avalonia.Controls/Grid.cs @@ -22,12 +22,6 @@ namespace Avalonia.Controls /// public class Grid : Panel { - //------------------------------------------------------ - // - // Constructors - // - //------------------------------------------------------ - static Grid() { IsSharedSizeScopeProperty.Changed.AddClassHandler(DefinitionBase.OnIsSharedSizeScopePropertyChanged); @@ -47,42 +41,6 @@ namespace Avalonia.Controls { } - //------------------------------------------------------ - // - // Public Methods - // - //------------------------------------------------------ - - - /// - /// - /// - /* protected internal override IEnumerator LogicalChildren - { - get - { - // empty panel or a panel being used as the items - // host has *no* logical children; give empty enumerator - bool noChildren = (base.VisualChildrenCount == 0) || IsItemsHost; - - if (noChildren) - { - ExtendedData extData = ExtData; - - if ( extData == null - || ( (extData.ColumnDefinitions == null || extData.ColumnDefinitions.Count == 0) - && (extData.RowDefinitions == null || extData.RowDefinitions.Count == 0) ) - ) - { - // grid is empty - return EmptyEnumerator.Instance; - } - } - - return (new GridChildrenCollectionEnumeratorSimple(this, !noChildren)); - } - } */ - /// /// Helper for setting Column property on a Control. /// @@ -193,12 +151,6 @@ namespace Avalonia.Controls return element.GetValue(IsSharedSizeScopeProperty); } - //------------------------------------------------------ - // - // Public Properties - // - //------------------------------------------------------ - /// /// ShowGridLines property. /// @@ -248,52 +200,6 @@ namespace Avalonia.Controls } } - //------------------------------------------------------ - // - // Protected Methods - // - //------------------------------------------------------ - - /* /// - /// Derived class must implement to support Visual children. The method must return - /// the child at the specified index. Index must be between 0 and GetVisualChildrenCount-1. - /// - /// By default a Visual does not have any children. - /// - /// Remark: - /// During this virtual call it is not valid to modify the Visual tree. - /// - protected override Visual GetVisualChild(int index) - { - // because "base.Count + 1" for GridLinesRenderer - // argument checking done at the base class - if(index == base.VisualChildrenCount) - { - if (_gridLinesRenderer == null) - { - throw new ArgumentOutOfRangeException("index", index, SR.Get(SRID.Visual_ArgumentOutOfRange)); - } - return _gridLinesRenderer; - } - else return base.GetVisualChild(index); - } - - /// - /// Derived classes override this property to enable the Visual code to enumerate - /// the Visual children. Derived classes need to return the number of children - /// from this method. - /// - /// By default a Visual does not have any children. - /// - /// Remark: During this virtual method the Visual tree must not be modified. - /// - protected override int VisualChildrenCount - { - //since GridLinesRenderer has not been added as a child, so we do not subtract - get { return base.VisualChildrenCount + (_gridLinesRenderer != null ? 1 : 0); } - }*/ - - /// /// Content measurement. /// @@ -306,8 +212,6 @@ namespace Avalonia.Controls try { - - ListenToNotifications = true; MeasureOverrideInProgress = true; @@ -550,7 +454,7 @@ namespace Avalonia.Controls // also use a count heuristic to break a loop in case of one. bool hasDesiredSizeUChanged = false; - int cnt=0; + int cnt = 0; // Cache Group2MinWidths & Group3MinHeights double[] group2MinSizes = CacheMinSizes(extData.CellGroup2, false); @@ -582,17 +486,14 @@ namespace Avalonia.Controls MeasureCellsGroup(extData.CellGroup4, constraint, false, false); - gridDesiredSize = new Size( CalculateDesiredSize(DefinitionsU), CalculateDesiredSize(DefinitionsV)); - } } finally { MeasureOverrideInProgress = false; - } return (gridDesiredSize); @@ -606,8 +507,6 @@ namespace Avalonia.Controls { try { - - ArrangeOverrideInProgress = true; if (_data == null) @@ -627,13 +526,9 @@ namespace Avalonia.Controls { Debug.Assert(DefinitionsU.Count > 0 && DefinitionsV.Count > 0); - - SetFinalSize(DefinitionsU, arrangeSize.Width, true); SetFinalSize(DefinitionsV, arrangeSize.Height, false); - - var children = this.Children; for (int currentCell = 0; currentCell < PrivateCells.Length; ++currentCell) @@ -653,11 +548,11 @@ namespace Avalonia.Controls columnIndex == 0 ? 0.0 : DefinitionsU[columnIndex].FinalOffset, rowIndex == 0 ? 0.0 : DefinitionsV[rowIndex].FinalOffset, GetFinalSizeForRange(DefinitionsU, columnIndex, columnSpan), - GetFinalSizeForRange(DefinitionsV, rowIndex, rowSpan) ); + GetFinalSizeForRange(DefinitionsV, rowIndex, rowSpan)); + - cell.Arrange(cellRect); - + } // update render bound on grid lines renderer visual @@ -669,31 +564,12 @@ namespace Avalonia.Controls { SetValid(); ArrangeOverrideInProgress = false; - } return (arrangeSize); } /// - /// - /// - /*protected internal override void OnVisualChildrenChanged( - AvaloniaObject visualAdded, - AvaloniaObject visualRemoved) - { - CellsStructureDirty = true; - - base.OnVisualChildrenChanged(visualAdded, visualRemoved); - }*/ - - //------------------------------------------------------ - // - // Internal Methods - // - //------------------------------------------------------ - - /// - /// Invalidates grid caches and makes the grid dirty for measure. + /// Invalidates grid caches and makes the grid dirty for measure. /// internal void Invalidate() { @@ -702,10 +578,10 @@ namespace Avalonia.Controls } /// - /// Returns final width for a column. + /// Returns final width for a column. /// /// - /// Used from public ColumnDefinition ActualWidth. Calculates final width using offset data. + /// Used from public ColumnDefinition ActualWidth. Calculates final width using offset data. /// internal double GetFinalColumnDefinitionWidth(int columnIndex) { @@ -724,10 +600,10 @@ namespace Avalonia.Controls } /// - /// Returns final height for a row. + /// Returns final height for a row. /// /// - /// Used from public RowDefinition ActualHeight. Calculates final height using offset data. + /// Used from public RowDefinition ActualHeight. Calculates final height using offset data. /// internal double GetFinalRowDefinitionHeight(int rowIndex) { @@ -745,12 +621,6 @@ namespace Avalonia.Controls return (value); } - //------------------------------------------------------ - // - // Internal Properties - // - //------------------------------------------------------ - /// /// Convenience accessor to MeasureOverrideInProgress bit flag. /// @@ -781,32 +651,22 @@ namespace Avalonia.Controls /// /// Convenience accessor to ValidDefinitionsVStructure bit flag. /// - internal bool RowDefinitionsDirty + internal bool RowDefinitionsDirty { get => RowDefinitions?.IsDirty ?? false; set => RowDefinitions.IsDirty = value; } - //------------------------------------------------------ - // - // Private Methods - // - //------------------------------------------------------ - /// /// Lays out cells according to rows and columns, and creates lookup grids. /// private void ValidateCells() { - - if (CellsStructureDirty) { ValidateCellsCore(); CellsStructureDirty = false; } - - } /// @@ -837,11 +697,8 @@ namespace Avalonia.Controls CellCache cell = new CellCache(); - // - // read and cache child positioning properties - // - // read indices from the corresponding properties + // Read indices from the corresponding properties: // clamp to value < number_of_columns // column >= 0 is guaranteed by property value validation callback cell.ColumnIndex = Math.Min(GetColumn((Control)child), DefinitionsU.Count - 1); @@ -849,7 +706,7 @@ namespace Avalonia.Controls // row >= 0 is guaranteed by property value validation callback cell.RowIndex = Math.Min(GetRow((Control)child), DefinitionsV.Count - 1); - // read span properties + // Read span properties: // clamp to not exceed beyond right side of the grid // column_span > 0 is guaranteed by property value validation callback cell.ColumnSpan = Math.Min(GetColumnSpan((Control)child), DefinitionsU.Count - cell.ColumnIndex); @@ -861,9 +718,7 @@ namespace Avalonia.Controls Debug.Assert(0 <= cell.ColumnIndex && cell.ColumnIndex < DefinitionsU.Count); Debug.Assert(0 <= cell.RowIndex && cell.RowIndex < DefinitionsV.Count); - // - // calculate and cache length types for the child - // + // Calculate and cache length types for the child. cell.SizeTypeU = GetLengthTypeForRange(DefinitionsU, cell.ColumnIndex, cell.ColumnSpan); cell.SizeTypeV = GetLengthTypeForRange(DefinitionsV, cell.RowIndex, cell.RowSpan); @@ -871,9 +726,7 @@ namespace Avalonia.Controls hasStarCellsU |= cell.IsStarU; hasStarCellsV |= cell.IsStarV; - // - // distribute cells into four groups. - // + // Distribute cells into four groups. if (!cell.IsStarV) { @@ -887,15 +740,15 @@ namespace Avalonia.Controls cell.Next = extData.CellGroup3; extData.CellGroup3 = i; - // remember if this cell belongs to auto row + // Remember if this cell belongs to auto row hasGroup3CellsInAutoRows |= cell.IsAutoV; } } else { - if ( cell.IsAutoU - // note below: if spans through Star column it is NOT Auto - && !cell.IsStarU ) + if (cell.IsAutoU + // Note below: if spans through Star column it is NOT Auto + && !cell.IsStarU) { cell.Next = extData.CellGroup2; extData.CellGroup2 = i; @@ -986,7 +839,7 @@ namespace Avalonia.Controls extData.DefinitionsV = new DefinitionBase[] { new RowDefinition() { Parent = this } }; } else - { + { extData.DefinitionsV = extData.RowDefinitions; } } @@ -1053,7 +906,7 @@ namespace Avalonia.Controls { double[] minSizes = isRows ? new double[DefinitionsV.Count] : new double[DefinitionsU.Count]; - for (int j=0; j (double)o ) + if (o == null + || value > (double)o) { store[key] = value; } @@ -1235,13 +1088,13 @@ namespace Avalonia.Controls int cell, bool forceInfinityV) { - + double cellMeasureWidth; double cellMeasureHeight; - if ( PrivateCells[cell].IsAutoU - && !PrivateCells[cell].IsStarU ) + if (PrivateCells[cell].IsAutoU + && !PrivateCells[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" @@ -1261,8 +1114,8 @@ namespace Avalonia.Controls { cellMeasureHeight = double.PositiveInfinity; } - else if ( PrivateCells[cell].IsAutoV - && !PrivateCells[cell].IsStarV ) + else if (PrivateCells[cell].IsAutoV + && !PrivateCells[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" @@ -1277,19 +1130,18 @@ namespace Avalonia.Controls PrivateCells[cell].RowSpan); } - + var child = this.Children[cell]; if (child != null) { Size childConstraint = new Size(cellMeasureWidth, cellMeasureHeight); child.Measure(childConstraint); } - - - } + } + /// /// Calculates one dimensional measure size for given definitions' range. /// @@ -1393,12 +1245,12 @@ namespace Avalonia.Controls // sanity check: no matter what, but min size must always be the smaller; // max size must be the biggest; and preferred should be in between - Debug.Assert( minSize <= preferredSize - && preferredSize <= maxSize - && rangeMinSize <= rangePreferredSize - && rangePreferredSize <= rangeMaxSize ); + Debug.Assert(minSize <= preferredSize + && preferredSize <= maxSize + && rangeMinSize <= rangePreferredSize + && rangePreferredSize <= rangeMaxSize); - if (maxMaxSize < maxSize) maxMaxSize = maxSize; + if (maxMaxSize < maxSize) maxMaxSize = maxSize; if (definitions[i].UserSize.IsAuto) autoDefinitionsCount++; tempDefinitions[i - start] = definitions[i]; } @@ -1492,8 +1344,8 @@ namespace Avalonia.Controls // double equalSize = requestedSize / count; - if ( equalSize < maxMaxSize - && !_AreClose(equalSize, maxMaxSize) ) + if (equalSize < maxMaxSize + && !_AreClose(equalSize, maxMaxSize)) { // equi-size is less than maximum of maxSizes. // in this case distribute so that smaller definitions grow faster than @@ -1502,12 +1354,12 @@ namespace Avalonia.Controls double sizeToDistribute = requestedSize - rangeMaxSize; // sanity check: totalRemainingSize and sizeToDistribute must be real positive numbers - Debug.Assert( !double.IsInfinity(totalRemainingSize) - && !double.IsNaN(totalRemainingSize) - && totalRemainingSize > 0 - && !double.IsInfinity(sizeToDistribute) - && !double.IsNaN(sizeToDistribute) - && sizeToDistribute > 0 ); + Debug.Assert(!double.IsInfinity(totalRemainingSize) + && !double.IsNaN(totalRemainingSize) + && totalRemainingSize > 0 + && !double.IsInfinity(sizeToDistribute) + && !double.IsNaN(sizeToDistribute) + && sizeToDistribute > 0); for (int i = 0; i < count; ++i) { @@ -1543,105 +1395,10 @@ namespace Avalonia.Controls IReadOnlyList definitions, double availableSize) { - // if (FrameworkAppContextSwitches.GridStarDefinitionsCanExceedAvailableSpace) - // { - // ResolveStarLegacy(definitions, availableSize); - // } - // else - // { - ResolveStarMaxDiscrepancy(definitions, availableSize); - // } + ResolveStarMaxDiscrepancy(definitions, availableSize); } - // original implementation, used from 3.0 through 4.6.2 - private void ResolveStarLegacy( - IReadOnlyList definitions, - double availableSize) - { - DefinitionBase[] tempDefinitions = TempDefinitions; - int starDefinitionsCount = 0; - double takenSize = 0; - - for (int i = 0; i < definitions.Count; ++i) - { - switch (definitions[i].SizeType) - { - case (LayoutTimeSizeType.Auto): - takenSize += definitions[i].MinSize; - break; - case (LayoutTimeSizeType.Pixel): - takenSize += definitions[i].MeasureSize; - break; - case (LayoutTimeSizeType.Star): - { - tempDefinitions[starDefinitionsCount++] = definitions[i]; - - double starValue = definitions[i].UserSize.Value; - - if (_IsZero(starValue)) - { - definitions[i].MeasureSize = 0; - definitions[i].SizeCache = 0; - } - else - { - // clipping by c_starClip guarantees that sum of even a very big number of max'ed out star values - // can be summed up without overflow - starValue = Math.Min(starValue, c_starClip); - - // Note: normalized star value is temporary cached into MeasureSize - definitions[i].MeasureSize = starValue; - double maxSize = Math.Max(definitions[i].MinSize, definitions[i].UserMaxSize); - maxSize = Math.Min(maxSize, c_starClip); - definitions[i].SizeCache = maxSize / starValue; - } - } - break; - } - } - - if (starDefinitionsCount > 0) - { - Array.Sort(tempDefinitions, 0, starDefinitionsCount, s_starDistributionOrderComparer); - - // the 'do {} while' loop below calculates sum of star weights in order to avoid fp overflow... - // partial sum value is stored in each definition's SizeCache member. - // this way the algorithm guarantees (starValue <= definition.SizeCache) and thus - // (starValue / definition.SizeCache) will never overflow due to sum of star weights becoming zero. - // this is an important change from previous implementation where the following was possible: - // ((BigValueStar + SmallValueStar) - BigValueStar) resulting in 0... - double allStarWeights = 0; - int i = starDefinitionsCount - 1; - do - { - allStarWeights += tempDefinitions[i].MeasureSize; - tempDefinitions[i].SizeCache = allStarWeights; - } while (--i >= 0); - - i = 0; - do - { - double resolvedSize; - double starValue = tempDefinitions[i].MeasureSize; - - if (_IsZero(starValue)) - { - resolvedSize = tempDefinitions[i].MinSize; - } - else - { - double userSize = Math.Max(availableSize - takenSize, 0.0) * (starValue / tempDefinitions[i].SizeCache); - resolvedSize = Math.Min(userSize, tempDefinitions[i].UserMaxSize); - resolvedSize = Math.Max(tempDefinitions[i].MinSize, resolvedSize); - } - - tempDefinitions[i].MeasureSize = resolvedSize; - takenSize += resolvedSize; - } while (++i < starDefinitionsCount); - } - } - - // new implementation as of 4.7. Several improvements: + // New implementation as of 4.7. Several improvements: // 1. Allocate to *-defs hitting their min or max constraints, before allocating // to other *-defs. A def that hits its min uses more space than its // proportional share, reducing the space available to everyone else. @@ -1668,7 +1425,7 @@ namespace Avalonia.Controls // Phase 1. Determine the maximum *-weight and prepare to adjust *-weights double maxStar = 0.0; - for (int i=0; i definitions, - double finalSize, - bool columns) - { - int starDefinitionsCount = 0; // traverses form the first entry up - int nonStarIndex = definitions.Count; // traverses from the last entry down - double allPreferredArrangeSize = 0; - bool useLayoutRounding = this.UseLayoutRounding; - int[] definitionIndices = DefinitionIndices; - double[] roundingErrors = null; - - // If using layout rounding, check whether rounding needs to compensate for high DPI - double dpi = 1.0; - - if (useLayoutRounding) - { - // DpiScale dpiScale = GetDpi(); - // dpi = columns ? dpiScale.DpiScaleX : dpiScale.DpiScaleY; - dpi = (VisualRoot as Layout.ILayoutRoot)?.LayoutScaling ?? 1.0; - roundingErrors = RoundingErrors; - } - - for (int i = 0; i < definitions.Count; ++i) - { - // if definition is shared then is cannot be star - Debug.Assert(!definitions[i].IsShared || !definitions[i].UserSize.IsStar); - - if (definitions[i].UserSize.IsStar) - { - double starValue = definitions[i].UserSize.Value; - - if (_IsZero(starValue)) - { - // cach normilized star value temporary into MeasureSize - definitions[i].MeasureSize = 0; - definitions[i].SizeCache = 0; - } - else - { - // clipping by c_starClip guarantees that sum of even a very big number of max'ed out star values - // can be summed up without overflow - starValue = Math.Min(starValue, c_starClip); - - // Note: normalized star value is temporary cached into MeasureSize - definitions[i].MeasureSize = starValue; - double maxSize = Math.Max(definitions[i].MinSizeForArrange, definitions[i].UserMaxSize); - maxSize = Math.Min(maxSize, c_starClip); - definitions[i].SizeCache = maxSize / starValue; - if (useLayoutRounding) - { - roundingErrors[i] = definitions[i].SizeCache; - definitions[i].SizeCache = MathUtilities.RoundLayoutValue(definitions[i].SizeCache, dpi); - } - } - definitionIndices[starDefinitionsCount++] = i; - } - else - { - double userSize = 0; - - switch (definitions[i].UserSize.GridUnitType) - { - case (GridUnitType.Pixel): - userSize = definitions[i].UserSize.Value; - break; - - case (GridUnitType.Auto): - userSize = definitions[i].MinSizeForArrange; - break; - } - - double userMaxSize; - - if (definitions[i].IsShared) - { - // overriding userMaxSize effectively prevents squishy-ness. - // this is a "solution" to avoid shared definitions from been sized to - // different final size at arrange time, if / when different grids receive - // different final sizes. - userMaxSize = userSize; - } - else - { - userMaxSize = definitions[i].UserMaxSize; - } - - definitions[i].SizeCache = Math.Max(definitions[i].MinSizeForArrange, Math.Min(userSize, userMaxSize)); - if (useLayoutRounding) - { - roundingErrors[i] = definitions[i].SizeCache; - definitions[i].SizeCache = MathUtilities.RoundLayoutValue(definitions[i].SizeCache, dpi); - } - - allPreferredArrangeSize += definitions[i].SizeCache; - definitionIndices[--nonStarIndex] = i; - } - } - - // indices should meet - Debug.Assert(nonStarIndex == starDefinitionsCount); - - if (starDefinitionsCount > 0) - { - StarDistributionOrderIndexComparer starDistributionOrderIndexComparer = new StarDistributionOrderIndexComparer(definitions); - Array.Sort(definitionIndices, 0, starDefinitionsCount, starDistributionOrderIndexComparer); - - // the 'do {} while' loop below calculates sum of star weights in order to avoid fp overflow... - // partial sum value is stored in each definition's SizeCache member. - // this way the algorithm guarantees (starValue <= definition.SizeCache) and thus - // (starValue / definition.SizeCache) will never overflow due to sum of star weights becoming zero. - // this is an important change from previous implementation where the following was possible: - // ((BigValueStar + SmallValueStar) - BigValueStar) resulting in 0... - double allStarWeights = 0; - int i = starDefinitionsCount - 1; - do - { - allStarWeights += definitions[definitionIndices[i]].MeasureSize; - definitions[definitionIndices[i]].SizeCache = allStarWeights; - } while (--i >= 0); - - i = 0; - do - { - double resolvedSize; - double starValue = definitions[definitionIndices[i]].MeasureSize; - - if (_IsZero(starValue)) - { - resolvedSize = definitions[definitionIndices[i]].MinSizeForArrange; - } - else - { - double userSize = Math.Max(finalSize - allPreferredArrangeSize, 0.0) * (starValue / definitions[definitionIndices[i]].SizeCache); - resolvedSize = Math.Min(userSize, definitions[definitionIndices[i]].UserMaxSize); - resolvedSize = Math.Max(definitions[definitionIndices[i]].MinSizeForArrange, resolvedSize); - } - - definitions[definitionIndices[i]].SizeCache = resolvedSize; - if (useLayoutRounding) - { - roundingErrors[definitionIndices[i]] = definitions[definitionIndices[i]].SizeCache; - definitions[definitionIndices[i]].SizeCache = MathUtilities.RoundLayoutValue(definitions[definitionIndices[i]].SizeCache, dpi); - } - - allPreferredArrangeSize += definitions[definitionIndices[i]].SizeCache; - } while (++i < starDefinitionsCount); - } - - if ( allPreferredArrangeSize > finalSize - && !_AreClose(allPreferredArrangeSize, finalSize) ) - { - DistributionOrderIndexComparer distributionOrderIndexComparer = new DistributionOrderIndexComparer(definitions); - Array.Sort(definitionIndices, 0, definitions.Count, distributionOrderIndexComparer); - double sizeToDistribute = finalSize - allPreferredArrangeSize; - - for (int i = 0; i < definitions.Count; ++i) - { - int definitionIndex = definitionIndices[i]; - double final = definitions[definitionIndex].SizeCache + (sizeToDistribute / (definitions.Count - i)); - double finalOld = final; - final = Math.Max(final, definitions[definitionIndex].MinSizeForArrange); - final = Math.Min(final, definitions[definitionIndex].SizeCache); - - if (useLayoutRounding) - { - roundingErrors[definitionIndex] = final; - final = MathUtilities.RoundLayoutValue(finalOld, dpi); - final = Math.Max(final, definitions[definitionIndex].MinSizeForArrange); - final = Math.Min(final, definitions[definitionIndex].SizeCache); - } - - sizeToDistribute -= (final - definitions[definitionIndex].SizeCache); - definitions[definitionIndex].SizeCache = final; - } - - allPreferredArrangeSize = finalSize - sizeToDistribute; - } - - if (useLayoutRounding) - { - if (!_AreClose(allPreferredArrangeSize, finalSize)) - { - // Compute deltas - for (int i = 0; i < definitions.Count; ++i) - { - roundingErrors[i] = roundingErrors[i] - definitions[i].SizeCache; - definitionIndices[i] = i; - } - - // Sort rounding errors - RoundingErrorIndexComparer roundingErrorIndexComparer = new RoundingErrorIndexComparer(roundingErrors); - Array.Sort(definitionIndices, 0, definitions.Count, roundingErrorIndexComparer); - double adjustedSize = allPreferredArrangeSize; - double dpiIncrement = MathUtilities.RoundLayoutValue(1.0, dpi); - - if (allPreferredArrangeSize > finalSize) - { - int i = definitions.Count - 1; - while ((adjustedSize > finalSize && !_AreClose(adjustedSize, finalSize)) && i >= 0) - { - DefinitionBase definition = definitions[definitionIndices[i]]; - double final = definition.SizeCache - dpiIncrement; - final = Math.Max(final, definition.MinSizeForArrange); - if (final < definition.SizeCache) - { - adjustedSize -= dpiIncrement; - } - definition.SizeCache = final; - i--; - } - } - else if (allPreferredArrangeSize < finalSize) - { - int i = 0; - while ((adjustedSize < finalSize && !_AreClose(adjustedSize, finalSize)) && i < definitions.Count) - { - DefinitionBase definition = definitions[definitionIndices[i]]; - double final = definition.SizeCache + dpiIncrement; - final = Math.Max(final, definition.MinSizeForArrange); - if (final > definition.SizeCache) - { - adjustedSize += dpiIncrement; - } - definition.SizeCache = final; - i++; - } - } - } - } - - definitions[0].FinalOffset = 0.0; - for (int i = 0; i < definitions.Count; ++i) - { - definitions[(i + 1) % definitions.Count].FinalOffset = definitions[i].FinalOffset + definitions[i].SizeCache; - } + SetFinalSizeMaxDiscrepancy(definitions, finalSize, columns); } // new implementation, as of 4.7. This incorporates the same algorithm @@ -2251,7 +1762,7 @@ namespace Avalonia.Controls // Phase 1. Determine the maximum *-weight and prepare to adjust *-weights double maxStar = 0.0; - for (int i=0; i finalSize) { @@ -2694,9 +2204,9 @@ namespace Avalonia.Controls /// if the max constraint has higher discrepancy /// null if proportion doesn't fail a min or max constraint /// The discrepancy is the ratio of the proportion to the max- or min-ratio. - /// When both ratios hit the constraint, minRatio < proportion < maxRatio, + /// When both ratios hit the constraint, minRatio < proportion < maxRatio, /// and the minRatio has higher discrepancy if - /// (proportion / minRatio) > (maxRatio / proportion) + /// (proportion / minRatio) > (maxRatio / proportion) /// private static bool? Choose(double minRatio, double maxRatio, double proportion) { @@ -2782,8 +2292,8 @@ namespace Avalonia.Controls ExtendedData extData = ExtData; if (extData != null) { -// for (int i = 0; i < PrivateColumnCount; ++i) DefinitionsU[i].SetValid (); -// for (int i = 0; i < PrivateRowCount; ++i) DefinitionsV[i].SetValid (); + // for (int i = 0; i < PrivateColumnCount; ++i) DefinitionsU[i].SetValid (); + // for (int i = 0; i < PrivateRowCount; ++i) DefinitionsV[i].SetValid (); if (extData.TempDefinitions != null) { @@ -2800,9 +2310,9 @@ namespace Avalonia.Controls public bool ShouldSerializeColumnDefinitions() { ExtendedData extData = ExtData; - return ( extData != null - && extData.ColumnDefinitions != null - && extData.ColumnDefinitions.Count > 0 ); + return (extData != null + && extData.ColumnDefinitions != null + && extData.ColumnDefinitions.Count > 0); } /// @@ -2811,9 +2321,9 @@ namespace Avalonia.Controls public bool ShouldSerializeRowDefinitions() { ExtendedData extData = ExtData; - return ( extData != null - && extData.RowDefinitions != null - && extData.RowDefinitions.Count > 0 ); + return (extData != null + && extData.RowDefinitions != null + && extData.RowDefinitions.Count > 0); } /// @@ -2872,25 +2382,19 @@ namespace Avalonia.Controls return (flags == 0 || (_flags & flags) != 0); } - /// - /// - /// private static void OnShowGridLinesPropertyChanged(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e) { Grid grid = (Grid)d; - if ( grid.ExtData != null // trivial grid is 1 by 1. there is no grid lines anyway - && grid.ListenToNotifications) + if (grid.ExtData != null // trivial grid is 1 by 1. there is no grid lines anyway + && grid.ListenToNotifications) { grid.InvalidateVisual(); } - grid.SetFlags((bool) e.NewValue, Flags.ShowGridLinesPropertyValue); + grid.SetFlags((bool)e.NewValue, Flags.ShowGridLinesPropertyValue); } - /// - /// - /// private static void OnCellAttachedPropertyChanged(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e) { Visual child = d as Visual; @@ -2898,36 +2402,20 @@ namespace Avalonia.Controls if (child != null) { Grid grid = child.GetVisualParent(); - if ( grid != null - && grid.ExtData != null - && grid.ListenToNotifications ) + if (grid != null + && grid.ExtData != null + && grid.ListenToNotifications) { grid.CellsStructureDirty = true; } } } - /* /// - /// - /// - private static bool IsIntValueNotNegative(object value) - { - return ((int)value >= 0); - } - - /// - /// - /// - private static bool IsIntValueGreaterThanZero(object value) - { - return ((int)value > 0); - }*/ - /// /// 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) @@ -2956,12 +2444,6 @@ namespace Avalonia.Controls return (result != 2); } - //------------------------------------------------------ - // - // Private Properties - // - //------------------------------------------------------ - /// /// Private version returning array of column definitions. /// @@ -2988,8 +2470,8 @@ namespace Avalonia.Controls ExtendedData extData = ExtData; int requiredLength = Math.Max(DefinitionsU.Count, DefinitionsV.Count) * 2; - if ( extData.TempDefinitions == null - || extData.TempDefinitions.Length < requiredLength ) + if (extData.TempDefinitions == null + || extData.TempDefinitions.Length < requiredLength) { WeakReference tempDefinitionsWeakRef = (WeakReference)Thread.GetData(s_tempDefinitionsDataSlot); if (tempDefinitionsWeakRef == null) @@ -3000,8 +2482,8 @@ namespace Avalonia.Controls else { extData.TempDefinitions = (DefinitionBase[])tempDefinitionsWeakRef.Target; - if ( extData.TempDefinitions == null - || extData.TempDefinitions.Length < requiredLength ) + if (extData.TempDefinitions == null + || extData.TempDefinitions.Length < requiredLength) { extData.TempDefinitions = new DefinitionBase[requiredLength]; tempDefinitionsWeakRef.Target = extData.TempDefinitions; @@ -3129,7 +2611,7 @@ namespace Avalonia.Controls /// true if d == 0. private static bool _IsZero(double d) { - return (Math.Abs(d) < c_epsilon); + return (Math.Abs(d) < double.Epsilon); } /// @@ -3140,7 +2622,7 @@ namespace Avalonia.Controls /// true if d1 == d2 private static bool _AreClose(double d1, double d2) { - return (Math.Abs(d1 - d2) < c_epsilon); + return (Math.Abs(d1 - d2) < double.Epsilon); } /// @@ -3169,13 +2651,11 @@ namespace Avalonia.Controls } } - //------------------------------------------------------ - // - // Private Fields - // - //------------------------------------------------------ - private ExtendedData _data; // extended data instantiated on demand, for non-trivial case handling only - private Flags _flags; // grid validity / property caches dirtiness flags + // Extended data instantiated on demand, for non-trivial case handling only + private ExtendedData _data; + + // Grid validity / property caches dirtiness flags + private Flags _flags; private GridLinesRenderer _gridLinesRenderer; // Keeps track of definition indices. @@ -3184,29 +2664,16 @@ namespace Avalonia.Controls // Stores unrounded values and rounding errors during layout rounding. double[] _roundingErrors; - //------------------------------------------------------ - // - // Static Fields - // - //------------------------------------------------------ - 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 + // 5 is an arbitrary constant chosen to end the measure loop + private const int c_layoutLoopMaxCount = 5; + 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(); - //------------------------------------------------------ - // - // Private Structures / Classes - // - //------------------------------------------------------ - /// /// Extended data instantiated on demand, when grid handles non-trivial case. /// @@ -3237,34 +2704,28 @@ namespace Avalonia.Controls // * Valid???Layout flags indicate that layout time portion of the information // stored on the objects should be updated. // - ValidDefinitionsUStructure = 0x00000001, - ValidDefinitionsVStructure = 0x00000002, - ValidCellsStructure = 0x00000004, + ValidDefinitionsUStructure = 0x00000001, + ValidDefinitionsVStructure = 0x00000002, + ValidCellsStructure = 0x00000004, // // boolean properties state // - ShowGridLinesPropertyValue = 0x00000100, // show grid lines ? + ShowGridLinesPropertyValue = 0x00000100, // show grid lines ? // // 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 + 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 } - //------------------------------------------------------ - // - // Properties - // - //------------------------------------------------------ - /// /// ShowGridLines property. This property is used mostly /// for simplification of visual debuggig. When it is set @@ -3289,8 +2750,11 @@ namespace Avalonia.Controls AvaloniaProperty.RegisterAttached( "Column", defaultValue: 0, - validate: (_, v) => { if (v >= 0) return v; - else throw new ArgumentException("Invalid Grid.Column value."); }); + validate: (_, v) => + { + if (v >= 0) return v; + else throw new ArgumentException("Invalid Grid.Column value."); + }); /// /// Row property. This is an attached property. @@ -3307,8 +2771,11 @@ namespace Avalonia.Controls AvaloniaProperty.RegisterAttached( "Row", defaultValue: 0, - validate: (_, v) => { if (v >= 0) return v; - else throw new ArgumentException("Invalid Grid.Row value."); }); + validate: (_, v) => + { + if (v >= 0) return v; + else throw new ArgumentException("Invalid Grid.Row value."); + }); /// /// ColumnSpan property. This is an attached property. @@ -3324,8 +2791,11 @@ namespace Avalonia.Controls AvaloniaProperty.RegisterAttached( "ColumnSpan", defaultValue: 1, - validate: (_, v) => { if (v >= 1) return v; - else throw new ArgumentException("Invalid Grid.ColumnSpan value."); }); + validate: (_, v) => + { + if (v >= 1) return v; + else throw new ArgumentException("Invalid Grid.ColumnSpan value."); + }); /// /// RowSpan property. This is an attached property. @@ -3341,8 +2811,11 @@ namespace Avalonia.Controls AvaloniaProperty.RegisterAttached( "RowSpan", defaultValue: 1, - validate: (_, v) => { if (v >= 1) return v; - else throw new ArgumentException("Invalid Grid.RowSpan value."); }); + validate: (_, v) => + { + if (v >= 1) return v; + else throw new ArgumentException("Invalid Grid.RowSpan value."); + }); /// /// IsSharedSizeScope property marks scoping element for shared size. @@ -3351,30 +2824,18 @@ namespace Avalonia.Controls AvaloniaProperty.RegisterAttached( "IsSharedSizeScope"); - //------------------------------------------------------ - // - // Internal Structures / Classes - // - //------------------------------------------------------ - /// /// LayoutTimeSizeType is used internally and reflects layout-time size type. /// [System.Flags] internal enum LayoutTimeSizeType : byte { - None = 0x00, - Pixel = 0x01, - Auto = 0x02, - Star = 0x04, + None = 0x00, + Pixel = 0x01, + Auto = 0x02, + Star = 0x04, } - //------------------------------------------------------ - // - // Private Structures / Classes - // - //------------------------------------------------------ - /// /// CellCache stored calculated values of /// 1. attached cell positioning properties; @@ -3422,7 +2883,7 @@ namespace Avalonia.Controls int hash = (_start ^ (_count << 2)); if (_u) hash &= 0x7ffffff; - else hash |= 0x8000000; + else hash |= 0x8000000; return (hash); } @@ -3433,10 +2894,10 @@ namespace Avalonia.Controls public override bool Equals(object obj) { SpanKey sk = obj as SpanKey; - return ( sk != null - && sk._start == _start - && sk._count == _count - && sk._u == _u ); + return (sk != null + && sk._start == _start + && sk._count == _count + && sk._u == _u); } /// @@ -3544,51 +3005,6 @@ namespace Avalonia.Controls } } - /// - /// StarDistributionOrderComparer. - /// - 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; - } - } - - /// - /// DistributionOrderComparer. - /// - 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; - } - } - - /// /// StarDistributionOrderIndexComparer. /// @@ -3895,94 +3311,8 @@ namespace Avalonia.Controls } } - /* /// - /// Implementation of a simple enumerator of grid's logical children - /// - private class GridChildrenCollectionEnumeratorSimple : IEnumerator - { - internal GridChildrenCollectionEnumeratorSimple(Grid grid, bool includeChildren) - { - Debug.Assert(grid != null); - _currentEnumerator = -1; - _enumerator0 = new ColumnDefinitions.Enumerator(grid.ExtData != null ? grid.ExtData.ColumnDefinitions : null); - _enumerator1 = new RowDefinitions.Enumerator(grid.ExtData != null ? grid.ExtData.RowDefinitions : null); - // GridLineRenderer is NOT included into this enumerator. - _enumerator2Index = 0; - if (includeChildren) - { - _enumerator2Collection = grid.Children; - _enumerator2Count = _enumerator2Collection.Count; - } - else - { - _enumerator2Collection = null; - _enumerator2Count = 0; - } - } - - public bool MoveNext() - { - while (_currentEnumerator < 3) - { - if (_currentEnumerator >= 0) - { - switch (_currentEnumerator) - { - case (0): if (_enumerator0.MoveNext()) { _currentChild = _enumerator0.Current; return (true); } break; - case (1): if (_enumerator1.MoveNext()) { _currentChild = _enumerator1.Current; return (true); } break; - case (2): if (_enumerator2Index < _enumerator2Count) - { - _currentChild = _enumerator2Collection[_enumerator2Index]; - _enumerator2Index++; - return (true); - } - break; - } - } - _currentEnumerator++; - } - return (false); - } - - public Object Current - { - get - { - if (_currentEnumerator == -1) - { - throw new InvalidOperationException(SR.Get(SRID.EnumeratorNotStarted)); - } - if (_currentEnumerator >= 3) - { - throw new InvalidOperationException(SR.Get(SRID.EnumeratorReachedEnd)); - } - - // assert below is not true anymore since Controls allowes for null children - //Debug.Assert(_currentChild != null); - return (_currentChild); - } - } - - public void Reset() - { - _currentEnumerator = -1; - _currentChild = null; - _enumerator0.Reset(); - _enumerator1.Reset(); - _enumerator2Index = 0; - } - - private int _currentEnumerator; - private Object _currentChild; - private ColumnDefinitions.Enumerator _enumerator0; - private RowDefinitions.Enumerator _enumerator1; - private Controls _enumerator2Collection; - private int _enumerator2Index; - private int _enumerator2Count; - }*/ - /// - /// Helper to render grid lines. + /// Helper for rendering grid lines. /// internal class GridLinesRenderer : Control { @@ -3995,15 +3325,15 @@ namespace Avalonia.Controls var ds1 = new DashStyle(dashArray, 0); _oddDashPen = new Pen(Brushes.Blue, - _penWidth, - lineCap: PenLineCap.Flat, - dashStyle: ds1); + _penWidth, + lineCap: PenLineCap.Flat, + dashStyle: ds1); var ds2 = new DashStyle(dashArray, _dashLength); _evenDashPen = new Pen(Brushes.Yellow, - _penWidth, - lineCap: PenLineCap.Flat, - dashStyle: ds2); + _penWidth, + lineCap: PenLineCap.Flat, + dashStyle: ds2); } /// @@ -4052,7 +3382,6 @@ namespace Avalonia.Controls internal void UpdateRenderBounds(Size arrangeSize) { _lastArrangeSize = arrangeSize; - this.InvalidateMeasure(); this.InvalidateVisual(); } @@ -4061,6 +3390,6 @@ namespace Avalonia.Controls 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/RowDefinitions.cs b/src/Avalonia.Controls/RowDefinitions.cs index 3090844251..cf72cc8ba3 100644 --- a/src/Avalonia.Controls/RowDefinitions.cs +++ b/src/Avalonia.Controls/RowDefinitions.cs @@ -14,10 +14,8 @@ namespace Avalonia.Controls /// /// Initializes a new instance of the class. /// - public RowDefinitions() + public RowDefinitions() : base() { - ResetBehavior = ResetBehavior.Remove; - CollectionChanged += OnCollectionChanged; } ///