【VtorMenu多级菜单】
【VtorMenu多级菜单】
【01】序
源码gitee网址,与视频讲解网址
https://gitee.com/vtor3478/vtor_menu
https://www.bilibili.com/video/BV1vB4y1E7Ej
VtorMenu由伪钞vtor原创开发,转载注明出处
发布于gitee,目前仅有diaan工程包含了该子模块
发布视频后对其进行了模块化,但大差不差,问题不大
VtorMenu及其所属工程遵循LGPL V3,
如需移植,请遵循开源协议
VtorMenu大量使用指针与树,
理解需要一定c语言与数据结构基础
VtorMenu包含函数指针模拟晚绑定,
理解需要一定设计模式基础
VtorMenu使用纯c语言,接口隔离,
可便于移植到用户的工程中
本设计(包括但不限于文字、图片、视频)
发布于博客园(主要),吾爱论坛,伪钞杂货铺微信公众号,
哔哩哔哩,知乎(暂定),开源中国(暂定),影子论坛(待定)等
【02】设计方案
【0201】结构体设计
【0201-结构体设计.png】

内部成员有菜单名,
菜单项的值
指向其他菜单项的指针
显示自身的函数
双击回调函数(用于扩展)
当前菜单内所选项
菜单内有多少项
【0202】菜单实例
【0202-菜单实例(参考手机).png】

参考我的miui手机的设置,写了基本菜单
使用缩进表示层级,最顶层为自身,
下面有my device,mobile net,display三个大菜单,
下面还有子菜单,自行查看即可
【0203】构建菜单树方法
【0203-构建菜单树方法.png】

详见MENU_RelateItem函数
参数为父菜单,和子项的指针
将子项根据父菜单的itemCnt添加到父菜单的item指针数组中
再将子项的item[0]指向父菜单,
这里就完成了树的创建
后面是display函数,如果为空,则使用默认的显示函数
【0204】操作菜单
【0204-操作菜单.png】

在MENU_Operate函数中
opType为操作类型
opValue为操作值
操作类型有 无操作 单击 选择项 更改值 双击
单击会进入所选菜单,
如果是自身,会回到上级菜单,省去了一个项
如果是子项,会进入选中的子项
此操作会影响全局指针变量pCurVtorMenu,特地单独处理
双击调用回调函数,暂时为空,谁知道用户会有什么奇怪需求呢
选择项是操作pCurVtorMenu,因为当前菜单中的所选项
更改值是操作pCurMenuItem,因为要改变选中的那一项
需要注意,因为item[0]指向父菜单,
所以需要重新指向自身!!!!!!!
【0205】显示菜单
【0205-显示菜单.png】

通过pCurVtorMenu获取其子项
并通过函数指针display进行显示
与操作相似,当遇上item[0]时,需要重新指向自身!!
在MENU_DisplayItem函数中,
有exData扩展表示是否被选中
如果被选中,反色,且前面显示“>”符号
并将其格式化,再通过oled进行显示,同时串口输出
【03】用户使用方法
说了这么多,终于到使用方法了
【0301】用户初始化菜单
【0301-用户初始化菜单.png】

前面我使用了手机内设置作为参考菜单
并且用缩进表明层级关系
在用户使用方法中,建议模仿我
使用局部指针指向具体菜单项
然后为各个菜单项添加子菜单,自顶向下添加
比如device,mobilenet,display均是root的子菜单
此外还需注意,为保证返回上级不会异常
需要将root设置为root的子菜单
【0302】用户使用菜单
【0302-用户使用菜单.png】

在User_Init中运行一次MENU_Init,构建菜单树
示例为1秒操作并更新菜单
调用MENU_Operate操作菜单
调用MENU_Display显示菜单
因为设备不同,你应该要自行实现MENU_Display
【0303】操作菜单示例
【0303-操作菜单示例.png】

电脑键盘如图所示
以 数字8 举例,触发的操作应该是是上移所选项
所以opType为2,Opvalue为1
使用正点原子xcom发送十六进制【0x21】即可
在diaan工程中
串口接收中断回调函数中opType与opValue
再在主循环中进行处理即可。
vtor_menu多级菜单,全文完,2022年9月18日。