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 /// /// Initializes a new instance of the Background class. /// public Background() { } /// /// Initializes a new instance of the Background class with single solid backgruond color. /// public Background(Color backColor) { _Colors = new Color[] { backColor }; } /// /// Initializes a new instance of the Background class. /// /// public Background(Color[] colors) { _Colors = colors; } /// /// Initializes a new instance of the Background class. /// /// /// public Background(Color[] colors, float[] positions) { _Colors = colors; _Positions = positions; } /// /// Initializes a new instance of the Background class. /// /// /// /// public Background(Color[] colors, float[] positions, eGradientType gradientType) { _Colors = colors; _Positions = positions; _GradientType = gradientType; } /// /// Initializes a new instance of the Background class. /// /// /// /// /// public Background(Color[] colors, float[] positions, eGradientType gradientType, int linearGradientAngle) { _Colors = colors; _Positions = positions; _GradientType = gradientType; _LinearGradientAngle = linearGradientAngle; } #endregion #region Implementation /// /// Gets whether class is empty. /// [Browsable(false)] public bool IsEmpty { get { return (_Colors == null || _Colors.Length == 0) && (_Positions == null || _Positions.Length == 0); } } /// /// Gets whether background is visible, i.e. colors are assigned. /// [Browsable(false)] public bool IsBackgroundSet { get { return !(_Colors == null || _Colors.Length == 0); } } /// /// Creates the brush which represents the background. /// /// Bounds for the brush. /// New instance of the brush or null if brush cannot be created. 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; /// /// Indicates the array of colors that make up background. /// [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; /// /// 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. /// [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; /// /// Indicates the gradient type used when multiple Colors are specified. /// [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; /// /// Indicates the linear gradient angle. /// [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 /// /// Occurs when property value has changed. /// public event PropertyChangedEventHandler PropertyChanged; /// /// Raises the PropertyChanged event. /// /// Event arguments protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) { PropertyChangedEventHandler eh = PropertyChanged; if (eh != null) eh(this, e); } /// /// Raises the PropertyChanged event. /// /// Event arguments 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 /// /// BackgroundConvertor /// 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 }