W ostatnim artykule omówiliśmy, w jaki sposób rozpocząć pracę z Revit API. Przedstawiony przykład przybliżył nam tworzenie nowych funkcji i ich uruchamianie. Nowe funkcje dodawane były pod przyciskiem “External Tools” w sekcji „Add-ins”. To podejście jest oczywiście jak najbardziej poprawne, jednak w przypadku, gdy nasz projekt znacznie urośnie, to nawigowanie po funkcjach z poziomu jednego menu kontekstowego będzie bardzo uciążliwe. W tym artykule zobaczysz, w jaki sposób działa wstążka, panele i elementy, które możemy do niej dodać. Myślę, że ta lekcja będzie równie przydatna, jak poprzednia.
Przygotowanie środowiska
Zaczynamy tak samo, od przygotowania nowego projektu biblioteki (library) w Visual Studio w wersji .net 4.7 lub wyższej. Do referencji podczytujemy pliki RevitAPIUI.dll i RevitAPI.dll. Jeśli to dla Ciebie nowość, koniecznie zobacz poprzedni artykuł (link na dole). Gdy już wszystko gotowe usuń domyślną klasę w projekcie „Class1.cs” i stwórz nową „App.cs”. Nazwa oczywiście dowolna, ja już przyzwyczaiłem się do głównego modułu aplikacji o nazwie właśnie „App.cs”. Nie zapomnij dodać modyfikatora dostępu „public” do nowej klasy. Stworzona klasa będzie dziedziczyć po „IExternalApplication”. Interfejs będzie wymagał zaimplementowania metod „OnShutdown” i „OnShutdown”. Powinno wyglądać to tak, jak u mnie.
using Autodesk.Revit.UI; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Sample2 { public class App : IExternalApplication { public Result OnShutdown(UIControlledApplication application) { return Result.Succeeded; } public Result OnStartup(UIControlledApplication application) { return Result.Succeeded; } } }
Na koniec skopiuj kod z przykładu 1 (lekcja 1). Będziemy tego kodu potrzebowali do testowania naszych przycisków.
Wstążka i panel
Teraz zajmiemy się tworzeniem wstążki. Jeżeli nie wiesz, co to wstążka, to odsyłam do artykułu na Wikipedii, swoją drogą bardzo ciekawa jest historia wstążki (art. w wersji angielskiej). Przydatny tu będzie tutorial zamieszczony na stronie dokumentacji projektu RevitApi. Link do przykładu tworzenia wstążki, panelu i przycisków daję tu. A mój kod poniżej:
public class App : IExternalApplication { public Result OnShutdown(UIControlledApplication application) { return Result.Succeeded; } public Result OnStartup(UIControlledApplication application) { //Tworzy ribbon tab String tabName = "My plugin"; application.CreateRibbonTab(tabName); //Tworzy ribbon panel RibbonPanel _ribbonPanel = application.CreateRibbonPanel(tabName, "Example Panel"); return Result.Succeeded; } }
Dodajemy elementy do panelu
W Revit podobnie, jak w Office, na wstążce możemy umieszczać dowolne komponenty. Komponent taki powinien dziedziczyć po obiekcie „RibbonItem”. Skupmy się jednak na dostępnych elementach, które możemy umieścić na panelu. Do wyboru mamy:
- ComboBox – lista rozwijana.
- TextBox – pole tekstowe.
- PulldownButton – przycisk z rozwijanym menu.
- PushButton – zwykły przycisk.
- RadioButtonGroup – przyciski typu „Toggle”.
- SplitButton – działa jak przycisk do rysowania „Slab” lub „Column”.
Dodajmy więc każdy z nich do naszego panelu.
public Result OnStartup(UIControlledApplication application) { //Ścieżka do Sample2.dll string ExecutingAssemblyPath = @"C:ProgramDataAutodeskRevitAddins2021"; string AddInPath = ExecutingAssemblyPath + "Sample2.dll"; //Tworzy ribbon tab String tabName = "My plugin"; application.CreateRibbonTab(tabName); //Tworzy ribbon panel RibbonPanel _ribbonPanel = application.CreateRibbonPanel(tabName, "Example Panel"); //Tworzy ikony var Ico32 = new BitmapImage(new Uri(ExecutingAssemblyPath + "SampleIco32.png")); //Ikona 32x32px var Ico16 = new BitmapImage(new Uri(ExecutingAssemblyPath + "SampleIco16.png")); //Ikona 16x16px //Dodawanie Textbox TextBoxData testBoxData = new TextBoxData("Textbox1"); //Tworzy nowy element Autodesk.Revit.UI.TextBox textBox = (Autodesk.Revit.UI.TextBox)(_ribbonPanel.AddItem(testBoxData)); //Dodaje textbox do panelu textBox.Value = "Example value"; //wartość początkowa textBox.Image = Ico16; //Dodaje obrazek textBox.ToolTip = "Example tooltip"; //Dodaje dymek textBox.ShowImageAsButton = true; //falga czy obrazek ma działać jak przycisk textBox.EnterPressed += TextBox_EnterPressed; //Wywołanie komendy akceptacji klawiszem Enter lub kliknięciem w przycisk. //Dodawanie Combobox ComboBoxData comboBoxData = new ComboBoxData("comboBox1"); //Tworzy nowy element Autodesk.Revit.UI.ComboBox comboBox = (Autodesk.Revit.UI.ComboBox)(_ribbonPanel.AddItem(comboBoxData)); //Dodaje combobox do panelu //Dodawanie opcji 1 ComboBoxMemberData member1 = new ComboBoxMemberData("option1", "My Option 1"); //Tworzy opcję ComboBoxMember comboboxMember1 = comboBox.AddItem(member1); //Dodaje opcję do combobox comboboxMember1.Image = Ico16; //Dodaje obrazek //Dodawanie opcji 2 ComboBoxMemberData member2 = new ComboBoxMemberData("option2", "My Option 2"); //Tworzy opcję ComboBoxMember comboboxMember2 = comboBox.AddItem(member2); //Dodaje opcję do combobox comboboxMember2.Image = Ico16; //Dodaje obrazek //Dodawanie Push button wraz z ikoną PushButtonData buttonData = new PushButtonData("Button1", "My Button", AddInPath, "Sample2.MyFeature"); //Tworzy szkielet przycisku i odwołanie do funkcji buttonData.LargeImage = Ico32; //Dodaje obrazek var pushButton = _ribbonPanel.AddItem(buttonData) as PushButton; //dodaje przycisk do panelu //Dodawanie SplitButton wraz z dziećmi SplitButtonData splitButtonData = new SplitButtonData("SplitButton1", "My SplitButton"); //Tworzy nowy SplitButton SplitButton splitButton = _ribbonPanel.AddItem(splitButtonData) as SplitButton; //Dodaje go do panelu PushButton pushButton1 = splitButton.AddPushButton(new PushButtonData("Button2", "My Button 2", AddInPath, "Sample2.MyFeature")); //Tworzy nowe dziecko w SplitButton'ie pushButton1.LargeImage = Ico32; //Dodaje obrazek PushButton pushButton2 = splitButton.AddPushButton(new PushButtonData("Button3", "My Button 3", AddInPath, "Sample2.MyFeature")); //Tworzy nowe dziecko w SplitButton'ie pushButton2.LargeImage = Ico32; //Dodaje obrazek //Dodawanie Pull down button wraz dziećmi PulldownButtonData pdbData = new PulldownButtonData("PulldownButton1", "My PulldownButton"); pdbData.LargeImage = Ico32; //Dodaje obrazek RibbonItem item = _ribbonPanel.AddItem(pdbData); //Dodaje przycisk do panelu PulldownButton optionsBtn = item as PulldownButton; //Tworzy opcje przycisku //Tu możesz dodawać również dzieci z własnymi ikonami! optionsBtn.AddPushButton(new PushButtonData("Button4", "My Button 4", AddInPath, "Sample2.MyFeature")); //Tworzy nowe dziecko w PullButton'ie optionsBtn.AddPushButton(new PushButtonData("Button5", "My Button 5", AddInPath, "Sample2.MyFeature")); //Tworzy nowe dziecko w PullButton'ie //Dodawanie RadioButtonGroup wraz z dziećmi RadioButtonGroupData radioButtonGroupData = new RadioButtonGroupData("RadioButtonGroup1"); //Tworz grupę przycisków RadioButtonGroup radioButtonGroup = (RadioButtonGroup)(_ribbonPanel.AddItem(radioButtonGroupData)); //dodaje komponent do panelu //Tworzy pierwszy przycisk i ikonę ToggleButton toggleButton = radioButtonGroup.AddItem(new ToggleButtonData("ToggleButton1", "My ToggleButton 1", AddInPath, "Sample2.MyFeature")); toggleButton.LargeImage = Ico32; //Tworzy drugi przycisk i ikonę toggleButton = radioButtonGroup.AddItem(new ToggleButtonData("ToggleButton2", "My ToggleButton 2", AddInPath, "Sample2.MyFeature")); toggleButton.LargeImage = Ico32; return Result.Succeeded; } private void TextBox_EnterPressed(object sender, Autodesk.Revit.UI.Events.TextBoxEnterPressedEventArgs e) { TaskDialog.Show("Komunikat", "Wprowadzony tekst: " + ((Autodesk.Revit.UI.TextBox)sender).Value.ToString()); }
Do pobrania szablon ikony
, oczywiście jeżeli ktoś chciałby korzystać z mojego szablonu. Ikona powinna być w 96dpi o rozmiarze 32×32 lub 16×16. Najlepiej pobrać szablon i dostosować go do swoich potrzeb.
Uruchomienie
W pierwszym artykule tej serii tworzyliśmy dodatek typu funkcja, a teraz tworzymy już aplikację. Zmieni nam się więc plik inicjujący *.addin. Teraz wklejam bezpośrednio plik „Sample2.dll” oraz pliki ikon „SampleIco16.png” i „SampleIco32.png” do katalogu rozszerzeń (C:ProgramDataAutodeskRevitAddins20xx). Mogę oczywiście stworzyć folder dla całego pluginu, ale musze pamiętać, że w kodzie już wykorzystałem tę ścieżkę do ikon. Dodatkowo w pliku *.addin musiałbym to określić w znaczniku Assembly, ścieżka jest relatywna w tym przypadku. Na koniec sprawdzamy znacznik FullClassName, powinien wyglądać tak [your-namespace].[your-application-class-name], a u mnie tak: „Sample2.App”.
<?xml version="1.0" encoding="utf-8"?> <RevitAddIns> <AddIn Type="Application"> <Name>Sample2</Name> <Assembly>Sample2.dll</Assembly> <AddInId>954a2500-608f-415c-b9dd-1c034d69d000</AddInId> <FullClassName>Sample2.App</FullClassName> <VendorId>Poradnik Inżyniera</VendorId> </AddIn> </RevitAddIns>
Podsumowanie
Efekt końcowy naszej pracy można zobaczyć na zrzucie ekranu (oczywiście został odpowiednio obrobiony, żeby wszystko się zmieściło na jednej rycinie). Najlepszą nauką jest analiza kodu. Polecam przekopiować tę lekcję uruchomić i spróbować przeanalizować linijkę po linijce. Mamy nadzieję, że ta lekcja przyda się wszystkim, którzy zaczynają swoją przygodę z programowaniem w Revit Api.

Zobacz też:
Obraz Harry Strauss z Pixabay