Исходник menuext - делаем свои настройки в настройках

chromiusj

Известный
Автор темы
Модератор
6,068
4,413
Привет. Это очередная библиотека, наряду с easy_dialog, которая добавляет новый глоток воздуха в ванильную игру. С её помощью можно добавлять свои страницы или отдельные пункты в меню GTA:SA и SA-MP. Работоспособность на сторонних лаунчерах и сборках не гарантируется.
1785949159280.png
Установка: распакуйте архив menuext в папку moonloader/lib/. Внутри должны оказаться файлы menuext_core.dll и menuext.lua.
Идея была взята(и распотрошена) с исходного кода ModLoader. Спасибо thelink2012 за такую возможность в реализации библиотеки
Быстрый старт:
Lua:
local menu = require('menuext')
local cfg = { enabled = true, volume = 50 }

function main()
    menu.ready()  -- ждём загрузку библиотеки
    -- Страница и ссылка в Options перед строкой Back
    local page = menu.page {
        title = 'ilyuxa korovam xvocti krutit',
        open_from = 'OPTIONS',
        insert_before = 'back',
    }
    -- Тумблер. Значение хранится в cfg.enabled
    page:toggle('Enabled', menu.bind(cfg, 'enabled'))
    -- Число со стрелками влево и вправо. Параметры min и max обязательны, step по умолчанию равен 1
    page:number('Volume', menu.bind(cfg, 'volume'), {
        min = 0,
        max = 100,
        step = 5,
        format = '%d%%',
    })
    page:button('Apply', function()
        print(cfg.enabled, cfg.volume)
    end)
    wait(-1)
end

Пример вставки пункта прямо в системную страницу Options:
Lua:
local options = menu.get_page('OPTIONS')

options:toggle('Quick option', menu.bind(cfg, 'flag'), {
    insert_before = 'back',  -- строка ставится перед Back на странице Options
    help = 'Added by script',
})
Полное описание API
Поля
ПолеТипОписание
menu.versionстрокаВерсия библиотеки (сейчас "1.0.0")

Функции
ФункцияВозвращаетОписание
menu.ready([timeout_ms])menuЖдёт готовности библиотеки. Параметр timeout_ms задаёт лимит ожидания в миллисекундах, можно не указывать, аргумент необязательный
menu.page(title) или menu.page(options)PageСоздаёт новую страницу. title может быть строкой или значением menu.gxt(...). options это таблица с параметрами (см. ниже). По умолчанию создаётся ссылка из страницы OPTIONS
menu.get_page(selector)Page или nilИщет уже существующую страницу по alias (например 'OPTIONS'), по индексу страницы от 0 до 126, по значению menu.gxt(...) или принимает уже готовый объект Page
menu.bind(table, key[, on_change])BindingСвязывает пункт меню с полем table[key]. Необязательный on_change вызывается при изменении значения через меню или через item:set. Сигнатура: on_change(new, old[, item, info]). Аргументы item и info присутствуют только если изменение пришло из пункта меню
menu.gxt(key)GXT-маркерСсылка на существующий в игре GXT-ключ длиной от 1 до 7 символов. Для собственного текста используйте обычную строку
menu.unload()-Удаляет все страницы и пункты, созданные текущим скриптом. Вызывать вручную не нужно, функция вызывается автоматически при завершении скрипта

Lua:
local page = menu.page {
    title = 'My settings', -- заголовок страницы
    open_from = 'OPTIONS', -- откуда будет ссылка (по умолчанию OPTIONS)
    insert_before = 'back', -- куда поставить ссылку на странице open_from
    link_label = 'My settings', -- текст ссылки (по умолчанию совпадает с title)
    link_help = 'Open…', -- подсказка при выборе ссылки
    back = true, -- false убирает строку Back; строка или gxt задаёт свой текст
    start_at = 0, -- какая строка будет выделена при входе (индекс от 0 до 11)
}

Параметры menu.page { … }
ПараметрПо умолчаниюОписание
titleобязателенЗаголовок страницы. Обычная строка или значение menu.gxt(...)
open_from'OPTIONS'Страница, с которой будет вести ссылка. Можно указать alias, индекс, объект Page или menu.gxt(...). Значение false отключает создание ссылки
insert_beforeперед Back (если он есть)Позиция ссылки на странице open_from. Подробные правила описаны в спойлере про insert_before
link_labelсовпадает с titleТекст пункта-ссылки на странице open_from
link_helpне заданТекст подсказки, который показывается при выборе ссылки
backстрока Back создаётся автоматическиfalse убирает строку Back. Строка или menu.gxt(...) задаёт для неё свой текст
start_atпервая доступная для выбора строкаИндекс строки, которая будет выделена при входе на страницу. Целое число от 0 до 11
Параметр insert_before задаёт место строки в списке, а не координаты на экране. На одной странице помещается не больше 12 строк с индексами от 0 до 11, включая строку Back.
Параметр используется в двух местах:
  1. в menu.page { insert_before = ... } определяет, куда на странице open_from поставить ссылку на новую страницу;
  2. в методах page:button, page:toggle и остальных определяет, куда на этой же странице поставить создаваемый пункт.
