Files
STM32F4-Base/Drivers/BSP/UI/ui_w_setlist.h
T
wandering1 ae09c5737a docs: 删任务规划两份已完成文档,数据可信内容迁入算法层/硬件平台/登记簿
任务规划目录从 5 个文件收敛到 3 个:只留导航(README)、待办(登记簿)、
暂缓专项(暂缓-RS485)。

删除的两个文件都不再有现行读者:
- UI补齐.md 执行清单 2026-10-28 清空、上板判据 2026-11-06 台架轮已复核;
  叶数口径迁 docs/UI设计/菜单页面设计.md §3.9,三条内容页硬规矩迁
  docs/UI设计/内容页架构.md §7.1,两条未闭环待办迁登记簿 §7/§8。
- 数据可信.md 不是完成记录,而是被约 130 处代码头注释引用的设计约束,
  因此按内容分三处落位后删除,不整篇丢弃。

数据可信内容的新归属(旧节号 → 新家):
- §2/§4 设计口径 → docs/算法/采集与算法层设计说明.md 新增 §13(13 小节),
  §7 前置决策表 → §13.12 已定案的前置决策。
- §3 台阶与波次退出判据 → docs/硬件平台/ADC通道映射说明.md 新增 §9。
- §5 任务卡 → docs/任务规划/登记簿.md §7(拆成变比确认 / 两点标定两行)。

引用改写 34 文件 77 处路径引用 + 14 文件 24 处昵称引用 + 双重节号 35 处,
覆盖代码头注释、测试、生成器与文档;归档区历史路径改纯文本提及。
四个 SVG 生成器文案同步并重跑,产物随脚本同批提交。

同批处理两件事:
- 9 个 UTF-16 LE 证据文件转 UTF-8。end-of-file-fixer 按字节判末尾换行,
  UTF-16 的换行是 0A 00、末字节 00,钩子会追加裸 0x0a 使文件变奇数长度,
  8 个已实际损坏。转码后逐文件比对 HEAD 原文验证正文零丢失。
- 修回 App/cfg/cfg_file.c 被剥掉的 UTF-8 BOM(补 3 字节,未整文件重写)。

验证:/keil-build 0 错误 0 警告(Code=255160);check_doc_links --all
--sections-strict 221 篇全通过、无法判定 0;pre-commit 全量全 Passed。
2026-11-09 16:13:57 +08:00

