mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-07-26 14:58:12 +00:00
feat(ui): migrate e-ink to misc-fixed font; fix Alarm UX and status-bar icon alignment
- GxEPDDisplay now uses the same single misc-fixed 6x9 font as the OLED driver (Lemon retired there too), with baseline math updated for the new ascent. - Clock Tools' Alarm screen: Repeat and Armed now respond to LEFT/RIGHT like every other multi-value/toggle field in Settings, not Enter-only; Hour/Minute merged into one Time row edited with a hand-rolled HH:MM digit cursor (like the Timer's), replacing the two-row DigitEditor popups; Repeat's "Off" label now matches the codebase-wide ON/OFF casing. - Top status bar: battery icon now shares the same box height as the other status icons (Bluetooth/mute/etc.) instead of standing 2px taller, and its charge nub is properly vertically centred instead of drifting off-centre at non-multiple-of-4 box heights. - Small settings-gear icon glyph tweak; wio-tracker-l1 screenshot build variant now enables DUAL_SERIAL. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -312,7 +312,7 @@ struct NodePrefs { // persisted to file
|
||||
}
|
||||
}
|
||||
static const char* alarmRepeatLabel(uint8_t idx) {
|
||||
static const char* L[ALARM_REPEAT_COUNT] = { "Off", "Daily", "Weekdays", "Weekends" };
|
||||
static const char* L[ALARM_REPEAT_COUNT] = { "OFF", "Daily", "Weekdays", "Weekends" };
|
||||
return L[idx < ALARM_REPEAT_COUNT ? idx : 0];
|
||||
}
|
||||
|
||||
|
||||
@@ -13,10 +13,14 @@
|
||||
// • Stopwatch — purely a display utility with no background action, so its
|
||||
// millis() state lives here; it keeps counting while you're elsewhere.
|
||||
//
|
||||
// Numeric fields (alarm hour/minute, timer h/m/s) are edited with the shared
|
||||
// framework DigitEditor (digit-by-digit: LEFT/RIGHT cursor, UP/DOWN +/- the
|
||||
// place, min/max enforced) — the same widget Settings/Repeater use for Freq,
|
||||
// rather than a hand-rolled wrap.
|
||||
// Alarm hour/minute and the Timer's HH:MM:SS are both edited with the same
|
||||
// hand-rolled digit cursor (LEFT/RIGHT moves between digits, UP/DOWN steps
|
||||
// the digit under it, wrapping within its place and keeping the whole field
|
||||
// a valid time) rather than the shared DigitEditor framework Settings/
|
||||
// Repeater use for Freq — DigitEditor edits one flat decimal value, and a
|
||||
// combined HH:MM/HH:MM:SS field needs each place capped independently (hour
|
||||
// tens <= 2, minute/second tens <= 5), which a single flat step size can't
|
||||
// express without landing on invalid times at the boundaries.
|
||||
//
|
||||
// E-INK: the running timer/stopwatch readouts would thrash a slow e-paper panel
|
||||
// if redrawn every second, so on e-ink the live readout refreshes only coarsely
|
||||
@@ -25,7 +29,6 @@
|
||||
|
||||
#include "../NodePrefs.h"
|
||||
#include "icons.h" // drawList / drawRowSelection
|
||||
#include "DigitEditor.h" // shared digit-by-digit numeric editor
|
||||
|
||||
class ClockToolsScreen : public UIScreen {
|
||||
UITask* _task;
|
||||
@@ -45,12 +48,10 @@ class ClockToolsScreen : public UIScreen {
|
||||
uint32_t _sw_start_ms = 0;
|
||||
uint32_t _sw_accum_ms = 0;
|
||||
|
||||
// Shared numeric editor (alarm hour/minute) + which field it targets. The
|
||||
// timer uses its own continuous digit cursor (per-place caps a single
|
||||
// DigitEditor can't express), so it isn't listed here.
|
||||
enum EditKind : uint8_t { EK_NONE, EK_A_HOUR, EK_A_MIN };
|
||||
DigitEditor _editor;
|
||||
EditKind _edit_kind = EK_NONE;
|
||||
// Alarm time's own digit cursor (same shape as the timer's, just HH:MM —
|
||||
// no seconds field).
|
||||
bool _alarm_editing = false;
|
||||
uint8_t _alarm_cur = 0; // digit cursor over HH:MM, 0..3 (skips the colon)
|
||||
|
||||
// E-ink: coarse refresh for the live readouts (millis underneath is exact).
|
||||
static int liveTickMs(DisplayDriver& d, int oled_ms) { return d.isEink() ? 30000 : oled_ms; }
|
||||
@@ -96,32 +97,49 @@ class ClockToolsScreen : public UIScreen {
|
||||
*f = (uint8_t)(t * 10 + u);
|
||||
}
|
||||
|
||||
// Open the DigitEditor on a numeric field (2 integer digits, no decimals).
|
||||
void editField(EditKind kind, uint8_t value, uint8_t vmax) {
|
||||
_edit_kind = kind;
|
||||
_editor.begin((float)value, 0.0f, (float)vmax, 2, 0);
|
||||
}
|
||||
|
||||
// Feed a key to the open editor, write the (live) value back to its field, and
|
||||
// close the editor when DigitEditor reports DONE/CANCELLED.
|
||||
bool feedEditor(char c) {
|
||||
DigitEditor::Result r = _editor.handleInput(c);
|
||||
uint8_t v = (uint8_t)(_editor.value + 0.5f);
|
||||
switch (_edit_kind) {
|
||||
case EK_A_HOUR: _prefs->alarm_hour = v; _alarm_dirty = true; _task->onAlarmChanged(); break;
|
||||
case EK_A_MIN: _prefs->alarm_min = v; _alarm_dirty = true; _task->onAlarmChanged(); break;
|
||||
default: break;
|
||||
// Step the digit under the alarm-time cursor by dir (+1/-1) — same shape as
|
||||
// stepTimerDigit, just two fields (hour/minute) instead of three.
|
||||
void stepAlarmDigit(int dir) {
|
||||
uint8_t* f; int tens_max; bool is_hours;
|
||||
if (_alarm_cur < 2) { f = &_prefs->alarm_hour; tens_max = 2; is_hours = true; }
|
||||
else { f = &_prefs->alarm_min; tens_max = 5; is_hours = false; }
|
||||
int t = *f / 10, u = *f % 10;
|
||||
if (_alarm_cur % 2 == 0) { // tens place
|
||||
t = (t + dir + (tens_max + 1)) % (tens_max + 1);
|
||||
if (is_hours && t == 2 && u > 3) u = 3; // 2X hours can't exceed 23
|
||||
} else { // units place
|
||||
int umax = (is_hours && t == 2) ? 3 : 9;
|
||||
u = (u + dir + (umax + 1)) % (umax + 1);
|
||||
}
|
||||
if (r != DigitEditor::NONE) _edit_kind = EK_NONE; // editor closed
|
||||
return true;
|
||||
*f = (uint8_t)(t * 10 + u);
|
||||
_alarm_dirty = true;
|
||||
_task->onAlarmChanged();
|
||||
}
|
||||
|
||||
// Draw a row's value column: the live editor when this row is the one being
|
||||
// edited, otherwise the static text.
|
||||
void drawValue(DisplayDriver& d, int y, int valx, int reserve, bool sel,
|
||||
EditKind mykind, const char* text) {
|
||||
if (sel && _editor.active && _edit_kind == mykind) _editor.render(d, valx, y);
|
||||
else d.drawTextEllipsized(valx, y, d.width() - valx - reserve, text);
|
||||
// Draw the alarm's "HH:MM" value: while this row is in its digit-cursor
|
||||
// sub-mode, the digit under the cursor is shown inverted (same convention as
|
||||
// DigitEditor::render — assumes the caller is already inside a selected row,
|
||||
// ink DARK on a LIGHT selection bar); otherwise just the plain text.
|
||||
void drawAlarmTime(DisplayDriver& d, int y, int valx, bool editing) {
|
||||
char buf[6];
|
||||
fmtClock(buf, sizeof(buf), _prefs->alarm_hour, _prefs->alarm_min);
|
||||
if (!editing) { d.setCursor(valx, y); d.print(buf); return; }
|
||||
const int cw = d.getCharWidth();
|
||||
const int char_idx = _alarm_cur + (_alarm_cur / 2); // skip the colon
|
||||
for (int k = 0; buf[k]; k++) {
|
||||
int cx = valx + k * cw;
|
||||
if (k == char_idx) {
|
||||
d.setColor(DisplayDriver::DARK);
|
||||
d.fillRect(cx, y - 1, cw, d.getLineHeight() + 1);
|
||||
d.setColor(DisplayDriver::LIGHT);
|
||||
} else {
|
||||
d.setColor(DisplayDriver::DARK);
|
||||
}
|
||||
char one[2] = { buf[k], '\0' };
|
||||
d.setCursor(cx, y);
|
||||
d.print(one);
|
||||
}
|
||||
d.setColor(DisplayDriver::LIGHT);
|
||||
}
|
||||
|
||||
// ── Sub-renders ───────────────────────────────────────────────────────────
|
||||
@@ -145,21 +163,22 @@ class ClockToolsScreen : public UIScreen {
|
||||
int renderAlarm(DisplayDriver& d) {
|
||||
d.drawCenteredHeader("ALARM");
|
||||
if (!_prefs) return 60000;
|
||||
const char* rows[4] = { "Hour", "Minute", "Repeat", "Armed" };
|
||||
if (_sel > 3) _sel = 3;
|
||||
const char* rows[3] = { "Time", "Repeat", "Armed" };
|
||||
if (_sel > 2) _sel = 2;
|
||||
const int valx = d.width() / 2 + 6;
|
||||
drawList(d, 4, _sel, _scroll, [&](int i, int y, bool sel, int reserve) {
|
||||
drawList(d, 3, _sel, _scroll, [&](int i, int y, bool sel, int reserve) {
|
||||
drawRowSelection(d, y, sel, reserve);
|
||||
d.setCursor(4, y); d.print(rows[i]);
|
||||
char b[10];
|
||||
if (i == 0) snprintf(b, sizeof(b), "%02u", _prefs->alarm_hour);
|
||||
else if (i == 1) snprintf(b, sizeof(b), "%02u", _prefs->alarm_min);
|
||||
else if (i == 2) snprintf(b, sizeof(b), "%s", NodePrefs::alarmRepeatLabel(NodePrefs::alarmRepeatIdxForMask(_prefs->alarm_repeat_mask)));
|
||||
else snprintf(b, sizeof(b), "%s", _prefs->alarm_on ? "ON" : "OFF");
|
||||
EditKind k = (i == 0) ? EK_A_HOUR : (i == 1) ? EK_A_MIN : EK_NONE;
|
||||
drawValue(d, y, valx, reserve, sel, k, b);
|
||||
if (i == 0) {
|
||||
drawAlarmTime(d, y, valx, sel && _alarm_editing);
|
||||
} else if (i == 1) {
|
||||
d.drawTextEllipsized(valx, y, d.width() - valx - reserve,
|
||||
NodePrefs::alarmRepeatLabel(NodePrefs::alarmRepeatIdxForMask(_prefs->alarm_repeat_mask)));
|
||||
} else {
|
||||
d.drawTextEllipsized(valx, y, d.width() - valx - reserve, _prefs->alarm_on ? "ON" : "OFF");
|
||||
}
|
||||
});
|
||||
return _editor.active ? 50 : 60000;
|
||||
return _alarm_editing ? 50 : 60000;
|
||||
}
|
||||
|
||||
int renderTimer(DisplayDriver& d) {
|
||||
@@ -220,25 +239,50 @@ class ClockToolsScreen : public UIScreen {
|
||||
|
||||
bool inputAlarm(char c) {
|
||||
if (!_prefs) { if (c == KEY_CANCEL) { _view = V_MENU; _sel = 0; } return true; }
|
||||
if (_editor.active) return feedEditor(c);
|
||||
|
||||
// Time row's digit-cursor sub-mode (same shape as the Timer's HH:MM:SS
|
||||
// cursor): LEFT/RIGHT moves across HH:MM's 4 digits, UP/DOWN steps the
|
||||
// digit under the cursor, Enter/Cancel commits and leaves (there's no
|
||||
// rollback — every step already writes straight to alarm_hour/min and
|
||||
// reschedules, same as the old per-field editor did).
|
||||
if (_alarm_editing) {
|
||||
if (keyIsPrev(c)) { _alarm_cur = (_alarm_cur + 3) % 4; return true; }
|
||||
if (keyIsNext(c)) { _alarm_cur = (_alarm_cur + 1) % 4; return true; }
|
||||
if (c == KEY_UP) { stepAlarmDigit(+1); return true; }
|
||||
if (c == KEY_DOWN) { stepAlarmDigit(-1); return true; }
|
||||
if (c == KEY_ENTER || c == KEY_CANCEL) { _alarm_editing = false; return true; }
|
||||
return true;
|
||||
}
|
||||
|
||||
if (c == KEY_CANCEL) {
|
||||
_task->savePrefsIfDirty(_alarm_dirty); // persist alarm fields only if edited
|
||||
_task->onAlarmChanged(); // re-schedule from the new time
|
||||
_view = V_MENU; _sel = 0; _scroll = 0;
|
||||
return true;
|
||||
}
|
||||
if (c == KEY_UP) { _sel = (_sel > 0) ? _sel - 1 : 3; return true; }
|
||||
if (c == KEY_DOWN) { _sel = (_sel < 3) ? _sel + 1 : 0; return true; }
|
||||
if (c == KEY_ENTER) {
|
||||
if (_sel == 0) editField(EK_A_HOUR, _prefs->alarm_hour, 23);
|
||||
else if (_sel == 1) editField(EK_A_MIN, _prefs->alarm_min, 59);
|
||||
else if (_sel == 2) { // Repeat: cycle Off -> Daily -> Weekdays -> Weekends -> Off
|
||||
uint8_t idx = (NodePrefs::alarmRepeatIdxForMask(_prefs->alarm_repeat_mask) + 1) % NodePrefs::ALARM_REPEAT_COUNT;
|
||||
_prefs->alarm_repeat_mask = NodePrefs::alarmRepeatMaskForIdx(idx);
|
||||
_alarm_dirty = true; _task->onAlarmChanged();
|
||||
} else { _prefs->alarm_on ^= 1; _alarm_dirty = true; _task->onAlarmChanged(); }
|
||||
if (c == KEY_UP) { _sel = (_sel > 0) ? _sel - 1 : 2; return true; }
|
||||
if (c == KEY_DOWN) { _sel = (_sel < 2) ? _sel + 1 : 0; return true; }
|
||||
// Repeat: LEFT/RIGHT steps Off -> Daily -> Weekdays -> Weekends (wrapping),
|
||||
// matching the rest of the UI's convention for multi-value fields (e.g.
|
||||
// Settings' Keyboard Alphabet / Battery display); Enter still advances one
|
||||
// step too, for parity with those same fields.
|
||||
if (_sel == 1 && (keyIsPrev(c) || keyIsNext(c) || c == KEY_ENTER)) {
|
||||
int idx = NodePrefs::alarmRepeatIdxForMask(_prefs->alarm_repeat_mask);
|
||||
idx = keyIsPrev(c) ? (idx + NodePrefs::ALARM_REPEAT_COUNT - 1) % NodePrefs::ALARM_REPEAT_COUNT
|
||||
: (idx + 1) % NodePrefs::ALARM_REPEAT_COUNT;
|
||||
_prefs->alarm_repeat_mask = NodePrefs::alarmRepeatMaskForIdx(idx);
|
||||
_alarm_dirty = true; _task->onAlarmChanged();
|
||||
return true;
|
||||
}
|
||||
// Armed: a plain on/off toggle, but still answers LEFT/RIGHT as well as
|
||||
// Enter (same as every boolean field in Settings — e.g. Auto-lock, Units,
|
||||
// Power save — flips either way rather than reserving direction for
|
||||
// "increase/decrease").
|
||||
if (_sel == 2 && (keyIsPrev(c) || keyIsNext(c) || c == KEY_ENTER)) {
|
||||
_prefs->alarm_on ^= 1; _alarm_dirty = true; _task->onAlarmChanged();
|
||||
return true;
|
||||
}
|
||||
if (c == KEY_ENTER && _sel == 0) { _alarm_editing = true; _alarm_cur = 0; return true; }
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -278,7 +322,7 @@ public:
|
||||
void onShow() override {
|
||||
_view = V_MENU; _sel = 0; _scroll = 0;
|
||||
_timer_cur = 0;
|
||||
_editor.active = false; _edit_kind = EK_NONE;
|
||||
_alarm_editing = false;
|
||||
}
|
||||
|
||||
int render(DisplayDriver& display) override {
|
||||
|
||||
@@ -459,13 +459,18 @@ class HomeScreen : public UIScreen {
|
||||
battLeftX = display.width() - display.getTextWidth(buf) - 1;
|
||||
display.setCursor(battLeftX, 0);
|
||||
display.print(buf);
|
||||
} else { // icon — scales with lh
|
||||
const int iconH = lh;
|
||||
} else { // icon — scales with lh, same box height as the status icons beside it (ind_h)
|
||||
const int iconH = ind_h;
|
||||
const int iconW = lh * 2;
|
||||
const int bm = display.isLandscape() ? 3 : 2; // inner margin: 3px on landscape e-ink, 2px on OLED/portrait
|
||||
battLeftX = display.width() - iconW - 3;
|
||||
display.drawRect(battLeftX, 0, iconW, iconH);
|
||||
display.fillRect(battLeftX + iconW, iconH / 4, 2, iconH / 2);
|
||||
// Nub height/2, vertically centred by remaining-space/2 rather than a flat
|
||||
// iconH/4 margin — the flat form only centres when iconH is a multiple of
|
||||
// 4 (true for the old built-in font's lh=8, false for misc-fixed's 7/9),
|
||||
// so it visibly drifted off-centre once the box height changed.
|
||||
const int nub_h = iconH / 2;
|
||||
display.fillRect(battLeftX + iconW, (iconH - nub_h) / 2, 2, nub_h);
|
||||
int fillW = (pct * (iconW - 2 * bm)) / 100;
|
||||
display.fillRect(battLeftX + bm, bm, fillW, iconH - 2 * bm);
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ MINI_ICON(ICON_PG_SENSORS, 5, // thermometer/gauge — sensors
|
||||
MINI_ICON(ICON_PG_SETTINGS, 5, // small cog — settings
|
||||
packRow(".#.#."),
|
||||
packRow("#####"),
|
||||
packRow("##.##"),
|
||||
packRow(".#.#."),
|
||||
packRow("#####"),
|
||||
packRow(".#.#."));
|
||||
MINI_ICON(ICON_PG_MAP, 5, // folded map — map page
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
// the two conventions match.
|
||||
static int fontAscender(int sz, bool use_lemon, int scale) {
|
||||
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
|
||||
if (sz == 1 && use_lemon) return 7 * scale; // misc-fixed 6x9 GFX font: baseline origin, ascent 7px×scale
|
||||
return 0; // GFX built-in font: cursor is top-left of cell
|
||||
}
|
||||
|
||||
@@ -47,11 +47,11 @@ int16_t GxEPDDisplay::drawLemonChar(int16_t x, int16_t y, uint32_t cp, int sc) {
|
||||
return x + xa * sc;
|
||||
}
|
||||
}
|
||||
if (cp < Lemon.first || cp > Lemon.last) {
|
||||
if (cp >= 0x20) display.fillRect(x + sc, y - 8*sc, 4*sc, 6*sc, _curr_color);
|
||||
if (cp < MiscFixed.first || cp > MiscFixed.last) {
|
||||
if (cp >= 0x20) display.fillRect(x + sc, y - 7*sc, 4*sc, 6*sc, _curr_color);
|
||||
return x + 6 * sc;
|
||||
}
|
||||
const GFXglyph* g = &lemonGlyphs[cp - Lemon.first];
|
||||
const GFXglyph* g = &MiscFixedGlyphs[cp - MiscFixed.first];
|
||||
uint8_t w = pgm_read_byte(&g->width), h = pgm_read_byte(&g->height);
|
||||
int8_t xo = (int8_t)pgm_read_byte(&g->xOffset), yo = (int8_t)pgm_read_byte(&g->yOffset);
|
||||
uint8_t xa = pgm_read_byte(&g->xAdvance);
|
||||
@@ -59,7 +59,7 @@ int16_t GxEPDDisplay::drawLemonChar(int16_t x, int16_t y, uint32_t cp, int sc) {
|
||||
uint8_t bits = 0, bit = 0;
|
||||
for (uint8_t row = 0; row < h; row++)
|
||||
for (uint8_t col = 0; col < w; col++) {
|
||||
if (!bit) { bits = pgm_read_byte(&lemonBitmaps[bo++]); bit = 0x80; }
|
||||
if (!bit) { bits = pgm_read_byte(&MiscFixedBitmaps[bo++]); bit = 0x80; }
|
||||
if (bits & bit) {
|
||||
if (sc == 1) display.drawPixel(x + xo + col, y + yo + row, _curr_color);
|
||||
else display.fillRect(x + xo*sc + col*sc, y + yo*sc + row*sc, sc, sc, _curr_color);
|
||||
@@ -71,8 +71,8 @@ int16_t GxEPDDisplay::drawLemonChar(int16_t x, int16_t y, uint32_t cp, int sc) {
|
||||
|
||||
uint8_t GxEPDDisplay::lemonXAdvance(uint32_t cp, int sc) {
|
||||
uint8_t xa;
|
||||
if (cp < Lemon.first || cp > Lemon.last) xa = 6;
|
||||
else xa = pgm_read_byte(&lemonGlyphs[cp - Lemon.first].xAdvance);
|
||||
if (cp < MiscFixed.first || cp > MiscFixed.last) xa = 6;
|
||||
else xa = pgm_read_byte(&MiscFixedGlyphs[cp - MiscFixed.first].xAdvance);
|
||||
return xa * sc;
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ void GxEPDDisplay::startFrame(Color bkg) {
|
||||
display.setTextColor(_curr_color = GxEPD_BLACK);
|
||||
_text_sz = 1;
|
||||
int sc = scale();
|
||||
display.setFont(_use_lemon ? &Lemon : NULL);
|
||||
display.setFont(_use_lemon ? &MiscFixed : NULL);
|
||||
display.setTextSize(sc);
|
||||
display_crc.reset();
|
||||
}
|
||||
@@ -156,7 +156,7 @@ void GxEPDDisplay::setTextSize(int sz) {
|
||||
display.setTextSize(scale() * 2);
|
||||
break;
|
||||
default:
|
||||
display.setFont(_use_lemon ? &Lemon : NULL);
|
||||
display.setFont(_use_lemon ? &MiscFixed : NULL);
|
||||
display.setTextSize(sc);
|
||||
break;
|
||||
}
|
||||
@@ -183,7 +183,7 @@ void GxEPDDisplay::setCursor(int x, int y) {
|
||||
|
||||
void GxEPDDisplay::print(const char* str) {
|
||||
display_crc.update<char>(str, strlen(str));
|
||||
// Lemon path only for sz=1 — setTextSize(2/3) switches GFX to non-Lemon fonts.
|
||||
// misc-fixed path only for sz=1 — setTextSize(2/3) switches GFX to other fonts.
|
||||
if (_use_lemon && _text_sz == 1) {
|
||||
int16_t cx = display.getCursorX();
|
||||
int16_t cy = display.getCursorY();
|
||||
@@ -191,7 +191,7 @@ void GxEPDDisplay::print(const char* str) {
|
||||
const uint8_t* p = (const uint8_t*)str;
|
||||
while (*p) {
|
||||
uint32_t cp = decodeCodepoint(p);
|
||||
if (cp == '\n') { cy += Lemon.yAdvance * sc; cx = 0; }
|
||||
if (cp == '\n') { cy += MiscFixed.yAdvance * sc; cx = 0; }
|
||||
else { cx = drawLemonChar(cx, cy, cp, sc); }
|
||||
}
|
||||
display.setCursor(cx, cy);
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <CRC32.h>
|
||||
|
||||
#include "DisplayDriver.h"
|
||||
#include "LemonFont.h"
|
||||
#include "MiscFixedFont.h"
|
||||
|
||||
#ifndef DISPLAY_ROTATION
|
||||
#define DISPLAY_ROTATION 0
|
||||
@@ -57,7 +57,7 @@ class GxEPDDisplay : public DisplayDriver {
|
||||
#endif
|
||||
bool _init = false;
|
||||
bool _isOn = false;
|
||||
bool _use_lemon = false;
|
||||
bool _use_lemon = true; // e-ink is single-font too now (misc-fixed 6x9), matching the OLED driver
|
||||
uint16_t _curr_color;
|
||||
CRC32 display_crc;
|
||||
int last_display_crc_value = 0;
|
||||
@@ -103,16 +103,16 @@ public:
|
||||
if (_text_sz == 4) return 6 * BIG_TEXT_SCALE;
|
||||
if (_text_sz == 3) return 17;
|
||||
if (_text_sz == 2) return 12 * sc;
|
||||
return (_use_lemon ? 5 : 6) * sc;
|
||||
return (_use_lemon ? 6 : 6) * sc; // misc-fixed 6x9 is 6px wide
|
||||
}
|
||||
int getLineHeight() const override {
|
||||
int sc = scale();
|
||||
if (_text_sz == 4) return 8 * BIG_TEXT_SCALE;
|
||||
if (_text_sz == 3) return 28;
|
||||
if (_text_sz == 2) return 16 * sc;
|
||||
return (_use_lemon ? 10 : 8) * sc;
|
||||
return (_use_lemon ? 9 : 8) * sc; // misc-fixed 6x9 box height
|
||||
}
|
||||
void setLemonFont(bool enabled) override { _use_lemon = enabled; _vw_dirty = true; }
|
||||
void setLemonFont(bool) override { } // single-font: ignore toggles, stay misc-fixed 6x9
|
||||
bool isLemonFont() const override { return _use_lemon; }
|
||||
void translateUTF8ToBlocks(char* dest, const char* src, size_t dest_size) override {
|
||||
if (_use_lemon) {
|
||||
|
||||
@@ -160,6 +160,7 @@ build_unflags = -Ofast
|
||||
build_flags = ${WioTrackerL1CompanionDual.build_flags}
|
||||
-D UI_HAS_JOYSTICK_UPDOWN=1
|
||||
-D ENABLE_SCREENSHOT
|
||||
-D DUAL_SERIAL=1
|
||||
-Os
|
||||
extra_scripts = post:create-uf2.py
|
||||
|
||||
|
||||
Reference in New Issue
Block a user