Перейти к содержимому

Окна, кнопки и меню

Параметры окон, iframe, кнопок и действий меню импорта и экспорта в editorAPI.

Методы этой страницы создают интерфейс внутри BDEngine. Примеры предполагают, что интерфейс редактора уже готов. При загрузке плагина вместе с редактором дождитесь события bde:started. Регистрация действий импорта и экспорта может выполняться раньше: они появятся после создания меню.

createWindow

editorAPI.createWindow(
name = 'Window',
name_id = 'default',
icon = 'icon-layout-grid',
width = 1100,
height = 550,
minWidth = 500,
minHeight = 400,
closeFunc = () => {}
);

Синхронно создаёт и открывает перемещаемое окно. Возвращает экземпляр окна, а не DOM-элемент. Содержимое добавляется в его container.

Параметр Значение
name Заголовок окна. Используйте собственную строку, без непроверенного HTML
name_id Идентификатор окна. Задайте префикс своего плагина, например my-plugin-preview
icon Класс иконки. Также поддерживается объект { type: 'image', src, fallback }, где fallback - класс запасной иконки
width, height Начальные размеры в CSS-пикселях
minWidth, minHeight Минимальные размеры при изменении пользователем
closeFunc Функция без аргументов, вызываемая при нажатии крестика

closeFunc должен быть функцией, иначе вызов выбросит ошибку API. Одинаковый name_id не переиспользует уже созданное окно: храните ссылку самостоятельно.

const panel = editorAPI.createWindow(
'Предпросмотр', 'my-plugin-preview', 'icon-eye',
700, 450, 400, 300
);
const text = document.createElement('p');
text.textContent = 'Здесь будет предпросмотр плагина.';
panel.container.append(text);

У возвращённого объекта есть следующие операции:

Член Действие
container DOM-контейнер для содержимого плагина
headerAdd DOM-контейнер дополнительных элементов заголовка
focus() Поднимает окно; свёрнутое окно разворачивается
minimize() / restore() Сворачивает / восстанавливает окно
setName(name) Меняет заголовок; строка обрабатывается как HTML
setIcon(icon, updateManager = true) Меняет иконку, по умолчанию обновляет менеджер окон
close() Запускает закрытие и удаление DOM окна

Эти методы синхронны и не возвращают результат. После анимации закрытия windowDiv и container становятся null. Для нового открытия создайте окно заново. Прямой вызов close() не вызывает closeFunc. Если очистка нужна при обоих способах закрытия, вызовите её явно и сделайте повторный вызов безопасным.

createWindowIFrame

editorAPI.createWindowIFrame(
url = 'https://www.block-display.com/',
name = 'Window', name_id = 'default', icon = 'icon-layout-grid',
width = 1100, height = 550, minWidth = 500, minHeight = 400,
closeFunc = () => {}, iframeAttributes = {}
);

Создаёт такое же окно с iframe внутри. Возвращает объект окна с дополнительным свойством iframe; внутренний отступ container устанавливается в 0. url задаёт адрес страницы, остальные параметры окна имеют тот же смысл.

iframeAttributes - объект HTML-атрибутов iframe. Значения null, undefined и false пропускаются, true превращается в пустой атрибут, остальные значения преобразуются в строки. Атрибуты устанавливаются до назначения src.

const help = editorAPI.createWindowIFrame(
'https://docs.bde.gg/plugins/',
'Документация плагинов', 'my-plugin-help', 'icon-book-open',
900, 600, 400, 300, () => {},
{ title: 'Документация', referrerpolicy: 'no-referrer' }
);

Метод не отменяет ограничения браузера: сайт может запрещать встраивание, а доступ к DOM страницы другого origin ограничен. sandbox, allow и другие необходимые атрибуты выбирает плагин; автоматически они не добавляются.

createModalWindow

const modal = editorAPI.createModalWindow(name = 'Window');

Синхронно создаёт скрытое модальное окно и возвращает объект ModalGUI. name - заголовок; элементы содержимого добавляйте в modal.container. Окно уже находится в DOM, но для показа нужен отдельный вызов.

const modal = editorAPI.createModalWindow('Настройки плагина');
const close = document.createElement('button');
close.type = 'button';
close.textContent = 'Готово';
close.addEventListener('click', () => modal.hideModal());
modal.container.append(close);
modal.showModal();

showModal

modal.showModal() показывает существующее окно. Возвращает undefined. Метод скрывает другие модальные компоненты из editor.gui, освобождает интерактивное управление камерой и при необходимости снимает Pointer Lock. Это не общий диспетчер всех модальных окон, созданных сторонними плагинами: переключение между собственными окнами организуйте самостоятельно.

hideModal

