1470 lines
		
	
	
		
			61 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			1470 lines
		
	
	
		
			61 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
 | |
| 
 | |
|         RectangleF rect_vision = RectangleF.Empty;
 | |
| 
 | |
|         public string arVision_RID { get; set; }
 | |
|         public string arVision_SID { get; set; }
 | |
| 
 | |
|         RectangleF rect_zlaxis = RectangleF.Empty;// new RectangleF((float)motZLPosX, (float)motZPosY, motZwPx, (float)motZhPx);
 | |
| 
 | |
|         public Boolean arVisionProcessL { get; set; }
 | |
|         public Boolean arVisionProcessC { get; set; }
 | |
|         public Boolean arVisionProcessR { get; set; }
 | |
| 
 | |
|         #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("Home search is possible", new Font("Tahoma", 20, FontStyle.Bold), Brushes.Lime, crect, new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
 | |
|             else
 | |
|             {
 | |
|                 if (MessageOn)
 | |
|                     g.DrawString("Move the picker to a safe position", new Font("Tahoma", 12, FontStyle.Bold), Brushes.Red, crect, new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
 | |
|                 else
 | |
|                     g.DrawString("Move the picker to a safe position", new Font("Tahoma", 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)
 | |
|         {
 | |
|             //전체 영역 테두리
 | |
|             g.DrawRectangle(new Pen(Color.White, 2), rect_main.Left, rect_main.Top, rect_main.Width, rect_main.Height);
 | |
| 
 | |
|             //포트표시(셔틀위에 표시됨)
 | |
|             Draw_Port(g);    //front
 | |
|        
 | |
| 
 | |
|             //프린터영역그리기  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 = "";// "Print Qty:" + arCountPrint0.ToString("000") + "\n";
 | |
|             var prnstr = prnstrbase + (arFGPrinter0END ? "Print Complete" : (arFGPrinter0RDY ? "Printing" : "Print Ready"));
 | |
|             prnstr += "\n" + arCountPrint0.ToString("0000");
 | |
|             g.DrawString(prnstr, new Font("Tahoma", 10, FontStyle.Bold), new SolidBrush(fColorPrn), rectpl,
 | |
|                 new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
 | |
| 
 | |
|             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 = "";// "Print Qty:" + arCountPrint1.ToString("000") + "\n";
 | |
|             prnstr = prnstrbase + (arFGPrinter1END ? "Print Complete" : (arFGPrinter1RDY ? "Printing" : "Print Ready"));
 | |
|             prnstr += "\n" + arCountPrint1.ToString("0000");
 | |
|             g.DrawString(prnstr, new Font("Tahoma", 10, FontStyle.Bold), new SolidBrush(fColorPrn), rectpl,
 | |
|                 new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
 | |
|           
 | |
|             //모터 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_Error(g);
 | |
| 
 | |
|             //메뉴는 최상위에 표시한다
 | |
|             Draw_Menu(g);
 | |
| 
 | |
|             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)
 | |
|                 {
 | |
|                     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));
 | |
| 
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         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();
 | |
|             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", "Check emergency stop\nEMERGENCY or POWER LOSS", Properties.Resources.error, true);
 | |
|             else if (this.arDI_SaftyOk == false) ShowPopupMessage(g, "SAFTY SENSOR", "Check safety sensor", Properties.Resources.alert, true);
 | |
|             else if (arConn_MOT && this.arMOT_Alm[0] == true) ShowPopupMessage(g, "SERVO ALARM", "Y-PICKER motor alarm occurred", Properties.Resources.error, true);
 | |
|             else if (arConn_MOT && this.arMOT_Alm[1] == true) ShowPopupMessage(g, "SERVO ALARM", "Z-FRONT motor alarm occurred", Properties.Resources.error, true);
 | |
|             else if (arConn_MOT && this.arMOT_Alm[2] == true) ShowPopupMessage(g, "SERVO ALARM", "Z-REAR motor alarm occurred", 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", "*Press the blue AIR button on the front to supply AIR\n* Check the AIR line", 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) + "Picker safety position: OFF";
 | |
|                 else SaftyMessage += "Picker safety position: ON"; ;
 | |
| 
 | |
|                 ShowPopupMessage(g, "SYSTEM NOT READY", "Initialization required\n" + SaftyMessage, Properties.Resources.error, true);
 | |
|             }
 | |
|             else if (arConn_MOT && this.arMOT_HSet[0] == false) ShowPopupMessage(g, "SERVO ALARM", "Y-PICKER home search required", Properties.Resources.alert, true);
 | |
|             else if (arConn_MOT && this.arMOT_HSet[1] == false) ShowPopupMessage(g, "SERVO ALARM", "Z-FRONT home search required", Properties.Resources.alert, true);
 | |
|             else if (arConn_MOT && this.arMOT_HSet[2] == false) ShowPopupMessage(g, "SERVO ALARM", "Z-REAR home search required", 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);
 | |
|         }
 | |
| 
 | |
| 
 | |
|         void Draw_Menu(Graphics g)
 | |
|         {
 | |
|             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(180, 180, 180), 10) { Alignment = PenAlignment.Center }, rect.Left, rect.Top, rect.Width, rect.Height);
 | |
|         }
 | |
| 
 | |
|         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("Tahoma", 20, FontStyle.Bold);
 | |
|         public Font MessageTitle { get; set; } = new Font("Tahoma", 10, FontStyle.Bold);
 | |
| 
 | |
|         void ShowPopupMessage(Graphics g, string title, string msg, Image icon, Boolean isError)
 | |
|         {
 | |
|             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;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         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("Tahoma", 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);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|       
 | |
|     
 | |
| 
 | |
|         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();
 | |
|         }
 | |
| 
 | |
|     }
 | |
| }
 | 
