Feedback

C# - iTunes-ProgressBar

Veröffentlicht von am 22.12.2007
(5 Bewertungen)
Dieses Control stellt ein ProgressBar im iTunes-Style dar.
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.ComponentModel;

namespace ViperBytes
{
    /// <summary>
    /// Special progress bar is a kind of iTunes bar
    /// Text member: The token {0} will be replaced with the difference between starting and ending value.
    /// </summary>
    public class SpecialProgressBar : Control
    {
        #region SpecialProgressBarStyle enumeration
        /// <summary>
        /// Lists possible styles
        /// </summary>
        public enum SpecialProgressBarStyle
        {
            Square,
            Round,
            Peaked,
            Slang
        }
        #endregion

        #region private fields
        /// <summary>
        /// Style of progress bar ends
        /// </summary>
        private SpecialProgressBarStyle style = SpecialProgressBarStyle.Square;

        /// <summary>
        /// Color of border
        /// </summary>
        private Color borderColor = Color.Gray;

        /// <summary>
        /// Light fill color of gradient
        /// </summary>
        private Color lightFillColor = Color.LightGreen;

        /// <summary>
        /// Dark fill color of gradient
        /// </summary>
        private Color darkFillColor = Color.DarkGreen;

        /// <summary>
        /// Light background color of gradient
        /// </summary>
        private Color lightBackColor = Color.LightGray;

        /// <summary>
        /// Dark background color of gradient
        /// </summary>
        private Color darkBackColor = Color.DarkGray;

        /// <summary>
        /// Number of separators
        /// </summary>
        private int separators = 10;

        /// <summary>
        /// Starting value of fillage
        /// </summary>
        private int startValue = 0;

        /// <summary>
        /// Ending value of fillage
        /// </summary>
        private int endValue = 0;
        #endregion

        #region public events
        /// <summary>
        /// Fired, when border color changed
        /// </summary>
        public event EventHandler BorderColorChanged;

        /// <summary>
        /// Fired, when light fill color changed
        /// </summary>
        public event EventHandler LightFillColorChanged;

        /// <summary>
        /// Fired, when dark fill color changed
        /// </summary>
        public event EventHandler DarkFillColorChanged;

        /// <summary>
        /// Fired, when light background color changed
        /// </summary>
        public event EventHandler LightBackColorChanged;

        /// <summary>
        /// Fired, when dark background color changed
        /// </summary>
        public event EventHandler DarkBackColorChanged;

        /// <summary>
        /// Fired, when number of separators changed
        /// </summary>
        public event EventHandler SeparatorsChanged;

        /// <summary>
        /// Fired, when starting value changed
        /// </summary>
        public event EventHandler StartValueChanged;

        /// <summary>
        /// Fired, when ending value changed
        /// </summary>
        public event EventHandler EndValueChanged;
        #endregion

        #region properties
        /// <summary>
        /// Specifyes the ending's style
        /// </summary>
        [DefaultValue(typeof(SpecialProgressBar.SpecialProgressBarStyle), "Square")]
        public SpecialProgressBarStyle Style
        {
            get
            {
                return this.style;
            }
            set
            {
                if (this.style != value)
                {
                    this.style = value;
                    Invalidate();
                    OnStyleChanged(EventArgs.Empty);
                }
            }
        }

        /// <summary>
        /// Specifyes the border color
        /// </summary>
        [DefaultValue(typeof(Color), "Gray")]
        public Color BorderColor
        {
            get
            {
                return this.borderColor;
            }
            set
            {
                if (this.borderColor != value)
                {
                    this.borderColor = value;
                    Invalidate();
                    OnBorderColorChanged(EventArgs.Empty);
                }
            }
        }

        /// <summary>
        /// Specifyes the light fill color of gradient
        /// </summary>
        [DefaultValue(typeof(Color), "LightGreen")]
        public Color LightFillColor
        {
            get
            {
                return this.lightFillColor;
            }
            set
            {
                if (this.lightFillColor != value)
                {
                    this.lightFillColor = value;
                    Invalidate();
                    OnLightFillColorChanged(EventArgs.Empty);
                }
            }
        }

