From 8514b636401b8a19fe66b55cdd53c58008aecef5 Mon Sep 17 00:00:00 2001 From: GeKtvi <61162497+GeKtvi@users.noreply.github.com> Date: Sun, 9 Mar 2025 21:40:43 +0300 Subject: [PATCH 01/10] Added first variant of context menu items --- .../CommandManager/CommandManager.cs | 2 +- .../Group/CommandContextMenuGroup.cs | 71 +++++++ .../Item/CommandContextMenuItem.cs | 174 ++++++++++++++++++ .../Item/CommandManagerFlyout.cs | 2 + .../CommandManager/Item/ICommandCreatable.cs | 16 ++ .../CommandManager/Item/ICommandItem.cs | 22 +++ .../Item/ICommandManagerItem.cs | 17 +- .../SolidDna.CommandItems/CommandItems.cs | 46 +++++ .../SolidDna.CommandItems.csproj | 87 ++++----- 9 files changed, 377 insertions(+), 60 deletions(-) create mode 100644 SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Group/CommandContextMenuGroup.cs create mode 100644 SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuItem.cs create mode 100644 SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandCreatable.cs create mode 100644 SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandItem.cs diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/CommandManager.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/CommandManager.cs index f4794c2..937e9ef 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/CommandManager.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/CommandManager.cs @@ -178,7 +178,7 @@ public CommandManagerFlyout CreateFlyoutGroup2(string title, List + /// A command flyout for the top command bar in SolidWorks + /// + public class CommandContextMenuGroup : ICommandCreatable, IDisposable + { + private bool _isCreated; + + #region Public Properties + + /// + /// The ID used when this command flyout was created + /// + public int UserId { get; } + + /// + /// The hint of this command group + /// + public string Name { get; set; } + + public List Items { get; set; } + + #endregion + + /// + /// Create a command manager flyout (group). + /// + public CommandContextMenuGroup() + { + } + + /// + /// Remove, then re-add all items to the flyout. + /// Is called on every click of the flyout, but only does something on the first click. + /// SolidWorks calls this a 'dynamic flyout' in the help. + /// + public /* TODO*/ void Create(string path) + { + if (_isCreated) + throw new NotImplementedException(); // TODO + + _isCreated = true; + + var name = string.IsNullOrEmpty(path) ? $"{Name}" : $"{path}@{Name}"; + + for (var i = 0; i < Items.Count; i++) + { + var item = Items[i]; + item.Create(name); + } + } + + /// + /// Disposing + /// + public void Dispose() + { + // Dispose child items + foreach (var item in Items.OfType()) + item.Dispose(); + } + + public override string ToString() => $"ContextMenuGroup with name: {Name}. Count of sub items: {Items.Count}"; + } +} diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuItem.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuItem.cs new file mode 100644 index 0000000..e8d5fef --- /dev/null +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuItem.cs @@ -0,0 +1,174 @@ +using CADBooster.SolidDna.SolidWorks.CommandManager.Item; +using SolidWorks.Interop.sldworks; +using SolidWorks.Interop.swconst; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Xml.Linq; + +namespace CADBooster.SolidDna +{ + /// + /// A command flyout for the top command bar in SolidWorks + /// + public class CommandContextItem : ICommandItem, ICommandCreatable, IDisposable + { + private bool _isCreated; + #region Public Properties + + /// + /// The ID used when this command flyout was created + /// + public int UserId { get; } + + /// + /// The unique Callback ID (set by creator) + /// + public string CallbackId { get; } = Guid.NewGuid().ToString("N"); + + /// + /// The command ID for this item + /// + public int CommandId { get; private set; } + + /// + /// The hint of this command group + /// + public string Name { get; set; } + + /// + /// The help text for this item. Is only used for toolbar items and flyouts, underneath the . Is not used for menus and flyout items. + /// + public string Hint { get; set; } + + /// + /// True to show this item in the command tab when an assembly is open. Only works for toolbar items and flyouts, not for menus or flyout items. + /// + public bool VisibleForAssemblies { get; set; } = true; + + /// + /// True to show this item in the command tab when a drawing is open. Only works for toolbar items and flyouts, not for menus or flyout items. + /// + public bool VisibleForDrawings { get; set; } = true; + + /// + /// True to show this item in the command tab when a part is open. Only works for toolbar items and flyouts, not for menus or flyout items. + /// + public bool VisibleForParts { get; set; } = true; + + /// + /// The action to call when the item is clicked + /// + public Action OnClick { get; set; } + + /// + /// The action to call when the item state requested + /// + public Action OnStateCheck { get; set; } + + public swSelectType_e SelectionType { get; set; } = swSelectType_e.swSelNOTHING; + + #endregion + + /// + /// Create a command manager flyout (group). + /// + public CommandContextItem() + { + } + + /// + /// Remove, then re-add all items to the flyout. + /// Is called on every click of the flyout, but only does something on the first click. + /// SolidWorks calls this a 'dynamic flyout' in the help. + /// + public void Create(string path = "") + { + if (_isCreated) + throw new NotImplementedException(); // TODO + + _isCreated = true; + + var name = string.IsNullOrEmpty(path) ? $"{Name}" : $"{path}@{Name}"; + + if(VisibleForAssemblies) + CreateForDocumentType(name, DocumentType.Assembly); + if(VisibleForDrawings) + CreateForDocumentType(name, DocumentType.Drawing); + if(VisibleForParts) + CreateForDocumentType(name, DocumentType.Part); + + // Listen out for callbacks + PlugInIntegration.CallbackFired += PlugInIntegration_CallbackFired; + + // Listen out for EnableMethod + PlugInIntegration.ItemStateCheckFired += PlugInIntegration_EnableMethodFired; + } + + private void CreateForDocumentType(string name, DocumentType documentType) + { + CommandId = AddInIntegration.SolidWorks.UnsafeObject.AddMenuPopupItem3( + (int)documentType, + SolidWorksEnvironment.Application.SolidWorksCookie, + (int)SelectionType, + name, + $"{nameof(SolidAddIn.Callback)}({CallbackId})", + $"{nameof(SolidAddIn.ItemStateCheck)}({CallbackId})", + Hint, + null + ); + } + + /// + /// Fired when a SolidWorks callback is fired + /// + /// The name of the callback that was fired + private void PlugInIntegration_CallbackFired(string name) + { + if (CallbackId != name) + return; + + // Call the action + OnClick?.Invoke(); + } + + /// + /// Fired when a SolidWorks UpdateCallbackFunction is fired + /// + /// The arguments for user handling + private void PlugInIntegration_EnableMethodFired(ItemStateCheckArgs args) + { + if (CallbackId != args.CallbackId) + return; + + // Call the action + OnStateCheck?.Invoke(args); + } + + /// + /// Disposing + /// + public void Dispose() + { + // Stop listening out for callbacks + PlugInIntegration.CallbackFired -= PlugInIntegration_CallbackFired; + PlugInIntegration.ItemStateCheckFired -= PlugInIntegration_EnableMethodFired; + } + + public override string ToString() => $"Flyout with name: {Name}. CommandID: {CommandId}. Hint: {Hint}."; + } + + public static class CommandManagerItemExtensions + { + public static IEnumerable AsCommandCreatable(this IEnumerable items, Func selectTypeSelector = null) + => items.Select(x => + new CommandContextItem() + { + Name = x.Name, + Hint = x.Hint, + OnClick = x.OnClick, + OnStateCheck = x.OnStateCheck, + SelectionType = selectTypeSelector is null ? swSelectType_e.swSelEVERYTHING : selectTypeSelector.Invoke(x) + }); + } +} diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerFlyout.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerFlyout.cs index 4bd8c85..8020bbb 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerFlyout.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerFlyout.cs @@ -200,6 +200,7 @@ private void AddCommandItem(CommandManagerItem item) /// The name of the callback that was fired private void PlugInIntegration_CallbackFired(string name) { + // TODO: This is not works with FlyoutGroup itself // Find the item, if any var item = Items?.FirstOrDefault(f => f.CallbackId == name); @@ -213,6 +214,7 @@ private void PlugInIntegration_CallbackFired(string name) /// The arguments for user handling private void PlugInIntegration_UpdateCallbackFunctionFired(ItemStateCheckArgs args) { + // TODO: This is not works with FlyoutGroup itself // Find the item, if any var item = Items?.FirstOrDefault(f => f.CallbackId == args.CallbackId); diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandCreatable.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandCreatable.cs new file mode 100644 index 0000000..dd3cfad --- /dev/null +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandCreatable.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CADBooster.SolidDna.SolidWorks.CommandManager.Item +{ + public interface ICommandCreatable + { + int UserId { get; } + string Name { get; } + + void Create(string path = ""); + } +} diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandItem.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandItem.cs new file mode 100644 index 0000000..8e5b5c5 --- /dev/null +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandItem.cs @@ -0,0 +1,22 @@ +using System; + +namespace CADBooster.SolidDna +{ + public interface ICommandItem + { + /// + /// The unique Callback ID (set by creator) + /// + string CallbackId { get; } + + /// + /// The action to call when the item is clicked + /// + Action OnClick { get; set; } + + /// + /// The action to call when the item state requested + /// + Action OnStateCheck { get; set; } + } +} \ No newline at end of file diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandManagerItem.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandManagerItem.cs index 4d67805..8564f3e 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandManagerItem.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandManagerItem.cs @@ -2,33 +2,18 @@ namespace CADBooster.SolidDna { - public interface ICommandManagerItem + public interface ICommandManagerItem : ICommandItem { /// /// True if the command should be added to the tab /// bool AddToTab { get; set; } - /// - /// The unique Callback ID (set by creator) - /// - string CallbackId { get; } - /// /// The command ID for this flyout item /// int CommandId { get; } - /// - /// The action to call when the item is clicked - /// - Action OnClick { get; set; } - - /// - /// The action to call when the item state requested - /// - Action OnStateCheck { get; set; } - /// /// The position of the item in the list. Specify 0 to add the item to the beginning of the toolbar or menu, or specify -1 to add it to the end. /// After creating the item, we set this to the actual position (flyouts and separators are not included in the count) and we use the actual position to get the . diff --git a/Tutorials/09-CommandItems/SolidDna.CommandItems/CommandItems.cs b/Tutorials/09-CommandItems/SolidDna.CommandItems/CommandItems.cs index 619cc5b..23973bc 100644 --- a/Tutorials/09-CommandItems/SolidDna.CommandItems/CommandItems.cs +++ b/Tutorials/09-CommandItems/SolidDna.CommandItems/CommandItems.cs @@ -1,4 +1,6 @@ using CADBooster.SolidDna; +using CADBooster.SolidDna.SolidWorks.CommandManager.Item; +using SolidWorks.Interop.swconst; using System.Collections.Generic; using System.IO; using System.Linq; @@ -62,6 +64,50 @@ public override void ConnectedToSolidWorks() { var imageFormat = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "icons{0}.png"); + var item = CreateCommandItems().First(); + + new CommandContextMenuGroup() + { + Name = "RootGroup", + Items = + [.. + CreateCommandItems().AsCommandCreatable(), + new CommandContextItem() + { + Name = "Plane item", + Hint = "Plane item Hint", + OnClick = item.OnClick, + SelectionType = swSelectType_e.swSelDATUMPLANES + }, + new CommandContextMenuGroup() + { + Name = "SubGroup", + Items = [ + new CommandContextItem() + { + Name = "SubItem", + Hint = "SubGroup", + OnClick = item.OnClick, + SelectionType = swSelectType_e.swSelCOMPONENTS + }, + new CommandContextMenuGroup() + { + Name = "SubSubGroup", + Items = [ + new CommandContextItem() + { + Name = "SubSubItem", + Hint = "SubSubItem Hint", + OnClick = item.OnClick, + SelectionType = swSelectType_e.swSelCOMPONENTS + } + ] + }, + ] + }, + ] + }.Create(string.Empty); + // FlyoutGroup var flyout = Application.CommandManager.CreateFlyoutGroup2( title: "CreateFlyoutGroup2 Example", diff --git a/Tutorials/09-CommandItems/SolidDna.CommandItems/SolidDna.CommandItems.csproj b/Tutorials/09-CommandItems/SolidDna.CommandItems/SolidDna.CommandItems.csproj index f8ebd75..715097c 100644 --- a/Tutorials/09-CommandItems/SolidDna.CommandItems/SolidDna.CommandItems.csproj +++ b/Tutorials/09-CommandItems/SolidDna.CommandItems/SolidDna.CommandItems.csproj @@ -1,45 +1,46 @@  - - net48-windows - Library - false - true - - - - - - - ..\..\..\SolidDna\CADBooster.SolidDna\bin\Debug\net48\CADBooster.SolidDna.dll - - - - - - - - - - - - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - + + net48-windows + Library + false + latest + true + + + + + + + ..\..\..\SolidDna\CADBooster.SolidDna\bin\Debug\net48\CADBooster.SolidDna.dll + + + + + + + + + + + + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + \ No newline at end of file From 86c357a7fcacebffdf9e341877d8df5d8eab05c8 Mon Sep 17 00:00:00 2001 From: GeKtvi <61162497+GeKtvi@users.noreply.github.com> Date: Fri, 14 Mar 2025 19:06:55 +0300 Subject: [PATCH 02/10] Fix multiple document type creation --- .../CommandManager/CommandManager.cs | 17 +- .../Group/CommandContextMenuGroup.cs | 71 ------ .../Item/CommandContextMenuGroup.cs | 134 ++++++++++ .../Item/CommandContextMenuItem.cs | 233 +++++++++++++++--- .../CommandManager/Item/ICommandCreatable.cs | 5 +- 5 files changed, 350 insertions(+), 110 deletions(-) delete mode 100644 SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Group/CommandContextMenuGroup.cs create mode 100644 SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuGroup.cs diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/CommandManager.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/CommandManager.cs index 937e9ef..ce57f20 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/CommandManager.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/CommandManager.cs @@ -1,4 +1,5 @@ -using SolidWorks.Interop.sldworks; +using CADBooster.SolidDna.SolidWorks.CommandManager.Item; +using SolidWorks.Interop.sldworks; using SolidWorks.Interop.swconst; using System; using System.Collections.Generic; @@ -19,6 +20,11 @@ public class CommandManager : SolidDnaObject /// private readonly List mCommandFlyouts = new List(); + /// + /// A list of all created command context menu items + /// + private readonly List mCommandContextItems = new List(); + /// /// Unique ID for flyouts (just increment every time we add one) /// @@ -76,6 +82,12 @@ public CommandManagerGroup CreateCommandTab(string title, int id, List commandItems) + { + foreach (var item in commandItems) + mCommandContextItems.AddRange(item.Create()); + } + /// /// Create a command group from a list of items. Uses a single list of items, separators and flyouts. /// NOTE: If you set to false, you should pick a new ID every time you change your tab. @@ -317,6 +329,9 @@ public override void Dispose() // Remove all command flyouts mCommandFlyouts?.ForEach(RemoveCommandFlyout); + // Remove all command context menu items + mCommandContextItems?.ForEach(x => x.Dispose()); + base.Dispose(); } } diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Group/CommandContextMenuGroup.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Group/CommandContextMenuGroup.cs deleted file mode 100644 index 4cb1757..0000000 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Group/CommandContextMenuGroup.cs +++ /dev/null @@ -1,71 +0,0 @@ -using CADBooster.SolidDna.SolidWorks.CommandManager.Item; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace CADBooster.SolidDna.SolidWorks.CommandManager.Group -{ - /// - /// A command flyout for the top command bar in SolidWorks - /// - public class CommandContextMenuGroup : ICommandCreatable, IDisposable - { - private bool _isCreated; - - #region Public Properties - - /// - /// The ID used when this command flyout was created - /// - public int UserId { get; } - - /// - /// The hint of this command group - /// - public string Name { get; set; } - - public List Items { get; set; } - - #endregion - - /// - /// Create a command manager flyout (group). - /// - public CommandContextMenuGroup() - { - } - - /// - /// Remove, then re-add all items to the flyout. - /// Is called on every click of the flyout, but only does something on the first click. - /// SolidWorks calls this a 'dynamic flyout' in the help. - /// - public /* TODO*/ void Create(string path) - { - if (_isCreated) - throw new NotImplementedException(); // TODO - - _isCreated = true; - - var name = string.IsNullOrEmpty(path) ? $"{Name}" : $"{path}@{Name}"; - - for (var i = 0; i < Items.Count; i++) - { - var item = Items[i]; - item.Create(name); - } - } - - /// - /// Disposing - /// - public void Dispose() - { - // Dispose child items - foreach (var item in Items.OfType()) - item.Dispose(); - } - - public override string ToString() => $"ContextMenuGroup with name: {Name}. Count of sub items: {Items.Count}"; - } -} diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuGroup.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuGroup.cs new file mode 100644 index 0000000..176c18c --- /dev/null +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuGroup.cs @@ -0,0 +1,134 @@ +using CADBooster.SolidDna.SolidWorks.CommandManager.Item; +using SolidWorks.Interop.swconst; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; + +namespace CADBooster.SolidDna +{ + /// + /// A command flyout for the top command bar in SolidWorks + /// + public class CommandContextMenuGroup : ICommandCreatable, IDisposable + { + private ObservableCollection _items = new ObservableCollection(); + private readonly Dictionary> _createdItems = new Dictionary>(); + private string _path = string.Empty; + private bool _isItemsSetAllowed = true; + + #region Public Properties + + /// + /// The ID used when this command flyout was created + /// + public int UserId { get; } + + /// + /// The hint of this command group + /// + public string Name { get; set; } + + public ObservableCollection Items + { + get => _items; + set + { + if (!_isItemsSetAllowed) + throw new NotImplementedException(); // TODO + + _isItemsSetAllowed = false; + _items.CollectionChanged -= ItemsCollectionChanged; + value.CollectionChanged += ItemsCollectionChanged; + _items = value; + //Create(_path); + } + } + + private void ItemsCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + { + Logger.LogTraceSource($"Context menu item group changed action: \t{e.Action}"); + Logger.LogTraceSource($"Context menu item group changed count: \t{_items.Count}"); + + _isItemsSetAllowed = false; + switch (e.Action) + { + case System.Collections.Specialized.NotifyCollectionChangedAction.Add: + Create(_path, e.NewItems.OfType()); + break; + case System.Collections.Specialized.NotifyCollectionChangedAction.Replace: + Create(_path, e.NewItems.OfType()); + if (e.OldItems != null) + foreach (var old in e.OldItems.OfType()) + { + _createdItems[old].ForEach(x => x.Dispose()); + _createdItems.Remove(old); + } + break; + case System.Collections.Specialized.NotifyCollectionChangedAction.Remove: + if (e.OldItems != null) + foreach (var old in e.OldItems.OfType()) + { + _createdItems[old].ForEach(x => x.Dispose()); + _createdItems.Remove(old); + } + break; + case System.Collections.Specialized.NotifyCollectionChangedAction.Reset: + foreach (var old in _createdItems.Values) + old.ForEach(x => x.Dispose()); + _createdItems.Clear(); + break; + case System.Collections.Specialized.NotifyCollectionChangedAction.Move: + Logger.LogWarningSource("Operation Move not supported."); + break; + } + + Logger.LogTraceSource($"Context menu item group changed created count: \t{_createdItems.Count}"); + } + + #endregion + + /// + /// Create a command manager flyout (group). + /// + public CommandContextMenuGroup() + { + _items.CollectionChanged += ItemsCollectionChanged; + } + + /// + /// Remove, then re-add all items to the flyout. + /// Is called on every click of the flyout, but only does something on the first click. + /// SolidWorks calls this a 'dynamic flyout' in the help. + /// + public IEnumerable Create(string path) => Create(path, null); + + public IEnumerable Create(string path, IEnumerable items = null) + { + _path = path; + var name = string.IsNullOrEmpty(path) ? $"{Name}" : $"{path}@{Name}"; + + var created = Enumerable.Empty(); + foreach (var item in items ?? Items) + { + var createdItems = item.Create(name).ToList(); + _createdItems[item] = createdItems; + created = created.Concat(createdItems); + } + + return created.ToArray(); + } + + /// + /// Disposing + /// + public void Dispose() + { + // Dispose child items + foreach (var item in _createdItems.Values) + item.ForEach(x => x.Dispose()); + } + + public override string ToString() => $"ContextMenuGroup with name: {Name}. Count of sub items: {Items.Count}"; + } +} diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuItem.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuItem.cs index e8d5fef..7ea0076 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuItem.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuItem.cs @@ -3,15 +3,16 @@ using SolidWorks.Interop.swconst; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; -using System.Xml.Linq; +using System.Windows.Shapes; namespace CADBooster.SolidDna { /// /// A command flyout for the top command bar in SolidWorks /// - public class CommandContextItem : ICommandItem, ICommandCreatable, IDisposable + public class CommandContextItem : ICommandItem, ICommandCreatable { private bool _isCreated; #region Public Properties @@ -82,41 +83,123 @@ public CommandContextItem() /// Is called on every click of the flyout, but only does something on the first click. /// SolidWorks calls this a 'dynamic flyout' in the help. /// - public void Create(string path = "") + public IEnumerable Create(string path = "") { if (_isCreated) throw new NotImplementedException(); // TODO _isCreated = true; - var name = string.IsNullOrEmpty(path) ? $"{Name}" : $"{path}@{Name}"; + var fullName = string.IsNullOrEmpty(path) ? $"{Name}" : $"{path}@{Name}"; - if(VisibleForAssemblies) - CreateForDocumentType(name, DocumentType.Assembly); - if(VisibleForDrawings) - CreateForDocumentType(name, DocumentType.Drawing); - if(VisibleForParts) - CreateForDocumentType(name, DocumentType.Part); + var created = new List(); - // Listen out for callbacks - PlugInIntegration.CallbackFired += PlugInIntegration_CallbackFired; + if (VisibleForAssemblies) + created.Add(new CommandContextItemCreated(this, fullName, DocumentType.Assembly)); + if (VisibleForDrawings) + created.Add(new CommandContextItemCreated(this, fullName, DocumentType.Drawing)); + if (VisibleForParts) + created.Add(new CommandContextItemCreated(this, fullName, DocumentType.Part)); - // Listen out for EnableMethod - PlugInIntegration.ItemStateCheckFired += PlugInIntegration_EnableMethodFired; + return created; } - private void CreateForDocumentType(string name, DocumentType documentType) + public override string ToString() => $"Flyout with name: {Name}. CommandID: {CommandId}. Hint: {Hint}."; + } + + public interface ICommandCreated : IDisposable + { + int UserId { get; } + string CallbackId { get; } + string Name { get; } + } + + internal class CommandContextItemCreated : ICommandCreated + { + + public int UserId { get; } + public string CallbackId => _callbackId; + public int CommandId { get; } + public string Name { get; } + public string Hint { get; } + public swSelectType_e SelectionType { get; } + public DocumentType DocumentType { get; } + public Action OnClick { get; } + public Action OnStateCheck { get; private set; } + public string FullName { get; } + + private readonly string _menuCallback; + private readonly string _menuEnableMethod; + //private bool _isDisposed; + private static readonly Action _hideStateAction = arg => arg.Result = ItemState.Hidden; +#pragma warning disable IDE0032 // Use auto property + private readonly string _callbackId = Guid.NewGuid().ToString("N"); +#pragma warning restore IDE0032 // Use auto property + + public CommandContextItemCreated(CommandContextItem commandContextItem, string fullName, DocumentType documentType) { + UserId = commandContextItem.UserId; + Name = commandContextItem.Name; + Hint = commandContextItem.Hint; + OnClick = commandContextItem.OnClick; + OnStateCheck = commandContextItem.OnStateCheck; + SelectionType = commandContextItem.SelectionType; + DocumentType = documentType; + FullName = fullName; + + _menuCallback = $"{nameof(SolidAddIn.Callback)}({CallbackId})"; + _menuEnableMethod = $"{nameof(SolidAddIn.ItemStateCheck)}({CallbackId})"; + + // create a third-party icon in the context-sensitive menus of faces in parts + var frame = (IFrame)AddInIntegration.SolidWorks.UnsafeObject.Frame(); + + var boo = frame.AddMenuPopupIcon2( + (int)swDocumentTypes_e.swDocASSEMBLY, + (int)swSelectType_e.swSelCOMPONENTS, + "contextsensitive", + SolidWorksEnvironment.Application.SolidWorksCookie, + "", + _menuCallback, + _menuEnableMethod, + + @"C:\Users\gektvi\source\repos\GeKtvi\solidworks-api\Tutorials\09-CommandItems\SolidDna.CommandItems\bin\Debug\net48-windows\icons20.png" + ); + var id = AddInIntegration.SolidWorks.UnsafeObject.RegisterThirdPartyPopupMenu(); + + var res = AddInIntegration.SolidWorks.UnsafeObject.AddItemToThirdPartyPopupMenu2( + id, + (int)DocumentType, + Name, + SolidWorksEnvironment.Application.SolidWorksCookie, + _menuCallback, + _menuEnableMethod, + string.Empty, + Hint, + @"C:\Users\gektvi\source\repos\GeKtvi\solidworks-api\Tutorials\09-CommandItems\SolidDna.CommandItems\bin\Debug\net48-windows\icons20.png", + (int)swMenuItemType_e.swMenuItemType_Default + ); + //// create and register the third party menu + //registerID = SwApp.RegisterThirdPartyPopupMenu(); + //(int)swDocumentTypes_e.swDocPART, (int)swSelectType_e.swSelFACES, "contextsensitive", addinID, "CSCallbackFunction", "CSEnable", "", cmdGroup.SmallMainIcon); + CommandId = AddInIntegration.SolidWorks.UnsafeObject.AddMenuPopupItem3( - (int)documentType, + (int)DocumentType, SolidWorksEnvironment.Application.SolidWorksCookie, (int)SelectionType, - name, - $"{nameof(SolidAddIn.Callback)}({CallbackId})", - $"{nameof(SolidAddIn.ItemStateCheck)}({CallbackId})", + FullName, + _menuCallback, + _menuEnableMethod, Hint, - null + string.Empty ); + + // Listen out for callbacks + PlugInIntegration.CallbackFired += PlugInIntegration_CallbackFired; + + // Listen out for EnableMethod + PlugInIntegration.ItemStateCheckFired += PlugInIntegration_EnableMethodFired; + + Logger.LogDebugSource("Context menu item created"); } /// @@ -138,9 +221,18 @@ private void PlugInIntegration_CallbackFired(string name) /// The arguments for user handling private void PlugInIntegration_EnableMethodFired(ItemStateCheckArgs args) { + if (args.CallbackId == "CommandContextItemCreated") + Debugger.Break(); + if (CallbackId != args.CallbackId) return; + //if (_isDisposed) + //{ + + //} + + // Call the action OnStateCheck?.Invoke(args); } @@ -150,25 +242,98 @@ private void PlugInIntegration_EnableMethodFired(ItemStateCheckArgs args) /// public void Dispose() { - // Stop listening out for callbacks - PlugInIntegration.CallbackFired -= PlugInIntegration_CallbackFired; - PlugInIntegration.ItemStateCheckFired -= PlugInIntegration_EnableMethodFired; - } + //_isDisposed = true; - public override string ToString() => $"Flyout with name: {Name}. CommandID: {CommandId}. Hint: {Hint}."; + //OnStateCheck = _hideStateAction; + + var result = AddInIntegration.SolidWorks.UnsafeObject.RemoveItemFromThirdPartyPopupMenu( + CommandId, + (int)DocumentType.None, + FullName, + 0 + ); + + //var result0 = AddInIntegration.SolidWorks.UnsafeObject.RemoveMenuPopupItem2( + // (int)DocumentType.None, + // SolidWorksEnvironment.Application.SolidWorksCookie, + // (int)SelectionType, + // Name, + // _menuCallback, + // $"{nameof(SolidAddIn.Callback)}(CommandContextItemCreated)", + // Hint, + // string.Empty + //); + + + //var result = AddInIntegration.SolidWorks.UnsafeObject.RemoveFromPopupMenu( + // CommandId, + // (int)DocumentType.None, + // (int)swSelectType_e.swSelEVERYTHING, + // true + //); + + //var result1 = AddInIntegration.SolidWorks.UnsafeObject.RemoveFromMenu( + // CommandId, + // (int)DocumentType, + // (int)1, + // true + //); + + //var result2 = AddInIntegration.SolidWorks.UnsafeObject.RemoveFromMenu( + // CommandId, + // (int)DocumentType, + // (int)2, + // true + //); + + //var result3 = AddInIntegration.SolidWorks.UnsafeObject.RemoveFromMenu( + // CommandId, + // (int)DocumentType, + // (int)3, + // true + //); + + ////var com = AddInIntegration.SolidWorks.UnsafeObject.AddMenuPopupItem3( + //// (int)DocumentType, + //// SolidWorksEnvironment.Application.SolidWorksCookie, + //// (int)SelectionType, + //// FullName, + //// _menuCallback, + //// $"{nameof(SolidAddIn.Callback)}(CommandContextItemCreated)", + //// Hint, + //// string.Empty + ////); + + //if (result) + // Logger.LogInformationSource("Item successful removed"); + //else + // Logger.LogErrorSource("Item is not successful removed"); + ////Logger.LogInformationSource("Item finally disposed"); + //// Stop listening out for callbacks + //PlugInIntegration.CallbackFired -= PlugInIntegration_CallbackFired; + //PlugInIntegration.ItemStateCheckFired -= PlugInIntegration_EnableMethodFired; + //PlugInIntegration.ItemStateCheckFired -= PlugInIntegration_EnableMethodFired; + } } public static class CommandManagerItemExtensions { - public static IEnumerable AsCommandCreatable(this IEnumerable items, Func selectTypeSelector = null) + public static IEnumerable AsCommandCreatable(this IEnumerable items, + Func selectTypeSelector = null) => items.Select(x => - new CommandContextItem() - { - Name = x.Name, - Hint = x.Hint, - OnClick = x.OnClick, - OnStateCheck = x.OnStateCheck, - SelectionType = selectTypeSelector is null ? swSelectType_e.swSelEVERYTHING : selectTypeSelector.Invoke(x) - }); + x.AsCommandCreatable( + selectTypeSelector is null + ? swSelectType_e.swSelEVERYTHING + : selectTypeSelector.Invoke(x))); + + public static ICommandCreatable AsCommandCreatable(this CommandManagerItem item, swSelectType_e selectType = swSelectType_e.swSelEVERYTHING) + => new CommandContextItem() + { + Name = item.Name, + Hint = item.Hint, + OnClick = item.OnClick, + OnStateCheck = item.OnStateCheck, + SelectionType = selectType + }; } } diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandCreatable.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandCreatable.cs index dd3cfad..d798abd 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandCreatable.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandCreatable.cs @@ -1,8 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace CADBooster.SolidDna.SolidWorks.CommandManager.Item { @@ -11,6 +8,6 @@ public interface ICommandCreatable int UserId { get; } string Name { get; } - void Create(string path = ""); + IEnumerable Create(string path = ""); } } From 263ca7e4e85c4b602c6976e2a5af832e7f73b1b5 Mon Sep 17 00:00:00 2001 From: GeKtvi <61162497+GeKtvi@users.noreply.github.com> Date: Sun, 16 Mar 2025 17:18:23 +0300 Subject: [PATCH 03/10] Remove broken functionality for removing context items --- .../CommandManager/CommandManager.cs | 7 + .../Item/CommandContextItemCreated.cs | 110 ++++++++ .../Item/CommandContextMenuGroup.cs | 109 +------- .../Item/CommandContextMenuGroupCreated.cs | 35 +++ .../Item/CommandContextMenuItem.cs | 257 +----------------- .../Item/CommandManagerItemExtensions.cs | 29 ++ .../CommandManager/Item/ICommandCreatable.cs | 1 - .../CommandManager/Item/ICommandCreated.cs | 9 + .../CommandManager/Item/ICommandItem.cs | 4 +- 9 files changed, 206 insertions(+), 355 deletions(-) create mode 100644 SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextItemCreated.cs create mode 100644 SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuGroupCreated.cs create mode 100644 SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerItemExtensions.cs create mode 100644 SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandCreated.cs diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/CommandManager.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/CommandManager.cs index ce57f20..22f5b32 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/CommandManager.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/CommandManager.cs @@ -262,7 +262,10 @@ private CommandManagerGroup CreateCommandGroup(string title, int id, List @@ -273,7 +276,10 @@ private void RemoveCommandFlyout(CommandManagerFlyout flyout) private void RemoveCommandGroup(CommandManagerGroup group, bool runtimeOnly = false) { lock (mCommandGroups) + { BaseObject.RemoveCommandGroup2(group.UserId, runtimeOnly); + mCommandGroups.Remove(group); + } } /// @@ -331,6 +337,7 @@ public override void Dispose() // Remove all command context menu items mCommandContextItems?.ForEach(x => x.Dispose()); + mCommandContextItems.Clear(); base.Dispose(); } diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextItemCreated.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextItemCreated.cs new file mode 100644 index 0000000..38ea907 --- /dev/null +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextItemCreated.cs @@ -0,0 +1,110 @@ +using SolidWorks.Interop.swconst; +using System; +using System.Diagnostics; + +namespace CADBooster.SolidDna +{ + internal class CommandContextItemCreated : ICommandCreated, ICommandItem + { + public string CallbackId { get; } = Guid.NewGuid().ToString("N"); + public int CommandId { get; } + public string Name { get; } + public string Hint { get; } + public swSelectType_e SelectionType { get; } + public DocumentType DocumentType { get; } + public Action OnClick { get; } + public Action OnStateCheck { get; private set; } + public string FullName { get; } + + public CommandContextItemCreated(CommandContextItem commandContextItem, string fullName, DocumentType documentType) + { + Name = commandContextItem.Name; + Hint = commandContextItem.Hint; + OnClick = commandContextItem.OnClick; + OnStateCheck = commandContextItem.OnStateCheck; + SelectionType = commandContextItem.SelectionType; + DocumentType = documentType; + FullName = fullName; + + CommandId = AddInIntegration.SolidWorks.UnsafeObject.AddMenuPopupItem3( + (int)DocumentType, + SolidWorksEnvironment.Application.SolidWorksCookie, + (int)SelectionType, + FullName, + $"{nameof(SolidAddIn.Callback)}({CallbackId})", + $"{nameof(SolidAddIn.ItemStateCheck)}({CallbackId})", + Hint, + string.Empty + ); + + // Listen out for callbacks + PlugInIntegration.CallbackFired += PlugInIntegration_CallbackFired; + + // Listen out for EnableMethod + PlugInIntegration.ItemStateCheckFired += PlugInIntegration_EnableMethodFired; + + Logger.LogDebugSource("Context menu item created"); + } + + /// + /// Fired when a SolidWorks callback is fired + /// + /// The name of the callback that was fired + private void PlugInIntegration_CallbackFired(string name) + { + if (CallbackId != name) + return; + + // Call the action + OnClick?.Invoke(); + } + + /// + /// Fired when a SolidWorks UpdateCallbackFunction is fired + /// + /// The arguments for user handling + private void PlugInIntegration_EnableMethodFired(ItemStateCheckArgs args) + { + if (args.CallbackId == "CommandContextItemCreated") + Debugger.Break(); + + if (CallbackId != args.CallbackId) + return; + + // Call the action + OnStateCheck?.Invoke(args); + } + + /// + /// Disposing + /// + public void Dispose() + { + // I can't find the way to remove the item + + // It always returns false, and the item isn't removed + //var removeMenuPopupItemResult = AddInIntegration.SolidWorks.UnsafeObject.RemoveMenuPopupItem2( + // (int)DocumentType, + // SolidWorksEnvironment.Application.SolidWorksCookie, + // (int)SelectionType, + // FullName, + // $"{nameof(SolidAddIn.Callback)}({CallbackId})", + // $"{nameof(SolidAddIn.ItemStateCheck)}({CallbackId})", + // Hint, + // string.Empty + //); + + // It always returns true, but the item isn't removed + //var removeFromPopupMenuResult = AddInIntegration.SolidWorks.UnsafeObject.RemoveFromPopupMenu( + // CommandId, + // (int)DocumentType, + // (int)SelectionType, + // true + //); + + // Stop listening out for callbacks + PlugInIntegration.CallbackFired -= PlugInIntegration_CallbackFired; + PlugInIntegration.ItemStateCheckFired -= PlugInIntegration_EnableMethodFired; + } + } +} diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuGroup.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuGroup.cs index 176c18c..63424e3 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuGroup.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuGroup.cs @@ -8,125 +8,36 @@ namespace CADBooster.SolidDna { /// - /// A command flyout for the top command bar in SolidWorks + /// A command context menu group in SolidWorks /// - public class CommandContextMenuGroup : ICommandCreatable, IDisposable + public class CommandContextMenuGroup : ICommandCreatable { - private ObservableCollection _items = new ObservableCollection(); - private readonly Dictionary> _createdItems = new Dictionary>(); - private string _path = string.Empty; - private bool _isItemsSetAllowed = true; + private bool _isCreated; #region Public Properties /// - /// The ID used when this command flyout was created - /// - public int UserId { get; } - - /// - /// The hint of this command group + /// The name of this command group /// public string Name { get; set; } - public ObservableCollection Items - { - get => _items; - set - { - if (!_isItemsSetAllowed) - throw new NotImplementedException(); // TODO - - _isItemsSetAllowed = false; - _items.CollectionChanged -= ItemsCollectionChanged; - value.CollectionChanged += ItemsCollectionChanged; - _items = value; - //Create(_path); - } - } - - private void ItemsCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) - { - Logger.LogTraceSource($"Context menu item group changed action: \t{e.Action}"); - Logger.LogTraceSource($"Context menu item group changed count: \t{_items.Count}"); - - _isItemsSetAllowed = false; - switch (e.Action) - { - case System.Collections.Specialized.NotifyCollectionChangedAction.Add: - Create(_path, e.NewItems.OfType()); - break; - case System.Collections.Specialized.NotifyCollectionChangedAction.Replace: - Create(_path, e.NewItems.OfType()); - if (e.OldItems != null) - foreach (var old in e.OldItems.OfType()) - { - _createdItems[old].ForEach(x => x.Dispose()); - _createdItems.Remove(old); - } - break; - case System.Collections.Specialized.NotifyCollectionChangedAction.Remove: - if (e.OldItems != null) - foreach (var old in e.OldItems.OfType()) - { - _createdItems[old].ForEach(x => x.Dispose()); - _createdItems.Remove(old); - } - break; - case System.Collections.Specialized.NotifyCollectionChangedAction.Reset: - foreach (var old in _createdItems.Values) - old.ForEach(x => x.Dispose()); - _createdItems.Clear(); - break; - case System.Collections.Specialized.NotifyCollectionChangedAction.Move: - Logger.LogWarningSource("Operation Move not supported."); - break; - } - - Logger.LogTraceSource($"Context menu item group changed created count: \t{_createdItems.Count}"); - } + public List Items { get; set; } #endregion - /// - /// Create a command manager flyout (group). - /// - public CommandContextMenuGroup() - { - _items.CollectionChanged += ItemsCollectionChanged; - } - /// /// Remove, then re-add all items to the flyout. /// Is called on every click of the flyout, but only does something on the first click. /// SolidWorks calls this a 'dynamic flyout' in the help. /// - public IEnumerable Create(string path) => Create(path, null); - - public IEnumerable Create(string path, IEnumerable items = null) + public IEnumerable Create(string path) { - _path = path; - var name = string.IsNullOrEmpty(path) ? $"{Name}" : $"{path}@{Name}"; + if (_isCreated) + throw new NotImplementedException(); // TODO - var created = Enumerable.Empty(); - foreach (var item in items ?? Items) - { - var createdItems = item.Create(name).ToList(); - _createdItems[item] = createdItems; - created = created.Concat(createdItems); - } + _isCreated = true; - return created.ToArray(); - } - - /// - /// Disposing - /// - public void Dispose() - { - // Dispose child items - foreach (var item in _createdItems.Values) - item.ForEach(x => x.Dispose()); + return Enumerable.Repeat(new CommandContextMenuGroupCreated(Name, path, Items), 1); } public override string ToString() => $"ContextMenuGroup with name: {Name}. Count of sub items: {Items.Count}"; diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuGroupCreated.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuGroupCreated.cs new file mode 100644 index 0000000..c17ee54 --- /dev/null +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuGroupCreated.cs @@ -0,0 +1,35 @@ +using CADBooster.SolidDna.SolidWorks.CommandManager.Item; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace CADBooster.SolidDna +{ + internal class CommandContextMenuGroupCreated : ICommandCreated + { + public string CallbackId => Guid.Empty.ToString("N"); + public string Name { get; } + + private readonly List _createdItems; + + public CommandContextMenuGroupCreated(string name, string path, List items) + { + Name = name; + + var fullName = string.IsNullOrEmpty(path) ? $"{Name}" : $"{path}@{Name}"; + + _createdItems = items + .SelectMany(x => x.Create(fullName)) + .ToList(); + } + + /// + /// Disposing + /// + public void Dispose() + { + // Dispose child items + _createdItems.ForEach(x => x.Dispose()); + } + } +} diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuItem.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuItem.cs index 7ea0076..f8b8a62 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuItem.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuItem.cs @@ -3,35 +3,18 @@ using SolidWorks.Interop.swconst; using System; using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; using System.Windows.Shapes; namespace CADBooster.SolidDna { /// - /// A command flyout for the top command bar in SolidWorks + /// A command context menu in SolidWorks /// - public class CommandContextItem : ICommandItem, ICommandCreatable + public class CommandContextItem : ICommandCreatable { private bool _isCreated; #region Public Properties - /// - /// The ID used when this command flyout was created - /// - public int UserId { get; } - - /// - /// The unique Callback ID (set by creator) - /// - public string CallbackId { get; } = Guid.NewGuid().ToString("N"); - - /// - /// The command ID for this item - /// - public int CommandId { get; private set; } - /// /// The hint of this command group /// @@ -85,8 +68,8 @@ public CommandContextItem() /// public IEnumerable Create(string path = "") { - if (_isCreated) - throw new NotImplementedException(); // TODO + //if (_isCreated) + // throw new NotImplementedException(); // TODO _isCreated = true; @@ -103,237 +86,5 @@ public IEnumerable Create(string path = "") return created; } - - public override string ToString() => $"Flyout with name: {Name}. CommandID: {CommandId}. Hint: {Hint}."; - } - - public interface ICommandCreated : IDisposable - { - int UserId { get; } - string CallbackId { get; } - string Name { get; } - } - - internal class CommandContextItemCreated : ICommandCreated - { - - public int UserId { get; } - public string CallbackId => _callbackId; - public int CommandId { get; } - public string Name { get; } - public string Hint { get; } - public swSelectType_e SelectionType { get; } - public DocumentType DocumentType { get; } - public Action OnClick { get; } - public Action OnStateCheck { get; private set; } - public string FullName { get; } - - private readonly string _menuCallback; - private readonly string _menuEnableMethod; - //private bool _isDisposed; - private static readonly Action _hideStateAction = arg => arg.Result = ItemState.Hidden; -#pragma warning disable IDE0032 // Use auto property - private readonly string _callbackId = Guid.NewGuid().ToString("N"); -#pragma warning restore IDE0032 // Use auto property - - public CommandContextItemCreated(CommandContextItem commandContextItem, string fullName, DocumentType documentType) - { - UserId = commandContextItem.UserId; - Name = commandContextItem.Name; - Hint = commandContextItem.Hint; - OnClick = commandContextItem.OnClick; - OnStateCheck = commandContextItem.OnStateCheck; - SelectionType = commandContextItem.SelectionType; - DocumentType = documentType; - FullName = fullName; - - _menuCallback = $"{nameof(SolidAddIn.Callback)}({CallbackId})"; - _menuEnableMethod = $"{nameof(SolidAddIn.ItemStateCheck)}({CallbackId})"; - - // create a third-party icon in the context-sensitive menus of faces in parts - var frame = (IFrame)AddInIntegration.SolidWorks.UnsafeObject.Frame(); - - var boo = frame.AddMenuPopupIcon2( - (int)swDocumentTypes_e.swDocASSEMBLY, - (int)swSelectType_e.swSelCOMPONENTS, - "contextsensitive", - SolidWorksEnvironment.Application.SolidWorksCookie, - "", - _menuCallback, - _menuEnableMethod, - - @"C:\Users\gektvi\source\repos\GeKtvi\solidworks-api\Tutorials\09-CommandItems\SolidDna.CommandItems\bin\Debug\net48-windows\icons20.png" - ); - var id = AddInIntegration.SolidWorks.UnsafeObject.RegisterThirdPartyPopupMenu(); - - var res = AddInIntegration.SolidWorks.UnsafeObject.AddItemToThirdPartyPopupMenu2( - id, - (int)DocumentType, - Name, - SolidWorksEnvironment.Application.SolidWorksCookie, - _menuCallback, - _menuEnableMethod, - string.Empty, - Hint, - @"C:\Users\gektvi\source\repos\GeKtvi\solidworks-api\Tutorials\09-CommandItems\SolidDna.CommandItems\bin\Debug\net48-windows\icons20.png", - (int)swMenuItemType_e.swMenuItemType_Default - ); - //// create and register the third party menu - //registerID = SwApp.RegisterThirdPartyPopupMenu(); - //(int)swDocumentTypes_e.swDocPART, (int)swSelectType_e.swSelFACES, "contextsensitive", addinID, "CSCallbackFunction", "CSEnable", "", cmdGroup.SmallMainIcon); - - CommandId = AddInIntegration.SolidWorks.UnsafeObject.AddMenuPopupItem3( - (int)DocumentType, - SolidWorksEnvironment.Application.SolidWorksCookie, - (int)SelectionType, - FullName, - _menuCallback, - _menuEnableMethod, - Hint, - string.Empty - ); - - // Listen out for callbacks - PlugInIntegration.CallbackFired += PlugInIntegration_CallbackFired; - - // Listen out for EnableMethod - PlugInIntegration.ItemStateCheckFired += PlugInIntegration_EnableMethodFired; - - Logger.LogDebugSource("Context menu item created"); - } - - /// - /// Fired when a SolidWorks callback is fired - /// - /// The name of the callback that was fired - private void PlugInIntegration_CallbackFired(string name) - { - if (CallbackId != name) - return; - - // Call the action - OnClick?.Invoke(); - } - - /// - /// Fired when a SolidWorks UpdateCallbackFunction is fired - /// - /// The arguments for user handling - private void PlugInIntegration_EnableMethodFired(ItemStateCheckArgs args) - { - if (args.CallbackId == "CommandContextItemCreated") - Debugger.Break(); - - if (CallbackId != args.CallbackId) - return; - - //if (_isDisposed) - //{ - - //} - - - // Call the action - OnStateCheck?.Invoke(args); - } - - /// - /// Disposing - /// - public void Dispose() - { - //_isDisposed = true; - - //OnStateCheck = _hideStateAction; - - var result = AddInIntegration.SolidWorks.UnsafeObject.RemoveItemFromThirdPartyPopupMenu( - CommandId, - (int)DocumentType.None, - FullName, - 0 - ); - - //var result0 = AddInIntegration.SolidWorks.UnsafeObject.RemoveMenuPopupItem2( - // (int)DocumentType.None, - // SolidWorksEnvironment.Application.SolidWorksCookie, - // (int)SelectionType, - // Name, - // _menuCallback, - // $"{nameof(SolidAddIn.Callback)}(CommandContextItemCreated)", - // Hint, - // string.Empty - //); - - - //var result = AddInIntegration.SolidWorks.UnsafeObject.RemoveFromPopupMenu( - // CommandId, - // (int)DocumentType.None, - // (int)swSelectType_e.swSelEVERYTHING, - // true - //); - - //var result1 = AddInIntegration.SolidWorks.UnsafeObject.RemoveFromMenu( - // CommandId, - // (int)DocumentType, - // (int)1, - // true - //); - - //var result2 = AddInIntegration.SolidWorks.UnsafeObject.RemoveFromMenu( - // CommandId, - // (int)DocumentType, - // (int)2, - // true - //); - - //var result3 = AddInIntegration.SolidWorks.UnsafeObject.RemoveFromMenu( - // CommandId, - // (int)DocumentType, - // (int)3, - // true - //); - - ////var com = AddInIntegration.SolidWorks.UnsafeObject.AddMenuPopupItem3( - //// (int)DocumentType, - //// SolidWorksEnvironment.Application.SolidWorksCookie, - //// (int)SelectionType, - //// FullName, - //// _menuCallback, - //// $"{nameof(SolidAddIn.Callback)}(CommandContextItemCreated)", - //// Hint, - //// string.Empty - ////); - - //if (result) - // Logger.LogInformationSource("Item successful removed"); - //else - // Logger.LogErrorSource("Item is not successful removed"); - ////Logger.LogInformationSource("Item finally disposed"); - //// Stop listening out for callbacks - //PlugInIntegration.CallbackFired -= PlugInIntegration_CallbackFired; - //PlugInIntegration.ItemStateCheckFired -= PlugInIntegration_EnableMethodFired; - //PlugInIntegration.ItemStateCheckFired -= PlugInIntegration_EnableMethodFired; - } - } - - public static class CommandManagerItemExtensions - { - public static IEnumerable AsCommandCreatable(this IEnumerable items, - Func selectTypeSelector = null) - => items.Select(x => - x.AsCommandCreatable( - selectTypeSelector is null - ? swSelectType_e.swSelEVERYTHING - : selectTypeSelector.Invoke(x))); - - public static ICommandCreatable AsCommandCreatable(this CommandManagerItem item, swSelectType_e selectType = swSelectType_e.swSelEVERYTHING) - => new CommandContextItem() - { - Name = item.Name, - Hint = item.Hint, - OnClick = item.OnClick, - OnStateCheck = item.OnStateCheck, - SelectionType = selectType - }; } } diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerItemExtensions.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerItemExtensions.cs new file mode 100644 index 0000000..14d931c --- /dev/null +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerItemExtensions.cs @@ -0,0 +1,29 @@ +using CADBooster.SolidDna.SolidWorks.CommandManager.Item; +using SolidWorks.Interop.swconst; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace CADBooster.SolidDna +{ + public static class CommandManagerItemExtensions + { + public static IEnumerable AsCommandCreatable(this IEnumerable items, + Func selectTypeSelector = null) + => items.Select(x => + x.AsCommandCreatable( + selectTypeSelector is null + ? swSelectType_e.swSelEVERYTHING + : selectTypeSelector.Invoke(x))); + + public static ICommandCreatable AsCommandCreatable(this CommandManagerItem item, swSelectType_e selectType = swSelectType_e.swSelEVERYTHING) + => new CommandContextItem() + { + Name = item.Name, + Hint = item.Hint, + OnClick = item.OnClick, + OnStateCheck = item.OnStateCheck, + SelectionType = selectType + }; + } +} diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandCreatable.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandCreatable.cs index d798abd..0f859a3 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandCreatable.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandCreatable.cs @@ -5,7 +5,6 @@ namespace CADBooster.SolidDna.SolidWorks.CommandManager.Item { public interface ICommandCreatable { - int UserId { get; } string Name { get; } IEnumerable Create(string path = ""); diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandCreated.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandCreated.cs new file mode 100644 index 0000000..113bde2 --- /dev/null +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandCreated.cs @@ -0,0 +1,9 @@ +using System; + +namespace CADBooster.SolidDna +{ + public interface ICommandCreated : IDisposable + { + string Name { get; } + } +} diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandItem.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandItem.cs index 8e5b5c5..2a93e52 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandItem.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandItem.cs @@ -12,11 +12,11 @@ public interface ICommandItem /// /// The action to call when the item is clicked /// - Action OnClick { get; set; } + Action OnClick { get; } /// /// The action to call when the item state requested /// - Action OnStateCheck { get; set; } + Action OnStateCheck { get; } } } \ No newline at end of file From aefe5550c59c38438f0eac7d8d35a8821f2a52ff Mon Sep 17 00:00:00 2001 From: GeKtvi <61162497+GeKtvi@users.noreply.github.com> Date: Mon, 17 Mar 2025 21:20:26 +0300 Subject: [PATCH 04/10] Separated item files by type --- .../Item/{ => ContextMenuItems}/CommandContextItemCreated.cs | 0 .../Item/{ => ContextMenuItems}/CommandContextMenuGroup.cs | 0 .../Item/{ => ContextMenuItems}/CommandContextMenuGroupCreated.cs | 0 .../Item/{ => ContextMenuItems}/CommandContextMenuItem.cs | 0 .../Item/{ => ContextMenuItems}/ICommandCreatable.cs | 0 .../CommandManager/Item/{ => ContextMenuItems}/ICommandCreated.cs | 0 .../CommandManager/Item/{ => Flyouts}/CommandManagerFlyout.cs | 0 .../CommandManager/Item/{ => Flyouts}/CommandManagerFlyoutType.cs | 0 .../Item/{ => ManagerItems}/CommandManagerItemTabView.cs | 0 .../Item/{ => ManagerItems}/CommandManagerSeparator.cs | 0 .../CommandManager/Item/{ => ManagerItems}/ICommandManagerItem.cs | 0 11 files changed, 0 insertions(+), 0 deletions(-) rename SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/{ => ContextMenuItems}/CommandContextItemCreated.cs (100%) rename SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/{ => ContextMenuItems}/CommandContextMenuGroup.cs (100%) rename SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/{ => ContextMenuItems}/CommandContextMenuGroupCreated.cs (100%) rename SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/{ => ContextMenuItems}/CommandContextMenuItem.cs (100%) rename SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/{ => ContextMenuItems}/ICommandCreatable.cs (100%) rename SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/{ => ContextMenuItems}/ICommandCreated.cs (100%) rename SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/{ => Flyouts}/CommandManagerFlyout.cs (100%) rename SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/{ => Flyouts}/CommandManagerFlyoutType.cs (100%) rename SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/{ => ManagerItems}/CommandManagerItemTabView.cs (100%) rename SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/{ => ManagerItems}/CommandManagerSeparator.cs (100%) rename SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/{ => ManagerItems}/ICommandManagerItem.cs (100%) diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextItemCreated.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextItemCreated.cs similarity index 100% rename from SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextItemCreated.cs rename to SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextItemCreated.cs diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuGroup.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuGroup.cs similarity index 100% rename from SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuGroup.cs rename to SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuGroup.cs diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuGroupCreated.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuGroupCreated.cs similarity index 100% rename from SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuGroupCreated.cs rename to SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuGroupCreated.cs diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuItem.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuItem.cs similarity index 100% rename from SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandContextMenuItem.cs rename to SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuItem.cs diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandCreatable.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/ICommandCreatable.cs similarity index 100% rename from SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandCreatable.cs rename to SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/ICommandCreatable.cs diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandCreated.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/ICommandCreated.cs similarity index 100% rename from SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandCreated.cs rename to SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/ICommandCreated.cs diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerFlyout.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/Flyouts/CommandManagerFlyout.cs similarity index 100% rename from SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerFlyout.cs rename to SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/Flyouts/CommandManagerFlyout.cs diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerFlyoutType.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/Flyouts/CommandManagerFlyoutType.cs similarity index 100% rename from SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerFlyoutType.cs rename to SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/Flyouts/CommandManagerFlyoutType.cs diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerItemTabView.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ManagerItems/CommandManagerItemTabView.cs similarity index 100% rename from SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerItemTabView.cs rename to SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ManagerItems/CommandManagerItemTabView.cs diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerSeparator.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ManagerItems/CommandManagerSeparator.cs similarity index 100% rename from SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerSeparator.cs rename to SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ManagerItems/CommandManagerSeparator.cs diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandManagerItem.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ManagerItems/ICommandManagerItem.cs similarity index 100% rename from SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandManagerItem.cs rename to SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ManagerItems/ICommandManagerItem.cs From 1ba905f9c8c20a42e314cd0b128139f31b10e316 Mon Sep 17 00:00:00 2001 From: GeKtvi <61162497+GeKtvi@users.noreply.github.com> Date: Mon, 17 Mar 2025 22:30:50 +0300 Subject: [PATCH 05/10] Added comments for context menu items and related classes --- .../Errors/SolidDnaErrorCode.cs | 5 ++ .../CommandManager/CommandManager.cs | 8 ++- .../Item/CommandManagerItemExtensions.cs | 23 +++++++- .../CommandContextItemCreated.cs | 56 ++++++++++++++++--- .../CommandContextMenuGroup.cs | 19 ++++--- .../CommandContextMenuGroupCreated.cs | 30 ++++++++-- .../CommandContextMenuItem.cs | 38 ++++++------- .../ContextMenuItems/ICommandCreatable.cs | 16 +++++- .../Item/ContextMenuItems/ICommandCreated.cs | 6 ++ .../CommandManager/Item/ICommandItem.cs | 7 ++- 10 files changed, 157 insertions(+), 51 deletions(-) diff --git a/SolidDna/CADBooster.SolidDna/Errors/SolidDnaErrorCode.cs b/SolidDna/CADBooster.SolidDna/Errors/SolidDnaErrorCode.cs index f7e6cf1..328bf75 100644 --- a/SolidDna/CADBooster.SolidDna/Errors/SolidDnaErrorCode.cs +++ b/SolidDna/CADBooster.SolidDna/Errors/SolidDnaErrorCode.cs @@ -228,6 +228,11 @@ public enum SolidDnaErrorCode /// SolidWorksCommandItemPositionError = 12010, + /// + /// There was an error while trying to activate a Context Menu Item that was already activated + /// + SolidWorksCommandContextMenuItemReActivateError = 12011, + #endregion #region Export Data (13,000) diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/CommandManager.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/CommandManager.cs index 22f5b32..331a0ee 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/CommandManager.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/CommandManager.cs @@ -82,6 +82,10 @@ public CommandManagerGroup CreateCommandTab(string title, int id, List + /// Creates context menu items from the provided collection of objects + /// + /// The collection of command items to create public void CreateContextMenuItems(IEnumerable commandItems) { foreach (var item in commandItems) @@ -131,7 +135,7 @@ public CommandManagerGroup CreateCommandGroupAndTabs(string title, int id, List< // Track all flyouts for all add-ins that use SolidDNA mCommandFlyouts.AddRange(commandManagerItems.OfType()); - + // Create the group group.Create(this, title); @@ -335,7 +339,7 @@ public override void Dispose() // Remove all command flyouts mCommandFlyouts?.ForEach(RemoveCommandFlyout); - // Remove all command context menu items + // Dispose all command context menu items mCommandContextItems?.ForEach(x => x.Dispose()); mCommandContextItems.Clear(); diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerItemExtensions.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerItemExtensions.cs index 14d931c..8e7930e 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerItemExtensions.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerItemExtensions.cs @@ -1,13 +1,21 @@ -using CADBooster.SolidDna.SolidWorks.CommandManager.Item; -using SolidWorks.Interop.swconst; +using SolidWorks.Interop.swconst; using System; using System.Collections.Generic; using System.Linq; namespace CADBooster.SolidDna { + /// + /// Provides extension methods for converting objects to + /// public static class CommandManagerItemExtensions { + /// + /// Converts a collection of objects to objects + /// + /// The collection of objects to convert + /// An optional function to determine the selection type for each item + /// A collection of objects public static IEnumerable AsCommandCreatable(this IEnumerable items, Func selectTypeSelector = null) => items.Select(x => @@ -16,6 +24,12 @@ selectTypeSelector is null ? swSelectType_e.swSelEVERYTHING : selectTypeSelector.Invoke(x))); + /// + /// Converts a single object to an object + /// + /// The object to convert + /// The selection type for the item (defaults to ) + /// An object public static ICommandCreatable AsCommandCreatable(this CommandManagerItem item, swSelectType_e selectType = swSelectType_e.swSelEVERYTHING) => new CommandContextItem() { @@ -23,7 +37,10 @@ public static ICommandCreatable AsCommandCreatable(this CommandManagerItem item, Hint = item.Hint, OnClick = item.OnClick, OnStateCheck = item.OnStateCheck, - SelectionType = selectType + SelectionType = selectType, + VisibleForAssemblies = item.VisibleForAssemblies, + VisibleForDrawings = item.VisibleForDrawings, + VisibleForParts = item.VisibleForParts }; } } diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextItemCreated.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextItemCreated.cs index 38ea907..b6d2c40 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextItemCreated.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextItemCreated.cs @@ -1,21 +1,61 @@ using SolidWorks.Interop.swconst; using System; -using System.Diagnostics; namespace CADBooster.SolidDna { internal class CommandContextItemCreated : ICommandCreated, ICommandItem { + /// + /// Gets the unique callback ID for this command context item + /// public string CallbackId { get; } = Guid.NewGuid().ToString("N"); + + /// + /// Gets the command ID assigned by SolidWorks for this item + /// public int CommandId { get; } + + /// + /// Gets the name of this command context item + /// public string Name { get; } + + /// + /// Gets the hint text for this command context item + /// public string Hint { get; } + + /// + /// Gets the selection type that determines where this item is shown + /// public swSelectType_e SelectionType { get; } + + /// + /// Gets the document type (Assembly, Part, or Drawing) for which this item is created + /// public DocumentType DocumentType { get; } + + /// + /// Gets the action to call when this item is clicked + /// public Action OnClick { get; } + + /// + /// Gets the action to call when the state of this item is checked + /// public Action OnStateCheck { get; private set; } + + /// + /// Gets the full name of this command context item, including its hierarchical path + /// public string FullName { get; } + /// + /// Initializes a new instance of the class + /// + /// The command context item to create + /// The full name of the item, including its hierarchical path + /// The document type (Assembly, Part, or Drawing) for which this item is created public CommandContextItemCreated(CommandContextItem commandContextItem, string fullName, DocumentType documentType) { Name = commandContextItem.Name; @@ -26,6 +66,9 @@ public CommandContextItemCreated(CommandContextItem commandContextItem, string f DocumentType = documentType; FullName = fullName; + /// Maybe we can add an icon using + /// Also, we have , but it adds a group, and there's no possibility to add a root item. + CommandId = AddInIntegration.SolidWorks.UnsafeObject.AddMenuPopupItem3( (int)DocumentType, SolidWorksEnvironment.Application.SolidWorksCookie, @@ -65,9 +108,6 @@ private void PlugInIntegration_CallbackFired(string name) /// The arguments for user handling private void PlugInIntegration_EnableMethodFired(ItemStateCheckArgs args) { - if (args.CallbackId == "CommandContextItemCreated") - Debugger.Break(); - if (CallbackId != args.CallbackId) return; @@ -80,9 +120,9 @@ private void PlugInIntegration_EnableMethodFired(ItemStateCheckArgs args) /// public void Dispose() { - // I can't find the way to remove the item + /// I can't find the way to remove the item - // It always returns false, and the item isn't removed + /// It always returns false, and the item isn't removed. //var removeMenuPopupItemResult = AddInIntegration.SolidWorks.UnsafeObject.RemoveMenuPopupItem2( // (int)DocumentType, // SolidWorksEnvironment.Application.SolidWorksCookie, @@ -94,7 +134,7 @@ public void Dispose() // string.Empty //); - // It always returns true, but the item isn't removed + /// It always returns true, but the item isn't removed. //var removeFromPopupMenuResult = AddInIntegration.SolidWorks.UnsafeObject.RemoveFromPopupMenu( // CommandId, // (int)DocumentType, @@ -102,6 +142,8 @@ public void Dispose() // true //); + /// Besides, the user can hide it using . + // Stop listening out for callbacks PlugInIntegration.CallbackFired -= PlugInIntegration_CallbackFired; PlugInIntegration.ItemStateCheckFired -= PlugInIntegration_EnableMethodFired; diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuGroup.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuGroup.cs index 63424e3..80e676a 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuGroup.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuGroup.cs @@ -1,14 +1,11 @@ using CADBooster.SolidDna.SolidWorks.CommandManager.Item; -using SolidWorks.Interop.swconst; -using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Linq; namespace CADBooster.SolidDna { /// - /// A command context menu group in SolidWorks + /// Represents a command context menu group in SolidWorks /// public class CommandContextMenuGroup : ICommandCreatable { @@ -21,19 +18,25 @@ public class CommandContextMenuGroup : ICommandCreatable /// public string Name { get; set; } + /// + /// Context menu items in this group + /// public List Items { get; set; } #endregion /// - /// Remove, then re-add all items to the flyout. - /// Is called on every click of the flyout, but only does something on the first click. - /// SolidWorks calls this a 'dynamic flyout' in the help. + /// Creates the command context menu group and its items /// + /// The hierarchical path for the group + /// A list of created command context menu items + /// Thrown if the group has already been created public IEnumerable Create(string path) { if (_isCreated) - throw new NotImplementedException(); // TODO + throw new SolidDnaException( + SolidDnaErrors.CreateError(SolidDnaErrorTypeCode.SolidWorksCommandManager, + SolidDnaErrorCode.SolidWorksCommandContextMenuItemReActivateError)); _isCreated = true; diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuGroupCreated.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuGroupCreated.cs index c17ee54..2bdcd13 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuGroupCreated.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuGroupCreated.cs @@ -1,23 +1,43 @@ -using CADBooster.SolidDna.SolidWorks.CommandManager.Item; -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; namespace CADBooster.SolidDna { + /// + /// Represents a created command context menu group in SolidWorks + /// This class handles the creation and disposal of a group of context menu items + /// internal class CommandContextMenuGroupCreated : ICommandCreated { - public string CallbackId => Guid.Empty.ToString("N"); + /// + /// Gets the unique callback ID for this command context menu group + /// + public string CallbackId => string.Empty; + + /// + /// Gets the name of this command context menu group + /// public string Name { get; } + /// + /// A list of created command items within this group + /// private readonly List _createdItems; + /// + /// Initializes a new instance of the class + /// + /// The name of the group + /// The hierarchical path for the group + /// The list of command items to include in the group public CommandContextMenuGroupCreated(string name, string path, List items) { Name = name; + // Construct the full name for the group using the provided path var fullName = string.IsNullOrEmpty(path) ? $"{Name}" : $"{path}@{Name}"; + // Create all child items and store them in the list _createdItems = items .SelectMany(x => x.Create(fullName)) .ToList(); @@ -28,7 +48,7 @@ public CommandContextMenuGroupCreated(string name, string path, List public void Dispose() { - // Dispose child items + // Dispose all child items _createdItems.ForEach(x => x.Dispose()); } } diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuItem.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuItem.cs index f8b8a62..d9de380 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuItem.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuItem.cs @@ -1,9 +1,6 @@ -using CADBooster.SolidDna.SolidWorks.CommandManager.Item; -using SolidWorks.Interop.sldworks; -using SolidWorks.Interop.swconst; +using SolidWorks.Interop.swconst; using System; using System.Collections.Generic; -using System.Windows.Shapes; namespace CADBooster.SolidDna { @@ -21,22 +18,22 @@ public class CommandContextItem : ICommandCreatable public string Name { get; set; } /// - /// The help text for this item. Is only used for toolbar items and flyouts, underneath the . Is not used for menus and flyout items. + /// The help text for this item. /// public string Hint { get; set; } /// - /// True to show this item in the command tab when an assembly is open. Only works for toolbar items and flyouts, not for menus or flyout items. + /// True to show this item in the context menu when an assembly is open. /// public bool VisibleForAssemblies { get; set; } = true; /// - /// True to show this item in the command tab when a drawing is open. Only works for toolbar items and flyouts, not for menus or flyout items. + /// True to show this item in the context menu when a drawing is open. /// public bool VisibleForDrawings { get; set; } = true; /// - /// True to show this item in the command tab when a part is open. Only works for toolbar items and flyouts, not for menus or flyout items. + /// True to show this item in the context menu when a part is open. /// public bool VisibleForParts { get; set; } = true; @@ -50,26 +47,25 @@ public class CommandContextItem : ICommandCreatable /// public Action OnStateCheck { get; set; } - public swSelectType_e SelectionType { get; set; } = swSelectType_e.swSelNOTHING; - - #endregion - /// - /// Create a command manager flyout (group). + /// The selection type that determines where the context menu will be shown /// - public CommandContextItem() - { - } + public swSelectType_e SelectionType { get; set; } = swSelectType_e.swSelEVERYTHING; + + #endregion /// - /// Remove, then re-add all items to the flyout. - /// Is called on every click of the flyout, but only does something on the first click. - /// SolidWorks calls this a 'dynamic flyout' in the help. + /// Creates the command context item for the specified document types /// + /// The path to use for hierarchical naming. If empty, the item's name is used + /// A list of created command context items + /// Thrown if the item has already been created public IEnumerable Create(string path = "") { - //if (_isCreated) - // throw new NotImplementedException(); // TODO + if (_isCreated) + throw new SolidDnaException( + SolidDnaErrors.CreateError(SolidDnaErrorTypeCode.SolidWorksCommandManager, + SolidDnaErrorCode.SolidWorksCommandContextMenuItemReActivateError)); _isCreated = true; diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/ICommandCreatable.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/ICommandCreatable.cs index 0f859a3..d3e79a4 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/ICommandCreatable.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/ICommandCreatable.cs @@ -1,12 +1,22 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; -namespace CADBooster.SolidDna.SolidWorks.CommandManager.Item +namespace CADBooster.SolidDna { + /// + /// Represents an interface for creating command items in the SolidWorks + /// public interface ICommandCreatable { + /// + /// Name of the command item + /// string Name { get; } + /// + /// Creates the command item for the specified path + /// + /// The path to use for hierarchical naming. If empty, the item's name is used + /// A list of created command items IEnumerable Create(string path = ""); } } diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/ICommandCreated.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/ICommandCreated.cs index 113bde2..22c571c 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/ICommandCreated.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/ICommandCreated.cs @@ -2,8 +2,14 @@ namespace CADBooster.SolidDna { + /// + /// Represents an interface for a created command item in SolidWorks + /// public interface ICommandCreated : IDisposable { + /// + /// Gets the name of the created command item + /// string Name { get; } } } diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandItem.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandItem.cs index 2a93e52..9dab4b1 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandItem.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ICommandItem.cs @@ -2,10 +2,13 @@ namespace CADBooster.SolidDna { + /// + /// Represents an interface for a command item + /// public interface ICommandItem { /// - /// The unique Callback ID (set by creator) + /// The unique Callback ID /// string CallbackId { get; } @@ -15,7 +18,7 @@ public interface ICommandItem Action OnClick { get; } /// - /// The action to call when the item state requested + /// The action to call when the item's state is requested /// Action OnStateCheck { get; } } From adb1e3296dd52811b63f6eb28508623c247b749e Mon Sep 17 00:00:00 2001 From: GeKtvi <61162497+GeKtvi@users.noreply.github.com> Date: Sat, 12 Apr 2025 23:02:13 +0300 Subject: [PATCH 06/10] Fixed namespace --- .../SolidWorks/CommandManager/CommandManager.cs | 3 +-- .../Item/ContextMenuItems/CommandContextMenuGroup.cs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/CommandManager.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/CommandManager.cs index 331a0ee..819181d 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/CommandManager.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/CommandManager.cs @@ -1,5 +1,4 @@ -using CADBooster.SolidDna.SolidWorks.CommandManager.Item; -using SolidWorks.Interop.sldworks; +using SolidWorks.Interop.sldworks; using SolidWorks.Interop.swconst; using System; using System.Collections.Generic; diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuGroup.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuGroup.cs index 80e676a..ffb7929 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuGroup.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuGroup.cs @@ -1,5 +1,4 @@ -using CADBooster.SolidDna.SolidWorks.CommandManager.Item; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; namespace CADBooster.SolidDna From d4a0f0c3a846136e262ddef6aff0a0f8a7221cdb Mon Sep 17 00:00:00 2001 From: GeKtvi <61162497+GeKtvi@users.noreply.github.com> Date: Sat, 12 Apr 2025 23:05:36 +0300 Subject: [PATCH 07/10] Added disabled by active model command example --- .../SolidDna.CommandItems/CommandItems.cs | 255 ++++++++++-------- 1 file changed, 140 insertions(+), 115 deletions(-) diff --git a/Tutorials/09-CommandItems/SolidDna.CommandItems/CommandItems.cs b/Tutorials/09-CommandItems/SolidDna.CommandItems/CommandItems.cs index 23973bc..210ecde 100644 --- a/Tutorials/09-CommandItems/SolidDna.CommandItems/CommandItems.cs +++ b/Tutorials/09-CommandItems/SolidDna.CommandItems/CommandItems.cs @@ -1,6 +1,6 @@ using CADBooster.SolidDna; -using CADBooster.SolidDna.SolidWorks.CommandManager.Item; using SolidWorks.Interop.swconst; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -64,50 +64,6 @@ public override void ConnectedToSolidWorks() { var imageFormat = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "icons{0}.png"); - var item = CreateCommandItems().First(); - - new CommandContextMenuGroup() - { - Name = "RootGroup", - Items = - [.. - CreateCommandItems().AsCommandCreatable(), - new CommandContextItem() - { - Name = "Plane item", - Hint = "Plane item Hint", - OnClick = item.OnClick, - SelectionType = swSelectType_e.swSelDATUMPLANES - }, - new CommandContextMenuGroup() - { - Name = "SubGroup", - Items = [ - new CommandContextItem() - { - Name = "SubItem", - Hint = "SubGroup", - OnClick = item.OnClick, - SelectionType = swSelectType_e.swSelCOMPONENTS - }, - new CommandContextMenuGroup() - { - Name = "SubSubGroup", - Items = [ - new CommandContextItem() - { - Name = "SubSubItem", - Hint = "SubSubItem Hint", - OnClick = item.OnClick, - SelectionType = swSelectType_e.swSelCOMPONENTS - } - ] - }, - ] - }, - ] - }.Create(string.Empty); - // FlyoutGroup var flyout = Application.CommandManager.CreateFlyoutGroup2( title: "CreateFlyoutGroup2 Example", @@ -137,6 +93,60 @@ public override void ConnectedToSolidWorks() title: "CreateCommandMenu Example", id: 150_001, commandManagerItems: CreateCommandItems()); + + Action onContextMenuItemClick = () => System.Windows.MessageBox.Show("Context menu item clicked"); + + Application.CommandManager.CreateContextMenuItems([ + new CommandContextItem() + { + Name = "RootItem", + Hint = "RootItem Hint", + OnClick = onContextMenuItemClick, + OnStateCheck = args => args.Result = ItemState.SelectedEnabled, + SelectionType = swSelectType_e.swSelCOMPONENTS + }, + new CommandContextMenuGroup() + { + Name = "RootGroup", + Items = + [.. + CreateCommandItems().AsCommandCreatable(x => swSelectType_e.swSelCOMPONENTS), + new CommandContextItem() + { + Name = "PlaneItem", + Hint = "PlaneItem Hint", + OnClick = onContextMenuItemClick, + SelectionType = swSelectType_e.swSelDATUMPLANES + }, + new CommandContextMenuGroup() + { + Name = "SubGroup", + Items = [ + new CommandContextItem() + { + Name = "SubSubItem", + Hint = "SubSubItem Hint", + OnClick = onContextMenuItemClick, + SelectionType = swSelectType_e.swSelCOMPONENTS + }, + new CommandContextMenuGroup() + { + Name = "SubSubGroup", + Items = [ + new CommandContextItem() + { + Name = "SubSubItem", + Hint = "SubSubItem Hint", + OnClick = onContextMenuItemClick, + SelectionType = swSelectType_e.swSelCOMPONENTS + } + ] + }, + ] + } + ] + } + ]); } /// @@ -144,79 +154,94 @@ public override void ConnectedToSolidWorks() /// /// CommandManagerItems public List CreateCommandItems() => - new List{ - new CommandManagerItem { - Name = "DeselectedDisabled item", - Tooltip = "DeselectedDisabled item Tooltip", - ImageIndex = 0, - Hint = "DeselectedDisabled item Hint", - VisibleForDrawings = true, - VisibleForAssemblies = true, - VisibleForParts = true, - OnClick = () => System.Windows.MessageBox.Show("CreateCommandTab DeselectedDisabled item clicked!"), - OnStateCheck = (args) => args.Result = ItemState.DeselectedDisabled - }, - new CommandManagerItem { - Name = "DeselectedEnabled item", - Tooltip = "DeselectedEnabled item Tooltip", - ImageIndex = 1, - Hint = "DeselectedEnabled item Hint", - VisibleForDrawings = true, - VisibleForAssemblies = true, - VisibleForParts = true, - OnClick = () => System.Windows.MessageBox.Show("CreateCommandTab DeselectedEnabled item clicked!"), - OnStateCheck = (args) => args.Result = ItemState.DeselectedEnabled - }, - new CommandManagerItem { - Name = "SelectedDisabled item", - Tooltip = "SelectedDisabled item Tooltip", - ImageIndex = 2, - Hint = "SelectedDisabled item Hint", - VisibleForDrawings = true, - VisibleForAssemblies = true, - VisibleForParts = true, - OnClick = () => System.Windows.MessageBox.Show("CreateCommandTab SelectedDisabled item clicked!"), - OnStateCheck = (args) => args.Result = ItemState.SelectedDisabled - }, - new CommandManagerItem { - Name = "SelectedEnabled item", - Tooltip = "SelectedEnabled item Tooltip", - ImageIndex = 0, - Hint = "SelectedEnabled item Hint", - VisibleForDrawings = true, - VisibleForAssemblies = true, - VisibleForParts = true, - OnClick = () => System.Windows.MessageBox.Show("CreateCommandTab SelectedEnabled item clicked!"), - OnStateCheck = (args) => args.Result = ItemState.SelectedEnabled - }, - new CommandManagerItem { - Name = "Hidden item", - Tooltip = "Hidden item Tooltip", - ImageIndex = 1, - Hint = "Hidden item Hint", - VisibleForDrawings = true, - VisibleForAssemblies = true, - VisibleForParts = true, - OnClick = () => System.Windows.MessageBox.Show("CreateCommandTab Hidden item clicked!"), - OnStateCheck = (args) => args.Result = ItemState.Hidden - }, - new CommandManagerItem { - Name = "Toggle item", - Tooltip = "Toggle item Tooltip", - ImageIndex = 2, - Hint = "Toggle item Hint", - VisibleForDrawings = true, - VisibleForAssemblies = true, - VisibleForParts = true, - OnClick = () => mToggle = !mToggle, - OnStateCheck = (args) => - args.Result = mToggle ? ItemState.SelectedEnabled : ItemState.DeselectedEnabled - } - }; + [ + // We cant hide item in ToolBar by document type, but it can be disabled manually + new CommandManagerItem { + Name = "Item for assembly", + Tooltip = "Item tool tip", + ImageIndex = 0, + Hint = "Item disabled in tool bar by active dock type (Assembly)", + VisibleForDrawings = false, + VisibleForAssemblies = false, + VisibleForParts = false, + OnClick = () => System.Windows.MessageBox.Show("CreateCommandTab DeselectedDisabled item clicked!"), + OnStateCheck = (args) => + { + if(Application.ActiveModel?.IsAssembly is true) + args.Result = ItemState.DeselectedDisabled; + } + }, + new CommandManagerItem { + Name = "DeselectedDisabled item", + Tooltip = "DeselectedDisabled item Tooltip", + ImageIndex = 0, + Hint = "DeselectedDisabled item Hint", + VisibleForDrawings = true, + VisibleForAssemblies = true, + VisibleForParts = true, + OnClick = () => System.Windows.MessageBox.Show("CreateCommandTab DeselectedDisabled item clicked!"), + OnStateCheck = (args) => args.Result = ItemState.DeselectedDisabled + }, + new CommandManagerItem { + Name = "DeselectedEnabled item", + Tooltip = "DeselectedEnabled item Tooltip", + ImageIndex = 1, + Hint = "DeselectedEnabled item Hint", + VisibleForDrawings = true, + VisibleForAssemblies = true, + VisibleForParts = true, + OnClick = () => System.Windows.MessageBox.Show("CreateCommandTab DeselectedEnabled item clicked!"), + OnStateCheck = (args) => args.Result = ItemState.DeselectedEnabled + }, + new CommandManagerItem { + Name = "SelectedDisabled item", + Tooltip = "SelectedDisabled item Tooltip", + ImageIndex = 2, + Hint = "SelectedDisabled item Hint", + VisibleForDrawings = true, + VisibleForAssemblies = true, + VisibleForParts = true, + OnClick = () => System.Windows.MessageBox.Show("CreateCommandTab SelectedDisabled item clicked!"), + OnStateCheck = (args) => args.Result = ItemState.SelectedDisabled + }, + new CommandManagerItem { + Name = "SelectedEnabled item", + Tooltip = "SelectedEnabled item Tooltip", + ImageIndex = 0, + Hint = "SelectedEnabled item Hint", + VisibleForDrawings = true, + VisibleForAssemblies = true, + VisibleForParts = true, + OnClick = () => System.Windows.MessageBox.Show("CreateCommandTab SelectedEnabled item clicked!"), + OnStateCheck = (args) => args.Result = ItemState.SelectedEnabled + }, + new CommandManagerItem { + Name = "Hidden item", + Tooltip = "Hidden item Tooltip", + ImageIndex = 1, + Hint = "Hidden item Hint", + VisibleForDrawings = true, + VisibleForAssemblies = true, + VisibleForParts = true, + OnClick = () => System.Windows.MessageBox.Show("CreateCommandTab Hidden item clicked!"), + OnStateCheck = (args) => args.Result = ItemState.Hidden + }, + new CommandManagerItem { + Name = "Toggle item", + Tooltip = "Toggle item Tooltip", + ImageIndex = 2, + Hint = "Toggle item Hint", + VisibleForDrawings = true, + VisibleForAssemblies = true, + VisibleForParts = true, + OnClick = () => mToggle = !mToggle, + OnStateCheck = (args) => + args.Result = mToggle ? ItemState.SelectedEnabled : ItemState.DeselectedEnabled + } + ]; public override void DisconnectedFromSolidWorks() { - } #endregion From 17e49018928655e98a6eab496ded1583fad0ac15 Mon Sep 17 00:00:00 2001 From: GeKtvi <61162497+GeKtvi@users.noreply.github.com> Date: Wed, 16 Apr 2025 21:05:50 +0300 Subject: [PATCH 08/10] Fix formatting in CommandItems example --- .../SolidDna.CommandItems/CommandItems.cs | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/Tutorials/09-CommandItems/SolidDna.CommandItems/CommandItems.cs b/Tutorials/09-CommandItems/SolidDna.CommandItems/CommandItems.cs index d684feb..e73cfb2 100644 --- a/Tutorials/09-CommandItems/SolidDna.CommandItems/CommandItems.cs +++ b/Tutorials/09-CommandItems/SolidDna.CommandItems/CommandItems.cs @@ -109,7 +109,7 @@ private void CreateMenus() Application.CommandManager.CreateContextMenuItems( [ - new CommandContextItem() + new CommandContextItem { Name = "RootItem", Hint = "RootItem Hint", @@ -117,37 +117,37 @@ private void CreateMenus() OnStateCheck = args => args.Result = CommandManagerItemState.SelectedEnabled, SelectionType = swSelectType_e.swSelCOMPONENTS }, - new CommandContextMenuGroup() + new CommandContextMenuGroup { Name = "RootGroup", Items = [.. CreateCommandItems().AsCommandCreatable(x => swSelectType_e.swSelCOMPONENTS), - new CommandContextItem() + new CommandContextItem { Name = "PlaneItem", Hint = "PlaneItem Hint", OnClick = onContextMenuItemClick, SelectionType = swSelectType_e.swSelDATUMPLANES }, - new CommandContextMenuGroup() + new CommandContextMenuGroup { Name = "SubGroup", Items = [ - new CommandContextItem() + new CommandContextItem { Name = "SubSubItem", Hint = "SubSubItem Hint", OnClick = onContextMenuItemClick, SelectionType = swSelectType_e.swSelCOMPONENTS }, - new CommandContextMenuGroup() + new CommandContextMenuGroup { Name = "SubSubGroup", Items = [ - new CommandContextItem() + new CommandContextItem { Name = "SubSubSubItem", Hint = "SubSubSubItem Hint", @@ -169,7 +169,8 @@ private void CreateMenus() public List CreateCommandItems() => [ // We cant hide item in ToolBar by document type, but it can be disabled manually - new CommandManagerItem { + new CommandManagerItem + { Name = "Item for assembly", Tooltip = "Item tool tip", ImageIndex = 0, @@ -184,7 +185,8 @@ public List CreateCommandItems() => args.Result = CommandManagerItemState.DeselectedDisabled; } }, - new CommandManagerItem { + new CommandManagerItem + { Name = "DeselectedDisabled item", Tooltip = "DeselectedDisabled item Tooltip", ImageIndex = 0, @@ -195,7 +197,8 @@ public List CreateCommandItems() => OnClick = () => System.Windows.MessageBox.Show("CreateCommandTab DeselectedDisabled item clicked!"), OnStateCheck = (args) => args.Result = CommandManagerItemState.DeselectedDisabled }, - new CommandManagerItem { + new CommandManagerItem + { Name = "DeselectedEnabled item", Tooltip = "DeselectedEnabled item Tooltip", ImageIndex = 1, @@ -206,7 +209,8 @@ public List CreateCommandItems() => OnClick = () => System.Windows.MessageBox.Show("CreateCommandTab DeselectedEnabled item clicked!"), OnStateCheck = (args) => args.Result = CommandManagerItemState.DeselectedEnabled }, - new CommandManagerItem { + new CommandManagerItem + { Name = "SelectedDisabled item", Tooltip = "SelectedDisabled item Tooltip", ImageIndex = 2, @@ -217,7 +221,8 @@ public List CreateCommandItems() => OnClick = () => System.Windows.MessageBox.Show("CreateCommandTab SelectedDisabled item clicked!"), OnStateCheck = (args) => args.Result = CommandManagerItemState.SelectedDisabled }, - new CommandManagerItem { + new CommandManagerItem + { Name = "SelectedEnabled item", Tooltip = "SelectedEnabled item Tooltip", ImageIndex = 0, @@ -228,7 +233,8 @@ public List CreateCommandItems() => OnClick = () => System.Windows.MessageBox.Show("CreateCommandTab SelectedEnabled item clicked!"), OnStateCheck = (args) => args.Result = CommandManagerItemState.SelectedEnabled }, - new CommandManagerItem { + new CommandManagerItem + { Name = "Hidden item", Tooltip = "Hidden item Tooltip", ImageIndex = 1, @@ -239,7 +245,8 @@ public List CreateCommandItems() => OnClick = () => System.Windows.MessageBox.Show("CreateCommandTab Hidden item clicked!"), OnStateCheck = (args) => args.Result = CommandManagerItemState.Hidden }, - new CommandManagerItem { + new CommandManagerItem + { Name = "Toggle item", Tooltip = "Toggle item Tooltip", ImageIndex = 2, @@ -249,7 +256,7 @@ public List CreateCommandItems() => VisibleForParts = true, OnClick = () => mToggle = !mToggle, OnStateCheck = (args) => - args.Result = mToggle ? CommandManagerItemState.SelectedEnabled : CommandManagerItemState.DeselectedEnabled + args.Result = mToggle ? CommandManagerItemState.SelectedEnabled : CommandManagerItemState.DeselectedEnabled } ]; From 32016d0db89cb114ff69ef344e260901bc2c58d6 Mon Sep 17 00:00:00 2001 From: GeKtvi <61162497+GeKtvi@users.noreply.github.com> Date: Mon, 23 Jun 2025 22:14:20 +0300 Subject: [PATCH 09/10] Added context icon --- .../ContextMenuItems/CommandContextBase.cs | 73 +++++++++ .../CommandContextCreatedBase.cs | 126 ++++++++++++++ .../ContextMenuItems/CommandContextIcon.cs | 42 +++++ .../CommandContextIconCreated.cs | 43 +++++ .../CommandContextItemCreated.cs | 155 +++--------------- .../CommandContextMenuItem.cs | 59 +------ .../SolidDna.CommandItems/CommandItems.cs | 9 + 7 files changed, 324 insertions(+), 183 deletions(-) create mode 100644 SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextBase.cs create mode 100644 SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextCreatedBase.cs create mode 100644 SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextIcon.cs create mode 100644 SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextIconCreated.cs diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextBase.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextBase.cs new file mode 100644 index 0000000..9bef158 --- /dev/null +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextBase.cs @@ -0,0 +1,73 @@ +using SolidWorks.Interop.swconst; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace CADBooster.SolidDna +{ + /// + /// A command context menu item base class + /// + public abstract class CommandContextBase + { + + private bool _isCreated; + + #region Public Properties + + /// + /// The help text for this item. + /// + public string Hint { get; set; } + + /// + /// True to show this item in the context menu when an assembly is open. + /// + public bool VisibleForAssemblies { get; set; } = true; + + /// + /// True to show this item in the context menu when a drawing is open. + /// + public bool VisibleForDrawings { get; set; } = true; + + /// + /// True to show this item in the context menu when a part is open. + /// + public bool VisibleForParts { get; set; } = true; + + /// + /// The action to call when the item is clicked + /// + public Action OnClick { get; set; } + + /// + /// The action to call when the item state requested + /// + public Action OnStateCheck { get; set; } + + /// + /// The selection type that determines where the context menu will be shown + /// + public swSelectType_e SelectionType { get; set; } = swSelectType_e.swSelEVERYTHING; + + #endregion + + /// + /// Creates the command context item for the specified document types + /// + /// The path to use for hierarchical naming. If empty, the item's name is used + /// A list of created command context items + /// Thrown if the item has already been created + public virtual IEnumerable Create(string path = "") + { + if (_isCreated) + throw new SolidDnaException( + SolidDnaErrors.CreateError(SolidDnaErrorTypeCode.SolidWorksCommandManager, + SolidDnaErrorCode.SolidWorksCommandContextMenuItemReActivateError)); + + _isCreated = true; + + return Enumerable.Empty(); + } + } +} diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextCreatedBase.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextCreatedBase.cs new file mode 100644 index 0000000..cdb6610 --- /dev/null +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextCreatedBase.cs @@ -0,0 +1,126 @@ +using SolidWorks.Interop.swconst; +using System; + +namespace CADBooster.SolidDna +{ + internal abstract class CommandContextCreatedBase : ICommandCreated, ICommandItem + { + /// + /// Gets the unique callback ID for this command context item + /// + public string CallbackId { get; } = Guid.NewGuid().ToString("N"); + + /// + /// Gets the name of this command context item + /// + public abstract string Name { get; } + + /// + /// Gets the hint text for this command context item + /// + public string Hint { get; } + + /// + /// Gets the selection type that determines where this item is shown + /// + public swSelectType_e SelectionType { get; } + + /// + /// Gets the document type (Assembly, Part, or Drawing) for which this item is created + /// + public DocumentType DocumentType { get; } + + /// + /// Gets the action to call when this item is clicked + /// + public Action OnClick { get; } + + /// + /// Gets the action to call when the state of this item is checked + /// + public Action OnStateCheck { get; private set; } + + /// + /// Initializes a new instance of the class + /// + /// The command context item to create + /// The full name of the item, including its hierarchical path + /// The document type (Assembly, Part, or Drawing) for which this item is created + public CommandContextCreatedBase(CommandContextBase commandContextBase, DocumentType documentType) + { + Hint = commandContextBase.Hint; + OnClick = commandContextBase.OnClick; + OnStateCheck = commandContextBase.OnStateCheck; + SelectionType = commandContextBase.SelectionType; + DocumentType = documentType; + + // Listen out for callbacks + PlugInIntegration.CallbackFired += PlugInIntegration_CallbackFired; + + // Listen out for EnableMethod + PlugInIntegration.ItemStateCheckFired += PlugInIntegration_EnableMethodFired; + + Logger.LogDebugSource("Context menu item created"); + } + + /// + /// Fired when a SolidWorks callback is fired + /// + /// The name of the callback that was fired + private void PlugInIntegration_CallbackFired(string name) + { + if (CallbackId != name) + return; + + // Call the action + OnClick?.Invoke(); + } + + /// + /// Fired when a SolidWorks UpdateCallbackFunction is fired + /// + /// The arguments for user handling + private void PlugInIntegration_EnableMethodFired(CommandManagerItemStateCheckArgs args) + { + if (CallbackId != args.CallbackId) + return; + + // Call the action + OnStateCheck?.Invoke(args); + } + + /// + /// Disposing + /// + public void Dispose() + { + /// I can't find the way to remove the item + + /// It always returns false, and the item isn't removed. + //var removeMenuPopupItemResult = AddInIntegration.SolidWorks.UnsafeObject.RemoveMenuPopupItem2( + // (int)DocumentType, + // SolidWorksEnvironment.Application.SolidWorksCookie, + // (int)SelectionType, + // FullName, + // $"{nameof(SolidAddIn.Callback)}({CallbackId})", + // $"{nameof(SolidAddIn.ItemStateCheck)}({CallbackId})", + // Hint, + // string.Empty + //); + + /// It always returns true, but the item isn't removed. + //var removeFromPopupMenuResult = AddInIntegration.SolidWorks.UnsafeObject.RemoveFromPopupMenu( + // CommandId, + // (int)DocumentType, + // (int)SelectionType, + // true + //); + + /// Besides, the user can hide it using . + + // Stop listening out for callbacks + PlugInIntegration.CallbackFired -= PlugInIntegration_CallbackFired; + PlugInIntegration.ItemStateCheckFired -= PlugInIntegration_EnableMethodFired; + } + } +} diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextIcon.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextIcon.cs new file mode 100644 index 0000000..ac06abe --- /dev/null +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextIcon.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; + +namespace CADBooster.SolidDna +{ + /// + /// Represents a context icon in SolidWorks + /// + public class CommandContextIcon : CommandContextBase, ICommandCreatable + { + /// + /// Gets or sets the icon formatted path + /// + public string Icon { get; set; } + + /// + /// Gets the name of the command (implementing ICommandCreatable interface) + /// + string ICommandCreatable.Name => Hint; + + /// + /// Creates the command context icon for the specified document types + /// + /// Not used for icon + /// A list of created command context icons + /// Thrown if the item has already been created + public sealed override IEnumerable Create(string _s = "") + { + _ = base.Create(); + + var created = new List(); + + if (VisibleForAssemblies) + created.Add(new CommandContextIconCreated(this, DocumentType.Assembly)); + if (VisibleForDrawings) + created.Add(new CommandContextIconCreated(this, DocumentType.Drawing)); + if (VisibleForParts) + created.Add(new CommandContextIconCreated(this, DocumentType.Part)); + + return created; + } + } +} diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextIconCreated.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextIconCreated.cs new file mode 100644 index 0000000..7d547a9 --- /dev/null +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextIconCreated.cs @@ -0,0 +1,43 @@ +using SolidWorks.Interop.sldworks; +using System.Runtime.InteropServices; + +namespace CADBooster.SolidDna +{ + /// + /// Represents a created command context icon in the SolidWorks + /// + internal class CommandContextIconCreated : CommandContextCreatedBase + { + /// + /// Gets the name of this command context item + /// + public sealed override string Name => Hint; + + /// + /// Initializes a new command context icon in the SolidWorks UI + /// + /// The icon configuration + /// The document type this icon applies to + public CommandContextIconCreated(CommandContextIcon commandContextIcon, + DocumentType documentType) : base(commandContextIcon, documentType) + { + // The list of icons. There should be a one multi sized icon. + var icons = Icons.GetArrayFromDictionary(Icons.GetFormattedPathDictionary(commandContextIcon.Icon)); + + // Get the SolidWorks frame and add the menu icon + var frame = (IFrame)AddInIntegration.SolidWorks.UnsafeObject.Frame(); + + _ = frame.AddMenuPopupIcon3( + (int)DocumentType, + (int)SelectionType, + Hint, + SolidWorksEnvironment.Application.SolidWorksCookie, + $"{nameof(SolidAddIn.Callback)}({CallbackId})", + $"{nameof(SolidAddIn.ItemStateCheck)}({CallbackId})", + string.Empty, + icons); + + _ = Marshal.ReleaseComObject(frame); + } + } +} diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextItemCreated.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextItemCreated.cs index 20f9da1..0bb1e8f 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextItemCreated.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextItemCreated.cs @@ -1,152 +1,47 @@ -using SolidWorks.Interop.swconst; -using System; +using System.Runtime.InteropServices; namespace CADBooster.SolidDna { - internal class CommandContextItemCreated : ICommandCreated, ICommandItem + /// + /// A command context menu item + /// + internal class CommandContextItemCreated : CommandContextCreatedBase { /// - /// Gets the unique callback ID for this command context item + /// Gets the name of this command context item /// - public string CallbackId { get; } = Guid.NewGuid().ToString("N"); + public sealed override string Name => _name; /// /// Gets the command ID assigned by SolidWorks for this item /// public int CommandId { get; } - /// - /// Gets the name of this command context item - /// - public string Name { get; } - - /// - /// Gets the hint text for this command context item - /// - public string Hint { get; } - - /// - /// Gets the selection type that determines where this item is shown - /// - public swSelectType_e SelectionType { get; } - - /// - /// Gets the document type (Assembly, Part, or Drawing) for which this item is created - /// - public DocumentType DocumentType { get; } - - /// - /// Gets the action to call when this item is clicked - /// - public Action OnClick { get; } - - /// - /// Gets the action to call when the state of this item is checked - /// - public Action OnStateCheck { get; private set; } - - /// - /// Gets the full name of this command context item, including its hierarchical path - /// - public string FullName { get; } + private readonly string _name; /// - /// Initializes a new instance of the class + /// Creates the command context item for the specified document types /// - /// The command context item to create - /// The full name of the item, including its hierarchical path - /// The document type (Assembly, Part, or Drawing) for which this item is created - public CommandContextItemCreated(CommandContextItem commandContextItem, string fullName, DocumentType documentType) + /// The path to use for hierarchical naming. If empty, the item's name is used + /// A list of created command context items + /// Thrown if the item has already been created + public CommandContextItemCreated(CommandContextItem commandContextItem, + string fullName, + DocumentType documentType) : base(commandContextItem, documentType) { - Name = commandContextItem.Name; - Hint = commandContextItem.Hint; - OnClick = commandContextItem.OnClick; - OnStateCheck = commandContextItem.OnStateCheck; - SelectionType = commandContextItem.SelectionType; - DocumentType = documentType; - FullName = fullName; - - /// Maybe we can add an icon using - /// Also, we have , but it adds a group, and there's no possibility to add a root item. + _name = commandContextItem.Name; + /// We have , but it adds a group, and there's no possibility to add a root item. CommandId = AddInIntegration.SolidWorks.UnsafeObject.AddMenuPopupItem3( - (int)DocumentType, - SolidWorksEnvironment.Application.SolidWorksCookie, - (int)SelectionType, - FullName, - $"{nameof(SolidAddIn.Callback)}({CallbackId})", - $"{nameof(SolidAddIn.ItemStateCheck)}({CallbackId})", - Hint, - string.Empty + (int)DocumentType, + SolidWorksEnvironment.Application.SolidWorksCookie, + (int)SelectionType, + fullName, + $"{nameof(SolidAddIn.Callback)}({CallbackId})", + $"{nameof(SolidAddIn.ItemStateCheck)}({CallbackId})", + Hint, + string.Empty ); - - // Listen out for callbacks - PlugInIntegration.CallbackFired += PlugInIntegration_CallbackFired; - - // Listen out for EnableMethod - PlugInIntegration.ItemStateCheckFired += PlugInIntegration_EnableMethodFired; - - Logger.LogDebugSource("Context menu item created"); - } - - /// - /// Fired when a SolidWorks callback is fired - /// - /// The name of the callback that was fired - private void PlugInIntegration_CallbackFired(string name) - { - if (CallbackId != name) - return; - - // Call the action - OnClick?.Invoke(); - } - - /// - /// Fired when a SolidWorks UpdateCallbackFunction is fired - /// - /// The arguments for user handling - private void PlugInIntegration_EnableMethodFired(CommandManagerItemStateCheckArgs args) - { - if (CallbackId != args.CallbackId) - return; - - // Call the action - OnStateCheck?.Invoke(args); - } - - /// - /// Disposing - /// - public void Dispose() - { - /// I can't find the way to remove the item - - /// It always returns false, and the item isn't removed. - //var removeMenuPopupItemResult = AddInIntegration.SolidWorks.UnsafeObject.RemoveMenuPopupItem2( - // (int)DocumentType, - // SolidWorksEnvironment.Application.SolidWorksCookie, - // (int)SelectionType, - // FullName, - // $"{nameof(SolidAddIn.Callback)}({CallbackId})", - // $"{nameof(SolidAddIn.ItemStateCheck)}({CallbackId})", - // Hint, - // string.Empty - //); - - /// It always returns true, but the item isn't removed. - //var removeFromPopupMenuResult = AddInIntegration.SolidWorks.UnsafeObject.RemoveFromPopupMenu( - // CommandId, - // (int)DocumentType, - // (int)SelectionType, - // true - //); - - /// Besides, the user can hide it using . - - // Stop listening out for callbacks - PlugInIntegration.CallbackFired -= PlugInIntegration_CallbackFired; - PlugInIntegration.ItemStateCheckFired -= PlugInIntegration_EnableMethodFired; } } } diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuItem.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuItem.cs index 6345bdb..2b174ab 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuItem.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextMenuItem.cs @@ -1,73 +1,26 @@ -using SolidWorks.Interop.swconst; -using System; -using System.Collections.Generic; +using System.Collections.Generic; namespace CADBooster.SolidDna { /// - /// A command context menu in SolidWorks + /// A command context menu item /// - public class CommandContextItem : ICommandCreatable + public class CommandContextItem : CommandContextBase, ICommandCreatable { - private bool _isCreated; - #region Public Properties - /// - /// The hint of this command group + /// The name of this command /// public string Name { get; set; } - /// - /// The help text for this item. - /// - public string Hint { get; set; } - - /// - /// True to show this item in the context menu when an assembly is open. - /// - public bool VisibleForAssemblies { get; set; } = true; - - /// - /// True to show this item in the context menu when a drawing is open. - /// - public bool VisibleForDrawings { get; set; } = true; - - /// - /// True to show this item in the context menu when a part is open. - /// - public bool VisibleForParts { get; set; } = true; - - /// - /// The action to call when the item is clicked - /// - public Action OnClick { get; set; } - - /// - /// The action to call when the item state requested - /// - public Action OnStateCheck { get; set; } - - /// - /// The selection type that determines where the context menu will be shown - /// - public swSelectType_e SelectionType { get; set; } = swSelectType_e.swSelEVERYTHING; - - #endregion - /// /// Creates the command context item for the specified document types /// /// The path to use for hierarchical naming. If empty, the item's name is used /// A list of created command context items /// Thrown if the item has already been created - public IEnumerable Create(string path = "") + public sealed override IEnumerable Create(string path = "") { - if (_isCreated) - throw new SolidDnaException( - SolidDnaErrors.CreateError(SolidDnaErrorTypeCode.SolidWorksCommandManager, - SolidDnaErrorCode.SolidWorksCommandContextMenuItemReActivateError)); - - _isCreated = true; + _ = base.Create(path); var fullName = string.IsNullOrEmpty(path) ? $"{Name}" : $"{path}@{Name}"; diff --git a/Tutorials/09-CommandItems/SolidDna.CommandItems/CommandItems.cs b/Tutorials/09-CommandItems/SolidDna.CommandItems/CommandItems.cs index e73cfb2..6df295f 100644 --- a/Tutorials/09-CommandItems/SolidDna.CommandItems/CommandItems.cs +++ b/Tutorials/09-CommandItems/SolidDna.CommandItems/CommandItems.cs @@ -109,6 +109,15 @@ private void CreateMenus() Application.CommandManager.CreateContextMenuItems( [ + new CommandContextIcon + { + Hint = "Icon Hint", + OnClick = () => System.Windows.MessageBox.Show("Context icon clicked"), + OnStateCheck = args => args.Result = CommandManagerItemState.DeselectedEnabled, + // Example only. Use indexed single icon instead. + Icon = imageFormat, + SelectionType = swSelectType_e.swSelCOMPONENTS + }, new CommandContextItem { Name = "RootItem", From f1ff8aaacbcd5e0dd1653309078fe0c55fce9dbf Mon Sep 17 00:00:00 2001 From: GeKtvi <61162497+GeKtvi@users.noreply.github.com> Date: Tue, 24 Jun 2025 20:38:05 +0300 Subject: [PATCH 10/10] Added SelectionType --- .../Item/CommandManagerItemExtensions.cs | 16 +- .../ContextMenuItems/CommandContextBase.cs | 2 +- .../CommandContextCreatedBase.cs | 2 +- .../CommandContextIconCreated.cs | 4 +- .../CommandContextItemCreated.cs | 4 +- .../SelectionManager/SelectionType.cs | 884 ++++++++++++++++++ .../SolidDna.CommandItems/CommandItems.cs | 14 +- .../SolidDna.CommandItems.csproj | 3 + 8 files changed, 913 insertions(+), 16 deletions(-) create mode 100644 SolidDna/CADBooster.SolidDna/SolidWorks/SelectionManager/SelectionType.cs diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerItemExtensions.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerItemExtensions.cs index 8e7930e..cddcb48 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerItemExtensions.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/CommandManagerItemExtensions.cs @@ -17,20 +17,28 @@ public static class CommandManagerItemExtensions /// An optional function to determine the selection type for each item /// A collection of objects public static IEnumerable AsCommandCreatable(this IEnumerable items, - Func selectTypeSelector = null) + Func selectTypeSelector = null) => items.Select(x => x.AsCommandCreatable( selectTypeSelector is null - ? swSelectType_e.swSelEVERYTHING + ? SelectionType.Everything : selectTypeSelector.Invoke(x))); /// /// Converts a single object to an object /// /// The object to convert - /// The selection type for the item (defaults to ) /// An object - public static ICommandCreatable AsCommandCreatable(this CommandManagerItem item, swSelectType_e selectType = swSelectType_e.swSelEVERYTHING) + public static ICommandCreatable AsCommandCreatable(this CommandManagerItem item) + => item.AsCommandCreatable(SelectionType.Everything); + + /// + /// Converts a single object to an object + /// + /// The object to convert + /// The selection type for the item (defaults to ) + /// An object + public static ICommandCreatable AsCommandCreatable(this CommandManagerItem item, SelectionType selectType) => new CommandContextItem() { Name = item.Name, diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextBase.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextBase.cs index 9bef158..d0c3d0e 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextBase.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextBase.cs @@ -48,7 +48,7 @@ public abstract class CommandContextBase /// /// The selection type that determines where the context menu will be shown /// - public swSelectType_e SelectionType { get; set; } = swSelectType_e.swSelEVERYTHING; + public SelectionType SelectionType { get; set; } = SelectionType.Everything; #endregion diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextCreatedBase.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextCreatedBase.cs index cdb6610..6b6c06e 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextCreatedBase.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextCreatedBase.cs @@ -23,7 +23,7 @@ internal abstract class CommandContextCreatedBase : ICommandCreated, ICommandIte /// /// Gets the selection type that determines where this item is shown /// - public swSelectType_e SelectionType { get; } + public SelectionType SelectionType { get; } /// /// Gets the document type (Assembly, Part, or Drawing) for which this item is created diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextIconCreated.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextIconCreated.cs index 7d547a9..1259ea5 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextIconCreated.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextIconCreated.cs @@ -29,12 +29,12 @@ public CommandContextIconCreated(CommandContextIcon commandContextIcon, _ = frame.AddMenuPopupIcon3( (int)DocumentType, - (int)SelectionType, + SelectionType, Hint, SolidWorksEnvironment.Application.SolidWorksCookie, $"{nameof(SolidAddIn.Callback)}({CallbackId})", $"{nameof(SolidAddIn.ItemStateCheck)}({CallbackId})", - string.Empty, + SelectionType.GetCustomFeaturesSelection(), icons); _ = Marshal.ReleaseComObject(frame); diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextItemCreated.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextItemCreated.cs index 0bb1e8f..0a27d4b 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextItemCreated.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CommandManager/Item/ContextMenuItems/CommandContextItemCreated.cs @@ -35,12 +35,12 @@ public CommandContextItemCreated(CommandContextItem commandContextItem, CommandId = AddInIntegration.SolidWorks.UnsafeObject.AddMenuPopupItem3( (int)DocumentType, SolidWorksEnvironment.Application.SolidWorksCookie, - (int)SelectionType, + SelectionType, fullName, $"{nameof(SolidAddIn.Callback)}({CallbackId})", $"{nameof(SolidAddIn.ItemStateCheck)}({CallbackId})", Hint, - string.Empty + SelectionType.GetCustomFeaturesSelection() ); } } diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/SelectionManager/SelectionType.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/SelectionManager/SelectionType.cs new file mode 100644 index 0000000..108a962 --- /dev/null +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/SelectionManager/SelectionType.cs @@ -0,0 +1,884 @@ +using System; + +namespace CADBooster.SolidDna +{ + public class SelectionType + { + #region Static values + + /// + /// Nothing selected. + /// + public static readonly SelectionType Nothing = new SelectionType(0, string.Empty); + + /// + /// Edge selection. + /// + public static readonly SelectionType Edge = new SelectionType(1, "EDGE"); + + /// + /// Face selection. + /// + public static readonly SelectionType Face = new SelectionType(2, "FACE"); + + /// + /// Vertex selection. + /// + public static readonly SelectionType Vertex = new SelectionType(3, "VERTEX"); + + /// + /// Datum plane selection. + /// + public static readonly SelectionType DatumPlane = new SelectionType(4, "PLANE"); + + /// + /// Datum axis selection. + /// + public static readonly SelectionType DatumAxis = new SelectionType(5, "AXIS"); + + /// + /// Datum point selection. + /// + public static readonly SelectionType DatumPoint = new SelectionType(6, "DATUMPOINT"); + + /// + /// OLE item selection. + /// + public static readonly SelectionType OleItem = new SelectionType(7, "OLEITEM"); + + /// + /// Attribute selection. + /// + public static readonly SelectionType Attribute = new SelectionType(8, "ATTRIBUTE"); + + /// + /// Sketch selection. + /// + public static readonly SelectionType Sketch = new SelectionType(9, "SKETCH"); + + /// + /// Sketch segment selection. + /// + public static readonly SelectionType SketchSegment = new SelectionType(10, "SKETCHSEGMENT"); + + /// + /// Sketch point selection. + /// + public static readonly SelectionType SketchPoint = new SelectionType(11, "SKETCHPOINT"); + + /// + /// Drawing view selection. + /// + public static readonly SelectionType DrawingView = new SelectionType(12, "DRAWINGVIEW"); + + /// + /// Geometric tolerance selection. + /// + public static readonly SelectionType GeometricTolerance = new SelectionType(13, "GTOL"); + + /// + /// Dimension selection. + /// + public static readonly SelectionType Dimension = new SelectionType(14, "DIMENSION"); + + /// + /// Note selection. + /// + public static readonly SelectionType Note = new SelectionType(15, "NOTE"); + + /// + /// Section line selection. + /// + public static readonly SelectionType SectionLine = new SelectionType(16, "SECTIONLINE"); + + /// + /// Detail circle selection. + /// + public static readonly SelectionType DetailCircle = new SelectionType(17, "DETAILCIRCLE"); + + /// + /// Section text selection. + /// + public static readonly SelectionType SectionText = new SelectionType(18, "SECTIONTEXT"); + + /// + /// Sheet selection. + /// + public static readonly SelectionType Sheet = new SelectionType(19, "SHEET"); + + /// + /// Component selection. + /// + public static readonly SelectionType Component = new SelectionType(20, "COMPONENT"); + + /// + /// Mate selection. + /// + public static readonly SelectionType Mate = new SelectionType(21, "MATE"); + + /// + /// Body feature selection. + /// + public static readonly SelectionType BodyFeature = new SelectionType(22, "BODYFEATURE"); + + /// + /// Reference curve selection. + /// + public static readonly SelectionType ReferenceCurve = new SelectionType(23, "REFCURVE"); + + /// + /// External sketch segment selection. + /// + public static readonly SelectionType ExternalSketchSegment = new SelectionType(24, "EXTSKETCHSEGMENT"); + + /// + /// External sketch point selection. + /// + public static readonly SelectionType ExternalSketchPoint = new SelectionType(25, "EXTSKETCHPOINT"); + + /// + /// Helix selection. + /// + public static readonly SelectionType Helix = new SelectionType(26, "HELIX"); + + /// + /// Reference surface selection. + /// + public static readonly SelectionType ReferenceSurface = new SelectionType(27, "REFSURFACE"); + + /// + /// Center mark selection. + /// + public static readonly SelectionType CenterMark = new SelectionType(28, "CENTERMARKS"); + + /// + /// In-context feature selection. + /// + public static readonly SelectionType InContextFeature = new SelectionType(29, "INCONTEXTFEAT"); + + /// + /// Mate group selection. + /// + public static readonly SelectionType MateGroup = new SelectionType(30, "MATEGROUP"); + + /// + /// Break line selection. + /// + public static readonly SelectionType BreakLine = new SelectionType(31, "BREAKLINE"); + + /// + /// In-context features selection. + /// + public static readonly SelectionType InContextFeatures = new SelectionType(32, "INCONTEXTFEATS"); + + /// + /// Mate groups selection. + /// + public static readonly SelectionType MateGroups = new SelectionType(33, "MATEGROUPS"); + + /// + /// Sketch text selection. + /// + public static readonly SelectionType SketchText = new SelectionType(34, "SKETCHTEXT"); + + /// + /// SF symbol selection. + /// + public static readonly SelectionType SfSymbol = new SelectionType(35, "SFSYMBOL"); + + /// + /// Datum tag selection. + /// + public static readonly SelectionType DatumTag = new SelectionType(36, "DATUMTAG"); + + /// + /// Component pattern selection. + /// + public static readonly SelectionType ComponentPattern = new SelectionType(37, "COMPPATTERN"); + + /// + /// Weld selection. + /// + public static readonly SelectionType Weld = new SelectionType(38, "WELD"); + + /// + /// Cosmetic thread selection. + /// + public static readonly SelectionType CosmeticThread = new SelectionType(39, "CTHREAD"); + + /// + /// Datum target selection. + /// + public static readonly SelectionType DatumTarget = new SelectionType(40, "DTMTARG"); + + /// + /// Point reference selection. + /// + public static readonly SelectionType PointReference = new SelectionType(41, "POINTREF"); + + /// + /// Cabinet selection. + /// + public static readonly SelectionType Cabinet = new SelectionType(42, "DCABINET"); + + /// + /// Exploded view selection. + /// + public static readonly SelectionType ExplodedView = new SelectionType(43, "EXPLODEDVIEWS"); + + /// + /// Explode step selection. + /// + public static readonly SelectionType ExplodeStep = new SelectionType(44, "EXPLODESTEPS"); + + /// + /// Explode line selection. + /// + public static readonly SelectionType ExplodeLine = new SelectionType(45, "EXPLODELINES"); + + /// + /// Silhouette selection. + /// + public static readonly SelectionType Silhouette = new SelectionType(46, "SILHOUETTE"); + + /// + /// Configuration selection. + /// + public static readonly SelectionType Configuration = new SelectionType(47, "CONFIGURATIONS"); + + /// + /// Object handle selection. + /// + public static readonly SelectionType ObjectHandle = new SelectionType(48, string.Empty); + + /// + /// Arrow selection. + /// + public static readonly SelectionType Arrow = new SelectionType(49, "VIEWARROW"); + + /// + /// Zone selection. + /// + public static readonly SelectionType Zone = new SelectionType(50, "ZONES"); + + /// + /// Reference edge selection. + /// + public static readonly SelectionType ReferenceEdge = new SelectionType(51, "REFERENCE-EDGE"); + + /// + /// Reference face selection. + /// + public static readonly SelectionType ReferenceFace = new SelectionType(52, string.Empty); + + /// + /// Reference silhouette selection. + /// + public static readonly SelectionType ReferenceSilhouette = new SelectionType(53, string.Empty); + + /// + /// BOM selection. + /// + public static readonly SelectionType Bom = new SelectionType(54, "BOM"); + + /// + /// Equation folder selection. + /// + public static readonly SelectionType EquationFolder = new SelectionType(55, "EQNFOLDER"); + + /// + /// Sketch hatch selection. + /// + public static readonly SelectionType SketchHatch = new SelectionType(56, "SKETCHHATCH"); + + /// + /// Import folder selection. + /// + public static readonly SelectionType ImportFolder = new SelectionType(57, "IMPORTFOLDER"); + + /// + /// Viewer hyperlink selection. + /// + public static readonly SelectionType ViewerHyperlink = new SelectionType(58, "HYPERLINK"); + + /// + /// Midpoint selection. + /// + public static readonly SelectionType Midpoint = new SelectionType(59, string.Empty); + + /// + /// Custom symbol selection. + /// + public static readonly SelectionType CustomSymbol = new SelectionType(60, "CUSTOMSYMBOL"); + + /// + /// Coordinate system selection. + /// + public static readonly SelectionType CoordinateSystem = new SelectionType(61, "COORDSYS"); + + /// + /// Datum line selection. + /// + public static readonly SelectionType DatumLine = new SelectionType(62, "REFLINE"); + + /// + /// Route curve selection. + /// + public static readonly SelectionType RouteCurve = new SelectionType(63, string.Empty); + + /// + /// BOM template selection. + /// + public static readonly SelectionType BomTemplate = new SelectionType(64, "BOMTEMP"); + + /// + /// Route point selection. + /// + public static readonly SelectionType RoutePoint = new SelectionType(65, "ROUTEPOINT"); + + /// + /// Connection point selection. + /// + public static readonly SelectionType ConnectionPoint = new SelectionType(66, "CONNECTIONPOINT"); + + /// + /// Route sweep selection. + /// + public static readonly SelectionType RouteSweep = new SelectionType(67, string.Empty); + + /// + /// Position group selection. + /// + public static readonly SelectionType PositionGroup = new SelectionType(68, "POSGROUP"); + + /// + /// Browser item selection. + /// + public static readonly SelectionType BrowserItem = new SelectionType(69, "BROWSERITEM"); + + /// + /// Fabricated route selection. + /// + public static readonly SelectionType FabricatedRoute = new SelectionType(70, "ROUTEFABRICATED"); + + /// + /// Sketch point feature selection. + /// + public static readonly SelectionType SketchPointFeature = new SelectionType(71, "SKETCHPOINTFEAT"); + + /// + /// Component don't override selection. + /// + public static readonly SelectionType ComponentDontOverride = new SelectionType(72, string.Empty); + + /// + /// Light selection. + /// + public static readonly SelectionType Light = new SelectionType(73, "LIGHTS"); + + /// + /// Wire body selection. + /// + public static readonly SelectionType WireBody = new SelectionType(74, string.Empty); + + /// + /// Surface body selection. + /// + public static readonly SelectionType SurfaceBody = new SelectionType(75, "SURFACEBODY"); + + /// + /// Solid body selection. + /// + public static readonly SelectionType SolidBody = new SelectionType(76, "SOLIDBODY"); + + /// + /// Frame point selection. + /// + public static readonly SelectionType FramePoint = new SelectionType(77, "FRAMEPOINT"); + + /// + /// Surface body first selection. + /// + public static readonly SelectionType SurfaceBodyFirst = new SelectionType(78, string.Empty); + + /// + /// Manipulator selection. + /// + public static readonly SelectionType Manipulator = new SelectionType(79, "MANIPULATOR"); + + /// + /// Picture body selection. + /// + public static readonly SelectionType PictureBody = new SelectionType(80, "PICTURE BODY"); + + /// + /// Solid body first selection. + /// + public static readonly SelectionType SolidBodyFirst = new SelectionType(81, string.Empty); + + /// + /// Hole series selection. + /// + public static readonly SelectionType HoleSeries = new SelectionType(83, "HOLESERIES"); + + /// + /// Leader selection. + /// + public static readonly SelectionType Leader = new SelectionType(84, "LEADER"); + + /// + /// Sketch bitmap selection. + /// + public static readonly SelectionType SketchBitmap = new SelectionType(85, "SKETCHBITMAP"); + + /// + /// Dowel symbol selection. + /// + public static readonly SelectionType DowelSymbol = new SelectionType(86, "DOWLELSYM"); + + /// + /// External sketch text selection. + /// + public static readonly SelectionType ExternalSketchText = new SelectionType(88, "EXTSKETCHTEXT"); + + /// + /// Block instance selection. + /// + public static readonly SelectionType BlockInstance = new SelectionType(93, "BLOCKINST"); + + /// + /// Feature folder selection. + /// + public static readonly SelectionType FeatureFolder = new SelectionType(94, "FTRFOLDER"); + + /// + /// Sketch region selection. + /// + public static readonly SelectionType SketchRegion = new SelectionType(95, "SKETCHREGION"); + + /// + /// Sketch contour selection. + /// + public static readonly SelectionType SketchContour = new SelectionType(96, "SKETCHCONTOUR"); + + /// + /// BOM feature selection. + /// + public static readonly SelectionType BomFeature = new SelectionType(97, "BOMFEATURE"); + + /// + /// Annotation table selection. + /// + public static readonly SelectionType AnnotationTable = new SelectionType(98, "ANNOTATIONTABLES"); + + /// + /// Block definition selection. + /// + public static readonly SelectionType BlockDefinition = new SelectionType(99, "BLOCKDEF"); + + /// + /// Center mark symbol selection. + /// + public static readonly SelectionType CenterMarkSymbol = new SelectionType(100, "CENTERMARKSYMS"); + + /// + /// Simulation selection. + /// + public static readonly SelectionType Simulation = new SelectionType(101, "SIMULATION"); + + /// + /// Simulation element selection. + /// + public static readonly SelectionType SimulationElement = new SelectionType(102, "SIMULATION_ELEMENT"); + + /// + /// Center line selection. + /// + public static readonly SelectionType CenterLine = new SelectionType(103, "CENTERLINE"); + + /// + /// Hole table feature selection. + /// + public static readonly SelectionType HoleTableFeature = new SelectionType(104, "HOLETABLE"); + + /// + /// Hole table axis selection. + /// + public static readonly SelectionType HoleTableAxis = new SelectionType(105, "HOLETABLEAXIS"); + + /// + /// Weldment selection. + /// + public static readonly SelectionType Weldment = new SelectionType(106, "WELDMENT"); + + /// + /// Sub weld folder selection. + /// + public static readonly SelectionType SubWeldFolder = new SelectionType(107, "SUBWELDMENT"); + + /// + /// Exclude manipulator selection. + /// + public static readonly SelectionType ExcludeManipulator = new SelectionType(111, string.Empty); + + /// + /// Sub-sketch instance selection. + /// + public static readonly SelectionType SubSketchInstance = new SelectionType(114, "SUBSKETCHINST"); + + /// + /// Weldment table feature selection. + /// + public static readonly SelectionType WeldmentTableFeature = new SelectionType(116, "WELDMENTTABLE"); + + /// + /// Body folder selection. + /// + public static readonly SelectionType BodyFolder = new SelectionType(118, "BDYFOLDER"); + + /// + /// Revision table feature selection. + /// + public static readonly SelectionType RevisionTableFeature = new SelectionType(119, "REVISIONTABLEFEAT"); + + /// + /// Sub-atom folder selection. + /// + public static readonly SelectionType SubAtomFolder = new SelectionType(121, string.Empty); + + /// + /// Weld bead selection. + /// + public static readonly SelectionType WeldBead = new SelectionType(122, "WELDBEADS"); + + /// + /// Embed link document selection. + /// + public static readonly SelectionType EmbedLinkDoc = new SelectionType(123, "EMBEDLINKDOC"); + + /// + /// Journal selection. + /// + public static readonly SelectionType Journal = new SelectionType(124, "JOURNAL"); + + /// + /// Documents folder selection. + /// + public static readonly SelectionType DocsFolder = new SelectionType(125, "DOCSFOLDER"); + + /// + /// Comments folder selection. + /// + public static readonly SelectionType CommentsFolder = new SelectionType(126, "COMMENTSFOLDER"); + + /// + /// Comment selection. + /// + public static readonly SelectionType Comment = new SelectionType(127, "COMMENT"); + + /// + /// Swift annotation selection. + /// + public static readonly SelectionType SwiftAnnotation = new SelectionType(130, "SWIFTANN"); + + /// + /// Swift feature selection. + /// + public static readonly SelectionType SwiftFeature = new SelectionType(132, "SWIFTFEATURE"); + + /// + /// Camera selection. + /// + public static readonly SelectionType Camera = new SelectionType(136, "CAMERAS"); + + /// + /// Mate supplement selection. + /// + public static readonly SelectionType MateSupplement = new SelectionType(138, "MATESUPPLEMENT"); + + /// + /// Annotation view selection. + /// + public static readonly SelectionType AnnotationView = new SelectionType(139, "ANNVIEW"); + + /// + /// General table feature selection. + /// + public static readonly SelectionType GeneralTableFeature = new SelectionType(142, "GENERALTABLEFEAT"); + + /// + /// Sub-sketch definition selection. + /// + public static readonly SelectionType SubSketchDefinition = new SelectionType(154, "SUBSKETCHDEF"); + + /// + /// Object group selection. + /// + public static readonly SelectionType ObjectGroup = new SelectionType(155, "OBJGROUP"); + + /// + /// Swift schema selection. + /// + public static readonly SelectionType SwiftSchema = new SelectionType(159, "SWIFTSCHEMA"); + + /// + /// Title block selection. + /// + public static readonly SelectionType TitleBlock = new SelectionType(192, "TITLEBLOCK"); + + /// + /// Title block table feature selection. + /// + public static readonly SelectionType TitleBlockTableFeature = new SelectionType(206, "TITLEBLOCKTABLEFEAT"); + + /// + /// Cosmetic weld selection. + /// + public static readonly SelectionType CosmeticWeld = new SelectionType(220, "COSMETICWELDS"); + + /// + /// Magnetic line selection. + /// + public static readonly SelectionType MagneticLine = new SelectionType(225, "MAGNETICLINES"); + + /// + /// Punch table feature selection. + /// + public static readonly SelectionType PunchTableFeature = new SelectionType(234, "PUNCHTABLE"); + + /// + /// Revision cloud selection. + /// + public static readonly SelectionType RevisionCloud = new SelectionType(240, string.Empty); + + /// + /// Selection set folder selection. + /// + public static readonly SelectionType SelectionSetFolder = new SelectionType(258, "SELECTIONSETFOLDER"); + + /// + /// Selection set node selection. + /// + public static readonly SelectionType SelectionSetNode = new SelectionType(259, "SUBSELECTIONSETNODE"); + + /// + /// Graphics body selection. + /// + public static readonly SelectionType GraphicsBody = new SelectionType(262, "MESH BODY FEATURE"); + + /// + /// Facet selection. + /// + public static readonly SelectionType Facet = new SelectionType(268, "MESHFACETREF"); + + /// + /// Mesh facet edge selection. + /// + public static readonly SelectionType MeshFacetEdge = new SelectionType(269, "MESHFINREF"); + + /// + /// Mesh facet vertex selection. + /// + public static readonly SelectionType MeshFacetVertex = new SelectionType(270, "MESHVERTEXREF"); + + /// + /// Mesh solid body selection. + /// + public static readonly SelectionType MeshSolidBody = new SelectionType(274, "MSOLIDBODY"); + + /// + /// Belt chain feature selection. + /// + public static readonly SelectionType BeltChainFeature = new SelectionType(149, "SKETCHBELT"); + + /// + /// Advanced structure member selection. + /// + public static readonly SelectionType AdvStructMember = new SelectionType(295, "ADVSTRUCTMEMBER"); + + /// + /// Everything selection. + /// + public static readonly SelectionType Everything = new SelectionType(-3, "EVERYTHING"); + + /// + /// Location selection. + /// + public static readonly SelectionType Location = new SelectionType(-2, "LOCATIONS"); + + /// + /// Unsupported selection. + /// + public static readonly SelectionType Unsupported = new SelectionType(-1, "UNSUPPORTED"); + + #endregion + + private readonly int _intValue; + private readonly string _stringValue; + private readonly string[] _customFeatureNames; + + /// + /// Internal constructor for predefined selection types. + /// Initializes a new with the specified integer and string values. + /// + /// The numeric identifier for the selection type. + /// The string representation used in the SOLIDWORKS API. + /// + /// Custom feature types should use instead. + /// + internal SelectionType(int intValue, string stringValue) + { + _intValue = intValue; + _stringValue = stringValue; + _customFeatureNames = null; + } + + /// + /// Internal constructor for custom feature selection types. + /// Initializes a new with custom feature names. + /// + /// An array of custom feature names. + /// + /// This constructor is used for user-defined selection types not covered by the standard enum. + /// The integer value is set to as a default for custom types. + /// + internal SelectionType(SelectionType baseType, string[] customFeatureNames) + { + _intValue = baseType; + _stringValue = baseType; + _customFeatureNames = customFeatureNames; + } + + /// + /// Creates a new for a single custom feature. + /// + /// The name of the custom feature. + /// A new instance. + /// + /// var weldBeadType = SelectionType.CreateCustomFeatureType("MyAwesomeFeature"); + /// + /// + /// Can be used with + /// + public static SelectionType CreateCustomFeatureType(SelectionType baseType, string featureName) + => new SelectionType(baseType, new[] { featureName }); + + /// + /// Creates a new for multiple custom features. + /// + /// An array of custom feature names. + /// A new instance. + /// + /// var customTypes = SelectionType.CreateCustomFeatureType(new[] { "MyAwesomeFeature1", "MyAwesomeFeature2" }); + /// + /// + /// Can be used with + /// + public static SelectionType CreateCustomFeatureType(SelectionType baseType, string[] featureNames) + => new SelectionType(baseType, featureNames); + + /// + /// Gets a semicolon-separated string of custom feature names (if applicable). + /// + /// + /// A combined string of custom feature names, or if this is not a custom type. + /// + /// + /// Used internally for SOLIDWORKS API calls that require multiple selection identifiers. + /// + internal string GetCustomFeaturesSelection() + => _customFeatureNames is null ? string.Empty : string.Join(";", _customFeatureNames); + + /// + /// Implicitly converts a to its integer value. + /// + /// The to convert. + /// The underlying integer value. + /// + /// Allows seamless use of where an integer is expected (e.g., API calls). + /// + public static implicit operator int(SelectionType selectionType) + { + return selectionType._intValue; + } + + /// + /// Implicitly converts a to its string representation. + /// + /// The to convert. + /// + /// The underlying string value, or for custom types. + /// + /// + /// Allows seamless use of where a string is expected (e.g., API calls). + /// + public static implicit operator string(SelectionType selectionType) + { + return selectionType._stringValue; + } + + /// + /// Determines whether the specified object is equal to the current SelectionType. + /// + /// The object to compare with the current object + /// true if the objects are considered equal; otherwise, false + public override bool Equals(object obj) + { + // Null and type check + if (obj == null || GetType() != obj.GetType()) + return false; + + var other = (SelectionType)obj; + + // Compare primitive values first for early exit + if (_intValue != other._intValue) + return false; + + // String comparison for _stringValue not used it depends on _intValue + + // Handle null cases for custom feature names + if (_customFeatureNames == null || other._customFeatureNames == null) + return _customFeatureNames == null && other._customFeatureNames == null; + + // Compare array lengths first for quick mismatch detection + if (_customFeatureNames.Length != other._customFeatureNames.Length) + return false; + + // Element-by-element comparison + for (var i = 0; i < _customFeatureNames.Length; i++) + { + if (!string.Equals(_customFeatureNames[i], other._customFeatureNames[i], StringComparison.Ordinal)) + return false; + } + + return true; + } + + /// + /// Serves as the default hash function for SelectionType. + /// + /// A hash code for the current object + public override int GetHashCode() + { + unchecked + { + if (_customFeatureNames is null) + { + // Handless only _intValue if no custom features, _stringValue check not needed + return _intValue.GetHashCode(); + } + else + { + // Handless _intValue and custom features array if has custom features, _stringValue check not needed + var hashCode = 0; + for (var i = 0; i < _customFeatureNames.Length; i++) + { + hashCode += _customFeatureNames[i].GetHashCode() * 17; + } + hashCode += _intValue.GetHashCode(); + return hashCode; + } + } + } + } +} diff --git a/Tutorials/09-CommandItems/SolidDna.CommandItems/CommandItems.cs b/Tutorials/09-CommandItems/SolidDna.CommandItems/CommandItems.cs index 6df295f..4980e76 100644 --- a/Tutorials/09-CommandItems/SolidDna.CommandItems/CommandItems.cs +++ b/Tutorials/09-CommandItems/SolidDna.CommandItems/CommandItems.cs @@ -1,8 +1,10 @@ using CADBooster.SolidDna; +using SolidWorks.Interop.sldworks; using SolidWorks.Interop.swconst; using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using static CADBooster.SolidDna.SolidWorksEnvironment; @@ -116,7 +118,7 @@ private void CreateMenus() OnStateCheck = args => args.Result = CommandManagerItemState.DeselectedEnabled, // Example only. Use indexed single icon instead. Icon = imageFormat, - SelectionType = swSelectType_e.swSelCOMPONENTS + SelectionType = SelectionType.InContextFeatures }, new CommandContextItem { @@ -124,20 +126,20 @@ private void CreateMenus() Hint = "RootItem Hint", OnClick = onContextMenuItemClick, OnStateCheck = args => args.Result = CommandManagerItemState.SelectedEnabled, - SelectionType = swSelectType_e.swSelCOMPONENTS + SelectionType = SelectionType.Component }, new CommandContextMenuGroup { Name = "RootGroup", Items = [.. - CreateCommandItems().AsCommandCreatable(x => swSelectType_e.swSelCOMPONENTS), + CreateCommandItems().AsCommandCreatable(x => SelectionType.Component), new CommandContextItem { Name = "PlaneItem", Hint = "PlaneItem Hint", OnClick = onContextMenuItemClick, - SelectionType = swSelectType_e.swSelDATUMPLANES + SelectionType = SelectionType.DatumPlane }, new CommandContextMenuGroup { @@ -149,7 +151,7 @@ private void CreateMenus() Name = "SubSubItem", Hint = "SubSubItem Hint", OnClick = onContextMenuItemClick, - SelectionType = swSelectType_e.swSelCOMPONENTS + SelectionType = SelectionType.Component }, new CommandContextMenuGroup { @@ -161,7 +163,7 @@ private void CreateMenus() Name = "SubSubSubItem", Hint = "SubSubSubItem Hint", OnClick = onContextMenuItemClick, - SelectionType = swSelectType_e.swSelCOMPONENTS + SelectionType = SelectionType.Component } ] }, diff --git a/Tutorials/09-CommandItems/SolidDna.CommandItems/SolidDna.CommandItems.csproj b/Tutorials/09-CommandItems/SolidDna.CommandItems/SolidDna.CommandItems.csproj index 63ae6e7..c0be980 100644 --- a/Tutorials/09-CommandItems/SolidDna.CommandItems/SolidDna.CommandItems.csproj +++ b/Tutorials/09-CommandItems/SolidDna.CommandItems/SolidDna.CommandItems.csproj @@ -31,4 +31,7 @@ + + + \ No newline at end of file