Public Access
M0 step 7: Settings, About, Storage, first-boot setup
- lib/apps_model (host-tested): SettingsMenu (rows, readable values, choices, validation messages) and SetupWizard (names, Region confirmation, timezone; saves only when finished) - AppManager: modal Apps that Home/Back can't leave (setup wizard) - SettingsApp: all settings plus Storage (usage, erase SD behind a dialog) and About (version, node id, battery, memory, uptime) pages, replacing the temporary Diagnostics App - SetupApp: first-boot wizard, opened modally until SetupDone - Node id and default names derived from the MAC like Meshtastic - Widget demo is now hidden (About, then w) - lib_ldf_mode = deep+ so libraries see each other's headers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
#include "setup_wizard.h"
|
||||
|
||||
#include "choices.h"
|
||||
|
||||
namespace roro {
|
||||
|
||||
SetupWizard::SetupWizard(Settings& settings, std::string defaultLongName, std::string defaultShortName)
|
||||
: settings_(settings), longName_(std::move(defaultLongName)), shortName_(std::move(defaultShortName)) {}
|
||||
|
||||
int SetupWizard::choiceCount() const {
|
||||
if (step_ == Step::Region) return sizeof(kRegions) / sizeof(kRegions[0]);
|
||||
if (step_ == Step::Timezone) return sizeof(kTimezones) / sizeof(kTimezones[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string SetupWizard::choiceLabel(int i) const {
|
||||
return step_ == Step::Region ? kRegions[i].label : kTimezones[i].label;
|
||||
}
|
||||
|
||||
int SetupWizard::selectedChoice() const { return step_ == Step::Region ? region_ : timezone_; }
|
||||
|
||||
void SetupWizard::selectChoice(int i) {
|
||||
if (i < 0 || i >= choiceCount()) return;
|
||||
(step_ == Step::Region ? region_ : timezone_) = i;
|
||||
}
|
||||
|
||||
void SetupWizard::enter(Step step) {
|
||||
step_ = step;
|
||||
error_.clear();
|
||||
if (step == Step::LongName) {
|
||||
editor_ = LineEditor(39);
|
||||
editor_.setText(longName_);
|
||||
} else if (step == Step::ShortName) {
|
||||
editor_ = LineEditor(4);
|
||||
editor_.setText(shortName_);
|
||||
}
|
||||
}
|
||||
|
||||
bool SetupWizard::next() {
|
||||
switch (step_) {
|
||||
case Step::Welcome: enter(Step::LongName); return true;
|
||||
case Step::LongName:
|
||||
if (editor_.text().empty()) {
|
||||
error_ = "Please enter a name";
|
||||
return false;
|
||||
}
|
||||
longName_ = editor_.text();
|
||||
enter(Step::ShortName);
|
||||
return true;
|
||||
case Step::ShortName:
|
||||
if (editor_.text().empty()) {
|
||||
error_ = "Please enter 1 to 4 characters";
|
||||
return false;
|
||||
}
|
||||
shortName_ = editor_.text();
|
||||
enter(Step::Region);
|
||||
return true;
|
||||
case Step::Region: enter(Step::Timezone); return true;
|
||||
case Step::Timezone: enter(Step::Done); return true;
|
||||
case Step::Done:
|
||||
save();
|
||||
finished_ = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetupWizard::back() {
|
||||
switch (step_) {
|
||||
case Step::LongName: longName_ = editor_.text(); enter(Step::Welcome); break;
|
||||
case Step::ShortName: shortName_ = editor_.text(); enter(Step::LongName); break;
|
||||
case Step::Region: enter(Step::ShortName); break;
|
||||
case Step::Timezone: enter(Step::Region); break;
|
||||
case Step::Done: enter(Step::Timezone); break;
|
||||
case Step::Welcome: break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetupWizard::save() {
|
||||
settings_.setString(Setting::LongName, longName_);
|
||||
settings_.setString(Setting::ShortName, shortName_);
|
||||
settings_.setString(Setting::Region, kRegions[region_].value);
|
||||
settings_.setString(Setting::Timezone, kTimezones[timezone_].value);
|
||||
settings_.setBool(Setting::RegionConfirmed, true);
|
||||
settings_.setBool(Setting::SetupDone, true);
|
||||
}
|
||||
|
||||
} // namespace roro
|
||||
Reference in New Issue
Block a user