# 按键版电子吧唧（ESP32-S3）功能变更总结

## 项目背景
本项目从触摸屏版 `Dzbj_ESP32_S3` 复制而来，将触摸手势操作全面替换为两键（BOOT + KEY2）按键控制，适配非触摸屏硬件。

---

## 一、按键驱动重构

### 1.1 iot_button 组件集成
- **文件**: `main/button/button.c`, `main/button/include/button.h`
- **变更**: 从原始 GPIO ISR 轮询改为 ESP Component Registry 的 `iot_button` 组件
- **新接口**: 6 种事件回调注册（BOOT/KEY2 × 单击/双击/长按）
- **参数优化**: 长按阈值 1200ms，双击检测窗口 300ms

### 1.2 依赖添加
- **文件**: `main/idf_component.yml`
- **新增**: `button: ">=3.2.0"` 依赖

---

## 二、按键导航管理器（key_nav）

### 2.1 新建模块
- **文件**: `main/key_nav/key_nav.c`, `main/key_nav/include/key_nav.h`
- **功能**: 根据当前界面上下文（nav_context_t）分发 BOOT/KEY2 的单击/双击/长按事件

### 2.2 导航上下文状态机
```
NAV_CTX_HOME              → Home 界面
NAV_CTX_IMG               → 图片浏览
NAV_CTX_IMG_DELETE        → 删除确认（第一步）
NAV_CTX_IMG_DELETE_CONFIRM→ 删除二次确认（第二步）
NAV_CTX_PEIWANG           → APP 蓝牙配对
NAV_CTX_UPDATE            → 更新界面
NAV_CTX_IMAGE_SHAR        → 发送方等待配对
NAV_CTX_IMAGE_RECEPTION   → 接收方等待配对
NAV_CTX_SHARING           → 发送方传输中
NAV_CTX_RECEIVING         → 接收方接收中
```

### 2.3 按键功能映射

| 界面 | BOOT 单击 | BOOT 双击 | BOOT 长按 | KEY2 单击 | KEY2 双击 | KEY2 长按 |
|------|-----------|-----------|-----------|-----------|-----------|-----------|
| Home | → Img | - | - | 开蓝牙→配对 | → 接收等待 | 初始化图片列表→分享等待 |
| Img | 下一张 | 上一张 | 删除确认 | → Home | → 接收等待 | → 分享等待 |
| 删除确认 | 显示白色边框→二次确认 | - | - | 取消 | - | - |
| 二次确认 | 执行删除 | - | - | 取消 | - | - |
| 配对/分享等待/接收等待 | 取消→Home | - | - | 取消→Home | - | - |
| 更新/传输中/接收中 | 不响应 | - | - | 不响应 | - | - |

### 2.4 关键设计
- 所有 iot_button 回调通过 `xTaskCreate` 派发到独立任务（避免阻塞 esp_timer）
- 屏幕关闭状态下任意按键仅唤醒屏幕，不触发业务逻辑
- 切图时自动显示电池指示器

---

## 三、BLE 模块改造

### 3.1 BLE 按需启停
- **文件**: `main/ble/ble.c`, `main/ble/include/ble.h`
- **新增接口**: `ble_start()` / `ble_stop()` / `ble_is_active()`
- **行为**: 开机默认不广播，KEY2 单击后才启动；退出配对界面自动关闭

### 3.2 BLE 设备间图片传输
- **新建文件**: `main/ble/ble_transfer.c`, `main/ble/include/ble_transfer.h`
- **功能**: GATT Client/Server 模式的设备间图片传输
- **流程**:
  - 发送方: 启动扫描 → 发现接收设备 → 连接 → GATT 写入图片数据
  - 接收方: 启动广播 → 等待连接 → 接收图片数据 → 保存到 SPIFFS

### 3.3 传输后处理
- APP 传图（通过已有 BLE 服务）→ 自动跳转 Update 界面 → 完成后显示 Img
- 设备间传图完成 → 自动跳转 Img 显示传输的图片 + 关闭蓝牙
- 扫描未发现接收设备 → 保持分享界面，等待用户手动退出
- 图片发送失败 → 自动切换回 Img 界面

---

## 四、UI 界面变更

