mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-07-26 14:58:12 +00:00
refactor(nav): move Add-by-coords inside the Waypoints list
Add-by-coords sat in the top-level Trail action popup alongside Mark here. Move it into the Waypoints view as a trailing "+ Add by coords" row, so the popup stays focused on trail/marking actions and waypoint management lives in one place. "Waypoints" is now always shown in the action menu (it hosts the list, backtrack and the add entry), so the first waypoint can be added by coordinates even with no trail or saved points yet. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -92,8 +92,7 @@ Cycle views with **LEFT / RIGHT**:
|
||||
| Readout | LEFT/RIGHT or Enter | Summary shows Speed or Pace (in the global unit system) |
|
||||
| Grid | LEFT/RIGHT or Enter | Toggle scale grid on the map |
|
||||
| Mark here | Enter | Drop a waypoint at the current GPS fix (see below) |
|
||||
| Add by coords | Enter | Add a waypoint from a lat/lon/label form — no GPS fix needed |
|
||||
| Waypoints | Enter | Open the waypoint list / navigation |
|
||||
| Waypoints | Enter | Open the waypoint list / navigation / add-by-coords |
|
||||
| Start / Stop tracking | Enter | Begin or end a recording session |
|
||||
| Save trail | Enter | Write RAM ring to flash (`/trail`) |
|
||||
| Load trail | Enter | Restore flash trail into RAM |
|
||||
@@ -102,7 +101,7 @@ Cycle views with **LEFT / RIGHT**:
|
||||
| Clear waypoints | Enter | Delete all saved waypoints (trail untouched) |
|
||||
| Reset trail | Enter | Clear RAM ring and elapsed time |
|
||||
|
||||
(Mark here / Waypoints / Clear waypoints appear only when applicable — e.g. with a GPS fix, or once at least one waypoint or trail point exists.)
|
||||
(Clear waypoints appears only once at least one waypoint exists. Mark here needs a GPS fix; Waypoints is always available.)
|
||||
|
||||
### Waypoints
|
||||
|
||||
@@ -110,7 +109,7 @@ A waypoint is a saved spot — your car, camp, a water source — that you can n
|
||||
|
||||
**Dropping a waypoint** — **Hold Enter → Mark here**. This captures the current GPS fix and opens the on-screen keyboard for a short label (up to 11 characters — e.g. `CAR`, `CAMP`, `H2O`). Leaving it blank auto-names it `WP1`, `WP2`, … Marking works whether or not the trail is being recorded; it needs a GPS fix (otherwise it reports *No GPS fix*).
|
||||
|
||||
**Adding by coordinates** — **Hold Enter → Add by coords** lets you create a waypoint without being there — no GPS fix required (handy for a meeting point or a spot read off a map). It opens a small form with three editable rows plus **Save**:
|
||||
**Adding by coordinates** — open **Hold Enter → Waypoints** and select the **+ Add by coords** row (always the last entry in the list). This creates a waypoint without being there — no GPS fix required (handy for a meeting point or a spot read off a map). It opens a small form with three editable rows plus **Save**:
|
||||
|
||||
- **Lat** / **Lon** — **Enter** opens the keyboard to type the value in decimal degrees (magnitude only; the keyboard has no minus sign), and **LEFT/RIGHT** toggles the hemisphere — N/S for latitude, E/W for longitude.
|
||||
- **Label** — **Enter** to type a name (blank → auto `WP<n>`).
|
||||
|
||||
@@ -48,9 +48,9 @@ class TrailScreen : public UIScreen {
|
||||
// (Start/Stop tracking, Reset). PopupMenu stores label pointers verbatim, so
|
||||
// the labels live in member buffers that get refreshed in openActionMenu()
|
||||
// and after every LEFT/RIGHT cycle.
|
||||
enum ActionId { ACT_MIN_DIST, ACT_UNITS, ACT_GRID, ACT_TOGGLE, ACT_SAVE, ACT_LOAD, ACT_RESET, ACT_EXPORT, ACT_EXPORT_SAVED, ACT_MARK, ACT_ADD_COORDS, ACT_WAYPOINTS, ACT_WP_CLEAR };
|
||||
enum ActionId { ACT_MIN_DIST, ACT_UNITS, ACT_GRID, ACT_TOGGLE, ACT_SAVE, ACT_LOAD, ACT_RESET, ACT_EXPORT, ACT_EXPORT_SAVED, ACT_MARK, ACT_WAYPOINTS, ACT_WP_CLEAR };
|
||||
PopupMenu _action_menu;
|
||||
uint8_t _act_map[16]; // 13 used today; pad so adding an action doesn't OOB
|
||||
uint8_t _act_map[16]; // 12 used today; pad so adding an action doesn't OOB
|
||||
uint8_t _act_count = 0;
|
||||
char _act_min_dist_label[24];
|
||||
char _act_units_label[24];
|
||||
@@ -183,14 +183,20 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
// Waypoint list (row 0 is the synthetic "Trail start" when a trail exists).
|
||||
// Waypoint list (row 0 is the synthetic "Trail start" when a trail exists;
|
||||
// the final row is "+ Add by coords").
|
||||
if (_wp_mode == WP_LIST) {
|
||||
int n = wpListCount();
|
||||
int total = n + 1; // + the "Add by coords" row
|
||||
if (c == KEY_CANCEL) { _wp_mode = WP_OFF; return true; }
|
||||
if (c == KEY_UP && _wp_sel > 0) { _wp_sel--; if (_wp_sel < _wp_scroll) _wp_scroll = _wp_sel; return true; }
|
||||
if (c == KEY_DOWN && _wp_sel < n - 1) { _wp_sel++; return true; }
|
||||
if (c == KEY_ENTER && n > 0) { _wp_mode = WP_NAV; return true; }
|
||||
// Rename/Delete apply to saved waypoints only — not the Trail-start row.
|
||||
if (c == KEY_UP && _wp_sel > 0) { _wp_sel--; if (_wp_sel < _wp_scroll) _wp_scroll = _wp_sel; return true; }
|
||||
if (c == KEY_DOWN && _wp_sel < total - 1) { _wp_sel++; return true; }
|
||||
if (c == KEY_ENTER) {
|
||||
if (_wp_sel == n) handleAddByCoords(); // last row → open the add form
|
||||
else _wp_mode = WP_NAV; // a waypoint / Trail-start row
|
||||
return true;
|
||||
}
|
||||
// Rename/Delete/Send apply to saved waypoints only — not Trail-start or Add.
|
||||
if (c == KEY_CONTEXT_MENU && !selIsStart() && wpIndex() < _task->waypoints().count()) {
|
||||
_wp_ctx.begin("Waypoint", 3);
|
||||
_wp_ctx.addItem("Rename");
|
||||
@@ -229,7 +235,6 @@ public:
|
||||
else if (act == ACT_EXPORT) { handleExport(); }
|
||||
else if (act == ACT_EXPORT_SAVED) { handleExportSaved(); }
|
||||
else if (act == ACT_MARK) { handleMarkHere(); }
|
||||
else if (act == ACT_ADD_COORDS) { handleAddByCoords(); }
|
||||
else if (act == ACT_WAYPOINTS) { _wp_mode = WP_LIST; _wp_sel = 0; _wp_scroll = 0; }
|
||||
else if (act == ACT_WP_CLEAR) { _task->waypoints().clear(); _task->saveWaypoints();
|
||||
_task->showAlert("Waypoints cleared", 800); }
|
||||
@@ -356,13 +361,10 @@ private:
|
||||
_act_map[_act_count++] = ACT_GRID; _action_menu.addItem(_act_grid_label);
|
||||
_act_map[_act_count++] = ACT_TOGGLE; _action_menu.addItem(_act_toggle_label);
|
||||
// Waypoints: mark the current spot, and browse/navigate saved ones.
|
||||
_act_map[_act_count++] = ACT_MARK; _action_menu.addItem("Mark here");
|
||||
_act_map[_act_count++] = ACT_ADD_COORDS; _action_menu.addItem("Add by coords");
|
||||
// "Waypoints" opens the nav list — useful when there are saved waypoints
|
||||
// OR a trail to backtrack to (the list always includes a "Trail start" row).
|
||||
if (_task->waypoints().count() > 0 || !_store->empty()) {
|
||||
_act_map[_act_count++] = ACT_WAYPOINTS; _action_menu.addItem("Waypoints");
|
||||
}
|
||||
_act_map[_act_count++] = ACT_MARK; _action_menu.addItem("Mark here");
|
||||
// "Waypoints" opens the nav list — always available; it hosts the list,
|
||||
// backtrack (Trail-start row) and the "+ Add by coords" entry.
|
||||
_act_map[_act_count++] = ACT_WAYPOINTS; _action_menu.addItem("Waypoints");
|
||||
if (_task->waypoints().count() > 0) {
|
||||
_act_map[_act_count++] = ACT_WP_CLEAR; _action_menu.addItem("Clear waypoints");
|
||||
}
|
||||
@@ -509,11 +511,8 @@ private:
|
||||
display.drawTextCentered(display.width() / 2, 0, "WAYPOINTS");
|
||||
display.fillRect(0, display.headerH() - 1, display.width(), display.sepH());
|
||||
|
||||
int n = wpListCount();
|
||||
if (n == 0) {
|
||||
display.drawTextCentered(display.width() / 2, display.height() / 2, "No waypoints");
|
||||
return;
|
||||
}
|
||||
int n = wpListCount();
|
||||
int total = n + 1; // final row = "+ Add by coords"
|
||||
const int top = display.listStart();
|
||||
const int step = display.lineStep();
|
||||
const int cw = display.getCharWidth();
|
||||
@@ -524,15 +523,21 @@ private:
|
||||
|
||||
int32_t mylat, mylon; bool have = ownPos(mylat, mylon);
|
||||
|
||||
for (int i = 0; i < vis && (_wp_scroll + i) < n; i++) {
|
||||
for (int i = 0; i < vis && (_wp_scroll + i) < total; i++) {
|
||||
int row = _wp_scroll + i;
|
||||
int32_t tlat, tlon; const char* label;
|
||||
if (!rowTarget(row, tlat, tlon, label)) continue;
|
||||
int y = top + i * step;
|
||||
bool sel = (row == _wp_sel);
|
||||
display.drawSelectionRow(0, y - 1, display.width(), step - 1, sel);
|
||||
display.setCursor(0, y); display.print(sel ? ">" : " ");
|
||||
|
||||
if (row == n) { // the synthetic "Add" row
|
||||
display.setCursor(cw + 2, y); display.print("+ Add by coords");
|
||||
display.setColor(DisplayDriver::LIGHT);
|
||||
continue;
|
||||
}
|
||||
|
||||
int32_t tlat, tlon; const char* label;
|
||||
if (!rowTarget(row, tlat, tlon, label)) continue;
|
||||
char dist[12] = ""; int bw = 0;
|
||||
if (have) {
|
||||
geo::fmtDist(dist, sizeof(dist), geo::haversineKm(mylat, mylon, tlat, tlon), useImperial());
|
||||
|
||||
Reference in New Issue
Block a user