Browse Source

Part 10 of n

pull/2563/head
Jumar Macato 7 years ago
parent
commit
9b1eb2ac8c
No known key found for this signature in database GPG Key ID: B19884DAC3A5BF3F
  1. 12
      src/Avalonia.Controls/ColumnDefinition.cs
  2. 370
      src/Avalonia.Controls/DefinitionBase.cs
  3. 209
      src/Avalonia.Controls/GridWPF.cs
  4. 13
      src/Avalonia.Controls/RowDefinition.cs

12
src/Avalonia.Controls/ColumnDefinition.cs

@ -29,7 +29,7 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ColumnDefinition"/> class. /// Initializes a new instance of the <see cref="ColumnDefinition"/> class.
/// </summary> /// </summary>
public ColumnDefinition() : base(true) public ColumnDefinition()
{ {
} }
@ -38,7 +38,7 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
/// <param name="value">The width of the column.</param> /// <param name="value">The width of the column.</param>
/// <param name="type">The width unit of the column.</param> /// <param name="type">The width unit of the column.</param>
public ColumnDefinition(double value, GridUnitType type): base(true) public ColumnDefinition(double value, GridUnitType type)
{ {
Width = new GridLength(value, type); Width = new GridLength(value, type);
} }
@ -47,7 +47,7 @@ namespace Avalonia.Controls
/// Initializes a new instance of the <see cref="ColumnDefinition"/> class. /// Initializes a new instance of the <see cref="ColumnDefinition"/> class.
/// </summary> /// </summary>
/// <param name="width">The width of the column.</param> /// <param name="width">The width of the column.</param>
public ColumnDefinition(GridLength width): base(true) public ColumnDefinition(GridLength width)
{ {
Width = width; Width = width;
} }
@ -87,5 +87,11 @@ namespace Avalonia.Controls
get { return GetValue(WidthProperty); } get { return GetValue(WidthProperty); }
set { SetValue(WidthProperty, value); } set { SetValue(WidthProperty, value); }
} }
internal override GridLength UserSizeValueCache => this.Width;
internal override double UserMinSizeValueCache => this.MinWidth;
internal override double UserMaxSizeValueCache => this.MaxWidth;
} }
} }

370
src/Avalonia.Controls/DefinitionBase.cs

