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()
|
|
|
|
|
{
|
2021-04-16 15:45:58 +08:00
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
[
|
2020-08-08 21:55:50 +08:00
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[
|
2020-08-08 21:55:50 +08:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[
|
2020-08-08 21:55:50 +08:00
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[
|
2020-08-08 21:55:50 +08:00
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[
|
2020-08-08 21:55:50 +08:00
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[
|
2020-08-08 21:55:50 +08:00
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[
|
2020-08-08 21:55:50 +08:00
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
}
|