// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Avalonia.Utilities;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
namespace Avalonia.Controls
{
///
/// Defines the valid units for a .
///
public enum GridUnitType
{
///
/// The row or column is auto-sized to fit its content.
///
Auto = 0,
///
/// The row or column is sized in device independent pixels.
///
Pixel = 1,
///
/// The row or column is sized as a weighted proportion of available space.
///
Star = 2,
}
///
/// Holds the width or height of a 's column and row definitions.
///
public struct GridLength : IEquatable
{
private readonly GridUnitType _type;
private readonly double _value;
///
/// Initializes a new instance of the struct.
///
/// The size of the GridLength in device independent pixels.
public GridLength(double value)
: this(value, GridUnitType.Pixel)
{
}
///
/// Initializes a new instance of the struct.
///
/// The size of the GridLength.
/// The unit of the GridLength.
public GridLength(double value, GridUnitType type)
{
if (value < 0 || double.IsNaN(value) || double.IsInfinity(value))
{
throw new ArgumentException("Invalid value", "value");
}
if (type < GridUnitType.Auto || type > GridUnitType.Star)
{
throw new ArgumentException("Invalid value", "type");
}
_type = type;
_value = value;
}
///
/// Gets an instance of that indicates that a row or column should
/// auto-size to fit its content.
///
public static GridLength Auto => new GridLength(0, GridUnitType.Auto);
///
/// Gets the unit of the .
///
public GridUnitType GridUnitType => _type;
///
/// Gets a value that indicates whether the has a of Pixel.
///
public bool IsAbsolute => _type == GridUnitType.Pixel;
///
/// Gets a value that indicates whether the has a of Auto.
///
public bool IsAuto => _type == GridUnitType.Auto;
///
/// Gets a value that indicates whether the has a of Star.
///
public bool IsStar => _type == GridUnitType.Star;
///
/// Gets the length.
///
public double Value => _value;
///
/// Compares two GridLength structures for equality.
///
/// The first GridLength.
/// The second GridLength.
/// True if the structures are equal, otherwise false.
public static bool operator ==(GridLength a, GridLength b)
{
return (a.IsAuto && b.IsAuto) || (a._value == b._value && a._type == b._type);
}
///
/// Compares two GridLength structures for inequality.
///
/// The first GridLength.
/// The first GridLength.
/// True if the structures are unequal, otherwise false.
public static bool operator !=(GridLength gl1, GridLength gl2)
{
return !(gl1 == gl2);
}
///
/// Determines whether the is equal to the specified object.
///
/// The object with which to test equality.
/// True if the objects are equal, otherwise false.
public override bool Equals(object o)
{
if (o == null)
{
return false;
}
if (!(o is GridLength))
{
return false;
}
return this == (GridLength)o;
}
///
/// Compares two GridLength structures for equality.
///
/// The structure with which to test equality.
/// True if the structures are equal, otherwise false.
public bool Equals(GridLength gridLength)
{
return this == gridLength;
}
///
/// Gets a hash code for the GridLength.
///
/// The hash code.
public override int GetHashCode()
{
return _value.GetHashCode() ^ _type.GetHashCode();
}
///
/// Gets a string representation of the .
///
/// The string representation.
public override string ToString()
{
if (IsAuto)
{
return "Auto";
}
string s = _value.ToString();
return IsStar ? s + "*" : s;
}
///
/// Parses a string to return a .
///
/// The string.
/// The .
public static GridLength Parse(string s)
{
s = s.ToUpperInvariant();
if (s == "AUTO")
{
return Auto;
}
else if (s.EndsWith("*"))
{
var valueString = s.Substring(0, s.Length - 1).Trim();
var value = valueString.Length > 0 ? double.Parse(valueString, CultureInfo.InvariantCulture) : 1;
return new GridLength(value, GridUnitType.Star);
}
else
{
var value = double.Parse(s, CultureInfo.InvariantCulture);
return new GridLength(value, GridUnitType.Pixel);
}
}
///
/// Parses a string to return a collection of s.
///
/// The string.
/// The .
public static IEnumerable ParseLengths(string s)
{
using (var tokenizer = new StringTokenizer(s, CultureInfo.InvariantCulture))
{
while (tokenizer.TryReadString(out var item))
{
yield return Parse(item);
}
}
}
}
}