refactor(panels): 几何算式收敛为单一来源 + 参数行提取(§17.6 第 1/2 项)

第 1 项:宽度算式与行高累加各自合并成一份来源
- 新增 `PanelColumnMetrics` + `MeasurePanelColumns(lane, kind)`:全仓唯一的一次"逐信号量宽"。
  * `EdgePanelWidth(laneIndex, kind)` 退化为"量一次 + 算一次"(`EdgePanelWidthFor`);
  * `EdgePanelLayoutFor` 量一次后,宽度与列几何(表格列 / 滑块轨道)都读同一份度量。
  * 改前两者各写一份同名同形的 UiMeasureTextWidth 链,注释只写着"同一组算式 ⇒ 不会漂移",
    那是靠人守的约定,改一处漏一处就是"面板变宽而列不动"(文字压到轨道上)。
- 新增 `PanelRowPlan` + `PlanListPanelRows(lane, kind)`:行高累加与行几何的唯一来源。
  * 改前 `EdgePanelLayoutFor` 对同一批信号遍历两趟(先算总高、再出行几何),
    两处判定(可见/勾选/收起/统计行/参数行数)必须逐字一致 —— 这类"两趟必须同步修改"
    正是"改一次布局就出错"的另一半机制。
  * 现在一个 {ref, checked, collapsed, hasStats, sliderRows} 数组同时喂高度算式与几何生成。
- 合并前先做等价性判别:`valueColumn` 两处算法不同但结果相同(100000 最宽)⇒ 可合并;
  `sliderLabel` 与 `resampleLabel` 不可合并(重采样标签更长,并进会让均值/弱峰变宽)。

第 2 项:`PaintPanelListRows` 的通用参数行提取
- 新增 `PaintPanelParamRows(g, layout, row, kind, PanelParamState{…})`:中心轴统计行 +
  两条滑块分支(均值/弱峰),`paintCounts`/`paintMeanSlider`/`paintPeakSlider` 三个 lambda
  与 `valueColumn` 随之迁入。
- 逐行状态打包进 `PanelParamState`(解析结果 / 两种条目指针 / 网格下标)⇒ 参数表 5 个,
  而不是 9 个散参数(签名比函数体更难读)。
- `PaintPanelListRows` 由约 300 行降到约 120 行,只负责"条目栏 + 按 kind 分派"。
- 顺手把机械搬移遗留的"整个函数体多缩进 2 个 tab"修正。

过程记录(两次锚点误伤,已写入文档避免重犯)
- 锚点 `// 两行滑块` 在 `EdgePanelWidthFor` 内也匹配 ⇒ 误删宽度函数尾部;
- 锚点 `float rowY = ...` 在表格分支先出现 ⇒ 误删「边沿计数」的行发射。
两次都是编译器立刻报错,从 Temp 备份回滚后重做。规则:整段替换的锚点必须唯一,
同名语句多次出现时先定位所属区块再取偏移。

第 3 项(体积)按用户指示暂停投入。

验证(双基线均为"零差异")
- make release / make debug / make -C Tools:零 warning;产物 782,336 → 781,824 B(−512)
- UnitTests:checks=260 failed=0 cases=19
- OffscreenChecks -all:7 检查 / 133 断言全 PASS
- panels -mode compare:7 面板像素哈希逐项不变(含 resample=2BFC74B3D9B3239C)
- rowgeom -mode compare:965+7 键 0 差异;-data MF4-Record.MF4 时 1268+7 键 0 差异

文档:Plan §十二、Progress 第 40 轮、Report §17、agent_mem 第 40 轮
This commit is contained in:
DeepSeek V4.1 Flash committed 2026-11-04 16:36:47 +08:00
1 parent 1463f9d3f8
commit a9f1563896
7 files changed
+1023 -599

No files matched your search

+29
View File
@@ -379,4 +379,33 @@ old keys = 919, new keys = 965
含义:旧结构里"某列根本没被 push"的那些行,现在每行都拥有该字段(值为空矩形)。
**逐行逐字段的真实几何一位都没变**,7 个面板的像素哈希也逐项未变。
---
## 十二、第 40 轮追加(2026-11-04):几何算式重写 + 参数行提取(§16.7 第 1 / 第 2 项)
> 触发:用户要求「继续上一轮报告中 §16.7 的 1 和 2 建议」,并明确第 3 点(体积)暂不投入,
> 等以后功能更新产生新的冗余时再优化。
| 节点 | 内容 | 验收标准 |
| --- | --- | --- |
| **P36** | 宽度算式与列几何共用一份 `PanelColumnMetrics`(`MeasurePanelColumns` + `EdgePanelWidthFor`) | `panels` 7 个面板像素哈希 + 矩形**逐项不变** |
| **P37** | 行高累加与行几何共用一份 `PanelRowPlan`(`PlanListPanelRows`):两趟遍历合一 | `rowgeom` 965+7 键 0 差异;`panelscroll` 全绿 |
| **P38** | `PaintPanelListRows` 的通用参数行提取为 `PaintPanelParamRows`(5 参数) | 双基线归零;`PaintPanelListRows` 由约 300 行降到约 120 行 |
### 12.1 本轮新增硬约束
1. **宽度算式与列几何只能有一份来源**:任何"这个面板的标签列 / 数值列有多宽"都从
`PanelColumnMetrics` 取。**禁止**在 `EdgePanelLayoutFor` 里再写 `UiMeasureTextWidth` 链
(旧代码注释写着"与 `EdgePanelWidth` 同一组算式 ⇒ 不会漂移"——那是靠人守的约定,
改一处漏一处就是"面板变宽而列不动",表现为文字压到轨道上)。
2. **行高与行几何只能有一份来源**:都读 `PlanListPanelRows` 的返回值(`PanelRowPlan`)。
**禁止**再出现"第一趟只算高度、第二趟才算几何"的双遍历 —— 两趟的判定条件必须逐字一致,
任何一处写错就表现为底部留白 / 最后一行被裁 / 没内容却能滚动。
3. **`PanelRowPlan::sliderRows`** 用整数表达"展开几个参数行"(0/2/4),
`hasStats` 表达「中心轴」多一行统计 —— 这两个量是"高度"与"几何"共享的**唯一判定**。
4. **参数行绘制**走 `PaintPanelParamRows(g, layout, row, kind, PanelParamState{…})`;
逐行状态打包进 `PanelParamState`(解析结果 / 两种条目指针 / 网格下标),
目的是把参数表压在 5 个 —— 一个个透传会让签名比函数体更难读。