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)
}
При создании этого документа использовался ИИ.