Commit Graph
5 Commits
Author SHA1 Message Date
DeepSeek V4.1 Flash 0c26da07d2 refactor(panels): 面板静态特征收敛为唯一登记表 + 标记面板绘制分段(§17.6 第 1/2 项)
- 新增 pvdetail::PanelKindTraits + PanelTraitsOf(唯一 switch):标题 / 排版类别 /
  滚动字段 / 面板状态 / 功能开关同表登记;新增面板只改「枚举 + 一行」,
  -Wswitch 仍在唯一登记点生效。PanelTitle 改为「前缀 + rangeSuffix 标志」,
  不再依赖 switch(标题降级为数据,不再需要函数指针)。
- PaintPanelMarkerGroups(约 340 行)拆成 6 个具名函数,主函数只保留绘制顺序
  (普通分组栏 -> 条目 -> 表头 -> 吸顶栏 -> 滚动条 -> 透明度行);纯搬移、0 字节变化。
- 顺手修正该函数体遗留的多余缩进。

验证:release/debug/tools 零 warning;UnitTests 260/19;OffscreenChecks -all 7/133;
panels -mode compare 7 面板像素哈希逐项不变;rowgeom compare 965+7 / 1268+7 键 0 差异。
产物 781,824 -> 782,336 B(+512,全部来自登记表)。
2026-11-04 17:22:06 +08:00
DeepSeek V4.1 Flash a9f1563896 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 轮
2026-11-04 16:36:47 +08:00
DeepSeek V4.1 Flash 1463f9d3f8 refactor(panels): 平行数组合并为 std::vector<PanelRow>(消除错位与字段重载)
对应 Code_Review_Report §15.6 第 1 项(方案 B:有结构,无列视图)。

结构
- EdgePanelLayout 的 16 个平行 std::vector 合并为 std::vector<PanelRow> rows,
  PanelRow 带 17 个具名成员:ref / header / nameRect / nameClose / triangle / check /
  stats / levelTrack / levelValue / levelReset / iterTrack / iterValue / iterReset /
  infoMaxInterval / infoMinInterval / intervalField / frequencyField。
- 唯一新增入口:AppendRow(ref, header, nameRect, triangle, check)(返回新行引用)与
  AppendMarkerGroupRow(ref, nameRect, nameClose)(「自由标记」分组行)。
  参数行/重采样行一律 layout.rows.back().xxx = … 赋值。
- 原 int rows(可见信号数)与新容器同名 ⇒ 改名 signalCount,并注明它与 rows.size()
  在 MARK 面板里不相等(只有有固定点的信号才有行)。

消掉的两类问题
1. 某分支漏 push 一列 ⇒ 该列之后所有行读到别人的矩形(静默错位)。现在一行一次成型。
2. rowRefs 字段重载(列表式 = 行信号 / MARK = 分组信号,其余 12 列必须为空)。
   现在每行自带 ref,语义由“填哪些字段”表达;不变式简化为语义断言
   (每行必须有名称区;MARK 行不得带 header/check/stats/滑块/重采样字段)。

顺带清理
- 合并后 rowIndex < layout.rowXxx.size() 全部变成恒真,批量删除 50+ 处
  (含 15 元组长度数组、? x : gd::RectF() 三元判空、if(...){extendRow(...)} 包裹)。
- 调试框与缓存键改为逐行遍历(新增字段只需在 PanelRow 与这两处循环各加一行)。

等价性证明(rowgeom 键名刻意保持不变,故可逐键比对)
  old keys = 919, new keys = 965
  仅存在于旧 = 0;已有键值变化 = 20(全部是 ".count":0 -> N)
  仅存在于新 = 46(全部是新增列的 [NNN],值 0.00,0.00,0.00,0.00)
⇒ 逐行逐字段的真实几何零位移;7 个面板像素哈希(含 resample=2BFC74B3D9B3239C)逐项不变。

验证
- make release:零 warning;784,896 → 782,336 B(−2,560);make debug / make -C Tools 同样零 warning
- UnitTests:checks=260 failed=0 cases=19
- OffscreenChecks -all:7 检查 / 133 断言(上轮 127)全 PASS
- panels -mode compare:7 面板像素哈希逐项不变
- rowgeom -mode compare:965+7 键 0 差异;-data MF4-Record.MF4 时 1268+7 键 0 差异
- 读点:旧 243 处 layout.rowXxx[…] → 现 95 处 layout.rows[…](84 命中判定 / 11 绘制)

过程记录:清理恒真判空时曾用整段替换把「均值滤波」双滑块段误换成「弱峰」双滑块,
编译器报 brace 不平衡,用备份回滚后重做 —— 整段替换必须先精确读出上下文。

文档:Plan §十一、Progress 第 39 轮、Report §16、agent_mem 第 39 轮、Tools/README §4.1/§4.4
2026-11-04 16:18:56 +08:00
DeepSeek V4.1 Flash f07ac74988 refactor(panels): 删除 rowPoints/rowIterations 死列 + 提取 PaintPanelResampleRows
对应 Code_Review_Report §14.5 第 1 项与第 3 项。

