diff --git a/src/CADShared/Algorithms/QuadTree/Rect.cs b/src/CADShared/Algorithms/QuadTree/Rect.cs index 1366442ee833adbd4aa9f6b84572abaa17637089..d771c19abe2e1b6bbfbc133d6bbecf0d068cbaf5 100644 --- a/src/CADShared/Algorithms/QuadTree/Rect.cs +++ b/src/CADShared/Algorithms/QuadTree/Rect.cs @@ -1,6 +1,4 @@ -using System.Diagnostics; -using System.Runtime.CompilerServices; -#if a2024 || zcad +#if !NET8_0_OR_GREATER using ArgumentNullException = IFoxCAD.Basal.ArgumentNullEx; #endif namespace IFoxCAD.Cad; diff --git a/src/CADShared/Basal/Nullable/ArgumentNullEx.cs b/src/CADShared/Basal/Nullable/ArgumentNullEx.cs index 7fb7763d155fe169740d82758ebdd19763ac4f61..517cd14c8a7658d4c277fa82539de35f42b15ba3 100644 --- a/src/CADShared/Basal/Nullable/ArgumentNullEx.cs +++ b/src/CADShared/Basal/Nullable/ArgumentNullEx.cs @@ -1,5 +1,5 @@  -#if a2024 || zcad +#if !NET8_0_OR_GREATER namespace IFoxCAD.Basal; /// diff --git a/src/CADShared/Basal/Nullable/CallerArgumentExpressionAttribute.cs b/src/CADShared/Basal/Nullable/CallerArgumentExpressionAttribute.cs index e6f566041731582fb5e2e0544ff199d4024257b3..505d5ee5e07b9c01f80abc5accca7da62b51be2b 100644 --- a/src/CADShared/Basal/Nullable/CallerArgumentExpressionAttribute.cs +++ b/src/CADShared/Basal/Nullable/CallerArgumentExpressionAttribute.cs @@ -1,5 +1,5 @@  -#if a2024 || zcad +#if !NET8_0_OR_GREATER namespace System.Runtime.CompilerServices; /// /// 指示参数将为另一个参数传递的表达式捕获为字符串。 diff --git a/src/CADShared/Basal/Win/WindowsAPI.cs b/src/CADShared/Basal/Win/WindowsAPI.cs index 5125d471e94c218224c4df83e8c5517ef2be4700..5b12ae2cc22560fc476fb352a8a9a4eddb6c1593 100644 --- a/src/CADShared/Basal/Win/WindowsAPI.cs +++ b/src/CADShared/Basal/Win/WindowsAPI.cs @@ -1,6 +1,6 @@ #pragma warning disable CS1591 // 缺少对公共可见类型或成员的 XML 注释 #define Marshal -#if a2024 || zcad +#if !NET8_0_OR_GREATER using ArgumentNullException = IFoxCAD.Basal.ArgumentNullEx; #endif namespace IFoxCAD.Basal; diff --git a/src/CADShared/CADShared.projitems b/src/CADShared/CADShared.projitems index 48f9e0187593056ef5e6c13ef0a0830214ac1848..6ff17a27578666b2cb03164ce3310087f2d866ef 100644 --- a/src/CADShared/CADShared.projitems +++ b/src/CADShared/CADShared.projitems @@ -100,6 +100,7 @@ + @@ -107,5 +108,7 @@ + + \ No newline at end of file diff --git a/src/CADShared/ExtensionMethod/EditorEx.cs b/src/CADShared/ExtensionMethod/EditorEx.cs index bd18a46727efd99b88e8a97e03e10449c61e54bd..ca53678295f6a489757f88ae50ee7d0daa46fb82 100644 --- a/src/CADShared/ExtensionMethod/EditorEx.cs +++ b/src/CADShared/ExtensionMethod/EditorEx.cs @@ -325,7 +325,7 @@ public static void SsgetAddKeys(this PromptSelectionOptions pso, /// /// 带格式项的字符串 /// 指定格式化的对象数组 - public static void StreamMessage(string format, params object[] args) + public static void StreamMessage(string format, params IEnumerable args) { StreamMessage(string.Format(format, args)); } @@ -392,7 +392,7 @@ public static void InfoMessageBox(string caption, string message) /// 对话框的标题 /// 带格式化项的对话框文本 /// 指定格式化的对象数组 - public static void InfoMessageBox(string caption, string format, params object[] args) + public static void InfoMessageBox(string caption, string format, params IEnumerable args) { InfoMessageBox(caption, string.Format(format, args)); } @@ -411,7 +411,7 @@ public static void InfoMessageBox(string message) /// /// 带格式化项的对话框文本 /// 指定格式化的对象数组 - public static void InfoMessageBox(string format, params object[] args) + public static void InfoMessageBox(string format, params IEnumerable args) { InfoMessageBox(string.Format(format, args)); } @@ -438,7 +438,7 @@ public static void WriteMessage(string message) /// /// 带格式化项的文本 /// 指定格式化的对象数组 - public static void WriteMessage(string format, params object[] args) + public static void WriteMessage(string format, params IEnumerable args) { WriteMessage(string.Format(format, args)); } @@ -1134,22 +1134,14 @@ public static void ComExportWMF(this Editor editor, string saveFile, ObjectId[]? #region JigEx - /// - /// jig前的准备工作,使图元暗显 - /// - /// 命令栏 - /// 实体(已存在数据库中) - public static void PrepareForJig(this Editor ed, params Entity[] ents) - { - ed.PrepareForJig(ents.ToList()); - } + /// /// jig前的准备工作,使图元暗显 /// /// 命令栏 /// 实体(已存在数据库中) - public static void PrepareForJig(this Editor ed, IEnumerable ents) + public static void PrepareForJig(this Editor ed, params IEnumerable ents) { var dic = new Dictionary(); foreach (var ent in ents) diff --git a/src/CADShared/ExtensionMethod/Entity/BlockReferenceEx.cs b/src/CADShared/ExtensionMethod/Entity/BlockReferenceEx.cs index 39ad840c361bb10b9628b76c61b3ea5e73c11c36..cdeda3235a45a8008fbae8c737731395491d4793 100644 --- a/src/CADShared/ExtensionMethod/Entity/BlockReferenceEx.cs +++ b/src/CADShared/ExtensionMethod/Entity/BlockReferenceEx.cs @@ -1,4 +1,4 @@ -#if a2024 || zcad +#if !NET8_0_OR_GREATER using ArgumentNullException = IFoxCAD.Basal.ArgumentNullEx; #endif @@ -23,7 +23,6 @@ public static void XClip(this BlockReference brf, IEnumerable pt3ds) { var mat = brf.BlockTransform.Inverse(); var pts = pt3ds.Select(p => p.TransformBy(mat).Point2d()).ToCollection(); - SpatialFilterDefinition sfd = new(pts, Vector3d.ZAxis, 0.0, double.PositiveInfinity, double.NegativeInfinity, true); using SpatialFilter sf = new(); @@ -43,13 +42,11 @@ public static void XClip(this BlockReference brf, Point3d pt1, Point3d pt2) var mat = brf.BlockTransform.Inverse(); pt1 = pt1.TransformBy(mat); pt2 = pt2.TransformBy(mat); - Point2dCollection pts = [ new Point2d(Math.Min(pt1.X, pt2.X), Math.Min(pt1.Y, pt2.Y)), new Point2d(Math.Max(pt1.X, pt2.X), Math.Max(pt1.Y, pt2.Y)) ]; - using SpatialFilter sf = new(); sf.Definition = new(pts, Vector3d.ZAxis, 0.0, double.PositiveInfinity, double.NegativeInfinity, true); @@ -223,9 +220,9 @@ public static string GetBlockName(this BlockReference blk) string nestedBlockName) { var tr = DBTrans.GetTopTransaction(parentBlockRef.Database); - var btr = tr.GetObject(parentBlockRef.BlockTableRecord); - if (btr == null) return null; + if (btr == null) + return null; foreach (var id in btr) { if (id.ObjectClass.Name == "AcDbBlockReference") @@ -323,4 +320,78 @@ public static void NestedForEach(this Entity blockReference, Action + /// 获取块可见性信息 + /// + /// 块参照 + /// 可见性信息 + public static BlockVisibilityInfo GetVisibilityInfo(this BlockReference blockReference) + { + var info = new BlockVisibilityInfo(); + if (blockReference.IsDynamicBlock) + { + var btr = (BlockTableRecord)blockReference.DynamicBlockTableRecord.GetObject(); + info = btr.GetVisibilityInfo(); + } + + return info; + } + + /// + /// 获取块可见性信息 + /// + /// 块表记录 + /// 可见性信息 + public static BlockVisibilityInfo GetVisibilityInfo(this BlockTableRecord btr) + { + var info = new BlockVisibilityInfo(); + if (btr.IsDynamicBlock && btr.ExtensionDictionary.IsOk()) + { + var dict = btr.GetXDictionary(); + if (dict.Contains("ACAD_ENHANCEDBLOCK")) + { + var idEnhancedBlock = dict.GetAt("ACAD_ENHANCEDBLOCK"); + var enhancedBlockTypedValues = Env.EntGet(idEnhancedBlock); + var parm = enhancedBlockTypedValues.FirstOrDefault(e => + e.TypeCode == 360 && e.Value is ObjectId id && id.IsOk() && + id.ObjectClass.DxfName == "BLOCKVISIBILITYPARAMETER") + .Value; + if (parm is ObjectId parmId) + { + info.Has = true; + var parmTypedValues = Env.EntGet(parmId); + info.PropertyName = parmTypedValues.FirstOrDefault(e => e.TypeCode == 301) + .Value?.ToString() ?? ""; + info.AllowedValues = parmTypedValues.Where(e => e.TypeCode == 303) + .Select(e => e.Value?.ToString() ?? "") + .Where(e => !string.IsNullOrWhiteSpace(e)) + .ToList(); + } + } + } + + return info; + } +} + +/// +/// 块可见性信息 +/// +public class BlockVisibilityInfo +{ + /// + /// 有无可见性 + /// + public bool Has { get; set; } + + /// + /// 属性名 + /// + public string PropertyName { get; set; } = ""; + + /// + /// 允许值 + /// + public List AllowedValues { get; set; } = []; } \ No newline at end of file diff --git a/src/CADShared/ExtensionMethod/Entity/CurveEx.cs b/src/CADShared/ExtensionMethod/Entity/CurveEx.cs index 14a51130884167c72f1099ce11dd0396dc90a847..0df06cde18045f47e8e36283ceba1ba07b32737f 100644 --- a/src/CADShared/ExtensionMethod/Entity/CurveEx.cs +++ b/src/CADShared/ExtensionMethod/Entity/CurveEx.cs @@ -1,6 +1,6 @@ // ReSharper disable ForCanBeConvertedToForeach -#if a2024 || zcad +#if !NET8_0_OR_GREATER using ArgumentNullException = IFoxCAD.Basal.ArgumentNullEx; #endif diff --git a/src/CADShared/ExtensionMethod/Geomerty/GeometryEx.cs b/src/CADShared/ExtensionMethod/Geomerty/GeometryEx.cs index d21d81851a17cacd5de05a4987a4e8f995937525..6fbbcd6dfc3ae25396658f5147b2e3939ba0658d 100644 --- a/src/CADShared/ExtensionMethod/Geomerty/GeometryEx.cs +++ b/src/CADShared/ExtensionMethod/Geomerty/GeometryEx.cs @@ -495,7 +495,85 @@ private static double Cross(Point2d o, Point2d a, Point2d b) return hullPts.Count >= 3 ? hullPts : null; } + + /// + /// 判断三个点是否左转 + /// + /// 第一点 + /// 第二点 + /// 第三点 + /// OrientationType 类型值 + public static OrientationType IsClockWise(Point3d p1, Point3d p2, Point3d p3) + { + return ((p2.X - p1.X) * (p3.Y - p2.Y) - (p2.Y - p1.Y) * (p3.X - p2.X)) switch + { + > 0 => OrientationType.CounterClockWise, + < 0 => OrientationType.ClockWise, + _ => OrientationType.Parallel + }; + + } + /// + /// Melkman算法求简单多边形凸包 + /// + /// 多边形端点列表 + /// 凸包端点列表 + public static List ConvexHull_Melkman(this List points) + { + if (points.Count <= 3) + { + return points; + } + var deque = new LinkedList(); + if (IsClockWise(points[0], points[1], points[2]) is OrientationType.CounterClockWise) + { + deque.AddFirst(points[2]); + deque.AddLast(points[0]); + deque.AddLast(points[1]); + deque.AddLast(points[2]); + } + else if (IsClockWise(points[0], points[1], points[2]) is OrientationType.ClockWise) + { + deque.AddFirst(points[2]); + deque.AddLast(points[1]); + deque.AddLast(points[0]); + deque.AddLast(points[2]); + } + else + { + deque.AddFirst(points[2]); + deque.AddLast(points[0]); + deque.AddLast(points[2]); + } + + foreach (var p in points.Skip(3)) + { + if (IsClockWise(deque.Last!.Previous!.Value, deque.Last.Value, p) is OrientationType.CounterClockWise + && IsClockWise(p, deque.First!.Value, deque.First.Next!.Value) is OrientationType.CounterClockWise) + { + continue; + } + while (deque.Count > 1 && IsClockWise(deque.Last!.Previous!.Value, deque.Last.Value, p) is not OrientationType.CounterClockWise) + { + deque.RemoveLast(); + } + deque.AddLast(p); + + while (deque.Count > 1 && IsClockWise(p, deque.First!.Value, deque.First.Next!.Value) is not OrientationType.CounterClockWise) + { + deque.RemoveFirst(); + } + deque.AddFirst(p); + + } + + if (deque.First!.Value == deque.Last!.Value) + { + deque.RemoveFirst(); + } + return [.. deque]; + } #endregion PointList #endregion Point&Circle @@ -632,17 +710,7 @@ public static Size GetSize(this Extents3d ext) /// /// 图形界面几何 /// 可绘制的对象列表 - public static void Draw(this Geometry geometry, IEnumerable drawables) - { - drawables.ForEach(d => geometry.Draw(d)); - } - - /// - /// 重绘 - /// - /// 图形界面几何 - /// 可绘制的对象列表 - public static void Draw(this Geometry geometry, params Drawable[] drawables) + public static void Draw(this Geometry geometry, params IEnumerable drawables) { drawables.ForEach(d => geometry.Draw(d)); } diff --git a/src/CADShared/ExtensionMethod/Geomerty/PointEx.cs b/src/CADShared/ExtensionMethod/Geomerty/PointEx.cs index f920a3cd0bf8aca0f3b82e8d8dd72a22119175e3..2a89e17409135e7fa89f6dd7e496cb484bc62bc5 100644 --- a/src/CADShared/ExtensionMethod/Geomerty/PointEx.cs +++ b/src/CADShared/ExtensionMethod/Geomerty/PointEx.cs @@ -1,4 +1,4 @@ -#if a2024 || zcad +#if !NET8_0_OR_GREATER using ArgumentNullException = IFoxCAD.Basal.ArgumentNullEx; #endif diff --git a/src/CADShared/ExtensionMethod/Hatch/HatchConverter.cs b/src/CADShared/ExtensionMethod/Hatch/HatchConverter.cs index fe79a623bd4dda12f333b6cbab53c6ad20401976..eb17ddd55da15c25aecacec9eeab4502c262698c 100644 --- a/src/CADShared/ExtensionMethod/Hatch/HatchConverter.cs +++ b/src/CADShared/ExtensionMethod/Hatch/HatchConverter.cs @@ -1,7 +1,7 @@ // ReSharper disable CompareOfFloatsByEqualityOperator // ReSharper disable ForCanBeConvertedToForeach -#if a2024 || zcad +#if !NET8_0_OR_GREATER using ArgumentNullException = IFoxCAD.Basal.ArgumentNullEx; #endif diff --git a/src/CADShared/ExtensionMethod/Hatch/HatchInfo.cs b/src/CADShared/ExtensionMethod/Hatch/HatchInfo.cs index f836615f30fabe9e69cd6f853899ebb89f4e6bad..b1d7576cbe63ed2f306658220b6b3707c7b6e4d2 100644 --- a/src/CADShared/ExtensionMethod/Hatch/HatchInfo.cs +++ b/src/CADShared/ExtensionMethod/Hatch/HatchInfo.cs @@ -1,6 +1,6 @@  -#if a2024 || zcad +#if !NET8_0_OR_GREATER using ArgumentNullException = IFoxCAD.Basal.ArgumentNullEx; #endif diff --git a/src/CADShared/ExtensionMethod/Jig/JigEx.cs b/src/CADShared/ExtensionMethod/Jig/JigEx.cs index 84fe2497835e1a012cfa11e5c700622e4c094285..eac7b62123861beea6321a79566386a58ce94afe 100644 --- a/src/CADShared/ExtensionMethod/Jig/JigEx.cs +++ b/src/CADShared/ExtensionMethod/Jig/JigEx.cs @@ -1,4 +1,4 @@ -#if a2024 || zcad +#if !NET8_0_OR_GREATER using ArgumentNullException = IFoxCAD.Basal.ArgumentNullEx; // ReSharper disable ClassWithVirtualMembersNeverInherited.Global diff --git a/src/CADShared/ExtensionMethod/PromptOptionsEx.cs b/src/CADShared/ExtensionMethod/PromptOptionsEx.cs index 637cc7cbbf67a6df7a67e537d8e6feb877705d97..17f33da3f07deca0b76f195f6b6a989818fc5f69 100644 --- a/src/CADShared/ExtensionMethod/PromptOptionsEx.cs +++ b/src/CADShared/ExtensionMethod/PromptOptionsEx.cs @@ -23,17 +23,18 @@ public static class PromptOptionsEx /// /// 选择集选项 /// 关键字 - public static void AddKeywords(this PromptSelectionOptions pso, params string[] keywords) + public static void AddKeywords(this PromptSelectionOptions pso, params IEnumerable keywords) { - for (var i = 0; i < keywords.Length / 2; i++) + var keyWords = keywords.ToList(); + for (var i = 0; i < keyWords.Count / 2; i++) { - var key = keywords[i * 2].ToUpper(); + var key = keyWords[i * 2].ToUpper(); if (SsGetSaveKeywords.FirstOrDefault(e => e.StartsWith(key)) is { } saveKey) { throw new ArgumentException($"关键字{key}与选择集保留关键字{saveKey}冲突"); } - var message = keywords[i * 2 + 1]; + var message = keyWords[i * 2 + 1]; var end = $"({key})"; if (!message.EndsWith(end)) { diff --git a/src/CADShared/ExtensionMethod/RXClassEx.cs b/src/CADShared/ExtensionMethod/RXClassEx.cs index a6e299a9a6a1624681b060ecf056df3c6c2def4e..d89e751303ddc5c9be4d0a0be18fccc32a9e72e8 100644 --- a/src/CADShared/ExtensionMethod/RXClassEx.cs +++ b/src/CADShared/ExtensionMethod/RXClassEx.cs @@ -1,5 +1,4 @@ -namespace IFoxCAD.CAD; - +namespace IFoxCAD.Cad; /// /// RXClass扩展 /// diff --git a/src/CADShared/ExtensionMethod/SelectionSetEx.cs b/src/CADShared/ExtensionMethod/SelectionSetEx.cs index 58d513a7175bfaca8a4382c1055586615a61c437..3e28927c99c73b5c63a38c8c7c819ac4a1808b38 100644 --- a/src/CADShared/ExtensionMethod/SelectionSetEx.cs +++ b/src/CADShared/ExtensionMethod/SelectionSetEx.cs @@ -1,6 +1,6 @@ -using IFoxCAD.CAD; -#if a2024 || zcad +#if !NET8_0_OR_GREATER using ArgumentNullException = IFoxCAD.Basal.ArgumentNullEx; + #endif namespace IFoxCAD.Cad; diff --git a/src/CADShared/ExtensionMethod/SingleKeyWordHook.cs b/src/CADShared/ExtensionMethod/SingleKeyWordHook.cs index 0f1f84cec713216190e24cca0c7c9371436c365b..f543953107124936e976f7511cb9787260e38647 100644 --- a/src/CADShared/ExtensionMethod/SingleKeyWordHook.cs +++ b/src/CADShared/ExtensionMethod/SingleKeyWordHook.cs @@ -74,7 +74,7 @@ public SingleKeyWordHook(SingleKeyWordWorkType workType = SingleKeyWordWorkType. /// 添加Keys /// /// Keys集合 - public void AddKeys(params Keys[] values) => values.ForEach(value => _keyWords.Add(value)); + public void AddKeys(params IEnumerable values) => values.ForEach(value => _keyWords.Add(value)); /// /// 添加Keys @@ -94,7 +94,7 @@ public void AddKeys(KeywordCollection keywordCollection) /// 移除Keys /// /// Keys集合 - public void Remove(params Keys[] values) => values.ForEach(value => _keyWords.Remove(value)); + public void Remove(params IEnumerable values) => values.ForEach(value => _keyWords.Remove(value)); /// /// 清空Keys diff --git a/src/CADShared/ExtensionMethod/SymbolTableEx.cs b/src/CADShared/ExtensionMethod/SymbolTableEx.cs index f780fd663274b97e0b25bf8c6ef27b5f0be8751e..0a20b8ab327ae43c71831f3938d701db2bbc8f81 100644 --- a/src/CADShared/ExtensionMethod/SymbolTableEx.cs +++ b/src/CADShared/ExtensionMethod/SymbolTableEx.cs @@ -1,6 +1,4 @@ -using ArgumentNullException = System.ArgumentNullException; - -namespace IFoxCAD.Cad; +namespace IFoxCAD.Cad; /// /// 符号表类扩展函数 @@ -85,14 +83,12 @@ public static bool Delete(this SymbolTable table, /// /// 块表 /// 块名 - /// 对所添加块表的委托n + /// 块定义额外处理的委托 /// 添加图元的委托 - /// 添加属性定义的委托 /// 块定义id /// TODO: 需要测试匿名块等特殊的块是否能定义 public static ObjectId Add(this SymbolTable table, string name, - Action? action = null, Func>? ents = null, - Func>? attDef = null) + Func>? ents = null, Action? action = null) { return table.Add(name, btr => { @@ -101,33 +97,9 @@ public static ObjectId Add(this SymbolTable table, var entsRes = ents?.Invoke(); if (entsRes is not null) btr.AddEntity(entsRes); - - var addDefRes = attDef?.Invoke(); - if (addDefRes is not null) - btr.AddEntity(addDefRes); }); } - - /// - /// 添加块定义 - /// - /// 块表 - /// 块名 - /// 图元 - /// 属性定义 - /// - public static ObjectId Add(this SymbolTable table, string name, - IEnumerable? ents = null, IEnumerable? attDef = null) - { - return table.Add(name, btr => - { - if (ents is not null) - btr.AddEntity(ents); - if (attDef is not null) - btr.AddEntity(attDef); - }); - } - + /// /// 添加块定义 /// @@ -136,9 +108,9 @@ public static ObjectId Add(this SymbolTable table, /// 图元(包括属性) /// public static ObjectId Add(this SymbolTable table, string name, - params Entity[] ents) + params IEnumerable ents) { - return table.Add(name, null, () => ents); + return table.Add(name, () => ents); } /// @@ -189,7 +161,7 @@ public static void AddAttsToBlocks(this SymbolTable table, string fileName, bool over) { - var blkDefName = SymbolUtilityServices.GetSymbolNameFromPathName(fileName, "dwg"); + var blkDefName = SymbolUtilityServices.GetSymbolNameFromPathName(fileName, "dwg;dxf"); #if acad blkDefName = SymbolUtilityServices.RepairSymbolName(blkDefName, false); #endif @@ -216,7 +188,14 @@ public static ObjectId GetBlockFrom(this SymbolTable块表记录 /// 实体集合 /// 对象 id 列表 - public static IEnumerable AddEntity(this BlockTableRecord btr, IEnumerable ents) + public static IEnumerable AddEntity(this BlockTableRecord btr, params IEnumerable ents) { var tr = DBTrans.GetTopTransaction(btr.Database); using (btr.ForWrite()) @@ -129,17 +129,6 @@ public static IEnumerable AddEntity(this BlockTableRecord btr, IEnumer } } - /// - /// 添加多个实体 - /// - /// 块表记录 - /// 实体集合 - /// 对象 id 列表 - public static IEnumerable AddEntity(this BlockTableRecord btr, params Entity[] ents) - { - return btr.AddEntity(ents.ToList()); - } - #endregion #region 获取实体/实体id diff --git a/src/CADShared/ExtensionMethod/TrustedPathEx.cs b/src/CADShared/ExtensionMethod/TrustedPathEx.cs index 00c1ccdf355fceb4dba87ff93efeae1cf7ed155d..a5c37da1aa267c6802957961def57aedce49afff 100644 --- a/src/CADShared/ExtensionMethod/TrustedPathEx.cs +++ b/src/CADShared/ExtensionMethod/TrustedPathEx.cs @@ -10,7 +10,7 @@ internal static class TrustedPathEx /// 路径列表 public static List Get() { - var str = Env.GetVar(kName).ToString(); + var str = Env.GetVar(kName).ToString()!; var set = str.ToLower() .Split([";"], StringSplitOptions.RemoveEmptyEntries) .Select(s => s.TrimEnd('\\')) diff --git a/src/CADShared/ExtensionMethod/XrefEx.cs b/src/CADShared/ExtensionMethod/XrefEx.cs index b23d94c581ab6bc5d5a87c763f799d6b46e3ad36..5910cd3520e6a32f6e2db305114843b1750597e9 100644 --- a/src/CADShared/ExtensionMethod/XrefEx.cs +++ b/src/CADShared/ExtensionMethod/XrefEx.cs @@ -1,6 +1,6 @@ // ReSharper disable ForCanBeConvertedToForeach -#if a2024 || zcad +#if !NET8_0_OR_GREATER using ArgumentNullException = IFoxCAD.Basal.ArgumentNullEx; #endif diff --git a/src/CADShared/Initialize/AutoRegAssem.cs b/src/CADShared/Initialize/AutoRegAssem.cs index eeecf3c769c2cc1c6f0c17086589bba05435b9c3..8bd70dcdc5067b77663927e5303b77b5bc7ec143 100644 --- a/src/CADShared/Initialize/AutoRegAssem.cs +++ b/src/CADShared/Initialize/AutoRegAssem.cs @@ -1,4 +1,4 @@ -#if a2024 || zcad +#if !NET8_0_OR_GREATER using ArgumentNullException = IFoxCAD.Basal.ArgumentNullEx; #endif diff --git a/src/CADShared/Initialize/MethodInfoHelper.cs b/src/CADShared/Initialize/MethodInfoHelper.cs index 79bede79fc9af4b5e429dc9830a571a587dfbe54..b671885e697734f5d3251c62af81cdf51e2253a7 100644 --- a/src/CADShared/Initialize/MethodInfoHelper.cs +++ b/src/CADShared/Initialize/MethodInfoHelper.cs @@ -1,4 +1,4 @@ -#if a2024 || zcad +#if !NET8_0_OR_GREATER using ArgumentNullException = IFoxCAD.Basal.ArgumentNullEx; #endif diff --git a/src/CADShared/Runtime/DBTrans.cs b/src/CADShared/Runtime/DBTrans.cs index a1a4cb44a0f84ccdfe11037b060187efc417d306..dd8766bae73f4354053337d0433b2a6493f51eba 100644 --- a/src/CADShared/Runtime/DBTrans.cs +++ b/src/CADShared/Runtime/DBTrans.cs @@ -1,5 +1,5 @@ namespace IFoxCAD.Cad; -#if a2024 || zcad +#if !NET8_0_OR_GREATER using ArgumentNullException = IFoxCAD.Basal.ArgumentNullEx; #endif using System.Diagnostics; diff --git a/src/CADShared/Runtime/Env.cs b/src/CADShared/Runtime/Env.cs index cbf39746ac8e253329bd14292561e27bf06bed71..2ad47309e2762b70b10d96e19560323eb90fc869 100644 --- a/src/CADShared/Runtime/Env.cs +++ b/src/CADShared/Runtime/Env.cs @@ -1,10 +1,14 @@ +#if zcad +using Marshaler = ZwSoft.ZwCAD.Runtime.Marshaler; +#else using System.Security; -#if a2024 || zcad +using Marshaler = Autodesk.AutoCAD.Runtime.Marshaler; +#endif +#if !NET8_0_OR_GREATER using ArgumentNullException = IFoxCAD.Basal.ArgumentNullEx; #endif // ReSharper disable StringLiteralTypo - namespace IFoxCAD.Cad; /// @@ -88,15 +92,6 @@ public static IConfigurationSection GetGlobalSection(string propertyName) #region Enum - /// - /// 控制在AutoLISP的command函数运行时AutoCAD是否回显提示和输入, 为显示, 为不显示 - /// - public static bool CmdEcho - { - get => Convert.ToInt16(Acaop.GetSystemVariable("cmdecho")) == 1; - set => Acaop.SetSystemVariable("cmdecho", Convert.ToInt16(value)); - } - /// /// 获取Cad当前是否有活动命令 /// @@ -111,15 +106,6 @@ public static bool OrthoMode set => Acaop.SetSystemVariable("ORTHOMODE", Convert.ToInt16(value)); } - /// - /// 读写系统变量LastPoint的坐标(UCS) - /// - public static Point3d LastPoint - { - get => (Point3d)Acaop.GetSystemVariable("LASTPOINT"); - set => Acaop.SetSystemVariable("LASTPOINT", value); - } - #region Dimblk /// @@ -414,17 +400,6 @@ public static OSModeType OSMode set => Acaop.SetSystemVariable("osmode", (int)value); } - /// - /// 捕捉模式osm1是否包含osm2 - /// - /// 原模式 - /// 要比较的模式 - /// 包含时返回 ,不包含时返回 - public static bool Include(this OSModeType osm1, OSModeType osm2) - { - return (osm1 & osm2) == osm2; - } - #endregion OsMode private static string? GetName(this T value) @@ -483,7 +458,6 @@ public static void SetVar(string varName, object value, bool echo = true) EntryPoint = "acedSetEnv")] private static extern int AcedSetEnv(string? envName, StringBuilder newValue); #endif - #if gcad [System.Security.SuppressUnmanagedCodeSecurity] [DllImport("gced.dll", CharSet = CharSet.Auto, CallingConvention = @@ -580,7 +554,7 @@ public static List GetSupportPath() /// 添加目录至CAD受信任的位置 /// /// 目录 - public static void AppendTrustedPath(params string[] folders) + public static void AppendTrustedPath(params IEnumerable folders) { TrustedPathEx.Add(folders); } @@ -589,7 +563,7 @@ public static void AppendTrustedPath(params string[] folders) /// 移除信任目录 /// /// 目录 - public static void RemoveTrustedPath(params string[] folders) + public static void RemoveTrustedPath(params IEnumerable folders) { TrustedPathEx.Remove(folders); } @@ -800,4 +774,31 @@ public static Dictionary SaveCadVar(Dictionary a } #endregion + + #region EntGet功能 + + /// + /// EntGet + /// + public static TypedValue[] EntGet(ObjectId objectId) + { + var adsName = GetAdsName(objectId); + var intPtr = PInvokeCad.AcdbEntGet(ref adsName); + var typedValues = Marshaler.ResbufToTypedValues(intPtr); + return typedValues; + } + + /// + /// GetAdsName + /// + /// ObjectId + /// ads_name + public static ads_name GetAdsName(ObjectId objectId) + { + var adsName = new ads_name(); + _ = PInvokeCad.GetAdsName(ref adsName, objectId); + return adsName; + } + + #endregion } \ No newline at end of file diff --git a/src/CADShared/Runtime/PInvokeCad.cs b/src/CADShared/Runtime/PInvokeCad.cs new file mode 100644 index 0000000000000000000000000000000000000000..9a4ae25baf548a0d3c8bc3832906fa36a4d5c392 --- /dev/null +++ b/src/CADShared/Runtime/PInvokeCad.cs @@ -0,0 +1,92 @@ +// ReSharper disable InconsistentNaming + +namespace IFoxCAD.Cad; + +/// +/// cad相关的PInvoke +/// +public static class PInvokeCad +{ + /// + /// Entget + /// + [DllImport("accore.dll", CallingConvention = CallingConvention.Cdecl, + EntryPoint = "acdbEntGet")] + public static extern IntPtr AcdbEntGet(ref ads_name adsName); + + /// + /// EntMod + /// + [DllImport("accore.dll", CallingConvention = CallingConvention.Cdecl, + EntryPoint = "acdbEntMod")] + public static extern void AcdbEndMod(IntPtr intPtr); + + [DllImport("acdb25.dll", CallingConvention = CallingConvention.Cdecl, + EntryPoint = "?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AEAY01_JVAcDbObjectId@@@Z")] + private static extern int AcdbGetAdsName25(ref ads_name adsName, ObjectId objectId); + + [DllImport("acdb24.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl, + EntryPoint = "?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AEAY01_JVAcDbObjectId@@@Z")] + private static extern int AcdbGetAdsName24(ref ads_name adsName, ObjectId objectId); + + [DllImport("acdb23.dll", CallingConvention = CallingConvention.Cdecl, + EntryPoint = "?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AEAY01_JVAcDbObjectId@@@Z")] + private static extern int AcdbGetAdsName23(ref ads_name adsName, ObjectId objectId); + + [DllImport("acdb22.dll", CallingConvention = CallingConvention.Cdecl, + EntryPoint = "?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AEAY01_JVAcDbObjectId@@@Z")] + private static extern int AcdbGetAdsName22(ref ads_name adsName, ObjectId objectId); + + [DllImport("acdb21.dll", CallingConvention = CallingConvention.Cdecl, + EntryPoint = "?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AEAY01_JVAcDbObjectId@@@Z")] + private static extern int AcdbGetAdsName21(ref ads_name adsName, ObjectId objectId); + + [DllImport("acdb20.dll", CallingConvention = CallingConvention.Cdecl, + EntryPoint = "?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AEAY01_JVAcDbObjectId@@@Z")] + private static extern int AcdbGetAdsName20(ref ads_name adsName, ObjectId objectId); + + [DllImport("acdb19.dll", CallingConvention = CallingConvention.Cdecl, + EntryPoint = "?acdbGetAdsName@@YA?AW4ErrorStatus@Acad@@AEAY01_JVAcDbObjectId@@@Z")] + private static extern int AcdbGetAdsName19(ref ads_name adsName, ObjectId objectId); + + /// + /// GetAdsName + /// + public static int GetAdsName(ref ads_name adsName, ObjectId id) + { + var major = Acaop.Version.Major; + var res = major switch + { + 25 => AcdbGetAdsName25(ref adsName, id), + 24 => AcdbGetAdsName24(ref adsName, id), + 23 => AcdbGetAdsName23(ref adsName, id), + 22 => AcdbGetAdsName22(ref adsName, id), + 21 => AcdbGetAdsName21(ref adsName, id), + 20 => AcdbGetAdsName20(ref adsName, id), + 19 => AcdbGetAdsName19(ref adsName, id), + _ => 1, + }; + return res; + } +} + +/// +/// 用于使用Entget等函数的结构体 +/// +// ReSharper disable once InconsistentNaming +public struct ads_name +{ + /// + /// 构造函数 + /// + public ads_name() + { + a = b = IntPtr.Zero; + } + + // ReSharper disable once NotAccessedField.Local + private IntPtr a; + + // ReSharper disable once NotAccessedField.Local + private IntPtr b; +} \ No newline at end of file diff --git a/src/CADShared/Runtime/SymbolTable.cs b/src/CADShared/Runtime/SymbolTable.cs index ad73274b0ddd15dca062e4dafc790bae63d62eaa..c6c9422ebc5dd7275ee43a4de992704eabd39527 100644 --- a/src/CADShared/Runtime/SymbolTable.cs +++ b/src/CADShared/Runtime/SymbolTable.cs @@ -1,6 +1,6 @@ // ReSharper disable RedundantNameQualifier -#if a2024 || zcad +#if !NET8_0_OR_GREATER using ArgumentNullException = IFoxCAD.Basal.ArgumentNullEx; #endif diff --git a/src/CADShared/Runtime/SystemVariableManager.cs b/src/CADShared/Runtime/SystemVariableManager.cs index c16dd8c3d4db110d5a81bdadbad494a6e938f785..fd874b59b1fcd87d330d41a28e449adfd2f5bb9c 100644 --- a/src/CADShared/Runtime/SystemVariableManager.cs +++ b/src/CADShared/Runtime/SystemVariableManager.cs @@ -202,10 +202,10 @@ public static short CVPort /// /// 是否开启双击 /// - public static bool DblClick + public static bool DblClkEdit { - get => Convert.ToBoolean(Acaop.GetSystemVariable(nameof(DblClick))); - set => Acaop.SetSystemVariable(nameof(DblClick), Convert.ToInt32(value)); + get => Convert.ToBoolean(Acaop.GetSystemVariable(nameof(DblClkEdit))); + set => Acaop.SetSystemVariable(nameof(DblClkEdit), Convert.ToInt32(value)); } /// diff --git a/src/CADShared/SelectionFilter/OpFilter.cs b/src/CADShared/SelectionFilter/OpFilter.cs index 7eb495db4a131fa9fd17f2e150907dee87f4752c..b1e2b43dbe402e8d9e2f138289715715dd42b0d9 100644 --- a/src/CADShared/SelectionFilter/OpFilter.cs +++ b/src/CADShared/SelectionFilter/OpFilter.cs @@ -117,7 +117,7 @@ private Op(OpFilter filter) /// 操作符类型的可变参数 /// Op对象 #pragma warning disable CA1822 // 将成员标记为 static - public Op And(params Op[] args) + public Op And(params IEnumerable args) #pragma warning restore CA1822 // 将成员标记为 static { var filter = new OpAnd(); @@ -132,7 +132,7 @@ public Op And(params Op[] args) /// 操作符类型的可变参数 /// Op对象 #pragma warning disable CA1822 // 将成员标记为 static - public Op Or(params Op[] args) + public Op Or(params IEnumerable args) #pragma warning restore CA1822 // 将成员标记为 static { var filter = new OpOr(); diff --git a/src/CADShared/UserInterface/Menu.cs b/src/CADShared/UserInterface/Menu.cs new file mode 100644 index 0000000000000000000000000000000000000000..5a2607b05d0550a720726ef3139f409fe4bd559e --- /dev/null +++ b/src/CADShared/UserInterface/Menu.cs @@ -0,0 +1,262 @@ +namespace IFoxCAD.Cad; + + +/// +/// 菜单项数据类 +/// +public record MenuData +{ + /// + /// + /// + public required string Label { get; init; } + /// + /// + /// + public required string Macro { get; init; } + /// + /// + /// + public required string HelpString { get; init; } + /// + /// + /// + public required List? SubItem { get; init; } +} + +/// +/// +/// +public record ToolBarData +{ + /// + /// + /// + public required string ToolBarName; + /// + /// + /// + public required List ToolButtonDatas; +} + +/// +/// +/// +public record ToolButtonData +{ + /// + /// + /// + public required string Name; + /// + /// + /// + public required string HelpString; + /// + /// + /// + public required string Macro; + /// + /// + /// + public required string SmallIconName; + /// + /// + /// + public required string LargeIconName; + /// + /// + /// + public required bool FlyoutButton; +} + +/// +/// +/// +public enum DockSide +{ + /// + /// + /// + Top, + /// + /// + /// + Bottom, + /// + /// + /// + Left, + /// + /// + /// + Right +} + +/// +/// +/// +public static class IFoxMenu +{ + private static dynamic _app = Acap.AcadApplication; //定义cad对象 + private static dynamic _menuBar = _app.MenuBar; + private static dynamic _menuGroups = _app.MenuGroups; + + #region 通用数据版API + + /// + /// 插入菜单条 + /// + /// 菜单条对象 + /// 菜单项列表 + private static void InsertPopMenuItems(dynamic popMenu, List popItems) + { + //int k = 0; + foreach (var item in popItems) + { + if (item.Label == "--") + { + popMenu.AddSeparator(popMenu.Count + 1); + } + else + { + { + var menu = popMenu.AddMenuItem(popMenu.Count + 1, item.Label, item.Macro); + //menu.HelpString = item.HelpString; + } + } + } + } + + /// + /// 添加下拉菜单 + /// + /// 下拉菜单名称 + /// 菜单项列表 + /// 菜单组名称 + /// 在哪个菜单之前插入,null或者找不到的插入最后 + public static void AddPopMenu(string popName, List popItems, string menuGroupName = "ACAD", string? insertBeforeItem = null) + { +#if zcad + menuGroupName = "ZWCAD"; +#endif + + RemoveMenuItem(popName); + int i; + if (insertBeforeItem != null) + { + i = _menuBar.Count - 1; + while (i >= 0 && insertBeforeItem != _menuBar.Item(i).Name) + { + i--; + } + if (i < 0) + { + i = _menuBar.Count; + } + } + else + { + i = _menuBar.Count; + } + dynamic newMenu; + try + { + newMenu = _menuGroups.Item(menuGroupName).Menus.Item(popName); + } + catch (Exception) + { + newMenu = _menuGroups.Item(menuGroupName).Menus.Add(popName); + } + + foreach (var item in newMenu) + { + item.Delete(); + } + newMenu.InsertInMenuBar(i); + InsertPopMenuItems(newMenu, popItems); + } + + /// + /// 添加工具条,由于分隔符的位置由于未知的原因不在正确的位置,不建议添加分隔符。 + /// + /// 工具条的列表 + /// 菜单组的名字 + public static void AddToolBars(ToolBarData toolBarData, string menuGroupName = "ACAD") + { + dynamic menuGroup; + try + { + menuGroup = _menuGroups.Item(menuGroupName); + } + catch (Exception) + { + throw new Exception($"菜单组 {menuGroupName} 不存在,无法加载工具条!"); + } + + var toolBars = menuGroup.Toolbars; + + dynamic toolBar; + try + { + toolBar = toolBars.Item(toolBarData.ToolBarName); + toolBar.Delete(); + } + catch (Exception) + { + } + + toolBar = toolBars.Add(toolBarData.ToolBarName); + toolBar.Dock(2); + + foreach (var item in toolBarData.ToolButtonDatas) + { + if (item.Name == "--") + { + try + { + toolBar.AddSeparator(toolBar.Count + 1); + } + catch (Exception) + { + } + } + else + { + var toolBarItem = toolBar.AddToolbarButton(toolBar.Count + 1, item.Name, item.HelpString, item.Macro, item.FlyoutButton); + try + { + toolBarItem.SetBitmaps(item.SmallIconName, item.LargeIconName); + } + catch (Exception) + { + } + + if (item.FlyoutButton) + { + toolBarItem.AttachToolbarToFlyout(menuGroupName, toolBarData.ToolBarName); + } + } + } + } + + /// + /// 删除下拉菜单函数 + /// + /// 菜单名称 + private static void RemoveMenuItem(string popName) + { + try + { + dynamic menu = _menuBar.Item(popName); + menu.RemoveFromMenuBar(); + } + catch (Exception) + { + } + } + + #endregion 通用数据版API + + +} \ No newline at end of file diff --git a/src/CADShared/UserInterface/Ribbon.cs b/src/CADShared/UserInterface/Ribbon.cs new file mode 100644 index 0000000000000000000000000000000000000000..c157f016b6163606bbf579a3c427b44232bbe281 --- /dev/null +++ b/src/CADShared/UserInterface/Ribbon.cs @@ -0,0 +1,372 @@ +namespace IFoxCAD.Cad; +using System.Windows.Controls; +using System.Windows.Media.Imaging; +internal class RibbonCommandHandler : ICommand +{ + //定义用于确定此命令是否可以在其当前状态下执行的方法。 + public bool CanExecute(object? parameter) + { + return true; + } +#pragma warning disable CS0067 + public event EventHandler? CanExecuteChanged; +#pragma warning restore CS0067 + // 定义在调用此命令时调用的方法。 + public void Execute(object? parameter) + { + if (parameter is not RibbonButton btn) return; + if (btn.CommandParameter == null) return; + var doc = Acaop.DocumentManager.MdiActiveDocument; + doc.SendStringToExecute(btn.CommandParameter.ToString(), true, false, false); + } +} + + + + + + +/// +/// +/// +public static class Ribbon +{ + //面板的按钮是按行排列,即row,所以涉及到换行的时候,多行的时候,要用ribbonrowbreak换行 + //面板下面隐藏的按钮,需要面板换行,用ribbonpanelbreak,不然不会自动隐藏 + //面板里按列排列的按钮要放在ribbonrowpanel的items里,同时要在每个按钮的后面加上分隔符和换行,顺序不能乱 + + #region 通用版本API + + /// + /// 添加ribbon选项卡 + /// + /// ribbon控件对象 + /// 选项卡名字,默认id=$"ID_Tab_{title}" + /// 是否激活 + /// ribbon选项卡 + public static RibbonTab AddTab(this RibbonControl control, string title, bool isActive) + { + RibbonTab tab = new RibbonTab + { + Title = title, + Id = $"ID_Tab_{title}" + }; + control.Tabs.Add(tab); + tab.IsActive = isActive; + return tab; + } + + /// + /// 添加ribbon面板 + /// + /// ribbon选项卡 + /// 面板名字 + /// ribbon面板资源对象 + public static RibbonPanelSource AddPanel(this RibbonTab tab, string title) + { + RibbonPanelSource source = new RibbonPanelSource + { + Title = title + }; + RibbonPanel panel = new RibbonPanel + { + Source = source + }; + tab.Panels.Add(panel); + return source; + } + + /// + /// 添加ribbon按钮 + /// + /// ribbon面板资源对象 + /// 按钮名字 + /// 按钮要执行的命令 + /// + /// 按钮尺寸大小 + /// 按钮名字相对图标的位置 + /// ribbon按钮 + public static RibbonButton AddButton(this RibbonPanelSource panel, string name, string cmd, + System.Windows.Media.ImageSource? imageSource = null, + RibbonItemSize size = RibbonItemSize.Standard, Orientation orient = Orientation.Horizontal) + { + RibbonButton button = new RibbonButton + { + Name = name,//按钮的名称 + Text = name, + ShowText = true, //显示文字 + + Size = size, //按钮尺寸 + Orientation = orient, //按钮排列方式 + CommandHandler = new RibbonCommandHandler(),//给按钮关联命令 + CommandParameter = cmd + " ", + + Image = imageSource, + LargeImage = imageSource, + ShowImage = true, //显示图片 + }; + + panel.Items.Add(button); + return button; + } + + /// + /// 添加ribbon按钮 + /// + /// ribbon下拉按钮对象 + /// 按钮名字 + /// 按钮要执行的命令 + /// 按钮尺寸大小 + /// 按钮名字相对图标的位置 + /// ribbon按钮 + public static RibbonButton AddButton(this RibbonSplitButton panel, string name, string cmd, + RibbonItemSize size = RibbonItemSize.Standard, Orientation orient = Orientation.Horizontal) + { + RibbonButton button = new RibbonButton + { + Name = name,//按钮的名称 + Text = name, + ShowText = true, //显示文字 + + Size = size, //按钮尺寸 + Orientation = orient, //按钮排列方式 + CommandHandler = new RibbonCommandHandler(),//给按钮关联命令 + CommandParameter = cmd + " ", + ShowImage = true, //显示图片 + }; + + panel.Items.Add(button); + + return button; + } + + /// + /// 添加ribbon按钮 + /// + /// ribbon行面板对象 + /// 按钮名字 + /// 按钮要执行的命令 + /// 按钮尺寸大小 + /// 按钮名字相对图标的位置 + /// ribbon按钮 + public static RibbonButton AddButton(this RibbonRowPanel panel, string name, string cmd, + RibbonItemSize size = RibbonItemSize.Standard, Orientation orient = Orientation.Horizontal) + { + RibbonButton button = new RibbonButton + { + Name = name,//按钮的名称 + Text = name, + ShowText = true, //显示文字 + + Size = size, //按钮尺寸 + Orientation = orient, //按钮排列方式 + CommandHandler = new RibbonCommandHandler(),//给按钮关联命令 + CommandParameter = cmd + " ", + ShowImage = true, //显示图片 + }; + panel.Items.Add(button); + return button; + } + /// + /// + /// + /// + /// + public static void AddButton(this RibbonPanelSource source, RibbonItemCollection items) + { + foreach (var item in items) + { + source.Items.Add(item); + } + } + + /// + /// 添加分隔符 + /// + /// ribbon面板资源对象 + /// 分隔符类型 + public static void AddSep(this RibbonPanelSource source, RibbonSeparatorStyle style) + { + RibbonSeparator separator = new RibbonSeparator + { + SeparatorStyle = style + }; + source.Items.Add(separator); + } + + /// + /// 添加分隔符 + /// + /// ribbon行面板对象 + /// 分隔符类型 + public static void AddSep(this RibbonRowPanel source, RibbonSeparatorStyle style) + { + RibbonSeparator separator = new RibbonSeparator + { + SeparatorStyle = style + }; + source.Items.Add(separator); + } + + /// + /// 添加ribbon行面板 + /// + /// ribbon面板资源对象 + /// ribbon行面板 + public static RibbonRowPanel AddRowPanel(this RibbonPanelSource source) + { + RibbonRowPanel panel = new RibbonRowPanel(); + source.Items.Add(panel); + return panel; + } + + /// + /// 添加ribbon换行符 + /// + /// ribbon面板资源对象 + public static void AddRowBreak(this RibbonPanelSource source) + { + RibbonRowBreak ribbonPanelBreak = new RibbonRowBreak(); + source.Items.Add(ribbonPanelBreak); + } + + /// + /// 添加ribbon换行符 + /// + /// ribbon行面板对象 + public static void AddRowBreak(this RibbonRowPanel source) + { + RibbonRowBreak ribbonPanelBreak = new RibbonRowBreak(); + source.Items.Add(ribbonPanelBreak); + } + + /// + /// 添加ribbon面板换行符,该对象之后的按钮全部默认隐藏 + /// + /// ribbon面板资源对象 + public static void AddPanelBreak(this RibbonPanelSource source) + { + RibbonPanelBreak ribbonPanelBreak = new RibbonPanelBreak(); + source.Items.Add(ribbonPanelBreak); + } + + /// + /// 添加ribbon下拉按钮 + /// + /// ribbon面板资源对象 + /// 下拉按钮名字 + /// 下拉按钮的尺寸大小 + /// 按钮名字相对图标的位置 + /// ribbon下拉按钮 + public static RibbonSplitButton AddSplitButton(this RibbonPanelSource source, string text, RibbonItemSize size = RibbonItemSize.Large, Orientation orientation = Orientation.Horizontal) + { + RibbonSplitButton splitButton = new RibbonSplitButton + { + Text = text, + ShowText = true, + Size = size, + ShowImage = true, + Orientation = orientation, + }; + source.Items.Add(splitButton); + return splitButton; + } + + /// + /// 添加ribbon下拉按钮 + /// + /// ribbon行面板对象 + /// 下拉按钮名字 + /// 下拉按钮的尺寸大小 + /// 按钮名字相对图标的位置 + /// ribbon下拉按钮 + public static RibbonSplitButton AddSplitButton(this RibbonRowPanel source, string text, RibbonItemSize size = RibbonItemSize.Large, Orientation orientation = Orientation.Horizontal) + { + RibbonSplitButton splitButton = new RibbonSplitButton + { + Text = text, + ShowText = true, + Size = size, + ShowImage = true, + Orientation = orientation, + }; + source.Items.Add(splitButton); + return splitButton; + } + + /// + /// 设置按钮的图标 + /// + /// ribbon按钮 + /// 图标路径 + /// 按钮对象 + public static RibbonButton SetImage(this RibbonButton button, string imgFileName) + { + try + { + // Uri uri = new Uri(imgFileName); + // BitmapImage bitmapImge = new BitmapImage(uri); + // + + + BitmapImage bmp = new BitmapImage(); + + // BitmapImage.UriSource must be in a BeginInit/EndInit block. + + bmp.BeginInit(); + + bmp.UriSource = new Uri( + + imgFileName); + + bmp.EndInit(); + + + + + + + + button.Image = bmp; //按钮图片 + button.LargeImage = bmp; //按钮大图片 + } + catch (Exception) + { + } + + return button; + } + + /// + /// 添加按钮提示 + /// + /// ribbon按钮 + /// 提示名字 + /// 提示内容 + /// 提示的命令 + /// 提示的扩展内容 + /// 提示的图标路径 + /// ribbon按钮 + public static RibbonButton SetToolTip(this RibbonButton button, string title = "", string content = "", string cmd = "", string expandContent = "", string imgFileName = "") + { + RibbonToolTip toolTip = new RibbonToolTip(); + toolTip.Title = title; + toolTip.Content = content; + toolTip.Command = cmd; + toolTip.ExpandedContent = expandContent; + try + { + Uri toolTipUri = new Uri(imgFileName); + BitmapImage toolTipBitmapImge = new BitmapImage(toolTipUri); + toolTip.ExpandedImage = toolTipBitmapImge; + } + catch (Exception) + { + } + + button.ToolTip = toolTip; + + return button; + } + #endregion +} \ No newline at end of file diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 9a365f1fbf81df30248c47e2523e8368754fa5a2..7dbaee6500cbd97c33a81de600ad5c91704a5528 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,8 +1,8 @@ - 0.9.4 - 整理支持文件搜索路径和信任路径的扩展方法并添加Get方法 + 0.9.5 + 添加EntGet,组织部分系统变量,添加可见性信息获取功能 diff --git a/src/IFoxCAD.AutoCad/GlobalUsings.cs b/src/IFoxCAD.AutoCad/GlobalUsings.cs index 67dcfff663047d2efb5ed03f2fb037777e1afd30..9e026384f6e6d6cfd9584e4476b41b8a64d7b90e 100644 --- a/src/IFoxCAD.AutoCad/GlobalUsings.cs +++ b/src/IFoxCAD.AutoCad/GlobalUsings.cs @@ -6,6 +6,7 @@ global using Autodesk.AutoCAD.Runtime; global using Autodesk.AutoCAD.Windows; global using Autodesk.AutoCAD.Colors; +global using Autodesk.Windows; global using Autodesk.AutoCAD.DatabaseServices.Filters; global using Autodesk.AutoCAD.GraphicsSystem; global using LineWeight = Autodesk.AutoCAD.DatabaseServices.LineWeight; diff --git a/src/IFoxCAD.AutoCad/IFoxCAD.AutoCad.csproj b/src/IFoxCAD.AutoCad/IFoxCAD.AutoCad.csproj index d6c0b9157f825fe3f69ec7d634ca95d00450cfee..eb42055c23f762c97898781a000bc9e54fb051ce 100644 --- a/src/IFoxCAD.AutoCad/IFoxCAD.AutoCad.csproj +++ b/src/IFoxCAD.AutoCad/IFoxCAD.AutoCad.csproj @@ -45,8 +45,7 @@ - - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/IFoxCAD.ZwCad/GlobalUsings.cs b/src/IFoxCAD.ZwCad/GlobalUsings.cs index a3365f56a2c6baa8b18683d5b5e54487f6ffbb4a..c159d90ff59dc8d216572783ee75043cbf2cadd8 100644 --- a/src/IFoxCAD.ZwCad/GlobalUsings.cs +++ b/src/IFoxCAD.ZwCad/GlobalUsings.cs @@ -6,6 +6,7 @@ global using ZwSoft.ZwCAD.Runtime; global using ZwSoft.ZwCAD.Windows; global using ZwSoft.ZwCAD.Colors; +global using ZwSoft.Windows; global using ZwSoft.ZwCAD.DatabaseServices.Filters; global using ZwSoft.ZwCAD.GraphicsSystem; global using LineWeight = ZwSoft.ZwCAD.DatabaseServices.LineWeight; diff --git a/src/IFoxCAD.ZwCad/IFoxCAD.ZwCad.csproj b/src/IFoxCAD.ZwCad/IFoxCAD.ZwCad.csproj index 4b659bef5716b847b13970b17f675cddffc5a990..581ae93c9ef6efe529e95efc194ea475de8385be 100644 --- a/src/IFoxCAD.ZwCad/IFoxCAD.ZwCad.csproj +++ b/src/IFoxCAD.ZwCad/IFoxCAD.ZwCad.csproj @@ -36,9 +36,8 @@ - - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/tests/TestAcad2025/GlobalUsings.cs b/tests/TestAcad2025/GlobalUsings.cs index 045196f703ea51e14af47638509ed97287167b95..a535b17fbb9c576b1ebe3e40052b60aca9213b05 100644 --- a/tests/TestAcad2025/GlobalUsings.cs +++ b/tests/TestAcad2025/GlobalUsings.cs @@ -30,7 +30,7 @@ global using Autodesk.AutoCAD.DatabaseServices.Filters; global using Autodesk.AutoCAD; - +global using Autodesk.Windows; // jig命名空间会引起Viewport/Polyline等等重义,最好逐个引入 using Autodesk.AutoCAD.GraphicsInterface global using WorldDraw = Autodesk.AutoCAD.GraphicsInterface.WorldDraw; global using Manager = Autodesk.AutoCAD.GraphicsSystem.Manager; diff --git a/tests/TestAcad2025/TestAcad2025.csproj b/tests/TestAcad2025/TestAcad2025.csproj index 1109e94ce4bcc98ccec94cb2b3f3dd9d0eeb7593..8ff61fe8fae33f65b30dada82c6141adaaeec507 100644 --- a/tests/TestAcad2025/TestAcad2025.csproj +++ b/tests/TestAcad2025/TestAcad2025.csproj @@ -34,12 +34,9 @@ - + - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/tests/TestShared/TestBlkVisibility.cs b/tests/TestShared/TestBlkVisibility.cs new file mode 100644 index 0000000000000000000000000000000000000000..8417fa3328e2571b3119cf84e8216af1896a4893 --- /dev/null +++ b/tests/TestShared/TestBlkVisibility.cs @@ -0,0 +1,20 @@ +using System.Windows; + +namespace TestAcad2025; + +public static class TestBlkVisibility +{ + [CommandMethod(nameof(TestBlkVisibility))] + public static void Main() + { + var r1 = Env.Editor.GetEntity("\n选择块参照"); + if (r1.Status != PromptStatus.OK) + return; + using var tr = new DBTrans(); + if (tr.GetObject(r1.ObjectId) is not BlockReference { IsDynamicBlock: true } brf) + return; + var info = brf.GetVisibilityInfo(); + MessageBox.Show( + $"块{brf.Name}的可见性名字:{info.PropertyName},参数:{string.Join(", ", info.AllowedValues)}。是否可见?{info.Has}"); + } +} \ No newline at end of file diff --git a/tests/TestShared/TestBlock.cs b/tests/TestShared/TestBlock.cs index 20baa825524e98a23c29a8e527db295beaa9513e..3065de4eddb5dc2bacdcb8bafa15c852fddf2c78 100644 --- a/tests/TestShared/TestBlock.cs +++ b/tests/TestShared/TestBlock.cs @@ -47,32 +47,33 @@ public void Test_BlockDef() using DBTrans tr = new(); // var line = new Line(new Point3d(0, 0, 0), new Point3d(1, 1, 0)); tr.BlockTable.Add("test", - btr => - { - btr.Origin = new Point3d(0, 0, 0); - }, - () => // 图元 - new List { new Line(new Point3d(0, 0, 0), new Point3d(1, 1, 0)) }, - () => // 属性定义 + () => // 图元和属性定义 { + var line1 = new Line(new Point3d(0, 0, 0),new Point3d(1, 1, 0)); var id1 = new AttributeDefinition() { Position = new Point3d(0, 0, 0), Tag = "start", Height = 0.2 }; var id2 = new AttributeDefinition() { Position = new Point3d(1, 1, 0), Tag = "end", Height = 0.2 }; - return new List { id1, id2 }; + return [line1, id1, id2 ]; + }, + btr => + { + btr.Origin = new Point3d(0, 0, 0); } ); // ObjectId objectId = tr.BlockTable.Add("a");// 新建块 // objectId.GetObject().AddEntity();// 测试添加空实体 tr.BlockTable.Add("test1", - btr => - { - btr.Origin = new Point3d(0, 0, 0); - }, + () => { var line = new Line(new Point3d(0, 0, 0), new Point3d(1, 1, 0)); var acText = DBTextEx.CreateDBText(Point3d.Origin, "123", 2.5); return new List { line, acText }; - }); + }, + btr => + { + btr.Origin = new Point3d(0, 0, 0); + } + ); } // 后台块定义 @@ -82,34 +83,37 @@ public void Test_BlockDefbehind() using DBTrans tr = new(@"C:\Users\vic\Desktop\test.dwg"); // var line = new Line(new Point3d(0, 0, 0), new Point3d(1, 1, 0)); tr.BlockTable.Add("test", - btr => + + + () => // 图元和属性定义 + { + var line1 = new Line(new Point3d(0, 0, 0),new Point3d(1, 1, 0)); + var id1 = new AttributeDefinition() { Position = new Point3d(0, 0, 0), Tag = "start", Height = 0.2 }; + var id2 = new AttributeDefinition() { Position = new Point3d(1, 1, 0), Tag = "end", Height = 0.2 }; + return [line1, id1, id2 ]; + }, + btr => { btr.Origin = new Point3d(0, 0, 0); - }, - () => // 图元 - { - return new List { new Line(new Point3d(0, 0, 0), new Point3d(1, 1, 0)) }; - }, - () => // 属性定义 - { - var id1 = new AttributeDefinition() { Position = new Point3d(0, 0, 0), Tag = "start", Height = 0.2 }; - var id2 = new AttributeDefinition() { Position = new Point3d(1, 1, 0), Tag = "end", Height = 0.2 }; - return new List { id1, id2 }; } + + + ); // ObjectId objectId = tr.BlockTable.Add("a");// 新建块 // objectId.GetObject().AddEntity();// 测试添加空实体 tr.BlockTable.Add("test1", - btr => - { - btr.Origin = new Point3d(0, 0, 0); - }, + () => { var line = new Line(new Point3d(0, 0, 0), new Point3d(1, 1, 0)); var acText = DBTextEx.CreateDBText(Point3d.Origin, "12345", 2.5); - return new List { line, acText }; + return [line, acText ]; + }, + btr => + { + btr.Origin = new Point3d(0, 0, 0); }); tr.Database.SaveDwgFile(); } @@ -179,7 +183,8 @@ public void Test_InsertBlockDef() var line4 = new Line(new Point3d(5, 5, 0), new Point3d(-6, 6, 0)); var att3 = new AttributeDefinition() { Position = new Point3d(10, 14, 0), Tag = "tagTest3", Height = 1, TextString = "valueTest3" }; var att4 = new AttributeDefinition() { Position = new Point3d(10, 16, 0), Tag = "tagTest4", Height = 1, TextString = "valueTest4" }; - tr.BlockTable.Add("test2", new List { line3, line4 }, new List { att3, att4 }); + List lst = [line3, line4, att3, att4]; + tr.BlockTable.Add("test2", lst); // tr.CurrentSpace.InsertBlock(new Point3d(4, 4, 0), "test1"); // 测试默认 // tr.CurrentSpace.InsertBlock(new Point3d(4, 4, 0), "test2"); // tr.CurrentSpace.InsertBlock(new Point3d(4, 4, 0), "test3"); // 测试插入不存在的块定义 @@ -209,18 +214,19 @@ public void Test_InsertBlockWithDoubleDatabase() using var trans = new DBTrans(); tr.BlockTable.Add("test456", - btr => - { - btr.Origin = new(0, 0, 0); - }, + () => { var line = new Line(new(0, 0, 0), new(1, 1, 0)); var actext = DBTextEx.CreateDBText(Point3d.Origin, "123", 2.5, database: tr.Database); - return new List { line, actext }; + return [ line, actext ]; - }); + }, + btr => + { + btr.Origin = new(0, 0, 0); + }); tr.CurrentSpace.InsertBlock(Point3d.Origin, "test456"); tr.Database.SaveDwgFile(); } @@ -237,7 +243,7 @@ public void Test_AddAttsDef() return; var att1 = new AttributeDefinition() { Position = new Point3d(20, 20, 0), Tag = "addtagTest1", Height = 1, TextString = "valueTest1" }; var att2 = new AttributeDefinition() { Position = new Point3d(10, 12, 0), Tag = "tagTest2", Height = 1, TextString = "valueTest2" }; - tr.BlockTable.AddAttsToBlocks(btf.BlockTableRecord, new() { att1, att2 }); + tr.BlockTable.AddAttsToBlocks(btf.BlockTableRecord, [att1, att2]); } [CommandMethod(nameof(Test_BlockNullBug))] @@ -390,8 +396,6 @@ public void Test_Block_ej() break; case "$$B": break; - default: - break; } } else if (ent is DBText dBText) @@ -408,8 +412,6 @@ public void Test_Block_ej() dimension.DimensionText = "350"; dimension.RecomputeDimensionBlock(true); break; - default: - break; } } } diff --git a/tests/TestShared/TestConvexHull.cs b/tests/TestShared/TestConvexHull.cs index 03692ae5ffc3cceec783cd35c053079e7374ba03..9060edfb5b3b33ae2a5f462d72e169e9b5a09600 100644 --- a/tests/TestShared/TestConvexHull.cs +++ b/tests/TestShared/TestConvexHull.cs @@ -73,4 +73,33 @@ public void Test_ConvexHull() Env.Editor.WriteMessage($"点集的有向面积:{area5} \n"); Env.Editor.WriteMessage($"点集的有向面积:{area6} \n"); } + + [CommandMethod(nameof(Test_ConvexHull_Melkman))] + public static void Test_ConvexHull_Melkman() + { + using var tr = new DBTrans(); + var ent = Env.Editor.GetEntity("选取多段线"); + if (ent.Status != PromptStatus.OK) return; + var pts = ent.ObjectId.GetObject()!.GetPoints(); + var ptss = pts.ConvexHull_Melkman(); + var pl = ptss.CreatePolyline(p => + { + p.Closed = true; + p.ColorIndex = 3; + }); + tr.CurrentSpace.AddEntity(pl); + } + + + [CommandMethod(nameof(Test_IsClockWise))] + public static void Test_IsClockWise() + { + using var tr = new DBTrans(); + var p1 = Env.Editor.GetPoint("第一点:").Value; + var p2 = Env.Editor.GetPoint("第二点:").Value; + var p3 = Env.Editor.GetPoint("第三点:").Value; + var res1 = GeometryEx.IsClockWise(p1, p2, p3); + Env.Printl($"IsClockWise(p1, p2, p3) 的结果为:{res1}"); + + } } \ No newline at end of file diff --git a/tests/TestShared/TestEnv.cs b/tests/TestShared/TestEnv.cs index d1df3b805e85db341e0c5d2b1dac25f400984ba3..b785dedf715e891ec7c7955d3ba8162c9619322c 100644 --- a/tests/TestShared/TestEnv.cs +++ b/tests/TestShared/TestEnv.cs @@ -5,12 +5,12 @@ public class Testenv [CommandMethod(nameof(Test_Enum))] public void Test_Enum() { - Env.CmdEcho = true; + SystemVariableManager.CmdEcho = true; } [CommandMethod(nameof(Test_Enum1))] public void Test_Enum1() { - Env.CmdEcho = false; + SystemVariableManager.CmdEcho = false; } [CommandMethod(nameof(Test_Dimblk))] @@ -46,7 +46,7 @@ public void Test_Osmode() // 追加模式 Env.OSMode |= Env.OSModeType.Center; // 检查是否有某个模式 - var os = Env.OSMode.Include(Env.OSModeType.Center); + var os = Env.OSMode.HasFlag(Env.OSModeType.Center); // 取消某个模式 Env.OSMode ^= Env.OSModeType.Center; Env.Editor.WriteMessage(Env.OSMode.ToString()); diff --git a/tests/TestShared/TestShared.projitems b/tests/TestShared/TestShared.projitems index 3c6557b28bc6bba6ae225c1eeb50395e7a956318..a9938e0afed8292ad9bd0a80e5201b2f22fa72c5 100644 --- a/tests/TestShared/TestShared.projitems +++ b/tests/TestShared/TestShared.projitems @@ -12,6 +12,7 @@ + @@ -42,6 +43,7 @@ + diff --git a/tests/TestShared/TestUserInterface.cs b/tests/TestShared/TestUserInterface.cs new file mode 100644 index 0000000000000000000000000000000000000000..dc4d416ed62319c039802fa78be703b10d468da4 --- /dev/null +++ b/tests/TestShared/TestUserInterface.cs @@ -0,0 +1,64 @@ +using System.Drawing; +using System.Drawing.Imaging; +using System.Reflection; +using System.Windows.Controls; +using System.Windows.Media.Imaging; + + +namespace Test; + +public static class TestUserInterface +{ + + + + [CommandMethod(nameof(Testifoxmenu))] + public static void Testifoxmenu() + { + List menuData = + [ + new MenuData + { + Label = "null", + Macro = "line", + HelpString = "null", + SubItem = null + }, + new MenuData + { + Label = "line", + Macro = "line", + HelpString = "line", + SubItem = null + }, + ]; + + IFoxMenu.AddPopMenu("Ifoxmenu",menuData); + } + + [CommandMethod(nameof(Testribbon))] + public static void Testribbon() + { + if (ComponentManager.Ribbon != null) + { + var control = ComponentManager.Ribbon; + var tab = control.AddTab("ifoxribbon", true); + var panel = tab.AddPanel("ifoxpanel"); + + var btn = panel.AddButton("line", "line", size: RibbonItemSize.Large, orient: Orientation.Vertical); + // 需要提前准备一张图片放在dll的目录里 + var path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, @"add-line.png"); + btn.SetImage(path); + + + // btn.SetImage(Path.Combine(Assembly.GetExecutingAssembly().Location,"add-line.png")); + panel.AddButton("line1", "line"); + panel.AddButton("line2", "line"); + panel.AddButton("line3", "line"); + panel.AddButton("line4", "line"); + + } + } + + +} \ No newline at end of file diff --git a/tests/TestZcad2025/GlobalUsings.cs b/tests/TestZcad2025/GlobalUsings.cs index 2c24797f6c0cde2a403ff8c6672248a0cb46058e..c4a78e3a1445e74c3c28cb22d07b0f30b2282201 100644 --- a/tests/TestZcad2025/GlobalUsings.cs +++ b/tests/TestZcad2025/GlobalUsings.cs @@ -25,6 +25,7 @@ global using ZwSoft.ZwCAD.DatabaseServices; global using ZwSoft.ZwCAD.Geometry; global using ZwSoft.ZwCAD.Runtime; +global using ZwSoft.Windows; global using Acap = ZwSoft.ZwCAD.ApplicationServices.Application; global using Acaop = ZwSoft.ZwCAD.ApplicationServices.Application; global using AcException = ZwSoft.ZwCAD.Runtime.Exception; diff --git a/tests/TestZcad2025/TestZcad2025.csproj b/tests/TestZcad2025/TestZcad2025.csproj index 280480b153b8da7a1016d183ba355342a32e2a31..a0587c508aa02dd771f394daed8966b7d3c697f3 100644 --- a/tests/TestZcad2025/TestZcad2025.csproj +++ b/tests/TestZcad2025/TestZcad2025.csproj @@ -15,7 +15,7 @@ - +