Files
StellarX-kaifa/开发记录/模块/Module-20260415-0004-布局系统第二阶段验收与封口.md

178 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 新增功能模块 / 模块重构
> 适用场景:新增模块、重大模块重构、核心架构能力演进。
> 不适用场景:小接口或轻量功能变更,请使用“功能变更”模板。
## 基本信息
- 模块 IDModule-20260415-0004
- 模块名称: 布局系统第二阶段验收与封口
- 状态:已验证
- 类型:模块重构
- 所属系统 / 子系统: GUI 框架 / Layout
- 版本 / 分支: 当前工作区 / 下一版本开发中
- 环境: Windows + EasyX
- 负责人: Codex 协作修改
## 背景与目标
- 背景:
- 第一阶段已完成统一锚点模型和统一解算入口。
- 第二阶段继续围绕“几何所有权收口 + 内容驱动规则收口”推进,实现几何写入口分层、内容驱动控件规则收口、局部重绘与 overlay 补画链修复。
-`KEY1 / KEY5` 回归过程中,又暴露出脏子树提交、coverage 低估、TabControl 层级顺序等一组重绘链问题,需要一并收口后才能视为阶段稳定。
- 当前痛点:
- 缺少一份明确的阶段验收记录,难以区分“本阶段完成项”和“明确延期项”。
- 当前主线 bug 虽已基于测试用例修复,但如果不做封口记录,后续继续推进下一主题时容易重复回头整理。
- 目标:
- 明确第二阶段已经完成的主线改造和已验证的 bug 修复。
- 明确当前接受的边界与明确延期的技术债。
- 为后续“公开布局 API + 旧 demo 迁移”提供稳定起点。
- 非目标:[可选]
- 本记录不新增运行时代码逻辑。
- 本记录不覆盖未来的 Tooltip 智能选位、`Table` 纵向拉伸、`Dialog` synthetic move 统一改造。
## 模块边界
- 职责:
- 汇总布局系统第二阶段的最终语义收口结果。
- 记录本阶段已完成的运行态 / 设计态几何规则、局部重绘提交规则与 overlay 补画规则。
- 明确已知延期项与后续主题边界。
- 不负责什么:
- 不扩展新的布局表达能力。
- 不重写 `Dialog` 旧 synthetic move 机制。
- 不实现 `Table` 内部局部重绘体系。
- 外部依赖:
- `Control / Window / Canvas / TabControl / Table / Label / Button`
- EasyX 绘制与消息循环环境
- 对外能力 / API:
- 保持旧 API`setLayoutMode(...)``setAnchor(...)`
- 保持显式设计基线提交入口:`commitCurrentGeometryAsDesignRect()`
- 保持 `Label::textStyle` 公开,但要求样式修改后手动 `setDirty(true)`
- 关键数据 / 状态:
- `localx / localy / localWidth / localHeight`
- `x / y / width / height`
- `LayoutSpec / LayoutCapability / ResolvedLayoutRect`
- `eventVisualChanged / dirty / coverage / overlay`
## 设计说明
- 核心流程:
- 几何变化先在父局部坐标系内统一解算,再通过内部受控路径应用到运行态矩形。
- 内容驱动控件在自身受控路径中刷新运行态尺寸;设计基线不得在普通布局过程中自动漂移。
- 托管局部重绘按“脏子树提交 -> 直接分支 coverage -> 传递式 overlay 补画”收口,确保嵌套容器、Tooltip、上层兄弟遮挡链闭合。
- 关键对象 / 类关系:
- [`Control.h`](D:/programming/imGUI-easyX/imGui-easyX/Control.h):统一布局解算、设计基线提交、托管重绘底座
- [`Label.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Label.cpp):内容驱动尺寸刷新前移,`draw()` 只消费运行态矩形
- [`Canvas.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Canvas.cpp):直接子树映射、脏子树提交、局部 overlay 补画
- [`TabControl.cpp`](D:/programming/imGUI-easyX/imGui-easyX/TabControl.cpp):外层统一布局,内部页签栏/页面区自管,绘制顺序与局部提交顺序统一
- [`Table.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Table.cpp):当前版本 `X Stretch / Y Fixed`、分页按钮视觉与页码重绘修复
- [`Window.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Window.cpp):顶层托管重绘、传递式 overlay 补画、顶层 coverage 收口
- 生命周期:
- 普通 resize / 重排不自动回写 `local*`
- 公开 setter 只写运行态,不隐式提交设计基线
- 显式设计基线提交只通过 `commitCurrentGeometryAsDesignRect()` 或控件内部受控结构刷新触发
- 事件 / 渲染 / 数据流:[按模块类型填写]
- `WM_MOUSEMOVE`:真实命中分支处理事件,后续兄弟仅清理鼠标瞬时状态
- 托管局部重绘:先提交 dirty root / dirty branch,再按 coverage 传递式补画 overlay
- Tooltip / 扩展绘制 coverage:通过 `getManagedRepaintCoverageRect()` 纳入托管 coverage 计算
- 关键不变量:
- `local*` 只表示设计态父局部矩形
- `x / y / width / height` 只表示运行态绘制矩形
- `draw()` 不再承担新的几何决策入口
- `Table` 当前版本 `Y Fixed` 是实现边界,不是永久产品结论
- 降级 / 回退策略:[可选]
- Stretch 不满足条件时降级为固定尺寸位移策略,并输出最小必要日志
- 控件能力边界拦截 Stretch 请求时,通过日志说明被拦截的轴和原因
## 实现与影响
- 关键实现点:
- 收口公开 setter、统一布局应用路径、内容驱动路径、显式设计基线提交四类几何写入口
- 修复 `WM_MOUSEMOVE` 短路后 hover / tooltip 无法及时清理的问题
- 修复局部重绘只认直接 dirty child、不认 dirty descendant 的链路缺口
- 修复 coverage 低估导致 Tooltip / overlay 漏补画的问题
- 修复 Tab 页签按钮与页面绘制顺序不一致导致 Tooltip 被页面覆盖的问题
- 修复重复激活已激活页签时的残影 / 快照链扰动问题
- 涉及文件 / 类 / 函数:
- [`Control.h`](D:/programming/imGUI-easyX/imGui-easyX/Control.h)
- [`Control.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Control.cpp)
- [`Label.h`](D:/programming/imGUI-easyX/imGui-easyX/Label.h)
- [`Label.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Label.cpp)
- [`Button.h`](D:/programming/imGUI-easyX/imGui-easyX/Button.h)
- [`Button.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Button.cpp)
- [`Canvas.h`](D:/programming/imGUI-easyX/imGui-easyX/Canvas.h)
- [`Canvas.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Canvas.cpp)
- [`TabControl.h`](D:/programming/imGUI-easyX/imGui-easyX/TabControl.h)
- [`TabControl.cpp`](D:/programming/imGUI-easyX/imGui-easyX/TabControl.cpp)
- [`Table.h`](D:/programming/imGUI-easyX/imGui-easyX/Table.h)
- [`Table.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Table.cpp)
- [`TextBox.h`](D:/programming/imGUI-easyX/imGui-easyX/TextBox.h)
- [`TextBox.cpp`](D:/programming/imGUI-easyX/imGui-easyX/TextBox.cpp)
- [`Dialog.h`](D:/programming/imGUI-easyX/imGui-easyX/Dialog.h)
- [`Dialog.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Dialog.cpp)
- [`Window.h`](D:/programming/imGUI-easyX/imGui-easyX/Window.h)
- [`Window.cpp`](D:/programming/imGUI-easyX/imGui-easyX/Window.cpp)
- [`MessageBox.h`](D:/programming/imGUI-easyX/imGui-easyX/MessageBox.h)
- [`z-testDome.cpp`](D:/programming/imGUI-easyX/imGui-easyX/z-testDome.cpp)
- 兼容性影响:
- 旧锚点 API 仍可用,内部实现已完全转到新布局模型
- `Label::textStyle` 仍为公开字段,但要求样式修改后显式 `setDirty(true)`
- `TabControl::setActiveIndex()``Button::setButtonClick()` 对重复同状态调用新增短路,不再重复触发链路
- 性能影响:
- 局部重绘 coverage 和 overlay 补画会更保守,补画次数可能略增
- 相比整窗 / 整容器强制重绘,这仍是更合理的正确性与性能折中
- `Table` 分页按钮视觉变化当前仍提升为整张 `Table` 重绘,颗粒度偏粗但正确性优先
- 风险点:
- `Dialog` 旧 synthetic move 机制仍与新清理模型并存
- `Table` 尚未拥有自己的内部局部重绘体系
- 公开 `AxisSizePolicy / AxisAlignPolicy` API 仍未开放,旧 demo 仍受旧入口表达能力限制
## 测试与验证
- 测试范围:
- `KEY1`:页签重复激活、表格超出页范围残影回归
- `KEY5`:三层 `Canvas` 嵌套、跨容器 hover / tooltip、overlay 补画、`TabControl``Table`、页码与分页按钮
- 核心源码编译级验证:布局主线、重绘主线、Tab / Table / Label / TextBox / Dialog 主线
- 验证步骤:
1. 编译 `Control.cpp / Button.cpp / Label.cpp / Canvas.cpp / TabControl.cpp / Table.cpp / TextBox.cpp / Dialog.cpp / Window.cpp`
2. 编译 `z-testDome.cpp /DKEY=1`
3. 编译 `z-testDome.cpp /DKEY=5`
4. 手动回归 `KEY1 / KEY5` 中的 tooltip、overlay、页签、分页、三层嵌套和跨容器按钮场景
- 验证结果:
- 编译级验证通过
- 基于当前 `KEY1 / KEY5` 用例回归,已知 bug 已修复
- GUI 手动回归依赖本机继续确认,当前结论基于现有测试反馈成立
- 已知限制 / 遗留问题:[可选]
- `Dialog` 旧 synthetic `WM_MOUSEMOVE` 机制尚未统一到新模型
- `Table` 内部局部重绘体系尚未实现
- Tooltip 智能选位明确后置
- 公开 `AxisSizePolicy / AxisAlignPolicy` API 尚未开放,`KEY2` 等旧场景仍受旧 anchor 语义限制
## 落地信息
- 关联功能变更 ID[可选]
- `Feature-20260415-0008`
- 关联 BUG / Fix[可选]
- `BUG-20260415-0005`
- `Fix-BUG-20260415-0005`
- `BUG-20260415-0006`
- `Fix-BUG-20260415-0006`
- `BUG-20260415-0007`
- `Fix-BUG-20260415-0007`
- `BUG-20260415-0008`
- `Fix-BUG-20260415-0008`
- Commit: 未提交(当前工作区)
- PR[可选]
- 发布版本:[可选]
- 相关文档:[可选]
- [Module-20260415-0003-布局系统第二阶段收口.md](D:/programming/imGUI-easyX/imGui-easyX/开发记录/模块/Module-20260415-0003-布局系统第二阶段收口.md)
- [Feature-20260415-0008-KEY5-第二阶段专项回归场景增强.md](D:/programming/imGUI-easyX/imGui-easyX/开发记录/功能变更/Feature-20260415-0008-KEY5-第二阶段专项回归场景增强.md)
- [BUG-20260415-0006-托管局部重绘未正确提交脏子树导致嵌套Canvas按钮状态不刷新.md](D:/programming/imGUI-easyX/imGui-easyX/开发记录/BUG/BUG-20260415-0006-托管局部重绘未正确提交脏子树导致嵌套Canvas按钮状态不刷新.md)
- [Fix-BUG-20260415-0006-托管局部重绘脏子树提交链修复.md](D:/programming/imGUI-easyX/imGui-easyX/开发记录/Fix/Fix-BUG-20260415-0006-托管局部重绘脏子树提交链修复.md)
- [BUG-20260415-0007-实际绘制coverage低估导致Tooltip与overlay补画漏算.md](D:/programming/imGUI-easyX/imGui-easyX/开发记录/BUG/BUG-20260415-0007-实际绘制coverage低估导致Tooltip与overlay补画漏算.md)
- [Fix-BUG-20260415-0007-实际绘制coverage与overlay补画链修复.md](D:/programming/imGUI-easyX/imGui-easyX/开发记录/Fix/Fix-BUG-20260415-0007-实际绘制coverage与overlay补画链修复.md)
- [BUG-20260415-0008-TabControl页签层级与重复激活链路导致Tooltip和残影异常.md](D:/programming/imGUI-easyX/imGui-easyX/开发记录/BUG/BUG-20260415-0008-TabControl页签层级与重复激活链路导致Tooltip和残影异常.md)
- [Fix-BUG-20260415-0008-TabControl页签层级与重复激活链路修复.md](D:/programming/imGUI-easyX/imGui-easyX/开发记录/Fix/Fix-BUG-20260415-0008-TabControl页签层级与重复激活链路修复.md)