modal.hideModal() скрывает окно, сохраняя DOM, содержимое и обработчики. Возвращает undefined. Окно можно повторно показать без повторного создания. Щелчок по фону вызывает тот же метод. В режиме погружения скрытие может откладываться, пока редактор переносит объект.

addButtonDockMenu

editorAPI.addButtonDockMenu(
icon = 'icon-box', name = 'New button', func = () => {}, sound = true
);

Добавляет пункт в меню дока и синхронно возвращает HTMLAnchorElement. icon - класс иконки, name - название пункта, func - обработчик без аргументов. После обработчика меню закрывается и воспроизводится звук. Название вставляется в разметку, поэтому используйте доверенный текст.

const button = editorAPI.addButtonDockMenu(
'icon-settings', 'Настройки плагина', () => modal.showModal()
);
// Когда пункт больше не нужен:
// button.remove();

В текущей реализации обёртка всегда передаёт sound = true: значение false у этого метода пока не отключает звук. Асинхронный func не ожидается и не блокирует повторные нажатия. Если выполняется длительная операция, управляйте состоянием самостоятельно, например классом disabled возвращённого элемента.

addButtonTool

editorAPI.addButtonTool(icon, func, right = false, sound = true);

Добавляет кнопку в левую (right = false) или правую (right = true) полосу инструментов. Синхронно возвращает HTMLButtonElement.

icon обязателен: одна непустая строка CSS-класса без пробельных символов. func обязателен и должен быть функцией; вызывается без аргументов. Неверные значения вызывают ошибку API. sound = false действительно отключает звук нажатия у этой кнопки.

const button = editorAPI.addButtonTool('icon-info', () => {
console.log('Выбрано объектов:', editorAPI.getSelectedObjects().length);
}, true, false);
button.title = 'Количество выделенных объектов';
button.setAttribute('aria-label', button.title);

Отключение выполняется через button.disabled, удаление - через button.remove(). Promise из обработчика не ожидается: блокировку повторных запусков и обработку ошибок асинхронной операции реализуйте в самом плагине.

addButtonImportMenu

const action = editorAPI.addButtonImportMenu({
id: 'my-plugin-import',
title: 'Импорт плагина',
icon: 'icon-upload',
enabled: true,
onClick(event) { /* открыть выбор файла */ }
});

Регистрирует пункт в Файл > Импорт, после встроенных действий и разделителя. Возвращает управляющий объект синхронно. У Файл > Экспорт тот же контракт.

Поле options Контракт
id Обязательная непустая строка. Идентификатор уникален внутри меню импорта или экспорта; используйте префикс плагина
title Обязательная непустая строка, отображается как текст
icon Необязательный одиночный CSS-класс без пробелов; по умолчанию '', без иконки
onClick Обязательная функция. Получает событие нажатия; может вернуть Promise
enabled Необязательный boolean. Для нового пункта по умолчанию true

Неверные типы или отсутствие обязательных полей вызывают ошибку API. Повторная регистрация того же id обновляет название, иконку и обработчик существующего пункта. Если enabled не передан повторно, его текущее значение сохраняется. Повторный вызов возвращает тот же управляющий объект.

Метод результата Возврат и действие
action.setEnabled(boolean) Меняет доступность и возвращает action для цепочки вызовов
action.remove() Удаляет регистрацию и кнопку. true при первом удалении, false, если регистрация уже отсутствует
action.setEnabled(false);
action.setEnabled(true);
// action.remove();

Во время исполнения пункт блокируется, в том числе на всё время ожидания Promise. Меню закрывается до запуска обработчика. Обработчик вызывается до первого await, чтобы выбор файла мог использовать пользовательское нажатие. Исключения и отклонённые Promise выводятся в консоль с контекстом действия, затем блокировка снимается. Пользовательское сообщение об ошибке организует плагин.

addButtonExportMenu

editorAPI.addButtonExportMenu(options) добавляет действие в Файл > Экспорт. Параметры, возврат, замена по id и ожидание Promise совпадают с импортом. Сам метод не определяет формат экспорта и не получает данные проекта.

const exportAction = editorAPI.addButtonExportMenu({
id: 'my-plugin-inspect-export',
title: 'Получить JSON для плагина',
icon: 'icon-download',
async onClick() {
const data = await editorAPI.exportToJSON(false);
if (data === false) return;
console.log(data);
}
});

Подробности результата и изменения окна экспорта описаны в exportToJSON.

Состояние и повторный запуск

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

Удаление кнопки не снимает обработчики, добавленные к window или document, и не останавливает интервалы, наблюдатели и сетевые запросы. Закрытие окна тоже не является автоматической выгрузкой плагина. Соберите собственную очистку ресурсов и проверьте её по статье Отладка и повторный запуск.

Применить на практике