--- title: Создание собственного окна summary: Собственный Lua-интерфейс: frame, таблица, текст, кнопка и корректное закрытие. section: ui kind: example status: example tags: ["ui","окно","интерфейс","Helper","button","lua"] sources: ["https://wiki.egosoft.com/X4%20Foundations%20Wiki/Modding%20Support/Breaking%20Changes/"] --- ## Выберите путь Нужна небольшая настройка? Рассмотрите [готовый API меню настроек](wiki:ui-settings). Нужна новая карточка или действие в существующем меню? Начните с [расширения штатного UI](wiki:extend-ui). Для собственного окна в Lua можно использовать Helper: создать frame, добавить таблицу, строки и widgets, затем отобразить frame. Ни Python, ни сетевой сервис для такого окна не нужны. ## Подключите Lua В `ui.xml` своего расширения объявите файл: ```xml ``` До первого вызова окна убедитесь, что Helper и игровой UI готовы. Загрузка Lua-файла сама по себе не означает, что мир и все меню уже созданы. ## Постройте окно Учебная заготовка для `ui/wiki_panel.lua`. Она регистрирует панель один раз; отображение вызывается отдельным событием после готовности игры. Внутренние callbacks и layer нужно сверять с текущей версией UI. ```lua local menu = { name = "WikiExamplePanel" } menu.onViewCreated = function() end menu.onRowChanged = function() end menu.onSelectElement = function() end function menu.onCloseElement() if menu.shown then Helper.clearFrame(menu, 3) menu.shown = false end end Menus = Menus or {} table.insert(Menus, menu) Helper.registerMenu(menu) local function showPanel() if menu.shown then return end local width = Helper.scaleX(480) local height = Helper.scaleY(150) local frame = Helper.createFrameHandle(menu, { layer = 3, x = (Helper.viewWidth - width) / 2, y = (Helper.viewHeight - height) / 2, width = width, height = height, standardButtons = {}, startAnimation = false, playerControls = true, }) local t = frame:addTable(1, { tabOrder = 1, width = width }) local title = t:addRow(false, {}) title[1]:createText("Hello, X4!", { fontsize = 14 }) local row = t:addRow(true, {}) row[1]:createButton({ height = 28 }):setText("Close") row[1].handlers.onClick = menu.onCloseElement menu.shown = true frame:display() end RegisterEvent("Wiki.ShowPanel", function() showPanel() end) ``` Для отображения отправьте из своего действующего MD-обработчика: ```xml ``` Это фрагмент внутри `actions`. Точку вызова - например, уже работающую кнопку или событие - подключает ваш мод. Пример не добавляет горячую клавишу автоматически. ## Проверьте жизненный цикл Окно должно открываться повторно без накопления callbacks. Проверьте закрытие кнопкой, поведение ESC/контроллера в выбранном контексте, переключение меню и загрузку сейва. Слишком маленькая высота таблицы может скрыть её целиком. Не закрывайте чужой frame на занятом layer и не меняйте глобальное управление игроком ради простого текста. Новая заготовка отдельно в игре не проверялась; она показывает используемые формы Helper, а не гарантирует совместимость со всеми обновлениями X4.