From 118f29b0a1cccc25d188713c374aafe38a77183f Mon Sep 17 00:00:00 2001 From: Jakub <106778416+MarekZegare4@users.noreply.github.com> Date: Fri, 22 May 2026 19:11:25 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20landscape=20e-ink=20layout=20corrections?= =?UTF-8?q?=20=E2=80=94=20clock=20overlap,=20keyboard=20overflow,=20bar=20?= =?UTF-8?q?sizing,=20nearby=20detail?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - GxEPDDisplay: fontAscender only applies to sz=1 with Lemon; sz=2 (NULL font) was incorrectly getting a 16px cursor offset, causing clock text to render 16px lower than expected and overlap the date line - KeyboardWidget: compute cell_h from available screen height instead of lh+1; tighten sep_y to lh so the grid fits within 122px even with Lemon font (lh=20) - SettingsScreen renderBar: constrain box size to available width so the 5th buzzer-volume square doesn't overflow past the right edge with Lemon font - NearbyScreen discover detail: manually truncate b64 public key by charWidth to guarantee one-line rendering; use dynamic step = (height-hdr)/5 so Status line doesn't fall off the bottom of the screen - NearbyScreen contacts detail: merge dist+az into one line and use dynamic step to fit 5 lines within the display; removes the off-screen Seen: row - AutoAdvertScreen: replace lineStep() gap before hints with 4px fixed gap so both hint lines fit within the display with large fonts Co-Authored-By: Claude Sonnet 4.6 --- .../companion_radio/ui-new/AutoAdvertScreen.h | 2 +- .../companion_radio/ui-new/KeyboardWidget.h | 6 +-- .../companion_radio/ui-new/NearbyScreen.h | 38 ++++++++++++------- .../companion_radio/ui-new/SettingsScreen.h | 9 +++-- src/helpers/ui/GxEPDDisplay.cpp | 6 +-- 5 files changed, 38 insertions(+), 23 deletions(-) diff --git a/examples/companion_radio/ui-new/AutoAdvertScreen.h b/examples/companion_radio/ui-new/AutoAdvertScreen.h index 4899f29d..c8dc1bfa 100644 --- a/examples/companion_radio/ui-new/AutoAdvertScreen.h +++ b/examples/companion_radio/ui-new/AutoAdvertScreen.h @@ -28,7 +28,7 @@ public: int label_y = display.listStart(); int bar_y = label_y + display.lineStep(); int bar_h = display.lineStep(); - int tip_y = bar_y + bar_h + display.lineStep(); + int tip_y = bar_y + bar_h + 4; display.drawTextCentered(display.width() / 2, 0, "AUTO-ADVERT"); display.fillRect(0, display.headerH() - 1, display.width(), 1); diff --git a/examples/companion_radio/ui-new/KeyboardWidget.h b/examples/companion_radio/ui-new/KeyboardWidget.h index 8cfbfd1d..ec1c89c6 100644 --- a/examples/companion_radio/ui-new/KeyboardWidget.h +++ b/examples/companion_radio/ui-new/KeyboardWidget.h @@ -61,9 +61,9 @@ struct KeyboardWidget { const int lh = display.getLineHeight(); const int cw = display.getCharWidth(); const int cell_w = display.width() / KB_COLS_CHAR; - const int cell_h = lh + 1; - const int sep_y = lh + 1; - const int chars_y = sep_y + 2; + const int sep_y = lh; // tight separator: preview row height only + const int chars_y = sep_y + 1; + const int cell_h = (display.height() - chars_y) / (KB_ROWS_CHAR + 1); const int spec_y = chars_y + KB_ROWS_CHAR * cell_h; const int spec_w = display.width() / KB_SPECIAL; diff --git a/examples/companion_radio/ui-new/NearbyScreen.h b/examples/companion_radio/ui-new/NearbyScreen.h index 315f79cb..b8e4e71d 100644 --- a/examples/companion_radio/ui-new/NearbyScreen.h +++ b/examples/companion_radio/ui-new/NearbyScreen.h @@ -215,12 +215,27 @@ class NearbyScreen : public UIScreen { display.setColor(DisplayDriver::LIGHT); display.fillRect(0, hdr - 1, display.width(), 1); - // public key as base64 + // public key as base64 — truncate to one line via charWidth char b64[48]; pubKeyToBase64(r.pub_key, b64, sizeof(b64)); - display.drawTextEllipsized(2, hdr, display.width() - 4, b64); + { + int max_chars = (display.width() - 4) / display.getCharWidth(); + int b64_len = strlen(b64); + char b64_line[48]; + if (b64_len > max_chars) { + strncpy(b64_line, b64, max_chars - 3); + b64_line[max_chars - 3] = '\0'; + strcat(b64_line, "..."); + } else { + strncpy(b64_line, b64, sizeof(b64_line) - 1); + b64_line[sizeof(b64_line) - 1] = '\0'; + } + display.setCursor(2, hdr); + display.print(b64_line); + } - int step = lh + 1; + // distribute 4 remaining lines across available height below b64 + int step = (display.height() - hdr) / 5; char buf[32]; snprintf(buf, sizeof(buf), "RSSI: %d dBm", (int)r.rssi); display.setCursor(2, hdr + step); display.print(buf); @@ -394,9 +409,7 @@ public: // ── detail view ────────────────────────────────────────────────────────── if (_detail && _sel < _count) { const Entry& e = _entries[_sel]; - int lh = display.getLineHeight(); int hdr = display.headerH(); - int step = lh + 1; display.setColor(DisplayDriver::LIGHT); display.fillRect(0, 0, display.width(), hdr - 1); @@ -406,6 +419,8 @@ public: display.drawTextEllipsized(2, 1, display.width() - 4, filtered); display.setColor(DisplayDriver::LIGHT); + // 5 lines: lat, lon, dist+bearing, type, seen — distributed across available height + int step = (display.height() - hdr) / 5; char buf[32]; snprintf(buf, sizeof(buf), "Lat: %.5f", e.lat_e6 / 1e6); display.setCursor(2, hdr); display.print(buf); @@ -417,22 +432,19 @@ public: char dist[12]; fmtDist(dist, sizeof(dist), e.dist_km); int az = bearingDeg(_own_lat, _own_lon, e.lat_e6, e.lon_e6); - snprintf(buf, sizeof(buf), "Dist: %s", dist); - display.setCursor(2, hdr + step * 2); display.print(buf); - snprintf(buf, sizeof(buf), "Az: %dd (%s)", az, bearingCardinal(az)); - display.setCursor(2, hdr + step * 3); display.print(buf); + snprintf(buf, sizeof(buf), "Dist: %s %s", dist, bearingCardinal(az)); } else { - display.setCursor(2, hdr + step * 2); display.print("Dist: no own GPS"); - display.setCursor(2, hdr + step * 3); display.print("Az: unknown"); + snprintf(buf, sizeof(buf), "Dist: no GPS"); } + display.setCursor(2, hdr + step * 2); display.print(buf); snprintf(buf, sizeof(buf), "Type: %s", typeName(e.type)); - display.setCursor(2, hdr + step * 4); display.print(buf); + display.setCursor(2, hdr + step * 3); display.print(buf); char age[16]; fmtAge(age, sizeof(age), e.lastmod); snprintf(buf, sizeof(buf), "Seen: %s", age); - display.setCursor(2, hdr + step * 5); display.print(buf); + display.setCursor(2, hdr + step * 4); display.print(buf); return 2000; } diff --git a/examples/companion_radio/ui-new/SettingsScreen.h b/examples/companion_radio/ui-new/SettingsScreen.h index 8f390ee2..49aef7ed 100644 --- a/examples/companion_radio/ui-new/SettingsScreen.h +++ b/examples/companion_radio/ui-new/SettingsScreen.h @@ -87,9 +87,12 @@ class SettingsScreen : public UIScreen { } void renderBar(DisplayDriver& display, int x, int y, int value, int max_val) { - const int box_h = display.getLineHeight() - 2; - const int box_w = box_h; - const int gap = 2; + const int gap = 2; + const int avail = display.width() - x; + const int raw = (avail - (max_val - 1) * gap) / max_val; + const int cap = display.getLineHeight() - 2; + const int box_h = raw < cap ? (raw < 2 ? 2 : raw) : cap; + const int box_w = box_h; for (int i = 0; i < max_val; i++) { int bx = x + i * (box_w + gap); display.drawRect(bx, y, box_w, box_h); diff --git a/src/helpers/ui/GxEPDDisplay.cpp b/src/helpers/ui/GxEPDDisplay.cpp index 17481946..ff4fff28 100644 --- a/src/helpers/ui/GxEPDDisplay.cpp +++ b/src/helpers/ui/GxEPDDisplay.cpp @@ -17,9 +17,9 @@ // coordinates (same convention as the OLED driver). Add the font ascender so // the two conventions match. static int fontAscender(int sz, bool use_lemon, int scale) { - if (sz == 3) return 26; // FreeSans18pt7b: proportional, baseline origin - if (use_lemon) return 8 * scale; // Lemon GFX font: baseline origin, ascender 8px×scale - return 0; // GFX built-in font: cursor is top-left of cell + if (sz == 3) return 26; // FreeSans18pt7b: proportional, baseline origin + if (sz == 1 && use_lemon) return 8 * scale; // Lemon GFX font: baseline origin, ascender 8px×scale + return 0; // GFX built-in font: cursor is top-left of cell } bool GxEPDDisplay::begin() {