Initial commit

This commit is contained in:
ChiKyun Kim
2025-07-17 16:11:46 +09:00
parent 4865711adc
commit 4a1b1924ba
743 changed files with 230954 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
namespace UIControl
{
partial class CtlBase
{
/// <summary>
/// 필수 디자이너 변수입니다.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 사용 중인 모든 리소스를 정리합니다.
/// </summary>
/// <param name="disposing">관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 디자이너 지원에 필요한 메서드입니다.
/// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}

View File

@@ -0,0 +1,109 @@
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 UIControl
{
[TypeConverterAttribute(typeof(ExpandableObjectConverter))]
public class PinInfo
{
public int PinIndex { get; set; }
public Boolean PinLevel { get; set; }
public Boolean Output { get; set; }
public eValueDirection ValueDirection { get; set; }
public Boolean Value
{
get
{
if (PinLevel == false) return !Raw;
else return Raw;
}
}
private Boolean _raw = false;
public Boolean Raw
{
get { return _raw; }
set
{
Boolean changed = _raw != value;
_raw = value;
if (changed && ValueChanged != null)
{
ValueChanged(this, new EventArgs());
}
}
}
public PinInfo(Boolean isOutput = false)
{
_raw = false;
PinIndex = -1;
PinLevel = true;
Output = isOutput;
ValueDirection = eValueDirection.input;
}
public event EventHandler ValueChanged;
}
public enum eValueDirection
{
input = 0,
output,
}
public abstract partial class CtlBase : Control
{
Boolean bRemakeRect ;
public List<PinInfo> PinList;
public CtlBase()
{
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);
this.SetStyle(ControlStyles.ContainerControl, false);
this.SetStyle(ControlStyles.Selectable, true);
PinList = new List<PinInfo>();
bRemakeRect = true;
this.Resize += Loader_Resize;
}
public abstract void MakeRect();
public abstract void UpdateValue();
protected void SetPinCount(int iCnt)
{
this.PinList = new List<PinInfo>(iCnt);
for (int i = 0; i < iCnt; i++)
PinList.Add(new PinInfo());
}
void Loader_Resize(object sender, EventArgs e)
{
bRemakeRect = true;
}
protected override void OnPaint(PaintEventArgs pe)
{
if (bRemakeRect)
{
MakeRect();
bRemakeRect = false;
}
base.OnPaint(pe);
}
}
}

View File

@@ -0,0 +1,36 @@
namespace UIControl
{
partial class CtlContainer
{
/// <summary>
/// 필수 디자이너 변수입니다.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 사용 중인 모든 리소스를 정리합니다.
/// </summary>
/// <param name="disposing">관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 디자이너 지원에 필요한 메서드입니다.
/// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}

View File

@@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace UIControl
{
public partial class CtlContainer : GroupBox
{
arDev.AjinEXTEK.Emulator.CEmuleDIO devIO;
arDev.AjinEXTEK.Emulator.CEmulMOT devMOT;
public CtlContainer()
{
InitializeComponent();
}
public void updateControl()
{
updateControl(this.Controls);
}
public void setDevice(arDev.AjinEXTEK.Emulator.CEmuleDIO dio, arDev.AjinEXTEK.Emulator.CEmulMOT mot)
{
this.devIO = dio;
this.devMOT = mot;
}
public void updateControl(System.Windows.Forms.Control.ControlCollection ctl)
{
if (devIO == null && devMOT == null) throw new Exception("디바이스(IO/MOT)가 설정되지 않았습니다");
foreach (Control c in ctl)
{
if (c.HasChildren)
{
updateControl(c.Controls);
}
else if (c is UIControl.CtlBase)
{
var cc = c as UIControl.CtlBase;
foreach (var pin in cc.PinList)
{
if (pin.PinIndex != -1)
{
if (pin.ValueDirection == UIControl.eValueDirection.input)
{
//io의 값을 컨트롤에 적용해줘야한다
if (pin.Output)
{
pin.Raw = devIO.Output[pin.PinIndex];
}
else
{
pin.Raw = devIO.Input[pin.PinIndex];
}
}
else
{
//컨트롤의 값을 io에 적용해줘야 한다
if (pin.Output)
{
//devIO.Output[pin.PinIndex] = pin.Value;
devIO.SetOutput(pin.PinIndex, pin.Value);
}
else
{
// devIO.Input[pin.PinIndex] = pin.Value;
devIO.SetInput(pin.PinIndex, pin.Value);
}
}
}
}
cc.UpdateValue();
cc.Invalidate();
}
}
}
}
}

View File

@@ -0,0 +1,36 @@
namespace UIControl
{
partial class CtlCylinder
{
/// <summary>
/// 필수 디자이너 변수입니다.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 사용 중인 모든 리소스를 정리합니다.
/// </summary>
/// <param name="disposing">관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 디자이너 지원에 필요한 메서드입니다.
/// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}

View File

@@ -0,0 +1,261 @@
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 UIControl
{
public partial class CtlCylinder : CtlBase
{
// string text_;
Font font_ = new Font("맑은 고딕", 10);
public enum eSensorType
{
= 0,
,
}
private eSensorType _arsensortype = eSensorType.;
public eSensorType arSensorType
{
get
{
return _arsensortype;
}
set
{
_arsensortype = value;
this.Invalidate();
}
}
[Browsable(true)]
public new Font Font { get { return font_; } set { font_ = value; this.Invalidate(); } }
public CtlCylinder()
{
InitializeComponent();
SetPinCount(4); //입력2개 출력2개
arOutputMax.ValueDirection = eValueDirection.output;
arOutputMin.ValueDirection = eValueDirection.output;
if (arVel == 0) arVel = 50;
//실린더 가동핀은 변경되면 시작시간을 업데이트해줘야 한다
PinList[0].ValueChanged += (s1, e1) => { RunStartTimeMax = DateTime.Now; };
PinList[1].ValueChanged += (s1, e1) => { RunStartTimeMin = DateTime.Now; };
}
public override void MakeRect()
{
}
public int arLength = 100;
public int arVel { get; set; }
public DateTime RunStartTimeMin = DateTime.Now;
public DateTime RunStartTimeMax = DateTime.Now;
// public TimeSpan arRunSec = new TimeSpan(0);
private double arRunLen = 0;
public double arProgress
{
get
{
var val = (arRunLen / (arLength * 1.0) * 100.0);
if (val > 100.0) val = 100;
return val;
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public PinInfo arOutputMax { get { return PinList[2]; } set { PinList[2] = value; } }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public PinInfo arOutputMin { get { return PinList[3]; } set { PinList[3] = value; } }
//Boolean aron1_ = false;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public PinInfo arInput1
{
get
{
return PinList[0];
}
set
{
//if (value != aron1_) RunStartTimeMax = DateTime.Now;
PinList[0] = value;
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public PinInfo arInput2
{
get
{
return PinList[1];
}
set
{
// if (value != aron2_) RunStartTimeMin = DateTime.Now;
PinList[1] = value;
this.Invalidate();
}
}
public Rectangle arRectProgress { get; set; }
public override void UpdateValue()
{
//둘다 켜져잇거나 거져잇다면 작동하지 않는다
if (arInput1 != arInput2)
{
if (arSensorType == eSensorType.)
{
var ts = DateTime.Now - RunStartTimeMax;
//단동은 1번 센서의 on/off 로 처리한다
if (arInput1.Value)
{
//경과시간만큼 MAX로 이동한다
arRunLen += ts.TotalSeconds * arVel;
}
else
{
//경과시간만큼 MIN으로 이동한다
arRunLen -= ts.TotalSeconds * arVel;
}
RunStartTimeMax = DateTime.Now;
}
else
{
//복동은 1번센서는 Max로 2번센서는 Min으로 이동시킨다
if (arInput1.Value)
{
var ts = DateTime.Now - RunStartTimeMax;
arRunLen += ts.TotalSeconds * arVel;
RunStartTimeMax = DateTime.Now;
}
else if (arInput2.Value)
{
var ts = DateTime.Now - RunStartTimeMin;
arRunLen -= ts.TotalSeconds * arVel;
RunStartTimeMin = DateTime.Now;
}
}
}
if (arRunLen > arLength) arRunLen = arLength;
if (arRunLen < 1) arRunLen = 0;
arOutputMax.Raw = arProgress >= 99.9;
arOutputMin.Raw = arProgress <= 0.1;
// public Boolean arMax { get { return arProgress >= 99.9; } }
//public Boolean arMin { get { return arProgress <= 0.1; } }
}
protected override void OnPaint(PaintEventArgs pe)
{ // base.OnPaint(pe);
pe.Graphics.DrawRectangle(Pens.Gray, DisplayRectangle.Left, DisplayRectangle.Top, DisplayRectangle.Width - 1, DisplayRectangle.Height - 1);
var baseRect = new Rectangle(DisplayRectangle.Left + Padding.Left,
DisplayRectangle.Top + Padding.Top,
DisplayRectangle.Width - Padding.Left - Padding.Right,
DisplayRectangle.Height - Padding.Top - Padding.Bottom);
//pe.Graphics.DrawRect(baseRect, Color.Blue, 1);
//사각형안에 사각형이 움직이는 걸로 하며 . 기본 H 배치한다
var rectH = (int)(baseRect.Height * 0.6);
var rectOut = new Rectangle(baseRect.Left,
(int)(baseRect.Top + (baseRect.Height - rectH) / 2.0),
(int)(baseRect.Width), rectH);
var InOffset = (int)(baseRect.Height * 0.15);
//var rectIn = new Rectangle(rectOut.Right, rectOut.Top + InOffset,
// DisplayRectangle.Width - rectOut.Width - 2, rectOut.Height - (InOffset * 2));
//진행율(%)
var progress = (arProgress / 100.0) * rectOut.Width;
var PWid = 10;
var rectP = new Rectangle((int)(progress - PWid + baseRect.Left), baseRect.Top, PWid, baseRect.Height);
pe.Graphics.FillRectangle(Brushes.Gray, rectOut);
pe.Graphics.DrawRect(rectOut, Color.Black, 2);
//pe.Graphics.DrawRect(rectIn, Color.Black, 2);
if (this.arOutputMax.Value)
pe.Graphics.FillRectangle(Brushes.Red, rectP);
else if (this.arOutputMin.Value)
pe.Graphics.FillRectangle(Brushes.Blue, rectP);
else
pe.Graphics.FillRectangle(Brushes.Gold, rectP);
pe.Graphics.DrawRect(rectP, Color.Black, 2);
//가동상태를 상단에 표시한다
var StSize = 10;// baseRect.Height * 0.15f;
var rectp1 = new RectangleF(
this.DisplayRectangle.Right - StSize - 3,
DisplayRectangle.Top + 3,
StSize, StSize
);
if (arInput1.Value)
pe.Graphics.FillRectangle(Brushes.Red, rectp1);
else
pe.Graphics.FillRectangle(Brushes.Gray, rectp1);
pe.Graphics.DrawRect(rectp1, Color.White);
if (arSensorType == eSensorType.)
{
var rectp2 = new RectangleF(
this.DisplayRectangle.Right - StSize - 3,
DisplayRectangle.Bottom - StSize - 3,
StSize, StSize
);
if (arInput2.Value)
pe.Graphics.FillRectangle(Brushes.Red, rectp2);
else
pe.Graphics.FillRectangle(Brushes.Gray, rectp2);
pe.Graphics.DrawRect(rectp2, Color.White);
}
// if (arMin)
// {
// pe.Graphics.DrawString("MIN", this.Font, Brushes.Black, rectOut,
// new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
// }
// else if(arMax)
// {
// pe.Graphics.DrawString("MAX", this.Font, Brushes.Black, rectOut,
//new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
// }
// else
// {
// pe.Graphics.DrawString(arProgress.ToString("N0")+"%", this.Font, Brushes.Black, rectOut,
//new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
// }
if (string.IsNullOrEmpty(Text) == false)
{
pe.Graphics.DrawString(Text + "\n" + progress.ToString(),
this.Font,
Brushes.Black,
rectOut,
new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
}
}
}
}

View File

@@ -0,0 +1,41 @@
namespace UIControl
{
partial class CtlMotor
{
/// <summary>
/// 필수 디자이너 변수입니다.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 사용 중인 모든 리소스를 정리합니다.
/// </summary>
/// <param name="disposing">관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 디자이너 지원에 필요한 메서드입니다.
/// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// CtlMotor
//
this.ResumeLayout(false);
}
#endregion
}
}

View File

@@ -0,0 +1,181 @@
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 UIControl
{
public partial class CtlMotor : CtlBase
{
public int Length { get; set; }
//public Boolean Pin_Run { get; set; }
//public Boolean Pin_DirCW { get; set; }
//public Boolean Pin_Max { get; set; }
//public Boolean Pin_Min { get; set; }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public PinInfo Pin_Run { get { return PinList[0]; } set { this.PinList[0] = value; } }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public PinInfo Pin_DirCW { get { return PinList[1]; } set { this.PinList[1] = value; } }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public PinInfo Pin_Max { get { return PinList[2]; } set { this.PinList[2] = value; } }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public PinInfo Pin_Min { get { return PinList[3]; } set { this.PinList[3] = value; } }
public Boolean speed { get; set; }
Font font_ = new Font("맑은 고딕", 10);
[Browsable(true)]
public new Font Font { get { return font_; } set { font_ = value; this.Invalidate(); } }
public CtlMotor()
{
InitializeComponent();
SetPinCount(4);
Length = 100;
this.Size = new Size(80, 80);
this.MaximumSize = new Size(80, 80);
this.MinimumSize = new Size(40, 40);
if (this.Font == null) this.Font = new Font("맑은 고딕", 10);
if (this.Text == null) this.Text = string.Empty;
}
public override void MakeRect()
{
}
public override void UpdateValue()
{
}
int anim = 0;
protected override void OnPaint(PaintEventArgs pe)
{
pe.Graphics.DrawRectangle(Pens.Gray, DisplayRectangle.Left, DisplayRectangle.Top, DisplayRectangle.Width - 1, DisplayRectangle.Height - 1);
var rect = new Rectangle(DisplayRectangle.Left + 2, DisplayRectangle.Top + 2, 10, 10);
var rect2 = new Rectangle(DisplayRectangle.Right - 2 - 10, DisplayRectangle.Top + 2, 10, 10);
//모터영역을 그린다.
var rectO = new RectangleF(
DisplayRectangle.Left + Padding.Left,
DisplayRectangle.Top + Padding.Top,
DisplayRectangle.Width * 0.6f,
DisplayRectangle.Height - Padding.Top - Padding.Bottom);
var rectiH = rectO.Height * 0.6f;
var rectI = new RectangleF(
rectO.Left,
rectO.Top + (rectO.Height - rectiH) / 2.0f,
DisplayRectangle.Width - Padding.Left- Padding.Right,
rectiH
);
if (this.Pin_Run.Value)
{
if (this.Pin_DirCW.Value)
{
if (anim % 2 == 0)
pe.Graphics.FillRectangle(Brushes.Lime, rectI);
else
pe.Graphics.FillRectangle(Brushes.Yellow, rectI);
pe.Graphics.DrawRectangle(Pens.Black, rectI);
}
else
{
if (anim % 2 == 0)
pe.Graphics.FillRectangle(Brushes.Lime, rectI);
else
pe.Graphics.FillRectangle(Brushes.Blue, rectI);
pe.Graphics.DrawRectangle(Pens.Black, rectI);
}
}
else
{
pe.Graphics.FillRectangle(Brushes.Red, rectI);
pe.Graphics.DrawRectangle(Pens.Black, rectI);
}
pe.Graphics.DrawRect(rectI, Color.Black, 2);
pe.Graphics.FillRectangle(Brushes.Gray, rectO);
pe.Graphics.DrawRect(rectO, Color.Black, 2);
//기어를 그린다.
Point SPT = new Point(30, 10);
int GearSize = 20;
List<PointF> pts = new List<PointF>();
pts.Add(new PointF(SPT.X, SPT.Y));
pts.Add(new PointF(SPT.X + GearSize, SPT.Y));
pts.Add(new PointF(SPT.X + GearSize, SPT.Y + GearSize));
pts.Add(new PointF(SPT.X, SPT.Y + GearSize));
pts.Add(pts[0]);
var CenterPT = new PointF((pts[1].X - pts[0].X) / 2.0f + pts[0].X, (pts[2].Y - pts[0].Y) / 2.0f + pts[0].Y);
var anglepts = GetAnglePonit(pts.ToArray(), PointF.Empty, 1);
var degree = 4;
var rad = degree * (Math.PI / 180);
// pe.Graphics.DrawPolygon(Pens.Blue, anglepts.ToArray());
//pe.Graphics.DrawLine(Pens.Red, CenterPT.X - 10, CenterPT.Y, CenterPT.X + 10, CenterPT.Y);
//pe.Graphics.DrawLine(Pens.Red, CenterPT.X, CenterPT.Y - 10, CenterPT.X, CenterPT.Y + 10);
if (string.IsNullOrEmpty(Text) == false)
{
pe.Graphics.DrawString(Text ,
this.Font,
Brushes.Black,
rectO,
new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
}
anim += 1;
}
List<PointF> GetAnglePonit(PointF[] array, PointF cpt, double degree)
{
if (degree > 360)
{
var mok = (int)(degree / 360.0);
degree = degree - (360 * mok);
if (degree > 180) degree *= -1;
}
var rad = degree * (Math.PI / 180);
var retval = new List<PointF>();
var x = array[0].X;// (Math.Cos(rad) * (CPT.X - array[0].X)) + (-Math.Sin(rad) * (CPT.Y - array[0].Y));
var y = array[0].Y;// (Math.Sin(rad) * (CPT.X - array[0].X)) + (Math.Cos(rad) * (CPT.Y - array[0].Y));
foreach (var p in array)
{
//변환해서 넣어줘야함
var x1 = (p.X - cpt.X) * Math.Cos(rad) - (p.Y - cpt.Y) * Math.Sign(rad) + cpt.X;
var y1 = (p.X - cpt.X) * Math.Sign(rad) + (p.Y - cpt.Y) * Math.Cos(rad) + cpt.Y;
retval.Add(new PointF((float)(x1), (float)(y1)));
}
return retval;
}
}
}

View File

@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
</root>

View File

@@ -0,0 +1,36 @@
namespace UIControl
{
partial class CtlSensor
{
/// <summary>
/// 필수 디자이너 변수입니다.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 사용 중인 모든 리소스를 정리합니다.
/// </summary>
/// <param name="disposing">관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 디자이너 지원에 필요한 메서드입니다.
/// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}

View File

@@ -0,0 +1,88 @@
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 UIControl
{
public partial class CtlSensor : CtlBase
{
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public PinInfo arPin { get { return PinList[0]; } set { PinList[0] = value; } }
Font font_ = new Font("맑은 고딕", 10);
[Browsable(true)]
public new Font Font { get { return font_; } set { font_ = value; this.Invalidate(); } }
public Boolean RectShape { get; set; }
public Color ColorOn { get; set; }
public Color ColorOff { get; set; }
public CtlSensor()
{
InitializeComponent();
SetPinCount(1);
//this.MaximumSize = new Size(80, 80);
this.MinimumSize = new Size(4, 4);
this.ColorOn = Color.Lime;
this.ColorOff = Color.DimGray;
//if (this.Font == null) this.Font = new Font("맑은 고딕", 10);
//if (this.Text == null) this.Text = string.Empty;
}
public override void MakeRect()
{
}
public override void UpdateValue()
{
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
pe.Graphics.DrawRectangle(Pens.Gray, DisplayRectangle.Left, DisplayRectangle.Top, DisplayRectangle.Width - 1, DisplayRectangle.Height - 1);
var baseRect = new Rectangle(DisplayRectangle.Left + Padding.Left,
DisplayRectangle.Top + Padding.Top,
DisplayRectangle.Width - Padding.Left - Padding.Right,
DisplayRectangle.Height - Padding.Top - Padding.Bottom);
var rect = new Rectangle(baseRect.Left + 1, baseRect.Top + 1, baseRect.Width - 2, baseRect.Height - 2);
if (RectShape)
{
if (arPin.Value) pe.Graphics.FillRectangle(new SolidBrush(ColorOn), rect);
else pe.Graphics.FillRectangle(new SolidBrush(ColorOff), rect);
pe.Graphics.DrawRectangle(Pens.Black, rect);
}
else
{
if (arPin.Value) pe.Graphics.FillEllipse(new SolidBrush(ColorOn), rect);
else pe.Graphics.FillEllipse(new SolidBrush(ColorOff), rect);
pe.Graphics.DrawEllipse(Pens.Black, rect);
}
if (string.IsNullOrEmpty(Text) == false)
{
pe.Graphics.DrawString(Text,
this.Font,
Brushes.Black,
baseRect,
new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
}
}
}
}

View File

@@ -0,0 +1,36 @@
namespace UIControl
{
partial class CtlTowerLamp
{
/// <summary>
/// 필수 디자이너 변수입니다.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 사용 중인 모든 리소스를 정리합니다.
/// </summary>
/// <param name="disposing">관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 디자이너 지원에 필요한 메서드입니다.
/// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}

View File

@@ -0,0 +1,125 @@
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 UIControl
{
public partial class CtlTowerLamp : CtlBase
{
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public PinInfo arPinRed { get { return PinList[0]; } set { PinList[0] = value; } }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public PinInfo arPinYel { get { return PinList[1]; } set { PinList[1] = value; } }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public PinInfo arPinGrn { get { return PinList[2]; } set { PinList[2] = value; } }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public PinInfo arPinBuz { get { return PinList[3]; } set { PinList[3] = value; } }
public CtlTowerLamp()
{
InitializeComponent();
SetPinCount(4);
this.MinimumSize = new Size(4, 4);
}
public override void MakeRect()
{
}
public override void UpdateValue()
{
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
pe.Graphics.DrawRectangle(Pens.Gray, DisplayRectangle.Left, DisplayRectangle.Top, DisplayRectangle.Width - 1, DisplayRectangle.Height - 1);
var baseRect = new Rectangle(DisplayRectangle.Left + Padding.Left,
DisplayRectangle.Top + Padding.Top,
DisplayRectangle.Width - Padding.Left - Padding.Right,
DisplayRectangle.Height - Padding.Top - Padding.Bottom);
//상위 80% 영역을 표시영역으로 사용한ㄷ
var term = 3;
var DispRect = new Rectangle(baseRect.Left, baseRect.Top, baseRect.Width, (int)(baseRect.Height * 0.8f));
var LampHeight = arPinBuz.PinIndex == -1 ? (DispRect.Height - 3 * term) / 3.0f : (DispRect.Height - 4 * term) / 4.0f;
var rectR = new RectangleF(DispRect.Left, DispRect.Top + term, DispRect.Width, LampHeight);
var rectY = new RectangleF(DispRect.Left, rectR.Bottom + term, DispRect.Width, LampHeight);
var rectG = new RectangleF(DispRect.Left, rectY.Bottom + term, DispRect.Width, LampHeight);
var rectB = RectangleF.Empty;
if (arPinBuz.PinIndex != -1)
{
rectB = new RectangleF(DispRect.Left, rectG.Bottom + term, DispRect.Width, LampHeight);
}
var rectCT = new RectangleF(DispRect.Left + (DispRect.Width - 20) / 2.0f, DispRect.Top, 20, baseRect.Height);
pe.Graphics.FillRectangle(Brushes.DimGray, rectCT);
pe.Graphics.DrawRectangle(Pens.Black, rectCT);
if(this.PinList[0].Value)
pe.Graphics.FillRectangle(Brushes.Red, rectR);
else
pe.Graphics.FillRectangle(Brushes.Gray, rectR);
if (this.PinList[1].Value)
pe.Graphics.FillRectangle(Brushes.Gold, rectY);
else
pe.Graphics.FillRectangle(Brushes.Gray, rectY);
if (this.PinList[2].Value)
pe.Graphics.FillRectangle(Brushes.Green, rectG);
else
pe.Graphics.FillRectangle(Brushes.Gray, rectG);
pe.Graphics.DrawRectangle(Pens.Black, rectR);
pe.Graphics.DrawRectangle(Pens.Black, rectY);
pe.Graphics.DrawRectangle(Pens.Black, rectG);
pe.Graphics.DrawString("RED",
this.Font,
Brushes.Black,
rectR,
new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
pe.Graphics.DrawString("YEL",
this.Font,
Brushes.Black,
rectY,
new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
pe.Graphics.DrawString("GRN",
this.Font,
Brushes.Black,
rectG,
new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
if (rectB.IsEmpty == false)
{
if (this.PinList[3].Value)
pe.Graphics.FillRectangle(Brushes.Magenta, rectB);
else
pe.Graphics.FillRectangle(Brushes.Gray, rectB);
pe.Graphics.DrawRectangle(Pens.Black, rectB);
pe.Graphics.DrawString("BUZ",
this.Font,
Brushes.Black,
rectB,
new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
}
}
}
}