Создание плавающей панели в аддонах Blender

Для размещения элементов пользовательского интерфейса при разработке аддонов Blender кроме обычных панелей (N/T/Properties) и их подпанелей можно использовать и так называемые плавающие панели — появляющиеся на экране в произвольном месте при нажатии пользователем определенного сочетания клавиш или при совершении им какого-либо действия. Простейшим примером таких панелей является панель, появляющаяся при нажатии клавиши f6 сразу после добавления в сцену какого-либо объекта (shift+a).

API Blender предоставляет разработчикам возможность создавать подобные панели для своих аддонов. Рассмотрим процесс создания плавающей панели на примере всплывающего окна с сообщением типа «Messagebox».

В отличие от обычных панелей, имеющих для построения собственный класс-предок bpy.types.Panel, плавающая панель является по сути оператором, обращающемся к определенным функциям оконного менеджера Blender, и соответственно наследуется от стандартного класса bpy.types.Operator.

Перейдем в любимый редактор кода, создадим базовую оболочку для класса MessageBox с уникальным идентификатором «message.messagebox», а так же оформим регистрацию этого класса в API Blender.

Для того, чтобы наш оператор создавал плавающее окно, оформим вызов нужной функции оконного менеджера Blender. Для этого переопределим интерактивную функцию invoke оператора на вызов нужной функции оконного менеджера window_manager:

Функция invoke_props_dialog создает необходимое нам плавающее окно. Во входных параметрах функции можно указать желаемые размеры окна через параметры width и height. Первым параметром в функцию передается указатель на наш текущий оператор MessageBox (self).

В зависимости от вида переданного в нее оператора функция может вернуть разные значения:

  • RUNNING_MODAL — модальный запуск
  • CANCELLED — отмена
  • FINISHED — нормальное завершение
  • PASS_THROUGH — пустой запуск (ничего не сделано)

В общем случае FINISHED будет возвращено по нажатию на кнопку OK, а CANCELLED — просто при закрытии окна (нажатии esc или клике вне его области).

Если invoke возвращает FINISHED наш оператор MessageBox должен выполнить функцию execute. Переопределим ее на вывод сообщения в строку статуса и отладочную консоль:

Код код оператора MessageBox теперь имеет следующий вид:

Для проверки можно создать кнопку в Т-панели, которая будет выводить результат выполнения оператора MessageBox, передавая ему текст «Sample Text»:

Если просто вызывать оконную функцию invoke_props_dialog, на экран будет выведено только базовое окно, состоящее из пустой рамки и кнопки «ОК».

Для того, чтобы расположить на нем нужные элементы интерфейса, нужно переопределить функцию оператора draw. Размещение элементов строится через стандартный объект layout.

Разместим на окне элемент label в который будем помещать текст выводимого сообщения:

Вторая строчка с пустым label нужна лишь для того, чтобы сделать промежуток между сообщением и кнопкой «ОК».

Для того, чтобы выводимое сообщение можно было передавать в наш оператор MessageBox в качестве входного параметра, определим параметр message в классе:

Полный код оператора MessageBox теперь имеет вид:

Это финальный код оператора, при вызове он будет выводить окно с переданным текстовым сообщением.

Кроме текстовых полей на таком окне можно располагать любые элементы интерфейса пользователя — кнопки, метки, чекбоксы, поля ввода и т.д.

Мини-бонус:

Класс MessageBox вполне функционален для использования его в любых аддонах Blender. Его можно сохранить в отдельный файл и если разрабатываемый аддон требует вывода каких-либо сообщений пользователю, можно использовать функционал рассмотренного класса, предварительно импортировав его.