initial commit
This commit is contained in:
@@ -0,0 +1,471 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Text;
|
||||
using System.Windows.Forms;
|
||||
using WinFormAnimation;
|
||||
|
||||
namespace Server.Helper;
|
||||
|
||||
[ToolboxItem(true)]
|
||||
[ToolboxBitmap(typeof(CircularProgressBar), "CircularProgressBar.bmp")]
|
||||
[DefaultBindingProperty("Value")]
|
||||
public class CircularProgressBar : ProgressBar
|
||||
{
|
||||
private readonly Animator _animator;
|
||||
|
||||
private int? _animatedStartAngle;
|
||||
|
||||
private float? _animatedValue;
|
||||
|
||||
private AnimationFunctions.Function _animationFunction;
|
||||
|
||||
private Brush _backBrush;
|
||||
|
||||
private KnownAnimationFunctions _knownAnimationFunction;
|
||||
|
||||
private ProgressBarStyle? _lastStyle;
|
||||
|
||||
private int _lastValue;
|
||||
|
||||
[Category("Behavior")]
|
||||
public KnownAnimationFunctions AnimationFunction
|
||||
{
|
||||
get
|
||||
{
|
||||
return _knownAnimationFunction;
|
||||
}
|
||||
set
|
||||
{
|
||||
_animationFunction = AnimationFunctions.FromKnown(value);
|
||||
_knownAnimationFunction = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Behavior")]
|
||||
public int AnimationSpeed { get; set; }
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
[Browsable(false)]
|
||||
public AnimationFunctions.Function CustomAnimationFunction
|
||||
{
|
||||
private get
|
||||
{
|
||||
return _animationFunction;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException("value");
|
||||
}
|
||||
_knownAnimationFunction = KnownAnimationFunctions.None;
|
||||
_animationFunction = value;
|
||||
}
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Always)]
|
||||
[Browsable(true)]
|
||||
public override Font Font
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.Font;
|
||||
}
|
||||
set
|
||||
{
|
||||
base.Font = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Appearance")]
|
||||
public Color InnerColor { get; set; }
|
||||
|
||||
[Category("Layout")]
|
||||
public int InnerMargin { get; set; }
|
||||
|
||||
[Category("Layout")]
|
||||
public int InnerWidth { get; set; }
|
||||
|
||||
[Category("Appearance")]
|
||||
public Color OuterColor { get; set; }
|
||||
|
||||
[Category("Layout")]
|
||||
public int OuterMargin { get; set; }
|
||||
|
||||
[Category("Layout")]
|
||||
public int OuterWidth { get; set; }
|
||||
|
||||
[Category("Appearance")]
|
||||
public Color ProgressColor { get; set; }
|
||||
|
||||
[Category("Layout")]
|
||||
public int ProgressWidth { get; set; }
|
||||
|
||||
[Category("Appearance")]
|
||||
public Font SecondaryFont { get; set; }
|
||||
|
||||
[Category("Layout")]
|
||||
public int StartAngle { get; set; }
|
||||
|
||||
[Category("Appearance")]
|
||||
public Color SubscriptColor { get; set; }
|
||||
|
||||
[Category("Layout")]
|
||||
public Padding SubscriptMargin { get; set; }
|
||||
|
||||
[Category("Appearance")]
|
||||
public string SubscriptText { get; set; }
|
||||
|
||||
[Category("Appearance")]
|
||||
public Color SuperscriptColor { get; set; }
|
||||
|
||||
[Category("Layout")]
|
||||
public Padding SuperscriptMargin { get; set; }
|
||||
|
||||
[Category("Appearance")]
|
||||
public string SuperscriptText { get; set; }
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Always)]
|
||||
[Browsable(true)]
|
||||
public override string Text
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.Text;
|
||||
}
|
||||
set
|
||||
{
|
||||
base.Text = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Layout")]
|
||||
public Padding TextMargin { get; set; }
|
||||
|
||||
public CircularProgressBar()
|
||||
{
|
||||
SetStyle(ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, value: true);
|
||||
_animator = (base.DesignMode ? null : new Animator());
|
||||
AnimationFunction = KnownAnimationFunctions.Liner;
|
||||
AnimationSpeed = 500;
|
||||
base.MarqueeAnimationSpeed = 2000;
|
||||
StartAngle = 270;
|
||||
_lastValue = base.Value;
|
||||
BackColor = Color.Transparent;
|
||||
ForeColor = Color.FromArgb(64, 64, 64);
|
||||
DoubleBuffered = true;
|
||||
Font = new Font(Font.FontFamily, 72f, FontStyle.Bold);
|
||||
SecondaryFont = new Font(Font.FontFamily, (float)((double)Font.Size * 0.5), FontStyle.Regular);
|
||||
OuterMargin = -25;
|
||||
OuterWidth = 26;
|
||||
OuterColor = Color.Gray;
|
||||
ProgressWidth = 25;
|
||||
ProgressColor = Color.FromArgb(255, 128, 0);
|
||||
InnerMargin = 2;
|
||||
InnerWidth = -1;
|
||||
InnerColor = Color.FromArgb(224, 224, 224);
|
||||
TextMargin = new Padding(8, 8, 0, 0);
|
||||
base.Value = 68;
|
||||
SuperscriptMargin = new Padding(10, 35, 0, 0);
|
||||
SuperscriptColor = Color.FromArgb(166, 166, 166);
|
||||
SuperscriptText = "°C";
|
||||
SubscriptMargin = new Padding(10, -35, 0, 0);
|
||||
SubscriptColor = Color.FromArgb(166, 166, 166);
|
||||
SubscriptText = ".23";
|
||||
base.Size = new Size(320, 320);
|
||||
}
|
||||
|
||||
private static PointF AddPoint(PointF p, int v)
|
||||
{
|
||||
p.X += v;
|
||||
p.Y += v;
|
||||
return p;
|
||||
}
|
||||
|
||||
private static SizeF AddSize(SizeF s, int v)
|
||||
{
|
||||
s.Height += v;
|
||||
s.Width += v;
|
||||
return s;
|
||||
}
|
||||
|
||||
private static Rectangle ToRectangle(RectangleF rect)
|
||||
{
|
||||
return new Rectangle((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height);
|
||||
}
|
||||
|
||||
protected override void OnLocationChanged(EventArgs e)
|
||||
{
|
||||
base.OnLocationChanged(e);
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!base.DesignMode)
|
||||
{
|
||||
if (base.Style == ProgressBarStyle.Marquee)
|
||||
{
|
||||
InitializeMarquee(_lastStyle != base.Style);
|
||||
}
|
||||
else
|
||||
{
|
||||
InitializeContinues(_lastStyle != base.Style);
|
||||
}
|
||||
_lastStyle = base.Style;
|
||||
}
|
||||
if (_backBrush == null)
|
||||
{
|
||||
RecreateBackgroundBrush();
|
||||
}
|
||||
StartPaint(e.Graphics);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnParentBackColorChanged(EventArgs e)
|
||||
{
|
||||
RecreateBackgroundBrush();
|
||||
}
|
||||
|
||||
protected override void OnParentBackgroundImageChanged(EventArgs e)
|
||||
{
|
||||
RecreateBackgroundBrush();
|
||||
}
|
||||
|
||||
protected override void OnParentChanged(EventArgs e)
|
||||
{
|
||||
if (base.Parent != null)
|
||||
{
|
||||
base.Parent.Invalidated -= ParentOnInvalidated;
|
||||
base.Parent.Resize -= ParentOnResize;
|
||||
}
|
||||
base.OnParentChanged(e);
|
||||
if (base.Parent != null)
|
||||
{
|
||||
base.Parent.Invalidated += ParentOnInvalidated;
|
||||
base.Parent.Resize += ParentOnResize;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnStyleChanged(EventArgs e)
|
||||
{
|
||||
base.OnStyleChanged(e);
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
protected virtual void InitializeContinues(bool firstTime)
|
||||
{
|
||||
if (_lastValue == base.Value && !firstTime)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_lastValue = base.Value;
|
||||
_animator.Stop();
|
||||
_animatedStartAngle = null;
|
||||
if (AnimationSpeed <= 0)
|
||||
{
|
||||
_animatedValue = base.Value;
|
||||
Invalidate();
|
||||
return;
|
||||
}
|
||||
_animator.Paths = new Path(_animatedValue ?? ((float)base.Value), base.Value, (ulong)AnimationSpeed, CustomAnimationFunction).ToArray();
|
||||
_animator.Repeat = false;
|
||||
_animator.Play(new SafeInvoker<float>(delegate(float v)
|
||||
{
|
||||
try
|
||||
{
|
||||
_animatedValue = v;
|
||||
Invalidate();
|
||||
}
|
||||
catch
|
||||
{
|
||||
_animator.Stop();
|
||||
}
|
||||
}, this));
|
||||
}
|
||||
|
||||
protected virtual void InitializeMarquee(bool firstTime)
|
||||
{
|
||||
if (!firstTime && (_animator.ActivePath == null || (_animator.ActivePath.Duration == (ulong)base.MarqueeAnimationSpeed && _animator.ActivePath.Function == CustomAnimationFunction)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_animator.Stop();
|
||||
_animatedValue = null;
|
||||
if (AnimationSpeed <= 0)
|
||||
{
|
||||
_animatedStartAngle = 0;
|
||||
Invalidate();
|
||||
return;
|
||||
}
|
||||
_animator.Paths = new Path(0f, 359f, (ulong)base.MarqueeAnimationSpeed, CustomAnimationFunction).ToArray();
|
||||
_animator.Repeat = true;
|
||||
_animator.Play(new SafeInvoker<float>(delegate(float v)
|
||||
{
|
||||
try
|
||||
{
|
||||
_animatedStartAngle = (int)(v % 360f);
|
||||
Invalidate();
|
||||
}
|
||||
catch
|
||||
{
|
||||
_animator.Stop();
|
||||
}
|
||||
}, this));
|
||||
}
|
||||
|
||||
protected virtual void ParentOnInvalidated(object sender, InvalidateEventArgs invalidateEventArgs)
|
||||
{
|
||||
RecreateBackgroundBrush();
|
||||
}
|
||||
|
||||
protected virtual void ParentOnResize(object sender, EventArgs eventArgs)
|
||||
{
|
||||
RecreateBackgroundBrush();
|
||||
}
|
||||
|
||||
protected virtual void RecreateBackgroundBrush()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
_backBrush?.Dispose();
|
||||
_backBrush = new SolidBrush(BackColor);
|
||||
if (BackColor.A == byte.MaxValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (base.Parent != null && base.Parent.Width > 0 && base.Parent.Height > 0)
|
||||
{
|
||||
using (Bitmap bitmap = new Bitmap(base.Parent.Width, base.Parent.Height))
|
||||
{
|
||||
using (Graphics graphics = Graphics.FromImage(bitmap))
|
||||
{
|
||||
PaintEventArgs e = new PaintEventArgs(graphics, new Rectangle(new Point(0, 0), bitmap.Size));
|
||||
InvokePaintBackground(base.Parent, e);
|
||||
InvokePaint(base.Parent, e);
|
||||
if (BackColor.A > 0)
|
||||
{
|
||||
graphics.FillRectangle(_backBrush, base.Bounds);
|
||||
}
|
||||
}
|
||||
_backBrush = new TextureBrush(bitmap);
|
||||
((TextureBrush)_backBrush).TranslateTransform(-base.Bounds.X, -base.Bounds.Y);
|
||||
return;
|
||||
}
|
||||
}
|
||||
_backBrush = new SolidBrush(Color.FromArgb(255, BackColor));
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void StartPaint(Graphics g)
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
g.TextRenderingHint = TextRenderingHint.AntiAlias;
|
||||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
PointF pointF = AddPoint(Point.Empty, 2);
|
||||
SizeF sizeF = AddSize(base.Size, -4);
|
||||
if (OuterWidth + OuterMargin < 0)
|
||||
{
|
||||
int num = Math.Abs(OuterWidth + OuterMargin);
|
||||
pointF = AddPoint(Point.Empty, num);
|
||||
sizeF = AddSize(base.Size, -2 * num);
|
||||
}
|
||||
if (OuterColor != Color.Empty && OuterColor != Color.Transparent && OuterWidth != 0)
|
||||
{
|
||||
g.FillEllipse(new SolidBrush(OuterColor), new RectangleF(pointF, sizeF));
|
||||
if (OuterWidth >= 0)
|
||||
{
|
||||
pointF = AddPoint(pointF, OuterWidth);
|
||||
sizeF = AddSize(sizeF, -2 * OuterWidth);
|
||||
g.FillEllipse(_backBrush, new RectangleF(pointF, sizeF));
|
||||
}
|
||||
}
|
||||
pointF = AddPoint(pointF, OuterMargin);
|
||||
sizeF = AddSize(sizeF, -2 * OuterMargin);
|
||||
g.FillPie(new SolidBrush(ProgressColor), ToRectangle(new RectangleF(pointF, sizeF)), _animatedStartAngle ?? StartAngle, ((_animatedValue ?? ((float)base.Value)) - (float)base.Minimum) / (float)(base.Maximum - base.Minimum) * 360f);
|
||||
if (ProgressWidth >= 0)
|
||||
{
|
||||
pointF = AddPoint(pointF, ProgressWidth);
|
||||
sizeF = AddSize(sizeF, -2 * ProgressWidth);
|
||||
g.FillEllipse(_backBrush, new RectangleF(pointF, sizeF));
|
||||
}
|
||||
pointF = AddPoint(pointF, InnerMargin);
|
||||
sizeF = AddSize(sizeF, -2 * InnerMargin);
|
||||
if (InnerColor != Color.Empty && InnerColor != Color.Transparent && InnerWidth != 0)
|
||||
{
|
||||
g.FillEllipse(new SolidBrush(InnerColor), new RectangleF(pointF, sizeF));
|
||||
if (InnerWidth >= 0)
|
||||
{
|
||||
pointF = AddPoint(pointF, InnerWidth);
|
||||
sizeF = AddSize(sizeF, -2 * InnerWidth);
|
||||
g.FillEllipse(_backBrush, new RectangleF(pointF, sizeF));
|
||||
}
|
||||
}
|
||||
if (Text == string.Empty)
|
||||
{
|
||||
return;
|
||||
}
|
||||
pointF.X += TextMargin.Left;
|
||||
pointF.Y += TextMargin.Top;
|
||||
sizeF.Width -= TextMargin.Right;
|
||||
sizeF.Height -= TextMargin.Bottom;
|
||||
StringFormat format = new StringFormat((RightToLeft == RightToLeft.Yes) ? StringFormatFlags.DirectionRightToLeft : ((StringFormatFlags)0))
|
||||
{
|
||||
Alignment = StringAlignment.Center,
|
||||
LineAlignment = StringAlignment.Near
|
||||
};
|
||||
SizeF size = g.MeasureString(Text, Font);
|
||||
PointF location = new PointF(pointF.X + (sizeF.Width - size.Width) / 2f, pointF.Y + (sizeF.Height - size.Height) / 2f);
|
||||
if (SubscriptText != string.Empty || SuperscriptText != string.Empty)
|
||||
{
|
||||
float num2 = 0f;
|
||||
SizeF size2 = SizeF.Empty;
|
||||
SizeF size3 = SizeF.Empty;
|
||||
if (SuperscriptText != string.Empty)
|
||||
{
|
||||
size2 = g.MeasureString(SuperscriptText, SecondaryFont);
|
||||
num2 = Math.Max(size2.Width, num2);
|
||||
size2.Width -= SuperscriptMargin.Right;
|
||||
size2.Height -= SuperscriptMargin.Bottom;
|
||||
}
|
||||
if (SubscriptText != string.Empty)
|
||||
{
|
||||
size3 = g.MeasureString(SubscriptText, SecondaryFont);
|
||||
num2 = Math.Max(size3.Width, num2);
|
||||
size3.Width -= SubscriptMargin.Right;
|
||||
size3.Height -= SubscriptMargin.Bottom;
|
||||
}
|
||||
location.X -= num2 / 4f;
|
||||
if (SuperscriptText != string.Empty)
|
||||
{
|
||||
PointF location2 = new PointF(location.X + size.Width - size2.Width / 2f, location.Y - size2.Height * 0.85f);
|
||||
location2.X += SuperscriptMargin.Left;
|
||||
location2.Y += SuperscriptMargin.Top;
|
||||
g.DrawString(SuperscriptText, SecondaryFont, new SolidBrush(SuperscriptColor), new RectangleF(location2, size2), format);
|
||||
}
|
||||
if (SubscriptText != string.Empty)
|
||||
{
|
||||
PointF location3 = new PointF(location.X + size.Width - size3.Width / 2f, location.Y + size.Height * 0.85f);
|
||||
location3.X += SubscriptMargin.Left;
|
||||
location3.Y += SubscriptMargin.Top;
|
||||
g.DrawString(SubscriptText, SecondaryFont, new SolidBrush(SubscriptColor), new RectangleF(location3, size3), format);
|
||||
}
|
||||
}
|
||||
g.DrawString(Text, Font, new SolidBrush(ForeColor), new RectangleF(location, size), format);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user