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

5.4 KiB
Raw Blame History

ProjectPanel

命名空间: XCEngine::Editor

类型: class

源文件: editor/src/panels/ProjectPanel.h

描述: 编辑器项目资源浏览面板,负责目录树、面包屑、搜索框、资源卡片和拖放交互的前端呈现。

概述

ProjectPanel 是当前 Editor 中最接近“资源浏览器”的面板。它本身不维护项目资源数据库,而是把 IProjectManager 暴露的数据模型转成一个典型的双栏浏览界面:

  • 左侧是目录树导航。
  • 右侧是当前目录的资源浏览区。
  • 顶部是搜索框与面包屑。

如果和 Unity 对照,可以把它理解成一个更轻量、当前聚焦于基础浏览和拖放的 Project Browser。

当前实现行为

editor/src/panels/ProjectPanel.cpp 的实现:

  • Initialize(projectPath) 直接委托给 m_context->GetProjectManager().Initialize(projectPath)
  • Render() 会:
    • 建立标准 PanelWindowScope
    • 把焦点动作路由标记为 EditorActionRoute::Project
    • 先渲染 toolbar。
    • 再创建左右分栏内容区。
    • 使用 UI::DrawSplitter(...) 支持调整左侧导航栏宽度。
    • 收尾时绘制“新建文件夹”对话框。

当前导航栏宽度会被显式夹紧在一个合理范围内:

  • 最小值来自 ProjectNavigationMinWidth()
  • 右侧浏览区最小宽度来自 ProjectBrowserMinWidth()

这说明当前实现已经从一开始就按“可调整工作区”的编辑器思路组织,而不是固定死尺寸。

左侧目录树

左侧目录树是当前 ProjectPanel 最典型的共享 UI 基建使用者之一:

  • 根节点来自 IProjectManager::GetRootFolder()
  • 当前目录来自 IProjectManager::GetCurrentFolder()
  • 每个目录节点都通过 UI::DrawTreeNode(...) 绘制。
  • 节点样式使用 UI::ProjectFolderTreeStyle()
  • 节点前缀使用 UI::DrawAssetIcon(..., AssetIconKind::Folder)
  • defaultOpen 会根据 IsCurrentTreeBranch(...) 判断当前目录是否位于该目录分支下。
  • 展开状态保存在 m_folderTreeState 中。

用户单击树节点时,会立即调用 manager.NavigateToFolder(folder) 完成导航;右键则通过 Actions::HandleProjectItemContextRequest(...) 打开对应上下文菜单。

右侧浏览区

右侧浏览区分成两层:

  • Header显示面包屑导航并在底部画一条 divider。
  • Body以资源网格形式显示当前目录下通过搜索过滤后的条目。

资源卡片当前通过 UI::DrawAssetTile(...) 绘制,并根据 item->isFolder 区分:

  • Folder 图标
  • File 图标

交互结果统一收集到 AssetItemInteraction 中,再在循环结束后统一处理。这种写法有一个很实用的好处:可以避免在绘制过程中直接修改当前迭代容器或导航状态,让即时模式 UI 代码更稳定。

搜索与导航

当前搜索实现比较明确,也需要在文档里写清楚:

  • 搜索框位于 toolbar 右侧。
  • 搜索只对 manager.GetCurrentItems() 返回的当前目录条目生效。
  • 匹配逻辑是大小写不敏感的子串匹配。
  • 当前没有全文索引、标签过滤或类型过滤。

面包屑则通过 UI::DrawToolbarBreadcrumbs(...) 实现,点击非当前段会调用 manager.NavigateToIndex(index)

拖放与上下文菜单

当前 ProjectPanel 并不自己实现拖放协议和命令执行,而是按职责分层调用其他模块:

  • Actions::BeginProjectAssetDrag(item, iconKind) 负责发起拖拽源。
  • Actions::AcceptProjectAssetDropPayload(item) 负责检测是否有资源被拖到当前目标上。
  • 若确实发生移动,则调用 Commands::MoveAssetToFolder(...)
  • 右键菜单与空白区域菜单由 Actions::*ContextPopup(...) 系列 helper 负责绘制。

这种组织方式和 HierarchyPanel 一样,遵循的是“面板负责展示与采样,动作层 / 命令层负责实际编辑行为”的编辑器架构。

生命周期与线程语义

  • 面板本身持有的是 UI 状态:搜索文本、导航栏宽度、目录树展开状态、弹窗状态。
  • 真实项目数据由 IProjectManager 持有。
  • 整套逻辑应视为编辑器 UI 主线程代码。

设计说明

当前 ProjectPanel 的设计方向是合理的,因为它先把“资源浏览器”拆成几个稳定的基础体验单元:

  • 分栏布局
  • 目录树
  • 面包屑
  • 资源网格
  • 拖放与上下文菜单

这样做的好处是,后续无论是加缩略图、资源导入器状态、筛选器还是收藏夹,都可以在现有骨架上演进,而不是推倒重来。

当前限制

  • 搜索只在当前目录里做前端子串过滤,不是全项目索引搜索。
  • 当前没有资源缩略图生成或异步预览系统,图标仍以 BuiltInIcons 和简单卡片为主。
  • 文件树展开状态只保存在内存中,不会自动跨重启恢复。
  • 拖放移动是直接命令式处理,没有更复杂的批处理或事务预览。

相关文档