Full T-echo card support + Compact UI (#11342)

* T-echo card

* Update NRF52I2SOutput.cpp

* Update NRF52I2SOutput.h

* cleanup

* Update buzz.cpp

* use consistent runtime compact-panel check instead of mixing with compile-time macro

* Update NodeDB.cpp

* Update ExternalNotificationModule.cpp

* switched to Throttle::isWithinTimespanMs

* Update SharedUIDisplay.h

* trunk fix

* last cleanup

* ClockRenderer.cpp for OLED_COMPACT_UI and setup Unit C6L for new UI.

* Fixed regressions in standard OLED and TFT

---------

Co-authored-by: Jason P <applewiz@mac.com>
This commit is contained in:
HarukiToreda
2026-08-04 14:27:35 +00:00
committed by GitHub
co-authored by Jason P
parent d89f3eb8fc
commit 39e7aa6a6c
26 changed files with 1231 additions and 186 deletions
+36 -17
View File
@@ -250,6 +250,11 @@ void NotificationRenderer::drawBannercallback(OLEDDisplay *display, OLEDDisplayU
return;
}
// Compact panels: DOWN cancels menus instead of scrolling (covers every picker below).
if (graphics::isCompactPanel(display) && inEvent.inputEvent == INPUT_BROKER_DOWN) {
inEvent.inputEvent = INPUT_BROKER_CANCEL;
}
switch (current_notification_type) {
case notificationTypeEnum::none:
// Do nothing - no notification to display
@@ -641,8 +646,12 @@ void NotificationRenderer::drawNodePicker(OLEDDisplay *display, OLEDDisplayUiSta
const int arrowWidth = (currentResolution == ScreenResolution::High)
? UIRenderer::measureStringWithEmotes(display, "> <")
: UIRenderer::measureStringWithEmotes(display, "><");
const int maxTextWidth = std::max(0, display->getWidth() - 28 - arrowWidth);
UIRenderer::truncateStringWithEmotes(display, rawName, tempName, sizeof(tempName), maxTextWidth);
const bool compactPanel = graphics::isCompactPanel(display);
// Compact panels: box spans the full width, so just a small edge margin.
const int margin = compactPanel ? 4 : 28;
const int maxTextWidth = std::max(0, display->getWidth() - margin - arrowWidth);
UIRenderer::truncateStringWithEmotes(display, rawName, tempName, sizeof(tempName), maxTextWidth,
compactPanel ? "" : "...");
}
} else {
snprintf(tempName, sizeof(tempName), "(%04X)", (uint16_t)(node ? (node->num & 0xFFFF) : 0));
@@ -688,8 +697,9 @@ void NotificationRenderer::drawAlertBannerOverlay(OLEDDisplay *display, OLEDDisp
const char *lineStarts[MAX_LINES + 1] = {0};
uint16_t lineCount = 0;
char lineBuffer[40] = {0};
bool useTaggedTextBanner =
(current_notification_type == notificationTypeEnum::text_banner && alertBannerOptions == 0 && alertBannerLineCount > 0);
bool useTaggedTextBanner = ((current_notification_type == notificationTypeEnum::text_banner ||
current_notification_type == notificationTypeEnum::pairing_pin) &&
alertBannerOptions == 0 && alertBannerLineCount > 0);
if (useTaggedTextBanner) {
lineCount = std::min<uint8_t>(alertBannerLineCount, MAX_LINES);
@@ -775,7 +785,7 @@ void NotificationRenderer::drawAlertBannerOverlay(OLEDDisplay *display, OLEDDisp
const char *linePointers[visibleTotalLines + 1] = {0}; // this is sort of a dynamic allocation
// copy the linestarts to display to the linePointers holder
for (int i = 0; i < lineCount; i++) {
for (uint16_t i = 0; i < lineCount && i < visibleTotalLines; i++) {
linePointers[i] = lineStarts[i];
}
@@ -835,7 +845,9 @@ void NotificationRenderer::drawNotificationBox(OLEDDisplay *display, OLEDDisplay
BannerFont lineFonts[totalLines] = {};
uint8_t lineEffectiveHeights[totalLines] = {0};
const char *renderLines[totalLines] = {0};
bool useTaggedBannerFonts = (current_notification_type == notificationTypeEnum::text_banner && alertBannerOptions == 0);
bool useTaggedBannerFonts = (current_notification_type == notificationTypeEnum::text_banner ||
current_notification_type == notificationTypeEnum::pairing_pin) &&
alertBannerOptions == 0;
if (maxWidth != 0)
is_picker = true;
@@ -937,18 +949,25 @@ void NotificationRenderer::drawNotificationBox(OLEDDisplay *display, OLEDDisplay
}
int16_t boxTop = (display->height() / 2) - (boxHeight / 2);
boxHeight += (currentResolution == ScreenResolution::High) ? 2 : 1;
if (graphics::isCompactPanel(display)) {
boxLeft = 0;
boxTop = 0;
boxWidth = display->width();
boxHeight = display->height();
} else {
#if defined(OLED_TINY)
if (visibleTotalLines == 1) {
boxTop += 25;
}
if (alertBannerOptions < 3) {
int missingLines = 3 - alertBannerOptions;
int moveUp = missingLines * (effectiveLineHeight / 2);
boxTop -= moveUp;
if (boxTop < 0)
boxTop = 0;
}
if (visibleTotalLines == 1) {
boxTop += 25;
}
if (alertBannerOptions < 3) {
int missingLines = 3 - alertBannerOptions;
int moveUp = missingLines * (effectiveLineHeight / 2);
boxTop -= moveUp;
if (boxTop < 0)
boxTop = 0;
}
#endif
}
// Draw Box
display->setColor(BLACK);
@@ -1009,7 +1028,7 @@ void NotificationRenderer::drawNotificationBox(OLEDDisplay *display, OLEDDisplay
}
#endif
display->setColor(BLACK);
int yOffset = 3;
const int yOffset = graphics::isCompactPanel(display) ? 2 : 3;
if (current_notification_type == notificationTypeEnum::node_picker) {
UIRenderer::drawStringWithEmotes(display, textX, lineY - yOffset, lineBuffer, FONT_HEIGHT_SMALL, 1, false);
} else {