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); } } } }