1657 lines
71 KiB
C#
1657 lines
71 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Linq;
|
|
using System.Windows.Forms;
|
|
using AR;
|
|
|
|
namespace UIControl
|
|
{
|
|
public partial class HMI : System.Windows.Forms.Control
|
|
{
|
|
arDev.DIO.IDIO dio = null;
|
|
arDev.MOT.IMotion mot = null;
|
|
|
|
#region "Variable - Private"
|
|
Timer tm;
|
|
Boolean _ardebugmode = false;
|
|
eScean _scean = eScean.Nomal;
|
|
//기타 내부 변수
|
|
int AnimationStepConv = 30; //컨베어 이동 애니메이션 최대 값
|
|
//int AnimationStepPort = 9; //포트 이동 애니메이션 최대 값
|
|
Boolean bRemakeRect = true; //이값이 활성화되면 각 영역을 다시 그리게 된다
|
|
DateTime updatetime = DateTime.Now; //화면을 다시 그린 시간
|
|
Brush BRPortBg = new SolidBrush(Color.FromArgb(50, Color.DimGray));
|
|
Brush BRDetectDn = new SolidBrush(Color.FromArgb(50, Color.DimGray));
|
|
StringFormat sfCenter;
|
|
StringFormat sfLeft = new StringFormat { Alignment = StringAlignment.Near, LineAlignment = StringAlignment.Center };
|
|
SolidBrush brVacOff = new SolidBrush(Color.FromArgb(150, Color.White));
|
|
SolidBrush brVacOn = new SolidBrush(Color.FromArgb(200, Color.Lime));
|
|
Font arFont_MotPosName { get; set; }
|
|
|
|
Pen penVacOn = new Pen(Color.Red, 5);
|
|
Pen penVacOff = new Pen(Color.Black, 5);
|
|
|
|
//영역(큰 그림?) (bRemakeRect 에 의 해 생성된다)
|
|
RectangleF rect_main = RectangleF.Empty;
|
|
// RectangleF rect_frontShuttle = RectangleF.Empty;
|
|
//RectangleF rect_rearShuttle = RectangleF.Empty;
|
|
RectangleF rect_conveyor = RectangleF.Empty;
|
|
RectangleF rect_picker = RectangleF.Empty;
|
|
RectangleF rect_printl = RectangleF.Empty;
|
|
RectangleF rect_printr = RectangleF.Empty;
|
|
|
|
|
|
//영역(피커)
|
|
RectangleF rect_picker_left = RectangleF.Empty;
|
|
RectangleF rect_picker_front_vac1 = RectangleF.Empty;
|
|
RectangleF rect_picker_front_vac2 = RectangleF.Empty;
|
|
RectangleF rect_picker_front_vac3 = RectangleF.Empty;
|
|
RectangleF rect_picker_front_vac4 = RectangleF.Empty;
|
|
|
|
//X축 포트 (F-L:0, F-R:1, R-L:2, R-R:3
|
|
//RectangleF[] rect_port = new RectangleF[4];
|
|
RectangleF[] rect_zone = new RectangleF[11];
|
|
|
|
//CIcon[] icons = new CIcon[7];
|
|
List<CMenuButton> Buttons = new List<CMenuButton>();
|
|
List<CMenuButton> menuButtons = new List<CMenuButton>();
|
|
|
|
#endregion
|
|
|
|
#region "Variable - Public"
|
|
// public double[] arMotorPosition = new double[] { 0, 0, 0, 0, 0 };
|
|
public int ConveyorRunPoint = 1; //컨베어 모터 이동시 이동 화살표의 위치값(내부 타이머에의해 증가함)
|
|
public double arMcLengthW = 1460;
|
|
public double arMcLengthH = 1350;//
|
|
public bool CVLeftBusy = false;
|
|
public bool CVLeftReady = false;
|
|
public bool CVRightBusy = false;
|
|
public bool CVRightReady = false;
|
|
#endregion
|
|
|
|
#region "Property"
|
|
|
|
public int arCountV0 { get; set; }
|
|
public int arCountV1 { get; set; }
|
|
public int arCountV2 { get; set; }
|
|
|
|
public int arCountPrint0 { get; set; }
|
|
public int arCountPrint1 { get; set; }
|
|
|
|
public Boolean arPortLItemOn { get; set; }
|
|
public Boolean arPortRItemOn { get; set; }
|
|
|
|
public Boolean arPLItemON { get; set; }
|
|
public Boolean arPRItemON { get; set; }
|
|
public Boolean arMagnet0 { get; set; }
|
|
public Boolean arMagnet1 { get; set; }
|
|
public Boolean arMagnet2 { get; set; }
|
|
public Boolean arPickerSafeZone { get; set; }
|
|
|
|
private Padding _padding = new Padding(0);
|
|
public new Padding Padding { get { return _padding; } set { _padding = value; bRemakeRect = true; this.Invalidate(); } }
|
|
|
|
/// <summary>
|
|
/// 현재 메뉴가 표시되어있는가?
|
|
/// </summary>
|
|
public Boolean HasPopupMenu { get; private set; }
|
|
/// <summary>
|
|
/// 현재표시된 메뉴는 사용자의 입력을 반드시 받아야 하는가?
|
|
/// </summary>
|
|
public Boolean PopupMenuRequireInput { get; private set; }
|
|
public Font arFont_PortMessage { get; set; }
|
|
|
|
|
|
public eScean Scean { get { return _scean; } set { _scean = value; bRemakeRect = true; this.Invalidate(); } }
|
|
|
|
//컨베이어에 설치된 자재 감지 센서
|
|
public Boolean[] arDI_Cv_Detect { get; set; }
|
|
//컨베이어 입구 안전 센서
|
|
public Boolean arInitMOT { get; set; }
|
|
public Boolean arJobEND { get; set; }
|
|
public Boolean arLowDiskSpace { get; set; } //용량 부족 메세지 여부
|
|
public double arFreespace { get; set; } //남은 디스크 용량 비율
|
|
|
|
public Boolean arFGVision0RDY { get; set; }
|
|
public Boolean arFGVision1RDY { get; set; }
|
|
public Boolean arFGVision2RDY { get; set; }
|
|
|
|
public Boolean arFGVision0END { get; set; }
|
|
public Boolean arFGVision1END { get; set; }
|
|
public Boolean arFGVision2END { get; set; }
|
|
|
|
public Boolean arFGPrinter0RDY { get; set; }
|
|
public Boolean arFGPrinter1RDY { get; set; }
|
|
public Boolean arFGPrinter2RDY { get; set; }
|
|
|
|
public Boolean arFGPrinter0END { get; set; }
|
|
public Boolean arFGPrinter1END { get; set; }
|
|
public Boolean arFGPrinter2END { get; set; }
|
|
|
|
|
|
public Boolean arDI_SaftyOk { get; set; }
|
|
|
|
public string arMotPosNamePX { get; set; }
|
|
public string arMotPosNamePZ { get; set; }
|
|
public string arMotPosNameLM { get; set; }
|
|
public string arMotPosNameLZ { get; set; }
|
|
public string arMotPosNameRM { get; set; }
|
|
public string arMotPosNameRZ { get; set; }
|
|
|
|
public Boolean arMotILockPKX { get; set; }
|
|
public Boolean arMotILockPKZ { get; set; }
|
|
public Boolean arMotILockPLM { get; set; }
|
|
public Boolean arMotILockPLZ { get; set; }
|
|
public Boolean arMotILockPRM { get; set; }
|
|
public Boolean arMotILockPRZ { get; set; }
|
|
|
|
public Boolean arMotILockPRL { get; set; }
|
|
public Boolean arMotILockPRR { get; set; }
|
|
public Boolean arMotILockVS0 { get; set; }
|
|
public Boolean arMotILockVS1 { get; set; }
|
|
public Boolean arMotILockVS2 { get; set; }
|
|
public Boolean arMotILockCVL { get; set; }
|
|
public Boolean arMotILockCVR { get; set; }
|
|
|
|
public Boolean PrintLPICK { get; set; }
|
|
public Boolean PrintRPICK { get; set; }
|
|
|
|
public Boolean L_PICK_FW { get; set; }
|
|
public Boolean L_PICK_BW { get; set; }
|
|
public Boolean R_PICK_FW { get; set; }
|
|
public Boolean R_PICK_BW { get; set; }
|
|
|
|
public Boolean[] arMOT_LimUp = new bool[] { false, false, false, false, false, false, false };
|
|
public Boolean[] arMOT_LimDn = new bool[] { false, false, false, false, false, false, false };
|
|
public Boolean[] arMOT_Origin = new bool[] { false, false, false, false, false, false, false };
|
|
public Boolean[] arMOT_Alm = new bool[] { false, false, false, false, false, false, false };
|
|
public Boolean[] arMOT_HSet = new bool[] { false, false, false, false, false, false, false };
|
|
public Boolean[] arMOT_SVOn = new bool[] { false, false, false, false, false, false, false };
|
|
|
|
public Boolean arFlag_Minspace { get; set; }
|
|
|
|
public byte arUnloaderSeq { get; set; }
|
|
public Boolean arFlag_UnloaderBusy { get; set; }
|
|
public Boolean arFlag_UnloaderErr { get; set; }
|
|
public Boolean arConn_REM { get; set; }
|
|
|
|
|
|
public Boolean arFG_RDY_YP_FPICKON { get; set; }
|
|
public Boolean arFG_RDY_YP_FPICKOF { get; set; }
|
|
public Boolean arFG_RDY_YP_RPICKON { get; set; }
|
|
public Boolean arFG_RDY_YP_RPICKOF { get; set; }
|
|
|
|
public Boolean arFG_CMD_YP_FPICKON { get; set; }
|
|
//public Boolean arFG_CMD_YP_FPICKOF { get; set; }
|
|
public Boolean arFG_CMD_YP_RPICKON { get; set; }
|
|
//public Boolean arFG_CMD_YP_RPICKOF { get; set; }
|
|
|
|
|
|
|
|
|
|
//비상정지 센서 상태
|
|
public Boolean arDI_Emergency { get; set; }
|
|
|
|
public Boolean arDIAir { get; set; }
|
|
|
|
public Boolean arConn_MOT { get; set; }
|
|
public Boolean arConn_DIO { get; set; }
|
|
public Boolean arAIRDetect { get; set; }
|
|
public Boolean arConn_BCD { get; set; }
|
|
public Boolean arConn_PLC { get; set; }
|
|
|
|
public int arLastDetectIndex { get; set; }
|
|
|
|
|
|
public Boolean arDebugMode { get { return _ardebugmode; } set { this._ardebugmode = value; Invalidate(); } }
|
|
|
|
public CPort[] arVar_Port { get; set; }
|
|
public CPicker[] arVar_Picker { get; set; }
|
|
|
|
public Boolean arConvRun { get; set; }
|
|
|
|
|
|
public Boolean arIsRunning { get; set; }
|
|
|
|
|
|
private List<CItem> zitem = new List<CItem>();
|
|
public long[] zonetime = new long[11];
|
|
|
|
public Font arFont_count { get; set; }
|
|
public Font arFont_picker { get; set; }
|
|
|
|
public double arMotorLengthY { get; set; }
|
|
public double arMotorLengthZL { get; set; }
|
|
public double arMotorLengthZR { get; set; }
|
|
|
|
private double[] _armotpos = new double[] { 0, 0, 0, 0, 0, 0, 0 };
|
|
public double[] arMotorPosition { get { return _armotpos; } set { _armotpos = value; } }
|
|
private double[] _arhomepgoress = new double[] { 0, 0, 0, 0, 0, 0, 0 };
|
|
public double[] arHomeProgress { get { return _arhomepgoress; } set { _arhomepgoress = value; } }
|
|
|
|
private CMenu[] _menus = null;
|
|
public CMenu[] arMenus { get { return _menus; } set { _menus = value; this.Invalidate(); } }
|
|
|
|
#endregion
|
|
|
|
public Boolean PickerSafezone = false;
|
|
public HMI()
|
|
{
|
|
// Set Optimized Double Buffer to reduce flickering
|
|
this.SetStyle(ControlStyles.UserPaint, true);
|
|
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
|
|
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
|
|
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
|
|
this.SetStyle(ControlStyles.ContainerControl, false);
|
|
this.SetStyle(ControlStyles.Selectable, true);
|
|
|
|
// Redraw when resized
|
|
this.SetStyle(ControlStyles.ResizeRedraw, true);
|
|
|
|
this.Resize += Loader_Resize;
|
|
|
|
sfCenter = new StringFormat();
|
|
sfCenter.Alignment = StringAlignment.Center;
|
|
sfCenter.LineAlignment = StringAlignment.Center;
|
|
|
|
|
|
tm = new Timer();
|
|
tm.Interval = 50; //10frame;
|
|
tm.Tick += Tm_Tick;
|
|
|
|
arLastDetectIndex = -1;
|
|
arFont_PortMessage = new Font("Consolas", 11, FontStyle.Bold);
|
|
arFont_picker = new Font("Arial", 10, FontStyle.Bold);
|
|
arFont_MotPosName = new Font("Consolas", 10, FontStyle.Bold);
|
|
|
|
arUnloaderSeq = 0;
|
|
arMotorLengthY = 400;
|
|
arMotorLengthZL = 580;
|
|
arMotorLengthZR = 590;
|
|
|
|
arDI_Cv_Detect = new bool[8];
|
|
for (int i = 0; i < arDI_Cv_Detect.Length; i++)
|
|
arDI_Cv_Detect[i] = false;
|
|
|
|
bool designMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
|
|
if (designMode == false) tm.Start();
|
|
|
|
arFont_count = new Font("Consolas", 30, FontStyle.Bold);
|
|
|
|
//기본수량설정됨
|
|
arVar_Port = new CPort[3];
|
|
arVar_Picker = new CPicker[1];
|
|
|
|
for (int i = 0; i < rect_zone.Length; i++)
|
|
rect_zone[i] = RectangleF.Empty;
|
|
|
|
for (int i = 0; i < zonetime.Length; i++)
|
|
zonetime[i] = 0;
|
|
|
|
//미리 10개를 생성한다. 슬롯에 10개이상 생기기 않는다.
|
|
zitem = new List<CItem>(10);
|
|
for (int i = 0; i < zitem.Count; i++)
|
|
zitem[i] = new CItem();
|
|
}
|
|
|
|
|
|
public void ClearMessage()
|
|
{
|
|
|
|
}
|
|
|
|
private List<string> lkitemsF = new List<string>();
|
|
private List<string> lkitemsR = new List<string>();
|
|
|
|
|
|
|
|
#region "Common Data & Device"
|
|
|
|
DateTime UpdateTime = DateTime.Now.AddSeconds(-1);
|
|
|
|
//public void SetFLAG(arUtil.IInterLock dio_)
|
|
//{
|
|
// this.flag = dio_;
|
|
// this.flag.ValueChanged += Flag_ValueChanged;
|
|
//}
|
|
public void SetDIO(arDev.DIO.IDIO dio_)
|
|
{
|
|
this.dio = dio_;
|
|
this.dio.IOValueChanged += Dio_IOValueChanged;
|
|
}
|
|
public void SetMOT(arDev.MOT.IMotion dio_)
|
|
{
|
|
this.mot = dio_;
|
|
this.mot.HomeStatusChanged += Mot_HomeStatusChanged;
|
|
this.mot.PositionChanged += Mot_PositionChanged;
|
|
this.mot.StatusChanged += Mot_StatusChanged;
|
|
}
|
|
private void Dio_IOValueChanged(object sender, arDev.DIO.IOValueEventArgs e)
|
|
{
|
|
var ts = DateTime.Now - UpdateTime;
|
|
if (ts.TotalMilliseconds < 500) return;
|
|
else UpdateTime = DateTime.Now;
|
|
this.Invalidate();
|
|
}
|
|
|
|
private void Mot_StatusChanged(object sender, arDev.MOT.StatusChangeEventArags e)
|
|
{
|
|
var ts = DateTime.Now - UpdateTime;
|
|
if (ts.TotalMilliseconds < 500) return;
|
|
else UpdateTime = DateTime.Now;
|
|
this.Invalidate();
|
|
}
|
|
|
|
private void Mot_PositionChanged(object sender, arDev.MOT.PositionChangeEventArgs e)
|
|
{
|
|
var ts = DateTime.Now - UpdateTime;
|
|
if (ts.TotalMilliseconds < 500) return;
|
|
else UpdateTime = DateTime.Now;
|
|
this.Invalidate();
|
|
}
|
|
|
|
private void Mot_HomeStatusChanged(object sender, arDev.MOT.HomeStatusChangeEventArgs e)
|
|
{
|
|
var ts = DateTime.Now - UpdateTime;
|
|
if (ts.TotalMilliseconds < 500) return;
|
|
else UpdateTime = DateTime.Now;
|
|
this.Invalidate();
|
|
}
|
|
|
|
//private void Flag_ValueChanged(object sender, arUtil.InterfaceValueEventArgs e)
|
|
//{
|
|
// var ts = DateTime.Now - UpdateTime;
|
|
// if (ts.TotalMilliseconds < 500) return;
|
|
// else UpdateTime = DateTime.Now;
|
|
// this.Invalidate();
|
|
//}
|
|
|
|
public Boolean MotionHome { get; set; }
|
|
|
|
bool GetBOOL(eVarBool idx)
|
|
{
|
|
return VAR.BOOL?[(int)idx] ?? false;
|
|
}
|
|
string GetSTR(eVarString idx)
|
|
{
|
|
return VAR.STR?[(int)idx] ?? string.Empty;
|
|
}
|
|
|
|
bool GetDOValue(eDOName pin)
|
|
{
|
|
return dio?.GetDOValue((int)pin) ?? false;
|
|
}
|
|
bool GetDIValue(eDIName pin)
|
|
{
|
|
return dio?.GetDIValue((int)pin) ?? false;
|
|
}
|
|
|
|
#endregion
|
|
|
|
public void ClearLockItem(int idx)
|
|
{
|
|
if (idx == 0)
|
|
{
|
|
lock (lkitemsF)
|
|
lkitemsF.Clear();
|
|
}
|
|
else
|
|
{
|
|
lock (lkitemsR)
|
|
lkitemsR.Clear();
|
|
}
|
|
}
|
|
public void AddLockItem(int idx, params string[] values)
|
|
{
|
|
if (idx == 0)
|
|
{
|
|
lock (lkitemsF)
|
|
{
|
|
foreach (var value in values)
|
|
{
|
|
if (lkitemsF.Contains(value) == false)
|
|
lkitemsF.Add(value);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lock (lkitemsR)
|
|
{
|
|
foreach (var value in values)
|
|
{
|
|
if (lkitemsR.Contains(value) == false)
|
|
lkitemsR.Add(value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
public void RemoveLockItem(int idx, params string[] values)
|
|
{
|
|
if (idx == 0)
|
|
{
|
|
lock (lkitemsF)
|
|
{
|
|
foreach (var value in values)
|
|
{
|
|
if (lkitemsF.Contains(value) == true)
|
|
lkitemsF.Remove(value);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lock (lkitemsR)
|
|
{
|
|
foreach (var value in values)
|
|
{
|
|
if (lkitemsR.Contains(value) == true)
|
|
lkitemsR.Remove(value);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
protected override void OnMouseMove(MouseEventArgs e)
|
|
{
|
|
base.OnMouseMove(e);
|
|
//if (this.icons == null || icons.Length < 1) return;
|
|
|
|
//var item = this.icons.Where(t => t.Rect.Contains(e.Location)).FirstOrDefault();
|
|
|
|
////선택된 것이 잇다면 모두 해제를 해준다.
|
|
//icons.Where(t => t.Focus == true).ToList().ForEach(t => t.Focus = false);
|
|
|
|
|
|
//if (item != null)
|
|
//{
|
|
// item.Focus = true;
|
|
// this.Cursor = Cursors.Hand;
|
|
//}
|
|
//else
|
|
//{
|
|
// this.Cursor = Cursors.Arrow;
|
|
//}
|
|
}
|
|
|
|
public class ZoneItemClickEventargs : EventArgs
|
|
{
|
|
public CItem item { get; private set; }
|
|
public ZoneItemClickEventargs(CItem item_)
|
|
{
|
|
this.item = item_;
|
|
}
|
|
}
|
|
public class IconClickEventargs : EventArgs
|
|
{
|
|
public CIcon item { get; private set; }
|
|
public IconClickEventargs(CIcon item_)
|
|
{
|
|
this.item = item_;
|
|
}
|
|
}
|
|
public class MenuItemClickEventargs : EventArgs
|
|
{
|
|
public CMenuButton item { get; private set; }
|
|
public MenuItemClickEventargs(CMenuButton item_)
|
|
{
|
|
this.item = item_;
|
|
}
|
|
}
|
|
public event EventHandler<MenuItemClickEventargs> ButtonClick;
|
|
public event EventHandler<IconClickEventargs> IConClick;
|
|
public event EventHandler<ZoneItemClickEventargs> ZoneItemClick;
|
|
protected override void OnMouseClick(MouseEventArgs e)
|
|
{
|
|
base.OnMouseClick(e);
|
|
|
|
if (e.Button == MouseButtons.Left)
|
|
{
|
|
//var item = this.icons.Where(t => t.Rect.Contains(e.Location)).FirstOrDefault();
|
|
//if (item != null)
|
|
//{
|
|
// //다른 메뉴가 선택되어잇다면 동작하지 않게 한다.
|
|
// if (IConClick != null)
|
|
// IConClick(this, new IconClickEventargs(item));
|
|
//}
|
|
|
|
var zitem = this.zitem.Where(t => t.Rect.Contains(e.Location)).FirstOrDefault();
|
|
if (zitem != null)
|
|
{
|
|
//특정 존의 아이템을 선택했다
|
|
if (ZoneItemClick != null)
|
|
ZoneItemClick(this, new ZoneItemClickEventargs(zitem));
|
|
|
|
}
|
|
|
|
//메뉴의해 생성된 버튼
|
|
var zbbut = this.menuButtons.Where(t => t.Rect.Contains(e.Location)).FirstOrDefault();
|
|
if (zbbut != null)
|
|
{
|
|
//특정 존의 아이템을 선택했다
|
|
if (ButtonClick != null)
|
|
ButtonClick(this, new MenuItemClickEventargs(zbbut));
|
|
|
|
}
|
|
|
|
//아이콘
|
|
var zbut = this.Buttons.Where(t => t.Rect.Contains(e.Location)).FirstOrDefault();
|
|
if (zbut != null)
|
|
{
|
|
//특정 존의 아이템을 선택했다
|
|
if (ButtonClick != null)
|
|
ButtonClick(this, new MenuItemClickEventargs(zbut));
|
|
}
|
|
|
|
}
|
|
}
|
|
void Loader_Resize(object sender, EventArgs e)
|
|
{
|
|
bRemakeRect = true;
|
|
}
|
|
|
|
|
|
public void RemakeRect()
|
|
{
|
|
bRemakeRect = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 각 영역을 현재 크기대비하여 재계산 한다
|
|
/// </summary>
|
|
void makeRect_Normal()
|
|
{
|
|
|
|
rect_main = new RectangleF(
|
|
DisplayRectangle.Left + Padding.Left,
|
|
DisplayRectangle.Top + Padding.Top,
|
|
DisplayRectangle.Width - Padding.Left - Padding.Right,
|
|
DisplayRectangle.Height - Padding.Top - Padding.Bottom);
|
|
|
|
//X축 모션(셔틀) 표시
|
|
var xPos1 = rect_main.Left + (rect_main.Width * 0.175);
|
|
var xPos2 = rect_main.Right - xPos1;
|
|
var yposR = rect_main.Height * 0.15;
|
|
var yposF = rect_main.Height * 0.85;
|
|
var h0p5 = rect_main.Height * 0.03;
|
|
var w0p5 = (rect_main.Width * 0.035) * ((rect_main.Height * 1.0) / rect_main.Width);
|
|
|
|
//var conv_height = rect_main.Height * 0.3;
|
|
|
|
var cx = (float)(rect_main.Top + (rect_main.Width / 2.0));
|
|
var cy = (float)(rect_main.Top + (rect_main.Height / 2.0));
|
|
|
|
|
|
var conv_height = CvtMMtoPX_H(350, 0); //컨베이어 높이
|
|
var conv_width = CvtMMtoPX_W(arMcLengthW, 0); //컨베어이어너비는 장비 너비와 같다
|
|
|
|
rect_conveyor = new RectangleF(rect_main.Left,
|
|
(float)(rect_main.Top + (rect_main.Height - conv_height) / 2.0f),
|
|
(float)conv_width,
|
|
(float)conv_height);
|
|
|
|
var h10p = rect_main.Height * 0.03;
|
|
|
|
|
|
//프론트셔틀의 영역(가동 영역) - 아래서 450mm 떨어진곳
|
|
var xAxisLengthMM = arMcLengthW - 200; // 컨베어 길이에서 좌우 100mm 씩 리밋센서가 있다
|
|
var xAxisLengthPX = CvtMMtoPX_W(xAxisLengthMM, rect_conveyor.Left);
|
|
//rect_frontShuttle = new RectangleF(
|
|
// (float)(CvtMMtoPX_W(100, rect_conveyor.Left)),
|
|
// (float)(CvtMMtoPX_H(100, rect_main.Top)),
|
|
// (float)xAxisLengthPX,
|
|
// (float)(CvtMMtoPX_H(20, 0)));
|
|
|
|
|
|
//세로축 총길이 1400mm Y축 모터는 양끝에 100mm 의 여유가 있으며, Y축
|
|
|
|
var pickWidth = rect_main.Width * 0.6f;
|
|
var pickerX = rect_main.Width / 2.0f;// CvtMMtoPX_W(750, rect_conveyor.Left);
|
|
|
|
var YAxisLenWMM = arMcLengthW - 100 * 2;
|
|
var YAxisLenHMM = 100;//
|
|
var yAxisLenWPx = CvtMMtoPX_W(YAxisLenWMM, 0); //너비
|
|
var yAxisLenHPx = CvtMMtoPX_H(YAxisLenHMM, 0); //길이
|
|
var yAxisX = CvtMMtoPX_W(100, rect_main.Left);
|
|
var yAxisY = CvtMMtoPX_H(200, rect_main.Top);
|
|
|
|
rect_picker = new RectangleF(
|
|
(float)(yAxisX),
|
|
(float)(yAxisY),
|
|
(float)(yAxisLenWPx),
|
|
(float)(yAxisLenHPx)
|
|
);
|
|
|
|
rect_printl = new RectangleF(rect_main.Left + 30, rect_picker.Bottom + 30, 30, rect_main.Height * 0.25f);
|
|
rect_printr = new RectangleF(rect_main.Right - rect_printl.Width - rect_printl.Left, rect_printl.Top, rect_printl.Width, rect_printl.Height);
|
|
|
|
|
|
//Y축 피커 관련 세부 영역 설정 (VAC 와 원)
|
|
|
|
//전체영역의 80% 영역에 Y-로봇의 축을 그린다.
|
|
//var motorMax = 400; //전체 가동 길이 400mm
|
|
RectangleF rect = rect_picker;
|
|
var MotPosPx = rect.Left + rect.Width * (this.arMotorPosition[0] / (this.arMotorLengthY * 1.0f));
|
|
cx = rect.Left + rect.Width / 2.0f;
|
|
|
|
//상(Rear), 하(Front)로 영역을 그린다
|
|
var port_height = rect.Height * 0.25f;
|
|
var port_width = port_height;
|
|
//;// var port_width = rect.Width * 3f;
|
|
//port_width = port_height;
|
|
var port_space = CvtMMtoPX_H(350 / 2.0f, 0);
|
|
var port_spacex = CvtMMtoPX_W(10, 0); ;
|
|
|
|
var PickerSizeW = CvtMMtoPX_W(200, 0);// (float)(Math.Max(CvtMMtoPX_W(150, 0), CvtMMtoPX_H(15, 0)));
|
|
var PickerSizeH = PickerSizeW;// CvtMMtoPX_H(130, 0);//(float)(Math.Max(CvtMMtoPX_W(150, 0), CvtMMtoPX_H(15, 0)));
|
|
var PickerSpaceW = CvtMMtoPX_H(100, 0);
|
|
|
|
|
|
rect_picker_left = new RectangleF(
|
|
(float)(MotPosPx - PickerSpaceW),
|
|
(float)(rect.Top + 50),
|
|
(float)PickerSizeW,
|
|
(float)PickerSizeH);
|
|
|
|
|
|
var pointoffset = 5;
|
|
|
|
|
|
//진공표시영역
|
|
rect_picker_front_vac1 = new RectangleF(
|
|
(float)rect_picker_left.Left + pointoffset,
|
|
(float)rect_picker_left.Top + pointoffset,
|
|
(float)rect_picker_left.Width * 0.2f,
|
|
(float)rect_picker_left.Height * 0.2f);
|
|
rect_picker_front_vac2 = new RectangleF(
|
|
(float)rect_picker_left.Right - rect_picker_front_vac1.Width - pointoffset,
|
|
(float)rect_picker_front_vac1.Top,
|
|
(float)rect_picker_front_vac1.Width,
|
|
(float)rect_picker_front_vac1.Height);
|
|
rect_picker_front_vac3 = new RectangleF(
|
|
(float)rect_picker_left.Left + pointoffset,
|
|
(float)rect_picker_left.Bottom - rect_picker_front_vac1.Height - pointoffset,
|
|
(float)rect_picker_front_vac1.Width,
|
|
(float)rect_picker_front_vac1.Height);
|
|
rect_picker_front_vac4 = new RectangleF(
|
|
(float)rect_picker_left.Right - rect_picker_front_vac1.Width - pointoffset,
|
|
(float)rect_picker_left.Bottom - rect_picker_front_vac1.Height - pointoffset,
|
|
(float)rect_picker_front_vac1.Width,
|
|
(float)rect_picker_front_vac1.Height);
|
|
|
|
|
|
//각 존의 영역 확인
|
|
|
|
//컨베어의 릴감지센서 위치를 표시한다
|
|
var senseW = rect_conveyor.Width * 0.02f;
|
|
var senseH = rect_conveyor.Height * 0.05f;
|
|
var slist = new double[] { 20, 340, 550, 890, 1110, 1440 };// new double[] { 0.02, 0.25, 0.4, 0.6, 0.75, 0.9 }; //센서의 위치정보(컨베어좌측기준)
|
|
|
|
|
|
|
|
//센서가 포함된 존의 영역을 생성한다
|
|
for (int i = 0; i < slist.Length; i++)
|
|
{
|
|
//선으로 영역을 표시해준다.
|
|
var PosMM = rect_conveyor.Width * (slist[i] / arMcLengthW);
|
|
var x = (float)(rect_conveyor.Left + PosMM);
|
|
var rx = x - senseW / 2.0f;
|
|
rect_zone[i * 2] = new RectangleF(rx, rect_conveyor.Top, senseW, rect_conveyor.Height);
|
|
}
|
|
|
|
var arraylis = new int[] { 1, 3, 5, 7, 9 };
|
|
var zterm = 4;
|
|
for (int i = 0; i < arraylis.Length; i++)
|
|
{
|
|
var idx = arraylis[i];
|
|
rect_zone[idx] = new RectangleF(
|
|
rect_zone[idx - 1].Right + zterm,
|
|
rect_zone[idx - 1].Top,
|
|
rect_zone[idx + 1].Left - rect_zone[idx - 1].Right - zterm * 2,
|
|
rect_zone[idx - 1].Height);
|
|
}
|
|
|
|
//입출력포트의 영역을 다시 계산한다
|
|
var portW = (int)(rect_main.Width * 0.175f);
|
|
var portH = (int)(rect_main.Height * 0.25f);
|
|
var portPad = (int)(rect_main.Width / 7f);
|
|
var MarginX = (int)((rect_main.Width - portW * 3 - portPad * 2) / 2.0);
|
|
var MarginY = (int)(rect_main.Height - portH - (portPad / 2f));
|
|
|
|
for (int i = 0; i < arVar_Port.Length; i++)
|
|
{
|
|
arVar_Port[i].Rect = new Rectangle(
|
|
(int)rect_main.Left + MarginX + (i * portW) + (i * portPad),
|
|
(int)rect_main.Top + MarginY,
|
|
portW, portH);
|
|
zitem.Add(new CItem
|
|
{
|
|
Rect = arVar_Port[i].Rect.toRect(),
|
|
index = i,
|
|
Tag = $"PORT{i}",
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
void makeRect_xmove()
|
|
{
|
|
rect_main = new RectangleF(
|
|
DisplayRectangle.Left + DisplayRectangle.Width * 0.05f,
|
|
DisplayRectangle.Top + DisplayRectangle.Height * 0.05f,
|
|
DisplayRectangle.Width * 0.9f,
|
|
DisplayRectangle.Height * 0.9f);
|
|
|
|
//화면에 꽉차도록 전체 영역을 할당한다.
|
|
var cx = rect_main.Left + rect_main.Width / 2.0f;
|
|
var cy = rect_main.Top + rect_main.Height / 2.0f;
|
|
|
|
var padding = (int)(rect_main.Width * 0.03);
|
|
|
|
var width = (int)((cx - rect_main.Left) - padding * 2);
|
|
var height = (int)((cy - rect_main.Top) - padding * 2);
|
|
arVar_Port[0].Rect = new Rectangle(
|
|
(int)rect_main.Left + padding,
|
|
(int)cy + padding,
|
|
width, height);
|
|
|
|
arVar_Port[1].Rect = new Rectangle(
|
|
(int)cx + padding,
|
|
(int)cy + padding,
|
|
width, height);
|
|
|
|
|
|
arVar_Port[2].Rect = new Rectangle(
|
|
(int)(rect_main.Left + (rect_main.Width - width) / 2f),
|
|
(int)rect_main.Top + padding,
|
|
width, height);
|
|
|
|
}
|
|
void makeRect_MotHome()
|
|
{
|
|
rect_main = new RectangleF(
|
|
DisplayRectangle.Left + DisplayRectangle.Width * 0.05f,
|
|
DisplayRectangle.Top + DisplayRectangle.Height * 0.05f,
|
|
DisplayRectangle.Width * 0.9f,
|
|
DisplayRectangle.Height * 0.9f);
|
|
}
|
|
|
|
double CvtMMtoPX_W(double PosMM, double startPos)
|
|
{
|
|
//컨베어 기준으로 값을 반환한ㄷ.
|
|
return startPos + rect_main.Width * (PosMM / arMcLengthW);
|
|
}
|
|
double CvtMMtoPX_H(double PosMM, double startPos)
|
|
{
|
|
//컨베어 기준으로 값을 반환한ㄷ.
|
|
return startPos + rect_main.Height * (PosMM / arMcLengthH);
|
|
}
|
|
|
|
#region "Menu Method"
|
|
public void ClearMenu()
|
|
{
|
|
_menus = null;
|
|
this.Invalidate();
|
|
}
|
|
public void AddMenu(CMenu menu)
|
|
{
|
|
var curCnt = 0;
|
|
if (this._menus != null) curCnt = this._menus.Length;
|
|
Array.Resize(ref _menus, curCnt + 1);
|
|
_menus[curCnt] = menu;
|
|
this.Invalidate();
|
|
}
|
|
|
|
public void DelMenu(CMenu menu)
|
|
{
|
|
List<CMenu> newlist = new List<CMenu>();
|
|
for (int i = 0; i < _menus.Length; i++)
|
|
{
|
|
if (_menus[i] != menu) newlist.Add(_menus[i]);
|
|
}
|
|
this._menus = newlist.ToArray();
|
|
this.Invalidate();
|
|
}
|
|
|
|
public void DelMenu(int idx)
|
|
{
|
|
List<CMenu> newlist = new List<CMenu>();
|
|
for (int i = 0; i < _menus.Length; i++)
|
|
{
|
|
if (i != idx) newlist.Add(_menus[i]);
|
|
}
|
|
this._menus = newlist.ToArray();
|
|
this.Invalidate();
|
|
}
|
|
public void DelMenu()
|
|
{
|
|
//제거할 아이템이 없다
|
|
if (_menus == null || _menus.Length < 1) return;
|
|
|
|
if (_menus.Length == 1) _menus = null;
|
|
else
|
|
{
|
|
//마지막요소를 제거 해주낟
|
|
Array.Resize(ref _menus, _menus.Length - 1);
|
|
|
|
}
|
|
|
|
this.Invalidate();
|
|
}
|
|
#endregion
|
|
|
|
protected override void OnPaint(PaintEventArgs e)
|
|
{
|
|
e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
|
|
e.Graphics.InterpolationMode = InterpolationMode.High;
|
|
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
|
|
|
base.OnPaint(e);
|
|
|
|
if (bRemakeRect)
|
|
{
|
|
this.zitem.Clear();
|
|
if (Scean == eScean.Nomal) makeRect_Normal();
|
|
else if (Scean == eScean.MotHome) makeRect_MotHome();
|
|
else if (Scean == eScean.xmove) makeRect_xmove();
|
|
bRemakeRect = false;
|
|
}
|
|
|
|
if (this.Scean == eScean.Nomal) Scean_Normal(e.Graphics);
|
|
else if (this.Scean == eScean.MotHome) Scean_MotHome(e.Graphics);
|
|
else if (this.Scean == eScean.xmove) Scean_XMove(e.Graphics);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Z축이 아이템을 내려놓은 시간(연속으로 놓는 증상이 발생하여, 일단 이것으로 2초이상 빠르게 놓는일이 없도록 한다)
|
|
/// </summary>
|
|
public DateTime LastDropTime = DateTime.Now;
|
|
|
|
|
|
void RaiseMessage(string m, Boolean iserr, params object[] args)
|
|
{
|
|
if (args != null && args.Length > 0) m = string.Format(m, args);
|
|
if (Message != null) Message(this, new MessageArgs(m, iserr));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 아이템을 DROP해도 되는가? 존 3번 부터 아이템이 존재하면 drop 불가능으로 한다
|
|
/// </summary>
|
|
|
|
void Scean_XMove(Graphics g)
|
|
{
|
|
//g.DrawRect(arVar_Port[0].Rect, Color.White, 3);
|
|
Pen p = new Pen(Color.White, 5);
|
|
|
|
var pts = new List<PointF>();
|
|
pts.Add(new PointF(arVar_Port[0].Rect.Right, arVar_Port[0].Rect.Top));
|
|
pts.Add(new PointF(arVar_Port[0].Rect.Left, arVar_Port[0].Rect.Bottom - arVar_Port[0].Rect.Height / 2f));
|
|
pts.Add(new PointF(arVar_Port[0].Rect.Right, arVar_Port[0].Rect.Bottom));
|
|
g.FillPolygon(Brushes.Blue, pts.ToArray());
|
|
g.DrawPolygon(p, pts.ToArray());
|
|
g.DrawString("[START]\nLEFT", this.Font, Brushes.Gold, arVar_Port[0].Rect, new StringFormat { Alignment = StringAlignment.Far, LineAlignment = StringAlignment.Center });
|
|
|
|
pts.Clear();
|
|
pts.Add(new PointF(arVar_Port[1].Rect.Left, arVar_Port[1].Rect.Top));
|
|
pts.Add(new PointF(arVar_Port[1].Rect.Right, arVar_Port[1].Rect.Bottom - arVar_Port[1].Rect.Height / 2f));
|
|
pts.Add(new PointF(arVar_Port[1].Rect.Left, arVar_Port[1].Rect.Bottom));
|
|
g.FillPolygon(Brushes.Brown, pts.ToArray());
|
|
g.DrawPolygon(p, pts.ToArray());
|
|
g.DrawString("[STOP]\nRIGHT", this.Font, Brushes.Gold, arVar_Port[1].Rect, new StringFormat { Alignment = StringAlignment.Near, LineAlignment = StringAlignment.Center });
|
|
|
|
if (arPickerSafeZone)
|
|
g.FillEllipse(Brushes.Lime, arVar_Port[2].Rect);
|
|
else
|
|
g.FillEllipse(Brushes.Tomato, arVar_Port[2].Rect);
|
|
g.DrawEllipse(new Pen(Color.White, 3), arVar_Port[2].Rect);
|
|
g.DrawString("PICKER\nSAFTY\n" + (arPickerSafeZone ? "ON" : "OFF"), this.Font, Brushes.Black, arVar_Port[2].Rect, new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
|
|
|
|
|
|
//중앙에 메세지를 표시한다.
|
|
var cpad = rect_main.Width * 0.1f;
|
|
var cheigh = rect_main.Height * 0.20f;
|
|
var crect = new RectangleF(rect_main.Left + cpad, rect_main.Top + (rect_main.Height - cheigh) / 2f, rect_main.Width - cpad * 2f, cheigh);
|
|
g.FillRectangle(new SolidBrush(Color.FromArgb(20, 20, 20)), crect);
|
|
|
|
if (arPickerSafeZone)
|
|
g.DrawString("홈 검색이 가능합니다", new Font("맑은 고딕", 20, FontStyle.Bold), Brushes.Lime, crect, new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
|
|
else
|
|
{
|
|
if (MessageOn)
|
|
g.DrawString("피커를 움직여 안전위치로 이동하세요", new Font("맑은 고딕", 12, FontStyle.Bold), Brushes.Red, crect, new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
|
|
else
|
|
g.DrawString("피커를 움직여 안전위치로 이동하세요", new Font("맑은 고딕", 12, FontStyle.Bold), Brushes.White, crect, new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
|
|
}
|
|
|
|
g.DrawRect(crect, Color.White, 5);
|
|
p.Dispose();
|
|
var ts = DateTime.Now - ScreenUpdateTime;
|
|
if (ts.TotalMilliseconds >= 200)
|
|
{
|
|
MessageOn = !MessageOn;
|
|
ScreenUpdateTime = DateTime.Now;
|
|
}
|
|
|
|
}
|
|
|
|
DateTime ScreenUpdateTime = DateTime.Now;
|
|
Boolean MessageOn = false;
|
|
|
|
|
|
void Scean_MotHome(Graphics g)
|
|
{
|
|
//g.DrawString("mot home", this.Font, Brushes.Black, 100, 100);
|
|
g.DrawRectangle(new Pen(Color.SteelBlue, 10), this.rect_main.Left, rect_main.Top, rect_main.Width, rect_main.Height);
|
|
Font f = new Font(this.Font.Name, 20f, FontStyle.Bold);
|
|
|
|
var titleSize = g.MeasureString("HOME", f);
|
|
|
|
var rectTitle = new RectangleF(
|
|
rect_main.Left,
|
|
rect_main.Top + 10,
|
|
rect_main.Width,
|
|
titleSize.Height * 1.2f);
|
|
|
|
g.DrawString("MOTION HOME", f, Brushes.White, rectTitle, sfCenter); ;
|
|
// g.DrawRectangle(Pens.Red, rectTitle.Left, rectTitle.Top, rectTitle.Width, rectTitle.Height);
|
|
|
|
var rectBody = new RectangleF(
|
|
rect_main.Left + 10,
|
|
rectTitle.Bottom + 10,
|
|
rect_main.Width - 20,
|
|
rect_main.Height - rectTitle.Height - 10 - 20);
|
|
|
|
//g.DrawRectangle(Pens.White, rectBody.Left, rectBody.Top, rectBody.Width, rectBody.Height);
|
|
|
|
|
|
|
|
var rectT = new Rectangle(
|
|
(int)(rectBody.Left + 20),
|
|
(int)(rectBody.Top + 30),
|
|
(int)(rectBody.Width * 0.3f),
|
|
(int)(rectBody.Height * 0.07));
|
|
|
|
var rectXF = new Rectangle(
|
|
(int)(rectT.Right + 20),
|
|
(int)(rectBody.Top + 30),
|
|
(int)(rectBody.Width - rectT.Width - rectT.Left - 10),
|
|
(int)(rectBody.Height * 0.07));
|
|
|
|
//g.DrawRect(rectT, Color.White, 1);
|
|
//g.DrawRect(rectXF, Color.Red, 1);
|
|
|
|
|
|
var titles = new string[] { "[0] PICKER-Y", "[1] PICKER-Z", "[2] PRINTL-Y", "[3] PRINTL-Z", "[4] PRINTR-Y", "[5] PRINTR-Z", "[6] ANGLE" };
|
|
for (int i = 0; i < titles.Length; i++)
|
|
{
|
|
var perc = arHomeProgress[i];
|
|
var title = titles[i];
|
|
var offsetY = (rectBody.Height * 0.12f);
|
|
|
|
//0번은 처리하지 않음
|
|
if (i > 0)
|
|
{
|
|
rectXF.Offset(0, (int)offsetY);
|
|
rectT.Offset(0, (int)offsetY);
|
|
}
|
|
|
|
|
|
//g.DrawRectangle(Pens.Yellow, rectT.Left, rectT.Top, rectT.Width, rectT.Height);
|
|
|
|
using (Font f2 = new Font(this.Font.Name, 10f, FontStyle.Bold))
|
|
{
|
|
g.DrawString("* " + title, f2, Brushes.Lime, rectT, sfLeft);
|
|
}
|
|
|
|
LinearGradientBrush brProgr = new LinearGradientBrush(rectXF, Color.Gold, Color.Yellow, LinearGradientMode.Vertical);
|
|
var rectXF_P = new Rectangle(rectXF.Left, rectXF.Top, (int)(rectXF.Width * (perc / 100.0)), rectXF.Height);
|
|
g.FillRectangle(brProgr, rectXF_P);
|
|
g.DrawRectangle(Pens.Gray, rectXF);
|
|
brProgr.Dispose();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
f.Dispose();
|
|
|
|
}
|
|
|
|
void Scean_Normal(Graphics g)
|
|
{
|
|
|
|
|
|
//Draw_Icon(g);
|
|
|
|
//전체 영역 테두리
|
|
g.DrawRectangle(new Pen(Color.White, 2), rect_main.Left, rect_main.Top, rect_main.Width, rect_main.Height);
|
|
|
|
//컨베어 그리기
|
|
//Draw_Conveyor(g, rect_conveyor);
|
|
|
|
//셔틀표시
|
|
//Draw_BallScrewRail(g, rect_frontShuttle, 50, 5, false, true, this.arMOT_Origin[(int)eAxis.X_F], arMOT_LimDn[(int)eAxis.X_F], arMOT_LimUp[(int)eAxis.X_F]);
|
|
|
|
//포트표시(셔틀위에 표시됨)
|
|
Draw_Port(g); //front
|
|
Draw_Vision(g);
|
|
|
|
|
|
|
|
//프린터영역그리기 201228
|
|
var printareahei = 50;
|
|
var printareaw = 100;
|
|
var printbordersize = 5;
|
|
var rectpl = new RectangleF(arVar_Port[0].Rect.Right + printbordersize, arVar_Port[0].Rect.Top - 85, printareaw, printareahei);
|
|
var fColorPrn = arFGPrinter0END ? Color.Lime : (arFGPrinter0RDY ? Color.Gold : Color.Gray);
|
|
g.DrawRect(rectpl, fColorPrn, printbordersize);
|
|
var prnstrbase = "";// "인쇄수량:" + arCountPrint0.ToString("000") + "\n";
|
|
var prnstr = prnstrbase + (arFGPrinter0END ? "인쇄완료" : (arFGPrinter0RDY ? "인쇄중" : "인쇄대기"));
|
|
prnstr += "\n" + arCountPrint0.ToString("0000");
|
|
g.DrawString(prnstr, new Font("맑은 고딕", 10, FontStyle.Bold), new SolidBrush(fColorPrn), rectpl,
|
|
new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
|
|
//g.DrawString(string.Format("AIR:{0}\nVI:{1}\nVO:{2}", PrintLAIRO, PrintLVACI, PrintLVACO), new Font("Consolas", 11, FontStyle.Bold),
|
|
// Brushes.Tomato, rectpl.Left, rectpl.Top);
|
|
|
|
|
|
|
|
rectpl = new RectangleF(arVar_Port[2].Rect.Left - 90 - printbordersize, arVar_Port[2].Rect.Top - 85, printareaw, printareahei);
|
|
fColorPrn = arFGPrinter1END ? Color.Lime : (arFGPrinter1RDY ? Color.Gold : Color.Gray);
|
|
g.DrawRect(rectpl, fColorPrn, printbordersize);
|
|
prnstrbase = "";// "인쇄수량:" + arCountPrint1.ToString("000") + "\n";
|
|
prnstr = prnstrbase + (arFGPrinter1END ? "인쇄완료" : (arFGPrinter1RDY ? "인쇄중" : "인쇄대기"));
|
|
prnstr += "\n" + arCountPrint1.ToString("0000");
|
|
g.DrawString(prnstr, new Font("맑은 고딕", 10, FontStyle.Bold), new SolidBrush(fColorPrn), rectpl,
|
|
new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
|
|
//g.DrawString(string.Format("AIR:{0}\nVI:{1}\nVO:{2}", PrintRAIRO, PrintRVACI, PrintRVACO), new Font("Consolas", 11, FontStyle.Bold),
|
|
// Brushes.Tomato, rectpl.Left, rectpl.Top);
|
|
|
|
|
|
//Y축 레일표시
|
|
//Draw_BallScrewRail(g, rect_picker, 50, 5, true, LockYP, this.arMOT_Origin[(int)eAxis.Y_P], arMOT_LimDn[(int)eAxis.Y_P], arMOT_LimUp[(int)eAxis.Y_P]);
|
|
|
|
|
|
|
|
//모터 Y/Z축
|
|
Draw_PickerY(g, rect_picker);
|
|
|
|
|
|
//왼쪽 프린터
|
|
Draw_PickerPrinter(g, rect_printl, 2, 3, false, arMotILockPLM, arMotILockPLZ, arPLItemON, PrintLPICK, L_PICK_FW, L_PICK_BW);
|
|
|
|
//오른쪽 프린터
|
|
Draw_PickerPrinter(g, rect_printr, 4, 5, true, arMotILockPRM, arMotILockPRZ, arPRItemON, PrintRPICK, R_PICK_FW, R_PICK_BW);
|
|
|
|
//정보 표시 (나중에 제거해야함) 별도 인포박스형태를 취해야 함
|
|
Draw_Info(g, rect_conveyor);
|
|
Draw_Error(g);
|
|
|
|
//메뉴는 최상위에 표시한다
|
|
Draw_Menu(g);
|
|
|
|
//arDebugMode = true;
|
|
|
|
if (arDebugMode)
|
|
{
|
|
|
|
var sb = new System.Text.StringBuilder();
|
|
sb.AppendLine("Debug Message");
|
|
sb.AppendLine(string.Format("Display {0}", rect_main));
|
|
sb.AppendLine(string.Format("Mot Name : {0}/{1}/{2}/{3}/{4}/{5}", arMotPosNamePX, arMotPosNamePZ, arMotPosNameLM, arMotPosNameLZ, arMotPosNameRM, arMotPosNameRZ));
|
|
|
|
updatetime = DateTime.Now;
|
|
|
|
//작업 수량 및 전체수량을 표시함
|
|
var sb2 = new System.Text.StringBuilder();
|
|
if (arVar_Port != null && arVar_Port.Length > 0)
|
|
{
|
|
//sb2.AppendLine(string.Format("입(PICKER)/출(SS:DET1)/겹침(SS:DET1) : {0}/{1}/{2}",
|
|
// ar_cnt_in, ar_cnt_out, ar_cnt_outdup));
|
|
|
|
//sb2.AppendLine(string.Format("바코드 입/출:CMD/DUP/READ/ERR/중복수신/할당실패 {0}/{1}:{2}/{3}/{4}/{5}/{6}/{7}",
|
|
// ar_cnt_barcodein, ar_cnt_barcodeot, ar_cnt_barcodecmd, ar_cnt_barcodedup, ar_cnt_barcoderead, ar_cnt_barcodereaderr, ar_cnt_barcodereaddup, ar_cnt_barcodeAssignErr));
|
|
|
|
//sb2.AppendLine(string.Format("언로더 입/출:CMD/DUP {0}/{1}:{2}/{3}",
|
|
// ar_cnt_plcin, ar_cnt_plcot, ar_cnt_plccmd, ar_cnt_plcdup));
|
|
|
|
|
|
sb.AppendLine(string.Format("DIO:{4},BCD:{5},PLC:{6}\n" +
|
|
"YP_RDY {7},{8},{9},{10}\n" +
|
|
"YP_CMD {7},{8},{9},{10}\n",
|
|
arVar_Port[0].reelCount,
|
|
arVar_Port[1].reelCount,
|
|
arVar_Port[2].reelCount,
|
|
arConn_DIO,
|
|
arConn_BCD,
|
|
arConn_PLC,
|
|
arFG_RDY_YP_FPICKON, arFG_RDY_YP_FPICKOF, arFG_RDY_YP_RPICKON, arFG_RDY_YP_RPICKOF,
|
|
arFG_CMD_YP_FPICKON, arFG_CMD_YP_RPICKON));
|
|
|
|
}
|
|
|
|
var pad = 10;
|
|
using (Font f = new Font("맑은 고딕", 9))
|
|
{
|
|
var smgsize = g.MeasureString(sb.ToString(), f);
|
|
var dbgrect = new RectangleF(rect_main.Left + pad, rect_main.Top + pad, smgsize.Width + pad * 2f, smgsize.Height + pad * 2f);
|
|
|
|
//g.FillRectangle(new SolidBrush(Color.FromArgb(252, 0, 0, 0)), dbgrect);
|
|
//g.DrawString(sb.ToString(), f, Brushes.SkyBlue, dbgrect, new StringFormat { Alignment = StringAlignment.Near, LineAlignment = StringAlignment.Center });
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void Draw_Info(Graphics g, RectangleF rect)
|
|
{
|
|
|
|
//디자인 모드에서는 표시하지 않는다 200714
|
|
//if (DesignMode == true) return;
|
|
|
|
//if (this.arFlag_UnloaderBusy) ShowPopupMessage(g, "언로더 작업 대기 중\nBUSY", Properties.Resources.info);
|
|
//if (this.arIsRunning)
|
|
//{
|
|
// if (this.arFlag_UnloaderErr == true) ShowPopupMessage(g, "언로더 오류 발생", "STOP된 언로더를 확인하세요", Properties.Resources.error, false);
|
|
// else if (this.arFlag_WaitPLC && arUnloaderSeq > 0)
|
|
// {
|
|
// if (arUnloaderSeq == 1) ShowPopupMessage(g, "언로더 작업 대기 중", "상태확인(#1)", Properties.Resources.info, false);
|
|
// else if (arUnloaderSeq == 2) ShowPopupMessage(g, "언로더 작업 대기 중", "BUSY(#2)", Properties.Resources.info, false);
|
|
// else if (arUnloaderSeq == 3) ShowPopupMessage(g, "언로더 작업 대기 중", "ITEM CHECK(#3)", Properties.Resources.info, false);
|
|
// else if (arUnloaderSeq == 4) ShowPopupMessage(g, "언로더 작업 대기 중", "NO SETTING(#4)", Properties.Resources.info, false);
|
|
// else if (arUnloaderSeq == 5) ShowPopupMessage(g, "언로더 작업 대기 중", "SIZE SETTING(#5)", Properties.Resources.info, false);
|
|
// else if (arUnloaderSeq == 6) ShowPopupMessage(g, "언로더 작업 대기 중", "No.ZERO CHECK(#6)", Properties.Resources.info, false);
|
|
// }
|
|
//}
|
|
|
|
}
|
|
|
|
//void Draw_PickerRail(Graphics g, RectangleF rect)
|
|
//{
|
|
// RectangleF rectRailL = new RectangleF(rect.Left, rect.Top, rect.Width / 2.0f + 1, rect.Height);
|
|
// RectangleF rectRailR = new RectangleF(rect.Left + rect.Width / 2.0f, rect.Top, rect.Width / 2.0f, rect.Height);
|
|
// var brR = new LinearGradientBrush(rect, Color.FromArgb(60, 60, 60), Color.FromArgb(80, 80, 80), LinearGradientMode.Horizontal);
|
|
// var brL = new LinearGradientBrush(rect, Color.FromArgb(80, 80, 80), Color.FromArgb(60, 60, 60), LinearGradientMode.Horizontal);
|
|
// g.FillRectangle(brL, rectRailL);
|
|
// //g.FillRectangle(brR, rectRailR);
|
|
// brL.Dispose();
|
|
// brR.Dispose();
|
|
// g.DrawRectangle(Pens.DimGray, rect.Left, rect.Top, rect.Width, rect.Height);
|
|
|
|
//}
|
|
|
|
RectangleF rect_zlaxis = RectangleF.Empty;// new RectangleF((float)motZLPosX, (float)motZPosY, motZwPx, (float)motZhPx);
|
|
//RectangleF rect_zraxis = RectangleF.Empty;//new RectangleF((float)motZRPosX, (float)motZPosY, motZwPx, (float)motZhPx);
|
|
|
|
void Draw_Screw(Graphics g, Rectangle rect)
|
|
{
|
|
//모터표시(X축)
|
|
g.FillRectangle(new SolidBrush(Color.FromArgb(50, 150, 150, 150)), rect);
|
|
|
|
//해다 영역에 사선으로그림을 그린다.
|
|
var termcount = 50;
|
|
var lineterm = rect.Width / termcount;
|
|
var skew = rect.Width * 0.01f;
|
|
Pen p = new Pen(Color.FromArgb(50, 120, 120, 120), 2);
|
|
for (int i = 0; i < termcount; i++)
|
|
{
|
|
var pt1 = new PointF(rect.Left + i * lineterm, rect.Top);
|
|
var pt2 = new PointF(pt1.X + skew, rect.Bottom);
|
|
g.DrawLine(p, pt1, pt2);
|
|
}
|
|
p.Dispose();
|
|
//e.Graphics.DrawRectangle(Pens.Gray, motr_rect.Left, motr_rect.Top, motr_rect.Width, motr_rect.Height);
|
|
//e.Graphics.DrawRectangle(Pens.Gray, motf_rect.Left, motf_rect.Top, motf_rect.Width, motf_rect.Height);
|
|
|
|
|
|
//RectangleF rectRailT = new RectangleF(rect.Left, rect.Top, rect.Width, rect.Height / 2.0f + 1);
|
|
//RectangleF rectRailB = new RectangleF(rect.Left, rect.Top + rect.Height / 2.0f, rect.Width, rect.Height / 2.0f);
|
|
//var brR = new LinearGradientBrush(rect, Color.FromArgb(100, 60, 60, 60), Color.FromArgb(100, 80, 80, 80), LinearGradientMode.Vertical);
|
|
//var brL = new LinearGradientBrush(rect, Color.FromArgb(100, 80, 80, 80), Color.FromArgb(100, 60, 60, 60), LinearGradientMode.Vertical);
|
|
////g.FillRectangle(brL, rectRailT);
|
|
////g.FillRectangle(brR, rectRailB);
|
|
//brL.Dispose();
|
|
//brR.Dispose();
|
|
|
|
g.DrawRectangle(new Pen(Color.FromArgb(50, Color.Gray)), rect.Left, rect.Top, rect.Width, rect.Height);
|
|
|
|
|
|
}
|
|
|
|
void Draw_BallScrewRail(Graphics g, RectangleF rect, int divCount, int alpha, Boolean downDirection, Boolean MLock, Boolean Org, Boolean LimDn, Boolean LimUp)
|
|
{
|
|
//모터표시(X축)
|
|
if (Org) g.FillRectangle(new SolidBrush(Color.FromArgb(alpha, Color.SkyBlue)), rect);
|
|
else if (LimUp) g.FillRectangle(new SolidBrush(Color.FromArgb(alpha, Color.Red)), rect);
|
|
else if (LimDn) g.FillRectangle(new SolidBrush(Color.FromArgb(alpha, Color.Blue)), rect);
|
|
else g.FillRectangle(new SolidBrush(Color.FromArgb(alpha, 150, 150, 150)), rect);
|
|
|
|
//해다 영역에 사선으로그림을 그린다.
|
|
var baseSize = (downDirection == false ? rect.Width : rect.Height);
|
|
var lineterm = baseSize / divCount;
|
|
var skew = baseSize * 0.01f;
|
|
Pen p = new Pen(Color.FromArgb(alpha, 120, 120, 120), 2);
|
|
PointF pt1 = PointF.Empty;
|
|
PointF pt2 = PointF.Empty;
|
|
for (int i = 0; i < divCount; i++)
|
|
{
|
|
if (downDirection)
|
|
{
|
|
pt1 = new PointF(rect.Left, rect.Top + i * lineterm);
|
|
pt2 = new PointF(rect.Right, pt1.Y + skew);
|
|
}
|
|
else
|
|
{
|
|
pt1 = new PointF(rect.Left + i * lineterm, rect.Top);
|
|
pt2 = new PointF(pt1.X + skew, rect.Bottom);
|
|
}
|
|
g.DrawLine(p, pt1, pt2);
|
|
}
|
|
p.Dispose();
|
|
|
|
//limi이 걸려있다면 해당 영역에 적색으로 표시한다.
|
|
var limwidth = 30;
|
|
if (LimUp)
|
|
{
|
|
RectangleF rectlu;
|
|
if (downDirection) rectlu = new RectangleF(rect.Left, rect.Top, rect.Width, limwidth);
|
|
else rectlu = new RectangleF(rect.Right - limwidth, rect.Top, limwidth, rect.Height);
|
|
|
|
g.FillRectangle(Brushes.Red, rectlu.Left, rectlu.Top, rectlu.Width, rectlu.Height);
|
|
}
|
|
|
|
if (LimDn)
|
|
{
|
|
RectangleF rectlu;
|
|
if (downDirection) rectlu = new RectangleF(rect.Left, rect.Bottom - limwidth, rect.Width, limwidth);
|
|
else rectlu = new RectangleF(rect.Left, rect.Top, limwidth, rect.Height);
|
|
|
|
g.FillRectangle(Brushes.Red, rectlu.Left, rectlu.Top, rectlu.Width, rectlu.Height);
|
|
}
|
|
//전체 테두리
|
|
g.DrawRectangle(new Pen(Color.FromArgb(alpha, Color.Gray)), rect.Left, rect.Top, rect.Width, rect.Height);
|
|
}
|
|
|
|
Boolean NeedHomeSet()
|
|
{
|
|
return arConn_MOT && (this.arMOT_HSet[0] == false || this.arMOT_HSet[1] == false || this.arMOT_HSet[2] == false || this.arMOT_HSet[3] == false || this.arMOT_HSet[4] == false);
|
|
}
|
|
|
|
byte errstep = 0;
|
|
bool errstepR = true;
|
|
void Draw_Error(Graphics g)
|
|
{
|
|
//디자인 모드에서는 표시하지 않는다 200714
|
|
if (DesignMode == true) return;
|
|
|
|
if (arConn_DIO && this.arDI_Emergency == true) ShowPopupMessage(g, "EMERGENCY BUTTON", "비상정지 확인\nEMERGENCY or POWER LOSS", Properties.Resources.error, true);
|
|
else if (this.arDI_SaftyOk == false) ShowPopupMessage(g, "SAFTY SENSOR", "안전 센서 확인", Properties.Resources.alert, true);
|
|
else if (arConn_MOT && this.arMOT_Alm[0] == true) ShowPopupMessage(g, "SERVO ALARM", "Y-PICKER 모터 알람 발생", Properties.Resources.error, true);
|
|
else if (arConn_MOT && this.arMOT_Alm[1] == true) ShowPopupMessage(g, "SERVO ALARM", "Z-FRONT 모터 알람 발생", Properties.Resources.error, true);
|
|
else if (arConn_MOT && this.arMOT_Alm[2] == true) ShowPopupMessage(g, "SERVO ALARM", "Z-REAR 모터 알람 발생", Properties.Resources.error, true);
|
|
|
|
else if (arConn_MOT && this.arMOT_SVOn[0] == false) ShowPopupMessage(g, "SERVO ALARM", "Y-PICKER\nSERVO-OFF", Properties.Resources.alert, true);
|
|
else if (arConn_MOT && this.arMOT_SVOn[1] == false) ShowPopupMessage(g, "SERVO ALARM", "Z-PICKER\nSERVO-OFF", Properties.Resources.alert, true);
|
|
else if (arConn_MOT && this.arMOT_SVOn[2] == false) ShowPopupMessage(g, "SERVO ALARM", "L-PRINT-Y\nSERVO-OFF", Properties.Resources.alert, true);
|
|
else if (arConn_MOT && this.arMOT_SVOn[3] == false) ShowPopupMessage(g, "SERVO ALARM", "L-PRINT-Z\nSERVO-OFF", Properties.Resources.alert, true);
|
|
else if (arConn_MOT && this.arMOT_SVOn[4] == false) ShowPopupMessage(g, "SERVO ALARM", "R-PRINT-Y\nSERVO-OFF", Properties.Resources.alert, true);
|
|
|
|
else if (arConn_DIO && this.arAIRDetect == false) ShowPopupMessage(g, "AIR DETECT", "*전면의 AIR버튼(청색)을 눌러 AIR를 공급하세요\n* AIR 라인을 확인하세요", Properties.Resources.error, true);
|
|
|
|
else if (arConn_MOT && (this.arMOT_HSet[0] == false || this.arMOT_HSet[1] == false || this.arMOT_HSet[2] == false))
|
|
{
|
|
//안전오류도 표시해줘야한다
|
|
var SaftyMessage = string.Empty;
|
|
if (arVar_Port[0].SaftyErr == true) SaftyMessage += "DOOR:LEFT";
|
|
if (arVar_Port[1].SaftyErr == true) SaftyMessage += (string.IsNullOrEmpty(SaftyMessage) == false ? "," : string.Empty) + "DOOR:CENTER";
|
|
if (arVar_Port[2].SaftyErr == true) SaftyMessage += (string.IsNullOrEmpty(SaftyMessage) == false ? "," : string.Empty) + "DOOR:RIGHT";
|
|
|
|
if (arPickerSafeZone == false) SaftyMessage += (string.IsNullOrEmpty(SaftyMessage) == false ? "\n" : string.Empty) + "피커안전위치 : OFF";
|
|
else SaftyMessage += "피커안전위치 : ON"; ;
|
|
|
|
ShowPopupMessage(g, "SYSTEM NOT READY", "초기화가 필요 합니다\n" + SaftyMessage, Properties.Resources.error, true);
|
|
}
|
|
else if (arConn_MOT && this.arMOT_HSet[0] == false) ShowPopupMessage(g, "SERVO ALARM", "Y-PICKER 홈 검색 필요", Properties.Resources.alert, true);
|
|
else if (arConn_MOT && this.arMOT_HSet[1] == false) ShowPopupMessage(g, "SERVO ALARM", "Z-FRONT 홈 검색 필요", Properties.Resources.alert, true);
|
|
else if (arConn_MOT && this.arMOT_HSet[2] == false) ShowPopupMessage(g, "SERVO ALARM", "Z-REAR 홈 검색 필요", Properties.Resources.alert, true);
|
|
|
|
else if (arVar_Port[0].OverLoad) ShowPopupMessage(g, "## OVERLOAD ##", "FRONT-LEFT", Properties.Resources.alert, true);
|
|
else if (arVar_Port[1].OverLoad) ShowPopupMessage(g, "## OVERLOAD ##", "FRONT-RIGHT", Properties.Resources.alert, true);
|
|
|
|
//else if (arFlag_UnloaderBusy) ShowPopupMessage(g, "## UNLOADER ##\nBUSY", Properties.Resources.alert);
|
|
//else if (arFlag_UnloaderErr) ShowPopupMessage(g, "## UNLOADER ##\nERROR", Properties.Resources.alert);
|
|
}
|
|
|
|
|
|
void Draw_Menu(Graphics g)
|
|
{
|
|
//var buttonOk = new CMenuButton("OK", "1");
|
|
//var buttonNo = new CMenuButton("CANCLE", "0");
|
|
//var newmenu = new CMenu("body str", "title", eMsgIcon.Error, buttonOk, buttonNo)
|
|
//{
|
|
// BorderColor = Color.Gray
|
|
//};
|
|
//this.menus.Push(newmenu);
|
|
|
|
if (arMenus == null || arMenus.Length < 1) { this.HasPopupMenu = false; return; }
|
|
else HasPopupMenu = true;
|
|
|
|
ShowMaskLayer(g, Color.FromArgb(250, Color.Black));
|
|
var item = this.arMenus.Last();//.Peek();
|
|
//이 메뉴를 표시 합니다.
|
|
|
|
PopupMenuRequireInput = item.RequireInput;
|
|
|
|
var buttonSpace = 10;
|
|
var hSpace = 5;
|
|
var vSpace = 10;
|
|
var iconSize = 80;
|
|
var menuheight = 64;
|
|
var padding = 10;
|
|
var msgW = 900;// (int)(this.rect_main.Width * 0.65f);// 640;// (int)(rect_main.Width * 0.7f);
|
|
var msgH = 400;
|
|
var rect = new RectangleF(
|
|
rect_main.Left + (rect_main.Width - msgW) / 2.0f,
|
|
rect_main.Top + (rect_main.Height - msgH) / 2.0f,
|
|
msgW, msgH);
|
|
|
|
Rectangle rectT = Rectangle.Empty; //title
|
|
Rectangle rectI = Rectangle.Empty; //icon
|
|
Rectangle rectC = Rectangle.Empty; //content
|
|
Rectangle rectB = Rectangle.Empty; //button
|
|
|
|
rectT = new Rectangle((int)rect.Left + padding, (int)rect.Top + padding, (int)rect.Width - (padding * 2), (int)(rect.Height * 0.1));
|
|
rectI = new Rectangle((int)rect.Left + padding + 10, (int)rectT.Bottom + vSpace, iconSize, iconSize); //icon size
|
|
rectB = new Rectangle((int)(rect.Left + padding * 2), (int)(rect.Bottom - menuheight - padding), (int)rect.Width - (padding * 4), menuheight);
|
|
rectC = new Rectangle((int)rectI.Right + 20 + hSpace * 2, (int)rectT.Bottom + 10 + vSpace,
|
|
(int)(rect.Width - hSpace - (padding * 2) - rectI.Width),
|
|
(int)(rect.Height - rectT.Height - rectB.Height - (padding * 2) - vSpace * 2));
|
|
|
|
g.FillRectangle(new SolidBrush(Color.FromArgb(220, item.BackColor)), rect);
|
|
|
|
//제목줄 표시
|
|
using (LinearGradientBrush sb = new LinearGradientBrush(rectT,
|
|
Color.FromArgb(160, 160, 160),
|
|
Color.FromArgb(180, 180, 180),
|
|
LinearGradientMode.Vertical))
|
|
{
|
|
g.FillRectangle(sb, rectT);
|
|
}
|
|
|
|
|
|
g.DrawString(item.Title, item.Font, new SolidBrush(item.ForeColor), rectT, sfCenter);
|
|
|
|
//버튼표시
|
|
if (item.buttons != null && item.buttons.Length > 0)
|
|
{
|
|
//현재 버튼 영역의 갯수가 다르면 다시 생성한다.
|
|
if (menuButtons.Count != item.buttons.Length)
|
|
{
|
|
|
|
menuButtons = new List<CMenuButton>();
|
|
foreach (var bt in item.buttons)
|
|
menuButtons.Add(bt);
|
|
|
|
g.DrawString("!!", this.Font, Brushes.Red, rectB.Left + 10, rectB.Top + 10);
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < menuButtons.Count; i++)
|
|
menuButtons[i] = item.buttons[i];
|
|
}
|
|
|
|
g.DrawString(item.buttons.Length.ToString() + "/" + menuButtons.Count.ToString(), this.Font, Brushes.Red, rectB);
|
|
var butidx = 0;
|
|
var butwid = (rectB.Width - (item.buttons.Length - 1) * buttonSpace) / item.buttons.Length;
|
|
foreach (var but in item.buttons)
|
|
{
|
|
but.menutag = item.Tag;
|
|
but.Rect = new Rectangle(rectB.Left + butwid * butidx + buttonSpace * butidx, rectB.Top, butwid, rectB.Height);
|
|
g.FillRectangle(new SolidBrush(but.BackColor), but.Rect);
|
|
g.DrawRectangle(new Pen(but.BorderColor, but.BorderSize), but.Rect);
|
|
g.DrawString(but.Text, item.Font, new SolidBrush(but.ForeColor), but.Rect, sfCenter);
|
|
butidx++;
|
|
}
|
|
}
|
|
else menuButtons.Clear();
|
|
|
|
//아이콘 영역에 그림표시
|
|
if (rectI.IsEmpty == false)
|
|
{
|
|
g.DrawImage(Properties.Resources.info, rectI);
|
|
}
|
|
|
|
//본문데이터표시
|
|
if (string.IsNullOrEmpty(item.Text) == false) //contec
|
|
{
|
|
g.DrawString(item.Text, item.Font, new SolidBrush(item.ForeColor), rectC);
|
|
}
|
|
|
|
//외각 테두리
|
|
//g.DrawRectangle(new Pen(Color.FromArgb(20,20,20), 10) { Alignment = PenAlignment.Center }, rect.Left + 1, rect.Top + 1, rect.Width, rect.Height);
|
|
|
|
g.DrawRectangle(new Pen(Color.FromArgb(180, 180, 180), 10) { Alignment = PenAlignment.Center }, rect.Left, rect.Top, rect.Width, rect.Height);
|
|
|
|
|
|
//g.DrawRectangle(Pens.Black, rect.Left, rect.Top, rect.Width, rect.Height);
|
|
|
|
//g.DrawRectangle(Pens.Red, rectT); //제목표시줄
|
|
//g.DrawRectangle(Pens.Blue, rectI); //아이콘
|
|
//g.DrawRectangle(Pens.Green, rectB); //버튼영역
|
|
//g.DrawRectangle(Pens.Black, rectC); //본문영역
|
|
}
|
|
|
|
void ShowMaskLayer(Graphics g, Color maskColor)
|
|
{
|
|
g.FillRectangle(new SolidBrush(maskColor), this.DisplayRectangle.Left, DisplayRectangle.Top, DisplayRectangle.Width, DisplayRectangle.Height);
|
|
|
|
}
|
|
|
|
public Font MessageBody { get; set; } = new Font("맑은 고딕", 20, FontStyle.Bold);
|
|
public Font MessageTitle { get; set; } = new Font("맑은 고딕", 10, FontStyle.Bold);
|
|
|
|
void ShowPopupMessage(Graphics g, string title, string msg, Image icon, Boolean isError)
|
|
{
|
|
//팝업표시할때마다 배경 마스킹을 한다
|
|
//var maskColor = Color.FromArgb(100, Color.White);
|
|
//ShowMaskLayer(g, maskColor);
|
|
|
|
//var msgf = new Font("맑은 고딕", 20, FontStyle.Bold);
|
|
//var msgt = new Font("맑은 고딕", 10, FontStyle.Bold);
|
|
|
|
if (isError == false)
|
|
{
|
|
//팝업표시할때마다 배경 마스킹을 한다
|
|
|
|
var maskColor = Color.FromArgb(50, Color.Gray);
|
|
ShowMaskLayer(g, maskColor);
|
|
|
|
var msgW = (int)(this.rect_main.Width * 0.65f);// 640;// (int)(rect_main.Width * 0.7f);
|
|
var msgH = 105;
|
|
var rect = new RectangleF(
|
|
rect_main.Left + (rect_main.Width - msgW) / 2.0f,
|
|
rect_main.Top + (rect_main.Height - msgH) / 2.0f,
|
|
msgW, msgH);
|
|
|
|
var TitleHeight = 25;
|
|
var rectT = new Rectangle((int)rect.Left, (int)rect.Bottom - TitleHeight, (int)rect.Width, TitleHeight);
|
|
var rectI = new Rectangle((int)rect.Left, (int)rect.Top, (int)rect.Width, (int)rect.Height - rectT.Height);
|
|
|
|
//g.FillRectangle(new SolidBrush(Color.FromArgb(220, Color.Black)), rect);
|
|
g.FillRectangle(new SolidBrush(Color.FromArgb(120, Color.White)), rect);
|
|
|
|
var rectTL = new RectangleF(rectT.Left, rectT.Top, rectT.Width / 2.0f, rectT.Height);
|
|
var rectTR = new RectangleF(rectTL.Right, rectT.Top, rectTL.Width, rectTL.Height);
|
|
using (var sb = new LinearGradientBrush(rectT, Color.Transparent, Color.White, LinearGradientMode.Horizontal))
|
|
g.FillRectangle(sb, rectTL);
|
|
using (var sb = new LinearGradientBrush(rectT, Color.White, Color.Transparent, LinearGradientMode.Horizontal))
|
|
g.FillRectangle(sb, rectTR);
|
|
|
|
//g.DrawImage(icon,
|
|
// (int)(rect.Left + 20),
|
|
// (int)(rect.Top + (rect.Height - icon.Height) / 2.0f));
|
|
|
|
g.DrawString(title, MessageTitle, Color.Black, rectT, ContentAlignment.MiddleCenter);
|
|
g.DrawString(msg, MessageBody, Color.White, rectI, ContentAlignment.MiddleCenter, Color.FromArgb(24, 24, 24));
|
|
|
|
if (errstep % 5 == 0) errstepR = !errstepR;
|
|
|
|
if (errstepR)
|
|
g.DrawRectangle(new Pen(Color.Gold, 2), rect.Left, rect.Top, rect.Width, rect.Height);
|
|
else
|
|
g.DrawRectangle(new Pen(Color.White, 2), rect.Left, rect.Top, rect.Width, rect.Height);
|
|
|
|
if (errstep < 255) errstep += 1;
|
|
else errstep = 0;
|
|
}
|
|
else
|
|
{
|
|
//팝업표시할때마다 배경 마스킹을 한다
|
|
var maskColor = Color.FromArgb(253, 15, 15, 15);
|
|
ShowMaskLayer(g, maskColor);
|
|
|
|
var msgW = (int)(this.rect_main.Width * 0.8f);// 640;// (int)(rect_main.Width * 0.7f);
|
|
var msgH = (int)(this.rect_main.Height * 0.8f);//
|
|
var rect = new RectangleF(
|
|
rect_main.Left + (rect_main.Width - msgW) / 2.0f,
|
|
rect_main.Top + (rect_main.Height - msgH) / 2.0f,
|
|
msgW, msgH);
|
|
|
|
var rectT = new Rectangle((int)rect.Left, (int)rect.Bottom - 200, (int)rect.Width, 200);
|
|
var rectI = new Rectangle((int)rect.Left, (int)rect.Top, (int)rect.Width, (int)rect.Height - rectT.Height);
|
|
|
|
//g.FillRectangle(new SolidBrush(Color.FromArgb(220, Color.Black)), rect);
|
|
g.FillRectangle(new SolidBrush(Color.FromArgb(253, Color.Black)), rect);
|
|
|
|
g.DrawImage(icon,
|
|
(int)(rectI.Left + rectI.Width / 2.0f) - 40,
|
|
(int)(rectI.Top + rectI.Height / 2.0f) + 10);
|
|
|
|
g.DrawString(msg, MessageBody, Brushes.Gold, rectT, sfCenter);
|
|
|
|
if (errstep % 5 == 0) errstepR = !errstepR;
|
|
|
|
if (errstepR)
|
|
g.DrawRectangle(new Pen(Color.Red, 10), rect.Left, rect.Top, rect.Width, rect.Height);
|
|
else
|
|
g.DrawRectangle(new Pen(Color.Gold, 10), rect.Left, rect.Top, rect.Width, rect.Height);
|
|
|
|
if (errstep < 255) errstep += 1;
|
|
else errstep = 0;
|
|
}
|
|
|
|
//msgf.Dispose();
|
|
//msgt.Dispose();
|
|
}
|
|
|
|
void Draw_Port(Graphics g)
|
|
{
|
|
var fSizeCnt = 20;
|
|
var convmode = VAR.BOOL?[eVarBool.Use_Conveyor] ?? false;
|
|
using (Font fCnt = new Font("consolas", fSizeCnt, FontStyle.Bold))
|
|
{
|
|
using (Font fMSg = new Font("맑은 고딕", 15, FontStyle.Bold))
|
|
{
|
|
if (convmode)
|
|
this.arVar_Port[0].DisplayConv(g, fCnt, fMSg, arMagnet0, arFGVision0RDY, arFGVision0END, arPortLItemOn, arMotILockVS0, arCountV0, CVLeftBusy, CVLeftReady);
|
|
else
|
|
this.arVar_Port[0].Display(g, fCnt, fMSg, arMagnet0, arFGVision0RDY, arFGVision0END, arPortLItemOn, arMotILockVS0, arCountV0);
|
|
|
|
this.arVar_Port[1].Display(g, fCnt, fMSg, arMagnet1, arFGVision1RDY, arFGVision1END, false, arMotILockVS1, arCountV1);
|
|
|
|
if (convmode)
|
|
this.arVar_Port[2].DisplayConv(g, fCnt, fMSg, arMagnet2, arFGVision2RDY, arFGVision2END, arPortRItemOn, arMotILockVS2, arCountV2, CVRightBusy, CVRightReady);
|
|
else
|
|
this.arVar_Port[2].Display(g, fCnt, fMSg, arMagnet2, arFGVision2RDY, arFGVision2END, arPortRItemOn, arMotILockVS2, arCountV2);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Draw_Vision(Graphics g)
|
|
{
|
|
|
|
//var NewX0 = arVar_Port[0].Rect.Right;
|
|
|
|
//var NewXDist = arVar_Port[1].Rect.Left - arVar_Port[0].Rect.Right;
|
|
//var NewYDist = arVar_Port[0].Rect.Height;
|
|
|
|
//var NewY = arVar_Port[0].Rect.Top;
|
|
//var portw_Px = arVar_Port[0].Rect.Width;
|
|
|
|
////둘사이의 공간으로 처리한다
|
|
//var VisionRectSizePx = (int)Math.Min(NewXDist - 10, NewYDist - 10);
|
|
//rect_vision = new RectangleF(
|
|
// (float)(NewX0 + (NewXDist - VisionRectSizePx) / 2.0f),
|
|
// (float)(NewY + (NewYDist - VisionRectSizePx) / 2.0f),
|
|
// (float)VisionRectSizePx,
|
|
// (float)VisionRectSizePx);
|
|
|
|
//g.DrawEllipse(Pens.Gray, rect_vision);
|
|
|
|
////가운에 영역(10% 작은)에. 감지된 릴 모양을 그려준다
|
|
//var padval = rect_vision.Width * 0.05f;
|
|
//var rellrect = new RectangleF(
|
|
// rect_vision.Left + padval,
|
|
// rect_vision.Top + padval,
|
|
// rect_vision.Width - padval * 2,
|
|
// rect_vision.Height - padval * 2);
|
|
|
|
//if (arVisionProcessC)
|
|
//{
|
|
// using (LinearGradientBrush br = new LinearGradientBrush(rellrect, Color.Lime, Color.Green, LinearGradientMode.BackwardDiagonal))
|
|
// g.FillEllipse(br, rellrect);
|
|
// g.DrawEllipse(Pens.Lime, rellrect);
|
|
//}
|
|
//else
|
|
//{
|
|
// using (LinearGradientBrush br = new LinearGradientBrush(rellrect, Color.Yellow, Color.Gold, LinearGradientMode.BackwardDiagonal))
|
|
// g.FillEllipse(br, rellrect);
|
|
// g.DrawEllipse(Pens.Lime, rellrect);
|
|
//}
|
|
|
|
////감지상태를 글자료 표시해준다.
|
|
////비젼데이터가 있다면 그것을 사용해준다
|
|
//var msg = string.IsNullOrEmpty(arVision_RID) ? "REEL ON" : arVision_RID;
|
|
//using (var sb = new SolidBrush(Color.FromArgb(120, Color.Black)))
|
|
// g.DrawString(msg, this.Font, sb, rellrect,
|
|
// new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
|
|
|
|
}
|
|
RectangleF rect_vision = RectangleF.Empty;
|
|
|
|
public string arVision_RID { get; set; }
|
|
public string arVision_SID { get; set; }
|
|
|
|
|
|
public Boolean arVisionProcessL { get; set; }
|
|
public Boolean arVisionProcessC { get; set; }
|
|
public Boolean arVisionProcessR { get; set; }
|
|
|
|
private void Tm_Tick(object sender, EventArgs e)
|
|
{
|
|
|
|
if (ConveyorRunPoint < (AnimationStepConv - 3)) ConveyorRunPoint += 1;
|
|
else ConveyorRunPoint = 1;
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
|
|
if (this.arVar_Port[i].arrowIndex < (arVar_Port[i].AnimationStepPort - 3)) this.arVar_Port[i].arrowIndex += 1;
|
|
else this.arVar_Port[i].arrowIndex = 1;
|
|
}
|
|
this.Invalidate();
|
|
|
|
// var ts = DateTime.Now - updatetime;
|
|
//if (ts.TotalMilliseconds >= tm.Interval) this.Invalidate();
|
|
}
|
|
|
|
}
|
|
}
|