307 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			307 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.ComponentModel;
 | |
| using System.Data;
 | |
| using System.Drawing;
 | |
| using System.Linq;
 | |
| using System.Text;
 | |
| using System.Windows.Forms;
 | |
| 
 | |
| namespace arFrame.Control
 | |
| {
 | |
|     public partial class MotionDisplay : System.Windows.Forms.Control
 | |
|     {
 | |
|         private Color[] colorB1 = new Color[] { 
 | |
|             Color.MediumSeaGreen,
 | |
|             Color.DeepSkyBlue,
 | |
|             Color.Tomato,
 | |
|             Color.Purple, 
 | |
|             Color.Tomato,
 | |
|             Color.FromArgb(40,40,40)
 | |
|         };
 | |
|         private Color[] colorB2 = new Color[] {
 | |
|             Color.SeaGreen, 
 | |
|             Color.SteelBlue, 
 | |
|             Color.Red, 
 | |
|             Color.Indigo, 
 | |
|             Color.Red,
 | |
|             Color.FromArgb(30,30,30)
 | |
|         };
 | |
| 
 | |
|         private StringFormat sf = new StringFormat();
 | |
|         private string[] IndiName = new string[] { "INP","ORG","LIM","HST","ALM","" };
 | |
|         public MotITem[] Items;
 | |
|         private int _colcount = 3;
 | |
|         private int _rowcount = 2;
 | |
|         private Color _bordercolor = Color.Black;
 | |
|         private Color _gridcolor = Color.FromArgb(50, 50, 50);
 | |
|         private int _bordersize = 1;
 | |
|         private Padding _padding;
 | |
|         private string _postionformat = "";
 | |
|         private int _headerHeight = 16;
 | |
|         private Font _headerfont = new Font("Consolas",7f);
 | |
| 
 | |
|         
 | |
|         private int itemCount { get { return _colcount * _rowcount; } }
 | |
|         
 | |
|         public new Font Font { get { return base.Font; } set { base.Font = value; this.Invalidate(); } }
 | |
|         public Font HeaderFont { get { return _headerfont; } set { _headerfont = value; this.Invalidate(); } }
 | |
|         public int HeaderHeight { get { return _headerHeight; } set { _headerHeight = value; RemakeChartRect(); this.Invalidate(); } }
 | |
|         public new Padding Padding { get { if (_padding == null) return Padding.Empty; else return _padding; } set { _padding = value; RemakeChartRect(); Invalidate(); } }
 | |
|         public int ColumnCount { get { return _colcount; } set { _colcount = value; ResetArray(); RemakeChartRect(); } }
 | |
|         public int RowCount { get { return _rowcount; } set { _rowcount = value; ResetArray(); RemakeChartRect(); } }
 | |
|         public int BorderSize { get { return _bordersize; } set { _bordersize = value; Invalidate(); } }
 | |
|         public Color BorderColor { get { return _bordercolor; } set { _bordercolor = value; Invalidate(); } }
 | |
|         public string PositionDisplayFormat { get { return _postionformat; } set { _postionformat = value; Invalidate(); } }
 | |
|         public Color GridColor { get { return _gridcolor; } set { _gridcolor = value; Invalidate(); } }
 | |
| 
 | |
|         public new Boolean Enabled { get { return base.Enabled; } set { base.Enabled = value; Invalidate(); } }
 | |
| 
 | |
|         public MotionDisplay()
 | |
|         {
 | |
|             InitializeComponent();
 | |
| 
 | |
|             // Set Optimized Double Buffer to reduce flickering
 | |
|             this.SetStyle(ControlStyles.UserPaint, true);
 | |
|             this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
 | |
|             this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
 | |
| 
 | |
|             // Redraw when resized
 | |
|             this.SetStyle(ControlStyles.ResizeRedraw, true);
 | |
|             sf.LineAlignment = StringAlignment.Center;
 | |
|             sf.Alignment = StringAlignment.Center;
 | |
| 
 | |
| 
 | |
|             //값과 이름은 외부의 값을 사용한다
 | |
|             ResetArray();
 | |
| 
 | |
|             if (MinimumSize.Width == 0 || MinimumSize.Height == 0)
 | |
|                 MinimumSize = new Size(100, 50);
 | |
|         }
 | |
| 
 | |
|         void ResetArray()
 | |
|         {
 | |
| 
 | |
|         }
 | |
| 
 | |
| 
 | |
|         protected override void OnSizeChanged(EventArgs e)
 | |
|         {
 | |
|             base.OnSizeChanged(e);
 | |
|             RemakeChartRect();
 | |
|         }
 | |
| 
 | |
|         public void RemakeChartRect()
 | |
|         {
 | |
|             if (DisplayRectangle == Rectangle.Empty) return;
 | |
| 
 | |
|             var baseRect = new Rectangle(
 | |
|                 DisplayRectangle.Left + _padding.Left,
 | |
|                 DisplayRectangle.Top + _padding.Top,
 | |
|                 DisplayRectangle.Width - _padding.Left - _padding.Right,
 | |
|                 DisplayRectangle.Height - _padding.Top - _padding.Bottom);
 | |
| 
 | |
|             double x = 0;
 | |
|             double y = 0;
 | |
|             double w = baseRect.Width / (_colcount * 1.0);
 | |
|             double h = baseRect.Height / (_rowcount * 1.0);
 | |
| 
 | |
|             if (this.Items == null || itemCount != this.Items.Length)
 | |
|             {
 | |
|                 //아이템갯수가 달라졌으므로 다시 갱신해야함
 | |
|                 var item = new MotITem[RowCount * ColumnCount];
 | |
|                 for (int r = 0; r < RowCount; r++)
 | |
|                 {
 | |
|                     for (int c = 0; c < ColumnCount; c++)
 | |
|                     {
 | |
|                         int idx = r * ColumnCount + c;
 | |
|                         item[idx] = new MotITem(idx);
 | |
|                         item[idx].Enable = false;
 | |
|                         item[idx].Padding = new Padding(0, 0, 0, 0);
 | |
|                         item[idx].TextAlign = ContentAlignment.MiddleCenter;
 | |
|                         x = baseRect.Left + (c * w);
 | |
|                         y = baseRect.Top + (r * h);
 | |
|                         item[idx].rect = new RectangleF((float)x, (float)y, (float)w, (float)h);
 | |
|                         item[idx].Dirty = true;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 this.Items = item;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 //아이템의 갯수는 같으므로 좌표값만 변경해준다.
 | |
|                 for (int r = 0; r < RowCount; r++)
 | |
|                 {
 | |
|                     for (int c = 0; c < ColumnCount; c++)
 | |
|                     {
 | |
|                         int idx = r * ColumnCount + c;
 | |
|                         var item = Items[idx];
 | |
|                         x = (c * w);
 | |
|                         y = (r * h);
 | |
|                         item.rect = new RectangleF((float)x, (float)y, (float)w, (float)h);
 | |
|                         item.Dirty = true;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             this.Invalidate();
 | |
| 
 | |
|         }
 | |
| 
 | |
|         protected override void OnPaint(PaintEventArgs pe)
 | |
|         {
 | |
|             //배경그리기
 | |
|             //using (var sb = new System.Drawing.Drawing2D.LinearGradientBrush(DisplayRectangle, BackColor, BackColor2On, System.Drawing.Drawing2D.LinearGradientMode.Vertical))
 | |
|             pe.Graphics.FillRectangle(new SolidBrush(this.BackColor), DisplayRectangle);
 | |
| 
 | |
|             if (Items == null)
 | |
|             {
 | |
|                 pe.Graphics.DrawString("no items", this.Font, Brushes.Red, 100, 100);
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             var items = Items.OrderBy(t => t.No);
 | |
|             foreach (var menu in items)
 | |
|             {
 | |
|                 drawItem(menu.idx, pe.Graphics);
 | |
|             }
 | |
| 
 | |
|             //테두리 그리기
 | |
|             if (BorderSize > 0)
 | |
|             {
 | |
|                 pe.Graphics.DrawRectangle(new Pen(this.BorderColor, BorderSize),
 | |
|                 this.DisplayRectangle.Left,
 | |
|                 this.DisplayRectangle.Top,
 | |
|                 this.DisplayRectangle.Width - 1,
 | |
|                 this.DisplayRectangle.Height - 1);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void drawItem(int itemIndex, Graphics g = null)
 | |
|         {
 | |
|             if (g == null) g = this.CreateGraphics();
 | |
|             var item = this.Items[itemIndex];
 | |
| 
 | |
|             // g.DrawString("rect null", this.Font, Brushes.White, 100, 100);
 | |
| 
 | |
|             if (item.rect == RectangleF.Empty) return;
 | |
| 
 | |
|             var rect = item.rect;// rects[i];
 | |
| 
 | |
|             var diplayText = item.Text;
 | |
| 
 | |
|             //byte Value = 0;
 | |
| 
 | |
|             //배경이 투명이 아니라면 그린다.            
 | |
|             //var bgColor1 = Color.DarkBlue; //BackColor1Off;
 | |
|             //var bgColor2 = Color.Blue;// BackColor2Off;
 | |
| 
 | |
|             //if (Value != 0 && item.Enable != false)
 | |
|             //{
 | |
|             //    //bgColor1 = Value == 1 ? BackColor1On : BackColor1Err;
 | |
|             //    //bgColor2 = Value == 1 ? BackColor2On : BackColor2Err;
 | |
|             //}
 | |
| 
 | |
|             //using (var sb = new System.Drawing.Drawing2D.LinearGradientBrush(rect, bgColor1, bgColor2, System.Drawing.Drawing2D.LinearGradientMode.Vertical))
 | |
|             //    g.FillRectangle(sb, rect);
 | |
| 
 | |
|             // if (mouseOverItemIndex == menu.idx)
 | |
|             //     this.Cursor = Cursors.Hand;
 | |
|             // else
 | |
|             //    this.Cursor = Cursors.Arrow;
 | |
| 
 | |
|             //테두리를 그리는 속성과 트기가 설정된 경우에만 표시
 | |
|             //if (mouseOverItemIndex == i)
 | |
|             // {
 | |
|             //    pe.Graphics.DrawRectangle(new Pen(Color.DeepSkyBlue), rect.Left, rect.Top, rect.Width, rect.Height);
 | |
|             //}
 | |
|             //else
 | |
|             {
 | |
|                // using (var p = new Pen(BorderColor, 1))
 | |
|                //     g.DrawRectangle(p, rect.Left, rect.Top, rect.Width, rect.Height);
 | |
|             }
 | |
| 
 | |
|             //총 5개의 인디게이터와 하단에 위치값을 표시하는 영역이 있따.
 | |
|             //줄 영역은 50%비율로 처리함
 | |
|             if(item.Dirty)
 | |
|             {
 | |
|                 //각 영역을 다시 그려줘야한다.
 | |
|                 var indiWidth = rect.Width / 5.0;
 | |
|                // var indiHeight = rect.Height / 2.0;
 | |
|                 for (int c = 0; c < 5; c++)
 | |
|                 {
 | |
|                     item.subRect[c] =   new Rectangle((int)(c * indiWidth + item.rect.Left), (int)(item.rect.Top), (int)indiWidth, (int)HeaderHeight);
 | |
|                 }
 | |
|                 item.Dirty = false;
 | |
| 
 | |
|                 //위치값을 나타내는 영역
 | |
|                 item.subRect[5] = new Rectangle((int)item.rect.Left, (int)(item.rect.Top + HeaderHeight), (int)rect.Width, (int)rect.Height - HeaderHeight );
 | |
| 
 | |
|             }
 | |
| 
 | |
|             for(int i = 0 ; i < item.subRect.Length;i++)
 | |
|             {
 | |
|                 var B1 = colorB1[i];
 | |
|                 var B2 = colorB2[i];
 | |
| 
 | |
|                 if (i < (item.subRect.Length - 1))  //상태표시칸은 현재 값에 따라서 색상을 달리한다
 | |
|                 {
 | |
|                     if ( this.Enabled == false || (item.State[i] == false && DesignMode == false))
 | |
|                     {
 | |
|                         B1 = Color.FromArgb(20,20,20);
 | |
|                         B2 = Color.FromArgb(50,50,50);
 | |
|                     }
 | |
|                 }
 | |
|                 
 | |
|                 var rt = item.subRect[i];
 | |
|                 using (var br = new System.Drawing.Drawing2D.LinearGradientBrush(rt, B1, B2, System.Drawing.Drawing2D.LinearGradientMode.Vertical))
 | |
|                     g.FillRectangle(br, rt);
 | |
| 
 | |
|                // g.DrawRectangle(Pens.Yellow, rt);
 | |
|                 if (i < (item.subRect.Length-1))
 | |
|                 {
 | |
|                     sf.Alignment = StringAlignment.Center; 
 | |
|                     sf.LineAlignment = StringAlignment.Center;
 | |
|                     g.DrawString(IndiName[i], HeaderFont, Brushes.White, rt, sf);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     sf.LineAlignment = StringAlignment.Center;
 | |
|                     sf.Alignment = StringAlignment.Far;
 | |
|                     g.DrawString(item.Position.ToString(PositionDisplayFormat) + " [" + item.PositionCmd.ToString(PositionDisplayFormat) + "] ", 
 | |
|                         this.Font,
 | |
|                         new SolidBrush(item.PositionColor), 
 | |
|                         rt,
 | |
|                         sf);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             //테두리선은 우측만 처리한다
 | |
|             for (int i = 0; i < item.subRect.Length ; i++)
 | |
|             {
 | |
|                 var rt = item.subRect[i];
 | |
|                 var x1 = rt.Right;
 | |
|                 var y1 = rt.Top;
 | |
|                 var x2 = rt.Right;
 | |
|                 var y2 = rt.Bottom;
 | |
|                 g.DrawLine(new Pen(GridColor), x1, y1, x2, y2);
 | |
|             }
 | |
|             var posRect = item.subRect[item.subRect.Length - 1];
 | |
|             g.DrawLine(new Pen(Color.Black,1), posRect.Left, posRect.Top, posRect.Right, posRect.Top);
 | |
|             
 | |
| 
 | |
|             //인덱스번호 출력
 | |
|             if (diplayText != "")
 | |
|             {
 | |
|                 g.DrawString(string.Format("[{0}] {1}", item.idx, diplayText),
 | |
|                 this.Font, new SolidBrush(this.ForeColor),
 | |
|                 item.rect.Left + 3, item.rect.Top + 3);
 | |
|             }
 | |
| 
 | |
|           
 | |
| 
 | |
|         }
 | |
| 
 | |
|     }
 | |
| }
 | 
