You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
707 lines
19 KiB
C#
707 lines
19 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Drawing;
|
|
using System.Drawing.Design;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
using BrightIdeasSoftware;
|
|
using static UCDraw.GeoSigma;
|
|
|
|
namespace UCDraw.Editor
|
|
{
|
|
//public delegate void DrawSymbol();
|
|
public partial class frmMarkEditor : DialogUIEditorFrom<string>
|
|
{
|
|
//public DrawSymbol drawSymbolEvent;
|
|
private MarkLibrary _library = new MarkLibrary();
|
|
public frmMarkEditor()
|
|
{
|
|
InitializeComponent();
|
|
|
|
toolStrip1.Renderer = MyToolStripRenderer.Instance;
|
|
|
|
treeSymbol.CanExpandGetter = delegate (object o)
|
|
{
|
|
if (o is MarkBaseNode mln)
|
|
{
|
|
if (_library.GetChildren(mln).Any())
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
treeSymbol.ChildrenGetter = delegate (object o)
|
|
{
|
|
var list = new ArrayList();
|
|
|
|
if (o is MarkBaseNode mlr)
|
|
{
|
|
list.AddRange(_library.GetChildren(mlr).ToList());
|
|
}
|
|
|
|
return list;
|
|
};
|
|
|
|
treeSymbol.ParentGetter = delegate (object o)
|
|
{
|
|
if (o is MarkBaseNode mln)
|
|
{
|
|
return _library.GetParent(mln);
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
|
|
treeSymbol.AllColumns.Add(new OLVColumn()
|
|
{
|
|
Text = "名称",
|
|
Width = 260,
|
|
Sortable = false,
|
|
|
|
AspectGetter = delegate (object o)
|
|
{
|
|
//if (o is MarkBaseItem mli)
|
|
// return mli.PathEx.Last();
|
|
|
|
if (o is MarkBaseNode mln)
|
|
return mln.PathEx.Last();
|
|
|
|
return "";
|
|
},
|
|
ImageGetter = delegate (object o)
|
|
{
|
|
if (treeSymbol.CanExpandGetter(o))
|
|
{
|
|
return "folder";
|
|
}
|
|
|
|
return "item";
|
|
},
|
|
});
|
|
|
|
treeSymbol.RebuildColumns();
|
|
|
|
treeSymbol.RowHeight = 20;
|
|
|
|
olvSymbol.ItemRenderer = new MarkItemRenderer();
|
|
|
|
//olvColumnText.ImageGetter += delegate (object o) {
|
|
|
|
// if (o is MarkItem mi)
|
|
// return mi.Image;
|
|
|
|
// return null;
|
|
//};
|
|
}
|
|
|
|
protected override void OnLoad(EventArgs e)
|
|
{
|
|
base.OnLoad(e);
|
|
|
|
_library = MarkLibrary.GetMarkLibrary();
|
|
|
|
_library.GenerateNodes();
|
|
|
|
var roots = _library.GetRoots().ToList();
|
|
|
|
treeSymbol.Objects = roots;
|
|
|
|
if (roots.Count > 0)
|
|
treeSymbol.SelectedObject = roots[0];
|
|
|
|
if (olvSymbol.Objects is List<MarkItem> list)
|
|
{
|
|
foreach (var mi in list)
|
|
{
|
|
if (this.Value != null)
|
|
{
|
|
if (mi.Name == this.Value)
|
|
{
|
|
olvSymbol.SelectedObject = mi;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void btnOk_Click(object sender, EventArgs e)
|
|
{
|
|
if (olvSymbol.SelectedObject is MarkItem mi)
|
|
{
|
|
if (mi is LibraryMarkItem lmi && DrawViewer.Current?.GetGeoSigma() is GeoSigma gs)
|
|
{
|
|
gs.MarkCopyLibraryToDocument(lmi.Id);
|
|
}
|
|
|
|
this.Value = mi.Name;
|
|
}
|
|
|
|
DialogResult = DialogResult.OK;
|
|
}
|
|
|
|
private void btnCancel_Click(object sender, EventArgs e)
|
|
{
|
|
DialogResult = DialogResult.Cancel;
|
|
this.Close();
|
|
}
|
|
|
|
private void treeSymbol_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
if (treeSymbol.SelectedObject is MarkDocumentNode dnode)
|
|
{
|
|
MarkLibrary.GenerateDocumentImage(dnode.Marks);
|
|
|
|
olvSymbol.Objects = dnode.Marks;
|
|
|
|
if (dnode.Marks.Count > 0)
|
|
olvSymbol.EnsureModelVisible(dnode.Marks[0]);
|
|
}
|
|
else if (treeSymbol.SelectedObject is MarkLibraryNode lnode)
|
|
{
|
|
MarkLibrary.GenerateLibraryImage(lnode.Marks);
|
|
|
|
olvSymbol.Objects = lnode.Marks;
|
|
|
|
if (lnode.Marks.Count > 0)
|
|
olvSymbol.EnsureModelVisible(lnode.Marks[0]);
|
|
}
|
|
}
|
|
|
|
private void tsbtnSearch_Click(object sender, EventArgs e)
|
|
{
|
|
var text = tstbSearch.Text;
|
|
|
|
var list = new List<MarkItem>();
|
|
|
|
foreach (var node in _library.Nodes.OfType<MarkItemNode>())
|
|
{
|
|
var tmp = node.Marks.Where(r => r.Name.Contains(text)).ToList();
|
|
|
|
if (node is MarkDocumentNode dnode)
|
|
{
|
|
MarkLibrary.GenerateDocumentImage(tmp);
|
|
}
|
|
else if (node is MarkLibraryNode lnode)
|
|
{
|
|
MarkLibrary.GenerateLibraryImage(tmp);
|
|
}
|
|
|
|
list.AddRange(tmp);
|
|
}
|
|
|
|
olvSymbol.Objects = list;
|
|
|
|
if (list.Count > 0)
|
|
olvSymbol.EnsureModelVisible(list[0]);
|
|
}
|
|
|
|
private void btnNew_Click(object sender, EventArgs e)
|
|
{
|
|
|
|
var mdNode = new MarkDocumentNode();
|
|
string aa = mdNode.Name;
|
|
|
|
olvSymbol.AddObject(mdNode);
|
|
this.olvSymbol.SelectObject(mdNode, true);
|
|
|
|
}
|
|
|
|
private void btnEdit_Click(object sender, EventArgs e)
|
|
{
|
|
if (treeSymbol.SelectedObject is MarkDocumentNode dnode)
|
|
{
|
|
olvSymbol.Objects = dnode.Marks;
|
|
}
|
|
}
|
|
|
|
private void olvSymbol_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
var symbol = olvSymbol.SelectedItem;
|
|
if (symbol != null)
|
|
{
|
|
var dataSymbol = symbol.RowObject;
|
|
DrawViewer.Current.GetGeoSigma().DrawImg();
|
|
//drawer1.InvokePaintEvent();
|
|
//this.Paint += new System.Windows.Forms.PaintEventHandler(DrawViewer.Current.Drawer_Paint);
|
|
|
|
//drawSymbolEvent?.Invoke();
|
|
}
|
|
}
|
|
}
|
|
|
|
public class MarkEditor : DialogUIEditor<string, frmMarkEditor>
|
|
{
|
|
private List<MarkItem> _items = new List<MarkItem>();
|
|
|
|
public override bool GetPaintValueSupported(ITypeDescriptorContext context)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
public override void PaintValue(PaintValueEventArgs e)
|
|
{
|
|
if (e.Value is string s)
|
|
{
|
|
MarkItem mi = _items.FirstOrDefault(r => r.Name == s);
|
|
|
|
if (mi == null)
|
|
{
|
|
foreach (var dm in MarkLibrary.GetDocumentMarks())
|
|
{
|
|
var tmp = _items.FirstOrDefault(r => r.Id == dm.Id);
|
|
|
|
if (tmp == null)
|
|
{
|
|
_items.Add(dm);
|
|
}
|
|
else
|
|
{
|
|
tmp.Name = dm.Name;
|
|
tmp.Image = dm.Image;
|
|
}
|
|
}
|
|
|
|
mi = _items.FirstOrDefault(r => r.Name == s);
|
|
}
|
|
|
|
if (mi != null)
|
|
{
|
|
if (mi.Image == null)
|
|
MarkLibrary.GenerateDocumentImage(new[] { mi });
|
|
|
|
e.Graphics.DrawImage(mi.Image, e.Bounds);
|
|
}
|
|
}
|
|
|
|
base.PaintValue(e);
|
|
}
|
|
}
|
|
|
|
#region 符号
|
|
|
|
public abstract class MarkItem
|
|
{
|
|
public string Name { get; set; }
|
|
|
|
public string Id { get; set; }
|
|
|
|
public Image Image { get; set; }
|
|
}
|
|
|
|
public class DocumentMarkItem : MarkItem { }
|
|
|
|
public class LibraryMarkItem : MarkItem { }
|
|
|
|
public abstract class MarkBaseNode
|
|
{
|
|
private string _path;
|
|
public string Path
|
|
{
|
|
get => _path;//string.Join("\\", PathEx);
|
|
set
|
|
{
|
|
_path = value;
|
|
|
|
PathEx.Clear();
|
|
|
|
PathEx.AddRange(value.Split(new[] { "\\" }, StringSplitOptions.RemoveEmptyEntries));
|
|
}
|
|
}
|
|
|
|
public List<string> PathEx { get; set; } = new List<string>();
|
|
|
|
public string Name
|
|
{
|
|
get
|
|
{
|
|
if (PathEx.Count > 0)
|
|
return PathEx.Last();
|
|
|
|
return string.Empty;
|
|
}
|
|
}
|
|
|
|
public int Level => PathEx.Count;
|
|
|
|
public string GetPathByLevel(int level)
|
|
{
|
|
return string.Join("\\", PathEx.Take(level));
|
|
}
|
|
|
|
public bool IsParentOf(MarkBaseNode rhs)
|
|
{
|
|
if (this.PathEx.Count == rhs.PathEx.Count - 1)
|
|
{
|
|
int count = 0;
|
|
|
|
for (int i = 0; i < this.PathEx.Count; i++)
|
|
{
|
|
if (this.PathEx[i] == rhs.PathEx[i])
|
|
count++;
|
|
}
|
|
|
|
return count == this.PathEx.Count;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public bool IsChildOf(MarkBaseNode rhs)
|
|
{
|
|
return rhs.IsParentOf(this);
|
|
}
|
|
|
|
public bool IsAncestorOf(MarkBaseNode rhs)
|
|
{
|
|
if (this.PathEx.Count < rhs.PathEx.Count)
|
|
{
|
|
int count = 0;
|
|
|
|
for (int i = 0; i < this.PathEx.Count; i++)
|
|
{
|
|
if (this.PathEx[i] == rhs.PathEx[i])
|
|
count++;
|
|
}
|
|
|
|
return count == this.PathEx.Count;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public bool IsPosterityOf(MarkBaseNode rhs)
|
|
{
|
|
return rhs.IsAncestorOf(this);
|
|
}
|
|
}
|
|
|
|
public class MarkVirtualNode : MarkBaseNode
|
|
{
|
|
|
|
}
|
|
|
|
|
|
public class MarkItemNode : MarkBaseNode
|
|
{
|
|
public List<MarkItem> Marks { get; set; } = new List<MarkItem>();
|
|
|
|
public override string ToString()
|
|
{
|
|
return $"{Path}: {Marks.Count}";
|
|
}
|
|
}
|
|
|
|
public class MarkLibraryNode : MarkItemNode { }
|
|
|
|
|
|
public class MarkDocumentNode : MarkItemNode { }
|
|
|
|
public class MarkLibrary
|
|
{
|
|
public List<MarkItemNode> Items { get; set; } = new List<MarkItemNode>();
|
|
|
|
public bool Empty => Items.Count == 0;
|
|
|
|
public List<MarkBaseNode> Nodes { get; set; } = new List<MarkBaseNode>();
|
|
|
|
public void GenerateNodes()
|
|
{
|
|
List<MarkBaseNode> GetRoots()
|
|
{
|
|
var list = new List<MarkBaseNode>();
|
|
|
|
list.AddRange(this.Items.OfType<MarkDocumentNode>());
|
|
|
|
var parents = this.Items.Where(r => !(r is MarkDocumentNode))
|
|
.Where(r => !this.Items.Any(k => k.IsParentOf(r)));
|
|
|
|
list.AddRange(parents.Where(r => r.PathEx.Count != 1)
|
|
.Select(r => r.PathEx[0])
|
|
.Distinct()
|
|
.Select(r => new MarkVirtualNode() { Path = r })
|
|
);
|
|
|
|
list.AddRange(parents.Where(r => r.PathEx.Count == 1));
|
|
|
|
return list;
|
|
}
|
|
|
|
List<MarkBaseNode> GetChildren(MarkBaseNode node)
|
|
{
|
|
var list = new List<MarkBaseNode>();
|
|
|
|
var tmp = this.Items.Where(r => r.IsPosterityOf(node));
|
|
|
|
list.AddRange(tmp.Where(r => !r.IsChildOf(node))
|
|
.Select(r => r.GetPathByLevel(node.Level + 1))
|
|
.Distinct()
|
|
.Select(r => new MarkVirtualNode() { Path = r })
|
|
.ToList()
|
|
);
|
|
|
|
list.AddRange(tmp.Where(r => r.IsChildOf(node)).ToList());
|
|
|
|
var children = list.SelectMany(r => GetChildren(r)).ToList();
|
|
|
|
list.AddRange(children);
|
|
|
|
return list;
|
|
}
|
|
|
|
Nodes.Clear();
|
|
|
|
var roots = GetRoots();
|
|
|
|
Nodes.AddRange(roots);
|
|
|
|
var nodes = roots.SelectMany(r => GetChildren(r));
|
|
|
|
Nodes.AddRange(nodes);
|
|
|
|
}
|
|
|
|
|
|
public IEnumerable<MarkBaseNode> GetRoots()
|
|
{
|
|
var list = new List<MarkBaseNode>();
|
|
|
|
list.AddRange(Nodes.OfType<MarkDocumentNode>());
|
|
|
|
list.AddRange(Nodes.OfType<MarkVirtualNode>().Where(r => r.Level == 1));
|
|
|
|
list.AddRange(Nodes.OfType<MarkLibraryNode>().Where(r => r.Level == 1));
|
|
|
|
return list;
|
|
}
|
|
|
|
public IEnumerable<MarkBaseNode> GetChildren(MarkBaseNode parent)
|
|
{
|
|
foreach (var mln in Nodes)
|
|
{
|
|
if (mln.IsChildOf(parent))
|
|
yield return mln;
|
|
}
|
|
}
|
|
|
|
public MarkBaseNode GetParent(MarkBaseNode child)
|
|
{
|
|
foreach (var mln in Nodes)
|
|
{
|
|
if (mln.IsParentOf(child))
|
|
return mln;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
|
|
#region 接口
|
|
|
|
|
|
public static List<MarkItem> GetDocumentMarks()
|
|
{
|
|
var list = new List<MarkItem>();
|
|
|
|
if (DrawViewer.Current?.GetGeoSigma() is GeoSigma gs)
|
|
{
|
|
var idList = new StringBuilder(65535);
|
|
var nameList = new StringBuilder(65535);
|
|
|
|
if (gs.MarkLoopName(idList, nameList))
|
|
{
|
|
var arrId = idList.ToString().Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
|
|
var arrName = nameList.ToString().Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
if (arrId.Length == arrName.Length)
|
|
{
|
|
for (int i = 0; i < arrId.Length; i++)
|
|
{
|
|
list.Add(new DocumentMarkItem()
|
|
{
|
|
Name = arrName[i],
|
|
Id = arrId[i],
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
public static MarkLibrary GetMarkLibrary()
|
|
{
|
|
var library = new MarkLibrary();
|
|
|
|
library.Items.Add(new MarkDocumentNode()
|
|
{
|
|
Path = "当前文件符号",
|
|
Marks = GetDocumentMarks(),
|
|
});
|
|
|
|
library.Items.AddRange(GetDefaultLibrary().Items);
|
|
|
|
return library;
|
|
}
|
|
|
|
private static MarkLibrary _defaultMarkLibrary = new MarkLibrary();
|
|
|
|
public static MarkLibrary GetDefaultLibrary()
|
|
{
|
|
if (_defaultMarkLibrary.Empty)
|
|
{
|
|
var pathList = new StringBuilder(65535);
|
|
|
|
if (GeoSigma.MarkLibraryLoopName(pathList))
|
|
{
|
|
var arrPath = pathList.ToString().Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
foreach (var path in arrPath)
|
|
{
|
|
var item = new MarkLibraryNode()
|
|
{
|
|
Path = path
|
|
};
|
|
|
|
var idList = new StringBuilder(65535);
|
|
var nameList = new StringBuilder(65535);
|
|
|
|
if (GeoSigma.MarkLibraryLoopMark(path, idList, nameList))
|
|
{
|
|
var arrId = idList.ToString().Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
|
|
var arrName = nameList.ToString().Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
if (arrId.Length == arrName.Length)
|
|
{
|
|
for (int i = 0; i < arrId.Length; i++)
|
|
{
|
|
item.Marks.Add(new DocumentMarkItem()
|
|
{
|
|
Name = arrName[i],
|
|
Id = arrId[i],
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
_defaultMarkLibrary.Items.Add(item);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return _defaultMarkLibrary;
|
|
}
|
|
|
|
public static void GenerateDocumentImage(IEnumerable<MarkItem> marks)
|
|
{
|
|
if (DrawViewer.Current?.GetGeoSigma() is GeoSigma gs)
|
|
{
|
|
foreach (var nm in marks)
|
|
{
|
|
int cx = 50, cy = 50;
|
|
|
|
var img = new Bitmap(cx, cy);
|
|
|
|
Graphics g = Graphics.FromImage(img);
|
|
|
|
if (gs.MarkDrawByName(nm.Id, g.GetHdc(), cx, cy))
|
|
{
|
|
//加上这句才能回写到bitmap中
|
|
g.ReleaseHdc();
|
|
|
|
nm.Image = img;
|
|
//nm.Image.Save($"d:\\{nm.Name}.bmp");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void GenerateLibraryImage(IEnumerable<MarkItem> marks)
|
|
{
|
|
foreach (var nm in marks)
|
|
{
|
|
int cx = 50, cy = 50;
|
|
|
|
var img = new Bitmap(cx, cy);
|
|
|
|
Graphics g = Graphics.FromImage(img);
|
|
|
|
if (GeoSigma.MarkLibraryDrawByName(nm.Id, g.GetHdc(), cx, cy))
|
|
{
|
|
//加上这句才能回写到bitmap中
|
|
g.ReleaseHdc();
|
|
|
|
nm.Image = img;
|
|
//nm.Image.Save($"d:\\{nm.Name}.bmp");
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region MarkItemRenderer
|
|
|
|
internal class MarkItemRenderer : BrightIdeasSoftware.BaseRenderer
|
|
{
|
|
public override bool RenderItem(DrawListViewItemEventArgs e, Graphics g, Rectangle r, object x)
|
|
{
|
|
var ret = base.RenderItem(e, g, r, x);
|
|
|
|
if (x is MarkItem mi)
|
|
{
|
|
if (e.Item.Selected)
|
|
{
|
|
g.FillRectangle(Brushes.LightGray, r);
|
|
}
|
|
|
|
int cx = 30;
|
|
int cy = 30;
|
|
|
|
int size = Math.Min(r.Width - cx, r.Height - cy);
|
|
|
|
var rcImageBorder = new Rectangle(r.Left + (r.Width-size) / 2, r.Top, size, size);
|
|
rcImageBorder.Inflate(-2, -2);
|
|
|
|
var rcImage = rcImageBorder;
|
|
rcImage.Inflate(-2, -2);
|
|
|
|
g.DrawImage(mi.Image, rcImage);
|
|
|
|
g.DrawRectangle(Pens.Black, rcImageBorder);
|
|
|
|
StringFormat fmt = new StringFormat();
|
|
fmt.LineAlignment = StringAlignment.Near;
|
|
fmt.Alignment = StringAlignment.Center;
|
|
|
|
g.DrawString(mi.Name, this.Font, Brushes.Black,
|
|
new Rectangle(r.Left, r.Top+size, r.Width, r.Height-size)
|
|
, fmt);
|
|
|
|
return true;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
#endregion
|
|
}
|