diff --git a/src/graphics/BRC.cpp b/src/graphics/BRC.cpp index 3928e3d33..d54ef4380 100644 --- a/src/graphics/BRC.cpp +++ b/src/graphics/BRC.cpp @@ -98,7 +98,7 @@ int BRCAddress::radial(char *buf, size_t len) return snprintf(buf, len, "%d:%02d", hour, minute); }; -int BRCAddress::annular(char *buf, size_t len) +int BRCAddress::annular(char *buf, size_t len, bool noUnit) { const char *unit = "m"; float unitMultiplier = FEET_TO_METER; @@ -106,6 +106,7 @@ int BRCAddress::annular(char *buf, size_t len) unitMultiplier = 1.0; unit = "ft"; } + if (noUnit) unit = ""; if (bearing > 1.75 && bearing < 10.25) { const char *street = nullptr; @@ -134,7 +135,17 @@ int BRCAddress::full(char *buf, size_t len) *(buf++) = ' '; *(buf++) = '&'; *(buf++) = ' '; - buf += annular(buf, len - l - 4); + buf += annular(buf, len - l - 4, false); + buf[l] = 0; // always null terminated + return l; +}; + +int BRCAddress::compact(char *buf, size_t len) +{ + auto l = radial(buf, len - 2); + buf += l; + *(buf++) = '&'; + buf += annular(buf, len - l - 2, true); buf[l] = 0; // always null terminated return l; }; diff --git a/src/graphics/BRC.h b/src/graphics/BRC.h index 84cb903a8..764131fd0 100644 --- a/src/graphics/BRC.h +++ b/src/graphics/BRC.h @@ -6,8 +6,9 @@ class BRCAddress BRCAddress(int32_t lat, int32_t lon); int radial(char *buf, size_t len); - int annular(char *buf, size_t len); + int annular(char *buf, size_t len, bool noUnit); int full(char *buf, size_t len); + int compact(char *buf, size_t len); private: float bearing; diff --git a/src/graphics/draw/NodeListRenderer.cpp b/src/graphics/draw/NodeListRenderer.cpp index 98e5332e2..ae4bcd7d6 100644 --- a/src/graphics/draw/NodeListRenderer.cpp +++ b/src/graphics/draw/NodeListRenderer.cpp @@ -345,15 +345,16 @@ void drawEntryBRC(OLEDDisplay *display, meshtastic_NodeInfoLite *node, int16_t x 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); + display->drawString(xText, y, nodeName); + + char buf[14] = ""; + BRCAddress(node->position.latitude_i, node->position.longitude_i).compact(buf, 14); + auto nameWidth = display->getStringWidth("WWWW"); // Fixed width so they are aligned. + display->drawString(xText + nameWidth, y, buf); - 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) { @@ -413,6 +414,34 @@ void drawCompassArrow(OLEDDisplay *display, meshtastic_NodeInfoLite *node, int16 */ } +void drawLastSeenExtra(OLEDDisplay *display, meshtastic_NodeInfoLite *node, int16_t x, int16_t y, int columnWidth, + float /*myHeading*/, double /*userLat*/, double /*userLon*/) +{ + char timeStr[10]; + uint32_t seconds = sinceLastSeen(node); + if (seconds == 0 || seconds == UINT32_MAX) { + snprintf(timeStr, sizeof(timeStr), "?"); + } else { + uint32_t minutes = seconds / 60, hours = minutes / 60, days = hours / 24; + snprintf(timeStr, sizeof(timeStr), (days > 99 ? "?" : "%d%c"), + (days ? days + : hours ? hours + : minutes), + (days ? 'd' + : hours ? 'h' + : 'm')); + } + + bool isLeftCol = (x < SCREEN_WIDTH / 2); + int timeOffset = (isHighResolution) ? (isLeftCol ? 7 : 10) : (isLeftCol ? 3 : 7); + int rightEdge = x + columnWidth - timeOffset; + if (timeStr[strlen(timeStr) - 1] == 'm') // Fix the fact that our fonts don't line up well all the time + rightEdge -= 1; + //display->setTextAlignment(TEXT_ALIGN_RIGHT); + int textWidth = display->getStringWidth(timeStr); + display->drawString(rightEdge - textWidth, y, timeStr); +} + // ============================= // Main Screen Functions // ============================= @@ -569,27 +598,11 @@ void drawNodeListWithCompasses(OLEDDisplay *display, OLEDDisplayUiState *state, void drawBRCList(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); + drawNodeListScreen(display, state, x, y, "BRC", drawEntryBRC, drawLastSeenExtra, 0, lat, lon, 1); } /// Draw a series of fields in a column, wrapping to multiple columns if needed