Files
ENIG/Cs_HMI/Project/CtlAuto.cs
2025-01-07 16:08:02 +09:00

1097 lines
44 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using COMM;
using System.Diagnostics;
namespace Project
{
/// <summary>
/// 2017-04-13 13:26:00 : 라벨이므로 커서 IN 시 Hand 에서 Default로 변경함
/// </summary>
public partial class CtlAuto : Control
{
#region "Enum & Structure"
public enum eColorTheme : byte
{
DaeHyun = 0,
eGrayBlue,
eDarkBlue,
TopMenu,
GrayButton,
GrayTitleBar,
IOStatus,
IOStatusDepp,
BlackButton,
RedButton,
GrayOmokButton,
Stepbar,
RobotStatus,
NewGray_Group,
NewGray_BG,
NewGray_Button,
NewBlue_Button,
Custom,
}
#endregion
public arDev.BMS dev_bms { private get; set; } = null;
public arDev.FakePLC dev_plc { private get; set; } = null;
public arDev.Narumi dev_agv { private get; set; } = null;
public Device.Xbee dev_xbe { private get; set; } = null;
public event EventHandler<ItemClickEventArgs> ItemClick;
private Font _font_bms_vlt = new Font("Consolas", 50, FontStyle.Bold);
private Font _font_bms_lev = new Font("Consolas", 150, FontStyle.Bold);
private Font _font_main_batlev = new Font("Consolas", 50, FontStyle.Bold);
public Font Font_MAIN_BMSLevel { get { return _font_main_batlev; } set { _font_main_batlev = value; Invalidate(); } }
public Font Font_BMS_Volt { get { return _font_bms_vlt; } set { _font_bms_vlt = value; Invalidate(); } }
public Font Font_BMS_Level { get { return _font_bms_lev; } set { _font_bms_lev = value; Invalidate(); } }
public enum eScean
{
Normal = 0,
Progress,
}
public eScean Scean { get; set; } = eScean.Normal;
//public new event EventHandler Click;
public string StatusMessage { get; set; } = string.Empty;
public CtlAuto()
{
InitializeComponent();
// 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);
// Redraw when resized
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.MouseDown += arButton_MouseDown;
this.MouseUp += arButton_MouseUp;
this.MouseEnter += arButton_MouseEnter;
this.MouseLeave += arButton_MouseLeave;
this.Resize += arLabel_Resize;
base.BackColor = Color.FromArgb(32, 32, 32);
ForeColor = Color.White;
}
~CtlAuto()
{
this.MouseDown -= arButton_MouseDown;
this.MouseUp -= arButton_MouseUp;
this.MouseEnter -= arButton_MouseEnter;
this.MouseLeave -= arButton_MouseLeave;
this.Resize -= arLabel_Resize;
}
public void PerformClick()
{
if (Enabled == false) return; //171126
this.InvokeOnClick(this, new EventArgs());
}
void arLabel_Resize(object sender, EventArgs e)
{
if (this.MinimumSize.Width == 0 || this.MinimumSize.Height == 0)
this.MinimumSize = new Size(100, 30);
//bRemakeRect = true;
Invalidate();
}
public new Padding Padding
{
get
{
return base.Padding;
}
set
{
base.Padding = value;
this.Invalidate();
}
}
public Color BorderColor { get; set; }
private int _itemgap = 0;
public int ItemGap { get { return _itemgap; } set { _itemgap = value; Invalidate(); } }
//Boolean bRemakeRect = true;
public item[] Items { get; set; }
public StateMachine.ERunStep runStep = StateMachine.ERunStep.READY;
public Boolean OnUpdateMode = false;
public Boolean Status_AutoRun
{
get
{
if (COMM.VAR.BOOL == null) return true;
else return COMM.VAR.BOOL[eVarBool.FLAG_AUTORUN];
}
}
public DateTime StopTime { get; set; }
private string stopmessage = "";
public string StopMessage { get { return stopmessage; } set { this.stopmessage = value; this.Invalidate(); } }
System.Diagnostics.Stopwatch wframe = new System.Diagnostics.Stopwatch();
Point centerpt;
protected override void OnPaint(PaintEventArgs e)
{
//Set Optimized Double Buffer to reduce flickering
e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
e.Graphics.InterpolationMode = InterpolationMode.High;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
if (wframe.IsRunning == false) wframe.Restart();
if (this.Scean == eScean.Normal)
{
var chargeM = VAR.BOOL?.Get(eVarBool.FLAG_CHARGEONM) ?? false;
var chargeA = dev_agv?.system1.Battery_charging ?? false;
var charge = chargeM || chargeA;
//if (DesignMode) charge = true;
if (charge)
{
Scean_Normal_Charge(e.Graphics, (chargeM ? "수동" : "자동"));
}
else
{
Scean_Normal(e.Graphics);
}
}
else if (this.Scean == eScean.Progress)
Scean_Progress(e.Graphics);
//버젼표시
var version = VAR.STR?.Get(eVarString.SWVersion) ?? string.Empty;
if (DesignMode) version = "1.1.1.1";
using (var f = new Font("Consolas", 8))
e.Graphics.DrawString(version, f, Brushes.Gray, DisplayRectangle, sfBottomRight);
}
StringFormat sfEnd = new StringFormat
{
Alignment = StringAlignment.Far,
LineAlignment = StringAlignment.Center
};
StringFormat sfStart = new StringFormat
{
Alignment = StringAlignment.Near,
LineAlignment = StringAlignment.Center
};
StringFormat sfCenter = new StringFormat
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
StringFormat sfBottom = new StringFormat
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Far
};
StringFormat sfBottomRight = new StringFormat
{
Alignment = StringAlignment.Far,
LineAlignment = StringAlignment.Far
};
StringFormat sfBottomLeft = new StringFormat
{
Alignment = StringAlignment.Near,
LineAlignment = StringAlignment.Far
};
public float ProgressMax { get; set; } = 100;
public float ProgressVal { get; set; } = 0;
Matrix TranslationTransform = new Matrix();
Matrix RotateTransform = new Matrix();
void Scean_Progress(Graphics g)
{
var progheight = DisplayRectangle.Height * 0.1f;
var r = new RectangleF(DisplayRectangle.Left + 50,
DisplayRectangle.Bottom - progheight - (DisplayRectangle.Height * 0.2f),
DisplayRectangle.Width - 100, progheight);
var rt = new RectangleF(
r.Left,
DisplayRectangle.Top,
r.Width,
r.Top - DisplayRectangle.Height * 0.05f);
//g.DrawRectangle(Pens.Blue, rt.Left, rt.Top, rt.Width, rt.Height);
g.DrawString(this.StatusMessage, this.Font, Brushes.White,
rt, sfBottom);
var progw = r.Width * (this.ProgressVal / this.ProgressMax);
var progr = new RectangleF(r.Left, r.Top, progw, r.Height);
g.FillRectangle(new LinearGradientBrush(r, Color.LightSkyBlue, Color.DeepSkyBlue, LinearGradientMode.Vertical), progr);
g.DrawRectangle(Pens.DimGray, r.Left, r.Top, r.Width, r.Height);
}
int textdir = -1;
void Scean_Normal_Charge(Graphics g, string mode)
{
var bmsready = dev_bms?.IsValid ?? false;// != null;
if (DesignMode) bmsready = true;
if (bmsready == false)
{
var pts = new List<Point>();
pts.Add(new Point(0, 0));
pts.Add(new Point(80, 0));
pts.Add(new Point(0, 80));
using (var f = new Font("Consolas", 110, FontStyle.Bold))
g.DrawString("BMS NOT CONNECTED", f, Brushes.Gold, this.DisplayRectangle, this.sfCenter);
g.FillPolygon(Brushes.Gold, pts.ToArray());
pts.Clear();
pts.Add(new Point(0, 0));
pts.Add(new Point(30, 0));
pts.Add(new Point(0, 30));
g.FillPolygon(Brushes.Orange, pts.ToArray());
}
else
{
//단순 수치값을 크게 표시히낟.
var Volt = dev_bms?.Current_Volt ?? 25.35f;
var Lev = dev_bms?.Current_Level ?? 80.1f;
var textColor = Color.Lime;
if (Lev < 30) textColor = Color.Red;
else if (Lev < 40) textColor = Color.Tomato;
else if (Lev < 60) textColor = Color.Orange;
else if (Lev < 80) textColor = Color.Gold;
using (var textbrush = new SolidBrush(textColor))
g.DrawString($"{Lev:N1}%", this.Font_BMS_Level, textbrush, DisplayRectangle, sfCenter);
g.DrawString($"{Volt:N1}v", this.Font_BMS_Volt, Brushes.Gold, DisplayRectangle, sfBottomRight);
var r = new RectangleF(DisplayRectangle.Left, DisplayRectangle.Top,
DisplayRectangle.Width, 25);
//msg = wframe.ElapsedMilliseconds.ToString() + msg;
var msgc = mode.Equals("수동") ? Color.Gray : Color.Gray;
using (var f = new Font("맑은 고딕", 11, FontStyle.Regular))
using (var sb = new SolidBrush(msgc))
{
var msg = mode.Equals("수동") ? "수동 충전 중입니다 / 해제 하려면 케이블을 제거하고 [충전취소] 버튼을 누르세요" :
"자동 충전 중 입니다 / 최대 충전량에 도달 하거나 (CALL)이 발생하면 자동 해제 됩니다";
var textsize = g.MeasureString(msg, f);
//msg = textsize.Width.ToString() + "_" + TranslationTransform.OffsetX.ToString() + ":" + msg;
//var minx = DisplayRectangle.Width - textsize.Width
//화면이 넘어갔다면 다시 오른쪽으로 간다
if (textdir < 0 && TranslationTransform.OffsetX < (textsize.Width - DisplayRectangle.Width))
textdir *= -1;
else if (textdir > 0 && TranslationTransform.OffsetX >= 0)
textdir *= -1;
//g.FillRectangle(Brushes.BlanchedAlmond, r.Left, r.Top, r.Width, r.Height);
TranslationTransform.Translate(textdir * (wframe.ElapsedMilliseconds / 10f), 0);
wframe.Restart();
g.Transform = TranslationTransform;
g.DrawString(msg, f, sb, r, sfEnd);
}
//TranslationTransform.Reset();
}
}
void Scean_Normal(Graphics g)
{
// if (Status_AutoRun)
// g.FillRectangle(new SolidBrush(Color.FromArgb(40, 40, 40)), this.DisplayRectangle);
//else
g.FillRectangle(new SolidBrush(Color.FromArgb(32, 32, 32)), this.DisplayRectangle);
var wheelSize = new Size((int)(DisplayRectangle.Width * 0.35),
(int)(DisplayRectangle.Width * 0.35));
bool agv_run = true;
if (dev_agv != null) agv_run = dev_agv.system1.agv_run;
Color wheelbackL = agv_run ? Color.DeepSkyBlue : Color.DimGray;
Color wheelBorder = Color.Gold;
if (dev_agv != null)
{
if (dev_agv.data.Speed == 'H') wheelBorder = Color.Red;
else if (dev_agv.data.Speed == 'M') wheelBorder = Color.Gold;
else if (dev_agv.data.Speed == 'L') wheelBorder = Color.Black;
else if (dev_agv.data.Speed == 'S') wheelBorder = Color.Magenta;
}
var wheelspace = 0;
var wheelborder = 8;
//충전중 아이콘 추가
//var charge = VAR.BOOL?.Get(eVarBool.FLAG_CHARGEONA) ?? false;
////charge = true;
//if (charge)
//{
// var x = DisplayRectangle.Right - Properties.Resources.ChargeH.Width - 20;
// var y = -30;
// g.DrawImage(Properties.Resources.ChargeH, x, y);
//}
//왼쪽오른쪽 분리해서 좌측에는 주행정보를 우측에는 배터리 정보를 표시한다
//left wheeel
centerpt = new Point(
(int)(DisplayRectangle.Width / 2.0),
(int)(DisplayRectangle.Height / 2.0));
var rectL = new Rectangle(DisplayRectangle.Left, DisplayRectangle.Top,
(int)(DisplayRectangle.Width / 2f), DisplayRectangle.Height);
var rectR = new Rectangle(rectL.Right, DisplayRectangle.Top,
(int)(DisplayRectangle.Width / 2f), DisplayRectangle.Height);
wheelSize = new Size((int)(rectL.Width * 0.7f), (int)(rectL.Width * 0.7f));
var rect_lwheel = new Rectangle(
(int)(rectL.Left + (rectL.Width - wheelSize.Width) / 2f),
(int)(rectL.Top + (rectL.Height - wheelSize.Height) / 2f),
wheelSize.Width,
wheelSize.Height);
g.FillEllipse(new SolidBrush(Color.FromArgb(200, wheelbackL)), rect_lwheel);
g.DrawEllipse(new Pen(Color.Black, wheelborder), rect_lwheel.AddOffset(1, 1));
g.DrawEllipse(new Pen(wheelBorder, wheelborder), rect_lwheel);
//g.DrawRectangle(Pens.Red, rectL);
//g.DrawRectangle(Pens.Blue, rectR);
//wheel speed text
string speedchar = "마크\n멈춤";
if (dev_bms != null)
{
//speedchar = dev_bms.Current_Level.ToString("N0");
if (dev_agv.data.Speed == 'H')
speedchar = "고속";
else if (dev_agv.data.Speed == 'L')
speedchar = "저속";
else if (dev_agv.data.Speed == 'M')
speedchar = "중속";
else if (dev_agv.data.Speed == 'S')
speedchar = "마크\n멈춤";
else
speedchar = dev_agv.data.Speed.ToString();
}
//g.FillRectangle(Brushes.BlanchedAlmond, r.Left, r.Top, r.Width, r.Height);
var degree = 10;// wframe.ElapsedMilliseconds / 10f;
//var angle = (float)(degree * Math.PI / 180f);
if (RotateTransform.OffsetX == 0)
{
RotateTransform.Translate(DisplayRectangle.Width / 2f, DisplayRectangle.Height / 2f);
}
g.Transform = RotateTransform;
//g.FillEllipse(Brushes.Magenta, new Rectangle(-5, -5, 10, 10));
RotateTransform.Reset();
g.Transform = RotateTransform;
//speedchar = "100";
using (Font f = new Font("맑은 고딕", 70, FontStyle.Bold))
g.DrawString(speedchar, f, Brushes.Black, rect_lwheel, sfCenter);
//배터리모양표시
List<PointF> batpts = new List<PointF>();
var batw = (int)(rectR.Width * 0.6f);
var bath = (int)(rectR.Height * 0.7f);
var ptLT = new PointF(rectR.Left + (rectR.Width - batw) / 2f, rectR.Top + ((rectR.Height - bath) / 2f) + (rectR.Height * 0.05f));
batpts.Add(ptLT);
batpts.Add(new PointF(ptLT.X + batw, ptLT.Y));
batpts.Add(new PointF(ptLT.X + batw, ptLT.Y + bath));
batpts.Add(new PointF(ptLT.X, ptLT.Y + bath));
//g.DrawPolygon(Pens.Gold, batpts.ToArray());
var bmslevel = 28f;
if (dev_bms != null) bmslevel = dev_bms.Current_Level;
var CornerRadius = 10;
var XPosition = rectR.Left + (rectR.Width - batw) / 2f;
var YPosition = rectR.Top + (rectR.Height - bath) / 2f + (rectR.Height * 0.05f);
var batrect = new RectangleF(XPosition, YPosition, batw, bath);
var bathatsizeH = 30;
Color bmsback = Color.Lime;
if (bmslevel < 30) bmsback = Color.Red;
else if (bmslevel < 40) bmsback = Color.Tomato;
else if (bmslevel < 70) bmsback = Color.Gold;
using (GraphicsPath Path = new GraphicsPath())
{
Path.AddLine(XPosition + CornerRadius, YPosition, XPosition + batw / 2f - (batw * 0.1f), YPosition);
Path.AddLine(XPosition + batw / 2f - (batw * 0.1f), YPosition, XPosition + batw / 2f - (batw * 0.1f), YPosition - bathatsizeH + CornerRadius);
Path.AddLine(XPosition + batw / 2f - (batw * 0.1f) + CornerRadius, YPosition - bathatsizeH, XPosition + batw / 2f + (batw * 0.1f) - CornerRadius , YPosition - bathatsizeH);
Path.AddLine(XPosition + batw / 2f + (batw * 0.1f), YPosition - bathatsizeH + CornerRadius, XPosition + batw / 2f + (batw * 0.1f), YPosition );
Path.AddLine(XPosition + batw / 2f - (batw * 0.1f), YPosition, XPosition + batw - (CornerRadius * 2), YPosition);
Path.AddArc(XPosition + batw - (CornerRadius * 2), YPosition, CornerRadius * 2, CornerRadius * 2, 270, 90);
Path.AddLine(XPosition + batw, YPosition + CornerRadius, XPosition + batw, YPosition + bath - (CornerRadius * 2));
Path.AddArc(XPosition + batw - (CornerRadius * 2), YPosition + bath - (CornerRadius * 2), CornerRadius * 2, CornerRadius * 2, 0, 90);
Path.AddLine(XPosition + batw - (CornerRadius * 2), YPosition + bath, XPosition + CornerRadius, YPosition + bath);
Path.AddArc(XPosition, YPosition + bath - (CornerRadius * 2), CornerRadius * 2, CornerRadius * 2, 90, 90);
Path.AddLine(XPosition, YPosition + bath - (CornerRadius * 2), XPosition, YPosition + CornerRadius);
Path.AddArc(XPosition, YPosition, CornerRadius * 2, CornerRadius * 2, 180, 90);
Path.CloseFigure();
var tRegion = new System.Drawing.Region(Path);
var bmsh = (int)(bath * (bmslevel / 100f));
var gRegion = new Region(new RectangleF(XPosition, YPosition + bath - bmsh, batw, bmsh));
gRegion.Intersect(tRegion);
g.DrawPath(new Pen(bmsback, 20), Path);
g.FillRegion(Brushes.WhiteSmoke, tRegion);
g.FillRegion(new SolidBrush(bmsback), gRegion);
g.DrawString($"{bmslevel:N0}", Font_MAIN_BMSLevel, Brushes.Black, batrect, sfCenter);
}
this.DrawDirection(g, rect_lwheel, wheelborder);
//경고메세지표시
DrawWarning(g);
//전체테두리
g.DrawRectangle(new Pen(BorderColor), DisplayRectangle.Left, DisplayRectangle.Top, DisplayRectangle.Width - 1, DisplayRectangle.Height - 1);
var nextstop = VAR.BOOL?.Get(eVarBool.NEXTSTOP_MARK) ?? false;
//if (VAR.BOOL != null) nextstop = VAR.BOOL[eVarBool.NEXTSTOP_MARK];
//상태메세지표시
string stmsg = string.Empty;
if (COMM.VAR.STR != null && COMM.VAR.STR[eVarString.StatusMessage].isEmpty() == false) stmsg = VAR.STR[eVarString.StatusMessage];
else stmsg = "STATUS MESSAGE DEMO";
if (nextstop) stmsg += "|MARK-STOP";
var MsgColor = Color.Lime;
if (PUB.Result != null) MsgColor = PUB.Result.SMSG_ForeColor;
using (SolidBrush sb = new SolidBrush(MsgColor))
using (Font f = new Font("맑은 고딕", 10, FontStyle.Bold))
g.DrawString(stmsg, f, sb, DisplayRectangle, new StringFormat
{
Alignment = StringAlignment.Near,
LineAlignment = StringAlignment.Far,
});
}
readonly Font StopFont = new Font("맑은 고딕", 30, FontStyle.Bold);
public class UIButton
{
public RectangleF rect { get; set; }
public string title { get; set; }
public string cmd { get; set; }
public bool Visible { get; set; }
}
public List<UIButton> Buttons = new List<UIButton>();
public delegate void ButtonClickHandler(UIButton idx);
public event ButtonClickHandler ButtonClick;
void DrawWarning(Graphics g)
{
string warnmsg = string.Empty;
string butcmd = string.Empty;
if (dev_agv != null)
{
if (dev_agv.error.Emergency)
warnmsg = "비상 정지";
else if (dev_agv.error.line_out_error)
warnmsg = "LINE OUT";
else if (dev_agv.error.Overcurrent)
warnmsg = "OVER CURRENT";
else if (dev_agv.system1.agv_run && dev_agv.system1.stop_by_front_detect)
warnmsg = "전방 장애물";
}
//if (DesignMode)
//{
// warnmsg = "비.상.정.지";
// butcmd = "EMG";
//}
if (warnmsg.isEmpty() && stopmessage.isEmpty() == false)
warnmsg = stopmessage;
if (warnmsg != "")
{
var but = this.Buttons.Where(t => t.title.Equals(warnmsg)).FirstOrDefault();
if (but == null)
{
but = new UIButton();
but.title = warnmsg;
this.Buttons.Add(but);
}
but.cmd = butcmd;
var w = this.Width * 0.9f;
var h = this.Height * 0.4f;
but.rect = new RectangleF(
(float)((this.Width - w) / 2.0f),
(float)((this.Height - h) / 2.0f),
w, h);
var rectt = new RectangleF(but.rect.Left, but.rect.Top, but.rect.Width, 10);
var rectb = new RectangleF(but.rect.Left, but.rect.Bottom - 10, but.rect.Width, 10);
g.FillRectangle(new SolidBrush(Color.FromArgb(200, Color.White)), but.rect);
g.FillRectangle(new SolidBrush(Color.FromArgb(220, Color.Red)), rectt);
g.FillRectangle(new SolidBrush(Color.FromArgb(220, Color.Red)), rectb);
//var sf = new StringFormat
//{
// LineAlignment = StringAlignment.Center,
// Alignment = StringAlignment.Center
//};
var sfsize = g.MeasureString(warnmsg, StopFont);
var scx = (float)((but.rect.Width - sfsize.Width) / 2.0);
var scy = (float)((but.rect.Height - sfsize.Height) / 2.0);
g.DrawString(warnmsg, StopFont, Brushes.Black, but.rect.Left + scx + 1, but.rect.Top + scy + 1);
g.DrawString(warnmsg, StopFont, Brushes.Red, but.rect.Left + scx, but.rect.Top + scy);
g.DrawRectangle(new Pen(Color.FromArgb(250, Color.Black), 2), but.rect.Left, but.rect.Top, but.rect.Width, but.rect.Height);
}
else
{
//버튼을 모두 숨긴다.
foreach (var but in Buttons)
but.Visible = false;
}
}
public int frame_direction = 1000 / 10; //초당 4프레임으로 표시한다
public long frame_direction_ms = 0;
public int frame_direction_idx = 0;
void DrawDirection(Graphics g, Rectangle rect, int wheelborder)
{
//위쪽에 방향지시등을 그린다.
var dirterm = 15;
var ditHeight = 50;
var dirWidth = (int)(rect.Width / 5.5f);
var rect_dirup = new Rectangle(
(int)((rect.Left + rect.Width / 2.0) - (dirWidth / 2.0)),
rect.Top - ditHeight - dirterm,
dirWidth,
(ditHeight - wheelborder));
var ptsUp = new Point[] {
new Point( rect_dirup.Left, rect_dirup.Bottom),
new Point( rect_dirup.Right, rect_dirup.Bottom),
new Point( (int)(rect_dirup.Left+ rect_dirup.Width/2.0), rect_dirup.Top)
};
bool dirup = true;
if (dev_agv != null) dirup = dev_agv.data.Direction == 'B';
if (dirup == true)
{
g.FillPolygon(Brushes.Lime, ptsUp);
}
else g.FillPolygon(new SolidBrush(Color.FromArgb(28, 28, 28)), ptsUp);
g.DrawPolygon(Pens.Black, ptsUp);
//아래쪾에 방향지시등을 그린다
var rect_dirdn = new Rectangle(
(int)((rect.Left + rect.Width / 2.0) - (dirWidth / 2.0)),
rect.Bottom + wheelborder + 1 + dirterm,
dirWidth,
(ditHeight - wheelborder));
var ptDn = new Point[] {
new Point( rect_dirdn.Left, rect_dirdn.Top),
new Point( rect_dirdn.Right, rect_dirdn.Top),
new Point( (int)(rect_dirdn.Left+ rect_dirdn.Width/2.0), rect_dirdn.Bottom)
};
if (dirup == false)
{
g.FillPolygon(Brushes.Lime, ptDn);
}
else g.FillPolygon(new SolidBrush(Color.FromArgb(28, 28, 28)), ptDn);
g.DrawPolygon(Pens.Black, ptDn);
////오른쪾에 방향지시등을 그린다
//var dirR = false;
//var rect_dirr = new Rectangle(
// (int)(rect.Right + dirterm),
// (int)(rect.Top + (rect.Height / 2f)),
// dirWidth,
// (ditHeight - wheelborder));
//var ptR = new Point[] {
// new Point( rect_dirr.Left, rect_dirr.Top),
// new Point( rect_dirr.Right, rect_dirr.Top),
// new Point( (int)(rect_dirr.Left+ rect_dirr.Width/2.0), rect_dirr.Bottom)
//};
//if (dirR == false)
//{
// g.FillPolygon(Brushes.Lime, ptR);
//}
//else g.FillPolygon(new SolidBrush(Color.FromArgb(28, 28, 28)), ptR);
//g.DrawPolygon(Pens.Black, ptR);
}
public bool LimitLU
{
get
{
if (dev_plc == null) return true;
return dev_plc.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_LU);
}
}
public bool LimitLD
{
get
{
if (dev_plc == null) return false;
return dev_plc.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_LD);
}
}
public bool LimitRU
{
get
{
if (dev_plc == null) return false;
return dev_plc.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_RU);
}
}
public bool LimitRD
{
get
{
if (dev_plc == null) return true;
return dev_plc.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_RD);
}
}
void DrawMC(Graphics g)
{
var boxw = DisplayRectangle.Width * 0.5f;
var r = new RectangleF(
boxw - 80,
DisplayRectangle.Top + 50,
boxw,
DisplayRectangle.Height - 20);
//g.DrawRectangle(Pens.Red, r.Left, r.Top, r.Width, r.Height);
var w = r.Width * 0.7f;// this.DisplayRectangle.Width * 0.45;
var h = r.Height * 0.5f;// this.DisplayRectangle.Height * 0.75;
var pt = new PointF(r.Left + r.Width / 2.0f, r.Top + r.Height / 2.0f);
var rect = new RectangleF((float)(pt.X - w / 2.0f), (float)((pt.Y - h / 2.0f) + 20), (float)w, (float)h);
//3d모형으로 엣지를 넣는다
// pt = new PointF(DisplayRectangle.Width / 2.1f, DisplayRectangle.Height / 1.5f);
var sizeX = 150;
// var sizeY = 100;
var sizeZ = 150;
var PtsFront = new PointF[] {
new PointF(pt.X-sizeX,pt.Y-sizeZ / 2.0f),
new PointF(pt.X+sizeX,pt.Y-sizeZ / 2.0f),
new PointF(pt.X+sizeX,pt.Y+sizeZ / 2.0f),
new PointF(pt.X-sizeX,pt.Y+sizeZ / 2.0f)
};
var PtsTop = new PointF[] {
new PointF(pt.X-sizeX,pt.Y-(sizeZ / 2.0f)),
new PointF(pt.X+sizeX,pt.Y-(sizeZ / 2.0f)),
new PointF(pt.X +sizeX + 75,pt.Y- sizeZ),
new PointF(pt.X - (sizeX / 2.0f) ,pt.Y-sizeZ)
};
var PtsBottom = new PointF[] {
new PointF(pt.X-sizeX,sizeZ+pt.Y-(sizeZ / 2.0f)),
new PointF(pt.X+sizeX,sizeZ+pt.Y-(sizeZ / 2.0f)),
new PointF(pt.X +sizeX +75,sizeZ+pt.Y- sizeZ),
new PointF(pt.X - (sizeX / 2.0f) ,sizeZ+pt.Y-sizeZ)
};
var PtsBack = new PointF[] {
new PointF( (sizeX / 2.0f)+pt.X-sizeX,pt.Y-sizeZ ),
new PointF( (sizeX / 2.0f)+pt.X+sizeX,pt.Y-sizeZ ),
new PointF( (sizeX / 2.0f)+pt.X+sizeX,pt.Y),
new PointF( (sizeX / 2.0f)+pt.X-sizeX,pt.Y)
};
var PtsRight = new PointF[] {
new PointF( PtsFront[1].X, PtsFront[1].Y ),
new PointF( PtsBack[1].X, PtsBack[1].Y ),
new PointF( PtsBack[2].X, PtsBack[2].Y ),
new PointF( PtsFront[2].X, PtsFront[2].Y )
};
var PtsLeft = new PointF[] {
new PointF( PtsFront[0].X, PtsFront[0].Y ),
new PointF( PtsBack[0].X, PtsBack[0].Y ),
new PointF( PtsBack[3].X, PtsBack[3].Y ),
new PointF( PtsFront[3].X, PtsFront[3].Y )
};
//foreach (var p in PtsBottom)
//{
// var xx = p.X - 5;
// var yy = p.Y - 5;
// var ww = 10;
// var hh = 10;
// g.DrawEllipse(Pens.Red, xx, yy, ww, hh);
//}
//바닥면 출력
g.FillPolygon(new SolidBrush(Color.FromArgb(150, Color.White)), PtsBottom);
g.DrawPolygon(Pens.Black, PtsBottom);
//윗면 출력
g.FillPolygon(new SolidBrush(Color.FromArgb(50, Color.White)), PtsTop);
////뒷면먼저출력
g.FillPolygon(new SolidBrush(Color.FromArgb(50, Color.White)), PtsBack);
////우측출력
g.FillPolygon(new SolidBrush(Color.FromArgb(10, Color.White)), PtsRight);
////좌측출력
g.FillPolygon(new SolidBrush(Color.FromArgb(10, Color.White)), PtsLeft);
//안전커버 뒷
var coverPadding = 10;
var coverYOffset = -30;
var coverLYOffset = 0;
var coverRYOffset = 0;
if (LimitRD == true) coverRYOffset = 20;
else if (LimitRU == true) coverRYOffset = coverYOffset;
if (LimitLD == true) coverLYOffset = 20;
else if (LimitLU == true) coverLYOffset = coverYOffset;
var PtsCoverBack = new PointF[] {
new PointF( PtsBack[0].X+coverPadding, PtsBack[0].Y+coverLYOffset ),
new PointF( PtsBack[1].X-coverPadding, PtsBack[1].Y+coverLYOffset ),
new PointF( PtsBack[2].X-coverPadding, PtsBack[2].Y+coverLYOffset ),
new PointF( PtsBack[3].X+coverPadding, PtsBack[3].Y+coverLYOffset )
};
var PtsCoverFront = new PointF[] {
new PointF( PtsFront[0].X+coverPadding, PtsFront[0].Y+coverRYOffset ),
new PointF( PtsFront[1].X-coverPadding, PtsFront[1].Y+coverRYOffset ),
new PointF( PtsFront[2].X-coverPadding, PtsFront[2].Y+coverRYOffset ),
new PointF( PtsFront[3].X+coverPadding, PtsFront[3].Y+coverRYOffset )
};
if (LimitLU == true)
{
g.FillPolygon(new SolidBrush(Color.FromArgb(100, Color.Red)), PtsCoverBack);
g.DrawPolygon(new Pen(Color.DarkRed, 2), PtsCoverBack);
}
else if (LimitLD == true)
{
g.FillPolygon(new SolidBrush(Color.FromArgb(100, Color.Blue)), PtsCoverBack);
g.DrawPolygon(new Pen(Color.DarkBlue, 2), PtsCoverBack);
}
else
{
g.FillPolygon(new SolidBrush(Color.FromArgb(100, Color.Gray)), PtsCoverBack);
g.DrawPolygon(Pens.DimGray, PtsCoverBack);
}
//g.DrawPolygon(Pens.Orange, PtsCoverBack);
g.FillPolygon(new SolidBrush(Color.FromArgb(50, Color.White)), PtsFront);
// g.DrawPolygon(Pens.Black, PtsFront);
if (LimitRU == true)
{
g.FillPolygon(new SolidBrush(Color.FromArgb(150, Color.Red)), PtsCoverFront);
g.DrawPolygon(new Pen(Color.DarkRed, 2), PtsCoverFront);
}
else if (LimitRD == true)
{
g.FillPolygon(new SolidBrush(Color.FromArgb(150, Color.Blue)), PtsCoverFront);
g.DrawPolygon(new Pen(Color.DarkBlue, 2), PtsCoverFront);
}
else
{
g.FillPolygon(new SolidBrush(Color.FromArgb(150, Color.Gray)), PtsCoverFront);
g.DrawPolygon(Pens.DimGray, PtsCoverFront);
}
//중앙포인트
g.FillEllipse(Brushes.White, pt.X - 2, pt.Y - 2, 4f, 4f);
////button - start
//var buttonSize = 15;
//var offset = 10;
//g.FillEllipse(Brushes.Red, offset * 2.7f + PtsTop[0].X - buttonSize / 2.0f, -offset + PtsTop[0].Y - buttonSize / 2.0f, buttonSize, buttonSize);
//g.DrawEllipse(Pens.Black, offset * 2.7f + PtsTop[0].X - buttonSize / 2.0f, -offset + PtsTop[0].Y - buttonSize / 2.0f, buttonSize, buttonSize);
//g.FillEllipse(Brushes.Blue, offset * 4.2f + PtsTop[0].X - buttonSize / 2.0f, -offset*2.5f + PtsTop[0].Y - buttonSize / 2.0f, buttonSize, buttonSize);
//g.DrawEllipse(Pens.Black, offset * 4.2f + PtsTop[0].X - buttonSize / 2.0f, -offset * 2.5f + PtsTop[0].Y - buttonSize / 2.0f, buttonSize, buttonSize);
//g.FillEllipse(Brushes.Green, offset * 5.5f + PtsTop[0].X - buttonSize / 2.0f, -offset * 4.0f + PtsTop[0].Y - buttonSize / 2.0f, buttonSize, buttonSize);
//g.DrawEllipse(Pens.Black, offset * 5.5f + PtsTop[0].X - buttonSize / 2.0f, -offset * 4.0f + PtsTop[0].Y - buttonSize / 2.0f, buttonSize, buttonSize);
}
//void DrawBattery(Graphics g)
//{
// //우측 끝에 세로로 표시한다
// int r = 10;
// int w = 25;
// int y = 10;
// Rectangle rect = new Rectangle(DisplayRectangle.Right - w - r, y, w, DisplayRectangle.Height - (y * 2));
// var ph = (this.ChargeLevel / 100.0) * rect.Height;
// Rectangle rectp = new Rectangle(rect.Left, (int)(rect.Top + rect.Height - ph), rect.Width, (int)ph);
// Color pColor = Color.Gold;
// if (ChargeLevel <= 40) pColor = Color.Tomato;
// else if (ChargeLevel >= 80) pColor = Color.Lime;
// if (rectp.Height > 1)
// {
// using (LinearGradientBrush b = new LinearGradientBrush(rectp, pColor, Color.FromArgb(150, 150, 150), LinearGradientMode.Vertical))
// g.FillRectangle(b, rectp);
// }
// //for (int i = 1; i < 10; i++)
// //{
// // var ly = (int)( rect.Height * ((i*1.0) / 10.0) );
// // g.DrawLine(Pens.Gray, rect.Left, rect.Top + ly, rect.Right, rect.Top + ly);
// // g.DrawString((10-i).ToString(), this.Font, Brushes.Gray, rect.Left+5, ly+5);
// //}
// //전체테두리
// using (Pen p = new Pen(Color.FromArgb(100, Color.Black)))
// g.DrawRectangle(p, rect);
//}
public class item
{
public bool Enable_Direction { get; set; }
public Color BackColor1 { get; set; }
public Color BackColor2 { get; set; }
public Color ForeColor { get; set; }
public Color ShadowColor { get; set; }
public Color BorderColor { get; set; }
public Color RightColor { get; set; }
public Color LeftColor { get; set; }
[Browsable(false)]
public Rectangle fullrect { get; set; }
[Browsable(false)]
public Rectangle leftrect { get; set; }
[Browsable(false)]
public Rectangle rightrect { get; set; }
public item()
{
BorderColor = Color.FromArgb(100, 100, 100);
fullrect = Rectangle.Empty;
leftrect = Rectangle.Empty;
rightrect = Rectangle.Empty;
BackColor1 = Color.White;
BackColor2 = Color.Transparent;
ForeColor = Color.DimGray;
ShadowColor = Color.Black;
Enable_Direction = true;
}
public string Title { get; set; }
public void Draw(Graphics g, Font font, StringFormat sf)
{
Pen pen_border = null;
LinearGradientBrush br_back = null;
SolidBrush br_text = null;
//펜
if (pen_border == null) pen_border = new Pen(this.BorderColor);
else pen_border.Color = this.BorderColor;
//배경브러쉬
if (br_back == null) br_back = new LinearGradientBrush(this.fullrect, this.BackColor1, this.BackColor2, LinearGradientMode.Vertical);
else
{
br_back.LinearColors[0] = this.BackColor1;
br_back.LinearColors[1] = this.BackColor2;
}
//제목브러쉬
if (br_text == null) br_text = new SolidBrush(this.ForeColor);
else br_text.Color = this.ForeColor;
//배경표시
g.FillRectangle(br_back, this.fullrect);
//제목표시
if (this.Title.isEmpty() == false)
{
if (this.ShadowColor != Color.Transparent && this.ShadowColor != this.ForeColor)
{
using (var brShadow = new SolidBrush(this.ShadowColor))
g.DrawString(
this.Title,
font, brShadow,
new Rectangle(
this.fullrect.Left + 1,
this.fullrect.Top + 1,
this.fullrect.Width,
this.fullrect.Height),
sf);
}
g.DrawString(this.Title, font, br_text, this.fullrect, sf);
g.DrawString(this.Title, font, br_text, this.fullrect, sf);
}
//테두리표시
g.DrawRectangle(pen_border, this.fullrect);
if (Enable_Direction)
{
//좌측테두리
if (this.leftrect.IsEmpty == false)
{
if (this.LeftColor != Color.Transparent)
{
using (SolidBrush sb = new SolidBrush(this.LeftColor))
g.FillRectangle(sb, this.leftrect);
}
g.DrawRectangle(pen_border, this.leftrect);
}
//우측테두리
if (this.rightrect.IsEmpty == false)
{
if (this.RightColor != Color.Transparent)
{
using (SolidBrush sb = new SolidBrush(this.RightColor))
g.FillRectangle(sb, this.rightrect);
}
g.DrawRectangle(pen_border, this.rightrect);
}
}
if (pen_border != null) pen_border.Dispose();
if (br_back != null) br_back.Dispose();
if (br_text != null) br_text.Dispose();
}
}
public class ItemClickEventArgs : EventArgs
{
public item Item { get; set; }
public ItemClickEventArgs(item item)
{
this.Item = item;
}
}
void arButton_MouseLeave(object sender, EventArgs e)
{
//isMouseOver = false;
this.Cursor = Cursors.Default;
Invalidate();
}
void arButton_MouseEnter(object sender, EventArgs e)
{
//isMouseOver = true;
//this.Cursor = Cursors.Hand;
Invalidate();
}
void arButton_MouseUp(object sender, MouseEventArgs e)
{
if (!Enabled)
{
return;
}
// isMouseDown = false;
Invalidate();
}
void arButton_MouseDown(object sender, MouseEventArgs e)
{
if (Enabled == false || Enabled == false) return;
// isMouseDown = true;
//item fullrect 에서 클릭위치를 찾아야함
if (Items != null && Items.Length > 0)
{
//마우스위치가 아이템에 포함되어있다면
var focusItem = Items.Where(t => t.fullrect.Contains(e.Location)).FirstOrDefault();
if (focusItem != null)
{
ItemClick?.Invoke(this, new ItemClickEventArgs(focusItem));
}
}
if (Buttons.Any())
{
//마우스위치가 아이템에 포함되어있다면
var focusItem = Buttons.Where(t => t.rect.Contains(e.Location)).FirstOrDefault();
if (focusItem != null)
{
//ItemClick?.Invoke(this, new ItemClickEventArgs(focusItem));
ButtonClick?.Invoke(focusItem);
}
}
Invalidate();
}
}
}