@ -13,7 +13,7 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// Base class for <see cref="ColumnDefinition"/> and <see cref="RowDefinition"/>. /// Base class for <see cref="ColumnDefinition"/> and <see cref="RowDefinition"/>.
/// </summary> /// </summary>
public class DefinitionBase : ContentControl public abstract class DefinitionBase : ContentControl
{ {
/// <summary> /// <summary>
/// Static ctor. Used for static registration of properties. /// Static ctor. Used for static registration of properties.
@ -21,8 +21,9 @@ namespace Avalonia.Controls
static DefinitionBase() static DefinitionBase()
{ {
SharedSizeGroupProperty.Changed.AddClassHandler<DefinitionBase>(OnSharedSizeGroupPropertyChanged); SharedSizeGroupProperty.Changed.AddClassHandler<DefinitionBase>(OnSharedSizeGroupPropertyChanged);
BoundsProperty.Changed.AddClassHandler<DefinitionBase>(OnUserSizePropertyChanged); // BoundsProperty.Changed.AddClassHandler<DefinitionBase>(OnUserSizePropertyChanged);
} }
/// <summary> /// <summary>
/// Defines the <see cref="SharedSizeGroup"/> property. /// Defines the <see cref="SharedSizeGroup"/> property.
@ -38,63 +39,6 @@ namespace Avalonia.Controls
get { return GetValue(SharedSizeGroupProperty); } get { return GetValue(SharedSizeGroupProperty); }
set { SetValue(SharedSizeGroupProperty, value); } set { SetValue(SharedSizeGroupProperty, value); }
} }
//------------------------------------------------------
//
// Constructors
//
//------------------------------------------------------
internal DefinitionBase(bool isColumnDefinition)
{
_isColumnDefinition = isColumnDefinition;
_parentIndex = -1;
}
//------------------------------------------------------
//
// Internal Methods
//
//------------------------------------------------------
#region Internal Methods
/// <summary>
/// Callback to notify about entering model tree.
/// </summary>
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);
// }
// }
// }
}
/// <summary>
/// Callback to notify about exitting model tree.
/// </summary>
internal void OnExitParentTree()
{
_offset = 0;
if (_sharedState != null)
{
_sharedState.RemoveMember(this);
_sharedState = null;
}
}
/// <summary> /// <summary>
/// Performs action preparing definition to enter layout calculation mode. /// Performs action preparing definition to enter layout calculation mode.
@ -109,161 +53,6 @@ namespace Avalonia.Controls
if (_sharedState != null) { _sharedState.EnsureDeferredValidation(grid); } if (_sharedState != null) { _sharedState.EnsureDeferredValidation(grid); }
} }
/// <summary>
/// Updates min size.
/// </summary>
/// <param name="minSize">New size.</param>
internal void UpdateMinSize(double minSize)
{
_minSize = Math.Max(_minSize, minSize);
}
/// <summary>
/// Sets min size.
/// </summary>
/// <param name="minSize">New size.</param>
internal void SetMinSize(double minSize)
{
_minSize = minSize;
}
/// <summary>
/// <see cref="PropertyMetadata.PropertyChangedCallback"/>
/// </summary>
/// <remarks>
/// This method needs to be internal to be accessable from derived classes.
/// </remarks>
internal static void OnUserSizePropertyChanged(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e)
{
DefinitionBase definition = (DefinitionBase)d;
if (definition.InParentLogicalTree)
{
if (definition._sharedState != null)
{
definition._sharedState.Invalidate();
}
else
{
Grid parentGrid = (Grid)definition.Parent;
if (((GridLength)e.OldValue).GridUnitType != ((GridLength)e.NewValue).GridUnitType)
{
parentGrid.Invalidate();
}
else
{
parentGrid.InvalidateMeasure();
}
}
}
}
/// <summary>
/// <see cref="DependencyProperty.ValidateValueCallback"/>
/// </summary>
/// <remarks>
/// This method needs to be internal to be accessable from derived classes.
/// </remarks>
internal static bool IsUserSizePropertyValueValid(object value)
{
return (((GridLength)value).Value >= 0);
}
/// <summary>
/// <see cref="PropertyMetadata.PropertyChangedCallback"/>
/// </summary>
/// <remarks>
/// This method needs to be internal to be accessable from derived classes.
/// </remarks>
internal static void OnUserMinSizePropertyChanged(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e)
{
DefinitionBase definition = (DefinitionBase)d;
if (definition.InParentLogicalTree)
{
Grid parentGrid = (Grid)definition.Parent;
parentGrid.InvalidateMeasure();
}
}
/// <summary>
/// <see cref="DependencyProperty.ValidateValueCallback"/>
/// </summary>
/// <remarks>
/// This method needs to be internal to be accessable from derived classes.
/// </remarks>
internal static bool IsUserMinSizePropertyValueValid(object value)
{
double v = (double)value;
return (!Double.IsNaN(v) && v >= 0.0d && !Double.IsPositiveInfinity(v));
}
/// <summary>
/// <see cref="PropertyMetadata.PropertyChangedCallback"/>
/// </summary>
/// <remarks>
/// This method needs to be internal to be accessable from derived classes.
/// </remarks>
internal static void OnUserMaxSizePropertyChanged(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e)
{
DefinitionBase definition = (DefinitionBase)d;
if (definition.InParentLogicalTree)
{
Grid parentGrid = (Grid)definition.Parent;
parentGrid.InvalidateMeasure();
}
}
/// <summary>
/// <see cref="DependencyProperty.ValidateValueCallback"/>
/// </summary>
/// <remarks>
/// This method needs to be internal to be accessable from derived classes.
/// </remarks>
internal static bool IsUserMaxSizePropertyValueValid(object value)
{
double v = (double)value;
return (!Double.IsNaN(v) && v >= 0.0d);
}
/// <summary>
/// <see cref="PropertyMetadata.PropertyChangedCallback"/>
/// </summary>
/// <remarks>
/// 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.
/// </remarks>
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)
{
SharedSizeScope sharedStatesCollection = new SharedSizeScope();
// d.SetValue(PrivateSharedSizeScopeProperty, sharedStatesCollection);
}
else
{
// d.ClearValue(PrivateSharedSizeScopeProperty);
}
}
#endregion Internal Methods
//------------------------------------------------------
//
// Internal Properties
//
//------------------------------------------------------
#region Internal Properties
/// <summary> /// <summary>
/// Returns <c>true</c> if this definition is a part of shared group. /// Returns <c>true</c> if this definition is a part of shared group.
@ -376,6 +165,25 @@ namespace Avalonia.Controls
} }
return (minSize); return (minSize);
} }
}
/// <summary>
/// Updates min size.
/// </summary>
/// <param name="minSize">New size.</param>
internal void UpdateMinSize(double minSize)
{
_minSize = Math.Max(_minSize, minSize);
}
/// <summary>
/// Sets min size.
/// </summary>
/// <param name="minSize">New size.</param>
internal void SetMinSize(double minSize)
{
_minSize = minSize;
} }
/// <summary> /// <summary>
@ -408,44 +216,18 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// Internal helper to access up-to-date UserSize property value. /// Internal helper to access up-to-date UserSize property value.
/// </summary> /// </summary>
internal GridLength UserSizeValueCache internal abstract GridLength UserSizeValueCache { get; }
{
get
{
return (GridLength)GetValue(
_isColumnDefinition ?
ColumnDefinition.WidthProperty :
RowDefinition.HeightProperty);
}
}
/// <summary> /// <summary>
/// Internal helper to access up-to-date UserMinSize property value. /// Internal helper to access up-to-date UserMinSize property value.
/// </summary> /// </summary>
internal double UserMinSizeValueCache internal abstract double UserMinSizeValueCache { get; }
{
get
{
return (double)GetValue(
_isColumnDefinition ?
ColumnDefinition.MinWidthProperty :
RowDefinition.MinHeightProperty);
}
}
/// <summary> /// <summary>
/// Internal helper to access up-to-date UserMaxSize property value. /// Internal helper to access up-to-date UserMaxSize property value.
/// </summary> /// </summary>
internal double UserMaxSizeValueCache internal abstract double UserMaxSizeValueCache { get; }
{
get
{
return (double)GetValue(
_isColumnDefinition ?
ColumnDefinition.MaxWidthProperty :
RowDefinition.MaxHeightProperty);
}
}
/// <summary> /// <summary>
/// Protected. Returns <c>true</c> if this DefinitionBase instance is in parent's logical tree. /// Protected. Returns <c>true</c> if this DefinitionBase instance is in parent's logical tree.
@ -455,37 +237,6 @@ namespace Avalonia.Controls
get { return (_parentIndex != -1); } get { return (_parentIndex != -1); }
} }
#endregion Internal Properties
//------------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
#region Private Methods
/// <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));
}
/// <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>
/// <see cref="PropertyMetadata.PropertyChangedCallback"/>
/// </summary>
private static void OnSharedSizeGroupPropertyChanged(DefinitionBase definition, AvaloniaPropertyChangedEventArgs e) private static void OnSharedSizeGroupPropertyChanged(DefinitionBase definition, AvaloniaPropertyChangedEventArgs e)
{ {
if (definition.InParentLogicalTree) if (definition.InParentLogicalTree)
@ -593,31 +344,13 @@ namespace Avalonia.Controls
} }
} }
#endregion Private Methods
//------------------------------------------------------
//
// Private Properties
//
//------------------------------------------------------
#region Private Properties
// /// <summary>
// /// Private getter of shared state collection dynamic property.
// /// </summary>
// private SharedSizeScope PrivateSharedSizeScope
// {
// get { return (SharedSizeScope)GetValue(PrivateSharedSizeScopeProperty); }
// }
/// <summary> /// <summary>
/// Convenience accessor to UseSharedMinimum flag /// Convenience accessor to UseSharedMinimum flag
/// </summary> /// </summary>
private bool UseSharedMinimum private bool UseSharedMinimum
{ {
get { return (CheckFlagsAnd(Flags.UseSharedMinimum)); } get { return _useSharedMinimum; }
set { SetFlags(value, Flags.UseSharedMinimum); } set { _useSharedMinimum = value; }
} }
/// <summary> /// <summary>
@ -625,22 +358,11 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
private bool LayoutWasUpdated private bool LayoutWasUpdated
{ {
get { return (CheckFlagsAnd(Flags.LayoutWasUpdated)); } get { return _layoutWasUpdated; }
set { SetFlags(value, Flags.LayoutWasUpdated); } set { _layoutWasUpdated = value; }
} }
#endregion Private Properties private int _parentIndex = -1; // this instance's index in parent's children collection
//------------------------------------------------------
//
// 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
private int _parentIndex; // this instance's index in parent's children collection
private Grid.LayoutTimeSizeType _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"
@ -650,29 +372,10 @@ namespace Avalonia.Controls
private double _offset; // offset of the DefinitionBase from left / top corner (assuming LTR case) 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 private SharedSizeState _sharedState; // reference to shared state object this instance is registered with
private bool _layoutWasUpdated;
private bool _useSharedMinimum;
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
{
//
// 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
}
/// <summary> /// <summary>
/// Collection of shared states objects for a single scope /// Collection of shared states objects for a single scope
@ -908,10 +611,5 @@ namespace Avalonia.Controls
private GridLength _userSize; // shared state private GridLength _userSize; // shared state
private double _minSize; // shared state private double _minSize; // shared state
} }
#endregion Properties
} }
} }

