273 lines
12 KiB
C#
273 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
|
|
namespace AGVEmulator.UC
|
|
{
|
|
public partial class AgvViewer : Control
|
|
{
|
|
|
|
public AgvViewer()
|
|
{
|
|
InitializeComponent();
|
|
|
|
// Set Optimized Double Buffer to reduce flickering
|
|
this.SetStyle(ControlStyles.UserPaint, true);
|
|
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
|
|
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
|
|
|
|
// Redraw when resized
|
|
this.SetStyle(ControlStyles.ResizeRedraw, true);
|
|
}
|
|
|
|
public class TagArgs : EventArgs
|
|
{
|
|
public string Data { get; set; }
|
|
public bool Active { get; set; }
|
|
public TagArgs(string tag,bool act)
|
|
{
|
|
this.Data = tag;
|
|
this.Active = act;
|
|
}
|
|
}
|
|
public event EventHandler<TagArgs> TagTouched;
|
|
public event EventHandler<TagArgs> MarkTouched;
|
|
public event EventHandler<TagArgs> Command;
|
|
|
|
public bool StopbyMark { get; set; }
|
|
public float mpos = 100;
|
|
public float posmax = 1200;
|
|
public float posmin = 0;
|
|
public float mspd = 10;
|
|
public System.Diagnostics.Stopwatch wat = new System.Diagnostics.Stopwatch();
|
|
public Font FontTag { get; set; }
|
|
public Font FontMrk { get; set; }
|
|
public int dir = 1;
|
|
|
|
public class ptdata
|
|
{
|
|
public float pos { get; set; } = 0f;
|
|
public string data { get; set; } = string.Empty;
|
|
public Boolean active { get; set; } = false;
|
|
}
|
|
public ptdata[] listMRK { get; set; }
|
|
public ptdata[] listTAG { get; set; }
|
|
|
|
public string lasttag { get; set; } = string.Empty;
|
|
public string lasttagdir { get; set; } = string.Empty;
|
|
public string lastmark { get; set; } = string.Empty;
|
|
public string lastmarkdir { get; set; } = string.Empty;
|
|
|
|
protected override void OnPaint(PaintEventArgs pe)
|
|
{
|
|
pe.Graphics.Clear(this.BackColor);
|
|
var r = new Rectangle(DisplayRectangle.Left + Padding.Left,
|
|
DisplayRectangle.Top + Padding.Top,
|
|
DisplayRectangle.Width - Padding.Right - Padding.Left - 1,
|
|
DisplayRectangle.Height - Padding.Top - Padding.Bottom - 1);
|
|
|
|
|
|
// pe.Graphics.FillRectangle(new SolidBrush(this.BackColor), DisplayRectangle);
|
|
pe.Graphics.DrawRectangle(Pens.Black, r);
|
|
|
|
|
|
var ptwidth = 25;
|
|
var ptheight = 35;
|
|
if (listMRK != null && listMRK.Any() && FontMrk != null)
|
|
{
|
|
foreach (var item in listMRK)
|
|
{
|
|
var x = r.Left + ((item.pos * 1f) / posmax) * r.Width;
|
|
var rr = new RectangleF(x - ptwidth, r.Top + r.Height / 2f - ptheight / 2f, ptwidth * 2, ptheight);
|
|
pe.Graphics.DrawLine(Pens.Gray, x, r.Top, x, r.Bottom);
|
|
pe.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(120, Color.Gold)), rr);
|
|
pe.Graphics.DrawRectangle(Pens.DimGray, rr.Left, rr.Top, rr.Width, rr.Height);
|
|
pe.Graphics.DrawString(item.data, FontMrk, Brushes.Gray, rr, new StringFormat
|
|
{
|
|
Alignment = StringAlignment.Center,
|
|
LineAlignment = StringAlignment.Center,
|
|
});
|
|
|
|
}
|
|
}
|
|
|
|
ptwidth = 15;
|
|
if (listTAG != null && listTAG.Any() && FontTag != null)
|
|
{
|
|
var lst = listTAG.Where(t => t.data.EndsWith("1"));
|
|
foreach (var item in lst)
|
|
{
|
|
var x = r.Left + ((item.pos * 1f) / posmax) * r.Width;
|
|
var rr = new RectangleF(x - ptwidth, r.Top + 5, ptwidth * 2, 15);
|
|
pe.Graphics.DrawLine(Pens.Orange, x, r.Top, x, rr.Top);
|
|
pe.Graphics.FillRectangle(Brushes.Orange, rr);
|
|
pe.Graphics.DrawRectangle(Pens.DimGray, rr.Left, rr.Top, rr.Width, rr.Height);
|
|
pe.Graphics.DrawString(item.data, FontTag, Brushes.Black, rr, new StringFormat
|
|
{
|
|
Alignment = StringAlignment.Center,
|
|
LineAlignment = StringAlignment.Center,
|
|
});
|
|
}
|
|
|
|
lst = listTAG.Where(t => t.data.EndsWith("0"));
|
|
foreach (var item in lst)
|
|
{
|
|
var x = r.Left + ((item.pos * 1f) / posmax) * r.Width;
|
|
var rr = new RectangleF(x - ptwidth, r.Bottom - 20, ptwidth * 2, 15);
|
|
pe.Graphics.DrawLine(Pens.Orange, x, rr.Bottom, x, r.Bottom);
|
|
pe.Graphics.FillRectangle(Brushes.Orange, rr);
|
|
pe.Graphics.DrawRectangle(Pens.DimGray, rr.Left, rr.Top, rr.Width, rr.Height);
|
|
pe.Graphics.DrawString(item.data, FontTag, Brushes.Black, rr, new StringFormat
|
|
{
|
|
Alignment = StringAlignment.Center,
|
|
LineAlignment = StringAlignment.Center,
|
|
});
|
|
}
|
|
}
|
|
|
|
var posX = r.Left + (mpos / posmax) * r.Width;
|
|
var posY = r.Top + r.Height / 2f;
|
|
var boxw = r.Width * 0.030f;
|
|
var boxh = r.Height * 0.15f;
|
|
var box = new RectangleF(posX - boxw, posY - boxh, boxw * 2, boxh * 2);
|
|
var box2 = new RectangleF(box.Left - 5, box.Top + 3, 10, box.Height - 6);
|
|
for (int i = 0; i < posmax; i += 100)
|
|
{
|
|
var x = r.Left + ((i * 1f) / posmax) * r.Width;
|
|
pe.Graphics.DrawLine(Pens.Black, x, r.Bottom - 3, x, r.Bottom);
|
|
if (i > 0)
|
|
pe.Graphics.DrawString($"{i / 10f}m", this.Font, Brushes.Black, x - 12, r.Bottom - 15);
|
|
}
|
|
pe.Graphics.FillRectangle(Brushes.LightSkyBlue, box);
|
|
pe.Graphics.DrawRectangle(Pens.Black, box.Left, box.Top, box.Width, box.Height);
|
|
pe.Graphics.DrawLine(new Pen(Color.Black, 4), posX, box.Top - 5, posX, box.Bottom + 5);
|
|
|
|
pe.Graphics.FillRectangle(Brushes.Gold, box2);
|
|
pe.Graphics.DrawRectangle(Pens.Black, box2.Left, box2.Top, box2.Width, box2.Height);
|
|
//pe.Graphics.DrawString((mpos / 10f).ToString("N1") + "m", this.Font, Brushes.Black, box, new StringFormat
|
|
//{
|
|
// Alignment = StringAlignment.Center,
|
|
// LineAlignment = StringAlignment.Center,
|
|
//});
|
|
|
|
if (StopbyMark)
|
|
pe.Graphics.DrawString("!MRK-STP!", this.Font, Brushes.Blue, r.Left+2, r.Top+2);
|
|
|
|
if (wat.IsRunning)
|
|
{
|
|
var newpos = mspd * (wat.ElapsedMilliseconds / 1000f);
|
|
if (dir < 0) //forward
|
|
{
|
|
if (mpos - newpos < 0)
|
|
mpos = posmax;
|
|
else mpos -= newpos;
|
|
|
|
//내위치주변에 마커가 있는지 본다
|
|
var mlist = listMRK.Where(t => t.pos <= mpos && (mpos - t.pos) < 10);
|
|
var mrk = mlist.FirstOrDefault();
|
|
if (mrk != null)
|
|
{
|
|
//대상마커가있다
|
|
if (lastmark.Equals(mrk.data) == false || lastmarkdir.Equals("F") == false)
|
|
{
|
|
lastmark = mrk.data;
|
|
lastmarkdir = "F";
|
|
mrk.active = true;
|
|
MarkTouched?.Invoke(this, new TagArgs(mrk.data,true));
|
|
if(StopbyMark)
|
|
{
|
|
Command?.Invoke(this, new TagArgs("stop",true));
|
|
StopbyMark = false;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (string.IsNullOrEmpty(lastmark) == false)
|
|
{
|
|
foreach(var item in listMRK.Where(t=>t.active))
|
|
{
|
|
item.active = false;
|
|
MarkTouched?.Invoke(this, new TagArgs(item.data,false));
|
|
}
|
|
}
|
|
}
|
|
|
|
//주변태그확인
|
|
var tlist = listTAG.Where(t => t.pos <= mpos && (mpos - t.pos) < 10);
|
|
var tag = tlist.FirstOrDefault();
|
|
if (tag != null)
|
|
{
|
|
//대상마커가있다
|
|
if (lasttag.Equals(tag.data) == false || lasttagdir.Equals("F") == false)
|
|
{
|
|
lasttag = tag.data;
|
|
lasttagdir = "F";
|
|
TagTouched?.Invoke(this, new TagArgs(tag.data, true));
|
|
}
|
|
}
|
|
}
|
|
else //backward
|
|
{
|
|
if (mpos + newpos > posmax)
|
|
mpos = 0;
|
|
else mpos += newpos;
|
|
|
|
//내위치주변에 마커가 있는지 본다
|
|
var mlist = listMRK.Where(t => t.pos >= mpos && (t.pos - mpos) < 10);
|
|
var mrk = mlist.FirstOrDefault();
|
|
if (mrk != null)
|
|
{
|
|
//대상마커가있다
|
|
if (lastmark.Equals(mrk.data) == false || lastmarkdir.Equals("B") == false)
|
|
{
|
|
lastmark = mrk.data;
|
|
lastmarkdir = "B";
|
|
mrk.active = true;
|
|
MarkTouched?.Invoke(this, new TagArgs(mrk.data, true));
|
|
if (StopbyMark)
|
|
{
|
|
Command?.Invoke(this, new TagArgs("stop", true));
|
|
StopbyMark = false;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (string.IsNullOrEmpty(lastmark) == false)
|
|
{
|
|
foreach (var item in listMRK.Where(t => t.active))
|
|
{
|
|
item.active = false;
|
|
MarkTouched?.Invoke(this, new TagArgs(item.data, false));
|
|
}
|
|
}
|
|
}
|
|
|
|
//주변태그확인
|
|
var tlist = listTAG.Where(t => t.pos >= mpos && (t.pos - mpos) < 10);
|
|
var tag = tlist.FirstOrDefault();
|
|
if (tag != null)
|
|
{
|
|
//대상마커가있다
|
|
if (lasttag.Equals(tag.data) == false || lasttagdir.Equals("B") == false)
|
|
{
|
|
lasttag = tag.data;
|
|
lasttagdir = "B";
|
|
TagTouched?.Invoke(this, new TagArgs(tag.data, true));
|
|
}
|
|
}
|
|
}
|
|
|
|
wat.Restart();
|
|
}
|
|
}
|
|
}
|
|
}
|