376 lines
12 KiB
C#
376 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Drawing;
|
|
using System.ComponentModel;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Globalization;
|
|
|
|
namespace DevComponents.DotNetBar.Layout
|
|
{
|
|
[TypeConverter(typeof(BackgroundConvertor))]
|
|
public class Background : INotifyPropertyChanged
|
|
{
|
|
#region Constructor
|
|
/// <summary>
|
|
/// Initializes a new instance of the Background class.
|
|
/// </summary>
|
|
public Background()
|
|
{
|
|
|
|
}
|
|
/// <summary>
|
|
/// Initializes a new instance of the Background class with single solid backgruond color.
|
|
/// </summary>
|
|
public Background(Color backColor)
|
|
{
|
|
_Colors = new Color[] { backColor };
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the Background class.
|
|
/// </summary>
|
|
/// <param name="colors"></param>
|
|
public Background(Color[] colors)
|
|
{
|
|
_Colors = colors;
|
|
}
|
|
/// <summary>
|
|
/// Initializes a new instance of the Background class.
|
|
/// </summary>
|
|
/// <param name="colors"></param>
|
|
/// <param name="positions"></param>
|
|
public Background(Color[] colors, float[] positions)
|
|
{
|
|
_Colors = colors;
|
|
_Positions = positions;
|
|
}
|
|
/// <summary>
|
|
/// Initializes a new instance of the Background class.
|
|
/// </summary>
|
|
/// <param name="colors"></param>
|
|
/// <param name="positions"></param>
|
|
/// <param name="gradientType"></param>
|
|
public Background(Color[] colors, float[] positions, eGradientType gradientType)
|
|
{
|
|
_Colors = colors;
|
|
_Positions = positions;
|
|
_GradientType = gradientType;
|
|
}
|
|
/// <summary>
|
|
/// Initializes a new instance of the Background class.
|
|
/// </summary>
|
|
/// <param name="colors"></param>
|
|
/// <param name="positions"></param>
|
|
/// <param name="gradientType"></param>
|
|
/// <param name="linearGradientAngle"></param>
|
|
public Background(Color[] colors, float[] positions, eGradientType gradientType, int linearGradientAngle)
|
|
{
|
|
_Colors = colors;
|
|
_Positions = positions;
|
|
_GradientType = gradientType;
|
|
_LinearGradientAngle = linearGradientAngle;
|
|
}
|
|
#endregion
|
|
|
|
#region Implementation
|
|
/// <summary>
|
|
/// Gets whether class is empty.
|
|
/// </summary>
|
|
[Browsable(false)]
|
|
public bool IsEmpty
|
|
{
|
|
get
|
|
{
|
|
return (_Colors == null || _Colors.Length == 0) &&
|
|
(_Positions == null || _Positions.Length == 0);
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Gets whether background is visible, i.e. colors are assigned.
|
|
/// </summary>
|
|
[Browsable(false)]
|
|
public bool IsBackgroundSet
|
|
{
|
|
get
|
|
{
|
|
return !(_Colors == null || _Colors.Length == 0);
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Creates the brush which represents the background.
|
|
/// </summary>
|
|
/// <param name="r">Bounds for the brush.</param>
|
|
/// <returns>New instance of the brush or null if brush cannot be created.</returns>
|
|
public Brush CreateBrush(Rectangle r)
|
|
{
|
|
if (!IsBackgroundSet)
|
|
return null;
|
|
if (_Colors.Length == 1)
|
|
return new SolidBrush(_Colors[0]);
|
|
if (_GradientType == eGradientType.LinearGradient)
|
|
{
|
|
LinearGradientBrush brush = null;
|
|
if (_Colors.Length == 2)
|
|
{
|
|
brush = new LinearGradientBrush(r, _Colors[0], _Colors[1], _LinearGradientAngle);
|
|
if (_Positions != null && _Positions.Length != 2) return brush;
|
|
}
|
|
else
|
|
brush = new LinearGradientBrush(r, _Colors[0], _Colors[_Colors.Length - 1], _LinearGradientAngle);
|
|
ColorBlend cb = GetColorBlend();
|
|
if (cb != null)
|
|
brush.InterpolationColors = cb;
|
|
return brush;
|
|
}
|
|
else
|
|
{
|
|
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 = _Colors[0];
|
|
pbr.SurroundColors = new Color[] { _Colors[_Colors.Length - 1] };
|
|
|
|
ColorBlend cb = GetColorBlend();
|
|
|
|
if (cb != null)
|
|
pbr.InterpolationColors = cb;
|
|
|
|
return (pbr);
|
|
}
|
|
}
|
|
}
|
|
private ColorBlend GetColorBlend()
|
|
{
|
|
if (_Colors != null &&
|
|
_Colors != null && _Colors.Length > 0)
|
|
{
|
|
ColorBlend cb = new ColorBlend(_Colors.Length);
|
|
|
|
cb.Colors = _Colors;
|
|
cb.Positions = GetPositions();
|
|
|
|
return (cb);
|
|
}
|
|
|
|
return (null);
|
|
}
|
|
private float[] GetPositions()
|
|
{
|
|
float[] cp = _Positions;
|
|
|
|
if (cp == null || cp.Length != _Colors.Length)
|
|
{
|
|
cp = new float[_Colors.Length];
|
|
|
|
float f = 1f / _Colors.Length;
|
|
|
|
for (int i = 0; i < cp.Length; i++)
|
|
cp[i] = i * f;
|
|
|
|
cp[_Colors.Length - 1] = 1;
|
|
}
|
|
|
|
return (cp);
|
|
}
|
|
|
|
|
|
private Color[] _Colors = null;
|
|
/// <summary>
|
|
/// Indicates the array of colors that make up background.
|
|
/// </summary>
|
|
[DefaultValue(null), Category("Appearance"), Description("Indicates the array of colors that make up background."), TypeConverter(typeof(ArrayConverter))]
|
|
public Color[] Colors
|
|
{
|
|
get
|
|
{
|
|
return _Colors;
|
|
}
|
|
set
|
|
{
|
|
if (_Colors != value)
|
|
{
|
|
_Colors = value;
|
|
OnPropertyChanged(new PropertyChangedEventArgs("Colors"));
|
|
}
|
|
}
|
|
}
|
|
|
|
private float[] _Positions = null;
|
|
/// <summary>
|
|
/// Indicates the positions for the gradient colors when multiple colors are set to Colors property. When not set
|
|
/// the gradient color positions are evenly distributed.
|
|
/// </summary>
|
|
[DefaultValue(null), Category("Appearance"), Description("Indicates the positions for the gradient colors when multiple colors are set to Colors property."), TypeConverter(typeof(ArrayConverter))]
|
|
public float[] Positions
|
|
{
|
|
get
|
|
{
|
|
return _Positions;
|
|
}
|
|
set
|
|
{
|
|
_Positions = value;
|
|
OnPropertyChanged(new PropertyChangedEventArgs("Positions"));
|
|
}
|
|
}
|
|
|
|
private eGradientType _GradientType = eGradientType.LinearGradient;
|
|
/// <summary>
|
|
/// Indicates the gradient type used when multiple Colors are specified.
|
|
/// </summary>
|
|
[DefaultValue(eGradientType.LinearGradient), Category("Appearance"), Description("Indicates the gradient type used when multiple Colors are specified.")]
|
|
public eGradientType GradientType
|
|
{
|
|
get { return _GradientType; }
|
|
set { _GradientType = value; OnPropertyChanged(new PropertyChangedEventArgs("GradientType")); }
|
|
}
|
|
|
|
private int _LinearGradientAngle = 90;
|
|
/// <summary>
|
|
/// Indicates the linear gradient angle.
|
|
/// </summary>
|
|
[DefaultValue(90), Description("Indicates the linear gradient angle."), Category("Appearance")]
|
|
public int LinearGradientAngle
|
|
{
|
|
get { return _LinearGradientAngle; }
|
|
set { _LinearGradientAngle = value; OnPropertyChanged(new PropertyChangedEventArgs("LinearGradientAngle")); }
|
|
}
|
|
#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(PropertyChangedEventArgs 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)
|
|
{
|
|
PropertyChangedEventArgs e =
|
|
new PropertyChangedEventArgs(s);
|
|
|
|
eh(this, e);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
public enum eGradientType
|
|
{
|
|
LinearGradient,
|
|
RadialGradient
|
|
}
|
|
|
|
#region BackgroundConvertor
|
|
|
|
///<summary>
|
|
/// BackgroundConvertor
|
|
///</summary>
|
|
public class BackgroundConvertor : ExpandableObjectConverter
|
|
{
|
|
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
|
|
{
|
|
return ((sourceType == typeof(string)) || base.CanConvertFrom(context, sourceType));
|
|
}
|
|
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.IsEmpty)
|
|
return "(Empty)";
|
|
|
|
if (gc.Colors != null && gc.Colors.Length == 1)
|
|
return ColorHelpers.ToArgbString(gc.Colors[0]);
|
|
|
|
if (gc.Colors != null && gc.Colors.Length > 1)
|
|
return ("Blended");
|
|
|
|
|
|
return "";
|
|
}
|
|
}
|
|
|
|
return (base.ConvertTo(context, culture, value, destinationType));
|
|
}
|
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
|
{
|
|
string str = value as string;
|
|
if (string.IsNullOrEmpty(str))
|
|
{
|
|
return new BorderColors();
|
|
}
|
|
string str2 = str.Trim();
|
|
if (str2.Length == 0)
|
|
{
|
|
return null;
|
|
}
|
|
if (culture == null)
|
|
{
|
|
culture = CultureInfo.CurrentCulture;
|
|
}
|
|
if (str2.IndexOf(culture.TextInfo.ListSeparator[0]) == -1)
|
|
{
|
|
Color c = Color.FromName(str2);
|
|
if (c.IsEmpty)
|
|
c = ColorHelpers.GetColor(str2);
|
|
return new Background(c);
|
|
}
|
|
|
|
throw new ArgumentException("Text Parsing Failed");
|
|
|
|
//char ch = culture.TextInfo.ListSeparator[0];
|
|
//string[] strArray = str2.Split(new char[] { ch });
|
|
//Color[] numArray = new Color[strArray.Length];
|
|
////TypeConverter converter = TypeDescriptor.GetConverter(typeof(Color));
|
|
//for (int i = 0; i < numArray.Length; i++)
|
|
//{
|
|
// numArray[i] = ColorHelpers.GetColor(strArray[i]);// (Color)converter.ConvertFromString(context, culture, strArray[i]);
|
|
//}
|
|
|
|
//if (numArray.Length == 1)
|
|
//{
|
|
// return new BorderColors(numArray[0]);
|
|
//}
|
|
|
|
//if (numArray.Length != 4)
|
|
//{
|
|
// throw new ArgumentException("Text Parsing Failed");
|
|
//}
|
|
//return new BorderColors(numArray[0], numArray[1], numArray[2], numArray[3]);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|