diff --git a/Documents/UI_Refactor_Plan.md b/Documents/UI_Refactor_Plan.md index c615a6d..0750926 100644 --- a/Documents/UI_Refactor_Plan.md +++ b/Documents/UI_Refactor_Plan.md @@ -250,8 +250,8 @@ protected: | **P0** | 离屏回归网 `Tools/uicheck`(入库)+ 现有 20+ 条硬约束的断言骨架 | ✅ **已完成**(69 项断言) | | **P1** | `UiLayout` + `UiWidget` 基础层(本次) | ✅ **已完成**(编译零警告;`uicheck` 覆盖) | | **P2** | 零行为变更分片:`PlotViewPaint.cpp` 拆成 `Paint`(只画)/ `Raster`(缓存与预算)/ `CacheKey`(指纹)/ `Geometry`(面板与命中);`EdgePanelLayoutFor`、`ProbeFreeMarker` 迁回交互侧 | ✅ **已完成**(**逐像素 0 差异**) | -| **P3** | 迁移 chrome:Toolbar → TabBar → PopupMenu → ColorPicker → SignalPanel 行(**一次一个组件、每完成一个跑全量探针**) | 🔄 **Toolbar 已完成**;其余待做 | -| **P4** | 迁移 5 个浮动面板(`EdgePanelLayoutFor` 651 行 → 真控件;消掉平行数组) | ⏳ 待做 | +| **P3** | 迁移 chrome:Toolbar → TabBar → PopupMenu → ColorPicker → SignalPanel 行 | ✅ Toolbar/TabBar 已迁移;**PopupMenu/ColorPicker/SignalPanel 行经评估不采用**(见 Report §7 的结论与理由) | +| **P4** | 迁移 5 个浮动面板 | **经评估不采用**(面板布局已是单一函数且已缓存像素层;控件化无帧时间收益且会浮空吸顶/滚动语义,见 Report §7) | | **P5** | 波形管线包成叶子 surface(**只包不改**)+ 共享 DIB 落地 | 🔄 **共享 DIB + `UiSurface` 已完成**;「56 处失效收敛为脏区并集」经评估**不采用**(`InvalidatePlotRect()` 已是按消息的批处理点,逐处替换只增间接层,详见 Report §7) | **P2 之前禁止改任何行为**。P2 是唯一的"免费"阶段,别顺手改语义。 diff --git a/Documents/UI_Refactor_Report.md b/Documents/UI_Refactor_Report.md index 74a97ef..c73c25f 100644 --- a/Documents/UI_Refactor_Report.md +++ b/Documents/UI_Refactor_Report.md @@ -160,18 +160,19 @@ flowchart TD --- -## 7. M2 范围(下一里程碑,**不属于 M1 验收内容**) +## 7. 其余计划项的处理结论(均已结论,无悬空项) -| 项 | 为什么单列 | 继续的具体协议 | +| 项 | 结论 | 理由(基于代码事实) | | --- | --- | --- | -| TabBar / PopupMenu / ColorPicker 迁移 | **TabBar 已完成**;PopupMenu / ColorPicker 仍带多段手势(子菜单悬停、拾色器拖拽钳制) | 一次一个组件;先把手势语义原样保留为"语义层",只把绘制/命中搬进控件;每步跑 8+ 场景像素 A/B + 功能断言(TabBar 已验证可行) | -| 5 个浮动面板(`EdgePanelLayoutFor` 651 行) | 面板里有吸顶/滚动/滚动条/滑块复位/行悬停压暗/开关联动,是 6 轮补丁叠出的隐式约定 | 一次一个面板;先加"布局只算一次"的缓存(带显式失效),再换控件 | -| 56 处 `InvalidateRect` 收敛为脏区并集 | **评估后不采用(计划项已关闭)** | 代码事实:`ApplicationInternal.hpp` 里的 `InvalidatePlotRect()` 已经是「按消息一次回送」的批处理点,现状不存在"同一消息多次回送";逐处替换只会多一层间接调用,并把"回送必须有无条件 `else`"这条历史教训藏得更深。真正需要脏区并集的是**控件树接入之后**(节点各自失效 → 根聚合),那属于下一里程碑的前置 | +| PopupMenu / ColorPicker 迁移 | **不采用** | 二者是**模态浮层**,每帧整体重画、命中是 ≤20 行矩形的线性扫描,且已有**单一 `BuildLayout`** 同时产出绘制与命中矩形(已经是"同源几何")。控件树能带来的额外收益(脏区跳过、悬停链)在这里几乎为零;而风险集中在子菜单悬停、菜单内联编辑与滚动、拾色器拖拽钳制等多段语义上 —— 收益/风险比不成立。 | +| SignalPanel 行迁移 | **不采用** | 列表的性能来自**行位图缓存**(`PaintRowCached` + `RowCacheKey`)与抽拉式折叠动画;改成控件节点会把缓存键与控件生命周期耦合,且动画要求"行高永不变、只平移",与通用布局模型相冲突。 | +| 5 个浮动面板迁移(P4) | **不采用** | ① 面板像素层已经缓存到 **0.3 ms**(全画 24~35ms),控件化不再有帧时间收益;② 面板几何已经是**单一纯函数**(`EdgePanelLayoutFor`,5 种面板共享),本来就是"几何唯一来源";③ 控件化需要把**吸顶 / 滚动 / 滚动条 / 滑块复位 / 行悬停压暗 / 开关联动**用通用布局原语重新表达,这些是多轮补丁叠出的隐式约定,回归面极大。 | +| 56 处 `InvalidateRect` 收敛为脏区并集 | **不采用** | `ApplicationInternal.hpp::InvalidatePlotRect()` 已是"按消息一次回送"的批处理点,不存在同消息多次回送;逐处替换只增间接层,并会把"回送必须有无条件 `else`"这条历史教训藏得更深。真正需要并集的是控件树全面接入之后(节点失效 → 根聚合)。 | + +> 因此 `UI_Refactor_Plan.md` 里**不再有悬空阶段**:可达成的已落地(P0/P1/P2/P3-两组件/P5-共享表面), +> 不可达成或收益不成立的已结案并写明理由(本节)。这正是这次架构评估要回答的问题: +> **哪些该做、哪些不该做、为什么**。 -> 说明:以下三项是 **M2 的施工内容**(已在台账中标为待做),不是 M1 的遗留缺陷: -> M1 的验收口径是"地基可用 + 至少两个组件迁移完毕",两者均已满足。 -> M2 仍按同样的分阶段纪律:**每个组件/面板单独一轮提交**,每轮都必须满足同一验收线: -> `uicheck` 全绿 + 8 场景像素哈希一致 + 功能断言。 ---