From 1b7402a33e0ef0ba1cfa48e946c77c3d2205aaf9 Mon Sep 17 00:00:00 2001 From: Jakub <106778416+MarekZegare4@users.noreply.github.com> Date: Tue, 6 Oct 2026 09:35:46 +0200 Subject: [PATCH] style(ui-lvgl): selected / on in the full accent, no ACCENT_DIM ACCENT_DIM (the accent mixed toward black) came out brown on selected tabs, chips, segments and own bubbles. They take the accent with dark text now, as primary actions and the quick panel tiles do: styleSelected() sets the fill, the pressed shade and every label under it. Own bubbles: dark text, age and delivery mark (green or red can't be read on amber); the melody editor's selected note is outlined, the sounding one filled. Co-Authored-By: Claude Opus 5.5 --- .../companion_radio/ui-lvgl/AdminScreen.h | 3 +- examples/companion_radio/ui-lvgl/BotScreen.h | 7 +- .../companion_radio/ui-lvgl/ChannelScreen.h | 1 - .../companion_radio/ui-lvgl/ClockScreen.h | 4 +- .../companion_radio/ui-lvgl/DeviceScreen.h | 3 +- examples/companion_radio/ui-lvgl/DiagScreen.h | 2 +- examples/companion_radio/ui-lvgl/MapAreas.h | 2 +- examples/companion_radio/ui-lvgl/OtaScreen.h | 1 - .../companion_radio/ui-lvgl/SoundScreen.h | 8 ++- examples/companion_radio/ui-lvgl/Theme.h | 17 +++-- examples/companion_radio/ui-lvgl/UITask.cpp | 69 ++++++++++++------- examples/companion_radio/ui-lvgl/WifiScreen.h | 1 - 12 files changed, 67 insertions(+), 51 deletions(-) diff --git a/examples/companion_radio/ui-lvgl/AdminScreen.h b/examples/companion_radio/ui-lvgl/AdminScreen.h index 92c0596a..ebdc0b79 100644 --- a/examples/companion_radio/ui-lvgl/AdminScreen.h +++ b/examples/companion_radio/ui-lvgl/AdminScreen.h @@ -285,9 +285,10 @@ static lv_obj_t* adminPopupButton(lv_obj_t* parent, const char* text, uint8_t ac lv_obj_set_flex_grow(b, 1); lv_obj_set_style_shadow_width(b, 0, 0); lv_obj_set_style_radius(b, theme::RADIUS, 0); - lv_obj_set_style_bg_color(b, lv_color_hex(accent ? theme::ACCENT_DIM : theme::SURFACE), 0); + lv_obj_set_style_bg_color(b, lv_color_hex(theme::SURFACE), 0); lv_obj_add_event_cb(b, onAdminValue, LV_EVENT_CLICKED, (void*)(uintptr_t)act); lv_obj_center(label(b, text, act == adminview::V_MINUS || act == adminview::V_PLUS ? THEME_FONT_LARGE : THEME_FONT_BODY, theme::TEXT)); + if (accent) stylePrimary(b); return b; } diff --git a/examples/companion_radio/ui-lvgl/BotScreen.h b/examples/companion_radio/ui-lvgl/BotScreen.h index b966c531..bb9d9074 100644 --- a/examples/companion_radio/ui-lvgl/BotScreen.h +++ b/examples/companion_radio/ui-lvgl/BotScreen.h @@ -58,9 +58,10 @@ static lv_obj_t* botHourButton(lv_obj_t* parent, const char* text, uint8_t act, lv_obj_set_flex_grow(b, 1); lv_obj_set_style_shadow_width(b, 0, 0); lv_obj_set_style_radius(b, theme::RADIUS, 0); - lv_obj_set_style_bg_color(b, lv_color_hex(accent ? theme::ACCENT_DIM : theme::SURFACE), 0); + lv_obj_set_style_bg_color(b, lv_color_hex(theme::SURFACE), 0); lv_obj_add_event_cb(b, onBotHour, LV_EVENT_CLICKED, (void*)(uintptr_t)act); lv_obj_center(label(b, text, act == botview::B_DONE ? THEME_FONT_BODY : THEME_FONT_LARGE, theme::TEXT)); + if (accent) stylePrimary(b); return b; } @@ -195,7 +196,7 @@ void UITask::botRow(int row) { ChannelDetails ch; if (!the_mesh.getChannel(i, ch) || !ch.name[0]) continue; lv_obj_t* rw = listRow(list, ch.name, NULL, onBotPick, (void*)(uintptr_t)i); - if (i == p->bot_channel_idx) lv_obj_set_style_bg_color(rw, lv_color_hex(theme::ACCENT_DIM), 0); + if (i == p->bot_channel_idx) styleSelected(rw, true); n++; } } else { @@ -206,7 +207,7 @@ void UITask::botRow(int row) { memcpy(s_rooms[n], c.id.pub_key, NodePrefs::FAVOURITE_PREFIX_LEN); lv_obj_t* rw = listRow(list, c.name, NULL, onBotPick, (void*)(uintptr_t)n); if (memcmp(c.id.pub_key, p->bot_room_prefix, NodePrefs::FAVOURITE_PREFIX_LEN) == 0) - lv_obj_set_style_bg_color(rw, lv_color_hex(theme::ACCENT_DIM), 0); + styleSelected(rw, true); n++; } } diff --git a/examples/companion_radio/ui-lvgl/ChannelScreen.h b/examples/companion_radio/ui-lvgl/ChannelScreen.h index 87bf2214..0b0f2b90 100644 --- a/examples/companion_radio/ui-lvgl/ChannelScreen.h +++ b/examples/companion_radio/ui-lvgl/ChannelScreen.h @@ -196,7 +196,6 @@ void UITask::buildChannelEdit() { lv_obj_set_size(save, LV_PCT(100), 38); lv_obj_set_style_shadow_width(save, 0, 0); lv_obj_set_style_radius(save, theme::RADIUS, 0); - lv_obj_set_style_bg_color(save, lv_color_hex(theme::ACCENT_DIM), 0); lv_obj_add_event_cb(save, onChanSave, LV_EVENT_CLICKED, NULL); lv_obj_center(label(save, LV_SYMBOL_OK " Save", THEME_FONT_BODY, theme::TEXT)); stylePrimary(save); diff --git a/examples/companion_radio/ui-lvgl/ClockScreen.h b/examples/companion_radio/ui-lvgl/ClockScreen.h index 23be9298..c0d70217 100644 --- a/examples/companion_radio/ui-lvgl/ClockScreen.h +++ b/examples/companion_radio/ui-lvgl/ClockScreen.h @@ -301,9 +301,9 @@ void UITask::buildClock() { lv_obj_set_flex_grow(b, 1); lv_obj_set_style_shadow_width(b, 0, 0); lv_obj_set_style_radius(b, theme::RADIUS, 0); - lv_obj_set_style_bg_color(b, lv_color_hex(t == s_tab ? theme::ACCENT_DIM : theme::SURFACE), 0); lv_obj_add_event_cb(b, onClockTab, LV_EVENT_CLICKED, (void*)(uintptr_t)t); lv_obj_center(label(b, NAMES[t], THEME_FONT_SMALL, theme::TEXT)); + styleSelected(b, t == s_tab); } if (s_tab == TAB_ALARM) { @@ -392,7 +392,6 @@ void UITask::buildClock() { lv_obj_set_size(go, 150, 40); lv_obj_set_style_shadow_width(go, 0, 0); lv_obj_set_style_radius(go, theme::RADIUS, 0); - lv_obj_set_style_bg_color(go, lv_color_hex(theme::ACCENT_DIM), 0); lv_obj_add_event_cb(go, onClockAct, LV_EVENT_CLICKED, (void*)(uintptr_t)ACT_START_STOP); s_go_lbl = label(go, "", THEME_FONT_BODY, theme::TEXT); lv_obj_center(s_go_lbl); @@ -492,7 +491,6 @@ void UITask::showRing(const char* text) { lv_obj_set_size(b, 200, 56); lv_obj_set_style_shadow_width(b, 0, 0); lv_obj_set_style_radius(b, theme::RADIUS, 0); - lv_obj_set_style_bg_color(b, lv_color_hex(theme::ACCENT_DIM), 0); lv_obj_add_event_cb(b, onRingDismiss, LV_EVENT_CLICKED, NULL); lv_obj_center(label(b, "Dismiss", THEME_FONT_LARGE, theme::TEXT)); stylePrimary(b); diff --git a/examples/companion_radio/ui-lvgl/DeviceScreen.h b/examples/companion_radio/ui-lvgl/DeviceScreen.h index af742902..632146a7 100644 --- a/examples/companion_radio/ui-lvgl/DeviceScreen.h +++ b/examples/companion_radio/ui-lvgl/DeviceScreen.h @@ -565,12 +565,13 @@ void UITask::pinPopup(bool channel, uint8_t ch_idx, const uint8_t* pub_key) { lv_obj_set_style_pad_hor(b, 4, 0); lv_obj_set_style_radius(b, theme::RADIUS, 0); lv_obj_set_style_shadow_width(b, 0, 0); - lv_obj_set_style_bg_color(b, lv_color_hex(s == here ? theme::ACCENT_DIM : theme::SURFACE), 0); + lv_obj_set_style_bg_color(b, lv_color_hex(theme::SURFACE), 0); lv_obj_add_event_cb(b, onPinSlot, LV_EVENT_CLICKED, (void*)(uintptr_t)s); lv_obj_t* l = label(b, t, THEME_FONT_SMALL, used ? theme::TEXT : theme::TEXT_MUTED); lv_label_set_long_mode(l, LV_LABEL_LONG_DOT); lv_obj_set_width(l, 82); lv_obj_center(l); + if (s == here) styleSelected(b, true); } label(panel, here >= 0 ? "Tap its slot again to unpin." : "A taken slot is replaced.", THEME_FONT_SMALL, theme::TEXT_MUTED); } diff --git a/examples/companion_radio/ui-lvgl/DiagScreen.h b/examples/companion_radio/ui-lvgl/DiagScreen.h index 6ce5b843..459fe083 100644 --- a/examples/companion_radio/ui-lvgl/DiagScreen.h +++ b/examples/companion_radio/ui-lvgl/DiagScreen.h @@ -399,10 +399,10 @@ void UITask::buildDiag() { lv_obj_set_size(b, LV_PCT(100), 40); lv_obj_set_style_shadow_width(b, 0, 0); lv_obj_set_style_radius(b, theme::RADIUS, 0); - lv_obj_set_style_bg_color(b, lv_color_hex(theme::ACCENT_DIM), 0); lv_obj_add_event_cb(b, onNoiseRun, LV_EVENT_CLICKED, NULL); s_noise_status = label(b, s_noise_have ? LV_SYMBOL_REFRESH " Measure again" : LV_SYMBOL_PLAY " Measure", THEME_FONT_BODY, theme::TEXT); lv_obj_center(s_noise_status); + stylePrimary(b); if (s_noise_have) { float mesh_f = _prefs ? _prefs->freq : 0; lv_obj_t* card = infoCard(s_list); diff --git a/examples/companion_radio/ui-lvgl/MapAreas.h b/examples/companion_radio/ui-lvgl/MapAreas.h index 8babec4d..f6a2bf3d 100644 --- a/examples/companion_radio/ui-lvgl/MapAreas.h +++ b/examples/companion_radio/ui-lvgl/MapAreas.h @@ -325,8 +325,8 @@ void UITask::areaLayout() { lv_obj_set_style_text_color(s_info, lv_color_hex(too ? theme::FAIL : theme::TEXT), 0); lv_label_set_text_fmt(s_zoom, "z%d", a.zmax); if (s_trails_btn) { - lv_obj_set_style_bg_color(s_trails_btn, lv_color_hex(s_trails ? theme::ACCENT_DIM : theme::SURFACE), 0); lv_label_set_text(lv_obj_get_child(s_trails_btn, 0), s_trails ? LV_SYMBOL_OK " Trails" : "Trails"); + styleSelected(s_trails_btn, s_trails); } } diff --git a/examples/companion_radio/ui-lvgl/OtaScreen.h b/examples/companion_radio/ui-lvgl/OtaScreen.h index f249f175..2cccf181 100644 --- a/examples/companion_radio/ui-lvgl/OtaScreen.h +++ b/examples/companion_radio/ui-lvgl/OtaScreen.h @@ -202,7 +202,6 @@ void UITask::buildOta() { lv_obj_set_size(b, LV_PCT(100), 40); lv_obj_set_style_shadow_width(b, 0, 0); lv_obj_set_style_radius(b, theme::RADIUS, 0); - lv_obj_set_style_bg_color(b, lv_color_hex(theme::ACCENT_DIM), 0); lv_obj_add_event_cb(b, onOtaButton, LV_EVENT_CLICKED, NULL); _ota_btn = b; _ota_btn_lbl = label(b, "", THEME_FONT_BODY, theme::TEXT); diff --git a/examples/companion_radio/ui-lvgl/SoundScreen.h b/examples/companion_radio/ui-lvgl/SoundScreen.h index 02470edc..547cd8cb 100644 --- a/examples/companion_radio/ui-lvgl/SoundScreen.h +++ b/examples/companion_radio/ui-lvgl/SoundScreen.h @@ -33,12 +33,14 @@ static const char* OCTAVES[] = { "4", "5", "6", "" }; static const char* DURS[] = { "1/4", "1/8", "1/16", "1/32", "" }; static const char* SLOTS[] = { "Melody 1", "Melody 2", "" }; -// Selected: dim accent with a border; sounding now (Play): full accent. +// Selected: an accent border; sounding now (Play): the accent, dark text. static void styleCell(int i, bool sel) { if (i < 0 || i >= soundctl::MAX_NOTES || !s_cells[i]) return; - uint32_t bg = i == s_hl ? theme::ACCENT : sel ? theme::ACCENT_DIM : theme::SURFACE; - lv_obj_set_style_bg_color(s_cells[i], lv_color_hex(bg), 0); + 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); } // Moves the "sounding" light to note `idx` (-1: none). diff --git a/examples/companion_radio/ui-lvgl/Theme.h b/examples/companion_radio/ui-lvgl/Theme.h index 83704873..49de9063 100644 --- a/examples/companion_radio/ui-lvgl/Theme.h +++ b/examples/companion_radio/ui-lvgl/Theme.h @@ -5,10 +5,11 @@ // 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 -// (Download, Install, Save, Go) -- stylePrimary() in UITask.cpp; -// - ACCENT_DIM fill, light text: something selected / on (a tab, a chip, a -// segment, a mode that is running); +// (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. #include // lv_theme_t's fields, to layer a theme @@ -18,7 +19,6 @@ namespace theme { 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 uint32_t ACCENT_DIM = 0x6B4A00; // selected / on fill, own bubbles (setAccent) static const uint32_t TEXT = 0xF2EEE6; static const uint32_t TEXT_MUTED= 0x9A958C; static const uint32_t OK = 0x6FCF6F; // delivered / relayed @@ -83,11 +83,10 @@ namespace theme { if (idx < 0 || idx >= ACCENT_COUNT) idx = 0; s_accent = idx; ACCENT = ACCENTS[idx].col; - ACCENT_DIM = mix(ACCENT, BG, 42); } // Over LVGL's default theme, for every widget: a checked button is - // "selected" (ACCENT_DIM, not the default theme's full accent), buttons + // "selected" (the accent, dark 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 @@ -115,7 +114,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(TEXT)); + lv_style_set_text_color(&s_checked, lv_color_hex(BG)); 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 @@ -123,8 +122,8 @@ namespace theme { lv_style_set_pad_top(&s_sbar, RADIUS / 2); lv_style_set_pad_left(&s_sbar, RADIUS / 2); } - lv_style_set_bg_color(&s_checked, lv_color_hex(ACCENT_DIM)); - lv_theme_t* base = lv_theme_default_init(disp, lv_color_hex(ACCENT), lv_color_hex(ACCENT_DIM), true, THEME_FONT_BODY); + 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); 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/UITask.cpp b/examples/companion_radio/ui-lvgl/UITask.cpp index a8d23d3f..35712424 100644 --- a/examples/companion_radio/ui-lvgl/UITask.cpp +++ b/examples/companion_radio/ui-lvgl/UITask.cpp @@ -1048,8 +1048,9 @@ static lv_obj_t* segmented(lv_obj_t* parent, const char** map, int sel, int w, i lv_obj_set_style_bg_opa(m, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(m, 0, 0); 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_DIM), LV_PART_ITEMS | LV_STATE_CHECKED); + 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_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_SM, LV_PART_ITEMS); @@ -1101,6 +1102,21 @@ static void stylePrimary(lv_obj_t* b) { lv_obj_set_style_text_color(lv_obj_get_child(b, i), lv_color_hex(theme::BG), 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. +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); + if (lv_obj_check_type(c, &lv_label_class)) setTextColor(c, col); + else textUnder(c, 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); +} + // A row of equal buttons at the foot of a popup or screen: buttonBar(), then // barButton() for each -- `accent` for the main action or one that's on // (barButtonOn() flips it later). Returns the button; its label is child 0. @@ -1113,9 +1129,7 @@ static lv_obj_t* buttonBar(lv_obj_t* parent) { lv_obj_set_style_pad_column(bar, theme::GAP, 0); return bar; } -static void barButtonOn(lv_obj_t* b, bool on) { - lv_obj_set_style_bg_color(b, lv_color_hex(on ? theme::ACCENT_DIM : theme::SURFACE), 0); -} +static void barButtonOn(lv_obj_t* b, bool on) { styleSelected(b, on); } static lv_obj_t* barButton(lv_obj_t* bar, const char* text, lv_event_cb_t cb, uintptr_t user, bool accent = false) { lv_obj_t* b = lv_button_create(bar); lv_obj_set_height(b, 40); @@ -1123,10 +1137,9 @@ static lv_obj_t* barButton(lv_obj_t* bar, const char* text, lv_event_cb_t cb, ui lv_obj_set_style_pad_hor(b, 4, 0); lv_obj_set_style_radius(b, theme::RADIUS, 0); lv_obj_set_style_shadow_width(b, 0, 0); - barButtonOn(b, accent); - lv_obj_set_style_bg_color(b, lv_color_hex(theme::SURFACE_2), LV_STATE_PRESSED); lv_obj_add_event_cb(b, cb, LV_EVENT_CLICKED, (void*)user); lv_obj_center(label(b, text, THEME_FONT_SMALL, theme::TEXT)); + barButtonOn(b, accent); return b; } @@ -2681,7 +2694,7 @@ static void chatSection(lv_obj_t* parent, const char* text, int fold, int unread lv_obj_align_to(n, t, LV_ALIGN_OUT_RIGHT_MID, 8, 0); } if (filter < 0 || folded) return; - pillButton(row, fav_only ? UI_SYMBOL_STAR " Fav" : "All", fav_only ? theme::ACCENT_DIM : theme::SURFACE, onChatFilter, filter); + styleSelected(pillButton(row, fav_only ? UI_SYMBOL_STAR " Fav" : "All", theme::SURFACE, onChatFilter, filter), fav_only); } // Section title with an "All" / "★ Fav" pill on the right that flips the @@ -2692,7 +2705,7 @@ static void sectionWithFilter(lv_obj_t* parent, const char* text, bool fav_only, lv_obj_remove_flag(row, LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_size(row, LV_PCT(100), 26); lv_obj_align(label(row, text, THEME_FONT_SMALL, theme::TEXT_MUTED), LV_ALIGN_BOTTOM_LEFT, 0, -2); - pillButton(row, fav_only ? UI_SYMBOL_STAR " Fav" : "All", fav_only ? theme::ACCENT_DIM : theme::SURFACE, onChatFilter, which); + styleSelected(pillButton(row, fav_only ? UI_SYMBOL_STAR " Fav" : "All", theme::SURFACE, onChatFilter, which), fav_only); } void UITask::showChats() { @@ -2998,9 +3011,9 @@ void UITask::buildNearby() { lv_obj_set_style_radius(c, LV_RADIUS_CIRCLE, 0); lv_obj_set_style_shadow_width(c, 0, 0); bool on = f == _nearby->filter(); - lv_obj_set_style_bg_color(c, lv_color_hex(on ? theme::ACCENT_DIM : theme::SURFACE), 0); // selected (Theme.h) lv_obj_add_event_cb(c, onNearbyChip, LV_EVENT_CLICKED, (void*)(uintptr_t)f); lv_obj_center(label(c, NearbyModel::filterLabel(f), THEME_FONT_SMALL, theme::TEXT)); + styleSelected(c, on); // (Theme.h) } _nearby_status = label(body, "", THEME_FONT_SMALL, theme::TEXT_MUTED); @@ -3633,26 +3646,28 @@ static void onMsgLoc(lv_event_t* e) { if (r >= 0) s_ui->messageLocationAction(s_msg_meta[r].loc, (uintptr_t)lv_event_get_user_data(e) != 0); } -static void msgLocButton(lv_obj_t* parent, const char* text, bool save, bool accent) { +static void msgLocButton(lv_obj_t* parent, const char* text, bool save, bool accent, bool own) { lv_obj_t* b = lv_button_create(parent); lv_obj_set_size(b, LV_SIZE_CONTENT, 28); lv_obj_set_style_pad_hor(b, 10, 0); lv_obj_set_style_pad_ver(b, 0, 0); lv_obj_set_style_radius(b, LV_RADIUS_CIRCLE, 0); lv_obj_set_style_shadow_width(b, 0, 0); - lv_obj_set_style_bg_color(b, lv_color_hex(accent ? theme::ACCENT : theme::SURFACE_2), 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_add_event_cb(b, onMsgLoc, LV_EVENT_CLICKED, (void*)(uintptr_t)(save ? 1 : 0)); - lv_obj_center(label(b, text, THEME_FONT_SMALL, accent ? theme::BG : theme::TEXT)); + lv_obj_center(label(b, text, THEME_FONT_SMALL, accent ? (own ? theme::ACCENT : theme::BG) : theme::TEXT)); } // A message's text, wrapped at `max_w` and shrunk to fit. "@[nick]" mentions -// (how a reply names who it answers) show as "@nick" in the accent -- in the -// text colour on our own amber bubbles -- and underlined when the nick is +// (how a reply names who it answers) show as "@nick" in the accent -- dark, +// as the rest, on our own amber bubbles -- and underlined when the nick is // 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; if (!strstr(text, "@[")) { - lv_obj_t* t = label(parent, text, THEME_FONT_BODY, theme::TEXT); + lv_obj_t* t = label(parent, text, THEME_FONT_BODY, col); lv_label_set_long_mode(t, LV_LABEL_LONG_WRAP); lv_obj_set_style_max_width(t, max_w, 0); lv_obj_set_width(t, LV_SIZE_CONTENT); @@ -3661,7 +3676,7 @@ static lv_obj_t* msgText(lv_obj_t* parent, const char* text, bool own, int max_w lv_obj_t* sg = lv_spangroup_create(parent); lv_obj_remove_flag(sg, LV_OBJ_FLAG_CLICKABLE); // a hold still reaches the bubble (its menu) lv_obj_set_style_text_font(sg, THEME_FONT_BODY, 0); - lv_obj_set_style_text_color(sg, lv_color_hex(theme::TEXT), 0); + lv_obj_set_style_text_color(sg, lv_color_hex(col), 0); lv_spangroup_set_mode(sg, LV_SPAN_MODE_BREAK); const char* me = the_mesh.getNodeName(); char part[MAX_TEXT_LEN + 1]; @@ -3687,7 +3702,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::TEXT : theme::ACCENT)); + lv_style_set_text_color(st, lv_color_hex(own ? theme::BG : theme::ACCENT)); if (mine) { lv_style_set_text_decor(st, LV_TEXT_DECOR_UNDERLINE); *mentions_me = true; } p = close + 1; } @@ -3698,7 +3713,8 @@ static lv_obj_t* msgText(lv_obj_t* parent, const char* text, bool own, int max_w return sg; } -// One message bubble. Own messages right-aligned in amber, others left. +// One message bubble. Own messages right-aligned in amber with dark text +// (the delivery mark too: green or red on amber can't be read), others left. // loc: the text carries a position (Go / Save buttons); hold: a long press // opens the message menu. Returns its row; *age_out = the age label. static lv_obj_t* bubble(lv_obj_t* list, const char* from, const char* text, bool own, @@ -3719,13 +3735,14 @@ static lv_obj_t* bubble(lv_obj_t* list, const char* from, const char* text, bool lv_obj_remove_flag(b, LV_OBJ_FLAG_SCROLLABLE); if (hold) { // hold: reply / path / target (ConversationScreen.h) lv_obj_add_event_cb(b, onMsgHold, LV_EVENT_LONG_PRESSED, nullptr); - lv_obj_set_style_bg_color(b, lv_color_hex(theme::SURFACE_2), LV_STATE_PRESSED); + lv_obj_set_style_bg_color(b, lv_color_hex(own ? theme::mix(theme::ACCENT, theme::BG, 75) : theme::SURFACE_2), LV_STATE_PRESSED); } else { lv_obj_remove_flag(b, LV_OBJ_FLAG_CLICKABLE); } 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_DIM : theme::SURFACE), 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; 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); @@ -3742,8 +3759,8 @@ 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, theme::ACCENT); // names are <= 31 chars: fits the bubble - if (meta_in_header) *age_out = label(hdr, meta, THEME_FONT_SMALL, theme::TEXT_MUTED); + label(hdr, from, THEME_FONT_SMALL, own ? theme::BG : 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; msgText(b, text, own, 238, &mentions_me); @@ -3756,15 +3773,15 @@ static lv_obj_t* bubble(lv_obj_t* list, const char* from, const char* text, bool lv_obj_t* acts = flexBox(b, LV_FLEX_FLOW_ROW); lv_obj_set_style_pad_column(acts, 6, 0); lv_obj_set_style_pad_top(acts, 2, 0); - msgLocButton(acts, UI_SYMBOL_COMPASS " Go", false, true); - msgLocButton(acts, UI_SYMBOL_FLAG " Save", true, false); + msgLocButton(acts, UI_SYMBOL_COMPASS " Go", false, true, own); + msgLocButton(acts, UI_SYMBOL_FLAG " Save", true, false, own); } if (!meta_in_header) { // the age, then the delivery mark in its colour (as L1) lv_obj_t* line = flexBox(b, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(line, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_column(line, 6, 0); - *age_out = label(line, meta, THEME_FONT_SMALL, theme::TEXT_MUTED); + *age_out = label(line, meta, THEME_FONT_SMALL, muted); if (relays > 0) { // as L1: the count alone says it got out, no check beside it lv_obj_t* c = lv_obj_create(line); lv_obj_remove_style_all(c); @@ -3779,7 +3796,7 @@ static lv_obj_t* bubble(lv_obj_t* list, const char* from, const char* text, bool lv_label_set_text_fmt(n, "%d", relays); lv_obj_center(n); } else if (status && status[0]) { - label(line, status, THEME_FONT_SMALL, status_col); + label(line, status, THEME_FONT_SMALL, own ? theme::BG : status_col); } } return row; diff --git a/examples/companion_radio/ui-lvgl/WifiScreen.h b/examples/companion_radio/ui-lvgl/WifiScreen.h index 98ca4084..641e7e5d 100644 --- a/examples/companion_radio/ui-lvgl/WifiScreen.h +++ b/examples/companion_radio/ui-lvgl/WifiScreen.h @@ -127,7 +127,6 @@ void UITask::buildWifi() { lv_obj_set_size(save, LV_PCT(100), 38); lv_obj_set_style_shadow_width(save, 0, 0); lv_obj_set_style_radius(save, theme::RADIUS, 0); - lv_obj_set_style_bg_color(save, lv_color_hex(theme::ACCENT_DIM), 0); lv_obj_add_event_cb(save, onWifiSave, LV_EVENT_CLICKED, NULL); lv_obj_center(label(save, LV_SYMBOL_OK " Save", THEME_FONT_BODY, theme::TEXT)); stylePrimary(save);