Files
ATV_STDLabelAttach/Handler/Sub/arFrameControl/MotionView/MotionDisplay.cs
2025-07-17 16:11:46 +09:00

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