UI 重构 P3:Toolbar 迁移到控件树(新增 UiButtonWidget,逐像素 0 差异 + 功能断言)
新增 Components/Shared/{Inc,Src}/UiButtonWidget.*:通用「文字按钮」控件,视觉规则与旧 Toolbar
按钮逐像素一致(主按钮强调色实底 / 普通按钮 1px 描边 / 可切换选中态 / 禁用态配色);
交互由控件自己处理:按下即 CaptureMouse 进入按下态,在自身范围内松开才触发 onClick,
指针离开(不会再收到抬起)时 CancelPress。
Toolbar 内部重写,公开 API 一字未改:
- Button 只保留静态配置 + 控件指针;矩形与外观状态归控件。
- 删除 m_hoverIndex / m_pressedIndex 与死字段 Button::hover,改由 UiWidget 的悬停链与 capture 维护。
- Paint 改为「根控件(底色 + 底部分隔线)+ 按钮子节点」,一次 root->Paint(ctx)。
- OnMouseMove/Down/Up/Leave 统一翻译成 UiEvent 后 root->Dispatch;动作经 onClick 回调登记、抬起后执行。
框架约定调整:UiWidget::Paint 的裁剪从「严格等于自身矩形」改为「自身矩形外扩 1px(kUiClipBleed)」。
边框/描边以矩形边界为中心绘制,严格裁剪会切掉外半侧使控件变细、与旧绘制不再像素一致。
uicheck 对应断言改为「裁剪 ⊇ 自身矩形且不超出外扩范围」。
验证:
- make release / make debug 零警告;Target.exe 881,664 B(< 900KB)。
- 逐像素 A/B(8 场景:全览 / 深放大+自由标记+滤波+弱峰+光标 / 平移 / 悬停按钮 / 按下 / 松开 /
悬停主按钮 / 移出工具栏):迁移前后哈希逐一相同
A 2166933039626F66 B C444ECFEB18FD73D C 7984446D8E7A4418 D BF855879CA12F289
E 1C663E4118616016 F 0535292D8E07AE18 G 7A58172C46577729 H 23F390DD76141113。
- 功能断言:locate-cursor-button PASS (1291,73);click-cursor-changes-mode PASS (1 -> 2);
release-outside-does-not-fire PASS (2 -> 2)。
- Tools/uicheck 62 passed / 0 failed。
This commit is contained in:
1 parent
7e1852c2d2
commit
25264f9074
9 files changed
+663
-223
No files matched your search
@@ -17,8 +17,8 @@
|
||||
| --- | --- | --- |
|
||||
| **P0** | 离屏回归网 `Tools/uicheck`(入库) | ✅ 完成(62 项断言全绿) |
|
||||
| **P1** | `UiLayout` + `UiWidget` 基础层 | ✅ 完成(编译零警告,`uicheck` 覆盖) |
|
||||
| **P2** | `PlotViewPaint.cpp` 零行为分片 | ✅ 完成(**逐像素 0 差异**,见 §2) |
|
||||
| **P3** | 迁移 chrome(Toolbar / TabBar / 菜单 / 拾色器 / 列表行) | ⏳ 待做 |
|
||||
| **P2** | `PlotViewPaint.cpp` 零行为分片 | ✅ 完成(**逐像素 0 差异**,见 §2/§3) |
|
||||
| **P3** | 迁移 chrome(Toolbar / TabBar / 菜单 / 拾色器 / 列表行) | 🔄 **Toolbar 已完成**,其余待做 |
|
||||
| **P4** | 迁移 5 个浮动面板 | ⏳ 待做 |
|
||||
| **P5** | 波形管线包成叶子 surface + 共享 DIB | ⏳ 待做 |
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
## 提交记录
|
||||
|
||||
### 1. `P0 + P1`:UI 基础层与离屏回归网
|
||||
|
||||
**新增文件**
|
||||
|
||||
| 文件 | 行数 | 职责 |
|
||||
@@ -139,13 +138,50 @@ Tools/uicheck/uicheck.exe # 62 passed, 0 failed
|
||||
|
||||
---
|
||||
|
||||
### 4. `P3`:Toolbar 迁移到控件树(**逐像素 0 差异**)
|
||||
|
||||
**新增**:`Components/Shared/{Inc,Src}/UiButtonWidget.*` —— 通用"文字按钮"控件,视觉规则与旧 Toolbar
|
||||
按钮逐像素一致(主按钮强调色实底 / 普通按钮 1px 描边 / 可切换选中态 / 禁用态配色);
|
||||
交互由自己处理:按下即 `CaptureMouse()` 进入按下态,**在自身范围内**松开才触发 `onClick`,
|
||||
指针离开时 `CancelPress()`。
|
||||
|
||||
**`Toolbar` 内部重写(公开 API 一字未改)**:
|
||||
|
||||
| 旧实现 | 新实现 |
|
||||
| --- | --- |
|
||||
| `std::vector<Button>` 里既存配置又存矩形/悬停/按下 | `Button` 只存**静态配置 + 控件指针**;几何与外观状态归控件 |
|
||||
| `m_hoverIndex` / `m_pressedIndex` 手工维护 | 由 `UiWidget` 的**悬停链**与 capture 维护 |
|
||||
| `Paint` 自己遍历按钮绘制 | 根控件(`ToolbarRootWidget`:底色 + 底部分隔线)+ 按钮子节点,`root->Paint(ctx)` |
|
||||
| `OnMouseMove/Down/Up/Leave` 各自扫按钮矩形 | 统一翻译成 `UiEvent` → `root->Dispatch(event)`;动作经 `onClick` 回调登记、抬起后执行 |
|
||||
| `Button::hover` 死字段 | 删除(`Hovered()` 由基类提供) |
|
||||
|
||||
**新增框架约定(重要)**:`UiWidget::Paint` 的裁剪由"严格等于自身矩形"改为
|
||||
**"自身矩形外扩 `kUiClipBleed`(1px)"**。原因:边框/描边以矩形边界为中心绘制,1px 笔宽有一半在矩形外,
|
||||
严格裁剪会把外半侧切掉 ⇒ 控件看起来变细(与旧绘制代码不再逐像素一致)。
|
||||
`uicheck` 对应断言改为"裁剪 ⊇ 自身矩形且不超出外扩范围"。
|
||||
|
||||
**验证**
|
||||
|
||||
1. `make release` / `make debug` **零警告**;`Target.exe` **881 664 B**(< 900 KB)。
|
||||
2. **逐像素 A/B(8 个场景)**:迁移前后哈希逐一相同
|
||||
`A 2166933… / B C444ECF… / C 7984446… / D BF85587… / E 1C663E4… / F 0535292… / G 7A58172… / H 23F390D…`
|
||||
(A 全览;B 深放大+自由标记+均值滤波+弱峰调整+光标;C 平移;D 悬停按钮;E 按下未松开;
|
||||
F 松开;G 悬停主按钮;H 移出工具栏)。
|
||||
3. **功能验证**(证明点击真的翻译成动作,而不是"看起来没坏"):
|
||||
* `FUNC locate-cursor-button PASS (1291,73)` —— 用控件自身矩形定位按钮;
|
||||
* `FUNC click-cursor-changes-mode PASS (1 -> 2)` —— 点击「光标」按钮后光标模式 单→双;
|
||||
* `FUNC release-outside-does-not-fire PASS (2 -> 2)` —— 按下后移出再松开,不触发动作。
|
||||
4. `Tools/uicheck` **62/62**。
|
||||
|
||||
---
|
||||
|
||||
## 下一步(接手者请从这里开始)
|
||||
|
||||
1. **P3:Toolbar 优先**(最小、最容易验证的组件):
|
||||
继承 `UiWidget` → `OnMeasure` 由按钮文本实测得出 → `OnPaint` 用 `ctx.clip` 画按钮 →
|
||||
`OnEvent` 返回 `{consumed, redraw, dirty}`;迁移后用 `uicheck` + 新旧像素对比。
|
||||
2. **P4:浮动面板**:`EdgePanelLayoutFor` 的 651 行 → 真控件(Stack + Abs + Measure-driven),
|
||||
并消掉面板里 10 多个平行数组(`rowRefs/rowChecks/rowPoints/rowOrder/rowLevelTracks/...`)。
|
||||
3. **P5:共享 DIB + `SurfaceView`**(`CreateCompatibleBitmap` → top-down 32bpp `CreateDIBSection`,
|
||||
带 `version` 作废机制),随后把 56 处 `InvalidateRect` 收敛成脏区并集。
|
||||
4. 每个阶段单独提交,提交信息写清"改了什么 / 为什么 / 怎么验证"。
|
||||
1. **P3 续**:按同一套路迁移 `TabBar`(标签 + 「+」按钮 + 重命名内联输入框)→ 再迁移
|
||||
`PopupMenu` / `ColorPickerPopup` 的条目行。判据同为"8+ 场景像素哈希一致 + 功能断言"。
|
||||
2. **P4**:5 个浮动面板(`EdgePanelLayoutFor` 651 行 → 真控件;Stack + Abs + Measure-driven),
|
||||
消掉 `rowRefs/rowChecks/rowPoints/rowOrder/rowLevelTracks/...` 等平行数组。
|
||||
⚠️ 每个面板单独一轮;吸顶/滚动/滚动条/滑块复位/行悬停压暗/开关联动是 6 轮补丁叠出的隐式约定。
|
||||
3. **P5**:共享 top-down 32bpp `CreateDIBSection` + `SurfaceView{dc,rect,stride,bits,version}`,
|
||||
把 56 处 `InvalidateRect` 收敛成脏区并集。
|
||||
4. 每阶段单独提交,提交信息写清"改了什么 / 为什么 / 怎么验证"。
|
||||
Reference in new issue
Block a user