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

+35 -114
View File
@@ -1,134 +1,55 @@
# SeasonalBuildsDialog
# SeasonalBuildsDialog.qml
## Обзор компонента
Каталог сезонных сборок с сервера лаунчера. Таблица показывает всё, что нужно, чтобы решить,
ставить сборку или нет. Остальное делает одна кнопка: создаёт запись сборки, ставит версию игры,
модлоадер и Java и раскладывает файлы. Как это устроено, описано в
[LauncherBackend](../cpp/LauncherBackend.md#сезонные-сборки).
`Minecraft_launcher` — десктопный лаунчер Minecraft на Qt Quick. Кроме сборок, которые
пользователь собирает сам, он умеет ставить готовые сезонные сборки с сервера лаунчера: набор
модов под конкретную версию игры и модлоадер, подготовленный заранее и выдаваемый целиком.
`SeasonalBuildsDialog` — окно этого каталога: таблица со всем, что нужно знать, чтобы решить,
ставить сборку или нет, и одна кнопка, которая делает всё остальное — заводит сборку, ставит
версию игры, модлоадер, Java и раскладывает файлы. Окно также показывает, что установленная
сборка устарела, и предлагает обновить её до свежей ревизии.
Таблица собрана из строк `Row` с фиксированными колонками, а не из `TableView`: в проекте нет ни
одной модели `QAbstractItemModel`, а строки приходят готовыми `QVariantMap` — заводить ради семи
колонок отдельную модель незачем.
## Место в проекте и зависимости
В начале файла объявлена `pragma ComponentBehavior: Bound`. Импортирует `QtQuick` и
`QtQuick.Controls 2.15` — слои `QtQuick.Layouts` здесь не нужны, вся раскладка на якорях и
фиксированных ширинах колонок.
Работает с C++-типом `LauncherBackend` (`launcherbackend.h`, `QML_ELEMENT` в модуле
`Minecraft_launcher`), передаваемым снаружи в свойство `backend`. Читает свойства
`seasonalCatalog`, `seasonalCatalogLoading`, `seasonalCatalogError`, `seasonalInstalling` и `busy`,
вызывает `refreshSeasonalCatalog()` и `installSeasonalBuild()`.
Объявлен в `QML_FILES` модуля (`CMakeLists.txt`). Инстанцируется в [Main](Main.md).
Строки каталога приходят из C++ уже отсортированными и сведёнными с локальными записями — окно
показывает статус, не считая ничего само. Запись содержит поля `id`, `name`, `description`,
`minecraftVersion`, `loaderTitle`, `loaderVersion`, `modCount`, `seasonStart`, `seasonEnd`,
`status`, `revision`, `installedRevision`, `updateAvailable`, `sizeBytes` и `serverUrl`.
## Иерархия и роль
Корневой тип — `Dialog`: модальный, 960×560 px, нулевой внутренний отступ, тёмный фон со
скруглением и акцентной рамкой.
Политика закрытия зависит от состояния: пока идёт установка, окно закрывается только кнопкой
(`Popup.NoAutoClose`), потому что случайный щелчок мимо не должен спрятать единственную видимую
отмену; в остальное время работают Escape и щелчок мимо.
Содержимое — шапка таблицы (`Row` с `Repeater` по `columns`), разделительная линия, список строк и
сообщение по центру для пустого состояния. Строка списка — `Rectangle` высотой 36 px с вложенным
`Row`, который повторяет тот же набор колонок; ширины берутся из общего описания `columns`,
поэтому шапка и строки не могут разъехаться.
Подвал высотой 76 px несёт описание и размер выбранной сборки (они длинные и в таблицу не
помещаются, а решение принимается именно по ним) и две кнопки — обновления списка и установки.
Открывается из [Main](Main.md) кнопкой в правом нижнем углу (`openCatalog()`).
## Свойства
| Свойство | Тип | По умолчанию | Обязательное | Описание |
|----------|-----|--------------|--------------|----------|
| `backend` | `var` | — | **Да** | Экземпляр `LauncherBackend` — источник каталога сезонных сборок и исполнитель установки. |
| `selectedId` | `string` | `""` | Нет | Идентификатор выбранной строки. Хранится по `id`, а не по индексу: список обновляется под руками, и индекс после обновления указывал бы на другую сборку. |
| `columns` | `var` (только чтение) | список из семи колонок | Нет | Описание таблицы: массив объектов с полями `key` (поле записи), `title` (заголовок), `width` (ширина в пикселях) и `align` (выравнивание). Колонки: название, версия, загрузчик, число модов, начало и конец сезона, статус. Ширины собраны в одном месте, потому что их повторяют и шапка, и делегат строки. |
| `entries` | `var` (только чтение) | `backend.seasonalCatalog` | Нет | Строки каталога напрямую из бэкенда. Отбора и сортировки в окне нет. |
| `selectedEntry` | `var` (только чтение) | вычисляется | Нет | Полная запись выбранной сборки или `null`, если ничего не выбрано. От неё зависят подвал и доступность кнопки установки. |
| | |
|---|---|
| `backend` (required) | `LauncherBackend` |
| `selectedId` | выбранная строка, по `id` сборки |
| `columns` | описание колонок: ключ, заголовок, ширина, выравнивание |
## Сигналы
Выбранная строка хранится по `id`, а не по индексу: список может обновиться, пока окно открыто,
и индекс начал бы указывать на другую сборку.
Собственных сигналов компонент не объявляет. Результат работы окна виден через состояние бэкенда:
установка меняет список сборок и запускает загрузку, за ходом которой следит главное окно.
## Таблица
## Методы
Колонки: название, версия, модлоадер с версией, число модов, начало и конец сезона, статус
(«не установлена», «установлена», «доступно обновление»). Ширины заданы в одном месте, `columns`,
и их используют и шапка, и строки.
#### openCatalog() : void
Таблица собрана из `Row` с колонками фиксированной ширины, а не из `TableView`. В проекте нет ни
одной модели на `QAbstractItemModel`, строки приходят из C++ готовыми `QVariantMap`, и заводить
модель ради семи колонок не стоит.
Открывает окно. Обновление каталога происходит само в обработчике `onAboutToShow`, который просит
у бэкенда `refreshSeasonalCatalog(false)` — без принудительного обхода кэша: свежий кэш отвечает
без сети, поэтому вызов при каждом открытии ничего не стоит.
Строки приходят уже отсортированными и сведёнными с локальными записями: окно ничего не считает.
#### formatMb(bytes) : string
Пустой список и ошибка сервера выглядят одинаково пусто, поэтому причина пишется прямо на месте
строк: «загрузка…», «сборок пока нет» или текст `seasonalCatalogError` красным.
Переводит размер в байтах в строку с мегабайтами и одним знаком после запятой. Для нулевого или
отсутствующего значения возвращает пустую строку, чтобы размер просто не попал в строку подвала.
Под таблицей описание выбранной сборки, ревизия, размер архива и установленная ревизия, если она
есть. Описания длинные и в таблицу не помещаются, а решение принимают как раз по ним.
#### cellText(entry, string key) : string
## Кнопки
Возвращает текст ячейки для записи и ключа колонки. Для всех колонок это значение одноимённого
поля записи, приведённое к строке; исключение — колонка загрузчика, где название и версия
склеиваются в одну подпись, а при пустой версии остаётся только название.
- **Обновить список** — `refreshSeasonalCatalog(true)`, мимо кэша. Выключена, пока идёт загрузка.
- **Установить / Обновить** — `installSeasonalBuild(id)`. Подпись зависит от `updateAvailable`.
Выключена, пока лаунчер чем-то занят (`busy`): установка занимает и панель загрузки, и
`.minecraft` целиком.
#### installSelected() : void
Двойной щелчок по строке делает то же, что кнопка установки.
Ставит выбранную сборку. Ничего не делает, если строка не выбрана или лаунчер занят другой
операцией: установка занимает и панель загрузки, и `.minecraft` целиком, поэтому вторую начинать
нельзя. Иначе вызывает `installSeasonalBuild()` у бэкенда.
Каталог обновляется при каждом открытии окна (`refreshSeasonalCatalog(false)`). Свежий кэш отвечает
без сети.
Вызывается кнопкой установки и двойным щелчком по строке.
## Взаимодействие с другими компонентами
**Со стороны родителя.** [Main](Main.md) задаёт `backend` и открывает окно вызовом
`openCatalog()`. Обратной связи наружу через сигналы нет.
**Со стороны бэкенда.** Всё содержимое таблицы — привязка к `seasonalCatalog`, поэтому обновление
каталога и изменение статуса установленной сборки перерисовывают окно сами. Пустое состояние
различает три случая по `seasonalCatalogLoading` и `seasonalCatalogError`: идёт загрузка, сборок
пока нет, произошла ошибка — её текст показывается прямо на месте строк, потому что пустой список
и ошибка выглядят одинаково пустыми.
**Занятость.** Кнопка установки выключается по общему признаку `busy`, кнопка обновления списка —
по `seasonalCatalogLoading` (её подпись при этом меняется на «Обновление…»). Политика закрытия
окна завязана на `seasonalInstalling`.
**Обновление ревизии.** Если у записи выставлен `updateAvailable`, статус в таблице подсвечивается
акцентным цветом, в подвале дописывается установленная ревизия, а кнопка установки называется
«Обновить». Отдельного пути обновления нет — это тот же вызов `installSeasonalBuild()`.
**Ход установки.** Окно не показывает прогресс: за это отвечает плашка
[ProgressPanel](ProgressPanel.md) в главном окне, а отмена — метод `cancelSeasonalInstall()`
бэкенда.
## Пример использования
```qml
SeasonalBuildsDialog {
id: seasonalDialog
parent: Overlay.overlay
backend: launcherBackend
}
Button {
text: qsTr("Сезонные сборки")
onClicked: seasonalDialog.openCatalog()
}
```
Пока идёт установка, окно закрывается только кнопкой. Отменить установку можно на панели загрузки
главного окна, и случайный щелчок мимо окна не должен её закрыть.
---