using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using System.Collections.Generic; namespace ProgressODoom { /// public enum ProgressType { Smooth, MarqueeWrap, MarqueeBounce, MarqueeBounceDeep, Animated } /// public abstract class AbstractProgressBar : Control { protected int minimum = 0; protected int maximum = 100; protected int value = 0; protected Rectangle borderbox; protected Rectangle progressbox; protected Rectangle backbox; private bool showPercent = false; private int padding = 0; #region Marquee protected ProgressType type = ProgressType.Smooth; protected int marqueeSpeed = 30; protected int marqueePercentage = 25; protected int marqueeStep = 1; #endregion protected EventHandler OnValueChanged; /// public event EventHandler ValueChanged { add { if (OnValueChanged != null) { foreach (Delegate d in OnValueChanged.GetInvocationList()) { if (object.ReferenceEquals(d, value)) { return; } } } OnValueChanged = (EventHandler)Delegate.Combine(OnValueChanged, value); } remove { OnValueChanged = (EventHandler)Delegate.Remove(OnValueChanged, value); } } public AbstractProgressBar() { this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.UserPaint, true); } /// [Category("Progress"), Description("Gets or sets whether or not to draw the percentage text"), Browsable(true)] public bool ShowPercentage { get { return showPercent; } set { showPercent = value; Invalidate(); if (!showPercent) { this.Text = ""; } } } /// [Category("Progress"), Description("Gets or sets the minimum value"), Browsable(true)] public virtual int Minimum { get { return this.minimum; } set { if (value > maximum) { throw new ArgumentException("Minimum must be smaller than maximum."); } this.minimum = value; this.Invalidate(); } } /// [Category("Progress"), Description("Gets or sets the maximum value"), Browsable(true)] public virtual int Maximum { get { return this.maximum; } set { if (value < minimum) { throw new ArgumentException("Maximum must be larger than minimum."); } this.maximum = value; this.Invalidate(); } } /// [Category("Progress"), Description("Gets or sets the current value"), Browsable(true)] public int Value { get { return this.value; } set { if (value < minimum) { throw new ArgumentException("Value must be greater than or equal to minimum."); } if (value > maximum) { throw new ArgumentException("Value must be less than or equal to maximum."); } this.value = value; if (showPercent) { int percent = (int)(((float)this.value / (float)(this.maximum - 1f)) * 100f); if (percent > 0) { if (percent > 100) { percent = 100; } this.Text = string.Format("{0}%", percent.ToString()); } else { this.Text = ""; } } if (OnValueChanged != null) { OnValueChanged(this, EventArgs.Empty); } ResizeProgress(); this.Invalidate(); } } /// [Category("Progress"), Description("Gets or sets the number of pixels to pad between the border and progress"), Browsable(true)] public int ProgressPadding { get { return this.padding; } set { this.padding = value; if (OnValueChanged != null) { OnValueChanged(this, EventArgs.Empty); } //ResizeProgress(); OnResize(EventArgs.Empty); this.Invalidate(); } } /// [Category("Progress"), Description("Gets or sets the type of progress"), Browsable(true)] public virtual ProgressType ProgressType { get { return this.type; } set { this.type = value; } } #region Marquee /// [Category("Marquee"), Description("Gets or sets the number of milliseconds between marquee steps"), Browsable(true)] public int MarqueeSpeed { get { return this.marqueeSpeed; } set { this.marqueeSpeed = value; if (this.marqueeSpeed < 10) { this.marqueeSpeed = 10; } } } /// [Category("Marquee"), Description("Gets or sets the number of pixels to progress the marquee bar"), Browsable(true)] public int MarqueeStep { get { return this.marqueeStep; } set { this.marqueeStep = value; } } /// [Category("Marquee"), Description("Gets or sets the percentage of the width that the marquee progress fills"), Browsable(true)] public int MarqueePercentage { get { return this.marqueePercentage; } set { if (value < 5 || value > 95) { throw new ArgumentException("Marquee percentage width must be between 5% and 95%."); } this.marqueePercentage = value; } } #endregion /// [Browsable(false)] public Rectangle BorderBox { get { return this.borderbox; } } /// [Browsable(false)] public Rectangle BackBox { get { return this.backbox; } } /// [Browsable(false)] public Rectangle ProgressBox { get { return this.progressbox; } } /// /// protected abstract void PaintBackground(Graphics gr); /// /// protected abstract void PaintProgress(Graphics gr); /// /// protected abstract void PaintText(Graphics gr); /// /// protected abstract void PaintBorder(Graphics gr); /// protected abstract void ResizeProgress(); /// /// protected override void OnResize(EventArgs e) { base.OnResize(e); borderbox = new Rectangle(0, 0, this.Width - 1, this.Height - 1); backbox = new Rectangle(0, 0, this.Width - 1, this.Height - 1); ResizeProgress(); } /// /// protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); PaintBackground(e.Graphics); PaintProgress(e.Graphics); e.Graphics.Clip = new Region(new Rectangle(0, 0, this.Width, this.Height)); PaintText(e.Graphics); PaintBorder(e.Graphics); } /// public abstract void MarqueeStart(); /// public abstract void MarqueePause(); /// public abstract void MarqueeStop(); } }