diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 4d98430d9..f81c7146b 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -755,35 +755,6 @@ float Screen::estimatedHeading(double lat, double lon) /// nodes static int8_t prevFrame = -1; -// Draw the arrow pointing to a node's location -void Screen::drawNodeHeading(OLEDDisplay *display, int16_t compassX, int16_t compassY, uint16_t compassDiam, float headingRadian) -{ - Point tip(0.0f, 0.5f), tail(0.0f, -0.35f); // pointing up initially - float arrowOffsetX = 0.14f, arrowOffsetY = 1.0f; - Point leftArrow(tip.x - arrowOffsetX, tip.y - arrowOffsetY), rightArrow(tip.x + arrowOffsetX, tip.y - arrowOffsetY); - - Point *arrowPoints[] = {&tip, &tail, &leftArrow, &rightArrow}; - - for (int i = 0; i < 4; i++) { - arrowPoints[i]->rotate(headingRadian); - arrowPoints[i]->scale(compassDiam * 0.6); - arrowPoints[i]->translate(compassX, compassY); - } - /* Old arrow - display->drawLine(tip.x, tip.y, tail.x, tail.y); - display->drawLine(leftArrow.x, leftArrow.y, tip.x, tip.y); - display->drawLine(rightArrow.x, rightArrow.y, tip.x, tip.y); - display->drawLine(leftArrow.x, leftArrow.y, tail.x, tail.y); - display->drawLine(rightArrow.x, rightArrow.y, tail.x, tail.y); - */ -#ifdef USE_EINK - display->drawTriangle(tip.x, tip.y, rightArrow.x, rightArrow.y, tail.x, tail.y); -#else - display->fillTriangle(tip.x, tip.y, rightArrow.x, rightArrow.y, tail.x, tail.y); -#endif - display->drawTriangle(tip.x, tip.y, leftArrow.x, leftArrow.y, tail.x, tail.y); -} - // Get a string representation of the time passed since something happened void Screen::getTimeAgoStr(uint32_t agoSecs, char *timeStr, uint8_t maxLength) { @@ -814,55 +785,6 @@ void Screen::getTimeAgoStr(uint32_t agoSecs, char *timeStr, uint8_t maxLength) snprintf(timeStr, maxLength, "unknown age"); } -void Screen::drawCompassNorth(OLEDDisplay *display, int16_t compassX, int16_t compassY, float myHeading) -{ - Serial.print("🧭 [Main Compass] Raw Heading (deg): "); - Serial.println(myHeading * RAD_TO_DEG); - - // If north is supposed to be at the top of the compass we want rotation to be +0 - if (config.display.compass_north_top) - myHeading = -0; - /* N sign points currently not deleted*/ - Point N1(-0.04f, 0.65f), N2(0.04f, 0.65f); // N sign points (N1-N4) - Point N3(-0.04f, 0.55f), N4(0.04f, 0.55f); - Point NC1(0.00f, 0.50f); // north circle center point - Point *rosePoints[] = {&N1, &N2, &N3, &N4, &NC1}; - - uint16_t compassDiam = Screen::getCompassDiam(SCREEN_WIDTH, SCREEN_HEIGHT); - - for (int i = 0; i < 5; i++) { - // North on compass will be negative of heading - rosePoints[i]->rotate(-myHeading); - rosePoints[i]->scale(compassDiam); - rosePoints[i]->translate(compassX, compassY); - } -} - -uint16_t Screen::getCompassDiam(uint32_t displayWidth, uint32_t displayHeight) -{ - uint16_t diam = 0; - uint16_t offset = 0; - - if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) - offset = FONT_HEIGHT_SMALL; - - // get the smaller of the 2 dimensions and subtract 20 - if (displayWidth > (displayHeight - offset)) { - diam = displayHeight - offset; - // if 2/3 of the other size would be smaller, use that - if (diam > (displayWidth * 2 / 3)) { - diam = displayWidth * 2 / 3; - } - } else { - diam = displayWidth; - if (diam > ((displayHeight - offset) * 2 / 3)) { - diam = (displayHeight - offset) * 2 / 3; - } - } - - return diam - 20; -}; - // Combined dynamic node list frame cycling through LastHeard, HopSignal, and Distance modes // Uses a single frame and changes data every few seconds (E-Ink variant is separate) diff --git a/src/graphics/Screen.h b/src/graphics/Screen.h index c8e2b1ffe..d3df70919 100644 --- a/src/graphics/Screen.h +++ b/src/graphics/Screen.h @@ -238,14 +238,8 @@ class Screen : public concurrency::OSThread void getTimeAgoStr(uint32_t agoSecs, char *timeStr, uint8_t maxLength); // Draw north - void drawCompassNorth(OLEDDisplay *display, int16_t compassX, int16_t compassY, float myHeading); - - static uint16_t getCompassDiam(uint32_t displayWidth, uint32_t displayHeight); - float estimatedHeading(double lat, double lon); - void drawNodeHeading(OLEDDisplay *display, int16_t compassX, int16_t compassY, uint16_t compassDiam, float headingRadian); - void drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char **fields); /// Handle button press, trackball or swipe action) diff --git a/src/graphics/draw/UIRenderer.cpp b/src/graphics/draw/UIRenderer.cpp index a379af2e3..7e1fe7e87 100644 --- a/src/graphics/draw/UIRenderer.cpp +++ b/src/graphics/draw/UIRenderer.cpp @@ -1,4 +1,5 @@ #include "UIRenderer.h" +#include "CompassRenderer.h" #include "GPSStatus.h" #include "NodeDB.h" #include "NodeListRenderer.h" @@ -451,7 +452,7 @@ void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, in const auto &op = ourNode->position; float myHeading = screen->hasHeading() ? screen->getHeading() * PI / 180 : screen->estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i)); - screen->drawCompassNorth(display, compassX, compassY, myHeading); + CompassRenderer::drawCompassNorth(display, compassX, compassY, myHeading); const auto &p = node->position; float d = @@ -459,7 +460,7 @@ void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, in float bearing = GeoCoord::bearing(DegD(op.latitude_i), DegD(op.longitude_i), DegD(p.latitude_i), DegD(p.longitude_i)); if (!config.display.compass_north_top) bearing -= myHeading; - screen->drawNodeHeading(display, compassX, compassY, compassDiam, bearing); + CompassRenderer::drawNodeHeading(display, compassX, compassY, compassDiam, bearing); display->drawCircle(compassX, compassY, compassRadius); } @@ -498,7 +499,7 @@ void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, in const auto &op = ourNode->position; float myHeading = screen->hasHeading() ? screen->getHeading() * PI / 180 : screen->estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i)); - screen->drawCompassNorth(display, compassX, compassY, myHeading); + graphics::CompassRenderer::drawCompassNorth(display, compassX, compassY, myHeading); const auto &p = node->position; float d = @@ -506,7 +507,7 @@ void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, in float bearing = GeoCoord::bearing(DegD(op.latitude_i), DegD(op.longitude_i), DegD(p.latitude_i), DegD(p.longitude_i)); if (!config.display.compass_north_top) bearing -= myHeading; - screen->drawNodeHeading(display, compassX, compassY, compassRadius * 2, bearing); + graphics::CompassRenderer::drawNodeHeading(display, compassX, compassY, compassRadius * 2, bearing); display->drawCircle(compassX, compassY, compassRadius); } @@ -1014,7 +1015,7 @@ void drawCompassAndLocationScreen(OLEDDisplay *display, OLEDDisplayUiState *stat // Center vertically and nudge down slightly to keep "N" clear of header const int16_t compassY = topY + (usableHeight / 2) + ((FONT_HEIGHT_SMALL - 1) / 2) + 2; - screen->drawNodeHeading(display, compassX, compassY, compassDiam, -heading); + CompassRenderer::drawNodeHeading(display, compassX, compassY, compassDiam, -heading); display->drawCircle(compassX, compassY, compassRadius); // "N" label @@ -1055,7 +1056,7 @@ void drawCompassAndLocationScreen(OLEDDisplay *display, OLEDDisplayUiState *stat int compassX = x + SCREEN_WIDTH / 2; int compassY = yBelowContent + availableHeight / 2; - screen->drawNodeHeading(display, compassX, compassY, compassRadius * 2, -heading); + CompassRenderer::drawNodeHeading(display, compassX, compassY, compassRadius * 2, -heading); display->drawCircle(compassX, compassY, compassRadius); // "N" label diff --git a/src/modules/WaypointModule.cpp b/src/modules/WaypointModule.cpp index 9313c3425..0e0cec9ca 100644 --- a/src/modules/WaypointModule.cpp +++ b/src/modules/WaypointModule.cpp @@ -2,6 +2,8 @@ #include "NodeDB.h" #include "PowerFSM.h" #include "configuration.h" +#include "graphics/draw/CompassRenderer.h" + #if HAS_SCREEN #include "gps/RTC.h" #include "graphics/Screen.h" @@ -119,7 +121,7 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, // Dimensions / co-ordinates for the compass/circle int16_t compassX = 0, compassY = 0; - uint16_t compassDiam = graphics::Screen::getCompassDiam(display->getWidth(), display->getHeight()); + uint16_t compassDiam = graphics::CompassRenderer::getCompassDiam(display->getWidth(), display->getHeight()); if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) { compassX = x + display->getWidth() - compassDiam / 2 - 5; @@ -137,7 +139,7 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, myHeading = (screen->getHeading()) * PI / 180; // gotta convert compass degrees to Radians else myHeading = screen->estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i)); - screen->drawCompassNorth(display, compassX, compassY, myHeading); + graphics::CompassRenderer::drawCompassNorth(display, compassX, compassY, myHeading); // Compass bearing to waypoint float bearingToOther = @@ -146,7 +148,7 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, // If the top of the compass is not a static north we need adjust bearingToOther based on heading if (!config.display.compass_north_top) bearingToOther -= myHeading; - screen->drawNodeHeading(display, compassX, compassY, compassDiam, bearingToOther); + graphics::CompassRenderer::drawNodeHeading(display, compassX, compassY, compassDiam, bearingToOther); float bearingToOtherDegrees = (bearingToOther < 0) ? bearingToOther + 2 * PI : bearingToOther; bearingToOtherDegrees = bearingToOtherDegrees * 180 / PI; diff --git a/src/motion/MotionSensor.cpp b/src/motion/MotionSensor.cpp index 840d64277..438fd4f7a 100755 --- a/src/motion/MotionSensor.cpp +++ b/src/motion/MotionSensor.cpp @@ -1,4 +1,5 @@ #include "MotionSensor.h" +#include "graphics/draw/CompassRenderer.h" #if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C @@ -48,7 +49,7 @@ void MotionSensor::drawFrameCalibration(OLEDDisplay *display, OLEDDisplayUiState display->drawString(x, y + 40, timeRemainingBuffer); int16_t compassX = 0, compassY = 0; - uint16_t compassDiam = graphics::Screen::getCompassDiam(display->getWidth(), display->getHeight()); + uint16_t compassDiam = graphics::CompassRenderer::getCompassDiam(display->getWidth(), display->getHeight()); // coordinates for the center of the compass/circle if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) { @@ -59,7 +60,7 @@ void MotionSensor::drawFrameCalibration(OLEDDisplay *display, OLEDDisplayUiState compassY = y + FONT_HEIGHT_SMALL + (display->getHeight() - FONT_HEIGHT_SMALL) / 2; } display->drawCircle(compassX, compassY, compassDiam / 2); - screen->drawCompassNorth(display, compassX, compassY, screen->getHeading() * PI / 180); + graphics::CompassRenderer::drawCompassNorth(display, compassX, compassY, screen->getHeading() * PI / 180); } #endif