This repository has been archived on 2025-02-28. You can view files and clone it, but cannot push or open issues or pull requests.
controller-hd/User/lib/menu/menu.h

171 lines
5.2 KiB
C
Raw Permalink 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.

/***
* @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__