#include "menu.h" #include #include /* 简单的静态菜单树: * * 层级 0: [运行界面] [定值设置] [查看数据] * │ │ * 层级 1: (子菜单...) (子菜单...) */ static MenuItem g_menuRun; static MenuItem g_menuSet; static MenuItem g_menuSee; static MenuItem g_menuSet1; static MenuItem g_menuSet2; void Menu_InitPC(MenuCtrl *ctrl) { memset(&g_menuRun, 0, sizeof(g_menuRun)); memset(&g_menuSet, 0, sizeof(g_menuSet)); memset(&g_menuSee, 0, sizeof(g_menuSee)); memset(&g_menuSet1, 0, sizeof(g_menuSet1)); memset(&g_menuSet2, 0, sizeof(g_menuSet2)); /* 0 级菜单 */ g_menuRun.name = "运行界面"; g_menuRun.tip = "显示运行状态"; g_menuRun.level = 0; g_menuRun.pos = 0; g_menuSet.name = "定值设置"; g_menuSet.tip = "进入定值设置菜单"; g_menuSet.level = 0; g_menuSet.pos = 1; g_menuSee.name = "查看数据"; g_menuSee.tip = "查看测量值和记录"; g_menuSee.level = 0; g_menuSee.pos = 2; /* 0 级链表关系 */ g_menuRun.before = &g_menuSee; g_menuRun.behind = &g_menuSet; g_menuSet.before = &g_menuRun; g_menuSet.behind = &g_menuSee; g_menuSee.before = &g_menuSet; g_menuSee.behind = &g_menuRun; /* 1 级菜单:定值设置下的两个子菜单 */ g_menuSet1.name = "保护定值"; g_menuSet1.tip = "编辑保护定值"; g_menuSet1.level = 1; g_menuSet1.pos = 0; g_menuSet1.higher = &g_menuSet; g_menuSet2.name = "通信参数"; g_menuSet2.tip = "编辑通信参数"; g_menuSet2.level = 1; g_menuSet2.pos = 1; g_menuSet2.higher = &g_menuSet; g_menuSet1.before = &g_menuSet2; g_menuSet1.behind = &g_menuSet2; g_menuSet2.before = &g_menuSet1; g_menuSet2.behind = &g_menuSet1; g_menuSet.lower = &g_menuSet1; /* 初始化控制结构 */ ctrl->head0 = &g_menuRun; ctrl->current = &g_menuRun; } /* 控制台绘制当前菜单状态 */ static void Menu_Draw(const MenuCtrl *ctrl) { const MenuItem *cur = ctrl->current; const MenuItem *p; printf("\n==== PC HMI 菜单模拟 ====\n"); printf("使用 W/S/A/D/Enter/Esc 操作,Ctrl+C 退出。\n\n"); /* 显示 0 级菜单 */ printf("[0级菜单]: "); p = ctrl->head0; if (!p) { printf("(空)\n"); return; } const MenuItem *start = p; do { if (p == cur) printf(" [*%s*] ", p->name); else printf(" %s ", p->name); p = p->behind; } while (p && p != start); printf("\n"); /* 若当前有下级,则显示 1 级菜单 */ if (cur->lower) { printf(" 子菜单:\n"); p = cur->lower; start = p; do { printf(" - %s\n", p->name); p = p->behind; } while (p && p != start); } /* 提示信息 */ printf("\n提示: %s\n", cur->tip ? cur->tip : ""); } void Menu_LoopStep(MenuCtrl *ctrl, int key) { MenuItem *cur = ctrl->current; switch (key) { case KEY_U: if (cur->before) cur = cur->before; break; case KEY_D: if (cur->behind) cur = cur->behind; break; case KEY_L: if (cur->higher) cur = cur->higher; break; case KEY_R: case KEY_ENT: if (cur->lower) cur = cur->lower; printf("\n>>> 进入 [%s] 功能(模拟用户层)...\n", cur->name); break; case KEY_ESC: if (cur->higher) cur = cur->higher; break; default: break; } ctrl->current = cur; Menu_Draw(ctrl); } int Menu_MapKey(int ch) { if (ch == 'w' || ch == 'W') return KEY_U; if (ch == 's' || ch == 'S') return KEY_D; if (ch == 'a' || ch == 'A') return KEY_L; if (ch == 'd' || ch == 'D') return KEY_R; if (ch == '\r' || ch == '\n') return KEY_ENT; if (ch == 27) return KEY_ESC; /* ESC */ return KEY_NONE; }