SunnyUI/SunnyUI/Controls/UIAnalogMeter.cs

420 lines
12 KiB
C#
Raw Normal View History

2020-05-11 21:11:29 +08:00
/******************************************************************************
* SunnyUI <EFBFBD><EFBFBD>Դ<EFBFBD>ؼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܡ<EFBFBD>
2021-02-20 15:45:47 +08:00
* CopyRight (C) 2012-2021 ShenYongHua(<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>).
* QQȺ<EFBFBD><EFBFBD>56829229 QQ<EFBFBD><EFBFBD>17612584 EMail<EFBFBD><EFBFBD>SunnyUI@QQ.Com
2020-05-11 21:11:29 +08:00
*
* Blog: https://www.cnblogs.com/yhuse
* Gitee: https://gitee.com/yhuse/SunnyUI
* GitHub: https://github.com/yhuse/SunnyUI
*
* SunnyUI can be used for free under the GPL-3.0 license.
* If you use this code, please keep this note.
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ô˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
******************************************************************************
* <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: UIAnalogMeter.cs
* <EFBFBD>ļ<EFBFBD>˵<EFBFBD><EFBFBD>: <EFBFBD>DZ<EFBFBD>
* <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: Luca Bonotto
* <EFBFBD><EFBFBD>ԴЭ<EFBFBD><EFBFBD>: CPOL
* <EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD>ַ: https://www.codeproject.com/Articles/24945/Analog-Meter
******************************************************************************/
/*
* Creato da SharpDevelop.
* Utente: lucabonotto
* Data: 03/04/2008
* Ora: 14.34
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
#pragma warning disable 1591
namespace Sunny.UI
{
/// <summary>
/// Class for the analog meter control
/// </summary>
[ToolboxItem(true)]
public class UIAnalogMeter : UIControl
{
#region Enumerator
public enum AnalogMeterStyle
{
Circular = 0,
};
#endregion Enumerator
#region Properties variables
private AnalogMeterStyle meterStyle;
private Color needleColor;
private Color scaleColor;
private bool viewGlass;
private double currValue;
private double minValue;
private double maxValue;
private int scaleDivisions;
private int scaleSubDivisions;
private LBAnalogMeterRenderer renderer;
#endregion Properties variables
#region Class variables
protected PointF needleCenter;
protected RectangleF drawRect;
protected RectangleF glossyRect;
protected RectangleF needleCoverRect;
protected float startAngle;
protected float endAngle;
protected float drawRatio;
protected LBAnalogMeterRenderer defaultRenderer;
#endregion Class variables
#region Costructors
public UIAnalogMeter()
{
SetStyleFlags(true, false, true);
2020-05-11 21:11:29 +08:00
// Properties initialization
needleColor = Color.Yellow;
scaleColor = Color.White;
meterStyle = AnalogMeterStyle.Circular;
viewGlass = false;
startAngle = 135;
endAngle = 405;
minValue = 0;
maxValue = 100;
currValue = 0;
scaleDivisions = 11;
scaleSubDivisions = 4;
renderer = null;
// Set the styles for drawing
SetStyle(ControlStyles.DoubleBuffer, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.UserPaint, true);
// Create the default renderer
defaultRenderer = new LBDefaultAnalogMeterRenderer();
defaultRenderer.AnalogMeter = this;
Width = Height = 180;
}
#endregion Costructors
#region Properties
[
Category("SunnyUI"),
2020-05-11 21:11:29 +08:00
Description("Style of the control"),
DefaultValue(AnalogMeterStyle.Circular)
]
public AnalogMeterStyle MeterStyle
{
get { return meterStyle; }
set
{
meterStyle = value;
Invalidate();
}
}
[
Category("SunnyUI"),
2020-05-11 21:11:29 +08:00
Description("Color of the body of the control"),
DefaultValue(typeof(Color), "80, 160, 255")
]
public Color BodyColor
{
get => fillColor;
set => SetFillColor(value);
}
[
Category("SunnyUI"),
2020-05-11 21:11:29 +08:00
Description("Color of the needle"),
DefaultValue(typeof(Color), "Yellow")
]
public Color NeedleColor
{
get { return needleColor; }
set
{
needleColor = value;
Invalidate();
}
}
[
Category("SunnyUI"),
2020-05-11 21:11:29 +08:00
Description("Show or hide the glass effect"),
DefaultValue(false)
]
public bool ViewGlass
{
get { return viewGlass; }
set
{
viewGlass = value;
Invalidate();
}
}
[
Category("SunnyUI"),
2020-05-11 21:11:29 +08:00
Description("Color of the scale of the control"),
DefaultValue(typeof(Color), "White")
]
public Color ScaleColor
{
get { return scaleColor; }
set
{
scaleColor = value;
Invalidate();
}
}
[
Category("Behavior"),
Description("Value of the data"),
DefaultValue(0)
]
public double Value
{
get { return currValue; }
set
{
double val = value;
if (val > maxValue)
val = maxValue;
if (val < minValue)
val = minValue;
currValue = val;
Invalidate();
}
}
[
Category("Behavior"),
Description("Minimum value of the data"),
DefaultValue(0)
]
public double MinValue
{
get { return minValue; }
set
{
minValue = value;
Invalidate();
}
}
[
Category("Behavior"),
Description("Maximum value of the data"),
DefaultValue(100)
]
public double MaxValue
{
get { return maxValue; }
set
{
maxValue = value;
Invalidate();
}
}
[
Category("SunnyUI"),
2020-05-11 21:11:29 +08:00
Description("Number of the scale divisions"),
DefaultValue(11)
]
public int ScaleDivisions
{
get { return scaleDivisions; }
set
{
scaleDivisions = value;
CalculateDimensions();
Invalidate();
}
}
[
Category("SunnyUI"),
2020-05-11 21:11:29 +08:00
Description("Number of the scale subdivisions"),
DefaultValue(4)
]
public int ScaleSubDivisions
{
get { return scaleSubDivisions; }
set
{
scaleSubDivisions = value;
CalculateDimensions();
Invalidate();
}
}
[Browsable(false)]
public LBAnalogMeterRenderer Renderer
{
get { return renderer; }
set
{
renderer = value;
if (renderer != null)
renderer.AnalogMeter = this;
Invalidate();
}
}
#endregion Properties
#region Public methods
public float GetDrawRatio()
{
return drawRatio;
}
public float GetStartAngle()
{
return startAngle;
}
public float GetEndAngle()
{
return endAngle;
}
public PointF GetNeedleCenter()
{
return needleCenter;
}
#endregion Public methods
#region Events delegates
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
// Calculate dimensions
CalculateDimensions();
Invalidate();
}
protected override void OnPaintBackground(PaintEventArgs e)
{
}
protected override void OnPaint(PaintEventArgs e)
{
if (Width <= 0 || Height <= 0) return;
RectangleF _rc = new RectangleF(0, 0, Width, Height);
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
if (renderer == null)
{
defaultRenderer.DrawBackground(e.Graphics, _rc);
defaultRenderer.DrawBody(e.Graphics, drawRect);
defaultRenderer.DrawThresholds(e.Graphics, drawRect);
defaultRenderer.DrawDivisions(e.Graphics, drawRect);
defaultRenderer.DrawUM(e.Graphics, drawRect);
defaultRenderer.DrawValue(e.Graphics, drawRect);
defaultRenderer.DrawNeedle(e.Graphics, drawRect);
defaultRenderer.DrawNeedleCover(e.Graphics, needleCoverRect);
defaultRenderer.DrawGlass(e.Graphics, glossyRect);
}
else
{
if (Renderer.DrawBackground(e.Graphics, _rc) == false)
defaultRenderer.DrawBackground(e.Graphics, _rc);
if (Renderer.DrawBody(e.Graphics, drawRect) == false)
defaultRenderer.DrawBody(e.Graphics, drawRect);
if (Renderer.DrawThresholds(e.Graphics, drawRect) == false)
defaultRenderer.DrawThresholds(e.Graphics, drawRect);
if (Renderer.DrawDivisions(e.Graphics, drawRect) == false)
defaultRenderer.DrawDivisions(e.Graphics, drawRect);
if (Renderer.DrawUM(e.Graphics, drawRect) == false)
defaultRenderer.DrawUM(e.Graphics, drawRect);
if (Renderer.DrawValue(e.Graphics, drawRect) == false)
defaultRenderer.DrawValue(e.Graphics, drawRect);
if (Renderer.DrawNeedle(e.Graphics, drawRect) == false)
defaultRenderer.DrawNeedle(e.Graphics, drawRect);
if (Renderer.DrawNeedleCover(e.Graphics, needleCoverRect) == false)
defaultRenderer.DrawNeedleCover(e.Graphics, needleCoverRect);
if (Renderer.DrawGlass(e.Graphics, glossyRect) == false)
defaultRenderer.DrawGlass(e.Graphics, glossyRect);
}
}
#endregion Events delegates
#region Virtual functions
protected virtual void CalculateDimensions()
{
// Rectangle
float x = 0;
float y = 0;
float w = Width;
float h = Height;
// Calculate ratio
drawRatio = (Math.Min(w, h)) / 200;
if (drawRatio < 0.00000001)
drawRatio = 1;
// Draw rectangle
drawRect.X = x;
drawRect.Y = y;
drawRect.Width = w - 2;
drawRect.Height = h - 2;
if (w < h)
drawRect.Height = w;
else if (w > h)
drawRect.Width = h;
if (drawRect.Width < 10)
drawRect.Width = 10;
if (drawRect.Height < 10)
drawRect.Height = 10;
// Calculate needle center
needleCenter.X = drawRect.X + (drawRect.Width / 2);
needleCenter.Y = drawRect.Y + (drawRect.Height / 2);
// Needle cover rect
needleCoverRect.X = needleCenter.X - (20 * drawRatio);
needleCoverRect.Y = needleCenter.Y - (20 * drawRatio);
needleCoverRect.Width = 40 * drawRatio;
needleCoverRect.Height = 40 * drawRatio;
// Glass effect rect
glossyRect.X = drawRect.X + (20 * drawRatio);
glossyRect.Y = drawRect.Y + (10 * drawRatio);
glossyRect.Width = drawRect.Width - (40 * drawRatio);
glossyRect.Height = needleCenter.Y + (30 * drawRatio);
}
#endregion Virtual functions
}
}