        /// <summary>
        /// Specifyes the dark fill color of gradient
        /// </summary>
        [DefaultValue(typeof(Color), "DarkGreen")]
        public Color DarkFillColor
        {
            get
            {
                return this.darkFillColor;
            }
            set
            {
                if (this.darkFillColor != value)
                {
                    this.darkFillColor = value;
                    Invalidate();
                    OnDarkFillColorChanged(EventArgs.Empty);
                }
            }
        }

        /// <summary>
        /// Specifyes the light background color of gradient
        /// </summary>
        [DefaultValue(typeof(Color), "LightGray")]
        public Color LightBackColor
        {
            get
            {
                return this.lightBackColor;
            }
            set
            {
                if (this.lightBackColor != value)
                {
                    this.lightBackColor = value;
                    Invalidate();
                    OnLightBackColorChanged(EventArgs.Empty);
                }
            }
        }

        /// <summary>
        /// Specifyes the dark background color of gradient
        /// </summary>
        [DefaultValue(typeof(Color), "DarkGray")]
        public Color DarkBackColor
        {
            get
            {
                return this.darkBackColor;
            }
            set
            {
                if (this.darkBackColor != value)
                {
                    this.darkBackColor = value;
                    Invalidate();
                    OnDarkBackColorChanged(EventArgs.Empty);
                }
            }
        }

        /// <summary>
        /// Specifyes the number of separators
        /// </summary>
        [DefaultValue(10)]
        public int Separators
        {
            get
            {
                return this.separators;
            }
            set
            {
                if (this.separators != value)
                {
                    this.separators = value;
                    Invalidate();
                    OnSeparatorsChanged(EventArgs.Empty);
                }
            }
        }

        /// <summary>
        /// Specifyes starting value
        /// </summary>
        [DefaultValue(0)]
        public int StartValue
        {
            get
            {
                return this.startValue;
            }
            set
            {
                if (this.startValue != value)
                {
                    this.startValue = value;
                    Invalidate();
                    OnStartValueChanged(EventArgs.Empty);
                }
            }
        }

        /// <summary>
        /// Specifyes ending value
        /// </summary>
        [DefaultValue(0)]
        public int EndValue
        {
            get
            {
                return this.endValue;
            }
            set
            {
                if (this.endValue != value)
                {
                    this.endValue = value;
                    Invalidate();
                    OnEndValueChanged(EventArgs.Empty);
                }
            }
        }
        #endregion

