DotNet 4.8.1 build of DotNetBar
This commit is contained in:
@@ -0,0 +1,644 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace DevComponents.Instrumentation
|
||||
{
|
||||
[TypeConverter(typeof(GaugeBaseLabelConvertor))]
|
||||
public class GaugeBaseLabel : GaugeItem
|
||||
{
|
||||
#region Private variables
|
||||
|
||||
private int _Radius;
|
||||
private int _Offset;
|
||||
|
||||
private LabelLayout _Layout;
|
||||
private GaugeScale _Scale;
|
||||
|
||||
#endregion
|
||||
|
||||
public GaugeBaseLabel()
|
||||
{
|
||||
_Layout = new LabelLayout();
|
||||
|
||||
HookEvents(true);
|
||||
}
|
||||
|
||||
#region Hidden properties
|
||||
|
||||
#region Tooltip
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public new string Tooltip
|
||||
{
|
||||
get { return (base.Tooltip); }
|
||||
set { base.Tooltip = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
|
||||
#region Layout
|
||||
|
||||
/// <summary>
|
||||
/// Gets the label Layout
|
||||
/// </summary>
|
||||
[Browsable(true), Category("Appearance")]
|
||||
[Description("Contains the Label layout properties.")]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
|
||||
public LabelLayout Layout
|
||||
{
|
||||
get { return (_Layout); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Scale
|
||||
|
||||
/// <summary>
|
||||
/// Gets the associated Scale
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public virtual GaugeScale Scale
|
||||
{
|
||||
get { return (_Scale); }
|
||||
|
||||
internal set
|
||||
{
|
||||
_Scale = value;
|
||||
|
||||
OnGaugeItemChanged(true);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Internal properties
|
||||
|
||||
#region AbsFont
|
||||
|
||||
internal Font AbsFont
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_Layout.AutoSize == false)
|
||||
return (_Layout.Font);
|
||||
|
||||
if (_Layout.AbsFont == null)
|
||||
{
|
||||
if (Scale is GaugeCircularScale)
|
||||
_Layout.AbsFont = GetAbsFont(Scale as GaugeCircularScale);
|
||||
|
||||
else if (Scale is GaugeLinearScale)
|
||||
_Layout.AbsFont = GetAbsFont(Scale as GaugeLinearScale);
|
||||
}
|
||||
|
||||
return (_Layout.AbsFont);
|
||||
}
|
||||
|
||||
set { _Layout.AbsFont = value; }
|
||||
}
|
||||
|
||||
private Font GetAbsFont(GaugeCircularScale scale)
|
||||
{
|
||||
float emSize = _Layout.Font.SizeInPoints;
|
||||
emSize = (emSize / 120) * scale.AbsRadius;
|
||||
|
||||
if (emSize <= 0)
|
||||
emSize = 1;
|
||||
|
||||
return (new Font(_Layout.Font.FontFamily, emSize, _Layout.Font.Style));
|
||||
}
|
||||
|
||||
private Font GetAbsFont(GaugeLinearScale scale)
|
||||
{
|
||||
float emSize = _Layout.Font.SizeInPoints;
|
||||
|
||||
emSize = (emSize / 120) * scale.AbsWidth;
|
||||
|
||||
return (new Font(_Layout.Font.FontFamily, emSize, _Layout.Font.Style));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Offset
|
||||
|
||||
internal int Offset
|
||||
{
|
||||
get { return (_Offset); }
|
||||
set { _Offset = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Radius
|
||||
|
||||
internal int Radius
|
||||
{
|
||||
get { return (_Radius); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region HookEvents
|
||||
|
||||
private void HookEvents(bool hook)
|
||||
{
|
||||
if (hook == true)
|
||||
{
|
||||
_Layout.LabelLayoutChanged += Layout_LabelLayoutChanged;
|
||||
}
|
||||
else
|
||||
{
|
||||
_Layout.LabelLayoutChanged -= Layout_LabelLayoutChanged;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event handling
|
||||
|
||||
void Layout_LabelLayoutChanged(object sender, EventArgs e)
|
||||
{
|
||||
OnGaugeItemChanged(true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region RecalcLayout
|
||||
|
||||
public override void RecalcLayout()
|
||||
{
|
||||
if (NeedRecalcLayout == true)
|
||||
{
|
||||
base.RecalcLayout();
|
||||
|
||||
CalcLabelMetrics();
|
||||
|
||||
AbsFont = null;
|
||||
_Layout.AbsFont = null;
|
||||
}
|
||||
}
|
||||
|
||||
#region CalcLabelMetrics
|
||||
|
||||
private void CalcLabelMetrics()
|
||||
{
|
||||
if (Scale is GaugeCircularScale)
|
||||
CalcCircularMetrics(Scale as GaugeCircularScale);
|
||||
|
||||
else if (Scale is GaugeLinearScale)
|
||||
CalcLinearMetrics(Scale as GaugeLinearScale);
|
||||
}
|
||||
|
||||
#region CalcCircularMetrics
|
||||
|
||||
private void CalcCircularMetrics(GaugeCircularScale scale)
|
||||
{
|
||||
_Radius = scale.AbsRadius;
|
||||
|
||||
if (_Radius > 0)
|
||||
{
|
||||
int offset = (int)(_Radius * _Layout.ScaleOffset);
|
||||
|
||||
switch (_Layout.Placement)
|
||||
{
|
||||
case DisplayPlacement.Near:
|
||||
_Radius = scale.GetNearLabelRadius() - offset;
|
||||
break;
|
||||
|
||||
case DisplayPlacement.Center:
|
||||
_Radius += offset;
|
||||
break;
|
||||
|
||||
case DisplayPlacement.Far:
|
||||
_Radius = scale.GetFarLabelRadius() + offset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CalcLinearMetrics
|
||||
|
||||
private void CalcLinearMetrics(GaugeLinearScale scale)
|
||||
{
|
||||
int width = scale.AbsWidth;
|
||||
int offset = (int)(width * _Layout.ScaleOffset);
|
||||
|
||||
switch (_Layout.Placement)
|
||||
{
|
||||
case DisplayPlacement.Near:
|
||||
_Offset = GetNearLabelOffset(scale) - offset;
|
||||
break;
|
||||
|
||||
case DisplayPlacement.Center:
|
||||
_Offset = scale.AbsScaleWidth / 2 - offset;
|
||||
break;
|
||||
|
||||
case DisplayPlacement.Far:
|
||||
_Offset = GetFarLabelOffset(scale) + offset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#region GetNearLabelOffset
|
||||
|
||||
private int GetNearLabelOffset(GaugeLinearScale scale)
|
||||
{
|
||||
int offset = 0;
|
||||
|
||||
if (scale.MajorTickMarks.Visible &&
|
||||
scale.MajorTickMarks.Layout.Placement == DisplayPlacement.Near
|
||||
&& scale.MajorTickMarks.Offset < offset)
|
||||
{
|
||||
offset = scale.MajorTickMarks.Offset;
|
||||
}
|
||||
|
||||
if (scale.MinorTickMarks.Visible &&
|
||||
scale.MinorTickMarks.Layout.Placement == DisplayPlacement.Near &&
|
||||
scale.MinorTickMarks.Offset < offset)
|
||||
{
|
||||
offset = scale.MinorTickMarks.Offset;
|
||||
}
|
||||
|
||||
return (offset);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetFarLabelOffset
|
||||
|
||||
private int GetFarLabelOffset(GaugeLinearScale scale)
|
||||
{
|
||||
int offset = scale.AbsScaleWidth;
|
||||
|
||||
if (scale.MajorTickMarks.Visible &&
|
||||
scale.MajorTickMarks.Layout.Placement == DisplayPlacement.Far)
|
||||
{
|
||||
int n = scale.MajorTickMarks.Offset + scale.MajorTickMarks.Length;
|
||||
|
||||
if (n > offset)
|
||||
offset = n;
|
||||
}
|
||||
|
||||
if (scale.MinorTickMarks.Visible &&
|
||||
scale.MinorTickMarks.Layout.Placement == DisplayPlacement.Far)
|
||||
{
|
||||
int n = scale.MinorTickMarks.Offset + scale.MinorTickMarks.Length;
|
||||
|
||||
if (n > offset)
|
||||
offset = n;
|
||||
}
|
||||
|
||||
return (offset);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region PaintLabel
|
||||
|
||||
internal void PaintLabel(Graphics g,
|
||||
string text, Brush br, LabelPoint lp, Font font)
|
||||
{
|
||||
if (Scale.Style == GaugeScaleStyle.Circular)
|
||||
{
|
||||
if (Layout.AdaptiveLabel == true)
|
||||
{
|
||||
PaintAdaptiveLabel(g, text, br, lp, font);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Layout.RotateLabel == true)
|
||||
PaintRotatedLabel(g, text, br, lp, font);
|
||||
else
|
||||
PaintNonRotatedLabel(g, text, br, lp, font);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PaintRotatedLabel(g, text, br, lp, font);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PaintRotatedLabel
|
||||
|
||||
internal void PaintRotatedLabel(Graphics g,
|
||||
string text, Brush br, LabelPoint lp, Font font)
|
||||
{
|
||||
if (Scale is GaugeCircularScale)
|
||||
PaintCircularRotatedLabel(g, text, br, lp, font);
|
||||
|
||||
else if (Scale is GaugeLinearScale)
|
||||
PaintLinearRotatedLabel(g, text, br, lp, font, Scale as GaugeLinearScale);
|
||||
}
|
||||
|
||||
#region PaintCircularRotatedLabel
|
||||
|
||||
private void PaintCircularRotatedLabel(
|
||||
Graphics g, string text, Brush br, LabelPoint lp, Font font)
|
||||
{
|
||||
SizeF sz = g.MeasureString(text, font);
|
||||
Size size = sz.ToSize();
|
||||
|
||||
float fontAngle = Layout.Angle;
|
||||
|
||||
if (Layout.AutoOrientLabel == true)
|
||||
{
|
||||
if (((fontAngle + lp.Angle) % 360) < 180)
|
||||
fontAngle += 180;
|
||||
}
|
||||
|
||||
g.TranslateTransform(lp.Point.X, lp.Point.Y);
|
||||
g.RotateTransform((lp.Angle + 90) % 360);
|
||||
|
||||
g.TranslateTransform(0, GetRadiusDelta(size.Width, size.Height, fontAngle));
|
||||
g.RotateTransform(fontAngle % 360);
|
||||
|
||||
g.DrawString(text, font, br,
|
||||
new Point(-size.Width / 2, -size.Height / 2));
|
||||
|
||||
g.ResetTransform();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PaintLinearRotatedLabel
|
||||
|
||||
private void PaintLinearRotatedLabel(Graphics g, string text,
|
||||
Brush br, LabelPoint lp, Font font, GaugeLinearScale scale)
|
||||
{
|
||||
SizeF sz = g.MeasureString(text, font);
|
||||
Size size = sz.ToSize();
|
||||
|
||||
float fontAngle = Layout.Angle;
|
||||
|
||||
g.TranslateTransform(lp.Point.X, lp.Point.Y);
|
||||
|
||||
if (scale.Orientation == Orientation.Horizontal)
|
||||
g.TranslateTransform(0, -GetRadiusDelta(size.Width, size.Height, fontAngle));
|
||||
else
|
||||
g.TranslateTransform(-GetRadiusDelta(size.Height, size.Width, fontAngle), 0);
|
||||
|
||||
g.RotateTransform(fontAngle % 360);
|
||||
|
||||
g.DrawString(text, font, br,
|
||||
new Point(-size.Width / 2, -size.Height / 2));
|
||||
|
||||
g.ResetTransform();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetRadiusDelta
|
||||
|
||||
private int GetRadiusDelta(int width, int height, float fontAngle)
|
||||
{
|
||||
if (Layout.Placement == DisplayPlacement.Center)
|
||||
return (0);
|
||||
|
||||
float spd = (float)((width / 2) - (height / 2)) / 90;
|
||||
float angle = fontAngle % 180;
|
||||
|
||||
int delta = (int)((height / 2) +
|
||||
((angle > 90) ? (180 - angle) : angle) * spd) + 2;
|
||||
|
||||
return (Layout.Placement == DisplayPlacement.Near ? delta : - delta);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region PaintNonRotatedLabel
|
||||
|
||||
internal void PaintNonRotatedLabel(Graphics g,
|
||||
string text, Brush br, LabelPoint lp, Font font)
|
||||
{
|
||||
SizeF sz = g.MeasureString(text, font);
|
||||
Size size = sz.ToSize();
|
||||
|
||||
float fontAngle = 360 - ((lp.Angle + Layout.Angle + 90) % 360);
|
||||
|
||||
g.TranslateTransform(lp.Point.X, lp.Point.Y);
|
||||
g.RotateTransform((lp.Angle + 90) % 360);
|
||||
|
||||
g.TranslateTransform(0, GetRadiusDelta(size.Width, size.Height, fontAngle));
|
||||
g.RotateTransform(fontAngle % 360);
|
||||
|
||||
g.DrawString(text, font, br,
|
||||
new Point(-size.Width / 2, -size.Height / 2));
|
||||
|
||||
g.ResetTransform();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PaintAdaptiveLabel
|
||||
|
||||
internal void PaintAdaptiveLabel(Graphics g,
|
||||
string text, Brush br, LabelPoint lp, Font font)
|
||||
{
|
||||
SizeF tw = g.MeasureString(text, font);
|
||||
|
||||
if (Layout.Placement == DisplayPlacement.Near)
|
||||
tw.Width += text.Length;
|
||||
|
||||
float c = (float)(Math.PI * _Radius * 2);
|
||||
|
||||
if (c > 0)
|
||||
{
|
||||
float radians = (float)GetRadians(lp.Angle);
|
||||
float radOffset = (float)GetRadians((180 * tw.Width) / c);
|
||||
float radCenter = radians;
|
||||
|
||||
radians -= radOffset;
|
||||
|
||||
bool flip = false;
|
||||
|
||||
if (_Layout.AutoOrientLabel == true)
|
||||
{
|
||||
flip = ((GetDegrees(radCenter) % 360) < 180);
|
||||
|
||||
if (flip == true)
|
||||
radians += (radOffset * 2);
|
||||
}
|
||||
|
||||
int n = (int)Math.Ceiling((double)text.Length / 32);
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
int len = Math.Min(text.Length - (i * 32), 32);
|
||||
|
||||
radians = PaintAdaptiveText(g,
|
||||
text.Substring(i * 32, len), br, font, radians, flip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PaintAdaptiveText
|
||||
|
||||
private float PaintAdaptiveText(Graphics g,
|
||||
string text, Brush br, Font font, float radians, bool flip)
|
||||
{
|
||||
CharacterRange[] crs = new CharacterRange[text.Length];
|
||||
|
||||
for (int j = 0; j < text.Length; j++)
|
||||
crs[j] = new CharacterRange(j, 1);
|
||||
|
||||
using (StringFormat sf = new StringFormat())
|
||||
{
|
||||
sf.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.MeasureTrailingSpaces;
|
||||
sf.SetMeasurableCharacterRanges(crs);
|
||||
|
||||
Rectangle r = new Rectangle(0, 0, 1000, 1000);
|
||||
Region[] rgns = g.MeasureCharacterRanges(text, font, r, sf);
|
||||
|
||||
for (int j = 0; j < text.Length; j++)
|
||||
{
|
||||
RectangleF t = rgns[j].GetBounds(g);
|
||||
|
||||
float z = (flip ? _Radius - t.Height / 2 : _Radius + t.Height / 2);
|
||||
|
||||
switch (Layout.Placement)
|
||||
{
|
||||
case DisplayPlacement.Near:
|
||||
t.Width += 1;
|
||||
z -= t.Height/2;
|
||||
break;
|
||||
|
||||
case DisplayPlacement.Far:
|
||||
z += t.Height/2;
|
||||
break;
|
||||
}
|
||||
|
||||
float y = (float)(_Scale.Center.Y + z * Math.Sin(radians));
|
||||
float x = (float)(_Scale.Center.X + z * Math.Cos(radians));
|
||||
|
||||
float rad = (float)Math.Asin(t.Width / (_Radius * 2));
|
||||
|
||||
radians += (flip ? -rad : rad);
|
||||
|
||||
g.TranslateTransform(x, y);
|
||||
g.RotateTransform((flip ? -90 : 90) + (float)GetDegrees(radians));
|
||||
|
||||
g.DrawString(text[j].ToString(), font, br, 0, 0);
|
||||
|
||||
g.ResetTransform();
|
||||
|
||||
radians += (flip ? -rad : rad);
|
||||
}
|
||||
}
|
||||
|
||||
return (radians);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetDegrees
|
||||
|
||||
internal double GetDegrees(float radians)
|
||||
{
|
||||
return (radians * 180 / Math.PI);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetRadians
|
||||
|
||||
/// <summary>
|
||||
/// Converts Degrees to Radians
|
||||
/// </summary>
|
||||
/// <param name="theta">Degrees</param>
|
||||
/// <returns>Radians</returns>
|
||||
internal double GetRadians(float theta)
|
||||
{
|
||||
return (theta * Math.PI / 180);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region OnDispose
|
||||
|
||||
protected override void OnDispose()
|
||||
{
|
||||
HookEvents(false);
|
||||
|
||||
base.OnDispose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ICloneable Members
|
||||
|
||||
public override object Clone()
|
||||
{
|
||||
GaugeBaseLabel copy = new GaugeBaseLabel();
|
||||
|
||||
CopyToItem(copy);
|
||||
|
||||
return (copy);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CopyToItem
|
||||
|
||||
public override void CopyToItem(GaugeItem copy)
|
||||
{
|
||||
GaugeBaseLabel c = copy as GaugeBaseLabel;
|
||||
|
||||
if (c != null)
|
||||
{
|
||||
base.CopyToItem(c);
|
||||
|
||||
_Layout.CopyToItem(c.Layout);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#region GaugeBaseLabelConvertor
|
||||
|
||||
public class GaugeBaseLabelConvertor : ExpandableObjectConverter
|
||||
{
|
||||
public override object ConvertTo(
|
||||
ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
|
||||
{
|
||||
if (destinationType == typeof(string))
|
||||
{
|
||||
GaugeBaseLabel label = value as GaugeBaseLabel;
|
||||
|
||||
if (label != null)
|
||||
return (String.Empty);
|
||||
}
|
||||
|
||||
return (base.ConvertTo(context, culture, value, destinationType));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
@@ -0,0 +1,352 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using DevComponents.Instrumentation.Primitives;
|
||||
|
||||
namespace DevComponents.Instrumentation
|
||||
{
|
||||
public class GaugeCustomLabelCollection : GenericCollection<GaugeCustomLabel>
|
||||
{
|
||||
#region ICloneable Members
|
||||
|
||||
public override object Clone()
|
||||
{
|
||||
GaugeCustomLabelCollection copy = new GaugeCustomLabelCollection();
|
||||
|
||||
CopyToItem(copy);
|
||||
|
||||
return (copy);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CopyToItem
|
||||
|
||||
internal void CopyToItem(GaugeCustomLabelCollection copy)
|
||||
{
|
||||
foreach (GaugeCustomLabel item in this)
|
||||
{
|
||||
GaugeCustomLabel ic = new GaugeCustomLabel();
|
||||
|
||||
item.CopyToItem(ic);
|
||||
|
||||
copy.Add(ic);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class GaugeCustomLabel : GaugeBaseLabel
|
||||
{
|
||||
#region Private variables
|
||||
|
||||
private string _Text;
|
||||
private double _Value;
|
||||
|
||||
private GaugeTickMarkLabel _TickMark;
|
||||
private LabelPoint _LabelPoint;
|
||||
|
||||
#endregion
|
||||
|
||||
public GaugeCustomLabel()
|
||||
{
|
||||
_Text = "Text";
|
||||
_Value = double.NaN;
|
||||
|
||||
_TickMark = new GaugeTickMarkLabel(
|
||||
Scale, GaugeTickMarkRank.Custom, GaugeMarkerStyle.Trapezoid, .09f, .14f, double.NaN);
|
||||
|
||||
HookEvents(true);
|
||||
}
|
||||
|
||||
#region Public properties
|
||||
|
||||
#region Scale
|
||||
|
||||
/// <summary>
|
||||
/// Gets the label's associated Scale
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public override GaugeScale Scale
|
||||
{
|
||||
get { return (base.Scale); }
|
||||
|
||||
internal set
|
||||
{
|
||||
base.Scale = value;
|
||||
|
||||
_TickMark.Scale = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Text
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Label text
|
||||
/// </summary>
|
||||
[Browsable(true)]
|
||||
[Category("Behavior"), DefaultValue("Text")]
|
||||
[Description("Indicates the Label text.")]
|
||||
public string Text
|
||||
{
|
||||
get { return (_Text); }
|
||||
|
||||
set
|
||||
{
|
||||
if (value != null && value.Equals(_Text) == false)
|
||||
{
|
||||
_Text = value;
|
||||
|
||||
OnGaugeItemChanged(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region TickMark
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Label Tickmark definition
|
||||
/// </summary>
|
||||
[Browsable(true), Category("Appearance")]
|
||||
[Description("Contains the Label TickMark layout properties.")]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
|
||||
public GaugeTickMarkLabel TickMark
|
||||
{
|
||||
get { return (_TickMark); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Value
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Label scale value
|
||||
/// </summary>
|
||||
[Browsable(true)]
|
||||
[Category("Behavior"), DefaultValue(double.NaN)]
|
||||
[Description("Indicates the Label scale value.")]
|
||||
public double Value
|
||||
{
|
||||
get { return (_Value); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_Value != value)
|
||||
{
|
||||
_Value = value;
|
||||
|
||||
OnGaugeItemChanged(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Internal properties
|
||||
|
||||
#region NeedRecalcLayout
|
||||
|
||||
internal override bool NeedRecalcLayout
|
||||
{
|
||||
get { return (base.NeedRecalcLayout); }
|
||||
|
||||
set
|
||||
{
|
||||
base.NeedRecalcLayout = value;
|
||||
|
||||
if (value == true)
|
||||
_TickMark.NeedRecalcLayout = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region HookEvents
|
||||
|
||||
private void HookEvents(bool hook)
|
||||
{
|
||||
if (hook == true)
|
||||
{
|
||||
_TickMark.GaugeItemChanged += LabelTickMark_GaugeItemChanged;
|
||||
}
|
||||
else
|
||||
{
|
||||
_TickMark.GaugeItemChanged -= LabelTickMark_GaugeItemChanged;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event processing
|
||||
|
||||
void LabelTickMark_GaugeItemChanged(object sender, EventArgs e)
|
||||
{
|
||||
OnGaugeItemChanged(true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region RecalcLayout
|
||||
|
||||
public override void RecalcLayout()
|
||||
{
|
||||
if (NeedRecalcLayout == true)
|
||||
{
|
||||
base.RecalcLayout();
|
||||
|
||||
if (_Value >= Scale.MinValue && _Value <= Scale.MaxValue)
|
||||
{
|
||||
if (Scale is GaugeCircularScale)
|
||||
CalcCircularLabelPoint(Scale as GaugeCircularScale);
|
||||
|
||||
else if (Scale is GaugeLinearScale)
|
||||
CalcLinearLabelPoint(Scale as GaugeLinearScale);
|
||||
|
||||
_TickMark.Interval = _Value - Scale.MinValue;
|
||||
_TickMark.NeedRecalcLayout = true;
|
||||
|
||||
_TickMark.RecalcLayout();
|
||||
}
|
||||
else
|
||||
{
|
||||
_LabelPoint = null;
|
||||
_TickMark.TickPoint = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region CalcCircularLabelPoint
|
||||
|
||||
private void CalcCircularLabelPoint(GaugeCircularScale scale)
|
||||
{
|
||||
double spread = scale.MaxValue - scale.MinValue;
|
||||
double dpt = scale.SweepAngle / spread;
|
||||
double interval = _Value - scale.MinValue;
|
||||
|
||||
double n = interval * dpt;
|
||||
|
||||
_LabelPoint = new LabelPoint();
|
||||
|
||||
_LabelPoint.Angle = (float)(scale.StartAngle + (scale.Reversed ? scale.SweepAngle - n : n));
|
||||
_LabelPoint.Point = scale.GetPoint(Radius, _LabelPoint.Angle);
|
||||
_LabelPoint.Interval = interval;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CalcLinearLabelPoint
|
||||
|
||||
private void CalcLinearLabelPoint(GaugeLinearScale scale)
|
||||
{
|
||||
double ticks = scale.MaxValue - scale.MinValue;
|
||||
|
||||
_LabelPoint = new LabelPoint();
|
||||
|
||||
if (scale.Orientation == Orientation.Horizontal)
|
||||
{
|
||||
double dpt = scale.ScaleBounds.Width / ticks;
|
||||
int dx = (int)((_Value - Scale.MinValue) * dpt);
|
||||
|
||||
int x = (scale.Reversed == true)
|
||||
? Scale.Bounds.Right - dx : Scale.Bounds.X + dx;
|
||||
|
||||
_LabelPoint.Point = new Point(x, scale.ScaleBounds.Y + Offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
double dpt = scale.ScaleBounds.Height / ticks;
|
||||
int dy = (int)((_Value - Scale.MinValue) * dpt);
|
||||
|
||||
int y = (scale.Reversed == true)
|
||||
? Scale.Bounds.Top + dy : Scale.Bounds.Bottom - dy;
|
||||
|
||||
_LabelPoint.Point = new Point(scale.ScaleBounds.X + Offset, y);
|
||||
}
|
||||
|
||||
_LabelPoint.Interval = _Value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region OnPaint
|
||||
|
||||
public override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
Graphics g = e.Graphics;
|
||||
|
||||
RecalcLayout();
|
||||
|
||||
if (_LabelPoint != null)
|
||||
{
|
||||
if (_LabelPoint.Visible == true)
|
||||
{
|
||||
if (Scale.GaugeControl.OnPreRenderScaleCustomLabel(e, this) == false)
|
||||
{
|
||||
using (Brush br = new SolidBrush(Layout.ForeColor))
|
||||
PaintLabel(g, _Text, br, _LabelPoint, AbsFont);
|
||||
|
||||
Scale.GaugeControl.OnPostRenderScaleCustomLabel(e, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region OnDispose
|
||||
|
||||
protected override void OnDispose()
|
||||
{
|
||||
HookEvents(false);
|
||||
|
||||
base.OnDispose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ICloneable Members
|
||||
|
||||
public override object Clone()
|
||||
{
|
||||
GaugeCustomLabel copy = new GaugeCustomLabel();
|
||||
|
||||
CopyToItem(copy);
|
||||
|
||||
return (copy);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CopyToItem
|
||||
|
||||
public override void CopyToItem(GaugeItem copy)
|
||||
{
|
||||
GaugeCustomLabel c = copy as GaugeCustomLabel;
|
||||
|
||||
if (c != null)
|
||||
{
|
||||
base.CopyToItem(c);
|
||||
|
||||
c.Text = _Text;
|
||||
c.Value = _Value;
|
||||
|
||||
_TickMark.CopyToItem(c.TickMark);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,585 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Design;
|
||||
using System.Globalization;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace DevComponents.Instrumentation
|
||||
{
|
||||
[TypeConverter(typeof(GaugeLabelConvertor))]
|
||||
public class GaugeIntervalLabel : GaugeBaseLabel
|
||||
{
|
||||
#region Private variables
|
||||
|
||||
private double _Interval;
|
||||
private double _IntervalOffset;
|
||||
|
||||
private LabelPoint[] _LabelPoints;
|
||||
|
||||
private bool _ShowMaxLabel;
|
||||
private bool _ShowMinLabel;
|
||||
|
||||
private string _FormatString;
|
||||
|
||||
#endregion
|
||||
|
||||
public GaugeIntervalLabel(GaugeScale scale)
|
||||
{
|
||||
Scale = scale;
|
||||
|
||||
_Interval = double.NaN;
|
||||
_IntervalOffset = double.NaN;
|
||||
|
||||
_ShowMinLabel = true;
|
||||
_ShowMaxLabel = true;
|
||||
}
|
||||
|
||||
#region Hidden properties
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public new string Name
|
||||
{
|
||||
get { return (base.Name); }
|
||||
set { base.Name = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
|
||||
#region FormatString
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the .Net format string used to display all non-custom defined labels.
|
||||
/// </summary>
|
||||
[Browsable(true), Category("Appearance"), DefaultValue(null)]
|
||||
[Description("Indicates the .Net format string used to display all non-custom defined labels.")]
|
||||
[Editor("DevComponents.Instrumentation.Design.FormatStringEditor, DevComponents.Instrumentation.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=76cb4c6eb576bca5", typeof(UITypeEditor))]
|
||||
public string FormatString
|
||||
{
|
||||
get { return (_FormatString); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_FormatString != value)
|
||||
{
|
||||
_FormatString = value;
|
||||
|
||||
OnGaugeItemChanged(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Interval
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Label Interval
|
||||
/// </summary>
|
||||
[Browsable(true), Category("Appearance"), DefaultValue(double.NaN)]
|
||||
[Description("Indicates the Label Interval.")]
|
||||
public double Interval
|
||||
{
|
||||
get { return (_Interval); }
|
||||
|
||||
set
|
||||
{
|
||||
if (value < 0)
|
||||
throw new ArgumentException("Value can not be less than zero.");
|
||||
|
||||
if (_Interval != value)
|
||||
{
|
||||
_Interval = value;
|
||||
|
||||
OnGaugeItemChanged(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IntervalOffset
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Label Interval Offset
|
||||
/// </summary>
|
||||
[Browsable(true), Category("Appearance"), DefaultValue(double.NaN)]
|
||||
[Description("Indicates the Label Interval Offset.")]
|
||||
public double IntervalOffset
|
||||
{
|
||||
get { return (_IntervalOffset); }
|
||||
|
||||
set
|
||||
{
|
||||
if (value < 0)
|
||||
throw new ArgumentException("Value can not be less than zero.");
|
||||
|
||||
if (_IntervalOffset != value)
|
||||
{
|
||||
_IntervalOffset = value;
|
||||
|
||||
OnGaugeItemChanged(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ShowMaxLabel
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether to show the Maximum Scale label
|
||||
/// </summary>
|
||||
[Browsable(true), Category("Appearance"), DefaultValue(true)]
|
||||
[Description("Indicates whether to show the Maximum Scale label.")]
|
||||
public bool ShowMaxLabel
|
||||
{
|
||||
get { return (_ShowMaxLabel); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_ShowMaxLabel != value)
|
||||
{
|
||||
_ShowMaxLabel = value;
|
||||
|
||||
OnGaugeItemChanged(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ShowMinLabel
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether to show the Minimum Scale label
|
||||
/// </summary>
|
||||
[Browsable(true), Category("Appearance"), DefaultValue(true)]
|
||||
[Description("Indicates whether to show the Minimum Scale label.")]
|
||||
public bool ShowMinLabel
|
||||
{
|
||||
get { return (_ShowMinLabel); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_ShowMinLabel != value)
|
||||
{
|
||||
_ShowMinLabel = value;
|
||||
|
||||
OnGaugeItemChanged(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region RecalcLayout
|
||||
|
||||
public override void RecalcLayout()
|
||||
{
|
||||
if (NeedRecalcLayout == true)
|
||||
{
|
||||
base.RecalcLayout();
|
||||
|
||||
CalcLabelPoints();
|
||||
}
|
||||
}
|
||||
|
||||
#region CalcLabelPoints
|
||||
|
||||
private void CalcLabelPoints()
|
||||
{
|
||||
if (Scale is GaugeCircularScale)
|
||||
CalcCircularLabelPoints(Scale as GaugeCircularScale);
|
||||
|
||||
else if (Scale is GaugeLinearScale)
|
||||
CalcLinearLabelPoints(Scale as GaugeLinearScale);
|
||||
}
|
||||
|
||||
#region CalcCircularLabelPoints
|
||||
|
||||
private void CalcCircularLabelPoints(GaugeCircularScale scale)
|
||||
{
|
||||
double labelInterval = (_Interval.Equals(double.NaN) ?
|
||||
scale.MajorTickMarks.Interval : _Interval);
|
||||
|
||||
double labelIntervalOffset = (_IntervalOffset.Equals(double.NaN) ?
|
||||
scale.MajorTickMarks.IntervalOffset : _IntervalOffset);
|
||||
|
||||
double spread = scale.MaxValue - scale.MinValue;
|
||||
double dpt = scale.SweepAngle / spread;
|
||||
|
||||
int n = GetPointCount(spread, labelInterval, labelIntervalOffset);
|
||||
|
||||
if (n > 0)
|
||||
{
|
||||
double startAngle = scale.StartAngle;
|
||||
double interval = (_ShowMinLabel == true ? 0 : labelIntervalOffset > 0 ? labelIntervalOffset : labelInterval);
|
||||
|
||||
int dir = (scale.Reversed ? -1 : 1);
|
||||
|
||||
if (scale.Reversed == true)
|
||||
startAngle += scale.SweepAngle;
|
||||
|
||||
_LabelPoints = new LabelPoint[n];
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
_LabelPoints[i] = new LabelPoint();
|
||||
|
||||
if (interval + scale.MinValue > scale.MaxValue)
|
||||
interval = scale.MaxValue - scale.MinValue;
|
||||
|
||||
_LabelPoints[i].Angle = (float)(startAngle + (interval * dpt) * dir);
|
||||
_LabelPoints[i].Point = scale.GetPoint(Radius, _LabelPoints[i].Angle);
|
||||
_LabelPoints[i].Interval = interval;
|
||||
|
||||
if (interval >= labelIntervalOffset)
|
||||
interval += labelInterval;
|
||||
else
|
||||
interval = labelIntervalOffset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_LabelPoints = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CalcLinearLabelPoints
|
||||
|
||||
private void CalcLinearLabelPoints(GaugeLinearScale scale)
|
||||
{
|
||||
double labelInterval = (_Interval.Equals(double.NaN) ?
|
||||
scale.MajorTickMarks.Interval : _Interval);
|
||||
|
||||
double labelIntervalOffset = (_IntervalOffset.Equals(double.NaN) ?
|
||||
scale.MajorTickMarks.IntervalOffset : _IntervalOffset);
|
||||
|
||||
double spread = Math.Abs(scale.MaxValue - scale.MinValue);
|
||||
double dpt = scale.AbsScaleLength / spread;
|
||||
|
||||
int n = GetPointCount(spread, labelInterval, labelIntervalOffset);
|
||||
|
||||
if (n > 0)
|
||||
{
|
||||
if (scale.Orientation == Orientation.Horizontal)
|
||||
CalcHorizontalLabelPoints(scale, n, dpt, labelInterval, labelIntervalOffset);
|
||||
else
|
||||
CalcVerticalLabelPoints(scale, n, dpt, labelInterval, labelIntervalOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
_LabelPoints = null;
|
||||
}
|
||||
}
|
||||
|
||||
#region CalcHorizontalLabelPoints
|
||||
|
||||
private void CalcHorizontalLabelPoints(GaugeLinearScale scale,
|
||||
int n, double dpt, double labelInterval, double labelIntervalOffset)
|
||||
{
|
||||
double interval = (_ShowMinLabel == true ?
|
||||
0 : labelIntervalOffset > 0 ? labelIntervalOffset : labelInterval);
|
||||
|
||||
int y = scale.ScaleBounds.Y + Offset;
|
||||
|
||||
_LabelPoints = new LabelPoint[n];
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
_LabelPoints[i] = new LabelPoint();
|
||||
|
||||
if (interval + Scale.MinValue > Scale.MaxValue)
|
||||
interval = Scale.MaxValue - Scale.MinValue;
|
||||
|
||||
int x = (scale.Reversed == true)
|
||||
? (int)(Scale.Bounds.Right - dpt * interval)
|
||||
: (int)(Scale.Bounds.X + dpt * interval);
|
||||
|
||||
_LabelPoints[i].Point = new Point(x, y);
|
||||
_LabelPoints[i].Interval = interval;
|
||||
|
||||
if (interval >= labelIntervalOffset)
|
||||
interval += labelInterval;
|
||||
else
|
||||
interval = labelIntervalOffset;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CalcVerticalLabelPoints
|
||||
|
||||
private void CalcVerticalLabelPoints(GaugeLinearScale scale,
|
||||
int n, double dpt, double labelInterval, double labelIntervalOffset)
|
||||
{
|
||||
double interval = (_ShowMinLabel == true ?
|
||||
0 : labelIntervalOffset > 0 ? labelIntervalOffset : labelInterval);
|
||||
|
||||
int x = scale.ScaleBounds.X + Offset;
|
||||
|
||||
_LabelPoints = new LabelPoint[n];
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
_LabelPoints[i] = new LabelPoint();
|
||||
|
||||
if (interval + Scale.MinValue > Scale.MaxValue)
|
||||
interval = Scale.MaxValue - Scale.MinValue;
|
||||
|
||||
int y = (scale.Reversed == true)
|
||||
? (int)(Scale.Bounds.Top + dpt * interval)
|
||||
: (int)(Scale.Bounds.Bottom - dpt * interval);
|
||||
|
||||
_LabelPoints[i].Point = new Point(x, y);
|
||||
_LabelPoints[i].Interval = interval;
|
||||
|
||||
if (interval >= labelIntervalOffset)
|
||||
interval += labelInterval;
|
||||
else
|
||||
interval = labelIntervalOffset;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetPointCount
|
||||
|
||||
private int GetPointCount(double spread,
|
||||
double labelInterval, double labelIntervalOffset)
|
||||
{
|
||||
int n = (int)Math.Ceiling((spread - labelIntervalOffset) / labelInterval) + 1;
|
||||
|
||||
if (labelIntervalOffset == 0)
|
||||
{
|
||||
if (_ShowMinLabel == false)
|
||||
n--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_ShowMinLabel == true)
|
||||
n++;
|
||||
}
|
||||
|
||||
if (_ShowMaxLabel == false)
|
||||
n--;
|
||||
|
||||
return (n);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region OnPaint
|
||||
|
||||
public override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
Graphics g = e.Graphics;
|
||||
|
||||
RecalcLayout();
|
||||
|
||||
if (Scale.GaugeControl.OnPreRenderScaleTickMarkLabels(e, Scale) == false)
|
||||
{
|
||||
if (_LabelPoints != null)
|
||||
{
|
||||
Font font = AbsFont;
|
||||
SolidBrush br = null;
|
||||
|
||||
try
|
||||
{
|
||||
foreach (LabelPoint lp in _LabelPoints)
|
||||
{
|
||||
if (CanDisplayLabel(lp) == true)
|
||||
{
|
||||
br = GetLabelBrush(br, lp);
|
||||
|
||||
PaintLabel(g, GetLabelText(lp), br, lp, font);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (br != null)
|
||||
br.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
Scale.GaugeControl.OnPostRenderScaleTickMarkLabels(e, Scale);
|
||||
}
|
||||
}
|
||||
|
||||
#region GetLabelText
|
||||
|
||||
private string GetLabelText(LabelPoint labelPoint)
|
||||
{
|
||||
double n = Scale.GetIntervalValue(labelPoint.Interval);
|
||||
|
||||
if (String.IsNullOrEmpty(_FormatString) == false)
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (_FormatString[0])
|
||||
{
|
||||
case 'X':
|
||||
case 'x':
|
||||
return (String.Format("{0:" + _FormatString + "}", (int) n));
|
||||
|
||||
default:
|
||||
return (String.Format("{0:" + _FormatString + "}", n));
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return (n.ToString());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetLabelBrush
|
||||
|
||||
private SolidBrush GetLabelBrush(SolidBrush br, LabelPoint lp)
|
||||
{
|
||||
Color color = GetLabelColor(lp);
|
||||
|
||||
if (br == null || br.Color != color)
|
||||
{
|
||||
if (br != null)
|
||||
br.Dispose();
|
||||
|
||||
br = new SolidBrush(color);
|
||||
}
|
||||
|
||||
return (br);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetLabelColor
|
||||
|
||||
private Color GetLabelColor(LabelPoint lp)
|
||||
{
|
||||
Color labelColor = Scale.GetRangeLabelColor(lp.Interval);
|
||||
|
||||
if (labelColor.IsEmpty == true)
|
||||
labelColor = Scale.GetSectionLabelColor(lp.Interval);
|
||||
|
||||
if (labelColor.IsEmpty == true)
|
||||
labelColor = Layout.ForeColor;
|
||||
|
||||
return (labelColor);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CanDisplayLabel
|
||||
|
||||
private bool CanDisplayLabel(LabelPoint labelPoint)
|
||||
{
|
||||
if (labelPoint.Visible == false)
|
||||
return (false);
|
||||
|
||||
if (Scale.HasCustomLabels == true)
|
||||
{
|
||||
foreach (GaugeCustomLabel label in Scale.CustomLabels)
|
||||
{
|
||||
if (label.Visible == true)
|
||||
{
|
||||
if (label.Layout.Placement == Layout.Placement)
|
||||
{
|
||||
if (label.Value == Scale.MinValue + labelPoint.Interval)
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region ICloneable Members
|
||||
|
||||
public override object Clone()
|
||||
{
|
||||
GaugeIntervalLabel copy = new GaugeIntervalLabel(Scale);
|
||||
|
||||
CopyToItem(copy);
|
||||
|
||||
return (copy);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CopyToItem
|
||||
|
||||
public override void CopyToItem(GaugeItem copy)
|
||||
{
|
||||
GaugeIntervalLabel c = copy as GaugeIntervalLabel;
|
||||
|
||||
if (c != null)
|
||||
{
|
||||
base.CopyToItem(c);
|
||||
|
||||
c.FormatString = _FormatString;
|
||||
c.Interval = _Interval;
|
||||
c.IntervalOffset = _IntervalOffset;
|
||||
c.ShowMaxLabel = _ShowMaxLabel;
|
||||
c.ShowMinLabel = _ShowMinLabel;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#region GaugeLabelConvertor
|
||||
|
||||
public class GaugeLabelConvertor : ExpandableObjectConverter
|
||||
{
|
||||
public override object ConvertTo(
|
||||
ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
|
||||
{
|
||||
if (destinationType == typeof(string))
|
||||
{
|
||||
GaugeIntervalLabel label = value as GaugeIntervalLabel;
|
||||
|
||||
if (label != null)
|
||||
{
|
||||
//ColorConverter cvt = new ColorConverter();
|
||||
|
||||
//if (lct.Start != Color.Empty)
|
||||
// return (cvt.ConvertToString(lct.Start));
|
||||
|
||||
//if (lct.End != Color.Empty)
|
||||
// return (cvt.ConvertToString(lct.End));
|
||||
|
||||
//if (lct.GradientAngle != 90)
|
||||
// return (lct.GradientAngle.ToString());
|
||||
|
||||
return (String.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
return (base.ConvertTo(context, culture, value, destinationType));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
@@ -0,0 +1,409 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Design;
|
||||
using System.Globalization;
|
||||
|
||||
namespace DevComponents.Instrumentation
|
||||
{
|
||||
[TypeConverter(typeof(LabelLayoutConvertor))]
|
||||
public class LabelLayout : IDisposable, ICloneable
|
||||
{
|
||||
#region Events
|
||||
|
||||
public event EventHandler<EventArgs> LabelLayoutChanged;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private variables
|
||||
|
||||
private DisplayPlacement _Placement;
|
||||
private float _ScaleOffset;
|
||||
|
||||
private Font _Font;
|
||||
private Font _AbsFont;
|
||||
private float _Angle;
|
||||
|
||||
private bool _AutoSize;
|
||||
private bool _RotateLabel;
|
||||
private bool _AdaptiveLabel;
|
||||
private bool _AutoOrientLabel;
|
||||
|
||||
private Color _ForeColor;
|
||||
|
||||
#endregion
|
||||
|
||||
public LabelLayout()
|
||||
{
|
||||
_ForeColor = Color.Black;
|
||||
|
||||
_Placement = DisplayPlacement.Near;
|
||||
|
||||
_AutoSize = true;
|
||||
_AutoOrientLabel = true;
|
||||
_RotateLabel = true;
|
||||
}
|
||||
|
||||
#region Public properties
|
||||
|
||||
#region AdaptiveLabel
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether labels are to adapt to the scale shape
|
||||
/// </summary>
|
||||
[Browsable(true)]
|
||||
[Category("Behavior"), DefaultValue(false)]
|
||||
[Description("Indicates whether labels are to adapt to the scale shape.")]
|
||||
public bool AdaptiveLabel
|
||||
{
|
||||
get { return (_AdaptiveLabel); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_AdaptiveLabel != value)
|
||||
{
|
||||
_AdaptiveLabel = value;
|
||||
|
||||
OnLabelLayoutChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Angle
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the additional number of degrees the label will be rotated
|
||||
/// </summary>
|
||||
[Browsable(true), Category("Appearance"), DefaultValue(0f)]
|
||||
[Description("Indicates the additional number of degrees the label will be rotated.")]
|
||||
[Editor("DevComponents.Instrumentation.Design.AngleRangeValueEditor, DevComponents.Instrumentation.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=76cb4c6eb576bca5", typeof(UITypeEditor))]
|
||||
[NotifyParentProperty(true)]
|
||||
public float Angle
|
||||
{
|
||||
get { return (_Angle); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_Angle != value)
|
||||
{
|
||||
_Angle = value;
|
||||
|
||||
OnLabelLayoutChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region AutoOrientLabel
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the label will be auto oriented away from being upside down
|
||||
/// </summary>
|
||||
[Browsable(true)]
|
||||
[Category("Behavior"), DefaultValue(true)]
|
||||
[Description("Indicates whether the label will be auto oriented away from being upside down.")]
|
||||
public bool AutoOrientLabel
|
||||
{
|
||||
get { return (_AutoOrientLabel); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_AutoOrientLabel != value)
|
||||
{
|
||||
_AutoOrientLabel = value;
|
||||
|
||||
OnLabelLayoutChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region AutoSize
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the label Font size is auto sized
|
||||
/// </summary>
|
||||
[Browsable(true)]
|
||||
[Category("Behavior"), DefaultValue(true)]
|
||||
[Description("Indicates whether the label Font size is auto sized.")]
|
||||
public bool AutoSize
|
||||
{
|
||||
get { return (_AutoSize); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_AutoSize != value)
|
||||
{
|
||||
_AutoSize = value;
|
||||
AbsFont = null;
|
||||
|
||||
OnLabelLayoutChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Font
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Font to use for the label
|
||||
/// </summary>
|
||||
[Browsable(true)]
|
||||
[Category("Appearance")]
|
||||
[Description("Indicates the Font to use for the label.")]
|
||||
public Font Font
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_Font == null)
|
||||
_Font = new Font("Microsoft SanSerif", 12);
|
||||
|
||||
return (_Font);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (_Font != null)
|
||||
_Font.Dispose();
|
||||
|
||||
_Font = value;
|
||||
AbsFont = null;
|
||||
|
||||
OnLabelLayoutChanged();
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
internal virtual bool ShouldSerializeFont()
|
||||
{
|
||||
if (_Font == null)
|
||||
return (false);
|
||||
|
||||
using (Font font = new Font("Microsoft SanSerif", 12))
|
||||
return (_Font.Equals(font) == false);
|
||||
}
|
||||
|
||||
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
internal virtual void ResetFont()
|
||||
{
|
||||
Font = new Font("Microsoft SanSerif", 12);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ForeColor
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Label text Color
|
||||
/// </summary>
|
||||
[Browsable(true), Category("Appearance"), DefaultValue(typeof(Color), "Black")]
|
||||
[Description("Indicates the Label text Color.")]
|
||||
public Color ForeColor
|
||||
{
|
||||
get { return (_ForeColor); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_ForeColor != value)
|
||||
{
|
||||
_ForeColor = value;
|
||||
|
||||
OnLabelLayoutChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Placement
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Placement of the Label with respect to the Scale
|
||||
/// </summary>
|
||||
[Browsable(true)]
|
||||
[Category("Layout"), DefaultValue(DisplayPlacement.Near)]
|
||||
[Description("Indicates the Placement of the Label with respect to the Scale.")]
|
||||
public DisplayPlacement Placement
|
||||
{
|
||||
get { return (_Placement); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_Placement != value)
|
||||
{
|
||||
_Placement = value;
|
||||
|
||||
OnLabelLayoutChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region RotateLabel
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether labels are rotated along the scale
|
||||
/// </summary>
|
||||
[Browsable(true)]
|
||||
[Category("Behavior"), DefaultValue(true)]
|
||||
[Description("Indicates whether labels are rotated along the scale.")]
|
||||
public bool RotateLabel
|
||||
{
|
||||
get { return (_RotateLabel); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_RotateLabel != value)
|
||||
{
|
||||
_RotateLabel = value;
|
||||
|
||||
OnLabelLayoutChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ScaleOffset
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the distance from the Label to the Scale, measured as a percentage
|
||||
/// </summary>
|
||||
[Browsable(true)]
|
||||
[Category("Layout"), DefaultValue(0f)]
|
||||
[Editor("DevComponents.Instrumentation.Design.OffsetRangeValueEditor, DevComponents.Instrumentation.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=76cb4c6eb576bca5", typeof(UITypeEditor))]
|
||||
[Description("Indicates the distance from the Label to the Scale, measured as a percentage.")]
|
||||
public float ScaleOffset
|
||||
{
|
||||
get { return (_ScaleOffset); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_ScaleOffset != value)
|
||||
{
|
||||
_ScaleOffset = value;
|
||||
|
||||
OnLabelLayoutChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Internal properties
|
||||
|
||||
#region AbsFont
|
||||
|
||||
internal Font AbsFont
|
||||
{
|
||||
get { return (_AbsFont); }
|
||||
|
||||
set
|
||||
{
|
||||
if (_AbsFont != null)
|
||||
_AbsFont.Dispose();
|
||||
|
||||
_AbsFont = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region OnLabelLayoutChanged
|
||||
|
||||
private void OnLabelLayoutChanged()
|
||||
{
|
||||
if (LabelLayoutChanged != null)
|
||||
LabelLayoutChanged(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Font = null;
|
||||
AbsFont = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ICloneable Members
|
||||
|
||||
public virtual object Clone()
|
||||
{
|
||||
LabelLayout copy = new LabelLayout();
|
||||
|
||||
CopyToItem(copy);
|
||||
|
||||
return (copy);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CopyToItem
|
||||
|
||||
internal virtual void CopyToItem(LabelLayout copy)
|
||||
{
|
||||
copy.AdaptiveLabel = _AdaptiveLabel;
|
||||
copy.Angle = _Angle;
|
||||
copy.AutoOrientLabel = _AutoOrientLabel;
|
||||
copy.AutoSize = _AutoSize;
|
||||
|
||||
if (_Font != null)
|
||||
copy.Font = (Font)_Font.Clone();
|
||||
|
||||
copy.ForeColor = _ForeColor;
|
||||
copy.Placement = _Placement;
|
||||
copy.RotateLabel = _RotateLabel;
|
||||
copy.ScaleOffset = _ScaleOffset;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#region LabelLayoutConvertor
|
||||
|
||||
public class LabelLayoutConvertor : ExpandableObjectConverter
|
||||
{
|
||||
public override object ConvertTo(
|
||||
ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
|
||||
{
|
||||
if (destinationType == typeof(string))
|
||||
{
|
||||
LabelLayout ll = value as LabelLayout;
|
||||
|
||||
if (ll != null)
|
||||
{
|
||||
//ColorConverter cvt = new ColorConverter();
|
||||
|
||||
//if (lct.Start != Color.Empty)
|
||||
// return (cvt.ConvertToString(lct.Start));
|
||||
|
||||
//if (lct.End != Color.Empty)
|
||||
// return (cvt.ConvertToString(lct.End));
|
||||
|
||||
//if (lct.GradientAngle != 90)
|
||||
// return (lct.GradientAngle.ToString());
|
||||
|
||||
return (String.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
return (base.ConvertTo(context, culture, value, destinationType));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
@@ -0,0 +1,152 @@
|
||||
using System.Drawing;
|
||||
|
||||
namespace DevComponents.Instrumentation
|
||||
{
|
||||
internal class LabelPoint
|
||||
{
|
||||
#region Private variables
|
||||
|
||||
private Point _Point;
|
||||
private float _Angle;
|
||||
private double _Interval;
|
||||
|
||||
private bool _Visible = true;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
|
||||
#region Angle
|
||||
|
||||
public float Angle
|
||||
{
|
||||
get { return (_Angle); }
|
||||
set { _Angle = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Point
|
||||
|
||||
public Point Point
|
||||
{
|
||||
get { return (_Point); }
|
||||
set { _Point = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Interval
|
||||
|
||||
public double Interval
|
||||
{
|
||||
get { return (_Interval); }
|
||||
set { _Interval = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Visible
|
||||
|
||||
public bool Visible
|
||||
{
|
||||
get { return (_Visible); }
|
||||
set { _Visible = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region PaintRotatedLabel
|
||||
|
||||
public void PaintRotatedLabel(Graphics g,
|
||||
string text, LabelLayout layout, int height, Brush br, Font font)
|
||||
{
|
||||
SizeF sz = g.MeasureString(text, font);
|
||||
Size size = sz.ToSize();
|
||||
|
||||
Point pt = new Point(0, 0);
|
||||
|
||||
switch (layout.Placement)
|
||||
{
|
||||
case DisplayPlacement.Far:
|
||||
pt.Y = -height / 2;
|
||||
break;
|
||||
|
||||
case DisplayPlacement.Near:
|
||||
pt.Y = height / 2;
|
||||
break;
|
||||
}
|
||||
|
||||
g.TranslateTransform(_Point.X, _Point.Y);
|
||||
g.RotateTransform((_Angle + 90) % 360);
|
||||
g.TranslateTransform(pt.X, pt.Y);
|
||||
|
||||
float fontAngle = layout.Angle;
|
||||
|
||||
if (layout.AutoOrientLabel == true)
|
||||
{
|
||||
if (((_Angle + layout.Angle) % 360) < 180)
|
||||
fontAngle += 180;
|
||||
}
|
||||
|
||||
g.RotateTransform(fontAngle);
|
||||
|
||||
g.DrawString(text, font, br,
|
||||
new Point(-size.Width / 2, -size.Height / 2));
|
||||
|
||||
g.ResetTransform();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PaintNonRotatedLabel
|
||||
|
||||
public void PaintNonRotatedLabel(Graphics g, string text,
|
||||
LabelLayout layout, Point center, int radius, Brush br, Font font)
|
||||
{
|
||||
SizeF sz = g.MeasureString(text, font);
|
||||
|
||||
int x = _Point.X - center.X;
|
||||
int y = _Point.Y - center.Y;
|
||||
|
||||
Point pt = new Point();
|
||||
|
||||
switch (layout.Placement)
|
||||
{
|
||||
case DisplayPlacement.Far:
|
||||
{
|
||||
int dx = (int)(((float)(x - radius) / (radius * 2)) * sz.Width);
|
||||
int dy = (int)(((float)(y - radius) / (radius * 2)) * sz.Height);
|
||||
|
||||
pt = new Point(_Point.X + dx, _Point.Y + dy);
|
||||
}
|
||||
break;
|
||||
|
||||
case DisplayPlacement.Near:
|
||||
{
|
||||
int dx = (int)(((float)(x + radius) / (radius * 2)) * sz.Width);
|
||||
int dy = (int)(((float)(y + radius) / (radius * 2)) * sz.Height);
|
||||
|
||||
pt = new Point(_Point.X - dx, _Point.Y - dy);
|
||||
}
|
||||
break;
|
||||
|
||||
case DisplayPlacement.Center:
|
||||
{
|
||||
int dx = (int)(sz.Width / 2);
|
||||
int dy = (int)(sz.Height / 2);
|
||||
|
||||
pt = new Point(_Point.X - dx, _Point.Y - dy);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
g.DrawString(text, font, br, pt);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user