From 76e96f7eaaba3a1cb656fcd73e927e044cf2a84a Mon Sep 17 00:00:00 2001 From: Jakub <106778416+MarekZegare4@users.noreply.github.com> Date: Wed, 14 Oct 2026 22:55:47 +0200 Subject: [PATCH] feat(l2): light theme Settings > Display > Theme: Dark / Light (NVS mc_ui/light). The colour tokens are set once before anything is built, so a change restarts the device. Text on an accent fill is the new ON_ACCENT (it was BG, white in the light theme); each accent has a deeper hand-picked light variant that reads on white and takes white text. The map's empty-tile fill and grid and the areas' outlines follow the theme too. Co-Authored-By: Claude Opus 5.5 --- docs/solo/settings.md | 3 +- .../companion_radio/ui-lvgl/ClockScreen.h | 4 +- .../companion_radio/ui-lvgl/DeviceScreen.h | 4 +- examples/companion_radio/ui-lvgl/HomeScreen.h | 6 +-- examples/companion_radio/ui-lvgl/LvglPort.h | 3 ++ examples/companion_radio/ui-lvgl/MapAreas.h | 2 +- examples/companion_radio/ui-lvgl/MapScreen.h | 6 +-- examples/companion_radio/ui-lvgl/QuickPanel.h | 2 +- .../companion_radio/ui-lvgl/SettingsPages.h | 12 ++++- .../companion_radio/ui-lvgl/SoundScreen.h | 4 +- .../companion_radio/ui-lvgl/StorageScreen.h | 2 +- examples/companion_radio/ui-lvgl/Theme.h | 53 ++++++++++++------- examples/companion_radio/ui-lvgl/ThreadView.h | 16 +++--- examples/companion_radio/ui-lvgl/UITask.cpp | 1 + examples/companion_radio/ui-lvgl/Widgets.h | 14 ++--- 15 files changed, 82 insertions(+), 50 deletions(-) diff --git a/docs/solo/settings.md b/docs/solo/settings.md index 03fef91a..193cf44f 100644 --- a/docs/solo/settings.md +++ b/docs/solo/settings.md @@ -91,7 +91,8 @@ if your mesh agrees on it. > [!NOTE] > **Wio Tracker L2:** one list of pages: > -> - **Device**: Display (including the lock and **Tap to wake**), Home apps, +> - **Device**: Display (including the lock, **Tap to wake**, the **Theme**, +> dark or light, which restarts the device, and the accent colour), Home apps, > Power (battery, GPS, and the **Battery curve** as a chart whose points you > drag), Sound (with the melody editor), Keyboard, Messages > & contacts. diff --git a/examples/companion_radio/ui-lvgl/ClockScreen.h b/examples/companion_radio/ui-lvgl/ClockScreen.h index 86ed592d..21a08274 100644 --- a/examples/companion_radio/ui-lvgl/ClockScreen.h +++ b/examples/companion_radio/ui-lvgl/ClockScreen.h @@ -68,14 +68,14 @@ static void onCalendarDraw(lv_event_t* e) { } snprintf(buf, sizeof(buf), "%d", day); td.text = buf; - td.color = lv_color_hex(today ? theme::BG : k % 7 >= 5 ? theme::TEXT_MUTED : theme::TEXT); + td.color = lv_color_hex(today ? theme::ON_ACCENT : k % 7 >= 5 ? theme::TEXT_MUTED : theme::TEXT); lv_area_t la = { cx, cy + (ch - fh) / 2, cx + cw - 1, cy + (ch + fh) / 2 }; lv_draw_label(layer, &td, &la); if (s_cal_marks & (1UL << (day - 1))) { // under the number lv_draw_rect_dsc_t md; lv_draw_rect_dsc_init(&md); md.radius = 1; - md.bg_color = lv_color_hex(today ? theme::BG : theme::ACCENT); + md.bg_color = lv_color_hex(today ? theme::ON_ACCENT : theme::ACCENT); lv_area_t ma = { cx + cw / 2 - 6, cy + ch - 2, cx + cw / 2 + 6, cy + ch - 1 }; lv_draw_rect(layer, &md, &ma); } diff --git a/examples/companion_radio/ui-lvgl/DeviceScreen.h b/examples/companion_radio/ui-lvgl/DeviceScreen.h index 3ca747da..165dcf37 100644 --- a/examples/companion_radio/ui-lvgl/DeviceScreen.h +++ b/examples/companion_radio/ui-lvgl/DeviceScreen.h @@ -404,12 +404,12 @@ void UITask::accentRow(lv_obj_t* body) { // a row of a group: the label over t lv_obj_t* sw = lv_button_create(row); lv_obj_set_size(sw, 32, 32); lv_obj_set_style_radius(sw, LV_RADIUS_CIRCLE, 0); - lv_obj_set_style_bg_color(sw, lv_color_hex(theme::ACCENTS[i].col), 0); + lv_obj_set_style_bg_color(sw, lv_color_hex(theme::s_light ? theme::ACCENTS[i].light : theme::ACCENTS[i].col), 0); bool cur = i == theme::s_accent; lv_obj_set_style_border_width(sw, cur ? 3 : 0, 0); lv_obj_set_style_border_color(sw, lv_color_hex(theme::TEXT), 0); lv_obj_add_event_cb(sw, onAccent, LV_EVENT_CLICKED, (void*)(uintptr_t)i); - if (cur) lv_obj_center(label(sw, LV_SYMBOL_OK, THEME_FONT_SMALL, theme::BG)); + if (cur) lv_obj_center(label(sw, LV_SYMBOL_OK, THEME_FONT_SMALL, theme::ON_ACCENT)); } } diff --git a/examples/companion_radio/ui-lvgl/HomeScreen.h b/examples/companion_radio/ui-lvgl/HomeScreen.h index 15d1a1ce..7d36e8e9 100644 --- a/examples/companion_radio/ui-lvgl/HomeScreen.h +++ b/examples/companion_radio/ui-lvgl/HomeScreen.h @@ -372,7 +372,7 @@ static void editTile(lv_obj_t* box, int pos) { lv_obj_set_style_bg_opa(b, LV_OPA_COVER, 0); lv_obj_set_style_bg_color(b, lv_color_hex(on ? theme::SURFACE_2 : theme::ACCENT), 0); lv_obj_align(b, LV_ALIGN_TOP_RIGHT, 2, -2); - lv_obj_center(label(b, on ? LV_SYMBOL_MINUS : LV_SYMBOL_PLUS, THEME_FONT_SMALL, on ? theme::TEXT : theme::BG)); + lv_obj_center(label(b, on ? LV_SYMBOL_MINUS : LV_SYMBOL_PLUS, THEME_FONT_SMALL, on ? theme::TEXT : theme::ON_ACCENT)); } } // namespace home @@ -479,7 +479,7 @@ void UITask::buildHome() { lv_obj_set_style_bg_color(b, lv_color_hex(theme::ACCENT), 0); lv_obj_align(b, LV_ALIGN_BOTTOM_RIGHT, 0, 24); lv_obj_add_event_cb(b, home::onEditDone, LV_EVENT_CLICKED, NULL); - lv_obj_center(label(b, "Done", THEME_FONT_SMALL, theme::BG)); + lv_obj_center(label(b, "Done", THEME_FONT_SMALL, theme::ON_ACCENT)); } setHomePage(home::s_page); } @@ -635,7 +635,7 @@ void UITask::buildHomeMap(lv_obj_t* box) { using namespace home::mini; lv_obj_set_layout(box, LV_LAYOUT_NONE); s_area = lv_obj_create(box); - styleSurface(s_area, 0x1A1A1E); // unloaded / missing tiles + styleSurface(s_area, theme::SURFACE); // unloaded / missing tiles lv_obj_set_size(s_area, LV_PCT(100), LV_PCT(100)); lv_obj_set_style_radius(s_area, theme::RADIUS, 0); lv_obj_set_style_clip_corner(s_area, true, 0); diff --git a/examples/companion_radio/ui-lvgl/LvglPort.h b/examples/companion_radio/ui-lvgl/LvglPort.h index 91aaea96..a3d8fc64 100644 --- a/examples/companion_radio/ui-lvgl/LvglPort.h +++ b/examples/companion_radio/ui-lvgl/LvglPort.h @@ -1010,6 +1010,9 @@ static void setVectorOn(bool on) { nvs::putBool("mc_ui", "vector", on); } // Accent colour (Settings > Display): an index into theme::ACCENTS. static int loadAccent() { return nvs::getU8("mc_ui", "accent", 0); } static void saveAccent(int idx) { nvs::putU8("mc_ui", "accent", idx); } +// Settings > Display > Theme: light (else dark), applied at start. +static bool loadLight() { return nvs::getU8("mc_ui", "light", 0) != 0; } +static void saveLight(bool on) { nvs::putU8("mc_ui", "light", on ? 1 : 0); } // Settings > Storage > Kept per conversation (an index into histstore::KEEP). static int loadHistKeep() { return nvs::getI8("mc_ui", "hkeep", -1); } static void saveHistKeep(int idx) { nvs::putI8("mc_ui", "hkeep", idx); } diff --git a/examples/companion_radio/ui-lvgl/MapAreas.h b/examples/companion_radio/ui-lvgl/MapAreas.h index f6a2bf3d..1f8035e1 100644 --- a/examples/companion_radio/ui-lvgl/MapAreas.h +++ b/examples/companion_radio/ui-lvgl/MapAreas.h @@ -119,7 +119,7 @@ static void drawLayer(lv_event_t* e) { lv_draw_rect_dsc_init(&d); d.bg_opa = LV_OPA_TRANSP; d.border_width = i == s_show ? 2 : 1; - d.border_color = lv_color_hex(i == s_show ? theme::ACCENT : 0x9A958C); + d.border_color = lv_color_hex(i == s_show ? theme::ACCENT : theme::TEXT_MUTED); d.border_opa = LV_OPA_COVER; lv_draw_rect(layer, &d, &r); } diff --git a/examples/companion_radio/ui-lvgl/MapScreen.h b/examples/companion_radio/ui-lvgl/MapScreen.h index 436cbc81..c132a01a 100644 --- a/examples/companion_radio/ui-lvgl/MapScreen.h +++ b/examples/companion_radio/ui-lvgl/MapScreen.h @@ -126,7 +126,7 @@ static void drawGrid(lv_event_t* e) { lv_obj_get_coords(o, &a); lv_draw_line_dsc_t d; lv_draw_line_dsc_init(&d); - d.color = lv_color_hex(0x3C3C46); + d.color = lv_color_hex(theme::SURFACE_2); d.width = 1; lv_layer_t* layer = lv_event_get_layer(e); int w = lv_area_get_width(&a), h = lv_area_get_height(&a); @@ -555,7 +555,7 @@ static void drawMarks(lv_event_t* e) { lv_draw_label_dsc_t bl; lv_draw_label_dsc_init(&bl); bl.font = THEME_FONT_SMALL; - bl.color = lv_color_hex(theme::BG); + bl.color = lv_color_hex(theme::ON_ACCENT); bl.align = LV_TEXT_ALIGN_CENTER; for (int k = 0; k < s_mark_count; k++) { const Mark& m = s_marks[k]; @@ -759,7 +759,7 @@ void UITask::buildMap() { lv_obj_set_layout(body, LV_LAYOUT_NONE); lv_obj_set_style_pad_all(body, 0, 0); lv_obj_remove_flag(body, LV_OBJ_FLAG_SCROLLABLE); - lv_obj_set_style_bg_color(body, lv_color_hex(0x1A1A1E), 0); // unloaded / missing tiles + lv_obj_set_style_bg_color(body, lv_color_hex(theme::SURFACE), 0); // unloaded / missing tiles lv_obj_set_style_bg_opa(body, LV_OPA_COVER, 0); lv_obj_add_event_cb(body, mapview::drawGrid, LV_EVENT_DRAW_MAIN_END, &mapview::s_grid); lv_obj_add_event_cb(body, mapview::tiledCovers, LV_EVENT_COVER_CHECK, &mapview::s_grid); diff --git a/examples/companion_radio/ui-lvgl/QuickPanel.h b/examples/companion_radio/ui-lvgl/QuickPanel.h index 4b774b81..9a4bcef8 100644 --- a/examples/companion_radio/ui-lvgl/QuickPanel.h +++ b/examples/companion_radio/ui-lvgl/QuickPanel.h @@ -102,7 +102,7 @@ static void onPagesScrolled(lv_event_t* e) { // A tile's look: on in the accent with dark text, off on the surface; // `dim`: nothing to switch on this device. static void tileSet(int t, const char* icon, const char* cap, bool on, bool dim = false) { - const uint32_t fg = on ? theme::BG : dim ? theme::TEXT_MUTED : theme::TEXT; + const uint32_t fg = on ? theme::ON_ACCENT : dim ? theme::TEXT_MUTED : theme::TEXT; const uint8_t look = 1 | (on ? 2 : 0); if (s_look[t] != look) { // LVGL restyles, and redraws, on every set (the refresh is each second) s_look[t] = look; diff --git a/examples/companion_radio/ui-lvgl/SettingsPages.h b/examples/companion_radio/ui-lvgl/SettingsPages.h index 71c665c5..ed0c3b90 100644 --- a/examples/companion_radio/ui-lvgl/SettingsPages.h +++ b/examples/companion_radio/ui-lvgl/SettingsPages.h @@ -127,6 +127,14 @@ void UITask::setBrightnessPct(uint8_t pct, bool save) { if (save) prefsSave(); } +// Every screen is built in the theme's colours: a new one starts afresh. +static void onThemeChoice(lv_event_t* e) { + const bool light = choiceSelected((lv_obj_t*)lv_event_get_target(e)) == 1; + if (light == theme::s_light) return; + lvport::saveLight(light); + restartScreen(light ? "Starting in the light theme." : "Starting in the dark theme."); +} + static void onTapWake(lv_event_t* e) { s_ui->setTapWake(lv_obj_has_state((lv_obj_t*)lv_event_get_target(e), LV_STATE_CHECKED)); } @@ -158,7 +166,9 @@ void UITask::buildSchemaSettings() { g = group(body, "LOCK"); schemaRow(g, SETTING(auto_lock)); listRow(g, "Screen PIN", pinSet() ? "On - asked when the screen wakes" : "Off", onPinSetup, NULL); - accentRow(group(body, "LOOK")); // DeviceScreen.h + g = group(body, "LOOK"); + choiceRow(g, "Theme", "Changing it restarts the device", "Dark\nLight", theme::s_light ? 1 : 0, onThemeChoice); + accentRow(g); // DeviceScreen.h return; } case PG_POWER: { diff --git a/examples/companion_radio/ui-lvgl/SoundScreen.h b/examples/companion_radio/ui-lvgl/SoundScreen.h index eeb11d35..92654ded 100644 --- a/examples/companion_radio/ui-lvgl/SoundScreen.h +++ b/examples/companion_radio/ui-lvgl/SoundScreen.h @@ -39,8 +39,8 @@ static void styleCell(int i, bool sel) { const bool hl = i == s_hl; lv_obj_set_style_bg_color(s_cells[i], lv_color_hex(hl ? theme::ACCENT : theme::SURFACE), 0); lv_obj_set_style_border_width(s_cells[i], sel ? 2 : 0, 0); - setTextColor(lv_obj_get_child(s_cells[i], 0), hl ? theme::BG : theme::TEXT); - setTextColor(lv_obj_get_child(s_cells[i], 1), hl ? theme::BG : theme::TEXT_MUTED); + setTextColor(lv_obj_get_child(s_cells[i], 0), hl ? theme::ON_ACCENT : theme::TEXT); + setTextColor(lv_obj_get_child(s_cells[i], 1), hl ? theme::ON_ACCENT : theme::TEXT_MUTED); } // Moves the "sounding" light to note `idx` (-1: none). diff --git a/examples/companion_radio/ui-lvgl/StorageScreen.h b/examples/companion_radio/ui-lvgl/StorageScreen.h index 8da53fc3..ab76933d 100644 --- a/examples/companion_radio/ui-lvgl/StorageScreen.h +++ b/examples/companion_radio/ui-lvgl/StorageScreen.h @@ -462,7 +462,7 @@ static void usbPanel(const char* title, const char* text, bool buttons) { lv_obj_set_style_radius(b, theme::RADIUS, 0); lv_obj_set_style_bg_color(b, lv_color_hex(i ? theme::ACCENT : theme::SURFACE_2), 0); lv_obj_add_event_cb(b, onUsbTap, LV_EVENT_CLICKED, i ? (void*)1 : nullptr); - lv_obj_center(label(b, i ? "USB drive" : "Keep card", THEME_FONT_BODY, i ? theme::BG : theme::TEXT)); + lv_obj_center(label(b, i ? "USB drive" : "Keep card", THEME_FONT_BODY, i ? theme::ON_ACCENT : theme::TEXT)); } } diff --git a/examples/companion_radio/ui-lvgl/Theme.h b/examples/companion_radio/ui-lvgl/Theme.h index 6da66eb1..3fa50fb4 100644 --- a/examples/companion_radio/ui-lvgl/Theme.h +++ b/examples/companion_radio/ui-lvgl/Theme.h @@ -4,25 +4,31 @@ // // The accent (amber by default; Settings > Display > Accent colour) // on near-black, soft corners. The accent means one of three things: -// - ACCENT fill, dark text: the primary action of a screen or popup +// - ACCENT fill, ON_ACCENT text: the primary action of a screen or popup // (Download, Install, Save, Go) -- stylePrimary() in UITask.cpp -- and // something selected / on (a tab, a chip, a segment, a mode that is // running, own bubbles) -- styleSelected(); // - ACCENT text or icon: a name, a count, a background mode, a value. // No accent mixed toward black for "selected": it came out brown. // Everything else is BG / SURFACE / SURFACE_2 with TEXT or TEXT_MUTED. +// +// Two themes, dark (the default) and light (Settings > Display > Theme). The +// colours are set once, before anything is built (setLight()), so changing +// the theme restarts the device. #include // lv_theme_t's fields, to layer a theme namespace theme { - // Colours (0xRRGGBB) - static const uint32_t BG = 0x0B0B0D; // screen background - static const uint32_t SURFACE = 0x1A1A1F; // cards, rows, bubbles (incoming) - static const uint32_t SURFACE_2 = 0x27272E; // pressed / raised - static uint32_t ACCENT = 0xFFB000; // primary actions, names, badges, modes (setAccent) - static const uint32_t TEXT = 0xF2EEE6; - static const uint32_t TEXT_MUTED= 0x9A958C; - static const uint32_t OK = 0x6FCF6F; // delivered / relayed - static const uint32_t FAIL = 0xE5534B; // not delivered + // Colours (0xRRGGBB), the dark theme's; setLight() sets the light one's. + static uint32_t BG = 0x0B0B0D; // screen background + static uint32_t SURFACE = 0x1A1A1F; // cards, rows, bubbles (incoming) + static uint32_t SURFACE_2 = 0x27272E; // pressed / raised + static uint32_t ACCENT = 0xFFB000; // primary actions, names, badges, modes (setAccent) + static uint32_t ON_ACCENT = 0x0B0B0D; // text and icons on an ACCENT fill + static uint32_t TEXT = 0xF2EEE6; + static uint32_t TEXT_MUTED= 0x9A958C; + static uint32_t OK = 0x6FCF6F; // delivered / relayed + static uint32_t FAIL = 0xE5534B; // not delivered + static bool s_light = false; // Spacing (px) static const int PAD = 8; @@ -67,11 +73,12 @@ namespace theme { #define UI_SYMBOL_SUN "\xEF\x86\x85" // U+F185, quick panel: brightness #define UI_SYMBOL_BULB "\xEF\x83\xAB" // U+F0EB, Flashlight - // Accent choices; the fill is the colour at 42% over the background. - struct Accent { const char* name; uint32_t col; }; + // Accent choices: on the dark theme, and deeper on the light one, to read + // as text on white and take white text on it. + struct Accent { const char* name; uint32_t col, light; }; static const Accent ACCENTS[] = { - { "Amber", 0xFFB000 }, { "Orange", 0xFF7A2E }, { "Coral", 0xFF6B7A }, - { "Violet", 0xB18CFF }, { "Cyan", 0x3CC8E8 }, { "Lime", 0xB5E04A }, + { "Amber", 0xFFB000, 0xC77800 }, { "Orange", 0xFF7A2E, 0xD9561A }, { "Coral", 0xFF6B7A, 0xD9455A }, + { "Violet", 0xB18CFF, 0x7A55E0 }, { "Cyan", 0x3CC8E8, 0x0E8AA8 }, { "Lime", 0xB5E04A, 0x5E8A12 }, }; static const int ACCENT_COUNT = sizeof(ACCENTS) / sizeof(ACCENTS[0]); static int s_accent = 0; @@ -88,11 +95,21 @@ namespace theme { static void setAccent(int idx) { if (idx < 0 || idx >= ACCENT_COUNT) idx = 0; s_accent = idx; - ACCENT = ACCENTS[idx].col; + ACCENT = s_light ? ACCENTS[idx].light : ACCENTS[idx].col; + } + // Before anything is built (the colours are copied into what is). + static void setLight(bool on) { + s_light = on; + if (on) { + BG = 0xF2F0EC; SURFACE = 0xFFFFFF; SURFACE_2 = 0xE2DFD9; + ON_ACCENT = 0xFFFFFF; TEXT = 0x1C1B19; TEXT_MUTED = 0x6E6A62; + OK = 0x2E9A3E; FAIL = 0xD23A32; + } + setAccent(s_accent); } // Over LVGL's default theme, for every widget: a checked button is - // "selected" (the accent, dark text), buttons + // "selected" (the accent, ON_ACCENT text), buttons // have the card radius and give a little under the finger (the default // theme's transitions animate it both ways). Scrollbars are thin and hug // the edge, inside the padding every panel and list has, instead of the @@ -120,7 +137,7 @@ namespace theme { lv_style_set_transform_width(&s_press, -2); lv_style_set_transform_height(&s_press, -2); lv_style_init(&s_checked); - lv_style_set_text_color(&s_checked, lv_color_hex(BG)); + lv_style_set_text_color(&s_checked, lv_color_hex(ON_ACCENT)); lv_style_init(&s_sbar); lv_style_set_width(&s_sbar, 3); lv_style_set_pad_right(&s_sbar, 2); // vertical bar: 2 px off the edge @@ -129,7 +146,7 @@ namespace theme { lv_style_set_pad_left(&s_sbar, RADIUS / 2); } lv_style_set_bg_color(&s_checked, lv_color_hex(ACCENT)); - lv_theme_t* base = lv_theme_default_init(disp, lv_color_hex(ACCENT), lv_color_hex(ACCENT), true, THEME_FONT_BODY); + lv_theme_t* base = lv_theme_default_init(disp, lv_color_hex(ACCENT), lv_color_hex(ACCENT), !s_light, THEME_FONT_BODY); s_theme = *base; lv_theme_set_parent(&s_theme, base); lv_theme_set_apply_cb(&s_theme, applyTheme); diff --git a/examples/companion_radio/ui-lvgl/ThreadView.h b/examples/companion_radio/ui-lvgl/ThreadView.h index c77e4c9b..4476c5af 100644 --- a/examples/companion_radio/ui-lvgl/ThreadView.h +++ b/examples/companion_radio/ui-lvgl/ThreadView.h @@ -289,9 +289,9 @@ static void msgLocButton(lv_obj_t* parent, const char* text, bool save, bool acc lv_obj_set_style_radius(b, theme::RADIUS, 0); lv_obj_set_style_shadow_width(b, 0, 0); // on our own amber bubble the main one goes dark instead - lv_obj_set_style_bg_color(b, lv_color_hex(accent ? (own ? theme::BG : theme::ACCENT) : theme::SURFACE_2), 0); + lv_obj_set_style_bg_color(b, lv_color_hex(accent ? (own ? theme::ON_ACCENT : theme::ACCENT) : theme::SURFACE_2), 0); lv_obj_add_event_cb(b, onMsgLoc, LV_EVENT_CLICKED, (void*)(uintptr_t)(save ? 1 : 0)); - lv_obj_center(label(b, text, THEME_FONT_SMALL, accent ? (own ? theme::ACCENT : theme::BG) : theme::TEXT)); + lv_obj_center(label(b, text, THEME_FONT_SMALL, accent ? (own ? theme::ACCENT : theme::ON_ACCENT) : theme::TEXT)); } // A message's text, wrapped at `max_w` and shrunk to fit. "@[nick]" mentions @@ -300,7 +300,7 @@ static void msgLocButton(lv_obj_t* parent, const char* text, bool save, bool acc // ours (*mentions_me set). Plain text stays a label. static lv_obj_t* msgText(lv_obj_t* parent, const char* text, bool own, int max_w, bool* mentions_me) { *mentions_me = false; - const uint32_t col = own ? theme::BG : theme::TEXT; + const uint32_t col = own ? theme::ON_ACCENT : theme::TEXT; if (!strstr(text, "@[")) { lv_obj_t* t = label(parent, text, THEME_FONT_BODY, col); lv_label_set_long_mode(t, LV_LABEL_LONG_WRAP); @@ -337,7 +337,7 @@ static lv_obj_t* msgText(lv_obj_t* parent, const char* text, bool own, int max_w lv_span_t* sp = lv_spangroup_new_span(sg); lv_span_set_text(sp, part); lv_style_t* st = lv_span_get_style(sp); - lv_style_set_text_color(st, lv_color_hex(own ? theme::BG : theme::ACCENT)); + lv_style_set_text_color(st, lv_color_hex(own ? theme::ON_ACCENT : theme::ACCENT)); if (mine) { lv_style_set_text_decor(st, LV_TEXT_DECOR_UNDERLINE); *mentions_me = true; } p = close + 1; } @@ -377,7 +377,7 @@ static lv_obj_t* bubble(lv_obj_t* list, const char* from, const char* text, bool lv_obj_set_size(b, LV_SIZE_CONTENT, LV_SIZE_CONTENT); lv_obj_set_style_max_width(b, 250, 0); lv_obj_set_style_bg_color(b, lv_color_hex(own ? theme::ACCENT : theme::SURFACE), 0); - const uint32_t muted = own ? theme::mix(theme::BG, theme::ACCENT, 60) : theme::TEXT_MUTED; + const uint32_t muted = own ? theme::mix(theme::ON_ACCENT, theme::ACCENT, 60) : theme::TEXT_MUTED; lv_obj_set_style_border_width(b, 0, 0); lv_obj_set_style_radius(b, theme::RADIUS, 0); lv_obj_set_style_pad_all(b, 6, 0); @@ -394,7 +394,7 @@ static lv_obj_t* bubble(lv_obj_t* list, const char* from, const char* text, bool if (from && from[0]) { lv_obj_t* hdr = flexBox(b, LV_FLEX_FLOW_ROW); lv_obj_set_style_pad_column(hdr, 8, 0); - label(hdr, from, THEME_FONT_SMALL, own ? theme::BG : theme::ACCENT); // names are <= 31 chars: fits the bubble + label(hdr, from, THEME_FONT_SMALL, own ? theme::ON_ACCENT : theme::ACCENT); // names are <= 31 chars: fits the bubble if (meta_in_header) *age_out = label(hdr, meta, THEME_FONT_SMALL, muted); } bool mentions_me; @@ -427,11 +427,11 @@ static lv_obj_t* bubble(lv_obj_t* list, const char* from, const char* text, bool lv_obj_set_style_bg_opa(c, LV_OPA_COVER, 0); lv_obj_set_style_bg_color(c, lv_color_hex(theme::OK), 0); lv_obj_set_style_radius(c, LV_RADIUS_CIRCLE, 0); - lv_obj_t* n = label(c, "", THEME_FONT_SMALL, theme::BG); + lv_obj_t* n = label(c, "", THEME_FONT_SMALL, theme::ON_ACCENT); lv_label_set_text_fmt(n, "%d", relays); lv_obj_center(n); } else if (status && status[0]) { - label(line, status, THEME_FONT_SMALL, own ? theme::BG : status_col); + label(line, status, THEME_FONT_SMALL, own ? theme::ON_ACCENT : status_col); } } return row; diff --git a/examples/companion_radio/ui-lvgl/UITask.cpp b/examples/companion_radio/ui-lvgl/UITask.cpp index 97d1b9ee..a1a9867e 100644 --- a/examples/companion_radio/ui-lvgl/UITask.cpp +++ b/examples/companion_radio/ui-lvgl/UITask.cpp @@ -177,6 +177,7 @@ void UITask::begin(DisplayDriver* display_drv, SensorManager* sensors, NodePrefs return; } theme::setAccent(lvport::loadAccent()); + theme::setLight(lvport::loadLight()); theme::install(lv_display_get_default()); lv_display_add_event_cb(lv_display_get_default(), [](lv_event_t*) { rowsFitPending(); }, LV_EVENT_REFR_START, NULL); diff --git a/examples/companion_radio/ui-lvgl/Widgets.h b/examples/companion_radio/ui-lvgl/Widgets.h index 163ee104..f7022282 100644 --- a/examples/companion_radio/ui-lvgl/Widgets.h +++ b/examples/companion_radio/ui-lvgl/Widgets.h @@ -972,7 +972,7 @@ static lv_obj_t* segmented(lv_obj_t* parent, const char** map, int sel, int w, i lv_obj_set_style_bg_color(m, lv_color_hex(item), LV_PART_ITEMS); lv_obj_set_style_bg_color(m, lv_color_hex(theme::ACCENT), LV_PART_ITEMS | LV_STATE_CHECKED); lv_obj_set_style_text_color(m, lv_color_hex(theme::TEXT), LV_PART_ITEMS); - lv_obj_set_style_text_color(m, lv_color_hex(theme::BG), LV_PART_ITEMS | LV_STATE_CHECKED); + lv_obj_set_style_text_color(m, lv_color_hex(theme::ON_ACCENT), LV_PART_ITEMS | LV_STATE_CHECKED); lv_obj_set_style_text_font(m, THEME_FONT_SMALL, LV_PART_ITEMS); lv_obj_set_style_shadow_width(m, 0, LV_PART_ITEMS); lv_obj_set_style_radius(m, theme::RADIUS, LV_PART_ITEMS); @@ -1016,16 +1016,16 @@ static void onByteCapInsert(lv_event_t* e) { if (ins && strlen(lv_textarea_get_text(ta)) + strlen(ins) > cap) lv_textarea_set_insert_replace(ta, ""); } -// The primary action of a screen or popup: full amber, dark text (Theme.h); +// The primary action of a screen or popup: full accent, ON_ACCENT text (Theme.h); // call after its label is made. static void stylePrimary(lv_obj_t* b) { lv_obj_set_style_bg_color(b, lv_color_hex(theme::ACCENT), 0); for (uint32_t i = 0; i < lv_obj_get_child_count(b); i++) - lv_obj_set_style_text_color(lv_obj_get_child(b, i), lv_color_hex(theme::BG), 0); + lv_obj_set_style_text_color(lv_obj_get_child(b, i), lv_color_hex(theme::ON_ACCENT), 0); } -// Something selected / on (a tab, a chip, a row): the accent with dark text, -// or back to the surface with light text. Every label under it follows. +// Something selected / on (a tab, a chip, a row): the accent with ON_ACCENT +// text, or back to the surface with TEXT. Every label under it follows. static void textUnder(lv_obj_t* o, uint32_t col) { for (uint32_t i = 0; i < lv_obj_get_child_count(o); i++) { lv_obj_t* c = lv_obj_get_child(o, i); @@ -1036,7 +1036,7 @@ static void textUnder(lv_obj_t* o, uint32_t col) { static void styleSelected(lv_obj_t* b, bool on) { lv_obj_set_style_bg_color(b, lv_color_hex(on ? theme::ACCENT : theme::SURFACE), 0); lv_obj_set_style_bg_color(b, lv_color_hex(on ? theme::mix(theme::ACCENT, theme::BG, 75) : theme::SURFACE_2), LV_STATE_PRESSED); - textUnder(b, on ? theme::BG : theme::TEXT); + textUnder(b, on ? theme::ON_ACCENT : theme::TEXT); } // A row of equal buttons at the foot of a popup or screen: buttonBar(), then @@ -1137,7 +1137,7 @@ static void badge(lv_obj_t* parent, int n, bool overflow) { lv_obj_set_style_pad_hor(b, 7, 0); lv_obj_set_style_pad_ver(b, 0, 0); lv_obj_align(b, LV_ALIGN_RIGHT_MID, -theme::PAD, 0); - lv_obj_t* l = label(b, "", THEME_FONT_SMALL, theme::BG); + lv_obj_t* l = label(b, "", THEME_FONT_SMALL, theme::ON_ACCENT); lv_label_set_text_fmt(l, "%d%s", n, overflow ? "+" : ""); lv_obj_center(l); }