using OTSIncAReportApp.DataOperation.Model;
using OTSIncAReportGraph.Class;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace OTSIncAReportGraph
{
///
/// Particle对象上操作状态的枚举,显示,不显示,已删除,已选择
///
public enum PaintState
{
NORMALPAINT = 0,
NOPAINT = 1,
CONCISEPAINT=2,// display as a "+"
}
public enum DisplayState
{
DISPLAY = 0,
NODISPLAY = 1,
}
///
/// Particle对象上操作xray的枚举状态,显示xray数据,不显示
///
public enum ParticleShowXray
{
SELECTANDDISPLAYXRAY = 0,
NODISPLAY = 1,
}
///
/// Segment对象绘制的枚举,以点绘制,还是以线绘制
///
public enum SegmentShowMode
{
DRAWPOINT = 0,
DRAWLINE = 1,
}
///
/// 颗粒类
///
public class DisplayParticle : BaseObject, ICloneable, IComparable
{
private const float m_zoom_displaymultiplier = 0.5f;
public Particle objParticleData;
private Guid m_id;
private RectangleF m_rect;
private PointF m_OTSPointF;
private RectangleF m_small_rect;
private bool m_isSelected_smallrect;
private bool m_showSmallx;
private bool m_isSelected;
private bool m_isDeleted;
private bool m_isMouseOver;
private PaintState m_paintState = PaintState.NORMALPAINT;
private ParticleShowXray m_operator_showxray = ParticleShowXray.NODISPLAY;//选定显示XRAY,不显示XRAY,默认应为(不显示XRAY)
private bool m_isdragging;
private PointF m_dragingpoint;
private Color m_color;
private Color m_backcolor;
private GraphicsPath m_gpath;
private List m_listdsegment = new List();
private DisplayState m_displayState;
private string m_sort_type = "从大到小";
private float m_f_size = 0;
private string m_str_lj = "颗粒粒级";
private string m_str_klzl = "颗粒种类";
private string m_str_klfl = "颗粒分类";
public int TypeId
{
get
{
return objParticleData.TypeId;
}
}
//TypeName
public string TypeName
{
get
{
return objParticleData.TypeName;
}
}
//XRayId
public int XRayId
{
get
{
return objParticleData.XrayId;
}
}
public int SEMPosX
{
get
{
return objParticleData.SEMPosX;
}
}
public int SEMPosY
{
get
{
return objParticleData.SEMPosY;
}
}
public DisplayParticle()
{
m_id = System.Guid.NewGuid();
}
public DisplayParticle(Particle part)
{
m_id = System.Guid.NewGuid();
objParticleData = part;
this.Color = GetColorBySTDTypeIDForBSEAndSorImage(part.TypeColor, part.TypeId);
}
public DisplayParticle(List in_list_segment, DisplayParticle in_particle)
{
objParticleData = in_particle.objParticleData;
m_id = in_particle.m_id;
m_paintState = in_particle.m_paintState;
m_operator_showxray = in_particle.m_operator_showxray;
foreach (DisplaySegment e in in_list_segment)
{
m_listdsegment.Add(e.Clone() as DisplaySegment);
}
}
///
/// [目前也不使用该方法了,因为该方法每次排序都有不同的结果]多边形排序,按传入的sort_type的排序类型行排序,但需要两个list做一致性排序
///
///
///
public int CompareTo(DisplayParticle in_particle)
{
int r_b = 0;//排序返回值
switch (m_sort_type)
{
case "从大到小":
r_b = in_particle.m_f_size.CompareTo(this.m_f_size);
break;
case "从小到大":
//与上面的从大到小正好相反即可
r_b = in_particle.m_f_size.CompareTo(this.m_f_size);
if (r_b == 1)
r_b = -1;
else
r_b = 1;
break;
default:
break;
}
return r_b;
}
public Color GetColorBySTDTypeIDForBSEAndSorImage(string in_partcolor, int in_stdtypeid)
{
Color ret_c = new Color();
if (in_stdtypeid < 1000)
{
ret_c = GetColorByEnum(in_stdtypeid);
}
else if (in_stdtypeid >= 1000)
{
//大于等于1000,并且小于10000时,使用用户标准库来分析夹杂物名称
if (!in_partcolor.Contains("#"))
{
ret_c = DrawFunction.colorHx16toRGB("#" + in_partcolor);//接收必须是#000000的格式
}
else
{
ret_c = DrawFunction.colorHx16toRGB(in_partcolor);//接收必须是#000000的格式
}
}
return ret_c;
}
public Color GetColorByEnum(int STDID)
{
Color ret_c = new Color();
switch (STDID)
{
case -1:
//INVALID = -1,
//stdName = "无效颗粒";
ret_c = Color.Black;
break;
case 0:
//small = 0;
//stdName = "过小颗粒";
ret_c = Color.Black;
break;
case 1:
//OVERSIZE = 1,
//stdName = "过大颗粒";
ret_c = Color.Black;
break;
case 2:
//AVE_GRAY_NOT_INRANRE = 2,
//stdName = "亮度不在分析范围内的颗粒";
ret_c = Color.Black;
break;
case 3:
//SEARCH_X_RAY = 3,
//stdName = "不进行搜索x-ray分析的颗粒";
ret_c = Color.Black;
break;
case 4:
//LOW_COUNT = 4,
//stdName = "低x-ray计数颗粒";
ret_c = Color.Black;
break;
case 5:
//NO_INTEREST_ELEMENTS = 5,
//stdName = "不含分析元素的颗粒";
ret_c = Color.Black;
break;
case 6:
//ALAYSIS_X_RAY = 6,
//stdName = "不进行x-ray分析的颗粒";
ret_c = Color.Black;
break;
case 7:
//NOT_IDENTIFIED = 7,
//stdName = "未识别颗粒";
ret_c = Color.Black;
break;
case 8:
//NOT_IDENTIFIED = 8,
//stdName = "未识别颗粒";
ret_c = Color.Black;
break;
case 9:
//NOT_IDENTIFIED = 9,
//stdName = "未识别颗粒";
ret_c = Color.Black;
break;
default:
ret_c = Color.Black;
break;
}
return ret_c;
}
///
/// 克隆方法
///
///
public override object Clone()
{
return new DisplayParticle(this.m_listdsegment, this);
}
///
/// ID
///
public override Guid guid
{
get { return m_id; }
set { m_id = value; }
}
///
/// 颗粒的外边框大小
///
public override RectangleF Rect
{
get { return m_rect; }
set { m_rect = value; }
}
///
/// OTSPointF
///
public override PointF OTSPointF
{
get { return m_OTSPointF; }
set { m_OTSPointF = value; }
}
///
/// 颗粒里+号位置的外边框大小
///
public RectangleF SmallRect
{
get { return m_small_rect; }
set { m_small_rect = value; }
}
///
/// 颗粒是否被选择
///
public override bool IsSelect
{
get { return m_isSelected; }
set { m_isSelected = value; }
}
///
/// 该颗粒是否被设置成,选中状态
///
public PaintState GetPaintState()
{
if (GetDisplayState() == DisplayState.NODISPLAY)
{
m_paintState = PaintState.NOPAINT;
}
return m_paintState;
}
///
/// 该颗粒是否被设置成,选中状态
///
public void SetPaintState(PaintState value)
{ m_paintState = value; }
///
/// 是否对该颗粒选定显示X-Ray能谱图
///
public ParticleShowXray Operator_ShowXRay
{
get { return m_operator_showxray; }
set { m_operator_showxray = value; }
}
///
/// 是否显示x号
///
public bool IsShowSmallX
{
get { return m_showSmallx; }
set { m_showSmallx = value; }
}
///
/// 颗粒的x-ray的点,是否被选择上了
///
public bool IsSelectedSmallRect
{
get { return m_isSelected_smallrect; }
set { m_isSelected_smallrect = value; }
}
///
/// 是否在被拖动
///
public override bool IsDragging
{
get { return m_isdragging; }
set { m_isdragging = value; }
}
///
/// 被拖动到的位置坐标
///
public override PointF DraggingPoint
{
get { return m_dragingpoint; }
set { m_dragingpoint = value; }
}
///
/// 线的颜色
///
public override Color Color
{
get { return m_color; }
set { m_color = value; }
}
///
/// 背景色
///
public override Color BackColor
{
get { return m_backcolor; }
set { m_backcolor = value; }
}
///
/// 多边形的图形路径边缘
///
public override GraphicsPath GPath
{
get { return m_gpath; }
set { m_gpath = value; }
}
///
/// 里面包含的多个线的集合
///
public List DSegments
{
get { return m_listdsegment; }
set { m_listdsegment = value; }
}
///
/// 控制多边形在进行缩放到多少倍时进行显示
///
public float Zoom_DisPlayThreshold
{
get { return m_zoom_displaymultiplier; }
}
///
/// 设置排序的类型
///
public string SortType
{
get { return m_sort_type; }
set { m_sort_type = value; }
}
///
/// 设置该多边形的尺寸大小
///
public float FSize
{
get { return m_f_size; }
set { m_f_size = value; }
}
///
/// 设置粒级
///
public string ParticleLJ
{
get { return m_str_lj; }
set { m_str_lj = value; }
}
///
/// 设置种类
///
public string ParticleZL
{
get { return m_str_klzl; }
set { m_str_klzl = value; }
}
///
/// 设置分类
///
public string ParticleFL
{
get { return m_str_klfl; }
set { m_str_klfl = value; }
}
///
/// 获取或设置该Particle对应底层的FieldID值
///
public int FieldId
{
get { return objParticleData.FieldId; }
}
///
/// 获取或设置该Particle对应底层的ParticleID值
///
public int ParticleId
{
get { return objParticleData.ParticleId; }
}
public bool IsDeleted { get => m_isDeleted; set => m_isDeleted = value; }
public bool IsMouseOver { get => m_isMouseOver; set => m_isMouseOver = value; }
public DisplayState GetDisplayState()
{
if (m_isDeleted)
{
m_displayState = DisplayState.NODISPLAY;
}
return m_displayState;
}
public void SetDisplayState(DisplayState value)
{
m_displayState = value;
}
///
/// 绘制函数
///
///
public override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
//绘制鼠标移动到颗粒上时的边框,需要判断当前鼠标在颗粒上,及颗粒的操作为正常显示
if (m_isMouseOver == true)
{
//如果有鼠标在该矩形上,那么进行描边
ControlPaint.DrawBorder(g,
Rectangle.Round(this.Rect),
Color.Lime,
1,
ButtonBorderStyle.Solid,
Color.Lime,
1,
ButtonBorderStyle.Solid,
Color.Lime,
1,
ButtonBorderStyle.Solid,
Color.Lime,
1,
ButtonBorderStyle.Solid);
}
if (GetPaintState() == PaintState.NORMALPAINT)
{
//调用绘制基本线
foreach (DisplaySegment item in m_listdsegment)
{
item.OnPaint(e);
}
}
if (GetPaintState() == PaintState.CONCISEPAINT)
{
g.DrawString("+", new Font("黑体", 6), new SolidBrush(Color.DarkSlateBlue), new PointF(m_small_rect.X, m_small_rect.Y));
}
if (m_isSelected)
{
//如果説该矩形被选择上了的话,那么也显示边框
ControlPaint.DrawBorder(g,
Rectangle.Round(this.Rect),
Color.Blue,
1,
ButtonBorderStyle.Solid,
Color.Blue,
1,
ButtonBorderStyle.Solid,
Color.Blue,
1,
ButtonBorderStyle.Solid,
Color.Blue,
1,
ButtonBorderStyle.Solid);
}
if (ParticleShowXray.SELECTANDDISPLAYXRAY == m_operator_showxray && PaintState.NOPAINT != GetPaintState())
{
//当鼠标在该颗粒上进行点击,则对颗粒状态更改为选定状态,用来显示X-ray能谱表
ControlPaint.DrawBorder(g,
Rectangle.Round(this.Rect),
Color.DeepSkyBlue,
1,
ButtonBorderStyle.Solid,
Color.DeepSkyBlue,
1,
ButtonBorderStyle.Solid,
Color.DeepSkyBlue,
1,
ButtonBorderStyle.Solid,
Color.DeepSkyBlue,
1,
ButtonBorderStyle.Solid);
}
}
///
/// 从Line中获取矩形的边缘闭合路径
///
///
public GraphicsPath GetRegionFromDSegments()
{
GraphicsPath gpath = new GraphicsPath();
List list_leftpointf = new List();
List list_rightpointf = new List();
//从y循环,这里假设y轴会按lines集合来计算,然后将所有的左x,和右x取出排成两个队列
foreach (DisplaySegment ds in this.m_listdsegment)
{
list_leftpointf.Add(new PointF(ds.Rect.X, ds.Rect.Y));
list_rightpointf.Add(new PointF(ds.Rect.X + ds.Rect.Width, ds.Rect.Y));
}
PointF[] lsp = new PointF[list_leftpointf.Count + list_rightpointf.Count];
//再将两个x,y点依次添加到闭合路径中
for (int i = 0; i < list_leftpointf.Count(); i++)
{
lsp[i] = list_leftpointf[i];
}
//右节点
for (int i = 0; i < list_rightpointf.Count(); i++)
{
//这边倒着存入
lsp[list_rightpointf.Count() + i] = list_rightpointf[list_rightpointf.Count() - i - 1];
}
//防止从低层拿到无数据的外边路径,在我的程序里却需要计算,而防止程序报死,这里做一下特殊处理。
if (lsp.Count() >= 3)
{
gpath.AddPolygon(lsp);
}
else
{
//有时居然有颗粒,有没有segment的时候,防止报错
if (this.DSegments.Count == 0)
{
lsp = new PointF[3] { new PointF(0, 0), new PointF(0, 0), new PointF(0, 0) };
gpath.AddPolygon(lsp);
return gpath;
}
//有2条数据
if (lsp[1].X != 0 && lsp[1].Y != 0)
{
lsp = new PointF[3] { new PointF(lsp[0].X, lsp[0].Y), new PointF(lsp[1].X, lsp[1].Y), new PointF(lsp[1].X, lsp[1].Y) };
}
//有1条数据
else if (lsp[0].X != 0 && lsp[0].Y != 0)
{
lsp = new PointF[3] { new PointF(lsp[0].X, lsp[0].Y), new PointF(lsp[0].X, lsp[0].Y), new PointF(lsp[0].X, lsp[0].Y) };
}
//剩下的情况
else
{
lsp = new PointF[3] { new PointF(0, 0), new PointF(0, 0), new PointF(0,0) };
}
gpath.AddPolygon(lsp);
}
return gpath;
}
///
/// 从已经确定的外边框来计算出里面的+号小框位置
///
///
public RectangleF GetSmallRectangleFromRect()
{
RectangleF rect = new RectangleF();
//用外边框的坐标,除2获得中心点,然后再分别+,- 4
float x = 0, y = 0;
x = m_rect.X + (m_rect.Width / 2);
y = m_rect.Y + (m_rect.Height / 2);
rect.X = x - 4;
rect.Y = y - 4;
rect.Width = 8;
rect.Height = 4;
return rect;
}
///
/// 根据该多边形所有包含的线长度,计算出,该多边形的面积大小
///
///
public float GetAreaFormSegments()
{
float f_size_sum = 0;
foreach (DisplaySegment ls_ds in this.m_listdsegment)
{
f_size_sum = f_size_sum + ls_ds.Rect.Width;
}
return f_size_sum;
}
///
/// 从基本线中获取整个矩形的Rectangle
///
///
public RectangleF GetRectFromDSegment()
{
RectangleF rect = new RectangleF();
float x1 = 0, y1 = 0;
float i_width = 0, i_height = 0;
//先从自身中初始化x,y,和宽,高
if (this.m_listdsegment.Count > 0)
{
x1 = this.m_listdsegment[0].Rect.X;
y1 = this.m_listdsegment[0].Rect.Y;
i_width = x1 + this.m_listdsegment[0].Rect.Width;
i_height = this.m_listdsegment[0].Rect.Y;
}
foreach (DisplaySegment ds in this.m_listdsegment)
{
//分别取出,最小的x,y,
if (ds.Rect.X < x1)
{
x1 = ds.Rect.X;
}
if (ds.Rect.Y < y1)
{
y1 = ds.Rect.Y;
}
//最大的x,y
if (ds.Rect.X + ds.Rect.Width > i_width)
{
i_width = ds.Rect.X + ds.Rect.Width;
}
if (ds.Rect.Y > i_height)
{
i_height = ds.Rect.Y;
}
}
//对矩形Rect大小位置进行修补,因为画线是内边框,并且计算出来的位置也是向内占用一像素的,
//正常应该是 +2,但实际效果,+3也才勉强够用,因为放大缩小画笔宽度影响的
rect.X = x1 - 2;
rect.Y = y1 - 3;
rect.Width = i_width - rect.X + 2;
rect.Height = i_height - rect.Y + 3;
//判断如果太小,就给个最小值吧
if (rect.Width < 8)
rect.Width = 8;
if (rect.Height < 8)
rect.Height = 8;
return rect;
}
}
}