159 lines
12 KiB
Markdown
159 lines
12 KiB
Markdown
# 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](BuildsDialog.md).
|
|
|
|
Каталог приходит из 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](BuildsDialog.md) задаёт `backend`, открывает окно вызовом
|
|
`openFor()` с текущей версией сборки и подписывается на `versionChosen()`, чтобы записать выбор.
|
|
Никаких других точек входа у окна нет — прямая запись `selectedId` снаружи не предполагается.
|
|
|
|
**Со стороны бэкенда.** `versionCatalog` и `catalogLoading` — привязки, от которых зависят и
|
|
модель списка, и текст пустого состояния: пришедшее обновление каталога пересчитывает
|
|
`visibleEntries` само. `refreshVersionCatalog()` вызывается при открытии окна, `removeVersion()` —
|
|
после подтверждения удаления.
|
|
|
|
**Клавиатура.** Фокус при открытии уходит в поле поиска. Стрелки вверх и вниз двигают выбор по
|
|
списку функцией `step()`, Enter подтверждает выбор, Escape закрывает окно.
|
|
|
|
## Пример использования
|
|
|
|
```qml
|
|
VersionPickerDialog {
|
|
id: versionPicker
|
|
parent: Overlay.overlay
|
|
backend: launcherBackend
|
|
onVersionChosen: (versionId) => buildCard.gameVersion = versionId
|
|
}
|
|
|
|
Button {
|
|
text: buildCard.gameVersion || qsTr("Выбрать версию")
|
|
onClicked: versionPicker.openFor(buildCard.gameVersion)
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
При создании этого документа использовался ИИ.
|