// This class is based on "Never-ending Progress Bar (C#)" by GregOsborne
// http://www.codeproject.com/cs/miscctrl/C_NeverEndingPBar.asp
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
namespace Grunwald.Gui.Controls
{
///
/// An endless progress bar.
///
public class EndlessProgressBar : System.Windows.Forms.UserControl
{
private System.ComponentModel.IContainer components;
///
/// Endless progress bar
///
public EndlessProgressBar()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
this.ResizeRedraw = true;
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.Paint += new PaintEventHandler(this.PaintHandler);
this.Resize += new EventHandler(this.ResizeHandler);
this.tmrAutoProgress.Tick += new EventHandler(this.TimerHandler);
}
///
/// Disposes all used resources.
///
protected override void Dispose(bool disposing)
{
if (disposing) {
if (components != null)
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent() {
this.components = new System.ComponentModel.Container();
this.tmrAutoProgress = new System.Windows.Forms.Timer(this.components);
//
// OSProgress
//
this.Name = "OSProgress";
this.Size = new System.Drawing.Size(226, 30);
}
#endregion
private System.Windows.Forms.Timer tmrAutoProgress;
private byte speedMultiPlier = 2;
private bool requireClear = false;
private bool increasing = true;
#region Properties
private ProgressType progressType = ProgressType.Box;
///
/// Gets/Sets the type of progress bar.
///
[Description("Determines the type of progress bar"), DefaultValue(ProgressType.Box)]
public ProgressType ProgressType {
get { return progressType; }
set {
progressType = value;
this.Invalidate();
}
}
private Image normalImage;
///
/// Gets/Sets the background graphic.
///
[Description("Gets/Sets the background graphic")]
public Image NormalImage {
get { return normalImage; }
set {
normalImage = value;
this.Invalidate();
}
}
private Image pointImage;
///
/// Gets/Sets the point graphic.
///
[Description("Gets/Sets the point graphic")]
public Image PointImage {
get { return pointImage; }
set {
pointImage = value;
this.Invalidate();
}
}
private bool showBorder = true;
///
/// Gets/Sets if the border is shown.
///
[Description("Determines if the border is shown"), DefaultValue(true)]
public bool ShowBorder {
get { return showBorder; }
set {
showBorder = value;
this.Invalidate();
}
}
private int numPoints;
///
/// Gets the number of points in the progressbar.
///
[Browsable(false)]
public int NumPoints {
get { return numPoints; }
}
private int position;
///
/// Gets/Sets the position of the progress indicator.
///
[Browsable(false)]
public int Position {
get { return position; }
set {
position = value;
this.Invalidate();
}
}
private Color indicatorColor = Color.Red;
///
/// Gets/Sets the color of the indicator.
///
[Description("Color of the indicator")]
public Color IndicatorColor {
get { return indicatorColor; }
set {
indicatorColor = value;
this.Invalidate();
}
}
private ProgressStyle progressStyle = ProgressStyle.LeftToRight;
///
/// Gets/Sets the progress indicator rotation style.
///
[Description("Indicates the progress indicator rotation style"),
DefaultValue(ProgressStyle.LeftToRight)]
public ProgressStyle ProgressStyle {
get { return progressStyle; }
set {
progressStyle = value;
this.Invalidate();
}
}
private bool autoProgress = false;
///
/// Gets/Sets whether auto-progress is enabled.
///
[Description("Indicates whether auto-progress is enabled"), DefaultValue(false)]
public bool AutoProgress {
get { return autoProgress; }
set {
if (!this.DesignMode) {
this.tmrAutoProgress.Interval = (255 - this.autoProgressSpeed) * this.speedMultiPlier;
if (value) {
this.tmrAutoProgress.Start();
} else {
this.tmrAutoProgress.Stop();
}
}
autoProgress = value;
}
}
private int autoProgressSpeed = 100;
///
/// Gets/Sets the speed of the progress indicator (1 [slower] to 254 [faster]).
///
[Description("Indicates the speed of the progress indicator (1 [slower] to 254 [faster])"),
DefaultValue(100)]
public int AutoProgressSpeed {
get { return autoProgressSpeed; }
set {
if (value < 1) {
value = 1;
} else if (value > 254) {
value = 254;
}
tmrAutoProgress.Stop();
tmrAutoProgress.Interval = (255 - value) * speedMultiPlier;
tmrAutoProgress.Enabled = this.autoProgress;
autoProgressSpeed = value;
}
}
private ProgressBoxStyle progressBoxStyle = ProgressBoxStyle.SolidSameSize;
///
/// Gets/Sets the style of the progress box.
///
[Description("Gets/Sets the style of the progress box."),
DefaultValue(ProgressBoxStyle.SolidSameSize)]
public ProgressBoxStyle ProgressBoxStyle {
get {
return progressBoxStyle;
}
set {
progressBoxStyle = value;
this.Invalidate();
}
}
#endregion
#region Methods
private void ResizeHandler(object sender, System.EventArgs e)
{
this.requireClear = true;
this.position = 0;
this.Invalidate();
}
private void TimerHandler(object sender, System.EventArgs e)
{
if (this.position == this.numPoints - 1) {
if (this.progressStyle == ProgressStyle.LeftToRight) {
this.position = 0;
} else {
this.position -= 1;
this.increasing = false;
}
} else if ((this.position == 0) && (!this.increasing)) {
this.position += 1;
this.increasing = true;
} else {
if (this.increasing) {
this.position += 1;
} else {
this.position -= 1;
}
}
this.requireClear = false;
this.Invalidate();
}
private void PaintHandler(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.HighSpeed;
if (this.requireClear) {
g.Clear(this.BackColor);
}
DrawBackground(g);
}
private void DrawBackground(Graphics g)
{
this.numPoints = 0;
if (this.Width > 0 && this.Height > 0) {
if (this.showBorder) {
Pen p = new Pen(SystemColors.ActiveBorder);
g.DrawRectangle(p, 0, 0, this.Width - 1, this.Height - 1);
p.Dispose();
}
int iBoxSize = checked((int)(this.Height * 0.75));
int iBoxLeft = iBoxSize / 2;
if (iBoxSize > 3) {
do {
Rectangle r = new Rectangle(iBoxLeft, 0, this.Height - 1, this.Height - 1);
if (r.Left + r.Width > this.Width) {
break;
}
if (this.numPoints == this.position) {
PositionIndicator(r, g);
}else {
Rectangle r2 = new Rectangle(r.Left + 3, r.Top + 3, r.Width - 6, r.Height - 6);
if ((this.normalImage != null) && (this.progressType == ProgressType.Graphic)) {
g.DrawImage(this.normalImage, r2);
} else {
Brush b = new SolidBrush(this.ForeColor);
g.FillRectangle(b, r2);
b.Dispose();
}
}
iBoxLeft += checked((int)(iBoxSize * 1.5));
this.numPoints += 1;
}
while (true);
}
}
}
private void PositionIndicator(Rectangle Rect, Graphics g)
{
if ((this.pointImage != null) && (this.progressType == ProgressType.Graphic)) {
g.DrawImage(this.pointImage, Rect);
}else {
Brush b = new SolidBrush(indicatorColor);
if (this.ProgressBoxStyle == ProgressBoxStyle.SolidSameSize) {
g.FillRectangle(b, Rect.Left + 3, Rect.Top + 3, Rect.Width - 5, Rect.Height - 5);
}else if (this.ProgressBoxStyle == ProgressBoxStyle.BoxAround) {
Pen p = new Pen(indicatorColor);
g.DrawRectangle(p, Rect);
p.Dispose();
g.FillRectangle(b, Rect.Left + 3, Rect.Top + 3, Rect.Width - 5, Rect.Height - 5);
}else if (this.ProgressBoxStyle == ProgressBoxStyle.SolidBigger) {
g.FillRectangle(b, Rect);
}else if(this.ProgressBoxStyle == ProgressBoxStyle.SolidSmaller) {
g.FillRectangle(b, Rect.Left + 5, Rect.Top + 5, Rect.Width - 9, Rect.Height - 9);
}
b.Dispose();
}
}
#endregion
}
///
/// The style of moving of the progress indicator.
///
public enum ProgressStyle
{
///
/// The progress indicator moves from left to right.
///
LeftToRight,
///
/// The progress indicator moves left and right.
///
LeftAndRight
}
///
/// The type of the progress indicator.
///
public enum ProgressType
{
///
/// Colored rectangle box as progress indicator.
///
Box,
///
/// Graphical progress indicator.
///
Graphic
}
///
/// The style of the active progress indicator (in box mode).
///
public enum ProgressBoxStyle
{
///
/// Active box has same size as other boxes.
///
SolidSameSize,
///
/// Active box has same size as other boxes but a rectangle
/// around it.
///
BoxAround,
///
/// Active box is bigger than the other boxes.
///
SolidBigger,
///
/// Active box is smaller than the other boxes.
///
SolidSmaller,
}
}