diff --git a/src/AtomUI.Controls.DataGrid/DataGridLength.cs b/src/AtomUI.Controls.DataGrid/DataGridLength.cs index 81c514509..572025111 100644 --- a/src/AtomUI.Controls.DataGrid/DataGridLength.cs +++ b/src/AtomUI.Controls.DataGrid/DataGridLength.cs @@ -1,3 +1,7 @@ +using System.ComponentModel; +using System.Globalization; +using Avalonia.Utilities; + namespace AtomUI.Controls; public enum DataGridLengthUnitType @@ -9,7 +13,268 @@ public enum DataGridLengthUnitType Star = 4 } -public class DataGridLength +/// +/// Represents the lengths of elements within the control. +/// +[TypeConverter(typeof(DataGridError.DataGridLengthConverter))] +public struct DataGridLength : IEquatable { - + private double _desiredValue; // desired value storage + private double _displayValue; // display value storage + private double _unitValue; // unit value storage + private DataGridLengthUnitType _unitType; // unit type storage + + // static instances of value invariant DataGridLengths + private static readonly DataGridLength _auto = + new DataGridLength(DATAGRIDLENGTH_DefaultValue, DataGridLengthUnitType.Auto); + + private static readonly DataGridLength _sizeToCells = + new DataGridLength(DATAGRIDLENGTH_DefaultValue, DataGridLengthUnitType.SizeToCells); + + private static readonly DataGridLength _sizeToHeader = + new DataGridLength(DATAGRIDLENGTH_DefaultValue, DataGridLengthUnitType.SizeToHeader); + + // WPF uses 1.0 as the default value as well + internal const double DATAGRIDLENGTH_DefaultValue = 1.0; + + /// + /// Initializes a new instance of the class. + /// + /// + public DataGridLength(double value) + : this(value, DataGridLengthUnitType.Pixel) + { + } + + /// + /// Initializes to a specified value and unit. + /// + /// The value to hold. + /// The unit of value. + /// + /// value is ignored unless type is + /// DataGridLengthUnitType.Pixel or + /// DataGridLengthUnitType.Star + /// + /// + /// If value parameter is double.NaN + /// or value parameter is double.NegativeInfinity + /// or value parameter is double.PositiveInfinity. + /// + public DataGridLength(double value, DataGridLengthUnitType type) + : this(value, type, (type == DataGridLengthUnitType.Pixel ? value : Double.NaN), + (type == DataGridLengthUnitType.Pixel ? value : Double.NaN)) + { + } + + /// + /// Initializes to a specified value and unit. + /// + /// The value to hold. + /// The unit of value. + /// + /// + /// + /// value is ignored unless type is + /// DataGridLengthUnitType.Pixel or + /// DataGridLengthUnitType.Star + /// + /// + /// If value parameter is double.NaN + /// or value parameter is double.NegativeInfinity + /// or value parameter is double.PositiveInfinity. + /// + public DataGridLength(double value, DataGridLengthUnitType type, double desiredValue, double displayValue) + { + if (double.IsNaN(value)) + { + throw DataGridError.DataGrid.ValueCannotBeSetToNAN("value"); + } + + if (double.IsInfinity(value)) + { + throw DataGridError.DataGrid.ValueCannotBeSetToInfinity("value"); + } + + if (double.IsInfinity(desiredValue)) + { + throw DataGridError.DataGrid.ValueCannotBeSetToInfinity("desiredValue"); + } + + if (double.IsInfinity(displayValue)) + { + throw DataGridError.DataGrid.ValueCannotBeSetToInfinity("displayValue"); + } + + if (value < 0) + { + throw DataGridError.DataGrid.ValueMustBeGreaterThanOrEqualTo("value", "value", 0); + } + + if (desiredValue < 0) + { + throw DataGridError.DataGrid.ValueMustBeGreaterThanOrEqualTo("desiredValue", "desiredValue", 0); + } + + if (displayValue < 0) + { + throw DataGridError.DataGrid.ValueMustBeGreaterThanOrEqualTo("displayValue", "displayValue", 0); + } + + if (type != DataGridLengthUnitType.Auto && + type != DataGridLengthUnitType.SizeToCells && + type != DataGridLengthUnitType.SizeToHeader && + type != DataGridLengthUnitType.Star && + type != DataGridLengthUnitType.Pixel) + { + throw DataGridError.DataGridLength.InvalidUnitType("type"); + } + + _desiredValue = desiredValue; + _displayValue = displayValue; + _unitValue = (type == DataGridLengthUnitType.Auto) ? DATAGRIDLENGTH_DefaultValue : value; + _unitType = type; + } + + /// + /// Gets a structure that represents the standard automatic sizing mode. + /// + /// + /// A structure that represents the standard automatic sizing mode. + /// + public static DataGridLength Auto => _auto; + + /// + /// Returns the desired value of this instance. + /// + public double DesiredValue => _desiredValue; + + /// + /// Returns the display value of this instance. + /// + public double DisplayValue => _displayValue; + + /// + /// Returns true if this DataGridLength instance holds + /// an absolute (pixel) value. + /// + public bool IsAbsolute => _unitType == DataGridLengthUnitType.Pixel; + + /// + /// Returns true if this DataGridLength instance is + /// automatic (not specified). + /// + public bool IsAuto => _unitType == DataGridLengthUnitType.Auto; + + /// + /// Returns true if this instance is to size to the cells of a column or row. + /// + public bool IsSizeToCells => _unitType == DataGridLengthUnitType.SizeToCells; + + /// + /// Returns true if this instance is to size to the header of a column or row. + /// + public bool IsSizeToHeader => _unitType == DataGridLengthUnitType.SizeToHeader; + + /// + /// Returns true if this DataGridLength instance holds a weighted proportion + /// of available space. + /// + public bool IsStar => _unitType == DataGridLengthUnitType.Star; + + /// + /// Gets a structure that represents the cell-based automatic sizing mode. + /// + /// + /// A structure that represents the cell-based automatic sizing mode. + /// + public static DataGridLength SizeToCells => _sizeToCells; + + /// + /// Gets a structure that represents the header-based automatic sizing mode. + /// + /// + /// A structure that represents the header-based automatic sizing mode. + /// + public static DataGridLength SizeToHeader => _sizeToHeader; + + /// + /// Gets the that represents the current sizing mode. + /// + public DataGridLengthUnitType UnitType => _unitType; + + /// + /// Gets the absolute value of the in pixels. + /// + /// + /// The absolute value of the in pixels. + /// + public double Value => _unitValue; + + /// + /// Overloaded operator, compares 2 DataGridLength's. + /// + /// first DataGridLength to compare. + /// second DataGridLength to compare. + /// true if specified DataGridLength have same value, + /// unit type, desired value, and display value. + public static bool operator ==(DataGridLength gl1, DataGridLength gl2) + { + return (gl1.UnitType == gl2.UnitType + && gl1.Value == gl2.Value + && gl1.DesiredValue == gl2.DesiredValue + && gl1.DisplayValue == gl2.DisplayValue); + } + + /// + /// Overloaded operator, compares 2 DataGridLength's. + /// + /// first DataGridLength to compare. + /// second DataGridLength to compare. + /// true if specified DataGridLength have either different value, + /// unit type, desired value, or display value. + public static bool operator !=(DataGridLength gl1, DataGridLength gl2) + { + return (gl1.UnitType != gl2.UnitType + || gl1.Value != gl2.Value + || gl1.DesiredValue != gl2.DesiredValue + || gl1.DisplayValue != gl2.DisplayValue); + } + + /// + /// Compares this instance of DataGridLength with another instance. + /// + /// DataGridLength length instance to compare. + /// true if this DataGridLength instance has the same value + /// and unit type as gridLength. + public bool Equals(DataGridLength other) + { + return (this == other); + } + + /// + /// Compares this instance of DataGridLength with another object. + /// + /// Reference to an object for comparison. + /// true if this DataGridLength instance has the same value + /// and unit type as oCompare. + public override bool Equals(object? obj) + { + DataGridLength? dataGridLength = obj as DataGridLength?; + if (dataGridLength.HasValue) + { + return (this == dataGridLength); + } + + return false; + } + + /// + /// Returns a unique hash code for this DataGridLength + /// + /// hash code + public override int GetHashCode() + { + return ((int)_unitValue + (int)_unitType) + (int)_desiredValue + (int)_displayValue; + } } \ No newline at end of file