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

12 KiB

VersionPickerDialog

Обзор компонента

Minecraft_launcher — десктопный лаунчер Minecraft на Qt Quick. Каталог версий Mojang — это около тысячи записей: релизы, снапшоты, старые беты и альфы. Раньше выбор версии был обычным выпадающим списком на всю эту тысячу, и найти в нём, скажем, бету 1.7 можно было только поиском по точному номеру.

VersionPickerDialog заменил тот список отдельным окном: слева категории, справа сами версии с поиском сверху. Категории делят каталог на обозримые части, а поиск работает внутри выбранной. Помимо выбора окно умеет удалять уже скачанные версии — с предупреждением о последствиях, потому что версия весит десятки мегабайт, а поверх неё могут стоять профили модлоадеров.

Окно открывается из карточки сборки, когда пользователь выбирает, на какой версии Minecraft собирается играть.

Место в проекте и зависимости

В начале файла объявлена pragma ComponentBehavior: Bound. Импортирует QtQuick, QtQuick.Controls 2.15 и QtQuick.Layouts 2.15.

Работает с C++-типом LauncherBackend (launcherbackend.h, QML_ELEMENT в модуле Minecraft_launcher), передаваемым снаружи в свойство backend. Читает у него свойства versionCatalog и catalogLoading, вызывает refreshVersionCatalog(), versionRemovalInfo() и removeVersion().

Объявлен в QML_FILES модуля (CMakeLists.txt); использует ресурс images/Trash.svg из RESOURCES того же модуля. Инстанцируется в BuildsDialog.

Каталог приходит из C++ уже отсортированным (новые сверху), поэтому окно только отбирает записи и порядок не трогает. Каждая запись каталога — объект с полями id (идентификатор версии), label (подпись строки), category (ключ категории), installed (скачана ли) и search (предвычисленная строка для поиска в нижнем регистре).

Иерархия и роль

Корневой тип — Dialog: модальный, 720×480 px, нулевой внутренний отступ, закрывается по Escape и щелчку мимо. Оформление задано вручную — тёмный фон со скруглением и акцентной рамкой.

Содержимое — RowLayout из двух частей, разделённых вертикальной линией: колонка категорий шириной 150 px (Repeater по categories) и область версий. В области версий сверху поле поиска, внизу флажок «Только установленные», между ними ListView со строками версий. Строка показывает подпись, галочку для установленной версии и корзину удаления; галочка рядом со строкой — единственное место, где видно, что именно скачано.

Отдельно объявлен вложенный Dialog подтверждения удаления шириной 420 px с красной рамкой. Он привязан к тому же родителю, что и само окно, и центрируется в нём вручную, чтобы не оказаться внутри области выбора.

Пустое состояние списка объясняется текстом по центру, который различает три случая: каталог ещё грузится, каталог пуст (нет соединения) и по фильтру ничего не найдено.

Свойства

Свойство Тип По умолчанию Обязательное Описание
backend var Да Экземпляр LauncherBackend — источник каталога версий и исполнитель удаления.
selectedId string "" Нет Идентификатор выбранной версии. Окно открывается с текущей версией, и по «Отмене» выбор возвращается к ней, потому что результат уходит наружу только через сигнал. Пустая строка — версия не выбрана, кнопка подтверждения выключена.
category string "release" Нет Ключ активной категории. Допустимые значения: release (релизы), snapshot (снапшоты), old_beta (беты), old_alpha (альфы), other (прочие — сюда попадают в том числе установленные профили модлоадеров).
filterText string "" Нет Текст поиска. Сравнивается в нижнем регистре без учёта регистра с полем search записи каталога; поиск идёт внутри активной категории.
installedOnly bool false Нет Показывать только скачанные версии.
categories var (только чтение) список из пяти записей Нет Описание колонки категорий: массив объектов с полями key и переведённым title. Задаёт и порядок пунктов, и набор допустимых значений category.
visibleEntries var (только чтение) вычисляется Нет Отобранные строки каталога: записи активной категории, прошедшие флажок «только установленные» и текст поиска. Порядок наследуется от каталога. Служит моделью списка.

Сигналы

versionChosen(string versionId)

Версия подтверждена — кнопкой «Выбрать», двойным щелчком по строке или клавишей Enter в поле поиска. В параметре приходит идентификатор версии.

Имя не accepted() сознательно: такой сигнал у Dialog уже есть и переопределить его нельзя.

Обработчик — карточка сборки — записывает выбранную версию в сборку. К моменту вызова обработчика окно уже закрыто. При отмене сигнал не испускается, поэтому снаружи ничего откатывать не нужно.

Методы

openFor(string versionId) : void

Открывает окно на переданной версии. Запоминает её в selectedId, очищает поиск, переключается на категорию именно этой версии (а не всегда на релизы), просит бэкенд обновить каталог и прокручивает список к выбранной строке.

categoryOf(string versionId) : string

Возвращает ключ категории версии по каталогу; для неизвестной версии — release.

indexOfSelected() : int

Позиция выбранной версии в visibleEntries или -1, если под текущим фильтром её не видно.

revealSelected() : void

Выставляет текущий индекс списка на выбранную версию и прокручивает список так, чтобы строка оказалась по центру. Вызывается после каждой смены фильтра, категории или удаления.

acceptSelection() : void

Подтверждает выбор: испускает versionChosen() и закрывает окно. При пустом selectedId не делает ничего.

catalogHas(string versionId) : bool

Есть ли версия в каталоге. Нужен после удаления: профиль модлоадера присутствовал в каталоге только потому, что был установлен, и после удаления строка исчезает совсем.

askRemove(string versionId) : void

Спрашивает подтверждение перед удалением. Запрашивает у бэкенда versionRemovalInfo() и, если версия действительно установлена, наполняет окно подтверждения: занимаемый объём, список зависящих профилей модлоадеров и список сборок, которые эту версию используют. Идентификатор запоминается в самом окне подтверждения, потому что к моменту ответа строка под курсором может быть уже другой.

Окно подтверждения объясняет три вещи: файлы удалятся из versions/ и освободится столько-то мегабайт; профили модлоадеров поверх этой версии без неё не запустятся; библиотеки и ресурсы в libraries/ и assets/ общие для всех версий и остаются на месте.

performRemove(string versionId) : void

Удаляет версию через бэкенд. Если удалена была именно выбранная версия и её больше нет в каталоге, снимает выбор. В конце обновляет позицию списка.

Взаимодействие с другими компонентами

Со стороны родителя. BuildsDialog задаёт backend, открывает окно вызовом openFor() с текущей версией сборки и подписывается на versionChosen(), чтобы записать выбор. Никаких других точек входа у окна нет — прямая запись selectedId снаружи не предполагается.

Со стороны бэкенда. versionCatalog и catalogLoading — привязки, от которых зависят и модель списка, и текст пустого состояния: пришедшее обновление каталога пересчитывает visibleEntries само. refreshVersionCatalog() вызывается при открытии окна, removeVersion() — после подтверждения удаления.

Клавиатура. Фокус при открытии уходит в поле поиска. Стрелки вверх и вниз двигают выбор по списку функцией step(), Enter подтверждает выбор, Escape закрывает окно.

Пример использования

VersionPickerDialog {
    id: versionPicker
    parent: Overlay.overlay
    backend: launcherBackend
    onVersionChosen: (versionId) => buildCard.gameVersion = versionId
}

Button {
    text: buildCard.gameVersion || qsTr("Выбрать версию")
    onClicked: versionPicker.openFor(buildCard.gameVersion)
}

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