| 298 | } |
| 299 | |
| 300 | void MainScreen::drawBottom(void) const |
| 301 | { |
| 302 | TextPool& text = TextPool::get(); |
| 303 | C2D_SceneBegin(g_bottom); |
| 304 | |
| 305 | if (selected.valid) { |
| 306 | // Header: title name, Save/Extdata segmented control. |
| 307 | C2D_DrawRectSolid(0, 0, 0.5f, 320, HEADER_H, COLOR_SURFACE); |
| 308 | C2D_DrawRectSolid(0, HEADER_H, 0.5f, 320, 1, COLOR_LINE); |
| 309 | |
| 310 | // Segmented Save / Extdata toggle (right-aligned in the header) — laid out |
| 311 | // first so the title name below knows how much width it can use. |
| 312 | const SegGeometry seg = segmentGeometry(); |
| 313 | { |
| 314 | C2D_DrawRectSolid(seg.segX, seg.segY, 0.5f, seg.width(), seg.segH, COLOR_RAISED); |
| 315 | const bool onSave = backupKind == BackupKind::Save; |
| 316 | C2D_DrawRectSolid( |
| 317 | onSave ? seg.segX : seg.segX + seg.cellSaveW, seg.segY, 0.5f, onSave ? seg.cellSaveW : seg.cellExtW, seg.segH, COLOR_ACCENT); |
| 318 | text.draw(i18n::t("main.tab_save"), seg.segX + seg.pad, seg.segY + 2, 0.4f, onSave ? COLOR_WHITE : COLOR_MUTED); |
| 319 | text.draw(i18n::t("main.tab_extdata"), seg.segX + seg.cellSaveW + seg.pad, seg.segY + 2, 0.4f, onSave ? COLOR_MUTED : COLOR_WHITE); |
| 320 | } |
| 321 | |
| 322 | std::string name = text.truncate(selected.name, seg.segX - 8 - 8, 0.5f); |
| 323 | text.draw(name, 8, 4, 0.5f, COLOR_TEXT); |
| 324 | |
| 325 | // Thin info line: cart identifier, media type, favorite. |
| 326 | { |
| 327 | float x = 8; |
| 328 | const float y = 28; |
| 329 | const float sep = 6; |
| 330 | x += text.draw(selected.cartId, x, y, 0.42f, COLOR_MUTED) + sep; |
| 331 | x += text.draw("· " + selected.mediaType, x, y, 0.42f, COLOR_MUTED) + sep; |
| 332 | if (selected.favorite) { |
| 333 | text.draw("· ★ " + i18n::t("main.favorite"), x, y, 0.42f, COLOR_GOLD); |
| 334 | } |
| 335 | } |
| 336 | |
| 337 | // Backups card. Rows (entry 0 "New backup", then existing backups with |
| 338 | // their async sizes) were rebuilt by refreshSelected() when they changed. |
| 339 | C2D_DrawRectSolid(8, 46, 0.5f, 304, 132, COLOR_CARD); |
| 340 | C2D_DrawRectSolid(8, 67, 0.5f, 304, 1, COLOR_LINE); |
| 341 | text.draw(i18n::t("main.backups"), 16, 49, 0.45f, COLOR_MUTED); |
| 342 | { |
| 343 | // Total: shown once the worker has resolved it; until then a "…" placeholder. |
| 344 | std::string meta = selected.backupCount == 0 ? i18n::t("main.no_backups") |
| 345 | : selected.totalSize ? i18n::t("main.backups_meta", |
| 346 | {std::to_string(selected.backupCount), StringUtils::humanBytes(*selected.totalSize)}) |
| 347 | : i18n::t("main.backups_meta_pending", {std::to_string(selected.backupCount)}); |
| 348 | float w = text.width(meta, 0.42f); |
| 349 | text.draw(meta, 312 - 8 - w, 50, 0.42f, COLOR_FAINT); |
| 350 | } |
| 351 | directoryList->draw(g_bottomScrollEnabled); |
| 352 | |
| 353 | // Actions. While multi-selecting, one full-width Backup button replaces the |
| 354 | // per-title Backup/Restore pair and drives the whole tagged batch. |
| 355 | if (MS::multipleSelectionEnabled()) { |
| 356 | buttonBackupAll->text(i18n::t("main.backup_n_selected", {std::to_string(MS::selectedEntries().size())}) + " "); |
| 357 | buttonBackupAll->draw(0.6f, COLOR_RING); |
no test coverage detected