diff --git a/src/AccelerometerThread.h b/src/AccelerometerThread.h index 0f04de057..39ae90385 100644 --- a/src/AccelerometerThread.h +++ b/src/AccelerometerThread.h @@ -288,7 +288,7 @@ class AccelerometerThread : public concurrency::OSThread compassY = y + FONT_HEIGHT_SMALL + (display->getHeight() - FONT_HEIGHT_SMALL) / 2; } display->drawCircle(compassX, compassY, getCompassDiam(display) / 2); - drawCompassNorth(display, compassX, compassY, screen->getHeading() * PI / 180); + screen->drawCompassNorth(display, compassX, compassY, screen->getHeading() * PI / 180); } #endif }; diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 924ca97c6..7c8bf40bb 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -79,7 +79,6 @@ namespace graphics // A text message frame + debug frame + all the node infos FrameCallback *normalFrames; static uint32_t targetFramerate = IDLE_FRAMERATE; -static char btPIN[16] = "888888"; uint32_t logo_timeout = 5000; // 4 seconds for EACH logo @@ -229,7 +228,7 @@ static void drawOEMBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, i drawOEMIconScreen(region, display, state, x, y); } -static void drawFrameText(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y, const char *message) +void Screen::drawFrameText(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y, const char *message) { uint16_t x_offset = display->width() / 2; display->setTextAlignment(TEXT_ALIGN_CENTER); @@ -237,19 +236,6 @@ static void drawFrameText(OLEDDisplay *display, OLEDDisplayUiState *state, int16 display->drawString(x_offset + x, 26 + y, message); } -static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -{ -#ifdef ARCH_ESP32 - if (wakeCause == ESP_SLEEP_WAKEUP_TIMER || wakeCause == ESP_SLEEP_WAKEUP_EXT1) { - drawFrameText(display, state, x, y, "Resuming..."); - } else -#endif - { - const char *region = myRegion ? myRegion->name : NULL; - drawIconScreen(region, display, state, x, y); - } -} - // Used on boot when a certificate is being created static void drawSSLScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { @@ -1336,32 +1322,10 @@ static void drawNodeHeading(OLEDDisplay *display, int16_t compassX, int16_t comp arrowPoints[i]->scale(getCompassDiam(display) * 0.6); arrowPoints[i]->translate(compassX, compassY); } - drawLine(display, tip, tail); - drawLine(display, leftArrow, tip); - drawLine(display, rightArrow, tip); + 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); } -/* -// Draw north -static void drawCompassNorth(OLEDDisplay *display, int16_t compassX, int16_t compassY, float myHeading) -{ - // 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; - - Point N1(-0.04f, 0.65f), N2(0.04f, 0.65f); - Point N3(-0.04f, 0.55f), N4(0.04f, 0.55f); - Point *rosePoints[] = {&N1, &N2, &N3, &N4}; - - for (int i = 0; i < 4; i++) { - // North on compass will be negative of heading - rosePoints[i]->rotate(-myHeading); - rosePoints[i]->scale(getCompassDiam(display)); - rosePoints[i]->translate(compassX, compassY); - } - drawLine(display, N1, N3); - drawLine(display, N2, N4); - drawLine(display, N1, N4); -}*/ // Get a string representation of the time passed since something happened static void getTimeAgoStr(uint32_t agoSecs, char *timeStr, uint8_t maxLength) @@ -1461,7 +1425,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_ myHeading = (screen->getHeading()) * PI / 180; // gotta convert compass degrees to Radians else myHeading = estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i)); - drawCompassNorth(display, compassX, compassY, myHeading); + screen->drawCompassNorth(display, compassX, compassY, myHeading); if (hasValidPosition(node)) { // display direction toward node @@ -1562,7 +1526,7 @@ static void drawWaypointFrame(OLEDDisplay *display, OLEDDisplayUiState *state, i myHeading = (screen->getHeading()) * PI / 180; // gotta convert compass degrees to Radians else myHeading = estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i)); - drawCompassNorth(display, compassX, compassY, myHeading); + screen->drawCompassNorth(display, compassX, compassY, myHeading); // Distance to Waypoint float d = GeoCoord::latLongToMeter(DegD(wp.latitude_i), DegD(wp.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i)); @@ -1758,9 +1722,19 @@ void Screen::setup() // Add frames. EINK_ADD_FRAMEFLAG(dispdev, DEMAND_FAST); - static FrameCallback bootFrames[] = {drawBootScreen}; - static const int bootFrameCount = sizeof(bootFrames) / sizeof(bootFrames[0]); - ui->setFrames(bootFrames, bootFrameCount); + alertFrames[0] = [this](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void { +#ifdef ARCH_ESP32 + if (wakeCause == ESP_SLEEP_WAKEUP_TIMER || wakeCause == ESP_SLEEP_WAKEUP_EXT1) { + drawFrameText(display, state, x, y, "Resuming..."); + } else +#endif + { + // Draw region in upper left + const char *region = myRegion ? myRegion->name : NULL; + drawIconScreen(region, display, state, x, y); + } + }; + ui->setFrames(alertFrames, 1); // No overlays. ui->setOverlays(nullptr, 0); @@ -2723,4 +2697,4 @@ int Screen::handleWaypoint(const meshtastic_MeshPacket *arg) } // namespace graphics #else graphics::Screen::Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY) {} -#endif // HAS_SCREEN +#endif // HAS_SCREEN \ No newline at end of file diff --git a/src/graphics/Screen.h b/src/graphics/Screen.h index a8aca3657..aa6e42893 100644 --- a/src/graphics/Screen.h +++ b/src/graphics/Screen.h @@ -82,6 +82,68 @@ class Screen #define SEGMENT_WIDTH 16 #define SEGMENT_HEIGHT 4 +namespace +{ +/// A basic 2D point class for drawing +class Point +{ + public: + float x, y; + + Point(float _x, float _y) : x(_x), y(_y) {} + + /// Apply a rotation around zero (standard rotation matrix math) + void rotate(float radian) + { + float cos = cosf(radian), sin = sinf(radian); + float rx = x * cos + y * sin, ry = -x * sin + y * cos; + + x = rx; + y = ry; + } + + void translate(int16_t dx, int dy) + { + x += dx; + y += dy; + } + + void scale(float f) + { + // We use -f here to counter the flip that happens + // on the y axis when drawing and rotating on screen + x *= f; + y *= -f; + } +}; + +} // namespace + +static uint16_t getCompassDiam(OLEDDisplay *display) +{ + 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 (display->getWidth() > (display->getHeight() - offset)) { + diam = display->getHeight() - offset; + // if 2/3 of the other size would be smaller, use that + if (diam > (display->getWidth() * 2 / 3)) { + diam = display->getWidth() * 2 / 3; + } + } else { + diam = display->getWidth(); + if (diam > ((display->getHeight() - offset) * 2 / 3)) { + diam = (display->getHeight() - offset) * 2 / 3; + } + } + + return diam - 20; +}; + namespace graphics { @@ -168,6 +230,30 @@ class Screen : public concurrency::OSThread void blink(); + void drawFrameText(OLEDDisplay *, OLEDDisplayUiState *, int16_t, int16_t, const char *); + + // Draw north + void drawCompassNorth(OLEDDisplay *display, int16_t compassX, int16_t compassY, float myHeading) + { + // 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; + + Point N1(-0.04f, 0.65f), N2(0.04f, 0.65f); + Point N3(-0.04f, 0.55f), N4(0.04f, 0.55f); + Point *rosePoints[] = {&N1, &N2, &N3, &N4}; + + for (int i = 0; i < 4; i++) { + // North on compass will be negative of heading + rosePoints[i]->rotate(-myHeading); + rosePoints[i]->scale(getCompassDiam(display)); + rosePoints[i]->translate(compassX, compassY); + } + display->drawLine(N1.x, N1.y, N3.x, N3.y); + display->drawLine(N2.x, N2.y, N4.x, N4.y); + display->drawLine(N1.x, N1.y, N4.x, N4.y); + } + /// Handle button press, trackball or swipe action) void onPress() { enqueueCmd(ScreenCmd{.cmd = Cmd::ON_PRESS}); } void showPrevFrame() { enqueueCmd(ScreenCmd{.cmd = Cmd::SHOW_PREV_FRAME}); } @@ -453,92 +539,5 @@ class Screen : public concurrency::OSThread }; } // namespace graphics -namespace -{ -/// A basic 2D point class for drawing -class Point -{ - public: - float x, y; - Point(float _x, float _y) : x(_x), y(_y) {} - - /// Apply a rotation around zero (standard rotation matrix math) - void rotate(float radian) - { - float cos = cosf(radian), sin = sinf(radian); - float rx = x * cos + y * sin, ry = -x * sin + y * cos; - - x = rx; - y = ry; - } - - void translate(int16_t dx, int dy) - { - x += dx; - y += dy; - } - - void scale(float f) - { - // We use -f here to counter the flip that happens - // on the y axis when drawing and rotating on screen - x *= f; - y *= -f; - } -}; - -} // namespace - -static void drawLine(OLEDDisplay *d, const Point &p1, const Point &p2) -{ - d->drawLine(p1.x, p1.y, p2.x, p2.y); -} - -static uint16_t getCompassDiam(OLEDDisplay *display) -{ - 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 (display->getWidth() > (display->getHeight() - offset)) { - diam = display->getHeight() - offset; - // if 2/3 of the other size would be smaller, use that - if (diam > (display->getWidth() * 2 / 3)) { - diam = display->getWidth() * 2 / 3; - } - } else { - diam = display->getWidth(); - if (diam > ((display->getHeight() - offset) * 2 / 3)) { - diam = (display->getHeight() - offset) * 2 / 3; - } - } - - return diam - 20; -}; - -// Draw north -static void drawCompassNorth(OLEDDisplay *display, int16_t compassX, int16_t compassY, float myHeading) -{ - // 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; - - Point N1(-0.04f, 0.65f), N2(0.04f, 0.65f); - Point N3(-0.04f, 0.55f), N4(0.04f, 0.55f); - Point *rosePoints[] = {&N1, &N2, &N3, &N4}; - - for (int i = 0; i < 4; i++) { - // North on compass will be negative of heading - rosePoints[i]->rotate(-myHeading); - rosePoints[i]->scale(getCompassDiam(display)); - rosePoints[i]->translate(compassX, compassY); - } - drawLine(display, N1, N3); - drawLine(display, N2, N4); - drawLine(display, N1, N4); -} #endif \ No newline at end of file