feat(display): 添加显示模块功能支持电池状态和模式切换
- 配置文件中启用USB CDC ACM类、UART相关配置和LVGL显示库 - 添加对bat_state_event、hid_led_event和mode_switch_event事件的订阅 - 实现UI模型结构体ui_main_model用于管理显示状态 - 添加refresh_ui函数用于刷新UI界面 - 集成电池电量显示、充电状态指示和模式切换状态更新 fix(ui): 重构主UI界面添加动态数据更新功能 - 重写ui_main.c实现完整的UI组件创建和刷新逻辑 - 添加状态栏芯片显示USB、BLE、NumLock、CapsLock状态 - 实现电池图标、电量百分比和充电状态的动态更新 - 添加日期时间显示区域和整体UI刷新功能 - 创建ui_main_model数据结构管理UI状态数据 chore(config): 更新项目配置启用串口和显示相关功能 - 启用串口和UART中断驱动配置 - 添加USB CDC ACM类和HID支持 - 增加LVGL工作队列栈大小到16KB - 添加蒙特赛拉特32号字体支持
This commit is contained in:
8
prj.conf
8
prj.conf
@@ -30,7 +30,13 @@ CONFIG_ASSERT=y
|
|||||||
|
|
||||||
# USB HID next stack
|
# USB HID next stack
|
||||||
CONFIG_USB_DEVICE_STACK_NEXT=y
|
CONFIG_USB_DEVICE_STACK_NEXT=y
|
||||||
|
CONFIG_SERIAL=y
|
||||||
|
CONFIG_UART_INTERRUPT_DRIVEN=y
|
||||||
|
CONFIG_UART_LINE_CTRL=y
|
||||||
|
CONFIG_UART_USE_RUNTIME_CONFIGURE=y
|
||||||
CONFIG_USBD_HID_SUPPORT=y
|
CONFIG_USBD_HID_SUPPORT=y
|
||||||
|
CONFIG_USBD_CDC_ACM_CLASS=y
|
||||||
|
CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n
|
||||||
|
|
||||||
# BLE
|
# BLE
|
||||||
CONFIG_BT=y
|
CONFIG_BT=y
|
||||||
@@ -100,6 +106,7 @@ CONFIG_BT_ADV_PROV_DEVICE_NAME_SD=y
|
|||||||
CONFIG_LVGL=y
|
CONFIG_LVGL=y
|
||||||
CONFIG_LV_Z_AUTO_INIT=n
|
CONFIG_LV_Z_AUTO_INIT=n
|
||||||
CONFIG_LV_Z_RUN_LVGL_ON_WORKQUEUE=y
|
CONFIG_LV_Z_RUN_LVGL_ON_WORKQUEUE=y
|
||||||
|
CONFIG_LV_Z_LVGL_WORKQUEUE_STACK_SIZE=16384
|
||||||
CONFIG_LV_Z_LVGL_MUTEX=y
|
CONFIG_LV_Z_LVGL_MUTEX=y
|
||||||
CONFIG_LV_COLOR_DEPTH_16=y
|
CONFIG_LV_COLOR_DEPTH_16=y
|
||||||
CONFIG_LV_COLOR_16_SWAP=y
|
CONFIG_LV_COLOR_16_SWAP=y
|
||||||
@@ -109,4 +116,5 @@ CONFIG_LV_Z_DOUBLE_VDB=y
|
|||||||
CONFIG_LV_Z_MEM_POOL_SIZE=16384
|
CONFIG_LV_Z_MEM_POOL_SIZE=16384
|
||||||
CONFIG_LV_USE_LABEL=y
|
CONFIG_LV_USE_LABEL=y
|
||||||
CONFIG_LV_FONT_MONTSERRAT_14=y
|
CONFIG_LV_FONT_MONTSERRAT_14=y
|
||||||
|
CONFIG_LV_FONT_MONTSERRAT_32=y
|
||||||
CONFIG_MAIN_STACK_SIZE=4096
|
CONFIG_MAIN_STACK_SIZE=4096
|
||||||
|
|||||||
@@ -13,6 +13,9 @@
|
|||||||
#include <zephyr/drivers/led.h>
|
#include <zephyr/drivers/led.h>
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
|
|
||||||
|
#include "bat_state_event.h"
|
||||||
|
#include "hid_led_event.h"
|
||||||
|
#include "mode_switch_event.h"
|
||||||
#include "ui/ui_main.h"
|
#include "ui/ui_main.h"
|
||||||
|
|
||||||
LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF);
|
LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF);
|
||||||
@@ -26,6 +29,11 @@ static const struct device *const display_dev =
|
|||||||
static const struct device *const backlight_dev =
|
static const struct device *const backlight_dev =
|
||||||
DEVICE_DT_GET(DT_PARENT(DT_ALIAS(backlight)));
|
DEVICE_DT_GET(DT_PARENT(DT_ALIAS(backlight)));
|
||||||
static const uint32_t backlight_idx = DT_NODE_CHILD_IDX(DT_ALIAS(backlight));
|
static const uint32_t backlight_idx = DT_NODE_CHILD_IDX(DT_ALIAS(backlight));
|
||||||
|
static struct ui_main_model ui_model = {
|
||||||
|
.theme_color = LV_COLOR_MAKE(0x4C, 0x9E, 0xF5),
|
||||||
|
.inactive_border_color = LV_COLOR_MAKE(0x3A, 0x44, 0x52),
|
||||||
|
.mode = MODE_SWITCH_BLE,
|
||||||
|
};
|
||||||
static bool initialized;
|
static bool initialized;
|
||||||
static bool running;
|
static bool running;
|
||||||
static bool lvgl_initialized;
|
static bool lvgl_initialized;
|
||||||
@@ -82,7 +90,7 @@ static int module_start(void)
|
|||||||
lvgl_initialized = true;
|
lvgl_initialized = true;
|
||||||
|
|
||||||
lvgl_lock();
|
lvgl_lock();
|
||||||
ui_main_init();
|
ui_main_init(&ui_model, "WH Mini", "Hello World");
|
||||||
lvgl_unlock();
|
lvgl_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,8 +125,45 @@ static void module_pause(void)
|
|||||||
LOG_INF("LVGL display paused");
|
LOG_INF("LVGL display paused");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void refresh_ui(void)
|
||||||
|
{
|
||||||
|
if (!lvgl_initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lvgl_lock();
|
||||||
|
ui_main_refresh_all(&ui_model, "WH Mini", "Hello World");
|
||||||
|
lvgl_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
static bool app_event_handler(const struct app_event_header *aeh)
|
static bool app_event_handler(const struct app_event_header *aeh)
|
||||||
{
|
{
|
||||||
|
if (is_bat_state_event(aeh)) {
|
||||||
|
const struct bat_state_event *event = cast_bat_state_event(aeh);
|
||||||
|
|
||||||
|
ui_model.battery_level = event->soc;
|
||||||
|
ui_model.charging = event->charging;
|
||||||
|
ui_model.full = event->full;
|
||||||
|
refresh_ui();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_mode_switch_event(aeh)) {
|
||||||
|
const struct mode_switch_event *event = cast_mode_switch_event(aeh);
|
||||||
|
|
||||||
|
ui_model.mode = event->mode;
|
||||||
|
refresh_ui();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_hid_led_event(aeh)) {
|
||||||
|
const struct hid_led_event *event = cast_hid_led_event(aeh);
|
||||||
|
|
||||||
|
ui_model.led_mask = event->led_bm;
|
||||||
|
refresh_ui();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (is_module_state_event(aeh)) {
|
if (is_module_state_event(aeh)) {
|
||||||
const struct module_state_event *event = cast_module_state_event(aeh);
|
const struct module_state_event *event = cast_module_state_event(aeh);
|
||||||
int err;
|
int err;
|
||||||
@@ -172,6 +217,9 @@ static bool app_event_handler(const struct app_event_header *aeh)
|
|||||||
}
|
}
|
||||||
|
|
||||||
APP_EVENT_LISTENER(MODULE, app_event_handler);
|
APP_EVENT_LISTENER(MODULE, app_event_handler);
|
||||||
|
APP_EVENT_SUBSCRIBE(MODULE, bat_state_event);
|
||||||
|
APP_EVENT_SUBSCRIBE(MODULE, hid_led_event);
|
||||||
APP_EVENT_SUBSCRIBE(MODULE, module_state_event);
|
APP_EVENT_SUBSCRIBE(MODULE, module_state_event);
|
||||||
|
APP_EVENT_SUBSCRIBE(MODULE, mode_switch_event);
|
||||||
APP_EVENT_SUBSCRIBE_EARLY(MODULE, power_down_event);
|
APP_EVENT_SUBSCRIBE_EARLY(MODULE, power_down_event);
|
||||||
APP_EVENT_SUBSCRIBE(MODULE, wake_up_event);
|
APP_EVENT_SUBSCRIBE(MODULE, wake_up_event);
|
||||||
|
|||||||
289
src/ui/ui_main.c
289
src/ui/ui_main.c
@@ -1,34 +1,291 @@
|
|||||||
#include <stdbool.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
|
#include <zephyr/sys/printk.h>
|
||||||
|
|
||||||
#include "ui_main.h"
|
#include "ui_main.h"
|
||||||
|
|
||||||
|
enum ui_status_id {
|
||||||
|
UI_STATUS_USB = 0,
|
||||||
|
UI_STATUS_BLE,
|
||||||
|
UI_STATUS_NUMLOCK,
|
||||||
|
UI_STATUS_CAPSLOCK,
|
||||||
|
UI_STATUS_COUNT,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
UI_LED_MASK_NUM_LOCK = BIT(0),
|
||||||
|
UI_LED_MASK_CAPS_LOCK = BIT(1),
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ui_main_ctx {
|
||||||
|
lv_obj_t *status_badges[UI_STATUS_COUNT];
|
||||||
|
lv_obj_t *status_labels[UI_STATUS_COUNT];
|
||||||
|
lv_obj_t *battery_icon;
|
||||||
|
lv_obj_t *battery_label;
|
||||||
|
lv_obj_t *battery_state_label;
|
||||||
|
lv_obj_t *date_label;
|
||||||
|
lv_obj_t *time_label;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ui_main_ctx g_ui;
|
||||||
static bool ui_initialized;
|
static bool ui_initialized;
|
||||||
|
|
||||||
void ui_main_init(void)
|
static const char *const status_texts[UI_STATUS_COUNT] = {
|
||||||
|
LV_SYMBOL_USB,
|
||||||
|
LV_SYMBOL_BLUETOOTH,
|
||||||
|
"1",
|
||||||
|
"A",
|
||||||
|
};
|
||||||
|
|
||||||
|
static lv_color_t ui_main_get_battery_color(uint8_t battery_level)
|
||||||
{
|
{
|
||||||
lv_obj_t *screen;
|
if (battery_level > 70U) {
|
||||||
lv_obj_t *title;
|
return lv_color_hex(0x8BD450);
|
||||||
lv_obj_t *subtitle;
|
}
|
||||||
|
|
||||||
|
if (battery_level >= 20U) {
|
||||||
|
return lv_color_hex(0xF4D35E);
|
||||||
|
}
|
||||||
|
|
||||||
|
return lv_color_hex(0xE63946);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *ui_main_get_battery_symbol(uint8_t battery_level)
|
||||||
|
{
|
||||||
|
if (battery_level > 85U) {
|
||||||
|
return LV_SYMBOL_BATTERY_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (battery_level > 60U) {
|
||||||
|
return LV_SYMBOL_BATTERY_3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (battery_level > 35U) {
|
||||||
|
return LV_SYMBOL_BATTERY_2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (battery_level >= 20U) {
|
||||||
|
return LV_SYMBOL_BATTERY_1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return LV_SYMBOL_BATTERY_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ui_main_status_is_active(enum ui_status_id id,
|
||||||
|
const struct ui_main_model *model)
|
||||||
|
{
|
||||||
|
switch (id) {
|
||||||
|
case UI_STATUS_USB:
|
||||||
|
return model->mode == MODE_SWITCH_USB;
|
||||||
|
|
||||||
|
case UI_STATUS_BLE:
|
||||||
|
return model->mode == MODE_SWITCH_BLE;
|
||||||
|
|
||||||
|
case UI_STATUS_NUMLOCK:
|
||||||
|
return (model->led_mask & UI_LED_MASK_NUM_LOCK) != 0U;
|
||||||
|
|
||||||
|
case UI_STATUS_CAPSLOCK:
|
||||||
|
return (model->led_mask & UI_LED_MASK_CAPS_LOCK) != 0U;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ui_main_create_status_chip(lv_obj_t *parent, enum ui_status_id id)
|
||||||
|
{
|
||||||
|
lv_obj_t *badge = lv_obj_create(parent);
|
||||||
|
lv_obj_t *label = lv_label_create(badge);
|
||||||
|
|
||||||
|
lv_obj_remove_style_all(badge);
|
||||||
|
lv_obj_set_size(badge, 50, 32);
|
||||||
|
lv_obj_set_style_radius(badge, 10, 0);
|
||||||
|
lv_obj_set_style_bg_opa(badge, LV_OPA_COVER, 0);
|
||||||
|
lv_obj_set_style_pad_all(badge, 0, 0);
|
||||||
|
|
||||||
|
lv_label_set_text(label, status_texts[id]);
|
||||||
|
lv_obj_set_width(label, LV_PCT(100));
|
||||||
|
lv_obj_set_style_text_font(label, &lv_font_montserrat_14, 0);
|
||||||
|
lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0);
|
||||||
|
lv_obj_center(label);
|
||||||
|
|
||||||
|
g_ui.status_badges[id] = badge;
|
||||||
|
g_ui.status_labels[id] = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_main_refresh_status_bar(const struct ui_main_model *model)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < UI_STATUS_COUNT; i++) {
|
||||||
|
lv_obj_t *badge = g_ui.status_badges[i];
|
||||||
|
lv_obj_t *label = g_ui.status_labels[i];
|
||||||
|
bool active = ui_main_status_is_active((enum ui_status_id)i, model);
|
||||||
|
|
||||||
|
if ((badge == NULL) || (label == NULL)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_obj_set_style_border_width(badge, 3, 0);
|
||||||
|
lv_obj_set_style_border_color(
|
||||||
|
badge,
|
||||||
|
active ? model->theme_color : model->inactive_border_color, 0);
|
||||||
|
lv_obj_set_style_bg_color(
|
||||||
|
badge,
|
||||||
|
active ? lv_color_hex(0x1D2735) : lv_color_hex(0x161A20), 0);
|
||||||
|
lv_obj_set_style_text_color(
|
||||||
|
label,
|
||||||
|
active ? lv_color_white() : lv_color_hex(0x7C8798), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_main_refresh_battery(const struct ui_main_model *model)
|
||||||
|
{
|
||||||
|
char battery_text[8];
|
||||||
|
const char *state_symbol = "";
|
||||||
|
lv_color_t battery_color;
|
||||||
|
lv_color_t state_color = lv_color_white();
|
||||||
|
|
||||||
|
if ((g_ui.battery_icon == NULL) || (g_ui.battery_label == NULL) ||
|
||||||
|
(g_ui.battery_state_label == NULL)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
battery_color = ui_main_get_battery_color(model->battery_level);
|
||||||
|
snprintk(battery_text, sizeof(battery_text), "%u%%", model->battery_level);
|
||||||
|
|
||||||
|
if (model->full) {
|
||||||
|
state_symbol = LV_SYMBOL_USB;
|
||||||
|
state_color = lv_color_hex(0x4C9EF5);
|
||||||
|
} else if (model->charging) {
|
||||||
|
state_symbol = LV_SYMBOL_CHARGE;
|
||||||
|
state_color = lv_color_hex(0xF4D35E);
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_label_set_text(g_ui.battery_icon,
|
||||||
|
ui_main_get_battery_symbol(model->battery_level));
|
||||||
|
lv_obj_set_style_text_color(g_ui.battery_icon, battery_color, 0);
|
||||||
|
lv_label_set_text(g_ui.battery_label, battery_text);
|
||||||
|
lv_label_set_text(g_ui.battery_state_label, state_symbol);
|
||||||
|
lv_obj_set_style_text_color(g_ui.battery_state_label, state_color, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_main_refresh_datetime(const char *date_text, const char *time_text)
|
||||||
|
{
|
||||||
|
if ((g_ui.date_label == NULL) || (g_ui.time_label == NULL)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_label_set_text(g_ui.date_label, date_text);
|
||||||
|
lv_label_set_text(g_ui.time_label, time_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_main_refresh_all(const struct ui_main_model *model,
|
||||||
|
const char *date_text,
|
||||||
|
const char *time_text)
|
||||||
|
{
|
||||||
|
ui_main_refresh_status_bar(model);
|
||||||
|
ui_main_refresh_battery(model);
|
||||||
|
ui_main_refresh_datetime(date_text, time_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_main_init(const struct ui_main_model *model,
|
||||||
|
const char *date_text,
|
||||||
|
const char *time_text)
|
||||||
|
{
|
||||||
|
lv_obj_t *screen = lv_screen_active();
|
||||||
|
lv_obj_t *content;
|
||||||
|
lv_obj_t *top_row;
|
||||||
|
lv_obj_t *battery_wrap;
|
||||||
|
lv_obj_t *middle_row;
|
||||||
|
lv_obj_t *bottom_row;
|
||||||
|
|
||||||
if (ui_initialized) {
|
if (ui_initialized) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
screen = lv_screen_active();
|
memset(&g_ui, 0, sizeof(g_ui));
|
||||||
lv_obj_set_style_bg_color(screen, lv_color_hex(0x101418), 0);
|
|
||||||
lv_obj_set_style_text_color(screen, lv_color_hex(0xF5F7FA), 0);
|
|
||||||
|
|
||||||
title = lv_label_create(screen);
|
lv_obj_clean(screen);
|
||||||
lv_label_set_text(title, "Hello World");
|
lv_obj_set_style_bg_color(screen, lv_color_hex(0x0F1115), 0);
|
||||||
lv_obj_set_style_text_font(title, &lv_font_montserrat_14, 0);
|
lv_obj_set_style_bg_grad_color(screen, lv_color_hex(0x1A1F29), 0);
|
||||||
lv_obj_align(title, LV_ALIGN_CENTER, 0, -10);
|
lv_obj_set_style_bg_grad_dir(screen, LV_GRAD_DIR_VER, 0);
|
||||||
|
lv_obj_set_style_bg_opa(screen, LV_OPA_COVER, 0);
|
||||||
|
lv_obj_set_style_text_color(screen, lv_color_white(), 0);
|
||||||
|
lv_obj_set_style_pad_all(screen, 0, 0);
|
||||||
|
lv_obj_set_scrollbar_mode(screen, LV_SCROLLBAR_MODE_OFF);
|
||||||
|
|
||||||
subtitle = lv_label_create(screen);
|
content = lv_obj_create(screen);
|
||||||
lv_label_set_text(subtitle, "WH Mini Keyboard");
|
lv_obj_remove_style_all(content);
|
||||||
lv_obj_set_style_text_opa(subtitle, LV_OPA_70, 0);
|
lv_obj_set_size(content, LV_PCT(100), LV_PCT(100));
|
||||||
lv_obj_align(subtitle, LV_ALIGN_CENTER, 0, 14);
|
lv_obj_set_style_bg_opa(content, LV_OPA_TRANSP, 0);
|
||||||
|
lv_obj_set_style_pad_left(content, 14, 0);
|
||||||
|
lv_obj_set_style_pad_right(content, 14, 0);
|
||||||
|
lv_obj_set_style_pad_top(content, 8, 0);
|
||||||
|
lv_obj_set_style_pad_bottom(content, 8, 0);
|
||||||
|
lv_obj_set_layout(content, LV_LAYOUT_FLEX);
|
||||||
|
lv_obj_set_flex_flow(content, LV_FLEX_FLOW_COLUMN);
|
||||||
|
lv_obj_set_flex_align(content, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER,
|
||||||
|
LV_FLEX_ALIGN_CENTER);
|
||||||
|
|
||||||
|
top_row = lv_obj_create(content);
|
||||||
|
lv_obj_remove_style_all(top_row);
|
||||||
|
lv_obj_set_width(top_row, LV_PCT(100));
|
||||||
|
lv_obj_set_flex_grow(top_row, 1);
|
||||||
|
lv_obj_set_style_bg_opa(top_row, LV_OPA_TRANSP, 0);
|
||||||
|
lv_obj_set_layout(top_row, LV_LAYOUT_FLEX);
|
||||||
|
lv_obj_set_flex_flow(top_row, LV_FLEX_FLOW_ROW);
|
||||||
|
lv_obj_set_flex_align(top_row, LV_FLEX_ALIGN_SPACE_BETWEEN,
|
||||||
|
LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||||
|
|
||||||
|
g_ui.date_label = lv_label_create(top_row);
|
||||||
|
lv_obj_set_style_text_font(g_ui.date_label, &lv_font_montserrat_14, 0);
|
||||||
|
lv_obj_set_style_text_color(g_ui.date_label, lv_color_hex(0xD8DEE9), 0);
|
||||||
|
|
||||||
|
battery_wrap = lv_obj_create(top_row);
|
||||||
|
lv_obj_remove_style_all(battery_wrap);
|
||||||
|
lv_obj_set_width(battery_wrap, LV_SIZE_CONTENT);
|
||||||
|
lv_obj_set_layout(battery_wrap, LV_LAYOUT_FLEX);
|
||||||
|
lv_obj_set_flex_flow(battery_wrap, LV_FLEX_FLOW_ROW);
|
||||||
|
lv_obj_set_flex_align(battery_wrap, LV_FLEX_ALIGN_CENTER,
|
||||||
|
LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||||
|
lv_obj_set_style_pad_column(battery_wrap, 4, 0);
|
||||||
|
|
||||||
|
g_ui.battery_icon = lv_label_create(battery_wrap);
|
||||||
|
lv_obj_set_style_text_font(g_ui.battery_icon, &lv_font_montserrat_14, 0);
|
||||||
|
|
||||||
|
g_ui.battery_label = lv_label_create(battery_wrap);
|
||||||
|
lv_obj_set_style_text_font(g_ui.battery_label, &lv_font_montserrat_14, 0);
|
||||||
|
lv_obj_set_style_text_color(g_ui.battery_label, lv_color_hex(0xD8DEE9), 0);
|
||||||
|
|
||||||
|
g_ui.battery_state_label = lv_label_create(battery_wrap);
|
||||||
|
lv_obj_set_style_text_font(g_ui.battery_state_label, &lv_font_montserrat_14, 0);
|
||||||
|
|
||||||
|
middle_row = lv_obj_create(content);
|
||||||
|
lv_obj_remove_style_all(middle_row);
|
||||||
|
lv_obj_set_width(middle_row, LV_PCT(100));
|
||||||
|
lv_obj_set_flex_grow(middle_row, 2);
|
||||||
|
lv_obj_set_style_bg_opa(middle_row, LV_OPA_TRANSP, 0);
|
||||||
|
|
||||||
|
g_ui.time_label = lv_label_create(middle_row);
|
||||||
|
lv_obj_set_style_text_font(g_ui.time_label, &lv_font_montserrat_32, 0);
|
||||||
|
lv_obj_set_style_text_color(g_ui.time_label, lv_color_white(), 0);
|
||||||
|
lv_obj_center(g_ui.time_label);
|
||||||
|
|
||||||
|
bottom_row = lv_obj_create(content);
|
||||||
|
lv_obj_remove_style_all(bottom_row);
|
||||||
|
lv_obj_set_width(bottom_row, LV_PCT(100));
|
||||||
|
lv_obj_set_flex_grow(bottom_row, 1);
|
||||||
|
lv_obj_set_style_bg_opa(bottom_row, LV_OPA_TRANSP, 0);
|
||||||
|
lv_obj_set_layout(bottom_row, LV_LAYOUT_FLEX);
|
||||||
|
lv_obj_set_flex_flow(bottom_row, LV_FLEX_FLOW_ROW);
|
||||||
|
lv_obj_set_flex_align(bottom_row, LV_FLEX_ALIGN_CENTER,
|
||||||
|
LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||||
|
lv_obj_set_style_pad_column(bottom_row, 6, 0);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < UI_STATUS_COUNT; i++) {
|
||||||
|
ui_main_create_status_chip(bottom_row, (enum ui_status_id)i);
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_main_refresh_all(model, date_text, time_text);
|
||||||
ui_initialized = true;
|
ui_initialized = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,36 @@
|
|||||||
#ifndef BLINKY_UI_MAIN_H_
|
#ifndef BLINKY_UI_MAIN_H_
|
||||||
#define BLINKY_UI_MAIN_H_
|
#define BLINKY_UI_MAIN_H_
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <lvgl.h>
|
||||||
|
|
||||||
|
#include "mode_switch_event.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void ui_main_init(void);
|
struct ui_main_model {
|
||||||
|
lv_color_t theme_color;
|
||||||
|
lv_color_t inactive_border_color;
|
||||||
|
uint8_t battery_level;
|
||||||
|
enum mode_switch_mode mode;
|
||||||
|
uint8_t led_mask;
|
||||||
|
bool charging;
|
||||||
|
bool full;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ui_main_init(const struct ui_main_model *model,
|
||||||
|
const char *date_text,
|
||||||
|
const char *time_text);
|
||||||
|
void ui_main_refresh_all(const struct ui_main_model *model,
|
||||||
|
const char *date_text,
|
||||||
|
const char *time_text);
|
||||||
|
void ui_main_refresh_status_bar(const struct ui_main_model *model);
|
||||||
|
void ui_main_refresh_battery(const struct ui_main_model *model);
|
||||||
|
void ui_main_refresh_datetime(const char *date_text, const char *time_text);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user