Files
esp32s3_player/main/APP/ui_common.c
T

164 lines
5.0 KiB
C

/**
****************************************************************************************************
* @file ui_common.c
* @author HiFi Player Project
* @version V1.2
* @date 2026-01-01
* @brief 界面共用组件实现
****************************************************************************************************
*/
#include "ui_common.h"
#include <stdio.h>
#include <string.h>
/* 底部按键提示条的布局参数 */
#define KEY_BAR_Y 196
#define KEY_BAR_W 74
#define KEY_BAR_H 40
#define KEY_BAR_GAP 4
#define KEY_BAR_X0 6
void ui_style_screen(lv_obj_t *scr)
{
lv_obj_clear_flag(scr, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_style_bg_color(scr, lv_color_hex(UI_COL_BG), LV_PART_MAIN);
lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_pad_all(scr, 0, LV_PART_MAIN);
lv_obj_set_style_text_color(scr, lv_color_hex(UI_COL_TEXT), LV_PART_MAIN);
}
lv_obj_t *ui_card(lv_obj_t *parent, lv_coord_t x, lv_coord_t y,
lv_coord_t w, lv_coord_t h, uint32_t color, lv_coord_t radius)
{
lv_obj_t *obj = lv_obj_create(parent);
lv_obj_set_pos(obj, x, y);
lv_obj_set_size(obj, w, h);
lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_style_bg_color(obj, lv_color_hex(color), LV_PART_MAIN);
lv_obj_set_style_bg_opa(obj, LV_OPA_COVER, LV_PART_MAIN);
lv_obj_set_style_radius(obj, radius, LV_PART_MAIN);
lv_obj_set_style_border_width(obj, 0, LV_PART_MAIN);
lv_obj_set_style_pad_all(obj, 0, LV_PART_MAIN);
return obj;
}
lv_obj_t *ui_label(lv_obj_t *parent, const char *text,
const lv_font_t *font, uint32_t color)
{
lv_obj_t *label = lv_label_create(parent);
lv_label_set_text(label, text);
lv_obj_set_style_text_font(label, font, LV_PART_MAIN);
lv_obj_set_style_text_color(label, lv_color_hex(color), LV_PART_MAIN);
return label;
}
void ui_label_set_if_changed(lv_obj_t *label, const char *text)
{
if (strcmp(lv_label_get_text(label), text) != 0)
{
lv_label_set_text(label, text);
}
}
void ui_format_time(uint32_t seconds, char *buffer, size_t size)
{
snprintf(buffer, size, "%02u:%02u",
(unsigned)((seconds / 60) % 100), (unsigned)(seconds % 60));
}
/* ---------------- 按键提示条 ---------------- */
void ui_key_bar_create(lv_obj_t *parent, ui_key_bar_t *bar,
const char *const symbols[APP_KEY_NUM],
const char *const captions[APP_KEY_NUM],
const bool enabled[APP_KEY_NUM])
{
memset(bar, 0, sizeof(*bar));
bar->highlight = -1;
for (int i = 0; i < APP_KEY_NUM; i++)
{
bool en = enabled[i];
bar->enabled[i] = en;
lv_obj_t *card = ui_card(parent,
(lv_coord_t)(KEY_BAR_X0 + i * (KEY_BAR_W + KEY_BAR_GAP)),
KEY_BAR_Y, KEY_BAR_W, KEY_BAR_H, UI_COL_CARD, 8);
bar->card[i] = card;
bar->icon[i] = ui_label(card, (symbols != NULL) ? symbols[i] : "",
&lv_font_montserrat_16, en ? UI_COL_ACCENT : UI_COL_DIM);
lv_obj_align(bar->icon[i], LV_ALIGN_TOP_MID, 0, 2);
bar->caption[i] = ui_label(card, captions[i], &lv_font_montserrat_12,
en ? UI_COL_SUB : UI_COL_DIM);
lv_obj_align(bar->caption[i], LV_ALIGN_BOTTOM_MID, 0, -3);
}
}
void ui_key_bar_set_highlight(ui_key_bar_t *bar, int index)
{
if (bar->highlight == index)
{
return; /* 状态未变化,避免无谓重绘 */
}
bar->highlight = index;
for (int i = 0; i < APP_KEY_NUM; i++)
{
bool on = (i == index) && bar->enabled[i];
lv_obj_set_style_bg_color(bar->card[i], lv_color_hex(on ? UI_COL_ACCENT : UI_COL_CARD),
LV_PART_MAIN);
lv_obj_set_style_text_color(bar->icon[i],
lv_color_hex(bar->enabled[i] ? (on ? UI_COL_BG : UI_COL_ACCENT)
: UI_COL_DIM),
LV_PART_MAIN);
}
}
void ui_key_bar_set_icon(ui_key_bar_t *bar, int key, const char *symbol)
{
if ((key < 0) || (key >= APP_KEY_NUM) || (symbol == NULL))
{
return;
}
ui_label_set_if_changed(bar->icon[key], symbol);
}
void ui_key_bar_set_caption(ui_key_bar_t *bar, int key, const char *caption)
{
if ((key < 0) || (key >= APP_KEY_NUM) || (caption == NULL))
{
return;
}
ui_label_set_if_changed(bar->caption[key], caption);
}
/* ---------------- 按键高亮 ---------------- */
void ui_flash_trigger(ui_flash_t *flash, int key)
{
flash->key = key;
flash->tick = lv_tick_get();
}
int ui_flash_active(const ui_flash_t *flash)
{
if ((flash->key < 0) || (flash->key >= APP_KEY_NUM))
{
return -1;
}
return (lv_tick_elaps(flash->tick) < UI_KEY_FLASH_MS) ? (int)flash->key : -1;
}