171 lines
5.2 KiB
C
171 lines
5.2 KiB
C
/***
|
||
* @Author:
|
||
* @Date: 2023-08-01 19:47:20
|
||
* @LastEditors: xxx
|
||
* @LastEditTime: 2023-08-01 19:48:10
|
||
* @Description:
|
||
这是一个简单的菜单系统实现,包括菜单页面的创建、添加、获取、注册按键、检测菜单定时器和关闭菜单定时器的函数。菜单系统使用定时器发送消息,当定时器过期时,菜单系统将发送消息给下一个页面或刷新当前页面
|
||
* @email:
|
||
* @Copyright (c) 2023 by xxx, All Rights Reserved.
|
||
*/
|
||
|
||
/**
|
||
* 使用教程
|
||
#include "menu.h"
|
||
|
||
// 定义菜单项
|
||
menu_txt_t menu_items[] = {
|
||
{"选项1", MENU_WHAT(NULL)},
|
||
{"选项2", MENU_WHAT(NULL)},
|
||
{"选项3", MENU_WHAT(NULL)},
|
||
};
|
||
|
||
menu_page_t page1 = {
|
||
1, 0, 0, 1, NULL
|
||
};
|
||
|
||
menu_page_t page2 = {
|
||
2, 1, 0, 2, NULL
|
||
};
|
||
|
||
menu_page_t page3 = {
|
||
3, 1, 0, 3, NULL
|
||
};
|
||
|
||
void page1_operate() {
|
||
// 在这里实现选项1的功能
|
||
printf("选项1的功能实现\n");
|
||
}
|
||
|
||
void page2_operate() {
|
||
// 在这里实现选项2的功能
|
||
printf("选项2的功能实现\n");
|
||
}
|
||
|
||
void page3_operate() {
|
||
// 在这里实现选项3的功能
|
||
printf("选项3的功能实现\n");
|
||
}
|
||
|
||
int main(void)
|
||
{
|
||
menu_t *menu = menu_create(1000); // 创建菜单,每隔1000毫秒刷新一次
|
||
menu_page_add(&page1);
|
||
menu_page_add(&page2);
|
||
menu_page_add(&page3);
|
||
|
||
menu_key_register(KEY_UP); // 注册上键
|
||
menu_key_register(KEY_DOWN); // 注册下键
|
||
menu_key_register(KEY_ENT); // 注册进入键
|
||
|
||
menu_timer_start(1000, WM_CREATE); // 启动菜单定时器,每隔1000毫秒发送一次创建消息
|
||
|
||
while (1)
|
||
{
|
||
menu_detection(); // 检测菜单定时器
|
||
|
||
if (menu->wm_msg == WM_CREATE)
|
||
{
|
||
// 刷新当前窗体
|
||
menu->wm_msg = 0;
|
||
}
|
||
else if (menu->wm_msg == WM_NEXT)
|
||
{
|
||
// 下一个窗体
|
||
menu->current_index = (menu->current_index + 1) % menu->pages->cnt;
|
||
menu->wm_msg = 0;
|
||
}
|
||
else if (menu->wm_msg == WM_REFUSH)
|
||
{
|
||
// 刷新当前窗体
|
||
menu->wm_msg = 0;
|
||
}
|
||
|
||
menu_page_t *cur_page = get_menu_page(menu->current_index);
|
||
if (cur_page != NULL)
|
||
{
|
||
cur_page->CurrentOperate();
|
||
}
|
||
|
||
delay_ms(10);
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
*/
|
||
#ifndef __MENU_H__
|
||
#define __MENU_H__
|
||
#include "lib.h"
|
||
|
||
#define KEY_ESC BIT1 // 返回
|
||
#define KEY_UP BIT2 // 上
|
||
#define KEY_DOWN BIT3 // 下
|
||
#define KEY_ENT BIT4 // 确认
|
||
#define KEY_LEFT BIT5 // 左
|
||
#define KEY_RIGHT BIT6 // 右
|
||
#define KEY_AUTO BIT7 // 自动
|
||
|
||
#define WM_CREATE BIT8 // 创建
|
||
#define WM_REFUSH BIT9 // 用于刷新当前窗体
|
||
#define WM_NEXT BIT10 // 下一个窗体
|
||
#define WM_LONG BIT11 // 长按
|
||
#define WM_LOADING BIT12 // 加载中
|
||
#define WM_COMPLETE BIT13 // 加载完成
|
||
|
||
#define KEY_IS_LONG(st) (st & WM_LONG)
|
||
|
||
#define MENU_WHAT(n) \
|
||
{ \
|
||
(uint8_t **)n, (sizeof(n) / sizeof(uint8_t *)), 0 \
|
||
}
|
||
|
||
typedef struct MENU_TXT menu_txt_t;
|
||
typedef struct MENU menu_t;
|
||
|
||
// Bar型菜单的数据结构
|
||
struct MENU_TXT
|
||
{
|
||
uint8_t **Text; // 指向显示内容数组的指针
|
||
uint8_t TextNum; // 项个数
|
||
void *(*Action)(); // 对应的执行函数
|
||
};
|
||
|
||
// 父窗 函数 (索引号从1开始,0表示没有下一个窗体,也没有父窗体)
|
||
typedef struct
|
||
{
|
||
uint8_t Index; // 窗体索引号 (从1开始)
|
||
uint8_t FatherIndex; // 父窗体索引号
|
||
uint8_t CurItem; // 当前状态索引号
|
||
uint8_t NextItem; // 下个窗体的索引号 (从1开始)
|
||
void (*CurrentOperate)(); // 当前状态应该执行的功能操作
|
||
} menu_page_t;
|
||
|
||
struct MENU
|
||
{
|
||
uint16_t menu_ticks; // 菜单刷新时间
|
||
clist_node_t *pages; // 窗体链表
|
||
volatile uint64_t wm_msg; // 窗体消息
|
||
uint8_t current_index; // 当前窗体索引号
|
||
uint32_t key_long_ticks; // 长按时间
|
||
uint8_t dir; // 按键方向 0:正常, 1:180度
|
||
};
|
||
|
||
extern menu_t *menu_create(uint16_t menu_ticks); // 创建菜单
|
||
extern void menu_rebuild(void);
|
||
extern menu_t *get_menu(void); // 获取菜单
|
||
extern void menu_page_add(menu_page_t *page); // 添加菜单页面
|
||
extern menu_page_t *get_menu_page(uint8_t index); // 获取菜单页面
|
||
extern menu_page_t *get_menu_sub_page(uint8_t index, uint8_t sub_index); // 获取菜单子页面
|
||
extern uint8_t get_menu_sub_page_count(uint8_t index, uint8_t sub_index); // 获取菜单子页面个数
|
||
|
||
extern void menu_key_register(uint64_t key); // 注册按键
|
||
extern void menu_key_long_start(void); // 开始长按
|
||
extern void menu_key_long_stop(void); // 停止长按
|
||
extern void menu_set_scandir(uint8_t dir); // 设置菜单扫描方向
|
||
extern void menu_set_ticks(uint16_t menu_ticks); // 设置菜单刷新时间
|
||
|
||
extern void menu_detection(void); // 菜单检测
|
||
extern void menu_timer_start(uint16_t time, uint64_t wm_msg); // 启动菜单定时器
|
||
extern void menu_timer_stop(void); // 关闭菜单定时器
|
||
#endif // __MENU_H__
|