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 { //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 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(); foreach (var node in _library.Nodes.OfType()) { 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 { private List _items = new List(); 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 PathEx { get; set; } = new List(); 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 Marks { get; set; } = new List(); public override string ToString() { return $"{Path}: {Marks.Count}"; } } public class MarkLibraryNode : MarkItemNode { } public class MarkDocumentNode : MarkItemNode { } public class MarkLibrary { public List Items { get; set; } = new List(); public bool Empty => Items.Count == 0; public List Nodes { get; set; } = new List(); public void GenerateNodes() { List GetRoots() { var list = new List(); list.AddRange(this.Items.OfType()); 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 GetChildren(MarkBaseNode node) { var list = new List(); 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 GetRoots() { var list = new List(); list.AddRange(Nodes.OfType()); list.AddRange(Nodes.OfType().Where(r => r.Level == 1)); list.AddRange(Nodes.OfType().Where(r => r.Level == 1)); return list; } public IEnumerable 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 GetDocumentMarks() { var list = new List(); 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 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 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 }