115 lines
4.1 KiB
C
115 lines
4.1 KiB
C
/**
|
||
****************************************************************************************************
|
||
* @file app.h
|
||
* @author HiFi Player Project
|
||
* @version V1.2
|
||
* @date 2026-01-01
|
||
* @brief 应用管理器:主界面(应用启动器)/ 各 App 切换 + 全局按键服务
|
||
*
|
||
* 设计目的:
|
||
* 把“哪个界面在运行”和“按键归谁处理”从各 App 里抽出来。
|
||
* 新增应用(设置、相册、录音等)只需要:
|
||
* 1) 在 app_mode_t 里加一个模式;
|
||
* 2) 在 app.c 的 s_apps[] 表里加一条记录;
|
||
* 3) 新建自己的文件夹(如 APP/clock/),实现 ui_clock_create/show/tick/handle_key,
|
||
* 并在 ui.c 的路由表里挂上。
|
||
*
|
||
* 按键语义(由 ui.c 统一实现):
|
||
* K0 短按 = 返回主界面(主界面时为切换下一个应用)
|
||
* K0 长按 = 直接切换到下一个应用
|
||
* K1/K2/K3 = 由各 App 自己定义
|
||
****************************************************************************************************
|
||
*/
|
||
|
||
#ifndef __APP_H
|
||
#define __APP_H
|
||
|
||
#include <stdbool.h>
|
||
#include <stdint.h>
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
/* ---------------- 应用(界面)模式 ---------------- */
|
||
typedef enum {
|
||
APP_MODE_HOME = 0, /* 主界面:应用启动器 */
|
||
APP_MODE_PLAYER, /* 音乐播放器 */
|
||
APP_MODE_NUM, /* 模式总数(新增应用请加在这之前) */
|
||
} app_mode_t;
|
||
|
||
#define APP_MODE_NONE APP_MODE_NUM /* “无对应界面”(禁用的表项使用) */
|
||
|
||
/* ---------------- 4 个物理按键(XL9555 的 KEY0~KEY3) ---------------- */
|
||
typedef enum {
|
||
APP_KEY_0 = 0, /* KEY0 */
|
||
APP_KEY_1, /* KEY1 */
|
||
APP_KEY_2, /* KEY2 */
|
||
APP_KEY_3, /* KEY3 */
|
||
APP_KEY_NUM
|
||
} app_key_t;
|
||
|
||
/* ---------------- 按键事件类型 ---------------- */
|
||
typedef enum {
|
||
APP_KEY_SHORT = 0, /* 短按(松开时上报) */
|
||
APP_KEY_LONG, /* 长按(按住达到阈值立即上报,松开不再上报短按) */
|
||
} app_key_event_t;
|
||
|
||
typedef struct {
|
||
uint8_t key; /* app_key_t */
|
||
uint8_t type; /* app_key_event_t */
|
||
} app_event_t;
|
||
|
||
/* ---------------- 主界面应用表项 ---------------- */
|
||
typedef struct {
|
||
const char *icon; /* 图标字形(LV_SYMBOL_xxx) */
|
||
const char *title; /* 图标下方名称 */
|
||
const char *subtitle; /* 选中时显示的说明(可选,NULL 表示不显示) */
|
||
app_mode_t mode; /* 进入后切到的模式(APP_MODE_NONE 表示尚未实现) */
|
||
bool enabled; /* 是否可进入 */
|
||
uint32_t color_from; /* 图标渐变起始色(顶部) */
|
||
uint32_t color_to; /* 图标渐变结束色(底部) */
|
||
} app_entry_t;
|
||
|
||
/**
|
||
* @brief 初始化应用管理器(创建按键服务任务与事件队列)
|
||
* @note 必须在 xl9555_init() 之后调用
|
||
*/
|
||
void app_start(void);
|
||
|
||
/* ---------------- 模式 ---------------- */
|
||
app_mode_t app_get_mode(void);
|
||
|
||
/**
|
||
* @brief 切换应用模式
|
||
* @note 切换时会清空按键事件队列,避免上一次界面的按键“漏”到新界面
|
||
*/
|
||
void app_set_mode(app_mode_t mode);
|
||
|
||
/** 返回主界面(已在主界面时无动作) */
|
||
void app_back(void);
|
||
|
||
/**
|
||
* @brief 切换到“下一个可用的应用"
|
||
* @retval true 切换成功;false 没有其它可切换的应用
|
||
* @note 主界面 K0、以及在任意 App 内长按 K0 都会调用它
|
||
*/
|
||
bool app_switch_next(void);
|
||
|
||
/* ---------------- 主界面应用表 ---------------- */
|
||
const app_entry_t *app_get_entries(int *count);
|
||
|
||
int app_get_selection(void);
|
||
void app_select_move(int delta); /* 在当前应用表中循环移动选择项 */
|
||
|
||
/* ---------------- 按键事件 ---------------- */
|
||
bool app_event_poll(app_event_t *ev); /* 非阻塞 */
|
||
bool app_event_wait(app_event_t *ev, uint32_t timeout_ms); /* 阻塞等待 */
|
||
void app_event_flush(void); /* 清空队列 */
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
|
||
#endif /* __APP_H */
|