fix: landscape e-ink layout corrections — clock overlap, keyboard overflow, bar sizing, nearby detail

- 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 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-05-22 19:11:25 +02:00
parent 1d8ca25469
commit 118f29b0a1
5 changed files with 38 additions and 23 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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() {