BaseUI: Nodelist screen/favorite screen cleanup (#10197)
* nodelist screen cleanup * Update UIRenderer.cpp * Update src/graphics/draw/UIRenderer.cpp * removed brackets from hop and made signal mutually exclusive
This commit is contained in:
@@ -275,9 +275,12 @@ void drawEntryHopSignal(OLEDDisplay *display, meshtastic_NodeInfoLite *node, int
|
|||||||
|
|
||||||
int nameMaxWidth = getNodeNameMaxWidth(columnWidth, columnWidth - 25);
|
int nameMaxWidth = getNodeNameMaxWidth(columnWidth, columnWidth - 25);
|
||||||
int barsOffset = (currentResolution == ScreenResolution::High) ? (isLeftCol ? 20 : 24) : (isLeftCol ? 15 : 19);
|
int barsOffset = (currentResolution == ScreenResolution::High) ? (isLeftCol ? 20 : 24) : (isLeftCol ? 15 : 19);
|
||||||
int hopOffset = (currentResolution == ScreenResolution::High) ? (isLeftCol ? 21 : 29) : (isLeftCol ? 13 : 17);
|
constexpr int kBarCount = 4;
|
||||||
|
constexpr int kBarWidth = 2;
|
||||||
|
constexpr int kBarGap = 1;
|
||||||
|
|
||||||
int barsXOffset = columnWidth - barsOffset;
|
int barsXOffset = columnWidth - barsOffset;
|
||||||
|
int barsRightEdge = x + barsXOffset + ((kBarCount - 1) * (kBarWidth + kBarGap)) + kBarWidth;
|
||||||
|
|
||||||
const int nameX = x + ((currentResolution == ScreenResolution::High) ? 6 : 3);
|
const int nameX = x + ((currentResolution == ScreenResolution::High) ? 6 : 3);
|
||||||
char nodeName[96];
|
char nodeName[96];
|
||||||
@@ -304,28 +307,35 @@ void drawEntryHopSignal(OLEDDisplay *display, meshtastic_NodeInfoLite *node, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw signal strength bars
|
const bool isZeroHop = node->has_hops_away && node->hops_away == 0;
|
||||||
int bars = (node->snr > 5) ? 4 : (node->snr > 0) ? 3 : (node->snr > -5) ? 2 : (node->snr > -10) ? 1 : 0;
|
|
||||||
int barWidth = 2;
|
|
||||||
int barStartX = x + barsXOffset;
|
|
||||||
int barStartY = y + 1 + (FONT_HEIGHT_SMALL / 2) + 2;
|
|
||||||
|
|
||||||
for (int b = 0; b < 4; b++) {
|
// Show signal only for direct neighbors (0 hops)
|
||||||
if (b < bars) {
|
if (isZeroHop) {
|
||||||
int height = (b * 2);
|
int bars = (node->snr > 5) ? 4 : (node->snr > 0) ? 3 : (node->snr > -5) ? 2 : (node->snr > -10) ? 1 : 0;
|
||||||
display->fillRect(barStartX + (b * (barWidth + 1)), barStartY - height, barWidth, height);
|
int barStartX = x + barsXOffset;
|
||||||
|
int barStartY = y + 1 + (FONT_HEIGHT_SMALL / 2) + 2;
|
||||||
|
|
||||||
|
for (int b = 0; b < kBarCount; b++) {
|
||||||
|
if (b < bars) {
|
||||||
|
int height = (b * 2);
|
||||||
|
display->fillRect(barStartX + (b * (kBarWidth + kBarGap)), barStartY - height, kBarWidth, height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw hop count
|
// Draw hop count + hop icon
|
||||||
char hopStr[6] = "";
|
if (node->has_hops_away && node->hops_away > 0) {
|
||||||
if (node->has_hops_away && node->hops_away > 0)
|
char hopCount[6];
|
||||||
snprintf(hopStr, sizeof(hopStr), "[%d]", node->hops_away);
|
snprintf(hopCount, sizeof(hopCount), "%d", node->hops_away);
|
||||||
|
|
||||||
if (hopStr[0] != '\0') {
|
const int hopCountWidth = display->getStringWidth(hopCount);
|
||||||
int rightEdge = x + columnWidth - hopOffset;
|
const int gap = 1;
|
||||||
int textWidth = display->getStringWidth(hopStr);
|
const int totalWidth = hopCountWidth + gap + hop_width;
|
||||||
display->drawString(rightEdge - textWidth, y, hopStr);
|
const int hopX = barsRightEdge - totalWidth;
|
||||||
|
const int iconY = y + (FONT_HEIGHT_SMALL - hop_height) / 2;
|
||||||
|
|
||||||
|
display->drawString(hopX, y, hopCount);
|
||||||
|
display->drawXbm(hopX + hopCountWidth + gap, iconY, hop_width, hop_height, hop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -405,10 +405,10 @@ void UIRenderer::drawFavoriteNode(OLEDDisplay *display, OLEDDisplayUiState *stat
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// === 2. Signal and Hops (combined on one line, if available) ===
|
// === 2. Signal/Hops line (if available) ===
|
||||||
char signalHopsStr[32] = "";
|
|
||||||
bool haveSignal = false;
|
bool haveSignal = false;
|
||||||
int bars = 0;
|
int bars = 0;
|
||||||
|
const char *qualityLabel = nullptr;
|
||||||
|
|
||||||
// Helper to get SNR limit based on modem preset
|
// Helper to get SNR limit based on modem preset
|
||||||
auto getSnrLimit = [](meshtastic_Config_LoRaConfig_ModemPreset preset) -> float {
|
auto getSnrLimit = [](meshtastic_Config_LoRaConfig_ModemPreset preset) -> float {
|
||||||
@@ -429,80 +429,51 @@ void UIRenderer::drawFavoriteNode(OLEDDisplay *display, OLEDDisplayUiState *stat
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Calculate signal grade using modem preset and SNR only
|
|
||||||
float snrLimit = getSnrLimit(config.lora.modem_preset);
|
|
||||||
float snr = node->snr;
|
|
||||||
|
|
||||||
// Determine signal quality label and bars using SNR-only grading
|
|
||||||
const char *qualityLabel = nullptr;
|
|
||||||
|
|
||||||
if (snr > snrLimit + 10) {
|
|
||||||
qualityLabel = "Good";
|
|
||||||
bars = 4;
|
|
||||||
} else if (snr > snrLimit + 6) {
|
|
||||||
qualityLabel = "Good";
|
|
||||||
bars = 3;
|
|
||||||
} else if (snr > snrLimit + 2) {
|
|
||||||
qualityLabel = "Good";
|
|
||||||
bars = 2;
|
|
||||||
} else if (snr > snrLimit - 4) {
|
|
||||||
qualityLabel = "Fair";
|
|
||||||
bars = 1;
|
|
||||||
} else {
|
|
||||||
qualityLabel = "Bad";
|
|
||||||
bars = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add extra spacing on the left if we have an API connection to account for the common footer icons
|
// Add extra spacing on the left if we have an API connection to account for the common footer icons
|
||||||
const char *leftSideSpacing =
|
const char *leftSideSpacing =
|
||||||
graphics::isAPIConnected(service->api_state) ? (currentResolution == ScreenResolution::High ? " " : " ") : " ";
|
graphics::isAPIConnected(service->api_state) ? (currentResolution == ScreenResolution::High ? " " : " ") : " ";
|
||||||
|
const bool isZeroHop = node->has_hops_away && node->hops_away == 0;
|
||||||
|
|
||||||
// --- Build the Signal/Hops line ---
|
// Signal text/bars are only for direct (zero-hop) nodes with valid SNR.
|
||||||
// Only show signal if we have valid SNR
|
if (isZeroHop) {
|
||||||
if (snr > -100 && snr != 0) {
|
float snr = node->snr;
|
||||||
snprintf(signalHopsStr, sizeof(signalHopsStr), "%sSig:%s", leftSideSpacing, qualityLabel);
|
if (snr > -100 && snr != 0) {
|
||||||
haveSignal = true;
|
float snrLimit = getSnrLimit(config.lora.modem_preset);
|
||||||
}
|
// Determine signal quality label and bars using SNR-only grading.
|
||||||
|
if (snr > snrLimit + 10) {
|
||||||
if (node->hops_away > 0) {
|
qualityLabel = "Good";
|
||||||
size_t len = strlen(signalHopsStr);
|
bars = 4;
|
||||||
if (haveSignal) {
|
} else if (snr > snrLimit + 6) {
|
||||||
snprintf(signalHopsStr + len, sizeof(signalHopsStr) - len, " [#]");
|
qualityLabel = "Good";
|
||||||
} else {
|
bars = 3;
|
||||||
snprintf(signalHopsStr, sizeof(signalHopsStr), "[#]");
|
} else if (snr > snrLimit + 2) {
|
||||||
}
|
qualityLabel = "Good";
|
||||||
}
|
bars = 2;
|
||||||
|
} else if (snr > snrLimit - 4) {
|
||||||
if (signalHopsStr[0]) {
|
qualityLabel = "Fair";
|
||||||
int yPos = getTextPositions(display)[line++];
|
bars = 1;
|
||||||
int curX = x;
|
} else {
|
||||||
|
qualityLabel = "Bad";
|
||||||
// Split combined string into signal text and hop suffix
|
bars = 1;
|
||||||
char sigPart[20] = "";
|
|
||||||
const char *hopPart = nullptr;
|
|
||||||
|
|
||||||
char *bracket = strchr(signalHopsStr, '[');
|
|
||||||
if (bracket) {
|
|
||||||
size_t n = (size_t)(bracket - signalHopsStr);
|
|
||||||
if (n >= sizeof(sigPart))
|
|
||||||
n = sizeof(sigPart) - 1;
|
|
||||||
memcpy(sigPart, signalHopsStr, n);
|
|
||||||
sigPart[n] = '\0';
|
|
||||||
|
|
||||||
// Trim trailing spaces
|
|
||||||
while (strlen(sigPart) && sigPart[strlen(sigPart) - 1] == ' ') {
|
|
||||||
sigPart[strlen(sigPart) - 1] = '\0';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hopPart = bracket; // "[n Hop(s)]"
|
haveSignal = true;
|
||||||
} else {
|
|
||||||
strncpy(sigPart, signalHopsStr, sizeof(sigPart) - 1);
|
|
||||||
sigPart[sizeof(sigPart) - 1] = '\0';
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Draw signal quality text
|
const bool showHops = node->has_hops_away && node->hops_away > 0;
|
||||||
display->drawString(curX, yPos, sigPart);
|
|
||||||
curX += display->getStringWidth(sigPart) + 4;
|
if (haveSignal || showHops) {
|
||||||
|
int yPos = getTextPositions(display)[line++];
|
||||||
|
int curX = x + display->getStringWidth(leftSideSpacing);
|
||||||
|
|
||||||
|
// Draw signal quality text for zero-hop nodes when present.
|
||||||
|
if (haveSignal && qualityLabel) {
|
||||||
|
char signalLabel[20];
|
||||||
|
snprintf(signalLabel, sizeof(signalLabel), "Sig:%s", qualityLabel);
|
||||||
|
display->drawString(curX, yPos, signalLabel);
|
||||||
|
curX += display->getStringWidth(signalLabel) + 4;
|
||||||
|
}
|
||||||
|
|
||||||
// Draw signal bars (skip on UltraLow, text only)
|
// Draw signal bars (skip on UltraLow, text only)
|
||||||
if (currentResolution != ScreenResolution::UltraLow && haveSignal && bars > 0) {
|
if (currentResolution != ScreenResolution::UltraLow && haveSignal && bars > 0) {
|
||||||
@@ -541,12 +512,12 @@ void UIRenderer::drawFavoriteNode(OLEDDisplay *display, OLEDDisplayUiState *stat
|
|||||||
curX += (kMaxBars * barWidth) + ((kMaxBars - 1) * barGap) + 2;
|
curX += (kMaxBars * barWidth) + ((kMaxBars - 1) * barGap) + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw hops AFTER the bars as: [ number + hop icon ]
|
// Draw hops for non-zero-hop nodes as: number + hop icon.
|
||||||
if (hopPart && node->hops_away > 0) {
|
// This path is mutually exclusive with the zero-hop signal-bars path above.
|
||||||
|
if (showHops) {
|
||||||
// open bracket
|
// hop label
|
||||||
display->drawString(curX, yPos, "[");
|
display->drawString(curX, yPos, "Hop:");
|
||||||
curX += display->getStringWidth("[") + 1;
|
curX += display->getStringWidth("Hop:") + 2;
|
||||||
|
|
||||||
// hop count
|
// hop count
|
||||||
char hopCount[6];
|
char hopCount[6];
|
||||||
@@ -558,9 +529,6 @@ void UIRenderer::drawFavoriteNode(OLEDDisplay *display, OLEDDisplayUiState *stat
|
|||||||
const int iconY = yPos + (FONT_HEIGHT_SMALL - hop_height) / 2;
|
const int iconY = yPos + (FONT_HEIGHT_SMALL - hop_height) / 2;
|
||||||
display->drawXbm(curX, iconY, hop_width, hop_height, hop);
|
display->drawXbm(curX, iconY, hop_width, hop_height, hop);
|
||||||
curX += hop_width + 1;
|
curX += hop_width + 1;
|
||||||
|
|
||||||
// closing bracket
|
|
||||||
display->drawString(curX, yPos, "]");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user