Baji_Rtc_Toy_Key/main/ui/screens/ui_ScreenImg.c
Rdzleo 3a05c3c7d5 双模设备电子吧唧按键功能完整实现 + BLE设备间图片传输 + 模式切换防护
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>
2026-03-26 17:44:46 +08:00

150 lines
5.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Img界面 - 图片浏览
// 按键导航BOOT单击→下一张BOOT双击→上一张BOOT长按→删除确认
// KEY2单击→返回HomeKEY2双击→接收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();
}