154 lines
5.1 KiB
C#
154 lines
5.1 KiB
C#
using System;
|
|
using System.ComponentModel;
|
|
using System.Drawing;
|
|
using System.Drawing.Design;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
|
|
namespace JD.Winforms.XmlGrid
|
|
{
|
|
[TypeConverter(typeof(AngleVarConverter))]
|
|
class AngleVar
|
|
{
|
|
private float angle;
|
|
|
|
public float Angle
|
|
{
|
|
get { return angle; }
|
|
set { angle = value; }
|
|
}
|
|
|
|
public float GetNormalized()
|
|
{
|
|
float ret = angle;
|
|
|
|
while (ret < -360.0f)
|
|
{
|
|
ret += 360.0f;
|
|
}
|
|
while (ret > 360.0f)
|
|
{
|
|
ret -= 360.0f;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return angle.ToString();
|
|
}
|
|
|
|
public static AngleVar Parse(string text)
|
|
{
|
|
AngleVar newAngle = new AngleVar();
|
|
CultureInfo ci = new CultureInfo(CultureInfo.CurrentCulture.Name, false);
|
|
NumberFormatInfo formatInfo = ci.NumberFormat;
|
|
formatInfo.NumberDecimalSeparator = ".";
|
|
formatInfo.NumberGroupSeparator = ",";
|
|
|
|
newAngle.Angle = float.Parse(text,formatInfo);
|
|
return newAngle;
|
|
}
|
|
}
|
|
|
|
public class AngleVarConverter : ExpandableObjectConverter
|
|
{
|
|
public override bool CanConvertTo(ITypeDescriptorContext context,
|
|
System.Type destinationType)
|
|
{
|
|
if (destinationType == typeof(string))
|
|
return true;
|
|
|
|
return base.CanConvertTo(context, destinationType);
|
|
}
|
|
|
|
public override object ConvertTo(ITypeDescriptorContext context,
|
|
CultureInfo culture,
|
|
object value,
|
|
System.Type destinationType)
|
|
{
|
|
if (destinationType == typeof(System.String) && value is AngleVar)
|
|
{
|
|
|
|
AngleVar so = (AngleVar)value;
|
|
return so.ToString();
|
|
}
|
|
|
|
return base.ConvertTo(context, culture, value, destinationType);
|
|
}
|
|
|
|
public override bool CanConvertFrom(ITypeDescriptorContext context,
|
|
System.Type sourceType)
|
|
{
|
|
if (sourceType == typeof(string))
|
|
return true;
|
|
|
|
return base.CanConvertFrom(context, sourceType);
|
|
}
|
|
|
|
public override object ConvertFrom(ITypeDescriptorContext context,
|
|
CultureInfo culture, object value)
|
|
{
|
|
if (value is string)
|
|
{
|
|
string val = (string)value;
|
|
AngleVar ret = new AngleVar();
|
|
|
|
if (val != null)
|
|
{
|
|
ret = AngleVar.Parse(val);
|
|
}
|
|
else
|
|
{
|
|
ret.Angle = 0.0f;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
return base.ConvertFrom(context, culture, value);
|
|
}
|
|
}
|
|
|
|
// This UITypeEditor can be associated with Int32, Double and Single
|
|
// properties to provide a design-mode angle selection interface.
|
|
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
|
|
public class AngleEditor : System.Drawing.Design.UITypeEditor
|
|
{
|
|
public AngleEditor()
|
|
{
|
|
}
|
|
|
|
// Indicates whether the UITypeEditor provides a form-based (modal) dialog,
|
|
// drop down dialog, or no UI outside of the properties window.
|
|
public override System.Drawing.Design.UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
|
|
{
|
|
return UITypeEditorEditStyle.None;
|
|
}
|
|
|
|
// Draws a representation of the property's value.
|
|
public override void PaintValue(System.Drawing.Design.PaintValueEventArgs e)
|
|
{
|
|
int normalX = (e.Bounds.Width/2);
|
|
int normalY = (e.Bounds.Height/2);
|
|
|
|
// Fill background and ellipse and center point.
|
|
e.Graphics.FillRectangle(new SolidBrush(Color.DarkBlue), e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height);
|
|
e.Graphics.FillEllipse(new SolidBrush(Color.White), e.Bounds.X+1, e.Bounds.Y+1, e.Bounds.Width-3, e.Bounds.Height-3);
|
|
e.Graphics.FillEllipse(new SolidBrush(Color.SlateGray), normalX+e.Bounds.X-1, normalY+e.Bounds.Y-1, 3, 3);
|
|
|
|
// Draw line along the current angle.
|
|
double radians = ((double)((AngleVar)e.Value).GetNormalized() * Math.PI) / (double)180;
|
|
e.Graphics.DrawLine( new Pen(new SolidBrush(Color.Red), 1), normalX+e.Bounds.X, normalY+e.Bounds.Y,
|
|
e.Bounds.X+ ( normalX + (int)( (double)normalX * Math.Cos( radians ) ) ),
|
|
e.Bounds.Y+ ( normalY - (int)( (double)normalY * Math.Sin( radians ) ) ) );
|
|
}
|
|
|
|
// Indicates whether the UITypeEditor supports painting a
|
|
// representation of a property's value.
|
|
public override bool GetPaintValueSupported(System.ComponentModel.ITypeDescriptorContext context)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|