1、按键驱动重构:从GPIO中断改为iot_button组件,支持BOOT/KEY2的单击/双击/长按6种事件; 2、新增按键导航管理器(key_nav):9种上下文状态机,统一分发按键事件到对应界面业务逻辑; 3、BLE模块改造:广播默认关闭由按键触发,新增设备间图片传输(GATT Client),支持扫描配对→MTU协商→分包发送; 4、新增6个UI界面:配对(Peiwang)、更新(Update)、发送等待(ImageShar)、接收等待(ImageReception)、发送中(Sharing)、接收中(Receiving); 5、新增电池指示器组件(battery_ui):支持多界面真实电量显示,3秒渐隐效果; 6、Home界面重构:移除手势事件,改为airhub背景图+电池指示器; 7、Img界面重构:移除触摸事件,新增删除二次确认边框机制; 8、禁用ScreenSet/ScreenChar界面(保留文件),禁用触摸初始化(保留代码可恢复); 9、sleep_mgr简化:移除ScreenSet亮度UI依赖,按键唤醒由key_nav统一处理; 10、新增9张图片资源(airhub背景、配对、传输状态、电池图标等); Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
162 lines
5.8 KiB
C
162 lines
5.8 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) {
|
||
// 初始化图片列表(内部有guard,不会重复初始化)
|
||
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界面时显示电池指示器3秒
|
||
battery_ui_show_briefly();
|
||
}
|
||
}
|
||
|
||
// build funtions
|
||
|
||
void ui_ScreenImg_screen_init(void)
|
||
{
|
||
ui_ScreenImg = lv_obj_create(NULL);
|
||
lv_obj_clear_flag( ui_ScreenImg, LV_OBJ_FLAG_SCROLLABLE ); /// Flags
|
||
|
||
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 ); /// Flags
|
||
lv_obj_clear_flag( ui_ImgBle, LV_OBJ_FLAG_SCROLLABLE ); /// Flags
|
||
|
||
// === 删除确认容器(220x220,屏幕底部半透明圆形) ===
|
||
// 容器向下偏移120px,可见高度 = 220-120 = 100px
|
||
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); // 正圆(220/2)
|
||
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); // 半透明 70%
|
||
lv_obj_add_flag(ui_ContainerDle, LV_OBJ_FLAG_HIDDEN); // 默认隐藏
|
||
|
||
// 删除图标容器(60x60正圆,在可见区域内垂直居中)
|
||
// 可见区域高度约100px,容器60px → y = (100-60)/2 = 20px(距容器顶部)
|
||
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); // (100-68)/2 = 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); // 正圆(68/2)
|
||
// 白色正圆边框(默认宽度为0,二次确认时显示)
|
||
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);
|
||
|
||
// 注意:不在此处加载图片,延迟到 LV_EVENT_SCREEN_LOADED 事件中加载
|
||
// 这样避免ui_init()时触发渲染导致开机闪烁
|
||
|
||
// 电池指示器 - 测试100%电量(绿色满格)
|
||
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);
|
||
|
||
// NULL screen variables
|
||
ui_ScreenImg= NULL;
|
||
ui_ImgBle= NULL;
|
||
ui_ContainerDle= NULL;
|
||
ui_ImageDel= NULL;
|
||
|
||
free_spiffs_image_list();
|
||
}
|