All checks were successful
Build NRO / build (push) Successful in 1m44s
Only remove PatchExtractor.nro on exit when the Done screen was reached; early quit no longer deletes the NRO. Drop the ineffective mid-run self-delete.
211 lines
7.0 KiB
C++
211 lines
7.0 KiB
C++
#include "patch_activity.hpp"
|
|
|
|
#include <cstdio>
|
|
|
|
namespace {
|
|
bool g_deleteSelfOnExit = false;
|
|
}
|
|
|
|
bool PatchActivity::shouldDeleteSelfOnExit() {
|
|
return g_deleteSelfOnExit;
|
|
}
|
|
|
|
PatchActivity::PatchActivity() {
|
|
extractor = std::make_unique<PatchExtractor>();
|
|
|
|
extractTimer.setCallback([this]() { onExtractTick(); });
|
|
extractTimer.setPeriod(0);
|
|
}
|
|
|
|
PatchActivity::~PatchActivity() {
|
|
extractTimer.stop();
|
|
if (extractor) extractor->close();
|
|
}
|
|
|
|
brls::View* PatchActivity::createContentView() {
|
|
frame = new brls::AppletFrame();
|
|
frame->setTitle("PatchExtractor");
|
|
frame->setIconFromRes("img/omninx.png");
|
|
|
|
contentBox = new brls::Box(brls::Axis::COLUMN);
|
|
contentBox->setAlignItems(brls::AlignItems::CENTER);
|
|
contentBox->setJustifyContent(brls::JustifyContent::CENTER);
|
|
contentBox->setMargins(40, 40, 40, 40);
|
|
contentBox->setGrow(1.0f);
|
|
|
|
titleLabel = new brls::Label();
|
|
titleLabel->setText("PatchExtractor");
|
|
titleLabel->setFontSize(28);
|
|
titleLabel->setHorizontalAlign(brls::HorizontalAlign::CENTER);
|
|
titleLabel->setMarginBottom(16);
|
|
|
|
messageLabel = new brls::Label();
|
|
messageLabel->setHorizontalAlign(brls::HorizontalAlign::CENTER);
|
|
messageLabel->setMarginBottom(12);
|
|
|
|
detailLabel = new brls::Label();
|
|
detailLabel->setHorizontalAlign(brls::HorizontalAlign::CENTER);
|
|
detailLabel->setFontSize(14);
|
|
detailLabel->setMarginBottom(24);
|
|
detailLabel->setVisibility(brls::Visibility::GONE);
|
|
|
|
progressLabel = new brls::Label();
|
|
progressLabel->setHorizontalAlign(brls::HorizontalAlign::CENTER);
|
|
progressLabel->setFontSize(16);
|
|
progressLabel->setMarginBottom(8);
|
|
progressLabel->setVisibility(brls::Visibility::GONE);
|
|
|
|
progressTrack = new brls::Box(brls::Axis::ROW);
|
|
progressTrack->setWidth(600);
|
|
progressTrack->setHeight(12);
|
|
progressTrack->setMarginBottom(24);
|
|
progressTrack->setVisibility(brls::Visibility::GONE);
|
|
|
|
progressFill = new brls::Rectangle(nvgRGB(0, 190, 80));
|
|
progressFill->setHeight(12);
|
|
progressFill->setWidth(0);
|
|
progressTrack->addView(progressFill);
|
|
|
|
actionButton = new brls::Button();
|
|
actionButton->setStyle(&brls::BUTTONSTYLE_PRIMARY);
|
|
actionButton->setWidth(320);
|
|
actionButton->registerClickAction([this](brls::View* view) { return onExtractClicked(view); });
|
|
|
|
contentBox->addView(titleLabel);
|
|
contentBox->addView(messageLabel);
|
|
contentBox->addView(detailLabel);
|
|
contentBox->addView(progressLabel);
|
|
contentBox->addView(progressTrack);
|
|
contentBox->addView(actionButton);
|
|
|
|
frame->setContentView(contentBox);
|
|
return frame;
|
|
}
|
|
|
|
void PatchActivity::onContentAvailable() {
|
|
registerExitAction(brls::BUTTON_START);
|
|
|
|
if (extractor->open()) {
|
|
char detail[128];
|
|
snprintf(detail, sizeof(detail), "%lu Eintraege in patches.zip", extractor->getTotal());
|
|
detailLabel->setText(detail);
|
|
showScreen(Screen::Ready);
|
|
} else {
|
|
detailLabel->setText(PatchExtractor::PATCHES_ZIP);
|
|
detailLabel->setVisibility(brls::Visibility::VISIBLE);
|
|
showScreen(Screen::Error);
|
|
}
|
|
}
|
|
|
|
void PatchActivity::showScreen(Screen screen) {
|
|
currentScreen = screen;
|
|
|
|
progressLabel->setVisibility(brls::Visibility::GONE);
|
|
progressTrack->setVisibility(brls::Visibility::GONE);
|
|
actionButton->setVisibility(brls::Visibility::VISIBLE);
|
|
|
|
switch (screen) {
|
|
case Screen::Error:
|
|
titleLabel->setText("Fehler");
|
|
messageLabel->setText("patches.zip nicht gefunden!");
|
|
detailLabel->setVisibility(brls::Visibility::VISIBLE);
|
|
actionButton->setText("Beenden");
|
|
actionButton->registerClickAction([](brls::View*) {
|
|
brls::Application::quit();
|
|
return true;
|
|
});
|
|
brls::Application::giveFocus(actionButton);
|
|
break;
|
|
|
|
case Screen::Ready:
|
|
titleLabel->setText("OmniNX OC");
|
|
messageLabel->setText("SaltyNX / FPSLocker Patch Installer");
|
|
detailLabel->setVisibility(brls::Visibility::VISIBLE);
|
|
actionButton->setText("Entpacken");
|
|
actionButton->registerClickAction([this](brls::View* view) { return onExtractClicked(view); });
|
|
brls::Application::giveFocus(actionButton);
|
|
break;
|
|
|
|
case Screen::Extracting:
|
|
titleLabel->setText("Entpacken...");
|
|
messageLabel->setText("Bitte nicht beenden, bis der Vorgang abgeschlossen ist!");
|
|
detailLabel->setVisibility(brls::Visibility::VISIBLE);
|
|
progressLabel->setVisibility(brls::Visibility::VISIBLE);
|
|
progressTrack->setVisibility(brls::Visibility::VISIBLE);
|
|
actionButton->setVisibility(brls::Visibility::GONE);
|
|
break;
|
|
|
|
case Screen::Done: {
|
|
g_deleteSelfOnExit = true;
|
|
titleLabel->setText("Fertig");
|
|
const unsigned long ok = extractor->getExtracted() - extractor->getSkipped();
|
|
char msg[128];
|
|
if (extractor->getSkipped() == 0 && extractor->cleanupOk())
|
|
snprintf(msg, sizeof(msg), "Alles erledigt! %lu / %lu entpackt.", ok, extractor->getTotal());
|
|
else
|
|
snprintf(msg, sizeof(msg), "Entpacken abgeschlossen. %lu / %lu entpackt.", ok, extractor->getTotal());
|
|
messageLabel->setText(msg);
|
|
|
|
if (extractor->getSkipped() > 0) {
|
|
char err[64];
|
|
snprintf(err, sizeof(err), "%lu Eintraege fehlgeschlagen.", extractor->getSkipped());
|
|
detailLabel->setText(err);
|
|
detailLabel->setVisibility(brls::Visibility::VISIBLE);
|
|
} else if (!extractor->cleanupOk()) {
|
|
detailLabel->setText("Aufräumen teilweise fehlgeschlagen.");
|
|
detailLabel->setVisibility(brls::Visibility::VISIBLE);
|
|
} else {
|
|
detailLabel->setVisibility(brls::Visibility::GONE);
|
|
}
|
|
|
|
actionButton->setText("Beenden");
|
|
actionButton->setVisibility(brls::Visibility::VISIBLE);
|
|
actionButton->registerClickAction([](brls::View*) {
|
|
brls::Application::quit();
|
|
return true;
|
|
});
|
|
brls::Application::unblockInputs();
|
|
brls::Application::giveFocus(actionButton);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool PatchActivity::onExtractClicked(brls::View* view) {
|
|
(void)view;
|
|
if (currentScreen != Screen::Ready) return false;
|
|
startExtraction();
|
|
return true;
|
|
}
|
|
|
|
void PatchActivity::startExtraction() {
|
|
showScreen(Screen::Extracting);
|
|
brls::Application::blockInputs();
|
|
updateProgressUi();
|
|
extractTimer.start();
|
|
}
|
|
|
|
void PatchActivity::onExtractTick() {
|
|
if (!extractor->step()) {
|
|
extractTimer.stop();
|
|
extractor->close();
|
|
extractor->cleanup();
|
|
updateProgressUi();
|
|
showScreen(Screen::Done);
|
|
return;
|
|
}
|
|
updateProgressUi();
|
|
}
|
|
|
|
void PatchActivity::updateProgressUi() {
|
|
const int pct = extractor->getProgressPercent();
|
|
progressLabel->setText(std::to_string(pct) + "%");
|
|
|
|
constexpr float trackWidth = 600.0f;
|
|
progressFill->setWidth(trackWidth * static_cast<float>(pct) / 100.0f);
|
|
|
|
const std::string& file = extractor->getCurrentFile();
|
|
if (!file.empty())
|
|
detailLabel->setText(file);
|
|
}
|