飞行雪绒 DOCS

鸣潮·爱弥斯纪念桌宠 · LTS1.0.6beta8

计划与归档 · P3

统一绘制模块改造清单

历史归档:把分散的绘制逻辑收敛进统一渲染模块的完整改造清单。

源文件 doc/统一绘制模块改造计划清单.txt 更新 2026-07-24 12.0 KB 在 GitHub 查看

统一绘制模块改造计划清单(历史归档)#

归档说明#

- 本文件用于追溯统一绘制与层级系统的迁移过程。
- 当前边界以 `doc/维护手册.md` 及源码为准。
- 文中的阶段、兼容包装和待办描述不再代表当前实施状态。

推进进度#

更新时间:2026-07-12

已完成:
1. 新增 lib/core/layer.py,定义统一 Layer 枚举与层级工具函数。
2. 新增 lib/core/layer_manager.py,集中管理顶层窗口 layer/z/注册顺序与 Win32 置顶重申。
3. 已完成旧调用迁移并删除 lib/core/topmost_manager.py,层级操作统一使用 LayerManager。
4. 接入 PetWindow 到 Layer.MAIN_PET。
5. 接入 ParticleOverlay 到 Layer.PARTICLE,并移除核心路径裸 raise_()。
6. 接入 EffectOverlay 到 Layer.EFFECT,并移除核心路径裸 raise_()。
7. 扩展 DrawRequest,支持 layer/z/order。
8. 扩展 DrawCore.render(),按 (layer, z, order) 稳定排序。
9. 扩展 DRAW_REQUEST dict 数据格式,支持 layer/z 透传。
10. 新增 lib/core/unified_draw.py 作为统一绘制模块门面。
11. 新增 lib/core/render_layer.py 与 lib/core/render_core.py,提供非窗口级绘制项队列基础。
12. 迁移常用主 UI 到 Layer.PET_UI。
13. 迁移播放列表、命令窗口、小游戏面板、AI 设置面板等到 Layer.PANEL。
14. 迁移二维码/更新弹窗到 Layer.DIALOG,启动/退出动画窗口到 Layer.SYSTEM_MODAL。
15. 迁移沙发、雪豹、雪球、雪堆、闹钟、音响、摩托等独立物件到 Layer.WORLD_OBJECT。
16. 清理核心顶层窗口路径中的裸 raise_(),改由 LayerManager/TopmostManager 兼容入口调度。
17. 新增 LayerManager.describe_snapshot(),支持输出当前窗口层级快照。
18. 新增 #图层 调试命令,运行时可通过信息气泡查看已注册窗口栈。
19. 业务模块层级注册已统一改走 lib/core/unified_draw.py,旧 topmost_manager 兼容层已删除。
20. 统一 DrawCore、RenderCore、LayerManager 排序键:先按 layer,再按 z;两者相同时按生成顺序后来居上。
21. 明确组件接入规范:顶层窗口必须显式注册 Layer,禁止业务代码用裸 raise_() 抢占全局窗口层级。
22. 新增 config/config_layer.py,支持集中设置全部 Layer 数值,无需挂载控制面板,修改后重启生效。
23. 重型运行资源改由 resc.net.txt 管理,安装脚本按缺失资源下载,仓库不再内置 Vosk 模型、启动动画、浏览器运行时和 Python 安装器。

进行中:
1. 评估各类 UI 是否需要进一步拆分 z 值,例如 PET_UI 内按钮、气泡、菜单的细粒度顺序。
2. 将粒子/特效进一步迁入 RenderCore 或统一 RenderOverlay。

待完成:
1. 评估 ParticleOverlay 与 EffectOverlay 是否合并为 RenderOverlay。
2. 进一步整理 PET_UI/PANEL 内部 z 值;未显式拆分 z 时,同级组件按生成顺序后来居上。

组件接入规范#

1. 新增顶层 QWidget/Overlay 必须通过 lib/core/unified_draw.py 获取 Layer 与 LayerManager,并显式注册所属 Layer。
2. 业务代码禁止使用裸 raise_() 调整顶层窗口顺序;窗口层级重申统一走 LayerManager。
3. QWidget 内部子控件可使用 raise_() 调整父窗口内部堆叠,该行为不属于全局窗口层级管理。
4. 非窗口绘制项优先注册到 RenderCore;主宠物帧资源继续使用 DrawCore。
5. 全部绘制路径采用统一顺序:layer 数值越大越靠前,z 数值越大越靠前;layer 与 z 相同时,按生成顺序绘制,后来生成者覆盖在上。
6. 重复更新同一组件保留原生成顺序;组件注销后重新注册视为重新生成,将获得新的顺序并位于同级旧组件上方。
7. 各层级数值统一在 config/config_layer.py 的 LAYER_VALUES 中配置;配置仅在模块首次导入时读取,运行中修改不会热更新。

