2026-03-29 01:36:53 +08:00
|
|
|
|
# BuiltInIcons
|
|
|
|
|
|
|
|
|
|
|
|
**命名空间**: `XCEngine::Editor::UI`
|
|
|
|
|
|
|
|
|
|
|
|
**类型**: `header-helper + enum class`
|
|
|
|
|
|
|
|
|
|
|
|
**源文件**: `editor/src/UI/BuiltInIcons.h`
|
|
|
|
|
|
|
2026-04-08 16:07:03 +08:00
|
|
|
|
**描述**: 为编辑器的资源树、资源网格和层级树提供内置图标枚举、初始化入口、统一图标绘制,以及轻量纹理预览缓存。
|
2026-03-29 01:36:53 +08:00
|
|
|
|
|
|
|
|
|
|
## 概述
|
|
|
|
|
|
|
|
|
|
|
|
`BuiltInIcons.h` 解决的不是“如何显示一张纹理”这个底层问题,而是“编辑器里哪些地方应该用统一图标语言表达文件夹、文件和场景对象”这个产品层问题。
|
|
|
|
|
|
|
|
|
|
|
|
当前源码里,这一层主要服务于三个界面:
|
|
|
|
|
|
|
|
|
|
|
|
- `HierarchyPanel` 通过 `GameObject` 图标给场景树节点补前缀。
|
|
|
|
|
|
- `ProjectPanel` 通过 `Folder` / `File` 图标绘制左侧目录树和右侧资源卡片。
|
|
|
|
|
|
- `ProjectActionRouter` 在拖拽预览等交互里复用同一套图标语义。
|
|
|
|
|
|
|
2026-04-08 16:07:03 +08:00
|
|
|
|
同时它现在还承担了一个额外职责:
|
|
|
|
|
|
|
|
|
|
|
|
- 为资源卡片提供异步缩略图预览入口 `DrawTextureAssetPreview(...)`
|
|
|
|
|
|
|
2026-03-29 01:36:53 +08:00
|
|
|
|
这和商业级编辑器常见的做法一致:业务面板不直接持有纹理资源,不自己决定某一类对象该显示什么图标,而是把“对象类别 -> 图标表现”的决定集中到一层共享 helper 中。这样做的好处是统一、可替换,而且不会让每个面板都自己重复写上传纹理、绘制 fallback 图形、适配尺寸的逻辑。
|
|
|
|
|
|
|
|
|
|
|
|
## 公开 API
|
|
|
|
|
|
|
|
|
|
|
|
| 成员 | 说明 |
|
|
|
|
|
|
|------|------|
|
2026-04-08 16:07:03 +08:00
|
|
|
|
| [AssetIconKind](AssetIconKind.md) | 定义当前编辑器可识别的内置图标类别。 |
|
|
|
|
|
|
| [InitializeBuiltInIcons](InitializeBuiltInIcons.md) | 初始化图标系统,上传内置图标并启动预览工作线程。 |
|
|
|
|
|
|
| [ShutdownBuiltInIcons](ShutdownBuiltInIcons.md) | 释放内置图标与预览缓存占用的 GPU / 后台资源。 |
|
|
|
|
|
|
| [DrawAssetIcon](DrawAssetIcon.md) | 在给定矩形内绘制指定类别的内置图标。 |
|
|
|
|
|
|
| [DrawTextureAssetPreview](DrawTextureAssetPreview.md) | 读取或异步准备资源缩略图,并在可用时直接绘制。 |
|
|
|
|
|
|
|
|
|
|
|
|
## 生命周期与公开入口
|
|
|
|
|
|
|
|
|
|
|
|
- [InitializeBuiltInIcons](InitializeBuiltInIcons.md)
|
|
|
|
|
|
- [ShutdownBuiltInIcons](ShutdownBuiltInIcons.md)
|
|
|
|
|
|
- [DrawAssetIcon](DrawAssetIcon.md)
|
|
|
|
|
|
- [DrawTextureAssetPreview](DrawTextureAssetPreview.md)
|
2026-03-29 01:36:53 +08:00
|
|
|
|
|
|
|
|
|
|
## 生命周期
|
|
|
|
|
|
|
|
|
|
|
|
- 这一层本质上是一个进程级的全局状态,当前实现通过匿名命名空间里的 `g_icons` 保存后端指针和已上传纹理。
|
|
|
|
|
|
- 正确顺序是先初始化 `ImGuiBackendBridge`,再调用 `InitializeBuiltInIcons(...)`。
|
|
|
|
|
|
- 关闭时应先停止使用这些图标,再调用 `ShutdownBuiltInIcons()`,最后销毁 ImGui 后端。
|
|
|
|
|
|
- 当前 `Application::InitializeImGui()` 和 `Application::Shutdown()` 已经按照这个顺序接线。
|
|
|
|
|
|
|
|
|
|
|
|
## 当前实现行为
|
|
|
|
|
|
|
|
|
|
|
|
按 `editor/src/UI/BuiltInIcons.cpp` 的实现,当前版本有几个值得明确写进文档的事实:
|
|
|
|
|
|
|
2026-04-08 16:07:03 +08:00
|
|
|
|
- `Folder`、`GameObject` 和 `Scene` 三类图标都会尝试从磁盘加载 PNG。
|
|
|
|
|
|
- 图标路径不是从项目目录查找,而是从可执行文件目录推导到:
|
|
|
|
|
|
- `../../resources/Icons/folder_icon.png`
|
|
|
|
|
|
- `../../resources/Icons/gameobject_icon.png`
|
|
|
|
|
|
- `../../resources/Icons/scene_icon.png`
|
|
|
|
|
|
- 图标上传路径目前只支持 D3D12,上传时会创建默认堆纹理、上传堆 buffer 和一次性命令列表;提交后通过 fence 跟踪完成状态,并把挂起 upload 保存在 `pendingIconUploads` 中。
|
2026-03-29 01:36:53 +08:00
|
|
|
|
- `File` 图标当前不是贴图资源,而是运行时用 `ImDrawList` 直接画出的简化文件形状。
|
2026-04-08 16:07:03 +08:00
|
|
|
|
- 如果 `Folder` / `GameObject` / `Scene` 的 PNG 加载失败,系统不会抛出错误或写日志;它会静默退回到程序化绘制的 fallback 图标。
|
|
|
|
|
|
- `DrawTextureAssetPreview(...)` 当前带有:
|
|
|
|
|
|
- 进程内预览缓存
|
|
|
|
|
|
- 后台解码 worker
|
|
|
|
|
|
- `.xceditor/thumbs/*.thumb` 磁盘缩略图缓存
|
|
|
|
|
|
- 每帧预览加载预算与缓存裁剪
|
2026-03-29 01:36:53 +08:00
|
|
|
|
|
|
|
|
|
|
这意味着它更接近“编辑器内部视觉资源辅助层”,而不是一个对外稳定暴露的通用图标资源系统。
|
|
|
|
|
|
|
|
|
|
|
|
## 设计说明
|
|
|
|
|
|
|
|
|
|
|
|
如果把它和 Unity 的使用体验类比,可以把这层理解成“轻量版的内建编辑器图标入口”。它的目标不是提供一个完整的图标数据库,而是确保最核心的编辑器对象类型在不同面板里看起来一致。
|
|
|
|
|
|
|
|
|
|
|
|
这样设计的收益是:
|
|
|
|
|
|
|
|
|
|
|
|
- 面板代码只关心“我要画文件夹图标”,而不关心纹理从哪里来。
|
|
|
|
|
|
- 资源加载失败时仍然有 fallback,不会导致整个面板失去可用性。
|
|
|
|
|
|
- 以后如果要统一替换图标风格,只需要改这一层,而不是同时改 `HierarchyPanel`、`ProjectPanel` 和拖拽预览逻辑。
|
|
|
|
|
|
|
|
|
|
|
|
代价也很明确:
|
|
|
|
|
|
|
|
|
|
|
|
- 当前实现和 D3D12 / ImGui 后端强绑定,还不是渲染后端无关的接口。
|
|
|
|
|
|
- 图标集合很小,只覆盖当前编辑器刚需。
|
|
|
|
|
|
- 路径解析和加载失败处理还比较工程化,不是面向内容制作流程的资源系统。
|
|
|
|
|
|
|
|
|
|
|
|
## 线程语义
|
|
|
|
|
|
|
|
|
|
|
|
- 这套 API 应被视为仅限编辑器 UI / 渲染线程使用。
|
2026-04-08 16:07:03 +08:00
|
|
|
|
- 初始化会触发 GPU 资源分配与命令提交;销毁阶段在后端对象齐全时还会显式等待队列空闲,因此都不适合在任意后台线程上调用。
|
2026-03-29 01:36:53 +08:00
|
|
|
|
- `DrawAssetIcon(...)` 依赖当前帧的 `ImDrawList` 和 ImGui 绘制上下文,也只能在 ImGui 绘制阶段调用。
|
|
|
|
|
|
|
|
|
|
|
|
## 典型用法
|
|
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
|
// 初始化阶段
|
|
|
|
|
|
m_imguiBackend.Initialize(...);
|
|
|
|
|
|
UI::InitializeBuiltInIcons(
|
|
|
|
|
|
m_imguiBackend,
|
|
|
|
|
|
m_windowRenderer.GetDevice(),
|
|
|
|
|
|
m_windowRenderer.GetCommandQueue());
|
|
|
|
|
|
|
|
|
|
|
|
// 面板绘制阶段
|
|
|
|
|
|
UI::DrawAssetIcon(
|
|
|
|
|
|
ImGui::GetWindowDrawList(),
|
|
|
|
|
|
iconMin,
|
|
|
|
|
|
iconMax,
|
|
|
|
|
|
UI::AssetIconKind::Folder);
|
|
|
|
|
|
|
|
|
|
|
|
// 关闭阶段
|
|
|
|
|
|
UI::ShutdownBuiltInIcons();
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 当前限制
|
|
|
|
|
|
|
|
|
|
|
|
- 当前只支持 D3D12 上传路径,没有 OpenGL / Vulkan / 软件后备实现。
|
2026-04-08 16:07:03 +08:00
|
|
|
|
- 内置图标种类固定为 `Folder`、`File`、`GameObject`、`Scene` 四类。
|
2026-03-29 01:36:53 +08:00
|
|
|
|
- 没有热重载、主题切换或 DPI 变体资源管理。
|
|
|
|
|
|
- 加载失败时以静默 fallback 为主,没有诊断级错误反馈。
|
|
|
|
|
|
|
|
|
|
|
|
## 相关文档
|
|
|
|
|
|
|
2026-04-08 16:07:03 +08:00
|
|
|
|
- [AssetIconKind](AssetIconKind.md)
|
|
|
|
|
|
- [InitializeBuiltInIcons](InitializeBuiltInIcons.md)
|
|
|
|
|
|
- [ShutdownBuiltInIcons](ShutdownBuiltInIcons.md)
|
|
|
|
|
|
- [DrawAssetIcon](DrawAssetIcon.md)
|
|
|
|
|
|
- [DrawTextureAssetPreview](DrawTextureAssetPreview.md)
|
2026-03-29 01:36:53 +08:00
|
|
|
|
- [UI](../UI.md)
|
|
|
|
|
|
- [StyleTokens](../StyleTokens/StyleTokens.md)
|
|
|
|
|
|
- [Application](../../Application/Application.md)
|
|
|
|
|
|
- [HierarchyPanel](../../panels/HierarchyPanel/HierarchyPanel.md)
|
|
|
|
|
|
- [ProjectPanel](../../panels/ProjectPanel/ProjectPanel.md)
|