Найти тему

Оформление пользовательской панели с помощью библиотеки AdWindows

Оглавление

Эту статью написал Никита Шишкин, инженер группы водоснабжения и водоотведения отделения инженерного проектирования IBS. С его любезного согласия, я публикую данную статью в своём блоге, с небольшими правками. Статья написана для Revit 2021, для остальных версий, всё будет аналогично.

Данная статья является продолжением статей по созданию и оформлению пользовательской панели на ленте инструментов в Revit.

В статье предложены решения по созданию объектов класса PushButton (кнопки), которые расположены в стеке, с возможностью изменения размера кнопок на панели и скрытия описания напротив них.

Введение

Как выглядят подобные кнопки? На вкладке Изменить и одноименной панели находятся два типа данных кнопок:

Рис. 1. Панель системных инструментов Revit на вкладке Изменить
Рис. 1. Панель системных инструментов Revit на вкладке Изменить

Тип 1 представляет собой стек, состоящий из двух кнопок класса PushButton. Их особенностью является увеличенный размер самой кнопки, которой можно задать иконку размером 24х24 или 32х32 пикселя.

Тип 2 — это стек, состоящий из трех кнопок с уже меньшим размером.

Общей особенностью обоих типов является отсутствие текста напротив кнопки.

Камнем преткновения для создания подобных кнопок является невозможность гибкой настройки с помощью библиотеки RevitAPIUI и пространства имен Autodesk.Revit.UI. Вы не сможете увеличить размер кнопки или скрыть её описание. При попытке задания свойства Text для объекта класса PushButtonData строкой нулевой длины получаем исключение:

Рис. 2. Исключение Autodesk.Revit.Exceptions ArgumentException
Рис. 2. Исключение Autodesk.Revit.Exceptions ArgumentException

О чем собственно заранее нас и предупреждает Revit API, если посмотреть свойство ItemText в классе RibbonItem:

"The text can be changed at run time. a null reference or empty string is not allowed"

Однако, можно добавить спецсимвол, тогда текст исчезнет и плагин загрузится корректно, но только кнопка приобретёт форму прямоугольную, а не квадратную, потому что символ будет отображаться напротив кнопки. В качестве спецсимвола можно добавить пробел нулевой ширины "\u200B".

var buttonData1 = new PushButtonData(buttonName1, "\u200B", assemblyLocation, typeof(ExampleCommand).FullName);

Это не наш метод.

Использование библиотеки AdWindows

На помощь приходит библиотека AdWindows с пространством имен Autodesk.Windows. Она позволяет не только получить доступ к ленте Revit, но и управлять ею.

Добавляем новую ссылку в ваш проект:

Рис. 3. Добавление библиотеки AdWindows
Рис. 3. Добавление библиотеки AdWindows

Создаем псевдоним, поскольку Autodesk.Revit.UI использует классы с теми же именами, что и Autodesk.Windows:

using AW= Autodesk.Windows;

Создаем пользовательские вкладку New Tab, панель Solution#1 и кнопки buttonData1..5, затем добавляем кнопки на панель через метод AddStackedItems.

Рис. 4. Основной код
Рис. 4. Основной код

Использую простой код, чтобы начинающим был более понятен. Те, кто поопытнее вполне могут создать собственные методы или классы, а даже и библиотеки. Например ricaun.Revit.UI от Luiz Henrique Cassettari (ricaun). С видеодемонстрацией можно ознакомиться тут.

Впрочем, у него закрытый исходный код, так что сложно понять, как работает эта библиотека (надо читать декомпилированный код в VS), но по видеоразбору и документации к nuget можно узнать, что именно она делает. Есть и open-source решения, например, RevitExtensions от Романа Nice3Point, входящие в его открытый шаблон плагина с автоматической сборкой msi, развёртыванием релиза на GitHub и многими другими фишками (Прим. ред.)

Теперь создаем пользовательский метод, который будет искать кнопку, которая находится на определённой вкладке и панели. RibbonItem в данном случае будет являться PushButton.

Рис. 5. Метод, предназначенный для поиска элемента на панели и вкладке ленты Revit
Рис. 5. Метод, предназначенный для поиска элемента на панели и вкладке ленты Revit

Что делает метод? Он обращается к менеджеру компонентов, который предоставляет ленту инструментов Revit. Далее находит ту вкладку, которую ему указали. Обращаясь к свойству Source каждой панели на вкладке, метод получит не только те элементы, которые находятся на этих панелях, но и названия панелей.

Ключевой частью пользовательского метода является метод FindItem класса RibbonPanel, который возвращает элемент панели, чей Id совпадает с указанным Id.

Как выглядит Id у элемента на ленте Revit? Он имеет нечисловые значения, которые мы привыкли видеть в модели, и начинается с CustomCtrl_%CustomCtrl_%. В качестве разделителя между элементами ленты используется %.

Для наглядности воспользуемся надстройкой RevitLookup и найдем нашу кнопку. Открываем Dashboard и переходим в ComponentManager.

Рис. 6. Панель инструментов надстройки RevitLookup
Рис. 6. Панель инструментов надстройки RevitLookup

Далее ищу значение RevitRibbonControl и проваливаюсь в него. Затем выбираю RibbonTabCollection, после чего нажимаю на панель New Tab и прокручиваю до значения RibbonPanelCollection => RibbonPanelSource, после чего дважды переходим в RibbonItemCollection, а там выбираем любую кнопку и смотрим какое у нее Id. В моем случае Id будет равно CustomCtrl_%CustomCtrl_%New Tab%Solution#1%ButtonTest1.

Рис. 7. Обращаемся к свойствам кнопок через RevitLookup
Рис. 7. Обращаемся к свойствам кнопок через RevitLookup

Дело остаётся за малым. Применяем метод и меняем свойства у полученных кнопок:

Рис. 8. Фрагмент кода, меняющий свойства кнопок, недоступные через Revit.UI
Рис. 8. Фрагмент кода, меняющий свойства кнопок, недоступные через Revit.UI

Копируем файл .addin и библиотеку .dll из нашей сборки в целевую папку Revit, расположенную по пути: %ProgramData%\Autodesk\Revit\Addins\2021

После чего запускаем Revit и наблюдаем на пользовательской панели Solution#1 два стека кнопок.

Рис. 9. Готовый результат
Рис. 9. Готовый результат

В первом стеке находится пара кнопок buttondata1 и buttondata2 с размером иконки равному 24х24 и 32х32 соответственно. Не рекомендую для такой пары использовать изображение 24х24, поскольку габариты самой кнопки больше чем у изображения.

Во втором стеке привычные кнопки маленького размера, за одним исключением – у них скрыто отображение свойства Text.

Заключение

В заключении можно сказать, что библиотека AdWindows позволяет настроить оформление элементов ленты Revit, которое недоступно стандартными инструментами Revit UI. В частности, можно создать кнопки с увеличенным размером и скрыть описание кнопки.

Итоговый код в репозитории Никиты на GitHub

Заключение от автора блога

Пару недель назад Никита написал мне в личку с вопросом, описанным в данной статье. Я сказал ему, куда копать, и предложил написать гайд, если получится. У Никиты получилось, он молодец, и теперь вы тоже знаете, как решить этот вопрос.

Напоминаю про свой телеграм-канал о Revit API. Подписывайтесь на него и успехов в изучении программирования. До новых встреч!

-10