Files
minecraft-launcher/doc/qml/LoaderRow.md
T
2026-09-03 09:16:56 +03:00

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()
}

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