目标#

在 lib/core 中建立统一绘制与图层管理模块,收敛主宠物、粒子、特效、独立物件、悬浮 UI、弹窗等所有运行期可视对象的层级控制入口,避免各模块分散调用 show()/raise_()/WindowStaysOnTopHint 导致层级互抢。

当前问题#

1. DrawCore 只负责主宠物 GIF/帧绘制,没有统一管理粒子、特效、UI 和独立物件窗口。
2. DrawRequest 没有 layer、z、order 等排序字段,当前渲染依赖 dict 插入顺序,不适合作为层级系统。
3. ParticleOverlay、EffectOverlay、PetWindow、多个 UI/对象窗口各自 show()/raise_(),没有统一调度。
4. TopmostManager 只解决“窗口置顶保持”,不是完整的绘制层级系统;priority 粒度过粗。
5. 特效内部已有 effect.z 排序,但只在 EffectOverlay 内生效,无法与主宠物、粒子、UI 层统一比较。
6. 新增绘制组件时缺少强约束,容易继续复制 Qt.Tool + WindowStaysOnTopHint + raise_() 的散落写法。

核心原则#

1. 统一入口:所有运行期可视对象必须经过 lib/core 的统一绘制/层级模块注册。
2. 分层管理:窗口 z-order 与单窗口内部绘制顺序都使用同一套 layer 语义。
3. 渐进迁移:先统一顶层窗口层级,再逐步合并绘制队列,避免一次性大重构引发回归。
4. 兼容旧接口:保留 get_draw_core()、TopmostManager 常用方法的兼容入口,减少脚本层改造成本。
5. 禁止裸 raise:业务模块不直接调用 raise_() 调整层级,改由统一模块执行。

建议新增模块#

1. lib/core/layer.py
   - 定义 Layer 枚举与默认层级常量。
   - 提供 normalize_layer()、layer_name() 等轻量工具。

2. lib/core/layer_manager.py
   - 统一注册 QWidget 顶层窗口和 overlay。
   - 提供 register(widget, layer, z=0, name=None)、unregister(widget)、set_layer(widget, layer, z=0)。
   - 提供 enforce_now()、enforce_on_frame()、bring_to_front(widget)、raise_layer(layer)。
   - 内部替代/整合 TopmostManager 的 Win32 SetWindowPos(HWND_TOPMOST) 能力。
   - 按 (layer, z, register_seq) 稳定排序,低层先设置,高层后设置。

3. lib/core/render_layer.py
   - 定义 RenderLayer/RenderItem/RenderRequest 数据结构。
   - 描述单窗口内部绘制项的 layer、z、seq、visible、opacity、paint 回调等属性。

4. lib/core/render_core.py
   - 新的统一绘制核心,管理可绘制 item 队列。
   - 提供 register_item()、remove_item()、render(painter, target_rect=None)。
   - 与现有 DrawCore 兼容,DrawCore 可逐步迁入或作为 RenderCore 的资源型 item 提供者。

5. lib/core/unified_draw.py
   - 对外门面模块,集中导出 get_layer_manager()、get_render_core()、get_draw_core() 兼容接口。
   - 后续业务模块优先从这里接入,减少直接依赖具体实现。

建议 Layer 定义#

1. BACKGROUND = 0
   - 预留背景、桌面底部装饰。

2. WORLD_OBJECT = 100
   - 沙发、雪球、雪堆、雪豹等独立物件窗口。

3. MAIN_PET = 200
   - 主宠物 PetWindow。

4. PET_EFFECT_BELOW = 250
   - 需要位于主宠物附近但低于粒子的局部效果。

5. PARTICLE = 300
   - ParticleOverlay。

6. EFFECT = 400
   - EffectOverlay,保留 effect.z 作为 EFFECT 层内排序。

7. PET_UI = 500
   - 关闭按钮、穿透按钮、缩放按钮、气泡、命令提示等宠物附属 UI。

8. PANEL = 600
   - 播放列表、设置面板、搜索框等常规交互面板。

9. DIALOG = 700
   - 登录二维码、更新对话框等需要明确压过普通 UI 的弹窗。

10. TOOLTIP = 800
    - tooltip、临时提示、悬浮说明。

11. SYSTEM_MODAL = 900
    - 退出确认、严重错误提示等最高业务层。

接入清单#

第一阶段:窗口层级统一
1. PetWindow
   - 文件:lib/core/pet_window.py
   - 注册到 Layer.MAIN_PET。
   - 移除每帧直接 self.raise_(),改为 LayerManager.enforce_on_frame()。

2. ParticleOverlay
   - 文件:lib/core/qt_particle_system.py
   - 注册到 Layer.PARTICLE。
   - show() 后不直接 raise_(),改为 LayerManager.bring_to_front(self) 或 enforce_now()。

