From 58b6399a52eedc5005b552565dc9620066ebe4d3 Mon Sep 17 00:00:00 2001 From: Jumar Macato Date: Fri, 24 May 2019 15:37:28 +0800 Subject: [PATCH] Part 8 of preliminary error-plugging, Grid running but somewhat broken. --- src/Avalonia.Controls/ColumnDefinition.cs | 6 +- src/Avalonia.Controls/DefinitionBase.cs | 117 +++++++++--------- src/Avalonia.Controls/GridWPF.cs | 105 ++++++++++++++-- src/Avalonia.Controls/RowDefinition.cs | 6 +- .../Utils/SharedSizeScopeHost.cs | 4 +- 5 files changed, 164 insertions(+), 74 deletions(-) diff --git a/src/Avalonia.Controls/ColumnDefinition.cs b/src/Avalonia.Controls/ColumnDefinition.cs index d316881a05..8c9f6323a9 100644 --- a/src/Avalonia.Controls/ColumnDefinition.cs +++ b/src/Avalonia.Controls/ColumnDefinition.cs @@ -29,7 +29,7 @@ namespace Avalonia.Controls /// /// Initializes a new instance of the class. /// - public ColumnDefinition() + public ColumnDefinition() : base(true) { } @@ -38,7 +38,7 @@ namespace Avalonia.Controls /// /// The width of the column. /// The width unit of the column. - public ColumnDefinition(double value, GridUnitType type) + public ColumnDefinition(double value, GridUnitType type): base(true) { Width = new GridLength(value, type); } @@ -47,7 +47,7 @@ namespace Avalonia.Controls /// Initializes a new instance of the class. /// /// The width of the column. - public ColumnDefinition(GridLength width) + public ColumnDefinition(GridLength width): base(true) { Width = width; } diff --git a/src/Avalonia.Controls/DefinitionBase.cs b/src/Avalonia.Controls/DefinitionBase.cs index e1c5979476..b25ae3ab59 100644 --- a/src/Avalonia.Controls/DefinitionBase.cs +++ b/src/Avalonia.Controls/DefinitionBase.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; +using System.Collections; using System.Collections.Generic; using System.Diagnostics; using Avalonia.Utilities; @@ -14,6 +15,13 @@ namespace Avalonia.Controls /// public class DefinitionBase : ContentControl { + /// + /// Static ctor. Used for static registration of properties. + /// + static DefinitionBase() + { + SharedSizeGroupProperty.Changed.AddClassHandler(OnSharedSizeGroupPropertyChanged); + } /// /// Defines the property. @@ -57,21 +65,21 @@ namespace Avalonia.Controls /// internal void OnEnterParentTree() { - if (_sharedState == null) - { - // start with getting SharedSizeGroup value. - // this property is NOT inhereted which should result in better overall perf. - string sharedSizeGroupId = SharedSizeGroup; - if (sharedSizeGroupId != null) - { - SharedSizeScope privateSharedSizeScope = PrivateSharedSizeScope; - if (privateSharedSizeScope != null) - { - _sharedState = privateSharedSizeScope.EnsureSharedState(sharedSizeGroupId); - _sharedState.AddMember(this); - } - } - } + // if (_sharedState == null) + // { + // // start with getting SharedSizeGroup value. + // // this property is NOT inhereted which should result in better overall perf. + // string sharedSizeGroupId = SharedSizeGroup; + // if (sharedSizeGroupId != null) + // { + // SharedSizeScope privateSharedSizeScope = PrivateSharedSizeScope; + // if (privateSharedSizeScope != null) + // { + // _sharedState = privateSharedSizeScope.EnsureSharedState(sharedSizeGroupId); + // _sharedState.AddMember(this); + // } + // } + // } } /// @@ -124,7 +132,7 @@ namespace Avalonia.Controls /// /// This method needs to be internal to be accessable from derived classes. /// - internal static void OnUserSizePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + internal static void OnUserSizePropertyChanged(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e) { DefinitionBase definition = (DefinitionBase)d; @@ -167,7 +175,7 @@ namespace Avalonia.Controls /// /// This method needs to be internal to be accessable from derived classes. /// - internal static void OnUserMinSizePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + internal static void OnUserMinSizePropertyChanged(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e) { DefinitionBase definition = (DefinitionBase)d; @@ -187,7 +195,7 @@ namespace Avalonia.Controls internal static bool IsUserMinSizePropertyValueValid(object value) { double v = (double)value; - return (!MathUtilities.IsNaN(v) && v >= 0.0d && !Double.IsPositiveInfinity(v)); + return (!Double.IsNaN(v) && v >= 0.0d && !Double.IsPositiveInfinity(v)); } /// @@ -196,7 +204,7 @@ namespace Avalonia.Controls /// /// This method needs to be internal to be accessable from derived classes. /// - internal static void OnUserMaxSizePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + internal static void OnUserMaxSizePropertyChanged(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e) { DefinitionBase definition = (DefinitionBase)d; @@ -216,7 +224,7 @@ namespace Avalonia.Controls internal static bool IsUserMaxSizePropertyValueValid(object value) { double v = (double)value; - return (!MathUtilities.IsNaN(v) && v >= 0.0d); + return (!Double.IsNaN(v) && v >= 0.0d); } /// @@ -230,7 +238,7 @@ namespace Avalonia.Controls /// 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(DependencyObject d, DependencyPropertyChangedEventArgs e) + 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) @@ -238,11 +246,11 @@ namespace Avalonia.Controls if ((bool)e.NewValue) { SharedSizeScope sharedStatesCollection = new SharedSizeScope(); - d.SetValue(PrivateSharedSizeScopeProperty, sharedStatesCollection); + // d.SetValue(PrivateSharedSizeScopeProperty, sharedStatesCollection); } else { - d.ClearValue(PrivateSharedSizeScopeProperty); + // d.ClearValue(PrivateSharedSizeScopeProperty); } } @@ -307,7 +315,7 @@ namespace Avalonia.Controls /// /// Layout-time user size type. /// - internal Grid.GridLayoutTimeSizeType SizeType + internal Grid.LayoutTimeSizeType SizeType { get { return (_sizeType); } set { _sizeType = value; } @@ -333,7 +341,7 @@ namespace Avalonia.Controls get { double preferredSize = MinSize; - if (_sizeType != Grid.GridLayoutTimeSizeType.Auto + if (_sizeType != Grid.LayoutTimeSizeType.Auto && preferredSize < _measureSize) { preferredSize = _measureSize; @@ -477,10 +485,8 @@ namespace Avalonia.Controls /// /// /// - private static void OnSharedSizeGroupPropertyChanged(AvaloniaPropertyChangedEventArgs e) + private static void OnSharedSizeGroupPropertyChanged(DefinitionBase definition, AvaloniaPropertyChangedEventArgs e) { - DefinitionBase definition = (DefinitionBase)e.Sender; - if (definition.InParentLogicalTree) { string sharedSizeGroupId = (string)e.NewValue; @@ -495,14 +501,14 @@ namespace Avalonia.Controls if ((definition._sharedState == null) && (sharedSizeGroupId != null)) { - SharedSizeScope privateSharedSizeScope = definition.PrivateSharedSizeScope; - if (privateSharedSizeScope != null) - { - // if definition is not registered and both: shared size group id AND private shared scope - // are available, then register definition. - definition._sharedState = privateSharedSizeScope.EnsureSharedState(sharedSizeGroupId); - definition._sharedState.AddMember(definition); - } + // SharedSizeScope privateSharedSizeScope = definition.PrivateSharedSizeScope; + // if (privateSharedSizeScope != null) + // { + // // if definition is not registered and both: shared size group id AND private shared scope + // // are available, then register definition. + // definition._sharedState = privateSharedSizeScope.EnsureSharedState(sharedSizeGroupId); + // definition._sharedState.AddMember(definition); + // } } } } @@ -513,12 +519,12 @@ namespace Avalonia.Controls /// b) contains only letters, digits and underscore ('_'). /// c) does not start with a digit. /// - private static bool SharedSizeGroupPropertyValueValid(string value) + private static string SharedSizeGroupPropertyValueValid(DefinitionBase _, string value) { // null is default value if (value == null) { - return (true); + return value; } string id = (string)value; @@ -541,11 +547,11 @@ namespace Avalonia.Controls if (i == id.Length) { - return (true); + return value; } } - return (false); + return null; } /// @@ -596,13 +602,13 @@ namespace Avalonia.Controls #region Private Properties - /// - /// Private getter of shared state collection dynamic property. - /// - private SharedSizeScope PrivateSharedSizeScope - { - get { return (SharedSizeScope)GetValue(PrivateSharedSizeScopeProperty); } - } + // /// + // /// Private getter of shared state collection dynamic property. + // /// + // private SharedSizeScope PrivateSharedSizeScope + // { + // get { return (SharedSizeScope)GetValue(PrivateSharedSizeScopeProperty); } + // } /// /// Convenience accessor to UseSharedMinimum flag @@ -635,7 +641,7 @@ namespace Avalonia.Controls private Flags _flags; // flags reflecting various aspects of internal state private int _parentIndex; // this instance's index in parent's children collection - private Grid.GridLayoutTimeSizeType _sizeType; // layout-time user size type. it may differ from _userSizeValueCache.UnitType when calculating "to-content" + private Grid.LayoutTimeSizeType _sizeType; // layout-time user size type. it may differ from _userSizeValueCache.UnitType when calculating "to-content" private double _minSize; // used during measure to accumulate size for "Auto" and "Star" DefinitionBase's private double _measureSize; // size, calculated to be the input contstraint size for Child.Measure @@ -716,7 +722,7 @@ namespace Avalonia.Controls _sharedSizeScope = sharedSizeScope; _sharedSizeGroupId = sharedSizeGroupId; _registry = new List(); - _layoutUpdated = new EventHandler(OnLayoutUpdated); + // _layoutUpdated = new EventHandler(OnLayoutUpdated); _broadcastInvalidation = true; } @@ -775,7 +781,8 @@ namespace Avalonia.Controls if (_layoutUpdatedHost == null) { _layoutUpdatedHost = layoutUpdatedHost; - _layoutUpdatedHost.LayoutUpdated += _layoutUpdated; + // PORTING HACK... Remove this when resolved. + _layoutUpdatedHost.GetSubject(Visual.BoundsProperty).Subscribe(p => _layoutUpdated?.Invoke(this, null)); } } @@ -884,7 +891,7 @@ namespace Avalonia.Controls _minSize = sharedMinSize; - _layoutUpdatedHost.LayoutUpdated -= _layoutUpdated; + // _layoutUpdatedHost.LayoutUpdated -= _layoutUpdated; _layoutUpdatedHost = null; _broadcastInvalidation = true; @@ -902,14 +909,6 @@ namespace Avalonia.Controls } - /// - /// Static ctor. Used for static registration of properties. - /// - static DefinitionBase() - { - SharedSizeGroupProperty.Changed.AddClassHandler(OnSharedSizeGroupPropertyChanged); - } - #endregion Properties } } diff --git a/src/Avalonia.Controls/GridWPF.cs b/src/Avalonia.Controls/GridWPF.cs index d42d6fc651..c9397e2e20 100644 --- a/src/Avalonia.Controls/GridWPF.cs +++ b/src/Avalonia.Controls/GridWPF.cs @@ -84,6 +84,98 @@ namespace Avalonia.Controls set { SetValue(ShowGridLinesProperty, value); } } + + /// + /// Gets the value of the Column attached property for a control. + /// + /// The control. + /// The control's column. + public static int GetColumn(AvaloniaObject element) + { + return element.GetValue(ColumnProperty); + } + + /// + /// Gets the value of the ColumnSpan attached property for a control. + /// + /// The control. + /// The control's column span. + public static int GetColumnSpan(AvaloniaObject element) + { + return element.GetValue(ColumnSpanProperty); + } + + /// + /// Gets the value of the Row attached property for a control. + /// + /// The control. + /// The control's row. + public static int GetRow(AvaloniaObject element) + { + return element.GetValue(RowProperty); + } + + /// + /// Gets the value of the RowSpan attached property for a control. + /// + /// The control. + /// The control's row span. + public static int GetRowSpan(AvaloniaObject element) + { + return element.GetValue(RowSpanProperty); + } + + + /// + /// Gets the value of the IsSharedSizeScope attached property for a control. + /// + /// The control. + /// The control's IsSharedSizeScope value. + public static bool GetIsSharedSizeScope(AvaloniaObject element) + { + return element.GetValue(IsSharedSizeScopeProperty); + } + + /// + /// Sets the value of the Column attached property for a control. + /// + /// The control. + /// The column value. + public static void SetColumn(AvaloniaObject element, int value) + { + element.SetValue(ColumnProperty, value); + } + + /// + /// Sets the value of the ColumnSpan attached property for a control. + /// + /// The control. + /// The column span value. + public static void SetColumnSpan(AvaloniaObject element, int value) + { + element.SetValue(ColumnSpanProperty, value); + } + + /// + /// Sets the value of the Row attached property for a control. + /// + /// The control. + /// The row value. + public static void SetRow(AvaloniaObject element, int value) + { + element.SetValue(RowProperty, value); + } + + /// + /// Sets the value of the RowSpan attached property for a control. + /// + /// The control. + /// The row span value. + public static void SetRowSpan(AvaloniaObject element, int value) + { + element.SetValue(RowSpanProperty, value); + } + private ColumnDefinitions _columnDefinitions; private RowDefinitions _rowDefinitions; @@ -484,12 +576,11 @@ namespace Avalonia.Controls for (int i = PrivateCells.Length - 1; i >= 0; --i) { - var child = Children[i]; + var child = Children[i] as Control; if (child == null) { continue; } - CellCache cell = new CellCache(); // @@ -499,20 +590,20 @@ namespace Avalonia.Controls // 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(child.GetValue(Grid.ColumnProperty), DefinitionsU.Length - 1); + cell.ColumnIndex = Math.Min(GetColumn(child), DefinitionsU.Length - 1); // clamp to value < number_of_rows // row >= 0 is guaranteed by property value validation callback - cell.RowIndex = Math.Min(child.GetValue(Grid.RowProperty), DefinitionsV.Length - 1); + cell.RowIndex = Math.Min(GetRow(child), DefinitionsV.Length - 1); // 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(child.GetValue(Grid.ColumnSpanProperty), DefinitionsU.Length - cell.ColumnIndex); + cell.ColumnSpan = Math.Min(GetColumnSpan(child), DefinitionsU.Length - cell.ColumnIndex); // clamp to not exceed beyond bottom side of the grid // row_span > 0 is guaranteed by property value validation callback - cell.RowSpan = Math.Min(child.GetValue(Grid.RowSpanProperty), DefinitionsV.Length - cell.RowIndex); - + cell.RowSpan = Math.Min(GetRowSpan(child), DefinitionsV.Length - cell.RowIndex); + Debug.Assert(0 <= cell.ColumnIndex && cell.ColumnIndex < DefinitionsU.Length); Debug.Assert(0 <= cell.RowIndex && cell.RowIndex < DefinitionsV.Length); diff --git a/src/Avalonia.Controls/RowDefinition.cs b/src/Avalonia.Controls/RowDefinition.cs index 7307843417..d42ffdfc28 100644 --- a/src/Avalonia.Controls/RowDefinition.cs +++ b/src/Avalonia.Controls/RowDefinition.cs @@ -29,7 +29,7 @@ namespace Avalonia.Controls /// /// Initializes a new instance of the class. /// - public RowDefinition() + public RowDefinition() : base(false) { } @@ -38,7 +38,7 @@ namespace Avalonia.Controls /// /// The height of the row. /// The height unit of the column. - public RowDefinition(double value, GridUnitType type) + public RowDefinition(double value, GridUnitType type): base(false) { Height = new GridLength(value, type); } @@ -47,7 +47,7 @@ namespace Avalonia.Controls /// Initializes a new instance of the class. /// /// The height of the column. - public RowDefinition(GridLength height) + public RowDefinition(GridLength height): base(false) { Height = height; } diff --git a/src/Avalonia.Controls/Utils/SharedSizeScopeHost.cs b/src/Avalonia.Controls/Utils/SharedSizeScopeHost.cs index 8553165e4b..5f70557385 100644 --- a/src/Avalonia.Controls/Utils/SharedSizeScopeHost.cs +++ b/src/Avalonia.Controls/Utils/SharedSizeScopeHost.cs @@ -395,8 +395,8 @@ namespace Avalonia.Controls /// public void Dispose() { - while (_measurementCaches.Any()) - _measurementCaches[0].Grid.SharedScopeChanged(); + // while (_measurementCaches.Any()) + // _measurementCaches[0].Grid.SharedScopeChanged(); } ///