mirror of
https://github.com/ratspeak/ratdeck.git
synced 2026-07-24 04:30:57 +00:00
Regenerated Montserrat 10/12/14 with Cyrillic and Latin Extended Unicode ranges so messages in Russian, Ukrainian, Bulgarian, and accented European languages render properly instead of rectangles.
137 lines
4.4 KiB
C++
137 lines
4.4 KiB
C++
#include "LvStatusBar.h"
|
|
#include "Theme.h"
|
|
#include <Arduino.h>
|
|
#include <time.h>
|
|
#include "fonts/fonts.h"
|
|
|
|
void LvStatusBar::create(lv_obj_t* parent) {
|
|
_bar = lv_obj_create(parent);
|
|
lv_obj_set_size(_bar, Theme::SCREEN_W, Theme::STATUS_BAR_H);
|
|
lv_obj_align(_bar, LV_ALIGN_TOP_LEFT, 0, 0);
|
|
lv_obj_set_style_bg_color(_bar, lv_color_hex(Theme::BG), 0);
|
|
lv_obj_set_style_bg_opa(_bar, LV_OPA_COVER, 0);
|
|
lv_obj_set_style_border_color(_bar, lv_color_hex(Theme::BORDER), 0);
|
|
lv_obj_set_style_border_width(_bar, 1, 0);
|
|
lv_obj_set_style_border_side(_bar, LV_BORDER_SIDE_BOTTOM, 0);
|
|
lv_obj_set_style_pad_all(_bar, 0, 0);
|
|
lv_obj_set_style_radius(_bar, 0, 0);
|
|
lv_obj_clear_flag(_bar, LV_OBJ_FLAG_SCROLLABLE);
|
|
|
|
const lv_font_t* font = &lv_font_ratdeck_12;
|
|
|
|
// Left: Time display (hidden until valid time is available)
|
|
_lblTime = lv_label_create(_bar);
|
|
lv_obj_set_style_text_font(_lblTime, font, 0);
|
|
lv_obj_set_style_text_color(_lblTime, lv_color_hex(Theme::PRIMARY), 0);
|
|
lv_label_set_text(_lblTime, "");
|
|
lv_obj_align(_lblTime, LV_ALIGN_LEFT_MID, 4, 0);
|
|
|
|
// Center: "Ratspeak.org"
|
|
_lblBrand = lv_label_create(_bar);
|
|
lv_obj_set_style_text_font(_lblBrand, font, 0);
|
|
lv_obj_set_style_text_color(_lblBrand, lv_color_hex(Theme::ACCENT), 0);
|
|
lv_label_set_text(_lblBrand, "Ratspeak.org");
|
|
lv_obj_align(_lblBrand, LV_ALIGN_CENTER, 0, 0);
|
|
|
|
// Right: Battery %
|
|
_lblBatt = lv_label_create(_bar);
|
|
lv_obj_set_style_text_font(_lblBatt, font, 0);
|
|
lv_label_set_text(_lblBatt, "");
|
|
lv_obj_align(_lblBatt, LV_ALIGN_RIGHT_MID, -4, 0);
|
|
|
|
// Toast overlay (hidden by default)
|
|
_toast = lv_obj_create(parent);
|
|
lv_obj_set_size(_toast, Theme::SCREEN_W, Theme::STATUS_BAR_H);
|
|
lv_obj_align(_toast, LV_ALIGN_TOP_LEFT, 0, 0);
|
|
lv_obj_set_style_bg_color(_toast, lv_color_hex(Theme::ACCENT), 0);
|
|
lv_obj_set_style_bg_opa(_toast, LV_OPA_COVER, 0);
|
|
lv_obj_set_style_pad_all(_toast, 0, 0);
|
|
lv_obj_set_style_radius(_toast, 0, 0);
|
|
lv_obj_clear_flag(_toast, LV_OBJ_FLAG_SCROLLABLE);
|
|
lv_obj_add_flag(_toast, LV_OBJ_FLAG_HIDDEN);
|
|
|
|
_lblToast = lv_label_create(_toast);
|
|
lv_obj_set_style_text_font(_lblToast, font, 0);
|
|
lv_obj_set_style_text_color(_lblToast, lv_color_hex(Theme::BG), 0);
|
|
lv_obj_center(_lblToast);
|
|
lv_label_set_text(_lblToast, "");
|
|
}
|
|
|
|
void LvStatusBar::update() {
|
|
// Handle announce flash timeout
|
|
if (_announceFlashEnd > 0 && millis() >= _announceFlashEnd) {
|
|
_announceFlashEnd = 0;
|
|
}
|
|
|
|
// Handle toast timeout
|
|
if (_toastEnd > 0 && millis() >= _toastEnd) {
|
|
_toastEnd = 0;
|
|
lv_obj_add_flag(_toast, LV_OBJ_FLAG_HIDDEN);
|
|
}
|
|
}
|
|
|
|
void LvStatusBar::updateTime() {
|
|
if (!_lblTime) return;
|
|
|
|
time_t now = time(nullptr);
|
|
if (now <= 1700000000) {
|
|
lv_label_set_text(_lblTime, "");
|
|
_lastHour = -1; _lastMinute = -1;
|
|
return;
|
|
}
|
|
|
|
struct tm* local = localtime(&now);
|
|
if (!local) {
|
|
lv_label_set_text(_lblTime, "");
|
|
_lastHour = -1; _lastMinute = -1;
|
|
return;
|
|
}
|
|
|
|
// Only update label when minute changes (avoids needless LVGL invalidation)
|
|
if (local->tm_hour == _lastHour && local->tm_min == _lastMinute) return;
|
|
_lastHour = local->tm_hour;
|
|
_lastMinute = local->tm_min;
|
|
|
|
char buf[8];
|
|
if (_use24h) {
|
|
snprintf(buf, sizeof(buf), "%02d:%02d", local->tm_hour, local->tm_min);
|
|
} else {
|
|
int h = local->tm_hour % 12;
|
|
if (h == 0) h = 12;
|
|
snprintf(buf, sizeof(buf), "%d:%02d", h, local->tm_min);
|
|
}
|
|
lv_label_set_text(_lblTime, buf);
|
|
}
|
|
|
|
void LvStatusBar::setGPSFix(bool hasFix) {
|
|
_gpsFix = hasFix;
|
|
}
|
|
|
|
void LvStatusBar::setBatteryPercent(int pct) {
|
|
if (_battPct == pct) return;
|
|
_battPct = pct;
|
|
if (pct >= 0) {
|
|
char buf[8];
|
|
snprintf(buf, sizeof(buf), "%d%%", pct);
|
|
lv_label_set_text(_lblBatt, buf);
|
|
uint32_t col = Theme::PRIMARY;
|
|
if (pct <= 15) col = Theme::ERROR_CLR;
|
|
else if (pct <= 30) col = Theme::WARNING_CLR;
|
|
lv_obj_set_style_text_color(_lblBatt, lv_color_hex(col), 0);
|
|
}
|
|
}
|
|
|
|
void LvStatusBar::setTransportMode(const char* mode) {
|
|
(void)mode;
|
|
}
|
|
|
|
void LvStatusBar::flashAnnounce() {
|
|
_announceFlashEnd = millis() + 1000;
|
|
}
|
|
|
|
void LvStatusBar::showToast(const char* msg, uint32_t durationMs) {
|
|
lv_label_set_text(_lblToast, msg);
|
|
_toastEnd = millis() + durationMs;
|
|
lv_obj_clear_flag(_toast, LV_OBJ_FLAG_HIDDEN);
|
|
}
|