Code cleanup; added one of my long-winded explanations for why the progress spinner does things the way it's doing

git-svn-id: file:///srv/devel/repo-conversion/nuwi@51 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
Markus Ewald 2019-02-13 11:31:05 +00:00
parent 7439c31390
commit bb672c59f8

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Data; using System.Data;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq; using System.Linq;
using System.Windows.Forms; using System.Windows.Forms;
@ -104,6 +105,26 @@ namespace Nuclex.Windows.Forms.Controls {
/// <summary>Called when the control should redraw itself</summary> /// <summary>Called when the control should redraw itself</summary>
/// <param name="arguments">Provides access to the drawing surface and tools</param> /// <param name="arguments">Provides access to the drawing surface and tools</param>
protected override void OnPaint(PaintEventArgs arguments) { protected override void OnPaint(PaintEventArgs arguments) {
paintControlsBehindMe(arguments);
paintAnimatedDots(arguments);
}
/// <summary>Forcefully redraws the controls below this one</summary>
/// <param name="arguments">Provides access to the drawing surface and tools</param>
/// <remarks>
/// <para>
/// WinForms has very poor transparency support. A transparent control will only
/// be transparent to its immediate parent (so the parent needs to be a container
/// control and hold the transparent control as its preferrably only child).
/// </para>
/// <para>
/// Worse yet, if you manually establish this relationship in your .Designer.cs
/// file, the Visual Studio WinForms designer will dismantle it next time you
/// edit something. This method fixes those issues by repainting all controls
/// that are behind this control and whose bounding box intersect this control.
/// </para>
/// </remarks>
private void paintControlsBehindMe(PaintEventArgs arguments) {
if(Parent != null && this.BackColor == Color.Transparent) { if(Parent != null && this.BackColor == Color.Transparent) {
using(var bmp = new Bitmap(Parent.Width, Parent.Height)) { using(var bmp = new Bitmap(Parent.Width, Parent.Height)) {
Parent.Controls.Cast<Control>() Parent.Controls.Cast<Control>()
@ -116,7 +137,11 @@ namespace Nuclex.Windows.Forms.Controls {
arguments.Graphics.DrawImage(bmp, -Left, -Top); arguments.Graphics.DrawImage(bmp, -Left, -Top);
} }
} }
}
/// <summary>Draws a simple animated dots animation</summary>
/// <param name="arguments">Provides access to the drawing surface and tools</param>
private void paintAnimatedDots(PaintEventArgs arguments) {
if(this.dotOutlinePen == null) { if(this.dotOutlinePen == null) {
this.dotOutlinePen = new Pen(this.dotOutlineColor); this.dotOutlinePen = new Pen(this.dotOutlineColor);
} }
@ -124,30 +149,40 @@ namespace Nuclex.Windows.Forms.Controls {
this.dotFillBrush = new SolidBrush(this.dotFillColor); this.dotFillBrush = new SolidBrush(this.dotFillColor);
} }
//e.Graphics.SmoothingMode = SmoothingMode.HighQuality; SmoothingMode prevousSmoothingMode = arguments.Graphics.SmoothingMode;
arguments.Graphics.SmoothingMode = SmoothingMode.HighQuality;
try {
int diameter = Math.Min(Width, Height);
PointF center = new PointF(diameter / 2.0f, diameter / 2.0f);
int diameter = Math.Min(Width, Height); int bigRadius = diameter / 2 - DotRadius - (DotCount - 1) * ScaleFactor;
PointF center = new PointF(diameter / 2.0f, diameter / 2.0f);
int bigRadius = diameter / 2 - DotRadius - (DotCount - 1) * ScaleFactor; // Draw the dots
float unitAngle = 360.0f / DotCount;
for(int index = 0; index < DotCount; ++index) {
int dotIndex = (index + leadingDotIndex) % DotCount;
float unitAngle = 360 / DotCount; var dotPosition = new PointF(
center.X + (float)(bigRadius * Math.Cos(unitAngle * dotIndex * Math.PI / 180.0f)),
center.Y + (float)(bigRadius * Math.Sin(unitAngle * dotIndex * Math.PI / 180.0f))
);
for(int index = 0; index < DotCount; ++index) { int currentDotRadius = DotRadius + index * ScaleFactor;
int dotIndex = (index + leadingDotIndex) % DotCount;
var dotPosition = new PointF( var corner = new PointF(
center.X + (float)(bigRadius * Math.Cos(unitAngle * dotIndex * Math.PI / 180)), dotPosition.X - currentDotRadius, dotPosition.Y - currentDotRadius
center.Y + (float)(bigRadius * Math.Sin(unitAngle * dotIndex * Math.PI / 180)) );
); arguments.Graphics.FillEllipse(
this.dotFillBrush, corner.X, corner.Y, 2 * currentDotRadius, 2 * currentDotRadius
int currentDotRadius = DotRadius + index * ScaleFactor; );
arguments.Graphics.DrawEllipse(
PointF c1 = new PointF(dotPosition.X - currentDotRadius, dotPosition.Y - currentDotRadius); this.dotOutlinePen, corner.X, corner.Y, 2 * currentDotRadius, 2 * currentDotRadius
arguments.Graphics.FillEllipse(this.dotFillBrush, c1.X, c1.Y, 2 * currentDotRadius, 2 * currentDotRadius); );
arguments.Graphics.DrawEllipse(this.dotOutlinePen, c1.X, c1.Y, 2 * currentDotRadius, 2 * currentDotRadius); }
}
finally {
arguments.Graphics.SmoothingMode = prevousSmoothingMode;
} }
} }
/// <summary>Called when the animation timer ticks to update the animation state</summary> /// <summary>Called when the animation timer ticks to update the animation state</summary>