From 61c75946f6d40c4c1caa27f28ce93fa46178f5cc Mon Sep 17 00:00:00 2001 From: Jakub <106778416+MarekZegare4@users.noreply.github.com> Date: Fri, 2 Oct 2026 11:25:58 +0200 Subject: [PATCH] feat(l2,core): battery curve editor and an L2 feedback round - Battery curve: NodePrefs batt_curve_mv[11] (voltage at 0..100 %, all zeros = built-in LiPo curve, sentinel 0xC0DE0032). ui-core/Battery.h uses it for every percentage. L1: Settings > System > Batt curve list (Left/Right 10 mV, Reset); L2: Settings > Power > Battery curve chart with draggable points and a line at the cell's voltage. - L2: the Nodes map is the full navigation map plus the nodes, Back returns to Nodes; the favourite button is lit while it is one; pinning to the Home dial uses a thumbtack (fonts regenerated); minimap dots follow the accent; arranging tiles shows where they land while dragging; emoji row in Diagnostics > Font. - Sim hooks: sim_open nodesmap / accent@N / homeedit / battcurve. Co-Authored-By: Claude Opus 5.5 --- examples/companion_radio/DataStore.cpp | 9 + examples/companion_radio/NodePrefs.h | 13 +- examples/companion_radio/ui-core/Battery.h | 103 ++++++++--- .../companion_radio/ui-lvgl/BatteryScreen.h | 169 ++++++++++++++++++ .../companion_radio/ui-lvgl/ChannelScreen.h | 2 +- .../ui-lvgl/ConversationScreen.h | 2 +- examples/companion_radio/ui-lvgl/DiagScreen.h | 6 + examples/companion_radio/ui-lvgl/HomeScreen.h | 69 +++++-- examples/companion_radio/ui-lvgl/MapScreen.h | 7 +- examples/companion_radio/ui-lvgl/Theme.h | 3 +- examples/companion_radio/ui-lvgl/UITask.cpp | 17 +- examples/companion_radio/ui-lvgl/UITask.h | 9 +- .../companion_radio/ui-lvgl/fonts/generate.sh | 4 +- .../ui-lvgl/fonts/ui_font_12.c | 99 +++++----- .../ui-lvgl/fonts/ui_font_14.c | 102 ++++++----- .../ui-lvgl/fonts/ui_font_16.c | 103 ++++++----- .../ui-lvgl/fonts/ui_font_20.c | 111 +++++++----- .../ui-new/BatteryCurveScreen.h | 80 +++++++++ .../companion_radio/ui-new/SettingsScreen.h | 15 +- examples/companion_radio/ui-new/UITask.cpp | 4 + examples/companion_radio/ui-new/UITask.h | 2 + 21 files changed, 702 insertions(+), 227 deletions(-) create mode 100644 examples/companion_radio/ui-lvgl/BatteryScreen.h create mode 100644 examples/companion_radio/ui-new/BatteryCurveScreen.h diff --git a/examples/companion_radio/DataStore.cpp b/examples/companion_radio/DataStore.cpp index 20e00373..c7699fcb 100644 --- a/examples/companion_radio/DataStore.cpp +++ b/examples/companion_radio/DataStore.cpp @@ -1,6 +1,7 @@ #include #include "DataStore.h" #include "Features.h" // FEAT_JOYSTICK_ROTATION_SETTING (else `#if !FEAT_…` is always true) +#include "ui-core/Battery.h" // validCurve() for the saved battery curve #include // radio_driver — repeater-profile freq bounds (getFreqBounds) #if defined(EXTRAFS) || defined(QSPIFLASH) @@ -642,6 +643,10 @@ void DataStore::loadPrefsInt(const char *filename, NodePrefs& _prefs, double& no rd(_prefs.lock_screen_password, sizeof(_prefs.lock_screen_password)); rd(_prefs.lock_screen_password_salt, sizeof(_prefs.lock_screen_password_salt)); + // batt_curve_mv: any point out of range or not rising -> the built-in curve. + rd(_prefs.batt_curve_mv, sizeof(_prefs.batt_curve_mv)); + if (!battery::validCurve(_prefs.batt_curve_mv)) memset(_prefs.batt_curve_mv, 0, sizeof(_prefs.batt_curve_mv)); + // Schema sentinel: bumped on layout changes. Mismatch means an older file // (or a different schema); rd() and the clamps above already keep every // field within its valid range regardless, so we just log it here — @@ -653,6 +658,9 @@ void DataStore::loadPrefsInt(const char *filename, NodePrefs& _prefs, double& no (unsigned)sentinel, (unsigned)NodePrefs::SCHEMA_SENTINEL); // 0xC0DE0030 → 0xC0DE0031: the lock-screen PIN appended; from an older // file it holds its sentinel's bytes, which would read as a PIN nobody knows. + // 0xC0DE0031 → 0xC0DE0032: the battery curve appended; an older file + // leaves stray bytes in it, so the built-in curve. + if (sentinel < 0xC0DE0032) memset(_prefs.batt_curve_mv, 0, sizeof(_prefs.batt_curve_mv)); if (sentinel < 0xC0DE0031) { memset(_prefs.lock_screen_password, 0, sizeof(_prefs.lock_screen_password)); memset(_prefs.lock_screen_password_salt, 0, sizeof(_prefs.lock_screen_password_salt)); @@ -857,6 +865,7 @@ void DataStore::savePrefs(const NodePrefs& _prefs, double node_lat, double node_ file.write((uint8_t *)&_prefs.quiet_to, sizeof(_prefs.quiet_to)); file.write((uint8_t *)_prefs.lock_screen_password, sizeof(_prefs.lock_screen_password)); file.write((uint8_t *)_prefs.lock_screen_password_salt, sizeof(_prefs.lock_screen_password_salt)); + file.write((uint8_t *)_prefs.batt_curve_mv, sizeof(_prefs.batt_curve_mv)); // Tail sentinel — must be last. See NodePrefs::SCHEMA_SENTINEL. Its write is // the one we check: once the flash fills, writes return 0, so a good diff --git a/examples/companion_radio/NodePrefs.h b/examples/companion_radio/NodePrefs.h index 18396ddd..aa1b17f3 100644 --- a/examples/companion_radio/NodePrefs.h +++ b/examples/companion_radio/NodePrefs.h @@ -556,6 +556,13 @@ struct NodePrefs { // persisted to file uint8_t lock_screen_password[LOCK_HASH_LEN]; uint8_t lock_screen_password_salt[LOCK_SALT_LEN]; + // ── Battery curve (0xC0DE0032) ───────────────────────────────────────── + // The cell voltage (mV) at 0, 10, ... 100 %, for the battery percentage + // (ui-core/Battery.h). All zeros = the built-in LiPo curve. Settings > + // Battery curve edits it; anything not rising point to point reads as unset. + static const uint8_t BATT_CURVE_PTS = 11; + uint16_t batt_curve_mv[BATT_CURVE_PTS]; + // Single source of truth for the live-share option tables (shared by the Map // UI labels and the auto-send engine in UITask). static const uint8_t LOC_SHARE_MOVE_COUNT = 4; @@ -643,7 +650,7 @@ struct NodePrefs { // persisted to file // repeat_* fields) instead of at the tail, which shifted every field after // them by 25 bytes when loading an older file. Never released, but a dev // build wrote it, so the number must not be reused for anything else. - static const uint32_t SCHEMA_SENTINEL = 0xC0DE0031; + static const uint32_t SCHEMA_SENTINEL = 0xC0DE0032; // Bit-index for each home page. Used by page_order (entries store bit+1) and // by home_pages_mask. Single source of truth — both HomeScreen::pageBit/bitToPage @@ -828,7 +835,9 @@ static inline bool inQuietHours(const NodePrefs& p, uint32_t utc) { // to buzzer_auto, rounded up to the alignment) -- sizeof 2832, confirmed via real // WioTrackerL1_companion_solo_dual (nRF52/ARM) and L2 (ESP32) builds. // lock_screen_password / _salt (0xC0DE0031) added 48 bytes -- sizeof 2880. -static_assert(sizeof(NodePrefs) == 2880, +// batt_curve_mv[11] (0xC0DE0032) added 16 bytes, not 22 (6 went into tail +// padding) -- sizeof 2896, confirmed via real L1 (nRF52) and L2 (ESP32) builds. +static_assert(sizeof(NodePrefs) == 2896, "NodePrefs layout changed — sync DataStore save/load + clamp, bump " "SCHEMA_SENTINEL, then update this size (see steps above)."); diff --git a/examples/companion_radio/ui-core/Battery.h b/examples/companion_radio/ui-core/Battery.h index 35fa17f6..956865cc 100644 --- a/examples/companion_radio/ui-core/Battery.h +++ b/examples/companion_radio/ui-core/Battery.h @@ -1,7 +1,8 @@ #pragma once // Battery level shared by the frontends' status bars (and ui-new's dashboard -// Batt% field), so both report the same number for the same voltage, plus the -// Settings > Battery display choice (NodePrefs::batt_display_mode). +// Batt% field), so both report the same number for the same voltage, the +// user's battery curve, and the Settings > Battery display choice +// (NodePrefs::batt_display_mode). #include @@ -13,32 +14,82 @@ namespace battery { enum Mode : uint8_t { ICON, PERCENT, VOLTAGE, MODE_COUNT }; // NodePrefs::batt_display_mode -// LiPo discharge curve: voltage (mV) -> raw capacity (%). low_mv (typically -// NodePrefs.low_batt_mv, the user-configurable auto-shutdown threshold in -// Settings) is rescaled to 0% so the bar empties at the cutoff the user -// actually cares about. -inline int percent(int mv, int low_mv) { - static const struct { uint16_t mv; uint8_t pct; } CURVE[] = { - {3200, 0}, {3300, 3}, {3400, 8}, {3500, 15}, - {3600, 25}, {3650, 33}, {3700, 45}, {3750, 58}, - {3800, 68}, {3900, 77}, {4000, 86}, {4100, 93}, {4170, 100} - }; - static const int CURVE_LEN = sizeof(CURVE) / sizeof(CURVE[0]); - auto curveAt = [&](int v) -> int { - if (v <= (int)CURVE[0].mv) return CURVE[0].pct; - if (v >= (int)CURVE[CURVE_LEN-1].mv) return CURVE[CURVE_LEN-1].pct; - for (int i = 1; i < CURVE_LEN; i++) { - if (v <= (int)CURVE[i].mv) { - int span_mv = CURVE[i].mv - CURVE[i-1].mv; - int span_pct = CURVE[i].pct - CURVE[i-1].pct; - return CURVE[i-1].pct + (v - (int)CURVE[i-1].mv) * span_pct / span_mv; - } - } +// The cell voltage at 0, 10, ... 100 % can be set by the user (Settings > +// Battery curve, NodePrefs::batt_curve_mv); all zeros means the built-in +// LiPo curve below. Each frontend points useCurve() at the prefs array once. +static const int CURVE_PTS = 11; +static const int CURVE_MIN_MV = 2500, CURVE_MAX_MV = 4500; + +// The user's curve, or nullptr. A function-local static in an inline +// function, so every translation unit shares the one pointer. +inline const uint16_t*& curvePtr() { static const uint16_t* p = nullptr; return p; } +inline void useCurve(const uint16_t* mv) { curvePtr() = mv; } + +// Set (not all zeros), in range and rising point to point. +inline bool validCurve(const uint16_t* mv) { + if (!mv || mv[0] == 0) return false; + for (int i = 0; i < CURVE_PTS; i++) { + if (mv[i] < CURVE_MIN_MV || mv[i] > CURVE_MAX_MV) return false; + if (i > 0 && mv[i] <= mv[i - 1]) return false; + } + return true; +} + +// Built-in LiPo discharge curve: voltage (mV) -> raw capacity (%). +struct CurvePt { uint16_t mv; uint8_t pct; }; +static const CurvePt BUILTIN[] = { + {3200, 0}, {3300, 3}, {3400, 8}, {3500, 15}, + {3600, 25}, {3650, 33}, {3700, 45}, {3750, 58}, + {3800, 68}, {3900, 77}, {4000, 86}, {4100, 93}, {4170, 100} +}; +static const int BUILTIN_LEN = sizeof(BUILTIN) / sizeof(BUILTIN[0]); + +// The built-in curve's voltage at point i (i * 10 %): where the editor starts. +inline int builtinMvAt(int i) { + const int pct = i * 10; + if (pct <= BUILTIN[0].pct) return BUILTIN[0].mv; + for (int k = 1; k < BUILTIN_LEN; k++) + if (pct <= BUILTIN[k].pct) + return BUILTIN[k-1].mv + (pct - BUILTIN[k-1].pct) * (BUILTIN[k].mv - BUILTIN[k-1].mv) / + (BUILTIN[k].pct - BUILTIN[k-1].pct); + return BUILTIN[BUILTIN_LEN-1].mv; +} + +// Voltage at point i of the curve in use. +inline int curveMvAt(int i) { + const uint16_t* c = curvePtr(); + return validCurve(c) ? c[i] : builtinMvAt(i); +} + +// Voltage (mV) -> raw capacity (%) on the curve in use. +inline int rawPercent(int v) { + const uint16_t* c = curvePtr(); + if (validCurve(c)) { + if (v <= c[0]) return 0; + if (v >= c[CURVE_PTS-1]) return 100; + for (int i = 1; i < CURVE_PTS; i++) + if (v <= c[i]) return (i - 1) * 10 + (v - c[i-1]) * 10 / (c[i] - c[i-1]); return 100; - }; + } + if (v <= (int)BUILTIN[0].mv) return BUILTIN[0].pct; + if (v >= (int)BUILTIN[BUILTIN_LEN-1].mv) return BUILTIN[BUILTIN_LEN-1].pct; + for (int i = 1; i < BUILTIN_LEN; i++) { + if (v <= (int)BUILTIN[i].mv) { + int span_mv = BUILTIN[i].mv - BUILTIN[i-1].mv; + int span_pct = BUILTIN[i].pct - BUILTIN[i-1].pct; + return BUILTIN[i-1].pct + (v - (int)BUILTIN[i-1].mv) * span_pct / span_mv; + } + } + return 100; +} + +// The percentage shown: low_mv (typically NodePrefs.low_batt_mv, the +// user-configurable auto-shutdown threshold in Settings) is rescaled to 0% +// so the bar empties at the cutoff the user actually cares about. +inline int percent(int mv, int low_mv) { if (low_mv <= 0) low_mv = BATT_MIN_MILLIVOLTS; - int raw_pct = curveAt(mv); - int low_pct = curveAt(low_mv); + int raw_pct = rawPercent(mv); + int low_pct = rawPercent(low_mv); int pct = (low_pct >= 100) ? 0 : (raw_pct - low_pct) * 100 / (100 - low_pct); if (pct < 0) pct = 0; if (pct > 100) pct = 100; diff --git a/examples/companion_radio/ui-lvgl/BatteryScreen.h b/examples/companion_radio/ui-lvgl/BatteryScreen.h new file mode 100644 index 00000000..18233ea9 --- /dev/null +++ b/examples/companion_radio/ui-lvgl/BatteryScreen.h @@ -0,0 +1,169 @@ +#pragma once +// Settings › Power › Battery curve: the cell voltage at 0, 10, ... 100 % +// (NodePrefs::batt_curve_mv, ui-core/Battery.h) as a chart. A finger takes +// the point nearest it along the % axis and drags it up or down in 10 mV +// steps, kept between its neighbours; the first drag copies the built-in +// curve in, Reset goes back to it. A dashed line marks the cell now, so a +// point can be set against what the battery reads. Included by UITask.cpp. + +namespace battview { +static lv_obj_t* s_chart = nullptr; +static lv_obj_t* s_now = nullptr; // "Now 3912 mV 76 %" +static lv_obj_t* s_reset = nullptr; // header button's label +static int s_drag = -1; // point under the finger +static const int PTS = battery::CURVE_PTS; +static const int MV_LO = 3000, MV_HI = 4400; // the chart's voltage range +static const int PAD_L = 44, PAD_R = 12, PAD_T = 10, PAD_B = 22; + +static int ptX(const lv_area_t& a, int i) { return a.x1 + PAD_L + i * (lv_area_get_width(&a) - PAD_L - PAD_R) / (PTS - 1); } +static int mvY(const lv_area_t& a, int mv) { + const int h = lv_area_get_height(&a) - PAD_T - PAD_B; + return a.y2 - PAD_B - (constrain(mv, MV_LO, MV_HI) - MV_LO) * h / (MV_HI - MV_LO); +} +static int yMv(const lv_area_t& a, int y) { + const int h = lv_area_get_height(&a) - PAD_T - PAD_B; + return MV_LO + (a.y2 - PAD_B - y) * (MV_HI - MV_LO) / h; +} + +static void text(lv_layer_t* layer, const char* t, int x, int y, int w, lv_text_align_t align, uint32_t col) { + lv_draw_label_dsc_t d; + lv_draw_label_dsc_init(&d); + d.font = THEME_FONT_SMALL; + d.color = lv_color_hex(col); + d.align = align; + d.text = t; + d.text_local = 1; + lv_area_t r = { x, y, x + w - 1, y + 16 }; + lv_draw_label(layer, &d, &r); +} +static void line(lv_layer_t* layer, int x1, int y1, int x2, int y2, uint32_t col, int w, int dash = 0) { + lv_draw_line_dsc_t d; + lv_draw_line_dsc_init(&d); + d.color = lv_color_hex(col); + d.width = w; + d.dash_width = dash; + d.dash_gap = dash; + d.p1.x = x1; d.p1.y = y1; d.p2.x = x2; d.p2.y = y2; + lv_draw_line(layer, &d); +} + +static void onDraw(lv_event_t* e) { + lv_obj_t* obj = lv_event_get_current_target_obj(e); + lv_layer_t* layer = lv_event_get_layer(e); + lv_area_t a; + lv_obj_get_coords(obj, &a); + char t[16]; + for (int mv = 3200; mv <= MV_HI; mv += 400) { // voltage grid + const int y = mvY(a, mv); + line(layer, a.x1 + PAD_L, y, a.x2 - PAD_R, y, theme::SURFACE_2, 1); + snprintf(t, sizeof(t), "%d.%d V", mv / 1000, mv % 1000 / 100); + text(layer, t, a.x1, y - 8, PAD_L - 6, LV_TEXT_ALIGN_RIGHT, theme::TEXT_MUTED); + } + for (int i = 0; i < PTS; i += 5) { // 0, 50, 100 % + snprintf(t, sizeof(t), "%d%%", i * 10); + const int x = i == PTS - 1 ? a.x2 - 40 : ptX(a, i) - 20; // the last one ends at the edge + text(layer, t, x, a.y2 - PAD_B + 4, 40, i == PTS - 1 ? LV_TEXT_ALIGN_RIGHT : LV_TEXT_ALIGN_CENTER, theme::TEXT_MUTED); + } + const int now = s_ui ? s_ui->battMv() : 0; + if (now > 0) line(layer, a.x1 + PAD_L, mvY(a, now), a.x2 - PAD_R, mvY(a, now), theme::OK, 1, 3); + for (int i = 1; i < PTS; i++) + line(layer, ptX(a, i - 1), mvY(a, battery::curveMvAt(i - 1)), ptX(a, i), mvY(a, battery::curveMvAt(i)), theme::ACCENT, 2); + for (int i = 0; i < PTS; i++) { + lv_draw_rect_dsc_t r; + lv_draw_rect_dsc_init(&r); + r.radius = LV_RADIUS_CIRCLE; + r.bg_color = lv_color_hex(i == s_drag ? theme::ACCENT : theme::BG); + r.border_color = lv_color_hex(theme::ACCENT); + r.border_width = 2; + const int d = i == s_drag ? 7 : 4, x = ptX(a, i), y = mvY(a, battery::curveMvAt(i)); + lv_area_t c = { x - d, y - d, x + d, y + d }; + lv_draw_rect(layer, &r, &c); + } + if (s_drag >= 0) { // the point being moved, above it + const int x = ptX(a, s_drag), y = mvY(a, battery::curveMvAt(s_drag)); + snprintf(t, sizeof(t), "%d%% %d mV", s_drag * 10, battery::curveMvAt(s_drag)); + const int lx = constrain(x - 50, (int)a.x1, (int)a.x2 - 100); + lv_draw_rect_dsc_t bg; // on a pill, clear of the grid and the "now" line + lv_draw_rect_dsc_init(&bg); + bg.radius = theme::RADIUS_SM; + bg.bg_color = lv_color_hex(theme::SURFACE_2); + lv_area_t ba = { lx, y - 30, lx + 99, y - 12 }; + lv_draw_rect(layer, &bg, &ba); + text(layer, t, lx, y - 29, 100, LV_TEXT_ALIGN_CENTER, theme::TEXT); + } +} + +static void onTouch(lv_event_t* e) { + lv_event_code_t code = lv_event_get_code(e); + lv_obj_t* obj = lv_event_get_current_target_obj(e); + lv_indev_t* in = lv_indev_active(); + lv_point_t p = { 0, 0 }; + if (in) lv_indev_get_point(in, &p); + lv_area_t a; + lv_obj_get_coords(obj, &a); + if (code == LV_EVENT_PRESSED) { // the point nearest along the % axis + int best = 0; + for (int i = 1; i < PTS; i++) if (abs(ptX(a, i) - p.x) < abs(ptX(a, best) - p.x)) best = i; + s_drag = best; + } + NodePrefs* np = s_ui->prefsMut(); + if ((code == LV_EVENT_PRESSED || code == LV_EVENT_PRESSING) && s_drag >= 0 && np) { + uint16_t* c = np->batt_curve_mv; + if (!battery::validCurve(c)) + for (int k = 0; k < PTS; k++) c[k] = (uint16_t)battery::builtinMvAt(k); + const int lo = s_drag > 0 ? c[s_drag - 1] + 10 : battery::CURVE_MIN_MV; + const int hi = s_drag < PTS - 1 ? c[s_drag + 1] - 10 : battery::CURVE_MAX_MV; + const int mv = constrain((yMv(a, p.y) + 5) / 10 * 10, lo, hi); + if (mv != c[s_drag]) { c[s_drag] = (uint16_t)mv; lv_obj_invalidate(obj); s_ui->refreshBattCurve(); } + } + if (code == LV_EVENT_RELEASED || code == LV_EVENT_PRESS_LOST) { + s_drag = -1; + lv_obj_invalidate(obj); + prefsSave(); + } +} + +static void onReset(lv_event_t* e) { + (void)e; + NodePrefs* np = s_ui->prefsMut(); + if (!np || !battery::validCurve(np->batt_curve_mv)) return; + memset(np->batt_curve_mv, 0, sizeof(np->batt_curve_mv)); + prefsSave(); + if (s_chart) lv_obj_invalidate(s_chart); + s_ui->refreshBattCurve(); +} +} // namespace battview + +void UITask::showBattCurve() { + using namespace battview; + _screen = SCR_BATT; + lv_obj_t* body = newScreen("Battery curve", true); + headerButton(_header, LV_SYMBOL_REFRESH " Reset", onReset, 8, &s_reset); + lv_obj_remove_flag(body, LV_OBJ_FLAG_SCROLLABLE); + s_chart = lv_obj_create(body); + styleSurface(s_chart, theme::BG); + lv_obj_remove_flag(s_chart, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_width(s_chart, LV_PCT(100)); + lv_obj_set_flex_grow(s_chart, 1); + lv_obj_add_flag(s_chart, LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_flag(s_chart, LV_OBJ_FLAG_PRESS_LOCK); // still its drag when the finger strays off it + lv_obj_add_event_cb(s_chart, onDraw, LV_EVENT_DRAW_MAIN_END, NULL); + lv_obj_add_event_cb(s_chart, onTouch, LV_EVENT_ALL, NULL); + s_now = noteLabel(body, ""); + s_drag = -1; + refreshBattCurve(); +} + +// Once a second from loop(), and after a change: the cell now, the reset's state. +void UITask::refreshBattCurve() { + using namespace battview; + if (_screen != SCR_BATT || !s_now) return; + const int mv = battMv(); + const bool custom = _prefs && battery::validCurve(_prefs->batt_curve_mv); + char t[64]; + if (mv > 0) snprintf(t, sizeof(t), "Now %d mV - %d %% - %s curve", mv, battery::rawPercent(mv), custom ? "your" : "LiPo"); + else snprintf(t, sizeof(t), "%s curve - drag a point up or down", custom ? "Your" : "LiPo"); + lv_label_set_text(s_now, t); + if (s_reset) lv_obj_set_style_text_opa(s_reset, custom ? LV_OPA_COVER : LV_OPA_40, 0); + if (s_chart && s_drag < 0) lv_obj_invalidate(s_chart); // the "now" line moves with the cell +} diff --git a/examples/companion_radio/ui-lvgl/ChannelScreen.h b/examples/companion_radio/ui-lvgl/ChannelScreen.h index d69adbe2..b28c5fd0 100644 --- a/examples/companion_radio/ui-lvgl/ChannelScreen.h +++ b/examples/companion_radio/ui-lvgl/ChannelScreen.h @@ -94,7 +94,7 @@ void UITask::channelMenu(int idx) { struct { const char* text; uint8_t act; } btns[] = { { UI_SYMBOL_STAR " Fav", A_FAV }, { LV_SYMBOL_OK " Read", A_READ }, - { UI_SYMBOL_PIN, A_PIN }, + { UI_SYMBOL_TACK, A_PIN }, { LV_SYMBOL_EDIT " Edit", A_EDIT }, { LV_SYMBOL_TRASH, A_DELETE }, }; diff --git a/examples/companion_radio/ui-lvgl/ConversationScreen.h b/examples/companion_radio/ui-lvgl/ConversationScreen.h index e9e2fc6b..d15f6513 100644 --- a/examples/companion_radio/ui-lvgl/ConversationScreen.h +++ b/examples/companion_radio/ui-lvgl/ConversationScreen.h @@ -160,7 +160,7 @@ void UITask::conversationMenu(const uint8_t* pub_key) { lv_obj_t* acts = buttonBar(panel); s_fav_btn = barButton(acts, UI_SYMBOL_STAR " Fav", onConvAction, A_FAV, contactctl::favourite(ci)); if (!room && _core->dmUnread(ci.id.pub_key) > 0) barButton(acts, LV_SYMBOL_OK " Read", onConvAction, A_READ, false); - barButton(acts, UI_SYMBOL_PIN, onConvAction, A_PIN, favslots::findContact(_prefs, ci.id.pub_key) >= 0); + barButton(acts, UI_SYMBOL_TACK, onConvAction, A_PIN, favslots::findContact(_prefs, ci.id.pub_key) >= 0); if (room) { barButton(acts, LV_SYMBOL_EDIT " Login", onConvAction, A_LOGIN, false); if (_core->rooms.isLoggedIn(ci.id.pub_key)) barButton(acts, LV_SYMBOL_CLOSE " Logout", onConvAction, A_LOGOUT, false); diff --git a/examples/companion_radio/ui-lvgl/DiagScreen.h b/examples/companion_radio/ui-lvgl/DiagScreen.h index ba6cc903..9f97d572 100644 --- a/examples/companion_radio/ui-lvgl/DiagScreen.h +++ b/examples/companion_radio/ui-lvgl/DiagScreen.h @@ -308,6 +308,12 @@ void UITask::buildDiag() { if (sp) *sp = '\0'; infoRow(card, lines[i], sp ? sp + 1 : "", theme::TEXT, THEME_FONT_TITLE); } + // Colour emoji (Twemoji images the text fonts fall back to) and a flag, + // two regional indicator letters swapped for one glyph. L2 only: the L1 + // font has none, so this isn't in the shared list. + infoRow(card, "Emoji", "\xF0\x9F\x98\x80 \xF0\x9F\x91\x8D \xE2\x9D\xA4 \xF0\x9F\x94\xA5 " + "\xF0\x9F\x93\xA1 \xE2\x9B\xB0 \xF0\x9F\x87\xB5\xF0\x9F\x87\xB1", + theme::TEXT, THEME_FONT_TITLE); // grin, thumbs up, heart, fire, antenna, mountain, PL return; } // System: this build and the radio settings. diff --git a/examples/companion_radio/ui-lvgl/HomeScreen.h b/examples/companion_radio/ui-lvgl/HomeScreen.h index 3cda3b99..6c2d2e24 100644 --- a/examples/companion_radio/ui-lvgl/HomeScreen.h +++ b/examples/companion_radio/ui-lvgl/HomeScreen.h @@ -153,7 +153,8 @@ static mapview::Grid s_grid; // under the tiles, as on the map static void onTap(lv_event_t* e) { (void)e; s_ui->openMap(true); } static lv_obj_t* dot(uint8_t kind) { - static const struct { uint8_t d; uint32_t col, border; } LOOK[] = { + // Not static: the accent can change after the first dot (Settings > Display). + const struct { uint8_t d; uint32_t col, border; } LOOK[] = { { 14, theme::ACCENT, theme::BG }, { 14, theme::BG, theme::ACCENT }, // you; no fix: the last position, hollow { 12, theme::BG, theme::ACCENT }, { 12, theme::OK, theme::BG }, // the target; live shares }; @@ -199,7 +200,9 @@ static lv_obj_t* homeTile(lv_obj_t* parent, const char* icon, const char* text, // Every app is on the pages, a hidden one dimmed with a "+" (the others a // "-"). A tap hides / shows it; a drag lifts a copy of the tile on the top // layer (the tile dims in place) and drops the app into the slot under the -// finger; held at a screen edge, it goes to that side's page. Done, or the +// finger. While it's dragged the page already shows where it would land: the +// dimmed tile takes that slot and the tiles it pushes glide, names and all, to +// theirs. Held at a screen edge, it goes to that side's page. Done, or the // side button, ends it. namespace home { static lv_obj_t* s_ghost = nullptr; @@ -208,12 +211,17 @@ static bool s_dragged = false; // past the slop: the release is a drop, no static lv_point_t s_drag_start, s_ghost_org; static uint32_t s_edge_since = 0; static const int DRAG_SLOP = 8, EDGE_PX = 20; -static const uint32_t EDGE_MS = 600; +static const uint32_t EDGE_MS = 600, GLIDE_MS = 160; +static lv_point_t s_slot_c[PER_PAGE]; // the slots' centres as the page was laid out +static int s_slots = 0; +static int s_preview = -1; // the slot the dragged tile shows in now static void dragEnd() { if (s_ghost) { lv_obj_delete(s_ghost); s_ghost = nullptr; } s_drag_pos = -1; s_edge_since = 0; + s_slots = 0; + s_preview = -1; } // Leaving Home: arranging ends and the order is saved (UITask::newScreen). static void leave() { @@ -222,19 +230,56 @@ static void leave() { flushOrder(); } -// The tile on this page nearest the point, as a slot 0..PER_PAGE-1. +// Where the slots are, taken once when a drag starts: the tiles then move +// about under the finger, the slots don't. +static void captureSlots() { + s_slots = 0; + for (int i = 0; i < (int)lv_obj_get_child_count(s_page_box) && i < PER_PAGE; i++) { + lv_area_t a; + lv_obj_get_coords(lv_obj_get_child(s_page_box, i), &a); + s_slot_c[s_slots++] = { (a.x1 + a.x2) / 2, (a.y1 + a.y2) / 2 }; + } +} + +// The slot on this page nearest the point, 0..PER_PAGE-1. static int slotAt(lv_point_t p) { int best = 0; int32_t bd = INT32_MAX; - for (int i = 0; i < (int)lv_obj_get_child_count(s_page_box); i++) { - lv_area_t a; - lv_obj_get_coords(lv_obj_get_child(s_page_box, i), &a); - int32_t dx = p.x - (a.x1 + a.x2) / 2, dy = p.y - (a.y1 + a.y2) / 2; + for (int i = 0; i < s_slots; i++) { + int32_t dx = p.x - s_slot_c[i].x, dy = p.y - s_slot_c[i].y; if (dx * dx + dy * dy < bd) { bd = dx * dx + dy * dy; best = i; } } return best; } +// The dragged tile `t` into `slot`, the others closing up round it: each +// tile is laid out at its new place, then glides there from where it showed. +static void previewSlot(lv_obj_t* t, int slot) { + if (slot == s_preview) return; + s_preview = slot; + const int n = (int)lv_obj_get_child_count(s_page_box); + lv_obj_t* objs[PER_PAGE]; + lv_point_t was[PER_PAGE]; + for (int i = 0; i < n && i < PER_PAGE; i++) { + objs[i] = lv_obj_get_child(s_page_box, i); + lv_area_t a; + lv_obj_get_coords(objs[i], &a); // where it shows, mid-glide included + was[i] = { a.x1, a.y1 }; + lv_anim_delete(objs[i], anim::setTx); + lv_anim_delete(objs[i], anim::setTy); + lv_obj_set_style_translate_x(objs[i], 0, 0); + lv_obj_set_style_translate_y(objs[i], 0, 0); + } + lv_obj_move_to_index(t, slot); + lv_obj_update_layout(s_page_box); + for (int i = 0; i < n && i < PER_PAGE; i++) { + lv_area_t a; + lv_obj_get_coords(objs[i], &a); + if (was[i].x != a.x1) anim::run(objs[i], anim::setTx, was[i].x - a.x1, 0, GLIDE_MS); + if (was[i].y != a.y1) anim::run(objs[i], anim::setTy, was[i].y - a.y1, 0, GLIDE_MS); + } +} + // The page is rebuilt after the event that changed it, not inside it. static int s_pending_from, s_pending_to, s_pending_page; static void applyDrop(void*) { s_ui->homeAppDrop(s_pending_from, s_pending_to); if (s_pending_page >= 0) s_ui->setHomePage(s_pending_page); } @@ -274,10 +319,13 @@ static void onEditTile(lv_event_t* e) { lv_obj_get_coords(t, &c); s_ghost_org = { c.x1, c.y1 }; lv_obj_set_style_opa(t, LV_OPA_20, 0); + captureSlots(); + s_preview = lv_obj_get_index(t); } lv_obj_set_pos(s_ghost, s_ghost_org.x + p.x - s_drag_start.x, s_ghost_org.y + p.y - s_drag_start.y); int w = lv_display_get_horizontal_resolution(NULL); int side = p.x < EDGE_PX ? -1 : p.x >= w - EDGE_PX ? 1 : 0; + if (!side) previewSlot(t, slotAt(p)); int page = s_page + side; if (!side || page < APPS || page >= pageCount()) { s_edge_since = 0; return; } if (!s_edge_since) { s_edge_since = millis() | 1; return; } @@ -290,10 +338,11 @@ static void onEditTile(lv_event_t* e) { return; } bool dropped = s_dragged && s_ghost; + int slot = s_preview >= 0 ? s_preview : slotAt(p); // where the page already shows it dragEnd(); - if (code == LV_EVENT_PRESS_LOST) { lv_obj_set_style_opa(t, LV_OPA_COVER, 0); return; } + if (code == LV_EVENT_PRESS_LOST) { later(pos, pos, -1, false); return; } // rebuilt as it was if (!dropped) { later(pos, 0, -1, true); return; } // a tap - int to = (s_page - APPS) * PER_PAGE + slotAt(p); + int to = (s_page - APPS) * PER_PAGE + slot; later(pos, to < APP_COUNT ? to : APP_COUNT - 1, -1, false); } diff --git a/examples/companion_radio/ui-lvgl/MapScreen.h b/examples/companion_radio/ui-lvgl/MapScreen.h index 143e20ec..3dc3cb00 100644 --- a/examples/companion_radio/ui-lvgl/MapScreen.h +++ b/examples/companion_radio/ui-lvgl/MapScreen.h @@ -350,7 +350,9 @@ void UITask::perfMap(bool reset) { #endif void UITask::openMap(bool nav) { - _map_nav = nav; + // One map everywhere (trail, target, tools); from Nodes it adds the nodes. + _map_nav = true; + _map_nodes = !nav; showMap(); } @@ -693,7 +695,7 @@ void UITask::rebuildMapMarkers() { mapview::s_mark_prev = mapview::s_mark_count; mapview::s_mark_count = 0; if (_map_nav) rebuildNavMarkers(); - else rebuildNodeMarkers(); + if (_map_nodes || !_map_nav) rebuildNodeMarkers(); for (int k = mapview::s_mark_count; k < mapview::s_mark_prev; k++) lv_obj_delete(mapview::s_marks[k].obj); mapview::s_mark_prev = 0; layoutNow(_map_marks); // so layoutMap() knows where each dot sits in its marker @@ -704,6 +706,7 @@ void UITask::rebuildNodeMarkers() { for (int i = 0; i < _nearby->count() && mapview::s_mark_count < mapview::MAX_MARKS; i++) { const NearbyModel::Entry& e = _nearby->at(i); if (e.lat_e6 == 0 && e.lon_e6 == 0) continue; + if (e.is_live && _map_nav) continue; // the live share's own marker shows it uint32_t col = e.is_live ? theme::OK : e.type == ADV_TYPE_CHAT ? theme::TEXT : theme::TEXT_MUTED; addMapMark(mapview::MK_NODE, i, e.lat_e6, e.lon_e6, col, e.name[0] ? e.name : "?"); } diff --git a/examples/companion_radio/ui-lvgl/Theme.h b/examples/companion_radio/ui-lvgl/Theme.h index ed3a99df..8640c083 100644 --- a/examples/companion_radio/ui-lvgl/Theme.h +++ b/examples/companion_radio/ui-lvgl/Theme.h @@ -49,7 +49,8 @@ namespace theme { #define UI_SYMBOL_USERS "\xEF\x83\x80" // U+F0C0, Nearby #define UI_SYMBOL_COMPASS "\xEF\x85\x8E" // U+F14E, Navigate #define UI_SYMBOL_FLAG "\xEF\x80\xA4" // U+F024, waypoint - #define UI_SYMBOL_PIN "\xEF\x8F\x85" // U+F3C5, mark here + #define UI_SYMBOL_PIN "\xEF\x8F\x85" // U+F3C5, mark here (a place on the map) + #define UI_SYMBOL_TACK "\xEF\x82\x8D" // U+F08D, thumbtack: pin to the Home dial #define UI_SYMBOL_CLOCK "\xEF\x80\x97" // U+F017, Clock tools #define UI_SYMBOL_STOPWATCH "\xEF\x8B\xB2" // U+F2F2 #define UI_SYMBOL_RADIO "\xEF\x94\x99" // U+F519, broadcast tower diff --git a/examples/companion_radio/ui-lvgl/UITask.cpp b/examples/companion_radio/ui-lvgl/UITask.cpp index b26b2cc1..fb71982f 100644 --- a/examples/companion_radio/ui-lvgl/UITask.cpp +++ b/examples/companion_radio/ui-lvgl/UITask.cpp @@ -1283,6 +1283,7 @@ void UITask::begin(DisplayDriver* display_drv, SensorManager* sensors, NodePrefs _sensors = sensors; _prefs = node_prefs; s_prefs = node_prefs; + if (node_prefs) battery::useCurve(node_prefs->batt_curve_mv); // Settings > Battery curve _core = new UiCore(); _core->begin(node_prefs, sensors, this); @@ -1960,6 +1961,7 @@ void UITask::loop() { refreshDiag(); refreshCompass(); refreshGps(); + refreshBattCurve(); } if (locked()) lockPoll(); else if (_screen == SCR_HOME) { homeSwipePoll(); homeMapLoop(); } @@ -2712,6 +2714,7 @@ void UITask::back() { case SCR_ADMIN_PICK: showHome(); break; case SCR_OTA: otaLeave(); break; case SCR_COMPASS: showHome(); break; + case SCR_BATT: showSchemaSettings(PG_POWER); break; case SCR_GPS: if (_gps_from_settings) showSettings(); else showHome(); break; case SCR_ADMIN: if (_nav_overlay) navClosePopup(); else adminLeave(); break; case SCR_SETTINGS: if (_nav_overlay) navClosePopup(); else showHome(); break; @@ -2766,7 +2769,7 @@ void UITask::back() { if (_nav_overlay) navClosePopup(); else if (areaSelecting()) areaSelectEnd(); else if (_dl_overlay) mapDownloadClose(); - else if (!_map_nav) showNearby(); // the Nodes map opens from Nearby + else if (_map_nodes || !_map_nav) showNearby(); // opened from Nodes else showHome(); break; case SCR_WIFI: showSettings(); break; @@ -3676,10 +3679,10 @@ void UITask::buildNode() { if (e.has_key) list[n++] = { LV_SYMBOL_LOOP, " Ping", NODE_PING, false }; if (pos) list[n++] = { UI_SYMBOL_COMPASS, "", NODE_NAV, false }; if (pos) list[n++] = { UI_SYMBOL_FLAG, "", NODE_WAYPOINT, false }; // save where it was seen - if (contact) list[n++] = { UI_SYMBOL_STAR, admin ? "" : e.fav ? " Unfav" : " Fav", NODE_FAV, e.fav && admin }; + if (contact) list[n++] = { UI_SYMBOL_STAR, admin ? "" : e.fav ? " Unfav" : " Fav", NODE_FAV, e.fav }; // lit while it is one if (admin) list[n++] = { LV_SYMBOL_SETTINGS, " Admin", NODE_ADMIN, false }; if (!contact && e.has_key && !e.is_known) list[n++] = { LV_SYMBOL_PLUS, " Add", NODE_ADD, true }; - if (contact && e.has_key) list[n++] = { UI_SYMBOL_PIN, "", NODE_PIN, favslots::findContact(_prefs, e.pub_key) >= 0 }; + if (contact && e.has_key) list[n++] = { UI_SYMBOL_TACK, "", NODE_PIN, favslots::findContact(_prefs, e.pub_key) >= 0 }; if (contact) list[n++] = { LV_SYMBOL_TRASH, "", NODE_DELETE, false }; for (int i = 0; i < n; i++) { // five or more: icons only, so every button fits one row char t[24]; @@ -4499,6 +4502,7 @@ static void onHomeApps(lv_event_t* e) { (void)e; s_ui->homeEdit(true); } static void onPruneContacts(lv_event_t* e) { (void)e; s_ui->pruneContacts(); } static void onOpenQuickMsgs(lv_event_t* e); static void onPinSetup(lv_event_t* e); // DeviceScreen.h +static void onBattCurve(lv_event_t* e) { (void)e; s_ui->showBattCurve(); } static void onOpenOta(lv_event_t* e); // OtaScreen.h static void bluetoothRow(lv_obj_t* body); static void onVolumeSlider(lv_event_t* e) { @@ -4593,6 +4597,8 @@ void UITask::buildSchemaSettings() { lv_obj_t* g = group(body, "BATTERY"); schemaRow(g, SETTING(batt_display_mode)); schemaRow(g, SETTING(low_batt_mv)); + listRow(g, "Battery curve", _prefs && battery::validCurve(_prefs->batt_curve_mv) ? "Your own" : "LiPo (built in)", + onBattCurve, NULL); g = group(body, "GPS"); schemaRow(g, SETTING(gps_interval)); return; @@ -4865,6 +4871,7 @@ void UITask::setKeyboardAlphabets(int main_idx, int alt_sel) { #include "DeviceScreen.h" #include "DiagScreen.h" #include "CompassScreen.h" +#include "BatteryScreen.h" #include "GpsScreen.h" #include "RadioExtras.h" #include "RepeaterScreen.h" @@ -4905,6 +4912,10 @@ extern "C" EMSCRIPTEN_KEEPALIVE void sim_open(const char* name) { for (auto& s : SCREENS) if (!strcmp(s.n, name)) { (s_ui->*s.fn)(); return; } if (!strncmp(name, "page", 4)) { s_ui->showSchemaSettings(atoi(name + 4)); return; } if (!strcmp(name, "map")) { s_ui->openMap(true); return; } + if (!strcmp(name, "nodesmap")) { s_ui->openMap(false); return; } // as from Nodes + if (!strcmp(name, "battcurve")) { s_ui->showBattCurve(); return; } + if (!strcmp(name, "homeedit")) { s_ui->showHome(); s_ui->homeEdit(true); return; } // arranging the apps + if (!strncmp(name, "accent@", 7)) { theme::setAccent(atoi(name + 7)); return; } // "accent@4": Cyan if (!strncmp(name, "map@", 4)) { s_ui->simMapAt(name + 4); return; } // "map@lat,lon,z" if (!strcmp(name, "vector")) { s_ui->setVectorMap(true); return; } if (!strcmp(name, "maptools")) { s_ui->navToolsPopup(); return; } diff --git a/examples/companion_radio/ui-lvgl/UITask.h b/examples/companion_radio/ui-lvgl/UITask.h index 5ccd9ddc..32f7bd97 100644 --- a/examples/companion_radio/ui-lvgl/UITask.h +++ b/examples/companion_radio/ui-lvgl/UITask.h @@ -70,7 +70,7 @@ public: void setSchemaValue(int idx, int v); void showNearby(); void showMap(); // in its current mode - void openMap(bool nav); // Nodes map (false) or Navigation map (true) + void openMap(bool nav); // the one map; false: from Nodes, with the nodes on it and Back to Nodes void mapLongPress(int x, int y); void mapZoom(int delta); void mapCenterOnMe(); @@ -284,6 +284,10 @@ public: void diagReset(); void diagNoiseRun(); void showCompass(); + void showBattCurve(); // Settings > Power > Battery curve (BatteryScreen.h) + void refreshBattCurve(); + int battMv() const { return _batt_mv; } // smoothed cell voltage, 0 before the first read + NodePrefs* prefsMut() const { return _prefs; } // for the free helpers that change a setting void favTap(int slot); void favHold(int slot); void favAction(uint8_t act); @@ -298,7 +302,7 @@ public: void openAdminFor(const ContactInfo& ci, bool from_picker) { (void)from_picker; openAdmin(ci.id.pub_key); } private: - enum Screen : uint8_t { SCR_HOME, SCR_CHATS, SCR_CONTACTS, SCR_THREAD, SCR_SETTINGS, SCR_NEARBY, SCR_NODE, SCR_MAP, SCR_WIFI, SCR_SETTINGS_NAV, SCR_CLOCK, SCR_RADIO, SCR_CHANNEL_EDIT, SCR_ADMIN, SCR_BOT, SCR_DIAG, SCR_COMPASS, SCR_SCOPES, SCR_REPEATER, SCR_MELODY, SCR_QUICK, SCR_ADMIN_PICK, SCR_OTA, SCR_STORAGE, SCR_GPS }; + enum Screen : uint8_t { SCR_HOME, SCR_CHATS, SCR_CONTACTS, SCR_THREAD, SCR_SETTINGS, SCR_NEARBY, SCR_NODE, SCR_MAP, SCR_WIFI, SCR_SETTINGS_NAV, SCR_CLOCK, SCR_RADIO, SCR_CHANNEL_EDIT, SCR_ADMIN, SCR_BOT, SCR_DIAG, SCR_COMPASS, SCR_SCOPES, SCR_REPEATER, SCR_MELODY, SCR_QUICK, SCR_ADMIN_PICK, SCR_OTA, SCR_STORAGE, SCR_GPS, SCR_BATT }; void buildStatusBar(); void refreshStatusBar(); @@ -575,6 +579,7 @@ private: // Navigation map (SCR_MAP with _map_nav) bool _map_nav = false; + bool _map_nodes = false; // opened from Nodes: their markers too, Back returns there uint32_t _next_nav_bar_ms = 0; lv_obj_t* _nav_bar = nullptr; // target bar along the bottom lv_obj_t* _nav_title = nullptr; diff --git a/examples/companion_radio/ui-lvgl/fonts/generate.sh b/examples/companion_radio/ui-lvgl/fonts/generate.sh index 12eecb99..f5610a4e 100755 --- a/examples/companion_radio/ui-lvgl/fonts/generate.sh +++ b/examples/companion_radio/ui-lvgl/fonts/generate.sh @@ -32,8 +32,8 @@ TEXT="$TEXT,0x2010-0x2027,0x2030,0x2039-0x203A,0x20A4-0x20BF,0x2116,0x2122" # 61476 = flag (waypoint), 62405 = map marker (mark here), 61463 = clock, # 62194 = stopwatch, 62745 = broadcast tower (radio), 61568 = bar chart (diagnostics), # 61572 = key (admin), 62679 = route (trail in the status bar), -# 63145 = volume-mute (muted, in the status bar) -SYMS="63145,61572,62679,61568,62745,61463,62194,61612,61445,62073,61632,61774,61476,62405,61441,61448,61451,61452,61453,61457,61459,61461,61465,61468,61473,61478,61479,61480,61502,61507,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61550,61552,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61641,61664,61671,61674,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62087,62099,62212,62189,62810,63426,63650" +# 63145 = volume-mute (muted, in the status bar), 61581 = thumbtack (pin to the Home dial) +SYMS="61581,63145,61572,62679,61568,62745,61463,62194,61612,61445,62073,61632,61774,61476,62405,61441,61448,61451,61452,61453,61457,61459,61461,61465,61468,61473,61478,61479,61480,61502,61507,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61550,61552,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61641,61664,61671,61674,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62087,62099,62212,62189,62810,63426,63650" CONV="npx -y lv_font_conv@1.5.3" gen() { # size weight ranges name diff --git a/examples/companion_radio/ui-lvgl/fonts/ui_font_12.c b/examples/companion_radio/ui-lvgl/fonts/ui_font_12.c index 2f1284c8..e6209d24 100644 --- a/examples/companion_radio/ui-lvgl/fonts/ui_font_12.c +++ b/examples/companion_radio/ui-lvgl/fonts/ui_font_12.c @@ -1,7 +1,7 @@ /******************************************************************************* * Size: 12 px * Bpp: 4 - * Opts: --bpp 4 --size 12 --no-compress --force-fast-kern-format --font /var/folders/1d/dgkmygls6x5gsb16pbn2mwlr0000gn/T//meshcore-ui-fonts/NotoSans-Medium.ttf -r 0x20-0x7E,0xA0-0x24F,0x370-0x3FF,0x400-0x52F,0x1E80-0x1E85,0x1E9E,0x1EF2-0x1EF3,0x2010-0x2027,0x2030,0x2039-0x203A,0x20A4-0x20BF,0x2116,0x2122 --font /var/folders/1d/dgkmygls6x5gsb16pbn2mwlr0000gn/T//meshcore-ui-fonts/fa.woff -r 63145,61572,62679,61568,62745,61463,62194,61612,61445,62073,61632,61774,61476,62405,61441,61448,61451,61452,61453,61457,61459,61461,61465,61468,61473,61478,61479,61480,61502,61507,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61550,61552,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61641,61664,61671,61674,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62087,62099,62212,62189,62810,63426,63650 --format lvgl --lv-include lvgl.h --lv-font-name ui_font_12 -o /Users/jakub/Documents/MeshCore/MeshCore/examples/companion_radio/ui-lvgl/fonts/ui_font_12.c + * Opts: --bpp 4 --size 12 --no-compress --force-fast-kern-format --font /var/folders/1d/dgkmygls6x5gsb16pbn2mwlr0000gn/T//meshcore-ui-fonts/NotoSans-Medium.ttf -r 0x20-0x7E,0xA0-0x24F,0x370-0x3FF,0x400-0x52F,0x1E80-0x1E85,0x1E9E,0x1EF2-0x1EF3,0x2010-0x2027,0x2030,0x2039-0x203A,0x20A4-0x20BF,0x2116,0x2122 --font /var/folders/1d/dgkmygls6x5gsb16pbn2mwlr0000gn/T//meshcore-ui-fonts/fa.woff -r 61581,63145,61572,62679,61568,62745,61463,62194,61612,61445,62073,61632,61774,61476,62405,61441,61448,61451,61452,61453,61457,61459,61461,61465,61468,61473,61478,61479,61480,61502,61507,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61550,61552,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61641,61664,61671,61674,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62087,62099,62212,62189,62810,63426,63650 --format lvgl --lv-include lvgl.h --lv-font-name ui_font_12 -o /Users/jakub/Documents/MeshCore/MeshCore/examples/companion_radio/ui-lvgl/fonts/ui_font_12.c ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE @@ -7461,6 +7461,16 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0x0, 0x0, 0xff, 0xfc, 0x10, 0x0, 0x0, 0x0, 0x89, 0x95, 0x0, 0x0, 0x0, 0x0, + /* U+F08D "" */ + 0x4, 0x44, 0x44, 0x44, 0x3, 0xff, 0xff, 0xff, + 0xf3, 0x2e, 0xff, 0xff, 0xfe, 0x20, 0xc, 0xff, + 0xfc, 0x0, 0x0, 0xdf, 0xff, 0xd0, 0x0, 0xf, + 0xff, 0xff, 0x0, 0x2e, 0xff, 0xff, 0xfe, 0x2c, + 0xff, 0xff, 0xff, 0xfc, 0xdf, 0xff, 0xff, 0xff, + 0xd0, 0x0, 0x4f, 0x40, 0x0, 0x0, 0x4, 0xf4, + 0x0, 0x0, 0x0, 0x2f, 0x20, 0x0, 0x0, 0x0, + 0x60, 0x0, 0x0, + /* U+F093 "" */ 0x0, 0x0, 0x2, 0x20, 0x0, 0x0, 0x0, 0x0, 0x3e, 0xe3, 0x0, 0x0, 0x0, 0x3, 0xef, 0xfe, @@ -8923,41 +8933,42 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { {.bitmap_index = 38831, .adv_w = 192, .box_w = 12, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, {.bitmap_index = 38885, .adv_w = 192, .box_w = 12, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, {.bitmap_index = 38939, .adv_w = 192, .box_w = 12, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 39017, .adv_w = 192, .box_w = 12, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 39095, .adv_w = 192, .box_w = 13, .box_h = 13, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 39180, .adv_w = 186, .box_w = 12, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 39258, .adv_w = 240, .box_w = 15, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 39341, .adv_w = 168, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 39402, .adv_w = 168, .box_w = 11, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 39474, .adv_w = 168, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 39535, .adv_w = 168, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 39596, .adv_w = 192, .box_w = 12, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 39650, .adv_w = 120, .box_w = 9, .box_h = 13, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 39709, .adv_w = 168, .box_w = 11, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 39781, .adv_w = 168, .box_w = 11, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 39853, .adv_w = 216, .box_w = 14, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 39916, .adv_w = 192, .box_w = 14, .box_h = 13, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 40007, .adv_w = 186, .box_w = 12, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 40085, .adv_w = 144, .box_w = 9, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 40144, .adv_w = 240, .box_w = 15, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 40234, .adv_w = 240, .box_w = 15, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 40302, .adv_w = 240, .box_w = 15, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 40370, .adv_w = 240, .box_w = 15, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 40438, .adv_w = 240, .box_w = 15, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 40506, .adv_w = 240, .box_w = 15, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 40574, .adv_w = 216, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 40651, .adv_w = 240, .box_w = 16, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 40739, .adv_w = 168, .box_w = 10, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 40804, .adv_w = 168, .box_w = 11, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 40876, .adv_w = 168, .box_w = 11, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 40948, .adv_w = 192, .box_w = 13, .box_h = 13, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 41033, .adv_w = 144, .box_w = 9, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 41092, .adv_w = 192, .box_w = 12, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 41170, .adv_w = 240, .box_w = 15, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 41268, .adv_w = 240, .box_w = 15, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 41336, .adv_w = 192, .box_w = 13, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 41401, .adv_w = 144, .box_w = 9, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 41460, .adv_w = 193, .box_w = 13, .box_h = 9, .ofs_x = 0, .ofs_y = 0} + {.bitmap_index = 39017, .adv_w = 144, .box_w = 9, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39076, .adv_w = 192, .box_w = 12, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39154, .adv_w = 192, .box_w = 13, .box_h = 13, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 39239, .adv_w = 186, .box_w = 12, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39317, .adv_w = 240, .box_w = 15, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 39400, .adv_w = 168, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 39461, .adv_w = 168, .box_w = 11, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39533, .adv_w = 168, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 39594, .adv_w = 168, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 39655, .adv_w = 192, .box_w = 12, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 39709, .adv_w = 120, .box_w = 9, .box_h = 13, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 39768, .adv_w = 168, .box_w = 11, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39840, .adv_w = 168, .box_w = 11, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39912, .adv_w = 216, .box_w = 14, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 39975, .adv_w = 192, .box_w = 14, .box_h = 13, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 40066, .adv_w = 186, .box_w = 12, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40144, .adv_w = 144, .box_w = 9, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40203, .adv_w = 240, .box_w = 15, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 40293, .adv_w = 240, .box_w = 15, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 40361, .adv_w = 240, .box_w = 15, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 40429, .adv_w = 240, .box_w = 15, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 40497, .adv_w = 240, .box_w = 15, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 40565, .adv_w = 240, .box_w = 15, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 40633, .adv_w = 216, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 40710, .adv_w = 240, .box_w = 16, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 40798, .adv_w = 168, .box_w = 10, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40863, .adv_w = 168, .box_w = 11, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40935, .adv_w = 168, .box_w = 11, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 41007, .adv_w = 192, .box_w = 13, .box_h = 13, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 41092, .adv_w = 144, .box_w = 9, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 41151, .adv_w = 192, .box_w = 12, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 41229, .adv_w = 240, .box_w = 15, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 41327, .adv_w = 240, .box_w = 15, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 41395, .adv_w = 192, .box_w = 13, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 41460, .adv_w = 144, .box_w = 9, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 41519, .adv_w = 193, .box_w = 13, .box_h = 9, .ofs_x = 0, .ofs_y = 0} }; /*--------------------- @@ -8986,11 +8997,11 @@ static const uint16_t unicode_list_12[] = { 0xcf10, 0xcf11, 0xcf12, 0xcf28, 0xcf2d, 0xcf32, 0xcf35, 0xcf36, 0xcf37, 0xcf3b, 0xcf3c, 0xcf3d, 0xcf3e, 0xcf51, 0xcf52, 0xcf58, 0xcf5a, 0xcf5b, 0xcf5e, 0xcf61, 0xcf62, 0xcf63, 0xcf65, 0xcf6a, - 0xcf6e, 0xcf7d, 0xcf7f, 0xcf96, 0xcfaa, 0xcfae, 0xcfaf, 0xcfb1, - 0xcfb3, 0xcfca, 0xcfd1, 0xcfd4, 0xcfdd, 0xd006, 0xd00e, 0xd038, - 0xd045, 0xd0d5, 0xd12a, 0xd12b, 0xd12c, 0xd12d, 0xd12e, 0xd163, - 0xd171, 0xd17d, 0xd1d7, 0xd1dc, 0xd1ee, 0xd2af, 0xd3c1, 0xd403, - 0xd444, 0xd593, 0xd6ac, 0xd78c + 0xcf6e, 0xcf77, 0xcf7d, 0xcf7f, 0xcf96, 0xcfaa, 0xcfae, 0xcfaf, + 0xcfb1, 0xcfb3, 0xcfca, 0xcfd1, 0xcfd4, 0xcfdd, 0xd006, 0xd00e, + 0xd038, 0xd045, 0xd0d5, 0xd12a, 0xd12b, 0xd12c, 0xd12d, 0xd12e, + 0xd163, 0xd171, 0xd17d, 0xd1d7, 0xd1dc, 0xd1ee, 0xd2af, 0xd3c1, + 0xd403, 0xd444, 0xd593, 0xd6ac, 0xd78c }; /*Collect the unicode lists and glyph_id offsets*/ @@ -9046,7 +9057,7 @@ static const lv_font_fmt_txt_cmap_t cmaps[] = }, { .range_start = 8470, .range_length = 55181, .glyph_id_start = 1017, - .unicode_list = unicode_list_12, .glyph_id_ofs_list = NULL, .list_length = 76, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + .unicode_list = unicode_list_12, .glyph_id_ofs_list = NULL, .list_length = 77, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY } }; @@ -9194,7 +9205,7 @@ static const uint8_t kern_left_class_mapping[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0 }; /*Map glyph_ids to kern right classes*/ @@ -9336,7 +9347,7 @@ static const uint8_t kern_right_class_mapping[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0 }; /*Kern values between classes*/ diff --git a/examples/companion_radio/ui-lvgl/fonts/ui_font_14.c b/examples/companion_radio/ui-lvgl/fonts/ui_font_14.c index 59b46c62..983c3c24 100644 --- a/examples/companion_radio/ui-lvgl/fonts/ui_font_14.c +++ b/examples/companion_radio/ui-lvgl/fonts/ui_font_14.c @@ -1,7 +1,7 @@ /******************************************************************************* * Size: 14 px * Bpp: 4 - * Opts: --bpp 4 --size 14 --no-compress --force-fast-kern-format --font /var/folders/1d/dgkmygls6x5gsb16pbn2mwlr0000gn/T//meshcore-ui-fonts/NotoSans-Medium.ttf -r 0x20-0x7E,0xA0-0x24F,0x370-0x3FF,0x400-0x52F,0x1E80-0x1E85,0x1E9E,0x1EF2-0x1EF3,0x2010-0x2027,0x2030,0x2039-0x203A,0x20A4-0x20BF,0x2116,0x2122 --font /var/folders/1d/dgkmygls6x5gsb16pbn2mwlr0000gn/T//meshcore-ui-fonts/fa.woff -r 63145,61572,62679,61568,62745,61463,62194,61612,61445,62073,61632,61774,61476,62405,61441,61448,61451,61452,61453,61457,61459,61461,61465,61468,61473,61478,61479,61480,61502,61507,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61550,61552,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61641,61664,61671,61674,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62087,62099,62212,62189,62810,63426,63650 --format lvgl --lv-include lvgl.h --lv-font-name ui_font_14 -o /Users/jakub/Documents/MeshCore/MeshCore/examples/companion_radio/ui-lvgl/fonts/ui_font_14.c + * Opts: --bpp 4 --size 14 --no-compress --force-fast-kern-format --font /var/folders/1d/dgkmygls6x5gsb16pbn2mwlr0000gn/T//meshcore-ui-fonts/NotoSans-Medium.ttf -r 0x20-0x7E,0xA0-0x24F,0x370-0x3FF,0x400-0x52F,0x1E80-0x1E85,0x1E9E,0x1EF2-0x1EF3,0x2010-0x2027,0x2030,0x2039-0x203A,0x20A4-0x20BF,0x2116,0x2122 --font /var/folders/1d/dgkmygls6x5gsb16pbn2mwlr0000gn/T//meshcore-ui-fonts/fa.woff -r 61581,63145,61572,62679,61568,62745,61463,62194,61612,61445,62073,61632,61774,61476,62405,61441,61448,61451,61452,61453,61457,61459,61461,61465,61468,61473,61478,61479,61480,61502,61507,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61550,61552,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61641,61664,61671,61674,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62087,62099,62212,62189,62810,63426,63650 --format lvgl --lv-include lvgl.h --lv-font-name ui_font_14 -o /Users/jakub/Documents/MeshCore/MeshCore/examples/companion_radio/ui-lvgl/fonts/ui_font_14.c ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE @@ -8826,6 +8826,19 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0x0, 0x0, 0x68, 0x88, 0x10, 0x0, 0x0, 0x0, 0x0, + /* U+F08D "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xff, 0xff, + 0xff, 0xff, 0x80, 0x1f, 0xff, 0xff, 0xff, 0xf9, + 0x0, 0x8b, 0xff, 0xff, 0xe9, 0x30, 0x0, 0x6f, + 0xff, 0xfe, 0x0, 0x0, 0x8, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0xaf, 0xff, 0xff, 0x20, 0x0, 0xaf, + 0xff, 0xff, 0xfe, 0x40, 0x8f, 0xff, 0xff, 0xff, + 0xff, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x79, + 0x99, 0xdf, 0xa9, 0x99, 0x20, 0x0, 0xa, 0xf2, + 0x0, 0x0, 0x0, 0x0, 0xaf, 0x20, 0x0, 0x0, + 0x0, 0x8, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x28, + 0x0, 0x0, 0x0, + /* U+F093 "" */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xdd, 0x10, 0x0, 0x0, 0x0, 0x0, @@ -10403,41 +10416,42 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { {.bitmap_index = 49996, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, {.bitmap_index = 50073, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, {.bitmap_index = 50150, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 50255, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 50360, .adv_w = 224, .box_w = 15, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 50473, .adv_w = 217, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 50578, .adv_w = 280, .box_w = 18, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 50695, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 50780, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 50878, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 50963, .adv_w = 196, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 51041, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 51118, .adv_w = 140, .box_w = 10, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 51193, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 51291, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 51389, .adv_w = 252, .box_w = 16, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 51477, .adv_w = 224, .box_w = 16, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 51597, .adv_w = 217, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 51702, .adv_w = 168, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 51785, .adv_w = 280, .box_w = 18, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 51902, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 51992, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 52082, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 52172, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 52262, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 52352, .adv_w = 252, .box_w = 16, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 52456, .adv_w = 280, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 52564, .adv_w = 196, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 52654, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 52752, .adv_w = 196, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 52842, .adv_w = 224, .box_w = 15, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 52955, .adv_w = 168, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53038, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53143, .adv_w = 280, .box_w = 18, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53278, .adv_w = 280, .box_w = 18, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 53377, .adv_w = 224, .box_w = 15, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 53467, .adv_w = 168, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 53550, .adv_w = 225, .box_w = 15, .box_h = 10, .ofs_x = 0, .ofs_y = 0} + {.bitmap_index = 50255, .adv_w = 168, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50338, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50443, .adv_w = 224, .box_w = 15, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 50556, .adv_w = 217, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50661, .adv_w = 280, .box_w = 18, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 50778, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 50863, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50961, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 51046, .adv_w = 196, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 51124, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 51201, .adv_w = 140, .box_w = 10, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 51276, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 51374, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 51472, .adv_w = 252, .box_w = 16, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 51560, .adv_w = 224, .box_w = 16, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 51680, .adv_w = 217, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 51785, .adv_w = 168, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 51868, .adv_w = 280, .box_w = 18, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 51985, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 52075, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 52165, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 52255, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 52345, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 52435, .adv_w = 252, .box_w = 16, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 52539, .adv_w = 280, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 52647, .adv_w = 196, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 52737, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 52835, .adv_w = 196, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 52925, .adv_w = 224, .box_w = 15, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 53038, .adv_w = 168, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 53121, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 53226, .adv_w = 280, .box_w = 18, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 53361, .adv_w = 280, .box_w = 18, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 53460, .adv_w = 224, .box_w = 15, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 53550, .adv_w = 168, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 53633, .adv_w = 225, .box_w = 15, .box_h = 10, .ofs_x = 0, .ofs_y = 0} }; /*--------------------- @@ -10466,11 +10480,11 @@ static const uint16_t unicode_list_12[] = { 0xcf10, 0xcf11, 0xcf12, 0xcf28, 0xcf2d, 0xcf32, 0xcf35, 0xcf36, 0xcf37, 0xcf3b, 0xcf3c, 0xcf3d, 0xcf3e, 0xcf51, 0xcf52, 0xcf58, 0xcf5a, 0xcf5b, 0xcf5e, 0xcf61, 0xcf62, 0xcf63, 0xcf65, 0xcf6a, - 0xcf6e, 0xcf7d, 0xcf7f, 0xcf96, 0xcfaa, 0xcfae, 0xcfaf, 0xcfb1, - 0xcfb3, 0xcfca, 0xcfd1, 0xcfd4, 0xcfdd, 0xd006, 0xd00e, 0xd038, - 0xd045, 0xd0d5, 0xd12a, 0xd12b, 0xd12c, 0xd12d, 0xd12e, 0xd163, - 0xd171, 0xd17d, 0xd1d7, 0xd1dc, 0xd1ee, 0xd2af, 0xd3c1, 0xd403, - 0xd444, 0xd593, 0xd6ac, 0xd78c + 0xcf6e, 0xcf77, 0xcf7d, 0xcf7f, 0xcf96, 0xcfaa, 0xcfae, 0xcfaf, + 0xcfb1, 0xcfb3, 0xcfca, 0xcfd1, 0xcfd4, 0xcfdd, 0xd006, 0xd00e, + 0xd038, 0xd045, 0xd0d5, 0xd12a, 0xd12b, 0xd12c, 0xd12d, 0xd12e, + 0xd163, 0xd171, 0xd17d, 0xd1d7, 0xd1dc, 0xd1ee, 0xd2af, 0xd3c1, + 0xd403, 0xd444, 0xd593, 0xd6ac, 0xd78c }; /*Collect the unicode lists and glyph_id offsets*/ @@ -10526,7 +10540,7 @@ static const lv_font_fmt_txt_cmap_t cmaps[] = }, { .range_start = 8470, .range_length = 55181, .glyph_id_start = 1017, - .unicode_list = unicode_list_12, .glyph_id_ofs_list = NULL, .list_length = 76, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + .unicode_list = unicode_list_12, .glyph_id_ofs_list = NULL, .list_length = 77, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY } }; @@ -10674,7 +10688,7 @@ static const uint8_t kern_left_class_mapping[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0 }; /*Map glyph_ids to kern right classes*/ @@ -10816,7 +10830,7 @@ static const uint8_t kern_right_class_mapping[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0 }; /*Kern values between classes*/ diff --git a/examples/companion_radio/ui-lvgl/fonts/ui_font_16.c b/examples/companion_radio/ui-lvgl/fonts/ui_font_16.c index b05ccd26..cf5dd951 100644 --- a/examples/companion_radio/ui-lvgl/fonts/ui_font_16.c +++ b/examples/companion_radio/ui-lvgl/fonts/ui_font_16.c @@ -1,7 +1,7 @@ /******************************************************************************* * Size: 16 px * Bpp: 4 - * Opts: --bpp 4 --size 16 --no-compress --force-fast-kern-format --font /var/folders/1d/dgkmygls6x5gsb16pbn2mwlr0000gn/T//meshcore-ui-fonts/NotoSans-Medium.ttf -r 0x20-0x7E,0xA0-0x24F,0x370-0x3FF,0x400-0x52F,0x1E80-0x1E85,0x1E9E,0x1EF2-0x1EF3,0x2010-0x2027,0x2030,0x2039-0x203A,0x20A4-0x20BF,0x2116,0x2122 --font /var/folders/1d/dgkmygls6x5gsb16pbn2mwlr0000gn/T//meshcore-ui-fonts/fa.woff -r 63145,61572,62679,61568,62745,61463,62194,61612,61445,62073,61632,61774,61476,62405,61441,61448,61451,61452,61453,61457,61459,61461,61465,61468,61473,61478,61479,61480,61502,61507,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61550,61552,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61641,61664,61671,61674,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62087,62099,62212,62189,62810,63426,63650 --format lvgl --lv-include lvgl.h --lv-font-name ui_font_16 -o /Users/jakub/Documents/MeshCore/MeshCore/examples/companion_radio/ui-lvgl/fonts/ui_font_16.c + * Opts: --bpp 4 --size 16 --no-compress --force-fast-kern-format --font /var/folders/1d/dgkmygls6x5gsb16pbn2mwlr0000gn/T//meshcore-ui-fonts/NotoSans-Medium.ttf -r 0x20-0x7E,0xA0-0x24F,0x370-0x3FF,0x400-0x52F,0x1E80-0x1E85,0x1E9E,0x1EF2-0x1EF3,0x2010-0x2027,0x2030,0x2039-0x203A,0x20A4-0x20BF,0x2116,0x2122 --font /var/folders/1d/dgkmygls6x5gsb16pbn2mwlr0000gn/T//meshcore-ui-fonts/fa.woff -r 61581,63145,61572,62679,61568,62745,61463,62194,61612,61445,62073,61632,61774,61476,62405,61441,61448,61451,61452,61453,61457,61459,61461,61465,61468,61473,61478,61479,61480,61502,61507,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61550,61552,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61641,61664,61671,61674,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62087,62099,62212,62189,62810,63426,63650 --format lvgl --lv-include lvgl.h --lv-font-name ui_font_16 -o /Users/jakub/Documents/MeshCore/MeshCore/examples/companion_radio/ui-lvgl/fonts/ui_font_16.c ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE @@ -10677,6 +10677,20 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0xff, 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdf, 0xff, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* U+F08D "" */ + 0xd, 0xff, 0xff, 0xff, 0xff, 0xd0, 0xf, 0xff, + 0xff, 0xff, 0xff, 0xf0, 0xd, 0xff, 0xff, 0xff, + 0xff, 0xd0, 0x0, 0xf, 0xff, 0xff, 0xf0, 0x0, + 0x0, 0x1f, 0xff, 0xff, 0xf1, 0x0, 0x0, 0x3f, + 0xff, 0xff, 0xf3, 0x0, 0x0, 0x5f, 0xff, 0xff, + 0xf5, 0x0, 0x8, 0xff, 0xff, 0xff, 0xff, 0x80, + 0x6f, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xdf, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0xdf, 0xff, 0xff, 0xff, + 0xff, 0xfd, 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, 0x0, + 0xf, 0xf0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0x6, 0x60, 0x0, 0x0, + /* U+F093 "" */ 0x0, 0x0, 0x0, 0xb, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbf, 0xfb, 0x0, 0x0, 0x0, @@ -12334,41 +12348,42 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { {.bitmap_index = 65163, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, {.bitmap_index = 65259, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, {.bitmap_index = 65355, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 65483, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 65611, .adv_w = 256, .box_w = 17, .box_h = 17, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 65756, .adv_w = 248, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 65884, .adv_w = 320, .box_w = 20, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 66024, .adv_w = 224, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 66129, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66241, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 66339, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 66437, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 66533, .adv_w = 160, .box_w = 12, .box_h = 16, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 66629, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66741, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 66853, .adv_w = 288, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 66961, .adv_w = 256, .box_w = 18, .box_h = 18, .ofs_x = -1, .ofs_y = -3}, - {.bitmap_index = 67123, .adv_w = 248, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67251, .adv_w = 192, .box_w = 12, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 67347, .adv_w = 320, .box_w = 20, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 67497, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 67597, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 67697, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 67797, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 67897, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 67997, .adv_w = 288, .box_w = 18, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68141, .adv_w = 320, .box_w = 21, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 68288, .adv_w = 224, .box_w = 12, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 68384, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68496, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68608, .adv_w = 256, .box_w = 17, .box_h = 17, .ofs_x = -1, .ofs_y = -3}, - {.bitmap_index = 68753, .adv_w = 192, .box_w = 12, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68849, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 68977, .adv_w = 320, .box_w = 20, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 69147, .adv_w = 320, .box_w = 20, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 69267, .adv_w = 256, .box_w = 17, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 69386, .adv_w = 192, .box_w = 12, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 69482, .adv_w = 258, .box_w = 17, .box_h = 11, .ofs_x = 0, .ofs_y = 1} + {.bitmap_index = 65483, .adv_w = 192, .box_w = 12, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 65579, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 65707, .adv_w = 256, .box_w = 17, .box_h = 17, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 65852, .adv_w = 248, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 65980, .adv_w = 320, .box_w = 20, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66120, .adv_w = 224, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66225, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 66337, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66435, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66533, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 66629, .adv_w = 160, .box_w = 12, .box_h = 16, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 66725, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 66837, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 66949, .adv_w = 288, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 67057, .adv_w = 256, .box_w = 18, .box_h = 18, .ofs_x = -1, .ofs_y = -3}, + {.bitmap_index = 67219, .adv_w = 248, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67347, .adv_w = 192, .box_w = 12, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67443, .adv_w = 320, .box_w = 20, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 67593, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 67693, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 67793, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 67893, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 67993, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 68093, .adv_w = 288, .box_w = 18, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 68237, .adv_w = 320, .box_w = 21, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 68384, .adv_w = 224, .box_w = 12, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 68480, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 68592, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 68704, .adv_w = 256, .box_w = 17, .box_h = 17, .ofs_x = -1, .ofs_y = -3}, + {.bitmap_index = 68849, .adv_w = 192, .box_w = 12, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 68945, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69073, .adv_w = 320, .box_w = 20, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 69243, .adv_w = 320, .box_w = 20, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 69363, .adv_w = 256, .box_w = 17, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 69482, .adv_w = 192, .box_w = 12, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69578, .adv_w = 258, .box_w = 17, .box_h = 11, .ofs_x = 0, .ofs_y = 1} }; /*--------------------- @@ -12397,11 +12412,11 @@ static const uint16_t unicode_list_12[] = { 0xcf10, 0xcf11, 0xcf12, 0xcf28, 0xcf2d, 0xcf32, 0xcf35, 0xcf36, 0xcf37, 0xcf3b, 0xcf3c, 0xcf3d, 0xcf3e, 0xcf51, 0xcf52, 0xcf58, 0xcf5a, 0xcf5b, 0xcf5e, 0xcf61, 0xcf62, 0xcf63, 0xcf65, 0xcf6a, - 0xcf6e, 0xcf7d, 0xcf7f, 0xcf96, 0xcfaa, 0xcfae, 0xcfaf, 0xcfb1, - 0xcfb3, 0xcfca, 0xcfd1, 0xcfd4, 0xcfdd, 0xd006, 0xd00e, 0xd038, - 0xd045, 0xd0d5, 0xd12a, 0xd12b, 0xd12c, 0xd12d, 0xd12e, 0xd163, - 0xd171, 0xd17d, 0xd1d7, 0xd1dc, 0xd1ee, 0xd2af, 0xd3c1, 0xd403, - 0xd444, 0xd593, 0xd6ac, 0xd78c + 0xcf6e, 0xcf77, 0xcf7d, 0xcf7f, 0xcf96, 0xcfaa, 0xcfae, 0xcfaf, + 0xcfb1, 0xcfb3, 0xcfca, 0xcfd1, 0xcfd4, 0xcfdd, 0xd006, 0xd00e, + 0xd038, 0xd045, 0xd0d5, 0xd12a, 0xd12b, 0xd12c, 0xd12d, 0xd12e, + 0xd163, 0xd171, 0xd17d, 0xd1d7, 0xd1dc, 0xd1ee, 0xd2af, 0xd3c1, + 0xd403, 0xd444, 0xd593, 0xd6ac, 0xd78c }; /*Collect the unicode lists and glyph_id offsets*/ @@ -12457,7 +12472,7 @@ static const lv_font_fmt_txt_cmap_t cmaps[] = }, { .range_start = 8470, .range_length = 55181, .glyph_id_start = 1017, - .unicode_list = unicode_list_12, .glyph_id_ofs_list = NULL, .list_length = 76, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + .unicode_list = unicode_list_12, .glyph_id_ofs_list = NULL, .list_length = 77, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY } }; @@ -12605,7 +12620,7 @@ static const uint8_t kern_left_class_mapping[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0 }; /*Map glyph_ids to kern right classes*/ @@ -12747,7 +12762,7 @@ static const uint8_t kern_right_class_mapping[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0 }; /*Kern values between classes*/ diff --git a/examples/companion_radio/ui-lvgl/fonts/ui_font_20.c b/examples/companion_radio/ui-lvgl/fonts/ui_font_20.c index 65bce367..4573a645 100644 --- a/examples/companion_radio/ui-lvgl/fonts/ui_font_20.c +++ b/examples/companion_radio/ui-lvgl/fonts/ui_font_20.c @@ -1,7 +1,7 @@ /******************************************************************************* * Size: 20 px * Bpp: 4 - * Opts: --bpp 4 --size 20 --no-compress --force-fast-kern-format --font /var/folders/1d/dgkmygls6x5gsb16pbn2mwlr0000gn/T//meshcore-ui-fonts/NotoSans-Medium.ttf -r 0x20-0x7E,0xA0-0x24F,0x370-0x3FF,0x400-0x52F,0x1E80-0x1E85,0x1E9E,0x1EF2-0x1EF3,0x2010-0x2027,0x2030,0x2039-0x203A,0x20A4-0x20BF,0x2116,0x2122 --font /var/folders/1d/dgkmygls6x5gsb16pbn2mwlr0000gn/T//meshcore-ui-fonts/fa.woff -r 63145,61572,62679,61568,62745,61463,62194,61612,61445,62073,61632,61774,61476,62405,61441,61448,61451,61452,61453,61457,61459,61461,61465,61468,61473,61478,61479,61480,61502,61507,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61550,61552,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61641,61664,61671,61674,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62087,62099,62212,62189,62810,63426,63650 --format lvgl --lv-include lvgl.h --lv-font-name ui_font_20 -o /Users/jakub/Documents/MeshCore/MeshCore/examples/companion_radio/ui-lvgl/fonts/ui_font_20.c + * Opts: --bpp 4 --size 20 --no-compress --force-fast-kern-format --font /var/folders/1d/dgkmygls6x5gsb16pbn2mwlr0000gn/T//meshcore-ui-fonts/NotoSans-Medium.ttf -r 0x20-0x7E,0xA0-0x24F,0x370-0x3FF,0x400-0x52F,0x1E80-0x1E85,0x1E9E,0x1EF2-0x1EF3,0x2010-0x2027,0x2030,0x2039-0x203A,0x20A4-0x20BF,0x2116,0x2122 --font /var/folders/1d/dgkmygls6x5gsb16pbn2mwlr0000gn/T//meshcore-ui-fonts/fa.woff -r 61581,63145,61572,62679,61568,62745,61463,62194,61612,61445,62073,61632,61774,61476,62405,61441,61448,61451,61452,61453,61457,61459,61461,61465,61468,61473,61478,61479,61480,61502,61507,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61550,61552,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61641,61664,61671,61674,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62087,62099,62212,62189,62810,63426,63650 --format lvgl --lv-include lvgl.h --lv-font-name ui_font_20 -o /Users/jakub/Documents/MeshCore/MeshCore/examples/companion_radio/ui-lvgl/fonts/ui_font_20.c ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE @@ -14693,6 +14693,28 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0x36, 0x66, 0x65, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* U+F08D "" */ + 0x5, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb5, 0x0, + 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb0, 0xc, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x0, 0x9f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x90, 0x0, 0x4, + 0xff, 0xff, 0xff, 0xf4, 0x0, 0x0, 0x0, 0x5f, + 0xff, 0xff, 0xff, 0x50, 0x0, 0x0, 0x6, 0xff, + 0xff, 0xff, 0xf6, 0x0, 0x0, 0x0, 0x8f, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x0, 0xb, 0xff, 0xff, + 0xff, 0xfb, 0x0, 0x0, 0x2c, 0xff, 0xff, 0xff, + 0xff, 0xfc, 0x20, 0x1e, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfe, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfa, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfd, 0x0, 0x0, 0x0, 0xcf, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc, 0xfc, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xcf, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0xfc, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9f, 0x90, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + /* U+F093 "" */ 0x0, 0x0, 0x0, 0x0, 0x3, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6f, 0xd1, @@ -16663,41 +16685,42 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { {.bitmap_index = 96355, .adv_w = 320, .box_w = 20, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, {.bitmap_index = 96505, .adv_w = 320, .box_w = 20, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, {.bitmap_index = 96655, .adv_w = 320, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 96865, .adv_w = 320, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 97075, .adv_w = 320, .box_w = 21, .box_h = 21, .ofs_x = -1, .ofs_y = -3}, - {.bitmap_index = 97296, .adv_w = 310, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 97506, .adv_w = 400, .box_w = 25, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97744, .adv_w = 280, .box_w = 18, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 97915, .adv_w = 280, .box_w = 18, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 98104, .adv_w = 280, .box_w = 18, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98275, .adv_w = 280, .box_w = 18, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 98428, .adv_w = 320, .box_w = 20, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 98578, .adv_w = 200, .box_w = 14, .box_h = 21, .ofs_x = -1, .ofs_y = -3}, - {.bitmap_index = 98725, .adv_w = 280, .box_w = 18, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 98914, .adv_w = 280, .box_w = 18, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 99103, .adv_w = 360, .box_w = 23, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 99276, .adv_w = 320, .box_w = 22, .box_h = 21, .ofs_x = -1, .ofs_y = -3}, - {.bitmap_index = 99507, .adv_w = 310, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 99717, .adv_w = 240, .box_w = 15, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 99875, .adv_w = 400, .box_w = 25, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 100113, .adv_w = 400, .box_w = 25, .box_h = 13, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 100276, .adv_w = 400, .box_w = 25, .box_h = 13, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 100439, .adv_w = 400, .box_w = 25, .box_h = 13, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 100602, .adv_w = 400, .box_w = 25, .box_h = 13, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 100765, .adv_w = 400, .box_w = 25, .box_h = 13, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 100928, .adv_w = 360, .box_w = 23, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 101147, .adv_w = 400, .box_w = 26, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 101368, .adv_w = 280, .box_w = 16, .box_h = 21, .ofs_x = 1, .ofs_y = -3}, - {.bitmap_index = 101536, .adv_w = 280, .box_w = 18, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 101725, .adv_w = 280, .box_w = 18, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 101914, .adv_w = 320, .box_w = 21, .box_h = 21, .ofs_x = -1, .ofs_y = -3}, - {.bitmap_index = 102135, .adv_w = 240, .box_w = 15, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 102293, .adv_w = 320, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 102503, .adv_w = 400, .box_w = 25, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 102766, .adv_w = 400, .box_w = 25, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 102954, .adv_w = 320, .box_w = 21, .box_h = 16, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 103122, .adv_w = 240, .box_w = 15, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 103280, .adv_w = 322, .box_w = 21, .box_h = 13, .ofs_x = 0, .ofs_y = 1} + {.bitmap_index = 96865, .adv_w = 240, .box_w = 15, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 97023, .adv_w = 320, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 97233, .adv_w = 320, .box_w = 21, .box_h = 21, .ofs_x = -1, .ofs_y = -3}, + {.bitmap_index = 97454, .adv_w = 310, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 97664, .adv_w = 400, .box_w = 25, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97902, .adv_w = 280, .box_w = 18, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98073, .adv_w = 280, .box_w = 18, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 98262, .adv_w = 280, .box_w = 18, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98433, .adv_w = 280, .box_w = 18, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 98586, .adv_w = 320, .box_w = 20, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 98736, .adv_w = 200, .box_w = 14, .box_h = 21, .ofs_x = -1, .ofs_y = -3}, + {.bitmap_index = 98883, .adv_w = 280, .box_w = 18, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 99072, .adv_w = 280, .box_w = 18, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 99261, .adv_w = 360, .box_w = 23, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 99434, .adv_w = 320, .box_w = 22, .box_h = 21, .ofs_x = -1, .ofs_y = -3}, + {.bitmap_index = 99665, .adv_w = 310, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 99875, .adv_w = 240, .box_w = 15, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 100033, .adv_w = 400, .box_w = 25, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100271, .adv_w = 400, .box_w = 25, .box_h = 13, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 100434, .adv_w = 400, .box_w = 25, .box_h = 13, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 100597, .adv_w = 400, .box_w = 25, .box_h = 13, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 100760, .adv_w = 400, .box_w = 25, .box_h = 13, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 100923, .adv_w = 400, .box_w = 25, .box_h = 13, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 101086, .adv_w = 360, .box_w = 23, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 101305, .adv_w = 400, .box_w = 26, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 101526, .adv_w = 280, .box_w = 16, .box_h = 21, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 101694, .adv_w = 280, .box_w = 18, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 101883, .adv_w = 280, .box_w = 18, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 102072, .adv_w = 320, .box_w = 21, .box_h = 21, .ofs_x = -1, .ofs_y = -3}, + {.bitmap_index = 102293, .adv_w = 240, .box_w = 15, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 102451, .adv_w = 320, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 102661, .adv_w = 400, .box_w = 25, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 102924, .adv_w = 400, .box_w = 25, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 103112, .adv_w = 320, .box_w = 21, .box_h = 16, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 103280, .adv_w = 240, .box_w = 15, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 103438, .adv_w = 322, .box_w = 21, .box_h = 13, .ofs_x = 0, .ofs_y = 1} }; /*--------------------- @@ -16726,11 +16749,11 @@ static const uint16_t unicode_list_12[] = { 0xcf10, 0xcf11, 0xcf12, 0xcf28, 0xcf2d, 0xcf32, 0xcf35, 0xcf36, 0xcf37, 0xcf3b, 0xcf3c, 0xcf3d, 0xcf3e, 0xcf51, 0xcf52, 0xcf58, 0xcf5a, 0xcf5b, 0xcf5e, 0xcf61, 0xcf62, 0xcf63, 0xcf65, 0xcf6a, - 0xcf6e, 0xcf7d, 0xcf7f, 0xcf96, 0xcfaa, 0xcfae, 0xcfaf, 0xcfb1, - 0xcfb3, 0xcfca, 0xcfd1, 0xcfd4, 0xcfdd, 0xd006, 0xd00e, 0xd038, - 0xd045, 0xd0d5, 0xd12a, 0xd12b, 0xd12c, 0xd12d, 0xd12e, 0xd163, - 0xd171, 0xd17d, 0xd1d7, 0xd1dc, 0xd1ee, 0xd2af, 0xd3c1, 0xd403, - 0xd444, 0xd593, 0xd6ac, 0xd78c + 0xcf6e, 0xcf77, 0xcf7d, 0xcf7f, 0xcf96, 0xcfaa, 0xcfae, 0xcfaf, + 0xcfb1, 0xcfb3, 0xcfca, 0xcfd1, 0xcfd4, 0xcfdd, 0xd006, 0xd00e, + 0xd038, 0xd045, 0xd0d5, 0xd12a, 0xd12b, 0xd12c, 0xd12d, 0xd12e, + 0xd163, 0xd171, 0xd17d, 0xd1d7, 0xd1dc, 0xd1ee, 0xd2af, 0xd3c1, + 0xd403, 0xd444, 0xd593, 0xd6ac, 0xd78c }; /*Collect the unicode lists and glyph_id offsets*/ @@ -16786,7 +16809,7 @@ static const lv_font_fmt_txt_cmap_t cmaps[] = }, { .range_start = 8470, .range_length = 55181, .glyph_id_start = 1017, - .unicode_list = unicode_list_12, .glyph_id_ofs_list = NULL, .list_length = 76, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + .unicode_list = unicode_list_12, .glyph_id_ofs_list = NULL, .list_length = 77, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY } }; @@ -16934,7 +16957,7 @@ static const uint8_t kern_left_class_mapping[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0 }; /*Map glyph_ids to kern right classes*/ @@ -17076,7 +17099,7 @@ static const uint8_t kern_right_class_mapping[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0 }; /*Kern values between classes*/ diff --git a/examples/companion_radio/ui-new/BatteryCurveScreen.h b/examples/companion_radio/ui-new/BatteryCurveScreen.h new file mode 100644 index 00000000..255d6c4b --- /dev/null +++ b/examples/companion_radio/ui-new/BatteryCurveScreen.h @@ -0,0 +1,80 @@ +#pragma once +#include "InfoKit.h" +#include "../ui-core/Battery.h" +// Settings › System › Battery curve: the cell voltage at 0, 10, ... 100 % +// (NodePrefs::batt_curve_mv, ui-core/Battery.h). Left/Right move the selected +// point 10 mV, kept between its neighbours; the first change copies the +// built-in curve in, Reset goes back to it. "Now" shows the cell as read, to +// set a point against. Saved on the way out. +// Included by UITask.cpp after AutoAdvertScreen.h. + +class BatteryCurveScreen : public UIScreen { + UITask* _task; + NodePrefs* _prefs; + int _sel = 1, _scroll = 0; + bool _dirty = false; + + static const int PTS = battery::CURVE_PTS; + static const int ROWS = 1 + PTS + 1; // Now, the points, Reset + static const int STEP_MV = 10; + + void nudge(int i, int d) { + uint16_t* c = _prefs->batt_curve_mv; + if (!battery::validCurve(c)) + for (int k = 0; k < PTS; k++) c[k] = (uint16_t)battery::builtinMvAt(k); + const int lo = i > 0 ? c[i - 1] + STEP_MV : battery::CURVE_MIN_MV; + const int hi = i < PTS - 1 ? c[i + 1] - STEP_MV : battery::CURVE_MAX_MV; + c[i] = (uint16_t)constrain((int)c[i] + d * STEP_MV, lo, hi); + _dirty = true; + } + +public: + BatteryCurveScreen(UITask* task, NodePrefs* prefs) : _task(task), _prefs(prefs) {} + + void onShow() override { _sel = 1; _scroll = 0; _dirty = false; } + + int render(DisplayDriver& display) override { + display.setTextSize(1); + display.setColor(DisplayDriver::LIGHT); + drawScreenHeader(display, "Battery curve"); + const int mv = _task->getBattMilliVolts(); + const bool custom = _prefs && battery::validCurve(_prefs->batt_curve_mv); + drawList(display, ROWS, _sel, _scroll, [&](int i, int y, bool sel, int reserve) { + drawRowSelection(display, y, sel, reserve); + char l[12], v[20]; + if (i == 0) { + strcpy(l, "Now"); + snprintf(v, sizeof(v), "%d mV %d%%", mv, battery::rawPercent(mv)); + } else if (i <= PTS) { + snprintf(l, sizeof(l), "%d%%", (i - 1) * 10); + snprintf(v, sizeof(v), "%d mV", battery::curveMvAt(i - 1)); + } else { + strcpy(l, "Reset"); + strcpy(v, custom ? "" : "LiPo"); // the built-in curve is the one in use + } + info::valueRow(display, y, l, v, sel, reserve); + }); + return 1000; // "Now" follows the cell + } + + bool handleInput(char c) override { + if (c == KEY_CANCEL) { + _task->savePrefsIfDirty(_dirty); + _task->gotoSettingsScreen(); + return true; + } + if (c == KEY_UP) { if (_sel > 0) _sel--; return true; } + if (c == KEY_DOWN) { if (_sel < ROWS - 1) _sel++; return true; } + if (!_prefs) return false; + if (_sel >= 1 && _sel <= PTS && (keyIsNext(c) || keyIsPrev(c))) { + nudge(_sel - 1, keyIsNext(c) ? 1 : -1); + return true; + } + if (_sel == ROWS - 1 && c == KEY_ENTER && battery::validCurve(_prefs->batt_curve_mv)) { + memset(_prefs->batt_curve_mv, 0, sizeof(_prefs->batt_curve_mv)); + _dirty = true; + return true; + } + return false; + } +}; diff --git a/examples/companion_radio/ui-new/SettingsScreen.h b/examples/companion_radio/ui-new/SettingsScreen.h index 2170f024..8b9f4651 100644 --- a/examples/companion_radio/ui-new/SettingsScreen.h +++ b/examples/companion_radio/ui-new/SettingsScreen.h @@ -9,6 +9,7 @@ #include "AccordionList.h" #include "PopupMenu.h" // scope list management's per-row action menu #include "InfoKit.h" // value / switch rows +#include "../ui-core/Battery.h" // the Battery curve row class SettingsScreen : public UIScreen { UITask* _task; @@ -49,6 +50,7 @@ class SettingsScreen : public UIScreen { SECTION_SYSTEM, DEVICE_NAME, SCHEMA_SYSTEM, // power, units + BATT_CURVE, REBOOT, // Keyboard section SECTION_KEYBOARD, @@ -78,6 +80,7 @@ class SettingsScreen : public UIScreen { int _selected = 0; // SettingItem under the cursor, resolved per input/render int _reserve = 0; // right-edge px reserved for the scrollbar (0 when list fits) bool _dirty = false; + bool _keep_place = false; // set when opening a screen from a row, so Back lands on it AccordionList _acc; static const int NUM_SECTIONS = 8; @@ -512,6 +515,8 @@ class SettingsScreen : public UIScreen { sw("Lock PIN", _task->passwordLockEnabled()); } else if (item == DEVICE_NAME) { val("Name", the_mesh.getNodeName()); + } else if (item == BATT_CURVE) { + val("Batt curve", p && battery::validCurve(p->batt_curve_mv) ? "Custom" : "LiPo"); } else if (item == REBOOT) { display.print("Reboot"); // action row: Enter reboots this device } else if (item == KEYBOARD_TYPE) { @@ -629,6 +634,8 @@ public: void onShow() override { + const bool keep = _keep_place; // back from a screen opened here: same row + _keep_place = false; _dirty = false; _edit_name = false; _scope_mgmt_active = false; @@ -638,7 +645,7 @@ public: _prune_confirm.active = false; _edit_lock_pass = false; _lock_pass_first[0] = '\0'; - resetList(); + if (!keep) resetList(); _editor.freq.active = false; } @@ -981,6 +988,12 @@ public: _scope_mgmt_scroll = 0; return true; } + if (_selected == BATT_CURVE && enter) { + _keep_place = true; // back from it to this row, not a folded list + _task->savePrefsIfDirty(_dirty); + _task->gotoBatteryCurve(); + return true; + } if (_selected == REBOOT && enter) { _task->showAlert("Rebooting...", 800); _task->shutdown(true); // flushes prefs/RTC/contacts/trail, then reboots -- single choke point diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index c5f45347..39aaf213 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -177,6 +177,7 @@ static void fmtAlt(char* buf, int n, float meters, bool imperial) { #include "NearbyScreen.h" #include "DashboardConfigScreen.h" #include "AutoAdvertScreen.h" +#include "BatteryCurveScreen.h" #include "LiveShareScreen.h" #include "LocatorScreen.h" #include "TrailScreen.h" @@ -1623,6 +1624,7 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* no _sensors = sensors; _node_prefs = node_prefs; _kb.prefs = node_prefs; + if (node_prefs) battery::useCurve(node_prefs->batt_curve_mv); // Settings > Battery curve uint32_t aoff = autoOffMillis(); _auto_off = millis() + (aoff > 0 ? aoff : AUTO_OFF_MILLIS); @@ -1719,6 +1721,7 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* no nearby_screen = new NearbyScreen(this); dashboard_config = new DashboardConfigScreen(this, node_prefs); auto_advert_screen = new AutoAdvertScreen(this, node_prefs); + batt_curve_screen = new BatteryCurveScreen(this, node_prefs); live_share_screen = new LiveShareScreen(this, node_prefs); locator_screen = new LocatorScreen(this, node_prefs); trail_screen = new TrailScreen(this, &_core->trail.store()); @@ -1853,6 +1856,7 @@ void UITask::gotoMapScreen() { void UITask::gotoLocatorScreen() { setCurrScreen(locator_screen); } void UITask::gotoAutoAdvertScreen() { setCurrScreen(auto_advert_screen); } +void UITask::gotoBatteryCurve() { setCurrScreen(batt_curve_screen); } bool UITask::startPing(const uint8_t* pub_key) { PingEngine::StartResult r = _core->ping.start(pub_key); diff --git a/examples/companion_radio/ui-new/UITask.h b/examples/companion_radio/ui-new/UITask.h index 4e01d66b..e4656dd6 100644 --- a/examples/companion_radio/ui-new/UITask.h +++ b/examples/companion_radio/ui-new/UITask.h @@ -112,6 +112,7 @@ class UITask : public UITaskBase, public UiCoreHost { UIScreen* nearby_screen = nullptr; UIScreen* dashboard_config = nullptr; UIScreen* auto_advert_screen = nullptr; + UIScreen* batt_curve_screen = nullptr; UIScreen* live_share_screen = nullptr; UIScreen* locator_screen = nullptr; UIScreen* trail_screen = nullptr; @@ -287,6 +288,7 @@ public: void gotoNearbyScreen(); void gotoDashboardConfig(); void gotoAutoAdvertScreen(); + void gotoBatteryCurve(); // Settings > System > Battery curve void gotoLiveShareScreen(); // Live share session control (ui-core/LiveShareEngine.h): restart = new // session (re-announce + fresh clock); clock-only = changed "Stop after".