ЗначениеРезультат
"back"Строка ставится перед Back
"end" или falseСтрока ставится в конец списка
число от 0 до 11Строка ставится перед строкой с этим индексом
menu.gxt("KEY") или строка-ключ GXTСтрока ставится перед пунктом с этим GXT-ключом
объект ItemСтрока ставится перед уже созданным пунктом
не указаноПеред Back, если он есть на странице, иначе в конец
Чтобы вставить строку после строки с индексом x, укажите insert_before = x + 1. Если это значение выходит за пределы 11, используйте insert_before = 'end'.
Lua:
local b = menu.bind(cfg, 'volume')

-- или с обработчиком изменения:
local b = menu.bind(cfg, 'volume', function(new, old, item, info)
    -- вызывается при изменении через меню, item:set или Binding:set
    -- item и info присутствуют только если изменение пришло из пункта
end)

page:number('Volume', b, { min = 0, max = 100 })
ДействиеРезультат
Изменение в меню или вызов item:set(value)Значение записывается в cfg[key], текст пункта обновляется, вызывается on_change (если он задан)
Прямое изменение cfg[key] снаружиМеню само об этом не узнает. Нужно вызвать item:refresh()
item:set(value, true)Значение записывается без вызова on_change
Если привязка не используется, значение хранится только внутри самого пункта:
Lua:
page:toggle('Temp', false)
Каждый метод добавляет одну строку на страницу. Позиции строк на экране библиотека выставляет автоматически.
Общие параметры в таблице opts: help (текст подсказки), insert_before и on_change (там, где у пункта есть значение).
МетодВозвращаетОписание
page:button(label, fn[, opts])ItemПри нажатии Enter вызывается fn(item, info). Если функция вернёт true, нажатие Enter передаётся игре дальше
page:label(label[, opts])ItemНевыбираемая строка с текстом
page:toggle(label, src[, opts])ItemПереключатель ON/OFF. src это bool или Binding. Дополнительные параметры: on_text (по умолчанию "ON"), off_text (по умолчанию "OFF"), on_change
page:number(label, src, opts)ItemЧисловое значение, которое меняется стрелками влево и вправо. src это number или Binding. Параметры min и max обязательны. Дополнительно: step (по умолчанию 1), wrap, format (строка вида '%d' или функция), on_change
page:choice(label, src, list[, opts])ItemВыбор одного значения из списка. list это массив строк { 'A', 'B' } или массив таблиц { value = ..., label = ... }. Дополнительно: wrap (по умолчанию true), value_mode ('value' или 'index' от 1 до N), on_change
page:custom(label, src, opts)ItemПункт с произвольной логикой. Обязателен opts.change(value, direction[, info, item]), где direction равен -1 или +1. Дополнительно: format, validate, on_change
page:link(label, target[, opts])ItemПереход на другую страницу. target это объект Page, alias, индекс страницы или menu.gxt(...). Дополнительно: help, insert_before
page:submenu(label[, opts])PageСоздаёт дочернюю страницу и ссылку на неё. Дополнительно: title, help, insert_before, start_at (0…11), back
page:back([label[, opts]])ItemСтрока Back. На нативной странице игры доступна только для чтения (нельзя менять label и help)
page:items()таблицаСписок актуальных объектов Item на странице (включая Back, если он создан скриптом)
page:refresh()pageЗаново читает значения из привязок и обновляет текст пунктов
page:show()pageОткрывает эту страницу
page:remove()boolЕсли страница создана скриптом, удаляет её целиком. Если страница нативная, удаляет только добавленные скриптом пункты
Поля объекта Page (только для чтения)
ПолеОписание
titleЗаголовок страницы
indexИндекс страницы в меню (от 0 до 126). Это не номер строки
ownedtrue, если страница создана текущим скриптом. false, если это нативная страница игры
removedtrue, если страница уже удалена
countКоличество актуальных пунктов, добавленных скриптом на этой странице (без учёта Back)
ЧленОписание
valueЗначение пункта (для типов toggle, number, choice, custom). Доступно для чтения и записи
kindТип пункта: 'button', 'toggle', 'number', 'choice', 'custom', 'link', 'label', 'back' и другие
indexИндекс строки на странице (от 0 до 11)
pageОбъект Page, которому принадлежит пункт
removedtrue, если пункт уже удалён
item:get()Возвращает текущее значение пункта
item:set(value[, silent])Записывает новое значение. Если silent равен true, обработчик on_change не вызывается
item:refresh()Обновляет значение пункта из привязки. Нужен после изменения таблицы в обход меню
item:remove()Убирает строку со страницы
В page:button функция получает аргументы fn(item, info).
В обработчиках on_change сигнатура выглядит так: function(new, old, item, info). Аргумент info присутствует, если изменение пришло из пункта меню.
ПолеВозможные значенияОписание
entertrue или falseБыла ли нажата клавиша Enter
wheel-1, 0 или +1Направление: влево, нет нажатия или вправо
direction-1, 0 или +1Итоговое направление изменения значения. Если wheel не равен нулю, берётся значение wheel. Иначе, если нажат Enter, получается +1. В остальных случаях 0
actionчислоВнутренний код типа действия строки в GTA. В обычных случаях не нужен
Ниже описан полный список экранов меню, куда можно вставить свою страницу. Так как тестировалось не на всех страницах, эффект может быть не предсказуем. Если есть какие-то проблемы, пишите. При создании строку указать необходимо точно так (регистр не важен: options или OPTIONS).
Как использовать:
Lua:
-- ссылка на нашу страницу появится в главном меню
menu.page { title = 'My mod', open_from = 'MAIN_MENU', insert_before = 'back' }
-- то же из Options
menu.page { title = 'My mod', open_from = 'OPTIONS', insert_before = 'back' }
-- вставка пункта в уже существующий экран
local p = menu.get_page('SOUND_SETTINGS')
p:toggle('my grodno hack', menu.bind(cfg, 'x'), { insert_before = 'back' })
Полный список alias: индекс - экран
АлиасыИндексЧто это за экран
STATS0Статистика
NEW_GAME1Новая игра
BRIEFS2Брифинги
SOUND_SETTINGS3Звук (Audio)
DISPLAY_SETTINGS4Экран (Display)
MAP5Карта
NEW_GAME_ASK6Подтверждение новой игры
SELECT_GAME7Выбор игры / слота старта
MISSIONPACK_LOADING_ASK8Mission pack - загрузка
CHOOSE_LOAD_SLOT9Выбор слота загрузки
CHOOSE_DELETE_SLOT10Выбор слота удаления
LOAD_GAME_ASK11Подтверждение загрузки
DELETE_GAME_ASK12Подтверждение удаления
LOAD_FIRST_SAVE13Загрузка первого сейва
DELETE_FINISHED14Удаление завершено
DELETE_SUCCESSFUL15Удаление успешно
CHOOSE_SAVE_SLOT16Выбор слота сохранения
SAVE_WRITE_ASK17Подтверждение записи сейва
SAVE_DONE_118Сейв записан (1)
SAVE_DONE_219Сейв записан (2)
GAME_SAVED20Игра сохранена
GAME_LOADED21Игра загружена
GAME_WARNING_DONT_SAVE22Предупреждение не сохранять
ASK_DISPLAY_DEFAULT_SETS23Сброс настроек экрана?
ASK_AUDIO_DEFAULT_SETS24Сброс настроек звука?
ASK_CONTROLLER_DEFAULT_SETS25Сброс контроллера?
USER_TRACKS_OPTIONS26User Tracks (своя музыка)
DISPLAY_ADVANCED27Доп. настройки экрана
LANGUAGE_SETTINGS28Язык
SAVE_GAME_DONE29Сохранение выполнено
SAVE_GAME_FAILED30Ошибка сохранения
SAVE_WRITE_FAILED31Ошибка записи сейва
SAVE_FAILED_FILE_ERROR32Ошибка файла сейва
OPTIONS33Настройки - главное место для настроек мода
MAIN_MENU34Главное меню (старт игры)
EXIT35Выход
CONTROLLER_PC36Контроллер (PC)
REDEFINE_CONTROLS37Переназначение клавиш
KEYBOARD_CONTROLS38Клавиатура
MOUSE_SETTINGS39Мышь
JOYPAD_SETTINGS40Геймпад
PAUSE_MENU41Меню паузы (ESC в игре)
QUIT42Выход в Windows / quit
EMPTY43Пустая служебная страница
Доступные ограничения:

ПараметрЗначение
Строк на одной странице12 (индексы от 0 до 11), включая Back, label и ссылки
menu.gxt(key)длина ключа от 1 до 7 символов
Свой текст ('строка')длина не ограничена
page.indexот 0 до 126 (индекс страницы, а не строки)
Кириллица в надписях работает так же, как у текстдравов. Поэтому, библиотека передаёт строки как есть. Если текст отображается неправильно, используйте те же функции перекодировки, что и для текстдравов. Добавлять в библиотеку лишний оверхед я не стал.
 

Вложения

  • menuext.rar
    184.8 KB · Просмотры: 5
  • full_demo.lua
    7.9 KB · Просмотры: 0
Последнее редактирование:

chromiusj

Известный
Автор темы
Модератор
6,068
4,413
Забыл добавить список алиасов, куда можно присобачить свои поделки, добавил таблицу