documentation rewrite

Signed-off-by: galeon <dertiellis@gmail.com>
This commit is contained in:
galeon committed 2026-10-11 22:32:13 +03:00
1 parent 1943996608
commit f10b654953
34 files changed
+2099 -4576

No files matched your search

+64 -148
View File
@@ -1,178 +1,94 @@
# BuildsDialog
# BuildsDialog.qml
## Обзор компонента
Окно пользовательских сборок. Слева список, справа карточка выбранной сборки: имя, сервер, версия
Minecraft, модлоадер. Отсюда сборку ставят, делают активной и удаляют.
`Minecraft_launcher` — десктопный лаунчер Minecraft на Qt Quick. Сборка в нём — это именованный
набор «версия игры + модлоадер + адрес сервера» вместе с собственным содержимым `.minecraft`:
модами, конфигами и мирами. Активная сборка одна, её содержимое лежит в `.minecraft`, остальные
хранятся в архивах и разворачиваются при переключении.
Сборка — это версия игры, модлоадер и адрес сервера плюс собственное содержимое `.minecraft`
(моды, конфиги, миры). Активная сборка одна, её файлы разложены в `.minecraft`, остальные лежат в
архивах. Подробнее в [BuildSwitcher](../cpp/BuildSwitcher.md).
`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 с красной рамкой,
привязанный к тому же родителю, что и само окно.
Подвал несёт три кнопки: «Установить», «Сделать активной» и «Закрыть».
Открывается из [Main](Main.md) по кнопке активной сборки.
## Свойства
| Свойство | Тип | По умолчанию | Обязательное | Описание |
|----------|-----|--------------|--------------|----------|
| `backend` | `var` | — | **Да** | Экземпляр `LauncherBackend` — хранилище сборок и исполнитель установки, удаления и переключения. |
| `editIndex` | `int` | `-1` | Нет | Индекс сборки, открытой в карточке справа. Значение `-1` означает, что карточка пуста и выключена. С активной сборкой не связан: активную меняет отдельная кнопка, чтобы случайный клик по списку не запускал архивацию `.minecraft`. |
| `loading` | `bool` | `false` | Нет | Признак того, что карточка сейчас заполняется данными сборки. Пока он выставлен, обработчики полей не должны писать обратно — иначе открытие сборки немедленно перезаписывало бы её. |
| Свойство | Что это |
|----------|---------|
| `backend` (required) | `LauncherBackend` |
| `editIndex` | сборка, открытая в карточке; −1 — ничего не открыто |
| `loading` | карточка сейчас заполняется данными сборки, обработчики полей ничего не записывают |
### Внутренняя панель модлоадеров
`editIndex` не связан с активной сборкой. Щелчок по строке списка только открывает карточку, а
активной сборку делает отдельная кнопка. Иначе случайный щелчок запускал бы архивацию
`.minecraft`.
Панель `loaderPanel` — это `Column` с четырьмя строками [LoaderRow](LoaderRow.md) и собственным
маленьким API. Лоадеры несовместимы между собой: игра запускается ровно с одним профилем
`versions/<id>`, поэтому отметка одного снимает остальные, а «ничего не отмечено» — это чистая
ваниль.
## Как устроено окно
| Свойство панели | Тип | Описание |
|-----------------|-----|----------|
| `rows` | `var` | Массив из четырёх строк лоадеров в порядке показа: Minecraft Forge (`forge`), Fabric Loader (`fabric`), NeoForge (`neoforge`), Quilt Loader (`quilt`). |
Модальный `Dialog` 880×600. Пока идёт смена сборки (`backend.switching`), окно закрывается только
кнопкой, а список и карточка выключены.
Функции панели: `applyBuild(loader, loaderVersion)` раздаёт данные сборки всем строкам;
`selectedRow()` возвращает отмеченную строку или `null`; `keepOnly(row)` очищает все строки,
кроме переданной; `commitSelection()` сохраняет выбор в сборку, записывая ключ лоадера, его версию
и пустой `resolvedVersionId` — профиль появится только после установки, а до неё сборка
запускается на чистой ванили.
**Слева** (260 px) список сборок. У активной пометка «активна», при наведении появляется корзина.
Ниже строка «+ Новая сборка»: создаёт сборку с первым свободным именем вида «Сборка N» и сразу
открывает её.
## Сигналы
**Справа** карточка в `Flickable`, потому что может не поместиться по высоте:
Собственных сигналов компонент не объявляет: все изменения уходят прямо в бэкенд, и о них
остальной интерфейс узнаёт по его сигналам.
- название и адрес сервера ([LabelledField](LabelledField.md));
- версия Minecraft. Это не выпадающий список, а поле, которое открывает
[VersionPickerDialog](VersionPickerDialog.md): версий около тысячи, и выбирать их удобнее в окне
с категориями и поиском;
- четыре строки [LoaderRow](LoaderRow.md): Forge, Fabric, NeoForge, Quilt;
- строка комплектности: «можно запускать» или «не хватает N файлов» и первый из них
(`checkInstallation()`).
## Методы
**Внизу** кнопки «Установить» (`installCustomBuild()`), «Сделать активной» (запись в
`activeBuildIndex`) и «Закрыть». Первые две выключены, пока `busy`. «Сделать активной» выключена
ещё и для уже активной сборки. Прогресс установки и смены сборки показывают панели главного окна.
#### selectBuild(int index) : void
## Сохранение по ходу
Открывает сборку с указанным индексом в карточке. Читает данные через `customBuildAt()`,
выставляет `loading` на время заполнения полей, раздаёт лоадеры панели через `applyBuild()` и в
конце обновляет строку состояния.
Отдельной кнопки «Сохранить» нет. Каждое поле записывается сразу после правки через
`commit(fields)` → `updateCustomBuild()`. Иначе пришлось бы как-то показывать несохранённые правки
при переключении между сборками в списке.
#### askRemove(int index) : void
Чтобы открытие сборки не записывало её саму в себя, на время `selectBuild()` выставляется
`loading`, и `commit()` в это время ничего не делает.
Спрашивает подтверждение перед удалением: оно необратимо и уносит с собой архив сборки. Запрашивает
`customBuildRemovalInfo()` и наполняет окно подтверждения именем сборки и тремя признаками — есть
ли у неё архив, активна ли она сейчас и последняя ли она. Индекс запоминается в самом окне
подтверждения, потому что к моменту ответа строка списка под курсором может быть уже другой.
## Модлоадеры
Окно подтверждения объясняет последствия по этим признакам: вместе со сборкой удалится её архив, и
моды, конфиги и миры восстановить будет нельзя; активная сборка владеет содержимым `.minecraft`,
оно будет очищено, а на его место развернётся следующая сборка; для последней сборки содержимое
`.minecraft` остаётся на месте.
`loaderPanel` держит четыре строки и следит, чтобы был отмечен не больше чем один модлоадер: игра
запускается с одним профилем из `versions/`. Ни одной отметки — ванильная сборка.
#### performRemove(int index) : void
- `applyBuild(loader, loaderVersion)` — раздать данные сборки строкам;
- `selectedRow()` — отмеченная строка или `null`;
- `keepOnly(row)` — снять отметки с остальных (на `userChecked` строки);
- `commitSelection()` — записать `loader`, `loaderVersion` и пустой `resolvedVersionId` (на
`changed` строки). Профиль модлоадера появится только после установки, а до этого сборка
запускается как ванильная.
Удаляет сборку через бэкенд и восстанавливает состояние карточки: если сборок не осталось,
сбрасывает `editIndex` в `-1`, иначе открывает соседнюю — ту же позицию или последнюю оставшуюся.
Строки получают `gameVersion` привязкой к выбранной версии, поэтому смена версии игры сама
перезапрашивает их списки.
#### commit(var fields) : void
## Удаление
Сохраняет часть полей сборки: передаёт `QVariantMap` в `updateCustomBuild()` и обновляет строку
состояния. Ничего не делает во время заполнения карточки (`loading`) и при пустом `editIndex` —
это и есть защита от записи при открытии сборки.
`askRemove(index)` берёт `customBuildRemovalInfo()` и открывает подтверждение. Текст зависит от
трёх признаков:
Вызывается по завершении правки каждого поля: имени, адреса сервера, версии Minecraft и выбора
модлоадера.
- `hasArchive` — вместе со сборкой удалится её архив, моды, конфиги и миры будет не вернуть;
- `active` — содержимое `.minecraft` принадлежит этой сборке, оно будет очищено, и на его место
развернётся следующая;
- `lastOne` — для последней сборки содержимое `.minecraft` остаётся как есть.
#### refreshStatus() : void
Индекс запоминается в самом окне подтверждения, потому что к моменту ответа под курсором может
оказаться другая строка.
Пересчитывает строку комплектности под карточкой. Спрашивает у бэкенда `checkInstallation()` и
показывает либо сообщение о готовности к запуску, либо число недостающих файлов вместе с первым из
них. При пустом `editIndex` очищает строку.
`performRemove(index)` удаляет сборку и открывает соседнюю (ту же позицию или последнюю), а если
сборок не осталось, очищает карточку.
#### 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()
}
```
`onAboutToShow` просит обновить каталог версий и открывает активную сборку (или первую). Через
`Connections` окно слушает `installedVersionsChanged` и обновляет строку комплектности: установка
могла закончиться, пока окно открыто.
---