### 4.1 新增 4 个分享/接收界面
| 界面 | 文件 | 用途 | 图片 |
|------|------|------|------|
| ScreenImageShar | `ui_ScreenImageShar.c/.h` | 发送方等待配对 | image_shar_png (260×300) |
| ScreenImageReception | `ui_ScreenImageReception.c/.h` | 接收方等待配对 | image_reception_png (260×300) |
| ScreenSharing | `ui_ScreenSharing.c/.h` | 发送方传输中 | sharing_png (260×310) |
| ScreenReceiving | `ui_ScreenReceiving.c/.h` | 接收方接收中 | receiving_png (260×310) |

### 4.2 Img 界面删除确认重设计
- **ContainerDle**: 220×220 半透明黑色正圆容器，底部对齐 + 向下偏移 120px（露出顶部约 100px）
- **删除图标**: S13 图片（48×48）居中于 68×68 正圆容器 (ui_ImageDel)
- **两步确认**: 第一次按 BOOT → 显示白色正圆边框；第二次按 BOOT → 执行删除
- **取消**: KEY2 单击隐藏容器 + 重置边框

### 4.3 手势事件移除
- 移除 ScreenHome、ScreenImg、ScreenPeiwang、ScreenUpdate 的手势回调
- ScreenImg 保留 `LV_EVENT_SCREEN_LOADED` 延迟加载逻辑

### 4.4 ScreenSet 界面禁用
- CMakeLists.txt 注释掉编译
- ui.h / ui.c 注释掉相关 include 和初始化

---

## 五、电池指示器重设计

### 5.1 显示策略
- **文件**: `main/ui/battery_ui.c`, `main/ui/battery_ui.h`
- **适用界面**: 仅 Home 和 Img
- **触发时机**: 进入 Home/Img 界面、切换图片时
- **显示时长**: 2 秒后自动渐隐（500ms fade-out 动画）

### 5.2 实现方式
- 药丸形容器（50×20，黑色背景，圆角 10）悬浮于屏幕顶部
- 电池图标使用 LVGL 基元绘制（主体 + 电池帽 + 填充条）
- 初始状态透明（LV_OPA_TRANSP），`show_briefly()` 时设为不透明 + 启动定时器
- `lv_anim_t` 实现 opacity 从 255→0 的渐隐动画
- `battery_ui_update_level()` 仅缓存电量值，不主动更新 UI

---

## 六、sleep_mgr 适配
- 移除 KEY2 唤醒回调注册（由 key_nav 统一处理）
- 保留 `sleep_mgr_notify_activity()` 和 `sleep_mgr_is_screen_off()` 接口

---

## 七、main.c 更新
- 移除旧 `boot_btn_handler` 和 flashlight 引用
- `ble_init()` 保留但不自动广播
- 新增 `key_nav_init()` 调用
- 移除 `button_on_boot_press()` 注册

---

## 八、按键时序参数

| 参数 | 原值 | 新值 |
|------|------|------|
| 长按阈值 | 2000ms | 1200ms |
| 双击检测窗口 | 180ms | 300ms |
| 电池显示时长 | 3000ms | 2000ms |
| 渐隐动画时长 | - | 500ms |

---

## 九、文件变更汇总

| 操作 | 文件 |
|------|------|
| 新建 | `main/key_nav/key_nav.c`, `main/key_nav/include/key_nav.h` |
| 新建 | `main/ble/ble_transfer.c`, `main/ble/include/ble_transfer.h` |
| 新建 | `main/ui/battery_ui.c`, `main/ui/battery_ui.h` |
| 新建 | `main/ui/screens/ui_ScreenImageShar.c/.h` |
| 新建 | `main/ui/screens/ui_ScreenImageReception.c/.h` |
| 新建 | `main/ui/screens/ui_ScreenSharing.c/.h` |
| 新建 | `main/ui/screens/ui_ScreenReceiving.c/.h` |
| 新建 | `main/ui/images/` 下 4 张新图片资源 |
| 重写 | `main/button/button.c`, `main/button/include/button.h` |
| 修改 | `main/ble/ble.c`, `main/ble/include/ble.h` |
| 修改 | `main/main.c` |
| 修改 | `main/ui/screens/ui_ScreenHome.c`, `ui_ScreenImg.c/.h` |
| 修改 | `main/ui/screens/ui_ScreenPeiwang.c`, `ui_ScreenUpdate.c` |
| 修改 | `main/battery/battery.c` |
| 修改 | `main/sleep_mgr/sleep_mgr.c` |
| 修改 | `main/ui/ui.c`, `main/ui/ui.h`, `main/ui/CMakeLists.txt` |
| 修改 | `main/CMakeLists.txt`, `main/idf_component.yml` |
| 禁用 | `main/ui/screens/ui_ScreenSet.c`（注释掉编译） |