第 1 项:删除 EdgePanelLayout::rowPoints / rowIterations(行数组 18 → 16)
- 写入方只有 AppendRow(推空矩形),读取方只有调试框 AddAll 与 PanelSlotKey 的 mix 循环,
  绘制方零(旧式“点数 / 迭代次数”输入框早被滑块版 rowLevelTracks / rowIterTracks 取代)。
- 连带同步:AppendRow、调试框、缓存键、rowgeom 导出、panels/panelscroll 长度不变式、
  文档里的列数(18/14 → 16/12)。

等价性由基线证伪,而不是靠人工 grep:
  old lines = 983, new lines = 919
  only in OLD = 64, only in NEW = 0
  only-in-OLD lines NOT belonging to rowPoints/rowIterations = 0
即除被删两列外,其余 919 条键逐字节相同。

第 3 项(前半):提取 PlotView::PaintPanelResampleRows
- PaintPanelListRows 里 `if (resamplePanel) { …; continue; }` 共 132 行整块提取,
  签名 (g, layout, rowIndex, laneIndex, ref, item);两个局部 lambda
  (paintInfoRow 只读统计行 / paintInputRow 联动输入框)随之迁移。
- maxInterval / minInterval 两个纯拷贝局部量直接用 item.maxInterval / item.minInterval。
- 通用参数行(中心轴统计 + 两行滑块)未提取:需 9 个参数,签名比函数体更难读。

§14.5 第 2 项(完整结构合并)本轮不做,方案已定并写入文档:
- 列视图(PanelColumn<T>)方案否决:拷贝忘重绑 = 静默悬垂,需额外自检兜住;
- 若要做就做“vector<PanelRow> + 具名成员访问(无视图)”,242 处读点(127 处命中判定),
  必须单独一轮。它属整洁性收益(漏推一列已被 AppendRow + 长度不变式挡住),不是紧急项。

验证
- make release:零 warning;785,408 → 784,896 B(−512);make debug 同样零 warning
- make -C Tools:零 warning
- UnitTests:checks=260 failed=0 cases=19
- OffscreenChecks -all:7 检查 / 127 断言全 PASS
- panels -mode compare:7 面板像素哈希 + 几何逐项不变(resample=2BFC74B3D9B3239C)
- rowgeom -mode compare:919 + 7 键,0 差异(基线已按 16 列重录)
- PlotViewPaint.cpp 5575 → 5565;PlotViewPanelPaint.cpp 1016 → 1020

文档:Plan §十、Progress 第 38 轮、Report §15、agent_mem 第 38 轮、Tools/README §4.4
2026-11-04 16:02:15 +08:00
DeepSeek V4.1 Flash 38fbd4b465 refactor(panels): 拆分 PaintEdgeCursor 的三段内容绘制到独立分片
背景:Code Review 报告 §12.7 建议 2。`PaintEdgeCursor` 原本约 1900 行,其中
"按面板排版类别绘制内容"占 1000 行以上,三段(表格 / 列表 / 自由标记)几乎互不相干,
却共享同一个函数的全部局部变量 —— 任何一段的改动都要在 1900 行里定位,
且很容易误用另一段的变量。

改动
* 新增 `Components/PlotView/Src/PlotViewPanelPaint.cpp`(1016 行,机械搬移、零逻辑改动):
  * `PaintPanelCountTableRows` —— 边沿计数表格:固定表头 + 可滚动数据行。
  * `PaintPanelListRows`      —— 列表式:条目栏 + 展开后的参数行(均值/中心轴/弱峰/重采样/截取)。
  * `PaintPanelMarkerGroups`  —— 自由标记:分组栏 + 表头 + 条目 + 吸顶。
  每个函数**只接收它真正需要的东西**(`layout` + `tabLane` + 少数几个参数),
  不再"整个函数都看得见"。
* `PaintEdgeCursor` 从 1900 → 约 900 行;三处块替换为一行调用,
  骨架(边框 / 标题栏 / 折起三角 / GX 徽标 / ✕)与底部按钮**仍留在一处**(对所有面板同源)。
* 滚条绘制抽为 `pvdetail::PaintPanelScrollBar(g, layout, theme)`(三个分支共用)。

顺带修掉报告里承诺但未落地的一处
* `PaintEdgeCursor` 的标题仍是 7 层三元式,与 `EdgePanelWidth` 里**另一条**链并存
  (那条漏了 MARK/CLIP)。现统一为 `PanelTitle(kind)` 唯一来源。

验证(像素基线全部不变,证明是纯搬移)
* `panels -mode compare` → 7 个面板像素哈希 + 几何**逐项不变**。
* `OffscreenChecks -all` → 6/6 PASS,`checks=108 failed=0`。
* `UnitTests` → `checks=260 failed=0`。
* `panelscroll`(MF4,566 信号)→ 6/7 面板可滚,行为不变。
* release 全量零 error / 零 warning;产物 786,944 → **786,432 B**(−512)。
2026-11-04 15:13:00 +08:00