SunnyUI/SunnyUI/Controls/UIAnalogMeter.cs

420 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/******************************************************************************
* SunnyUI 开源控件库、工具类库、扩展类库、多页面开发框架。
* CopyRight (C) 2012-2021 ShenYongHua(沈永华).
* QQ群56829229 QQ17612584 EMailSunnyUI@QQ.Com
*
* 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.
* 如果您使用此代码,请保留此说明。
******************************************************************************
* 文件名称: UIAnalogMeter.cs
* 文件说明: 仪表
* 文件作者: Luca Bonotto
* 开源协议: CPOL
* 引用地址: 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);
// 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"),
Description("Style of the control"),
DefaultValue(AnalogMeterStyle.Circular)
]
public AnalogMeterStyle MeterStyle
{
get { return meterStyle; }
set
{
meterStyle = value;
Invalidate();
}
}
[
Category("SunnyUI"),
Description("Color of the body of the control"),
DefaultValue(typeof(Color), "80, 160, 255")
]
public Color BodyColor
{
get => fillColor;
set => SetFillColor(value);
}
[
Category("SunnyUI"),
Description("Color of the needle"),
DefaultValue(typeof(Color), "Yellow")
]
public Color NeedleColor
{
get { return needleColor; }
set
{
needleColor = value;
Invalidate();
}
}
[
Category("SunnyUI"),
Description("Show or hide the glass effect"),
DefaultValue(false)
]
public bool ViewGlass
{
get { return viewGlass; }
set
{
viewGlass = value;
Invalidate();
}
}
[
Category("SunnyUI"),
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"),
Description("Number of the scale divisions"),
DefaultValue(11)
]
public int ScaleDivisions
{
get { return scaleDivisions; }
set
{
scaleDivisions = value;
CalculateDimensions();
Invalidate();
}
}
[
Category("SunnyUI"),
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
}
}