3. EffectOverlay
   - 文件:lib/core/qt_effect_system.py
   - 注册到 Layer.EFFECT。
   - 保留内部 effect.z 排序,同时纳入全局层级。

4. 旧 TopmostManager(已完成)
   - 所有调用方已迁移到 LayerManager,兼容包装已删除。

第二阶段:主绘制请求排序
1. DrawRequest
   - 文件:lib/core/draw_core.py
   - 增加 layer、z、order 字段。
   - add_draw_request() 记录稳定 seq。
   - render() 按 (layer, z, seq) 排序。

2. DRAW_REQUEST 事件
   - 文件:lib/core/pet_window.py、lib/core/event/center.py
   - 支持 data 中传入 layer、z。
   - 旧格式默认 Layer.MAIN_PET。

第三阶段:UI 层级统一
1. PetWindow 主 UI 工厂
   - 文件:lib/core/pet_window_ui_factory.py
   - 创建 UI 后统一注册 Layer.PET_UI / Layer.PANEL。

2. 常用 UI 组件
   - 文件:lib/script/ui/close_button.py、clickthrough_button.py、scale_button.py、bubble.py、command_dialog.py、command_hint_box.py 等。
   - 移除分散的裸 raise_(),按组件类型接入 LayerManager。

3. 弹窗类
   - 文件:lib/script/ui/update_dialog.py、cloudmusic_login_dialog.py、yuanbao_login_dialog.py、ai_settings_panel.py 等。
   - 注册 Layer.DIALOG 或 Layer.PANEL。

第四阶段:独立物件统一
1. 沙发
   - 文件:lib/script/obj-沙发/sofa.py
   - 注册 Layer.WORLD_OBJECT。

2. 雪豹、雪球、雪堆等对象
   - 文件:lib/script/obj-雪豹/、lib/script/obj-雪球/、lib/script/obj-雪堆/。
   - 注册 Layer.WORLD_OBJECT,禁止自行抢占顶层。

第五阶段:统一 Overlay 可选收敛
1. 新建 RenderOverlay
   - 将 ParticleOverlay、EffectOverlay 合并为一个透明覆盖层。
   - 内部按 RenderItem 的 layer/z 统一绘制。

2. 粒子/特效绘制项化
   - 粒子系统输出 RenderItem 或 paint callback。
   - 特效系统输出 RenderItem,effect.z 映射为 RenderItem.z。

3. 保留兼容路径
   - 短期允许旧 Overlay 与新 RenderCore 并存。
   - 长期目标是全局只有主宠物窗口 + 统一 overlay + 必要弹窗。

验收标准#

1. lib/core 中存在统一绘制/层级入口,新增可视组件有明确接入方式。
2. PetWindow、ParticleOverlay、EffectOverlay 已接入统一 layer,不再互相裸 raise。
3. DrawCore 支持 layer/z 排序,主绘制请求顺序可控。
4. TopmostManager 不再作为业务层直接依赖的唯一层级入口。
5. 新增文档说明各 Layer 的职责和适用组件。
6. 启动、移动、粒子、特效、气泡、弹窗在常规场景下层级稳定。

风险与注意事项#

1. Windows 顶层窗口 z-order 与 Qt raise_() 存在异步行为,需要保留 enforce_burst() 兜底。
2. 穿透模式下需要继续尊重 TopmostManager/LayerManager 的 pause()/resume() 行为,避免干扰全屏应用。
3. 独立 QWidget 跨窗口无法像单 painter 内部一样精确混排,第一阶段只能做到窗口级 layer。
4. 合并 Overlay 可能影响粒子/特效清屏、透明背景和性能,需要单独压测。
5. 大量 UI 组件使用 Qt.Tool,迁移时要避免改变焦点、鼠标穿透、任务栏显示等行为。

建议实施顺序#

1. 新增 Layer/LayerManager/UnifiedDraw 基础模块。
2. 用 LayerManager 包装 TopmostManager 能力,保持旧接口可用。
3. 接入 PetWindow、ParticleOverlay、EffectOverlay 三个核心层。
4. 扩展 DrawRequest layer/z 排序。
5. 分批迁移 UI 与独立物件窗口。
6. 补充文档和最小验证脚本。
7. 评估是否进入 RenderOverlay 合并阶段。

最小验证清单#

1. 启动程序后主宠物正常显示。
2. 主宠物移动时粒子显示在主宠物上方。
3. 特效显示在粒子或指定层级上方。
4. 气泡、命令框、按钮显示在主宠物和特效上方。
5. 登录/更新/设置弹窗显示在普通 UI 上方。
6. 鼠标穿透模式切换后层级不抖动,鼠标事件行为不变。
7. 退出清理时所有注册窗口不会残留或触发已销毁对象异常。