Files
barcodeManager/LibShapes/Core/Shape/ShapeEle.cs
2026-01-24 08:45:54 +08:00

358 lines
10 KiB
C#

using Io.Github.Kerwinxu.LibShapes.Utils;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
namespace Io.Github.Kerwinxu.LibShapes.Core.Shape
{
/// <summary>
/// 形状的基类
/// </summary>
public abstract class ShapeEle
{
/// <summary>
/// 构造函数
/// </summary>
public ShapeEle()
{
// 提供一些默认的参数
PenWidth = 1;
PenColor = Color.Black;
}
#region
#region
/// <summary>
/// 唯一的标识符
/// </summary>
[CategoryAttribute("设计")]
public int ID { get; set; }
#endregion
#region
[CategoryAttribute("布局")]
public float X { get; set; }
[CategoryAttribute("布局")]
public float Y { get; set; }
[DescriptionAttribute("宽度"), DisplayName("宽度"), CategoryAttribute("布局")]
public float Width { get; set; }
[DescriptionAttribute("高度"), DisplayName("高度"), CategoryAttribute("布局")]
public float Height { get; set; }
[DescriptionAttribute("角度"), DisplayName("角度"), CategoryAttribute("外观")]
public float Angle { get; set; }
#endregion
#region
[DescriptionAttribute("边框颜色"), DisplayName("边框颜色"), CategoryAttribute("外观")]
public Color PenColor { get; set; }
[DescriptionAttribute("边框粗细"), DisplayName("边框粗细"), CategoryAttribute("外观")]
public float PenWidth { get; set; }
[DescriptionAttribute("虚线的样式"), DisplayName("虚线的样式"), CategoryAttribute("外观")]
public DashStyle PenDashStyle { get; set; }
[DescriptionAttribute("是否填充"), DisplayName("是否填充"), CategoryAttribute("外观")]
public bool IsFill { get; set; }
[DescriptionAttribute("填充颜色"), DisplayName("填充颜色"), CategoryAttribute("外观")]
public Color FillColor { get; set; }
#region
float x_add, y_add, width_add, height_add;
#endregion
#endregion
#endregion
#region
public virtual void Draw(Graphics g, Matrix matrix) {
// 首先取得绘图路径
try
{
var path = GetGraphicsPath(matrix);
// 定义画笔
Pen pen = new Pen(PenColor);
pen.Width = PenWidth; // 画笔的粗细
pen.DashStyle = PenDashStyle; // 虚线的样式
g.DrawPath(pen, path); // 画边框
if (IsFill) // 如果填充
{
Brush brush = new SolidBrush(FillColor);
g.FillPath(brush, path);
}
path.Dispose();
}
catch (Exception ex)
{
//throw;
}
}
/// <summary>
/// 这个返回的是屏幕画布上的真实的坐标体系
/// </summary>
/// <param name="matrix"></param>
/// <returns></returns>
public virtual GraphicsPath GetGraphicsPath(Matrix matrix)
{
GraphicsPath path = null;
if (getWidth() == 0 || getHeight() == 0)
{
// 这里表示只是一条线段或者一个点了
path = new GraphicsPath();
path.AddLine(new PointF(getX(), getY()), new PointF(getX() + getWidth(), getY() + getHeight()));
}
else
{
path = GetGraphicsPathWithAngle();
}
// 这里加上旋转
Matrix matrix1 = new Matrix();
// 这里按照中心点旋转,
var rect = path.GetBounds();
var centerPoint = new PointF() { X = rect.X + rect.Width / 2, Y = rect.Y + rect.Height / 2 };
matrix1.RotateAt(Angle, centerPoint);
Matrix matrix2 = matrix.Clone();
matrix2.Multiply(matrix1);
// 应用这个转换
path.Transform(matrix2);
// 返回这个路径
return path;
}
/// <summary>
/// 矫正矩形,宽和高都不能是复数
/// </summary>
/// <param name="rect"></param>
/// <returns></returns>
protected RectangleF correctRectangle(RectangleF rect)
{
RectangleF rect2 = new RectangleF() {
X = rect.X,
Y = rect.Y,
Width = rect.Width,
Height = rect.Height,
};
if (rect2.Width < 0)
{
rect2.X += rect2.Width;
rect2.Width = -rect2.Width;
}
if (rect2.Height < 0)
{
rect2.Y += rect2.Height;
rect2.Height = -rect2.Height;
}
return rect2;
}
/// <summary>
/// 返回不包括旋转的路径,且这个是虚拟世界的坐标,不用考虑画布中实际的坐标。
/// </summary>
/// <returns></returns>
public virtual GraphicsPath GetGraphicsPathWithAngle()
{
GraphicsPath path = new GraphicsPath();
var rect = new System.Drawing.RectangleF()
{
X = getX(),
Y = getY(),
Width = getWidth(),
Height = getHeight()
};
var rect2 = correctRectangle(rect);
path.AddRectangle(rect2);
return path;
}
/// <summary>
/// 返回外接矩形
/// </summary>
/// <returns></returns>
public virtual RectangleF GetBounds(Matrix matrix)
{
// 请注意,这里是以旋转后的。
return GetGraphicsPath(matrix).GetBounds();
}
/// <summary>
/// 选择的容忍度
/// </summary>
private Pen pen_select_tolerance = new Pen(Color.White) {
Width = DistanceCalculation.select_tolerance
};
/// <summary>
/// 这个点是否在这个图形的轮廓上
/// </summary>
/// <param name="mousePointF"></param>
/// <returns></returns>
public virtual bool isOutlineVisible(Matrix matrix, PointF mousePointF)
{
var pen = new Pen(new SolidBrush(this.PenColor), this.PenWidth);
return GetGraphicsPath(matrix).IsOutlineVisible(mousePointF, pen);
//return GetGraphicsPath(matrix).IsVisible(mousePointF);
}
/// <summary>
/// 这个点是否在这个图形的的内部
/// </summary>
/// <param name="mousePointF"></param>
/// <returns></returns>
public virtual bool isVisible(Matrix matrix, PointF mousePointF)
{
return GetGraphicsPath(matrix).IsVisible(mousePointF);
//return GetGraphicsPath(matrix).IsVisible(mousePointF);
}
/// <summary>
/// 这个表示是否被包含在这个矩形内
/// </summary>
/// <param name="rect"></param>
/// <returns></returns>
public virtual bool isBeContains(Matrix matrix, RectangleF rect)
{
var rect2 = GetBounds(matrix);
return rect.Contains(rect2);
}
public virtual void setVals(Dictionary<string, string> vars)
{
// 什么都不做,子类如果需要,就自己实现。
}
/// <summary>
/// 根据这个矩形更改
/// </summary>
/// <param name="rect"></param>
public void Change(RectangleF rect)
{
x_add = rect.X;
y_add = rect.Y;
width_add = rect.Width;
height_add = rect.Height;
}
public virtual void ChangeComplated()
{
// 将更改固定下来
X += x_add;
Y += y_add;
Width += width_add;
Height += height_add;
// 清零
x_add = 0;
y_add = 0;
width_add = 0;
height_add = 0;
// 这里要注意矫正 todo
if (Width < 0)
{
X += Width;
Width = -Width;
}
if (Height < 0)
{
Y += Height;
Height = -Height;
}
}
/// <summary>
/// 深度拷贝
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public abstract ShapeEle DeepClone();
public override bool Equals(object obj)
{
// 首先判断是否是
var shape = obj as ShapeEle;
if (shape == null) return false; // 转换失败就是不同啦
return this.X == shape.X &&
this.Y == shape.Y &&
this.Width == shape.Width &&
this.Height == shape.Height &&
this.Angle == shape.Angle &&
this.ID == shape.ID &&
this.PenColor == shape.PenColor &&
this.PenWidth == shape.PenWidth &&
this.PenDashStyle == shape.PenDashStyle &&
this.IsFill == shape.IsFill &&
this.FillColor == shape.FillColor;
//return base.Equals(obj);
}
#region add后的参数
protected float getX()
{
return X + x_add;
}
protected float getY()
{
return Y + y_add;
}
protected float getWidth()
{
return Width + width_add;
}
protected float getHeight()
{
return Height + height_add;
}
#endregion
#endregion
public override int GetHashCode()
{
return ID * base.GetHashCode();
//return base.GetHashCode();
}
}
}