diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 57ea64fa9..934040d88 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -919,7 +919,7 @@ void Screen::setFrames(FrameFocus focus) #endif #if HAS_GPS fsi.positions.nodelist_bearings = numframes; - normalFrames[numframes++] = graphics::NodeListRenderer::drawNodeListWithCompasses; + normalFrames[numframes++] = graphics::NodeListRenderer::drawBRCListWithCompasses; indicatorIcons.push_back(icon_list); fsi.positions.gps = numframes; diff --git a/src/graphics/draw/NodeListRenderer.cpp b/src/graphics/draw/NodeListRenderer.cpp index d8746fb69..519c4363e 100644 --- a/src/graphics/draw/NodeListRenderer.cpp +++ b/src/graphics/draw/NodeListRenderer.cpp @@ -9,6 +9,7 @@ #include "graphics/ScreenFonts.h" #include "graphics/SharedUIDisplay.h" #include "graphics/images.h" +#include "graphics/BRC.h" #include "meshUtils.h" #include @@ -335,6 +336,34 @@ void drawEntryCompass(OLEDDisplay *display, meshtastic_NodeInfoLite *node, int16 } } + +void drawEntryBRC(OLEDDisplay *display, meshtastic_NodeInfoLite *node, int16_t x, int16_t y, int columnWidth) +{ + bool isLeftCol = (x < SCREEN_WIDTH / 2); + + // Adjust max text width depending on column and screen width + int nameMaxWidth = columnWidth - (isHighResolution ? (isLeftCol ? 25 : 28) : (isLeftCol ? 20 : 22)); + + const char *nodeName = getSafeNodeName(node); + auto nameWidth = display->getStringWidth("XXXXX"); + display->setTextAlignment(TEXT_ALIGN_LEFT); + display->setFont(FONT_SMALL); + auto xText = x + ((isHighResolution) ? 6 : 3); + display->drawStringMaxWidth(xText, y, nameMaxWidth, nodeName); + + char buf[32] = ""; + BRCAddress(node->position.latitude_i, node->position.longitude_i).full(buf, 32); + display->drawStringMaxWidth(xText + nameWidth, y, nameMaxWidth - nameWidth + 20, buf); + + if (node->is_favorite) { + if (isHighResolution) { + drawScaledXBitmap16x16(x, y + 6, smallbulletpoint_width, smallbulletpoint_height, smallbulletpoint, display); + } else { + display->drawXbm(x, y + 5, smallbulletpoint_width, smallbulletpoint_height, smallbulletpoint); + } + } +} + void drawCompassArrow(OLEDDisplay *display, meshtastic_NodeInfoLite *node, int16_t x, int16_t y, int columnWidth, float myHeading, double userLat, double userLon) { @@ -389,12 +418,12 @@ void drawCompassArrow(OLEDDisplay *display, meshtastic_NodeInfoLite *node, int16 // ============================= void drawNodeListScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y, const char *title, - EntryRenderer renderer, NodeExtrasRenderer extras, float heading, double lat, double lon) + EntryRenderer renderer, NodeExtrasRenderer extras, float heading, double lat, double lon, int totalColumns) { const int COMMON_HEADER_HEIGHT = FONT_HEIGHT_SMALL - 1; const int rowYOffset = FONT_HEIGHT_SMALL - 3; - int columnWidth = display->getWidth() / 2; + int columnWidth = display->getWidth() / totalColumns; display->clear(); @@ -408,7 +437,6 @@ void drawNodeListScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t int totalRowsAvailable = (display->getHeight() - y) / rowYOffset; int visibleNodeRows = totalRowsAvailable; - int totalColumns = 2; int startIndex = scrollIndex * visibleNodeRows * totalColumns; if (nodeDB->getMeshNodeByIndex(startIndex)->num == nodeDB->getNodeNum()) { @@ -446,7 +474,7 @@ void drawNodeListScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t } // Draw column separator - if (shownCount > 0) { + if (shownCount > 0 && totalColumns > 1) { const int firstNodeY = y + 3; drawColumnSeparator(display, x, firstNodeY, lastNodeY); } @@ -539,6 +567,31 @@ void drawNodeListWithCompasses(OLEDDisplay *display, OLEDDisplayUiState *state, drawNodeListScreen(display, state, x, y, "Bearings", drawEntryCompass, drawCompassArrow, heading, lat, lon); } +void drawBRCListWithCompasses(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) +{ + float heading = 0; + bool validHeading = false; + auto ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum()); + double lat = DegD(ourNode->position.latitude_i); + double lon = DegD(ourNode->position.longitude_i); + + if (uiconfig.compass_mode != meshtastic_CompassMode_FREEZE_HEADING) { +#if HAS_GPS + if (screen->hasHeading()) { + heading = screen->getHeading(); // degrees + validHeading = true; + } else { + heading = screen->estimatedHeading(lat, lon); + validHeading = !isnan(heading); + } +#endif + + if (!validHeading) + return; + } + drawNodeListScreen(display, state, x, y, "Black Rock City", drawEntryBRC, drawCompassArrow, heading, lat, lon, 1); +} + /// Draw a series of fields in a column, wrapping to multiple columns if needed void drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char **fields) { @@ -564,4 +617,4 @@ void drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char **fields } // namespace NodeListRenderer } // namespace graphics -#endif \ No newline at end of file +#endif diff --git a/src/graphics/draw/NodeListRenderer.h b/src/graphics/draw/NodeListRenderer.h index ea8df8bd9..32fb8144d 100644 --- a/src/graphics/draw/NodeListRenderer.h +++ b/src/graphics/draw/NodeListRenderer.h @@ -29,7 +29,7 @@ enum NodeListMode { MODE_LAST_HEARD = 0, MODE_HOP_SIGNAL = 1, MODE_DISTANCE = 2, // Main node list screen function void drawNodeListScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y, const char *title, EntryRenderer renderer, NodeExtrasRenderer extras = nullptr, float heading = 0, double lat = 0, - double lon = 0); + double lon = 0, int totalColumns = 2); // Entry renderers void drawEntryLastHeard(OLEDDisplay *display, meshtastic_NodeInfoLite *node, int16_t x, int16_t y, int columnWidth); @@ -48,6 +48,7 @@ void drawHopSignalScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_ void drawDistanceScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); void drawDynamicNodeListScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); void drawNodeListWithCompasses(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); +void drawBRCListWithCompasses(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); // Utility functions const char *getCurrentModeTitle(int screenWidth);