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:
MarekZegare4
2026-06-25 12:02:22 +02:00
parent 5955fab31b
commit d2c9f2e19b
3 changed files with 32 additions and 20 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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);