RevitRibbonOperate.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. /* ==============================================================================
  2. * 功能描述:RevitRibbon生成操作
  3. * 创 建 者:Garrett
  4. * 创建日期:2018/9/17 18:01:44
  5. * ==============================================================================*/
  6. using System;
  7. using System.Collections.Generic;
  8. using System.IO;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Threading.Tasks;
  12. using System.Windows.Media.Imaging;
  13. using Autodesk.Revit.UI;
  14. using Autodesk.Windows;
  15. using SAGA.RevitUtils;
  16. using TSZ.RevitMenu.Configuration;
  17. using RibbonItem = Autodesk.Revit.UI.RibbonItem;
  18. using RibbonPanel = Autodesk.Revit.UI.RibbonPanel;
  19. namespace SAGA.RevitMenu.Configuration
  20. {
  21. /// <summary>
  22. /// RevitRibbonOperate
  23. /// </summary>
  24. class RevitRibbonOperate
  25. {
  26. /// <summary>
  27. /// 创建菜单
  28. /// </summary>
  29. /// <param name="app"></param>
  30. /// <param name="configTabs"></param>
  31. /// <returns></returns>
  32. public static bool ApplyConfigTabs(UIControlledApplication app, TszTabData[] configTabs)
  33. {
  34. int index = 0;
  35. if (!AddSignToTab(configTabs))
  36. return false;
  37. for (int j = 0; j < configTabs.Length; j++)
  38. {
  39. if (j == 18)
  40. {
  41. //经测试,最多为20个,为保险暂保留15个。
  42. MessageShow.Infomation("菜单Tab页签项过多,只加载了18个Tab页签。");
  43. break;
  44. }
  45. #region 创建RibbonTab 前后加【】
  46. TszTabData tabData = configTabs[j];
  47. //没有可用button不创建
  48. if (!tabData.HasVisibleItem())
  49. continue;
  50. List<RibbonPanel> listRibPanel;
  51. try
  52. {//获取自定义Tab下的Panel,如果Tab不存在,抛出异常
  53. listRibPanel = app.GetRibbonPanels(tabData.TabName);
  54. }
  55. catch (Exception e)
  56. {
  57. app.CreateRibbonTab(tabData.TabName);
  58. listRibPanel = new List<RibbonPanel>();
  59. }
  60. #endregion
  61. foreach (TszPanelData panelData in tabData.Panels)
  62. {
  63. #region 创建RibbonPanel
  64. bool blnExist = panelData.ValidateData();
  65. if (!blnExist||!panelData.HasVisibleItem())
  66. {
  67. continue;
  68. }
  69. var rvtRibbonPanel = listRibPanel.Find(p => p.Name == panelData.PanelName);
  70. List<RibbonItem> listPanelItem = new List<RibbonItem>();
  71. if (rvtRibbonPanel == null)
  72. {
  73. rvtRibbonPanel = app.CreateRibbonPanel(tabData.TabName, panelData.PanelName);
  74. rvtRibbonPanel.Visible = panelData.Visible;
  75. }
  76. else
  77. {
  78. listPanelItem = rvtRibbonPanel.GetItems().ToList();
  79. }
  80. #endregion
  81. //分割符数据
  82. RibbonItem separatorBeforeVisibleItem = null;//分割符之前的可见Button
  83. bool separatorStandBy = false;//准备放置分割符
  84. Action<RibbonItem, bool> setRibbonItemVisibleAction = (t, b) =>
  85. {
  86. t.Visible = b;
  87. if (b)
  88. separatorBeforeVisibleItem = t;
  89. };
  90. PulldownButton pulldownButton = null;
  91. List<Tuple<ButtonData, bool>> stackButtonDatas = new List<Tuple<ButtonData, bool>>();
  92. IList<RibbonItem> ribbonItems = null;
  93. for (int i = 0; i < panelData.Buttons.Count; i++)
  94. {
  95. bool isLast = false;
  96. #region 按钮
  97. TszButtonData tszbuttonData = panelData.Buttons[i];
  98. tszbuttonData.ButtonText = tszbuttonData.ButtonText?.Replace(" ", Environment.NewLine);
  99. //不加载名为NEWTEXTBUTTON的按钮(该按钮在Panel为空时仅为找TabName用,自行在XML中添加) wxy 2017-4-18
  100. if (tszbuttonData.ButtonText == "NEWTEXTBUTTON")
  101. continue;
  102. //RibbonPalel中不允许同名Button
  103. if (listPanelItem.Exists(p => p.Name == tszbuttonData.ButtonName))
  104. {
  105. continue;
  106. }
  107. PushButtonData pushbuttonData = null;
  108. PushButton pushButton = null;
  109. //加载Stack排列类型的命令
  110. #region 添加Stack Button
  111. PlaceStackStart:
  112. if (stackButtonDatas.Count > 0 && tszbuttonData.Styles != ButtonStyles.Stacked || isLast)
  113. {
  114. if (stackButtonDatas.Count >= 3)
  115. {
  116. ribbonItems = rvtRibbonPanel.AddStackedItems(stackButtonDatas[0].Item1, stackButtonDatas[1].Item1, stackButtonDatas[2].Item1);
  117. SetStackItemsVisible(ribbonItems, stackButtonDatas);
  118. stackButtonDatas.RemoveRange(0, 3);
  119. goto PlaceStackStart;
  120. }
  121. if (stackButtonDatas.Count == 2)
  122. {
  123. ribbonItems = rvtRibbonPanel.AddStackedItems(stackButtonDatas[0].Item1, stackButtonDatas[1].Item1);
  124. SetStackItemsVisible(ribbonItems, stackButtonDatas);
  125. }
  126. else if (stackButtonDatas.Count == 1)
  127. {
  128. pushButton = rvtRibbonPanel.AddItem(stackButtonDatas[0].Item1) as PushButton;
  129. setRibbonItemVisibleAction(pushButton, stackButtonDatas[0].Item2);
  130. }
  131. stackButtonDatas.Clear();
  132. if (isLast)
  133. continue;
  134. }
  135. #endregion
  136. //创建分割符。分割符创建条件,1,分割符之前有可见Button,2,在分割符之后的下一个可见Button之前创建分割符
  137. if (separatorStandBy && tszbuttonData.Visible)
  138. {
  139. rvtRibbonPanel.AddSeparator();
  140. separatorBeforeVisibleItem = null;
  141. separatorStandBy = false;
  142. }
  143. //创建pullButton
  144. if (tszbuttonData.Styles != ButtonStyles.Separator)
  145. {
  146. pushbuttonData = new PushButtonData(tszbuttonData.ButtonName, tszbuttonData.ButtonText,
  147. tszbuttonData.AssemblyName, tszbuttonData.ClassName);
  148. if (!string.IsNullOrEmpty(tszbuttonData.ImageName))
  149. {
  150. var stringImagePath = tszbuttonData.ImageName + "16.png";
  151. var stringLargeImagePath = tszbuttonData.ImageName + ".png";
  152. if (File.Exists(stringImagePath))
  153. {
  154. pushbuttonData.Image = new BitmapImage(new Uri(stringImagePath));
  155. }
  156. if (File.Exists(stringLargeImagePath))
  157. {
  158. pushbuttonData.LargeImage = new BitmapImage(new Uri(stringLargeImagePath));
  159. }
  160. }
  161. pushbuttonData.ToolTip = tszbuttonData.ToolTip;
  162. pushbuttonData.LongDescription = tszbuttonData.LongDescription;
  163. pushbuttonData.AvailabilityClassName = tszbuttonData.ClassName;
  164. }
  165. //加载图标并且将Button添加到菜单
  166. switch (tszbuttonData.Styles)
  167. {
  168. case ButtonStyles.Separator:
  169. if (separatorBeforeVisibleItem != null)
  170. separatorStandBy = true;
  171. //rvtRibbonPanel.AddSeparator();
  172. break;
  173. case ButtonStyles.Large:
  174. pushButton = rvtRibbonPanel.AddItem(pushbuttonData) as PushButton;
  175. setRibbonItemVisibleAction(pushButton, tszbuttonData.Visible);
  176. break;
  177. case ButtonStyles.Pushdown:
  178. if (pulldownButton == null || pulldownButton.Visible == false)
  179. {
  180. SplitButtonData spliteButtonData = new SplitButtonData("push" + panelData.PanelName + i, panelData.PanelName);
  181. spliteButtonData.Text = pushbuttonData.Text;
  182. spliteButtonData.LargeImage = pushbuttonData.LargeImage;
  183. spliteButtonData.ToolTip = tszbuttonData.ToolTip;
  184. spliteButtonData.LongDescription = tszbuttonData.LongDescription;
  185. pulldownButton = rvtRibbonPanel.AddItem(spliteButtonData) as PulldownButton;
  186. pulldownButton.Visible = tszbuttonData.Visible;
  187. setRibbonItemVisibleAction(pulldownButton, tszbuttonData.Visible);
  188. }
  189. pushButton = pulldownButton?.AddPushButton(pushbuttonData);
  190. setRibbonItemVisibleAction(pushButton, tszbuttonData.Visible);
  191. break;
  192. case ButtonStyles.Stacked:
  193. case ButtonStyles.StackedBox:
  194. stackButtonDatas.Add(new Tuple<ButtonData, bool>(pushbuttonData, tszbuttonData.Visible));
  195. break;
  196. }
  197. //最后一项,并且是Stacked ,跳转到添加Stacked
  198. isLast = panelData.Buttons.Count - 1 == i;
  199. if (isLast&&stackButtonDatas.Count>0)
  200. goto PlaceStackStart;
  201. #endregion
  202. }
  203. }
  204. ////调整选项卡到最前
  205. RibbonTab tab = ComponentManager.Ribbon.Tabs.FirstOrDefault(t => t.Name == tabData.TabName);
  206. if (tab != null)
  207. {
  208. ComponentManager.Ribbon.Tabs.Remove(tab);
  209. ComponentManager.Ribbon.Tabs.Insert(index, tab);
  210. index++;
  211. }
  212. }
  213. return true;
  214. }
  215. /// <summary>
  216. /// Tab前后加【】
  217. /// </summary>
  218. /// <param name="configTabs"></param>
  219. /// <returns></returns>
  220. private static bool AddSignToTab(TszTabData[] configTabs)
  221. {
  222. var firstVisibleTabItem = configTabs.FirstOrDefault(t => t.HasVisibleItem());
  223. //如果都不可见,直接返回,不创建了
  224. if (firstVisibleTabItem == null) return false;
  225. firstVisibleTabItem.TabName = "【"+ firstVisibleTabItem.TabName;
  226. var lastVisibleTabItem = configTabs.LastOrDefault(t => t.HasVisibleItem());
  227. if (lastVisibleTabItem == null) return false;
  228. lastVisibleTabItem.TabName += "】";
  229. return true;
  230. }
  231. /// <summary>
  232. /// 设置StackButton的可见性
  233. /// </summary>
  234. /// <param name="ribbonItems"></param>
  235. /// <param name="stackButtonDatas"></param>
  236. private static void SetStackItemsVisible(IList<RibbonItem> ribbonItems, List<Tuple<ButtonData, bool>> stackButtonDatas)
  237. {
  238. int i = 0;
  239. foreach (RibbonItem ribbonItem in ribbonItems)
  240. {
  241. var tuple = stackButtonDatas[i];
  242. ribbonItem.Visible = tuple.Item2;
  243. i++;
  244. }
  245. }
  246. }
  247. }