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

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