using System;
using System.Drawing;
using System.Collections;
using System.Diagnostics;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
namespace Scripting
{
public class ProgressbarForm : System.Windows.Forms.Form
{
#region Public interface...
public void Increment()
{
position++;
if (position > maxPosition)
{
position = 0;
}
CalcUnits();
using(Graphics g = CreateGraphics())
{
DrawProgressBar(g, true);
}
}
public void UpdateProgress()
{
CalcUnits();
using(Graphics g = CreateGraphics())
{
if (g != null)
{
DrawProgressBar(g, true);
}
}
}
public void Setup(int position, int maxPosition, int unitsInGrpup, int autoIncrementDelay) // -1 means no autoincrementing
{
this.position = position;
this.maxPosition = maxPosition;
this.unitsInGrpup = unitsInGrpup;
this.currCount = 0;
this.extraPositions = 0;
this.autoIncrementDelay = autoIncrementDelay;
System.Diagnostics.Debug.Assert(maxPosition - unitsInGrpup >= unitsInGrpup);
CalcUnits();
}
public int AutoIncrementDelay { set { autoIncrementDelay = value; UpdateProgress(); } get { return autoIncrementDelay; } }
public int Position { set { position = value; UpdateProgress(); } get { return position; } }
public int MaxPosition { set { maxPosition = value; UpdateProgress(); } get { return maxPosition; } }
public int UnitsInGrpup { set { unitsInGrpup = value; UpdateProgress(); } get { return unitsInGrpup; }}
#endregion
//drawing and calculating rutines
private void Init()
{
progressRectangle = ClientRectangle;
progressRectangle.Inflate(-4, -4);
unitsRectangle = progressRectangle;
unitsRectangle.Inflate(-10, -2);
RectangleF rcUnit0 = unitsRectangle;
float unitWidth = (float)(unitsRectangle.Width / (maxPosition - unitsInGrpup + 1));
rcUnit0.Width = unitWidth;
float offset = ((float)(unitsRectangle.Width - ((maxPosition - unitsInGrpup + 1) * unitWidth))) / (float)2.0;
rcUnit0.Offset(offset, 0); //center units in clientRect
rcUnit0.Inflate(-1, -4); //shrink it a little
unitRects.Clear();
for (int i = 0; i < (maxPosition - unitsInGrpup + 1); i++)
{
RectangleF rcUnit = rcUnit0;
rcUnit.X += (float)i * (float)unitWidth;
unitRects.Add(rcUnit);
}
if (autoIncrementDelay > 0)
{
timer1.Enabled = true;
timer1.Interval = autoIncrementDelay;
}
else
{
timer1.Enabled = false;
}
}
private void CalcUnits()
{
int maxUnits = maxPosition;
if (position == 0)
{
currCount = -1;
extraPositions = 0;
}
else
{
currCount = position - 1;
if (currCount < unitsInGrpup)
{
extraPositions = currCount;
}
else
{
extraPositions = unitsInGrpup - 1;
if (currCount > maxUnits - unitsInGrpup)
{
extraPositions -= unitsInGrpup - (maxUnits - currCount);
currCount = maxUnits - unitsInGrpup;
}
}
}
}
private void DrawProgressBar(Graphics g, bool unitsOnly)
{
Bitmap myBitmap = new Bitmap((int)ClientRectangle.Width, (int)ClientRectangle.Height, g);
using(Graphics memSurface = Graphics.FromImage(myBitmap))
{
RectangleF rc = progressRectangle;
if (!unitsOnly)
{
using (Brush blackBrush = new SolidBrush(Color.Black))
{
memSurface.FillRectangle(blackBrush, ClientRectangle);
}
using (Pen whitePan = new Pen(Color.White, 3))
{
using (GraphicsPath path = RoundRectangle(rc))
{
memSurface.DrawPath(whitePan, path);
}
}
}
using (Brush darkBrush = new SolidBrush(Color.FromArgb(18, 1, 100)))
{
rc.Inflate(-2, -2);
using (GraphicsPath path = RoundRectangle(rc))
{
memSurface.FillPath(darkBrush, path);
}
}
DrawUnits(memSurface);
}
g.DrawImage(myBitmap, 0, 0);
myBitmap.Dispose();
}
private void DrawUnits(Graphics g)
{
int index = currCount;
if (index != -1)
{
using (Brush unitBrush = CreateUnitBrash((RectangleF)unitRects[index]))
{
g.FillRectangle(unitBrush, (RectangleF)unitRects[index]);
for (int i = extraPositions; i > 0; i--)
{
g.FillRectangle(unitBrush, (RectangleF)unitRects[index - i]);
}
}
}
}
private Brush CreateUnitBrash(RectangleF rc)
{
bool useGradient = true;
if (useGradient)
{
using (GraphicsPath path = new GraphicsPath())
{
RectangleF rc1 = unitsRectangle;
rc1.Offset(0, -10); //shift "reflection spot" a bit up from the center
rc1.Height += 10;
path.AddRectangle(rc1);
PathGradientBrush pthGrBrush = new PathGradientBrush(path);
pthGrBrush.SurroundColors = new Color[]{Color.Green};
pthGrBrush.CenterColor = Color.LawnGreen;
pthGrBrush.FocusScales = new PointF(1.0f, 0.15f);
return pthGrBrush;
}
// int unitVOffest = 2;
// LinearGradientBrush linGrBrush = new LinearGradientBrush(
// unitsRectangle,
// Color.FromArgb(245, 255, 245),
// Color.FromArgb(8,255,0), LinearGradientMode.Vertical);
// //linGrBrush.GammaCorrection = true;
// return linGrBrush;
}
else
return new SolidBrush(Color.FromArgb(8,255,0));
}
private GraphicsPath RoundRectangle(RectangleF rc)
{
float radius = rc.Height / 2.0f;
PointF point1 = new PointF(rc.X + radius, rc.Y);
PointF point2 = new PointF(rc.X + rc.Width - radius, rc.Y);
PointF point3 = new PointF(rc.X + rc.Width - radius, rc.Y + rc.Height);
PointF point4 = new PointF(rc.X + radius, rc.Y + rc.Height);
GraphicsPath myPath = new GraphicsPath();
myPath.AddLine(point1, point2);
myPath.AddArc(point2.X - radius, point2.Y, radius*2.0f, rc.Height, 270, 180);
myPath.AddLine(point3, point4);
myPath.AddArc(point4.X - radius, point1.Y, radius*2.0f, rc.Height, 90, 180);
return myPath;
}
//internal progressbar data
private int currCount;
private int extraPositions;
private RectangleF progressRectangle;
private RectangleF unitsRectangle;
private int position;
private int maxPosition;
private int unitsInGrpup;
private int autoIncrementDelay;
private ArrayList unitRects;
//form data and methods
private System.Windows.Forms.Timer timer1;
private System.ComponentModel.IContainer components;
public ProgressbarForm(string title)
{
InitializeComponent();
if (title != null)
{
this.Text = title;
}
}
static public void ShowContinuous(string title)
{
using(ProgressbarForm dlg = new ProgressbarForm(title))
{
dlg.Setup(0, 20, 4, 70);
dlg.ShowDialog();
}
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.timer1 = new System.Windows.Forms.Timer(this.components);
//
// timer1
//
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
// ProgressbarForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(258, 32);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "ProgressbarForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Progressbar";
this.Click += new System.EventHandler(this.ProgressbarForm_Click);
this.Load += new System.EventHandler(this.ProgressbarForm_Load);
this.Paint += new System.Windows.Forms.PaintEventHandler(this.ProgressbarForm_Paint);
}
#endregion
private void ProgressbarForm_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
DrawProgressBar(e.Graphics, false);
}
private void ProgressbarForm_Load(object sender, System.EventArgs e)
{
unitRects = new ArrayList();
Init();
}
private void timer1_Tick(object sender, System.EventArgs e)
{
Increment();
}
private void ProgressbarForm_Click(object sender, System.EventArgs e)
{
//timer1.Enabled = !timer1.Enabled; for testing only
}
}
class Script
{
static public void Main(string[] args)
{
ProgressbarForm.ShowContinuous("Progress");
}
}
}