209
src/Avalonia.Controls/GridWPF.cs

@ -186,6 +186,7 @@ namespace Avalonia.Controls
get get
{ {
if (_columnDefinitions == null) if (_columnDefinitions == null)
{ {
ColumnDefinitions = new ColumnDefinitions(); ColumnDefinitions = new ColumnDefinitions();
@ -207,9 +208,13 @@ namespace Avalonia.Controls
_columnDefinitions = value; _columnDefinitions = value;
_columnDefinitions.TrackItemPropertyChanged(_ => InvalidateMeasure()); _columnDefinitions.TrackItemPropertyChanged(_ => InvalidateMeasure());
_columnDefinitions.CollectionChanged += (_, __) => ColumnDefinitionsDirty = true;
DefinitionsU = _columnDefinitions.Cast<DefinitionBase>().ToArray();
_columnDefinitions.CollectionChanged += (_, e) =>
{ {
_data.DefinitionsU = _columnDefinitions.Select(p => (DefinitionBase)p).ToArray(); DefinitionsU = e.NewItems.Cast<DefinitionBase>().ToArray();
ColumnDefinitionsDirty = true;
InvalidateMeasure(); InvalidateMeasure();
}; };
@ -242,16 +247,21 @@ namespace Avalonia.Controls
_rowDefinitions = value; _rowDefinitions = value;
_rowDefinitions.TrackItemPropertyChanged(_ => InvalidateMeasure()); _rowDefinitions.TrackItemPropertyChanged(_ => InvalidateMeasure());
_rowDefinitions.CollectionChanged += (_, __) => RowDefinitionsDirty = true;
DefinitionsV = _rowDefinitions.Cast<DefinitionBase>().ToArray();
_rowDefinitions.CollectionChanged += (_, e) =>
{ {
_data.DefinitionsV = _rowDefinitions.Select(p => (DefinitionBase)p).ToArray(); DefinitionsV = e.NewItems.Cast<DefinitionBase>().ToArray();
RowDefinitionsDirty = true;
InvalidateMeasure(); InvalidateMeasure();
}; };
} }
} }
private bool rowColDefsEmpty => (RowDefinitions == null || RowDefinitions?.Count == 0) && private bool rowColDefsEmpty => (DefinitionsU.Length == 0) &&
(ColumnDefinitions == null || ColumnDefinitions?.Count == 0); (DefinitionsV.Length == 0);
/// <summary> /// <summary>
/// Content measurement. /// Content measurement.
@ -309,10 +319,10 @@ namespace Avalonia.Controls
} }
} }
ValidateDefinitionsUStructure(); // ValidateColumnDefinitionsStructure();
ValidateDefinitionsLayout(DefinitionsU, sizeToContentU); ValidateDefinitionsLayout(DefinitionsU, sizeToContentU);
ValidateDefinitionsVStructure(); // ValidateRowDefinitionsStructure();
ValidateDefinitionsLayout(DefinitionsV, sizeToContentV); ValidateDefinitionsLayout(DefinitionsV, sizeToContentV);
CellsStructureDirty |= (SizeToContentU != sizeToContentU) || (SizeToContentV != sizeToContentV); CellsStructureDirty |= (SizeToContentU != sizeToContentU) || (SizeToContentV != sizeToContentV);
@ -453,12 +463,12 @@ namespace Avalonia.Controls
cell.Arrange(cellRect); cell.Arrange(cellRect);
} }
// update render bound on grid lines renderer visual // // update render bound on grid lines renderer visual
var gridLinesRenderer = EnsureGridLinesRenderer(); // var gridLinesRenderer = EnsureGridLinesRenderer();
if (gridLinesRenderer != null) // if (gridLinesRenderer != null)
{ // {
gridLinesRenderer.UpdateRenderBounds(arrangeSize); // gridLinesRenderer.UpdateRenderBounds(arrangeSize);
} // }
} }
} }
finally finally
@ -493,7 +503,7 @@ namespace Avalonia.Controls
// actual value calculations require structure to be up-to-date // actual value calculations require structure to be up-to-date
if (!ColumnDefinitionsDirty) if (!ColumnDefinitionsDirty)
{ {
DefinitionBase[] definitions = DefinitionsU; var definitions = DefinitionsU;
value = definitions[(columnIndex + 1) % definitions.Length].FinalOffset; value = definitions[(columnIndex + 1) % definitions.Length].FinalOffset;
if (columnIndex != 0) { value -= definitions[columnIndex].FinalOffset; } if (columnIndex != 0) { value -= definitions[columnIndex].FinalOffset; }
} }
@ -515,7 +525,7 @@ namespace Avalonia.Controls
// actual value calculations require structure to be up-to-date // actual value calculations require structure to be up-to-date
if (!RowDefinitionsDirty) if (!RowDefinitionsDirty)
{ {
DefinitionBase[] definitions = DefinitionsV; var definitions = DefinitionsV;
value = definitions[(rowIndex + 1) % definitions.Length].FinalOffset; value = definitions[(rowIndex + 1) % definitions.Length].FinalOffset;
if (rowIndex != 0) { value -= definitions[rowIndex].FinalOffset; } if (rowIndex != 0) { value -= definitions[rowIndex].FinalOffset; }
} }
@ -525,38 +535,20 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// Convenience accessor to MeasureOverrideInProgress bit flag. /// Convenience accessor to MeasureOverrideInProgress bit flag.
/// </summary> /// </summary>
internal bool MeasureOverrideInProgress internal bool MeasureOverrideInProgress { get; set; }
{
get { return (CheckFlagsAnd(Flags.MeasureOverrideInProgress)); }
set { SetFlags(value, Flags.MeasureOverrideInProgress); }
}
/// <summary> /// <summary>
/// Convenience accessor to ArrangeOverrideInProgress bit flag. /// Convenience accessor to ArrangeOverrideInProgress bit flag.
/// </summary> /// </summary>
internal bool ArrangeOverrideInProgress internal bool ArrangeOverrideInProgress { get; set; }
{
get { return (CheckFlagsAnd(Flags.ArrangeOverrideInProgress)); }
set { SetFlags(value, Flags.ArrangeOverrideInProgress); }
}
/// <summary> /// <summary>
/// Convenience accessor to ValidDefinitionsUStructure bit flag. /// Convenience accessor to ValidColumnDefinitionsStructure bit flag.
/// </summary> /// </summary>
internal bool ColumnDefinitionsDirty internal bool ColumnDefinitionsDirty { get; set; }
{
get { return (!CheckFlagsAnd(Flags.ValidDefinitionsUStructure)); }
set { SetFlags(!value, Flags.ValidDefinitionsUStructure); }
}
/// <summary> /// <summary>
/// Convenience accessor to ValidDefinitionsVStructure bit flag. /// Convenience accessor to ValidRowDefinitionsStructure bit flag.
/// </summary> /// </summary>
internal bool RowDefinitionsDirty internal bool RowDefinitionsDirty { get; set; }
{
get { return (!CheckFlagsAnd(Flags.ValidDefinitionsVStructure)); }
set { SetFlags(!value, Flags.ValidDefinitionsVStructure); }
}
/// <summary> /// <summary>
/// Lays out cells according to rows and columns, and creates lookup grids. /// Lays out cells according to rows and columns, and creates lookup grids.
@ -674,92 +666,6 @@ namespace Avalonia.Controls
HasGroup3CellsInAutoRows = hasGroup3CellsInAutoRows; HasGroup3CellsInAutoRows = hasGroup3CellsInAutoRows;
} }
/// <summary>
/// Initializes DefinitionsU memeber either to user supplied ColumnDefinitions collection
/// or to a default single element collection. DefinitionsU gets trimmed to size.
/// </summary>
/// <remarks>
/// This is one of two methods, where ColumnDefinitions and DefinitionsU are directly accessed.
/// All the rest measure / arrange / render code must use DefinitionsU.
/// </remarks>
private void ValidateDefinitionsUStructure()
{
if (ColumnDefinitionsDirty)
{
ExtendedData extData = ExtData;
if (extData.ColumnDefinitions == null)
{
if (extData.DefinitionsU == null)
{
extData.DefinitionsU = new DefinitionBase[] { new ColumnDefinition() };
}
}
else
{
// extData.ColumnDefinitions.InternalTrimToSize();
if (extData.ColumnDefinitions.Count == 0)
{
// if column definitions collection is empty
// mockup array with one column
extData.DefinitionsU = new DefinitionBase[] { new ColumnDefinition() };
}
else
{
extData.DefinitionsU = extData.ColumnDefinitions.ToArray();
}
}
ColumnDefinitionsDirty = false;
}
Debug.Assert(ExtData.DefinitionsU != null && ExtData.DefinitionsU.Length > 0);
}
/// <summary>
/// Initializes DefinitionsV memeber either to user supplied RowDefinitions collection
/// or to a default single element collection. DefinitionsV gets trimmed to size.
/// </summary>
/// <remarks>
/// This is one of two methods, where RowDefinitions and DefinitionsV are directly accessed.
/// All the rest measure / arrange / render code must use DefinitionsV.
/// </remarks>
private void ValidateDefinitionsVStructure()
{
if (RowDefinitionsDirty)
{
ExtendedData extData = ExtData;
if (extData.RowDefinitions == null)
{
if (extData.DefinitionsV == null)
{
extData.DefinitionsV = new DefinitionBase[] { new RowDefinition() };
}
}
else
{
// extData.RowDefinitions.InternalTrimToSize();
if (extData.RowDefinitions.Count == 0)
{
// if row definitions collection is empty
// mockup array with one row
extData.DefinitionsV = new DefinitionBase[] { new RowDefinition() };
}
else
{
extData.DefinitionsV = extData.RowDefinitions.ToArray();
}
}
RowDefinitionsDirty = false;
}
Debug.Assert(ExtData.DefinitionsV != null && ExtData.DefinitionsV.Length > 0);
}
/// <summary> /// <summary>
/// Validates layout time size type information on given array of definitions. /// Validates layout time size type information on given array of definitions.
/// Sets MinSize and MeasureSizes. /// Sets MinSize and MeasureSizes.
@ -1607,7 +1513,7 @@ namespace Avalonia.Controls
/// <param name="definitions">Array of definitions to use for calculations.</param> /// <param name="definitions">Array of definitions to use for calculations.</param>
/// <returns>Desired size.</returns> /// <returns>Desired size.</returns>
private double CalculateDesiredSize( private double CalculateDesiredSize(
DefinitionBase[] definitions) DefinitionBase[] definitions)
{ {
double desiredSize = 0; double desiredSize = 0;
@ -1762,9 +1668,9 @@ namespace Avalonia.Controls
double remainingAvailableSize = finalSize - takenSize; double remainingAvailableSize = finalSize - takenSize;
double remainingStarWeight = totalStarWeight - takenStarWeight; double remainingStarWeight = totalStarWeight - takenStarWeight;
MinRatioIndexComparer minRatioIndexComparer = new MinRatioIndexComparer(definitions); MinRatioIndexComparer minRatioIndexComparer = new MinRatioIndexComparer((DefinitionBase[])definitions);
Array.Sort(definitionIndices, 0, minCount, minRatioIndexComparer); Array.Sort(definitionIndices, 0, minCount, minRatioIndexComparer);
MaxRatioIndexComparer maxRatioIndexComparer = new MaxRatioIndexComparer(definitions); MaxRatioIndexComparer maxRatioIndexComparer = new MaxRatioIndexComparer((DefinitionBase[])definitions);
Array.Sort(definitionIndices, defCount, maxCount, maxRatioIndexComparer); Array.Sort(definitionIndices, defCount, maxCount, maxRatioIndexComparer);
while (minCount + maxCount > 0 && remainingAvailableSize > 0.0) while (minCount + maxCount > 0 && remainingAvailableSize > 0.0)
@ -2147,7 +2053,7 @@ namespace Avalonia.Controls
/// <param name="count">Number of items in the range.</param> /// <param name="count">Number of items in the range.</param>
/// <returns>Final size.</returns> /// <returns>Final size.</returns>
private double GetFinalSizeForRange( private double GetFinalSizeForRange(
DefinitionBase[] definitions, DefinitionBase[] definitions,
int start, int start,
int count) int count)
{ {
@ -2338,22 +2244,6 @@ namespace Avalonia.Controls
return (result != 2); return (result != 2);
} }
/// <summary>
/// Private version returning array of column definitions.
/// </summary>
private DefinitionBase[] DefinitionsU
{
get { return (ExtData.DefinitionsU); }
}
/// <summary>
/// Private version returning array of row definitions.
/// </summary>
private DefinitionBase[] DefinitionsV
{
get { return (ExtData.DefinitionsV); }
}
/// <summary> /// <summary>
/// Helper accessor to layout time array of definitions. /// Helper accessor to layout time array of definitions.
/// </summary> /// </summary>
@ -2545,7 +2435,7 @@ namespace Avalonia.Controls
} }
} }
private ExtendedData _data; // extended data instantiated on demand, for non-trivial case handling only 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 Flags _flags; // grid validity / property caches dirtiness flags
private GridLinesRenderer _gridLinesRenderer; private GridLinesRenderer _gridLinesRenderer;
@ -2554,7 +2444,8 @@ namespace Avalonia.Controls
// Stores unrounded values and rounding errors during layout rounding. // Stores unrounded values and rounding errors during layout rounding.
double[] _roundingErrors; 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_epsilon = 1e-5; // used in fp calculations
private const double c_starClip = 1e298; // used as maximum for clipping star values during normalization 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 const int c_layoutLoopMaxCount = 5; // 5 is an arbitrary constant chosen to end the measure loop
@ -2572,17 +2463,13 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
private class ExtendedData private class ExtendedData
{ {
internal ColumnDefinitions ColumnDefinitions; // collection of column definitions (logical tree support)
internal RowDefinitions RowDefinitions; // collection of row definitions (logical tree support)
internal DefinitionBase[] DefinitionsU; // collection of column definitions used during calc
internal DefinitionBase[] DefinitionsV; // collection of row definitions used during calc
internal CellCache[] CellCachesCollection; // backing store for logical Children internal CellCache[] CellCachesCollection; // backing store for logical Children
internal int CellGroup1; // index of the first cell in first cell group 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 CellGroup2; // index of the first cell in second cell group
internal int CellGroup3; // index of the first cell in third 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 int CellGroup4; // index of the first cell in forth cell group
internal DefinitionBase[] TempDefinitions; // temporary array used during layout for various purposes internal DefinitionBase[] TempDefinitions; // temporary array used during layout for various purposes
// TempDefinitions.Length == Max(definitionsU.Length, definitionsV.Length) // TempDefinitions.Length == Max(DefinitionsU.Length, DefinitionsV.Length)
} }
/// <summary> /// <summary>
@ -2597,8 +2484,8 @@ namespace Avalonia.Controls
// * Valid???Layout flags indicate that layout time portion of the information // * Valid???Layout flags indicate that layout time portion of the information
// stored on the objects should be updated. // stored on the objects should be updated.
// //
ValidDefinitionsUStructure = 0x00000001, ValidColumnDefinitionsStructure = 0x00000001,
ValidDefinitionsVStructure = 0x00000002, ValidRowDefinitionsStructure = 0x00000002,
ValidCellsStructure = 0x00000004, ValidCellsStructure = 0x00000004,
// //
@ -3188,20 +3075,20 @@ namespace Avalonia.Controls
return; return;
} }
for (int i = 1; i < grid.DefinitionsU.Length; ++i) for (int i = 1; i < grid.ColumnDefinitions.Count; ++i)
{ {
DrawGridLine( DrawGridLine(
drawingContext, drawingContext,
grid.DefinitionsU[i].FinalOffset, 0.0, grid.ColumnDefinitions[i].FinalOffset, 0.0,
grid.DefinitionsU[i].FinalOffset, lastArrangeSize.Height); grid.ColumnDefinitions[i].FinalOffset, lastArrangeSize.Height);
} }
for (int i = 1; i < grid.DefinitionsV.Length; ++i) for (int i = 1; i < grid.RowDefinitions.Count; ++i)
{ {
DrawGridLine( DrawGridLine(
drawingContext, drawingContext,
0.0, grid.DefinitionsV[i].FinalOffset, 0.0, grid.RowDefinitions[i].FinalOffset,
lastArrangeSize.Width, grid.DefinitionsV[i].FinalOffset); lastArrangeSize.Width, grid.RowDefinitions[i].FinalOffset);
} }
} }

