2026-06-05 13:44:39 +09:00

217 lines
7.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text.Json;
using System.Xml;
namespace CoreUnit.Control.UserControl.Canvas
{
public class GridLayer : ICanvasLayer, ISerialize
{
public enum eStyle
{
Dots,
Lines,
}
public SizeF m_spacing = new SizeF(10, 10);//(0.001f, 0.001f); // 단위표시는 0.001단위까지 결정됨
private bool m_enabled = true;
private int m_minSize = 15;
private eStyle m_gridStyle = eStyle.Lines;
private Color m_color = Color.White;//Color.FromArgb(50, Color.Gray);
int m_no = 0;
public SizeF Spacing {
get { return m_spacing; }
set { m_spacing = value; }
}
public int MinSize {
get { return m_minSize; }
set { m_minSize = value; }
}
public eStyle GridStyle {
get { return m_gridStyle; }
set { m_gridStyle = value; }
}
public Color Color {
get { return m_color; }
set { m_color = value; }
}
public void Copy(GridLayer acopy)
{
m_enabled = acopy.m_enabled;
m_spacing = acopy.m_spacing;
m_minSize = acopy.m_minSize;
m_gridStyle = acopy.m_gridStyle;
m_color = acopy.m_color;
}
#region ICanvasLayer Members
public void Draw(ICanvas canvas, RectangleF unitrect)
{
if (Enabled == false)
return;
float gridX = Spacing.Width;
float gridY = Spacing.Height;
float gridscreensizeX = canvas.ToScreen(gridX);
float gridscreensizeY = canvas.ToScreen(gridY);
if (gridscreensizeX < MinSize || gridscreensizeY < MinSize)
return;
//// 특정 부분 선택
unitrect = SetSpecificRange(unitrect, canvas.BackgroundSize);
PointF leftpoint = unitrect.Location;
PointF rightpoint = ScreenUtils.RightPoint(canvas, unitrect);
float left = (float)Math.Round(leftpoint.X / gridX) * gridX;
float top = unitrect.Height + unitrect.Y;
float right = rightpoint.X;
float bottom = (float)Math.Round(leftpoint.Y / gridY) * gridY;
if (GridStyle == eStyle.Dots) {
GDI gdi = new GDI();
gdi.BeginGDI(canvas.Graphics);
for (float x = left; x <= right; x += gridX) {
for (float y = bottom; y <= top; y += gridY) {
PointF p1 = canvas.ToScreen(new UnitPoint(x, y));
gdi.SetPixel((int)p1.X, (int)p1.Y, m_color.ToArgb());
}
}
gdi.EndGDI();
}
if (GridStyle == eStyle.Lines) {
//m_color = Color.Black;
//m_color = Color.FromArgb(32,0,0,0);
Pen pen = new Pen(m_color);
pen.DashStyle = DashStyle.Dot;
pen.DashPattern = new float[] { 1f, 10f };
GraphicsPath path = new GraphicsPath();
// draw vertical lines
while (left <= right) {
PointF p1 = canvas.ToScreen(new UnitPoint(left, leftpoint.Y));
PointF p2 = canvas.ToScreen(new UnitPoint(left, rightpoint.Y));
path.AddLine(p1, p2);
path.CloseFigure();
left += gridX;
}
// draw horizontal lines
while (bottom <= top) {
PointF p1 = canvas.ToScreen(new UnitPoint(leftpoint.X, bottom));
PointF p2 = canvas.ToScreen(new UnitPoint(rightpoint.X, bottom));
path.AddLine(p1, p2);
path.CloseFigure();
bottom += gridY;
}
canvas.Graphics.DrawPath(pen, path);
}
}
public int No {
get { return m_no; }
set { m_no = value; }
}
public ISnapPoint SnapPoint(ICanvas canvas, UnitPoint point, List<IDrawObject> otherobj)
{
if (Enabled == false)
return null;
UnitPoint snappoint = new UnitPoint();
UnitPoint mousepoint = point;
float gridX = Spacing.Width;
float gridY = Spacing.Height;
snappoint.X = (float)(Math.Round(mousepoint.X / gridX)) * gridX;
snappoint.Y = (float)(Math.Round(mousepoint.Y / gridY)) * gridY;
double threshold = canvas.ToUnit(/*ThresholdPixel*/6);
if ((snappoint.X < point.X - threshold) || (snappoint.X > point.X + threshold))
return null;
if ((snappoint.Y < point.Y - threshold) || (snappoint.Y > point.Y + threshold))
return null;
return new GridSnapPoint(canvas, snappoint);
}
public List<IDrawObject> Objects {
get { return null; }
}
public bool Enabled {
get { return m_enabled; }
set { m_enabled = value; }
}
public bool Visible {
get { return true; }
}
SolidBrush m_backgroundBrush;
SolidBrush m_fieldBrush;
Color m_backgroundColor = Color.Black;
Color m_fieldColor = Color.White;
public Color BackgroundColor {
get { return m_backgroundColor; }
set {
m_color = value;
m_backgroundColor = value;
m_backgroundBrush = new SolidBrush(m_backgroundColor);
}
}
public Color FieldColor {
get { return m_fieldColor; }
set {
m_fieldColor = value;
m_fieldBrush = new SolidBrush(m_fieldColor);
}
}
#endregion
#region ISerialize
public void GetObjectData(XmlWriter wr)
{
wr.WriteStartElement("gridlayer");
Common.XmlUtil.WriteProperties(this, wr);
wr.WriteEndElement();
}
public virtual string GetObjectData()
{
string jsonString = string.Empty;
var options = new JsonSerializerOptions { WriteIndented = true };
try {
jsonString += JsonSerializer.Serialize(this, options);
} catch {
}
return jsonString;
}
public void AfterSerializedIn()
{
}
#endregion
public RectangleF SetSpecificRange(RectangleF Unitrect, float range)
{
RectangleF unitrect = Unitrect;
//// 우리가 정한 구역은 흰색으로
float maxValue = range / 2, minValue = -range / 2;
if (unitrect.X + unitrect.Width > maxValue && unitrect.X < minValue) {
unitrect.X = minValue;
unitrect.Width = maxValue - minValue;
} else if (unitrect.X + unitrect.Width > maxValue) {
unitrect.Width = maxValue - unitrect.X;
} else if (unitrect.X < minValue) {
unitrect.Width = unitrect.X + unitrect.Width - minValue;
unitrect.X = minValue;
}
//else;
if (unitrect.Y + unitrect.Height > maxValue && unitrect.Y < minValue) {
unitrect.Y = minValue;
unitrect.Height = maxValue - minValue;
} else if (unitrect.Y + unitrect.Height > maxValue) unitrect.Height = maxValue - unitrect.Y;
else if (unitrect.Y < minValue) { unitrect.Height = unitrect.Y + unitrect.Height - minValue; unitrect.Y = minValue; }
//else;
return unitrect;
}
}
}