Commit Graph

21 Commits

Author SHA1 Message Date
Jakub
a6bf3ee08f feat(eink): full refresh interval setting in Settings › Display
Add "Full rfsh" setting (e-ink only) with options off/5/10/20/30
partial refreshes between full refreshes. Prevents ghosting on panels
that accumulate artifacts after many partial updates.

GxEPDDisplay counts partial refreshes and calls display.display(false)
every N frames when the interval is set. Persisted in DataStore and
applied at startup via applyFullRefreshInterval().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 10:22:03 +02:00
Jakub
b279b95b2d refactor(ui): apply code review fixes — bugs, risk, optimisations, cleanup
Fixes 7 bugs (timing UB on unsigned long, abs() no-op, XBM CRC PROGMEM
scan, CayenneLPP heap thrash ×2, UTF-8 reply prefix, lock-seq reset on
wake), 3 risk items (notif melody stop guard, bot trigger pre-lowercase,
lock-seq cleared on display wake), plus optimisations (fmtMsgAge/
getTextWidth caching, RTTTL builder consolidated to NodePrefs, HP_*
constants and homePageLabel table moved to NodePrefs, DataStore flat
lambda schema, translateUTF8Static factored out) and minor cleanup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 20:03:45 +02:00
Jakub
85cfb6f1af fix(ui): unified unknown-char block rendering and display layout fixes
- GxEPDDisplay::print() renders '\xDB' as filled rect for Lemon font,
  matching OLED Lemon block behavior
- Remove translateUTF8ToBlocks override (base class passthrough sufficient)
- transliterateCodepoint fallback changed '?' → '\xDB' for consistency
- drawTextCentered/Right/LeftAlign now call translateUTF8ToBlocks
- isLemonFont() added to DisplayDriver, SH1106Display, GxEPDDisplay
- isLandscape() guarded by EINK_DISPLAY_MODEL to distinguish OLED vs e-ink
- ind_h trims indicator box height only for Lemon font
- getTextWidth disables wrap before getTextBounds, restores after
- QuickMsgScreen: tighter hist_item padding; 2 messages visible with Lemon
- Hibernate hint fits on one line when width allows, splits otherwise
- BLE PIN page shows toggle hint on landscape e-ink
- Remove unused muted_icon bitmap

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 14:45:24 +02:00
Jakub
9c671891d9 fix: e-ink portrait/landscape layout — separators, battery, keyboard, screens
- DisplayDriver: add sepH() (2px landscape, 1px OLED); fix transliterateCodepoint
  fallback '?' (was '\xDB' which broke UTF-8 word-wrap and rendered tiny block char)
- GxEPDDisplay: drawRect draws double border on landscape for visible 2px weight
- UITask: navigation dots scale with lh; content_y saves 16px by using dots_y+6;
  battery iconW=lh*2, fill margin bm scales with orientation; indicator spacing fixed;
  clock separator uses sepH(); alert popup tight and vertically centred
- KeyboardWidget: compact cell height (no stretch), multi-line preview, cursor always
  on last visible line
- BotScreen / NearbyScreen detail: use lineStep() as natural item height, shrink only
  when items don't fit (fixes portrait stretch)
- QuickMsgScreen: send button pinned to display bottom (height-lh-2), not floating
- SettingsScreen: AUTO_OFF guarded with #if AUTO_OFF_MILLIS>0; default sel=AUTO_LOCK
- All screens: separators updated to sepH()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 23:13:27 +02:00
Jakub
744f263932 refactor: replace all hardcoded pixel positions with layout helpers
Add lineStep(), headerH(), listStart(), listVisible(), valCol() to
DisplayDriver so layout derives from getLineHeight() instead of fixed
OLED constants. Refactor all screens (SettingsScreen, NearbyScreen,
FullscreenMsgView, QuickMsgScreen, BotScreen, DashboardConfigScreen,
AutoAdvertScreen, RingtoneEditorScreen) and all HomeScreen pages plus
the lock screen and splash screen in UITask.cpp.

On OLED (lh=8) positions are unchanged; on landscape e-ink (lh=16) all
text and widgets now scale correctly to the 250×122 display.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 18:05:09 +02:00
Jakub
6a3b8e3135 feat: add runtime display rotation setting for e-ink builds
Adds Settings > Display > Rotation (0°/90°/180°/270°) that persists to
NodePrefs and is applied on startup. Falls back to compile-time
DISPLAY_ROTATION when the field is missing from an older prefs file.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 09:58:33 +02:00
Jakub
a115916d8f feat: runtime font switcher — Default vs Lemon in Settings > Display
- Add Lemon font (LemonFont.h, LemonIcons.h) to the standard build
  alongside the Adafruit built-in font; ~101 KB added to flash
- SH1106Display: add _use_lemon flag + setLemonFont(bool) to switch
  at runtime; print() and getTextWidth() use Lemon path when active;
  translateUTF8ToBlocks() passes UTF-8 through unchanged (Lemon supports
  full Unicode U+0020-U+04FF) vs transliterating for the default font
- DisplayDriver: add getCharWidth()/getLineHeight() virtuals (defaults 6/8);
  SH1106Display returns 5/9 for Lemon, 6/8 for default; add setLemonFont()
  no-op virtual; fix orphaned UTF-8 leading byte in drawTextEllipsized
