当前位置: 首页 > news >正文

一个适合MCU的分级菜单框架

框架结构体如下:

struct ui_menu
{uint8_t item;                         // 当前选择的子菜单编号uint8_t level;                          // 菜单级别,0是最高级别,主菜单。struct ui_menu* parent;                 // 父菜单,即上一级菜单 struct ui_menu* items[UI_MENU_ITEM_MAX];//此菜单下的子菜单uint8_t (*on_Key_Up)(void);             // 返回值,是否是最后一个子项,可根据此返回值执行特定的操作uint8_t (*on_Key_Down)(void);           // 返回值,是否是最后一个子项,可根据此返回值执行特定的操作struct ui_menu* (*on_Key_Back)(void);   // 返回上一级菜单struct ui_menu* (*on_Key_OK)(uint8_t* flag);void (*menu_Show)(void);                // 显示逻辑在此处执行void (*menu_Enter)(uint8_t item);       // 进入此菜单会被调用一次void (*menu_Exit)(void);                // 退出此菜单会被调用一次
};

菜单的链接实现

/** 连接菜单* @param in:parent:父菜单,为空则为顶级菜单* @param in:item:父菜单下的一个菜单项,不能为空* @param in:itemIndex:本菜单功能不使用动态分配,索引不能超过最大索引。*/
int UI_Menu_Link(ui_menu_t* parent,ui_menu_t* item,uint8_t itemIndex)
{if(item == NULL){return -1;}if(itemIndex >= UI_MENU_ITEM_MAX){return -1;}if(parent == NULL){return -1;}item->level = parent->level + 1;        // 将当前项设置为父菜单的下一级item->parent = parent;parent->items[itemIndex] = item;return 0;
}ui_menu_t* UI_Menu_Top_Get(ui_menu_t* item)
{ui_menu_t* top = item;if(top != NULL){while(top->parent != NULL){top = top->parent;}}return top;}

菜单的调用方式,根据不同的按键执行对应的功能。

void UI_Page_Menu_Handler(uint16_t key)
{uint16_t keyEvent = key;uint8_t isSave = 0;     if(keyEvent == KEY_OK)      // 保存参数,进入下一步{if(curMenu->on_Key_OK){curMenu = curMenu->on_Key_OK(&isSave);      // 调用当前菜单的OKif(curMenu->menu_Enter){if(curMenu->level > lastMenu->level){curMenu->menu_Enter(lastMenu->itemID);}}lastMenu = curMenu;}else{isSave = 0xFF;}if(isSave == 1)      // 保存数据{}else if(isSave == 0){}        }else if(keyEvent == KEY_BACK){if(curMenu->menu_Exit){curMenu->menu_Exit();}if(curMenu->on_Key_Back){curMenu = curMenu->on_Key_Back();lastMenu = curMenu;}}else if(keyEvent == KEY_UP){if(curMenu->on_Key_Up){if(curMenu->on_Key_Up()){}else{}}        }else if(keyEvent == KEY_DOWN){if(curMenu->on_Key_Down){if(curMenu->on_Key_Down()){}else{}}}  curMenu->menu_Show();
}

本框架没有使用动态内存分配。在菜单分级较多的情况下,没有框架的支持,写起来会显得非常混乱。在框架的支持下,可以将各个菜单功能解耦合,利于后期的维护及扩展。

http://www.lryc.cn/news/594783.html

相关文章:

  • 格式工厂5.21.0简介
  • 设计模式六:工厂模式(Factory Pattern)
  • 从安装到上手:Ubuntu 22.04 玩转 Containerd 2.1.3 容器运行时
  • 在 Windows上用WSL和VSCode进行Linux开发环境配置
  • 《使用 IDEA 部署 Docker 应用指南》
  • 在Anolis8.6上源码编译安装部署OpenVAS(GVM)未完待续
  • git bash命令不够完善,想整合msys2该怎么办?
  • Dynamics 365 Contact Center是什么
  • Java 解析前端上传 ZIP 压缩包内 Excel 文件的完整实现方案
  • 前端开发者快速理解Spring Boot项目指南
  • 在 Angular 应用程序中使用 Genkit 的完整指南
  • docker 容器学习
  • Three.js 全景图(Equirectangular Texture)教程:从加载到球面映射
  • AR技术:应急响应的加速利器
  • AR技术:石化行业培训的“游戏规则改变者”
  • Web开发:ABP框架12——中间件Middleware的创建和使用
  • AR巡检和传统巡检的区别
  • CCLink IE转ModbusTCP网关与三菱PLC通讯无纸记录器
  • uni-app开发小程序,根据图片提取主题色值
  • 网络编程基础:从 OSI 模型到 TCP/IP 协议族的全面解析
  • Android 中 SystemServiceManager 和 ServiceManager 的应用场景、区别与联系
  • 漏洞扫描 + 渗透测试:双轮驱动筑牢网络安全防线
  • Ubuntu 22.04 使用 Docker 安装 Redis 5 (安装包形式)
  • 内网与外网是通过什么进行传输的?内外网文件传输的安全方法
  • C#最佳实践:为何应尽量减少静态类的使用
  • 迅为八核高算力RK3576开发板摄像头实时推理测试 RetinaFace人脸检测
  • Curtain e-locker 易锁防泄密:无需网络隔离,实现安全与效率并存
  • 大腾智能国产3D CAD软件正式上架华为云云商店
  • 进程资源分配的安全性判断与安全序列
  • ZooKeeper学习专栏(四):单机模式部署与基础操作详解