refactor(编号): UI 菜单层级 L0~L3 → 主界面/一级/二级/三级菜单(批次 3a)
这族是菜单深度号:L0 根、L1 一级、L2 二级、L3 三级。用户 2026-10-28:「编号看不懂」, 且与采集链分层的 L1~L5 撞形(同一份文档里两套 L 号,读的人得先猜是哪套)。 改法(生成物走生成器,不手改): - `tools/menu_gen/gen_menu.py`:加 MENU_LEVEL_NAMES 常量,生成 ui_menu_tab.c 的注释从 `/* 12 L2 */` 变成 `/* 12 二级菜单 */`;重跑生成器,生成物 42 行注释随之更新。 - 文档 4 篇 113 行:菜单页面设计(94)、内容页架构(10)、01_主界面_说明(8)、 中文字体生成与配置(1)。映射:L0 → 主界面(根)、L1/L2/L3 → 一级/二级/三级菜单; `4 级(L0~L3)` → `4 级(主界面 → 三级菜单)`;括号里的 `(L1)` → `(一级菜单)`。 范围纪律:只动 UI 菜单这一族。同名的测试层级族(L0/L0.5/L1/L2/L3,见测试开发标准流程) 与链路延迟分段 L1~L8 不动——那两个属批次 3 的另两族。 验证:@build 0 错 0 警;check_menu_rows 8 状态 PASS(5368 B 池不变);生成器重跑幂等 (rc=0,生成物只剩注释差异 42/42 行);doc-links 通过(195 文档);mojibake / bom-guard / 新编号门禁 / git diff --check 全绿。
This commit is contained in:
@@ -12,48 +12,48 @@
|
||||
#include "ui_menu_tab.h"
|
||||
|
||||
const ui_menu_node_t g_menu_tab[UI_MENU_TAB_COUNT] = {
|
||||
{ MENU_ROOT, 0u, "主界面" }, /* 0 L0 */
|
||||
{ 0, 0u, "装置信息" }, /* 1 L1 */
|
||||
{ 0, 0u, "实时数据" }, /* 2 L1 */
|
||||
{ 2, 0u, "交流量" }, /* 3 L2 */
|
||||
{ 2, 0u, "直流量" }, /* 4 L2 */
|
||||
{ 2, 0u, "遥信量" }, /* 5 L2 */
|
||||
{ 0, 0u, "参数定值" }, /* 6 L1 */
|
||||
{ 6, 0u, "整定" }, /* 7 L2 */
|
||||
{ 7, 1u, "参数" }, /* 8 L3 */
|
||||
{ 7, 1u, "定值" }, /* 9 L3 */
|
||||
{ 7, 1u, "控制字" }, /* 10 L3 */
|
||||
{ 7, 1u, "软压板" }, /* 11 L3 */
|
||||
{ 6, 0u, "查看" }, /* 12 L2 */
|
||||
{ 12, 0u, "参数" }, /* 13 L3 */
|
||||
{ 12, 0u, "定值" }, /* 14 L3 */
|
||||
{ 12, 0u, "控制字" }, /* 15 L3 */
|
||||
{ 12, 0u, "软压板" }, /* 16 L3 */
|
||||
{ 0, 0u, "三遥设置" }, /* 17 L1 */
|
||||
{ 17, 1u, "遥测死区" }, /* 18 L2 */
|
||||
{ 17, 1u, "遥测系数" }, /* 19 L2 */
|
||||
{ 17, 1u, "遥信类型" }, /* 20 L2 */
|
||||
{ 17, 1u, "遥信防抖" }, /* 21 L2 */
|
||||
{ 17, 1u, "双点遥信" }, /* 22 L2 */
|
||||
{ 0, 0u, "装置维护" }, /* 23 L1 */
|
||||
{ 23, 1u, "时钟设置" }, /* 24 L2 */
|
||||
{ 23, 1u, "强制复归" }, /* 25 L2 */
|
||||
{ 23, 1u, "手动录波" }, /* 26 L2 */
|
||||
{ 23, 1u, "清除记录" }, /* 27 L2 */
|
||||
{ 0, 0u, "通讯参数" }, /* 28 L1 */
|
||||
{ 28, 1u, "通讯设置" }, /* 29 L2 */
|
||||
{ 28, 1u, "网口设置" }, /* 30 L2 */
|
||||
{ 28, 1u, "SNTP设置" }, /* 31 L2 */
|
||||
{ 0, 0u, "记录查询" }, /* 32 L1 */
|
||||
{ 32, 0u, "SOE记录" }, /* 33 L2 */
|
||||
{ 32, 0u, "事故记录" }, /* 34 L2 */
|
||||
{ 32, 0u, "操作记录" }, /* 35 L2 */
|
||||
{ 32, 0u, "保护告警" }, /* 36 L2 */
|
||||
{ 32, 0u, "保护启动" }, /* 37 L2 */
|
||||
{ 32, 0u, "遥控记录" }, /* 38 L2 */
|
||||
{ 32, 0u, "自检记录" }, /* 39 L2 */
|
||||
{ 32, 0u, "运行记录" }, /* 40 L2 */
|
||||
{ 32, 0u, "运行报告" }, /* 41 L2 */
|
||||
{ MENU_ROOT, 0u, "主界面" }, /* 0 主界面 */
|
||||
{ 0, 0u, "装置信息" }, /* 1 一级菜单 */
|
||||
{ 0, 0u, "实时数据" }, /* 2 一级菜单 */
|
||||
{ 2, 0u, "交流量" }, /* 3 二级菜单 */
|
||||
{ 2, 0u, "直流量" }, /* 4 二级菜单 */
|
||||
{ 2, 0u, "遥信量" }, /* 5 二级菜单 */
|
||||
{ 0, 0u, "参数定值" }, /* 6 一级菜单 */
|
||||
{ 6, 0u, "整定" }, /* 7 二级菜单 */
|
||||
{ 7, 1u, "参数" }, /* 8 三级菜单 */
|
||||
{ 7, 1u, "定值" }, /* 9 三级菜单 */
|
||||
{ 7, 1u, "控制字" }, /* 10 三级菜单 */
|
||||
{ 7, 1u, "软压板" }, /* 11 三级菜单 */
|
||||
{ 6, 0u, "查看" }, /* 12 二级菜单 */
|
||||
{ 12, 0u, "参数" }, /* 13 三级菜单 */
|
||||
{ 12, 0u, "定值" }, /* 14 三级菜单 */
|
||||
{ 12, 0u, "控制字" }, /* 15 三级菜单 */
|
||||
{ 12, 0u, "软压板" }, /* 16 三级菜单 */
|
||||
{ 0, 0u, "三遥设置" }, /* 17 一级菜单 */
|
||||
{ 17, 1u, "遥测死区" }, /* 18 二级菜单 */
|
||||
{ 17, 1u, "遥测系数" }, /* 19 二级菜单 */
|
||||
{ 17, 1u, "遥信类型" }, /* 20 二级菜单 */
|
||||
{ 17, 1u, "遥信防抖" }, /* 21 二级菜单 */
|
||||
{ 17, 1u, "双点遥信" }, /* 22 二级菜单 */
|
||||
{ 0, 0u, "装置维护" }, /* 23 一级菜单 */
|
||||
{ 23, 1u, "时钟设置" }, /* 24 二级菜单 */
|
||||
{ 23, 1u, "强制复归" }, /* 25 二级菜单 */
|
||||
{ 23, 1u, "手动录波" }, /* 26 二级菜单 */
|
||||
{ 23, 1u, "清除记录" }, /* 27 二级菜单 */
|
||||
{ 0, 0u, "通讯参数" }, /* 28 一级菜单 */
|
||||
{ 28, 1u, "通讯设置" }, /* 29 二级菜单 */
|
||||
{ 28, 1u, "网口设置" }, /* 30 二级菜单 */
|
||||
{ 28, 1u, "SNTP设置" }, /* 31 二级菜单 */
|
||||
{ 0, 0u, "记录查询" }, /* 32 一级菜单 */
|
||||
{ 32, 0u, "SOE记录" }, /* 33 二级菜单 */
|
||||
{ 32, 0u, "事故记录" }, /* 34 二级菜单 */
|
||||
{ 32, 0u, "操作记录" }, /* 35 二级菜单 */
|
||||
{ 32, 0u, "保护告警" }, /* 36 二级菜单 */
|
||||
{ 32, 0u, "保护启动" }, /* 37 二级菜单 */
|
||||
{ 32, 0u, "遥控记录" }, /* 38 二级菜单 */
|
||||
{ 32, 0u, "自检记录" }, /* 39 二级菜单 */
|
||||
{ 32, 0u, "运行记录" }, /* 40 二级菜单 */
|
||||
{ 32, 0u, "运行报告" }, /* 41 二级菜单 */
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
> & '.venv\Scripts\python.exe' tools/font_gen/make_font.py
|
||||
> ```
|
||||
>
|
||||
> PATH 默认 `python` 是 msys64 的(无 fonttools),直接跑会失败。`.venv` 缺失/换机时重建:`& <本机任一 python ≥3.10> -m venv .venv; & '.venv\Scripts\python.exe' -m pip install -r requirements.txt`(`requirements.txt` 已含 `pre-commit`,重建后 L0 门禁直接可跑)。
|
||||
> PATH 默认 `python` 是 msys64 的(无 fonttools),直接跑会失败。`.venv` 缺失/换机时重建:`& <本机任一 python ≥3.10> -m venv .venv; & '.venv\Scripts\python.exe' -m pip install -r requirements.txt`(`requirements.txt` 已含 `pre-commit`,重建后 主界面门禁直接可跑)。
|
||||
> `extract_cn.py` 纯标准库,任意 python3 均可。
|
||||
|
||||
---
|
||||
|
||||
@@ -57,15 +57,15 @@
|
||||
|
||||
| # | 条目 | 现有节点 | 建议映射 |
|
||||
|---|---|---|---|
|
||||
| 1 | 装置信息 | 装置信息(L1) | 直接沿用(无变化) |
|
||||
| 2 | 实时数据 | 实时数据(L1)→ 交流量/直流量/开入量 | 直接沿用(无变化) |
|
||||
| 3 | 参数定值 | 定值参数(L1)→ 定值/查看 | **重命名** 定值参数 → 参数定值?(待确认) |
|
||||
| 4 | 三遥设置 | 遥测量(L1)→ 测量值/遥调系数/… | 对应"遥测量"?或新增"三遥"(遥测/遥信/遥控)节点?(Q2) |
|
||||
| 5 | 装置维护 | 装置维护(L1)→ 时间设置/强制复归/手动录波/自动录波 | 直接沿用(无变化) |
|
||||
| 6 | 通讯参数 | 通讯设置(L1)→ 通讯参数/网络配置/SNTP设置 | **重命名** 通讯设置 → 通讯参数?或提升 L2"通讯参数"?(待确认) |
|
||||
| 7 | 记录查询 | 记录查询(L1)→ SOE/事故/操作/告警/… | 直接沿用(无变化) |
|
||||
| 1 | 装置信息 | 装置信息(一级菜单) | 直接沿用(无变化) |
|
||||
| 2 | 实时数据 | 实时数据(一级菜单)→ 交流量/直流量/开入量 | 直接沿用(无变化) |
|
||||
| 3 | 参数定值 | 定值参数(一级菜单)→ 定值/查看 | **重命名** 定值参数 → 参数定值?(待确认) |
|
||||
| 4 | 三遥设置 | 遥测量(一级菜单)→ 测量值/遥调系数/… | 对应"遥测量"?或新增"三遥"(遥测/遥信/遥控)节点?(Q2) |
|
||||
| 5 | 装置维护 | 装置维护(一级菜单)→ 时间设置/强制复归/手动录波/自动录波 | 直接沿用(无变化) |
|
||||
| 6 | 通讯参数 | 通讯设置(一级菜单)→ 通讯参数/网络配置/SNTP设置 | **重命名** 通讯设置 → 通讯参数?或提升 二级菜单"通讯参数"?(待确认) |
|
||||
| 7 | 记录查询 | 记录查询(一级菜单)→ SOE/事故/操作/告警/… | 直接沿用(无变化) |
|
||||
|
||||
注:旧菜单中的"厂家设置"(L0,含 元件设置/恢复默认/版本显示/版本信息/装置遥调/装置记录)未出现在新 7 项列表中,入口待 Q3 确认。
|
||||
注:旧菜单中的"厂家设置"(主界面,含 元件设置/恢复默认/版本显示/版本信息/装置遥调/装置记录)未出现在新 7 项列表中,入口待 Q3 确认。
|
||||
|
||||
## 六、LVGL 翻译要点(P1 用)
|
||||
|
||||
|
||||
+10
-10
@@ -33,16 +33,16 @@ flowchart TD
|
||||
|
||||
subgraph FW["框架 ui_content_page.c/h —— 只有机制,零页面数据"]
|
||||
S[("描述符表 s_defs[]<br/>页 ID → const content_page_def_t *<br/>(几何 + 数据源 + 4 钩子)")]
|
||||
L1["屏/容器生命周期<br/>按需建毁 · 焦点 · 切屏"]
|
||||
L2["按键分发<br/>内置 ↑↓/ESC + key_cb 钩子"]
|
||||
L3["通用绘制(LV_EVENT_DRAW_MAIN)<br/>浅 V → 标题/副标题 → 行 → 选中带 → 页脚 → draw_cb"]
|
||||
一级菜单["屏/容器生命周期<br/>按需建毁 · 焦点 · 切屏"]
|
||||
二级菜单["按键分发<br/>内置 ↑↓/ESC + key_cb 钩子"]
|
||||
三级菜单["通用绘制(LV_EVENT_DRAW_MAIN)<br/>浅 V → 标题/副标题 → 行 → 选中带 → 页脚 → draw_cb"]
|
||||
end
|
||||
|
||||
M -- "ENTER:ui_content_page_open(id, perm)" --> S
|
||||
S -- "描述符驱动" --> L1
|
||||
S -- "描述符驱动" --> L2
|
||||
S -- "描述符驱动" --> L3
|
||||
L2 -- "ESC/←:close()" --> L1
|
||||
S -- "描述符驱动" --> 一级菜单
|
||||
S -- "描述符驱动" --> 二级菜单
|
||||
S -- "描述符驱动" --> 三级菜单
|
||||
二级菜单 -- "ESC/←:close()" --> 一级菜单
|
||||
|
||||
subgraph PG["页面插件 —— 数据(Flash)+ 几何 + 钩子实现,零 LVGL 对象"]
|
||||
P1["ui_page_device_info<br/>装置信息(静态信息页)"]
|
||||
@@ -58,9 +58,9 @@ flowchart TD
|
||||
P4 -- "const 描述符(Flash)" --> S
|
||||
PN -- "const 描述符(Flash)" --> S
|
||||
|
||||
L3 -- "ui_deco_draw" --> D["ui_deco(共享)<br/>顶部“浅 V”装饰"]
|
||||
L3 -- "动态行:refresh / count_cb" --> PG
|
||||
L2 -- "页面自有键:key_cb" --> PG
|
||||
三级菜单 -- "ui_deco_draw" --> D["ui_deco(共享)<br/>顶部“浅 V”装饰"]
|
||||
三级菜单 -- "动态行:refresh / count_cb" --> PG
|
||||
二级菜单 -- "页面自有键:key_cb" --> PG
|
||||
```
|
||||
|
||||
读图要点:
|
||||
|
||||
+94
-94
@@ -3,7 +3,7 @@
|
||||
> **用途**:定义 DTU 主菜单的**内容(42 节点层级树)、视觉规范、三层代码架构**(数据层 / 显示层 / 逻辑层),以及叶子节点进入后的**内容页模块**(§九)。
|
||||
> **范围**:菜单层级(节点/父子/层级/进出导航)+ 三个已实现的内容页(装置信息/交流量/直流量,§九);其余叶子的内容页后续按同模式扩展。
|
||||
> **来源**:用户提供的主菜单截图 7 屏(根页 + 实时数据/参数定值/三遥设置/装置维护/通讯参数/记录查询各一级子页 + 参数定值·整定二级)。
|
||||
> **导航模型**:树形**逐级进入**——`ENTER`/`→` 进入子页,`ESC`/`←` 返回上一级;最多 **4 级(L0~L3)**。
|
||||
> **导航模型**:树形**逐级进入**——`ENTER`/`→` 进入子页,`ESC`/`←` 返回上一级;最多 **4 级(主界面 → 三级菜单)**。
|
||||
|
||||
> **阅读指南**:
|
||||
>
|
||||
@@ -135,10 +135,10 @@ sequenceDiagram
|
||||
|
||||
| 层级 | 含义 | 例子 |
|
||||
|---|---|---|
|
||||
| **L0 根** | 主界面,7 个一级条目 | 主界面 |
|
||||
| **L1 一级** | 根页的 7 个条目 | 装置信息、实时数据、参数定值、三遥设置、装置维护、通讯参数、记录查询 |
|
||||
| **L2 二级** | 一级子菜单的子项 | 交流量、整定、遥测死区、时钟设置、通讯设置、SOE记录 … |
|
||||
| **L3 三级** | 仅"参数定值 → 整定/查看"下的子项 | 参数、定值、控制字、软压板 |
|
||||
| **主界面(根)** | 主界面,7 个一级条目 | 主界面 |
|
||||
| **一级菜单** | 根页的 7 个条目 | 装置信息、实时数据、参数定值、三遥设置、装置维护、通讯参数、记录查询 |
|
||||
| **二级菜单** | 一级子菜单的子项 | 交流量、整定、遥测死区、时钟设置、通讯设置、SOE记录 … |
|
||||
| **三级菜单** | 仅"参数定值 → 整定/查看"下的子项 | 参数、定值、控制字、软压板 |
|
||||
|
||||
节点分两类(决定导航行为):
|
||||
|
||||
@@ -152,7 +152,7 @@ sequenceDiagram
|
||||
### 2.2 完整层级树
|
||||
|
||||
```text
|
||||
主界面 (L0)
|
||||
主界面
|
||||
├─ 装置信息 [叶子]
|
||||
├─ 实时数据 ▶ [菜单]
|
||||
│ ├─ 交流量 [叶子]
|
||||
@@ -204,48 +204,48 @@ sequenceDiagram
|
||||
|
||||
| # | 名称 | 层级 | 类型 | 父节点 | 子项数 |
|
||||
|---|---|---|---|---|---|
|
||||
| 0 | 主界面 | L0 | 菜单(根) | — | 7 |
|
||||
| 1 | 装置信息 | L1 | 叶子 | 0 | 0 |
|
||||
| 2 | 实时数据 | L1 | 菜单 | 0 | 3 |
|
||||
| 3 | 交流量 | L2 | 叶子 | 2 | 0 |
|
||||
| 4 | 直流量 | L2 | 叶子 | 2 | 0 |
|
||||
| 5 | 遥信量 | L2 | 叶子 | 2 | 0 |
|
||||
| 6 | 参数定值 | L1 | 菜单 | 0 | 2 |
|
||||
| 7 | 整定 | L2 | 菜单 | 6 | 4 |
|
||||
| 8 | 参数 | L3 | 叶子 | 7 | 0 |
|
||||
| 9 | 定值 | L3 | 叶子 | 7 | 0 |
|
||||
| 10 | 控制字 | L3 | 叶子 | 7 | 0 |
|
||||
| 11 | 软压板 | L3 | 叶子 | 7 | 0 |
|
||||
| 12 | 查看 | L2 | 菜单 | 6 | 4 |
|
||||
| 13 | 参数 | L3 | 叶子 | 12 | 0 |
|
||||
| 14 | 定值 | L3 | 叶子 | 12 | 0 |
|
||||
| 15 | 控制字 | L3 | 叶子 | 12 | 0 |
|
||||
| 16 | 软压板 | L3 | 叶子 | 12 | 0 |
|
||||
| 17 | 三遥设置 | L1 | 菜单 | 0 | 5 |
|
||||
| 18 | 遥测死区 | L2 | 叶子 | 17 | 0 |
|
||||
| 19 | 遥测系数 | L2 | 叶子 | 17 | 0 |
|
||||
| 20 | 遥信类型 | L2 | 叶子 | 17 | 0 |
|
||||
| 21 | 遥信防抖 | L2 | 叶子 | 17 | 0 |
|
||||
| 22 | 双点遥信 | L2 | 叶子 | 17 | 0 |
|
||||
| 23 | 装置维护 | L1 | 菜单 | 0 | 4 |
|
||||
| 24 | 时钟设置 | L2 | 叶子 | 23 | 0 |
|
||||
| 25 | 强制复归 | L2 | 叶子 | 23 | 0 |
|
||||
| 26 | 手动录波 | L2 | 叶子 | 23 | 0 |
|
||||
| 27 | 清除记录 | L2 | 叶子 | 23 | 0 |
|
||||
| 28 | 通讯参数 | L1 | 菜单 | 0 | 3 |
|
||||
| 29 | 通讯设置 | L2 | 叶子 | 28 | 0 |
|
||||
| 30 | 网口设置 | L2 | 叶子 | 28 | 0 |
|
||||
| 31 | SNTP设置 | L2 | 叶子 | 28 | 0 |
|
||||
| 32 | 记录查询 | L1 | 菜单 | 0 | 9 |
|
||||
| 33 | SOE记录 | L2 | 叶子 | 32 | 0 |
|
||||
| 34 | 事故记录 | L2 | 叶子 | 32 | 0 |
|
||||
| 35 | 操作记录 | L2 | 叶子 | 32 | 0 |
|
||||
| 36 | 保护告警 | L2 | 叶子 | 32 | 0 |
|
||||
| 37 | 保护启动 | L2 | 叶子 | 32 | 0 |
|
||||
| 38 | 遥控记录 | L2 | 叶子 | 32 | 0 |
|
||||
| 39 | 自检记录 | L2 | 叶子 | 32 | 0 |
|
||||
| 40 | 运行记录 | L2 | 叶子 | 32 | 0 |
|
||||
| 41 | 运行报告 | L2 | 叶子 | 32 | 0 |
|
||||
| 0 | 主界面 | 主界面 | 菜单(根) | — | 7 |
|
||||
| 1 | 装置信息 | 一级菜单 | 叶子 | 0 | 0 |
|
||||
| 2 | 实时数据 | 一级菜单 | 菜单 | 0 | 3 |
|
||||
| 3 | 交流量 | 二级菜单 | 叶子 | 2 | 0 |
|
||||
| 4 | 直流量 | 二级菜单 | 叶子 | 2 | 0 |
|
||||
| 5 | 遥信量 | 二级菜单 | 叶子 | 2 | 0 |
|
||||
| 6 | 参数定值 | 一级菜单 | 菜单 | 0 | 2 |
|
||||
| 7 | 整定 | 二级菜单 | 菜单 | 6 | 4 |
|
||||
| 8 | 参数 | 三级菜单 | 叶子 | 7 | 0 |
|
||||
| 9 | 定值 | 三级菜单 | 叶子 | 7 | 0 |
|
||||
| 10 | 控制字 | 三级菜单 | 叶子 | 7 | 0 |
|
||||
| 11 | 软压板 | 三级菜单 | 叶子 | 7 | 0 |
|
||||
| 12 | 查看 | 二级菜单 | 菜单 | 6 | 4 |
|
||||
| 13 | 参数 | 三级菜单 | 叶子 | 12 | 0 |
|
||||
| 14 | 定值 | 三级菜单 | 叶子 | 12 | 0 |
|
||||
| 15 | 控制字 | 三级菜单 | 叶子 | 12 | 0 |
|
||||
| 16 | 软压板 | 三级菜单 | 叶子 | 12 | 0 |
|
||||
| 17 | 三遥设置 | 一级菜单 | 菜单 | 0 | 5 |
|
||||
| 18 | 遥测死区 | 二级菜单 | 叶子 | 17 | 0 |
|
||||
| 19 | 遥测系数 | 二级菜单 | 叶子 | 17 | 0 |
|
||||
| 20 | 遥信类型 | 二级菜单 | 叶子 | 17 | 0 |
|
||||
| 21 | 遥信防抖 | 二级菜单 | 叶子 | 17 | 0 |
|
||||
| 22 | 双点遥信 | 二级菜单 | 叶子 | 17 | 0 |
|
||||
| 23 | 装置维护 | 一级菜单 | 菜单 | 0 | 4 |
|
||||
| 24 | 时钟设置 | 二级菜单 | 叶子 | 23 | 0 |
|
||||
| 25 | 强制复归 | 二级菜单 | 叶子 | 23 | 0 |
|
||||
| 26 | 手动录波 | 二级菜单 | 叶子 | 23 | 0 |
|
||||
| 27 | 清除记录 | 二级菜单 | 叶子 | 23 | 0 |
|
||||
| 28 | 通讯参数 | 一级菜单 | 菜单 | 0 | 3 |
|
||||
| 29 | 通讯设置 | 二级菜单 | 叶子 | 28 | 0 |
|
||||
| 30 | 网口设置 | 二级菜单 | 叶子 | 28 | 0 |
|
||||
| 31 | SNTP设置 | 二级菜单 | 叶子 | 28 | 0 |
|
||||
| 32 | 记录查询 | 一级菜单 | 菜单 | 0 | 9 |
|
||||
| 33 | SOE记录 | 二级菜单 | 叶子 | 32 | 0 |
|
||||
| 34 | 事故记录 | 二级菜单 | 叶子 | 32 | 0 |
|
||||
| 35 | 操作记录 | 二级菜单 | 叶子 | 32 | 0 |
|
||||
| 36 | 保护告警 | 二级菜单 | 叶子 | 32 | 0 |
|
||||
| 37 | 保护启动 | 二级菜单 | 叶子 | 32 | 0 |
|
||||
| 38 | 遥控记录 | 二级菜单 | 叶子 | 32 | 0 |
|
||||
| 39 | 自检记录 | 二级菜单 | 叶子 | 32 | 0 |
|
||||
| 40 | 运行记录 | 二级菜单 | 叶子 | 32 | 0 |
|
||||
| 41 | 运行报告 | 二级菜单 | 叶子 | 32 | 0 |
|
||||
|
||||
---
|
||||
|
||||
@@ -295,48 +295,48 @@ typedef struct {
|
||||
```c
|
||||
const ui_menu_node_t g_menu_tab[UI_MENU_TAB_COUNT] = {
|
||||
/* parent name 下标 */
|
||||
{ MENU_ROOT, "主界面" }, /* 0 L0 菜单(根) */
|
||||
{ 0, "装置信息" }, /* 1 L1 叶子 */
|
||||
{ 0, "实时数据" }, /* 2 L1 菜单 */
|
||||
{ 2, "交流量" }, /* 3 L2 叶子 */
|
||||
{ 2, "直流量" }, /* 4 L2 叶子 */
|
||||
{ 2, "遥信量" }, /* 5 L2 叶子 */
|
||||
{ 0, "参数定值" }, /* 6 L1 菜单 */
|
||||
{ 6, "整定" }, /* 7 L2 菜单 */
|
||||
{ 7, "参数" }, /* 8 L3 叶子 */
|
||||
{ 7, "定值" }, /* 9 L3 叶子 */
|
||||
{ 7, "控制字" }, /* 10 L3 叶子 */
|
||||
{ 7, "软压板" }, /* 11 L3 叶子 */
|
||||
{ 6, "查看" }, /* 12 L2 菜单 */
|
||||
{ 12, "参数" }, /* 13 L3 叶子 */
|
||||
{ 12, "定值" }, /* 14 L3 叶子 */
|
||||
{ 12, "控制字" }, /* 15 L3 叶子 */
|
||||
{ 12, "软压板" }, /* 16 L3 叶子 */
|
||||
{ 0, "三遥设置" }, /* 17 L1 菜单 */
|
||||
{ 17, "遥测死区" }, /* 18 L2 叶子 */
|
||||
{ 17, "遥测系数" }, /* 19 L2 叶子 */
|
||||
{ 17, "遥信类型" }, /* 20 L2 叶子 */
|
||||
{ 17, "遥信防抖" }, /* 21 L2 叶子 */
|
||||
{ 17, "双点遥信" }, /* 22 L2 叶子 */
|
||||
{ 0, "装置维护" }, /* 23 L1 菜单 */
|
||||
{ 23, "时钟设置" }, /* 24 L2 叶子 */
|
||||
{ 23, "强制复归" }, /* 25 L2 叶子 */
|
||||
{ 23, "手动录波" }, /* 26 L2 叶子 */
|
||||
{ 23, "清除记录" }, /* 27 L2 叶子 */
|
||||
{ 0, "通讯参数" }, /* 28 L1 菜单 */
|
||||
{ 28, "通讯设置" }, /* 29 L2 叶子 */
|
||||
{ 28, "网口设置" }, /* 30 L2 叶子 */
|
||||
{ 28, "SNTP设置" }, /* 31 L2 叶子 */
|
||||
{ 0, "记录查询" }, /* 32 L1 菜单 */
|
||||
{ 32, "SOE记录" }, /* 33 L2 叶子 */
|
||||
{ 32, "事故记录" }, /* 34 L2 叶子 */
|
||||
{ 32, "操作记录" }, /* 35 L2 叶子 */
|
||||
{ 32, "保护告警" }, /* 36 L2 叶子 */
|
||||
{ 32, "保护启动" }, /* 37 L2 叶子 */
|
||||
{ 32, "遥控记录" }, /* 38 L2 叶子 */
|
||||
{ 32, "自检记录" }, /* 39 L2 叶子 */
|
||||
{ 32, "运行记录" }, /* 40 L2 叶子 */
|
||||
{ 32, "运行报告" }, /* 41 L2 叶子 */
|
||||
{ MENU_ROOT, "主界面" }, /* 0 主界面菜单(根) */
|
||||
{ 0, "装置信息" }, /* 1 一级菜单叶子 */
|
||||
{ 0, "实时数据" }, /* 2 一级菜单菜单 */
|
||||
{ 2, "交流量" }, /* 3 二级菜单叶子 */
|
||||
{ 2, "直流量" }, /* 4 二级菜单叶子 */
|
||||
{ 2, "遥信量" }, /* 5 二级菜单叶子 */
|
||||
{ 0, "参数定值" }, /* 6 一级菜单菜单 */
|
||||
{ 6, "整定" }, /* 7 二级菜单菜单 */
|
||||
{ 7, "参数" }, /* 8 三级菜单叶子 */
|
||||
{ 7, "定值" }, /* 9 三级菜单叶子 */
|
||||
{ 7, "控制字" }, /* 10 三级菜单叶子 */
|
||||
{ 7, "软压板" }, /* 11 三级菜单叶子 */
|
||||
{ 6, "查看" }, /* 12 二级菜单菜单 */
|
||||
{ 12, "参数" }, /* 13 三级菜单叶子 */
|
||||
{ 12, "定值" }, /* 14 三级菜单叶子 */
|
||||
{ 12, "控制字" }, /* 15 三级菜单叶子 */
|
||||
{ 12, "软压板" }, /* 16 三级菜单叶子 */
|
||||
{ 0, "三遥设置" }, /* 17 一级菜单菜单 */
|
||||
{ 17, "遥测死区" }, /* 18 二级菜单叶子 */
|
||||
{ 17, "遥测系数" }, /* 19 二级菜单叶子 */
|
||||
{ 17, "遥信类型" }, /* 20 二级菜单叶子 */
|
||||
{ 17, "遥信防抖" }, /* 21 二级菜单叶子 */
|
||||
{ 17, "双点遥信" }, /* 22 二级菜单叶子 */
|
||||
{ 0, "装置维护" }, /* 23 一级菜单菜单 */
|
||||
{ 23, "时钟设置" }, /* 24 二级菜单叶子 */
|
||||
{ 23, "强制复归" }, /* 25 二级菜单叶子 */
|
||||
{ 23, "手动录波" }, /* 26 二级菜单叶子 */
|
||||
{ 23, "清除记录" }, /* 27 二级菜单叶子 */
|
||||
{ 0, "通讯参数" }, /* 28 一级菜单菜单 */
|
||||
{ 28, "通讯设置" }, /* 29 二级菜单叶子 */
|
||||
{ 28, "网口设置" }, /* 30 二级菜单叶子 */
|
||||
{ 28, "SNTP设置" }, /* 31 二级菜单叶子 */
|
||||
{ 0, "记录查询" }, /* 32 一级菜单菜单 */
|
||||
{ 32, "SOE记录" }, /* 33 二级菜单叶子 */
|
||||
{ 32, "事故记录" }, /* 34 二级菜单叶子 */
|
||||
{ 32, "操作记录" }, /* 35 二级菜单叶子 */
|
||||
{ 32, "保护告警" }, /* 36 二级菜单叶子 */
|
||||
{ 32, "保护启动" }, /* 37 二级菜单叶子 */
|
||||
{ 32, "遥控记录" }, /* 38 二级菜单叶子 */
|
||||
{ 32, "自检记录" }, /* 39 二级菜单叶子 */
|
||||
{ 32, "运行记录" }, /* 40 二级菜单叶子 */
|
||||
{ 32, "运行报告" }, /* 41 二级菜单叶子 */
|
||||
};
|
||||
```
|
||||
|
||||
@@ -399,7 +399,7 @@ for (uint8_t i = 0; i < cnt; i++) {
|
||||
python tools/menu_gen/gen_menu.py
|
||||
```
|
||||
|
||||
> 产物 `ui_menu_tab.c/.h` 含 42 节点(9 菜单 + 33 叶子,最深 L3);`ui_menu.c` 不持有本地表,导航/显示一律走 `ui_menu_tab_*` 查询 API(§3.4)。
|
||||
> 产物 `ui_menu_tab.c/.h` 含 42 节点(9 菜单 + 33 叶子,最深 三级菜单);`ui_menu.c` 不持有本地表,导航/显示一律走 `ui_menu_tab_*` 查询 API(§3.4)。
|
||||
|
||||
> **编码陷阱(已踩)**:产物含中文**字符串字面量**,必须 **UTF-8 带 BOM**(同 `ui_menu.c`)。
|
||||
> 无 BOM 时 cl.exe(代码页 936/GBK)会按 GBK 误读 UTF-8 字节 → 字符串解析错乱(C2001/C4819)。`gen_menu.py` 已用 `utf-8-sig` 输出。
|
||||
@@ -686,7 +686,7 @@ s_path[0]=0 ─▶ s_path[1]=6 ─▶ s_path[2]=7 ─▶ s_path[3]=8
|
||||
**进入/返回示例**(路径,`→`/`←` = 进/退动作方向):
|
||||
```
|
||||
主界面 → 参数定值 → 整定 → 参数
|
||||
L0 L1 L2 L3
|
||||
主界面一级菜单 二级菜单三级菜单
|
||||
返回:主界面 ← 参数定值 ← 整定 ← 参数
|
||||
```
|
||||
|
||||
@@ -880,14 +880,14 @@ bool ui_content_page_is_open(void); /* 查询是否有内容页
|
||||
| 2026-09-03 | 按范围调整:移除"内容页类型"相关内容,聚焦菜单层级(节点/父子/层级/导航);新增 `子项数` 列;标注"查看"子项为推测待确认 |
|
||||
| 2026-09-03 | **查看(#12)子项经用户确认**与"整定"同构(参数/定值/控制字/软压板),由推测转为正式定义,移除全部 ⚠ 标记与待确认节 |
|
||||
| 2026-09-03 | 新增 §六"菜单树数据结构":选型扁平"父子索引表"(邻接表/关系表模型,对比指针树/首子-兄弟/堆式),给出 `ui_menu_node_t` + 完整 42 节点表 + 导航 API(`menu_get_children`/`menu_has_children`/`menu_get_name`)+ 启动自检 + 声明式生成器 + 与现有 `g_menu_tab` 迁移映射 |
|
||||
| 2026-09-03 | **声明式生成器落地**(§6.6 由"可选"转"已实现"):新增 `ui_menu_tree.txt`(缩进即层级源)+ `tools/menu_gen/gen_menu.py`(同 `make_font.py` 模式),生成 `Drivers/BSP/UI/ui_menu_tab.c/.h`(42 节点:9 菜单 + 33 叶子,最深 L3);已跑通并校验 parent 下标/连通性/子项数全部正确 |
|
||||
| 2026-09-03 | **声明式生成器落地**(§6.6 由"可选"转"已实现"):新增 `ui_menu_tree.txt`(缩进即层级源)+ `tools/menu_gen/gen_menu.py`(同 `make_font.py` 模式),生成 `Drivers/BSP/UI/ui_menu_tab.c/.h`(42 节点:9 菜单 + 33 叶子,最深 三级菜单);已跑通并校验 parent 下标/连通性/子项数全部正确 |
|
||||
| 2026-09-04 | §四 新增"**导航走查**":用真实 `g_menu_tab` 下标逐步演示"移/进/退"如何由 `parent==当前节点` 一次过滤驱动(当前页=过滤、进=压页/终点、退=弹页、导航态=当前节点链),并修正根页模型为"主界面 node 0 的子项"(§6.2/6.7 同步,去掉"虚拟根页"表述) |
|
||||
| 2026-09-04 | 新增 §七"导航运行时数据结构(完整清单)":静态层(`g_menu_tab` 只读)+ 运行时层(导航历史 `s_path`+`s_sel`+`s_depth`=13 B、持久容器 `s_cont[4]`、单套活跃行 `s_row*[]`、页头/装饰、样式);"存 vs 算"区分、操作×字段读写表、内存预算、与现有 `s_pages[4]` 收敛对照 |
|
||||
| 2026-09-04 | 改名 `menu_is_menu` → `menu_has_children`(原名"menu 是不是 menu"含糊;新名=该节点有无子项);§四 路径/代码映射由旧 `s_pages[]` 统一为 §七 的 `s_path[]`/`s_depth`/`s_sel[]`/`s_row*[]` 模型,消除 §四/§七 不一致 |
|
||||
| 2026-09-04 | 改名 `menu_children` → `menu_get_children`、`menu_name` → `menu_get_name`(裸名词改"动词+对象",API 统一 `has_`/`get_` 风格);§6.4 建页片段改用 `s_path`/`s_depth`/`s_cont` 现算模型(条目不落地) |
|
||||
| 2026-09-04 | §6.4 补"签名约定"说明:`node`/`out` 取 `uint16_t` 因与 `parent`(须装 `0xFFFF` 根哨兵)同域、**非容量所需**(42 下标 8 位够);`max`=出参缓冲容量(防越界 + 对齐单页行数,今日 9≤16 不触发截断) |
|
||||
| 2026-09-04 | **索引位宽 16→8 位**:`MENU_ROOT` 由 `0xFFFF` 降为 `0xFF`,`parent`/`node`/`out`/`s_path[]` 均改 `uint8_t`(菜单上限 255 项,远够);路径历史 13→9 B、省 ~20 B RAM,Flash 不变(结构体因指针仍 8 B/项);双护栏=生成器 `节点数>255 报错` + 头文件 C99 断言 `menu_tab_count_check`。生成器已改并重生成 `ui_menu_tab.c/.h`,MSVC /W4 编译 + 导航测试(根 7 / 整定 4 / 查看 4 / 记录查询 9)通过;同步 §四/§6.2/§6.4/§6.5/§七。取代上一条"签名约定(uint16_t)"决定 |
|
||||
| 2026-09-04 | 修正 §四"进入/返回示例":返回行节点顺序原与进入行相反(参数在左)致 `←` 被读成"前进"方向;改为与进入行**同序**(主界面 L0 在左…参数 L3 在右)+ `←`,并补"怎么读"注(`→`/`←` = 进/退动作方向;返回 = 从最右 参数(L3) 沿 `←` 一级级退回最左 主界面(L0)) |
|
||||
| 2026-09-04 | 修正 §四"进入/返回示例":返回行节点顺序原与进入行相反(参数在左)致 `←` 被读成"前进"方向;改为与进入行**同序**(主界面主界面 在左…参数 三级菜单在右)+ `←`,并补"怎么读"注(`→`/`←` = 进/退动作方向;返回 = 从最右 参数(三级菜单) 沿 `←` 一级级退回最左 主界面) |
|
||||
| 2026-09-04 | **子页面显示模型定稿(横向级联子框)**:§四 新增 ⑧"显示模型"——横向树,每级一框在上一级**右侧**、顶边对齐上级"选中行"行顶;水平**右锚定**(最深框钉右缘、父框超宽滚出左、行按屏上/外建毁)+ 框宽文字自适应 + **无动画**;垂直每框独立(顶边=上级选中行行顶、框高按内容、**仅底边>160 才上移**贴屏底、比整屏高则 `↑`/`↓` 滚);焦点=最右框(`↑`/`↓` 移选/滚、`→`/`ENTER` 进、`←`/`ESC` 关最右框)。§七 同步:行对象按层 `s_row[d][i]` 仅屏上框建、去掉逐框页头(`s_header`/`s_back_btn`/`s_title`)、新增每框滚动 `s_scroll[]`(8 B)、"存 vs 算"增 滚动=存/位置=算、持久态 9→17 B、内存预算(静态 ~0.75→~1.3 KB、LVGL 池=屏上 2~3 框)、对照表更新 |
|
||||
| 2026-09-04 | **§四⑧ 按参考图 02~07 像素实测校准**(设备 px,误差 ≤3px):层级树/命名/箭头/选中态全部与图一致 ✓;显示模型两处修正——水平由"右锚定(钉屏幕右缘)"改为"**子框左缘=父框右缘**(共享边框列、零间隙)+ 宽自适应"(实测各子框均贴父框右缘 x≈67/106,最深框止于 x≈113~127 而非屏右缘);垂直溢出由"上移使底边贴屏底"改为"**上移使子框底边对齐父选中行行底**"(实测三遥 top=26/装置维护 top=54/通讯参数 top=82/记录查询 top=12 均吻合,且可叠到屏顶状态行区、顶部不钳制)。本菜单最深路径 ≈155<160 不会溢出;>160 行为与"根页框宽 99 vs 68"列为待确认。§7.2/§7.3/§7.4 "右锚定"表述同步 |
|
||||
| 2026-09-04 | **实现落地,本文档与代码同步**:三层拆分实现(`ui_menu_tab` 生成物 + 新增 `ui_menu_view` 显示层、`ui_menu` 瘦身为纯状态机,§8.1);§四⑦/§6.4/§6.5/§6.6/§6.7 函数与 API 名同步为实际 `ui_menu_tab_*`/`ui_menu_view_*`/`menu_open\|menu_back\|menu_key_handle`;§五"待实现"→"已实现";§七 修正为实际字段(容器从不切 HIDDEN、`s_style_frame`、新增框几何缓存 `s_frame[]`,§7.2 G);§四⑧ 实测值区分"参考图/实现"两套(实现:根框 66、子框 42/46/54/6,顶 28/58/88/13,偏差入 §8.8 注 5),>160 溢出"待确认"落定为实现行为"屏缘裁切";新增 **§八 实现架构与关键实施细节**(布局常量/几何公式/对象模型/键路径/初始化时序/分级验证/6 条陷阱与保真度说明);验证:模拟器 7 状态对照参考图 01~07 + `@build` 0 错 0 警 |
|
||||
|
||||
@@ -36,6 +36,10 @@ UVPROJX = os.path.join(ROOT, 'MDK-ARM', 'STM32F407-Demo.uvprojx')
|
||||
CMAKELISTS = os.path.join(ROOT, 'simulator', 'CMakeLists.txt')
|
||||
UI_GROUP = 'Drivers/BSP/UI' # uvprojx 里的组名
|
||||
ROOT_ID = 0xFF # 内部根标记(= MENU_ROOT=0xFF);与 8 位索引一致,映射到 C 的 MENU_ROOT 宏
|
||||
# 菜单层级语义名(索引 = 深度)。过去生成物注释里写 L0~L3,用户 2026-10-28 裁定改语义名——
|
||||
# 生成物里的层号人看不懂,且与"采集链分层"的 L1~L5 撞形。
|
||||
MENU_LEVEL_NAMES = ("主界面", "一级菜单", "二级菜单", "三级菜单",
|
||||
"四级菜单", "五级菜单", "六级菜单", "七级菜单")
|
||||
MAX_DEPTH = 8
|
||||
MAX_NODES = 255 # uint8_t 索引 + 哨兵 0xFF → 最多 255 个节点(下标 0..254)
|
||||
STEM_RE = re.compile(r'^[a-z][a-z0-9_]*$')
|
||||
@@ -254,7 +258,9 @@ def emit(nodes):
|
||||
for i, (parent, name, depth, pwd, _page) in enumerate(nodes):
|
||||
pstr = 'MENU_ROOT' if parent == ROOT_ID else '%d' % parent
|
||||
cstr = '1u' if pwd else '0u'
|
||||
c.append(' { %8s, %2s, "%s" }, /* %2d L%d */' % (pstr, cstr, name, i, depth))
|
||||
# 层级用语义名(2026-10-28 用户裁定:L0~L3 这套层号看不懂,改成语义层名)
|
||||
c.append(' { %8s, %2s, "%s" }, /* %2d %s */'
|
||||
% (pstr, cstr, name, i, MENU_LEVEL_NAMES[depth]))
|
||||
c.append('};')
|
||||
c.append('')
|
||||
c += [
|
||||
|
||||
Reference in New Issue
Block a user