feat(ui-lvgl): quick panel from the status bar; L2 fixes from rc1

The quick panel, as a phone's: pulled down from the status bar (or a tap
on it). Bluetooth, WiFi, GPS, sound, trail and live share switch at a
tap; Advert opens the advert popup (moved here from the Nodes header);
Lock locks the screen; a brightness slider. Holding a tile opens its
settings. Lock and sun glyphs added to the fonts.

Fixes from rc1 testing on the L2:
- GPS status icon: none when GPS is off (the module kept its last fix
  valid, so it stayed green); grey on, green with a fix. ensureGps()
  turns GPS on before trusting that stale fix.
- Screen wake: the panel wakes dark, a frame is drawn, then the
  backlight fades in -- no white flash. Off fades out first.
- Power off / flat battery: the chip wakes every 30 s to look for USB
  power and starts when plugged in (it slept with no wake source before,
  until the reset button). Plugged in when switched off: stays off until
  re-plugged.
- Message ages in a conversation refresh every 2 s, as on ui-new; the
  message popup keeps its age, repeaters heard and delivery up to date.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-10-05 09:10:06 +02:00
co-authored by Claude Opus 5.5
parent d66f04ba94
commit b5e4845dae
17 changed files with 940 additions and 333 deletions
@@ -188,6 +188,20 @@ public:
class WioTrackerL2Display : public LGFXDisplay {
LGFX_WioTrackerL2 disp;
// The backlight from one PWM level to another over ~180 ms, on a square
// curve (the eye sees the low end's steps). Blocks; 0 ends in standby.
void fade(uint8_t from, uint8_t to) {
const int STEPS = 12;
for (int i = 1; i <= STEPS; i++) {
const int t = i * 256 / STEPS; // 0..256
const int k = from < to ? t * t / 256 : 256 - (256 - t) * (256 - t) / 256;
const int v = from + ((int)to - from) * k / 256;
display->panel()->setBrightness((uint8_t)(i == STEPS ? to : (v < 1 ? 1 : v)));
delay(15);
}
}
public:
WioTrackerL2Display() : LGFXDisplay(320, 240, disp) {}
@@ -197,6 +211,26 @@ public:
display->setBrightness(PWM[level > 4 ? 4 : level]);
}
// Screen off: the backlight fades out, then the panel sleeps. Screen on: the
// panel wakes with the light still off -- the caller draws a fresh frame
// first (the panel shows what's left in its memory for a moment, a white
// flash) -- and fadeIn() brings the light up.
void turnOff() override {
if (_isOn) {
fade(display->getBrightness(), 0);
display->sleep();
}
_isOn = false;
}
void turnOn() override {
if (!_isOn) {
display->panel()->setSleep(false);
delay(10); // the panel takes no pixels just out of sleep
}
_isOn = true;
}
void fadeIn() { fade(0, display->getBrightness()); }
// direct access to the LGFX device (LVGL flush/touch glue)
lgfx::LGFX_Device* lgfxDevice() { return &disp; }
Panel_WioTrackerL2& panel() { return disp.panelL2(); }