mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-07-26 23:08:11 +00:00
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:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user