13
src/Avalonia.Controls/RowDefinition.cs

@ -29,7 +29,7 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="RowDefinition"/> class. /// Initializes a new instance of the <see cref="RowDefinition"/> class.
/// </summary> /// </summary>
public RowDefinition() : base(false) public RowDefinition()
{ {
} }
@ -38,7 +38,7 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
/// <param name="value">The height of the row.</param> /// <param name="value">The height of the row.</param>
/// <param name="type">The height unit of the column.</param> /// <param name="type">The height unit of the column.</param>
public RowDefinition(double value, GridUnitType type): base(false) public RowDefinition(double value, GridUnitType type)
{ {
Height = new GridLength(value, type); Height = new GridLength(value, type);
} }
@ -47,7 +47,7 @@ namespace Avalonia.Controls
/// Initializes a new instance of the <see cref="RowDefinition"/> class. /// Initializes a new instance of the <see cref="RowDefinition"/> class.
/// </summary> /// </summary>
/// <param name="height">The height of the column.</param> /// <param name="height">The height of the column.</param>
public RowDefinition(GridLength height): base(false) public RowDefinition(GridLength height)
{ {
Height = height; Height = height;
} }
@ -87,5 +87,12 @@ namespace Avalonia.Controls
get { return GetValue(HeightProperty); } get { return GetValue(HeightProperty); }
set { SetValue(HeightProperty, value); } set { SetValue(HeightProperty, value); }
} }
internal override GridLength UserSizeValueCache => this.Height;
internal override double UserMinSizeValueCache => this.MinHeight;
internal override double UserMaxSizeValueCache => this.MaxHeight;
} }
} }
Loading…
Cancel
Save