mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-08-01 01:36:12 +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:
co-authored by
Claude Opus 4.8
parent
5955fab31b
commit
d2c9f2e19b
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <helpers/ui/DisplayDriver.h>
|
#include <helpers/ui/DisplayDriver.h>
|
||||||
#include <stdlib.h> // abs
|
#include <stdlib.h> // abs
|
||||||
|
#include "../Trail.h"
|
||||||
|
|
||||||
namespace gfx {
|
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
|
} // namespace gfx
|
||||||
|
|||||||
@@ -740,19 +740,9 @@ private:
|
|||||||
int x0, y0;
|
int x0, y0;
|
||||||
proj.project(_store->at(0).lat_1e6, _store->at(0).lon_1e6, x0, y0);
|
proj.project(_store->at(0).lat_1e6, _store->at(0).lon_1e6, x0, y0);
|
||||||
miniIconDrawCentered(display, x0, y0, ICON_MAP_DOT);
|
miniIconDrawCentered(display, x0, y0, ICON_MAP_DOT);
|
||||||
for (int i = 1; i < _store->count(); i++) {
|
gfx::drawTrail(display, *_store,
|
||||||
const TrailPoint& pt = _store->at(i);
|
[&](int32_t la, int32_t lo, int& x, int& y) { proj.project(la, lo, x, y); },
|
||||||
int x1, y1;
|
[&](int xa, int ya, int xb, int yb) { drawFilledDot(display, xa, ya); drawOpenDot(display, xb, yb); });
|
||||||
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;
|
|
||||||
}
|
|
||||||
int sx, sy;
|
int sx, sy;
|
||||||
proj.project(_store->first().lat_1e6, _store->first().lon_1e6, sx, sy);
|
proj.project(_store->first().lat_1e6, _store->first().lon_1e6, sx, sy);
|
||||||
drawStartMarker(display, sx, sy);
|
drawStartMarker(display, sx, sy);
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "icons.h"
|
#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
|
// 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.
|
// 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,
|
// 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
|
// 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
|
// cousin of TrailScreen's map (no grid/labels, no break markers) so the home
|
||||||
// stays light. Returns false (and draws nothing) when there's nothing to show.
|
// 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) {
|
bool drawMapPreview(DisplayDriver& display, int ax, int ay, int aw, int ah) {
|
||||||
if (aw < 8 || ah < 8) return false;
|
if (aw < 8 || ah < 8) return false;
|
||||||
bool init = false;
|
bool init = false;
|
||||||
@@ -608,11 +610,9 @@ public:
|
|||||||
px = off_x + (int)((float)(lo - mnlo) * lon_scale * scale);
|
px = off_x + (int)((float)(lo - mnlo) * lon_scale * scale);
|
||||||
py = off_y + (int)((float)(mxla - la) * scale);
|
py = off_y + (int)((float)(mxla - la) * scale);
|
||||||
};
|
};
|
||||||
// Trail as dots (no line — gfx isn't available this early in the TU).
|
// Trail as a connected line, matching the full Trail map (shared helper —
|
||||||
for (int i = 0; i < tr.count(); i++) {
|
// see gfx::drawTrail); no break marker here, just a silent gap.
|
||||||
int px, py; project(tr.at(i).lat_1e6, tr.at(i).lon_1e6, px, py);
|
gfx::drawTrail(display, tr, project, [](int, int, int, int) {});
|
||||||
display.fillRect(px, py, 1, 1);
|
|
||||||
}
|
|
||||||
for (int i = 0; i < LiveTrackStore::CAPACITY; i++) {
|
for (int i = 0; i < LiveTrackStore::CAPACITY; i++) {
|
||||||
if (!lt.isActive(i, now)) continue;
|
if (!lt.isActive(i, now)) continue;
|
||||||
int px, py; project(lt.slotAt(i).lat_1e6, lt.slotAt(i).lon_1e6, px, py);
|
int px, py; project(lt.slotAt(i).lat_1e6, lt.slotAt(i).lon_1e6, px, py);
|
||||||
|
|||||||
Reference in New Issue
Block a user