diff --git a/Actions/ChemicalWeighing/Mesnac.Action.ChemicalWeighing/Product/PptPlan/FrmPlan.cs b/Actions/ChemicalWeighing/Mesnac.Action.ChemicalWeighing/Product/PptPlan/FrmPlan.cs
index 3291e4c..17fd5f1 100644
--- a/Actions/ChemicalWeighing/Mesnac.Action.ChemicalWeighing/Product/PptPlan/FrmPlan.cs
+++ b/Actions/ChemicalWeighing/Mesnac.Action.ChemicalWeighing/Product/PptPlan/FrmPlan.cs
@@ -212,6 +212,7 @@ namespace Mesnac.Action.ChemicalWeighing.Product.PptPlan
{
this.InitUI();
this.InitData();
+ // InitRecipeVersionData();
}
private void FrmPlan_Activated(object sender, EventArgs e)
diff --git a/Controls/Mesnac.Controls.ChemicalWeighing/HslHelper.cs b/Controls/Mesnac.Controls.ChemicalWeighing/HslHelper.cs
new file mode 100644
index 0000000..7355efc
--- /dev/null
+++ b/Controls/Mesnac.Controls.ChemicalWeighing/HslHelper.cs
@@ -0,0 +1,639 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing.Drawing2D;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace Mesnac.Controls.ChemicalWeighing
+{
+ /// 整个组件的代码辅助工具,提供了一个基础的类库方法
+ public class HslHelper
+ {
+ static HslHelper()
+ {
+ HslHelper.StringFormatDefault = new StringFormat();
+ HslHelper.StringFormatCenter = new StringFormat();
+ HslHelper.StringFormatCenter.Alignment = StringAlignment.Center;
+ HslHelper.StringFormatCenter.LineAlignment = StringAlignment.Center;
+ HslHelper.StringFormatLeft = new StringFormat();
+ HslHelper.StringFormatLeft.LineAlignment = StringAlignment.Center;
+ HslHelper.StringFormatLeft.Alignment = StringAlignment.Near;
+ HslHelper.StringFormatRight = new StringFormat();
+ HslHelper.StringFormatRight.LineAlignment = StringAlignment.Center;
+ HslHelper.StringFormatRight.Alignment = StringAlignment.Far;
+ HslHelper.StringFormatTopCenter = new StringFormat();
+ HslHelper.StringFormatTopCenter.Alignment = StringAlignment.Center;
+ HslHelper.StringFormatTopCenter.LineAlignment = StringAlignment.Near;
+ }
+
+ /// 返回中间范围值数据,如果大于最大值,则返回最大值,如果小于最小值,则返回最小值
+ /// 最小值
+ /// 实际值
+ /// 最大值
+ /// 中间值信息
+ public static int Middle(int min, int value, int max)
+ {
+ if (value > max)
+ return max;
+ return value < min ? min : value;
+ }
+
+ /// 从一个矩形的图形中获取菱形的坐标数组
+ /// 矩形
+ /// 数组结果
+ public static Point[] GetRhombusFromRectangle(Rectangle rect) => new Point[5]
+ {
+ new Point(rect.X, rect.Y + rect.Height / 2),
+ new Point(rect.X + rect.Width / 2, rect.Y + rect.Height - 1),
+ new Point(rect.X + rect.Width - 1, rect.Y + rect.Height / 2),
+ new Point(rect.X + rect.Width / 2, rect.Y),
+ new Point(rect.X, rect.Y + rect.Height / 2)
+ };
+
+ /// 计算绘图时的相对偏移值
+ /// 0-100分的最大值,就是指准备绘制的最大值
+ /// 0-100分的最小值,就是指准备绘制的最小值
+ /// 实际绘图区域的高度
+ /// 需要绘制数据的当前值
+ /// 相对于0的位置,还需要增加上面的偏值
+ public static float ComputePaintLocationY(int max, int min, int height, int value) => (double)(max - min) == 0.0 ? (float)height : (float)height - (float)(value - min) * 1f / (float)(max - min) * (float)height;
+
+ /// 计算绘图Y轴时的相对偏移值
+ /// 0-100分的最大值,就是指准备绘制的最大值
+ /// 0-100分的最小值,就是指准备绘制的最小值
+ /// 实际绘图区域的高度
+ /// 需要绘制数据的当前值
+ /// 相对于0的位置,还需要增加上面的偏值
+ public static float ComputePaintLocationY(float max, float min, float height, float value)
+ {
+ if ((double)max - (double)min == 0.0)
+ return height;
+ float num = max - min;
+ if ((double)num == 0.0)
+ num = 1f;
+ return height - (value - min) / num * height;
+ }
+
+ /// 计算绘图X轴时的相对偏移值
+ /// 0-100分的最大值,就是指准备绘制的最大值
+ /// 0-100分的最小值,就是指准备绘制的最小值
+ /// 实际绘图区域的宽度
+ /// 需要绘制数据的当前值
+ /// 相对于0的位置,还需要增加上面的偏值
+ public static float ComputePaintLocationX(float max, float min, float width, float value)
+ {
+ if ((double)max - (double)min == 0.0)
+ return width;
+ float num = max - min;
+ if ((double)num == 0.0)
+ num = 1f;
+ return (value - min) / num * width;
+ }
+
+ /// 根据绘制的值计算原始的值信息
+ /// 0-100分的最大值,就是指准备绘制的最大值
+ /// 0-100分的最小值,就是指准备绘制的最小值
+ /// 实际绘图区域的高度
+ /// 实际绘制的位置信息
+ /// 实际的值信息
+ public static float ComputeValueFromPaintLocationY(
+ float max,
+ float min,
+ float height,
+ float paint)
+ {
+ if ((double)max - (double)min == 0.0)
+ return max;
+ float num = max - min;
+ if ((double)num == 0.0)
+ num = 1f;
+ return (height - paint) * num / height + min;
+ }
+
+ /// 计算绘图时的相对偏移值
+ /// 坐标轴信息
+ /// 实际绘图区域的高度
+ /// 需要绘制数据的当前值
+ /// 相对于0的位置,还需要增加上面的偏值
+ public static float ComputePaintLocationY(
+ ReferenceAxis referenceAxis,
+ float height,
+ float value)
+ {
+ return HslHelper.ComputePaintLocationY(referenceAxis.Max, referenceAxis.Min, height, value);
+ }
+
+ /// 绘制坐标系中的刻度线
+ /// 绘图对象
+ /// 画坐标轴的画笔
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static void PaintCoordinateDivide(
+ Graphics g,
+ System.Drawing.Pen penLine,
+ System.Drawing.Pen penDash,
+ Font font,
+ System.Drawing.Brush brush,
+ StringFormat sf,
+ int degree,
+ int max,
+ int min,
+ int width,
+ int height,
+ int left = 60,
+ int right = 8,
+ int up = 8,
+ int down = 8)
+ {
+ for (int index = 0; index <= degree; ++index)
+ {
+ int num1 = (max - min) * index / degree + min;
+ int num2 = (int)HslHelper.ComputePaintLocationY(max, min, height - up - down, num1) + up + 1;
+ g.DrawLine(penLine, left - 1, num2, left - 4, num2);
+ if (index != 0)
+ g.DrawLine(penDash, left, num2, width - right, num2);
+ g.DrawString(num1.ToString(), font, brush, (RectangleF)new Rectangle(-5, num2 - font.Height / 2, left, font.Height), sf);
+ }
+ }
+
+ /// 根据指定的方向绘制一个箭头
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static void PaintTriangle(
+ Graphics g,
+ System.Drawing.Brush brush,
+ Point point,
+ int size,
+ GraphDirection direction)
+ {
+ Point[] points = new Point[4];
+ switch (direction)
+ {
+ case GraphDirection.Upward:
+ points[0] = new Point(point.X - size, point.Y);
+ points[1] = new Point(point.X + size, point.Y);
+ points[2] = new Point(point.X, point.Y - 2 * size);
+ break;
+ case GraphDirection.Leftward:
+ points[0] = new Point(point.X, point.Y - size);
+ points[1] = new Point(point.X, point.Y + size);
+ points[2] = new Point(point.X - 2 * size, point.Y);
+ break;
+ case GraphDirection.Rightward:
+ points[0] = new Point(point.X, point.Y - size);
+ points[1] = new Point(point.X, point.Y + size);
+ points[2] = new Point(point.X + 2 * size, point.Y);
+ break;
+ default:
+ points[0] = new Point(point.X - size, point.Y);
+ points[1] = new Point(point.X + size, point.Y);
+ points[2] = new Point(point.X, point.Y + 2 * size);
+ break;
+ }
+ points[3] = points[0];
+ g.FillPolygon(brush, points);
+ }
+
+ /// 绘制向左或是向右的箭头,例如 << 或是 >>
+ /// 画刷资源
+ /// 画笔资源
+ /// 绘制的矩形
+ /// 方向信息
+ public static void DrawLeftRight(
+ Graphics g,
+ System.Drawing.Pen pen,
+ Rectangle rectangle,
+ GraphDirection direction)
+ {
+ if (direction == GraphDirection.Leftward)
+ {
+ g.DrawLines(pen, new Point[3]
+ {
+ new Point(rectangle.X + rectangle.Width / 2, rectangle.Y),
+ new Point(rectangle.X, rectangle.Y + rectangle.Height / 2),
+ new Point(rectangle.X + rectangle.Width / 2, rectangle.Y + rectangle.Height)
+ });
+ g.DrawLines(pen, new Point[3]
+ {
+ new Point(rectangle.X + rectangle.Width, rectangle.Y),
+ new Point(rectangle.X + rectangle.Width / 2, rectangle.Y + rectangle.Height / 2),
+ new Point(rectangle.X + rectangle.Width, rectangle.Y + rectangle.Height)
+ });
+ }
+ else
+ {
+ if (direction != GraphDirection.Rightward)
+ return;
+ g.DrawLines(pen, new Point[3]
+ {
+ new Point(rectangle.X, rectangle.Y),
+ new Point(rectangle.X + rectangle.Width / 2, rectangle.Y + rectangle.Height / 2),
+ new Point(rectangle.X, rectangle.Y + rectangle.Height)
+ });
+ g.DrawLines(pen, new Point[3]
+ {
+ new Point(rectangle.X + rectangle.Width / 2, rectangle.Y),
+ new Point(rectangle.X + rectangle.Width, rectangle.Y + rectangle.Height / 2),
+ new Point(rectangle.X + rectangle.Width / 2, rectangle.Y + rectangle.Height)
+ });
+ }
+ }
+
+ /// 根据指定的方向绘制一个箭头
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static void PaintTriangle(
+ Graphics g,
+ System.Drawing.Brush brush,
+ PointF point,
+ int size,
+ GraphDirection direction)
+ {
+ PointF[] points = new PointF[4];
+ switch (direction)
+ {
+ case GraphDirection.Upward:
+ points[0] = new PointF(point.X - (float)size, point.Y);
+ points[1] = new PointF(point.X + (float)size, point.Y);
+ points[2] = new PointF(point.X, point.Y - (float)(2 * size));
+ break;
+ case GraphDirection.Leftward:
+ points[0] = new PointF(point.X, point.Y - (float)size);
+ points[1] = new PointF(point.X, point.Y + (float)size);
+ points[2] = new PointF(point.X - (float)(2 * size), point.Y);
+ break;
+ case GraphDirection.Rightward:
+ points[0] = new PointF(point.X, point.Y - (float)size);
+ points[1] = new PointF(point.X, point.Y + (float)size);
+ points[2] = new PointF(point.X + (float)(2 * size), point.Y);
+ break;
+ default:
+ points[0] = new PointF(point.X - (float)size, point.Y);
+ points[1] = new PointF(point.X + (float)size, point.Y);
+ points[2] = new PointF(point.X, point.Y + (float)(2 * size));
+ break;
+ }
+ points[3] = points[0];
+ g.FillPolygon(brush, points);
+ }
+
+ ///
+ /// 一个通用的数组新增个数方法,会自动判断越界情况,越界的情况下,会自动的截断或是填充 ->
+ /// A common array of new methods, will automatically determine the cross-border situation, in the case of cross-border, will be automatically truncated or filled
+ ///
+ /// 数据类型
+ /// 原数据
+ /// 等待新增的数据
+ /// 原数据的最大值
+ public static void AddArrayData(ref T[] array, T[] data, int max)
+ {
+ if (data == null || data.Length == 0)
+ return;
+ if (array.Length == max)
+ {
+ Array.Copy((Array)array, data.Length, (Array)array, 0, array.Length - data.Length);
+ Array.Copy((Array)data, 0, (Array)array, array.Length - data.Length, data.Length);
+ }
+ else if (array.Length + data.Length > max)
+ {
+ T[] objArray = new T[max];
+ for (int index = 0; index < max - data.Length; ++index)
+ objArray[index] = array[index + (array.Length - max + data.Length)];
+ for (int index = 0; index < data.Length; ++index)
+ objArray[objArray.Length - data.Length + index] = data[index];
+ array = objArray;
+ }
+ else
+ {
+ T[] objArray = new T[array.Length + data.Length];
+ for (int index = 0; index < array.Length; ++index)
+ objArray[index] = array[index];
+ for (int index = 0; index < data.Length; ++index)
+ objArray[objArray.Length - data.Length + index] = data[index];
+ array = objArray;
+ }
+ }
+
+ /// 尺寸转换,计算旋转后的尺寸。
+ ///
+ ///
+ ///
+ public static SizeF ConvertSize(SizeF size, float angle)
+ {
+ System.Drawing.Drawing2D.Matrix matrix = new System.Drawing.Drawing2D.Matrix();
+ matrix.Rotate(angle);
+ PointF[] pts = new PointF[4];
+ pts[0].X = (float)(-(double)size.Width / 2.0);
+ pts[0].Y = (float)(-(double)size.Height / 2.0);
+ pts[1].X = (float)(-(double)size.Width / 2.0);
+ pts[1].Y = size.Height / 2f;
+ pts[2].X = size.Width / 2f;
+ pts[2].Y = size.Height / 2f;
+ pts[3].X = size.Width / 2f;
+ pts[3].Y = (float)(-(double)size.Height / 2.0);
+ matrix.TransformPoints(pts);
+ float num1 = float.MaxValue;
+ float num2 = float.MinValue;
+ float num3 = float.MaxValue;
+ float num4 = float.MinValue;
+ foreach (PointF pointF in pts)
+ {
+ if ((double)pointF.X < (double)num1)
+ num1 = pointF.X;
+ if ((double)pointF.X > (double)num2)
+ num2 = pointF.X;
+ if ((double)pointF.Y < (double)num3)
+ num3 = pointF.Y;
+ if ((double)pointF.Y > (double)num4)
+ num4 = pointF.Y;
+ }
+ return new SizeF(num2 - num1, num4 - num3);
+ }
+
+ /// 绘制旋转文本
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static void DrawString(
+ Graphics g,
+ string s,
+ Font font,
+ System.Drawing.Brush brush,
+ PointF point,
+ StringFormat format,
+ float angle)
+ {
+ System.Drawing.Drawing2D.Matrix transform1 = g.Transform;
+ System.Drawing.Drawing2D.Matrix transform2 = g.Transform;
+ transform2.RotateAt(angle, point);
+ g.Transform = transform2;
+ g.DrawString(s, font, brush, point, format);
+ g.Transform = transform1;
+ }
+
+ private static int GetPow(int digit)
+ {
+ int pow = 1;
+ for (int index = 0; index < digit; ++index)
+ pow *= 10;
+ return pow;
+ }
+
+ /// 将int数组转换为double数组
+ /// int数组值
+ /// 结果值
+ public static double[] TranlateArrayToDouble(int[] values)
+ {
+ if (values == null)
+ return (double[])null;
+ double[] numArray = new double[values.Length];
+ for (int index = 0; index < values.Length; ++index)
+ numArray[index] = (double)values[index];
+ return numArray;
+ }
+
+ /// 将float数组转换为double数组值
+ /// float数组值
+ /// 结果值
+ public static double[] TranlateArrayToDouble(float[] values)
+ {
+ double[] numArray = new double[values.Length];
+ for (int index = 0; index < values.Length; ++index)
+ numArray[index] = (double)values[index];
+ return numArray;
+ }
+
+ /// 获得数据的上限值,这个上限值是自动计算的。
+ /// 数据值
+ /// 数据值
+ public static int CalculateMaxSectionFrom(double[] values)
+ {
+ double a = ((IEnumerable)values).Max();
+ if (a <= 5.0)
+ return 5;
+ if (a <= 9.0)
+ return 10;
+ int int32 = Convert.ToInt32(Math.Ceiling(a));
+ int digit = int32.ToString().Length - 2;
+ int num = int.Parse(int32.ToString().Substring(0, 2));
+ if (num < 11)
+ return 12 * HslHelper.GetPow(digit);
+ if (num < 13)
+ return 14 * HslHelper.GetPow(digit);
+ if (num < 15)
+ return 16 * HslHelper.GetPow(digit);
+ if (num < 17)
+ return 18 * HslHelper.GetPow(digit);
+ if (num < 19)
+ return 20 * HslHelper.GetPow(digit);
+ if (num < 21)
+ return 22 * HslHelper.GetPow(digit);
+ if (num < 23)
+ return 24 * HslHelper.GetPow(digit);
+ if (num < 25)
+ return 26 * HslHelper.GetPow(digit);
+ if (num < 27)
+ return 28 * HslHelper.GetPow(digit);
+ if (num < 29)
+ return 30 * HslHelper.GetPow(digit);
+ if (num < 33)
+ return 34 * HslHelper.GetPow(digit);
+ if (num < 40)
+ return 40 * HslHelper.GetPow(digit);
+ if (num < 50)
+ return 50 * HslHelper.GetPow(digit);
+ if (num < 60)
+ return 60 * HslHelper.GetPow(digit);
+ if (num < 80)
+ return 80 * HslHelper.GetPow(digit);
+ return num < 95 ? 100 * HslHelper.GetPow(digit) : 100 * HslHelper.GetPow(digit);
+ }
+
+ ///
+ public static int CalculateMaxSectionFrom(Dictionary values) => HslHelper.CalculateMaxSectionFrom(values.Select, double>((Func, double>)(m => ((IEnumerable)m.Value).Max())).ToArray());
+
+ /// 获取当前颜色更淡的颜色信息
+ /// 颜色信息
+ /// 颜色
+ public static System.Drawing.Color GetColorLight(System.Drawing.Color color) => HslHelper.GetColorLight(color, 40);
+
+ /// 获取当前颜色更深的颜色信息
+ /// 颜色信息
+ /// 颜色
+ public static System.Drawing.Color GetColorDeep(System.Drawing.Color color) => HslHelper.GetColorLight(color, -40);
+
+ /// 获取当前颜色更淡的颜色信息,需要指定系数0-100,0时是原来的原色,100时是纯白色
+ /// 颜色信息
+ /// 获取颜色的系数信息
+ /// 颜色
+ public static System.Drawing.Color GetColorLight(System.Drawing.Color color, int scale) => scale > 0 ? System.Drawing.Color.FromArgb((int)color.R + ((int)byte.MaxValue - (int)color.R) * scale / 100, (int)color.G + ((int)byte.MaxValue - (int)color.G) * scale / 100, (int)color.B + ((int)byte.MaxValue - (int)color.B) * scale / 100) : System.Drawing.Color.FromArgb((int)color.R + (int)color.R * scale / 100, (int)color.G + (int)color.G * scale / 100, (int)color.B + (int)color.B * scale / 100);
+
+ /// 获取颜色的偏移信息
+ /// 颜色值
+ /// 颜色偏移信息
+ /// 颜色值
+ public static System.Drawing.Color GetColorOffset(System.Drawing.Color color, int offset)
+ {
+ int red = (int)color.R + offset;
+ if (red < 0)
+ red = 0;
+ if (red > (int)byte.MaxValue)
+ red = (int)byte.MaxValue;
+ int green = (int)color.G + offset;
+ if (green < 0)
+ green = 0;
+ if (green > (int)byte.MaxValue)
+ green = (int)byte.MaxValue;
+ int blue = (int)color.B + offset;
+ if (blue < 0)
+ blue = 0;
+ if (blue > (int)byte.MaxValue)
+ blue = (int)byte.MaxValue;
+ return System.Drawing.Color.FromArgb(red, green, blue);
+ }
+
+ /// 获取当前颜色更淡的颜色信息
+ /// 颜色信息
+ /// 颜色
+ public static System.Drawing.Color GetColorLightFive(System.Drawing.Color color) => HslHelper.GetColorLight(color, 50);
+
+ /// 获取当前颜色更淡的颜色信息
+ /// 颜色信息
+ /// 颜色
+ public static System.Windows.Media.Color GetColorLight(System.Windows.Media.Color color) => System.Windows.Media.Color.FromRgb((byte)((uint)color.R + (uint)(((int)byte.MaxValue - (int)color.R) * 40 / 100)), (byte)((uint)color.G + (uint)(((int)byte.MaxValue - (int)color.G) * 40 / 100)), (byte)((uint)color.B + (uint)(((int)byte.MaxValue - (int)color.B) * 40 / 100)));
+
+ /// 获取当前颜色更淡的颜色信息
+ /// 颜色信息
+ /// 颜色
+ public static System.Windows.Media.Color GetColorLightFive(System.Windows.Media.Color color) => System.Windows.Media.Color.FromRgb((byte)((uint)color.R + (uint)(((int)byte.MaxValue - (int)color.R) * 50 / 100)), (byte)((uint)color.G + (uint)(((int)byte.MaxValue - (int)color.G) * 50 / 100)), (byte)((uint)color.B + (uint)(((int)byte.MaxValue - (int)color.B) * 50 / 100)));
+
+ /// 从字符串表示的点位信息里解析出真正的点位信息
+ /// 字符串的点位
+ /// 原来的长度信息
+ /// 原来的高度信息
+ /// 实际的宽度信息
+ /// 实际的高度信息
+ /// x偏移量信息
+ /// y偏移量信息
+ ///
+ public static PointF[] GetPointsFrom(
+ string points,
+ float soureWidth,
+ float sourceHeight,
+ float width,
+ float height,
+ float dx = 0.0f,
+ float dy = 0.0f)
+ {
+ string[] strArray = points.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
+ PointF[] pointsFrom = new PointF[strArray.Length];
+ for (int index = 0; index < strArray.Length; ++index)
+ {
+ int length = strArray[index].IndexOf(',');
+ float single1 = Convert.ToSingle(strArray[index].Substring(0, length));
+ float single2 = Convert.ToSingle(strArray[index].Substring(length + 1));
+ pointsFrom[index] = new PointF(width * (single1 + dx) / soureWidth, height * (single2 + dy) / sourceHeight);
+ }
+ return pointsFrom;
+ }
+
+ /// 根据矩形及其各个定点的配置信息,获取圆角的路径信息,可以指定每个定点的圆角情况
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static GraphicsPath GetRoundRectange(
+ Rectangle rectangle,
+ int radius,
+ bool topLeft,
+ bool topRight,
+ bool buttomRight,
+ bool buttomLeft)
+ {
+ GraphicsPath roundRectange = new GraphicsPath();
+ Point pt1_1 = new Point(rectangle.X + (topLeft ? radius : 0), rectangle.Y);
+ Point pt2_1 = new Point(rectangle.X + rectangle.Width - 1 - (topRight ? radius : 0), rectangle.Y);
+ roundRectange.AddLine(pt1_1, pt2_1);
+ if (topRight && radius > 0)
+ roundRectange.AddArc(rectangle.X + rectangle.Width - radius * 2 - 1, rectangle.Y, radius * 2, radius * 2, 270f, 90f);
+ Point pt1_2 = new Point(rectangle.X + rectangle.Width - 1, rectangle.Y + (topRight ? radius : 0));
+ Point pt2_2 = new Point(rectangle.X + rectangle.Width - 1, rectangle.Y + rectangle.Height - 1 - (buttomRight ? radius : 0));
+ roundRectange.AddLine(pt1_2, pt2_2);
+ if (buttomRight && radius > 0)
+ roundRectange.AddArc(rectangle.X + rectangle.Width - radius * 2 - 1, rectangle.Y + rectangle.Height - radius * 2 - 1, radius * 2, radius * 2, 0.0f, 90f);
+ Point pt1_3 = new Point(rectangle.X + rectangle.Width - 1 - (buttomRight ? radius : 0), rectangle.Y + rectangle.Height - 1);
+ Point pt2_3 = new Point(rectangle.X + (buttomLeft ? radius : 0), rectangle.Y + rectangle.Height - 1);
+ roundRectange.AddLine(pt1_3, pt2_3);
+ if (buttomLeft && radius > 0)
+ roundRectange.AddArc(rectangle.X, rectangle.Y + rectangle.Height - radius * 2 - 1, radius * 2, radius * 2, 90f, 90f);
+ Point pt1_4 = new Point(rectangle.X, rectangle.Y + rectangle.Height - 1 - (buttomLeft ? radius : 0));
+ Point pt2_4 = new Point(rectangle.X, rectangle.Y + (topLeft ? radius : 0));
+ roundRectange.AddLine(pt1_4, pt2_4);
+ if (topLeft && radius > 0)
+ roundRectange.AddArc(rectangle.X, rectangle.Y, radius * 2, radius * 2, 180f, 90f);
+ return roundRectange;
+ }
+
+ private static string FloatMatchEvaluator(Match m) => m.Value.Length == 5 ? m.Value.Substring(0, 3) : m.Value.Substring(0, 2);
+
+ /// 获取浮点数值的格式化文本信息,如果发生了异常,则返回错误消息
+ /// 格式化信息
+ /// 值信息
+ /// 是否保留0的信息
+ /// 等待显示的文本
+ public static string GetFormatString(string format, float value, bool remainZero = false)
+ {
+ try
+ {
+ string input = string.Format(format, (object)value);
+ return remainZero ? input : Regex.Replace(input, "[Ee][+-][0]+", new MatchEvaluator(HslHelper.FloatMatchEvaluator));
+ }
+ catch
+ {
+ return "Wrong";
+ }
+ }
+
+ /// 矩形中间的字符串对齐机制
+ public static StringFormat StringFormatCenter { get; set; }
+
+ /// 矩形的左侧中间的对齐机制
+ public static StringFormat StringFormatLeft { get; set; }
+
+ /// 矩形的右侧的中间对齐机制
+ public static StringFormat StringFormatRight { get; set; }
+
+ /// 矩形的的默认的左上角对齐的机制
+ public static StringFormat StringFormatDefault { get; set; }
+
+ /// 矩形的下方中间的对齐的机制
+ public static StringFormat StringFormatTopCenter { get; set; }
+ }
+}
diff --git a/Controls/Mesnac.Controls.ChemicalWeighing/HslPipeTurnDirection.cs b/Controls/Mesnac.Controls.ChemicalWeighing/HslPipeTurnDirection.cs
new file mode 100644
index 0000000..18fa4c8
--- /dev/null
+++ b/Controls/Mesnac.Controls.ChemicalWeighing/HslPipeTurnDirection.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Mesnac.Controls.ChemicalWeighing
+{
+ /// 管道线的端点朝向
+ public enum HslPipeTurnDirection
+ {
+ /// 向上
+ Up = 1,
+ /// 向下
+ Down = 2,
+ /// 向左
+ Left = 3,
+ /// 向右
+ Right = 4,
+ /// 无效果
+ None = 5,
+ }
+}
diff --git a/Controls/Mesnac.Controls.ChemicalWeighing/HslTruck.cs b/Controls/Mesnac.Controls.ChemicalWeighing/HslTruck.cs
new file mode 100644
index 0000000..e8482b5
--- /dev/null
+++ b/Controls/Mesnac.Controls.ChemicalWeighing/HslTruck.cs
@@ -0,0 +1,360 @@
+using Mesnac.Basic;
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing.Drawing2D;
+using System.Drawing.Text;
+using System.Drawing;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace Mesnac.Controls.ChemicalWeighing
+{
+ [Description("一个卡车控件,支持两种样式,支持车体升降操作")]
+ public class HslTruck : UserControl
+ {
+ private HslPipeTurnDirection directionStyle = HslPipeTurnDirection.Left;
+ private float widthDesign = 530f;
+ private float heightDesign = 325f;
+ private StringFormat sf = (StringFormat)null;
+ private float truckAngle = 0.0f;
+ private int styleMode = 1;
+ private Color themeColor = Color.FromArgb(235, 209, 159);
+ private Color boderColor = Color.Silver;
+ private Pen borderPen = new Pen(Color.FromArgb(150, 150, 150));
+ private Color edgeColor = Color.FromArgb(176, 176, 176);
+ private Color centerColor = Color.FromArgb(229, 229, 229);
+ /// 必需的设计器变量。
+ private IContainer components = (IContainer)null;
+
+ public HslTruck()
+ {
+ this.InitializeComponent();
+ this.sf = new StringFormat();
+ this.sf.Alignment = StringAlignment.Center;
+ this.sf.LineAlignment = StringAlignment.Center;
+ this.SetStyle(ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, true);
+ this.SetStyle(ControlStyles.ResizeRedraw, true);
+ this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
+ this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
+ }
+
+ /// 获取或设置控件的背景色
+ [Browsable(true)]
+ [Description("获取或设置控件的背景色")]
+ [Category("HslControls")]
+ [DefaultValue(typeof(Color), "Transparent")]
+ [EditorBrowsable(EditorBrowsableState.Always)]
+ public override Color BackColor
+ {
+ get => base.BackColor;
+ set => base.BackColor = value;
+ }
+
+ /// 获取或设置分类器控件的边缘颜色
+ [Browsable(true)]
+ [Description("获取或设置分类器控件的边缘颜色")]
+ [Category("HslControls")]
+ [DefaultValue(typeof(Color), "[176, 176, 176]")]
+ public Color EdgeColor
+ {
+ get => this.edgeColor;
+ set
+ {
+ this.edgeColor = value;
+ this.Invalidate();
+ }
+ }
+
+ /// 获取或设置当前的卡车的倾斜角度,合适范围为0-21
+ [Browsable(true)]
+ [Description("获取或设置当前的卡车的倾斜角度,合适范围为0-21")]
+ [Category("HslControls")]
+ [DefaultValue(0.0f)]
+ public float TruckAngle
+ {
+ get => this.truckAngle;
+ set
+ {
+ this.truckAngle = value;
+ this.Invalidate();
+ }
+ }
+
+ /// 获取或设置分类器控件的中心颜色
+ [Browsable(true)]
+ [Description("获取或设置分类器控件的中心颜色")]
+ [Category("HslControls")]
+ [DefaultValue(typeof(Color), "[229, 229, 229]")]
+ public Color CenterColor
+ {
+ get => this.centerColor;
+ set
+ {
+ this.centerColor = value;
+ this.Invalidate();
+ }
+ }
+
+ /// 获取或设置分类器控件的边缘颜色
+ [Browsable(true)]
+ [Description("获取或设置分类器控件的边缘颜色")]
+ [Category("HslControls")]
+ [DefaultValue(typeof(Color), "Silver")]
+ public Color BorderColor
+ {
+ get => this.boderColor;
+ set
+ {
+ this.boderColor = value;
+ this.borderPen.Dispose();
+ this.borderPen = new Pen(this.boderColor);
+ this.Invalidate();
+ }
+ }
+
+ /// 获取或设置卡车的主题颜色
+ [Browsable(true)]
+ [Description("获取或设置卡车的主题颜色")]
+ [Category("HslControls")]
+ [DefaultValue(typeof(Color), "[235, 209, 159]")]
+ public Color ThemeColor
+ {
+ get => this.themeColor;
+ set
+ {
+ this.themeColor = value;
+ this.Invalidate();
+ }
+ }
+
+ /// 获取或设置卡车的状态,有两个选择,1,2
+ [Browsable(true)]
+ [Description("获取或设置卡车的状态,有两个选择,1,2")]
+ [Category("HslControls")]
+ [DefaultValue(1)]
+ public int TruckStyle
+ {
+ get => this.styleMode;
+ set
+ {
+ this.styleMode = value;
+ this.Invalidate();
+ }
+ }
+
+ /// 获取或设置卡车的朝向,仅支持朝右边或是左边
+ [Browsable(true)]
+ [Description("获取或设置卡车的朝向,仅支持朝右边或是左边")]
+ [Category("HslControls")]
+ [DefaultValue(typeof(HslPipeTurnDirection), "Right")]
+ public HslPipeTurnDirection TurnDirection
+ {
+ get => this.directionStyle;
+ set
+ {
+ this.directionStyle = value;
+ this.Invalidate();
+ }
+ }
+
+ ///
+ protected override void OnPaint(PaintEventArgs e)
+ {
+ Graphics graphics = e.Graphics;
+ graphics.SmoothingMode = SmoothingMode.HighQuality;
+ graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
+ this.PaintHslControls(graphics, this.Width, this.Height);
+ base.OnPaint(e);
+ }
+
+ ///
+ public void PaintHslControls(Graphics g, int width, int height)
+ {
+ //if (!Authorization.iashdiadasbdnajsdhjaf())
+ // return;
+ if (this.directionStyle == HslPipeTurnDirection.Left)
+ {
+ g.ScaleTransform(-1f, 1f);
+ g.TranslateTransform((float)-width, 0.0f);
+ }
+ if (width > 15 && height > 15)
+ {
+ if ((double)width > (double)this.widthDesign / (double)this.heightDesign * (double)height)
+ this.PaintMain(g, this.widthDesign / this.heightDesign * (float)height, (float)height);
+ else
+ this.PaintMain(g, (float)width, this.heightDesign / this.widthDesign * (float)width);
+ }
+ if (this.directionStyle != HslPipeTurnDirection.Left)
+ return;
+ g.TranslateTransform((float)width, 0.0f);
+ g.ScaleTransform(-1f, 1f);
+ }
+
+ private RectangleF TransRectangleF(RectangleF rectangle, float width, float height) => new RectangleF(rectangle.X * width / this.widthDesign, rectangle.Y * height / this.heightDesign, rectangle.Width * width / this.widthDesign, rectangle.Height * height / this.heightDesign);
+
+ private PointF[] TransPoints(PointF[] points, float width, float height)
+ {
+ PointF[] pointFArray = new PointF[points.Length];
+ for (int index = 0; index < points.Length; ++index)
+ pointFArray[index] = new PointF(points[index].X * width / this.widthDesign, points[index].Y * height / this.heightDesign);
+ return pointFArray;
+ }
+
+ private void PaintPolygon(Graphics g, string points, Color color, float width, float height)
+ {
+ PointF[] pointsFrom = HslHelper.GetPointsFrom(points, this.widthDesign, this.heightDesign, width, height);
+ using (SolidBrush solidBrush = new SolidBrush(color))
+ g.FillPolygon((Brush)solidBrush, pointsFrom);
+ g.DrawPolygon(this.borderPen, pointsFrom);
+ }
+
+ private void PaintMain(Graphics g, float width, float height)
+ {
+ ColorBlend colorBlend = new ColorBlend();
+ colorBlend.Positions = new float[3] { 0.0f, 0.35f, 1f };
+ colorBlend.Colors = new Color[3]
+ {
+ this.edgeColor,
+ this.centerColor,
+ this.edgeColor
+ };
+ this.PaintPolygon(g, "244,274 410,274 410,283 244,283", this.themeColor, width, height);
+ this.PaintPolygon(g, "410,125 485,125 529,188 529,283 410,283 410,125", this.themeColor, width, height);
+ using (SolidBrush solidBrush = new SolidBrush(Color.FromArgb(251, 253, 252)))
+ g.FillPolygon((Brush)solidBrush, HslHelper.GetPointsFrom("430,137 482,137 509,180 509,195 430,195 430,137", this.widthDesign, this.heightDesign, width, height));
+ using (SolidBrush solidBrush = new SolidBrush(Color.FromArgb(232, 244, 237)))
+ g.FillPolygon((Brush)solidBrush, HslHelper.GetPointsFrom("430,137 482,137 454,195 430,195 430,137", this.widthDesign, this.heightDesign, width, height));
+ using (Pen pen = new Pen(Color.FromArgb(81, 81, 81), 3f))
+ g.DrawPolygon(pen, HslHelper.GetPointsFrom("430,137 482,137 509,180 509,195 430,195 430,137", this.widthDesign, this.heightDesign, width, height));
+ using (SolidBrush solidBrush = new SolidBrush(Color.FromArgb(81, 81, 81)))
+ g.FillEllipse((Brush)solidBrush, this.TransRectangleF((RectangleF)new Rectangle(511, 200, 6, 6), width, height));
+ using (Pen pen = new Pen(Color.FromArgb(212, 186, 137), 5f))
+ {
+ g.DrawLines(pen, HslHelper.GetPointsFrom("413,209 527,209 527,280 413,280 413,209", this.widthDesign, this.heightDesign, width, height));
+ g.DrawArc(pen, this.TransRectangleF(new RectangleF(430f, 258f, 58f, 52f), width, height), 180f, 180f);
+ g.DrawPolygon(pen, HslHelper.GetPointsFrom(string.Format("350,268 {0},{1}", (object)(Math.Cos((double)this.truckAngle * 2.0 * Math.PI / 360.0) * 298.0 + 52.0), (object)(258.0 - Math.Sin((double)this.truckAngle * 2.0 * Math.PI / 360.0) * 298.0)), this.widthDesign, this.heightDesign, width, height));
+ }
+ this.PaintPolygon(g, "510,179 516,179 516,194 510,194 510,179", Color.FromArgb(81, 81, 81), width, height);
+ this.PaintPolygon(g, "513,203 515,203 515,194 513,194 513,203", HslHelper.GetColorLight(Color.FromArgb(81, 81, 81)), width, height);
+ this.PaintPolygon(g, "52,260 396,260 396,275 52,275 52,260", Color.FromArgb(81, 81, 81), width, height);
+ this.PaintTair(g, 460f, 293f, width, height);
+ this.PaintTair(g, 102f, 293f, width, height);
+ this.PaintTair(g, 162f, 293f, width, height);
+ g.TranslateTransform(52f * width / this.widthDesign, 259f * height / this.heightDesign);
+ if ((double)this.truckAngle != 0.0)
+ g.RotateTransform(-this.truckAngle);
+ if (this.styleMode == 1)
+ {
+ this.PaintPolygon(g, "0,-139 348,-139 348,0 0,0 0,-139", Color.FromArgb(233, 233, 233), width, height);
+ this.PaintPolygon(g, "8,-131 340,-131 340,-8 8,-8 8,-131", this.themeColor, width, height);
+ float[] numArray = new float[15]
+ {
+ 30f,
+ 40f,
+ 50f,
+ 95f,
+ 105f,
+ 115f,
+ 160f,
+ 170f,
+ 180f,
+ 225f,
+ 235f,
+ 245f,
+ 290f,
+ 300f,
+ 310f
+ };
+ for (int index = 0; index < numArray.Length; ++index)
+ this.PaintPolygon(g, string.Format("{0},-131 {1},-131 {2},-8 {3},-8 {4},-131", (object)numArray[index], (object)(float)((double)numArray[index] + 5.0), (object)(float)((double)numArray[index] + 5.0), (object)numArray[index], (object)numArray[index]), HslHelper.GetColorLight(this.themeColor), width, height);
+ }
+ else if (this.styleMode == 2)
+ {
+ RectangleF rect1 = this.TransRectangleF(new RectangleF(-10f, -130f, 20f, 121f), width, height);
+ LinearGradientBrush linearGradientBrush = new LinearGradientBrush(new PointF(rect1.X, rect1.Y), new PointF(rect1.X, rect1.Y + rect1.Height), Color.FromArgb(142, 196, 216), Color.FromArgb(240, 240, 240));
+ linearGradientBrush.InterpolationColors = colorBlend;
+ g.FillEllipse((Brush)linearGradientBrush, rect1);
+ using (Pen pen = new Pen(this.edgeColor, 1f))
+ g.DrawEllipse(pen, rect1);
+ g.FillPolygon((Brush)linearGradientBrush, HslHelper.GetPointsFrom("348,-130 355,-120 355,-10 348,0 348,-130", this.widthDesign, this.heightDesign, width, height));
+ g.DrawPolygon(this.borderPen, HslHelper.GetPointsFrom("348,-130 355,-120 355,-10 348,0 348,-130", this.widthDesign, this.heightDesign, width, height));
+ linearGradientBrush.Dispose();
+ RectangleF rect2 = this.TransRectangleF(new RectangleF(0.0f, -139f, 348f, 140f), width, height);
+ g.FillRectangle((Brush)new LinearGradientBrush(new PointF(rect2.X, rect2.Y), new PointF(rect2.X, rect2.Y + rect2.Height), Color.FromArgb(142, 196, 216), Color.FromArgb(240, 240, 240))
+ {
+ InterpolationColors = colorBlend
+ }, rect2);
+ g.DrawRectangle(this.borderPen, rect2.X, rect2.Y, rect2.Width, rect2.Height);
+ this.PaintPolygon(g, "0,-139 348,-139 348,-134 0,-134 0,-139", this.BorderColor, width, height);
+ this.PaintPolygon(g, "0,-75 348,-75 348,-65 0,-65 0,-75", this.themeColor, width, height);
+ this.PaintPolygon(g, "0,-50 348,-50 348,-40 0,-40 0,-50", this.themeColor, width, height);
+ }
+ if ((double)this.truckAngle != 0.0)
+ g.RotateTransform(this.truckAngle);
+ g.TranslateTransform(-52f * width / this.widthDesign, -259f * height / this.heightDesign);
+ }
+
+ private void PaintTair(Graphics g, float x, float y, float width, float height)
+ {
+ SolidBrush solidBrush = new SolidBrush(Color.FromArgb(55, 55, 55));
+ RectangleF rectangle = new RectangleF(x - 30f, y - 30f, 60f, 60f);
+ g.FillEllipse((Brush)solidBrush, this.TransRectangleF(rectangle, width, height));
+ rectangle = new RectangleF(x - 20f, y - 20f, 40f, 40f);
+ ColorBlend colorBlend = new ColorBlend();
+ colorBlend.Positions = new float[3] { 0.0f, 0.45f, 1f };
+ colorBlend.Colors = new Color[3]
+ {
+ Color.FromArgb(150, 150, 150),
+ Color.FromArgb(220, 220, 220),
+ Color.FromArgb(150, 150, 150)
+ };
+ PointF[] pointsFrom = HslHelper.GetPointsFrom(string.Format("{0},{1} {2},{3}", (object)(float)((double)x + 15.0), (object)(float)((double)y - 20.0), (object)(float)((double)x - 15.0), (object)(float)((double)y + 20.0)), this.widthDesign, this.heightDesign, width, height);
+ LinearGradientBrush linearGradientBrush = new LinearGradientBrush(pointsFrom[0], pointsFrom[1], Color.FromArgb(142, 196, 216), Color.FromArgb(240, 240, 240));
+ linearGradientBrush.InterpolationColors = colorBlend;
+ g.FillEllipse((Brush)linearGradientBrush, this.TransRectangleF(rectangle, width, height));
+ linearGradientBrush.Dispose();
+ rectangle = new RectangleF(x - 7f, y - 7f, 14f, 14f);
+ using (Pen pen = new Pen((Brush)solidBrush, 2f))
+ g.DrawEllipse(pen, this.TransRectangleF(rectangle, width, height));
+ rectangle = new RectangleF(x - 11f, y - 15f, 8f, 8f);
+ g.FillEllipse((Brush)solidBrush, this.TransRectangleF(rectangle, width, height));
+ rectangle = new RectangleF(x - 16f, y + 1f, 8f, 8f);
+ g.FillEllipse((Brush)solidBrush, this.TransRectangleF(rectangle, width, height));
+ rectangle = new RectangleF(x - 3f, y + 10f, 8f, 8f);
+ g.FillEllipse((Brush)solidBrush, this.TransRectangleF(rectangle, width, height));
+ rectangle = new RectangleF(x + 8f, y + 2f, 8f, 8f);
+ g.FillEllipse((Brush)solidBrush, this.TransRectangleF(rectangle, width, height));
+ rectangle = new RectangleF(x + 5f, y - 14f, 8f, 8f);
+ g.FillEllipse((Brush)solidBrush, this.TransRectangleF(rectangle, width, height));
+ solidBrush.Dispose();
+ }
+
+ /// 清理所有正在使用的资源。
+ /// 如果应释放托管资源,为 true;否则为 false。
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && this.components != null)
+ this.components.Dispose();
+ base.Dispose(disposing);
+ }
+
+ ///
+ /// 设计器支持所需的方法 - 不要修改
+ /// 使用代码编辑器修改此方法的内容。
+ ///
+ private void InitializeComponent()
+ {
+ this.SuspendLayout();
+ this.AutoScaleMode = AutoScaleMode.None;
+ this.BackColor = Color.Transparent;
+ this.Name = nameof(HslTruck);
+ this.Size = new Size(329, 185);
+ this.ResumeLayout(false);
+ }
+ }
+}
diff --git a/Controls/Mesnac.Controls.ChemicalWeighing/Mesnac.Controls.ChemicalWeighing.csproj b/Controls/Mesnac.Controls.ChemicalWeighing/Mesnac.Controls.ChemicalWeighing.csproj
index 83cf8a4..0ce4366 100644
--- a/Controls/Mesnac.Controls.ChemicalWeighing/Mesnac.Controls.ChemicalWeighing.csproj
+++ b/Controls/Mesnac.Controls.ChemicalWeighing/Mesnac.Controls.ChemicalWeighing.csproj
@@ -89,6 +89,11 @@
GanHunJi.cs
+
+
+
+ UserControl
+
UserControl
@@ -125,6 +130,8 @@
PControl.cs
+
+
UserControl
diff --git a/Controls/Mesnac.Controls.ChemicalWeighing/ReferenceAxis.cs b/Controls/Mesnac.Controls.ChemicalWeighing/ReferenceAxis.cs
new file mode 100644
index 0000000..f1d33cd
--- /dev/null
+++ b/Controls/Mesnac.Controls.ChemicalWeighing/ReferenceAxis.cs
@@ -0,0 +1,145 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace Mesnac.Controls.ChemicalWeighing
+{
+ /// 参考坐标系的轴信息
+ [TypeConverter(typeof(ReferenceAxisConverter))]
+ public class ReferenceAxis
+ {
+ private float _max;
+ private float _min;
+ private string _unit;
+ private string _format;
+ private Color _color;
+ private UserControl _control;
+ private Pen _pen;
+
+ /// 实例化一个默认的对象
+ public ReferenceAxis()
+ {
+ this.Max = 100f;
+ this.Min = 0.0f;
+ this.Color = Color.LightGray;
+ this.Format = "{0}";
+ }
+
+ /// 实例化一个默认的对象
+ public ReferenceAxis(UserControl userControl)
+ : this()
+ {
+ this._control = userControl;
+ }
+
+ /// 实例化一个默认的对象
+ /// 最大值
+ /// 最小值
+ public ReferenceAxis(float max, float min)
+ {
+ this.Max = max;
+ this.Min = min;
+ }
+
+ /// 最大值
+ [Category("HslControls")]
+ [Description("获取或设置当前的Y轴的最大值")]
+ [Browsable(true)]
+ [DefaultValue(100f)]
+ public float Max
+ {
+ get => this._max;
+ set
+ {
+ this._max = value;
+ this._control?.Invalidate();
+ }
+ }
+
+ /// 最小值
+ [Category("HslControls")]
+ [Description("获取或设置当前的Y轴的最小值")]
+ [Browsable(true)]
+ [DefaultValue(0.0f)]
+ public float Min
+ {
+ get => this._min;
+ set
+ {
+ this._min = value;
+ this._control?.Invalidate();
+ }
+ }
+
+ /// 单位信息
+ [Category("HslControls")]
+ [Description("获取或设置当前的Y轴的单位值")]
+ [Browsable(true)]
+ [DefaultValue("")]
+ public string Unit
+ {
+ get => this._unit;
+ set
+ {
+ this._unit = value;
+ this._control?.Invalidate();
+ }
+ }
+
+ /// 获取或设置当前的坐标系的颜色信息
+ [Category("HslControls")]
+ [Description("获取或设置当前的坐标系的颜色信息")]
+ [Browsable(true)]
+ [DefaultValue(typeof(Color), "LightGray")]
+ public Color Color
+ {
+ get => this._color;
+ set
+ {
+ this._color = value;
+ this.Brush?.Dispose();
+ this.Brush = (Brush)new SolidBrush(this._color);
+ this._pen?.Dispose();
+ this._pen = new Pen(this._color, 1f);
+ this._control?.Invalidate();
+ }
+ }
+
+ /// 获取或设置当前坐标轴数字的格式化信息,默认为 {0}, 直接转字符串
+ [Category("HslControls")]
+ [Description("获取或设置当前坐标轴数字的格式化信息,默认为 {0}, 直接转字符串")]
+ [Browsable(true)]
+ [DefaultValue("{0}")]
+ public string Format
+ {
+ get => this._format;
+ set
+ {
+ this._format = value;
+ this._control?.Invalidate();
+ }
+ }
+
+ /// 获取画笔信息
+ /// 画笔信息
+ public Pen GetPen()
+ {
+ if (this._pen != null)
+ return this._pen;
+ this._pen = new Pen(this.Color, 1f);
+ return this._pen;
+ }
+
+ /// 画刷资源
+ [Browsable(false)]
+ public Brush Brush { get; set; }
+ }
+}
diff --git a/Controls/Mesnac.Controls.ChemicalWeighing/ReferenceAxisConverter.cs b/Controls/Mesnac.Controls.ChemicalWeighing/ReferenceAxisConverter.cs
new file mode 100644
index 0000000..19d8895
--- /dev/null
+++ b/Controls/Mesnac.Controls.ChemicalWeighing/ReferenceAxisConverter.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Mesnac.Controls.ChemicalWeighing
+{
+ /// 参考坐标轴的转换器
+ public class ReferenceAxisConverter : TypeConverter
+ {
+ ///
+ public override PropertyDescriptorCollection GetProperties(
+ ITypeDescriptorContext context,
+ object value,
+ Attribute[] attributes)
+ {
+ return TypeDescriptor.GetProperties(value, attributes);
+ }
+
+ ///
+ public override bool GetPropertiesSupported(ITypeDescriptorContext context) => true;
+ }
+}
diff --git a/Main/MCEdit/Data/MCProject/nodeDevice.xml b/Main/MCEdit/Data/MCProject/nodeDevice.xml
index defc882..7c9d4cd 100644
--- a/Main/MCEdit/Data/MCProject/nodeDevice.xml
+++ b/Main/MCEdit/Data/MCProject/nodeDevice.xml
@@ -1666,6 +1666,1853 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Main/MCEdit/Data/MCProject/nodeForm/Form1.xml b/Main/MCEdit/Data/MCProject/nodeForm/Form1.xml
index 6925b4e..12e11f3 100644
--- a/Main/MCEdit/Data/MCProject/nodeForm/Form1.xml
+++ b/Main/MCEdit/Data/MCProject/nodeForm/Form1.xml
@@ -1,5 +1,6 @@