/
Ribbon.cs
300 lines (271 loc) · 18.6 KB
/
Ribbon.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
//
// (C) Copyright 2003-2019 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Revit;
using System.Diagnostics;
using System.IO;
using System.Windows.Media;
using System.Windows.Forms;
using System.Windows.Media.Imaging;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.UI.Events;
using TaskDialog = Autodesk.Revit.UI.TaskDialog;
namespace Revit.SDK.Samples.Ribbon.CS
{
/// <summary>
/// Implements the Revit add-in interface IExternalApplication,
/// show user how to create RibbonItems by API in Revit.
/// we add one RibbonPanel:
/// 1. contains a SplitButton for user to create Non-Structural or Structural Wall;
/// 2. contains a StackedButton which is consisted with one PushButton and two Comboboxes,
/// PushButton is used to reset all the RibbonItem, Comboboxes are use to select Level and WallShape
/// 3. contains a RadioButtonGroup for user to select WallType.
/// 4. Adds a Slide-Out Panel to existing panel with following functionalities:
/// 5. a text box is added to set mark for new wall, mark is a instance parameter for wall,
/// Eg: if user set text as "wall", then Mark for each new wall will be "wall1", "wall2", "wall3"....
/// 6. a StackedButton which consisted of a PushButton (delete all the walls) and a PulldownButton (move all the walls in X or Y direction)
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
[Autodesk.Revit.Attributes.Journaling(Autodesk.Revit.Attributes.JournalingMode.NoCommandData)]
public class Ribbon : IExternalApplication
{
// ExternalCommands assembly path
static string AddInPath = typeof(Ribbon).Assembly.Location;
// Button icons directory
static string ButtonIconsFolder = Path.GetDirectoryName(AddInPath);
// uiApplication
static UIApplication uiApplication = null;
#region IExternalApplication Members
/// <summary>
/// Implement this method to implement the external application which should be called when
/// Revit starts before a file or default template is actually loaded.
/// </summary>
/// <param name="application">An object that is passed to the external application
/// which contains the controlled application.</param>
/// <returns>Return the status of the external application.
/// A result of Succeeded means that the external application successfully started.
/// Cancelled can be used to signify that the user cancelled the external operation at
/// some point.
/// If Failed is returned then Revit should inform the user that the external application
/// failed to load and the release the internal reference.</returns>
public Autodesk.Revit.UI.Result OnStartup(UIControlledApplication application)
{
try
{
// create customer Ribbon Items
CreateRibbonSamplePanel(application);
return Autodesk.Revit.UI.Result.Succeeded;
}
catch (Exception ex)
{
TaskDialog.Show("Ribbon Sample", ex.ToString());
return Autodesk.Revit.UI.Result.Failed;
}
}
/// <summary>
/// Implement this method to implement the external application which should be called when
/// Revit is about to exit, Any documents must have been closed before this method is called.
/// </summary>
/// <param name="application">An object that is passed to the external application
/// which contains the controlled application.</param>
/// <returns>Return the status of the external application.
/// A result of Succeeded means that the external application successfully shutdown.
/// Cancelled can be used to signify that the user cancelled the external operation at
/// some point.
/// If Failed is returned then the Revit user should be warned of the failure of the external
/// application to shut down correctly.</returns>
public Autodesk.Revit.UI.Result OnShutdown(UIControlledApplication application)
{
//remove events
List<RibbonPanel> myPanels = application.GetRibbonPanels();
Autodesk.Revit.UI.ComboBox comboboxLevel = (Autodesk.Revit.UI.ComboBox)(myPanels[0].GetItems()[2]);
application.ControlledApplication.DocumentCreated -= new EventHandler<
Autodesk.Revit.DB.Events.DocumentCreatedEventArgs>(DocumentCreated);
Autodesk.Revit.UI.TextBox textBox = myPanels[0].GetItems()[5] as Autodesk.Revit.UI.TextBox;
textBox.EnterPressed -= new EventHandler<
Autodesk.Revit.UI.Events.TextBoxEnterPressedEventArgs>(SetTextBoxValue);
return Autodesk.Revit.UI.Result.Succeeded;
}
#endregion
/// <summary>
/// This method is used to create RibbonSample panel, and add wall related command buttons to it:
/// 1. contains a SplitButton for user to create Non-Structural or Structural Wall;
/// 2. contains a StackedBotton which is consisted with one PushButton and two Comboboxes,
/// PushButon is used to reset all the RibbonItem, Comboboxes are use to select Level and WallShape
/// 3. contains a RadioButtonGroup for user to select WallType.
/// 4. Adds a Slide-Out Panel to existing panel with following functionalities:
/// 5. a text box is added to set mark for new wall, mark is a instance parameter for wall,
/// Eg: if user set text as "wall", then Mark for each new wall will be "wall1", "wall2", "wall3"....
/// 6. a StackedButton which consisted of a PushButton (delete all the walls) and a PulldownButton (move all the walls in X or Y direction)
/// </summary>
/// <param name="application">An object that is passed to the external application
/// which contains the controlled application.</param>
private void CreateRibbonSamplePanel(UIControlledApplication application)
{
// create a Ribbon panel which contains three stackable buttons and one single push button.
string firstPanelName = "Ribbon Sample";
RibbonPanel ribbonSamplePanel = application.CreateRibbonPanel(firstPanelName);
#region Create a SplitButton for user to create Non-Structural or Structural Wall
SplitButtonData splitButtonData = new SplitButtonData("NewWallSplit", "Create Wall");
SplitButton splitButton = ribbonSamplePanel.AddItem(splitButtonData) as SplitButton;
PushButton pushButton = splitButton.AddPushButton(new PushButtonData("WallPush", "Wall", AddInPath, "Revit.SDK.Samples.Ribbon.CS.CreateWall"));
pushButton.LargeImage = new BitmapImage(new Uri(Path.Combine(ButtonIconsFolder, "CreateWall.png"), UriKind.Absolute));
pushButton.Image = new BitmapImage(new Uri(Path.Combine(ButtonIconsFolder, "CreateWall-S.png"), UriKind.Absolute));
pushButton.ToolTip = "Creates a partition wall in the building model.";
pushButton.ToolTipImage = new BitmapImage(new Uri(Path.Combine(ButtonIconsFolder, "CreateWallTooltip.bmp"), UriKind.Absolute));
pushButton = splitButton.AddPushButton(new PushButtonData("StrWallPush", "Structure Wall", AddInPath, "Revit.SDK.Samples.Ribbon.CS.CreateStructureWall"));
pushButton.LargeImage = new BitmapImage(new Uri(Path.Combine(ButtonIconsFolder, "StrcturalWall.png"), UriKind.Absolute));
pushButton.Image = new BitmapImage(new Uri(Path.Combine(ButtonIconsFolder, "StrcturalWall-S.png"), UriKind.Absolute));
#endregion
ribbonSamplePanel.AddSeparator();
#region Add a StackedButton which is consisted of one PushButton and two Comboboxes
PushButtonData pushButtonData = new PushButtonData("Reset", "Reset", AddInPath, "Revit.SDK.Samples.Ribbon.CS.ResetSetting");
ComboBoxData comboBoxDataLevel = new ComboBoxData("LevelsSelector");
ComboBoxData comboBoxDataShape = new ComboBoxData("WallShapeComboBox");
IList<RibbonItem> ribbonItemsStacked = ribbonSamplePanel.AddStackedItems(pushButtonData, comboBoxDataLevel, comboBoxDataShape);
((PushButton)(ribbonItemsStacked[0])).Image = new BitmapImage(new Uri(Path.Combine(ButtonIconsFolder, "Reset.png"), UriKind.Absolute));
//Add options to WallShapeComboBox
Autodesk.Revit.UI.ComboBox comboboxWallShape = (Autodesk.Revit.UI.ComboBox)(ribbonItemsStacked[2]);
ComboBoxMemberData comboBoxMemberData = new ComboBoxMemberData("RectangleWall", "RectangleWall");
ComboBoxMember comboboxMember = comboboxWallShape.AddItem(comboBoxMemberData);
comboboxMember.Image = new BitmapImage(new Uri(Path.Combine(ButtonIconsFolder, "RectangleWall.png"), UriKind.Absolute));
comboBoxMemberData = new ComboBoxMemberData("CircleWall", "CircleWall");
comboboxMember = comboboxWallShape.AddItem(comboBoxMemberData);
comboboxMember.Image = new BitmapImage(new Uri(Path.Combine(ButtonIconsFolder, "CircleWall.png"), UriKind.Absolute));
comboBoxMemberData = new ComboBoxMemberData("TriangleWall", "TriangleWall");
comboboxMember = comboboxWallShape.AddItem(comboBoxMemberData);
comboboxMember.Image = new BitmapImage(new Uri(Path.Combine(ButtonIconsFolder, "TriangleWall.png"), UriKind.Absolute));
comboBoxMemberData = new ComboBoxMemberData("SquareWall", "SquareWall");
comboboxMember = comboboxWallShape.AddItem(comboBoxMemberData);
comboboxMember.Image = new BitmapImage(new Uri(Path.Combine(ButtonIconsFolder, "SquareWall.png"), UriKind.Absolute));
#endregion
ribbonSamplePanel.AddSeparator();
#region Add a RadioButtonGroup for user to select WallType
RadioButtonGroupData radioButtonGroupData = new RadioButtonGroupData("WallTypeSelector");
RadioButtonGroup radioButtonGroup = (RadioButtonGroup)(ribbonSamplePanel.AddItem(radioButtonGroupData));
ToggleButton toggleButton = radioButtonGroup.AddItem(new ToggleButtonData("Generic8", "Generic - 8\"", AddInPath, "Revit.SDK.Samples.Ribbon.CS.Dummy"));
toggleButton.LargeImage = new BitmapImage(new Uri(Path.Combine(ButtonIconsFolder, "Generic8.png"), UriKind.Absolute));
toggleButton.Image = new BitmapImage(new Uri(Path.Combine(ButtonIconsFolder, "Generic8-S.png"), UriKind.Absolute));
toggleButton = radioButtonGroup.AddItem(new ToggleButtonData("ExteriorBrick", "Exterior - Brick", AddInPath, "Revit.SDK.Samples.Ribbon.CS.Dummy"));
toggleButton.LargeImage = new BitmapImage(new Uri(Path.Combine(ButtonIconsFolder, "ExteriorBrick.png"), UriKind.Absolute));
toggleButton.Image = new BitmapImage(new Uri(Path.Combine(ButtonIconsFolder, "ExteriorBrick-S.png"), UriKind.Absolute));
#endregion
//slide-out panel:
ribbonSamplePanel.AddSlideOut();
#region add a Text box to set the mark for new wall
TextBoxData testBoxData = new TextBoxData("WallMark");
Autodesk.Revit.UI.TextBox textBox = (Autodesk.Revit.UI.TextBox)(ribbonSamplePanel.AddItem(testBoxData));
textBox.Value = "new wall"; //default wall mark
textBox.Image = new BitmapImage(new Uri(Path.Combine(ButtonIconsFolder, "WallMark.png"), UriKind.Absolute));
textBox.ToolTip = "Set the mark for new wall";
textBox.ShowImageAsButton = true;
textBox.EnterPressed += new EventHandler<Autodesk.Revit.UI.Events.TextBoxEnterPressedEventArgs>(SetTextBoxValue);
#endregion
ribbonSamplePanel.AddSeparator();
#region Create a StackedButton which consisted of a PushButton (delete all the walls) and a PulldownButton (move all the walls in X or Y direction)
PushButtonData deleteWallsButtonData = new PushButtonData("deleteWalls", "Delete Walls", AddInPath, "Revit.SDK.Samples.Ribbon.CS.DeleteWalls");
deleteWallsButtonData.ToolTip = "Delete all the walls created by the Create Wall tool.";
deleteWallsButtonData.Image = new BitmapImage(new Uri(Path.Combine(ButtonIconsFolder, "DeleteWalls.png"), UriKind.Absolute));
PulldownButtonData moveWallsButtonData = new PulldownButtonData("moveWalls", "Move Walls");
moveWallsButtonData.ToolTip = "Move all the walls in X or Y direction";
moveWallsButtonData.Image = new BitmapImage(new Uri(Path.Combine(ButtonIconsFolder, "MoveWalls.png"), UriKind.Absolute));
// create stackable buttons
IList<RibbonItem> ribbonItems = ribbonSamplePanel.AddStackedItems(deleteWallsButtonData, moveWallsButtonData);
// add two push buttons as sub-items of the moveWalls PulldownButton.
PulldownButton moveWallItem = ribbonItems[1] as PulldownButton;
PushButton moveX = moveWallItem.AddPushButton(new PushButtonData("XDirection", "X Direction", AddInPath, "Revit.SDK.Samples.Ribbon.CS.XMoveWalls"));
moveX.ToolTip = "move all walls 10 feet in X direction.";
moveX.LargeImage = new BitmapImage(new Uri(Path.Combine(ButtonIconsFolder, "MoveWallsXLarge.png"), UriKind.Absolute));
PushButton moveY = moveWallItem.AddPushButton(new PushButtonData("YDirection", "Y Direction", AddInPath, "Revit.SDK.Samples.Ribbon.CS.YMoveWalls"));
moveY.ToolTip = "move all walls 10 feet in Y direction.";
moveY.LargeImage = new BitmapImage(new Uri(Path.Combine(ButtonIconsFolder, "MoveWallsYLarge.png"), UriKind.Absolute));
#endregion
ribbonSamplePanel.AddSeparator();
application.ControlledApplication.DocumentCreated += new EventHandler<Autodesk.Revit.DB.Events.DocumentCreatedEventArgs>(DocumentCreated);
}
/// <summary>
/// Insert Level into ComboBox - LevelsSelector
/// </summary>
/// <param name="evnetArgs">Autodesk.Revit.DB.Events.DocumentCreatedEventArgs</param>
public void DocumentCreated(object sender, Autodesk.Revit.DB.Events.DocumentCreatedEventArgs e)
{
uiApplication = new UIApplication(e.Document.Application);
List<RibbonPanel> myPanels = uiApplication.GetRibbonPanels();
Autodesk.Revit.UI.ComboBox comboboxLevel = (Autodesk.Revit.UI.ComboBox)(myPanels[0].GetItems()[2]);
if (null == comboboxLevel) { return; }
FilteredElementCollector collector = new FilteredElementCollector(uiApplication.ActiveUIDocument.Document);
ICollection<Element> founds = collector.OfClass(typeof(Level)).ToElements();
foreach (Element elem in founds)
{
Level level = elem as Level;
ComboBoxMemberData comboBoxMemberData = new ComboBoxMemberData(level.Name, level.Name);
ComboBoxMember comboboxMember = comboboxLevel.AddItem(comboBoxMemberData);
comboboxMember.Image = new BitmapImage(new Uri(Path.Combine(ButtonIconsFolder, "LevelsSelector.png"), UriKind.Absolute));
}
//refresh level list (in case user created new level after document created)
comboboxLevel.DropDownOpened += new EventHandler<ComboBoxDropDownOpenedEventArgs>(AddNewLevels);
}
/// <summary>
/// Bind to combobox's DropDownOpened Event, add new levels that created by user.
/// </summary>
/// <param name="evnetArgs">Autodesk.Revit.UI.Events.ComboBoxDropDownOpenedEventArgs</param>
public void AddNewLevels(object sender, ComboBoxDropDownOpenedEventArgs args)
{
Autodesk.Revit.UI.ComboBox comboboxLevel = sender as Autodesk.Revit.UI.ComboBox;
if (null == comboboxLevel) { return; }
FilteredElementCollector collector = new FilteredElementCollector(uiApplication.ActiveUIDocument.Document);
ICollection<Element> founds = collector.OfClass(typeof(Level)).ToElements();
foreach (Element elem in founds)
{
Level level = elem as Level;
bool alreadyContained = false;
foreach (ComboBoxMember comboboxMember in comboboxLevel.GetItems())
{
if (comboboxMember.Name == level.Name)
{
alreadyContained = true;
}
}
if (!alreadyContained)
{
ComboBoxMemberData comboBoxMemberData = new ComboBoxMemberData(level.Name, level.Name);
ComboBoxMember comboboxMember = comboboxLevel.AddItem(comboBoxMemberData);
comboboxMember.Image = new BitmapImage(new Uri(Path.Combine(ButtonIconsFolder, "LevelsSelector.png"), UriKind.Absolute));
}
}
}
/// <summary>
/// Bind to text box's EnterPressed Event, show a dialogue tells user value of test box changed.
/// </summary>
/// <param name="evnetArgs">Autodesk.Revit.UI.Events.TextBoxEnterPressedEventArgs</param>
public void SetTextBoxValue(object sender, TextBoxEnterPressedEventArgs args)
{
TaskDialog.Show("TextBox EnterPressed Event", "New wall's mark changed.");
}
}
}