767 lines
21 KiB
C#
767 lines
21 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.ComponentModel;
|
|
using System.Drawing.Design;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Globalization;
|
|
using DevComponents.Instrumentation.Primitives;
|
|
|
|
namespace DevComponents.DotNetBar.SuperGrid.Style
|
|
{
|
|
/// <summary>
|
|
/// Represents background of visual style.
|
|
/// </summary>
|
|
[TypeConverter(typeof(BackgroundConvertor))]
|
|
[Editor(typeof(BackgroundEditor), typeof(UITypeEditor))]
|
|
public class Background : INotifyPropertyChanged, IDisposable
|
|
{
|
|
#region Static data
|
|
|
|
///<summary>
|
|
/// Empty
|
|
///</summary>
|
|
/// <summary>
|
|
/// Returns Empty instance of BorderPattern.
|
|
/// </summary>
|
|
public static Background Empty
|
|
{
|
|
get { return (new Background()); }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Private variables
|
|
|
|
private Color _Color1 = Color.Empty;
|
|
private Color _Color2 = Color.Empty;
|
|
|
|
private int _GradientAngle = 90;
|
|
|
|
private BackFillType _BackFillType = BackFillType.Angle;
|
|
private BackColorBlend _BackColorBlend;
|
|
|
|
#endregion
|
|
|
|
#region Constructors
|
|
|
|
/// <summary>
|
|
/// Creates new instance of the object.
|
|
/// </summary>
|
|
public Background() { }
|
|
|
|
/// <summary>
|
|
/// Creates new instance of the object.
|
|
/// </summary>
|
|
/// <param name="color1">Start color.</param>
|
|
public Background(Color color1)
|
|
{
|
|
_Color1 = color1;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates new instance of the object.
|
|
/// </summary>
|
|
/// <param name="color1">Start color.</param>
|
|
/// <param name="color2">End color.</param>
|
|
public Background(Color color1, Color color2)
|
|
{
|
|
_Color1 = color1;
|
|
_Color2 = color2;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates new instance of the object.
|
|
/// </summary>
|
|
/// <param name="color1">Start color in hexadecimal representation like FFFFFF.</param>
|
|
/// <param name="color2">End color in hexadecimal representation like FFFFFF.</param>
|
|
public Background(string color1, string color2)
|
|
{
|
|
_Color1 = ColorFactory.GetColor(color1);
|
|
_Color2 = ColorFactory.GetColor(color2);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates new instance of the object.
|
|
/// </summary>
|
|
/// <param name="color1">Start color in 32-bit RGB representation.</param>
|
|
/// <param name="color2">End color in 32-bit RGB representation.</param>
|
|
public Background(int color1, int color2)
|
|
{
|
|
_Color1 = ColorFactory.GetColor(color1);
|
|
_Color2 = ColorFactory.GetColor(color2);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates new instance of the object.
|
|
/// </summary>
|
|
/// <param name="color1">Start color in 32-bit RGB representation.</param>
|
|
/// <param name="color2">End color in 32-bit RGB representation.</param>
|
|
/// <param name="gradientAngle">Gradient angle.</param>
|
|
public Background(int color1, int color2, int gradientAngle)
|
|
{
|
|
_Color1 = ColorFactory.GetColor(color1);
|
|
_Color2 = ColorFactory.GetColor(color2);
|
|
|
|
GradientAngle = gradientAngle;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates new instance of the object.
|
|
/// </summary>
|
|
/// <param name="color1">Start color.</param>
|
|
/// <param name="color2">End color.</param>
|
|
/// <param name="gradientAngle">Gradient angle.</param>
|
|
public Background(Color color1, Color color2, int gradientAngle)
|
|
{
|
|
_Color1 = color1;
|
|
_Color2 = color2;
|
|
|
|
GradientAngle = gradientAngle;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates new instance of the object.
|
|
/// </summary>
|
|
/// <param name="color1">Start color.</param>
|
|
/// <param name="color2">End color.</param>
|
|
/// <param name="fillType">Gradient angle.</param>
|
|
public Background(Color color1, Color color2, BackFillType fillType)
|
|
{
|
|
_Color1 = color1;
|
|
_Color2 = color2;
|
|
|
|
_BackFillType = fillType;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Public properties
|
|
|
|
#region Color1
|
|
|
|
/// <summary>
|
|
/// Gets or sets the start color.
|
|
/// </summary>
|
|
[Description("Indicates the Starting Gradient Color.")]
|
|
public Color Color1
|
|
{
|
|
get { return (_Color1); }
|
|
|
|
set
|
|
{
|
|
if (_Color1 != value)
|
|
{
|
|
_Color1 = value;
|
|
|
|
OnPropertyChangedEx("Color1");
|
|
}
|
|
}
|
|
}
|
|
|
|
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
|
internal virtual bool ShouldSerializeColor1()
|
|
{
|
|
return (_Color1.IsEmpty == false);
|
|
}
|
|
|
|
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
|
internal virtual void ResetColor1()
|
|
{
|
|
_Color1 = Color.Empty;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Color2
|
|
|
|
/// <summary>
|
|
/// Gets or sets the Ending Gradient Color
|
|
/// </summary>
|
|
[Description("Indicates the Ending Gradient Color")]
|
|
public Color Color2
|
|
{
|
|
get { return (_Color2); }
|
|
|
|
set
|
|
{
|
|
if (_Color2 != value)
|
|
{
|
|
_Color2 = value;
|
|
|
|
OnPropertyChangedEx("Color2");
|
|
}
|
|
}
|
|
}
|
|
|
|
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
|
internal virtual bool ShouldSerializeColor2()
|
|
{
|
|
return (_Color2.IsEmpty == false);
|
|
}
|
|
|
|
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
|
internal virtual void ResetColor2()
|
|
{
|
|
_Color2 = Color.Empty;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region BackColorBlend
|
|
|
|
/// <summary>
|
|
/// Gets or sets the BackColorBlend.
|
|
/// </summary>
|
|
[Description("Indicates the BackColorBlend.")]
|
|
public BackColorBlend BackColorBlend
|
|
{
|
|
get
|
|
{
|
|
if (_BackColorBlend == null)
|
|
{
|
|
_BackColorBlend = new BackColorBlend();
|
|
|
|
UpgateChangeHandler(null, _BackColorBlend);
|
|
}
|
|
|
|
return (_BackColorBlend);
|
|
}
|
|
|
|
set
|
|
{
|
|
if (_BackColorBlend != value)
|
|
{
|
|
UpgateChangeHandler(_BackColorBlend, value);
|
|
|
|
_BackColorBlend = value;
|
|
|
|
OnPropertyChangedEx("BackColorBlend");
|
|
}
|
|
}
|
|
}
|
|
|
|
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
|
internal virtual bool ShouldSerializeBackColorBlend()
|
|
{
|
|
return (_BackColorBlend != null && _BackColorBlend.IsEmpty == false);
|
|
}
|
|
|
|
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
|
internal virtual void ResetBackColorBlend()
|
|
{
|
|
BackColorBlend = null;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region GradientAngle
|
|
|
|
/// <summary>
|
|
/// Gets or sets the gradient angle (default is 90)
|
|
/// </summary>
|
|
[DefaultValue(90)]
|
|
[Description("Indicates the Gradient Angle default is 90)")]
|
|
public int GradientAngle
|
|
{
|
|
get { return (_GradientAngle); }
|
|
|
|
set
|
|
{
|
|
if (_GradientAngle != value)
|
|
{
|
|
_GradientAngle = value;
|
|
|
|
OnPropertyChangedEx("GradientAngle");
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region BackFillType
|
|
|
|
/// <summary>
|
|
/// Gets or sets the Gradient BackFillType
|
|
/// </summary>
|
|
[DefaultValue(BackFillType.Angle)]
|
|
[Description("Indicates the Gradient BackFillType.")]
|
|
public BackFillType BackFillType
|
|
{
|
|
get { return (_BackFillType); }
|
|
|
|
set
|
|
{
|
|
if (_BackFillType != value)
|
|
{
|
|
_BackFillType = value;
|
|
|
|
OnPropertyChangedEx("BackFillType");
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IsEmpty
|
|
|
|
/// <summary>
|
|
/// Gets whether both colors assigned are empty.
|
|
/// </summary>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public bool IsEmpty
|
|
{
|
|
get
|
|
{
|
|
return (_Color1.IsEmpty && _Color2.IsEmpty &&
|
|
(_BackColorBlend == null || _BackColorBlend.IsEmpty));
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IsEqualTo
|
|
|
|
/// <summary>
|
|
/// Determines if the Background is equal to the given one
|
|
/// </summary>
|
|
/// <param name="background">Background to compare</param>
|
|
/// <returns>true if equal</returns>
|
|
[Browsable(false)]
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
public bool IsEqualTo(Background background)
|
|
{
|
|
return (_Color1 == background.Color1 &&
|
|
_Color2 == background.Color2 &&
|
|
_BackColorBlend.Equals(background._BackColorBlend) &&
|
|
_GradientAngle == background.GradientAngle &&
|
|
_BackFillType == background.BackFillType);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region GetBrush
|
|
|
|
///<summary>
|
|
/// GetBrush
|
|
///</summary>
|
|
///<param name="r"></param>
|
|
///<returns></returns>
|
|
public Brush GetBrush(Rectangle r)
|
|
{
|
|
if (_BackColorBlend != null && _BackColorBlend.IsEmpty == false)
|
|
{
|
|
if (_BackColorBlend.Colors.Length == 1)
|
|
return (new SolidBrush(_BackColorBlend.Colors[0]));
|
|
|
|
Brush br = GetLinearBrush(r);
|
|
|
|
if (br is LinearGradientBrush)
|
|
{
|
|
ColorBlend cb = GetColorBlend();
|
|
|
|
if (cb != null)
|
|
((LinearGradientBrush) br).InterpolationColors = cb;
|
|
}
|
|
|
|
return (br);
|
|
}
|
|
|
|
if (_Color2.IsEmpty == true)
|
|
return (new SolidBrush(_Color1));
|
|
|
|
return (GetLinearBrush(r));
|
|
}
|
|
|
|
#region GetLinearBrush
|
|
|
|
private Brush GetLinearBrush(Rectangle r)
|
|
{
|
|
LinearGradientBrush lbr = null;
|
|
|
|
if (r.Width > 0 && r.Height > 0)
|
|
{
|
|
switch (_BackFillType)
|
|
{
|
|
case BackFillType.Angle:
|
|
lbr = new LinearGradientBrush(r, _Color1, _Color2, _GradientAngle);
|
|
break;
|
|
|
|
case BackFillType.HorizontalCenter:
|
|
r.Width /= 2;
|
|
r.Width = Math.Max(1, r.Width);
|
|
|
|
lbr = new LinearGradientBrush(r, _Color1, _Color2, 0f);
|
|
break;
|
|
|
|
case BackFillType.VerticalCenter:
|
|
r.Height /= 2;
|
|
r.Height = Math.Max(1, r.Height);
|
|
|
|
lbr = new LinearGradientBrush(r, _Color1, _Color2, 90f);
|
|
break;
|
|
|
|
case BackFillType.ForwardDiagonal:
|
|
lbr = new LinearGradientBrush(r, _Color1, _Color2, LinearGradientMode.ForwardDiagonal);
|
|
break;
|
|
|
|
case BackFillType.BackwardDiagonal:
|
|
lbr = new LinearGradientBrush(r, _Color1, _Color2, LinearGradientMode.BackwardDiagonal);
|
|
break;
|
|
|
|
case BackFillType.ForwardDiagonalCenter:
|
|
r.Width /= 2;
|
|
r.Height /= 2;
|
|
lbr = new LinearGradientBrush(r, _Color1, _Color2, LinearGradientMode.ForwardDiagonal);
|
|
break;
|
|
|
|
case BackFillType.BackwardDiagonalCenter:
|
|
r.Width /= 2;
|
|
r.Height /= 2;
|
|
r.X += r.Width;
|
|
|
|
lbr = new LinearGradientBrush(r, _Color1, _Color2, LinearGradientMode.BackwardDiagonal);
|
|
break;
|
|
|
|
case BackFillType.Center:
|
|
using (GraphicsPath path = new GraphicsPath())
|
|
{
|
|
path.AddRectangle(r);
|
|
|
|
PathGradientBrush pbr = new PathGradientBrush(path);
|
|
|
|
pbr.CenterColor = _Color1;
|
|
pbr.SurroundColors = new Color[] {_Color2};
|
|
|
|
ColorBlend cb = GetColorBlend();
|
|
|
|
if (cb != null)
|
|
pbr.InterpolationColors = cb;
|
|
|
|
return (pbr);
|
|
}
|
|
|
|
case BackFillType.Radial:
|
|
int n = (int) Math.Sqrt(r.Width*r.Width + r.Height*r.Height) + 4;
|
|
|
|
using (GraphicsPath path = new GraphicsPath())
|
|
{
|
|
path.AddEllipse(r.X - (n - r.Width)/2, r.Y - (n - r.Height)/2, n, n);
|
|
|
|
PathGradientBrush pbr = new PathGradientBrush(path);
|
|
|
|
pbr.CenterColor = _Color1;
|
|
pbr.SurroundColors = new Color[] {_Color2};
|
|
|
|
ColorBlend cb = GetColorBlend();
|
|
|
|
if (cb != null)
|
|
pbr.InterpolationColors = cb;
|
|
|
|
return (pbr);
|
|
}
|
|
}
|
|
|
|
if (lbr != null)
|
|
lbr.WrapMode = WrapMode.TileFlipXY;
|
|
}
|
|
|
|
return (lbr);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region GetColorBlend
|
|
|
|
private ColorBlend GetColorBlend()
|
|
{
|
|
if (_BackColorBlend != null &&
|
|
_BackColorBlend.Colors != null && _BackColorBlend.Colors.Length > 0)
|
|
{
|
|
ColorBlend cb = new ColorBlend(_BackColorBlend.Colors.Length);
|
|
|
|
cb.Colors = _BackColorBlend.Colors;
|
|
cb.Positions = GetPositions();
|
|
|
|
return (cb);
|
|
}
|
|
|
|
return (null);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region GetPositions
|
|
|
|
private float[] GetPositions()
|
|
{
|
|
float[] cp = _BackColorBlend.Positions;
|
|
|
|
if (cp == null || cp.Length != _BackColorBlend.Colors.Length)
|
|
{
|
|
cp = new float[_BackColorBlend.Colors.Length];
|
|
|
|
float f = 1f / _BackColorBlend.Colors.Length;
|
|
|
|
for (int i = 0; i < cp.Length; i++)
|
|
cp[i] = i * f;
|
|
|
|
cp[_BackColorBlend.Colors.Length - 1] = 1;
|
|
}
|
|
|
|
return (cp);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region Copy
|
|
|
|
/// <summary>
|
|
/// Creates an exact copy of the background.
|
|
/// </summary>
|
|
/// <returns>Copy of the background.</returns>
|
|
public Background Copy()
|
|
{
|
|
Background copy = new Background();
|
|
|
|
copy.Color1 = _Color1;
|
|
copy.Color2 = _Color2;
|
|
|
|
copy.GradientAngle = _GradientAngle;
|
|
copy.BackFillType = _BackFillType;
|
|
|
|
if (_BackColorBlend != null)
|
|
copy.BackColorBlend = _BackColorBlend.Copy();
|
|
|
|
return (copy);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region INotifyPropertyChanged Members
|
|
|
|
/// <summary>
|
|
/// Occurs when property value has changed.
|
|
/// </summary>
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
|
|
|
/// <summary>
|
|
/// Raises the PropertyChanged event.
|
|
/// </summary>
|
|
/// <param name="e">Event arguments</param>
|
|
protected virtual void OnPropertyChanged(VisualPropertyChangedEventArgs e)
|
|
{
|
|
PropertyChangedEventHandler eh = PropertyChanged;
|
|
|
|
if (eh != null)
|
|
eh(this, e);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Raises the PropertyChanged event.
|
|
/// </summary>
|
|
/// <param name="s">Event arguments</param>
|
|
protected virtual void OnPropertyChangedEx(string s)
|
|
{
|
|
PropertyChangedEventHandler eh = PropertyChanged;
|
|
|
|
if (eh != null)
|
|
{
|
|
VisualPropertyChangedEventArgs e =
|
|
new VisualPropertyChangedEventArgs(s);
|
|
|
|
eh(this, e);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region UpgateChangeHandler
|
|
|
|
private void UpgateChangeHandler(
|
|
INotifyPropertyChanged oldValue, INotifyPropertyChanged newValue)
|
|
{
|
|
if (oldValue != null)
|
|
oldValue.PropertyChanged -= StyleChanged;
|
|
|
|
if (newValue != null)
|
|
newValue.PropertyChanged += StyleChanged;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region StyleChanged
|
|
|
|
/// <summary>
|
|
/// StyleChanged
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
protected virtual void StyleChanged(
|
|
object sender, PropertyChangedEventArgs e)
|
|
{
|
|
OnPropertyChanged((VisualPropertyChangedEventArgs)e);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IDisposable
|
|
|
|
/// <summary>
|
|
/// Dispose
|
|
/// </summary>
|
|
public void Dispose()
|
|
{
|
|
BackColorBlend = null;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
#region enums
|
|
|
|
///<summary>
|
|
/// BackFillType
|
|
///</summary>
|
|
public enum BackFillType
|
|
{
|
|
///<summary>
|
|
/// Angle
|
|
///</summary>
|
|
Angle,
|
|
|
|
///<summary>
|
|
/// Center
|
|
///</summary>
|
|
Center,
|
|
|
|
///<summary>
|
|
/// HorizontalCenter
|
|
///</summary>
|
|
HorizontalCenter,
|
|
|
|
///<summary>
|
|
/// VerticalCenter
|
|
///</summary>
|
|
VerticalCenter,
|
|
|
|
///<summary>
|
|
/// ForwardDiagonal
|
|
///</summary>
|
|
ForwardDiagonal,
|
|
|
|
///<summary>
|
|
/// BackwardDiagonal
|
|
///</summary>
|
|
BackwardDiagonal,
|
|
|
|
///<summary>
|
|
/// ForwardDiagonalCenter
|
|
///</summary>
|
|
ForwardDiagonalCenter,
|
|
|
|
///<summary>
|
|
/// BackwardDiagonalCenter
|
|
///</summary>
|
|
BackwardDiagonalCenter,
|
|
|
|
///<summary>
|
|
/// Radial
|
|
///</summary>
|
|
Radial,
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region BackgroundConvertor
|
|
|
|
///<summary>
|
|
/// BackgroundConvertor
|
|
///</summary>
|
|
public class BackgroundConvertor : ExpandableObjectConverter
|
|
{
|
|
/// <summary>
|
|
/// ConvertTo
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <param name="culture"></param>
|
|
/// <param name="value"></param>
|
|
/// <param name="destinationType"></param>
|
|
/// <returns></returns>
|
|
public override object ConvertTo(
|
|
ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
|
|
{
|
|
if (destinationType == typeof(string))
|
|
{
|
|
Background gc = value as Background;
|
|
|
|
if (gc != null)
|
|
{
|
|
if (gc.BackColorBlend != null && gc.BackColorBlend.IsEmpty == false)
|
|
return ("Blended");
|
|
|
|
ColorConverter cvt = new ColorConverter();
|
|
|
|
string s = gc.Color1.IsEmpty ? "(Empty)" : cvt.ConvertToString(gc.Color1);
|
|
|
|
if (gc.Color2 != Color.Empty)
|
|
s += ", " + cvt.ConvertToString(gc.Color2);
|
|
|
|
return (s);
|
|
}
|
|
}
|
|
|
|
return (base.ConvertTo(context, culture, value, destinationType));
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region BackgroundEditor
|
|
|
|
///<summary>
|
|
/// BackgroundEditor
|
|
///</summary>
|
|
public class BackgroundEditor : UITypeEditor
|
|
{
|
|
#region GetPaintValueSupported
|
|
|
|
/// <summary>
|
|
/// GetPaintValueSupported
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <returns></returns>
|
|
public override bool GetPaintValueSupported(ITypeDescriptorContext context)
|
|
{
|
|
return (true);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region PaintValue
|
|
|
|
/// <summary>
|
|
/// PaintValue
|
|
/// </summary>
|
|
/// <param name="e"></param>
|
|
public override void PaintValue(PaintValueEventArgs e)
|
|
{
|
|
Background b = e.Value as Background;
|
|
|
|
if (b != null)
|
|
{
|
|
using (Brush br = b.GetBrush(e.Bounds))
|
|
e.Graphics.FillRectangle(br, e.Bounds);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
#endregion
|
|
}
|