1、按键驱动重构:dzbj_button改为iot_button组件,支持BOOT/KEY2单击/双击/长按,回调通过xTaskCreate派发避免阻塞esp_timer; 2、新增按键导航管理器(key_nav):9种上下文状态机,统一分发按键事件到对应界面; 3、BLE改造:广播默认关闭由按键触发启停,新增设备间GATT Client图片传输(扫描→连接→MTU协商→分包发送),WRITE_EVT区分APP/设备传图跳转不同界面; 4、新增模式切换按键抑制:NVS标志+2秒时间窗,防止AI↔吧唧切换时幽灵按键触发配网或白屏; 5、AI模式BOOT单击回调添加抑制检查,吧唧模式key_nav_boot_click同步添加; 6、新增6个UI界面:配对(Peiwang)、更新(Update)、发送等待/接收等待/发送中/接收中; 7、新增电池指示器组件(battery_ui):多界面真实电量显示+3秒渐隐; 8、Home/Img界面重构:移除触摸手势事件,改为airhub背景+按键导航; 9、禁用触摸(DZBJ_ENABLE_TOUCH=0),保留代码可恢复; 10、sleep_mgr简化:按键唤醒由key_nav统一处理; Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
150 lines
5.2 KiB
C
150 lines
5.2 KiB
C
// Img界面 - 图片浏览
|
||
// 按键导航:BOOT单击→下一张,BOOT双击→上一张,BOOT长按→删除确认
|
||
// KEY2单击→返回Home,KEY2双击→接收,KEY2长按→分享
|
||
|
||
#include "../ui.h"
|
||
#include "../battery_ui.h"
|
||
#include "../../pages/include/pages.h"
|
||
#include "esp_log.h"
|
||
|
||
extern void init_spiffs_image_list(void);
|
||
extern bool update_ui_ImgBle(const char *img_name);
|
||
extern void free_spiffs_image_list(void);
|
||
extern const char* get_next_image(void);
|
||
extern const char* get_prev_image(void);
|
||
|
||
lv_obj_t *ui_ScreenImg = NULL;
|
||
lv_obj_t *ui_ImgBle = NULL;
|
||
lv_obj_t *ui_ContainerDle = NULL;
|
||
lv_obj_t *ui_ImageDel = NULL;
|
||
|
||
// 标志:是否需要显示 ContainerDle
|
||
static bool should_show_container = false;
|
||
|
||
// 显示 ContainerDle
|
||
void ui_ScreenImg_show_delete_container(void) {
|
||
should_show_container = true;
|
||
if (ui_ContainerDle) {
|
||
lv_obj_clear_flag(ui_ContainerDle, LV_OBJ_FLAG_HIDDEN);
|
||
}
|
||
// 重置边框为隐藏
|
||
if (ui_ImageDel) {
|
||
lv_obj_set_style_border_width(ui_ImageDel, 0, LV_PART_MAIN);
|
||
}
|
||
}
|
||
|
||
// 隐藏 ContainerDle
|
||
void ui_ScreenImg_hide_delete_container(void) {
|
||
should_show_container = false;
|
||
if (ui_ContainerDle) {
|
||
lv_obj_add_flag(ui_ContainerDle, LV_OBJ_FLAG_HIDDEN);
|
||
}
|
||
if (ui_ImageDel) {
|
||
lv_obj_set_style_border_width(ui_ImageDel, 0, LV_PART_MAIN);
|
||
}
|
||
}
|
||
|
||
// 显示白色圆角边框(二次确认状态)
|
||
void ui_ScreenImg_show_delete_confirm_border(void) {
|
||
if (ui_ImageDel) {
|
||
lv_obj_set_style_border_width(ui_ImageDel, 2, LV_PART_MAIN);
|
||
}
|
||
}
|
||
|
||
// 隐藏白色圆角边框
|
||
void ui_ScreenImg_hide_delete_confirm_border(void) {
|
||
if (ui_ImageDel) {
|
||
lv_obj_set_style_border_width(ui_ImageDel, 0, LV_PART_MAIN);
|
||
}
|
||
}
|
||
|
||
// 界面加载事件
|
||
static void ui_event_ScreenImg(lv_event_t *e) {
|
||
lv_event_code_t event_code = lv_event_get_code(e);
|
||
|
||
if (event_code == LV_EVENT_SCREEN_LOADED) {
|
||
init_spiffs_image_list();
|
||
|
||
const char *current_img = get_current_image();
|
||
if (current_img) {
|
||
update_ui_ImgBle(current_img);
|
||
} else {
|
||
ESP_LOGI("ScreenImg", "SPIFFS无可用图片,显示默认UI图片");
|
||
}
|
||
|
||
ui_ScreenImg_hide_delete_container();
|
||
|
||
// 进入Img界面时显示电池指示器
|
||
battery_ui_show_briefly();
|
||
}
|
||
}
|
||
|
||
void ui_ScreenImg_screen_init(void)
|
||
{
|
||
ui_ScreenImg = lv_obj_create(NULL);
|
||
lv_obj_clear_flag(ui_ScreenImg, LV_OBJ_FLAG_SCROLLABLE);
|
||
|
||
ui_ImgBle = lv_img_create(ui_ScreenImg);
|
||
// 不设置默认占位图,延迟到 SCREEN_LOADED 事件中加载 SPIFFS 图片
|
||
lv_obj_set_width(ui_ImgBle, 360);
|
||
lv_obj_set_height(ui_ImgBle, 360);
|
||
lv_obj_set_align(ui_ImgBle, LV_ALIGN_CENTER);
|
||
lv_obj_set_flex_flow(ui_ImgBle, LV_FLEX_FLOW_ROW);
|
||
lv_obj_set_flex_align(ui_ImgBle, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
|
||
lv_obj_add_flag(ui_ImgBle, LV_OBJ_FLAG_ADV_HITTEST);
|
||
lv_obj_clear_flag(ui_ImgBle, LV_OBJ_FLAG_SCROLLABLE);
|
||
|
||
// === 删除确认容器(220x220,屏幕底部半透明圆形) ===
|
||
ui_ContainerDle = lv_obj_create(ui_ScreenImg);
|
||
lv_obj_remove_style_all(ui_ContainerDle);
|
||
lv_obj_set_size(ui_ContainerDle, 220, 220);
|
||
lv_obj_set_align(ui_ContainerDle, LV_ALIGN_BOTTOM_MID);
|
||
lv_obj_set_y(ui_ContainerDle, 120); // 向下偏移120px,露出顶部约100px
|
||
lv_obj_clear_flag(ui_ContainerDle, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLLABLE);
|
||
lv_obj_set_style_radius(ui_ContainerDle, 110, LV_PART_MAIN);
|
||
lv_obj_set_style_clip_corner(ui_ContainerDle, true, LV_PART_MAIN);
|
||
lv_obj_set_style_bg_color(ui_ContainerDle, lv_color_hex(0x000000), LV_PART_MAIN);
|
||
lv_obj_set_style_bg_opa(ui_ContainerDle, 180, LV_PART_MAIN);
|
||
lv_obj_add_flag(ui_ContainerDle, LV_OBJ_FLAG_HIDDEN);
|
||
|
||
// 删除图标容器(68x68正圆,白色边框默认隐藏)
|
||
ui_ImageDel = lv_obj_create(ui_ContainerDle);
|
||
lv_obj_remove_style_all(ui_ImageDel);
|
||
lv_obj_set_size(ui_ImageDel, 68, 68);
|
||
lv_obj_set_align(ui_ImageDel, LV_ALIGN_TOP_MID);
|
||
lv_obj_set_y(ui_ImageDel, 16);
|
||
lv_obj_clear_flag(ui_ImageDel, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLLABLE);
|
||
lv_obj_set_style_bg_opa(ui_ImageDel, LV_OPA_TRANSP, LV_PART_MAIN);
|
||
lv_obj_set_style_radius(ui_ImageDel, 34, LV_PART_MAIN);
|
||
lv_obj_set_style_border_color(ui_ImageDel, lv_color_hex(0xFFFFFF), LV_PART_MAIN);
|
||
lv_obj_set_style_border_width(ui_ImageDel, 0, LV_PART_MAIN);
|
||
lv_obj_set_style_border_opa(ui_ImageDel, LV_OPA_COVER, LV_PART_MAIN);
|
||
|
||
// S13图片(48x48)在容器内居中
|
||
lv_obj_t *del_icon = lv_img_create(ui_ImageDel);
|
||
lv_img_set_src(del_icon, &ui_img_s13_png);
|
||
lv_obj_set_align(del_icon, LV_ALIGN_CENTER);
|
||
lv_obj_clear_flag(del_icon, LV_OBJ_FLAG_SCROLLABLE);
|
||
|
||
// 注册界面加载事件(图片切换和删除由key_nav按键导航处理)
|
||
lv_obj_add_event_cb(ui_ScreenImg, ui_event_ScreenImg, LV_EVENT_ALL, NULL);
|
||
|
||
// 电池指示器
|
||
battery_ui_add_to_screen(ui_ScreenImg, 100);
|
||
}
|
||
|
||
void ui_ScreenImg_screen_destroy(void)
|
||
{
|
||
#if LV_USE_GIF
|
||
pages_cleanup_gif();
|
||
#endif
|
||
if (ui_ScreenImg) lv_obj_del(ui_ScreenImg);
|
||
|
||
ui_ScreenImg = NULL;
|
||
ui_ImgBle = NULL;
|
||
ui_ContainerDle = NULL;
|
||
ui_ImageDel = NULL;
|
||
|
||
free_spiffs_image_list();
|
||
}
|