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 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-10-02 11:25:58 +02:00
co-authored by Claude Opus 5.5
parent 1166ea8dde
commit 61c75946f6
21 changed files with 702 additions and 227 deletions
+9
View File
@@ -1,6 +1,7 @@
#include <Arduino.h>
#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 <target.h> // 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
+11 -2
View File
@@ -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).");
+77 -26
View File
@@ -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 <stdint.h>
@@ -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;
@@ -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
}
@@ -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 },
};
@@ -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);
@@ -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.
+59 -10
View File
@@ -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);
}
+5 -2
View File
@@ -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 : "?");
}
+2 -1
View File
@@ -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
+14 -3
View File
@@ -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; }
+7 -2
View File
@@ -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;
@@ -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
@@ -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*/
@@ -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*/
@@ -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*/
@@ -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*/
@@ -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;
}
};
@@ -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
@@ -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);
+2
View File
@@ -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".