RevitRibbonOperate.cs 13 KB

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