GUI 0.3 — темы, раскладка, выбор клавиши и состояние
Это GUI-часть выпуска 0.3. Новые встроенные функции работают
с пакетами API 0.1/0.2/0.3. Namespace gui зарезервирован SDK.
Сохранение состояния
gui::enabled() можно вызывать без разрешений. Остальные функции требуют storage
в manifest и явного согласия пользователя:
bool gui::enabled();
string gui::get(const string &in key,const string &in fallback='');
void gui::set(const string &in key,const string &in value);
bool gui::contains(const string &in key);
bool gui::remove(const string &in key);
До 64 ключей с обычными SDK-ID, значения — строки до 1024 байт. Файл фиксирован:
data/<package-id>/gui.json. Это отдельное пространство от config.json.
GUI не требует чтения процесса. Без согласия хранения файл не читается/создаётся.
Повторная установка того же значения не помечает состояние изменённым.
Загрузка происходит перед on_load; ошибочный существующий JSON останавливает
запуск, а не перезаписывается. Изменения сохраняются после успешного кадра не
чаще раза в секунду по монотонным часам, а также при успешном Stop/Reload.
Сохранение происходит в worker, вне callback и UI-потока, через отдельный
эксклюзивный временный файл и замену целевого. Ошибка записи сообщает ошибку
сеанса. Reparse points блокируются; гонки с другим локальным процессом не
являются защищённым сценарием. Одновременные экземпляры одного package-id
могут перезаписать состояние друг друга.
Автосохранение является контрольной точкой: авария после уже успешного
сохранения не откатывает предыдущий файл. Изменения неуспешного callback
не фиксируются; неполученные/несохранённые изменения при аварии могут потеряться.
config.json по-прежнему сохраняется только при успешном unload.
Необязательные помощники
Скопируйте sdk/helpers/menu.as и gui.as в пакет, укажите оба в modules.
Классы easy_gui не зарегистрированы автоматически:
- Tabs: до 8 вкладок, selected index принадлежит скрипту.
- CheckboxGroup: до 16 вариантов; array<bool> values хранит отдельные значения.
- HsvPicker: Hue 0–360, Saturation/Brightness 0–1, Alpha 0–255.
color() возвращает 0xRRGGBBAA; hsv() доступен отдельно для конверсии.
- load_uint: строгое чтение десятичного uint из gui.json, fallback при неверном
типе/переполнении/отсутствии согласия.
Используйте короткие уникальные ID-prefixes. Действуют общие ограничения
геометрии, команд, событий и разрешение render. Вкладки — кнопки в собственном
preview; ни глобальных горячих клавиш, ни игрового ввода нет.
Без storage все элементы работают с временным состоянием.
Пример sdk/templates/gui-panel сохраняет вкладку, три флага, HSV/Alpha,
выбранную клавишу, индекс темы и пять цветов. Загруженные числовые значения
ограничиваются диапазоном. Список выбора и RGBA-пикер остаются в menu.as.
Темы
void ui::theme(uint background,uint panel,uint text,uint accent,uint border);
Цвета имеют формат 0xRRGGBBAA. Вызов требует render и должен быть первой
командой on_frame, до label, элементов меню и render-команд. Палитра действует
только на текущий кадр preview и его ui-элементы. Следующий кадр без theme
возвращает стандартную палитру. render::text сохраняет явно переданный цвет.
Прозрачный overlay не получает непрозрачную подложку из темы. Это не смена
оформления самого менеджера/редактора Easy Universal.
easy_gui::Theme предоставляет preset(0/1/2): Dark / Light / Minimal,
apply(), load(prefix), save(prefix). Пользовательские цвета задаются его полями
background, panel, text, accent, border; сохранение требует storage.
Шаблон позволяет выбрать preset и применить текущий HSV-цвет как accent.
Выбор клавиши
uint ui::keybind(const string &in id,const string &in label,uint code,
float x,float y,float width,float height);
code — Windows VK 0–254, 0 означает отсутствие привязки. Нажмите поле в
preview, затем клавишу. Escape отменяет захват; Backspace/Delete очищают
привязку. F5 во время захвата становится выбранной клавишей, а не Reload.
Повтор удерживаемой клавиши игнорируется. Захват отменяется при потере фокуса,
клике вне поля, исчезновении/полном отсечении поля и перезагрузке preview.
Событие доступно только в соответствующем кадре; скрытое поле не применяет
старые события. Подпись показывает числовой VK.
Это локальный picker, не обработчик игровых действий: нет глобальных hooks,
автоматического ввода в другие процессы, комбинаций модификаторов или mouse
bindings. Click-through overlay не принимает ввод picker. Сохранение и
использование выбранного значения — ответственность скрипта.
Раскладка и прокрутка
easy_gui::BoxLayout: begin(x,y,width,columns,padding,gap), place(span,height,
preferredWidth,alignment), row(), content_height(). До 8 колонок; place возвращает
vec2 и выставляет placedWidth/placedHeight. alignment: 0 слева, 1 по центру,
2 справа. preferredWidth=0 заполняет доступную ширину. Элементы автоматически
переносятся при нехватке колонок; высота строки равна максимальной высоте её
элементов. Это измеряемая ограниченная сетка, не CSS/flexbox.
easy_gui::ScrollPanel: begin(id,contentHeight,x,y,width,height) обновляет поле offset,
ставит ui.scroll и clip. Вычитайте offset из Y содержимого и обязательно
вызывайте end() для парного pop_clip в том же кадре. Работают общие clip/event
квоты SDK. В шаблоне Theme используется такой scroll-panel.
Доступность остаётся ограниченной: нет screen-reader integration и полной
клавиатурной навигации dropdown/вкладок. Эти возможности не заявлены готовыми.