Files
menu/examples/menu_example.c
2025-12-18 21:24:20 +08:00

304 lines
7.9 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.

/**
* @file menu_example.c
* @brief 菜单组件使用示例
* @note 工业级嵌入式菜单组件 - 使用示例
*/
#include "menu.h"
#include "menu_port.h"
#include <stdio.h>
// 条件编译:处理不同平台的键盘输入函数
#if defined(_WIN32)
#include <conio.h> // Windows平台
#else
// MinGW或其他平台的模拟实现
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
int _kbhit(void)
{
struct termios oldt, newt;
int ch;
int oldf;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
ch = getchar();
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
fcntl(STDIN_FILENO, F_SETFL, oldf);
if(ch != EOF)
{
ungetc(ch, stdin);
return 1;
}
return 0;
}
int _getch(void)
{
struct termios oldt, newt;
int ch;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
ch = getchar();
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
return ch;
}
#endif
/************************** 菜单节点ID定义 **************************/
#define MENU_ID_MAIN 100 ///< 主菜单
#define MENU_ID_SETTINGS 200 ///< 设置菜单
#define MENU_ID_DISPLAY 201 ///< 显示设置
#define MENU_ID_LANGUAGE 202 ///< 语言设置
#define MENU_ID_PARAMETER 300 ///< 参数设置
#define MENU_ID_ABOUT 400 ///< 关于
/************************** 参数ID定义 **************************/
#define PARAM_ID_BRIGHTNESS 1000 ///< 亮度参数
#define PARAM_ID_CONTRAST 1001 ///< 对比度参数
/************************** 菜单回调函数 **************************/
/**
* @brief 主菜单进入回调
* @param node_id 菜单节点ID
* @return 错误码
*/
static MenuErrCode menu_cb_main(MenuNodeId node_id)
{
(void)node_id; // 未使用的参数
printf("Enter Main Menu\r\n");
return MENU_OK;
}
/**
* @brief 设置菜单进入回调
* @param node_id 菜单节点ID
* @return 错误码
*/
static MenuErrCode menu_cb_settings(MenuNodeId node_id)
{
(void)node_id; // 未使用的参数
printf("Enter Settings Menu\r\n");
return MENU_OK;
}
/**
* @brief 显示设置进入回调
* @param node_id 菜单节点ID
* @return 错误码
*/
static MenuErrCode menu_cb_display(MenuNodeId node_id)
{
(void)node_id; // 未使用的参数
printf("Enter Display Settings\r\n");
return MENU_OK;
}
/**
* @brief 语言设置进入回调
* @param node_id 菜单节点ID
* @return 错误码
*/
static MenuErrCode menu_cb_language(MenuNodeId node_id)
{
(void)node_id; // 未使用的参数
printf("Enter Language Settings\r\n");
return MENU_OK;
}
/**
* @brief 参数设置进入回调
* @param node_id 菜单节点ID
* @return 错误码
*/
static MenuErrCode menu_cb_parameter(MenuNodeId node_id)
{
(void)node_id; // 未使用的参数
printf("Enter Parameter Settings\r\n");
return MENU_OK;
}
/**
* @brief 关于菜单进入回调
* @param node_id 菜单节点ID
* @return 错误码
*/
static MenuErrCode menu_cb_about(MenuNodeId node_id)
{
(void)node_id; // 未使用的参数
printf("Enter About Menu\r\n");
printf("Industrial Menu Component v1.0\r\n");
printf("Highly Portable & Modular\r\n");
return MENU_OK;
}
/************************** 辅助函数 **************************/
/**
* @brief 按键扫描函数Windows平台示例
* @return 按键事件类型
*/
static MenuEventType key_scan(void)
{
if (_kbhit())
{
int key = _getch();
switch (key)
{
case 'w':
case 'W':
case 72: // 上箭头
return MENU_EVENT_KEY_UP;
case 's':
case 'S':
case 80: // 下箭头
return MENU_EVENT_KEY_DOWN;
case 13: // 回车键
return MENU_EVENT_KEY_ENTER;
case 'b':
case 'B':
case 27: // ESC键
return MENU_EVENT_KEY_BACK;
default:
break;
}
}
return MENU_EVENT_NONE;
}
/************************** 主函数 **************************/
int main(void)
{
printf("Industrial Menu Component Example\r\n");
printf("==================================\r\n");
printf("Controls:\r\n");
printf(" W/Up Arrow - Up\r\n");
printf(" S/Down Arrow - Down\r\n");
printf(" Enter - Enter\r\n");
printf(" B/ESC - Back\r\n");
printf(" Q - Quit\r\n");
printf("==================================\r\n\r\n");
/************************** 初始化菜单组件 **************************/
MenuErrCode err = menu_init();
if (err != MENU_OK)
{
printf("Menu initialization failed: %d\r\n", err);
return -1;
}
printf("Menu initialized successfully\r\n\r\n");
/************************** 注册菜单节点 **************************/
// 注册主菜单
err = menu_register_node(0, MENU_ID_MAIN, "Main Menu", menu_cb_main, NULL);
if (err != MENU_OK)
{
printf("Register Main Menu failed: %d\r\n", err);
return -1;
}
// 注册设置菜单
err = menu_register_node(MENU_ID_MAIN, MENU_ID_SETTINGS, "Settings", menu_cb_settings, NULL);
if (err != MENU_OK)
{
printf("Register Settings Menu failed: %d\r\n", err);
return -1;
}
// 注册显示设置菜单
err = menu_register_node(MENU_ID_SETTINGS, MENU_ID_DISPLAY, "Display Settings", menu_cb_display, NULL);
if (err != MENU_OK)
{
printf("Register Display Menu failed: %d\r\n", err);
return -1;
}
// 注册语言设置菜单
err = menu_register_node(MENU_ID_SETTINGS, MENU_ID_LANGUAGE, "Language", menu_cb_language, NULL);
if (err != MENU_OK)
{
printf("Register Language Menu failed: %d\r\n", err);
return -1;
}
// 注册参数设置菜单
err = menu_register_node(MENU_ID_MAIN, MENU_ID_PARAMETER, "Parameters", menu_cb_parameter, NULL);
if (err != MENU_OK)
{
printf("Register Parameter Menu failed: %d\r\n", err);
return -1;
}
// 注册关于菜单
err = menu_register_node(MENU_ID_MAIN, MENU_ID_ABOUT, "About", menu_cb_about, NULL);
if (err != MENU_OK)
{
printf("Register About Menu failed: %d\r\n", err);
return -1;
}
/************************** 注册参数 **************************/
#if MENU_CONFIG_ENABLE_PARAM
// 注册亮度参数范围0-100默认50步长1
err = menu_param_register(MENU_ID_DISPLAY, PARAM_ID_BRIGHTNESS,
MENU_PARAM_TYPE_UINT8, 0.0f, 100.0f, 50.0f, 1.0f);
if (err != MENU_OK)
{
printf("Register Brightness Param failed: %d\r\n", err);
return -1;
}
// 注册对比度参数范围0-100默认50步长1
err = menu_param_register(MENU_ID_DISPLAY, PARAM_ID_CONTRAST,
MENU_PARAM_TYPE_UINT8, 0.0f, 100.0f, 50.0f, 1.0f);
if (err != MENU_OK)
{
printf("Register Contrast Param failed: %d\r\n", err);
return -1;
}
#endif
printf("Menu nodes registered successfully\r\n\r\n");
/************************** 主循环 **************************/
while (1)
{
// 扫描按键
MenuEventType event = key_scan();
if (event != MENU_EVENT_NONE)
{
// 发送按键事件到菜单组件
menu_post_event(event, 0);
}
// 处理菜单主循环
menu_main_loop();
// 检查退出条件
if (_kbhit() && _getch() == 'q')
{
printf("\r\nQuit program\r\n");
break;
}
// 轻微延迟避免CPU占用过高
menu_port_delay_ms(10);
}
return 0;
}