- FullscreenMsgView: replace fixed-char-count word-wrap with pixel-accurate
  wrap using display.getTextWidth(); use getLineHeight() for spacing so
  Lemon (9 px) and default (8 px) both render correctly
- NodePrefs: add use_lemon_font field (0=default, 1=Lemon)
- SettingsScreen: add "Font" item in Display section (Default / Lemon),
  calls UITask::applyFont() on change
- UITask: add applyFont() that calls display->setLemonFont(use_lemon_font);
  called at startup (begin()) and when the setting changes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 09:33:35 +02:00
Jakub
2bc6dae78e feat: add Icelandic and Romanian legacy cedilla transliteration
Adds ð/Ð (eth), þ/Þ (thorn) for Icelandic, and ţ/Ţ (t with cedilla)
for legacy-encoded Romanian text.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:11:42 +02:00
Jakub
b0552e246a feat: extend UTF-8 transliteration to cover all major European languages
Adds Scandinavian (å ø æ), Hungarian (ő ű), Romanian (ă ș ț),
Croatian (đ), Turkish (ğ ş ı), and Baltic/Lithuanian/Latvian
(ā ē ī ū ģ ķ ļ ņ ŗ ų ė į) diacritics.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:08:20 +02:00
Jakub
6492fd490e feat: add Czech and Slovak diacritic transliteration
Adds háček and other Czech/Slovak characters (č š ž ř ě ů ď ť ň ľ ĺ ŕ)
to the UTF-8 transliteration table so they display as ASCII letters
instead of █ blocks.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:01:51 +02:00
Jakub
31962726ec fix: apply UTF-8 transliteration in drawTextEllipsized
Names printed via drawTextEllipsized (contacts, senders) bypassed
translateUTF8ToBlocks, causing raw UTF-8 bytes to render as garbage
on the Adafruit font. Now transliteration happens inside the method.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 15:11:12 +02:00
Jakub
f6b13c5cab fix: use block char █ fallback for unknown codepoints in transliteration
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 15:05:53 +02:00
Jakub
8d3b955da1 feat: transliterate accented/diacritic characters to ASCII in translateUTF8ToBlocks
Replaces the block-character fallback with proper transliteration for
Polish (ą→a, ć→c, ę→e, ł→l, ń→n, ó→o, ś→s, ź→z, ż→z), German (ä ö ü ß),
and common French/Spanish/Portuguese accents. Unknown codepoints fall back
to '?' instead of █.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 14:46:53 +02:00
Jakub
c3846ba9f5 feat(wio-tracker-l1): add settings screen and companion radio improvements
Settings screen (UI_HAS_JOYSTICK_UPDOWN build variant):
- Display brightness (5 levels, contrast curve tuned for SH1106 non-linearity)
- Buzzer on/off (respected at startup, no more forced unmute)
- TX power (2–22 dBm)
- Auto-off delay (5s / 15s / 30s / 60s / never)
- GPS update interval (off / 30s / 1min / 5min / 15min / 30min)
- Timezone offset (UTC-12..+14) for clock screen
- Low battery auto-shutdown threshold (off / 3.0–3.5V, default 3.4V)
- Battery display mode (icon / % / voltage)

Battery:
- EMA filter (alpha=0.2) on ADC readings to smooth voltage spikes from uneven load
- Battery % calculated using low_batt_mv as 0% anchor
- Mute icon repositions dynamically based on battery display width

Clock screen on HomeScreen showing time/date with timezone support.

Build:
- _settings variants added for USB and BLE companion radio builds
- Automatic UF2 generation on every build via create-uf2.py post-script
- UI_HAS_JOYSTICK_UPDOWN flag guards joystick_up/down to avoid breaking other boards

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:09:46 +02:00
Florent de Lamotte
18bfc2d81a DisplayDriver: introduce drawTextRightAlign and drawTextLeftAlign 2025-10-01 18:07:59 +02:00
Michael Hart
bd6aa983a3 feat: add DisplayDriver methods for UTF-8 filtering and text ellipsis
- Add translateUTF8ToBlocks() method to convert UTF-8 characters to displayable blocks
- Add drawTextEllipsized() method for text truncation with ellipsis
- Apply UTF-8 filtering to node names, recent contacts, and message content
- Use ellipsized text rendering for recent contacts to prevent overflow
- Addresses PR feedback by moving text processing to DisplayDriver level
2025-09-16 17:17:15 -07:00
Scott Powell
4b95c981bb * UI revamp for companion radios 2025-08-08 20:01:31 +10:00
JQ
678f36a57b Implement getTextWidth for display classes
- Added getTextWidth method to DisplayDriver interface
- Implemented getTextWidth in all display classes
- Updated examples to use getTextWidth directly
2025-05-04 18:17:18 -07:00
Florent
cf3d55201f ui : manage colors and ensure fw using ssd1306 still compile 2025-04-11 22:23:47 +02:00
liamcottle
87443ad43f clear display on init to avoid static 2025-04-01 14:46:48 +13:00
Scott Powell
372c228210 * new ui/DisplayDriver classes (just SSD1306Display impl for now)
* companion radio: now with optional UITask (enabled by DISPLAY_CLASS config in target/env)
2025-03-04 23:09:43 +11:00