259 lines
8.0 KiB
C#

using System;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Globalization;
using System.ComponentModel.Design.Serialization;
namespace DevComponents.WinForms.Drawing
{
[StructLayout(LayoutKind.Sequential), TypeConverter(typeof(CornerRadiusConverter))]
public struct CornerRadius
#if FRAMEWORK20
: IEquatable<CornerRadius>
#endif
{
#region Private Variables
private int _TopLeft;
private int _topRight;
private int _bottomLeft;
private int _bottomRight;
#endregion
#region Constructor
public CornerRadius(int uniformRadius)
{
this._TopLeft = this._topRight = this._bottomLeft = this._bottomRight = uniformRadius;
}
public CornerRadius(int topLeft, int topRight, int bottomRight, int bottomLeft)
{
this._TopLeft = topLeft;
this._topRight = topRight;
this._bottomRight = bottomRight;
this._bottomLeft = bottomLeft;
}
#endregion
#region Internal Implementation
public override bool Equals(object obj)
{
if (obj is CornerRadius)
{
CornerRadius radius = (CornerRadius)obj;
return (this == radius);
}
return false;
}
public bool Equals(CornerRadius cornerRadius)
{
return (this == cornerRadius);
}
public override int GetHashCode()
{
return (((this._TopLeft.GetHashCode() ^ this._topRight.GetHashCode()) ^ this._bottomLeft.GetHashCode()) ^ this._bottomRight.GetHashCode());
}
public override string ToString()
{
return CornerRadiusConverter.ToString(this, CultureInfo.InvariantCulture);
}
public static bool operator ==(CornerRadius cr1, CornerRadius cr2)
{
return ((cr1._TopLeft == cr2._TopLeft) && (cr1._topRight == cr2._topRight) && (cr1._bottomRight == cr2._bottomRight) && (cr1._bottomLeft == cr2._bottomLeft));
}
public static bool operator !=(CornerRadius cr1, CornerRadius cr2)
{
return !(cr1 == cr2);
}
public int TopLeft
{
get
{
return this._TopLeft;
}
set
{
this._TopLeft = value;
}
}
public int TopRight
{
get
{
return this._topRight;
}
set
{
this._topRight = value;
}
}
public int BottomRight
{
get
{
return this._bottomRight;
}
set
{
this._bottomRight = value;
}
}
public int BottomLeft
{
get
{
return this._bottomLeft;
}
set
{
this._bottomLeft = value;
}
}
internal bool IsValid(bool allowNegative)
{
if (!allowNegative && (((this._TopLeft < 0.0) || (this._topRight < 0.0)) || ((this._bottomLeft < 0.0) || (this._bottomRight < 0.0))))
{
return false;
}
return true;
}
internal bool IsZero
{
get
{
return (_TopLeft == 0 && _topRight == 0 && _bottomRight == 0 && _bottomLeft == 0);
}
}
#endregion
}
#region CornerRadiusConverter
public class CornerRadiusConverter : TypeConverter
{
// Methods
public override bool CanConvertFrom(ITypeDescriptorContext typeDescriptorContext, Type sourceType)
{
switch (Type.GetTypeCode(sourceType))
{
case TypeCode.Int16:
case TypeCode.UInt16:
case TypeCode.Int32:
case TypeCode.UInt32:
case TypeCode.Int64:
case TypeCode.UInt64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
case TypeCode.String:
return true;
}
return false;
}
public override bool CanConvertTo(ITypeDescriptorContext typeDescriptorContext, Type destinationType)
{
if ((destinationType != typeof(InstanceDescriptor)) && (destinationType != typeof(string)))
{
return false;
}
return true;
}
public override object ConvertFrom(ITypeDescriptorContext typeDescriptorContext, CultureInfo cultureInfo, object source)
{
if (source == null)
{
throw base.GetConvertFromException(source);
}
if (source is string)
{
return FromString((string)source, cultureInfo);
}
return new CornerRadius(Convert.ToInt32(source, cultureInfo));
}
public override object ConvertTo(ITypeDescriptorContext typeDescriptorContext, CultureInfo cultureInfo, object value, Type destinationType)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
if (destinationType == null)
{
throw new ArgumentNullException("destinationType");
}
if (!(value is CornerRadius))
{
throw new ArgumentException("Unexpected parameter type", "value");
}
CornerRadius cr = (CornerRadius)value;
if (destinationType == typeof(string))
{
return ToString(cr, cultureInfo);
}
if (destinationType != typeof(InstanceDescriptor))
{
throw new ArgumentException("Cannot convert to type " + destinationType.FullName);
}
return new InstanceDescriptor(typeof(CornerRadius).GetConstructor(new Type[] { typeof(int), typeof(int), typeof(int), typeof(int) }), new object[] { cr.TopLeft, cr.TopRight, cr.BottomRight, cr.BottomLeft });
}
internal static CornerRadius FromString(string s, CultureInfo cultureInfo)
{
string[] parsed = s.Split(GetNumericListSeparator(cultureInfo));
int[] numArray = new int[4];
for (int i = 0; i < parsed.Length; i++)
{
numArray[i] = int.Parse(parsed[i], cultureInfo);
}
int index = Math.Min(5, parsed.Length);
switch (index)
{
case 1:
return new CornerRadius(numArray[0]);
case 4:
return new CornerRadius(numArray[0], numArray[1], numArray[2], numArray[3]);
}
throw new FormatException("Invalid string corner radius");
}
internal static string ToString(CornerRadius cr, CultureInfo cultureInfo)
{
char numericListSeparator = GetNumericListSeparator(cultureInfo);
StringBuilder builder = new StringBuilder(0x40);
builder.Append(cr.TopLeft.ToString(cultureInfo));
builder.Append(numericListSeparator);
builder.Append(cr.TopRight.ToString(cultureInfo));
builder.Append(numericListSeparator);
builder.Append(cr.BottomRight.ToString(cultureInfo));
builder.Append(numericListSeparator);
builder.Append(cr.BottomLeft.ToString(cultureInfo));
return builder.ToString();
}
internal static char GetNumericListSeparator(IFormatProvider provider)
{
char ch = ',';
NumberFormatInfo instance = NumberFormatInfo.GetInstance(provider);
if ((instance.NumberDecimalSeparator.Length > 0) && (ch == instance.NumberDecimalSeparator[0]))
{
ch = ';';
}
return ch;
}
}
#endregion
}