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 { /// /// Represents background of visual style. /// [TypeConverter(typeof(BackgroundConvertor))] [Editor(typeof(BackgroundEditor), typeof(UITypeEditor))] public class Background : INotifyPropertyChanged, IDisposable { #region Static data /// /// Empty /// /// /// Returns Empty instance of BorderPattern. /// 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 /// /// Creates new instance of the object. /// public Background() { } /// /// Creates new instance of the object. /// /// Start color. public Background(Color color1) { _Color1 = color1; } /// /// Creates new instance of the object. /// /// Start color. /// End color. public Background(Color color1, Color color2) { _Color1 = color1; _Color2 = color2; } /// /// Creates new instance of the object. /// /// Start color in hexadecimal representation like FFFFFF. /// End color in hexadecimal representation like FFFFFF. public Background(string color1, string color2) { _Color1 = ColorFactory.GetColor(color1); _Color2 = ColorFactory.GetColor(color2); } /// /// Creates new instance of the object. /// /// Start color in 32-bit RGB representation. /// End color in 32-bit RGB representation. public Background(int color1, int color2) { _Color1 = ColorFactory.GetColor(color1); _Color2 = ColorFactory.GetColor(color2); } /// /// Creates new instance of the object. /// /// Start color in 32-bit RGB representation. /// End color in 32-bit RGB representation. /// Gradient angle. public Background(int color1, int color2, int gradientAngle) { _Color1 = ColorFactory.GetColor(color1); _Color2 = ColorFactory.GetColor(color2); GradientAngle = gradientAngle; } /// /// Creates new instance of the object. /// /// Start color. /// End color. /// Gradient angle. public Background(Color color1, Color color2, int gradientAngle) { _Color1 = color1; _Color2 = color2; GradientAngle = gradientAngle; } /// /// Creates new instance of the object. /// /// Start color. /// End color. /// Gradient angle. public Background(Color color1, Color color2, BackFillType fillType) { _Color1 = color1; _Color2 = color2; _BackFillType = fillType; } #endregion #region Public properties #region Color1 /// /// Gets or sets the start color. /// [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 /// /// Gets or sets the Ending Gradient Color /// [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 /// /// Gets or sets the BackColorBlend. /// [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 /// /// Gets or sets the gradient angle (default is 90) /// [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 /// /// Gets or sets the Gradient BackFillType /// [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 /// /// Gets whether both colors assigned are empty. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsEmpty { get { return (_Color1.IsEmpty && _Color2.IsEmpty && (_BackColorBlend == null || _BackColorBlend.IsEmpty)); } } #endregion #region IsEqualTo /// /// Determines if the Background is equal to the given one /// /// Background to compare /// true if equal [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 /// /// GetBrush /// /// /// 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 /// /// Creates an exact copy of the background. /// /// Copy of the background. 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 /// /// Occurs when property value has changed. /// public event PropertyChangedEventHandler PropertyChanged; /// /// Raises the PropertyChanged event. /// /// Event arguments protected virtual void OnPropertyChanged(VisualPropertyChangedEventArgs 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) { 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 /// /// StyleChanged /// /// /// protected virtual void StyleChanged( object sender, PropertyChangedEventArgs e) { OnPropertyChanged((VisualPropertyChangedEventArgs)e); } #endregion #region IDisposable /// /// Dispose /// public void Dispose() { BackColorBlend = null; } #endregion } #region enums /// /// BackFillType /// public enum BackFillType { /// /// Angle /// Angle, /// /// Center /// Center, /// /// HorizontalCenter /// HorizontalCenter, /// /// VerticalCenter /// VerticalCenter, /// /// ForwardDiagonal /// ForwardDiagonal, /// /// BackwardDiagonal /// BackwardDiagonal, /// /// ForwardDiagonalCenter /// ForwardDiagonalCenter, /// /// BackwardDiagonalCenter /// BackwardDiagonalCenter, /// /// Radial /// Radial, } #endregion #region BackgroundConvertor /// /// BackgroundConvertor /// public class BackgroundConvertor : ExpandableObjectConverter { /// /// ConvertTo /// /// /// /// /// /// 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 /// /// BackgroundEditor /// public class BackgroundEditor : UITypeEditor { #region GetPaintValueSupported /// /// GetPaintValueSupported /// /// /// public override bool GetPaintValueSupported(ITypeDescriptorContext context) { return (true); } #endregion #region PaintValue /// /// PaintValue /// /// 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 }