256 lines
6.5 KiB
C
256 lines
6.5 KiB
C
/*
|
||
* @Author: xxx
|
||
* @Date: 2023-08-03 17:13:28
|
||
* @LastEditors: xxx
|
||
* @LastEditTime: 2023-08-21 17:01:29
|
||
* @Description:
|
||
这是一个简单的菜单系统,其中包含一个定时器,当定时器过期时发送消息。菜单系统由多个菜单页面组成,用户可以通过特定键(如“NEXT”和“REFUSH”)导航过各个页面。当定时器过期时,菜单系统将发送消息给下一个页面或刷新当前页面。
|
||
|
||
The menu_create 函数创建一个新的菜单,通过初始化一个菜单页面列表来完成。The menu_page_add 函数向菜单页面列表中添加一个新的菜单页面。The menu_key_register 函数注册一个特定的键,用于导航菜单。The menu_timer_start 函数开始菜单定时器,指定一个时间并为过期时发送一个消息。The menu_timer_stop 函数关闭菜单定时器。
|
||
|
||
The get_menu_page 函数根据索引返回指定的菜单页面,如果没有找到则返回 NULL。The menu_detection 函数检查菜单定时器是否正在运行,如果运行,它 decrements 定时器计数器并在定时器过期时发送消息。同时,它检查当前菜单页面并根据接收到的消息执行相应的操作。
|
||
* email:
|
||
* Copyright (c) 2023 by xxx, All Rights Reserved.
|
||
*/
|
||
#include "menu.h"
|
||
#include "sys.h"
|
||
|
||
static menu_t _menu;
|
||
static volatile uint16_t menu_times = 0; // 菜单定时器时间
|
||
static volatile uint64_t next_wm_msg = 0; // 下一个窗体消息
|
||
static volatile BOOL menu_times_start_flag = FALSE; // 菜单定时器启动标志
|
||
/**
|
||
* @brief 创建菜单
|
||
* @param {uint16_t} menu_ticks - 菜单定时器时间
|
||
* @return {menu_t *} - 创建的菜单指针
|
||
*/
|
||
menu_t *menu_create(uint16_t menu_ticks)
|
||
{
|
||
if (NULL == _menu.pages)
|
||
{
|
||
clist_init(&_menu.pages);
|
||
}
|
||
_menu.menu_ticks = menu_ticks;
|
||
return &_menu;
|
||
}
|
||
|
||
/**
|
||
* @brief 设置菜单定时器时间
|
||
* @param {uint16_t} menu_ticks
|
||
* @return {*}
|
||
* @note
|
||
*/
|
||
void menu_set_ticks(uint16_t menu_ticks)
|
||
{
|
||
_menu.menu_ticks = menu_ticks;
|
||
}
|
||
|
||
/**
|
||
* @brief 获取菜单
|
||
* @return {menu_t *} - 菜单指针
|
||
*/
|
||
menu_t *get_menu(void)
|
||
{
|
||
return &_menu;
|
||
}
|
||
|
||
/**
|
||
* @brief 向菜单页面列表中添加一个菜单页面
|
||
* @param {menu_page_t *} page - 要添加的菜单页面指针
|
||
*/
|
||
void menu_page_add(menu_page_t *page)
|
||
{
|
||
clist_push_back(&_menu.pages, (cnode)page);
|
||
}
|
||
|
||
/**
|
||
* @brief 注册菜单按键
|
||
* @param {uint8_t} key - 要注册的菜单按键
|
||
*/
|
||
void menu_key_register(uint64_t key)
|
||
{
|
||
if (KEY_IS_LONG(key))
|
||
{
|
||
if (_menu.wm_msg == 0)
|
||
{
|
||
_menu.wm_msg = key;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
_menu.wm_msg = key;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 按键长按计时开始
|
||
* @return {*}
|
||
* @note
|
||
*/
|
||
void menu_key_long_start(void)
|
||
{
|
||
if (_menu.key_long_ticks == 0)
|
||
{
|
||
_menu.key_long_ticks = sys_millis();
|
||
}
|
||
}
|
||
|
||
void menu_key_long_stop(void)
|
||
{
|
||
_menu.key_long_ticks = 0;
|
||
}
|
||
|
||
void menu_set_scandir(uint8_t dir)
|
||
{
|
||
_menu.dir = dir > 1 ? 1 : dir;
|
||
}
|
||
/**
|
||
* @brief 启动菜单定时器
|
||
* @param {uint16_t} time - 菜单定时器时间
|
||
* @param {uint64_t} wm_msg - 发送的消息
|
||
*/
|
||
void menu_timer_start(uint16_t time, uint64_t wm_msg)
|
||
{
|
||
menu_times = time / _menu.menu_ticks;
|
||
next_wm_msg = wm_msg;
|
||
}
|
||
|
||
/**
|
||
* @brief 关闭菜单定时器
|
||
* @return {*}
|
||
*/
|
||
void menu_timer_stop(void)
|
||
{
|
||
menu_times = 0;
|
||
}
|
||
|
||
/**
|
||
* @brief 获取指定索引的菜单页面
|
||
* @param {uint8_t} index - 菜单页面的索引
|
||
* @return {*} - 找到的菜单页面指针,否则为NULL
|
||
*/
|
||
menu_page_t *get_menu_page(uint8_t index)
|
||
{
|
||
for (clist_node_t *p = _menu.pages; p != NULL; p = p->Next)
|
||
{
|
||
menu_page_t *page = (menu_page_t *)p->data;
|
||
if (page->Index == index)
|
||
{
|
||
return page;
|
||
}
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
menu_page_t *get_menu_sub_page(uint8_t index, uint8_t sub_index)
|
||
{
|
||
menu_page_t *menu = get_menu_page(index);
|
||
uint8_t i = 0;
|
||
for (clist_node_t *p = _menu.pages; p != NULL; p = p->Next)
|
||
{
|
||
menu_page_t *page = (menu_page_t *)p->data;
|
||
if (menu->Index == page->FatherIndex)
|
||
{
|
||
i++;
|
||
if (i == sub_index)
|
||
{
|
||
return page;
|
||
}
|
||
}
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
/**
|
||
* @brief 获取指定索引的菜单页面的子菜单页面个数
|
||
* @param {uint8_t} index
|
||
* @return {*}
|
||
* @note
|
||
*/
|
||
uint8_t get_menu_sub_page_count(uint8_t index, uint8_t sub_index)
|
||
{
|
||
uint8_t count = 0;
|
||
menu_page_t *menu = get_menu_sub_page(index, sub_index);
|
||
if (menu != NULL)
|
||
{
|
||
for (clist_node_t *p = _menu.pages; p != NULL; p = p->Next)
|
||
{
|
||
menu_page_t *page = (menu_page_t *)p->data;
|
||
if (menu->Index == page->FatherIndex)
|
||
{
|
||
count++;
|
||
}
|
||
}
|
||
}
|
||
|
||
return count;
|
||
}
|
||
|
||
/**
|
||
* @brief 菜单重建
|
||
*/
|
||
void menu_rebuild(void)
|
||
{
|
||
_menu.wm_msg = WM_CREATE;
|
||
}
|
||
|
||
/**
|
||
* @brief 菜单检测
|
||
*/
|
||
void menu_detection(void)
|
||
{
|
||
if (menu_times > 0) // 定时器启动判断
|
||
{
|
||
menu_times--; // 定时器计数
|
||
if (menu_times == 0) // 定时器时间到,发送消息
|
||
{
|
||
_menu.wm_msg = next_wm_msg;
|
||
menu_times_start_flag = TRUE;
|
||
}
|
||
}
|
||
|
||
uint32_t count = clist_node_count(_menu.pages); // 获取链表节点个数
|
||
if (count == 0)
|
||
{
|
||
return; // 没有菜单页面
|
||
}
|
||
for (clist_node_t *p = _menu.pages; p != NULL; p = p->Next)
|
||
{
|
||
menu_page_t *page = (menu_page_t *)p->data;
|
||
if (page->Index == _menu.current_index)
|
||
{
|
||
if (menu_times_start_flag == TRUE)
|
||
{
|
||
menu_times_start_flag = FALSE; // 定时器启动标志清零
|
||
switch (_menu.wm_msg)
|
||
{
|
||
case WM_NEXT:
|
||
_menu.current_index = page->NextItem; // 下一个菜单页面
|
||
_menu.wm_msg = WM_CREATE;
|
||
return;
|
||
case WM_REFUSH:
|
||
_menu.current_index = page->Index; // 当前菜单页面
|
||
return;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (page->CurrentOperate != NULL)
|
||
{
|
||
page->CurrentOperate(); // 当前页面操作
|
||
_menu.wm_msg = 0;
|
||
}
|
||
else
|
||
{
|
||
_menu.current_index = page->FatherIndex; // 返回上一级菜单
|
||
_menu.wm_msg = 0;
|
||
}
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|