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

8.5 KiB
Raw Blame History

新增功能模块 / 模块重构

适用场景:新增模块、重大模块重构、核心架构能力演进。 不适用场景:小接口或轻量功能变更,请使用“功能变更”模板。

基本信息

  • 模块 IDModule-20260415-0003
  • 模块名称: 布局系统第二阶段收口
  • 状态:已完成
  • 类型:模块重构
  • 所属系统 / 子系统: GUI 框架 / Layout
  • 版本 / 分支: 当前工作区 / 下一版本开发中
  • 环境: Windows + EasyX
  • 负责人: Codex 协作修改

背景与目标

  • 背景:
    • 第一阶段已经完成统一布局链路打通,但几何写入口、内容驱动控件规则、复合控件职责边界仍有残留混用。
    • Label 曾在 draw() 阶段临时决定尺寸,TabControlCanvas 在子树几何映射上也存在职责重叠。
    • WM_MOUSEMOVE 的容器分发和局部重绘合成,在复杂遮挡场景下容易暴露 hover/tooltip 与 overlay 残留问题。
  • 当前痛点:
    • 几何语义还不够制度化,后续继续演进布局系统时容易再次混回“draw 阶段改几何”。
    • 内容驱动控件和复合控件没有完全落成可解释的边界。
    • 局部重绘与上层兄弟补画机制不完整时,会直接破坏遮挡正确性。
  • 目标:
    • 收口几何写入口语义,明确公开 setter、统一布局应用路径、内容驱动路径、显式设计基线提交。
    • 收口 Label / Table 的内容驱动规则与设计基线边界。
    • 收口 TabControl / Canvas 的职责边界,不重写页签系统,但消除页内子控件手工回填。
    • 建立轻量级鼠标瞬时状态清理路径和 overlay 补画机制,保证 hover / tooltip / 局部重绘链正确。
  • 非目标:[可选]
    • 不做字体缩放。
    • 不做 Table 纵向拉伸。
    • 不做 Dialog 旧 synthetic move 机制统一。
    • 不做 Table 内部局部重绘体系。

模块边界

  • 职责:
    • 定义并收口布局系统第二阶段的运行态 / 设计态几何语义。
    • 为当前主线控件显式写出能力边界和默认策略。
    • 收口局部重绘下的 overlay 补画规则。
  • 不负责什么:
    • 不扩展新的布局表达能力。
    • 不处理字体、图标、DPI 自适应。
    • 不把所有控件都改造成内容驱动或局部重绘型复合控件。
  • 外部依赖:
    • EasyX 绘制环境
    • 现有 Control / Window / Canvas / TabControl / Table / Label / Button 体系
  • 对外能力 / API:
    • 保留 setLayoutMode(...)
    • 保留 setAnchor(a1, a2)
    • 保留 commitCurrentGeometryAsDesignRect()
    • Label::textStyle 继续保持公开,但要求样式修改后显式 setDirty(true)
  • 关键数据 / 状态:
    • localx / localy / localWidth / localHeight
    • x / y / width / height
    • LayoutSpec / LayoutCapability / ResolvedLayoutRect
    • eventVisualChanged

设计说明

  • 核心流程:
    • 先在父局部坐标系内完成统一布局解算。
    • 再由内部受控路径把运行态矩形应用到控件。
    • 内容驱动控件在自己的受控路径里刷新运行态尺寸。
    • 局部重绘提交后,由父容器按实际绘制顺序补画 coverage 上方的 overlay 兄弟。
  • 关键对象 / 类关系:
    • Control:几何语义、解算入口、设计基线提交入口。
    • Label:内容驱动尺寸,draw() 只消费运行态矩形。
    • Canvas:管理直接子控件的世界坐标映射与局部 overlay 补画。
    • TabControl:外层接统一解算,内部页签栏 / 页面区继续自管。
    • Table:当前版本 X Stretch / Y Fixed,并保留内部受控结构尺寸基线刷新。
    • Window:顶层托管重绘收口与 overlay 兄弟补画。
  • 生命周期:
    • 普通 resize / 父容器重排不自动回写 local*
    • 显式设计基线提交只通过 commitCurrentGeometryAsDesignRect() 或控件内部受控结构刷新点发生。
    • 内容驱动尺寸刷新优先发生在 draw() 之前。
  • 事件 / 渲染 / 数据流:[按模块类型填写]
    • WM_MOUSEMOVE:第一个命中的兄弟收到真实消息,后续兄弟只清理瞬时鼠标状态。
    • 局部重绘:先画本次 dirty 单元,再补画 coverage 上方相交 overlay。
    • 运行态几何:统一解算或内容驱动路径写入;设计基线不自动漂移。
  • 关键不变量:
    • local* 始终表示设计态父局部矩形。
    • x / y / width / height 始终表示运行态绘制矩形。
    • draw() 不再承担新的几何决策入口。
    • Table 当前版本 Y Fixed 是实现边界,不是永久产品结论。
  • 降级 / 回退策略:[可选]
    • Stretch 条件不满足时自然降级为固定尺寸位置策略。
    • 控件能力边界禁止 Stretch 时,通过日志输出拦截原因。

实现与影响

  • 关键实现点:
    • Control.cpp 增加布局降级日志、能力边界拦截日志、显式设计基线提交日志。
    • Label.cpp 收口内容驱动尺寸刷新,并显式关闭双轴 Stretch。
    • Canvas.cppTabControl.cppWindow.cpp 收口 overlay 补画。
    • Table.cpp 收口 Y Fixed、分页按钮视觉链与页码重绘。
  • 涉及文件 / 类 / 函数:
  • 兼容性影响:
    • 对旧锚点 API 保持兼容。
    • Label::textStyle 仍为公开字段,但使用约定更严格。
  • 性能影响:
    • WM_MOUSEMOVE 和 overlay 补画路径增加了必要的状态清理与补画,但避免了整窗级重绘。
    • Table 分页按钮视觉变化当前仍提升为整表重绘,颗粒度偏粗,但正确性优先。
  • 风险点:
    • Dialog 旧 synthetic move 机制仍与新清理模型并存。
    • Table 内部局部重绘体系尚未建立,分页区仍偏重。

测试与验证

  • 测试范围:
    • 顶层 resize
    • 三层 Canvas 嵌套
    • TabControl 外层 resize 与页内稳定性
    • overlay 补画
    • Table 横向拉伸、分页按钮、页码重绘
    • Label 文本 / 字体样式变化
  • 验证步骤:
  1. 编译 Control.cpp / Label.cpp / Canvas.cpp / TabControl.cpp / Table.cpp / TextBox.cpp / Dialog.cpp
  2. 编译 z-testDome.cpp /DKEY=5
  3. 手动回归 KEY5 的 hover、tooltip、overlay、分页与页码场景
  • 验证结果:
    • 编译级验证通过。
    • 手动 GUI 回归依赖本机继续执行。
  • 已知限制 / 遗留问题:[可选]
    • Dialog 旧 synthetic move 机制暂未统一。
    • Table 尚未引入内部局部重绘模型。
    • 全项目所有控件的能力边界总审计未做。

落地信息