增加网络配置界面
This commit is contained in:
+73
-12
@@ -12,6 +12,14 @@
|
||||
* 2026-09-08 王建锋 按代码规范 V1.0 补全分区注释与关键行注释;函数定义括号改 K&R 风格(同行)
|
||||
* 2026-09-08 王建锋 4 层容器→单一持久容器(焦点/键唯一入口;键回调深度改取
|
||||
* s_depth,去掉 user_data=depth;container/focus 调用去参)
|
||||
* 2026-09-09 王建锋 密码页路由:需密码叶子(ui_menu_tab_has_pwd)ENTER
|
||||
* → 先密码页;确认一致由 menu_password_ok 续做原"进入"动作
|
||||
* (内容屏/子框)
|
||||
* 2026-09-09 王建锋 权限模型:密码检查提到内容页判断之前(带内容页的受保护
|
||||
* 叶子也先经密码页,修复"内容页叶子绕过密码"路由缺口);表 pwd
|
||||
* 列改布尔"需密码"(行尾 #P);密码页按所输密码授权(查看→只读
|
||||
* / 修改→可修改),授权经回调随开页传给内容页(页面经
|
||||
* is_editable 判编辑);无密码叶子直接进、默认只读
|
||||
*/
|
||||
|
||||
/* 头文件包含区 */
|
||||
@@ -23,8 +31,12 @@
|
||||
|
||||
#include "ui_content_page.h"
|
||||
|
||||
#include "ui_page_password.h"
|
||||
|
||||
#include "ui_menu_tab.h"
|
||||
|
||||
#include "ui_pwd_def.h"
|
||||
|
||||
#include "lvgl.h"
|
||||
|
||||
#define DBG_TAG "[UI_MENU]"
|
||||
@@ -95,15 +107,54 @@ static void menu_back(void) {
|
||||
* 入口参数:node - 菜单节点下标 uint8_t
|
||||
* 返回值:内容页 ID content_page_id_t;无内容页 = CONTENT_PAGE_COUNT
|
||||
* 限定条件:无
|
||||
* 函数说明:仅部分叶子有内容页(参考图 10/20/21);下标对应 ui_menu_tab.c
|
||||
* node 1=装置信息、3=交流量、4=直流量(表序变更时须同步本映射)
|
||||
* 函数说明:仅部分叶子有内容页(参考图 10/20/21 + 网口设置);下标对应
|
||||
* ui_menu_tab.c
|
||||
* node 1=装置信息、3=交流量、4=直流量、30=网口设置(表序变更时须同步本映射)
|
||||
*/
|
||||
static content_page_id_t menu_content_page_for(uint8_t node) {
|
||||
switch (node) {
|
||||
case 1u: return CONTENT_PAGE_DEVICE_INFO; /* 装置信息(L1 叶子) */
|
||||
case 3u: return CONTENT_PAGE_AC; /* 交流量(实时数据子项) */
|
||||
case 4u: return CONTENT_PAGE_DC; /* 直流量(实时数据子项) */
|
||||
default: return (content_page_id_t)CONTENT_PAGE_COUNT; /* 无内容页 */
|
||||
case 1u: return CONTENT_PAGE_DEVICE_INFO; /* 装置信息(L1 叶子) */
|
||||
case 3u: return CONTENT_PAGE_AC; /* 交流量(实时数据子项) */
|
||||
case 4u: return CONTENT_PAGE_DC; /* 直流量(实时数据子项) */
|
||||
case 30u: return CONTENT_PAGE_NET_CFG; /* 网口设置(通讯参数子项,需密码) */
|
||||
default: return (content_page_id_t)CONTENT_PAGE_COUNT; /* 无内容页 */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:密码页确认一致回调(预装进密码页模块;uiTask 上下文调用)
|
||||
* 入口参数:perm - 密码页按所输密码授予的权限 ui_perm_t(UI_PERM_MODIFY/UI_PERM_VIEW)
|
||||
* 返回值:无
|
||||
* 限定条件:密码页打开中;导航状态未变(选中条目仍为该受保护叶子)
|
||||
* 函数说明: 1. 先关密码页(焦点回菜单容器、切回菜单屏;与 ESC 路径同模式,
|
||||
* 事件内删对象由 LVGL e->deleted 机制保证安全)
|
||||
* 2. 再沿未变的导航状态续做"进入"动作:有内容页 → 开内容页(携授予的
|
||||
* 权限;页面经 is_editable 判只读/可编辑);否则压层进子框
|
||||
* (叶子 → 空白终点框,权限不涉及)
|
||||
* 3. 防御:状态异常 / 最深层无子层可压时仅停在菜单屏(页已关)
|
||||
*/
|
||||
static void menu_password_ok(uint8_t perm) {
|
||||
ui_content_page_close(); /* 先关密码页回菜单屏,后续动作才不会落在被盖住的菜单屏上 */
|
||||
|
||||
uint8_t depth = s_depth;
|
||||
uint8_t kids[MENU_ITEM_MAX];
|
||||
uint8_t cnt = ui_menu_tab_children(s_path[depth], kids, MENU_ITEM_MAX);
|
||||
|
||||
if (cnt == 0u || s_sel[depth] >= cnt) {
|
||||
return; /* 防御:状态异常,页已关,停在菜单屏 */
|
||||
}
|
||||
|
||||
{
|
||||
uint8_t child = kids[s_sel[depth]];
|
||||
content_page_id_t pid = menu_content_page_for(child);
|
||||
|
||||
if (pid < CONTENT_PAGE_COUNT) {
|
||||
ui_content_page_open(pid, perm); /* 页已关,守卫可过:开目标内容页(携权限) */
|
||||
}
|
||||
else if (depth < MENU_PAGE_MAX - 1u) {
|
||||
menu_open(child); /* 压层:建新框 + 焦点移到新框(叶子 → 空白终点框) */
|
||||
}
|
||||
/* 最深层无子层可压:页已关,停在菜单屏 */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +165,10 @@ static content_page_id_t menu_content_page_for(uint8_t node) {
|
||||
* 返回值:无
|
||||
* 限定条件:ui_menu_init() 已完成
|
||||
* 函数说明: 1. UP/DOWN:移选(首尾环绕);选中越出可见区由显示层跟随滚动
|
||||
* 2. ENTER/RIGHT:叶子有内容页 → 切内容屏(不压层);否则进子框(叶子 → 空白终点框)
|
||||
* 2. ENTER/RIGHT:需密码叶子(含带内容页者)→ 密码页(授权按所输
|
||||
* 密码:查看→只读 / 修改→可修改,menu_password_ok 携权续进入);
|
||||
* 否则叶子有内容页 → 切内容屏(不压层,默认只读);
|
||||
* 再否则进子框(叶子 → 空白终点框)
|
||||
* 3. ESC/LEFT:关最右框(根框不响应)
|
||||
* 4. 空框(终点页 0 条目)只响应返回
|
||||
*/
|
||||
@@ -141,14 +195,21 @@ static void menu_key_handle(uint8_t depth, lv_key_t key) {
|
||||
case LV_KEY_RIGHT: {
|
||||
/* 进子框:空框无条目可进;最深层(depth=MAX-1)无子层可再开 */
|
||||
if (cnt > 0u) {
|
||||
content_page_id_t pid = menu_content_page_for(kids[s_sel[depth]]);
|
||||
uint8_t child = kids[s_sel[depth]];
|
||||
content_page_id_t pid = menu_content_page_for(child);
|
||||
|
||||
if (pid < CONTENT_PAGE_COUNT) {
|
||||
/* 叶子有内容页:切内容屏(不压层,导航状态原样保留;ESC 返回即还原) */
|
||||
ui_content_page_open(pid);
|
||||
if (ui_menu_tab_has_pwd(child)) {
|
||||
/* 需密码叶子(含带内容页者):先经密码页;授权按所输密码
|
||||
(查看→只读 / 修改→可修改),回调携权续做"进入"动作 */
|
||||
ui_page_password_arm(menu_password_ok);
|
||||
ui_content_page_open(CONTENT_PAGE_PASSWORD, (uint8_t)UI_PERM_VIEW);
|
||||
}
|
||||
else if (pid < CONTENT_PAGE_COUNT) {
|
||||
/* 叶子有内容页:无密码直接进(默认只读权限) */
|
||||
ui_content_page_open(pid, (uint8_t)UI_PERM_VIEW);
|
||||
}
|
||||
else if (depth < MENU_PAGE_MAX - 1u) {
|
||||
menu_open(kids[s_sel[depth]]); /* 压层:建新框 + 焦点移到新框(叶子 → 空白终点框) */
|
||||
menu_open(child); /* 压层:建新框 + 焦点移到新框(叶子 → 空白终点框) */
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user