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.c

256 lines
6.5 KiB
C
Raw 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: 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;
}
}
}