Font Manager overhaul

This commit is contained in:
jpirnay
2026-05-13 12:39:24 +02:00
parent d337110649
commit d6fd744b3c
21 changed files with 207 additions and 46 deletions
@@ -322,6 +322,8 @@ void OpdsBookBrowserActivity::render(RenderLock&&) {
const int barY = midY + 20;
GUI.drawProgressBar(renderer, Rect{barX, barY, barWidth, barHeight}, downloadProgress, downloadTotal);
}
const auto labels = mappedInput.mapLabels(tr(STR_BACK), "", "", "");
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
renderer.displayBuffer();
return;
}
@@ -535,10 +537,12 @@ void OpdsBookBrowserActivity::downloadBook(const OpdsEntry& book, const OpdsAcqu
const auto result = HttpDownloader::downloadToFile(
downloadUrl, filename,
[this](const size_t downloaded, const size_t total) {
[this](const unsigned int downloaded, const unsigned int total) {
mappedInput.update();
downloadProgress = downloaded;
downloadTotal = total;
requestUpdate(true);
return !mappedInput.wasPressed(MappedInputManager::Button::Back);
},
server.username, server.password);
@@ -583,8 +587,13 @@ void OpdsBookBrowserActivity::downloadBook(const OpdsEntry& book, const OpdsAcqu
std::string sidecarPath = baseFilename + ext;
const auto coverDlResult = HttpDownloader::downloadToFile(
coverUrl, sidecarPath, [this](const size_t, const size_t) { requestUpdate(true); }, server.username,
server.password);
coverUrl, sidecarPath,
[this](const unsigned int, const unsigned int) {
mappedInput.update();
requestUpdate(true);
return !mappedInput.wasPressed(MappedInputManager::Button::Back);
},
server.username, server.password);
if (coverDlResult != HttpDownloader::OK) {
LOG_ERR("OPDS", "Failed to download cover from %s (err %d)", coverUrl.c_str(), (int)coverDlResult);
Storage.remove(sidecarPath.c_str());
@@ -600,6 +609,11 @@ void OpdsBookBrowserActivity::downloadBook(const OpdsEntry& book, const OpdsAcqu
formatSelectionLabels.clear();
state = BrowserState::BROWSING;
requestUpdate();
} else if (result == HttpDownloader::ABORTED) {
selectedBookIndex = -1;
formatSelectionLabels.clear();
state = BrowserState::BROWSING;
requestUpdate();
} else {
selectedBookIndex = -1;
formatSelectionLabels.clear();
@@ -42,7 +42,8 @@ class OpdsBookBrowserActivity final : public Activity {
std::string currentPath;
std::string searchTemplate;
bool consumeConfirm = false;
bool consumeBack = false; // Added missing member
bool consumeBack = false;
bool cancelDownloadRequested = false;
int selectorIndex = 0;
int selectedBookIndex = -1;
int formatSelectorIndex = 0;
@@ -163,10 +163,23 @@ bool FontDownloadActivity::fetchAndParseManifest() {
// --- Download ---
void FontDownloadActivity::downloadAll() {
cancelRequested_ = false;
for (size_t i = 0; i < families_.size(); i++) {
if (families_[i].installed && !families_[i].hasUpdate) continue;
if (families_[i].installed) continue;
downloadFamily(families_[i]);
if (state_ == ERROR) return;
if (state_ == ERROR || cancelRequested_) return;
}
RenderLock lock(*this);
state_ = COMPLETE;
}
void FontDownloadActivity::updateAll() {
cancelRequested_ = false;
for (size_t i = 0; i < families_.size(); i++) {
if (!families_[i].installed || !families_[i].hasUpdate) continue;
downloadFamily(families_[i]);
if (state_ == ERROR || cancelRequested_) return;
}
RenderLock lock(*this);
@@ -176,12 +189,35 @@ void FontDownloadActivity::downloadAll() {
size_t FontDownloadActivity::totalUninstalledSize() const {
size_t total = 0;
for (const auto& f : families_) {
if (!f.installed || f.hasUpdate) total += f.totalSize;
if (!f.installed) total += f.totalSize;
}
return total;
}
size_t FontDownloadActivity::totalUpdateSize() const {
size_t total = 0;
for (const auto& f : families_) {
if (f.installed && f.hasUpdate) total += f.totalSize;
}
return total;
}
bool FontDownloadActivity::hasDownloadCandidates() const {
for (const auto& f : families_) {
if (!f.installed) return true;
}
return false;
}
bool FontDownloadActivity::hasUpdateCandidates() const {
for (const auto& f : families_) {
if (f.installed && f.hasUpdate) return true;
}
return false;
}
void FontDownloadActivity::downloadFamily(ManifestFamily& family) {
cancelRequested_ = false;
{
RenderLock lock(*this);
state_ = DOWNLOADING;
@@ -249,12 +285,23 @@ void FontDownloadActivity::downloadFamily(ManifestFamily& family) {
std::string url = baseUrl_ + file.name;
auto result = HttpDownloader::downloadToFile(url, stagedPath, [this](size_t downloaded, size_t total) {
auto result = HttpDownloader::downloadToFile(url, stagedPath, [this](unsigned int downloaded, unsigned int total) {
mappedInput.update();
fileProgress_ = downloaded;
fileTotal_ = total;
requestUpdate(true);
return !mappedInput.wasPressed(MappedInputManager::Button::Back);
});
if (result == HttpDownloader::ABORTED) {
LOG_INF("FONT", "Download cancelled: %s", file.name.c_str());
Storage.removeDir(stagingDir);
cancelRequested_ = true;
RenderLock lock(*this);
state_ = FAMILY_LIST;
return;
}
if (result != HttpDownloader::OK) {
LOG_ERR("FONT", "Download failed: %s (%d)", file.name.c_str(), result);
Storage.removeDir(stagingDir);
@@ -377,6 +424,7 @@ void FontDownloadActivity::deleteFamilyAtIndex(int familyIndex) {
std::string FontDownloadActivity::confirmButtonLabel() const {
if (families_.empty()) return tr(STR_DOWNLOAD);
if (isDownloadAllSelected()) return tr(STR_DOWNLOAD);
if (isUpdateAllSelected()) return tr(STR_UPDATE);
const auto& family = families_[familyIndexFromList(selectedIndex_)];
if (family.installed && !family.hasUpdate) return tr(STR_DELETE);
if (family.hasUpdate) return tr(STR_UPDATE);
@@ -411,6 +459,9 @@ void FontDownloadActivity::loop() {
if (isDownloadAllSelected()) {
downloadAll();
requestUpdateAndWait();
} else if (isUpdateAllSelected()) {
updateAll();
requestUpdateAndWait();
} else {
const int familyIndex = familyIndexFromList(selectedIndex_);
const auto& family = families_[familyIndex];
@@ -498,18 +549,39 @@ void FontDownloadActivity::render(RenderLock&&) {
Rect{0, contentTop, pageWidth, pageHeight - contentTop - metrics.buttonHintsHeight - metrics.verticalSpacing},
listItemCount(), selectedIndex_,
[this](int index) -> std::string {
if (index == 0) {
return std::string(tr(STR_DOWNLOAD_ALL)) + " (" + formatSize(totalUninstalledSize()) + ")";
if (hasDownloadCandidates()) {
if (index == 0) {
return std::string(tr(STR_DOWNLOAD_ALL)) + " (" + formatSize(totalUninstalledSize()) + ")";
}
if (hasUpdateCandidates() && index == 1) {
return std::string(tr(STR_UPDATE_ALL)) + " (" + formatSize(totalUpdateSize()) + ")";
}
} else if (hasUpdateCandidates() && index == 0) {
return std::string(tr(STR_UPDATE_ALL)) + " (" + formatSize(totalUpdateSize()) + ")";
}
return families_[familyIndexFromList(index)].name;
},
nullptr, nullptr,
[this](int index) -> std::string {
if (index == 0) return "";
if (hasDownloadCandidates()) {
if (index == 0) return "";
if (hasUpdateCandidates() && index == 1) return "";
} else if (hasUpdateCandidates() && index == 0) {
return "";
}
return families_[familyIndexFromList(index)].description;
},
nullptr,
[this](int index) -> std::string {
if (hasDownloadCandidates()) {
if (index == 0) return "";
if (hasUpdateCandidates() && index == 1) return "";
} else if (hasUpdateCandidates() && index == 0) {
return "";
}
const auto& f = families_[familyIndexFromList(index)];
if (f.hasUpdate) return tr(STR_UPDATE_AVAILABLE);
if (f.installed) return tr(STR_INSTALLED);
return f.description;
return "";
},
true);
@@ -538,6 +610,9 @@ void FontDownloadActivity::render(RenderLock&&) {
int percentY = barY + metrics.progressBarHeight + metrics.verticalSpacing;
renderer.drawCenteredText(UI_10_FONT_ID, percentY,
(std::to_string(static_cast<int>(progress * 100)) + "%").c_str());
const auto labels = mappedInput.mapLabels(tr(STR_BACK), "", "", "");
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
} else if (state_ == COMPLETE) {
renderer.drawCenteredText(UI_10_FONT_ID, centerY, tr(STR_FONT_INSTALLED), true, EpdFontFamily::BOLD);
const auto labels = mappedInput.mapLabels(tr(STR_BACK), "", "", "");
+13 -3
View File
@@ -69,15 +69,25 @@ class FontDownloadActivity : public Activity {
int downloadingFamilyIndex_ = 0;
PendingFontAction pendingErrorAction_ = PendingFontAction::None;
std::string errorMessage_;
bool cancelRequested_ = false;
void onWifiSelectionComplete(bool success);
bool fetchAndParseManifest();
void downloadFamily(ManifestFamily& family);
void downloadAll();
bool isDownloadAllSelected() const { return selectedIndex_ == 0 && !families_.empty(); }
int familyIndexFromList(int listIndex) const { return listIndex - 1; }
int listItemCount() const { return families_.empty() ? 0 : static_cast<int>(families_.size()) + 1; }
void updateAll();
bool isDownloadAllSelected() const { return hasDownloadCandidates() && selectedIndex_ == 0; }
bool isUpdateAllSelected() const {
if (!hasUpdateCandidates()) return false;
return selectedIndex_ == (hasDownloadCandidates() ? 1 : 0);
}
bool hasDownloadCandidates() const;
bool hasUpdateCandidates() const;
int actionCount() const { return (hasDownloadCandidates() ? 1 : 0) + (hasUpdateCandidates() ? 1 : 0); }
int familyIndexFromList(int listIndex) const { return listIndex - actionCount(); }
int listItemCount() const { return families_.empty() ? 0 : static_cast<int>(families_.size()) + actionCount(); }
size_t totalUninstalledSize() const;
size_t totalUpdateSize() const;
std::string confirmButtonLabel() const;
void promptDeleteFamily(int familyIndex);