12 KiB
LoaderRow
Обзор компонента
Minecraft_launcher — десктопный лаунчер Minecraft на Qt Quick. Кроме чистой игры он умеет
ставить модлоадеры: Forge, Fabric, NeoForge и Quilt. В карточке сборки лоадер выбирается
чекбоксом, а под ним — конкретная версия лоадера.
LoaderRow — одна такая строка: чекбокс с названием лоадера и, когда он отмечен, выпадающий
список версий именно под выбранную версию Minecraft. Компонент берёт на себя всю возню со
списком версий: подтягивает его из кэша, обновляет по сети, следит, чтобы выбранная версия
всегда существовала под текущую версию игры, и словами объясняет случай «лоадер эту версию игры
не поддерживает» вместо показа пустого списка.
Совместимость компонент не проверяет и проверять не должен: бэкенд отдаёт список, уже собранный под конкретную версию игры, поэтому несовместимой строки в нём не бывает. Пустой список — это и есть отсутствие поддержки.
Место в проекте и зависимости
Импортирует QtQuick и QtQuick.Controls 2.15.
Использует компонент DarkCombo из того же QML-модуля — выпадающий список версий в тёмном стиле окна.
Работает с C++-типом LauncherBackend (launcherbackend.h, зарегистрирован через QML_ELEMENT
в модуле Minecraft_launcher), который передаётся снаружи в свойство backend. Из него
компонент вызывает loaderVersions(), refreshLoaderVersions() и loaderVersionsLoading(), а
также слушает сигнал loaderVersionsChanged.
Объявлен в QML_FILES модуля Minecraft_launcher (CMakeLists.txt). Инстанцируется в
BuildsDialog — по одной строке на каждый поддерживаемый лоадер.
Иерархия и роль
Корневой тип — Column с расстоянием 4 px. Внутри три потомка, видимость которых
взаимоисключающая по нижней части:
CheckBoxс полностью переопределённым индикатором (квадрат со скруглением и галочкой) и подписью. Выключен, пока не выбрана версия игры.- DarkCombo со списком версий лоадера — виден, только когда чекбокс отмечен и список непустой.
- Текстовая строка на месте списка — видна, когда чекбокс отмечен, а список пуст. Пока идёт запрос, она серая и говорит о загрузке; когда запрос закончен, она красноватая и сообщает, что лоадер не поддерживает выбранную версию Minecraft.
Ширина внутренних элементов считается от ширины колонки, поэтому снаружи достаточно задать
width.
Свойства
| Свойство | Тип | По умолчанию | Обязательное | Описание |
|---|---|---|---|---|
backend |
var |
— | Да | Экземпляр LauncherBackend. Через него запрашиваются и обновляются списки версий лоадера. |
loaderKey |
string |
— | Да | Ключ лоадера, которым он опознаётся в бэкенде и в сохранённой сборке: forge, fabric, neoforge, quilt. |
title |
string |
— | Да | Человекочитаемое название лоадера рядом с чекбоксом; оно же подставляется в сообщения о загрузке и об отсутствии поддержки. |
gameVersion |
string |
"" |
Нет | Версия Minecraft, выбранная в карточке. Пустая строка выключает чекбокс. Смена значения сбрасывает выбранную версию лоадера и перезапрашивает список. |
checked |
bool (алиас на чекбокс) |
false |
Нет | Отмечен ли лоадер. Чтение даёт текущее состояние, запись переключает чекбокс программно — без сигнала userChecked(). |
selectedVersion |
string |
"" |
Нет | Выбранная версия лоадера. Устанавливается только через applyEntries(), поэтому всегда либо пуста, либо присутствует в текущем списке. |
entries |
var |
[] |
Нет | Текущий список версий лоадера — массив записей, у каждой есть поля version (значение) и label (подпись для списка). Заполняется из бэкенда. |
applying |
bool |
false |
Нет | Признак того, что строку сейчас заполняет карточка данными сохранённой сборки. Пока он выставлен, изменения не считаются пользовательскими и сигнал changed() не испускается. |
Сигналы
userChecked()
Пользователь сам отметил чекбокс (не программная установка checked). Карточка сборки в ответ
снимает отметки с остальных строк лоадеров: одновременно в .minecraft может жить только один
лоадер.
changed()
Отметка или версия лоадера изменились и это изменение пользовательское. Обработчик — карточка сборки — сохраняет сборку с новыми значениями.
Сигнал сознательно не испускается, пока выставлен applying, то есть при заполнении строки из
уже сохранённой сборки: иначе загрузка карточки сразу же приводила бы к её перезаписи.
Методы
versionIndex(string version) : int
Возвращает позицию версии в текущем массиве entries или -1, если такой версии в списке нет.
Вспомогательная функция для синхронизации выбранного значения с выпадающим списком.
applyEntries(var list) : void
Единственное место, где меняются entries и selectedVersion. Через него проходят все три пути
получения списка — кэш, ответ сети и заполнение из сохранённой сборки, — потому что выбранная
версия обязана существовать в списке под текущую версию игры.
Записывает новый список, а затем проверяет выбранную версию: если её в списке нет, подставляет
первую строку (список отсортирован новыми вперёд, поэтому первая — максимально доступная под эту
версию игры) или пустую строку для пустого списка. Если подстановка изменила значение и строка не
находится в режиме applying, испускает changed(). В конце синхронизирует currentIndex
выпадающего списка.
reload() : void
Перезапрашивает список версий. Если лоадер не отмечен или версия игры не выбрана, очищает список
через applyEntries([]). Иначе сначала берёт список из кэша бэкенда (loaderVersions()) — он
появляется мгновенно, — а затем просит обновление по сети (refreshLoaderVersions()), результат
которого придёт позже сигналом.
applyBuild(string loader, string loaderVersion) : void
Заполняет строку данными сохранённой сборки, не испуская changed(): на время работы выставляет
applying. Отмечает чекбокс, если ключ лоадера сборки совпадает с loaderKey, подставляет версию
из сборки как пожелание и вызывает reload(). Если под выбранную версию игры такой версии
лоадера нет, applyEntries() заменит её на максимально доступную.
Взаимодействие с другими компонентами
Что приходит извне. Карточка сборки в BuildsDialog задаёт backend,
loaderKey, title и привязывает gameVersion к версии Minecraft, выбранной в карточке.
Заполнение сохранённой сборкой идёт вызовом applyBuild() снаружи.
Что уходит наружу. По userChecked() карточка снимает отметки с остальных строк — набор
строк она держит в собственном списке. По changed() карточка сохраняет сборку, читая checked и
selectedVersion.
Бэкенд. Компонент сам подписан на сигнал loaderVersionsChanged(key, game) через
Connections: пришедшее обновление принимается, только если ключ и версия игры совпадают с
текущими и чекбокс отмечен, — иначе ответ относится к другой строке или устарел. Текст в пустом
состоянии опрашивает loaderVersionsLoading(), чтобы отличать «ещё грузим» от «не поддерживается».
Реакция на смену версии игры. Обработчик onGameVersionChanged сбрасывает selectedVersion и
вызывает reload(): сборка лоадера привязана к версии игры, поэтому под новой версией прежний
выбор недействителен.
Пример использования
LoaderRow {
id: forgeRow
width: parent.width
backend: launcherBackend
loaderKey: "forge"
title: "Forge"
gameVersion: buildCard.gameVersion
onUserChecked: buildCard.keepOnly(forgeRow)
onChanged: buildCard.commitSelection()
}
При создании этого документа использовался ИИ.