You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

550 lines
16 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using HalconDotNet;
using Rs.Framework;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;
namespace Rs.Controls
{
public enum ESortDir
{
LeftToRight,
RightToLeft
}
public enum ESlotStatus
{
Have,
NotHave,
Ok,
Ng,
Disable
}
public partial class RsTray : UserControl
{
public string ItemName { get; set; }
private ESortDir sortDir = ESortDir.LeftToRight;
public ESortDir SortDir
{
get { return sortDir; }
set { sortDir = value;
UpdateSlotPos();
}
}
public event Action<TraySlot, MouseEventArgs> SlotClickEvent;
#region 是否显示状态
private bool mShowStatus = true;
/// <summary>
/// 是否显示状态
/// </summary>
public bool ShowStatus
{
get { return mShowStatus; }
set { mShowStatus = value;
lblStatus.Visible = mShowStatus;
}
}
#endregion
private string mStatus;
public string Status
{
get { return mStatus; }
set {
mStatus = value;
lblStatus.Text = mStatus;
Invalidate();
}
}
public RsTray()
{
InitializeComponent();
DoubleBuffered = true;
InitSlot(InitSlotStatus);
this.SizeChanged += (s, e) => {
UpdateSlotPos();
};
}
public void ResetTray()
{
}
private ESlotStatus _InitSlotStatus = ESlotStatus.Have;
public ESlotStatus InitSlotStatus
{
get { return _InitSlotStatus; }
set { _InitSlotStatus = value; InitSlot(InitSlotStatus); Invalidate(); }
}
public TraySlot GetSlot(ESlotStatus status)
{
foreach(KeyValuePair<int,TraySlot> kv in traySlotsDic)
{
if (kv.Value.SlotStatus == status)
return kv.Value;
}
return null;
}
public bool CanDraw { get; set; } = true;
private Dictionary<int, TraySlot> traySlotsDic = new Dictionary<int, TraySlot>();
private string _HeadText;
public string HeadText
{
get { return _HeadText; }
set { _HeadText = value; this.label1.Text = value; }
}
private int _RowNum = 26;
/// <summary>
/// 行数
/// </summary>
public int RowNum
{
get { return _RowNum; }
set { _RowNum = value; InitSlot(InitSlotStatus); Invalidate(); }
}
private int _ColumnNum = 10;
/// <summary>
/// 列数量
/// </summary>
public int ColumnNum
{
get { return _ColumnNum; }
set { _ColumnNum = value; InitSlot(InitSlotStatus); Invalidate(); }
}
private int _TopSpaceHeight = 20;
/// <summary>
/// 料盘上部留白高度
/// </summary>
public int TopSpaceHeight
{
get { return _TopSpaceHeight; }
set { _TopSpaceHeight = value; }
}
private int _LeftSpaceWidth = 20;
/// <summary>
/// 料盘左边留白宽度
/// </summary>
public int LeftSpaceWidth
{
get { return _LeftSpaceWidth; }
set { _LeftSpaceWidth = value; }
}
private int _RowSpace = 3;
public int RowSpace
{
get { return _RowSpace; }
set { _RowSpace = value; }
}
private int _ColSpace = 5;
public int ColSpace
{
get { return _ColSpace; }
set { _ColSpace = value; }
}
private bool _ShowText;
public bool ShowText
{
get { return _ShowText; }
set { _ShowText = value; }
}
private float _OffsetX;
/// <summary>
/// X方向偏移
/// </summary>
public float OffsetX
{
get { return _OffsetX; }
set { _OffsetX = value; }
}
private float _OffsetY;
/// <summary>
/// Y方向偏移
/// </summary>
public float OffsetY
{
get { return _OffsetY; }
set { _OffsetY = value; }
}
private float _OffsetYEven;
/// <summary>
/// Y方向偏移偶数行
/// </summary>
public float OffsetYEven
{
get { return _OffsetYEven; }
set { _OffsetYEven = value; }
}
private bool _SinglePoint=false;
/// <summary>
/// 单点定位
/// </summary>
public bool SinglePoint
{
get { return _SinglePoint; }
set { _SinglePoint = value; }
}
private Bitmap drawImage;
private void InitSlot(ESlotStatus status)
{
int index = 0;
traySlotsDic.Clear();
for (int r = 0; r < RowNum; r++)
{
for (int c = 0; c < ColumnNum; c++)
{
index++;
TraySlot slot = new TraySlot();
slot.Index = index;
slot.Row = r;
slot.Column = c;
slot.SlotStatus = status;
traySlotsDic.Add(index, slot);
}
}
UpdateSlotPos();
}
public void Fill()
{
foreach (KeyValuePair<int, TraySlot> kv in traySlotsDic)
{
ChangeStatus(kv.Value.Index, ESlotStatus.Have);
}
}
public void Clear()
{
foreach (KeyValuePair<int, TraySlot> kv in traySlotsDic)
{
ChangeStatus(kv.Value.Index, ESlotStatus.NotHave);
}
}
public void ChangeStatus(int index, ESlotStatus status)
{
if (traySlotsDic.ContainsKey(index))
{
traySlotsDic[index].SlotStatus = status;
traySlotsDic[index].Refresh(this.panel2.CreateGraphics(), ShowText);
}
}
private void UpdateSlotPos()
{
float slotWidth = (this.panel2.Width - LeftSpaceWidth) / ColumnNum;
float slotHeight = (this.panel2.Height - TopSpaceHeight) / RowNum;
int index = 0;
if (SortDir == ESortDir.LeftToRight)
{
for (int r = 0; r < RowNum; r++)
{
for (int c = 0; c < ColumnNum; c++)
{
index++;
if (traySlotsDic.ContainsKey(index))
{
traySlotsDic[index].Bound = new RectangleF((LeftSpaceWidth + slotWidth * c), (TopSpaceHeight + slotHeight * r), (int)slotWidth - ColSpace, (int)slotHeight - RowSpace);
}
}
}
}
else if (SortDir == ESortDir.RightToLeft)
{
for (int r = 0; r < RowNum; r++)
{
for (int c = 0; c < ColumnNum; c++)
{
index++;
if (traySlotsDic.ContainsKey(index))
{
traySlotsDic[index].Bound = new RectangleF((LeftSpaceWidth + slotWidth * (ColumnNum-1-c)), (TopSpaceHeight + slotHeight * r), (int)slotWidth - ColSpace, (int)slotHeight - RowSpace);
}
}
}
}
panel2.Refresh();
}
private void panel2_Paint(object sender, PaintEventArgs e)
{
this.DoubleBuffered = true;
Graphics g = this.panel2.CreateGraphics();
drawImage = new Bitmap(this.panel2.Width, this.panel2.Height);
Graphics g2 = Graphics.FromImage(drawImage);
g2.Clear(BackColor);
//先计算出每一个料仓中穴位占用的宽度和高度
float widthPer = (this.panel2.Width - LeftSpaceWidth) / ColumnNum;
float heightPer = (this.panel2.Height - TopSpaceHeight) / RowNum;
//先画列,再画行
int index = 0;
for (int c = 0; c < ColumnNum; c++)
{
for (int r = 0; r < RowNum; r++)
{
index++;
if (r == 0)
{
//画料盘的列号
if (SortDir == ESortDir.LeftToRight)
{
g2.DrawString((c+ 1).ToString(), new Font("宋体", 7.0F), new SolidBrush(Color.White), new PointF(LeftSpaceWidth + (widthPer * c) + 5, 5));
}
else if(SortDir== ESortDir.RightToLeft)
{
g2.DrawString((ColumnNum - c).ToString(), new Font("宋体", 7.0F), new SolidBrush(Color.White), new PointF(LeftSpaceWidth + (widthPer * c) + 5, 5));
}
}
if (c == 0)
{
//画料盘的行号
g2.DrawString((r + 1).ToString(), new Font("宋体", 7.0F), new SolidBrush(Color.White), new PointF(5, TopSpaceHeight + (heightPer * r)));
}
if (traySlotsDic.ContainsKey(index))
{
traySlotsDic[index].Draw(g2, ShowText);
}
}
}
g2.Flush();
g.DrawImage(drawImage, 0, 0, drawImage.Width, drawImage.Height);
if (drawRegion)
{
g.FillRectangle(new SolidBrush(Color.FromArgb(200, Color.Pink)), drawRect);
}
g.Flush();
g.Dispose();
g2.Dispose();
}
bool drawRegion = false;
RectangleF drawRect = new RectangleF();
private void panel2_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && drawRegion == false)
{
if (CanDraw)
{
drawRegion = true;
drawRect.X = e.X;
drawRect.Y = e.Y;
}
}
}
private void panel2_MouseMove(object sender, MouseEventArgs e)
{
if (drawRegion)
{
drawRect.Width = e.X - drawRect.X;
drawRect.Height = e.Y - drawRect.Y;
panel2_Paint(null, null);
}
}
private void panel2_MouseUp(object sender, MouseEventArgs e)
{
drawRegion = false;
}
public TraySlot SelectSlot { get; set; }
private void panel2_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
if (!drawRect.IsEmpty && drawRect.Contains(e.Location))
{
contextMenuStrip1.Show(panel2, e.Location);
}
else
{
SelectSlot = null;
bool find = false;
foreach (KeyValuePair<int,TraySlot> kvSlot in traySlotsDic)
{
if (kvSlot.Value.Bound.Contains(e.Location))
{
find = true;
SelectSlot = kvSlot.Value;
break;
}
}
if (find)
{
if (SlotClickEvent != null)
SlotClickEvent(SelectSlot, e);
}
}
}
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
ChangeSlotStatus(ESlotStatus.Disable);
}
private void ChangeSlotStatus(ESlotStatus status)
{
foreach (KeyValuePair<int, TraySlot> kvSlot in traySlotsDic)
{
if (drawRect.IntersectsWith(kvSlot.Value.Bound))
{
kvSlot.Value.SlotStatus = status;
}
}
UpdateSlotPos();
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
ChangeSlotStatus(ESlotStatus.Have);
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
ChangeSlotStatus(ESlotStatus.NotHave);
}
}
/// <summary>
/// 料盘槽位
/// </summary>
public class TraySlot
{
public ESlotStatus SlotStatus { get; set; } = ESlotStatus.Have;
private int _Index;
public int Index
{
get { return _Index; }
set { _Index = value; }
}
private int _Row;
public int Row
{
get { return _Row; }
set { _Row = value; }
}
private int _Column;
public int Column
{
get { return _Column; }
set { _Column = value; }
}
private string _SN;
public string SN
{
get { return _SN; }
set { _SN = value; }
}
private RectangleF _Bound;
[XmlIgnore]
public RectangleF Bound
{
get { return _Bound; }
set { _Bound = value; }
}
public void Refresh(Graphics g, bool isShowText)
{
Draw(g, isShowText);
}
public void Draw(Graphics g, bool isShowText)
{
if (_Bound != null)
{
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
switch (SlotStatus)
{
case ESlotStatus.Have:
g.FillRectangle(new SolidBrush(Color.Blue), Bound.X, Bound.Y, Bound.Width - 1, Bound.Height - 1);
break;
case ESlotStatus.NotHave:
g.FillRectangle(new SolidBrush(Color.FromArgb(11, 16, 36)), Bound.X, Bound.Y, Bound.Width - 1, Bound.Height - 1);
break;
case ESlotStatus.Ok:
g.FillRectangle(new SolidBrush(Color.Green), Bound.X, Bound.Y, Bound.Width - 1, Bound.Height - 1);
break;
case ESlotStatus.Ng:
g.FillRectangle(new SolidBrush(Color.Red), Bound.X, Bound.Y, Bound.Width - 1, Bound.Height - 1);
break;
case ESlotStatus.Disable:
g.FillRectangle(new SolidBrush(Color.Gray), Bound.X, Bound.Y, Bound.Width - 1, Bound.Height - 1);
break;
default:
break;
}
g.DrawRectangle(Pens.White, Bound.X, Bound.Y, Bound.Width, Bound.Height);
if (isShowText)
{
g.DrawString(Index.ToString(), new Font("宋体", 8), new SolidBrush(Color.Yellow), _Bound, sf);
}
}
}
}
}