using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using System.Collections.Generic; namespace ProgressODoom { /// [ToolboxBitmapAttribute(typeof(ProgressODoom.ProgressBarEx), "Icons.ProgressBarEx.ico")] public class ProgressBarEx : AbstractProgressBar { protected IProgressBackgroundPainter backgroundpainter; protected IProgressPainter progresspainter; protected IProgressBorderPainter borderpainter; public ProgressBarEx() { backgroundpainter = new PlainBackgroundPainter(); progresspainter = new PlainProgressPainter(Color.Gold); borderpainter = new PlainBorderPainter(); } /// [Category("Painters"), Description("Paints this progress bar's background"), Browsable(true)] public IProgressBackgroundPainter BackgroundPainter { get { return this.backgroundpainter; } set { this.backgroundpainter = value; this.backgroundpainter.PropertiesChanged += new EventHandler(component_PropertiesChanged); this.Invalidate(); } } /// /// /// protected virtual void component_PropertiesChanged(object sender, EventArgs e) { this.Invalidate(); } /// [Category("Painters"), Description("Paints this progress bar's progress"), Browsable(true)] public IProgressPainter ProgressPainter { get { return this.progresspainter; } set { if (!(value is IAnimatedProgressPainter) && base.ProgressType == ProgressType.Animated) { base.ProgressType = ProgressType.Smooth; } this.progresspainter = value; if (this.progresspainter is AbstractProgressPainter) { ((AbstractProgressPainter)this.progresspainter).padding = base.ProgressPadding; } this.progresspainter.PropertiesChanged += new EventHandler(component_PropertiesChanged); this.Invalidate(); } } /// [Category("Progress"), Description("Gets or sets the type of progress"), Browsable(true)] public override ProgressType ProgressType { get { return base.type; } set { if (value == ProgressType.Animated && !(progresspainter is IAnimatedProgressPainter)) { throw new ArgumentException("Animated is not available with the current Progress Painter"); } this.type = value; } } /// [Category("Painters"), Description("Paints this progress bar's border"), Browsable(true)] public IProgressBorderPainter BorderPainter { get { return this.borderpainter; } set { this.borderpainter = value; this.borderpainter.PropertiesChanged += new EventHandler(component_PropertiesChanged); ResizeProgress(); this.Invalidate(); } } protected override void ResizeProgress() { if (base.ProgressType != ProgressType.Smooth) { return; } Rectangle newprog = base.borderbox; //newprog.Inflate(this.borderpainter.BorderWidth, this.borderpainter.BorderWidth); newprog.Offset(this.borderpainter.BorderWidth, this.borderpainter.BorderWidth); newprog.Size = new Size(newprog.Size.Width - this.borderpainter.BorderWidth, newprog.Size.Height - this.borderpainter.BorderWidth); base.backbox = newprog; int val = value; if (val > 0) { val++; } int progWidth = maximum > 0 ? (backbox.Width * val / maximum) : 1; if (value >= maximum && maximum > 0) { progWidth = backbox.Width; } /*else if (value > 0) { progWidth++; }*/ newprog.Inflate(-base.ProgressPadding, -base.ProgressPadding); newprog.Width = progWidth - (base.ProgressPadding * 2); //newprog.Offset(base.ProgressPadding, base.ProgressPadding); //newprog = new Rectangle(backbox.X + base.ProgressPadding, backbox.Y + base.ProgressPadding, progWidth - (base.ProgressPadding * 2), backbox.Height - (base.ProgressPadding * 2)); base.progressbox = newprog; } #region Animation public void StartAnimation() { if (running) { return; } IAnimatedProgressPainter iapp = this.progresspainter as IAnimatedProgressPainter; if (iapp == null) { return; } iapp.Animating = true; running = true; timerMethod = new EventHandler(DoAnimation); timer.Interval = iapp.AnimationSpeed; timer.Tick += timerMethod; timer.Enabled = true; } public void StopAnimation() { timer.Enabled = false; timer.Tick -= timerMethod; running = false; IAnimatedProgressPainter iapp = this.progresspainter as IAnimatedProgressPainter; if (iapp == null) { return; } iapp.Animating = false; } private void DoAnimation(object sender, EventArgs e) { IAnimatedProgressPainter iapp = this.progresspainter as IAnimatedProgressPainter; if (iapp == null) { return; } //Rectangle newprog = base.borderbox; //newprog.Offset(this.borderpainter.BorderWidth, this.borderpainter.BorderWidth); //newprog.Size = new Size(newprog.Size.Width - this.borderpainter.BorderWidth, newprog.Size.Height - this.borderpainter.BorderWidth); ////int progWidth = (int)(((float)marqueePercentage * (float)backbox.Width) / 100f); //int progWidth = (int)(((float)marqueePercentage * (float)backbox.Width) / 100f); //newprog.Inflate(-base.ProgressPadding, -base.ProgressPadding); //newprog.Width = progWidth - (base.ProgressPadding * 2); //base.progressbox = newprog; ////iapp.AnimateFrame(newprog, g, ref marqueeX); this.Invalidate(); this.Refresh(); } #endregion #region Marquee private bool running = false; private Timer timer = new Timer(); private EventHandler timerMethod; /// public override void MarqueeStart() { if (running) { return; } running = true; switch (base.ProgressType) { case ProgressType.MarqueeWrap: timerMethod = new EventHandler(DoMarqueeWrap); break; case ProgressType.MarqueeBounce: timerMethod = new EventHandler(DoMarqueeBounce); break; case ProgressType.MarqueeBounceDeep: timerMethod = new EventHandler(DoMarqueeDeep); break; } timer.Interval = base.marqueeSpeed; timer.Tick += timerMethod; timer.Enabled = true; } private int marqueeX = 0; private void DoMarqueeWrap(object sender, EventArgs e) { Rectangle newprog = base.borderbox; newprog.Offset(this.borderpainter.BorderWidth, this.borderpainter.BorderWidth); newprog.Size = new Size(newprog.Size.Width - this.borderpainter.BorderWidth, newprog.Size.Height - this.borderpainter.BorderWidth); int progWidth = (int)(((float)marqueePercentage * (float)backbox.Width) / 100f); marqueeX += marqueeStep; if (marqueeX > backbox.Width) { marqueeX = 0 - progWidth; } newprog.Inflate(-base.ProgressPadding, -base.ProgressPadding); newprog.Width = progWidth - (base.ProgressPadding * 2); newprog.X += marqueeX; int leftBoundry = backbox.X + this.borderpainter.BorderWidth + base.ProgressPadding; int rightBoundry = backbox.X + backbox.Width - (this.borderpainter.BorderWidth + base.ProgressPadding); if (marqueeX <= leftBoundry) { newprog.Width -= leftBoundry - marqueeX; newprog.X = leftBoundry; } else if (marqueeX + newprog.Width >= rightBoundry) { newprog.Width -= (marqueeX + newprog.Width + base.ProgressPadding) - rightBoundry; } base.progressbox = newprog; this.Invalidate(); this.Refresh(); } private bool marqueeForward = true; private void DoMarqueeBounce(object sender, EventArgs e) { Rectangle newprog = base.borderbox; newprog.Offset(this.borderpainter.BorderWidth, this.borderpainter.BorderWidth); newprog.Size = new Size(newprog.Size.Width - this.borderpainter.BorderWidth, newprog.Size.Height - this.borderpainter.BorderWidth); int progWidth = (int)(((float)marqueePercentage * (float)backbox.Width) / 100f); if (marqueeForward) { marqueeX += marqueeStep; } else { marqueeX -= marqueeStep; } newprog.Inflate(-base.ProgressPadding, -base.ProgressPadding); newprog.Width = progWidth - (base.ProgressPadding * 2); newprog.X += marqueeX; int leftBoundry = backbox.X + this.borderpainter.BorderWidth + base.ProgressPadding; int rightBoundry = backbox.X + backbox.Width - (this.borderpainter.BorderWidth + base.ProgressPadding); if (marqueeX + progWidth >= rightBoundry) { marqueeForward = false; } else if (marqueeX <= leftBoundry) { marqueeForward = true; } base.progressbox = newprog; this.Invalidate(); this.Refresh(); } private void DoMarqueeDeep(object sender, EventArgs e) { Rectangle newprog = base.borderbox; newprog.Offset(this.borderpainter.BorderWidth, this.borderpainter.BorderWidth); newprog.Size = new Size(newprog.Size.Width - this.borderpainter.BorderWidth, newprog.Size.Height - this.borderpainter.BorderWidth); int progWidth = (int)(((float)marqueePercentage * (float)backbox.Width) / 100f); if (marqueeForward) { marqueeX += marqueeStep; } else { marqueeX -= marqueeStep; } if (marqueeX > backbox.Width) { marqueeForward = false; } else if (marqueeX < backbox.X - progWidth) { marqueeForward = true; } newprog.Inflate(-base.ProgressPadding, -base.ProgressPadding); newprog.Width = progWidth - (base.ProgressPadding * 2); newprog.X += marqueeX; int leftBoundry = backbox.X + this.borderpainter.BorderWidth + base.ProgressPadding; int rightBoundry = backbox.X + backbox.Width - (this.borderpainter.BorderWidth + base.ProgressPadding); if (marqueeX <= leftBoundry) { newprog.Width -= leftBoundry - marqueeX; newprog.X = leftBoundry; } else if (marqueeX + newprog.Width >= rightBoundry) { newprog.Width -= (marqueeX + newprog.Width + base.ProgressPadding) - rightBoundry; } base.progressbox = newprog; this.Invalidate(); this.Refresh(); } /// public override void MarqueePause() { running = false; timer.Enabled = false; timer.Tick -= timerMethod; } /// public override void MarqueeStop() { Rectangle newprog = base.borderbox; newprog.Offset(this.borderpainter.BorderWidth, this.borderpainter.BorderWidth); newprog.Size = new Size(newprog.Size.Width - this.borderpainter.BorderWidth, newprog.Size.Height - this.borderpainter.BorderWidth); newprog.Inflate(-base.ProgressPadding, -base.ProgressPadding); newprog.Width = 1; base.progressbox = newprog; running = false; timer.Enabled = false; timer.Tick -= timerMethod; marqueeX = 0; this.Invalidate(); } #endregion /// /// protected override void Dispose(bool disposing) { base.Dispose(disposing); if (running) { running = false; } } /// /// protected override void OnResize(EventArgs e) { base.OnResize(e); ResizeProgress(); if (this.backgroundpainter != null) { this.backgroundpainter.Resize(borderbox); } if (this.progresspainter != null) { this.progresspainter.Resize(borderbox); } if (this.borderpainter != null) { this.borderpainter.Resize(borderbox); } } /// /// protected override void PaintBackground(Graphics g) { if (this.backgroundpainter != null) { this.backgroundpainter.PaintBackground(backbox, g); } } /// /// protected override void PaintProgress(Graphics g) { if (this.progresspainter != null) { this.progresspainter.PaintProgress(progressbox, g); } } /// /// protected override void PaintText(Graphics g) { if (base.ProgressType != ProgressType.Smooth) { return; } Brush b = new SolidBrush(ForeColor); SizeF sf = g.MeasureString(Text, Font, Convert.ToInt32(Width), StringFormat.GenericDefault); float m = sf.Width; float x = (Width / 2) - (m / 2); float w = (Width / 2) + (m / 2); float h = (float)borderbox.Height - (2f * (float)this.borderpainter.BorderWidth); float y = (float)this.borderpainter.BorderWidth + ((h - sf.Height) / 2f); g.DrawString(Text, Font, b, RectangleF.FromLTRB(x, y, w, Height - 1), StringFormat.GenericDefault); } /// /// protected override void PaintBorder(Graphics g) { if (this.borderpainter != null) { this.borderpainter.PaintBorder(borderbox, g); } } } }