mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-07-26 14:58:12 +00:00
refactor(ui): align screens to the documented UI conventions
Audit pass against docs/design/solo_ui_framework.md, converging deviations: - prev/next: replace hand-rolled (c == KEY_LEFT || c == KEY_PREV) with keyIsPrev()/keyIsNext() in QuickMsgScreen, RingtoneEditor, TrailScreen, FullscreenMsgView. Two were real rotary-encoder gaps, not just style: NearbyScreen's filter and WaypointsView's hemisphere toggle used raw KEY_LEFT/RIGHT with no encoder twin, so the encoder couldn't drive them. - NearbyScreen's list right column used a manual setCursor(width - getTextWidth(...)) instead of the existing drawTextRightAlign() helper (which also UTF-8-translates) — now uses it, like Diagnostics/Repeater. - RepeaterScreen hand-rolled the whole drawList skeleton (scroll clamp + reserve + row loop + indicator); collapsed onto drawList(). No D-pad behaviour change; more uniform encoder support. Net -19 lines. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -156,8 +156,8 @@ struct FullscreenMsgView {
|
||||
Result handleInput(char c) {
|
||||
if (c == KEY_UP) { if (scroll > 0) scroll--; return NONE; }
|
||||
if (c == KEY_DOWN) { if (scroll < _max_scroll) scroll++; return NONE; }
|
||||
if (c == KEY_LEFT) return NEXT;
|
||||
if (c == KEY_RIGHT) return PREV;
|
||||
if (keyIsPrev(c)) return NEXT; // page between messages (encoder too)
|
||||
if (keyIsNext(c)) return PREV;
|
||||
if (c == KEY_CONTEXT_MENU) return REPLY;
|
||||
if (c == KEY_ENTER || c == KEY_CANCEL) return CLOSE;
|
||||
return NONE;
|
||||
|
||||
@@ -715,8 +715,7 @@ public:
|
||||
if (e.dist_km >= 0.0f) geo::fmtDist(right, sizeof(right), e.dist_km, useImperial());
|
||||
else strncpy(right, "?GPS", sizeof(right));
|
||||
}
|
||||
display.setCursor(display.width() - display.getTextWidth(right) - 2 - reserve, y);
|
||||
display.print(right);
|
||||
display.drawTextRightAlign(display.width() - reserve - 2, y, right);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -779,8 +778,8 @@ public:
|
||||
_detail_refresh_ms = millis();
|
||||
return true;
|
||||
}
|
||||
if (c == KEY_LEFT) { _filter = (_filter + F_COUNT - 1) % F_COUNT; refresh(); return true; }
|
||||
if (c == KEY_RIGHT) { _filter = (_filter + 1) % F_COUNT; refresh(); return true; }
|
||||
if (keyIsPrev(c)) { _filter = (_filter + F_COUNT - 1) % F_COUNT; refresh(); return true; }
|
||||
if (keyIsNext(c)) { _filter = (_filter + 1) % F_COUNT; refresh(); return true; }
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1518,8 +1518,8 @@ public:
|
||||
}
|
||||
// LEFT/RIGHT cycle Notif/Melody in-place (menu stays open).
|
||||
if (!_pin_picker_active && _num_contacts > 0) {
|
||||
bool left = (c == KEY_LEFT || c == KEY_PREV);
|
||||
bool right = (c == KEY_RIGHT || c == KEY_NEXT);
|
||||
bool left = keyIsPrev(c);
|
||||
bool right = keyIsNext(c);
|
||||
if (left || right) {
|
||||
static const char* NOTIF_LABELS[] = { "default", "OFF", "ON" };
|
||||
static const char* ML[] = { "global", "M1", "M2" };
|
||||
@@ -1674,8 +1674,8 @@ public:
|
||||
if (_ctx_menu.active) {
|
||||
// LEFT/RIGHT cycle Notif/Melody/Fav in-place (menu stays open).
|
||||
if (_num_channels > 0) {
|
||||
bool left = (c == KEY_LEFT || c == KEY_PREV);
|
||||
bool right = (c == KEY_RIGHT || c == KEY_NEXT);
|
||||
bool left = keyIsPrev(c);
|
||||
bool right = keyIsNext(c);
|
||||
if (left || right) {
|
||||
static const char* NOTIF_LABELS[] = { "default", "OFF", "ON" };
|
||||
static const char* ML[] = { "global", "M1", "M2" };
|
||||
|
||||
@@ -143,39 +143,21 @@ public:
|
||||
display.setColor(DisplayDriver::LIGHT);
|
||||
display.drawCenteredHeader("REPEATER");
|
||||
|
||||
const int item_h = display.lineStep();
|
||||
const int start_y = display.listStart();
|
||||
int visible = display.listVisible(item_h);
|
||||
if (visible < 1) visible = 1;
|
||||
|
||||
// Config only — live forwarding stats live on Tools › Diagnostics.
|
||||
int total = _item_count;
|
||||
if (_sel < _scroll) _scroll = _sel;
|
||||
if (_sel >= _scroll + visible) _scroll = _sel - visible + 1;
|
||||
int max_scroll = total - visible;
|
||||
if (max_scroll < 0) max_scroll = 0;
|
||||
if (_scroll > max_scroll) _scroll = max_scroll;
|
||||
if (_scroll < 0) _scroll = 0;
|
||||
|
||||
const int reserve = scrollIndicatorReserve(display, total, visible);
|
||||
for (int i = 0; i < visible && (_scroll + i) < total; i++) {
|
||||
int row = _scroll + i;
|
||||
int y = start_y + i * item_h;
|
||||
char val[16];
|
||||
bool sel = (row == _sel);
|
||||
drawList(display, _item_count, _sel, _scroll, [&](int row, int y, bool sel, int reserve) {
|
||||
int item = _items[row];
|
||||
display.drawSelectionRow(0, y - 1, display.width() - reserve, item_h - 1, sel);
|
||||
display.drawSelectionRow(0, y - 1, display.width() - reserve, display.lineStep() - 1, sel);
|
||||
display.setCursor(2, y);
|
||||
display.print(itemLabel(item));
|
||||
if (item == IT_RFREQ && sel && _editor.active()) {
|
||||
_editor.render(display, display.valCol(), y);
|
||||
} else {
|
||||
char val[16];
|
||||
itemValue(item, p, val, sizeof(val));
|
||||
display.drawTextRightAlign(display.width() - reserve - 2, y, val);
|
||||
}
|
||||
display.setColor(DisplayDriver::LIGHT);
|
||||
}
|
||||
drawScrollIndicator(display, start_y, visible * item_h, total, visible, _scroll);
|
||||
});
|
||||
display.setColor(DisplayDriver::LIGHT);
|
||||
if (_picker.menu.active) _picker.menu.render(display);
|
||||
return (_picker.menu.active || _editor.active()) ? 50 : 500;
|
||||
|
||||
@@ -164,8 +164,8 @@ public:
|
||||
bool handleInput(char c) override {
|
||||
bool up = (c == KEY_UP);
|
||||
bool down = (c == KEY_DOWN);
|
||||
bool left = (c == KEY_LEFT || c == KEY_PREV);
|
||||
bool right = (c == KEY_RIGHT || c == KEY_NEXT);
|
||||
bool left = keyIsPrev(c);
|
||||
bool right = keyIsNext(c);
|
||||
bool enter = (c == KEY_ENTER);
|
||||
bool menu_key = (c == KEY_CONTEXT_MENU);
|
||||
bool cancel = (c == KEY_CANCEL);
|
||||
|
||||
@@ -143,8 +143,8 @@ public:
|
||||
if (_action_menu.active) {
|
||||
// LEFT/RIGHT cycles the focused value — only meaningful in the Settings
|
||||
// submenu; the popup stays open so the user can keep tapping.
|
||||
if (c == KEY_LEFT || c == KEY_RIGHT || c == KEY_PREV || c == KEY_NEXT) {
|
||||
int dir = (c == KEY_RIGHT || c == KEY_NEXT) ? 1 : -1;
|
||||
if (keyIsPrev(c) || keyIsNext(c)) {
|
||||
int dir = keyIsNext(c) ? 1 : -1;
|
||||
int idx = _action_menu.selectedIndex();
|
||||
if (idx >= 0 && idx < _act_count && _menu_level == ML_SETTINGS)
|
||||
cycleSetting((ActionId)_act_map[idx], dir);
|
||||
@@ -207,8 +207,8 @@ public:
|
||||
}
|
||||
if (c == KEY_CONTEXT_MENU) { openActionMenu(); return true; }
|
||||
|
||||
if (c == KEY_LEFT || c == KEY_PREV) { _view = (uint8_t)((_view + V_COUNT - 1) % V_COUNT); return true; }
|
||||
if (c == KEY_RIGHT || c == KEY_NEXT) { _view = (uint8_t)((_view + 1) % V_COUNT); return true; }
|
||||
if (keyIsPrev(c)) { _view = (uint8_t)((_view + V_COUNT - 1) % V_COUNT); return true; }
|
||||
if (keyIsNext(c)) { _view = (uint8_t)((_view + 1) % V_COUNT); return true; }
|
||||
if (_view == V_SUMMARY && c == KEY_UP) {
|
||||
_summary_scroll = (_summary_scroll > 0) ? _summary_scroll - 1 : _summary_max_scroll;
|
||||
return true;
|
||||
|
||||
@@ -309,7 +309,7 @@ public:
|
||||
if (c == KEY_CANCEL) { _mode = OFF; return true; }
|
||||
if (c == KEY_UP) { _add_sel = (_add_sel > 0) ? _add_sel - 1 : 3; return true; }
|
||||
if (c == KEY_DOWN) { _add_sel = (_add_sel < 3) ? _add_sel + 1 : 0; return true; }
|
||||
if (c == KEY_LEFT || c == KEY_RIGHT) {
|
||||
if (keyIsPrev(c) || keyIsNext(c)) {
|
||||
if (_add_sel == 0) _add_lat_neg = !_add_lat_neg; // N <-> S
|
||||
else if (_add_sel == 1) _add_lon_neg = !_add_lon_neg; // E <-> W
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user