180 lines
14 KiB
Markdown
180 lines
14 KiB
Markdown
|
|
# BuildsDialog
|
|||
|
|
|
|||
|
|
## Обзор компонента
|
|||
|
|
|
|||
|
|
`Minecraft_launcher` — десктопный лаунчер Minecraft на Qt Quick. Сборка в нём — это именованный
|
|||
|
|
набор «версия игры + модлоадер + адрес сервера» вместе с собственным содержимым `.minecraft`:
|
|||
|
|
модами, конфигами и мирами. Активная сборка одна, её содержимое лежит в `.minecraft`, остальные
|
|||
|
|
хранятся в архивах и разворачиваются при переключении.
|
|||
|
|
|
|||
|
|
`BuildsDialog` — окно управления этими сборками: слева список со сменой активной, справа карточка
|
|||
|
|
выбранной — имя, сервер, версия Minecraft и модлоадеры. Отсюда же сборка ставится (скачивание
|
|||
|
|
версии игры и модлоадера) и удаляется.
|
|||
|
|
|
|||
|
|
Карточка сохраняет правки по ходу редактирования, отдельной кнопки «Сохранить» нет: иначе
|
|||
|
|
появляется неочевидное несохранённое состояние, пока пользователь переключается между сборками в
|
|||
|
|
левом списке.
|
|||
|
|
|
|||
|
|
## Место в проекте и зависимости
|
|||
|
|
|
|||
|
|
В начале файла объявлена `pragma ComponentBehavior: Bound`. Импортирует `QtQuick`,
|
|||
|
|
`QtQuick.Controls 2.15` и `QtQuick.Layouts 2.15`.
|
|||
|
|
|
|||
|
|
Использует три компонента из того же QML-модуля:
|
|||
|
|
|
|||
|
|
- [LabelledField](LabelledField.md) — поля названия сборки и адреса сервера;
|
|||
|
|
- [LoaderRow](LoaderRow.md) — по одной строке на каждый из четырёх модлоадеров;
|
|||
|
|
- [VersionPickerDialog](VersionPickerDialog.md) — вложенное окно выбора версии Minecraft.
|
|||
|
|
|
|||
|
|
Работает с C++-типом `LauncherBackend` (`launcherbackend.h`, `QML_ELEMENT` в модуле
|
|||
|
|
`Minecraft_launcher`) через свойство `backend`. Читает свойства `customBuildNames`,
|
|||
|
|
`activeBuildIndex`, `switching` и `busy`; вызывает `customBuildAt()`, `addCustomBuild()`,
|
|||
|
|
`updateCustomBuild()`, `customBuildRemovalInfo()`, `removeCustomBuild()`, `checkInstallation()`,
|
|||
|
|
`installCustomBuild()` и `refreshVersionCatalog()`; слушает сигнал `installedVersionsChanged`.
|
|||
|
|
|
|||
|
|
Объявлен в `QML_FILES` модуля (`CMakeLists.txt`); использует ресурс `images/Trash.svg`.
|
|||
|
|
Инстанцируется в [Main](Main.md).
|
|||
|
|
|
|||
|
|
## Иерархия и роль
|
|||
|
|
|
|||
|
|
Корневой тип — `Dialog`: модальный, 880×600 px, нулевой внутренний отступ, тёмный фон со
|
|||
|
|
скруглением и акцентной рамкой. Пока идёт смена активной сборки (`backend.switching`), окно
|
|||
|
|
закрывается только кнопкой: архивация и распаковка `.minecraft` не должны прерываться случайным
|
|||
|
|
щелчком мимо.
|
|||
|
|
|
|||
|
|
Содержимое — `RowLayout` из двух частей:
|
|||
|
|
|
|||
|
|
- **Слева** (260 px) список сборок и строка «+ Новая сборка» под ним. Строка списка показывает имя,
|
|||
|
|
пометку «активна» у активной сборки и корзину, появляющуюся при наведении. Вся колонка
|
|||
|
|
выключается на время смены активной сборки.
|
|||
|
|
- **Справа** карточка выбранной сборки внутри `Flickable` — она может не поместиться по высоте.
|
|||
|
|
Карточка выключается и приглушается, когда сборка не выбрана или идёт переключение.
|
|||
|
|
|
|||
|
|
Карточка сверху вниз: название, адрес сервера, поле версии Minecraft, панель модлоадеров и строка
|
|||
|
|
состояния комплектности. Поле версии — не выпадающий список, а прямоугольник, который только
|
|||
|
|
показывает выбор и открывает отдельное окно: версий около тысячи, и разбираться в них удобнее в
|
|||
|
|
окне с категориями.
|
|||
|
|
|
|||
|
|
Отдельно объявлен вложенный `Dialog` подтверждения удаления шириной 420 px с красной рамкой,
|
|||
|
|
привязанный к тому же родителю, что и само окно.
|
|||
|
|
|
|||
|
|
Подвал несёт три кнопки: «Установить», «Сделать активной» и «Закрыть».
|
|||
|
|
|
|||
|
|
## Свойства
|
|||
|
|
|
|||
|
|
| Свойство | Тип | По умолчанию | Обязательное | Описание |
|
|||
|
|
|----------|-----|--------------|--------------|----------|
|
|||
|
|
| `backend` | `var` | — | **Да** | Экземпляр `LauncherBackend` — хранилище сборок и исполнитель установки, удаления и переключения. |
|
|||
|
|
| `editIndex` | `int` | `-1` | Нет | Индекс сборки, открытой в карточке справа. Значение `-1` означает, что карточка пуста и выключена. С активной сборкой не связан: активную меняет отдельная кнопка, чтобы случайный клик по списку не запускал архивацию `.minecraft`. |
|
|||
|
|
| `loading` | `bool` | `false` | Нет | Признак того, что карточка сейчас заполняется данными сборки. Пока он выставлен, обработчики полей не должны писать обратно — иначе открытие сборки немедленно перезаписывало бы её. |
|
|||
|
|
|
|||
|
|
### Внутренняя панель модлоадеров
|
|||
|
|
|
|||
|
|
Панель `loaderPanel` — это `Column` с четырьмя строками [LoaderRow](LoaderRow.md) и собственным
|
|||
|
|
маленьким API. Лоадеры несовместимы между собой: игра запускается ровно с одним профилем
|
|||
|
|
`versions/<id>`, поэтому отметка одного снимает остальные, а «ничего не отмечено» — это чистая
|
|||
|
|
ваниль.
|
|||
|
|
|
|||
|
|
| Свойство панели | Тип | Описание |
|
|||
|
|
|-----------------|-----|----------|
|
|||
|
|
| `rows` | `var` | Массив из четырёх строк лоадеров в порядке показа: Minecraft Forge (`forge`), Fabric Loader (`fabric`), NeoForge (`neoforge`), Quilt Loader (`quilt`). |
|
|||
|
|
|
|||
|
|
Функции панели: `applyBuild(loader, loaderVersion)` раздаёт данные сборки всем строкам;
|
|||
|
|
`selectedRow()` возвращает отмеченную строку или `null`; `keepOnly(row)` очищает все строки,
|
|||
|
|
кроме переданной; `commitSelection()` сохраняет выбор в сборку, записывая ключ лоадера, его версию
|
|||
|
|
и пустой `resolvedVersionId` — профиль появится только после установки, а до неё сборка
|
|||
|
|
запускается на чистой ванили.
|
|||
|
|
|
|||
|
|
## Сигналы
|
|||
|
|
|
|||
|
|
Собственных сигналов компонент не объявляет: все изменения уходят прямо в бэкенд, и о них
|
|||
|
|
остальной интерфейс узнаёт по его сигналам.
|
|||
|
|
|
|||
|
|
## Методы
|
|||
|
|
|
|||
|
|
#### selectBuild(int index) : void
|
|||
|
|
|
|||
|
|
Открывает сборку с указанным индексом в карточке. Читает данные через `customBuildAt()`,
|
|||
|
|
выставляет `loading` на время заполнения полей, раздаёт лоадеры панели через `applyBuild()` и в
|
|||
|
|
конце обновляет строку состояния.
|
|||
|
|
|
|||
|
|
#### askRemove(int index) : void
|
|||
|
|
|
|||
|
|
Спрашивает подтверждение перед удалением: оно необратимо и уносит с собой архив сборки. Запрашивает
|
|||
|
|
`customBuildRemovalInfo()` и наполняет окно подтверждения именем сборки и тремя признаками — есть
|
|||
|
|
ли у неё архив, активна ли она сейчас и последняя ли она. Индекс запоминается в самом окне
|
|||
|
|
подтверждения, потому что к моменту ответа строка списка под курсором может быть уже другой.
|
|||
|
|
|
|||
|
|
Окно подтверждения объясняет последствия по этим признакам: вместе со сборкой удалится её архив, и
|
|||
|
|
моды, конфиги и миры восстановить будет нельзя; активная сборка владеет содержимым `.minecraft`,
|
|||
|
|
оно будет очищено, а на его место развернётся следующая сборка; для последней сборки содержимое
|
|||
|
|
`.minecraft` остаётся на месте.
|
|||
|
|
|
|||
|
|
#### performRemove(int index) : void
|
|||
|
|
|
|||
|
|
Удаляет сборку через бэкенд и восстанавливает состояние карточки: если сборок не осталось,
|
|||
|
|
сбрасывает `editIndex` в `-1`, иначе открывает соседнюю — ту же позицию или последнюю оставшуюся.
|
|||
|
|
|
|||
|
|
#### commit(var fields) : void
|
|||
|
|
|
|||
|
|
Сохраняет часть полей сборки: передаёт `QVariantMap` в `updateCustomBuild()` и обновляет строку
|
|||
|
|
состояния. Ничего не делает во время заполнения карточки (`loading`) и при пустом `editIndex` —
|
|||
|
|
это и есть защита от записи при открытии сборки.
|
|||
|
|
|
|||
|
|
Вызывается по завершении правки каждого поля: имени, адреса сервера, версии Minecraft и выбора
|
|||
|
|
модлоадера.
|
|||
|
|
|
|||
|
|
#### refreshStatus() : void
|
|||
|
|
|
|||
|
|
Пересчитывает строку комплектности под карточкой. Спрашивает у бэкенда `checkInstallation()` и
|
|||
|
|
показывает либо сообщение о готовности к запуску, либо число недостающих файлов вместе с первым из
|
|||
|
|
них. При пустом `editIndex` очищает строку.
|
|||
|
|
|
|||
|
|
#### newBuildName() : string
|
|||
|
|
|
|||
|
|
Придумывает имя для новой сборки: перебирает «Сборка 1», «Сборка 2» и так далее, пока не найдёт
|
|||
|
|
свободное среди существующих имён.
|
|||
|
|
|
|||
|
|
## Взаимодействие с другими компонентами
|
|||
|
|
|
|||
|
|
**Со стороны родителя.** [Main](Main.md) задаёт `backend` и открывает окно. Начальное состояние
|
|||
|
|
окно выбирает само в обработчике `onAboutToShow`: просит обновить каталог версий и открывает
|
|||
|
|
активную сборку, а при пустом списке оставляет карточку выключенной.
|
|||
|
|
|
|||
|
|
**Внутрь — к вложенным компонентам.** Поля [LabelledField](LabelledField.md) сообщают о правке
|
|||
|
|
сигналом `editingFinished`, и карточка сразу вызывает `commit()` с обрезанным по краям значением.
|
|||
|
|
Поле версии открывает [VersionPickerDialog](VersionPickerDialog.md) вызовом `openFor()` и получает
|
|||
|
|
результат сигналом `versionChosen`; запись выбранной версии сама вызывает `commit()` через
|
|||
|
|
обработчик изменения. Строки [LoaderRow](LoaderRow.md) получают `gameVersion` привязкой к
|
|||
|
|
выбранной версии игры, поэтому смена версии Minecraft автоматически перезапрашивает списки версий
|
|||
|
|
лоадеров.
|
|||
|
|
|
|||
|
|
**Наружу — к бэкенду.** Кнопка «Установить» вызывает `installCustomBuild()`, кнопка «Сделать
|
|||
|
|
активной» пишет в свойство `activeBuildIndex`. Обе выключены, пока лаунчер занят (`busy`), а
|
|||
|
|
кнопка активации — ещё и когда выбранная сборка уже активна. Ход установки и переключения
|
|||
|
|
показывает плашка [ProgressPanel](ProgressPanel.md) главного окна, а не это окно.
|
|||
|
|
|
|||
|
|
**Обратная связь от бэкенда.** Окно подписано на `installedVersionsChanged` через `Connections`:
|
|||
|
|
установка версии или модлоадера меняет комплектность сборки, и строка состояния должна это
|
|||
|
|
заметить, не дожидаясь переоткрытия окна.
|
|||
|
|
|
|||
|
|
## Пример использования
|
|||
|
|
|
|||
|
|
```qml
|
|||
|
|
BuildsDialog {
|
|||
|
|
id: buildsDialog
|
|||
|
|
parent: Overlay.overlay
|
|||
|
|
anchors.centerIn: parent
|
|||
|
|
backend: launcherBackend
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Button {
|
|||
|
|
text: qsTr("Сборки")
|
|||
|
|
onClicked: buildsDialog.open()
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
При создании этого документа использовался ИИ.
|