1052 lines
37 KiB
C#
1052 lines
37 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text.Json;
|
|
using System.Xml;
|
|
using static CoreUnit.Control.UserControl.Canvas.ZigZag;
|
|
|
|
namespace CoreUnit.Control.UserControl.Canvas
|
|
{
|
|
public class AddObjectParam
|
|
{
|
|
public string ObjectType;
|
|
public UnitPoint Point1;
|
|
public UnitPoint Point2;
|
|
public UnitPoint Center;
|
|
public float StartAngle;
|
|
public float EndAngle;
|
|
public float SweepAngle;
|
|
public string Direction;
|
|
public float MajorRadius;
|
|
public float MinorRadius;
|
|
public Color Color = Color.White;
|
|
public float RotateAngle;
|
|
|
|
public double Pitch; // 지그재그 간격
|
|
public double Amplitude; // 지그재그 높이
|
|
public double Radius; // 아크 반지름
|
|
public eDrawDirection DrawDirection; // 그리기 방향 (Left/Right 등)
|
|
}
|
|
|
|
public class DataModel : IModel
|
|
{
|
|
static Dictionary<string, Type> m_toolTypes = new Dictionary<string, Type>();
|
|
static public IDrawObject NewDrawObject(string objecttype)
|
|
{
|
|
if (m_toolTypes.ContainsKey(objecttype)) {
|
|
string type = m_toolTypes[objecttype].ToString();
|
|
IDrawObject drawObj = Assembly.GetExecutingAssembly().CreateInstance(type) as IDrawObject;
|
|
return drawObj;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
Dictionary<string, IDrawObject> m_drawObjectTypes = new Dictionary<string, IDrawObject>();
|
|
DrawObjectBase CreateObject(string objecttype)
|
|
{
|
|
if (m_drawObjectTypes.ContainsKey(objecttype)) {
|
|
return m_drawObjectTypes[objecttype].Clone() as DrawObjectBase;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
Dictionary<string, IEditTool> m_editTools = new Dictionary<string, IEditTool>();
|
|
public void AddEditTool(string key, IEditTool tool)
|
|
{
|
|
m_editTools.Add(key, tool);
|
|
}
|
|
|
|
public bool IsDirty {
|
|
get { return m_undoBuffer.Dirty; }
|
|
}
|
|
|
|
UndoRedoBuffer m_undoBuffer = new UndoRedoBuffer();
|
|
|
|
UnitPoint m_centerPoint = UnitPoint.Empty;
|
|
|
|
public UnitPoint CenterPoint {
|
|
get { return m_centerPoint; }
|
|
set { m_centerPoint = value; }
|
|
}
|
|
|
|
float m_scaleToFit = 0;//zoom fit에 맞는 스케일 값
|
|
public float ScaleToFit {
|
|
get { return m_scaleToFit; }
|
|
set { m_scaleToFit = value; }
|
|
}
|
|
|
|
float m_zoom = 1;
|
|
ICanvasLayer m_gridLayer = new GridLayer();
|
|
ICanvasLayer m_backgroundLayer = new BackgroundLayer();
|
|
List<ICanvasLayer> m_layers = new List<ICanvasLayer>();
|
|
ICanvasLayer m_activeLayer;
|
|
Dictionary<IDrawObject, bool> m_selection = new Dictionary<IDrawObject, bool>();
|
|
|
|
public delegate void EventHandlerCopyObjects(List<IDrawObject> objectList);
|
|
public EventHandlerCopyObjects evtCopyObjects;
|
|
|
|
public delegate void EventHandlerAddObject(IDrawObject obj);
|
|
public EventHandlerAddObject evtAddObject;
|
|
|
|
public delegate void EventHandlerDeleteObjects(List<IDrawObject> objectList);
|
|
public EventHandlerDeleteObjects evtDeleteObjects;
|
|
|
|
public delegate void EventHandlerMoveObjects(List<IDrawObject> originalObjectList, List<IDrawObject> newObjectList);
|
|
public EventHandlerMoveObjects evtMoveObjects;
|
|
|
|
public delegate void EventHandlerMoveNodes(List<INodePoint> nodes);
|
|
public EventHandlerMoveNodes evtMoveNodes;
|
|
|
|
public delegate void EventHandlerSelectObjects(List<IDrawObject> objects);
|
|
public EventHandlerSelectObjects evtSelectObjects;
|
|
|
|
public delegate void EventHandlerDeselectAllObjects();
|
|
public EventHandlerDeselectAllObjects evtDeselectAllObjects;
|
|
|
|
public delegate void EventHandlerRedo();
|
|
public EventHandlerRedo evtRedo;
|
|
|
|
public delegate void EventHandlerUndo();
|
|
public EventHandlerUndo evtUndo;
|
|
|
|
public DataModel()
|
|
{
|
|
m_toolTypes.Clear();
|
|
|
|
m_toolTypes[Line.ObjectType] = typeof(Line);
|
|
m_toolTypes[Circle.ObjectType] = typeof(Circle);
|
|
m_toolTypes[Arc.ObjectType] = typeof(Arc);
|
|
m_toolTypes[Arc3Point.ObjectType] = typeof(Arc3Point);
|
|
m_toolTypes[Dot.ObjectType] = typeof(Dot);
|
|
m_toolTypes[Spline.ObjectType] = typeof(Spline);
|
|
m_toolTypes[SnowMan.ObjectType] = typeof(SnowMan);
|
|
m_toolTypes[ZigZag.ObjectType] = typeof(ZigZag);
|
|
//group tool 타입 생성
|
|
m_toolTypes[Group.ObjectType] = typeof(Group);
|
|
m_toolTypes[EllipseTool.ObjectType] = typeof(EllipseTool);
|
|
m_toolTypes[RectangleTool.ObjectType] = typeof(RectangleTool);
|
|
m_toolTypes[RoiTool.ObjectType] = typeof(RoiTool);
|
|
|
|
m_centerPoint = new UnitPoint(0, 0);
|
|
|
|
DefaultLayer();
|
|
}
|
|
|
|
public void AddDrawTool(string key, IDrawObject drawtool)
|
|
{
|
|
m_drawObjectTypes[key] = drawtool;
|
|
if (!m_toolTypes.ContainsKey(key)) {
|
|
m_toolTypes[key] = drawtool.GetType();
|
|
}
|
|
}
|
|
|
|
void DefaultLayer()
|
|
{
|
|
m_layers.Clear();
|
|
m_layers.Add(new DrawingLayer(m_layers.Count, string.Empty, Color.Black, 0.01f));
|
|
}
|
|
|
|
public IDrawObject GetFirstSelected()
|
|
{
|
|
if (m_selection.Count > 0) {
|
|
Dictionary<IDrawObject, bool>.KeyCollection.Enumerator e = m_selection.Keys.GetEnumerator();
|
|
e.MoveNext();
|
|
return e.Current;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public IDrawObject GetLastSelected()
|
|
{
|
|
if (m_selection.Count > 0) {
|
|
Dictionary<IDrawObject, bool>.KeyCollection.Enumerator e = m_selection.Keys.GetEnumerator();
|
|
IDrawObject drawObject = null;
|
|
while (e.MoveNext()) { drawObject = e.Current; }
|
|
return drawObject;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
#region IModel Members
|
|
|
|
public float Zoom {
|
|
get { return m_zoom; }
|
|
set { m_zoom = value; }
|
|
}
|
|
|
|
public ICanvasLayer BackgroundLayer {
|
|
get { return m_backgroundLayer; }
|
|
set { m_backgroundLayer = value; }
|
|
}
|
|
|
|
public ICanvasLayer GridLayer {
|
|
get { return m_gridLayer; }
|
|
set { m_gridLayer = value; }
|
|
}
|
|
|
|
public ICanvasLayer[] Layers {
|
|
get { return m_layers.ToArray(); }
|
|
set { m_layers = value?.ToList(); }
|
|
}
|
|
|
|
public ICanvasLayer ActiveLayer {
|
|
get {
|
|
if (m_activeLayer == null)
|
|
m_activeLayer = m_layers[0];
|
|
return m_activeLayer;
|
|
}
|
|
set {
|
|
m_activeLayer = value;
|
|
}
|
|
}
|
|
|
|
public ICanvasLayer GetLayer(int no)
|
|
{
|
|
foreach (ICanvasLayer layer in m_layers) {
|
|
if (layer.No == no)
|
|
return layer;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public ICanvasLayer CreateLayer()
|
|
{
|
|
ICanvasLayer layer = new DrawingLayer(m_layers.Count, string.Empty, Color.Black, 0.01f);
|
|
m_layers.Add(layer);
|
|
m_activeLayer = layer;
|
|
return layer;
|
|
}
|
|
|
|
public void DeleteLayer(int no)
|
|
{
|
|
if (m_layers.Count <= 1) {
|
|
throw new Exception("ERR_SCANNER_CANVAS_USER_CONTROL_NOT_DELETE_DEFAULT_LAYER");
|
|
}
|
|
|
|
ICanvasLayer deleteLayer = GetLayer(no);
|
|
m_layers.Remove(deleteLayer);
|
|
|
|
for (int i = 0; i < m_layers.Count; i++) {
|
|
ICanvasLayer layer = m_layers[i];
|
|
layer.No = i;
|
|
}
|
|
|
|
ActiveLayer = m_layers[0];
|
|
}
|
|
|
|
public void ChangeLayer(int no)
|
|
{
|
|
foreach (ICanvasLayer layer in m_layers) {
|
|
if (layer.No == no) {
|
|
ActiveLayer = layer;
|
|
ClearSelectedObjects();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void CopyLayer(int no)
|
|
{
|
|
ICanvasLayer targetLayer = GetLayer(no);
|
|
ICanvasLayer newLayer = CreateLayer();
|
|
((DrawingLayer)newLayer).Copy((DrawingLayer)targetLayer, true);
|
|
}
|
|
public void ReverseLayer(int PageNo, int ListNo, float Length)
|
|
{
|
|
//// 선택된 Parameter 별 Distance 낮추기
|
|
ICanvasLayer targetLayer = GetLayer(PageNo);
|
|
foreach (var obj in targetLayer.Objects) {
|
|
if (obj.ScannerParamID == targetLayer.Objects[ListNo].ScannerParamID) {
|
|
obj.MakeLength(float.Parse(obj.GetInfoAsString().Split()[5].Substring(2)) + Length);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
public void PreHitingCreate(int PageNo, int ListNo)
|
|
{
|
|
// Pre-Hiting Create
|
|
ICanvasLayer targetLayer = GetLayer(PageNo);
|
|
int RecipeNo = 0;
|
|
List<IDrawObject> PreHitingLayer = new List<IDrawObject>();
|
|
foreach (var obj in targetLayer.Objects) {
|
|
if (obj.ScannerParamID == targetLayer.Objects[ListNo].ScannerParamID) {
|
|
IDrawObject TempPreHiting = obj.Clone();
|
|
TempPreHiting.MakeLength(float.Parse(obj.GetInfoAsString().Split()[5].Substring(2)) / 2);
|
|
TempPreHiting.ScannerParamID = 8;
|
|
TempPreHiting.No = RecipeNo;
|
|
PreHitingLayer.Add(TempPreHiting);
|
|
RecipeNo++;
|
|
obj.No = RecipeNo;
|
|
PreHitingLayer.Add(obj);
|
|
RecipeNo++;
|
|
}
|
|
}
|
|
targetLayer.Objects.Clear();
|
|
|
|
for (int i = 0; i < PreHitingLayer.Count; i++) {
|
|
targetLayer.Objects.Add(PreHitingLayer[i]);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
public IDrawObject CreateObject(string type, UnitPoint point, ISnapPoint snappoint)
|
|
{
|
|
DrawingLayer layer = ActiveLayer as DrawingLayer;
|
|
|
|
if (layer.Enabled == false) {
|
|
return null;
|
|
}
|
|
|
|
DrawObjectBase newobj = CreateObject(type);
|
|
|
|
if (newobj != null) {
|
|
(newobj as IDrawObject).No = layer.Objects.Count;
|
|
newobj.Layer = layer;
|
|
newobj.InitializeFromModel(point, layer, snappoint);
|
|
}
|
|
|
|
return newobj as IDrawObject;
|
|
}
|
|
|
|
public void AddObject(ICanvasLayer layer, IDrawObject drawobject, bool useEventMode = true)
|
|
{
|
|
if (drawobject is IObjectEditInstance) {
|
|
drawobject = ((IObjectEditInstance)drawobject).GetDrawObject();
|
|
}
|
|
|
|
if (m_undoBuffer.CanCapture) {
|
|
m_undoBuffer.AddCommand(new EditCommandAdd(layer, drawobject));
|
|
}
|
|
|
|
//객체의 이름을 명명
|
|
drawobject.No = layer.Objects.Count;
|
|
/////////////////////////////////////////////////
|
|
|
|
((DrawingLayer)layer).AddObject(drawobject);
|
|
// 그리자마자 선택됨,
|
|
AddSelectedObject(drawobject);
|
|
|
|
if (useEventMode == true) {
|
|
evtAddObject(drawobject);
|
|
}
|
|
}
|
|
|
|
public void DeleteObjects(List<IDrawObject> objects, bool useEventMode = true)
|
|
{
|
|
if (m_undoBuffer.CanCapture) {
|
|
m_undoBuffer.AddCommand(new EditCommandRemove(ActiveLayer, objects));
|
|
}
|
|
|
|
((DrawingLayer)ActiveLayer).DeleteObjects(objects);
|
|
|
|
//객체 삭제 후 이름을 재 명명(hochul.kim)
|
|
for (int i = 0; i < ActiveLayer.Objects.Count; i++) {
|
|
IDrawObject obj = ActiveLayer.Objects[i];
|
|
obj.No = i;
|
|
}
|
|
/////////////////////////////////////////////////
|
|
|
|
if (useEventMode == true) {
|
|
evtDeleteObjects(objects);
|
|
}
|
|
}
|
|
|
|
public void MoveObjects(UnitPoint offset, List<IDrawObject> objects, bool useEventMode = true)
|
|
{
|
|
if (m_undoBuffer.CanCapture) {
|
|
m_undoBuffer.AddCommand(new EditCommandMove(offset, objects));
|
|
}
|
|
|
|
List<IDrawObject> originalObjects = new List<IDrawObject>();
|
|
foreach (IDrawObject obj in objects) {
|
|
IDrawObject newobj = obj.Clone();
|
|
originalObjects.Add(newobj);
|
|
}
|
|
|
|
foreach (IDrawObject obj in objects) {
|
|
obj.Move(offset);
|
|
}
|
|
|
|
if (useEventMode == true) {
|
|
evtMoveObjects(originalObjects, objects);
|
|
}
|
|
}
|
|
|
|
public void RotateObjects(float angle, List<IDrawObject> objects, bool useObjCenter, bool useEventMode = true)
|
|
{
|
|
if (m_undoBuffer.CanCapture) {
|
|
m_undoBuffer.AddCommand(new EditCommandRotate(angle, objects));
|
|
}
|
|
|
|
// 원본 객체에 대하여 저장함
|
|
List<IDrawObject> originalObjects = new List<IDrawObject>();
|
|
foreach (IDrawObject obj in objects) {
|
|
IDrawObject newobj = obj.Clone();
|
|
originalObjects.Add(newobj);
|
|
}
|
|
|
|
foreach (IDrawObject obj in objects) {
|
|
UnitPoint center = useObjCenter ? new UnitPoint(obj.MiddlePoint.X, obj.MiddlePoint.Y) : new UnitPoint(0, 0);
|
|
obj.Rotate(angle, center);
|
|
}
|
|
|
|
if (useEventMode == true) {
|
|
evtMoveObjects(originalObjects, objects);
|
|
}
|
|
}
|
|
|
|
public void SizeObjects(float distance, List<IDrawObject> objects, bool useEventMode = true)
|
|
{
|
|
if (m_undoBuffer.CanCapture) {
|
|
m_undoBuffer.AddCommand(new EditCommandMakeLength(distance, objects));
|
|
}
|
|
|
|
// 원본 객체에 대하여 저장함
|
|
List<IDrawObject> originalObjects = new List<IDrawObject>();
|
|
foreach (IDrawObject obj in objects) {
|
|
IDrawObject newobj = obj.Clone();
|
|
originalObjects.Add(newobj);
|
|
}
|
|
|
|
foreach (IDrawObject obj in objects) {
|
|
obj.MakeLength(distance);
|
|
}
|
|
|
|
if (useEventMode == true) {
|
|
evtMoveObjects(originalObjects, objects);
|
|
}
|
|
}
|
|
|
|
List<IDrawObject> m_selectedCopyObject;
|
|
public List<IDrawObject> SelectedCopyObject {
|
|
get {
|
|
return m_selectedCopyObject;
|
|
}
|
|
set {
|
|
m_selectedCopyObject = value;
|
|
}
|
|
}
|
|
|
|
bool m_isCopying = false;
|
|
public bool IsArrayCopying {
|
|
get { return m_isCopying; }
|
|
set { m_isCopying = value; }
|
|
}
|
|
|
|
public void AddSelectedObjects(List<IDrawObject> objects)
|
|
{
|
|
foreach (IDrawObject drawobject in objects) {
|
|
DrawObjectBase obj = drawobject as DrawObjectBase;
|
|
RemoveSelectedObject(drawobject);
|
|
m_selection[drawobject] = true;
|
|
obj.Selected = true;
|
|
}
|
|
}
|
|
|
|
int m_copyCnt = 0;
|
|
public int CopyCnt {
|
|
get { return m_copyCnt; }
|
|
set { m_copyCnt = value; }
|
|
}
|
|
|
|
public void CopyObjects(UnitPoint offset, List<IDrawObject> objects, bool useEventMode = true)
|
|
{
|
|
ClearSelectedObjects();
|
|
|
|
List<IDrawObject> newobjects = new List<IDrawObject>();
|
|
|
|
foreach (IDrawObject obj in objects) {
|
|
IDrawObject newobj = obj.Clone();
|
|
newobjects.Add(newobj);
|
|
newobj.Move(offset);
|
|
|
|
AddObject(ActiveLayer, newobj, useEventMode);
|
|
|
|
if (IsArrayCopying) {
|
|
SelectedCopyObject.Add(newobj);
|
|
AddSelectedObjects(SelectedCopyObject);
|
|
} else AddSelectedObject(newobj);
|
|
}
|
|
|
|
if (m_undoBuffer.CanCapture) {
|
|
m_undoBuffer.AddCommand(new EditCommandAdd(ActiveLayer, newobjects));
|
|
}
|
|
|
|
if (useEventMode == true) {
|
|
if (IsArrayCopying) newobjects = SelectedCopyObject;
|
|
|
|
evtCopyObjects(newobjects);
|
|
}
|
|
}
|
|
|
|
public void AfterEditObjects(IEditTool edittool)
|
|
{
|
|
edittool.Finished();
|
|
if (m_undoBuffer.CanCapture) {
|
|
m_undoBuffer.AddCommand(new EditCommandEditTool(edittool));
|
|
}
|
|
}
|
|
|
|
public IEditTool GetEditTool(string edittoolid)
|
|
{
|
|
if (m_editTools.ContainsKey(edittoolid))
|
|
return m_editTools[edittoolid].Clone();
|
|
return null;
|
|
}
|
|
|
|
public void MoveNodes(UnitPoint position, List<INodePoint> nodes, bool useEventMode = true)
|
|
{
|
|
if (m_undoBuffer.CanCapture) {
|
|
m_undoBuffer.AddCommand(new EditCommandNodeMove(nodes));
|
|
}
|
|
|
|
foreach (INodePoint node in nodes) {
|
|
node.SetPosition(position);
|
|
node.Finish();
|
|
}
|
|
|
|
if (useEventMode == true) {
|
|
evtMoveNodes(nodes);
|
|
}
|
|
}
|
|
|
|
public List<IDrawObject> GetHitObjects(ICanvas canvas, RectangleF selection, bool anyPoint)
|
|
{
|
|
List<IDrawObject> selected = new List<IDrawObject>();
|
|
|
|
foreach (IDrawObject drawobject in ActiveLayer.Objects) {
|
|
if (drawobject.ObjectInRectangle(canvas, selection, anyPoint)) {
|
|
selected.Add(drawobject);
|
|
}
|
|
}
|
|
|
|
return selected;
|
|
}
|
|
|
|
public List<IDrawObject> GetHitObjects(ICanvas canvas, UnitPoint point)
|
|
{
|
|
List<IDrawObject> selected = new List<IDrawObject>();
|
|
|
|
foreach (IDrawObject drawobject in ActiveLayer.Objects) {
|
|
if (drawobject.PointInObject(canvas, point)) {
|
|
selected.Add(drawobject);
|
|
}
|
|
}
|
|
|
|
return selected;
|
|
}
|
|
|
|
public bool IsSelected(IDrawObject drawobject)
|
|
{
|
|
return m_selection.ContainsKey(drawobject);
|
|
}
|
|
|
|
public void AddSelectedObject(IDrawObject drawobject)
|
|
{
|
|
DrawObjectBase obj = drawobject as DrawObjectBase;
|
|
RemoveSelectedObject(drawobject);
|
|
m_selection[drawobject] = true;
|
|
obj.Selected = true;
|
|
}
|
|
|
|
public void RemoveSelectedObject(IDrawObject drawobject)
|
|
{
|
|
if (m_selection.ContainsKey(drawobject)) {
|
|
DrawObjectBase obj = drawobject as DrawObjectBase;
|
|
obj.Selected = false;
|
|
m_selection.Remove(drawobject);
|
|
}
|
|
}
|
|
|
|
public List<IDrawObject> SelectedObjects {
|
|
get {
|
|
List<IDrawObject> obj = new List<IDrawObject>();
|
|
obj.AddRange(m_selection.Keys);
|
|
return obj;
|
|
}
|
|
}
|
|
|
|
public int SelectedCount {
|
|
get { return m_selection.Count; }
|
|
}
|
|
|
|
public void ClearSelectedObjects()
|
|
{
|
|
List<IDrawObject> x = SelectedObjects;
|
|
foreach (IDrawObject drawobject in x) {
|
|
DrawObjectBase obj = drawobject as DrawObjectBase;
|
|
obj.Selected = false;
|
|
}
|
|
|
|
m_selection.Clear();
|
|
}
|
|
|
|
public ISnapPoint SnapPoint(ICanvas canvas, UnitPoint point, Type[] runningsnaptypes, Type usersnaptype)
|
|
{
|
|
List<IDrawObject> objects = GetHitObjects(canvas, point);
|
|
if (objects.Count == 0)
|
|
return null;
|
|
|
|
foreach (IDrawObject obj in objects) {
|
|
ISnapPoint snap = obj.SnapPoint(canvas, point, objects, runningsnaptypes, usersnaptype);
|
|
if (snap != null)
|
|
return snap;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public bool CanUndo()
|
|
{
|
|
return m_undoBuffer.CanUndo;
|
|
}
|
|
|
|
public bool DoUndo()
|
|
{
|
|
bool result = m_undoBuffer.DoUndo(this);
|
|
if (result) evtUndo();
|
|
return result;
|
|
}
|
|
|
|
public bool CanRedo()
|
|
{
|
|
bool result = m_undoBuffer.CanRedo;
|
|
return result;
|
|
}
|
|
|
|
public bool DoRedo()
|
|
{
|
|
bool result = m_undoBuffer.DoRedo(this);
|
|
ClearSelectedObjects();
|
|
if (result) evtRedo();
|
|
return result;
|
|
}
|
|
|
|
#region ISerialization function
|
|
public void Save(XmlWriter wr)
|
|
{
|
|
try {
|
|
#region 2.Drawing Objects에 대한 데이터 로딩
|
|
wr.WriteStartElement("DrawingObjects");
|
|
(m_backgroundLayer as BackgroundLayer).GetObjectData(wr);
|
|
(m_gridLayer as GridLayer).GetObjectData(wr);
|
|
foreach (ICanvasLayer layer in m_layers) {
|
|
if (layer is ISerialize) {
|
|
((ISerialize)layer).GetObjectData(wr);
|
|
}
|
|
}
|
|
wr.WriteEndElement();
|
|
|
|
m_undoBuffer.Dirty = false;
|
|
|
|
#endregion
|
|
} catch { }
|
|
}
|
|
|
|
public string Save()
|
|
{
|
|
string jsonString = string.Empty;
|
|
var options = new JsonSerializerOptions { WriteIndented = true };
|
|
try {
|
|
#region 2.Drawing Objects에 대한 데이터 로딩
|
|
|
|
//jsonString += JsonSerializer.Serialize(m_backgroundLayer, options);
|
|
//jsonString += JsonSerializer.Serialize(m_gridLayer, options);
|
|
foreach (ICanvasLayer layer in m_layers) {
|
|
if (layer is ISerialize) {
|
|
jsonString += ((ISerialize)layer).GetObjectData();
|
|
}
|
|
}
|
|
|
|
m_undoBuffer.Dirty = false;
|
|
|
|
#endregion
|
|
} catch { }
|
|
|
|
return jsonString;
|
|
}
|
|
|
|
public bool Load(XmlElement root)
|
|
{
|
|
try {
|
|
foreach (XmlElement node in root.ChildNodes) {
|
|
#region 2.Drawing Objects에 대한 데이터 로딩
|
|
ActiveLayer = null;
|
|
m_layers.Clear();
|
|
m_undoBuffer.Clear();
|
|
m_undoBuffer.Dirty = false;
|
|
|
|
foreach (XmlElement subNode in node.ChildNodes) {
|
|
if (subNode.Name == "backgroundlayer") {
|
|
Common.XmlUtil.ParseProperties(subNode, m_backgroundLayer);
|
|
continue;
|
|
}
|
|
if (subNode.Name == "gridlayer") {
|
|
Common.XmlUtil.ParseProperties(subNode, m_gridLayer);
|
|
continue;
|
|
}
|
|
if (subNode.Name == "layer") {
|
|
DrawingLayer l = DrawingLayer.NewLayer(subNode as XmlElement);
|
|
m_layers.Add(l);
|
|
}
|
|
if (subNode.Name == "property") {
|
|
Common.XmlUtil.ParseProperty(subNode, this);
|
|
}
|
|
}
|
|
if (m_layers.Count == UInt16.MinValue) //만약 Serialize한 레이어의 데이터가 없을 경우에는 default layer의 생성.
|
|
{
|
|
DefaultLayer();
|
|
}
|
|
#endregion
|
|
}
|
|
|
|
return true;
|
|
} catch (Exception e) {
|
|
DefaultLayer();
|
|
Console.WriteLine("Load exception - {0}", e.Message);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
#endregion
|
|
|
|
#region Group/Ungorup 기능
|
|
public void GroupObjects()
|
|
{
|
|
Group obj = (Group)CreateObject("Group");
|
|
List<IDrawObject> rearrangeObjects = RearrangeObjects(SelectedObjects);
|
|
obj.IncludeObjects(rearrangeObjects);
|
|
DeleteObjects(SelectedObjects, false);
|
|
ClearSelectedObjects();
|
|
AddObject(ActiveLayer, obj);
|
|
}
|
|
|
|
private List<IDrawObject> RearrangeObjects(List<IDrawObject> objects)
|
|
{
|
|
for (int i = 0; i < objects.Count - 1; i++) {
|
|
for (int j = i + 1; j < objects.Count; j++) {
|
|
if (objects[i].No > objects[j].No) {
|
|
IDrawObject obj = objects[i]; objects[i] = objects[j]; objects[j] = obj;
|
|
}
|
|
}
|
|
}
|
|
|
|
return objects;
|
|
}
|
|
|
|
public void UngroupObjects()
|
|
{
|
|
List<IDrawObject> releaseObjects = new List<IDrawObject>();
|
|
|
|
foreach (IDrawObject obj in SelectedObjects) {
|
|
if (obj is Group)//그룹인 경우에만 ungroup 작업 진행
|
|
{
|
|
foreach (IDrawObject subObj in ((Group)obj).SubObjects) {
|
|
releaseObjects.Add(subObj.Clone());
|
|
}
|
|
|
|
DeleteObjects(new List<IDrawObject> { obj }, false);
|
|
}
|
|
}
|
|
|
|
foreach (IDrawObject obj in releaseObjects) {
|
|
AddObject(ActiveLayer, obj);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 1.외부에서 Canvas의 객체를 관리하는 함수
|
|
/// <summary>
|
|
/// 새로운 객체를 생성하는 함수(Canvas에서 생성하는 것이 아니라, 외부에서 생성할 때 실행)
|
|
/// </summary>
|
|
///
|
|
public IDrawObject AddObject(AddObjectParam param)
|
|
{
|
|
IDrawObject drawObj = null;
|
|
|
|
switch (param.ObjectType) {
|
|
case "Line":
|
|
drawObj = CreateObject(param.ObjectType, param.Point1, null);
|
|
((LineEdit)drawObj).P2 = param.Point2;
|
|
((LineEdit)drawObj).Color = param.Color;
|
|
AddObject(ActiveLayer, drawObj, false);
|
|
break;
|
|
|
|
case "Dot":
|
|
drawObj = CreateObject(param.ObjectType, param.Point1, null);
|
|
((Dot)drawObj).Color = param.Color;
|
|
AddObject(ActiveLayer, drawObj, false);
|
|
break;
|
|
|
|
case "ArcCR":
|
|
drawObj = CreateObject(param.ObjectType, param.Center, null);
|
|
((Arc)drawObj).Radius = param.MajorRadius;
|
|
((Arc)drawObj).Color = param.Color;
|
|
|
|
if (param.Direction == "CW") {
|
|
((Arc)drawObj).Direction = Arc.eDirection.CW;
|
|
((Arc)drawObj).StartAngle = param.StartAngle;
|
|
((Arc)drawObj).EndAngle = param.EndAngle;
|
|
((Arc)drawObj).SweepAngle = param.SweepAngle;
|
|
} else {
|
|
((Arc)drawObj).Direction = Arc.eDirection.CCW;
|
|
((Arc)drawObj).StartAngle = param.StartAngle;
|
|
((Arc)drawObj).EndAngle = param.EndAngle;
|
|
((Arc)drawObj).SweepAngle = param.SweepAngle;
|
|
}
|
|
AddObject(ActiveLayer, drawObj, false);
|
|
break;
|
|
|
|
case "Spline":
|
|
drawObj = CreateObject(param.ObjectType, param.Point1, null);
|
|
((Dot)drawObj).Color = param.Color;
|
|
AddObject(ActiveLayer, drawObj, false);
|
|
break;
|
|
|
|
case "SnowMan":
|
|
drawObj = CreateObject(param.ObjectType, param.Point1, null);
|
|
((SnowMan)drawObj).P2 = param.Point2;
|
|
((SnowMan)drawObj).Color = param.Color;
|
|
AddObject(ActiveLayer, drawObj, false);
|
|
break;
|
|
|
|
case "Group":
|
|
drawObj = CreateObject(param.ObjectType, param.Point1, null);
|
|
((Group)drawObj).Color = param.Color;
|
|
AddObject(ActiveLayer, drawObj, false);
|
|
break;
|
|
|
|
case "Rectangle":
|
|
drawObj = CreateObject(param.ObjectType, param.Point1, null);
|
|
((RectangleTool)drawObj).Color = param.Color;
|
|
((RectangleTool)drawObj).DrawBound(param.Point1, param.Point2);
|
|
AddObject(ActiveLayer, drawObj, false);
|
|
break;
|
|
|
|
case "Roi":
|
|
drawObj = CreateObject(param.ObjectType, param.Point1, null);
|
|
((RoiTool)drawObj).Color = param.Color;
|
|
((RoiTool)drawObj).Locked = true;
|
|
((RoiTool)drawObj).DrawBound(param.Point1, param.Point2);
|
|
AddObject(ActiveLayer, drawObj, false);
|
|
break;
|
|
|
|
case "PolyLine":
|
|
drawObj = CreateObject(param.ObjectType, param.Point1, null);
|
|
((LineEdit)drawObj).P2 = param.Point2;
|
|
((LineEdit)drawObj).Color = param.Color;
|
|
AddObject(ActiveLayer, drawObj, false);
|
|
break;
|
|
|
|
case "Ellipse":
|
|
drawObj = CreateObject(param.ObjectType, param.Center, null);
|
|
((EllipseTool)drawObj).Color = param.Color;
|
|
((EllipseTool)drawObj).DrawBound(param.Point1, param.Point2);
|
|
((EllipseTool)drawObj).Rotate(param.RotateAngle, param.Center);
|
|
((EllipseTool)drawObj).StartAngle = param.StartAngle;
|
|
((EllipseTool)drawObj).EndAngle = param.EndAngle;
|
|
AddObject(ActiveLayer, drawObj, false);
|
|
break;
|
|
|
|
case "ZigZag":
|
|
drawObj = CreateObject(param.ObjectType, param.Point1, null);
|
|
var zigzag = (ZigZag)drawObj;
|
|
zigzag.P1 = param.Point1;
|
|
zigzag.P2 = param.Point2;
|
|
zigzag.Color = param.Color;
|
|
|
|
// Pitch, Amplitude, Radius, Angle 등 필요한 파라미터를 param에서 전달
|
|
zigzag.Pitch = param.Pitch;
|
|
zigzag.Amplitude = param.Amplitude;
|
|
zigzag.Radius = param.Radius;
|
|
zigzag.Angle = param.RotateAngle;
|
|
zigzag.Distance = (float)Math.Sqrt(
|
|
Math.Pow(param.Point2.X - param.Point1.X, 2) +
|
|
Math.Pow(param.Point2.Y - param.Point1.Y, 2)
|
|
);
|
|
zigzag.DrawDirection = param.DrawDirection;
|
|
|
|
// 실제 ZigZag 라인/아크 포인트 생성
|
|
//zigzag.CreateZigZagPointList();
|
|
|
|
AddObject(ActiveLayer, zigzag, false);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return drawObj;
|
|
}
|
|
|
|
public IDrawObject AddObject(string objectType, UnitPoint pt1, UnitPoint pt2, Color color)
|
|
{
|
|
IDrawObject drawObj = null;
|
|
|
|
switch (objectType) {
|
|
case "Line":
|
|
drawObj = CreateObject(objectType, pt1, null);
|
|
((LineEdit)drawObj).P2 = pt2;
|
|
((LineEdit)drawObj).Color = color;
|
|
AddObject(ActiveLayer, drawObj, false);
|
|
break;
|
|
|
|
case "Dot":
|
|
drawObj = CreateObject(objectType, pt1, null);
|
|
((Dot)drawObj).Color = color;
|
|
AddObject(ActiveLayer, drawObj, false);
|
|
break;
|
|
|
|
case "Arc":
|
|
drawObj = CreateObject(objectType, pt1, null);
|
|
((Arc)drawObj).Color = color;
|
|
AddObject(ActiveLayer, drawObj, false);
|
|
break;
|
|
|
|
case "Spline":
|
|
drawObj = CreateObject(objectType, pt1, null);
|
|
((Dot)drawObj).Color = color;
|
|
AddObject(ActiveLayer, drawObj, false);
|
|
break;
|
|
|
|
case "SnowMan":
|
|
drawObj = CreateObject(objectType, pt1, null);
|
|
((SnowMan)drawObj).P2 = pt2;
|
|
((SnowMan)drawObj).Color = color;
|
|
AddObject(ActiveLayer, drawObj, false);
|
|
break;
|
|
|
|
case "Group":
|
|
drawObj = CreateObject(objectType, pt1, null);
|
|
((Group)drawObj).Color = color;
|
|
AddObject(ActiveLayer, drawObj, false);
|
|
break;
|
|
|
|
case "Rectangle":
|
|
drawObj = CreateObject(objectType, pt1, null);
|
|
((RectangleTool)drawObj).Color = color;
|
|
((RectangleTool)drawObj).Locked = true;
|
|
((RectangleTool)drawObj).DrawBound(pt1, pt2);
|
|
AddObject(ActiveLayer, drawObj, false);
|
|
break;
|
|
|
|
case "Roi":
|
|
drawObj = CreateObject(objectType, pt1, null);
|
|
((RoiTool)drawObj).Color = color;
|
|
((RoiTool)drawObj).Locked = true;
|
|
((RoiTool)drawObj).DrawBound(pt1, pt2);
|
|
AddObject(ActiveLayer, drawObj, false);
|
|
break;
|
|
|
|
case "ZigZag":
|
|
drawObj = CreateObject(objectType, pt1, null);
|
|
((ZigZag)drawObj).P2 = pt2;
|
|
((ZigZag)drawObj).Color = color;
|
|
AddObject(ActiveLayer, drawObj, false);
|
|
break;
|
|
|
|
case "PolyLine":
|
|
drawObj = CreateObject(objectType, pt1, null);
|
|
((LineEdit)drawObj).P2 = pt2;
|
|
((LineEdit)drawObj).Color = color;
|
|
AddObject(ActiveLayer, drawObj, false);
|
|
break;
|
|
|
|
case "Ellipse":
|
|
drawObj = CreateObject(objectType, pt1, null);
|
|
((EllipseTool)drawObj).Color = color;
|
|
((EllipseTool)drawObj).Locked = true;
|
|
((EllipseTool)drawObj).DrawBound(pt1, pt2);
|
|
AddObject(ActiveLayer, drawObj, false);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return drawObj;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 선택된 객체를 지우는 함수(Canvas에서 지우는 것이 아니라, 외부에서 지울 때 실행)
|
|
/// </summary>
|
|
public void DeleteAllObjects()
|
|
{
|
|
((DrawingLayer)ActiveLayer).DeleteObjects(((DrawingLayer)ActiveLayer).Objects);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 객체를 선택하는 함수(Canvas에서 선택하는 것이 아니라, 외부에서 선택할 때 실행)
|
|
/// </summary>
|
|
public void SelectObject(int index, bool addMode)
|
|
{
|
|
if (addMode == false) ClearSelectedObjects();
|
|
AddSelectedObject(((DrawingLayer)ActiveLayer).Objects[index]);
|
|
}
|
|
#endregion
|
|
|
|
#region 2. 필드 이미지 기능
|
|
SizeF m_canvasImageSize = new SizeF(0, 0);
|
|
public SizeF CanvasImageSize {
|
|
get { return m_canvasImageSize; }
|
|
set { m_canvasImageSize = value; }
|
|
}
|
|
|
|
bool m_canvasImageEnable = false;
|
|
public bool CanvasImageEnable {
|
|
get { lock (this) { return m_canvasImageEnable; } }
|
|
set { lock (this) { m_canvasImageEnable = value; } }
|
|
}
|
|
|
|
Bitmap m_canvasImage = null;
|
|
public Bitmap CanvasImage {
|
|
get { lock (this) { return m_canvasImage; } }
|
|
set { lock (this) { m_canvasImage = value; } }
|
|
}
|
|
#endregion
|
|
#region 3. Canvas 색상 및 격자 사용 유무 옵션
|
|
bool m_canvasColorEnable = false;
|
|
public bool EnableCanvasColor {
|
|
get { lock (this) { return m_canvasColorEnable; } }
|
|
set { lock (this) { m_canvasColorEnable = value; } }
|
|
}
|
|
|
|
bool m_canvasGridEnable = false;
|
|
public bool EnableCanvasGrid {
|
|
get { lock (this) { return m_canvasGridEnable; } }
|
|
set { lock (this) { m_canvasGridEnable = value; } }
|
|
}
|
|
#endregion
|
|
#endregion
|
|
|
|
public void Clone(DataModel org)
|
|
{
|
|
lock (this) {
|
|
CanvasImage = org.CanvasImage;
|
|
CenterPoint = org.CenterPoint;
|
|
CanvasImageEnable = org.CanvasImageEnable;
|
|
CanvasImageSize = org.CanvasImageSize;
|
|
ScaleToFit = org.ScaleToFit;
|
|
Zoom = org.Zoom;
|
|
EnableCanvasColor = org.EnableCanvasColor;
|
|
EnableCanvasGrid = org.EnableCanvasGrid;
|
|
Layers = (ICanvasLayer[])org.Layers.Clone();
|
|
m_activeLayer = m_layers[0];
|
|
|
|
//var thisDrawing = ActiveLayer as DrawingLayer;
|
|
//var orgDrawing = org.ActiveLayer as DrawingLayer;
|
|
//thisDrawing.Copy(orgDrawing, true);
|
|
|
|
var thisGrid = GridLayer as GridLayer;
|
|
var orgGrid = org.GridLayer as GridLayer;
|
|
thisGrid.Copy(orgGrid);
|
|
|
|
var thisBackground = BackgroundLayer as BackgroundLayer;
|
|
var orgBackground = org.BackgroundLayer as BackgroundLayer;
|
|
thisBackground.Copy(orgBackground);
|
|
}
|
|
}
|
|
}
|
|
}
|