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
 | 
						|
}
 |