review(panels+size): 面板结构收敛收尾、审查清理、新增平行数组护栏

一、审查清理
* `PlotView::FreeMarkerValue` 的 `const Lane&` 形参从未使用(函数体里只有一句
  `(void)lane;`)⇒ 删除形参与该语句,更新 2 个调用点。
* `EdgePanelLayoutFor` 里「选区截取是否就绪(双光标)」算了 3 遍 ⇒ 收敛为函数顶部
  一次 `clipReady`。它同时决定面板高度 footer、条目行可见性、按钮几何,
  三处各算一遍时只要有一处条件写错,就是"底部多一段空白"或"没双光标却能滚动"。

二、新增护栏(离屏检查)
* `panels`:新增「平行数组长度一致」不变式 —— `EdgePanelLayout` 的 13 个按行平行
  vector 必须与行数一致;4 个「重采样」专属数组允许为空、非空则必须对齐。
  这是"某列读到别人矩形"这类错位缺陷的唯一低成本护栏(O(1))。
* `panelscroll`:同样加一份(大文件、566 行时才会暴露的问题)。
* `panels` 输出增加 rows 数,便于定位。

三、文档
* `Documents/Code_Review_Plan.md` 新增 §七(第 35 轮节点与硬约束)。
* `Documents/Code_Review_Progress.md` 新增第 35 轮(面板架构评估 + 三次重构记录)。
* `Documents/Code_Review_Report.md` 新增 §12(评估结论 + gdtoa 最终结论 + 护栏价值)。
* `Documents/agent_mem.md` 新增第 35 轮六条规则。
* `Tools/README.md`:补 `panelscroll`、`integer_replacement_matches_std`,
  断言数更新为 260 / 108,最小集表补充面板相关条目。

验证:
* `make release`(删 .o 全量)零 error / 零 warning,产物 **786,944 B**。
* `make -C Tools` 零 error / 零 warning。
* `UnitTests` → checks=260 failed=0 cases=19。
* `OffscreenChecks -all` → 6/6 检查 PASS,checks=108 failed=0。
* `panels -mode compare` → 7 个面板像素哈希与几何逐项不变。
This commit is contained in:
DeepSeek V4.1 Flash committed 2026-11-04 14:37:59 +08:00
1 parent 34365b3c1c
commit b58b427f62
8 files changed
+408 -15

No files matched your search

