mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-07-27 15:28:11 +00:00
fix(ui): connect mini-map trail points with a line
The Home "Map" page preview only plotted each trail vertex as a single pixel, leaving gaps wherever the streaming simplifier collapsed a straight stretch to its two endpoints — so a route looked like scattered dots instead of a path. The stale "gfx isn't available this early in the TU" comment no longer holds: GfxUtils.h is already reachable here, so draw the same Bresenham line the full Trail map uses. Extracted the shared "walk points, draw a line, break on TRAIL_FLAG_SEG_START" loop into gfx::drawTrail() (GfxUtils.h) so the full map and the mini-map preview don't carry two copies of it; they differ only in their projection and what (if anything) they draw at a segment break. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <helpers/ui/DisplayDriver.h>
|
||||
#include <stdlib.h> // abs
|
||||
#include "../Trail.h"
|
||||
|
||||
namespace gfx {
|
||||
|
||||
@@ -37,4 +38,25 @@ static inline void drawCircle(DisplayDriver& d, int cx, int cy, int r) {
|
||||
}
|
||||
}
|
||||
|
||||
// Walks a TrailStore and renders it as a connected polyline via drawLine(),
|
||||
// breaking the line at each TRAIL_FLAG_SEG_START point (trail paused/
|
||||
// restarted) instead of bridging the dead-time gap. Shared by the full Trail
|
||||
// map and the Home screen's mini-map preview, which only differ in how they
|
||||
// project lat/lon to screen coords and what (if anything) they draw at a
|
||||
// break. `project(lat, lon, x, y)` fills the screen coords for one point;
|
||||
// `on_break(x_prev_end, y_prev_end, x_new_start, y_new_start)` runs at each
|
||||
// break instead of drawLine() — pass a no-op lambda for a silent gap.
|
||||
template <typename Project, typename OnBreak>
|
||||
static void drawTrail(DisplayDriver& d, TrailStore& tr, Project project, OnBreak on_break) {
|
||||
if (tr.count() == 0) return;
|
||||
int x0, y0; project(tr.at(0).lat_1e6, tr.at(0).lon_1e6, x0, y0);
|
||||
for (int i = 1; i < tr.count(); i++) {
|
||||
const TrailPoint& pt = tr.at(i);
|
||||
int x1, y1; project(pt.lat_1e6, pt.lon_1e6, x1, y1);
|
||||
if (pt.flags & TRAIL_FLAG_SEG_START) on_break(x0, y0, x1, y1);
|
||||
else drawLine(d, x0, y0, x1, y1);
|
||||
x0 = x1; y0 = y1;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
|
||||
@@ -740,19 +740,9 @@ private:
|
||||
int x0, y0;
|
||||
proj.project(_store->at(0).lat_1e6, _store->at(0).lon_1e6, x0, y0);
|
||||
miniIconDrawCentered(display, x0, y0, ICON_MAP_DOT);
|
||||
for (int i = 1; i < _store->count(); i++) {
|
||||
const TrailPoint& pt = _store->at(i);
|
||||
int x1, y1;
|
||||
proj.project(pt.lat_1e6, pt.lon_1e6, x1, y1);
|
||||
if (pt.flags & TRAIL_FLAG_SEG_START) {
|
||||
drawFilledDot(display, x0, y0);
|
||||
drawOpenDot(display, x1, y1);
|
||||
} else {
|
||||
gfx::drawLine(display, x0, y0, x1, y1);
|
||||
}
|
||||
x0 = x1;
|
||||
y0 = y1;
|
||||
}
|
||||
gfx::drawTrail(display, *_store,
|
||||
[&](int32_t la, int32_t lo, int& x, int& y) { proj.project(la, lo, x, y); },
|
||||
[&](int xa, int ya, int xb, int yb) { drawFilledDot(display, xa, ya); drawOpenDot(display, xb, yb); });
|
||||
int sx, sy;
|
||||
proj.project(_store->first().lat_1e6, _store->first().lon_1e6, sx, sy);
|
||||
drawStartMarker(display, sx, sy);
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#endif
|
||||
|
||||
#include "icons.h"
|
||||
#include "GfxUtils.h" // gfx::drawLine — connects trail points on the Home map preview
|
||||
|
||||
// Blinking status indicators: on for the first half of a 4 s cycle, but e-ink
|
||||
// can't repaint fast enough to blink, so it shows them steadily.
|
||||
@@ -554,8 +555,9 @@ public:
|
||||
|
||||
// Compact map preview for the Home "Map" page: own position, the GPS trail,
|
||||
// and live-tracked contacts (◆) folded into one auto-scaled box. A simplified
|
||||
// cousin of TrailScreen's map (dots, no grid/labels) so the home carousel
|
||||
// stays light. Returns false (and draws nothing) when there's nothing to show.
|
||||
// cousin of TrailScreen's map (no grid/labels, no break markers) so the home
|
||||
// carousel stays light. Returns false (and draws nothing) when there's
|
||||
// nothing to show.
|
||||
bool drawMapPreview(DisplayDriver& display, int ax, int ay, int aw, int ah) {
|
||||
if (aw < 8 || ah < 8) return false;
|
||||
bool init = false;
|
||||
@@ -608,11 +610,9 @@ public:
|
||||
px = off_x + (int)((float)(lo - mnlo) * lon_scale * scale);
|
||||
py = off_y + (int)((float)(mxla - la) * scale);
|
||||
};
|
||||
// Trail as dots (no line — gfx isn't available this early in the TU).
|
||||
for (int i = 0; i < tr.count(); i++) {
|
||||
int px, py; project(tr.at(i).lat_1e6, tr.at(i).lon_1e6, px, py);
|
||||
display.fillRect(px, py, 1, 1);
|
||||
}
|
||||
// Trail as a connected line, matching the full Trail map (shared helper —
|
||||
// see gfx::drawTrail); no break marker here, just a silent gap.
|
||||
gfx::drawTrail(display, tr, project, [](int, int, int, int) {});
|
||||
for (int i = 0; i < LiveTrackStore::CAPACITY; i++) {
|
||||
if (!lt.isActive(i, now)) continue;
|
||||
int px, py; project(lt.slotAt(i).lat_1e6, lt.slotAt(i).lon_1e6, px, py);
|
||||
|
||||
Reference in New Issue
Block a user