From 350393436a0d16922a393e8c575181b40e2a9898 Mon Sep 17 00:00:00 2001 From: Jakub <106778416+MarekZegare4@users.noreply.github.com> Date: Mon, 28 Sep 2026 15:19:10 +0200 Subject: [PATCH] feat(ui-lvgl): AM / PM beside the big clock on a 12-hour clock It was a muted prefix on the date line, easy to miss. clockFace() -- the digits and a small AM / PM on their baseline -- is shared by Home and both lock screens (the PIN card showed no AM / PM at all). The date loses the prefix. Co-Authored-By: Claude Opus 5.5 --- .../ui-lvgl/ConversationScreen.h | 2 +- .../companion_radio/ui-lvgl/DeviceScreen.h | 11 +++--- examples/companion_radio/ui-lvgl/HomeScreen.h | 13 ++++--- examples/companion_radio/ui-lvgl/UITask.cpp | 34 ++++++++++++++++--- 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/examples/companion_radio/ui-lvgl/ConversationScreen.h b/examples/companion_radio/ui-lvgl/ConversationScreen.h index 9d66935a..9ea41d33 100644 --- a/examples/companion_radio/ui-lvgl/ConversationScreen.h +++ b/examples/companion_radio/ui-lvgl/ConversationScreen.h @@ -321,7 +321,7 @@ void UITask::messageMenu(int idx) { fmtClock(clk, sizeof(clk), ti, _prefs, true); if (clockBehind(now, ts)) { // the clock isn't set yet: the date instead of an age char date[32]; - fmtDate(date, sizeof(date), ti, nullptr); + fmtDate(date, sizeof(date), ti); snprintf(when, sizeof(when), "%s %s", date, clk); } else snprintf(when, sizeof(when), "%s - %s ago", clk, age); } else { diff --git a/examples/companion_radio/ui-lvgl/DeviceScreen.h b/examples/companion_radio/ui-lvgl/DeviceScreen.h index 72856462..13046042 100644 --- a/examples/companion_radio/ui-lvgl/DeviceScreen.h +++ b/examples/companion_radio/ui-lvgl/DeviceScreen.h @@ -192,7 +192,7 @@ void UITask::lockScreen() { lv_obj_set_flex_flow(top, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(top, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_column(top, 14, 0); - s_lock_clock = label(top, "--:--", THEME_FONT_LARGE, theme::TEXT); + s_lock_clock = clockFace(top, THEME_FONT_LARGE, THEME_FONT_SMALL); s_lock_unread = label(top, "", THEME_FONT_BODY, theme::ACCENT); s_lock_date = nullptr; _pin_entry[0] = '\0'; @@ -202,7 +202,7 @@ void UITask::lockScreen() { refreshLock(); return; } - s_lock_clock = label(s_lock, "--:--", THEME_FONT_CLOCK, theme::TEXT); + s_lock_clock = clockFace(s_lock, THEME_FONT_CLOCK, THEME_FONT_TITLE); s_lock_date = label(s_lock, "", THEME_FONT_BODY, theme::TEXT_MUTED); s_lock_unread = label(s_lock, "", THEME_FONT_BODY, theme::ACCENT); lv_obj_set_style_pad_top(s_lock_unread, 8, 0); @@ -296,10 +296,9 @@ void UITask::refreshLock() { if (!s_lock) return; struct tm ti; if (localTime(_prefs, ti)) { - char clk[12], date[48]; - fmtClock(clk, sizeof(clk), ti, _prefs, false, true); - fmtDate(date, sizeof(date), ti, _prefs); - lv_label_set_text(s_lock_clock, clk); + clockFaceSet(s_lock_clock, &ti, _prefs); + char date[48]; + fmtDate(date, sizeof(date), ti); if (s_lock_date) lv_label_set_text(s_lock_date, date); } int unread = unreadTotal(); diff --git a/examples/companion_radio/ui-lvgl/HomeScreen.h b/examples/companion_radio/ui-lvgl/HomeScreen.h index f77038cd..79ff7d66 100644 --- a/examples/companion_radio/ui-lvgl/HomeScreen.h +++ b/examples/companion_radio/ui-lvgl/HomeScreen.h @@ -249,7 +249,7 @@ void UITask::buildHomeClock(lv_obj_t* box) { lv_obj_add_flag(clk, LV_OBJ_FLAG_CLICKABLE); lv_obj_set_style_opa(clk, LV_OPA_70, LV_STATE_PRESSED); lv_obj_add_event_cb(clk, onClockTap, LV_EVENT_CLICKED, NULL); - _home_clock = label(clk, "--:--", THEME_FONT_CLOCK, theme::TEXT); + _home_clock = clockFace(clk, THEME_FONT_CLOCK, THEME_FONT_TITLE); _home_date = label(clk, "", THEME_FONT_BODY, theme::TEXT_MUTED); label(clk, the_mesh.getNodeName(), THEME_FONT_BODY, theme::ACCENT); @@ -574,14 +574,13 @@ void UITask::refreshHome() { } if (!_home_clock) return; struct tm ti; - if (localTime(_prefs, ti)) { - char clk[12], date[48]; - fmtClock(clk, sizeof(clk), ti, _prefs, false, true); - fmtDate(date, sizeof(date), ti, _prefs); - lv_label_set_text(_home_clock, clk); + bool known = localTime(_prefs, ti); + clockFaceSet(_home_clock, known ? &ti : nullptr, _prefs); + if (known) { + char date[48]; + fmtDate(date, sizeof(date), ti); lv_label_set_text(_home_date, date); } else { - lv_label_set_text(_home_clock, "--:--"); lv_label_set_text(_home_date, "time not synced"); } for (int i = 0; i < FIELDS; i++) { diff --git a/examples/companion_radio/ui-lvgl/UITask.cpp b/examples/companion_radio/ui-lvgl/UITask.cpp index 18ad1a39..5a5f55d7 100644 --- a/examples/companion_radio/ui-lvgl/UITask.cpp +++ b/examples/companion_radio/ui-lvgl/UITask.cpp @@ -704,14 +704,38 @@ static void fmtClock(char* b, size_t n, const struct tm& ti, const NodePrefs* p, snprintf(b, n, "%02d:%02d%s", ti.tm_hour, ti.tm_min, sec); } } -// "Thu 25 Sep 2026" ("PM Thu 25 Sep 2026" on a 12-hour clock, whose big -// digits have no room for it). -static void fmtDate(char* b, size_t n, const struct tm& ti, const NodePrefs* p) { +// "Thu 25 Sep 2026". +static void fmtDate(char* b, size_t n, const struct tm& ti) { static const char* DOW[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; static const char* MON[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - snprintf(b, n, "%s%s %d %s %d", (p && p->clock_12h) ? (ti.tm_hour < 12 ? "AM " : "PM ") : "", - DOW[ti.tm_wday], ti.tm_mday, MON[ti.tm_mon], ti.tm_year + 1900); + snprintf(b, n, "%s %d %s %d", DOW[ti.tm_wday], ti.tm_mday, MON[ti.tm_mon], ti.tm_year + 1900); +} + +// A big clock (Home, the lock screen): the digits and, on a 12-hour clock, +// AM / PM beside them in `small`, on the digits' baseline. clockFaceSet() +// once a second; "--:--" until the time is known. +static lv_obj_t* clockFace(lv_obj_t* parent, const lv_font_t* big, const lv_font_t* small) { + lv_obj_t* f = flexBox(parent, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(f, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_END, LV_FLEX_ALIGN_END); + lv_obj_set_style_pad_column(f, 4, 0); + label(f, "--:--", big, theme::TEXT); + lv_obj_t* ap = label(f, "", small, theme::TEXT_MUTED); + lv_obj_set_style_pad_bottom(ap, big->base_line - small->base_line, 0); + lv_obj_add_flag(ap, LV_OBJ_FLAG_HIDDEN); + return f; +} +static void clockFaceSet(lv_obj_t* f, const struct tm* ti, const NodePrefs* p) { + lv_obj_t* ap = lv_obj_get_child(f, 1); + char clk[12] = "--:--"; + if (ti) fmtClock(clk, sizeof(clk), *ti, p, false, true); + lv_label_set_text(lv_obj_get_child(f, 0), clk); + bool h12 = ti && p && p->clock_12h; + if (h12) lv_label_set_text(ap, ti->tm_hour < 12 ? "AM" : "PM"); + if (h12 != !lv_obj_has_flag(ap, LV_OBJ_FLAG_HIDDEN)) { + if (h12) lv_obj_remove_flag(ap, LV_OBJ_FLAG_HIDDEN); + else lv_obj_add_flag(ap, LV_OBJ_FLAG_HIDDEN); + } } // A message's age ("12s" / "5m" / "3h" / "2d"). After a restart the clock runs // from the build date until GPS or the app sets it, so messages restored from