From 45d53b7a89c8d24deb530b89e6a3d90ca7510967 Mon Sep 17 00:00:00 2001 From: shichuyibushishiwu <49446319+shichuyibushishiwu@users.noreply.github.com> Date: Mon, 1 Jul 2024 23:01:23 +0800 Subject: [PATCH 1/6] Update TestCommand.cs --- src/TestCommand.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/TestCommand.cs b/src/TestCommand.cs index 79ed723..b30190e 100644 --- a/src/TestCommand.cs +++ b/src/TestCommand.cs @@ -22,17 +22,17 @@ public Result Execute(ExternalCommandData commandData, ref string message, Eleme { UIDocument uiDocument = commandData.Application.ActiveUIDocument; Document document = uiDocument.Document; - + long id = 2312; var result = uiDocument.SelectObjects(Autodesk.Revit.UI.Selection.ObjectType.Element, prompt: "asd", pPreSelected: new List() { - new Reference(document.GetElement(new ElementId(2312))) - }); + new Reference(document.GetElement(new ElementId(id))) + }); ; if (result.SelectionStatus == SelectionStatus.Succeeded) { foreach (var item in result.Value) { - + } } From 0deb60d1593788e19034a6200910057db35ca70e Mon Sep 17 00:00:00 2001 From: shichuyibushishiwu <49446319+shichuyibushishiwu@users.noreply.github.com> Date: Tue, 2 Jul 2024 10:07:34 +0800 Subject: [PATCH 2/6] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5f4c5b2..abae3a3 100644 --- a/README.md +++ b/README.md @@ -24,11 +24,12 @@ Welcome to the Tuna.Revit.Extensions wiki! This is an extension package for revi * Revit 2022 * Revit 2023 * Revit 2024 +* Revit 2025 # Install ``` - > dotnet add package Tuna.Revit.Extension --version 2021.0.0 + > dotnet add package Tuna.Revit.Extension --version 2025.0.17 ``` From 4484c2919582173b19c5dd9d6c9a71d6eff8cb28 Mon Sep 17 00:00:00 2001 From: shichuyibushishiwu <49446319+shichuyibushishiwu@users.noreply.github.com> Date: Tue, 2 Jul 2024 10:09:49 +0800 Subject: [PATCH 3/6] Update Tuna.Revit.Build.props --- Tuna.Revit.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tuna.Revit.Build.props b/Tuna.Revit.Build.props index f70ee0d..45a93b8 100644 --- a/Tuna.Revit.Build.props +++ b/Tuna.Revit.Build.props @@ -13,7 +13,7 @@ Rvt_24_Debug;Rvt_24_Release; Rvt_25_Debug;Rvt_25_Release; - 15 + 17 x64 preview From bf34b3d8287cb4a5d472c7c4da8afe36561a1ce1 Mon Sep 17 00:00:00 2001 From: shichuyibushishiwu <49446319+shichuyibushishiwu@users.noreply.github.com> Date: Tue, 2 Jul 2024 10:10:56 +0800 Subject: [PATCH 4/6] Update LICENSE --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index fb12733..5983019 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 Shiwu +Copyright (c) 2024 ITuna Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 5c0e86663f8980f22f9f613a1394e751bb74f4bc Mon Sep 17 00:00:00 2001 From: shichuyibushishiwu <49446319+shichuyibushishiwu@users.noreply.github.com> Date: Wed, 10 Jul 2024 21:51:35 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E6=B2=A1=E5=8A=A0=E8=BD=BD=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sample/Tuna.Sample/Tuna.Sample.csproj | 4 ++-- src/Ribbon/Abstraction/IRibbonComboBox.cs | 2 +- src/Ribbon/Abstraction/IRibbonPanel.cs | 16 +++++++++++----- src/Ribbon/Abstraction/IRibbonStackedPanel.cs | 16 +++++++++++++++- src/Ribbon/Proxy/RibbonComboBoxProxy.cs | 3 ++- src/Ribbon/Proxy/RibbonPanelProxy.cs | 4 ++-- src/Ribbon/Proxy/RibbonTabProxy.cs | 2 ++ src/Ribbon/RibbonExtension.cs | 4 ++-- src/Ribbon/UIExtension.cs | 9 ++++++--- src/TestCommand.cs | 2 +- 10 files changed, 44 insertions(+), 18 deletions(-) diff --git a/sample/Tuna.Sample/Tuna.Sample.csproj b/sample/Tuna.Sample/Tuna.Sample.csproj index a2a6798..f84aa3d 100644 --- a/sample/Tuna.Sample/Tuna.Sample.csproj +++ b/sample/Tuna.Sample/Tuna.Sample.csproj @@ -115,12 +115,12 @@ 2025.0.$(TunaVer) - + diff --git a/src/Ribbon/Abstraction/IRibbonComboBox.cs b/src/Ribbon/Abstraction/IRibbonComboBox.cs index a0a669c..71c7cda 100644 --- a/src/Ribbon/Abstraction/IRibbonComboBox.cs +++ b/src/Ribbon/Abstraction/IRibbonComboBox.cs @@ -8,7 +8,7 @@ namespace Tuna.Revit.Extension; /// -/// +/// 下拉选项 /// public interface IRibbonComboBox : IRibbonItem { diff --git a/src/Ribbon/Abstraction/IRibbonPanel.cs b/src/Ribbon/Abstraction/IRibbonPanel.cs index 225ac3a..294f7dc 100644 --- a/src/Ribbon/Abstraction/IRibbonPanel.cs +++ b/src/Ribbon/Abstraction/IRibbonPanel.cs @@ -29,7 +29,7 @@ public interface IRibbonPanel : IRibbonPushButtonContainer /// /// /// - /// + /// 当前面板 IRibbonPanel AddPulldownButton(string title, Action handle = null); /// @@ -37,24 +37,30 @@ public interface IRibbonPanel : IRibbonPushButtonContainer /// /// /// - /// + /// 当前面板 IRibbonPanel AddSplitButton(string title, Action handle = null); + /// + /// 添加堆叠式按钮 + /// + /// 当前面板 + //IRibbonPanel AddStackPanel(Action handle = null); + /// /// 添加单选框按钮组 /// - /// + /// 当前面板 IRibbonPanel AddRadioButtonGroup(); /// /// 添加文本输入框 /// - /// + /// 当前面板 IRibbonPanel AddTextBox(); /// /// 添加下拉框 /// - /// + /// 当前面板 IRibbonPanel AddComboBox(string name, Action handle = null); } diff --git a/src/Ribbon/Abstraction/IRibbonStackedPanel.cs b/src/Ribbon/Abstraction/IRibbonStackedPanel.cs index c3785e8..c91b224 100644 --- a/src/Ribbon/Abstraction/IRibbonStackedPanel.cs +++ b/src/Ribbon/Abstraction/IRibbonStackedPanel.cs @@ -6,9 +6,23 @@ namespace Tuna.Revit.Extension; -internal interface IRibbonStackedPanel +/// +/// 堆叠式面板 +/// +public interface IRibbonStackedPanel { + /// + /// + /// + /// + /// + /// public void AddPushButton(); + /// + /// + /// + /// + /// public void AddPushButton(); } diff --git a/src/Ribbon/Proxy/RibbonComboBoxProxy.cs b/src/Ribbon/Proxy/RibbonComboBoxProxy.cs index 19a8efa..b8862a3 100644 --- a/src/Ribbon/Proxy/RibbonComboBoxProxy.cs +++ b/src/Ribbon/Proxy/RibbonComboBoxProxy.cs @@ -14,8 +14,9 @@ internal class RibbonComboBoxProxy : RibbonElementProxy, IRibbonComboB public string Name { get; set; } - public RibbonComboBoxProxy() + public RibbonComboBoxProxy(ComboBox comboBox) { + this.OriginalObject = comboBox; this.OriginalObject.CurrentChanged += OriginalObject_CurrentChanged; } diff --git a/src/Ribbon/Proxy/RibbonPanelProxy.cs b/src/Ribbon/Proxy/RibbonPanelProxy.cs index 83a0a4b..2083710 100644 --- a/src/Ribbon/Proxy/RibbonPanelProxy.cs +++ b/src/Ribbon/Proxy/RibbonPanelProxy.cs @@ -35,6 +35,7 @@ public IRibbonPanel AddSeparator() RibbonButton ribbonButton = this.OriginalObject.CreatePushButton(btn => UIExtension.SetPushButtonData(btn, ribbonButtonProxy.RibbonButtonData)); + ribbonButtonProxy.OriginalObject = ribbonButton; ribbonButtonProxy.Title = ribbonButton.ItemText; ribbonButtonProxy.Name = ribbonButton.Name; @@ -80,9 +81,8 @@ public IRibbonPanel AddComboBox(string name, Action handle = nu { ComboBox comboBox = this.OriginalObject.CreateComboBox(name); - RibbonComboBoxProxy comboBoxProxy = new() + RibbonComboBoxProxy comboBoxProxy = new(comboBox) { - OriginalObject = comboBox, Title = comboBox.Name, }; diff --git a/src/Ribbon/Proxy/RibbonTabProxy.cs b/src/Ribbon/Proxy/RibbonTabProxy.cs index 81ccac8..5ecc634 100644 --- a/src/Ribbon/Proxy/RibbonTabProxy.cs +++ b/src/Ribbon/Proxy/RibbonTabProxy.cs @@ -25,6 +25,8 @@ public IRibbonPanel AddRibbonPanel(string name, Action handle) _items.Add(ribbonPanelProxy); + handle.Invoke(ribbonPanelProxy); + return ribbonPanelProxy; } diff --git a/src/Ribbon/RibbonExtension.cs b/src/Ribbon/RibbonExtension.cs index f201f32..b664673 100644 --- a/src/Ribbon/RibbonExtension.cs +++ b/src/Ribbon/RibbonExtension.cs @@ -74,9 +74,9 @@ public static IRibbonTab AddRibbonTab(this UIControlledApplication application, ribbonHost.Assembly = Assembly.GetCallingAssembly(); ribbonHost.UIApplication = GetUIApplication(application); ribbonHost.UIControlledApplication = application; - + return ribbonHost.UIApplication.AddRibbonTab(title); } - + } diff --git a/src/Ribbon/UIExtension.cs b/src/Ribbon/UIExtension.cs index 01bef19..c680f67 100644 --- a/src/Ribbon/UIExtension.cs +++ b/src/Ribbon/UIExtension.cs @@ -116,7 +116,7 @@ public static PulldownButton CreatePulldownButton(this RibbonPanel panel, string } /// - /// 在面板上创建一个下拉按钮 + /// 在面板上创建一个下拉式按钮 /// /// /// @@ -156,9 +156,10 @@ public static ComboBox CreateComboBox(this RibbonPanel panel, string name, Actio return panel.AddItem(combo) as ComboBox; } + /// - /// + /// 创建按压式按钮 /// /// /// @@ -172,7 +173,7 @@ public static ComboBox CreateComboBox(this RibbonPanel panel, string name, Actio } /// - /// + /// 创建按压式按钮 /// /// /// @@ -184,4 +185,6 @@ internal static PushButton CreatePushButton(this PulldownButton pulldownButton, return pulldownButton.AddPushButton(CreatePushButtonData(handle, type)); } + + } diff --git a/src/TestCommand.cs b/src/TestCommand.cs index b30190e..693bf58 100644 --- a/src/TestCommand.cs +++ b/src/TestCommand.cs @@ -25,7 +25,7 @@ public Result Execute(ExternalCommandData commandData, ref string message, Eleme long id = 2312; var result = uiDocument.SelectObjects(Autodesk.Revit.UI.Selection.ObjectType.Element, prompt: "asd", pPreSelected: new List() { - new Reference(document.GetElement(new ElementId(id))) + //new Reference(document.GetElement(new ElementId(id))) }); ; if (result.SelectionStatus == SelectionStatus.Succeeded) From b4c13d4792c592d57a74a193816e46153f7bd349 Mon Sep 17 00:00:00 2001 From: shichuyibushishiwu <49446319+shichuyibushishiwu@users.noreply.github.com> Date: Thu, 11 Jul 2024 21:46:21 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sample/Tuna.Sample/App.cs | 45 ++++----- sample/Tuna.Sample/Commands/CommandA.cs | 2 - .../ParameterFilterRuleFactoryExtension.cs | 2 +- ...bbonHost.cs => RevitApplicationContext.cs} | 26 ++++- src/RevitApplicationEvent.cs | 97 +++++++++++++++++++ src/Ribbon/Abstraction/IRibbonComboBox.cs | 6 +- src/Ribbon/Abstraction/IRibbonTab.cs | 9 +- src/Ribbon/Proxy/RibbonButtonDescriptor.cs | 60 ++++++++++++ src/Ribbon/Proxy/RibbonPanelProxy.cs | 23 +++-- src/Ribbon/Proxy/RibbonPulldownButtonProxy.cs | 25 +++-- src/Ribbon/Proxy/RibbonTabProxy.cs | 5 + src/Ribbon/RibbonExtension.cs | 8 +- src/Ribbon/RibbonImageResovler.cs | 6 +- src/Ribbon/UIExtension.cs | 83 ++++++++-------- src/Selection/SelectionChangedEventArgs.cs | 38 ++++++++ src/Tuna.Revit.Extension.csproj | 24 ++--- 16 files changed, 347 insertions(+), 112 deletions(-) rename src/{Ribbon/RibbonHost.cs => RevitApplicationContext.cs} (53%) create mode 100644 src/RevitApplicationEvent.cs create mode 100644 src/Ribbon/Proxy/RibbonButtonDescriptor.cs create mode 100644 src/Selection/SelectionChangedEventArgs.cs diff --git a/sample/Tuna.Sample/App.cs b/sample/Tuna.Sample/App.cs index e949a07..8195940 100644 --- a/sample/Tuna.Sample/App.cs +++ b/sample/Tuna.Sample/App.cs @@ -26,29 +26,30 @@ public Result OnShutdown(UIControlledApplication application) public Result OnStartup(UIControlledApplication application) { - var tab = application.AddRibbonTab("tuna") - .AddRibbonPanel("archi", panel => - { - panel.AddPushButton() - .AddSeparator() - .AddPulldownButton("pdb", pbt => pbt - .AddPushButton() - .AddSeparator() - .AddPushButton() - .Configurate(d => - { - d.LargeImage = "compass.png"; - })) - .AddSplitButton("stb", slt => slt - .AddPushButton() - .AddSeparator() - .AddPushButton()) - .AddComboBox("s", cb => cb.AddItem("dd").AddItem("ssad").OnSelectedChanged(e => - { + var tab = application.AddRibbonTab("tuna"); - })) - .AddSlideOut(); - }); + tab.AddRibbonPanel("archi", panel => + { + panel.AddPushButton() + .AddSeparator() + .AddPulldownButton("pdb", pbt => pbt + .AddPushButton() + .AddSeparator() + .AddPushButton() + .Configurate(d => + { + d.LargeImage = "compass.png"; + })) + .AddSplitButton("stb", slt => slt + .AddPushButton() + .AddSeparator() + .AddPushButton()) + .AddComboBox("s", cb => cb.AddItem("dd").AddItem("ssad").OnSelectedChanged(e => + { + + })) + .AddSlideOut(); + }); return Result.Succeeded; } diff --git a/sample/Tuna.Sample/Commands/CommandA.cs b/sample/Tuna.Sample/Commands/CommandA.cs index 408685c..3a20505 100644 --- a/sample/Tuna.Sample/Commands/CommandA.cs +++ b/sample/Tuna.Sample/Commands/CommandA.cs @@ -40,8 +40,6 @@ internal class CommandB : IExternalCommand { public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { - - TaskDialog.Show("msg", "B"); return Result.Succeeded; } diff --git a/src/Extensions/ParameterFilterRuleFactoryExtension.cs b/src/Extensions/ParameterFilterRuleFactoryExtension.cs index 984f160..78f6def 100644 --- a/src/Extensions/ParameterFilterRuleFactoryExtension.cs +++ b/src/Extensions/ParameterFilterRuleFactoryExtension.cs @@ -31,7 +31,7 @@ public static class ParameterFilterRuleFactoryExtension /// public static FilterRule CreateEqualsRule(ElementId id, string name, bool caseSensitive = false) { -#if Rvt_23||Rvt_24 +#if Rvt_23||Rvt_24||Rvt_25 return ParameterFilterRuleFactory.CreateEqualsRule(id, name); #else return ParameterFilterRuleFactory.CreateEqualsRule(id, name, caseSensitive); diff --git a/src/Ribbon/RibbonHost.cs b/src/RevitApplicationContext.cs similarity index 53% rename from src/Ribbon/RibbonHost.cs rename to src/RevitApplicationContext.cs index 0752c94..5ed2305 100644 --- a/src/Ribbon/RibbonHost.cs +++ b/src/RevitApplicationContext.cs @@ -9,7 +9,10 @@ namespace Tuna.Revit.Extension; -internal class RibbonHost +/// +/// 应用程序上下文 +/// +public class RevitApplicationContext { private Assembly _assembly; private bool _isValid; @@ -17,10 +20,13 @@ internal class RibbonHost /// /// 默认值 /// - public static RibbonHost Default { get; } = new RibbonHost(); + public static RevitApplicationContext Instance { get; } = new RevitApplicationContext(); - RibbonHost() { } + RevitApplicationContext() { } + /// + /// 当前加载的插件的程序集 + /// public Assembly Assembly { get => _assembly; @@ -30,16 +36,28 @@ internal set { _assembly = value; _isValid = true; - InstallPath = $"{Directory.GetParent(_assembly?.Location).FullName}//Assets//Icon"; + InstallPath = @$"{Directory.GetParent(_assembly?.Location).FullName}\Assets\Icon"; } } } + /// + /// Revit 实例 + /// public UIControlledApplication UIControlledApplication { get; internal set; } + /// + /// Revit 实例 + /// public UIApplication UIApplication { get; internal set; } + /// + /// 上下文是否有效 + /// public bool IsVaild => _isValid; + /// + /// 当前加载的插件的安装位置 + /// public string InstallPath { get; set; } } diff --git a/src/RevitApplicationEvent.cs b/src/RevitApplicationEvent.cs new file mode 100644 index 0000000..7fd7ba1 --- /dev/null +++ b/src/RevitApplicationEvent.cs @@ -0,0 +1,97 @@ +using Autodesk.Revit.ApplicationServices; +using Autodesk.Revit.UI; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tuna.Revit.Extension; + +/// +/// Revit application events +/// +public class RevitApplicationEvent +{ + private readonly UIControlledApplication _application; + + /// + /// Initialize revit application event + /// + /// + public RevitApplicationEvent(UIControlledApplication uIControlledApplication) + { + _application = uIControlledApplication; + uIControlledApplication.ApplicationClosing += UIControlledApplication_ApplicationClosing; + uIControlledApplication.ControlledApplication.ApplicationInitialized += ControlledApplication_ApplicationInitialized; + + +#if !Rvt_23_Before + uIControlledApplication.SelectionChanged += UIControlledApplication_SelectionChanged; +#endif + +#if !Rvt_24_Before + uIControlledApplication.ThemeChanged += UIControlledApplication_ThemeChanged; +#endif + } + + private void ControlledApplication_ApplicationInitialized(object sender, Autodesk.Revit.DB.Events.ApplicationInitializedEventArgs e) { } + +#if !Rvt_24_Before + private void UIControlledApplication_ThemeChanged(object sender, Autodesk.Revit.UI.Events.ThemeChangedEventArgs e) + { + OnThemeChanged(sender); + } +#endif + +#if !Rvt_23_Before + private void UIControlledApplication_SelectionChanged(object sender, Autodesk.Revit.UI.Events.SelectionChangedEventArgs e) + { + OnApplicationSelectionChanged(sender, new SelectionChangedEventArgs(e)); + } +#endif + + private void UIControlledApplication_ApplicationClosing(object sender, Autodesk.Revit.UI.Events.ApplicationClosingEventArgs e) + { + OnApplicationClosing(sender, e); + _application.ApplicationClosing -= UIControlledApplication_ApplicationClosing; + _application.ControlledApplication.ApplicationInitialized -= ControlledApplication_ApplicationInitialized; + +#if !Rvt_23_Before + _application.SelectionChanged -= UIControlledApplication_SelectionChanged; +#endif + +#if !Rvt_24_Before + _application.ThemeChanged -= UIControlledApplication_ThemeChanged; +#endif + } + + /// + /// 当应用初始化后触发的事件 + /// + /// + /// + protected virtual void OnApplicationInitialized(object sender, Autodesk.Revit.DB.Events.ApplicationInitializedEventArgs e) { } + + /// + /// 当应用关闭时触发的事件 + /// + /// + /// + protected virtual void OnApplicationClosing(object sender, Autodesk.Revit.UI.Events.ApplicationClosingEventArgs e) { } + + /// + /// 当主题改变触发的事件 + /// + /// 仅适用于 Revti 2024 以上的版本 + /// + protected virtual void OnThemeChanged(object sender) { } + + /// + /// 当应用程序的选择对象变更后触发的事件 + /// + /// 仅适用于 Revti 2023 以上的版本 + /// + /// + protected virtual void OnApplicationSelectionChanged(object sender, SelectionChangedEventArgs e) { } +} diff --git a/src/Ribbon/Abstraction/IRibbonComboBox.cs b/src/Ribbon/Abstraction/IRibbonComboBox.cs index 71c7cda..c269cf6 100644 --- a/src/Ribbon/Abstraction/IRibbonComboBox.cs +++ b/src/Ribbon/Abstraction/IRibbonComboBox.cs @@ -13,21 +13,21 @@ namespace Tuna.Revit.Extension; public interface IRibbonComboBox : IRibbonItem { /// - /// + /// 添加成员 /// /// /// IRibbonComboBox AddItem(string title); /// - /// + /// 添加多个成员 /// /// /// IRibbonComboBox AddItems(params string[] titles); /// - /// + /// 添加分割线 /// /// IRibbonComboBox AddSeparator(); diff --git a/src/Ribbon/Abstraction/IRibbonTab.cs b/src/Ribbon/Abstraction/IRibbonTab.cs index 15a691f..ef81697 100644 --- a/src/Ribbon/Abstraction/IRibbonTab.cs +++ b/src/Ribbon/Abstraction/IRibbonTab.cs @@ -1,4 +1,5 @@ -using System; +using Autodesk.Revit.UI; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -23,4 +24,10 @@ public interface IRibbonTab : IRibbonItemsCollector /// 面板的标题 /// 添加面板的元素 IRibbonPanel AddRibbonPanel(string title, Action handle); + + /// + /// 获取面板 + /// + /// + List GetRibbonPanels(); } diff --git a/src/Ribbon/Proxy/RibbonButtonDescriptor.cs b/src/Ribbon/Proxy/RibbonButtonDescriptor.cs new file mode 100644 index 0000000..2904cc3 --- /dev/null +++ b/src/Ribbon/Proxy/RibbonButtonDescriptor.cs @@ -0,0 +1,60 @@ + +using Autodesk.Revit.UI; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace Tuna.Revit.Extension.Ribbon.Proxy; + +internal class RibbonButtonDescriptor +{ + public Action Handle { get; set; } + + public Type CommandType { get; set; } + + public IRibbonButtonData RibbonButtonData { get; set; } + + public PushButtonData PushButtonData { get; set; } + + public static RibbonButtonDescriptor CreateRibbonButtonDescriptor(Action handle, Type commandType) + { + //按钮的名称 + string name = commandType.Name; + + //实例化一个按钮的数据 + PushButtonData pushButtonData = new($"btn_{name}", name ?? name, commandType.Assembly.Location, commandType.FullName); + + //如果命令实现了 IExternalCommandAvailability 接口 + if (typeof(IExternalCommandAvailability).IsAssignableFrom(commandType)) + { + pushButtonData.AvailabilityClassName = commandType.FullName; + } + + //方式三,通过属性进行配置,优先级第三 + IRibbonButtonData ribbonButtonData = commandType.GetCustomAttribute(); + if (ribbonButtonData != null) + { + UIExtension.SetPushButtonData(pushButtonData, ribbonButtonData); + } + + //方式二,通过接口进行配置,优先级第二 + if (typeof(IRibbonButtonData).IsAssignableFrom(commandType)) + { + ribbonButtonData = Activator.CreateInstance(commandType) as IRibbonButtonData; + UIExtension.SetPushButtonData(pushButtonData, ribbonButtonData); + } + + //方式一,通过回调进行配置,优先级第一 + handle?.Invoke(pushButtonData); + + return new RibbonButtonDescriptor() + { + PushButtonData = pushButtonData, + RibbonButtonData = ribbonButtonData, + CommandType = commandType + }; + } +} diff --git a/src/Ribbon/Proxy/RibbonPanelProxy.cs b/src/Ribbon/Proxy/RibbonPanelProxy.cs index 2083710..9aabc5d 100644 --- a/src/Ribbon/Proxy/RibbonPanelProxy.cs +++ b/src/Ribbon/Proxy/RibbonPanelProxy.cs @@ -1,7 +1,9 @@ using Autodesk.Revit.UI; using System; using System.Collections.Generic; +using System.Data; using System.Linq; +using System.Reflection; using System.Text; using System.Threading.Tasks; using Tuna.Revit.Extension.Ribbon.Abstraction; @@ -28,14 +30,23 @@ public IRibbonPanel AddSeparator() public IRibbonPanel AddPushButton(Action handle = null) where TCommand : class, IExternalCommand, new() { - if (!_items.Any(item => item.Name == $"btn_{typeof(TCommand)}")) + Type commandType = typeof(TCommand); + if (!_items.Any(item => item.Name == $"btn_{commandType}")) { RibbonButtonProxy ribbonButtonProxy = new RibbonButtonProxy(); - handle?.Invoke(ribbonButtonProxy.RibbonButtonData); + ribbonButtonProxy.Configurate(handle); - RibbonButton ribbonButton = this.OriginalObject.CreatePushButton(btn => UIExtension.SetPushButtonData(btn, ribbonButtonProxy.RibbonButtonData)); + RibbonButtonDescriptor descriptor = RibbonButtonDescriptor.CreateRibbonButtonDescriptor(btn => + { + if (handle != null) + { + UIExtension.SetPushButtonData(btn, ribbonButtonProxy.RibbonButtonData); + } + }, commandType); + + + var ribbonButton = this.OriginalObject.AddItem(descriptor.PushButtonData) as PushButton; - ribbonButtonProxy.OriginalObject = ribbonButton; ribbonButtonProxy.Title = ribbonButton.ItemText; ribbonButtonProxy.Name = ribbonButton.Name; @@ -48,7 +59,7 @@ public IRibbonPanel AddSeparator() public IRibbonPanel AddPulldownButton(string title, Action handle = null) { RibbonPulldownButtonProxy pulldownButtonProxy = new(); - handle.Invoke(pulldownButtonProxy); + handle?.Invoke(pulldownButtonProxy); PulldownButton pulldownButton = this.OriginalObject.CreatePulldownButton(title, title, btn => UIExtension.SetPushButtonData(btn, pulldownButtonProxy.RibbonButtonData)); @@ -79,7 +90,7 @@ public IRibbonPanel AddSplitButton(string title, Action hand public IRibbonPanel AddComboBox(string name, Action handle = null) { - ComboBox comboBox = this.OriginalObject.CreateComboBox(name); + ComboBox comboBox = this.OriginalObject.InternalCreateComboBox(name); RibbonComboBoxProxy comboBoxProxy = new(comboBox) { diff --git a/src/Ribbon/Proxy/RibbonPulldownButtonProxy.cs b/src/Ribbon/Proxy/RibbonPulldownButtonProxy.cs index 89d2f55..ee875e9 100644 --- a/src/Ribbon/Proxy/RibbonPulldownButtonProxy.cs +++ b/src/Ribbon/Proxy/RibbonPulldownButtonProxy.cs @@ -1,6 +1,7 @@ using Autodesk.Revit.UI; using System; using System.Collections.Generic; +using System.Data; using Tuna.Revit.Extension.Ribbon.Abstraction; namespace Tuna.Revit.Extension.Ribbon.Proxy; @@ -10,13 +11,6 @@ internal class RibbonPulldownButtonProxy : RibbonElementProxy, I private readonly List _items = new(); private readonly List> _components = new(); - private class RibbonButtonDescriptor - { - public Action Handle { get; set; } - - public Type Type { get; set; } - } - public RibbonPulldownButtonProxy() => RibbonButtonData = new RibbonButtonData(); public RibbonItemType Type => RibbonItemType.PulldownButton; @@ -25,11 +19,17 @@ private class RibbonButtonDescriptor public IRibbonPulldownButton AddPushButton(Action handle = null) where TCommand : class, IExternalCommand, new() { - _components.Add(new(RibbonItemType.PushButton, new RibbonButtonDescriptor() + RibbonButtonDescriptor descriptor = RibbonButtonDescriptor.CreateRibbonButtonDescriptor(btn => { - Handle = handle, - Type = typeof(TCommand) - })); + if (handle != null) + { + RibbonButtonData pushButtonData=new RibbonButtonData(); + handle.Invoke(pushButtonData); + UIExtension.SetPushButtonData(btn, pushButtonData); + } + }, typeof(TCommand)); + + _components.Add(new(RibbonItemType.PushButton, descriptor)); return this; } @@ -59,9 +59,8 @@ public void InitializeComponent() case RibbonItemType.PushButton: RibbonButtonDescriptor descriptor = item.Item2; RibbonButtonProxy ribbonButtonProxy = new(); - descriptor.Handle?.Invoke(ribbonButtonProxy.RibbonButtonData); - RibbonButton ribbonButton = this.OriginalObject.CreatePushButton(descriptor.Type, btn => UIExtension.SetPushButtonData(btn, ribbonButtonProxy.RibbonButtonData)); + RibbonButton ribbonButton = this.OriginalObject.AddPushButton(descriptor.PushButtonData); ribbonButtonProxy.OriginalObject = ribbonButton; ribbonButtonProxy.Title = ribbonButton.Name; diff --git a/src/Ribbon/Proxy/RibbonTabProxy.cs b/src/Ribbon/Proxy/RibbonTabProxy.cs index 5ecc634..b849c37 100644 --- a/src/Ribbon/Proxy/RibbonTabProxy.cs +++ b/src/Ribbon/Proxy/RibbonTabProxy.cs @@ -31,4 +31,9 @@ public IRibbonPanel AddRibbonPanel(string name, Action handle) } public IEnumerable GetItems() => _items; + + public List GetRibbonPanels() + { + return Application.GetRibbonPanels(this.Title); + } } diff --git a/src/Ribbon/RibbonExtension.cs b/src/Ribbon/RibbonExtension.cs index b664673..c5e11db 100644 --- a/src/Ribbon/RibbonExtension.cs +++ b/src/Ribbon/RibbonExtension.cs @@ -54,11 +54,11 @@ private static IRibbonTab AddRibbonTab(this UIApplication application, string ti /// public static void AddRibbonTab(this UIControlledApplication application, string title, Action action) { - RibbonHost ribbonHost = RibbonHost.Default; + RevitApplicationContext ribbonHost = RevitApplicationContext.Instance; ribbonHost.Assembly = Assembly.GetCallingAssembly(); ribbonHost.UIApplication = GetUIApplication(application); ribbonHost.UIControlledApplication = application; - + IRibbonTab ribbonTab = ribbonHost.UIApplication.AddRibbonTab(title); action?.Invoke(ribbonTab); } @@ -70,13 +70,11 @@ public static void AddRibbonTab(this UIControlledApplication application, string /// public static IRibbonTab AddRibbonTab(this UIControlledApplication application, string title) { - RibbonHost ribbonHost = RibbonHost.Default; + RevitApplicationContext ribbonHost = RevitApplicationContext.Instance; ribbonHost.Assembly = Assembly.GetCallingAssembly(); ribbonHost.UIApplication = GetUIApplication(application); ribbonHost.UIControlledApplication = application; return ribbonHost.UIApplication.AddRibbonTab(title); } - - } diff --git a/src/Ribbon/RibbonImageResovler.cs b/src/Ribbon/RibbonImageResovler.cs index 4f10f4c..515702f 100644 --- a/src/Ribbon/RibbonImageResovler.cs +++ b/src/Ribbon/RibbonImageResovler.cs @@ -12,7 +12,7 @@ > 对于路径的解析: - 如果用户给的是绝对路径指向资源位置,则直接返回资源对象 - - 如果用户给的是相对路径,则默认按照在启动文件的相对路径 [/Assets/Icon/] 文件下进行读取 + - 如果用户给的是相对路径,则默认按照在启动文件的相对路径 [\Assets\Icon/\] 文件夹下进行读取 - 如果用户通过 [.Addin] 进行配置(指定的属性为Resource) 则相对路径修改为用户指定的路径 @@ -40,9 +40,9 @@ public static ImageSource Resolve(object source) } else { - if (RibbonHost.Default.IsVaild) + if (RevitApplicationContext.Instance.IsVaild) { - path = $"{RibbonHost.Default.InstallPath}//{path}"; + path = @$"{RevitApplicationContext.Instance.InstallPath}\{path}"; if (File.Exists(path)) { return new BitmapImage(new Uri(path)); diff --git a/src/Ribbon/UIExtension.cs b/src/Ribbon/UIExtension.cs index c680f67..408026d 100644 --- a/src/Ribbon/UIExtension.cs +++ b/src/Ribbon/UIExtension.cs @@ -22,6 +22,7 @@ using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging; +using Tuna.Revit.Extension.Ribbon.Proxy; namespace Tuna.Revit.Extension; @@ -33,49 +34,48 @@ public static class UIExtension { internal static void SetPushButtonData(ButtonData buttonData, IRibbonButtonData buttonDataProxy) { - buttonData.Text = string.IsNullOrWhiteSpace(buttonDataProxy.Title) ? buttonData.Text : buttonDataProxy.Title; - buttonData.Image = RibbonImageResovler.Resolve(buttonDataProxy.Image); - buttonData.LargeImage = RibbonImageResovler.Resolve(buttonDataProxy.LargeImage); - buttonData.ToolTipImage = RibbonImageResovler.Resolve(buttonDataProxy.ToolTipImage); - buttonData.ToolTip = buttonDataProxy.ToolTip; - buttonData.LongDescription = buttonDataProxy.LongDescription; - buttonData.SetContextualHelp(buttonDataProxy.ContextualHelp); - } - - static PushButtonData CreatePushButtonData(Action handle, Type commandType) - { - //按钮的名称 - string name = commandType.Name; + if (!string.IsNullOrWhiteSpace(buttonDataProxy.Title) && !EqualityComparer.Default.Equals(buttonData.Text, buttonDataProxy.Title)) + { + buttonData.Text = buttonDataProxy.Title; + } - //实例化一个按钮的数据 - PushButtonData pushButtonData = new($"btn_{name}", name ?? name, commandType.Assembly.Location, commandType.FullName); + var image = RibbonImageResovler.Resolve(buttonDataProxy.Image); + if (buttonDataProxy.Image != null && !EqualityComparer.Default.Equals(buttonData.Image, image)) + { + buttonData.Image = image; + } - //如果命令实现了 IExternalCommandAvailability 接口 - if (typeof(IExternalCommandAvailability).IsAssignableFrom(commandType)) + var largeImage = RibbonImageResovler.Resolve(buttonDataProxy.LargeImage); + if (buttonDataProxy.LargeImage != null && !EqualityComparer.Default.Equals(buttonData.LargeImage, largeImage)) { - pushButtonData.AvailabilityClassName = commandType.FullName; + buttonData.LargeImage = largeImage; } - //方式三,通过属性进行配置,优先级第三 - CommandButtonAttribute command = commandType.GetCustomAttribute(); - if (command != null) + var toolTipImage = RibbonImageResovler.Resolve(buttonDataProxy.ToolTipImage); + if (toolTipImage != null && !EqualityComparer.Default.Equals(buttonData.ToolTipImage, toolTipImage)) { - SetPushButtonData(pushButtonData, command); + buttonData.ToolTipImage = toolTipImage; } - //方式二,通过接口进行配置,优先级第二 - if (typeof(IRibbonButtonData).IsAssignableFrom(commandType)) + if (buttonDataProxy.ToolTip != null && !EqualityComparer.Default.Equals(buttonData.ToolTip, buttonDataProxy.ToolTip)) { - SetPushButtonData(pushButtonData, Activator.CreateInstance(commandType) as IRibbonButtonData); + buttonData.ToolTip = buttonDataProxy.ToolTip; } - //方式一,通过回调进行配置,优先级第一 - handle?.Invoke(pushButtonData); + if (buttonDataProxy.LongDescription != null && !EqualityComparer.Default.Equals(buttonData.LongDescription, buttonDataProxy.LongDescription)) + { + buttonData.LongDescription = buttonDataProxy.LongDescription; + } - return pushButtonData; + ContextualHelp contextualHelp = buttonData.GetContextualHelp(); + if (buttonDataProxy.ContextualHelp != null && !EqualityComparer.Default.Equals(contextualHelp, buttonDataProxy.ContextualHelp)) + { + buttonData.SetContextualHelp(buttonDataProxy.ContextualHelp); + } } - static PushButtonData CreatePushButtonData(Action handle = null) where T : class, IExternalCommand, new() => CreatePushButtonData(handle, typeof(T)); + static PushButtonData CreatePushButtonData(Action handle = null) where T : class, IExternalCommand, new() + => RibbonButtonDescriptor.CreateRibbonButtonDescriptor(handle, typeof(T)).PushButtonData; /// /// 在面板上创建一个按钮 @@ -89,8 +89,8 @@ static PushButtonData CreatePushButtonData(Action handle, Type c { ArgumentNullExceptionUtils.ThrowIfNull(panel); - RibbonHost.Default.Assembly = Assembly.GetCallingAssembly(); - + RevitApplicationContext.Instance.Assembly = Assembly.GetCallingAssembly(); + return panel.AddItem(CreatePushButtonData(handle)) as PushButton; } @@ -110,7 +110,7 @@ public static PulldownButton CreatePulldownButton(this RibbonPanel panel, string handle?.Invoke(data); - RibbonHost.Default.Assembly = Assembly.GetCallingAssembly(); + RevitApplicationContext.Instance.Assembly = Assembly.GetCallingAssembly(); return panel.AddItem(data) as PulldownButton; } @@ -131,7 +131,7 @@ public static SplitButton CreateSplitButton(this RibbonPanel panel, string name, handle?.Invoke(data); - RibbonHost.Default.Assembly = Assembly.GetCallingAssembly(); + RevitApplicationContext.Instance.Assembly = Assembly.GetCallingAssembly(); return panel.AddItem(data) as SplitButton; } @@ -144,6 +144,12 @@ public static SplitButton CreateSplitButton(this RibbonPanel panel, string name, /// /// public static ComboBox CreateComboBox(this RibbonPanel panel, string name, Action handle = null) + { + RevitApplicationContext.Instance.Assembly = Assembly.GetCallingAssembly(); + return InternalCreateComboBox(panel, name, handle); + } + + internal static ComboBox InternalCreateComboBox(this RibbonPanel panel, string name, Action handle = null) { ArgumentNullExceptionUtils.ThrowIfNull(panel); @@ -151,12 +157,9 @@ public static ComboBox CreateComboBox(this RibbonPanel panel, string name, Actio handle?.Invoke(combo); - RibbonHost.Default.Assembly = Assembly.GetCallingAssembly(); - return panel.AddItem(combo) as ComboBox; } - /// /// 创建按压式按钮 @@ -167,7 +170,7 @@ public static ComboBox CreateComboBox(this RibbonPanel panel, string name, Actio /// public static PushButton CreatePushButton(this PulldownButton pulldownButton, Action handle = null) where T : class, IExternalCommand, new() { - RibbonHost.Default.Assembly = Assembly.GetCallingAssembly(); + RevitApplicationContext.Instance.Assembly = Assembly.GetCallingAssembly(); return CreatePushButton(pulldownButton, typeof(T), handle); } @@ -183,8 +186,8 @@ internal static PushButton CreatePushButton(this PulldownButton pulldownButton, { ArgumentNullExceptionUtils.ThrowIfNull(pulldownButton); - return pulldownButton.AddPushButton(CreatePushButtonData(handle, type)); - } - + RibbonButtonDescriptor descriptor = RibbonButtonDescriptor.CreateRibbonButtonDescriptor(handle, type); + return pulldownButton.AddPushButton(descriptor.PushButtonData); + } } diff --git a/src/Selection/SelectionChangedEventArgs.cs b/src/Selection/SelectionChangedEventArgs.cs new file mode 100644 index 0000000..24cfc6a --- /dev/null +++ b/src/Selection/SelectionChangedEventArgs.cs @@ -0,0 +1,38 @@ +using Autodesk.Revit.DB; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tuna.Revit.Extension; + +/// +/// 用户选择变更事件的参数 +/// +public class SelectionChangedEventArgs +{ +#if !Rvt_23_Before + internal SelectionChangedEventArgs(Autodesk.Revit.UI.Events.SelectionChangedEventArgs e) + { + Document = e.GetDocument(); + Elements = e.GetSelectedElements(); + References = e.GetReferences(); + } +#endif + + /// + /// 发生选择变更的文档 + /// + public Document Document { get; } + + /// + /// 被选择的图元 + /// + public IEnumerable Elements { get; } + + /// + /// 被选择的引用 + /// + public IEnumerable References { get; } +} diff --git a/src/Tuna.Revit.Extension.csproj b/src/Tuna.Revit.Extension.csproj index 7c2c9fc..5213ca9 100644 --- a/src/Tuna.Revit.Extension.csproj +++ b/src/Tuna.Revit.Extension.csproj @@ -29,62 +29,62 @@ Rvt_24_Debug;Rvt_24_Release; Rvt_25_Debug;Rvt_25_Release; - 17 + 18 x64 preview 2016 - Rvt_16 + Rvt_16;Rvt_20_Before;Rvt_23_Before;Rvt_24_Before net452 2016.2.$(TunaVer) 2017 - Rvt_17 + Rvt_17;Rvt_20_Before;Rvt_23_Before;Rvt_24_Before net46 2017.2.$(TunaVer) 2018 - Rvt_18 + Rvt_18;Rvt_20_Before;Rvt_23_Before;Rvt_24_Before net46 2018.2.$(TunaVer) 2019 - Rvt_19 + Rvt_19;Rvt_20_Before;Rvt_23_Before;Rvt_24_Before net47 2019.0.$(TunaVer) 2020 - Rvt_20 + Rvt_20;Rvt_23_Before;Rvt_24_Before net47 2020.0.$(TunaVer) 2021 - Rvt_21 + Rvt_21;Rvt_23_Before;Rvt_24_Before net48 2021.0.$(TunaVer) 2022 - Rvt_22 + Rvt_22;Rvt_23_Before;Rvt_24_Before net48 2022.0.$(TunaVer) 2023 - Rvt_23 + Rvt_23;Rvt_24_Before net48 2023.0.$(TunaVer) @@ -102,7 +102,7 @@ net8.0-windows 2025.0.$(TunaVer) - + True @@ -141,7 +141,7 @@ - True + True @@ -203,7 +203,7 @@ - +