        #region Constructor
        /// <summary>
        /// Constructor
        /// </summary>
        public SpecialProgressBar()
            : base()
        {
            Size = new Size(320, 32);
            DoubleBuffered = true;
            Text = "{0} %";
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="text">Text member</param>
        public SpecialProgressBar(string text)
            : base(text)
        {
            Size = new Size(320, 32);
            DoubleBuffered = true;
            Text = "{0} %";
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="parent">Parent control</param>
        /// <param name="text">Text members</param>
        public SpecialProgressBar(Control parent, string text)
            : base(parent, text)
        {
            Size = new Size(320, 32);
            DoubleBuffered = true;
            Text = "{0} %";
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="text">Text member</param>
        /// <param name="left">X-coordinate</param>
        /// <param name="top">Y-coordinate</param>
        /// <param name="width">Width member</param>
        /// <param name="height">Height member</param>
        public SpecialProgressBar(string text, int left, int top, int width, int height)
            : base(text, left, top, width, height)
        {
            DoubleBuffered = true;
            Text = "{0} %";
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="parent">Parent control</param>
        /// <param name="text">Text member</param>
        /// <param name="left">X-coordinate</param>
        /// <param name="top">Y-coordinate</param>
        /// <param name="width">Width member</param>
        /// <param name="height">Height member</param>
        public SpecialProgressBar(Control parent, string text, int left, int top, int width, int height)
            : base(parent, text, left, top, width, height)
        {
            DoubleBuffered = true;
            Text = "{0} %";
        }
        #endregion

        #region protected members
        /// <summary>
        /// Fired, when border color changed
        /// </summary>
        protected void OnBorderColorChanged(EventArgs e)
        {
            if (BorderColorChanged != null)
                BorderColorChanged(this, e);
        }

        /// <summary>
        /// Fired, when light fill color changed
        /// </summary>
        protected void OnLightFillColorChanged(EventArgs e)
        {
            if (LightFillColorChanged != null)
                LightFillColorChanged(this, e);
        }

        /// <summary>
        /// Fired, when dark fill color changed
        /// </summary>
        protected void OnDarkFillColorChanged(EventArgs e)
        {
            if (DarkFillColorChanged != null)
                DarkFillColorChanged(this, e);
        }

        /// <summary>
        /// Fired, when light background color changed
        /// </summary>
        protected void OnLightBackColorChanged(EventArgs e)
        {
            if (LightBackColorChanged != null)
                LightBackColorChanged(this, e);
        }

        /// <summary>
        /// Fired, when dark background color changed
        /// </summary>
        protected void OnDarkBackColorChanged(EventArgs e)
        {
            if (DarkBackColorChanged != null)
                DarkBackColorChanged(this, e);
        }

        /// <summary>
        /// Fired, when number of separators changed
        /// </summary>
        protected void OnSeparatorsChanged(EventArgs e)
        {
            if (SeparatorsChanged != null)
                SeparatorsChanged(this, e);
        }

        /// <summary>
        /// Fired, when starting value changed
        /// </summary>
        protected void OnStartValueChanged(EventArgs e)
        {
            if (StartValueChanged != null)
                StartValueChanged(this, e);
        }

        /// <summary>
        /// Fired, when ending value changed
        /// </summary>
        protected void OnEndValueChanged(EventArgs e)
        {
            if (EndValueChanged != null)
                EndValueChanged(this, e);
        }

        /// <summary>
        /// Fired, when size changed
        /// </summary>
        /// <param name="e"></param>
        protected override void OnSizeChanged(EventArgs e)
        {
            if (Height > Width)
                Width = Height;

            base.OnSizeChanged(e);
        }

        /// <summary>
        /// Fired, when text changed
        /// </summary>
        /// <param name="e"></param>
        protected override void OnTextChanged(EventArgs e)
        {
            Invalidate();
            base.OnTextChanged(e);
        }

        /// <summary>
        /// Fired on paint event
        /// </summary>
        /// <param name="e">Event arguments</param>
        protected override void OnPaint(PaintEventArgs e)
        {
            Rectangle rect = new Rectangle(1, 1, Width - 2, Height - 2);
            Graphics g = e.Graphics;
            g.SmoothingMode = SmoothingMode.HighQuality;

            GraphicsPath path = GetPath(rect);

            // Draw back gradient
            using (LinearGradientBrush brush = new LinearGradientBrush(rect, LightBackColor, DarkBackColor, LinearGradientMode.Vertical))
            {
                g.FillPath(brush, path);
            }

            if (EndValue - StartValue != 0)
            {
                // Draw fill gradient
                using (LinearGradientBrush brush = new LinearGradientBrush(rect, LightFillColor, DarkFillColor, LinearGradientMode.Vertical))
                {
                    RectangleF clip = new RectangleF(rect.X + (float)rect.Width * (float)StartValue / 100F, rect.Y, (float)rect.Width * (float)(EndValue - StartValue) / 100F, rect.Height);

                    g.SetClip(clip);
                    g.FillPath(brush, path);
                    g.ResetClip();
                }
            }
            using (Pen pen = new Pen(BorderColor, 1))
            {
                if (EndValue - StartValue != 0)
                {
                    float startSplit = rect.X + (float)rect.Width * (float)StartValue / 100F - 0.5F;
                    float endSplit = rect.X + (float)rect.Width * (float)EndValue / 100F - 0.5F;

                    g.SetClip(path);
                    g.DrawLine(pen, startSplit, rect.Y - 0.5F, startSplit, rect.Y + rect.Height - 0.5F);
                    g.DrawLine(pen, endSplit, rect.Y - 0.5F, endSplit, rect.Y + rect.Height - 0.5F);
                    g.ResetClip();
                }

                // draw Border
                Matrix matrix = new Matrix();
                matrix.Translate(-0.5F, -0.5F);
                path.Transform(matrix);
                g.DrawPath(pen, path);
            }

            if (Separators > 0)
            {
                using (Pen pen1 = new Pen(Color.FromArgb(48, Color.Black), 1))
                {
                    using (Pen pen2 = new Pen(Color.FromArgb(48, Color.White), 1))
                    {
                        float step = (float)rect.Width / (float)(Separators + 1);

                        g.SetClip(path);
                        for (float split = rect.X + step - 0.5F; split < rect.X + rect.Width - 0.5F; split += step)
                        {
                            g.DrawLine(pen1, split - 0.5F, rect.Y - 0.5F, split - 0.5F, rect.Y + rect.Height - 0.5F);
                            g.DrawLine(pen2, split + 0.5F, rect.Y - 0.5F, split + 0.5F, rect.Y + rect.Height - 0.5F);
                        }
                        g.ResetClip();
                    }
                }
            }
            // draw light
            using (SolidBrush brush = new SolidBrush(Color.FromArgb(48, Color.White)))
            {
                g.SetClip(path);
                g.FillRectangle(brush, new RectangleF(rect.X, rect.Y, rect.Width, rect.Height / 2F));
                g.ResetClip();
            }

            string text;
            if (Text.Contains("{0}"))
                text = Text.Replace("{0}", ((int)Math.Abs(EndValue - StartValue)).ToString());
            else
                text = Text;

            if (text.Length > 0)
            {
                SizeF fontSize = g.MeasureString(text, Font);

                RectangleF fontRect = new RectangleF(
                    rect.X + rect.Width / 2F - fontSize.Width / 2F,
                    rect.Y + rect.Height / 2F - fontSize.Height / 2F,
                    fontSize.Width,
                    fontSize.Height);

                g.DrawString(text, Font, new SolidBrush(ForeColor), fontRect);
            }

            base.OnPaint(e);
        }
        #endregion

        #region private members
        private GraphicsPath GetPath(RectangleF rect)
        {
            GraphicsPath path = new GraphicsPath();
            switch (Style)
            {
                case SpecialProgressBarStyle.Square:
                    path.AddRectangle(rect);
                    break;
                case SpecialProgressBarStyle.Round:
                    path.AddArc(new RectangleF(rect.X, rect.Y, rect.Height, rect.Height), 90, 180);
                    path.AddArc(new RectangleF(rect.X + rect.Width - rect.Height, rect.Y, rect.Height, rect.Height), 270, 180);
                    path.CloseFigure();
                    break;
                case SpecialProgressBarStyle.Peaked:
                    {
                        PointF[] points = new PointF[] {
                            new PointF(rect.X, rect.Y + rect.Height / 2F),
                            new PointF(rect.X + rect.Height / 2F, rect.Y),
                            new PointF(rect.X + rect.Width - rect.Height / 2F, rect.Y),
                            new PointF(rect.X + rect.Width, rect.Y + rect.Height / 2F),
                            new PointF(rect.X + rect.Width - rect.Height / 2F, rect.Y + rect.Height),
                            new PointF(rect.X + rect.Height / 2F, rect.Y + rect.Height)
                        };
                        path.AddLines(points);
                        path.CloseFigure();
                    }
                    break;
                case SpecialProgressBarStyle.Slang:
                    {
                        PointF[] points = new PointF[] {
                            new PointF(rect.X, rect.Y),
                            new PointF(rect.X + rect.Width - rect.Height / 2F, rect.Y),
                            new PointF(rect.X + rect.Width, rect.Y + rect.Height),
                            new PointF(rect.X + rect.Height / 2F, rect.Y + rect.Height)
                        };
                        path.AddLines(points);
                        path.CloseFigure();
                    }
                    break;
            }

            return path;
        }
        #endregion
    }
}

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!