using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
namespace FurnaceUI.Controls
{
///
/// 整个组件的代码辅助工具,提供了一个基础的类库方法
///
public class Helper
{
///
/// 从一个矩形的图形中获取菱形的坐标数组
///
/// 矩形
/// 数组结果
public static Point[] GetRhombusFromRectangle(Rectangle rect)
{
return new Point[]
{
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)
{
if ((max - min) == 0f)
{
return height;
}
else
{
return height - (value - min) * 1.0f / (max - min) * height;
}
}
///
/// 计算绘图时的相对偏移值
///
/// 0-100分的最大值,就是指准备绘制的最大值
/// 0-100分的最小值,就是指准备绘制的最小值
/// 实际绘图区域的高度
/// 需要绘制数据的当前值
/// 相对于0的位置,还需要增加上面的偏值
public static float ComputePaintLocationY(float max, float min, float height, float value)
{
if ((max - min) == 0f)
{
return height;
}
else
{
return height - (value - min) / (max - min) * height;
}
}
///
/// 绘制坐标系中的刻度线
///
/// 绘图对象
/// 画坐标轴的画笔
///
///
///
///
///
///
///
///
///
///
///
///
///
public static void PaintCoordinateDivide(
Graphics g,
Pen penLine,
Pen penDash,
Font font,
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 i = 0; i <= degree; i++)
{
int value = (max - min) * i / degree + min;
int location = (int)ComputePaintLocationY(max, min, (height - up - down), value) + up + 1;
g.DrawLine(penLine, left - 1, location, left - 4, location);
if (i != 0)
{
g.DrawLine(penDash, left, location, width - right, location);
}
g.DrawString(value.ToString(), font, brush, new Rectangle(-5, location - font.Height / 2, left, font.Height), sf);
}
}
///
/// 根据指定的方向绘制一个箭头
///
///
///
///
///
///
public static void PaintTriangle(Graphics g, Brush brush, Point point, int size, GraphDirection direction)
{
Point[] points = new Point[4];
if (direction == 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);
}
else if (direction == 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);
}
else if (direction == 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);
}
else
{
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);
}
points[3] = points[0];
g.FillPolygon(brush, points);
}
///
/// 根据指定的方向绘制一个箭头
///
///
///
///
///
///
public static void PaintTriangle(Graphics g, Brush brush, PointF point, int size, GraphDirection direction)
{
PointF[] points = new PointF[4];
if (direction == GraphDirection.Leftward)
{
points[0] = new PointF(point.X, point.Y - size);
points[1] = new PointF(point.X, point.Y + size);
points[2] = new PointF(point.X - 2 * size, point.Y);
}
else if (direction == GraphDirection.Rightward)
{
points[0] = new PointF(point.X, point.Y - size);
points[1] = new PointF(point.X, point.Y + size);
points[2] = new PointF(point.X + 2 * size, point.Y);
}
else if (direction == GraphDirection.Upward)
{
points[0] = new PointF(point.X - size, point.Y);
points[1] = new PointF(point.X + size, point.Y);
points[2] = new PointF(point.X, point.Y - 2 * size);
}
else
{
points[0] = new PointF(point.X - size, point.Y);
points[1] = new PointF(point.X + size, point.Y);
points[2] = new PointF(point.X, point.Y + 2 * size);
}
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) return; // 数据为空
if (data.Length == 0) return; // 数据长度为空
if (array.Length == max)
{
Array.Copy(array, data.Length, array, 0, array.Length - data.Length);
Array.Copy(data, 0, array, array.Length - data.Length, data.Length);
}
else
{
if ((array.Length + data.Length) > max)
{
T[] tmp = new T[max];
for (int i = 0; i < (max - data.Length); i++)
{
tmp[i] = array[i + (array.Length - max + data.Length)];
}
for (int i = 0; i < data.Length; i++)
{
tmp[tmp.Length - data.Length + i] = data[i];
}
// 更新数据
array = tmp;
}
else
{
T[] tmp = new T[array.Length + data.Length];
for (int i = 0; i < array.Length; i++)
{
tmp[i] = array[i];
}
for (int i = 0; i < data.Length; i++)
{
tmp[tmp.Length - data.Length + i] = data[i];
}
array = tmp;
}
}
}
///
/// 尺寸转换,计算旋转后的尺寸。
///
///
///
///
public static SizeF ConvertSize(SizeF size, float angle)
{
Matrix matrix = new Matrix();
matrix.Rotate(angle);
// 旋转矩形四个顶点
PointF[] pts = new PointF[4];
pts[0].X = -size.Width / 2f;
pts[0].Y = -size.Height / 2f;
pts[1].X = -size.Width / 2f;
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 = -size.Height / 2f;
matrix.TransformPoints(pts);
// 求取四个顶点的包围盒
float left = float.MaxValue;
float right = float.MinValue;
float top = float.MaxValue;
float bottom = float.MinValue;
foreach (PointF pt in pts)
{
// 求取并集
if (pt.X < left)
left = pt.X;
if (pt.X > right)
right = pt.X;
if (pt.Y < top)
top = pt.Y;
if (pt.Y > bottom)
bottom = pt.Y;
}
SizeF result = new SizeF(right - left, bottom - top);
return result;
}
///
/// 绘制旋转文本
///
///
///
///
///
///
///
///
public static void DrawString(Graphics g, string s, Font font, Brush brush, PointF point, StringFormat format, float angle)
{
// Save the matrix
Matrix mtxSave = g.Transform;
Matrix mtxRotate = g.Transform;
mtxRotate.RotateAt(angle, point);
g.Transform = mtxRotate;
g.DrawString(s, font, brush, point, format);
// Reset the matrix
g.Transform = mtxSave;
}
private static int GetPow(int digit)
{
int result = 1;
for (int i = 0; i < digit; i++)
{
result *= 10;
}
return result;
}
///
/// 获得数据的上限值,这个上限值是自动计算的。
///
/// 数据值
/// 数据值
public static int CalculateMaxSectionFrom(int[] values)
{
int max = values.Max();
if (max <= 5) return 5;
if (max <= 10) return 10;
int digit = max.ToString().Length - 2;
int head = int.Parse(max.ToString().Substring(0, 2));
if (head < 12) return 12 * GetPow(digit);
if (head < 14) return 14 * GetPow(digit);
if (head < 16) return 16 * GetPow(digit);
if (head < 18) return 18 * GetPow(digit);
if (head < 20) return 20 * GetPow(digit);
if (head < 22) return 22 * GetPow(digit);
if (head < 24) return 24 * GetPow(digit);
if (head < 26) return 26 * GetPow(digit);
if (head < 28) return 28 * GetPow(digit);
if (head < 30) return 30 * GetPow(digit);
if (head < 40) return 40 * GetPow(digit);
if (head < 50) return 50 * GetPow(digit);
if (head < 60) return 60 * GetPow(digit);
if (head < 80) return 80 * GetPow(digit);
return 100 * GetPow(digit);
}
///
/// 获取当前颜色更淡的颜色信息
///
/// 颜色信息
/// 颜色
public static Color GetColorLight(Color color)
{
return Color.FromArgb(color.R + (255 - color.R) * 40 / 100, color.G + (255 - color.G) * 40 / 100, color.B + (255 - color.B) * 40 / 100);
}
///
/// 获取当前颜色更淡的颜色信息
///
/// 颜色信息
/// 颜色
public static Color GetColorLightFive(Color color)
{
return Color.FromArgb(color.R + (255 - color.R) * 50 / 100, color.G + (255 - color.G) * 50 / 100, color.B + (255 - color.B) * 50 / 100);
}
#if NET45
///
/// 获取当前颜色更淡的颜色信息
///
/// 颜色信息
/// 颜色
public static System.Windows.Media.Color GetColorLight( System.Windows.Media.Color color )
{
return System.Windows.Media.Color.FromRgb( (byte)(color.R + (255 - color.R) * 40 / 100), (byte)(color.G + (255 - color.G) * 40 / 100), (byte)(color.B + (255 - color.B) * 40 / 100) );
}
///
/// 获取当前颜色更淡的颜色信息
///
/// 颜色信息
/// 颜色
public static System.Windows.Media.Color GetColorLightFive( System.Windows.Media.Color color )
{
return System.Windows.Media.Color.FromRgb( (byte)(color.R + (255 - color.R) * 50 / 100), (byte)(color.G + (255 - color.G) * 50 / 100), (byte)(color.B + (255 - color.B) * 50 / 100) );
}
#endif
///
/// 从字符串表示的点位信息里解析出真正的点位信息
///
/// 字符串的点位
/// 原来的长度信息
/// 原来的高度信息
/// 实际的宽度信息
/// 实际的高度信息
/// x偏移量信息
/// y偏移量信息
///
public static PointF[] GetPointsFrom(string points, float soureWidth, float sourceHeight, float width, float height, float dx = 0, float dy = 0)
{
string[] itemPoint = points.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
PointF[] ret = new PointF[itemPoint.Length];
for (int i = 0; i < itemPoint.Length; i++)
{
int index = itemPoint[i].IndexOf(',');
float x = Convert.ToSingle(itemPoint[i].Substring(0, index));
float y = Convert.ToSingle(itemPoint[i].Substring(index + 1));
ret[i] = new PointF(width * (x + dx) / soureWidth, height * (y + dy) / sourceHeight);
}
return ret;
}
}
///
/// 图形的方向
///
public enum GraphDirection
{
///
/// 向上
///
Upward = 1,
///
/// 向下
///
Downward = 2,
///
/// 向左
///
Leftward = 3,
///
/// 向右
///
Rightward = 4,
}
///
/// 指示控件的样子
///
public enum HslDirectionStyle
{
///
/// 控件是横向摆放的
///
Horizontal = 1,
///
/// 控件是纵向摆放的
///
Vertical = 2
}
///
/// 系统的主题样式,将会改变一些控件的外观
///
public enum HslThemeStyle
{
///
/// 浅色的主题
///
Light = 1,
///
/// 深色的主题
///
Dark = 2,
}
///
/// 某些特殊图形的表现形式
///
public enum HslRenderStyle
{
///
/// 椭圆
///
Ellipse = 1,
///
/// 矩形
///
Rectangle = 2,
///
/// 菱形
///
Rhombus = 3
}
///
/// 包含整型和字符串描述的数据类型
///
public struct Paintdata
{
///
/// 数量
///
public int Count { get; set; }
///
/// 描述
///
public string Description { get; set; }
}
///
/// 计算的基础数据
///
public class CenterPoint
{
///
/// 中心点的位置
///
public Point Point { get; set; }
///
/// 半径
///
public int Radius { get; set; }
///
/// 角度
///
public double Angle { get; set; }
}
}