Files
XCEngine/docs/api/XCEngine/Editor/UI/BuiltInIcons/BuiltInIcons.md
2026-03-29 01:36:53 +08:00

5.2 KiB
Raw Blame History

BuiltInIcons

命名空间: XCEngine::Editor::UI

类型: header-helper + enum class

源文件: editor/src/UI/BuiltInIcons.h

描述: 为编辑器的资源树、资源网格和层级树提供内置图标枚举、初始化入口与统一绘制函数。

概述

BuiltInIcons.h 解决的不是“如何显示一张纹理”这个底层问题,而是“编辑器里哪些地方应该用统一图标语言表达文件夹、文件和场景对象”这个产品层问题。

当前源码里,这一层主要服务于三个界面:

  • HierarchyPanel 通过 GameObject 图标给场景树节点补前缀。
  • ProjectPanel 通过 Folder / File 图标绘制左侧目录树和右侧资源卡片。
  • ProjectActionRouter 在拖拽预览等交互里复用同一套图标语义。

这和商业级编辑器常见的做法一致:业务面板不直接持有纹理资源,不自己决定某一类对象该显示什么图标,而是把“对象类别 -> 图标表现”的决定集中到一层共享 helper 中。这样做的好处是统一、可替换,而且不会让每个面板都自己重复写上传纹理、绘制 fallback 图形、适配尺寸的逻辑。

公开 API

成员 说明
enum class AssetIconKind { Folder, File, GameObject } 定义当前编辑器可识别的内置图标类别。
InitializeBuiltInIcons(ImGuiBackendBridge&, ID3D12Device*, ID3D12CommandQueue*) 初始化图标系统,上传贴图并分配 ImGui 可见的 SRV 描述符。
ShutdownBuiltInIcons() 释放内置图标占用的 GPU 资源与描述符。
DrawAssetIcon(ImDrawList*, const ImVec2& min, const ImVec2& max, AssetIconKind) 在给定矩形内绘制指定类别的图标。

生命周期

  • 这一层本质上是一个进程级的全局状态,当前实现通过匿名命名空间里的 g_icons 保存后端指针和已上传纹理。
  • 正确顺序是先初始化 ImGuiBackendBridge,再调用 InitializeBuiltInIcons(...)
  • 关闭时应先停止使用这些图标,再调用 ShutdownBuiltInIcons(),最后销毁 ImGui 后端。
  • 当前 Application::InitializeImGui()Application::Shutdown() 已经按照这个顺序接线。

当前实现行为

editor/src/UI/BuiltInIcons.cpp 的实现,当前版本有几个值得明确写进文档的事实:

  • 只有 FolderGameObject 两类图标会尝试从磁盘加载 PNG。
  • 图标路径不是从项目目录查找,而是从可执行文件目录推导到 ../../resources/Icons/folder_icon.png../../resources/Icons/gameobject_icon.png
  • 贴图上传路径目前只支持 D3D12上传时会创建默认堆纹理、上传堆 buffer、一次性命令列表并在结束后主动等待命令队列空闲。
  • File 图标当前不是贴图资源,而是运行时用 ImDrawList 直接画出的简化文件形状。
  • 如果 Folder / GameObject 的 PNG 加载失败,系统不会抛出错误或写日志;它会静默退回到程序化绘制的 fallback 图标。

这意味着它更接近“编辑器内部视觉资源辅助层”,而不是一个对外稳定暴露的通用图标资源系统。

设计说明

如果把它和 Unity 的使用体验类比,可以把这层理解成“轻量版的内建编辑器图标入口”。它的目标不是提供一个完整的图标数据库,而是确保最核心的编辑器对象类型在不同面板里看起来一致。

这样设计的收益是:

  • 面板代码只关心“我要画文件夹图标”,而不关心纹理从哪里来。
  • 资源加载失败时仍然有 fallback不会导致整个面板失去可用性。
  • 以后如果要统一替换图标风格,只需要改这一层,而不是同时改 HierarchyPanelProjectPanel 和拖拽预览逻辑。

代价也很明确:

  • 当前实现和 D3D12 / ImGui 后端强绑定,还不是渲染后端无关的接口。
  • 图标集合很小,只覆盖当前编辑器刚需。
  • 路径解析和加载失败处理还比较工程化,不是面向内容制作流程的资源系统。

线程语义

  • 这套 API 应被视为仅限编辑器 UI / 渲染线程使用。
  • 初始化和销毁会触发 GPU 资源分配、命令提交与队列等待,不适合在任意后台线程上调用。
  • DrawAssetIcon(...) 依赖当前帧的 ImDrawList 和 ImGui 绘制上下文,也只能在 ImGui 绘制阶段调用。

典型用法

// 初始化阶段
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 / 软件后备实现。
  • 图标种类固定为 FolderFileGameObject 三类。
  • 没有热重载、主题切换或 DPI 变体资源管理。
  • 加载失败时以静默 fallback 为主,没有诊断级错误反馈。

相关文档