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

一个适合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.xdnf.cn/news/15917.html

相关文章:

  • .NET SDK 9.0.200引入对SLNX解决方案文件的支持
  • django filter按两个属性 去重
  • Linux——自制shell命令行解释器
  • 【LeetCode 热题 100】208. 实现 Trie (前缀树)
  • 剖析Sully.ai:革新医疗领域的AI助手功能启示
  • ssms(SQL 查询编辑器) 添加快捷键 Ctrl+D(功能等于Ctrl+C + Ctrl+V),一步到位
  • Bun v1.2.19发布,node_modules隔离,sql比node快6倍
  • Kotlin 高阶函数初步学习
  • Laravel 系统版本查看及artisan管理员密码找回方法针对各个版本通用方法及原理-优雅草卓伊凡
  • 信息学奥赛一本通 1576:【例 2】选课 | 洛谷 P2014 [CTSC1997] 选课
  • 子网划分核心原理 (网络原理1)
  • [学习] Hilbert变换:从数学原理到物理意义的深度解析与仿真实验(完整实验代码)
  • 《通信原理》学习笔记——第五章
  • Spring 源码阅读(二) 核心概念解析 ApplicationContext、类型转化
  • 【PyTorch】图像二分类项目
  • 【JS逆向基础】数据库之mysql
  • 7.19-7.20 Java基础 | File类 I/O流学习笔记
  • pyhton基础【27】课后拓展
  • 【Linux】3. Shell语言
  • 深度相机的工作模式(以奥比中光深度相机为例)
  • SQL Server(2022)安装教程及使用_sqlserver下载安装图文
  • 《计算机网络》实验报告四 TCP协议分析
  • 0719代码调试记录
  • IsaacLab学习记录(四)
  • Milvus Dify 学习笔记
  • 题单【循环结构】
  • 基于单片机出租车计价器设计
  • 30天打牢数模基础-决策树讲解
  • 【C语言】字符串与字符函数详解(上)
  • C++ 并发 future, promise和async