660 lines
20 KiB
C
660 lines
20 KiB
C
#include "ui_music.h"
|
||
#include "img_bg.h"
|
||
#include "kt_ui.h"
|
||
#include "kt.h"
|
||
#include "key_event_deal.h"
|
||
#include "lvgl.h"
|
||
#include "drv_st7789.h"
|
||
#include "system/fs/fs.h"
|
||
#include "dev_manager/dev_manager.h"
|
||
#include "system/app_msg.h"
|
||
#include "app_config.h"
|
||
#include "music_player.h"
|
||
#include "eye_led.h"
|
||
|
||
#define MUSIC_SCAN_PARAM "-tMP1MP2MP3 -sn -r"
|
||
#define FILE_NAME_BUF_SIZE 128
|
||
#define SHORT_NAME_LEN 13 /* 8.3 + null */
|
||
#define LED_MODE_COUNT 8
|
||
|
||
#define LIST_TOP 36
|
||
#define LIST_ROWS 6
|
||
#define ROW_GAP 1
|
||
#define LIST_AVAIL_H (LCD_H - 50 - LIST_TOP) /* BAR_Y - LIST_TOP = 154 */
|
||
#define ROW_H ((LIST_AVAIL_H - (LIST_ROWS - 1) * ROW_GAP) / LIST_ROWS) /* 每行约 24px,保证6行容纳 */
|
||
#define LIST_H (LIST_ROWS * ROW_H + (LIST_ROWS - 1) * ROW_GAP)
|
||
#define LIST_W ((LCD_W - 16) / 2 - 4) /* 左右各一半,中间留缝 */
|
||
|
||
#define BAR_W (LCD_W - 48)
|
||
#define BAR_X 24
|
||
#define BAR_H 14
|
||
#define BAR_Y (LCD_H - 45)
|
||
#define TIME_Y (BAR_Y + BAR_H + 7)
|
||
|
||
static lv_obj_t *file_list = NULL;
|
||
static lv_obj_t *bar_progress = NULL;
|
||
static lv_obj_t *label_curr_time = NULL;
|
||
static lv_obj_t *label_total_time = NULL;
|
||
static lv_obj_t *led_list = NULL;
|
||
static struct vfscan *file_scan_fs = NULL;
|
||
#if defined(TCFG_LFN_EN) && TCFG_LFN_EN
|
||
static u8 lfn_buf[512];
|
||
#endif
|
||
|
||
/* 设置模式:长按 PP 进入;先选 list(红框),再 ENTER 进入行选择 */
|
||
static u8 setting_flag = 0;
|
||
#define FOCUS_LIST_FILE 0
|
||
#define FOCUS_LIST_LED 1
|
||
#define ROW_SELECT_LIST 0 /* 选择列表(红框) */
|
||
#define ROW_SELECT_ROW 1 /* 选择行(行内循环) */
|
||
static u8 row_select_mode = ROW_SELECT_LIST; /* 0=list 选择,1=行选择 */
|
||
static u8 focus_list_id = FOCUS_LIST_FILE; /* 当前选中的列表 */
|
||
static int focus_idx = 0; /* 行选择时当前列表内的索引 */
|
||
|
||
void ui_music_update_led_mode_item(u8 mode);
|
||
|
||
static int get_file_count(void)
|
||
{
|
||
int n = 0;
|
||
if (file_list)
|
||
{
|
||
uint32_t cnt = lv_obj_get_child_cnt(file_list);
|
||
for (uint32_t i = 0; i < cnt; i++)
|
||
{
|
||
lv_obj_t *c = lv_obj_get_child(file_list, i);
|
||
if (lv_obj_get_user_data(c) != NULL)
|
||
n++;
|
||
}
|
||
}
|
||
return n;
|
||
}
|
||
|
||
static void clear_focus_style(lv_obj_t *btn)
|
||
{
|
||
lv_obj_set_style_bg_opa(btn, LV_OPA_TRANSP, 0);
|
||
}
|
||
|
||
static void set_focus_style(lv_obj_t *btn)
|
||
{
|
||
lv_obj_set_style_bg_opa(btn, LV_OPA_COVER, 0);
|
||
lv_obj_set_style_bg_color(btn, lv_color_hex(0x333333), 0); /* 反显:深色底 */
|
||
lv_obj_scroll_to_view(btn, LV_ANIM_OFF); /* 滚动到可见 */
|
||
}
|
||
|
||
#define BORDER_NORMAL 0xCCCCCC
|
||
#define BORDER_SELECT 0xFF0000
|
||
|
||
/* 更新 list 外框颜色:list 选择模式下,选中项红框 */
|
||
static void update_list_border_style(void)
|
||
{
|
||
if (!file_list || !led_list)
|
||
return;
|
||
lv_color_t file_c = (row_select_mode == ROW_SELECT_LIST && focus_list_id == FOCUS_LIST_FILE)
|
||
? lv_color_hex(BORDER_SELECT) : lv_color_hex(BORDER_NORMAL);
|
||
lv_color_t led_c = (row_select_mode == ROW_SELECT_LIST && focus_list_id == FOCUS_LIST_LED)
|
||
? lv_color_hex(BORDER_SELECT) : lv_color_hex(BORDER_NORMAL);
|
||
lv_obj_set_style_border_color(file_list, file_c, 0);
|
||
lv_obj_set_style_border_color(led_list, led_c, 0);
|
||
}
|
||
|
||
/* 根据 focus_list_id + focus_idx 更新焦点样式(行选择模式才显示行焦点) */
|
||
static void update_focus_style(void)
|
||
{
|
||
update_list_border_style();
|
||
|
||
if (row_select_mode != ROW_SELECT_ROW)
|
||
{
|
||
/* list 选择模式:清除所有行焦点 */
|
||
if (file_list)
|
||
{
|
||
uint32_t cnt = lv_obj_get_child_cnt(file_list);
|
||
for (uint32_t i = 0; i < cnt; i++)
|
||
clear_focus_style(lv_obj_get_child(file_list, i));
|
||
}
|
||
if (led_list)
|
||
{
|
||
for (int i = 0; i < LED_MODE_COUNT; i++)
|
||
{
|
||
lv_obj_t *c = lv_obj_get_child(led_list, i);
|
||
if (c)
|
||
clear_focus_style(c);
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
/* 行选择模式:修正 focus_idx,标亮当前行 */
|
||
int file_cnt = get_file_count();
|
||
if (focus_list_id == FOCUS_LIST_FILE)
|
||
{
|
||
if (file_cnt > 0 && focus_idx >= file_cnt)
|
||
focus_idx = 0;
|
||
}
|
||
else
|
||
{
|
||
if (focus_idx >= LED_MODE_COUNT)
|
||
focus_idx = 0;
|
||
}
|
||
|
||
int file_i = 0;
|
||
if (file_list)
|
||
{
|
||
uint32_t cnt = lv_obj_get_child_cnt(file_list);
|
||
for (uint32_t i = 0; i < cnt; i++)
|
||
{
|
||
lv_obj_t *c = lv_obj_get_child(file_list, i);
|
||
if (lv_obj_get_user_data(c) != NULL)
|
||
{
|
||
if (focus_list_id == FOCUS_LIST_FILE && focus_idx == file_i)
|
||
set_focus_style(c);
|
||
else
|
||
clear_focus_style(c);
|
||
file_i++;
|
||
}
|
||
}
|
||
}
|
||
if (led_list)
|
||
{
|
||
for (int i = 0; i < LED_MODE_COUNT; i++)
|
||
{
|
||
lv_obj_t *c = lv_obj_get_child(led_list, i);
|
||
if (c)
|
||
{
|
||
if (focus_list_id == FOCUS_LIST_LED && focus_idx == i)
|
||
set_focus_style(c);
|
||
else
|
||
clear_focus_style(c);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* NEXT/PREV: list 选择模式下切换 list;行选择模式下仅在当前 list 内循环 */
|
||
static void focus_next(void)
|
||
{
|
||
if (row_select_mode == ROW_SELECT_LIST)
|
||
{
|
||
focus_list_id = (focus_list_id == FOCUS_LIST_FILE) ? FOCUS_LIST_LED : FOCUS_LIST_FILE;
|
||
}
|
||
else
|
||
{
|
||
if (focus_list_id == FOCUS_LIST_FILE)
|
||
{
|
||
int n = get_file_count();
|
||
if (n <= 0)
|
||
return;
|
||
focus_idx = (focus_idx + 1) % n;
|
||
}
|
||
else
|
||
focus_idx = (focus_idx + 1) % LED_MODE_COUNT;
|
||
}
|
||
update_focus_style();
|
||
}
|
||
|
||
static void focus_prev(void)
|
||
{
|
||
if (row_select_mode == ROW_SELECT_LIST)
|
||
{
|
||
focus_list_id = (focus_list_id == FOCUS_LIST_FILE) ? FOCUS_LIST_LED : FOCUS_LIST_FILE;
|
||
}
|
||
else
|
||
{
|
||
if (focus_list_id == FOCUS_LIST_FILE)
|
||
{
|
||
int n = get_file_count();
|
||
if (n <= 0)
|
||
return;
|
||
focus_idx = (focus_idx - 1 + n) % n;
|
||
}
|
||
else
|
||
focus_idx = (focus_idx - 1 + LED_MODE_COUNT) % LED_MODE_COUNT;
|
||
}
|
||
update_focus_style();
|
||
}
|
||
|
||
static void focus_exit_setting(void);
|
||
|
||
/* 确认键:list 选择时进入行选择;行选择时确认并退出设置 */
|
||
static void focus_confirm(void)
|
||
{
|
||
if (row_select_mode == ROW_SELECT_LIST)
|
||
{
|
||
row_select_mode = ROW_SELECT_ROW;
|
||
focus_idx = 0;
|
||
if (focus_list_id == FOCUS_LIST_FILE)
|
||
{
|
||
int n = get_file_count();
|
||
if (n <= 0)
|
||
row_select_mode = ROW_SELECT_LIST; /* 空列表不进入 */
|
||
}
|
||
}
|
||
else
|
||
{
|
||
/* 行选择确认:file 播放选中曲目,LED 仅退出 */
|
||
if (focus_list_id == FOCUS_LIST_FILE)
|
||
{
|
||
int file_i = 0;
|
||
uint32_t cnt = file_list ? lv_obj_get_child_cnt(file_list) : 0;
|
||
for (uint32_t i = 0; i < cnt; i++)
|
||
{
|
||
lv_obj_t *c = lv_obj_get_child(file_list, i);
|
||
if (lv_obj_get_user_data(c) != NULL)
|
||
{
|
||
if (file_i == focus_idx)
|
||
{
|
||
u32 sclust = (u32)(uintptr_t)lv_obj_get_user_data(c);
|
||
app_task_put_key_msg(KEY_MUSIC_PLAYE_BY_DEV_SCLUST, (int)sclust);
|
||
break;
|
||
}
|
||
file_i++;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
eye_led_stop();
|
||
eye_led_set_mode((u8)(focus_idx + 1));
|
||
eye_led_start();
|
||
ui_music_update_led_mode_item((u8)(focus_idx + 1));
|
||
}
|
||
setting_flag = 0;
|
||
focus_exit_setting();
|
||
return;
|
||
}
|
||
update_focus_style();
|
||
}
|
||
|
||
static void focus_enter_setting(void)
|
||
{
|
||
row_select_mode = ROW_SELECT_LIST;
|
||
focus_list_id = FOCUS_LIST_FILE; /* 默认选中 file_list */
|
||
focus_idx = 0;
|
||
int file_cnt = get_file_count();
|
||
if (file_cnt <= 0)
|
||
focus_list_id = FOCUS_LIST_LED;
|
||
update_focus_style();
|
||
}
|
||
|
||
static void focus_exit_setting(void)
|
||
{
|
||
row_select_mode = ROW_SELECT_LIST;
|
||
if (file_list)
|
||
lv_obj_set_style_border_color(file_list, lv_color_hex(BORDER_NORMAL), 0);
|
||
if (led_list)
|
||
lv_obj_set_style_border_color(led_list, lv_color_hex(BORDER_NORMAL), 0);
|
||
if (file_list)
|
||
{
|
||
uint32_t cnt = lv_obj_get_child_cnt(file_list);
|
||
for (uint32_t i = 0; i < cnt; i++)
|
||
clear_focus_style(lv_obj_get_child(file_list, i));
|
||
}
|
||
if (led_list)
|
||
{
|
||
for (int i = 0; i < LED_MODE_COUNT; i++)
|
||
{
|
||
lv_obj_t *c = lv_obj_get_child(led_list, i);
|
||
if (c)
|
||
clear_focus_style(c);
|
||
}
|
||
}
|
||
}
|
||
|
||
static void file_btn_click_cb(lv_event_t *e)
|
||
{
|
||
lv_obj_t *btn = lv_event_get_target(e);
|
||
u32 sclust = (u32)(uintptr_t)lv_obj_get_user_data(btn);
|
||
app_task_put_key_msg(KEY_MUSIC_PLAYE_BY_DEV_SCLUST, (int)sclust);
|
||
}
|
||
|
||
static void refresh_file_list_content(lv_obj_t *list)
|
||
{
|
||
if (!list)
|
||
return;
|
||
|
||
lv_obj_t *child;
|
||
while ((child = lv_obj_get_child(list, 0)) != NULL)
|
||
{
|
||
lv_obj_del(child);
|
||
}
|
||
|
||
void *dev = dev_manager_find_active(1);
|
||
if (!dev)
|
||
{
|
||
lv_list_add_text(list, "No storage device");
|
||
return;
|
||
}
|
||
|
||
char *path = dev_manager_get_root_path(dev);
|
||
if (!path)
|
||
{
|
||
lv_list_add_text(list, "No storage device");
|
||
return;
|
||
}
|
||
|
||
if (file_scan_fs)
|
||
{
|
||
fscan_release(file_scan_fs);
|
||
file_scan_fs = NULL;
|
||
}
|
||
|
||
file_scan_fs = fscan(path, MUSIC_SCAN_PARAM, 9);
|
||
#if defined(TCFG_LFN_EN) && TCFG_LFN_EN
|
||
if (file_scan_fs)
|
||
{
|
||
fset_lfn_buf(file_scan_fs, lfn_buf);
|
||
}
|
||
#endif
|
||
|
||
if (!file_scan_fs || file_scan_fs->file_number == 0)
|
||
{
|
||
lv_list_add_text(list, "No music files");
|
||
return;
|
||
}
|
||
|
||
u8 *name_buf = (u8 *)lv_mem_alloc(FILE_NAME_BUF_SIZE);
|
||
if (!name_buf)
|
||
{
|
||
lv_list_add_text(list, "Out of memory");
|
||
return;
|
||
}
|
||
|
||
int add_cnt = 0;
|
||
for (u32 i = 0; i < file_scan_fs->file_number; i++)
|
||
{
|
||
FILE *f = fselect(file_scan_fs, FSEL_BY_NUMBER, i + 1);
|
||
if (!f)
|
||
continue;
|
||
|
||
struct vfs_attr attr;
|
||
fget_attrs(f, &attr);
|
||
if (attr.attr & F_ATTR_DIR)
|
||
{
|
||
fclose(f);
|
||
continue;
|
||
}
|
||
|
||
int len = fget_name(f, name_buf, SHORT_NAME_LEN);
|
||
fclose(f);
|
||
if (len <= 0)
|
||
continue;
|
||
|
||
if (len >= SHORT_NAME_LEN)
|
||
len = SHORT_NAME_LEN - 1;
|
||
name_buf[len] = '\0';
|
||
|
||
int need_fallback = 0;
|
||
if (len >= 2 && name_buf[0] == '\\' && name_buf[1] == 'U')
|
||
{
|
||
need_fallback = 1;
|
||
}
|
||
else
|
||
{
|
||
for (int j = 0; j < len; j++)
|
||
{
|
||
if ((u8)name_buf[j] < 0x20 || (u8)name_buf[j] > 0x7E)
|
||
{
|
||
need_fallback = 1;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
const char *disp_text;
|
||
char fallback[16];
|
||
if (need_fallback)
|
||
{
|
||
int n = add_cnt + 1;
|
||
memcpy(fallback, "Music ", 6);
|
||
if (n >= 10)
|
||
{
|
||
fallback[6] = '0' + n / 10;
|
||
fallback[7] = '0' + n % 10;
|
||
fallback[8] = '\0';
|
||
}
|
||
else
|
||
{
|
||
fallback[6] = '0' + n;
|
||
fallback[7] = '\0';
|
||
}
|
||
disp_text = fallback;
|
||
}
|
||
else
|
||
{
|
||
disp_text = (const char *)name_buf;
|
||
}
|
||
|
||
lv_obj_t *btn = lv_list_add_btn(list, LV_SYMBOL_AUDIO, disp_text);
|
||
lv_obj_set_height(btn, ROW_H);
|
||
lv_obj_set_style_pad_all(btn, 2, 0); /* 压缩按钮内边距,适配12号字体 */
|
||
lv_obj_set_style_bg_opa(btn, LV_OPA_TRANSP, 0); /* 行背景透明 */
|
||
lv_obj_set_style_text_color(btn, lv_color_hex(0xFFFFFF), 0); /* 白色文字,需设在按钮上才生效 */
|
||
lv_obj_set_style_border_width(btn, 1, 0);
|
||
lv_obj_set_style_border_side(btn, LV_BORDER_SIDE_BOTTOM, 0);
|
||
lv_obj_set_style_border_color(btn, lv_color_hex(0xAAAAAA), 0); /* 浅色行分隔线 */
|
||
lv_obj_set_user_data(btn, (void *)(uintptr_t)attr.sclust);
|
||
lv_obj_add_event_cb(btn, file_btn_click_cb, LV_EVENT_CLICKED, NULL);
|
||
add_cnt++;
|
||
}
|
||
|
||
lv_mem_free(name_buf);
|
||
}
|
||
|
||
static void create_led_mode_list(lv_obj_t *list)
|
||
{
|
||
const char *mode_text[] = {"Mode 1", "Mode 2", "Mode 3", "Mode 4", "Mode 5", "Mode 6", "Mode 7", "Mode 8"};
|
||
for (int i = 0; i < LED_MODE_COUNT; i++)
|
||
{
|
||
lv_obj_t *btn = lv_list_add_btn(list, LV_SYMBOL_CHARGE, mode_text[i]);
|
||
lv_obj_set_height(btn, ROW_H);
|
||
lv_obj_set_style_pad_all(btn, 2, 0); /* 压缩按钮内边距,适配12号字体 */
|
||
lv_obj_set_style_bg_opa(btn, LV_OPA_TRANSP, 0); /* 行背景透明 */
|
||
lv_obj_set_style_text_color(btn, lv_color_hex(0xFFFFFF), 0); /* 白色文字,需设在按钮上才生效 */
|
||
lv_obj_set_style_border_width(btn, 1, 0);
|
||
lv_obj_set_style_border_side(btn, LV_BORDER_SIDE_BOTTOM, 0);
|
||
lv_obj_set_style_border_color(btn, lv_color_hex(0xAAAAAA), 0); /* 浅色行分隔线 */
|
||
}
|
||
}
|
||
|
||
void ui_music_update_playing_item(u32 sclust);
|
||
|
||
void ui_music_refresh_file_list(void)
|
||
{
|
||
if (file_list)
|
||
{
|
||
refresh_file_list_content(file_list);
|
||
/* 若正在播放,恢复高亮对应列表项 */
|
||
if (music_player_get_play_status() == 1) /* FILE_DEC_STATUS_PLAY */
|
||
ui_music_update_playing_item(music_player_get_file_sclust());
|
||
}
|
||
/* 若 eye LED 正在运行,恢复高亮对应模式 */
|
||
ui_music_update_led_mode_item(eye_led_get_mode());
|
||
}
|
||
|
||
/* 刷新播放进度(music_player 返回秒,与 file_dec_get_cur_time 一致) */
|
||
static void ui_music_refresh_play_time(void)
|
||
{
|
||
if (!bar_progress || !label_curr_time || !label_total_time)
|
||
return;
|
||
int cur_sec = music_player_get_dec_cur_time();
|
||
int total_sec = music_player_get_dec_total_time();
|
||
u32 cur_min = (u32)(cur_sec / 60);
|
||
u32 cur_s = (u32)(cur_sec % 60);
|
||
u32 total_min = (u32)(total_sec / 60);
|
||
u32 total_s = (u32)(total_sec % 60);
|
||
|
||
char buf[16];
|
||
lv_snprintf(buf, sizeof(buf), "%" LV_PRIu32 ":%02" LV_PRIu32, cur_min, cur_s);
|
||
lv_label_set_text(label_curr_time, buf);
|
||
lv_snprintf(buf, sizeof(buf), "%" LV_PRIu32 ":%02" LV_PRIu32, total_min, total_s);
|
||
lv_label_set_text(label_total_time, buf);
|
||
|
||
int val = (total_sec > 0) ? (int)((u32)cur_sec * 100 / (u32)total_sec) : 0;
|
||
if (val > 100)
|
||
val = 100;
|
||
lv_bar_set_value(bar_progress, val, LV_ANIM_OFF);
|
||
}
|
||
|
||
void ui_music_update_play_time(void)
|
||
{
|
||
ui_music_refresh_play_time();
|
||
}
|
||
|
||
#define COLOR_PLAYING 0x00FF00 /* 正在播放:绿色 */
|
||
#define COLOR_NORMAL 0xFFFFFF /* 普通:白色 */
|
||
|
||
/* 根据当前 eye LED 模式高亮对应列表项(绿色),mode 0 表示全部恢复白色 */
|
||
void ui_music_update_led_mode_item(u8 mode)
|
||
{
|
||
if (!led_list)
|
||
return;
|
||
for (int i = 0; i < LED_MODE_COUNT; i++)
|
||
{
|
||
lv_obj_t *c = lv_obj_get_child(led_list, i);
|
||
if (c)
|
||
{
|
||
lv_color_t color = (mode != 0 && (int)(mode - 1) == i)
|
||
? lv_color_hex(COLOR_PLAYING) : lv_color_hex(COLOR_NORMAL);
|
||
lv_obj_set_style_text_color(c, color, 0);
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 根据播放文件的 sclust 高亮对应列表项(绿色) */
|
||
void ui_music_update_playing_item(u32 sclust)
|
||
{
|
||
if (!file_list)
|
||
return;
|
||
uint32_t cnt = lv_obj_get_child_cnt(file_list);
|
||
for (uint32_t i = 0; i < cnt; i++)
|
||
{
|
||
lv_obj_t *c = lv_obj_get_child(file_list, i);
|
||
void *ud = lv_obj_get_user_data(c);
|
||
if (ud != NULL)
|
||
{
|
||
u32 item_sclust = (u32)(uintptr_t)ud;
|
||
lv_color_t color = (item_sclust == sclust) ? lv_color_hex(COLOR_PLAYING) : lv_color_hex(COLOR_NORMAL);
|
||
lv_obj_set_style_text_color(c, color, 0);
|
||
}
|
||
}
|
||
}
|
||
|
||
lv_obj_t *ui_music_create(void)
|
||
{
|
||
lv_obj_t *scr = lv_obj_create(NULL);
|
||
lv_obj_set_style_bg_img_src(scr, &img_bg, 0);
|
||
lv_obj_set_style_pad_all(scr, 0, 0);
|
||
lv_obj_clear_flag(scr, LV_OBJ_FLAG_SCROLLABLE);
|
||
|
||
/* 顶部标题 */
|
||
lv_obj_t *title = lv_label_create(scr);
|
||
lv_label_set_text(title, "Music");
|
||
lv_obj_set_style_text_font(title, &lv_font_montserrat_20, 0);
|
||
lv_obj_set_style_text_color(title, lv_color_hex(0xFFFFFF), 0);
|
||
lv_obj_set_pos(title, 0, 8);
|
||
lv_obj_set_width(title, LCD_W);
|
||
lv_obj_set_style_text_align(title, LV_TEXT_ALIGN_CENTER, 0);
|
||
|
||
/* 左侧:文件列表 */
|
||
file_list = lv_list_create(scr);
|
||
lv_obj_set_size(file_list, LIST_W, LIST_H);
|
||
lv_obj_set_pos(file_list, 4, LIST_TOP);
|
||
lv_obj_set_style_bg_opa(file_list, LV_OPA_TRANSP, 0);
|
||
lv_obj_set_style_border_width(file_list, 1, 0);
|
||
lv_obj_set_style_border_color(file_list, lv_color_hex(0xCCCCCC), 0); /* 浅色边框 */
|
||
lv_obj_set_style_text_color(file_list, lv_color_hex(0xFFFFFF), 0); /* 白色前景 */
|
||
lv_obj_set_style_text_font(file_list, &lv_font_montserrat_12, 0);
|
||
lv_obj_set_style_pad_row(file_list, ROW_GAP, 0);
|
||
refresh_file_list_content(file_list);
|
||
|
||
/* 右侧:LED 模式列表 */
|
||
led_list = lv_list_create(scr);
|
||
lv_obj_set_size(led_list, LIST_W, LIST_H);
|
||
lv_obj_set_pos(led_list, 12 + LIST_W, LIST_TOP);
|
||
lv_obj_set_style_bg_opa(led_list, LV_OPA_TRANSP, 0);
|
||
lv_obj_set_style_border_width(led_list, 1, 0);
|
||
lv_obj_set_style_border_color(led_list, lv_color_hex(0xCCCCCC), 0); /* 浅色边框 */
|
||
lv_obj_set_style_text_color(led_list, lv_color_hex(0xFFFFFF), 0); /* 白色前景 */
|
||
lv_obj_set_style_text_font(led_list, &lv_font_montserrat_12, 0);
|
||
lv_obj_set_style_pad_row(led_list, ROW_GAP, 0);
|
||
create_led_mode_list(led_list);
|
||
|
||
/* 底部进度条(同 BT 页) */
|
||
bar_progress = lv_bar_create(scr);
|
||
lv_obj_set_size(bar_progress, BAR_W, BAR_H);
|
||
lv_obj_set_pos(bar_progress, BAR_X, BAR_Y);
|
||
lv_bar_set_range(bar_progress, 0, 100);
|
||
lv_bar_set_value(bar_progress, 0, LV_ANIM_OFF);
|
||
lv_obj_set_style_bg_color(bar_progress, lv_color_hex(0xAAAAAA), LV_PART_MAIN);
|
||
lv_obj_set_style_bg_opa(bar_progress, LV_OPA_70, LV_PART_MAIN);
|
||
lv_obj_set_style_bg_color(bar_progress, lv_color_hex(0x2196F3), LV_PART_INDICATOR);
|
||
lv_obj_set_style_radius(bar_progress, 7, 0);
|
||
lv_obj_set_style_radius(bar_progress, 7, LV_PART_INDICATOR);
|
||
|
||
label_curr_time = lv_label_create(scr);
|
||
lv_label_set_text(label_curr_time, "0:00");
|
||
lv_obj_set_style_text_color(label_curr_time, lv_color_hex(0xFFFFFF), 0);
|
||
lv_obj_set_style_text_font(label_curr_time, &lv_font_montserrat_12, 0);
|
||
lv_obj_set_pos(label_curr_time, BAR_X, TIME_Y);
|
||
|
||
label_total_time = lv_label_create(scr);
|
||
lv_label_set_text(label_total_time, "0:00");
|
||
lv_obj_set_style_text_color(label_total_time, lv_color_hex(0xFFFFFF), 0);
|
||
lv_obj_set_style_text_font(label_total_time, &lv_font_montserrat_12, 0);
|
||
lv_obj_set_pos(label_total_time, BAR_X + BAR_W - 30, TIME_Y);
|
||
|
||
ui_music_refresh_play_time();
|
||
|
||
return scr;
|
||
}
|
||
|
||
void ui_music_on_key(int key_event, int key_value)
|
||
{
|
||
switch (key_event)
|
||
{
|
||
case KEY_MUSIC_PREV:
|
||
//case KEY_USER_PREV:
|
||
if (setting_flag)
|
||
focus_prev();
|
||
break;
|
||
case KEY_MUSIC_NEXT:
|
||
//case KEY_USER_NEXT:
|
||
if (setting_flag)
|
||
focus_next();
|
||
break;
|
||
//case KEY_USER_ENTER:
|
||
case KEY_MUSIC_PP: /* 设置模式下 PP 单击 = 确认 */
|
||
if (setting_flag)
|
||
{
|
||
focus_confirm(); /* 确认:音乐列表 <-> LED 列表切换焦点 */
|
||
}
|
||
break;
|
||
case KEY_USER_PLAY_TIME_UPDATE:
|
||
ui_music_refresh_play_time();
|
||
break;
|
||
case KEY_USER_MUSIC_PLAYING:
|
||
ui_music_update_playing_item((u32)key_value);
|
||
break;
|
||
case KEY_USER_EYE_LED_STOP:
|
||
ui_music_update_led_mode_item(0);
|
||
break;
|
||
case KEY_USER_SETTING:
|
||
setting_flag = !setting_flag;
|
||
if (setting_flag)
|
||
{
|
||
focus_enter_setting(); /* 进入设置,默认焦点到文件列表第一项 */
|
||
}
|
||
else
|
||
{
|
||
focus_exit_setting();
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
u8 ui_music_get_setting_flag(void)
|
||
{
|
||
return setting_flag;
|
||
}
|