+70
View File
@@ -10429,3 +10429,73 @@ release/debug **零警告**;Release `TargetCheck.exe` **890,880 B**(< 1 MB
* 单元测试写错过的 5 处"我以为的语义"(都已按产品语义修正):
`9.999999999999999`(>15 位有效数字允许 1 ULP)、`1..2` 合法、`FormulaIsIdentity` 不去空格、
非法公式 `EvaluateFormula` **原样返回采样值**(不是 NaN)。
---
## 2026-11-04 · 第 35 轮(`Code_Review` 分支):浮动面板结构收敛 + 整数格式化替换
> 计划 `Documents/Code_Review_Plan.md` §七,逐节点 `Documents/Code_Review_Progress.md` 第 35 轮,
> 结论 `Documents/Code_Review_Report.md` §12。提交:`abcf3e6`(面板)、`34365b3`(整数)、
> 本提交(清理 + 文档 + 新检查)。
### 1. ⭐ 面板"改一次就出错"的真实机制(用户 2026-11-04 指出的问题)
**不是缺公共基类**,而是同一套"按种类分支"被抄了 6 份:
| 重复项 | 份数 |
| --- | --- |
| 分类布尔量(listStyle/countTable/hasButton…) | 3(宽度 / 布局 / 绘制) |
| 滚动条几何 + 夹取 | 3(表格 / 列表 / 自由标记分支) |
| 滚动条绘制 | 3 |
| `SetLane*Scroll` 实现 | 7 |
| 按种类转发滚动写入 | 2(滚轮 / 拖滚动条) |
| 标题文本 | 2(**内容还不一致**) |
**新增硬规则:新增一种实验性功能面板,只允许改三个地方** ——
`LanePanelScrollOf` / `PanelStyleOf` / `PanelTitle`。
三者都是穷举 `switch` 且**不写 `default:`** ⇒ 漏登记会被 `-Wswitch` 编译报警。
**禁止**再在宽度 / 布局 / 绘制里各写一份 `kind == XXX` 组合判断。
### 2. ⚠️ `PanelStyle` 里"有按钮行"≠"是构建按钮"
`footerButtons()`(有按钮行:buildButton || twoButtons)与 `buildButton`(是「构建为新信号」)
必须分开:混用会让「选区截取」底部按钮行高归零 ⇒ 面板高度 124 → 87 px,
而内容区仍按旧高度算。**这次是 `panels -mode compare` 当场抓到的**(5 个面板哈希同时变),
它就是"改面板必须跑像素基线"的最好例证。
### 3. ⛔ gdtoa(≈33 KB)**在 C++ 里去不掉**(别再试)
* 替换 76 处 `std::to_wstring` + 2 处 `std::to_string` 为 `Utf8Util::FormatInteger*`:**−1,024 B**。
* 再叠加 `-D__USE_MINGW_ANSI_STDIO=0`:**0 字节**。
* 根因(精确到行):libstdc++ 的
`.../include/c++/x86_64-w64-mingw32/bits/os_defines.h:48-51` **无条件**
`#undef __USE_MINGW_ANSI_STDIO` + `#define … 1`
("libstdc++ depends on POSIX-definitions of those functions")。
`g++ -E -dM` 实测最终值恒为 1 ⇒ 任何 C++ TU 的 `swprintf`/`strtod` 都是 MinGW 版本。
* ⇒ 要省它只能自己重写浮点↔十进制(等价 gdtoa)。**判定:不做**,`Makefile` 已留结论。
### 4. 面板"公共组件"评估结论(用户问的)
* **右键菜单 / 二级菜单**:`Components/Shared/PopupMenu` —— 已是公共组件(5 类菜单共用)。
* **拾色器**:`Components/Shared/ColorPickerPopup` —— 已是公共组件。
* **实验性功能面板**:骨架已是一份(标题栏 = 折起三角 + GX 徽标 + 标题 + ✕ / 滚动内容区 /
底部按钮行),**不该**搬进 `UiWidget` 树:面板像素走 `m_panelDc` 图层缓存、
几何必须由 `EdgePanelLayoutFor` 唯一给出、还要 `BitBlt` 抓像素 + `AddOccluder` 挖洞 +
按 `m_panelOrder` 设文本层号 —— 全是 `PlotView` 内部协议。
⇒ 正确方向是**派发点收敛**(本轮已做),不是控件树化。
### 5. 新增护栏(本轮最重要的产出)
1. **`panelscroll`**:7 种面板逐一滚到底/回顶,验证夹取、滑块端点、内容区不动、
不可滚时无滚动条。`MF4-Record.MF4`(566 信号并入同一网格)实测 6/7 可滚。
2. **平行数组长度不变式**(`panels` + `panelscroll`):`EdgePanelLayout` 的 13 个按行平行
`vector` 必须等于行数;4 个「重采样」专属数组允许为空、非空则必须对齐。
O(1) 成本,守住"某列读到别人矩形"这一整类错位。
3. 工具断言总数:UnitTests **260**、OffscreenChecks **108**(-all)。
### 6. 遗留(下一步候选,按性价比)
* `EdgePanelLayout` 17 个平行数组合并为 `std::vector<PanelRow>` —— **314 处引用**,
是"改布局就出错"的最后一块机制隐患;已先用长度检查兜住。
* `PaintEdgeCursor`(约 1600 行)把三段内容绘制机械提取为 3 个成员函数,
判据 = `panels -mode compare` 全绿。