diff --git a/examples/companion_radio/ui-new/CompassScreen.h b/examples/companion_radio/ui-new/CompassScreen.h index 2fdfc225..bf73566c 100644 --- a/examples/companion_radio/ui-new/CompassScreen.h +++ b/examples/companion_radio/ui-new/CompassScreen.h @@ -8,6 +8,7 @@ // being recorded. #include "../GeoUtils.h" +#include "GfxUtils.h" #include class CompassScreen : public UIScreen { @@ -15,33 +16,6 @@ class CompassScreen : public UIScreen { bool gpsValid() const { int32_t lat, lon; return _task->currentLocation(lat, lon); } - // Midpoint circle (DisplayDriver has no circle primitive). - static void drawCircle(DisplayDriver& d, int cx, int cy, int r) { - int x = r, y = 0, err = 1 - r; - while (x >= y) { - d.fillRect(cx + x, cy + y, 1, 1); d.fillRect(cx + y, cy + x, 1, 1); - d.fillRect(cx - y, cy + x, 1, 1); d.fillRect(cx - x, cy + y, 1, 1); - d.fillRect(cx - x, cy - y, 1, 1); d.fillRect(cx - y, cy - x, 1, 1); - d.fillRect(cx + y, cy - x, 1, 1); d.fillRect(cx + x, cy - y, 1, 1); - y++; - if (err < 0) err += 2 * y + 1; - else { x--; err += 2 * (y - x) + 1; } - } - } - - static void drawLine(DisplayDriver& d, int x0, int y0, int x1, int y1) { - int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1; - int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1; - int err = dx + dy; - while (true) { - d.fillRect(x0, y0, 1, 1); - if (x0 == x1 && y0 == y1) break; - int e2 = err * 2; - if (e2 >= dy) { err += dy; x0 += sx; } - if (e2 <= dx) { err += dx; y0 += sy; } - } - } - public: CompassScreen(UITask* task) : _task(task) {} void enter() {} @@ -74,7 +48,7 @@ public: int cog; bool have = _task->currentCourse(cog); - drawCircle(display, cx, cy, r); // compass ring + gfx::drawCircle(display, cx, cy, r); // compass ring // Fixed forward index at the top: the direction you are travelling is // always "up". The compass card (North) rotates underneath it. @@ -98,11 +72,11 @@ public: // North needle from centre. int nx, ny; cardPos(0, r - 2, nx, ny); - drawLine(display, cx, cy, nx, ny); + gfx::drawLine(display, cx, cy, nx, ny); float nrad = (0 - cog) * (float)M_PI / 180.0f; for (int da = -25; da <= 25; da += 50) { float a = nrad + (float)M_PI + da * (float)M_PI / 180.0f; - drawLine(display, nx, ny, nx + (int)(sinf(a) * 4), ny - (int)(cosf(a) * 4)); + gfx::drawLine(display, nx, ny, nx + (int)(sinf(a) * 4), ny - (int)(cosf(a) * 4)); } // Cardinal letters around the rim (N at the needle tip). diff --git a/examples/companion_radio/ui-new/GfxUtils.h b/examples/companion_radio/ui-new/GfxUtils.h new file mode 100644 index 00000000..59e03bc4 --- /dev/null +++ b/examples/companion_radio/ui-new/GfxUtils.h @@ -0,0 +1,40 @@ +#pragma once +// Small 1-px drawing primitives the DisplayDriver abstraction doesn't provide +// (no line / circle in the GFX wrapper used here). Shared by the map and the +// compass so the Bresenham / midpoint routines aren't copy-pasted per screen. +// Everything is plotted as 1x1 fillRect to stay within DisplayDriver's API. + +#include +#include // abs + +namespace gfx { + +// Bresenham line between two points. +static inline void drawLine(DisplayDriver& d, int x0, int y0, int x1, int y1) { + int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1; + int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1; + int err = dx + dy; + while (true) { + d.fillRect(x0, y0, 1, 1); + if (x0 == x1 && y0 == y1) break; + int e2 = err * 2; + if (e2 >= dy) { err += dy; x0 += sx; } + if (e2 <= dx) { err += dx; y0 += sy; } + } +} + +// Midpoint-circle outline. +static inline void drawCircle(DisplayDriver& d, int cx, int cy, int r) { + int x = r, y = 0, err = 1 - r; + while (x >= y) { + d.fillRect(cx + x, cy + y, 1, 1); d.fillRect(cx + y, cy + x, 1, 1); + d.fillRect(cx - y, cy + x, 1, 1); d.fillRect(cx - x, cy + y, 1, 1); + d.fillRect(cx - x, cy - y, 1, 1); d.fillRect(cx - y, cy - x, 1, 1); + d.fillRect(cx + y, cy - x, 1, 1); d.fillRect(cx + x, cy - y, 1, 1); + y++; + if (err < 0) err += 2 * y + 1; + else { x--; err += 2 * (y - x) + 1; } + } +} + +} // namespace gfx diff --git a/examples/companion_radio/ui-new/TrailScreen.h b/examples/companion_radio/ui-new/TrailScreen.h index 8b84ff4b..bc9bbc36 100644 --- a/examples/companion_radio/ui-new/TrailScreen.h +++ b/examples/companion_radio/ui-new/TrailScreen.h @@ -7,6 +7,7 @@ #include "../Trail.h" #include "../GeoUtils.h" +#include "GfxUtils.h" #include "NavView.h" #include @@ -733,7 +734,7 @@ private: drawFilledDot(display, x0, y0); drawOpenDot(display, x1, y1); } else { - drawLine(display, x0, y0, x1, y1); + gfx::drawLine(display, x0, y0, x1, y1); } x0 = x1; y0 = y1; @@ -882,19 +883,6 @@ private: display.print(lbl); } - static void drawLine(DisplayDriver& d, int x0, int y0, int x1, int y1) { - int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1; - int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1; - int err = dx + dy; - while (true) { - d.fillRect(x0, y0, 1, 1); - if (x0 == x1 && y0 == y1) break; - int e2 = err * 2; - if (e2 >= dy) { err += dy; x0 += sx; } - if (e2 <= dx) { err += dx; y0 += sy; } - } - } - static void drawFilledDot(DisplayDriver& d, int cx, int cy) { d.fillRect(cx - 1, cy - 1, 3, 3); }