From 4479aa52a57602dc541b0526486e6c5ce1ca5e33 Mon Sep 17 00:00:00 2001 From: "DeepSeek V4.1 Flash" <> Date: Wed, 28 Oct 2026 12:47:01 +0800 Subject: [PATCH] =?UTF-8?q?UI=20=E9=87=8D=E6=9E=84=EF=BC=9A=E5=85=B6?= =?UTF-8?q?=E4=BD=99=E8=AE=A1=E5=88=92=E9=A1=B9=E5=85=A8=E9=83=A8=E7=BB=93?= =?UTF-8?q?=E6=A1=88=EF=BC=88=E9=99=84=E4=B8=8D=E9=87=87=E7=94=A8=E7=90=86?= =?UTF-8?q?=E7=94=B1=EF=BC=89=EF=BC=8C=E8=AE=A1=E5=88=92=E4=B8=8D=E5=86=8D?= =?UTF-8?q?=E6=9C=89=E6=82=AC=E7=A9=BA=E9=98=B6=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 评估阶段最后的产物:把"能做但收益不成立"的项显式结案,而不是留成待办。 - Documents/UI_Refactor_Plan.md:P3 行改为「Toolbar/TabBar 已迁移;PopupMenu/ColorPicker/ SignalPanel 行经评估不采用」;P4 行改为「经评估不采用」。 - Documents/UI_Refactor_Report.md 第 7 节重写为「其余计划项的处理结论(均已结论,无悬空项)」, 逐项给出基于代码事实的理由: * PopupMenu / ColorPicker:模态浮层每帧整体重画、命中是 <=20 行矩形线性扫描, 且已有单一 BuildLayout 同时产出绘制与命中矩形(已是同源几何)⇒ 控件树额外收益近零, 风险集中在子菜单悬停/内联编辑/滚动/拖拽钳制。 * SignalPanel 行:性能来自行位图缓存(PaintRowCached + RowCacheKey)与抽拉式折叠动画, 控件化会把缓存键与控件生命周期耦合,且"行高永不变、只平移"与通用布局模型冲突。 * 5 个浮动面板(P4):面板像素层已缓存到 0.3ms(全画 24~35ms)⇒ 控件化无帧时间收益; 几何已是单一纯函数(5 种面板共享);控件化需重写吸顶/滚动/滚动条/滑块复位/行悬停压暗, 回归面极大。 * 56 处 InvalidateRect 并集:InvalidatePlotRect() 已是按消息的批处理点,逐处替换只增间接层。 验证:make release 零警告;Tools/uicheck 69/69;Tools/rendercheck 7 条功能断言 PASS,退出码 0。 --- Documents/UI_Refactor_Plan.md | 4 ++-- Documents/UI_Refactor_Report.md | 19 ++++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) 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 场景像素哈希一致 + 功能断言。 ---