Settings: its rows in five groups
CI / build (pull_request) Successful in 2m22s
Site / build (pull_request) Successful in 10s

Settings had grown to 21 rows in one list. It opens on five groups (This
device, Display, GNSS and radio, Network, System); Enter opens one, Back
returns to the groups, and Back from the groups leaves Settings.

SettingsMenu holds the groups and which one is open (host-tested: every
setting is in exactly one group). The guide, the how-tos, the README,
the scripts' messages and the firmware's own name the new paths, such as
"Settings > System > Firmware".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0162FokPdvY2KsS4NBfwyWPk
This commit is contained in:
2026-10-10 00:11:52 +02:00
co-authored by Claude Opus 5.5
parent 37335b4829
commit 0c52613b72
43 changed files with 305 additions and 98 deletions
+27 -4
View File
@@ -15,7 +15,9 @@ using Row = SettingsMenu::Row;
void SettingsApp::onEnter() {
page_ = Page::Menu;
menu_.close();
list_.setCount(menu_.count());
list_.select(0);
}
void SettingsApp::warn(const std::string& text) {
@@ -56,7 +58,12 @@ bool SettingsApp::onMenuKey(const KeyEvent& e) {
if (menu_.kind(i) == Kind::Toggle) menu_.toggle(i);
return true;
case Key::Select: break;
default: return false; // Back leaves Settings
case Key::Back:
if (!menu_.close()) return false; // from the groups, Back leaves Settings
list_.setCount(menu_.count());
list_.select(menu_.groupIndex());
return true;
default: return false;
}
editingRow_ = i;
switch (menu_.kind(i)) {
@@ -72,6 +79,11 @@ bool SettingsApp::onMenuKey(const KeyEvent& e) {
break;
case Kind::Toggle: menu_.toggle(i); break;
case Kind::Slider: break;
case Kind::Group:
menu_.open(i);
list_.setCount(menu_.count());
list_.select(0);
break;
case Kind::Page:
switch (menu_.row(i)) {
case Row::Wifi:
@@ -194,16 +206,27 @@ std::vector<std::string> SettingsApp::aboutLines() const {
void SettingsApp::draw(Canvas& c) {
const auto& area = theme::kContent;
switch (page_) {
case Page::Menu:
case Page::Menu: {
// An open group has its name on a line of its own, over its rows.
theme::Rect rows = area;
if (menu_.inGroup()) {
c.setFont(&fonts::bold);
c.setTextDatum(top_left);
c.setTextColor(theme::kMuted);
c.drawString(menu_.title().c_str(), 4, area.y + 1);
rows.y += theme::kLineHeight;
rows.h -= theme::kLineHeight;
}
widgets::list(
c, list_, area, [this](int i) { return menu_.label(i); },
c, list_, rows, [this](int i) { return menu_.label(i); },
[this](int i) {
auto kind = menu_.kind(i);
if (kind == Kind::Page) return std::string(">");
if (kind == Kind::Page || kind == Kind::Group) return std::string(">");
if (kind == Kind::Slider) return "< " + menu_.value(i) + " >";
return menu_.value(i);
});
break;
}
case Page::Text:
c.setFont(&fonts::body);
c.setTextColor(theme::kMuted);