/** * @file menu_example.c * @brief 菜单组件使用示例 * @note 工业级嵌入式菜单组件 - 使用示例 */ #include "menu.h" #include "menu_port.h" #include // 条件编译:处理不同平台的键盘输入函数 #if defined(_WIN32) #include // Windows平台 #else // MinGW或其他平台的模拟实现 #include #include #include 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; }