215 lines
11 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 模块名称:UI 定值表共享组件(ui_w_setlist)
* 模块功能:把"参数/定值/控制字/软压板"四类视图的列表渲染与整定输入抽象成
* 一份实现——行表 + 数据回调注入(取数/写工作副本/提交/状态回读/
* 越界行查询),同一份组件供多个页面实例复用:
* 查看视图(commit=NULL:无保存行、ENTER 无效)与整定视图
* (commit 非空:末行固定为"保存"行,ENTER 投递整表提交)只差绑定;
* 数值行走 ui_w_editor 逐位编辑(范围校验提交),二态文字行
* (控制字"告警/跳闸"、软压板"投入/退出")ENTER 直接切换;
* 保存失败后的越界行经 bad 回调反显高亮;
* 分页跟随内容页框架内置(8 行/页,UI_LIST_ROWS)
* 适用范围:Drivers/BSP/UI(标准列表页骨架几何:UI_LIST_TOP/ROW_PITCH/
* ROW_BAND_H/LIST_ROWS/RIGHT_X 令牌;页面描述符须 selectable=1、
* key_intercept=1、rows_per_page=UI_LIST_ROWS、text_dy=0)
* 说明:数据绑定全部经回调注入(批 2 ui_data/prot_set 交接时由页面薄跳板
* 提供实现),组件不 include 任何 App 头(分层门禁方向);
* 实例化使用——每个页面文件 static 一份实例,钩子包一层 &inst 转调
* (同 ui_w_records 模式)
* 作者:王建锋
* 创建日期:2026-10-25
* 修改记录:
* v1.0 2026-10-25 王建锋 创建(道B task-5;规格 = 页面扩充详细方案.md
* §3.2 四视图表/§3.2.6 查看与整定差别/§3.2.7 编辑
* 交互/§4.2 bind 要点;保存行 ENTER/WAIT/OK/ERR
* 沿用 ui_page_net_cfg 交接显示先例)
* v1.1 2026-10-26 DTU 项目组 道F task-2(整定 4 页):态枚举尾追加 LOCK
* (值列显 LOCK + ENTER 不消费 = 闭锁禁编辑);
* 查看视图不绑 commit/state,走不到新分支,
* 四张查看页像素零变化(黄金用例 vparam~vplate 为证)
*/
#ifndef UI_W_SETLIST_H
#define UI_W_SETLIST_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <stdint.h>
#include "ui_content_page.h" /* lvgl(lv_key_t/lv_layer_t)+ 框架类型 */
#include "ui_w_editor.h"
/* 保存交接显示态(值列 ENTER/WAIT/OK/ERR/LOCK,与 net_cfg 保存行同字面)
* ⚠ 新增态一律**尾追加**:前四个值按序被各页与先例使用,中间插入会把后续态的
* 数值整体挪位——数值挪位在 C 里不报错,只会让屏上的词换成另一个词 */
typedef enum {
UI_W_SETLIST_ST_IDLE = 0, /* 空闲:保存行显示 ENTER */
UI_W_SETLIST_ST_WAIT, /* 请求已投递、属主任务处理中:WAIT */
UI_W_SETLIST_ST_OK, /* 上轮提交成功:OK */
UI_W_SETLIST_ST_FAIL, /* 上轮提交失败:ERR */
UI_W_SETLIST_ST_LOCK /* 定值闭锁(= par.locked,校验和自检失败):值列 LOCK
* 且**禁编辑**(组件见 LOCK 即不消费 ENTER)。
* ⚠ 与「未标定」是两件事、屏上两条通道:未标定
* (= par.cal_block)仍可改定值、只是判据停走,
* 用标题右侧徽标表达;LOCK 才是"写不进去"。
* 三词三源 → docs/算法/采集与算法层设计说明.md §13.4 */
} ui_w_setlist_st_t;
/* 行种类 */
#define UI_W_SETLIST_KIND_NUM 0u /* 数值行:ui_w_editor 逐位编辑(min/max/decimals 有效) */
#define UI_W_SETLIST_KIND_ENUM 1u /* 二态文字行:ENTER 在 opts 串表内循环切换 */
/*
* 视图行描述(Flash const 表,一行一条)
* 值通道统一 int32_t 定点:
* 数值行 = 工程量 * 10^decimals(如 10.24 A -> 1024)
* 二态行 = opts 串表下标(0/1/...)
*/
typedef struct {
const char *name; /* 中文名 <= 7 字(字体子集已预置) */
uint8_t id; /* 应用侧枚举 ID:组件只透传给回调,不解释语义 */
uint8_t kind; /* UI_W_SETLIST_KIND_NUM / _ENUM */
uint8_t decimals; /* 数值行小数位 0..3(二态行忽略) */
int32_t min; /* 数值行下限(含;>=0;二态行忽略) */
int32_t max; /* 数值行上限(含;二态行忽略) */
const char *const *opts; /* 二态行:NUL 结尾 Flash 字符串串表(数值行 NULL) */
const char *unit; /* 数值行单位后缀(Flash,NULL = 不挂;二态行忽略)
* 单位是"屏上的话",跟视图表走、不进 App 快照;只挂在
* 非编辑态的数值串尾——编辑中是逐位输入串,挂单位会让
* ui_w_editor 的位光标算错列宽(其契约:串内只有数字与点) */
} ui_w_setlist_row_t;
/* 数据回调组(均 uiTask 上下文、页面绘制/按键链内调用;实现由批 2 页面跳板提供,
* 组件不 include 任何 App 头——数据绑定经此注入) */
/*
* 函数功能:读某行当前值(数值行 = 工程量 * 10^decimals;二态行 = 串表下标)
* 入口参数:id - 行表登记的枚举 ID uint8_t
* 返回值:当前值 int32_t
*/
typedef int32_t (*ui_w_setlist_get_fn)(uint8_t a_id);
/*
* 函数功能:写某行 RAM 工作副本(不写盘;落盘统一经 commit 整表提交)
* 入口参数:id - 行枚举 ID uint8_t
* val - 新值(口径同 get) int32_t
* 返回值:无
*/
typedef void (*ui_w_setlist_set_fn)(uint8_t a_id, int32_t a_val);
/*
* 函数功能:整表提交(一次封存一次校验和;实现只投递请求到属主任务,不阻塞)
* 入口参数:无
* 返回值:无(投递结果经 state 回调回读)
*/
typedef void (*ui_w_setlist_commit_fn)(void);
/*
* 函数功能:保存交接态回读(保存行值列显示源)
* 入口参数:无
* 返回值:当前交接态 ui_w_setlist_st_t
*/
typedef ui_w_setlist_st_t (*ui_w_setlist_state_fn)(void);
/*
* 函数功能:查询某数据行是否为"保存失败越界行"(需反显高亮)
* 入口参数:row - 数据行下标(不含保存行) uint16_t
* 返回值:true = 需反显;false = 正常(提问谓词,非错误通道) bool
*/
typedef bool (*ui_w_setlist_bad_fn)(uint16_t a_row);
/*
* 定值表实例
* 用法(页面跳板示例,批 2):
* static ui_w_setlist_t s_sl = { .rows = s_rows, .count = N, .get = get, ... };
* count_cb -> ui_w_setlist_count(&s_sl)
* refresh -> ui_w_setlist_refresh(&s_sl, row, name, value)
* key_cb -> ui_w_setlist_key(&s_sl, key)
* draw_cb -> ui_w_setlist_draw(&s_sl, layer, clip)
* init_cb -> ui_w_setlist_reset(&s_sl)
*/
typedef struct {
const ui_w_setlist_row_t *rows; /* Flash 行表 */
uint16_t count; /* 数据行数(不含保存行) */
ui_w_setlist_get_fn get; /* 必填 */
ui_w_setlist_set_fn set; /* 必填(整定提交前的 RAM 副本写入口) */
ui_w_setlist_commit_fn commit; /* NULL = 查看视图(无保存行、禁编辑) */
ui_w_setlist_state_fn state; /* NULL = 保存行恒显示 ENTER */
ui_w_setlist_bad_fn bad; /* NULL = 不做越界行反显 */
ui_w_editor_t ed; /* 数值编辑实例 */
uint16_t ed_row; /* 编辑中行下标(仅 editing 时有效) */
} ui_w_setlist_t;
/*
* 函数功能:开页复位(清编辑态;接页面 init_cb)
* 入口参数:inst - 定值表实例 ui_w_setlist_t *
* 返回值:无
* 限定条件:无
*/
void ui_w_setlist_reset(ui_w_setlist_t *a_inst);
/*
* 函数功能:总行数(接框架 count_cb:数据行 + 保存行[仅整定视图])
* 入口参数:inst - 定值表实例 const ui_w_setlist_t *
* 返回值:总行数 uint16_t
* 限定条件:rows 非空(空表防御返回 0)
*/
uint16_t ui_w_setlist_count(const ui_w_setlist_t *a_inst);
/*
* 函数功能:逐行取数(接框架 refresh:名 = 行表、值 = 回调读/编辑器实时串/保存态)
* 入口参数:inst - 定值表实例 ui_w_setlist_t *
* row - 全局行下标 uint16_t
* name - 名输出缓冲(UI_BUF_STRLEN) char *
* value - 值输出缓冲(同上) char *
* 返回值:无
* 限定条件:页面打开(框架绘制链内调用)
* 函数说明:编辑中行的值列显示编辑器当前串(实时随 ↑↓ 变,同 net_cfg);
* 保存行(最后一行、整定视图)值 = ENTER/WAIT/OK/ERR(state 回调)
*/
void ui_w_setlist_refresh(ui_w_setlist_t *a_inst, uint16_t a_row,
char *a_name, char *a_value);
/*
* 函数功能:按键处理(接框架 key_cb;配合描述符 key_intercept=1 转发 LEFT)
* 入口参数:inst - 定值表实例 ui_w_setlist_t *
* key - LVGL 键值 lv_key_t
* 返回值:1 = 已消费(框架跳过内置);0 = 交回框架(↑↓ 移选、← 关页等)
* (键分发标志非错误通道,取 uint8_t——BSP 公开 API 约定)
* 限定条件:页面打开(内部经 ui_content_page_selected_row / is_editable 判态)
* 函数说明:1. 数值编辑中:↑↓ 步进 / ←→ 移位 / ENTER 提交(越界拒绝)全由
* ui_w_editor 消费;提交成功即经 set 回调写工作副本
* 2. 正常态 ENTER(可编辑权限):数值行进编辑(光标个位);
* 二态行循环切换;保存行投递整表提交(一次封存一次校验和,
* 整表提交口径见 页面补齐规划.md §3.2)
* 3. 只读权限 ENTER 一律不消费;ESC 恒关页(框架,未提交编辑丢弃,
* 已经 ENTER 提交到工作副本的调整保留、不落盘——net_cfg 先例)
* 4. 整定视图 state()==LOCK(定值闭锁)→ ENTER 同样一律不消费:
* 不进数值编辑、不切二态、不投保存——**为什么闭锁不由组件解释**,
* 它只按 state 回调给的事实收住写交互(闭锁 vs 未标定的分工见
* ui_w_setlist_st_t 的 LOCK 注);已在编辑中的那一格不强制打断,
* 但其值只落在工作副本,投递口已被 LOCK 堵住,落不了盘
*/
uint8_t ui_w_setlist_key(ui_w_setlist_t *a_inst, lv_key_t a_key);
/*
* 函数功能:自绘(接框架 draw_cb:编辑光标反显 + 保存失败越界行反显)
* 入口参数:inst - 定值表实例 ui_w_setlist_t *
* layer - 绘制层 lv_layer_t *
* clip - 重绘区 const lv_area_t *
* 返回值:无
* 限定条件:页面打开;框架内置区块(行/带/页脚)已绘完
* 函数说明:行槽 y 按标准列表骨架 + 当前页窗口换算(与框架 cp_draw_rows 同式:
* first = sel / UI_LIST_ROWS * UI_LIST_ROWS)
*/
void ui_w_setlist_draw(ui_w_setlist_t *a_inst, lv_layer_t *a_layer,
const lv_area_t *a_clip);
#ifdef __cplusplus
}
#endif
#endif /* UI_W_SETLIST_H */