Add progress-dot feedback to Settings Backup/Restore buttons
The SD-bound copy in SettingsBackup::backup()/restore() blocked noticeably with no visual feedback, making the button look frozen. Both functions now accept an optional callback invoked before each of the two file copies, which menu_screen.cpp uses to append dots to the button label in place. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -126,6 +126,27 @@ namespace {
|
|||||||
|
|
||||||
String onOff(bool on) { return I18n::t(on ? StringId::ON : StringId::OFF); }
|
String onOff(bool on) { return I18n::t(on ? StringId::ON : StringId::OFF); }
|
||||||
|
|
||||||
|
// Fortschrittspunkte-Anzeige waehrend SettingsBackup::backup()/restore()
|
||||||
|
// laufen (siehe Aufrufe unten in Page::BackupReset) - diese sind
|
||||||
|
// synchrone, SD-lastige Vorgaenge, die spuerbar dauern koennen und den
|
||||||
|
// Button vorher wie eingefroren wirken liessen. SettingsBackup ruft den
|
||||||
|
// hier uebergebenen Funktionszeiger vor jedem der beiden Kopiervorgaenge
|
||||||
|
// (erst Einstellungen, dann WLAN) auf. Namespace-globale Zeiger/Variablen
|
||||||
|
// statt Lambda-Capture, da ein einfacher C-Funktionszeiger uebergeben
|
||||||
|
// werden muss (kein std::function im Projekt).
|
||||||
|
TFT_eSPI* progressTft = nullptr;
|
||||||
|
Rect progressBtnRect;
|
||||||
|
String progressLabel;
|
||||||
|
uint8_t progressDots = 0;
|
||||||
|
|
||||||
|
void drawProgressStep() {
|
||||||
|
if (!progressTft) return;
|
||||||
|
progressDots++;
|
||||||
|
String label = progressLabel;
|
||||||
|
for (uint8_t i = 0; i < progressDots; i++) label += ".";
|
||||||
|
drawButton(*progressTft, progressBtnRect, label);
|
||||||
|
}
|
||||||
|
|
||||||
String screenTimeoutLabel(uint8_t minutes) {
|
String screenTimeoutLabel(uint8_t minutes) {
|
||||||
String prefix = I18n::t(StringId::MENU_SCREEN_TIMEOUT_PREFIX);
|
String prefix = I18n::t(StringId::MENU_SCREEN_TIMEOUT_PREFIX);
|
||||||
if (minutes == 0) return prefix + I18n::t(StringId::NEVER);
|
if (minutes == 0) return prefix + I18n::t(StringId::NEVER);
|
||||||
@@ -449,12 +470,22 @@ void run(TFT_eSPI& tft) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (backupBtn.contains(tap.x, tap.y)) {
|
if (backupBtn.contains(tap.x, tap.y)) {
|
||||||
bool ok = SettingsBackup::backup();
|
progressTft = &tft;
|
||||||
|
progressBtnRect = backupBtn;
|
||||||
|
progressLabel = I18n::t(StringId::MENU_BACKUP);
|
||||||
|
progressDots = 0;
|
||||||
|
bool ok = SettingsBackup::backup(drawProgressStep);
|
||||||
|
progressTft = nullptr;
|
||||||
showBriefMessage(tft, I18n::t(ok ? StringId::MENU_BACKUP_SAVED : StringId::MENU_BACKUP_FAILED),
|
showBriefMessage(tft, I18n::t(ok ? StringId::MENU_BACKUP_SAVED : StringId::MENU_BACKUP_FAILED),
|
||||||
ok ? TFT_GREEN : TFT_RED);
|
ok ? TFT_GREEN : TFT_RED);
|
||||||
} else if (restoreBtn.contains(tap.x, tap.y)) {
|
} else if (restoreBtn.contains(tap.x, tap.y)) {
|
||||||
if (SettingsBackup::hasBackup()) {
|
if (SettingsBackup::hasBackup()) {
|
||||||
bool ok = SettingsBackup::restore();
|
progressTft = &tft;
|
||||||
|
progressBtnRect = restoreBtn;
|
||||||
|
progressLabel = I18n::t(StringId::MENU_RESTORE);
|
||||||
|
progressDots = 0;
|
||||||
|
bool ok = SettingsBackup::restore(drawProgressStep);
|
||||||
|
progressTft = nullptr;
|
||||||
showBriefMessage(tft, I18n::t(ok ? StringId::MENU_RESTORED : StringId::MENU_RESTORE_FAILED),
|
showBriefMessage(tft, I18n::t(ok ? StringId::MENU_RESTORED : StringId::MENU_RESTORE_FAILED),
|
||||||
ok ? TFT_GREEN : TFT_RED);
|
ok ? TFT_GREEN : TFT_RED);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,20 +33,24 @@ namespace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool backup() {
|
bool backup(void (*onStep)()) {
|
||||||
if (!SdStorage::isMounted()) return false;
|
if (!SdStorage::isMounted()) return false;
|
||||||
SdMutex::Guard guard;
|
SdMutex::Guard guard;
|
||||||
|
|
||||||
|
if (onStep) onStep();
|
||||||
bool okSettings = copyFile(Config::SD_SETTINGS_FILE, SETTINGS_BACKUP_FILE);
|
bool okSettings = copyFile(Config::SD_SETTINGS_FILE, SETTINGS_BACKUP_FILE);
|
||||||
|
if (onStep) onStep();
|
||||||
bool okWifi = copyFile(Config::SD_WIFI_CREDENTIALS_FILE, WIFI_BACKUP_FILE);
|
bool okWifi = copyFile(Config::SD_WIFI_CREDENTIALS_FILE, WIFI_BACKUP_FILE);
|
||||||
return okSettings || okWifi;
|
return okSettings || okWifi;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool restore() {
|
bool restore(void (*onStep)()) {
|
||||||
if (!SdStorage::isMounted()) return false;
|
if (!SdStorage::isMounted()) return false;
|
||||||
SdMutex::Guard guard;
|
SdMutex::Guard guard;
|
||||||
|
|
||||||
|
if (onStep) onStep();
|
||||||
bool okSettings = copyFile(SETTINGS_BACKUP_FILE, Config::SD_SETTINGS_FILE);
|
bool okSettings = copyFile(SETTINGS_BACKUP_FILE, Config::SD_SETTINGS_FILE);
|
||||||
|
if (onStep) onStep();
|
||||||
bool okWifi = copyFile(WIFI_BACKUP_FILE, Config::SD_WIFI_CREDENTIALS_FILE);
|
bool okWifi = copyFile(WIFI_BACKUP_FILE, Config::SD_WIFI_CREDENTIALS_FILE);
|
||||||
return okSettings || okWifi;
|
return okSettings || okWifi;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,14 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
namespace SettingsBackup {
|
namespace SettingsBackup {
|
||||||
bool backup();
|
// onStep (falls angegeben) wird bei jedem der beiden Kopiervorgaenge
|
||||||
bool restore();
|
// (erst Einstellungen, dann WLAN-Zugangsdaten) direkt VOR dem
|
||||||
|
// jeweiligen Kopieren aufgerufen - der aufrufende Screen
|
||||||
|
// (menu_screen.cpp) nutzt das, um waehrend des SD-bedingt spuerbar
|
||||||
|
// langsamen Sicherns/Wiederherstellens Fortschrittspunkte auf dem
|
||||||
|
// Button anzuzeigen, statt dass der Button eingefroren wirkt.
|
||||||
|
bool backup(void (*onStep)() = nullptr);
|
||||||
|
bool restore(void (*onStep)() = nullptr);
|
||||||
bool hasBackup();
|
bool hasBackup();
|
||||||
|
|
||||||
// Loescht den kompletten Flightradar-Ordner von der SD-Karte und
|
// Loescht den kompletten Flightradar-Ordner von der SD-Karte und
|
||||||
|
|||||||
Reference in New Issue
Block a user