mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-08-03 02:36:11 +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:
co-authored by
Claude Opus 4.8
parent
e44df01b9b
commit
089048a036
@@ -156,8 +156,8 @@ struct FullscreenMsgView {
|
|||||||
Result handleInput(char c) {
|
Result handleInput(char c) {
|
||||||
if (c == KEY_UP) { if (scroll > 0) scroll--; return NONE; }
|
if (c == KEY_UP) { if (scroll > 0) scroll--; return NONE; }
|
||||||
if (c == KEY_DOWN) { if (scroll < _max_scroll) scroll++; return NONE; }
|
if (c == KEY_DOWN) { if (scroll < _max_scroll) scroll++; return NONE; }
|
||||||
if (c == KEY_LEFT) return NEXT;
|
if (keyIsPrev(c)) return NEXT; // page between messages (encoder too)
|
||||||
if (c == KEY_RIGHT) return PREV;
|
if (keyIsNext(c)) return PREV;
|
||||||
if (c == KEY_CONTEXT_MENU) return REPLY;
|
if (c == KEY_CONTEXT_MENU) return REPLY;
|
||||||
if (c == KEY_ENTER || c == KEY_CANCEL) return CLOSE;
|
if (c == KEY_ENTER || c == KEY_CANCEL) return CLOSE;
|
||||||
return NONE;
|
return NONE;
|
||||||
|
|||||||
@@ -715,8 +715,7 @@ public:
|
|||||||
if (e.dist_km >= 0.0f) geo::fmtDist(right, sizeof(right), e.dist_km, useImperial());
|
if (e.dist_km >= 0.0f) geo::fmtDist(right, sizeof(right), e.dist_km, useImperial());
|
||||||
else strncpy(right, "?GPS", sizeof(right));
|
else strncpy(right, "?GPS", sizeof(right));
|
||||||
}
|
}
|
||||||
display.setCursor(display.width() - display.getTextWidth(right) - 2 - reserve, y);
|
display.drawTextRightAlign(display.width() - reserve - 2, y, right);
|
||||||
display.print(right);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -779,8 +778,8 @@ public:
|
|||||||
_detail_refresh_ms = millis();
|
_detail_refresh_ms = millis();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (c == KEY_LEFT) { _filter = (_filter + F_COUNT - 1) % F_COUNT; refresh(); return true; }
|
if (keyIsPrev(c)) { _filter = (_filter + F_COUNT - 1) % F_COUNT; refresh(); return true; }
|
||||||
if (c == KEY_RIGHT) { _filter = (_filter + 1) % F_COUNT; refresh(); return true; }
|
if (keyIsNext(c)) { _filter = (_filter + 1) % F_COUNT; refresh(); return true; }
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1518,8 +1518,8 @@ public:
|
|||||||
}
|
}
|
||||||
// LEFT/RIGHT cycle Notif/Melody in-place (menu stays open).
|
// LEFT/RIGHT cycle Notif/Melody in-place (menu stays open).
|
||||||
if (!_pin_picker_active && _num_contacts > 0) {
|
if (!_pin_picker_active && _num_contacts > 0) {
|
||||||
bool left = (c == KEY_LEFT || c == KEY_PREV);
|
bool left = keyIsPrev(c);
|
||||||
bool right = (c == KEY_RIGHT || c == KEY_NEXT);
|
bool right = keyIsNext(c);
|
||||||
if (left || right) {
|
if (left || right) {
|
||||||
static const char* NOTIF_LABELS[] = { "default", "OFF", "ON" };
|
static const char* NOTIF_LABELS[] = { "default", "OFF", "ON" };
|
||||||
static const char* ML[] = { "global", "M1", "M2" };
|
static const char* ML[] = { "global", "M1", "M2" };
|
||||||
@@ -1674,8 +1674,8 @@ public:
|
|||||||
if (_ctx_menu.active) {
|
if (_ctx_menu.active) {
|
||||||
// LEFT/RIGHT cycle Notif/Melody/Fav in-place (menu stays open).
|
// LEFT/RIGHT cycle Notif/Melody/Fav in-place (menu stays open).
|
||||||
if (_num_channels > 0) {
|
if (_num_channels > 0) {
|
||||||
bool left = (c == KEY_LEFT || c == KEY_PREV);
|
bool left = keyIsPrev(c);
|
||||||
bool right = (c == KEY_RIGHT || c == KEY_NEXT);
|
bool right = keyIsNext(c);
|
||||||
if (left || right) {
|
if (left || right) {
|
||||||
static const char* NOTIF_LABELS[] = { "default", "OFF", "ON" };
|
static const char* NOTIF_LABELS[] = { "default", "OFF", "ON" };
|
||||||
static const char* ML[] = { "global", "M1", "M2" };
|
static const char* ML[] = { "global", "M1", "M2" };
|
||||||
|
|||||||
@@ -143,39 +143,21 @@ public:
|
|||||||
display.setColor(DisplayDriver::LIGHT);
|
display.setColor(DisplayDriver::LIGHT);
|
||||||
display.drawCenteredHeader("REPEATER");
|
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.
|
// Config only — live forwarding stats live on Tools › Diagnostics.
|
||||||
int total = _item_count;
|
drawList(display, _item_count, _sel, _scroll, [&](int row, int y, bool sel, int reserve) {
|
||||||
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);
|
|
||||||
int item = _items[row];
|
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.setCursor(2, y);
|
||||||
display.print(itemLabel(item));
|
display.print(itemLabel(item));
|
||||||
if (item == IT_RFREQ && sel && _editor.active()) {
|
if (item == IT_RFREQ && sel && _editor.active()) {
|
||||||
_editor.render(display, display.valCol(), y);
|
_editor.render(display, display.valCol(), y);
|
||||||
} else {
|
} else {
|
||||||
|
char val[16];
|
||||||
itemValue(item, p, val, sizeof(val));
|
itemValue(item, p, val, sizeof(val));
|
||||||
display.drawTextRightAlign(display.width() - reserve - 2, y, val);
|
display.drawTextRightAlign(display.width() - reserve - 2, y, val);
|
||||||
}
|
}
|
||||||
display.setColor(DisplayDriver::LIGHT);
|
display.setColor(DisplayDriver::LIGHT);
|
||||||
}
|
});
|
||||||
drawScrollIndicator(display, start_y, visible * item_h, total, visible, _scroll);
|
|
||||||
display.setColor(DisplayDriver::LIGHT);
|
display.setColor(DisplayDriver::LIGHT);
|
||||||
if (_picker.menu.active) _picker.menu.render(display);
|
if (_picker.menu.active) _picker.menu.render(display);
|
||||||
return (_picker.menu.active || _editor.active()) ? 50 : 500;
|
return (_picker.menu.active || _editor.active()) ? 50 : 500;
|
||||||
|
|||||||
@@ -164,8 +164,8 @@ public:
|
|||||||
bool handleInput(char c) override {
|
bool handleInput(char c) override {
|
||||||
bool up = (c == KEY_UP);
|
bool up = (c == KEY_UP);
|
||||||
bool down = (c == KEY_DOWN);
|
bool down = (c == KEY_DOWN);
|
||||||
bool left = (c == KEY_LEFT || c == KEY_PREV);
|
bool left = keyIsPrev(c);
|
||||||
bool right = (c == KEY_RIGHT || c == KEY_NEXT);
|
bool right = keyIsNext(c);
|
||||||
bool enter = (c == KEY_ENTER);
|
bool enter = (c == KEY_ENTER);
|
||||||
bool menu_key = (c == KEY_CONTEXT_MENU);
|
bool menu_key = (c == KEY_CONTEXT_MENU);
|
||||||
bool cancel = (c == KEY_CANCEL);
|
bool cancel = (c == KEY_CANCEL);
|
||||||
|
|||||||
@@ -143,8 +143,8 @@ public:
|
|||||||
if (_action_menu.active) {
|
if (_action_menu.active) {
|
||||||
// LEFT/RIGHT cycles the focused value — only meaningful in the Settings
|
// LEFT/RIGHT cycles the focused value — only meaningful in the Settings
|
||||||
// submenu; the popup stays open so the user can keep tapping.
|
// submenu; the popup stays open so the user can keep tapping.
|
||||||
if (c == KEY_LEFT || c == KEY_RIGHT || c == KEY_PREV || c == KEY_NEXT) {
|
if (keyIsPrev(c) || keyIsNext(c)) {
|
||||||
int dir = (c == KEY_RIGHT || c == KEY_NEXT) ? 1 : -1;
|
int dir = keyIsNext(c) ? 1 : -1;
|
||||||
int idx = _action_menu.selectedIndex();
|
int idx = _action_menu.selectedIndex();
|
||||||
if (idx >= 0 && idx < _act_count && _menu_level == ML_SETTINGS)
|
if (idx >= 0 && idx < _act_count && _menu_level == ML_SETTINGS)
|
||||||
cycleSetting((ActionId)_act_map[idx], dir);
|
cycleSetting((ActionId)_act_map[idx], dir);
|
||||||
@@ -207,8 +207,8 @@ public:
|
|||||||
}
|
}
|
||||||
if (c == KEY_CONTEXT_MENU) { openActionMenu(); return true; }
|
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 (keyIsPrev(c)) { _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 (keyIsNext(c)) { _view = (uint8_t)((_view + 1) % V_COUNT); return true; }
|
||||||
if (_view == V_SUMMARY && c == KEY_UP) {
|
if (_view == V_SUMMARY && c == KEY_UP) {
|
||||||
_summary_scroll = (_summary_scroll > 0) ? _summary_scroll - 1 : _summary_max_scroll;
|
_summary_scroll = (_summary_scroll > 0) ? _summary_scroll - 1 : _summary_max_scroll;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ public:
|
|||||||
if (c == KEY_CANCEL) { _mode = OFF; return true; }
|
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_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_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
|
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
|
else if (_add_sel == 1) _add_lon_neg = !_add_lon_neg; // E <-> W
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user