linuxOS_AP06/app/lvgl_demo/rk_demo/setting/setting_ui.c
2025-06-03 12:28:32 +08:00

446 lines
12 KiB
C

#include <lvgl/lvgl.h>
#include "about_ui.h"
#include "bt_ui.h"
#include "display_ui.h"
#include "home_ui.h"
#include "language_and_date_ui.h"
#include "lv_toast.h"
#include "main.h"
#include "volume_ui.h"
#include "wallpaper_ui.h"
#include "wifi_ui.h"
#include "wifibt.h"
enum
{
SUBMENU_MIN = 0,
SUBMENU_WALLPAPER = SUBMENU_MIN,
SUBMENU_LANGUAGE_DATE,
SUBMENU_ABOUT,
#if WIFIBT_EN
SUBMENU_WIFI,
#endif
#if BT_EN
SUBMENU_BT,
#endif
SUBMENU_MAX,
};
struct submenu_s
{
char *name;
void (*init)(void);
void (*deinit)(void);
lv_obj_t *menu;
};
static lv_obj_t *main = NULL;
static lv_obj_t *btn_return;
static lv_obj_t *ui_cont;
static lv_obj_t *ui_box_main;
static lv_obj_t *ui_sliders;
#if WIFIBT_EN
static lv_obj_t *ui_wifi;
#endif
#if BT_EN
static lv_obj_t *ui_bt;
#endif
static lv_obj_t *ui_wallpaper;
static lv_obj_t *ui_data;
static lv_obj_t *ui_about;
static lv_obj_t *submenu_mask;
static lv_obj_t *submenu_area;
static lv_obj_t *cancel_btn;
static lv_timer_t *timer;
static lv_obj_t *sub_menu[SUBMENU_MAX];
static int cur_menu = SUBMENU_MAX;
static struct submenu_s submenu_desc[SUBMENU_MAX];
static void sliders_draw(lv_obj_t *parent, struct btn_desc *desc);
static void menu_switch_cb(lv_event_t *e);
#if WIFIBT_EN
static void wifi_switch_cb(lv_event_t *e);
#endif
#if BT_EN
static void switch_toggled(lv_event_t *e);
#endif
#define SUBMENU_COMMON_DEFINE(enum_t, name) \
static void submenu_##name(void) \
{ \
lv_obj_scroll_to_y(submenu_area, 0, LV_ANIM_OFF); \
if (!submenu_desc[enum_t].menu)\
submenu_desc[enum_t].menu = menu_##name##_init(submenu_area);\
} \
static void submenu_##name##_destroy(void) \
{ \
if (submenu_desc[enum_t].menu)\
{ \
menu_##name##_deinit();\
submenu_desc[enum_t].menu = NULL;\
} \
}
#if WIFIBT_EN
SUBMENU_COMMON_DEFINE(SUBMENU_WIFI, wifi)
#endif
#if BT_EN
SUBMENU_COMMON_DEFINE(SUBMENU_BT, bt)
#endif
SUBMENU_COMMON_DEFINE(SUBMENU_WALLPAPER, wallpaper)
SUBMENU_COMMON_DEFINE(SUBMENU_LANGUAGE_DATE, language)
SUBMENU_COMMON_DEFINE(SUBMENU_ABOUT, about)
static struct submenu_s submenu_desc[SUBMENU_MAX] =
{
{"锁屏和壁纸", submenu_wallpaper, submenu_wallpaper_destroy, NULL},
{"语言和日期", submenu_language, submenu_language_destroy, NULL},
{"关于", submenu_about, submenu_about_destroy, NULL},
#if WIFIBT_EN
{"WIFI", submenu_wifi, submenu_wifi_destroy, NULL},
#endif
#if BT_EN
{"蓝牙", submenu_bt, submenu_bt_destroy, NULL},
#endif
};
static struct btn_desc setting_btn[] =
{
{
.obj = &ui_sliders,
.w = 2,
.h = 1,
.draw = sliders_draw,
},
#if WIFIBT_EN
{
.obj = &ui_wifi,
.img = ICON_WIFI,
.text = "WiFi",
.w = 1,
.h = 1,
.draw = common_draw,
.cb = wifi_switch_cb,
.user_data = (void *)SUBMENU_WIFI
},
#endif
#if BT_EN
{
.obj = &ui_bt,
.img = ICON_BT,
.text = "蓝牙",
.w = 1,
.h = 1,
.draw = common_draw,
.cb = switch_toggled,
.user_data = (void *)SUBMENU_BT
},
#endif
{
.obj = &ui_wallpaper,
.img = ICON_WALLPAPER,
.text = "锁屏和壁纸",
.w = 1,
.h = 1,
.draw = common_draw,
.cb = menu_switch_cb,
.user_data = (void *)SUBMENU_WALLPAPER
},
{
.obj = &ui_data,
.img = ICON_DATA,
.text = "语言和日期",
.w = 1,
.h = 1,
.draw = common_draw,
.cb = menu_switch_cb,
.user_data = (void *)SUBMENU_LANGUAGE_DATE
},
{
.obj = &ui_about,
.img = ICON_ABOUT,
.text = "关于",
.w = 1,
.h = 1,
.draw = common_draw,
.cb = menu_switch_cb,
.user_data = (void *)SUBMENU_ABOUT
}
};
#ifdef LARGE
static lv_coord_t col_dsc[] = {300, 300, LV_GRID_TEMPLATE_LAST};
static lv_coord_t row_dsc[] = {140, 140, 140, 140, LV_GRID_TEMPLATE_LAST};
#else
static lv_coord_t col_dsc[] = {200, 200, LV_GRID_TEMPLATE_LAST};
static lv_coord_t row_dsc[] = {140, 140, 140, 140, LV_GRID_TEMPLATE_LAST};
#endif
struct btn_matrix_desc setting_desc =
{
.col_dsc = col_dsc,
.row_dsc = row_dsc,
.pad = 5,
.gap = 20,
.desc = setting_btn,
.btn_cnt = sizeof(setting_btn) / sizeof(setting_btn[0]),
};
static void slider_event_cb(lv_event_t *e)
{
lv_obj_t *slider = lv_event_get_target(e);
lv_obj_t *label = lv_event_get_user_data(e);
char buf[8];
lv_snprintf(buf, sizeof(buf), "%d%%", (int)lv_slider_get_value(slider));
lv_label_set_text(label, buf);
}
static void sliders_draw(lv_obj_t *parent, struct btn_desc *desc)
{
lv_obj_t *cont_v, *cont_d;
lv_obj_t *label_v, *label_d;
lv_obj_t *obj_v, *obj_d;
lv_obj_t *label_vp, *label_dp;
lv_obj_clear_flag(parent, LV_OBJ_FLAG_CLICKABLE);
lv_obj_set_style_pad_all(parent, 0, LV_PART_MAIN);
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
cont_v = lv_obj_create(parent);
lv_obj_remove_style_all(cont_v);
lv_obj_set_size(cont_v, lv_pct(100), lv_pct(50));
cont_d = lv_obj_create(parent);
lv_obj_remove_style_all(cont_d);
lv_obj_set_size(cont_d, lv_pct(100), lv_pct(50));
obj_v = lv_slider_create(cont_v);
lv_obj_set_size(obj_v, lv_pct(75), lv_pct(30));
lv_obj_center(obj_v);
lv_obj_set_style_bg_opa(obj_v, LV_OPA_TRANSP, LV_PART_KNOB);
lv_slider_set_range(obj_v, 10, 100);
lv_slider_set_value(obj_v, 100, LV_ANIM_OFF);
lv_obj_refr_size(obj_v);
lv_obj_refr_pos(obj_v);
label_v = lv_label_create(cont_v);
lv_label_set_text(label_v, "音量");
lv_obj_add_style(label_v, &style_txt_s, LV_PART_MAIN);
lv_obj_set_style_text_color(label_v, lv_color_white(), LV_PART_MAIN);
lv_obj_align_to(label_v, obj_v, LV_ALIGN_OUT_LEFT_MID, -5, 0);
label_vp = lv_label_create(cont_v);
lv_label_set_text(label_vp, "100%");
lv_obj_add_style(label_vp, &style_txt_s, LV_PART_MAIN);
lv_obj_set_style_text_color(label_vp, lv_color_white(), LV_PART_MAIN);
lv_obj_align_to(label_vp, obj_v, LV_ALIGN_OUT_RIGHT_MID, 5, 0);
lv_obj_add_event_cb(obj_v, slider_event_cb, LV_EVENT_VALUE_CHANGED, label_vp);
obj_d = lv_slider_create(cont_d);
lv_obj_set_size(obj_d, lv_pct(75), lv_pct(30));
lv_obj_center(obj_d);
lv_obj_set_style_bg_opa(obj_d, LV_OPA_TRANSP, LV_PART_KNOB);
lv_slider_set_range(obj_d, 10, 100);
lv_slider_set_value(obj_d, 100, LV_ANIM_OFF);
lv_obj_refr_size(obj_d);
lv_obj_refr_pos(obj_d);
label_d = lv_label_create(cont_d);
lv_label_set_text(label_d, "亮度");
lv_obj_add_style(label_d, &style_txt_s, LV_PART_MAIN);
lv_obj_set_style_text_color(label_d, lv_color_white(), LV_PART_MAIN);
lv_obj_align_to(label_d, obj_d, LV_ALIGN_OUT_LEFT_MID, -5, 0);
label_dp = lv_label_create(cont_d);
lv_label_set_text(label_dp, "100%");
lv_obj_add_style(label_dp, &style_txt_s, LV_PART_MAIN);
lv_obj_set_style_text_color(label_dp, lv_color_white(), LV_PART_MAIN);
lv_obj_align_to(label_dp, obj_d, LV_ALIGN_OUT_RIGHT_MID, 5, 0);
lv_obj_add_event_cb(obj_d, slider_event_cb, LV_EVENT_VALUE_CHANGED, label_dp);
}
#if BT_EN
static struct wifibt_cmdarg cmdarg;
static struct bt_info new_info;
static void switch_toggled(lv_event_t *e)
{
lv_color_t color = lv_obj_get_style_bg_color(ui_bt, LV_PART_MAIN);
lv_color_t hl = HL_BLUE;
if (e->code == LV_EVENT_CLICKED)
{
if (color.full == hl.full)
{
lv_obj_set_style_bg_color(ui_bt, MAIN_COLOR, LV_PART_MAIN);
cmdarg.cmd = BT_DISABLE;
}
else
{
lv_obj_set_style_bg_color(ui_bt, HL_BLUE, LV_PART_MAIN);
cmdarg.cmd = BT_ENABLE;
}
bt_query(&cmdarg, sizeof(cmdarg));
}
}
#endif
static void menu_switch_cb(lv_event_t *e)
{
intptr_t idx = (intptr_t)lv_event_get_user_data(e);
if (idx < SUBMENU_MIN || idx >= SUBMENU_MAX)
return;
if ((cur_menu >= SUBMENU_MIN)
&& (cur_menu < SUBMENU_MAX)
&& submenu_desc[cur_menu].menu)
{
lv_obj_add_flag(submenu_desc[cur_menu].menu,
LV_OBJ_FLAG_HIDDEN);
}
if (submenu_desc[idx].init)
submenu_desc[idx].init();
cur_menu = idx;
if (submenu_desc[cur_menu].menu)
{
lv_obj_clear_flag(submenu_mask, LV_OBJ_FLAG_HIDDEN);
lv_obj_clear_flag(submenu_desc[cur_menu].menu,
LV_OBJ_FLAG_HIDDEN);
}
}
#if WIFIBT_EN
static void wifi_switch_cb(lv_event_t *e)
{
if (wifi_init_done())
{
menu_switch_cb(e);
}
else
{
lv_obj_t *toast = lv_toast_create(lv_layer_sys());
lv_toast_set_text(toast, "WiFi初始化未完成请稍后重试");
lv_obj_add_style(toast, &style_txt_m, LV_PART_MAIN);
lv_obj_align(toast, LV_ALIGN_TOP_MID, 0, 20);
lv_toast_show(toast);
}
}
#endif
static void btn_return_cb(lv_event_t *e)
{
switch (e->code)
{
case LV_EVENT_CLICKED:
home_ui_init();
lv_timer_del(timer);
for (int i = SUBMENU_MIN; i < SUBMENU_MAX; i++)
{
if (submenu_desc[i].deinit)
submenu_desc[i].deinit();
}
lv_obj_del(main);
main = NULL;
lv_obj_del(submenu_mask);
submenu_mask = NULL;
break;
default:
break;
}
}
static void submenu_mask_cb(lv_event_t *e)
{
lv_obj_add_flag(submenu_mask, LV_OBJ_FLAG_HIDDEN);
}
static void state_update(lv_timer_t *timer)
{
#if WIFIBT_EN
if (wifi_enabled())
lv_obj_set_style_bg_color(ui_wifi, HL_BLUE, LV_PART_MAIN);
else
lv_obj_set_style_bg_color(ui_wifi, MAIN_COLOR, LV_PART_MAIN);
#endif
#if BT_EN
cmdarg.cmd = BT_INFO;
cmdarg.val = &new_info;
bt_query_wait(&cmdarg, sizeof(cmdarg));
if (new_info.bt_state >= BT_STATE_ON)
lv_obj_set_style_bg_color(ui_bt, HL_BLUE, LV_PART_MAIN);
else
lv_obj_set_style_bg_color(ui_bt, MAIN_COLOR, LV_PART_MAIN);
#endif
}
void setting_ui_init(void)
{
if (main)
{
lv_obj_clear_flag(main, LV_OBJ_FLAG_HIDDEN);
return;
}
main = lv_obj_create(lv_scr_act());
lv_obj_remove_style_all(main);
lv_obj_set_style_pad_all(main, 0, LV_PART_MAIN);
lv_obj_set_size(main, lv_pct(100), lv_pct(100));
lv_obj_refr_size(main);
btn_return = ui_return_btn_create(main, btn_return_cb, "系统设置");
ui_box_main = ui_btnmatrix_create(main, &setting_desc);
lv_obj_align(ui_box_main, LV_ALIGN_TOP_MID, 0, lv_pct(10));
#if WIFIBT_EN
if (wifi_enabled())
lv_obj_set_style_bg_color(ui_wifi, HL_BLUE, LV_PART_MAIN);
else
lv_obj_set_style_bg_color(ui_wifi, MAIN_COLOR, LV_PART_MAIN);
#endif
#if BT_EN
cmdarg.cmd = BT_INFO;
cmdarg.val = &new_info;
bt_query_wait(&cmdarg, sizeof(cmdarg));
if (new_info.bt_state >= BT_STATE_ON)
lv_obj_set_style_bg_color(ui_bt, HL_BLUE, LV_PART_MAIN);
else
lv_obj_set_style_bg_color(ui_bt, MAIN_COLOR, LV_PART_MAIN);
#endif
submenu_mask = lv_obj_create(lv_scr_act());
lv_obj_add_flag(submenu_mask, LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_CLICKABLE);
lv_obj_remove_style_all(submenu_mask);
lv_obj_set_size(submenu_mask, lv_pct(100), lv_pct(100));
lv_obj_set_style_bg_color(submenu_mask, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_bg_opa(submenu_mask, LV_OPA_80, LV_PART_MAIN);
lv_obj_add_event_cb(submenu_mask, submenu_mask_cb, LV_EVENT_CLICKED,
submenu_mask);
submenu_area = lv_obj_create(submenu_mask);
lv_obj_set_size(submenu_area, lv_pct(70), lv_pct(70));
lv_obj_set_style_bg_color(submenu_area, lv_color_white(), LV_PART_MAIN);
lv_obj_center(submenu_area);
lv_obj_refr_size(submenu_area);
lv_obj_refr_pos(submenu_area);
cancel_btn = lv_img_create(submenu_mask);
lv_obj_add_flag(cancel_btn, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_EVENT_BUBBLE);
lv_img_set_src(cancel_btn, IMG_CANCEL);
lv_obj_align_to(cancel_btn, submenu_area, LV_ALIGN_OUT_BOTTOM_MID, 0, 20);
timer = lv_timer_create(state_update, 1000, NULL);
lv_timer_enable(timer);
}