docs: add Editor API documentation
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
# ActionBinding
|
||||
|
||||
**命名空间**: `XCEngine::Editor::Actions`
|
||||
|
||||
**类型**: `header utility set`
|
||||
|
||||
**源文件**: `editor/src/Actions/ActionBinding.h`
|
||||
|
||||
**描述**: 定义快捷键和 UI 动作绑定数据结构,并提供菜单、按钮和快捷键处理辅助函数。
|
||||
|
||||
## 概述
|
||||
|
||||
`ActionBinding.h` 当前不是单一 class,而是一组围绕动作绑定组织起来的轻量工具:
|
||||
|
||||
- `ShortcutChord`
|
||||
- `ShortcutRoute`
|
||||
- `ShortcutContext`
|
||||
- `ActionBinding`
|
||||
- 一系列 `Shortcut(...)` / `MakeAction(...)` / `Draw*Action(...)` / `HandleShortcut(...)` 辅助函数
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- 一个 `ActionBinding` 最多保存两个快捷键 chord。
|
||||
- `ShortcutContext` 当前支持 `Global` 和 `FocusedWindow` 两种上下文。
|
||||
- `MakeAction()` 用来快速构造动作描述对象。
|
||||
- `DrawMenuAction()` / `DrawButtonAction()` / `DrawInspectorAction()` / `DrawToolbarAction()` 等函数把动作直接映射成 UI 绘制。
|
||||
- `HandleShortcut()` 则把动作和快捷键触发逻辑连起来。
|
||||
|
||||
## 设计说明
|
||||
|
||||
这类做法很像商业工具链里常见的 command metadata + shortcut binding 层:
|
||||
|
||||
- 动作有 label、shortcut、enabled、selected 等状态
|
||||
- UI 表现和实际执行函数分离
|
||||
- 快捷键逻辑能复用在菜单、按钮和工具栏上
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 当前快捷键判断直接基于 ImGui input state。
|
||||
- 当前没有统一的命令注册表或可重绑定快捷键配置系统。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Actions](../Actions.md)
|
||||
- [UI](../../UI/UI.md)
|
||||
- [SceneCommands](../../Commands/SceneCommands/SceneCommands.md)
|
||||
@@ -0,0 +1,50 @@
|
||||
# ActionRouting
|
||||
|
||||
**命名空间**: `XCEngine::Editor::Actions`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/Actions/ActionRouting.h`
|
||||
|
||||
**描述**: 根据当前 ImGui 窗口焦点更新 `EditorActionRoute`,让 Edit 菜单和快捷键知道“当前应该作用于哪个面板”。
|
||||
|
||||
## 概述
|
||||
|
||||
`ActionRouting.h` 提供的是一组很小但很关键的粘合函数:
|
||||
|
||||
- `ObserveFocusedActionRoute` 在当前窗口获得根窗口焦点时,把上下文的活动路由设置为指定值
|
||||
- `ObserveInactiveActionRoute` 把活动路由显式重置为 `EditorActionRoute::None`
|
||||
- `IsActionRouteActive` 用于查询当前路由
|
||||
|
||||
这层设计的意义,不是再造一套复杂命令系统,而是把“UI 焦点”翻译成“编辑目标”。这样 `ProjectPanel` 获得焦点时,`Delete` 可以删除资源;`HierarchyPanel` 获得焦点时,同样的按键变成删除实体。
|
||||
|
||||
## 当前实现
|
||||
|
||||
- 路由判断直接依赖 `ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows)`
|
||||
- 没有独立的焦点管理器,也没有优先级仲裁器
|
||||
- 当前只有 `Hierarchy`、`Project` 和 `None` 三种路由状态
|
||||
- `HierarchyPanel` 与 `ProjectPanel` 会设置显式路由;`InspectorPanel` 与 `ConsolePanel` 当前会调用 `ObserveInactiveActionRoute`
|
||||
|
||||
## 设计说明
|
||||
|
||||
这是一种很典型的商业编辑器做法:把“全局 Edit 菜单”做成上下文敏感,而不是把复制、粘贴、删除分别硬编码进每个面板。
|
||||
相对 Unity、Unreal 这类编辑器,这里的实现还很轻量,但方向是一致的:
|
||||
|
||||
- 面板负责声明自己何时成为当前编辑目标
|
||||
- `EditActionRouter` 负责根据当前目标解析动作
|
||||
- `Commands` 层负责真正落地状态变更
|
||||
|
||||
这样拆开以后,快捷键、菜单栏和右键菜单可以共享同一套行为,不容易出现同一操作在不同入口行为不一致的问题。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 焦点路由完全依赖 ImGui 窗口焦点,尚未覆盖更细粒度的控件级编辑上下文
|
||||
- `Inspector` 尚未注册独立路由,因此它不会接管全局 Edit 行为
|
||||
- 没有多窗口、多文档或浮动工具窗之间的冲突处理策略
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Actions](../Actions.md)
|
||||
- [EditorActions](../EditorActions/EditorActions.md)
|
||||
- [EditActionRouter](../EditActionRouter/EditActionRouter.md)
|
||||
- [EditorActionRoute](../../Core/EditorActionRoute/EditorActionRoute.md)
|
||||
37
docs/api/XCEngine/Editor/Actions/Actions.md
Normal file
37
docs/api/XCEngine/Editor/Actions/Actions.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# Actions
|
||||
|
||||
**命名空间**: `XCEngine::Editor::Actions`
|
||||
|
||||
**类型**: `submodule`
|
||||
|
||||
**描述**: 编辑器动作与快捷键绑定层,连接菜单、按钮、工具栏和快捷键触发逻辑。
|
||||
|
||||
## 概述
|
||||
|
||||
`Actions` 子模块当前承担的是“UI 交互元素如何对应到一个可执行动作”的抽象。
|
||||
|
||||
已文档化的核心页面:
|
||||
|
||||
- [ActionBinding](ActionBinding/ActionBinding.md)
|
||||
- [EditorActions](EditorActions/EditorActions.md)
|
||||
- [ActionRouting](ActionRouting/ActionRouting.md)
|
||||
- [EditActionRouter](EditActionRouter/EditActionRouter.md)
|
||||
- [MainMenuActionRouter](MainMenuActionRouter/MainMenuActionRouter.md)
|
||||
- [HierarchyActionRouter](HierarchyActionRouter/HierarchyActionRouter.md)
|
||||
- [ProjectActionRouter](ProjectActionRouter/ProjectActionRouter.md)
|
||||
- [InspectorActionRouter](InspectorActionRouter/InspectorActionRouter.md)
|
||||
- [ConsoleActionRouter](ConsoleActionRouter/ConsoleActionRouter.md)
|
||||
|
||||
它们共同构成当前编辑器的动作分层:
|
||||
|
||||
- `EditorActions` 定义动作标签、快捷键和启用条件
|
||||
- `ActionRouting` 声明当前哪个面板拥有编辑焦点
|
||||
- 各种 `*ActionRouter` 把菜单、按钮、快捷键翻译成具体命令或事件
|
||||
|
||||
这种组织方式和商业编辑器常见的 context-sensitive edit menu 思路一致,能避免相同行为在多个 UI 入口里各自实现一遍。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Editor 模块](../Editor.md)
|
||||
- [Commands](../Commands/Commands.md)
|
||||
- [UI](../UI/UI.md)
|
||||
@@ -0,0 +1,48 @@
|
||||
# ConsoleActionRouter
|
||||
|
||||
**命名空间**: `XCEngine::Editor::Actions`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/Actions/ConsoleActionRouter.h`
|
||||
|
||||
**描述**: 为 Console 面板提供工具栏动作和日志列表绘制逻辑。
|
||||
|
||||
## 概述
|
||||
|
||||
`ConsoleActionRouter` 目前主要负责两件事:
|
||||
|
||||
- `DrawConsoleToolbarActions` 绘制清空按钮和 Info / Warn / Error 过滤切换
|
||||
- `DrawConsoleLogRows` 读取 `EditorConsoleSink` 中的日志,并按过滤条件输出到面板
|
||||
|
||||
`ConsolePanel.cpp` 只负责搭窗口和滚动区域,真正的交互逻辑由这层统一承接。这样 Console 面板本身会保持很薄,不会把过滤策略、日志格式化和按钮语义都堆在一个类里。
|
||||
|
||||
## 当前实现
|
||||
|
||||
- 数据源固定为 [`EditorConsoleSink`](../../Core/EditorConsoleSink/EditorConsoleSink.md)
|
||||
- 过滤状态由 [`ConsoleFilterState`](../../UI/ConsoleFilterState/ConsoleFilterState.md) 持有
|
||||
- 每条日志通过 [`BuildConsoleLogText`](../../UI/ConsoleLogFormatter/ConsoleLogFormatter.md) 生成展示字符串
|
||||
- 点击日志行时会把完整字符串复制到剪贴板
|
||||
|
||||
## 设计说明
|
||||
|
||||
这层拆分的价值在于把“日志存储”和“日志呈现”分开:
|
||||
|
||||
- `EditorConsoleSink` 关注线程安全和日志缓存
|
||||
- `ConsoleActionRouter` 关注工具栏与列表交互
|
||||
- `UI` 辅助函数负责外观和文本格式
|
||||
|
||||
这种分层比直接在 `ConsolePanel::Render` 中处理全部逻辑更容易维护,也更接近商业级编辑器里常见的 presenter / controller 风格。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 当前过滤粒度只有三档:信息、警告、错误
|
||||
- 没有搜索、分类树、时间戳列或堆栈追踪展开
|
||||
- `GetLogs()` 会复制整个日志数组,日志量继续增大后可能需要增量视图或虚拟列表
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Actions](../Actions.md)
|
||||
- [ConsolePanel](../../panels/ConsolePanel/ConsolePanel.md)
|
||||
- [EditorConsoleSink](../../Core/EditorConsoleSink/EditorConsoleSink.md)
|
||||
- [ConsoleFilterState](../../UI/ConsoleFilterState/ConsoleFilterState.md)
|
||||
@@ -0,0 +1,51 @@
|
||||
# EditActionRouter
|
||||
|
||||
**命名空间**: `XCEngine::Editor::Actions`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/Actions/EditActionRouter.h`
|
||||
|
||||
**描述**: 把全局 Edit 菜单和快捷键解析为上下文敏感的实体编辑或资源编辑动作。
|
||||
|
||||
## 概述
|
||||
|
||||
`EditActionRouter` 是当前编辑器“上下文式编辑命令”的核心桥接层。它先通过 `ResolveEditActionTarget` 读取:
|
||||
|
||||
- 当前活动路由 `EditorActionRoute`
|
||||
- 当前选中的实体
|
||||
- 当前选中的资源项
|
||||
|
||||
然后再决定 `Open`、`Delete`、`Rename`、`Copy`、`Paste`、`Duplicate`、`Navigate Back` 这些动作是否可用,以及真正应该调用哪个 `Commands` 函数。
|
||||
|
||||
## 当前实现
|
||||
|
||||
- `Project` 路由下,编辑动作主要映射到 [`ProjectCommands`](../../Commands/ProjectCommands/ProjectCommands.md)
|
||||
- `Hierarchy` 路由下,编辑动作主要映射到 [`EntityCommands`](../../Commands/EntityCommands/EntityCommands.md)
|
||||
- `HandleEditShortcuts` 统一处理快捷键
|
||||
- `DrawEditActions` 统一绘制菜单项
|
||||
- `Undo` / `Redo` 由当前上下文的 `IUndoManager` 直接提供
|
||||
|
||||
`EditActionTarget` 本身是一个轻量快照结构,不持有复杂状态,也不缓存引用生命周期。
|
||||
|
||||
## 设计说明
|
||||
|
||||
很多编辑器最容易退化的地方,就是每个面板各写一套删除、复制、粘贴逻辑。
|
||||
`EditActionRouter` 的作用正好相反:它把不同面板共享的“编辑语义”集中到一处,只把具体数据对象交给路由判断。
|
||||
|
||||
这和 Unity 菜单栏的思路很接近:同一个 `Delete` 菜单项,在不同焦点上下文里对应不同对象,但用户感知到的是统一操作。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- `Cut` 仍然是禁用占位动作,没有真正实现
|
||||
- `Inspector` 没有独立路由,因此不会接管复制粘贴等全局编辑行为
|
||||
- `Paste` 当前只在 Hierarchy 路由下生效,不支持资源粘贴
|
||||
- 没有多选批处理版本的删除、复制与重命名
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Actions](../Actions.md)
|
||||
- [ActionRouting](../ActionRouting/ActionRouting.md)
|
||||
- [EditorActions](../EditorActions/EditorActions.md)
|
||||
- [EntityCommands](../../Commands/EntityCommands/EntityCommands.md)
|
||||
- [ProjectCommands](../../Commands/ProjectCommands/ProjectCommands.md)
|
||||
@@ -0,0 +1,59 @@
|
||||
# EditorActions
|
||||
|
||||
**命名空间**: `XCEngine::Editor::Actions`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/Actions/EditorActions.h`
|
||||
|
||||
**描述**: 定义编辑器中可复用的动作描述,包括菜单标题、快捷键、启用状态和选中项解析辅助函数。
|
||||
|
||||
## 概述
|
||||
|
||||
`EditorActions.h` 并不直接执行命令,它负责生产 [`ActionBinding`](../ActionBinding/ActionBinding.md)。
|
||||
|
||||
当前文件中的动作工厂可以分成几类:
|
||||
|
||||
- 场景级动作:`MakeNewSceneAction`、`MakeOpenSceneAction`、`MakeSaveSceneAction`
|
||||
- 编辑级动作:`MakeUndoAction`、`MakeRedoAction`、`MakeCopyEntityAction`、`MakePasteEntityAction`
|
||||
- 层级面板动作:`MakeCreateChildEntityAction`、`MakeDetachEntityAction`
|
||||
- 项目面板动作:`MakeNavigateBackAction`、`MakeOpenAssetAction`、`MakeCreateFolderAction`
|
||||
- Inspector / Console 动作:`MakeAddComponentButtonAction`、`MakeRemoveComponentAction`、`MakeClearConsoleAction`
|
||||
|
||||
此外它还提供:
|
||||
|
||||
- `GetSelectedGameObject`
|
||||
- `GetSelectedAssetItem`
|
||||
|
||||
用于把当前上下文解析为后续路由与命令层需要的对象。
|
||||
|
||||
## 当前实现
|
||||
|
||||
- 动作标签、快捷键文本和 `ImGuiKey` 触发条件都集中写在这里
|
||||
- `Undo` / `Redo` 标签会根据 `IUndoManager` 动态显示历史项名称
|
||||
- `Paste`、`Delete`、`Duplicate` 等动作会根据当前选择动态启用或禁用
|
||||
- 资源选择解析依赖 `IProjectManager::GetSelectedIndex()` 和 `GetCurrentItems()`
|
||||
|
||||
## 设计说明
|
||||
|
||||
把动作描述统一集中,是商业编辑器里常见的稳定做法。
|
||||
原因很直接:
|
||||
|
||||
- 菜单栏、工具栏、右键菜单、快捷键需要共享同一组语义
|
||||
- “名称、快捷键、是否可用” 应该只有一个权威来源
|
||||
- 如果动作定义分散在各个面板里,最终会出现文本不一致、快捷键冲突和启用逻辑漂移
|
||||
|
||||
所以 `EditorActions` 更像编辑器的“动作字典”,而 `ActionRouter` 是“动作分发器”,`Commands` 则是“真正执行业务变更的地方”。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 动作仍然以手写 inline 工厂为主,尚未发展成可注册、可枚举的统一 action registry
|
||||
- 没有本地化层,标签文本直接写死为英文
|
||||
- 资源动作当前只覆盖文件夹导航和场景资源打开
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Actions](../Actions.md)
|
||||
- [ActionBinding](../ActionBinding/ActionBinding.md)
|
||||
- [EditActionRouter](../EditActionRouter/EditActionRouter.md)
|
||||
- [MainMenuActionRouter](../MainMenuActionRouter/MainMenuActionRouter.md)
|
||||
@@ -0,0 +1,51 @@
|
||||
# HierarchyActionRouter
|
||||
|
||||
**命名空间**: `XCEngine::Editor::Actions`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/Actions/HierarchyActionRouter.h`
|
||||
|
||||
**描述**: 封装 Hierarchy 面板中的选中、重命名、拖拽重挂接、排序和上下文菜单动作。
|
||||
|
||||
## 概述
|
||||
|
||||
`HierarchyActionRouter` 是当前实体层级树交互的主要承载者。它把 `HierarchyPanel.cpp` 中最容易膨胀的逻辑拆成了几类可复用动作:
|
||||
|
||||
- 选择与背景点击清空选择
|
||||
- 实体重命名请求与提交
|
||||
- 拖拽实体到其他父节点或根节点
|
||||
- 创建 / 删除 / 复制 / 粘贴 / 重复实体
|
||||
- 排序选项弹窗
|
||||
|
||||
## 当前实现
|
||||
|
||||
- 拖拽载荷类型固定为字符串 `"ENTITY_PTR"`
|
||||
- `HandleHierarchySelectionClick` 只实现了单选和 Ctrl 增选
|
||||
- `CommitEntityRename` 会先验证实体存在且名字非空,再调用 [`RenameEntity`](../../Commands/EntityCommands/EntityCommands.md)
|
||||
- 拖拽重挂接时会调用 `Commands::CanReparentEntity` 和 `ReparentEntityPreserveWorldTransform`
|
||||
- 背景右键菜单可以直接创建空物体、Camera、Light,以及命名为 `Cube` / `Sphere` / `Plane` 的空实体
|
||||
|
||||
## 设计说明
|
||||
|
||||
这类层级树交互通常非常碎,如果全写在面板类里,后续一加多选、拖放规则或菜单项就会迅速失控。
|
||||
把交互逻辑集中在 router 里有三个好处:
|
||||
|
||||
- 面板类仍然只负责树结构遍历和 UI 布局
|
||||
- 所有入口都能复用同一套实体命令
|
||||
- 可以明确把“层级树交互规则”与“SceneManager 真正修改场景”的职责隔开
|
||||
|
||||
这和 Unity Hierarchy 的设计也比较接近:Hierarchy 面板只是入口,真正的数据修改要落到场景编辑命令层。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 暂不支持多实体批量拖拽
|
||||
- 只有 `Ctrl` 增选,没有框选、Shift 范围选中等高级交互
|
||||
- `Cube` / `Sphere` / `Plane` 当前只是命名约定,不会自动附加网格或渲染组件
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Actions](../Actions.md)
|
||||
- [HierarchyPanel](../../panels/HierarchyPanel/HierarchyPanel.md)
|
||||
- [EntityCommands](../../Commands/EntityCommands/EntityCommands.md)
|
||||
- [EditorEvents](../../Core/EditorEvents/EditorEvents.md)
|
||||
@@ -0,0 +1,50 @@
|
||||
# InspectorActionRouter
|
||||
|
||||
**命名空间**: `XCEngine::Editor::Actions`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/Actions/InspectorActionRouter.h`
|
||||
|
||||
**描述**: 为 Inspector 面板封装组件添加、组件菜单和交互式撤销收尾逻辑。
|
||||
|
||||
## 概述
|
||||
|
||||
`InspectorActionRouter` 把 Inspector 面板里最核心的交互从 `InspectorPanel` 中抽离出来:
|
||||
|
||||
- 选中对象变化时重置弹窗状态
|
||||
- 绘制 “Add Component” 按钮与弹窗
|
||||
- 遍历注册的组件编辑器,生成添加菜单
|
||||
- 绘制组件右上角菜单中的 “Remove Component”
|
||||
- 在控件停止交互后,结束交互式撤销录制
|
||||
|
||||
## 当前实现
|
||||
|
||||
- `HandleInspectorSelectionChanged` 会在切换选中对象时主动结束未完成的交互式改动
|
||||
- 组件添加菜单依赖 [`ComponentEditorRegistry`](../../ComponentEditors/ComponentEditorRegistry/ComponentEditorRegistry.md)
|
||||
- 如果没有任何注册 editor,弹窗会显示 “No registered component editors”
|
||||
- `FinalizeInspectorInteractiveChangeIfIdle` 通过 `ImGui::IsAnyItemActive()` 判断当前是否仍在拖拽或编辑
|
||||
|
||||
## 设计说明
|
||||
|
||||
Inspector 是最容易把 UI、数据绑定、撤销系统缠在一起的地方。
|
||||
当前设计明确把职责拆开:
|
||||
|
||||
- `IComponentEditor` 负责某个组件的字段 UI
|
||||
- `InspectorActionRouter` 负责 Inspector 面板级别的交互
|
||||
- `ComponentCommands` 负责真正添加/删除组件并写入撤销
|
||||
|
||||
这比把 “Add Component” 和 “Remove Component” 直接嵌进每个组件 editor 更稳定,也更容易在后续演进到搜索、分类和脚本组件等复杂场景。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 添加组件菜单尚无搜索框与分类树
|
||||
- 组件排序、拖拽重排还没有实现
|
||||
- 当前删除组件只依赖 editor 的 `CanRemove` 规则,没有更高层的依赖分析
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Actions](../Actions.md)
|
||||
- [InspectorPanel](../../panels/InspectorPanel/InspectorPanel.md)
|
||||
- [ComponentCommands](../../Commands/ComponentCommands/ComponentCommands.md)
|
||||
- [ComponentEditorRegistry](../../ComponentEditors/ComponentEditorRegistry/ComponentEditorRegistry.md)
|
||||
@@ -0,0 +1,52 @@
|
||||
# MainMenuActionRouter
|
||||
|
||||
**命名空间**: `XCEngine::Editor::Actions`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/Actions/MainMenuActionRouter.h`
|
||||
|
||||
**描述**: 实现主菜单栏的文件、编辑、视图、帮助菜单,以及相应的全局快捷键和弹窗入口。
|
||||
|
||||
## 概述
|
||||
|
||||
`MainMenuActionRouter` 是 `MenuBar` 面板背后的实际逻辑层。当前它负责:
|
||||
|
||||
- 新建、打开、保存场景
|
||||
- 撤销与重做
|
||||
- 请求退出编辑器
|
||||
- 请求重置 Dock 布局
|
||||
- 打开 About 弹窗
|
||||
- 在菜单栏右侧绘制当前场景状态
|
||||
|
||||
## 当前实现
|
||||
|
||||
- `ExecuteNewScene` / `ExecuteOpenScene` / `ExecuteSaveScene` 最终调用 [`SceneCommands`](../../Commands/SceneCommands/SceneCommands.md)
|
||||
- `RequestEditorExit` 发布 `EditorExitRequestedEvent`
|
||||
- `RequestDockLayoutReset` 发布 `DockLayoutResetRequestedEvent`
|
||||
- `RequestAboutPopup` 通过 [`DeferredPopupState`](../../UI/PopupState/PopupState.md) 延迟打开 About 对话框
|
||||
- `HandleMenuBarShortcuts` 目前使用 `GlobalShortcutContext()`
|
||||
|
||||
`MenuBar.cpp` 的 `Render()` 顺序也比较清晰:先处理快捷键,再绘制菜单栏,最后绘制弹窗覆盖层。
|
||||
|
||||
## 设计说明
|
||||
|
||||
把主菜单作为单独 router,而不是直接在 `MenuBar::Render` 里写一大串 `ImGui::MenuItem`,有两个明显收益:
|
||||
|
||||
- 菜单项逻辑可以和命令层、事件总线清晰对接
|
||||
- 快捷键和菜单点击能共享同一套执行入口
|
||||
|
||||
这正是商业编辑器常见的菜单层设计方式。菜单不是业务逻辑本体,它只是统一入口。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 文件菜单当前只覆盖场景级工作流,没有项目级导入、构建或设置入口
|
||||
- About 弹窗内容仍然是开发中状态说明,不是正式产品级信息页
|
||||
- 全局快捷键冲突处理比较简单,尚未提供用户可配置热键系统
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Actions](../Actions.md)
|
||||
- [MenuBar](../../panels/MenuBar/MenuBar.md)
|
||||
- [SceneCommands](../../Commands/SceneCommands/SceneCommands.md)
|
||||
- [PopupState](../../UI/PopupState/PopupState.md)
|
||||
@@ -0,0 +1,52 @@
|
||||
# ProjectActionRouter
|
||||
|
||||
**命名空间**: `XCEngine::Editor::Actions`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/Actions/ProjectActionRouter.h`
|
||||
|
||||
**描述**: 封装 Project 面板中的资源选择、导航、拖放、上下文菜单和创建文件夹弹窗流程。
|
||||
|
||||
## 概述
|
||||
|
||||
`ProjectActionRouter` 让 `ProjectPanel.cpp` 可以专注于资源网格布局,而把交互行为集中管理。当前覆盖的能力包括:
|
||||
|
||||
- 资源项选中与右键上下文菜单
|
||||
- 文件夹打开与返回上级导航
|
||||
- 资源拖放到目录
|
||||
- 空白区域上下文菜单
|
||||
- “Create Folder” 弹窗与提交
|
||||
|
||||
## 当前实现
|
||||
|
||||
- 资源拖拽载荷类型固定为 `"ASSET_ITEM"`
|
||||
- 打开资源时只支持两类:文件夹与 `type == "Scene"` 的资源
|
||||
- 删除资源调用 [`DeleteAsset`](../../Commands/ProjectCommands/ProjectCommands.md)
|
||||
- 移动资源调用 `MoveAssetToFolder`
|
||||
- 创建目录弹窗依赖 [`TextInputPopupState`](../../UI/PopupState/PopupState.md)
|
||||
|
||||
`FindProjectItemIndex` 还额外做了 `fullPath` 匹配,这说明当前实现允许在某些刷新路径下通过值语义重新定位资源项,而不是完全依赖共享指针地址。
|
||||
|
||||
## 设计说明
|
||||
|
||||
Project 面板本质上是一个资产浏览器。
|
||||
把这些动作单独放在 router 层,有助于把以下两类变化隔开:
|
||||
|
||||
- 视觉变化:列表改网格、加图标、加搜索、加分栏
|
||||
- 交互语义变化:打开、删除、移动、创建目录
|
||||
|
||||
这样后续即使 Project 面板彻底重画 UI,动作语义仍然可以稳定保留。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 当前资源系统没有更细的资源类型分发,场景之外的资源多数只能展示,不能打开
|
||||
- 资源重命名、复制、粘贴尚未实现
|
||||
- 没有回收站、删除确认和批量操作
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Actions](../Actions.md)
|
||||
- [ProjectPanel](../../panels/ProjectPanel/ProjectPanel.md)
|
||||
- [ProjectCommands](../../Commands/ProjectCommands/ProjectCommands.md)
|
||||
- [PopupState](../../UI/PopupState/PopupState.md)
|
||||
56
docs/api/XCEngine/Editor/Application/Application.md
Normal file
56
docs/api/XCEngine/Editor/Application/Application.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Application
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class (singleton)`
|
||||
|
||||
**源文件**: `editor/src/Application.h`
|
||||
|
||||
**描述**: 编辑器应用主入口,负责窗口渲染器、ImGui 后端、LayerStack 和 `EditorContext` 的初始化、渲染与关闭。
|
||||
|
||||
## 概述
|
||||
|
||||
`Application` 是当前编辑器应用真正的壳层对象。
|
||||
|
||||
它负责把几类本来分散的系统拼成一个可运行编辑器:
|
||||
|
||||
- Win32 宿主窗口句柄
|
||||
- [Platform::D3D12WindowRenderer](../Platform/D3D12WindowRenderer/D3D12WindowRenderer.md)
|
||||
- [UI::ImGuiSession](../UI/ImGuiSession/ImGuiSession.md)
|
||||
- ImGui 平台/渲染后端桥
|
||||
- `LayerStack`
|
||||
- [Core::EditorContext](../Core/EditorContext/EditorContext.md)
|
||||
- [Layers::EditorLayer](../Layers/EditorLayer/EditorLayer.md)
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- 采用单例入口 `Get()`。
|
||||
- `Initialize(HWND)` 会安装崩溃过滤器、配置日志、初始化窗口渲染器、创建编辑器上下文、初始化 ImGui,并挂接 `EditorLayer`。
|
||||
- `Shutdown()` 会按反向顺序关闭 layer、ImGui 和窗口渲染器。
|
||||
- `Render()` 当前只是执行一帧编辑器 UI 渲染。
|
||||
- `OnResize()` 会把尺寸变化转发给窗口渲染器。
|
||||
|
||||
## 关键公开接口
|
||||
|
||||
| 方法 | 作用 |
|
||||
|------|------|
|
||||
| `Get()` | 获取全局应用单例。 |
|
||||
| `Initialize(HWND)` | 初始化编辑器应用。 |
|
||||
| `Shutdown()` | 关闭编辑器应用。 |
|
||||
| `Render()` | 绘制一帧编辑器。 |
|
||||
| `OnResize(int, int)` | 处理窗口尺寸变化。 |
|
||||
| `GetWindowHandle()` | 获取当前窗口句柄。 |
|
||||
| `GetEditorContext()` | 获取当前编辑器上下文。 |
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 目前窗口渲染路径绑定到 D3D12 窗口渲染器,不是抽象后端。
|
||||
- `InitializeEditorContext()` 当前默认把项目路径设为可执行目录。
|
||||
- `Render()` 当前只走 ImGui 帧,不承载独立游戏循环或模拟步进逻辑。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Editor 模块](../Editor.md)
|
||||
- [EditorContext](../Core/EditorContext/EditorContext.md)
|
||||
- [EditorLayer](../Layers/EditorLayer/EditorLayer.md)
|
||||
- [Win32EditorHost](../Platform/Win32EditorHost/Win32EditorHost.md)
|
||||
37
docs/api/XCEngine/Editor/Commands/Commands.md
Normal file
37
docs/api/XCEngine/Editor/Commands/Commands.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# Commands
|
||||
|
||||
**命名空间**: `XCEngine::Editor::Commands`
|
||||
|
||||
**类型**: `submodule`
|
||||
|
||||
**描述**: 编辑器高层命令封装层,把场景、项目、实体与组件编辑工作流收束成可复用操作。
|
||||
|
||||
## 概述
|
||||
|
||||
`Commands` 层的定位,是把 UI 或 action router 中触发的具体操作,收口为更高层的编辑命令。
|
||||
|
||||
当前目录中包括:
|
||||
|
||||
- [SceneCommands](SceneCommands/SceneCommands.md)
|
||||
- [ProjectCommands](ProjectCommands/ProjectCommands.md)
|
||||
- [EntityCommands](EntityCommands/EntityCommands.md)
|
||||
- [ComponentCommands](ComponentCommands/ComponentCommands.md)
|
||||
|
||||
## 设计说明
|
||||
|
||||
把面板代码里的按钮逻辑收束到命令层,是必要的。否则菜单、工具栏、快捷键和上下文菜单会各自复制一套场景操作流程。
|
||||
|
||||
从当前代码看,`Commands` 的职责边界已经比较清楚:
|
||||
|
||||
- `SceneCommands` 负责场景文件生命周期
|
||||
- `ProjectCommands` 负责资产浏览器中的资源动作
|
||||
- `EntityCommands` 负责场景树结构编辑
|
||||
- `ComponentCommands` 负责 Inspector 中的组件增删
|
||||
|
||||
这正是商业级编辑器 API 文档里应当强调的部分:用户不应只知道“这里有几个 helper”,而应明确知道“不同级别的修改应该落到哪一层”。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Editor 模块](../Editor.md)
|
||||
- [Actions](../Actions/Actions.md)
|
||||
- [Core](../Core/Core.md)
|
||||
@@ -0,0 +1,52 @@
|
||||
# ComponentCommands
|
||||
|
||||
**命名空间**: `XCEngine::Editor::Commands`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/Commands/ComponentCommands.h`
|
||||
|
||||
**描述**: 封装组件添加与移除命令,并把这些操作统一纳入场景撤销系统。
|
||||
|
||||
## 概述
|
||||
|
||||
`ComponentCommands` 处理的是 Inspector 中最典型的一类结构性编辑操作:
|
||||
|
||||
- 给实体添加某种组件
|
||||
- 从实体移除某个组件
|
||||
|
||||
它并不直接知道 Camera、Light、Transform 的具体字段,而是通过 [`IComponentEditor`](../../ComponentEditors/IComponentEditor/IComponentEditor.md) 提供的能力判断:
|
||||
|
||||
- 某个组件能否添加到该实体
|
||||
- 某个组件能否被移除
|
||||
|
||||
## 当前实现
|
||||
|
||||
- `AddComponent` 会通过 `editor.AddTo(gameObject)` 完成真实创建
|
||||
- `RemoveComponent` 会调用 `gameObject->RemoveComponent(component)`
|
||||
- 两类操作都会使用 [`UndoUtils::ExecuteSceneCommand`](../../Utils/UndoUtils/UndoUtils.md) 包装
|
||||
- 操作成功后会显式调用 `SceneManager::MarkSceneDirty()`
|
||||
|
||||
## 设计说明
|
||||
|
||||
这层命令抽象的意义,是把组件编辑器从“直接改场景结构”里解耦出来。
|
||||
组件编辑器更适合回答“这个组件怎么画 UI、能不能加、能不能删”,而不适合自己关心:
|
||||
|
||||
- 如何录制撤销
|
||||
- 如何标记场景 dirty
|
||||
- 如何统一命令标签
|
||||
|
||||
这正是 `ComponentCommands` 应该做的事。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 组件依赖关系仍然很弱,没有自动补齐必需组件的机制
|
||||
- 删除组件时没有跨组件引用检查
|
||||
- 当前命令标签主要由组件显示名拼接,不支持更丰富的操作上下文
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Commands](../Commands.md)
|
||||
- [InspectorActionRouter](../../Actions/InspectorActionRouter/InspectorActionRouter.md)
|
||||
- [IComponentEditor](../../ComponentEditors/IComponentEditor/IComponentEditor.md)
|
||||
- [UndoUtils](../../Utils/UndoUtils/UndoUtils.md)
|
||||
@@ -0,0 +1,54 @@
|
||||
# EntityCommands
|
||||
|
||||
**命名空间**: `XCEngine::Editor::Commands`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/Commands/EntityCommands.h`
|
||||
|
||||
**描述**: 封装实体创建、重命名、删除、复制粘贴、重复和父子重挂接等场景编辑命令。
|
||||
|
||||
## 概述
|
||||
|
||||
`EntityCommands` 是当前 Scene 编辑工作流里最重要的一层命令辅助。
|
||||
Hierarchy 面板、Edit 菜单和快捷键触发的实体级操作,最终大多落到这里。
|
||||
|
||||
当前覆盖:
|
||||
|
||||
- 创建空实体、Camera、Light
|
||||
- 重命名与删除实体
|
||||
- 复制、粘贴、重复实体
|
||||
- 重挂接父节点并尽量保持世界变换
|
||||
- 从父节点分离实体
|
||||
|
||||
## 当前实现
|
||||
|
||||
- 结构性修改统一通过 [`UndoUtils::ExecuteSceneCommand`](../../Utils/UndoUtils/UndoUtils.md) 包装
|
||||
- 创建实体后会自动把新实体设置为当前选中对象
|
||||
- `CreateCameraEntity` 与 `CreateLightEntity` 会附加对应组件
|
||||
- `CanReparentEntity` 会阻止把对象挂到自己的子孙节点下
|
||||
- `ReparentEntityPreserveWorldTransform` 会缓存当前位置、旋转和缩放,再执行 `MoveEntity`
|
||||
|
||||
## 设计说明
|
||||
|
||||
把实体编辑动作做成独立命令层,是编辑器架构里非常关键的一步。
|
||||
如果直接在 Hierarchy 面板里 `CreateEntity`、`DeleteEntity`、`MoveEntity`,会很快遇到三个问题:
|
||||
|
||||
- 撤销历史无法统一
|
||||
- 菜单栏、快捷键、右键菜单会重复同一逻辑
|
||||
- 结构修改和 UI 交互代码缠在一起
|
||||
|
||||
`EntityCommands` 把“编辑行为语义”稳定下来,面板和 router 只需要负责调用它。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- `CreateCubeEntity` / `CreateSphereEntity` / `CreatePlaneEntity` 在当前路由中实际上还是创建命名后的空实体,不会自动生成渲染组件
|
||||
- 粘贴和重复的深拷贝语义完全依赖 `ISceneManager` 当前实现
|
||||
- 多实体批量命令尚未覆盖
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Commands](../Commands.md)
|
||||
- [HierarchyActionRouter](../../Actions/HierarchyActionRouter/HierarchyActionRouter.md)
|
||||
- [SceneManager](../../Managers/SceneManager/SceneManager.md)
|
||||
- [UndoUtils](../../Utils/UndoUtils/UndoUtils.md)
|
||||
@@ -0,0 +1,49 @@
|
||||
# ProjectCommands
|
||||
|
||||
**命名空间**: `XCEngine::Editor::Commands`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/Commands/ProjectCommands.h`
|
||||
|
||||
**描述**: 封装 Project 面板中与资源打开、目录创建、删除和移动相关的高层操作。
|
||||
|
||||
## 概述
|
||||
|
||||
`ProjectCommands` 当前是一个很轻量的命令头,但它已经把 Project 面板最基础的资源管理语义集中起来:
|
||||
|
||||
- `CanOpenAsset`
|
||||
- `OpenAsset`
|
||||
- `CreateFolder`
|
||||
- `DeleteAsset`
|
||||
- `MoveAssetToFolder`
|
||||
|
||||
这让资源浏览面板不必直接操作底层 manager 细节。
|
||||
|
||||
## 当前实现
|
||||
|
||||
- 资源能否打开,当前只看两种情况:目录,或 `item->type == "Scene"`
|
||||
- 打开目录时调用 `IProjectManager::NavigateToFolder`
|
||||
- 打开场景资源时转发到 [`LoadScene`](../SceneCommands/SceneCommands.md)
|
||||
- 创建目录和删除资源只做最小参数校验,然后委托给 `IProjectManager`
|
||||
- 资源拖入目录时会比较源路径与目标路径,避免把资源移动到自己身上
|
||||
|
||||
## 设计说明
|
||||
|
||||
现在这层看起来很薄,但它依然有存在价值。
|
||||
原因在于 Project 面板的 UI 以后很可能持续变化,而“什么资源能打开、什么动作合法、如何调用 manager”这些规则应该集中在一个稳定位置。
|
||||
|
||||
这也是商业编辑器常见的演进路径:先用轻量命令层收口,等资源类型和导入系统成熟后,再逐渐扩展成完整 asset workflow。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 只能打开文件夹和场景资源
|
||||
- 没有资源重命名、复制粘贴、导入和重新导入
|
||||
- 删除和移动操作没有事务、确认框或冲突解决策略
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Commands](../Commands.md)
|
||||
- [ProjectActionRouter](../../Actions/ProjectActionRouter/ProjectActionRouter.md)
|
||||
- [ProjectManager](../../Managers/ProjectManager/ProjectManager.md)
|
||||
- [SceneCommands](../SceneCommands/SceneCommands.md)
|
||||
@@ -0,0 +1,49 @@
|
||||
# SceneCommands
|
||||
|
||||
**命名空间**: `XCEngine::Editor::Commands`
|
||||
|
||||
**类型**: `header utility set`
|
||||
|
||||
**源文件**: `editor/src/Commands/SceneCommands.h`
|
||||
|
||||
**描述**: 提供场景新建、加载、保存、启动场景加载和脏场景保存回退等高层编辑命令。
|
||||
|
||||
## 概述
|
||||
|
||||
`SceneCommands.h` 当前是一组 inline 命令函数,不是 class。
|
||||
|
||||
当前包含的核心命令包括:
|
||||
|
||||
- `ResetSceneEditingState()`
|
||||
- `NewScene()`
|
||||
- `LoadScene()`
|
||||
- `OpenSceneWithDialog()`
|
||||
- `SaveCurrentScene()`
|
||||
- `SaveSceneAsWithDialog()`
|
||||
- `LoadStartupScene()`
|
||||
- `SaveDirtySceneWithFallback()`
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- 这些命令统一依赖 [IEditorContext](../../Core/IEditorContext/IEditorContext.md)。
|
||||
- 新建/切换场景前会通过 `SceneEditorUtils::ConfirmSceneSwitch()` 进行确认。
|
||||
- 成功切换场景后会清空选择并清理 undo 历史。
|
||||
- `SaveSceneAsWithDialog()` 成功后会刷新项目面板当前目录。
|
||||
- `SaveDirtySceneWithFallback()` 在当前场景脏且普通保存失败时,会尝试保存到给定回退路径。
|
||||
|
||||
## 设计说明
|
||||
|
||||
这类命令层让:
|
||||
|
||||
- 菜单栏
|
||||
- 快捷键
|
||||
- 工具栏
|
||||
- 关闭工作区流程
|
||||
|
||||
都能复用同一套场景操作语义。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Commands](../Commands.md)
|
||||
- [IEditorContext](../../Core/IEditorContext/IEditorContext.md)
|
||||
- [EditorWorkspace](../../Core/EditorWorkspace/EditorWorkspace.md)
|
||||
@@ -0,0 +1,52 @@
|
||||
# CameraComponentEditor
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/ComponentEditors/CameraComponentEditor.h`
|
||||
|
||||
**描述**: `CameraComponent` 的专用 Inspector 编辑器,负责投影模式、裁剪面、主摄像机和清屏色等属性编辑。
|
||||
|
||||
## 概述
|
||||
|
||||
`CameraComponentEditor` 把运行时摄像机组件转换成 Inspector 中可直接编辑的字段组。
|
||||
当前覆盖的字段包括:
|
||||
|
||||
- 投影类型 `Perspective / Orthographic`
|
||||
- 透视视野或正交尺寸
|
||||
- Near / Far Clip
|
||||
- Depth
|
||||
- Primary
|
||||
- Clear Color
|
||||
|
||||
## 当前实现
|
||||
|
||||
- 仅接受 `CameraComponent`
|
||||
- 投影模式切换通过 `DrawPropertyCombo` 实现
|
||||
- 透视模式下显示 `Field Of View`
|
||||
- 正交模式下显示 `Orthographic Size`
|
||||
- `CanAddTo` 要求目标实体当前没有 `CameraComponent`
|
||||
- `CanRemove` 允许删除已经能被本编辑器识别的 Camera 组件
|
||||
|
||||
## 设计说明
|
||||
|
||||
把摄像机编辑做成独立 editor,而不是塞进通用属性反射层,有两个现实收益:
|
||||
|
||||
- UI 可以按照摄像机语义分支展示,而不是无差别列字段
|
||||
- Inspector 可以明确控制哪些组合合法,比如只在正交模式下显示正交尺寸
|
||||
|
||||
这和 Unity 的 Camera Inspector 思路类似:不是简单罗列成员变量,而是按摄影机工作方式组织编辑体验。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 没有视口预览、Frustum 可视化或 Gizmo 联动
|
||||
- 没有后处理、渲染层、输出目标等更高阶配置
|
||||
- `Far Clip` 的最小值只基于 `nearClip + 0.001f` 做轻量约束
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [ComponentEditors](../ComponentEditors.md)
|
||||
- [IComponentEditor](../IComponentEditor/IComponentEditor.md)
|
||||
- [ComponentCommands](../../Commands/ComponentCommands/ComponentCommands.md)
|
||||
- [PropertyGrid](../../UI/PropertyGrid/PropertyGrid.md)
|
||||
@@ -0,0 +1,41 @@
|
||||
# ComponentEditorRegistry
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class (singleton)`
|
||||
|
||||
**源文件**: `editor/src/ComponentEditors/ComponentEditorRegistry.h`
|
||||
|
||||
**描述**: 持有并注册所有组件编辑器实例,按组件类型名为 Inspector 提供查询入口。
|
||||
|
||||
## 概述
|
||||
|
||||
`ComponentEditorRegistry` 是当前组件编辑器系统的注册中心。
|
||||
|
||||
它负责:
|
||||
|
||||
- 注册 `IComponentEditor`
|
||||
- 根据组件实例查找对应 editor
|
||||
- 根据组件类型名查找 editor
|
||||
- 暴露全部 editor 列表
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- 采用单例 `Get()`。
|
||||
- 构造函数里会自动注册:
|
||||
- `TransformComponentEditor`
|
||||
- `CameraComponentEditor`
|
||||
- `LightComponentEditor`
|
||||
- `m_editors` 负责拥有这些 editor 对象。
|
||||
- `m_editorsByType` 提供按组件类型名的快速查找。
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 当前注册列表写死在构造函数中,不是插件式发现机制。
|
||||
- 如果后注册 editor 与已有类型名重复,`m_editorsByType` 会被覆盖,但 `m_editors` 里仍会保留多个对象。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [ComponentEditors](../ComponentEditors.md)
|
||||
- [IComponentEditor](../IComponentEditor/IComponentEditor.md)
|
||||
- [InspectorPanel](../../panels/InspectorPanel/InspectorPanel.md)
|
||||
@@ -0,0 +1,33 @@
|
||||
# ComponentEditors
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `submodule`
|
||||
|
||||
**描述**: 组件属性编辑器层,负责把运行时组件映射到 Inspector 中的具体编辑 UI。
|
||||
|
||||
## 概述
|
||||
|
||||
当前目录包含:
|
||||
|
||||
- [IComponentEditor](IComponentEditor/IComponentEditor.md)
|
||||
- [ComponentEditorRegistry](ComponentEditorRegistry/ComponentEditorRegistry.md)
|
||||
- [TransformComponentEditor](TransformComponentEditor/TransformComponentEditor.md)
|
||||
- [CameraComponentEditor](CameraComponentEditor/CameraComponentEditor.md)
|
||||
- [LightComponentEditor](LightComponentEditor/LightComponentEditor.md)
|
||||
|
||||
这说明 Inspector 当前走的是“按组件类型注册专用 editor”的路线。这和商业编辑器里常见的 custom inspector / property drawer 思路是一致的。
|
||||
|
||||
当前这组 editor 也已经体现出比较明确的分层:
|
||||
|
||||
- `IComponentEditor` 定义统一契约
|
||||
- `ComponentEditorRegistry` 负责注册和查找
|
||||
- 具体 editor 只处理本组件的 Inspector 体验
|
||||
|
||||
这比把所有组件字段硬塞进一个大而全的 Inspector 渲染器更容易扩展。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Editor 模块](../Editor.md)
|
||||
- [panels](../panels/panels.md)
|
||||
- [Components](../../Components/Components.md)
|
||||
@@ -0,0 +1,40 @@
|
||||
# IComponentEditor
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class (abstract)`
|
||||
|
||||
**源文件**: `editor/src/ComponentEditors/IComponentEditor.h`
|
||||
|
||||
**描述**: 定义 Inspector 中单个组件编辑器的统一接口,包括显示名、可编辑性、渲染逻辑以及组件添加/移除相关能力。
|
||||
|
||||
## 概述
|
||||
|
||||
`IComponentEditor` 是当前 Inspector 扩展点的核心接口。
|
||||
|
||||
它把每个组件在编辑器中的专用处理统一抽象成几类能力:
|
||||
|
||||
- 识别自己负责的组件类型
|
||||
- 渲染该组件的编辑 UI
|
||||
- 决定是否显示在 Add Component 菜单里
|
||||
- 决定是否可被添加到某个 `GameObject`
|
||||
- 决定组件是否可移除
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- 默认 `CanEdit()` 按 `component->GetName() == GetComponentTypeName()` 判断。
|
||||
- 默认 `AddTo()` 会通过 `ComponentFactoryRegistry` 按组件名创建组件。
|
||||
- 默认 `CanAddTo()` 和 `CanRemove()` 都返回 `false`,因此派生类需要显式放开能力。
|
||||
|
||||
## 设计说明
|
||||
|
||||
这条路线和很多商业编辑器里的 custom inspector 模型很像:
|
||||
|
||||
- 运行时组件保持干净
|
||||
- 编辑器层通过专用 editor 决定如何显示和编辑它
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [ComponentEditors](../ComponentEditors.md)
|
||||
- [ComponentEditorRegistry](../ComponentEditorRegistry/ComponentEditorRegistry.md)
|
||||
- [InspectorPanel](../../panels/InspectorPanel/InspectorPanel.md)
|
||||
@@ -0,0 +1,46 @@
|
||||
# LightComponentEditor
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/ComponentEditors/LightComponentEditor.h`
|
||||
|
||||
**描述**: `LightComponent` 的专用 Inspector 编辑器,负责灯光类型、颜色、强度、范围和阴影开关等属性编辑。
|
||||
|
||||
## 概述
|
||||
|
||||
`LightComponentEditor` 当前覆盖的是最基本的光源参数编辑:
|
||||
|
||||
- 灯光类型 `Directional / Point / Spot`
|
||||
- 颜色
|
||||
- 强度
|
||||
- 范围
|
||||
- 聚光角度
|
||||
- 是否投射阴影
|
||||
|
||||
## 当前实现
|
||||
|
||||
- 仅接受 `LightComponent`
|
||||
- 方向光不会显示 `Range`
|
||||
- 只有聚光灯会显示 `Spot Angle`
|
||||
- `CanAddTo` 要求目标实体当前没有 `LightComponent`
|
||||
- `CanRemove` 允许删除已存在的 Light 组件
|
||||
|
||||
## 设计说明
|
||||
|
||||
灯光编辑和摄像机编辑类似,天然需要条件式 UI。
|
||||
如果走完全通用的字段表单,很容易把不适用于当前灯光类型的选项也暴露出来,给用户造成误导。当前这种专用 editor 设计更贴近商业编辑器常见的“按组件语义组织 Inspector”。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 没有阴影贴图、衰减曲线、颜色温度等更高级设置
|
||||
- 没有场景视图里的灯光 Gizmo 或范围预览
|
||||
- 多光源批量编辑尚未覆盖
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [ComponentEditors](../ComponentEditors.md)
|
||||
- [IComponentEditor](../IComponentEditor/IComponentEditor.md)
|
||||
- [ComponentCommands](../../Commands/ComponentCommands/ComponentCommands.md)
|
||||
- [PropertyGrid](../../UI/PropertyGrid/PropertyGrid.md)
|
||||
@@ -0,0 +1,54 @@
|
||||
# TransformComponentEditor
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/ComponentEditors/TransformComponentEditor.h`
|
||||
|
||||
**描述**: `TransformComponent` 的专用 Inspector 编辑器,负责位置、旋转和缩放字段的交互式编辑。
|
||||
|
||||
## 概述
|
||||
|
||||
`TransformComponentEditor` 是当前 Inspector 中最基础的组件编辑器之一。
|
||||
它实现了 [`IComponentEditor`](../IComponentEditor/IComponentEditor.md),并专门处理:
|
||||
|
||||
- 本地位置 `LocalPosition`
|
||||
- 本地欧拉角 / 四元数旋转
|
||||
- 本地缩放 `LocalScale`
|
||||
|
||||
这类编辑器的职责不是管理场景结构,而是把组件字段以可交互、可撤销的方式暴露给用户。
|
||||
|
||||
## 当前实现
|
||||
|
||||
- 仅接受 `TransformComponent`,内部通过 `dynamic_cast` 验证类型
|
||||
- 属性绘制基于 [`PropertyGrid`](../../UI/PropertyGrid/PropertyGrid.md) 和 [`VectorControls`](../../UI/VectorControls/VectorControls.md)
|
||||
- 每次字段修改都会通过 `UI::ApplyPropertyChange` 触发交互式撤销录制
|
||||
- `Transform` 被视为内建组件:
|
||||
- `CanAddTo` 永远返回 `false`
|
||||
- `GetAddDisabledReason` 返回 `"Built-in"`
|
||||
- `CanRemove` 永远返回 `false`
|
||||
|
||||
## 旋转编辑策略
|
||||
|
||||
旋转编辑是这页里最值得注意的设计点。
|
||||
当前实现没有直接把四元数原样暴露给用户,而是:
|
||||
|
||||
- 用 `RotationEditState` 缓存展示中的欧拉角
|
||||
- 当检测到外部旋转变化时,同步刷新缓存
|
||||
- 只有在当前控件不处于编辑状态时,才用最新四元数回写展示值
|
||||
|
||||
这比直接每帧做欧拉角往返转换更稳定,能减少拖拽过程中数值跳变。商业编辑器通常也会做类似的“显示态缓存”。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 状态缓存以 `TransformComponent*` 为键,当前实现里没有显式清理失效键
|
||||
- 只覆盖本地变换,不提供世界坐标 / 局部坐标切换
|
||||
- 没有多对象联动编辑
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [ComponentEditors](../ComponentEditors.md)
|
||||
- [IComponentEditor](../IComponentEditor/IComponentEditor.md)
|
||||
- [InspectorPanel](../../panels/InspectorPanel/InspectorPanel.md)
|
||||
- [PropertyGrid](../../UI/PropertyGrid/PropertyGrid.md)
|
||||
35
docs/api/XCEngine/Editor/Core/AssetItem/AssetItem.md
Normal file
35
docs/api/XCEngine/Editor/Core/AssetItem/AssetItem.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# AssetItem
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `struct + alias`
|
||||
|
||||
**源文件**: `editor/src/Core/AssetItem.h`
|
||||
|
||||
**描述**: 表示 Project 面板中的一个资产或文件夹节点,并定义共享指针别名 `AssetItemPtr`。
|
||||
|
||||
## 概述
|
||||
|
||||
`AssetItem` 当前是项目浏览器里最基础的树节点结构。
|
||||
|
||||
字段包括:
|
||||
|
||||
- `name`
|
||||
- `type`
|
||||
- `isFolder`
|
||||
- `fullPath`
|
||||
- `children`
|
||||
|
||||
同时还定义了:
|
||||
|
||||
- `using AssetItemPtr = std::shared_ptr<AssetItem>`
|
||||
|
||||
## 设计说明
|
||||
|
||||
当前项目浏览器把目录树直接建成共享指针树,优点是结构简单、递归扫描方便;缺点是没有额外的懒加载或虚拟化机制。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Core](../Core.md)
|
||||
- [IProjectManager](../IProjectManager/IProjectManager.md)
|
||||
- [ProjectManager](../../Managers/ProjectManager/ProjectManager.md)
|
||||
53
docs/api/XCEngine/Editor/Core/Core.md
Normal file
53
docs/api/XCEngine/Editor/Core/Core.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Core
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `submodule`
|
||||
|
||||
**描述**: 编辑器核心上下文与服务层,包含事件总线、上下文接口、场景快照、撤销与选择系统的基础抽象。
|
||||
|
||||
## 概述
|
||||
|
||||
`Editor/Core` 是编辑器应用的状态中枢。这里的类型决定了各个面板、命令和管理器如何共享状态。
|
||||
|
||||
当前最关键的核心对象包括:
|
||||
|
||||
- [IEditorContext](IEditorContext/IEditorContext.md)
|
||||
- [EditorContext](EditorContext/EditorContext.md)
|
||||
- [EventBus](EventBus/EventBus.md)
|
||||
- [EditorEvents](EditorEvents/EditorEvents.md)
|
||||
- [EditorActionRoute](EditorActionRoute/EditorActionRoute.md)
|
||||
- [EditorConsoleSink](EditorConsoleSink/EditorConsoleSink.md)
|
||||
- [EditorLoggingSetup](EditorLoggingSetup/EditorLoggingSetup.md)
|
||||
- [EditorWindowTitle](EditorWindowTitle/EditorWindowTitle.md)
|
||||
- [EditorWorkspace](EditorWorkspace/EditorWorkspace.md)
|
||||
- [IProjectManager](IProjectManager/IProjectManager.md)
|
||||
- [ISceneManager](ISceneManager/ISceneManager.md)
|
||||
- [ISelectionManager](ISelectionManager/ISelectionManager.md)
|
||||
- [IUndoManager](IUndoManager/IUndoManager.md)
|
||||
- [SceneSnapshot](SceneSnapshot/SceneSnapshot.md)
|
||||
- [SelectionManager](SelectionManager/SelectionManager.md)
|
||||
- [UndoManager](UndoManager/UndoManager.md)
|
||||
- [AssetItem](AssetItem/AssetItem.md)
|
||||
|
||||
## 设计说明
|
||||
|
||||
把 manager 接口、事件系统和上下文聚合都放在 `Core` 层,是很合理的工具架构做法:
|
||||
|
||||
- 面板层不必直接 new 具体管理器。
|
||||
- 命令层可以只依赖 `IEditorContext`。
|
||||
- undo/selection/project/scene 这些服务可以被统一组织和替换。
|
||||
|
||||
当前还可以看到一个很清晰的工程化方向:
|
||||
|
||||
- `EditorActionRoute` 负责动作路由语义
|
||||
- `SceneSnapshot + UndoManager` 负责状态回滚
|
||||
- `EditorConsoleSink + EditorLoggingSetup` 负责把引擎日志接入编辑器壳层
|
||||
- `EditorWindowTitle` 负责把底层状态翻译成可见的主窗口反馈
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Editor 模块](../Editor.md)
|
||||
- [Managers](../Managers/Managers.md)
|
||||
- [Commands](../Commands/Commands.md)
|
||||
- [panels](../panels/panels.md)
|
||||
@@ -0,0 +1,39 @@
|
||||
# EditorActionRoute
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `enum class`
|
||||
|
||||
**源文件**: `editor/src/Core/EditorActionRoute.h`
|
||||
|
||||
**描述**: 定义当前全局编辑动作应该作用到哪个面板上下文。
|
||||
|
||||
## 概述
|
||||
|
||||
`EditorActionRoute` 是 `ActionRouting` 和 `EditActionRouter` 之间的最小契约。
|
||||
当前枚举值只有三个:
|
||||
|
||||
- `None`
|
||||
- `Hierarchy`
|
||||
- `Project`
|
||||
|
||||
它本质上回答的是一个问题:当用户按下 `Delete`、`Ctrl+C` 或 `Ctrl+V` 时,编辑器到底应该操作实体树,还是资产浏览器,还是暂时不响应。
|
||||
|
||||
## 设计说明
|
||||
|
||||
把路由显式枚举出来,而不是靠每个面板自己判断快捷键,有几个直接收益:
|
||||
|
||||
- 全局 Edit 菜单可以统一生成启用状态
|
||||
- 快捷键处理逻辑可以收口到 `EditActionRouter`
|
||||
- 不同面板之间的编辑语义冲突会更容易排查
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 当前只覆盖 `Hierarchy` 和 `Project`
|
||||
- `Inspector`、`Console`、未来的材质编辑器或资源检查器都还没有自己的路由值
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Core](../Core.md)
|
||||
- [ActionRouting](../../Actions/ActionRouting/ActionRouting.md)
|
||||
- [EditActionRouter](../../Actions/EditActionRouter/EditActionRouter.md)
|
||||
@@ -0,0 +1,42 @@
|
||||
# EditorConsoleSink
|
||||
|
||||
**命名空间**: `XCEngine::Debug`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/Core/EditorConsoleSink.h`
|
||||
|
||||
**描述**: 编辑器专用日志 sink,把引擎日志桥接到 Console 面板可读取的内存缓冲区。
|
||||
|
||||
## 概述
|
||||
|
||||
`EditorConsoleSink` 虽然位于 `editor/src/Core`,但命名空间属于 `XCEngine::Debug`。
|
||||
它的定位很明确:作为 `Logger` 的一个输出目标,把日志保存在内存中,供 Console 面板显示。
|
||||
|
||||
## 当前实现
|
||||
|
||||
- 继承自 `ILogSink`
|
||||
- 通过 `std::mutex` 保护 `m_logs`
|
||||
- `Log()` 会把新日志追加到数组尾部
|
||||
- 最大缓存条数固定为 `1000`
|
||||
- 超限时直接丢弃最早的一条日志
|
||||
- `GetLogs()` 返回日志数组的拷贝
|
||||
- `GetInstance()` 在没有显式注册实例时会返回一个静态 fallback 实例
|
||||
|
||||
## 设计说明
|
||||
|
||||
这是一个典型的“工具层 sink”。
|
||||
引擎日志系统不应该知道编辑器面板怎么画 UI,但编辑器又确实需要消费同一份日志流。把桥接能力做成一个 `ILogSink` 子类,是最干净的集成方式。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 当前只保留最近 1000 条日志
|
||||
- `GetLogs()` 会复制整个缓冲区
|
||||
- `SetCallback()` 没有更复杂的线程调度机制,回调触发策略非常轻量
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Core](../Core.md)
|
||||
- [ConsoleActionRouter](../../Actions/ConsoleActionRouter/ConsoleActionRouter.md)
|
||||
- [ConsolePanel](../../panels/ConsolePanel/ConsolePanel.md)
|
||||
- [Debug::Logger](../../../Debug/Logger/Logger.md)
|
||||
43
docs/api/XCEngine/Editor/Core/EditorContext/EditorContext.md
Normal file
43
docs/api/XCEngine/Editor/Core/EditorContext/EditorContext.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# EditorContext
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/Core/EditorContext.h`
|
||||
|
||||
**描述**: 当前编辑器默认的上下文实现,负责创建并持有事件总线、选择管理、场景管理、撤销管理和项目管理对象。
|
||||
|
||||
## 概述
|
||||
|
||||
`EditorContext` 是 [IEditorContext](../IEditorContext/IEditorContext.md) 的默认实现。
|
||||
|
||||
它当前在构造时就把主要编辑器服务完整拼装出来:
|
||||
|
||||
- `EventBus`
|
||||
- `SelectionManager`
|
||||
- `SceneManager`
|
||||
- `UndoManager`
|
||||
- `ProjectManager`
|
||||
|
||||
并额外订阅 `EntityDeletedEvent`,在被删实体刚好是当前选中实体时清理选择状态。
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- 事件总线采用 `unique_ptr<EventBus>` 持有。
|
||||
- `UndoManager` 依赖 `SceneManager` 与 `SelectionManager`。
|
||||
- 通过 `EditorActionRoute` 记录当前激活的动作路由。
|
||||
- 同时保存项目路径字符串。
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 当前所有服务都在构造时固定实例化,不是懒加载。
|
||||
- 当前不是插件化服务容器,没有注册/替换任意服务的通用机制。
|
||||
- 删除实体时自动清理选择这一逻辑是直接写在构造函数订阅里的。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Core](../Core.md)
|
||||
- [IEditorContext](../IEditorContext/IEditorContext.md)
|
||||
- [EventBus](../EventBus/EventBus.md)
|
||||
- [SceneManager](../../Managers/SceneManager/SceneManager.md)
|
||||
44
docs/api/XCEngine/Editor/Core/EditorEvents/EditorEvents.md
Normal file
44
docs/api/XCEngine/Editor/Core/EditorEvents/EditorEvents.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# EditorEvents
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `event set`
|
||||
|
||||
**源文件**: `editor/src/Core/EditorEvents.h`
|
||||
|
||||
**描述**: 定义编辑器内部事件类型,包括选择变化、实体生命周期、场景变化、播放模式变化、Dock 布局重置和退出请求等事件。
|
||||
|
||||
## 概述
|
||||
|
||||
`EditorEvents.h` 当前定义的是一组轻量事件结构体,而不是复杂基类层级。
|
||||
|
||||
这和当前 [EventBus](../EventBus/EventBus.md) 的模板化设计很匹配:只要是明确的结构体类型,就能被直接作为事件类型发布与订阅。
|
||||
|
||||
## 当前事件
|
||||
|
||||
| 事件 | 作用 |
|
||||
|------|------|
|
||||
| `SelectionChangedEvent` | 选择集合变化。 |
|
||||
| `EntityCreatedEvent` | 新建实体。 |
|
||||
| `EntityDeletedEvent` | 删除实体。 |
|
||||
| `EntityChangedEvent` | 实体内容变化。 |
|
||||
| `EntityRenameRequestedEvent` | 请求重命名实体。 |
|
||||
| `EntityParentChangedEvent` | 实体父子关系变化。 |
|
||||
| `SceneChangedEvent` | 当前场景发生变化。 |
|
||||
| `PlayModeStartedEvent` / `Stopped` / `Paused` | 编辑器播放模式状态变化。 |
|
||||
| `EditorModeChangedEvent` | 编辑器模式切换。 |
|
||||
| `DockLayoutResetRequestedEvent` | 请求重置 dock 布局。 |
|
||||
| `EditorExitRequestedEvent` | 请求关闭编辑器。 |
|
||||
|
||||
## 特别说明
|
||||
|
||||
- `GameObjectID` 当前被定义为 `uint64_t` 别名。
|
||||
- `SelectionChangedEvent` 同时包含完整选择列表和主选择。
|
||||
- `EditorModeChangedEvent` 当前使用整数记录旧模式/新模式,而不是更强类型的枚举。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Core](../Core.md)
|
||||
- [EventBus](../EventBus/EventBus.md)
|
||||
- [SelectionManager](../SelectionManager/SelectionManager.md)
|
||||
- [SceneManager](../../Managers/SceneManager/SceneManager.md)
|
||||
@@ -0,0 +1,50 @@
|
||||
# EditorLoggingSetup
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/Core/EditorLoggingSetup.h`
|
||||
|
||||
**描述**: 配置编辑器启动时的日志输出目标,包括控制台、编辑器内存 sink 和磁盘日志文件。
|
||||
|
||||
## 概述
|
||||
|
||||
`ConfigureEditorLogging` 是应用启动流程里非常早期的一步。它会把编辑器需要的日志通道一次性接到全局 `Debug::Logger` 上。
|
||||
|
||||
当前会注册:
|
||||
|
||||
- `Debug::ConsoleLogSink`
|
||||
- `Debug::EditorConsoleSink`
|
||||
- `Debug::FileLogSink`
|
||||
|
||||
然后写入两条启动信息,说明编辑器已启动以及日志文件路径。
|
||||
|
||||
## 当前实现
|
||||
|
||||
- 日志文件路径固定为 `{executableDirectory}\\editor.log`
|
||||
- 使用 `Logger::Get()` 直接操作全局单例
|
||||
- 没有去重逻辑,也没有“只初始化一次”的保护
|
||||
|
||||
## 设计说明
|
||||
|
||||
对编辑器来说,同时拥有三份日志出口是合理的:
|
||||
|
||||
- 控制台便于开发调试
|
||||
- 内存 sink 便于 UI 面板即时查看
|
||||
- 文件 sink 便于排查启动期和崩溃前问题
|
||||
|
||||
这也是商业工具软件常见的组合,尤其是在图形程序里,单靠控制台通常不够。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 如果重复调用,sink 可能被重复注册
|
||||
- 日志文件路径策略目前不可配置
|
||||
- 没有按等级或模块分别路由到不同文件
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Core](../Core.md)
|
||||
- [EditorConsoleSink](../EditorConsoleSink/EditorConsoleSink.md)
|
||||
- [Application](../../Application/Application.md)
|
||||
- [Logger](../../../Debug/Logger/Logger.md)
|
||||
@@ -0,0 +1,41 @@
|
||||
# EditorWindowTitle
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/Core/EditorWindowTitle.h`
|
||||
|
||||
**描述**: 根据当前场景状态构造编辑器主窗口标题字符串。
|
||||
|
||||
## 概述
|
||||
|
||||
`BuildEditorWindowTitle` 会从 `IEditorContext` 中读取当前场景信息,并拼出类似下面的标题:
|
||||
|
||||
- `No Scene - XCEngine Editor`
|
||||
- `Untitled Scene * (Unsaved) - XCEngine Editor`
|
||||
- `Main Scene - Main.xc - XCEngine Editor`
|
||||
|
||||
这类函数虽然简单,但它把编辑器当前状态的用户反馈统一到了一个位置。
|
||||
|
||||
## 当前实现
|
||||
|
||||
- 没有活动场景时显示 `No Scene`
|
||||
- 场景名为空时显示 `Untitled Scene`
|
||||
- 场景 dirty 时追加 `*`
|
||||
- 没有场景路径时追加 `(Unsaved)`
|
||||
- 有路径时会额外拼接文件名
|
||||
|
||||
`Application.cpp` 会在每帧窗口标题刷新时把它转成宽字符,再交给 Win32 宿主窗口。
|
||||
|
||||
## 设计说明
|
||||
|
||||
商业编辑器通常都会把“场景是否已保存”“当前文件名是什么”直接反映在窗口标题上,因为这是最低成本但很有效的状态反馈。
|
||||
把标题拼接逻辑独立出来,也能避免窗口宿主层去关心场景管理细节。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Core](../Core.md)
|
||||
- [Application](../../Application/Application.md)
|
||||
- [SceneManager](../../Managers/SceneManager/SceneManager.md)
|
||||
- [Win32Utf8](../../Platform/Win32Utf8/Win32Utf8.md)
|
||||
@@ -0,0 +1,45 @@
|
||||
# EditorWorkspace
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/Core/EditorWorkspace.h`
|
||||
|
||||
**描述**: 负责组织编辑器面板集合、Dock 布局控制器以及工作区级 attach/detach/update/render 生命周期。
|
||||
|
||||
## 概述
|
||||
|
||||
`EditorWorkspace` 是当前编辑器 UI 结构真正聚合起来的地方。
|
||||
|
||||
在 [Attach](../../Layers/EditorLayer/EditorLayer.md) 阶段,它会:
|
||||
|
||||
- 清空并配置 `PanelCollection`
|
||||
- 创建 `MenuBar`
|
||||
- 创建 `HierarchyPanel`
|
||||
- 创建 `SceneViewPanel`
|
||||
- 创建 `GameViewPanel`
|
||||
- 创建 `InspectorPanel`
|
||||
- 创建 `ConsolePanel`
|
||||
- 创建 `ProjectPanel`
|
||||
- 创建 `DockLayoutController`
|
||||
- 初始化项目面板并尝试加载启动场景
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- `Attach(IEditorContext&)` 是工作区初始化入口。
|
||||
- `Detach(IEditorContext&)` 会在拆除 UI 前调用 `SaveDirtySceneWithFallback()` 保存脏场景。
|
||||
- `Update(float)`、`DispatchEvent(void*)` 和 `Render()` 都只是把行为转发给面板集合与 dock 控制器。
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 默认工作区结构目前是硬编码的。
|
||||
- `BuildFallbackScenePath()` 当前固定回退到 `<Project>/Assets/Scenes/Main.xc`。
|
||||
- 当前没有多工作区方案,也没有动态工作区配置对象。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Core](../Core.md)
|
||||
- [EditorLayer](../../Layers/EditorLayer/EditorLayer.md)
|
||||
- [PanelCollection](../../panels/PanelCollection/PanelCollection.md)
|
||||
- [SceneCommands](../../Commands/SceneCommands/SceneCommands.md)
|
||||
43
docs/api/XCEngine/Editor/Core/EventBus/EventBus.md
Normal file
43
docs/api/XCEngine/Editor/Core/EventBus/EventBus.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# EventBus
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class template host`
|
||||
|
||||
**源文件**: `editor/src/Core/EventBus.h`
|
||||
|
||||
**描述**: 提供编辑器内部的轻量级泛型事件总线,支持按事件类型订阅、取消订阅、发布和清空。
|
||||
|
||||
## 概述
|
||||
|
||||
`EventBus` 是当前编辑器内部通信的基础设施。
|
||||
|
||||
它的核心机制是:
|
||||
|
||||
- 每个事件类型通过 `EventTypeId<T>` 获得一个静态类型 ID。
|
||||
- `Subscribe<T>()` 返回 handler ID。
|
||||
- `Publish<T>()` 根据类型 ID 找到对应处理器并逐个调用。
|
||||
|
||||
同时这个头里还定义了:
|
||||
|
||||
- `EventTypeRegistry`
|
||||
- `EventTypeId<T>`
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- 订阅表使用 `std::unordered_map<uint32_t, std::vector<HandlerEntry>>`。
|
||||
- `Subscribe` / `Unsubscribe` 使用 `std::lock_guard<std::shared_mutex>`。
|
||||
- `Publish` 使用 `std::shared_lock<std::shared_mutex>`。
|
||||
- `Clear()` 会清空全部 handler。
|
||||
|
||||
## 当前实现风险与边界
|
||||
|
||||
- `Publish()` 在持有共享锁时直接执行 handler。
|
||||
- 如果某个 handler 在回调内部再次对同一个 `EventBus` 做需要独占锁的订阅/取消订阅操作,重入语义需要格外小心。
|
||||
- 当前没有事件排队、延迟分发或线程切换机制。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Core](../Core.md)
|
||||
- [EditorEvents](../EditorEvents/EditorEvents.md)
|
||||
- [EditorContext](../EditorContext/EditorContext.md)
|
||||
@@ -0,0 +1,45 @@
|
||||
# IEditorContext
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class (abstract)`
|
||||
|
||||
**源文件**: `editor/src/Core/IEditorContext.h`
|
||||
|
||||
**描述**: 定义编辑器服务定位接口,为面板、命令和 layer 提供统一的项目、场景、选择、撤销和事件访问入口。
|
||||
|
||||
## 概述
|
||||
|
||||
`IEditorContext` 是当前编辑器架构里最关键的接口之一。
|
||||
|
||||
它把编辑器里最常被共享的服务统一收口到一个对象上:
|
||||
|
||||
- `EventBus`
|
||||
- `ISelectionManager`
|
||||
- `ISceneManager`
|
||||
- `IProjectManager`
|
||||
- `IUndoManager`
|
||||
- 当前激活的动作路由
|
||||
- 当前项目路径
|
||||
|
||||
## 核心接口
|
||||
|
||||
| 方法 | 作用 |
|
||||
|------|------|
|
||||
| `GetEventBus()` | 获取事件总线。 |
|
||||
| `GetSelectionManager()` | 获取选择管理服务。 |
|
||||
| `GetSceneManager()` | 获取场景管理服务。 |
|
||||
| `GetProjectManager()` | 获取项目管理服务。 |
|
||||
| `GetUndoManager()` | 获取撤销管理服务。 |
|
||||
| `SetActiveActionRoute()` / `GetActiveActionRoute()` | 管理当前动作路由。 |
|
||||
| `SetProjectPath()` / `GetProjectPath()` | 管理当前项目根路径。 |
|
||||
|
||||
## 设计说明
|
||||
|
||||
这类 context 接口和商业编辑器工具链里常见的 service hub / editor context 是一致的。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Core](../Core.md)
|
||||
- [EditorContext](../EditorContext/EditorContext.md)
|
||||
- [SceneCommands](../../Commands/SceneCommands/SceneCommands.md)
|
||||
@@ -0,0 +1,41 @@
|
||||
# IProjectManager
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class (abstract)`
|
||||
|
||||
**源文件**: `editor/src/Core/IProjectManager.h`
|
||||
|
||||
**描述**: 定义项目浏览器接口,负责当前资产列表、路径导航、文件夹刷新以及基础资源文件操作。
|
||||
|
||||
## 概述
|
||||
|
||||
`IProjectManager` 面向的是编辑器 Project 面板这一类工作流。
|
||||
|
||||
它的接口组合非常清晰:
|
||||
|
||||
- 当前目录的资产项列表
|
||||
- 当前选中项索引
|
||||
- 路径导航
|
||||
- 项目根路径
|
||||
- 文件夹刷新/创建/删除/移动
|
||||
|
||||
## 核心接口
|
||||
|
||||
| 方法 | 作用 |
|
||||
|------|------|
|
||||
| `GetCurrentItems()` | 获取当前目录条目。 |
|
||||
| `GetSelectedIndex()` / `SetSelectedIndex()` | 管理当前选中项索引。 |
|
||||
| `NavigateToFolder()` / `NavigateBack()` / `NavigateToIndex()` | 处理路径导航。 |
|
||||
| `CanNavigateBack()` | 判断能否返回上一级。 |
|
||||
| `GetCurrentPath()` / `GetPathDepth()` / `GetPathName()` | 查询当前路径面包屑。 |
|
||||
| `Initialize()` | 初始化项目目录。 |
|
||||
| `RefreshCurrentFolder()` | 刷新当前目录内容。 |
|
||||
| `CreateFolder()` / `DeleteItem()` / `MoveItem()` | 执行基础文件操作。 |
|
||||
| `GetProjectPath()` | 获取项目根目录。 |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Core](../Core.md)
|
||||
- [AssetItem](../AssetItem/AssetItem.md)
|
||||
- [ProjectManager](../../Managers/ProjectManager/ProjectManager.md)
|
||||
38
docs/api/XCEngine/Editor/Core/ISceneManager/ISceneManager.md
Normal file
38
docs/api/XCEngine/Editor/Core/ISceneManager/ISceneManager.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# ISceneManager
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class (abstract)`
|
||||
|
||||
**源文件**: `editor/src/Core/ISceneManager.h`
|
||||
|
||||
**描述**: 定义编辑器场景服务接口,覆盖实体创建/删除/重命名、复制粘贴、层级移动、场景加载保存和脏状态管理。
|
||||
|
||||
## 概述
|
||||
|
||||
`ISceneManager` 当前承担的是编辑器场景服务的统一接口层。
|
||||
|
||||
它同时覆盖了三类职责:
|
||||
|
||||
- 实体层级操作
|
||||
- 场景文件生命周期
|
||||
- 剪贴板与脏状态管理
|
||||
|
||||
## 核心接口
|
||||
|
||||
| 方法 | 作用 |
|
||||
|------|------|
|
||||
| `CreateEntity()` / `DeleteEntity()` / `RenameEntity()` | 实体生命周期管理。 |
|
||||
| `GetEntity()` / `GetRootEntities()` | 查询当前实体树。 |
|
||||
| `CopyEntity()` / `PasteEntity()` / `DuplicateEntity()` / `MoveEntity()` | 编辑器层级编辑操作。 |
|
||||
| `HasClipboardData()` | 查询是否有可粘贴内容。 |
|
||||
| `NewScene()` / `LoadScene()` / `SaveScene()` / `SaveSceneAs()` / `LoadStartupScene()` | 场景文件生命周期。 |
|
||||
| `HasActiveScene()` / `IsSceneDirty()` / `MarkSceneDirty()` | 当前场景状态。 |
|
||||
| `GetCurrentScenePath()` / `GetCurrentSceneName()` | 当前场景元信息。 |
|
||||
| `CreateDemoScene()` | 创建内置示例场景。 |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Core](../Core.md)
|
||||
- [SceneManager](../../Managers/SceneManager/SceneManager.md)
|
||||
- [SceneCommands](../../Commands/SceneCommands/SceneCommands.md)
|
||||
@@ -0,0 +1,36 @@
|
||||
# ISelectionManager
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class (abstract)`
|
||||
|
||||
**源文件**: `editor/src/Core/ISelectionManager.h`
|
||||
|
||||
**描述**: 定义编辑器选择集合接口,以实体 ID 为中心管理当前选中对象列表。
|
||||
|
||||
## 概述
|
||||
|
||||
`ISelectionManager` 当前使用的是“按实体 ID 管理选择”的模型,而不是直接保存 `GameObject*`。
|
||||
|
||||
这样做的好处是:
|
||||
|
||||
- 选择状态更适合跨场景快照与撤销系统保存。
|
||||
- 不直接依赖对象指针生命周期。
|
||||
|
||||
## 核心接口
|
||||
|
||||
| 方法 | 作用 |
|
||||
|------|------|
|
||||
| `SetSelectedEntity()` | 设置单选对象。 |
|
||||
| `SetSelectedEntities()` | 设置多选集合。 |
|
||||
| `AddToSelection()` / `RemoveFromSelection()` | 增删选择。 |
|
||||
| `ClearSelection()` | 清空选择。 |
|
||||
| `GetSelectedEntity()` / `GetSelectedEntities()` | 查询当前选择。 |
|
||||
| `HasSelection()` / `GetSelectionCount()` | 查询选择状态。 |
|
||||
| `IsSelected()` | 判断某实体是否已选中。 |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Core](../Core.md)
|
||||
- [SelectionManager](../SelectionManager/SelectionManager.md)
|
||||
- [UndoManager](../UndoManager/UndoManager.md)
|
||||
50
docs/api/XCEngine/Editor/Core/IUndoManager/IUndoManager.md
Normal file
50
docs/api/XCEngine/Editor/Core/IUndoManager/IUndoManager.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# IUndoManager
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class (abstract) + struct`
|
||||
|
||||
**源文件**: `editor/src/Core/IUndoManager.h`
|
||||
|
||||
**描述**: 定义撤销/重做接口与快照结构,支持命令历史和交互式修改收束。
|
||||
|
||||
## 概述
|
||||
|
||||
`IUndoManager` 当前不是传统 command object 继承体系,而是以“前后状态快照”作为撤销数据核心。
|
||||
|
||||
这里同时定义了:
|
||||
|
||||
- `UndoStateSnapshot`
|
||||
- `IUndoManager`
|
||||
|
||||
其中 `UndoStateSnapshot` 当前包含:
|
||||
|
||||
- `SceneSnapshot scene`
|
||||
- `std::vector<uint64_t> selectionIds`
|
||||
|
||||
## 核心接口
|
||||
|
||||
| 方法 | 作用 |
|
||||
|------|------|
|
||||
| `ClearHistory()` | 清空撤销历史。 |
|
||||
| `CanUndo()` / `CanRedo()` | 查询撤销重做能力。 |
|
||||
| `GetUndoLabel()` / `GetRedoLabel()` | 查询当前可见动作标签。 |
|
||||
| `Undo()` / `Redo()` | 执行撤销或重做。 |
|
||||
| `CaptureCurrentState()` | 抓取当前编辑状态快照。 |
|
||||
| `PushCommand()` | 推入一条历史记录。 |
|
||||
| `BeginInteractiveChange()` / `FinalizeInteractiveChange()` / `CancelInteractiveChange()` | 支持拖拽等交互式修改的合并记录。 |
|
||||
| `HasPendingInteractiveChange()` | 判断是否有未收束的交互更改。 |
|
||||
|
||||
## 设计说明
|
||||
|
||||
对当前编辑器规模来说,快照式 undo 是非常务实的选择:
|
||||
|
||||
- 实现简单。
|
||||
- 容易和场景序列化结合。
|
||||
- 不必为每个编辑动作都设计一套命令对象。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Core](../Core.md)
|
||||
- [UndoManager](../UndoManager/UndoManager.md)
|
||||
- [SceneManager](../../Managers/SceneManager/SceneManager.md)
|
||||
43
docs/api/XCEngine/Editor/Core/SceneSnapshot/SceneSnapshot.md
Normal file
43
docs/api/XCEngine/Editor/Core/SceneSnapshot/SceneSnapshot.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# SceneSnapshot
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**源文件**: `editor/src/Core/SceneSnapshot.h`
|
||||
|
||||
**描述**: 表示一个可用于撤销/重做恢复的场景状态快照。
|
||||
|
||||
## 概述
|
||||
|
||||
`SceneSnapshot` 是编辑器撤销系统使用的基础数据结构。当前字段很少,但角色明确:
|
||||
|
||||
- `hasScene` 表示当前是否存在有效场景
|
||||
- `sceneData` 保存序列化后的场景内容
|
||||
- `scenePath` 保存场景文件路径
|
||||
- `dirty` 保存场景脏标记
|
||||
|
||||
它通常不会单独暴露给 UI 层,而是作为 [`UndoStateSnapshot`](../IUndoManager/IUndoManager.md) 的一部分被 `UndoManager` 和 `SceneManager` 消费。
|
||||
|
||||
## 当前实现
|
||||
|
||||
- [`SceneManager`](../../Managers/SceneManager/SceneManager.md) 负责捕获和恢复 `SceneSnapshot`
|
||||
- [`UndoManager`](../UndoManager/UndoManager.md) 会把它和选择状态一起组成一条撤销记录
|
||||
- 状态相等判断会比较 `hasScene`、`scenePath`、`sceneData`、`dirty`
|
||||
|
||||
## 设计说明
|
||||
|
||||
当前实现选择了“序列化场景快照 + 选择集”的方式,而不是更复杂的命令对象增量回放。
|
||||
这种设计对中小规模编辑器很实用:
|
||||
|
||||
- 撤销逻辑简单直接
|
||||
- 组件字段、实体层级和场景文件状态都能统一恢复
|
||||
- 对 Action / Command 层没有额外入侵
|
||||
|
||||
代价是快照体积和序列化成本会随着场景规模增加而增长。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Core](../Core.md)
|
||||
- [UndoManager](../UndoManager/UndoManager.md)
|
||||
- [SceneManager](../../Managers/SceneManager/SceneManager.md)
|
||||
@@ -0,0 +1,36 @@
|
||||
# SelectionManager
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/Core/SelectionManager.h`
|
||||
|
||||
**描述**: `ISelectionManager` 的默认实现,维护当前选中实体 ID 列表并通过 `EventBus` 发布 `SelectionChangedEvent`。
|
||||
|
||||
## 概述
|
||||
|
||||
`SelectionManager` 当前非常直接:
|
||||
|
||||
- 内部只保存一个 `std::vector<uint64_t>`。
|
||||
- 所有选择变化都会调用 `PublishSelectionChanged()`。
|
||||
- 事件内容由 [SelectionChangedEvent](../EditorEvents/EditorEvents.md) 表示。
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- 单选通过 `SetSelectedEntity()` 实现,本质上会把选择列表压缩成一个元素。
|
||||
- `GetSelectedEntity()` 返回当前列表最后一个元素。
|
||||
- 空实体 ID `0` 不会被 `AddToSelection()` 添加。
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 当前没有选择历史。
|
||||
- 当前没有“激活对象”和“多选主对象”以外的更多选择语义。
|
||||
- 当前选择变化完全是同步事件。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Core](../Core.md)
|
||||
- [ISelectionManager](../ISelectionManager/ISelectionManager.md)
|
||||
- [EditorEvents](../EditorEvents/EditorEvents.md)
|
||||
- [UndoManager](../UndoManager/UndoManager.md)
|
||||
39
docs/api/XCEngine/Editor/Core/UndoManager/UndoManager.md
Normal file
39
docs/api/XCEngine/Editor/Core/UndoManager/UndoManager.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# UndoManager
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/Core/UndoManager.h`
|
||||
|
||||
**描述**: 基于场景快照和选择快照实现编辑器撤销/重做历史,并支持交互式修改的合并提交。
|
||||
|
||||
## 概述
|
||||
|
||||
`UndoManager` 是当前 [IUndoManager](../IUndoManager/IUndoManager.md) 的默认实现。
|
||||
|
||||
它内部维护:
|
||||
|
||||
- 有标签的命令历史 `m_history`
|
||||
- 当前历史游标 `m_nextIndex`
|
||||
- 一个可选的交互式修改暂存 `m_pendingInteractiveChange`
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- 历史上限当前固定为 `128`。
|
||||
- `Undo()` 会先 finalize 未结束的交互修改,再回退到 `before` 快照。
|
||||
- `Redo()` 同理会应用 `after` 快照。
|
||||
- `CaptureCurrentState()` 会抓取当前场景快照,并仅保留仍然有效的选中实体 ID。
|
||||
- `PushCommand()` 会在状态没变化时直接丢弃该记录。
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 这是快照式 undo,不是细粒度命令式 undo。
|
||||
- 历史存储大小和场景序列化数据量直接相关。
|
||||
- `ApplyState()` 当前依赖 [SceneManager](../../Managers/SceneManager/SceneManager.md) 恢复场景,然后再恢复选择。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Core](../Core.md)
|
||||
- [IUndoManager](../IUndoManager/IUndoManager.md)
|
||||
- [SceneManager](../../Managers/SceneManager/SceneManager.md)
|
||||
56
docs/api/XCEngine/Editor/Editor.md
Normal file
56
docs/api/XCEngine/Editor/Editor.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Editor
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `app-module`
|
||||
|
||||
**描述**: 编辑器应用层 API 文档入口,镜像 `editor/src` 的目录结构,覆盖编辑器启动、上下文、面板工作区、项目浏览、场景编辑与 UI 基础设施。
|
||||
|
||||
## 概述
|
||||
|
||||
这一组文档对应的不是 `engine/include/XCEngine` 的 public engine headers,而是独立编辑器应用 `editor/src/**`。
|
||||
|
||||
因此这里需要先建立一个正确心智模型:
|
||||
|
||||
- `XCEngine` 引擎模块负责运行时系统。
|
||||
- `Editor` 模块负责围绕这些运行时系统搭建编辑器应用。
|
||||
- 它更接近“应用层/工具层 API”,而不是给游戏代码直接依赖的稳定引擎 ABI。
|
||||
|
||||
当前编辑器的主链路大致是:
|
||||
|
||||
1. [Application](Application/Application.md) 启动 Win32 窗口、D3D12 窗口渲染器和 ImGui 会话。
|
||||
2. [Core::EditorContext](Core/EditorContext/EditorContext.md) 组装事件总线、场景管理、项目管理、选择管理和撤销系统。
|
||||
3. [Layers::EditorLayer](Layers/EditorLayer/EditorLayer.md) 承载编辑器工作区生命周期。
|
||||
4. [Core::EditorWorkspace](Core/EditorWorkspace/EditorWorkspace.md) 组织菜单、层级、场景视图、GameView、Inspector、Console 和 Project 等面板。
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 当前编辑器主要是 Windows + D3D12 + ImGui 路径。
|
||||
- 这组代码整体是应用层源码,不像 engine public headers 那样已经完全按稳定 SDK 方式整理。
|
||||
- 当前文档页会优先标注 `源文件`,而不是 `头文件`,以反映它们来自 `editor/src/**`。
|
||||
- 当前自动审计脚本仍以 `engine/include/XCEngine` 为主,因此 `Editor` 这组页主要靠链接完整性和人工结构约束维护。
|
||||
|
||||
## 目录
|
||||
|
||||
- [Application](Application/Application.md) - 顶层编辑器应用入口。
|
||||
- [Theme](Theme/Theme.md) - 顶层主题入口。
|
||||
- [Core](Core/Core.md) - 上下文、事件、撤销、选择与基础数据结构。
|
||||
- [Managers](Managers/Managers.md) - 项目与场景管理实现。
|
||||
- [panels](panels/panels.md) - 编辑器面板基础设施。
|
||||
- [Layers](Layers/Layers.md) - 编辑器 layer 封装。
|
||||
- [Platform](Platform/Platform.md) - Win32 窗口宿主与 D3D12 窗口渲染器。
|
||||
- [UI](UI/UI.md) - ImGui 会话与编辑器 UI 基础设施。
|
||||
- [Actions](Actions/Actions.md) - 菜单/按钮/快捷键动作绑定与路由层。
|
||||
- [Commands](Commands/Commands.md) - 面向场景与项目操作的高层命令封装。
|
||||
- [ComponentEditors](ComponentEditors/ComponentEditors.md) - 组件属性编辑器注册与实现层。
|
||||
- [Layout](Layout/Layout.md) - Dock 布局控制。
|
||||
- [Utils](Utils/Utils.md) - 场景编辑与撤销相关辅助函数。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [XCEngine 根目录](../XCEngine.md)
|
||||
- [Scene](../Scene/Scene.md)
|
||||
- [Components](../Components/Components.md)
|
||||
- [Rendering](../Rendering/Rendering.md)
|
||||
- [Editor Architecture And Workflow](../../_guides/Editor/Editor-Architecture-And-Workflow.md)
|
||||
- [API 总索引](../../main.md)
|
||||
40
docs/api/XCEngine/Editor/Layers/EditorLayer/EditorLayer.md
Normal file
40
docs/api/XCEngine/Editor/Layers/EditorLayer/EditorLayer.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# EditorLayer
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/Layers/EditorLayer.h`
|
||||
|
||||
**描述**: 编辑器 UI 的 Layer 封装,负责把 `EditorWorkspace` 接入 `Core::Layer` 生命周期。
|
||||
|
||||
## 概述
|
||||
|
||||
`EditorLayer` 当前是 `Core::Layer` 的一个专用适配层。
|
||||
|
||||
它把:
|
||||
|
||||
- 一个共享的 `IEditorContext`
|
||||
- 一个 [EditorWorkspace](../../Core/EditorWorkspace/EditorWorkspace.md)
|
||||
|
||||
接到引擎的 layer 生命周期中。
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- 构造函数把 layer 名设为 `"Editor"`。
|
||||
- `SetContext()` 用于外部注入共享上下文。
|
||||
- `onAttach()` 若未提供上下文,会自行创建一个 `EditorContext`。
|
||||
- `onAttach()` / `onDetach()` / `onUpdate()` / `onEvent()` / `onImGuiRender()` 都只是把行为转发给 `EditorWorkspace`。
|
||||
|
||||
## 设计说明
|
||||
|
||||
这让:
|
||||
|
||||
- `Application` 不必自己直接处理每个面板。
|
||||
- 编辑器 UI 能复用已有的 `LayerStack` 机制。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Layers](../Layers.md)
|
||||
- [Application](../../Application/Application.md)
|
||||
- [EditorWorkspace](../../Core/EditorWorkspace/EditorWorkspace.md)
|
||||
21
docs/api/XCEngine/Editor/Layers/Layers.md
Normal file
21
docs/api/XCEngine/Editor/Layers/Layers.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# Layers
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `submodule`
|
||||
|
||||
**描述**: 编辑器的 Layer 封装层,当前核心是 `EditorLayer`,用于把编辑器工作区挂到引擎的 `LayerStack` 中。
|
||||
|
||||
## 概述
|
||||
|
||||
当前 `Layers` 子模块主要承担“把编辑器 UI 嵌入应用层 LayerStack”的职责。
|
||||
|
||||
已文档化的核心类型:
|
||||
|
||||
- [EditorLayer](EditorLayer/EditorLayer.md)
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Editor 模块](../Editor.md)
|
||||
- [Application](../Application/Application.md)
|
||||
- [Core](../Core/Core.md)
|
||||
@@ -0,0 +1,48 @@
|
||||
# DockLayoutController
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/Layout/DockLayoutController.h`
|
||||
|
||||
**描述**: 控制编辑器主 Dockspace 的建立、默认布局构建以及布局重置请求的处理。
|
||||
|
||||
## 概述
|
||||
|
||||
`DockLayoutController` 负责当前编辑器主窗口里最上层的 Dock 布局控制。
|
||||
|
||||
它主要做三件事:
|
||||
|
||||
- 订阅 `DockLayoutResetRequestedEvent`
|
||||
- 在 ImGui 中创建主 Dockspace
|
||||
- 在需要时重建默认布局
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- `Attach(IEditorContext&)` 会订阅布局重置事件。
|
||||
- `Detach()` 会取消订阅并把 `m_layoutDirty` 重新标记为 `true`。
|
||||
- `RenderDockspace()` 每帧都会绘制全窗口 dock host,并在 `m_layoutDirty` 为真时重建默认布局。
|
||||
- 默认布局当前是:
|
||||
- 左边 `Hierarchy`
|
||||
- 中间 `Scene` / `Game`
|
||||
- 右边 `Inspector`
|
||||
- 底部 `Console` / `Project`
|
||||
|
||||
## 设计说明
|
||||
|
||||
把布局控制单独拿出来很合理,因为:
|
||||
|
||||
- 工作区本身负责“有哪些面板”
|
||||
- 布局控制器负责“这些面板怎么停靠”
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 当前默认布局是硬编码的。
|
||||
- 当前只依赖 ImGui DockBuilder,没有更高层布局配置文件系统。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Layout](../Layout.md)
|
||||
- [EditorWorkspace](../../Core/EditorWorkspace/EditorWorkspace.md)
|
||||
- [EditorEvents](../../Core/EditorEvents/EditorEvents.md)
|
||||
19
docs/api/XCEngine/Editor/Layout/Layout.md
Normal file
19
docs/api/XCEngine/Editor/Layout/Layout.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Layout
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `submodule`
|
||||
|
||||
**描述**: 编辑器布局控制层,当前主要由 `DockLayoutController` 负责 ImGui Dockspace 布局。
|
||||
|
||||
## 概述
|
||||
|
||||
`Layout` 子模块当前规模不大,但职责很明确:控制编辑器的 Dock 布局与布局重置行为。
|
||||
|
||||
它直接服务于 [EditorWorkspace](../Core/EditorWorkspace/EditorWorkspace.md)。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Editor 模块](../Editor.md)
|
||||
- [EditorWorkspace](../Core/EditorWorkspace/EditorWorkspace.md)
|
||||
- [UI](../UI/UI.md)
|
||||
29
docs/api/XCEngine/Editor/Managers/Managers.md
Normal file
29
docs/api/XCEngine/Editor/Managers/Managers.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Managers
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `submodule`
|
||||
|
||||
**描述**: 编辑器状态服务的默认实现层,当前主要包括项目管理与场景管理实现。
|
||||
|
||||
## 概述
|
||||
|
||||
`Managers` 层的角色,是把 `Core` 里定义的抽象接口真正落成可工作的默认实现。
|
||||
|
||||
当前主要文档化的实现有:
|
||||
|
||||
- [ProjectManager](ProjectManager/ProjectManager.md)
|
||||
- [SceneManager](SceneManager/SceneManager.md)
|
||||
- [SelectionManager](SelectionManager/SelectionManager.md)
|
||||
|
||||
## 当前实现特征
|
||||
|
||||
- `ProjectManager` 更偏文件系统浏览器。
|
||||
- `SceneManager` 更偏场景编辑服务与场景文件生命周期管理。
|
||||
- `SelectionManager` 则是旧版单例实现,当前主链路已转向 `Core/ISelectionManager + Core/SelectionManager`。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Editor 模块](../Editor.md)
|
||||
- [Core](../Core/Core.md)
|
||||
- [Commands](../Commands/Commands.md)
|
||||
@@ -0,0 +1,40 @@
|
||||
# ProjectManager
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/Managers/ProjectManager.h`
|
||||
|
||||
**描述**: `IProjectManager` 的默认实现,负责扫描项目 `Assets` 目录、维护面包屑路径,并支持基础文件夹与文件操作。
|
||||
|
||||
## 概述
|
||||
|
||||
`ProjectManager` 当前本质上是一个面向 `Assets` 目录的轻量文件系统浏览器。
|
||||
|
||||
它负责:
|
||||
|
||||
- 初始化项目目录结构
|
||||
- 扫描目录并构建 `AssetItem` 树
|
||||
- 维护当前路径栈
|
||||
- 创建文件夹、删除项、移动项
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- `Initialize(projectPath)` 会确保 `<project>/Assets` 以及若干默认子目录存在。
|
||||
- 若第一次初始化发现目录不存在,会自动创建 `Textures/Models/Scripts/Materials/Scenes` 等目录,并生成少量示例文件。
|
||||
- `GetCurrentItems()` 返回当前路径末尾节点的 `children`。
|
||||
- 目录扫描时,文件夹会排在文件前面,并按名字排序。
|
||||
- 资源类型当前按扩展名启发式推断,例如 `.png -> Texture`、`.fbx -> Model`、`.cs/.cpp/.h -> Script`。
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 目前是实时扫描树,不是文件系统监听模式。
|
||||
- 异常处理大多是吞掉异常并保持当前状态,错误反馈很弱。
|
||||
- 类型判断完全靠扩展名映射,不依赖资源导入数据库。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Managers](../Managers.md)
|
||||
- [IProjectManager](../../Core/IProjectManager/IProjectManager.md)
|
||||
- [AssetItem](../../Core/AssetItem/AssetItem.md)
|
||||
@@ -0,0 +1,46 @@
|
||||
# SceneManager
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/Managers/SceneManager.h`
|
||||
|
||||
**描述**: `ISceneManager` 的默认实现,负责编辑器场景对象树、复制粘贴、场景文件加载保存、脏状态与快照恢复。
|
||||
|
||||
## 概述
|
||||
|
||||
`SceneManager` 是当前编辑器里最重的服务之一。
|
||||
|
||||
它当前同时负责:
|
||||
|
||||
- `Scene` 与根实体列表
|
||||
- 实体新建/删除/重命名
|
||||
- 复制/粘贴/复制快照
|
||||
- 层级移动
|
||||
- 场景文件新建、加载、保存
|
||||
- 场景脏状态
|
||||
- 场景快照抓取与恢复
|
||||
- 向 `EventBus` 和本地 `Core::Event` 发布事件
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- 内部持有 `std::unique_ptr<Components::Scene>`。
|
||||
- `CreateEntity()` 会在没有场景时自动创建 `"EditorScene"`。
|
||||
- 删除实体时会递归删除全部子节点。
|
||||
- 剪贴板数据是自定义 `ClipboardData` 树,不是系统剪贴板。
|
||||
- `CaptureSceneSnapshot()` / `RestoreSceneSnapshot()` 是当前 undo 的基础。
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 事件通知是同步的。
|
||||
- 复制粘贴依赖 `ComponentFactoryRegistry` 和组件自己的 `Serialize/Deserialize`。
|
||||
- 当前没有更高级的 prefab、variant 或 scene diff 机制。
|
||||
- `HasClipboardData()` 和 clipboard 生命周期都只在当前进程内有效。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Managers](../Managers.md)
|
||||
- [ISceneManager](../../Core/ISceneManager/ISceneManager.md)
|
||||
- [UndoManager](../../Core/UndoManager/UndoManager.md)
|
||||
- [Scene](../../../Scene/Scene.md)
|
||||
@@ -0,0 +1,44 @@
|
||||
# SelectionManager
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class (legacy singleton)`
|
||||
|
||||
**源文件**: `editor/src/Managers/SelectionManager.h`
|
||||
|
||||
**描述**: 旧版基于 `GameObject*` 的单例选择管理器,当前主编辑器链路已经不再以它为核心。
|
||||
|
||||
## 概述
|
||||
|
||||
这个 `Managers/SelectionManager.h` 与当前正在使用的 [`Core/SelectionManager`](../../Core/SelectionManager/SelectionManager.md) 不是同一套实现。
|
||||
|
||||
它的特征是:
|
||||
|
||||
- 单例访问 `SelectionManager::Get()`
|
||||
- 直接保存 `GameObject*`
|
||||
- 通过 `OnSelectionChanged` 事件对象通知变化
|
||||
|
||||
而当前 `EditorContext` 真实接入的是 `Core/SelectionManager`,后者实现了 `ISelectionManager`,并以实体 ID 为核心,与 `EventBus` 结合得更紧。
|
||||
|
||||
## 当前状态判断
|
||||
|
||||
按当前仓库搜索结果,`Managers/SelectionManager.h` 没有出现在现行 Editor 主路径引用中。
|
||||
因此更合理的理解是:它属于重构前残留实现,文档保留是为了说明历史包袱,而不是推荐新代码继续依赖。
|
||||
|
||||
## 使用建议
|
||||
|
||||
- 新代码应优先依赖 [`ISelectionManager`](../../Core/ISelectionManager/ISelectionManager.md)
|
||||
- 默认实现应优先使用 [`Core/SelectionManager`](../../Core/SelectionManager/SelectionManager.md)
|
||||
- 除非明确在迁移旧代码,否则不建议再引入这个单例版本
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 直接持有 `GameObject*`,生命周期耦合更重
|
||||
- 不符合当前 `EditorContext` 的服务注入方向
|
||||
- 事件机制与新的 `EventBus + EditorEvents` 体系并不统一
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Managers](../Managers.md)
|
||||
- [ISelectionManager](../../Core/ISelectionManager/ISelectionManager.md)
|
||||
- [Core::SelectionManager](../../Core/SelectionManager/SelectionManager.md)
|
||||
@@ -0,0 +1,43 @@
|
||||
# D3D12WindowRenderer
|
||||
|
||||
**命名空间**: `XCEngine::Editor::Platform`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/Platform/D3D12WindowRenderer.h`
|
||||
|
||||
**描述**: 编辑器专用的 D3D12 窗口渲染器,负责交换链、RTV/SRV 堆、命令列表和 ImGui 绘制提交。
|
||||
|
||||
## 概述
|
||||
|
||||
`D3D12WindowRenderer` 解决的是“编辑器 UI 窗口本身怎么被呈现到屏幕”这个问题。
|
||||
|
||||
它当前自己管理:
|
||||
|
||||
- `ID3D12Device`
|
||||
- `ID3D12CommandQueue`
|
||||
- `ID3D12CommandAllocator`
|
||||
- `ID3D12GraphicsCommandList`
|
||||
- `IDXGISwapChain3`
|
||||
- RTV / SRV descriptor heap
|
||||
- back buffer render targets
|
||||
- fence
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- `Initialize(hwnd, width, height)` 会创建设备与渲染目标。
|
||||
- `Render(imguiBackend, clearColor)` 会完成 back buffer 状态切换、清屏、ImGui draw data 提交、present 和 fence signal。
|
||||
- `Resize()` 会重建 back buffer RTV。
|
||||
- `GetDevice()` / `GetSrvHeap()` 为 ImGui backend 提供初始化依赖。
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 当前完全是编辑器宿主级 D3D12 代码,不走引擎自己的 RHI 抽象。
|
||||
- 当前资源释放与错误处理都比较直接,没有更高层的资源状态对象。
|
||||
- `SetEventOnCompletion()` 当前传的是 `nullptr` 事件句柄,这个等待路径仍然很原始。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Platform](../Platform.md)
|
||||
- [Application](../../Application/Application.md)
|
||||
- [Win32EditorHost](../Win32EditorHost/Win32EditorHost.md)
|
||||
34
docs/api/XCEngine/Editor/Platform/Platform.md
Normal file
34
docs/api/XCEngine/Editor/Platform/Platform.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Platform
|
||||
|
||||
**命名空间**: `XCEngine::Editor::Platform`
|
||||
|
||||
**类型**: `submodule`
|
||||
|
||||
**描述**: 编辑器宿主平台层,当前主要围绕 Win32 窗口消息循环与 D3D12 窗口渲染路径实现。
|
||||
|
||||
## 概述
|
||||
|
||||
当前 `Platform` 子模块的角色非常直接:
|
||||
|
||||
- 提供 Win32 宿主窗口和消息循环入口
|
||||
- 提供一个专用于编辑器的 D3D12 窗口渲染器
|
||||
|
||||
已文档化的核心类型/入口:
|
||||
|
||||
- [Win32EditorHost](Win32EditorHost/Win32EditorHost.md)
|
||||
- [D3D12WindowRenderer](D3D12WindowRenderer/D3D12WindowRenderer.md)
|
||||
- [Win32Utf8](Win32Utf8/Win32Utf8.md)
|
||||
- [WindowsProcessDiagnostics](WindowsProcessDiagnostics/WindowsProcessDiagnostics.md)
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 目前平台宿主明确偏向 Windows。
|
||||
- 窗口渲染器明确绑定 D3D12。
|
||||
- 这层更像编辑器宿主实现,不是跨平台窗口抽象框架。
|
||||
- 编码转换、崩溃日志和 `stderr` 重定向也都放在这一层,体现出“编辑器宿主进程基础设施”这一定位。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Editor 模块](../Editor.md)
|
||||
- [Application](../Application/Application.md)
|
||||
- [UI](../UI/UI.md)
|
||||
@@ -0,0 +1,35 @@
|
||||
# Win32EditorHost
|
||||
|
||||
**命名空间**: `XCEngine::Editor::Platform`
|
||||
|
||||
**类型**: `host entry`
|
||||
|
||||
**源文件**: `editor/src/Platform/Win32EditorHost.h`
|
||||
|
||||
**描述**: 提供 Win32 编辑器宿主入口,包括窗口过程 `EditorWndProc` 和主循环函数 `RunEditor()`。
|
||||
|
||||
## 概述
|
||||
|
||||
`Win32EditorHost.h` 当前不是传统意义上的 class,而是一组 inline 平台宿主入口:
|
||||
|
||||
- `EditorWndProc`
|
||||
- `RunEditor(HINSTANCE, int)`
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- `EditorWndProc` 会先把消息交给 `ImGuiBackendBridge::HandleWindowMessage()`。
|
||||
- `WM_SIZE` 会转发到 `Application::OnResize()`。
|
||||
- `WM_DESTROY` 会发出 `PostQuitMessage(0)`。
|
||||
- `RunEditor()` 负责注册窗口类、创建窗口、调用 `Application::Initialize()`,并在消息循环空闲时执行 `Application::Render()`。
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 这是典型的 Win32 专用宿主入口。
|
||||
- 当前没有抽象出更高层的平台无关 host interface。
|
||||
- 默认窗口类名和标题字符串目前写死在实现里。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Platform](../Platform.md)
|
||||
- [Application](../../Application/Application.md)
|
||||
- [ImGuiSession](../../UI/ImGuiSession/ImGuiSession.md)
|
||||
43
docs/api/XCEngine/Editor/Platform/Win32Utf8/Win32Utf8.md
Normal file
43
docs/api/XCEngine/Editor/Platform/Win32Utf8/Win32Utf8.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Win32Utf8
|
||||
|
||||
**命名空间**: `XCEngine::Editor::Platform`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/Platform/Win32Utf8.h`
|
||||
|
||||
**描述**: 提供 Win32 宽字符与 UTF-8 字符串互转,以及可执行文件目录获取辅助函数。
|
||||
|
||||
## 概述
|
||||
|
||||
Windows API 与编辑器内部字符串在编码层面并不一致。
|
||||
`Win32Utf8.h` 的职责就是把这些转换集中在一个地方,避免编码细节散落到 Application、文件对话框和路径辅助函数中。
|
||||
|
||||
当前提供:
|
||||
|
||||
- `WideToUtf8`
|
||||
- `Utf8ToWide`
|
||||
- `GetExecutableDirectoryUtf8`
|
||||
|
||||
## 当前实现
|
||||
|
||||
- 转换基于 `WideCharToMultiByte` 与 `MultiByteToWideChar`
|
||||
- 空字符串会直接返回空结果
|
||||
- `GetExecutableDirectoryUtf8` 使用 `GetModuleFileNameW` 读取当前进程路径,再取目录部分
|
||||
|
||||
## 设计说明
|
||||
|
||||
把编码转换集中封装,是 Windows 工具程序里非常必要的工程卫生。
|
||||
否则你会很快在应用启动、文件对话框、窗口标题和日志路径中混用 `std::string` 与 `std::wstring`,最后让边界越来越混乱。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- `GetExecutableDirectoryUtf8` 使用固定 `MAX_PATH` 缓冲区
|
||||
- 没有专门处理更复杂的错误码或长路径场景
|
||||
- 只覆盖了编辑器当前主路径所需的最小转换能力
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Platform](../Platform.md)
|
||||
- [Application](../../Application/Application.md)
|
||||
- [EditorWindowTitle](../../Core/EditorWindowTitle/EditorWindowTitle.md)
|
||||
@@ -0,0 +1,50 @@
|
||||
# WindowsProcessDiagnostics
|
||||
|
||||
**命名空间**: `XCEngine::Editor::Platform`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/Platform/WindowsProcessDiagnostics.h`
|
||||
|
||||
**描述**: 提供 Windows 进程级崩溃日志和 `stderr` 重定向辅助函数。
|
||||
|
||||
## 概述
|
||||
|
||||
`WindowsProcessDiagnostics.h` 负责编辑器启动期的两类进程级诊断措施:
|
||||
|
||||
- 安装未处理异常过滤器
|
||||
- 把 `stderr` 重定向到可执行目录下的日志文件
|
||||
|
||||
当前提供的入口包括:
|
||||
|
||||
- `GetExecutableLogPath`
|
||||
- `CrashExceptionFilter`
|
||||
- `InstallCrashExceptionFilter`
|
||||
- `RedirectStderrToExecutableLog`
|
||||
|
||||
## 当前实现
|
||||
|
||||
- 崩溃信息会追加写入 `crash.log`
|
||||
- 同时也会把崩溃摘要写到 `stderr`
|
||||
- `stderr` 会被重定向到 `stderr.log`
|
||||
- 路径基础依赖 [`GetExecutableDirectoryUtf8`](../Win32Utf8/Win32Utf8.md)
|
||||
|
||||
`Application.cpp` 会在应用初始化早期调用这些函数,因此它们更偏“进程启动保护”,而不是普通运行时 API。
|
||||
|
||||
## 设计说明
|
||||
|
||||
对图形编辑器来说,启动早期和窗口系统崩溃阶段往往最难排查。
|
||||
在这种情况下,哪怕只有一条异常码和地址,也比完全静默退出强得多。
|
||||
所以这类轻量诊断入口非常符合商业工具软件的最小可运维要求。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 只记录非常基础的异常信息,没有 minidump
|
||||
- 依赖 Windows SEH,不是跨平台方案
|
||||
- `freopen` 重定向策略比较直接,没有控制台回显复用
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Platform](../Platform.md)
|
||||
- [Win32Utf8](../Win32Utf8/Win32Utf8.md)
|
||||
- [Application](../../Application/Application.md)
|
||||
27
docs/api/XCEngine/Editor/Theme/Theme.md
Normal file
27
docs/api/XCEngine/Editor/Theme/Theme.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Theme
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `namespace utility`
|
||||
|
||||
**源文件**: `editor/src/Theme.h`
|
||||
|
||||
**描述**: 编辑器顶层主题入口,当前暴露 `ApplyUnityDarkTheme()` 用于应用 Unity 风格深色主题。
|
||||
|
||||
## 概述
|
||||
|
||||
`Theme.h` 当前很轻,只暴露一个顶层主题函数:
|
||||
|
||||
- `ApplyUnityDarkTheme()`
|
||||
|
||||
这说明当前编辑器主题系统的真正细节主要还是沉在 [UI](../UI/UI.md) 子模块里,而顶层 `Theme` 更像统一入口。
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 该头文件本身只声明接口,不承载复杂主题配置结构。
|
||||
- 命名空间采用 `inline namespace Editor` 风格,这和大多数 `XCEngine::Editor` 写法略有差异。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Editor 模块](../Editor.md)
|
||||
- [UI](../UI/UI.md)
|
||||
@@ -0,0 +1,46 @@
|
||||
# AboutEditorDialog
|
||||
|
||||
**命名空间**: `XCEngine::Editor::UI`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/UI/AboutEditorDialog.h`
|
||||
|
||||
**描述**: 绘制编辑器 About 模态弹窗。
|
||||
|
||||
## 概述
|
||||
|
||||
`DrawEditorAboutDialog` 是一个很轻量的 UI helper,用来响应主菜单 Help -> About 的弹窗请求。
|
||||
它依赖 [`DeferredPopupState`](../PopupState/PopupState.md) 控制打开时机,并在弹窗中显示:
|
||||
|
||||
- 编辑器名称
|
||||
- 简短说明文字
|
||||
- 固定日期信息
|
||||
- 当前项目路径
|
||||
|
||||
## 当前实现
|
||||
|
||||
- 弹窗 ID 固定为 `About XCEngine Editor`
|
||||
- 打开请求由 `popupState.ConsumeOpenRequest()` 驱动
|
||||
- 如果传入上下文,会显示 `context->GetProjectPath()`
|
||||
- 关闭方式只有一个 `Close` 按钮
|
||||
|
||||
## 设计说明
|
||||
|
||||
About 弹窗本身不是复杂系统,但把它收口成独立 helper 是合理的:
|
||||
|
||||
- `MainMenuActionRouter` 不需要关心弹窗内部布局
|
||||
- `MenuBar` 不需要持有具体 UI 绘制细节
|
||||
- 日后扩展版本号、版权、第三方库列表时,改动面会更集中
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 日期 `2026-03-27` 是硬编码文本,不是构建时自动注入
|
||||
- “UI Refactor in progress” 也是当前开发态说明,不是正式产品文案
|
||||
- 没有版本号、提交哈希或许可证信息
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [UI](../UI.md)
|
||||
- [PopupState](../PopupState/PopupState.md)
|
||||
- [MainMenuActionRouter](../../Actions/MainMenuActionRouter/MainMenuActionRouter.md)
|
||||
49
docs/api/XCEngine/Editor/UI/BaseTheme/BaseTheme.md
Normal file
49
docs/api/XCEngine/Editor/UI/BaseTheme/BaseTheme.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# BaseTheme
|
||||
|
||||
**命名空间**: `XCEngine::Editor::UI`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/UI/BaseTheme.h`
|
||||
|
||||
**描述**: 定义编辑器默认 Dear ImGui 主题的颜色与尺寸指标。
|
||||
|
||||
## 概述
|
||||
|
||||
`BaseTheme.h` 把编辑器默认外观拆成三层函数:
|
||||
|
||||
- `ApplyBaseThemeColors`
|
||||
- `ApplyBaseThemeMetrics`
|
||||
- `ApplyBaseTheme`
|
||||
|
||||
这让主题既能整体应用,也能在需要时分别覆盖颜色或间距。
|
||||
|
||||
## 当前实现
|
||||
|
||||
- 主题整体是偏中性、低饱和的灰色编辑器风格
|
||||
- Docking 标签、按钮、工具栏、表格、滚动条等颜色都在这里集中定义
|
||||
- 圆角、边框、间距和 padding 也都由这里设置
|
||||
- [`ImGuiSession`](../ImGuiSession/ImGuiSession.md) 和 `Theme.cpp` 会使用这组 helper
|
||||
|
||||
## 设计说明
|
||||
|
||||
商业编辑器通常不会把颜色和 spacing 散落在所有面板里,而是会先建立一套基础主题。
|
||||
这样做的好处是:
|
||||
|
||||
- 新面板默认继承统一视觉语言
|
||||
- 后续品牌化或皮肤切换时有一个集中入口
|
||||
- 设计 token 和实际 ImGui style 之间的边界更清楚
|
||||
|
||||
当前实现已经具备这个方向,虽然还不是完整可换肤系统。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 主题参数主要是硬编码值
|
||||
- 没有亮色主题或用户配置
|
||||
- 主题切换和局部覆盖机制尚未成体系
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [UI](../UI.md)
|
||||
- [StyleTokens](../StyleTokens/StyleTokens.md)
|
||||
- [ImGuiSession](../ImGuiSession/ImGuiSession.md)
|
||||
@@ -0,0 +1,38 @@
|
||||
# ConsoleFilterState
|
||||
|
||||
**命名空间**: `XCEngine::Editor::UI`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/UI/ConsoleFilterState.h`
|
||||
|
||||
**描述**: 保存 Console 面板的日志等级过滤开关。
|
||||
|
||||
## 概述
|
||||
|
||||
`ConsoleFilterState` 是一个很小的状态对象,负责决定哪些日志等级会在 Console 面板中显示。
|
||||
|
||||
当前内部维护三组布尔值:
|
||||
|
||||
- `m_showInfo`
|
||||
- `m_showWarning`
|
||||
- `m_showError`
|
||||
|
||||
## 当前实现
|
||||
|
||||
- `ShowInfo()` / `ShowWarning()` / `ShowError()` 返回可写引用,便于直接绑定工具栏切换按钮
|
||||
- `Allows()` 的等级映射如下:
|
||||
- `Verbose` / `Debug` / `Info` 归到 Info
|
||||
- `Warning` 归到 Warning
|
||||
- `Error` / `Fatal` 归到 Error
|
||||
|
||||
## 设计说明
|
||||
|
||||
这种“三档过滤”很像商业编辑器控制台的第一层筛选:先把低成本的等级过滤做好,再考虑更重的搜索、分类和标签系统。
|
||||
对于当前阶段的编辑器,这已经能显著提升日志可读性。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [UI](../UI.md)
|
||||
- [ConsoleActionRouter](../../Actions/ConsoleActionRouter/ConsoleActionRouter.md)
|
||||
- [ConsolePanel](../../panels/ConsolePanel/ConsolePanel.md)
|
||||
@@ -0,0 +1,44 @@
|
||||
# ConsoleLogFormatter
|
||||
|
||||
**命名空间**: `XCEngine::Editor::UI`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/UI/ConsoleLogFormatter.h`
|
||||
|
||||
**描述**: 把 `Debug::LogEntry` 转换为 Console 面板展示文本。
|
||||
|
||||
## 概述
|
||||
|
||||
`ConsoleLogFormatter.h` 负责把引擎日志记录格式化为用户在 Console 面板里看到的单行文本。
|
||||
当前主要入口:
|
||||
|
||||
- `ConsoleLogPrefix`
|
||||
- `BuildConsoleLogText`
|
||||
|
||||
## 当前实现
|
||||
|
||||
- `Info` / `Debug` / `Verbose` 会被统一格式化为 `[INFO]`
|
||||
- `Warning` 会格式化为 `[WARN]`
|
||||
- `Error` / `Fatal` 会格式化为 `[ERROR]`
|
||||
- 最终文本格式是:`[PREFIX] [Category] message`
|
||||
|
||||
## 设计说明
|
||||
|
||||
把格式化独立出来很有必要,因为:
|
||||
|
||||
- 日志采集层不应关心 UI 文本长什么样
|
||||
- Console 面板也不应自己拼接 category 和 level
|
||||
- 后续如果引入时间戳、来源文件、富文本高亮,只需要收敛改这一层
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 当前格式是纯文本单行
|
||||
- 没有时间戳、线程号或源码位置
|
||||
- `Debug` 和 `Verbose` 被归并到 Info,颗粒度较粗
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [UI](../UI.md)
|
||||
- [ConsoleActionRouter](../../Actions/ConsoleActionRouter/ConsoleActionRouter.md)
|
||||
- [EditorConsoleSink](../../Core/EditorConsoleSink/EditorConsoleSink.md)
|
||||
46
docs/api/XCEngine/Editor/UI/Core/Core.md
Normal file
46
docs/api/XCEngine/Editor/UI/Core/Core.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# Core
|
||||
|
||||
**命名空间**: `XCEngine::Editor::UI`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/UI/Core.h`
|
||||
|
||||
**描述**: 提供更高层 UI helper 依赖的底层 ImGui 包装,包括控制行、样式栈、弹窗包装和工具栏按钮。
|
||||
|
||||
## 概述
|
||||
|
||||
不要把这个文件和 `Editor/Core` 子模块混淆。
|
||||
`UI/Core.h` 是 UI 辅助层自己的基础工具头,许多上层 helper 都会依赖它,包括:
|
||||
|
||||
- 控件行绘制 `DrawControlRow`
|
||||
- 样式压栈 / 出栈辅助
|
||||
- 带统一 padding 的 Popup 包装
|
||||
- `ToolbarButton`
|
||||
- 当前窗口底边线绘制
|
||||
|
||||
## 当前实现
|
||||
|
||||
- `DrawControlRow` 用 ImGui table 实现“标签列 + 控件列”的双列布局
|
||||
- `BeginPopup` / `BeginPopupContextItem` / `BeginModalPopup` 都会统一应用 popup window padding
|
||||
- `BeginDisabled` / `EndDisabled` 做了条件包装,便于上层少写分支
|
||||
- 这是 [`ScalarControls`](../ScalarControls/ScalarControls.md) 与 [`VectorControls`](../VectorControls/VectorControls.md) 的基础依赖
|
||||
|
||||
## 设计说明
|
||||
|
||||
这类“内部基础 UI helper”在商业编辑器里很常见。
|
||||
原因是 ImGui 原生 API 非常灵活,但如果每个面板都直接手写 style push/pop、table 布局和 popup 细节,代码会很快失控。
|
||||
先建立一层统一的 UI Core,能让上层组件写得更稳、更少样板代码。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 这层仍然是 inline helper 集合,不是完整 widget framework
|
||||
- 样式栈安全主要依赖调用约定,没有更强的静态约束
|
||||
- 仍然明显偏向当前编辑器自己的使用场景
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [UI](../UI.md)
|
||||
- [ScalarControls](../ScalarControls/ScalarControls.md)
|
||||
- [VectorControls](../VectorControls/VectorControls.md)
|
||||
- [PropertyGrid](../PropertyGrid/PropertyGrid.md)
|
||||
35
docs/api/XCEngine/Editor/UI/DockHostStyle/DockHostStyle.md
Normal file
35
docs/api/XCEngine/Editor/UI/DockHostStyle/DockHostStyle.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# DockHostStyle
|
||||
|
||||
**命名空间**: `XCEngine::Editor::UI`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/UI/DockHostStyle.h`
|
||||
|
||||
**描述**: 为主 DockSpace 应用一组临时样式覆盖的 RAII scope。
|
||||
|
||||
## 概述
|
||||
|
||||
`DockHostStyleScope` 的角色很单一:在进入主 DockSpace 绘制前压入一组 docking 相关样式,在离开时自动恢复。
|
||||
|
||||
它主要服务于 [`DockLayoutController`](../../Layout/DockLayoutController/DockLayoutController.md)。
|
||||
|
||||
## 当前实现
|
||||
|
||||
- 构造时 `PushStyleVar` 5 次,`PushStyleColor` 7 次
|
||||
- 覆盖内容主要是:
|
||||
- Dock tab padding
|
||||
- Tab 边框与 overline
|
||||
- Tab 的普通 / hover / selected / dimmed 颜色
|
||||
- 析构时自动对称 `Pop`
|
||||
|
||||
## 设计说明
|
||||
|
||||
这是一种标准 RAII UI 封装。
|
||||
对于 ImGui 这种依赖成对 push/pop 的库,scope 包装几乎是最稳妥的工程化手段之一,能显著减少忘记恢复样式导致的串色问题。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [UI](../UI.md)
|
||||
- [StyleTokens](../StyleTokens/StyleTokens.md)
|
||||
- [DockLayoutController](../../Layout/DockLayoutController/DockLayoutController.md)
|
||||
@@ -0,0 +1,51 @@
|
||||
# ImGuiBackendBridge
|
||||
|
||||
**命名空间**: `XCEngine::Editor::UI`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/UI/ImGuiBackendBridge.h`
|
||||
|
||||
**描述**: 封装 Dear ImGui Win32 + D3D12 backend 的初始化、逐帧驱动和窗口消息桥接。
|
||||
|
||||
## 概述
|
||||
|
||||
`ImGuiBackendBridge` 是编辑器 UI 栈里很关键但很底层的一环。
|
||||
它不创建 ImGui context,也不负责布局,而是把现有 context 接到具体平台和渲染后端上。
|
||||
|
||||
当前核心职责:
|
||||
|
||||
- 初始化 `imgui_impl_win32`
|
||||
- 初始化 `imgui_impl_dx12`
|
||||
- 每帧调用 backend 的 `NewFrame`
|
||||
- 把 `ImGui::GetDrawData()` 提交到 D3D12 command list
|
||||
- 处理 Win32 消息转发
|
||||
|
||||
## 当前实现
|
||||
|
||||
- `Initialize()` 需要 `HWND`、`ID3D12Device*` 和 SRV heap
|
||||
- 默认 frame count 为 `3`
|
||||
- 默认 back buffer format 为 `DXGI_FORMAT_R8G8B8A8_UNORM`
|
||||
- `HandleWindowMessage()` 是静态 helper,直接转发给 `ImGui_ImplWin32_WndProcHandler`
|
||||
|
||||
## 设计说明
|
||||
|
||||
把 backend 绑定层单独抽出来,有两个很现实的好处:
|
||||
|
||||
- `Application` 不需要直接依赖第三方 backend 细节
|
||||
- 如果未来替换成别的渲染后端或宿主窗口层,修改点更集中
|
||||
|
||||
在商业级编辑器里,这一层通常都存在,即使名字不同,本质上也是“UI 平台绑定桥”。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 当前明确绑定 Win32 + D3D12
|
||||
- 没有重复初始化保护之外的更复杂状态机
|
||||
- 不负责 ImGui context 生命周期,那部分由 [`ImGuiSession`](../ImGuiSession/ImGuiSession.md) 管理
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [UI](../UI.md)
|
||||
- [ImGuiSession](../ImGuiSession/ImGuiSession.md)
|
||||
- [Application](../../Application/Application.md)
|
||||
- [D3D12WindowRenderer](../../Platform/D3D12WindowRenderer/D3D12WindowRenderer.md)
|
||||
38
docs/api/XCEngine/Editor/UI/ImGuiSession/ImGuiSession.md
Normal file
38
docs/api/XCEngine/Editor/UI/ImGuiSession/ImGuiSession.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# ImGuiSession
|
||||
|
||||
**命名空间**: `XCEngine::Editor::UI`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/UI/ImGuiSession.h`
|
||||
|
||||
**描述**: 管理编辑器的 ImGui 上下文、布局 ini 文件位置、基础字体配置和默认主题应用。
|
||||
|
||||
## 概述
|
||||
|
||||
`ImGuiSession` 负责的是 ImGui 自身的生命周期和持久化布局配置。
|
||||
|
||||
它当前主要做三件事:
|
||||
|
||||
- 创建/销毁 ImGui context
|
||||
- 把布局 ini 文件放到 `<project>/.xceditor/imgui_layout.ini`
|
||||
- 配置默认字体并应用基础主题
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- `Initialize(projectPath)` 会开启 `ImGuiConfigFlags_DockingEnable`。
|
||||
- 字体优先尝试加载 `C:/Windows/Fonts/msyh.ttc`,失败时回退到 ImGui 默认字体。
|
||||
- `Shutdown()` 会先保存设置,再销毁当前 context。
|
||||
- `SaveSettings()` 只在 context 存在且 ini 路径非空时生效。
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 当前字体路径写死为 Windows 字体目录。
|
||||
- 当前 ini 文件位置策略是项目局部目录,而不是全局用户目录。
|
||||
- 当前主要负责会话和基础样式,不处理平台/渲染后端桥接。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [UI](../UI.md)
|
||||
- [Application](../../Application/Application.md)
|
||||
- [Win32EditorHost](../../Platform/Win32EditorHost/Win32EditorHost.md)
|
||||
45
docs/api/XCEngine/Editor/UI/PanelChrome/PanelChrome.md
Normal file
45
docs/api/XCEngine/Editor/UI/PanelChrome/PanelChrome.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# PanelChrome
|
||||
|
||||
**命名空间**: `XCEngine::Editor::UI`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/UI/PanelChrome.h`
|
||||
|
||||
**描述**: 提供编辑器面板窗口、工具栏和内容区的 RAII 外壳。
|
||||
|
||||
## 概述
|
||||
|
||||
`PanelChrome.h` 让各个面板可以用统一方式搭建三段式结构:
|
||||
|
||||
- `PanelWindowScope`
|
||||
- `PanelToolbarScope`
|
||||
- `PanelContentScope`
|
||||
|
||||
这几乎就是当前编辑器所有面板的“标准壳层”。
|
||||
|
||||
## 当前实现
|
||||
|
||||
- 三个 scope 都在构造时 Begin,在析构时 End
|
||||
- 会统一应用窗口 padding、工具栏背景色、item spacing 等样式
|
||||
- `PanelToolbarScope` 还会在退出时绘制底部分隔线
|
||||
|
||||
从 `HierarchyPanel`、`ProjectPanel`、`ConsolePanel`、`InspectorPanel` 当前实现看,这套壳层已经成为面板 UI 的主路径。
|
||||
|
||||
## 设计说明
|
||||
|
||||
这是很典型的商业编辑器代码组织方式:
|
||||
先把窗口 chrome 标准化,再让具体面板只关心业务内容。
|
||||
|
||||
收益非常直接:
|
||||
|
||||
- 面板外观一致
|
||||
- Begin/End 对称性更安全
|
||||
- 工具栏和内容区的布局约束自然统一
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [UI](../UI.md)
|
||||
- [StyleTokens](../StyleTokens/StyleTokens.md)
|
||||
- [HierarchyPanel](../../panels/HierarchyPanel/HierarchyPanel.md)
|
||||
- [ProjectPanel](../../panels/ProjectPanel/ProjectPanel.md)
|
||||
49
docs/api/XCEngine/Editor/UI/PopupState/PopupState.md
Normal file
49
docs/api/XCEngine/Editor/UI/PopupState/PopupState.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# PopupState
|
||||
|
||||
**命名空间**: `XCEngine::Editor::UI`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/UI/PopupState.h`
|
||||
|
||||
**描述**: 提供延迟弹窗、定向弹窗、文本输入弹窗和行内重命名状态容器。
|
||||
|
||||
## 概述
|
||||
|
||||
`PopupState.h` 当前包含四类非常实用的 UI 状态辅助类型:
|
||||
|
||||
- `DeferredPopupState`
|
||||
- `TargetedPopupState<T>`
|
||||
- `TextInputPopupState<BufferCapacity>`
|
||||
- `InlineTextEditState<ItemId, BufferCapacity>`
|
||||
|
||||
它们共同解决一个问题:把 ImGui 的即时模式弹窗交互变成可维护的状态机。
|
||||
|
||||
## 当前实现
|
||||
|
||||
- `DeferredPopupState` 负责“下一帧打开弹窗”
|
||||
- `TargetedPopupState<T>` 在打开弹窗的同时绑定一个目标对象
|
||||
- `TextInputPopupState` 内置固定容量字符缓冲区,适合创建目录等对话框
|
||||
- `InlineTextEditState` 适合 Hierarchy 中的行内重命名
|
||||
|
||||
## 设计说明
|
||||
|
||||
即时模式 UI 最大的痛点之一,就是弹窗、右键菜单和重命名输入框的状态容易散。
|
||||
把这些交互状态抽成小类型,是非常划算的工程化投资:
|
||||
|
||||
- 面板类不会充满零散布尔标志和字符数组
|
||||
- 打开请求和真正 `OpenPopup()` 的时机能被清晰区分
|
||||
- 复用性很好,多个面板都能直接用
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 输入缓冲区容量是模板常量,需要调用者自己选大小
|
||||
- 没有更复杂的校验、历史记录或多字段表单状态
|
||||
- 目标对象状态主要依赖值拷贝或轻量句柄,不负责更深生命周期管理
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [UI](../UI.md)
|
||||
- [ProjectActionRouter](../../Actions/ProjectActionRouter/ProjectActionRouter.md)
|
||||
- [HierarchyActionRouter](../../Actions/HierarchyActionRouter/HierarchyActionRouter.md)
|
||||
- [AboutEditorDialog](../AboutEditorDialog/AboutEditorDialog.md)
|
||||
49
docs/api/XCEngine/Editor/UI/PropertyGrid/PropertyGrid.md
Normal file
49
docs/api/XCEngine/Editor/UI/PropertyGrid/PropertyGrid.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# PropertyGrid
|
||||
|
||||
**命名空间**: `XCEngine::Editor::UI`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/UI/PropertyGrid.h`
|
||||
|
||||
**描述**: 在 Inspector 中提供统一的属性行控件,并集成交互式撤销辅助。
|
||||
|
||||
## 概述
|
||||
|
||||
`PropertyGrid.h` 是当前 Inspector 属性编辑体验的中枢之一。
|
||||
它在 [`ScalarControls`](../ScalarControls/ScalarControls.md) 和 [`VectorControls`](../VectorControls/VectorControls.md) 之上封装了一组更贴近 Inspector 语义的 API:
|
||||
|
||||
- `DrawPropertyFloat`
|
||||
- `DrawPropertyBool`
|
||||
- `DrawPropertyColor4`
|
||||
- `DrawPropertyCombo`
|
||||
- `DrawPropertyVec3Input`
|
||||
- `ApplyPropertyChange`
|
||||
|
||||
## 当前实现
|
||||
|
||||
- 统一使用 `InspectorPropertyLabelWidth()` 作为标签列宽
|
||||
- `ApplyPropertyChange` 在字段变化时可选地调用 `undoManager->BeginInteractiveChange()`
|
||||
- 具体组件编辑器通常会先调用 `DrawProperty*`,再把结果交给 `ApplyPropertyChange`
|
||||
|
||||
## 设计说明
|
||||
|
||||
商业编辑器里的 Inspector 很少直接暴露底层控件 API,而是会先收口成属性网格层。
|
||||
这样做的好处是:
|
||||
|
||||
- 全部组件 editor 的标签宽度、排版和交互节奏统一
|
||||
- 撤销系统可以自然嵌入属性修改路径
|
||||
- 组件编辑器代码更接近“编辑语义”,而不是原始 ImGui 调用
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 目前仍然是手写属性 helper,不是基于反射的通用属性系统
|
||||
- `ApplyPropertyChange` 只负责开始交互式改动,最终收尾仍要靠 Inspector 路由层
|
||||
- 主要面向 Inspector,不是通用任意表单框架
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [UI](../UI.md)
|
||||
- [ScalarControls](../ScalarControls/ScalarControls.md)
|
||||
- [VectorControls](../VectorControls/VectorControls.md)
|
||||
- [TransformComponentEditor](../../ComponentEditors/TransformComponentEditor/TransformComponentEditor.md)
|
||||
46
docs/api/XCEngine/Editor/UI/ScalarControls/ScalarControls.md
Normal file
46
docs/api/XCEngine/Editor/UI/ScalarControls/ScalarControls.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# ScalarControls
|
||||
|
||||
**命名空间**: `XCEngine::Editor::UI`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/UI/ScalarControls.h`
|
||||
|
||||
**描述**: 提供基于双列表格布局的标量属性控件,如 float、int、bool、颜色和下拉框。
|
||||
|
||||
## 概述
|
||||
|
||||
`ScalarControls.h` 封装的是 Inspector 最基础的输入部件:
|
||||
|
||||
- `DrawFloat`
|
||||
- `DrawInt`
|
||||
- `DrawBool`
|
||||
- `DrawColor3`
|
||||
- `DrawColor4`
|
||||
- `DrawSliderFloat`
|
||||
- `DrawSliderInt`
|
||||
- `DrawCombo`
|
||||
|
||||
## 当前实现
|
||||
|
||||
- 所有控件都建立在 [`DrawControlRow`](../Core/Core.md) 之上
|
||||
- 默认列宽来自 `DefaultControlLabelWidth()`
|
||||
- 每个控件都统一使用 `##value` 作为内部 item id 后缀,并通过外层 `PushID(label)` 隔离
|
||||
|
||||
## 设计说明
|
||||
|
||||
这层的价值在于把“输入控件长什么样”从组件编辑器里抽出来。
|
||||
否则每个组件 editor 都会重复写:
|
||||
|
||||
- 两列表格
|
||||
- 标签列宽
|
||||
- `SetNextItemWidth`
|
||||
- 不同控件的 ImGui 参数模板
|
||||
|
||||
`ScalarControls` 让上层代码只保留业务字段名和少量范围参数。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [UI](../UI.md)
|
||||
- [Core](../Core/Core.md)
|
||||
- [PropertyGrid](../PropertyGrid/PropertyGrid.md)
|
||||
@@ -0,0 +1,36 @@
|
||||
# SceneStatusWidget
|
||||
|
||||
**命名空间**: `XCEngine::Editor::UI`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/UI/SceneStatusWidget.h`
|
||||
|
||||
**描述**: 在主菜单栏右侧绘制当前场景文件状态,并在悬停时提供详细提示。
|
||||
|
||||
## 概述
|
||||
|
||||
`DrawSceneStatusWidget` 是一个很小但很有价值的状态反馈组件。
|
||||
它会把当前场景的保存状态浓缩成菜单栏右侧的一段文本,并在悬停时展开 tooltip。
|
||||
|
||||
## 当前实现
|
||||
|
||||
- dirty 场景会以前缀 `* ` 标记
|
||||
- 没有场景路径时会显示 `Unsaved.xc`
|
||||
- 有路径时只显示文件名
|
||||
- tooltip 中会进一步展示:
|
||||
- 场景名
|
||||
- 文件名
|
||||
- 状态 `Modified / Saved`
|
||||
- 完整路径或“尚未保存”提示
|
||||
|
||||
## 设计说明
|
||||
|
||||
这非常符合商业编辑器的 UI 习惯:
|
||||
把高频状态压缩成轻量但始终可见的角落信息,而不是每次都让用户去打开另一个面板确认场景是否已保存。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [UI](../UI.md)
|
||||
- [MainMenuActionRouter](../../Actions/MainMenuActionRouter/MainMenuActionRouter.md)
|
||||
- [SceneManager](../../Managers/SceneManager/SceneManager.md)
|
||||
46
docs/api/XCEngine/Editor/UI/StyleTokens/StyleTokens.md
Normal file
46
docs/api/XCEngine/Editor/UI/StyleTokens/StyleTokens.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# StyleTokens
|
||||
|
||||
**命名空间**: `XCEngine::Editor::UI`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/UI/StyleTokens.h`
|
||||
|
||||
**描述**: 统一定义编辑器 UI 使用的颜色、尺寸、间距和布局 token。
|
||||
|
||||
## 概述
|
||||
|
||||
`StyleTokens.h` 是当前 UI 层的设计 token 中心。
|
||||
它集中提供了大量 inline token helper,例如:
|
||||
|
||||
- Dock 标签颜色
|
||||
- 工具栏高度与 padding
|
||||
- 资产网格尺寸
|
||||
- Inspector 标签列宽
|
||||
- 弹窗按钮尺寸
|
||||
- 向量控件按钮颜色
|
||||
- Console 状态颜色
|
||||
|
||||
## 设计说明
|
||||
|
||||
这是商业编辑器 UI 非常推荐的做法。
|
||||
不要在控件代码里到处写 `6.0f`、`0.24f`、`104.0f` 这种魔法数字,而应先抽象成 token。
|
||||
|
||||
收益包括:
|
||||
|
||||
- 调整风格时能集中修改
|
||||
- 命名本身就表达设计意图
|
||||
- 高层 widget 与具体数值解耦
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 仍然是 header inline 常量函数,而不是数据驱动主题系统
|
||||
- token 数量已经较多,后续可能需要再分层
|
||||
- 当前主要围绕唯一默认主题设计
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [UI](../UI.md)
|
||||
- [BaseTheme](../BaseTheme/BaseTheme.md)
|
||||
- [PanelChrome](../PanelChrome/PanelChrome.md)
|
||||
- [Widgets](../Widgets/Widgets.md)
|
||||
50
docs/api/XCEngine/Editor/UI/UI.md
Normal file
50
docs/api/XCEngine/Editor/UI/UI.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# UI
|
||||
|
||||
**命名空间**: `XCEngine::Editor::UI`
|
||||
|
||||
**类型**: `submodule`
|
||||
|
||||
**描述**: 编辑器 ImGui 基础设施、主题、控件与面板绘制辅助层。
|
||||
|
||||
## 概述
|
||||
|
||||
`UI` 子模块当前内容很多,但核心方向很清楚:
|
||||
|
||||
- 维护 ImGui 会话与布局文件
|
||||
- 封装统一视觉主题
|
||||
- 提供属性面板、工具栏、菜单、场景状态等 UI 辅助
|
||||
|
||||
已文档化的核心页面:
|
||||
|
||||
- [ImGuiSession](ImGuiSession/ImGuiSession.md)
|
||||
- [ImGuiBackendBridge](ImGuiBackendBridge/ImGuiBackendBridge.md)
|
||||
- [BaseTheme](BaseTheme/BaseTheme.md)
|
||||
- [StyleTokens](StyleTokens/StyleTokens.md)
|
||||
- [Core](Core/Core.md)
|
||||
- [PanelChrome](PanelChrome/PanelChrome.md)
|
||||
- [Widgets](Widgets/Widgets.md)
|
||||
- [PopupState](PopupState/PopupState.md)
|
||||
- [ScalarControls](ScalarControls/ScalarControls.md)
|
||||
- [VectorControls](VectorControls/VectorControls.md)
|
||||
- [PropertyGrid](PropertyGrid/PropertyGrid.md)
|
||||
- [DockHostStyle](DockHostStyle/DockHostStyle.md)
|
||||
- [ConsoleFilterState](ConsoleFilterState/ConsoleFilterState.md)
|
||||
- [ConsoleLogFormatter](ConsoleLogFormatter/ConsoleLogFormatter.md)
|
||||
- [SceneStatusWidget](SceneStatusWidget/SceneStatusWidget.md)
|
||||
- [AboutEditorDialog](AboutEditorDialog/AboutEditorDialog.md)
|
||||
|
||||
`UI/UI.h` 本身只是聚合入口,真正值得阅读的是这些分层 helper:
|
||||
|
||||
- `ImGuiSession + ImGuiBackendBridge` 负责上下文与后端绑定
|
||||
- `BaseTheme + StyleTokens` 负责视觉规范
|
||||
- `Core + PanelChrome + Widgets` 负责通用交互壳层
|
||||
- `ScalarControls + VectorControls + PropertyGrid` 负责 Inspector 表单体验
|
||||
|
||||
这样拆分的好处,是把 Dear ImGui 容易失控的即时模式代码收束成一套可复用部件库。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Editor 模块](../Editor.md)
|
||||
- [Application](../Application/Application.md)
|
||||
- [Platform](../Platform/Platform.md)
|
||||
- [Editor Architecture And Workflow](../../../_guides/Editor/Editor-Architecture-And-Workflow.md)
|
||||
49
docs/api/XCEngine/Editor/UI/VectorControls/VectorControls.md
Normal file
49
docs/api/XCEngine/Editor/UI/VectorControls/VectorControls.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# VectorControls
|
||||
|
||||
**命名空间**: `XCEngine::Editor::UI`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/UI/VectorControls.h`
|
||||
|
||||
**描述**: 提供向量属性的多轴输入控件,支持带重置按钮和纯输入两种模式。
|
||||
|
||||
## 概述
|
||||
|
||||
`VectorControls.h` 当前提供:
|
||||
|
||||
- `DrawVec2`
|
||||
- `DrawVec3`
|
||||
- `DrawVec3Input`
|
||||
- 更底层的 `DrawAxisFloatControls`
|
||||
|
||||
它是 Transform 类组件编辑体验的核心基础。
|
||||
|
||||
## 当前实现
|
||||
|
||||
- `DrawVec3` / `DrawVec2` 提供带轴按钮的重置式控件
|
||||
- `DrawVec3Input` 提供更紧凑的纯输入版本
|
||||
- 可选输出 `isActive`,用于让 Inspector 感知控件是否仍在持续拖拽
|
||||
- 每个轴以 `AxisFloatControlSpec` 描述
|
||||
|
||||
## 设计说明
|
||||
|
||||
相比直接把 `Vector3` 画成三个普通 `DragFloat`,这种按轴组织的控件更符合编辑器习惯:
|
||||
|
||||
- X/Y/Z 维度更直观
|
||||
- 重置按钮更利于快速归零
|
||||
- 更容易和交互式撤销衔接
|
||||
|
||||
这和 Unity Inspector 中 Transform 的体验方向是相近的,只是当前实现更轻量。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 只覆盖 `Vector2` / `Vector3`
|
||||
- 没有 quaternion、rect、bounds 等更复杂类型控件
|
||||
- 没有多对象混合值显示
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [UI](../UI.md)
|
||||
- [PropertyGrid](../PropertyGrid/PropertyGrid.md)
|
||||
- [TransformComponentEditor](../../ComponentEditors/TransformComponentEditor/TransformComponentEditor.md)
|
||||
52
docs/api/XCEngine/Editor/UI/Widgets/Widgets.md
Normal file
52
docs/api/XCEngine/Editor/UI/Widgets/Widgets.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# Widgets
|
||||
|
||||
**命名空间**: `XCEngine::Editor::UI`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/UI/Widgets.h`
|
||||
|
||||
**描述**: 提供更接近编辑器业务语义的中高层 widget,如菜单命令、层级树节点、资产格子、组件区块和对话框按钮行。
|
||||
|
||||
## 概述
|
||||
|
||||
如果说 [`Core`](../Core/Core.md) 是底层 UI 包装,那么 `Widgets.h` 就是更贴近编辑器业务的通用组件库。
|
||||
当前文件涵盖的内容很多,主要可以分成几类:
|
||||
|
||||
- 菜单与命令:`MenuCommand`、`DrawMenuScope`、`DrawMenuCommands`
|
||||
- 工具栏:搜索框、标签、切换按钮、面包屑
|
||||
- Hierarchy / Project:`DrawHierarchyNode`、`DrawAssetTile`、`DrawAssetIcon`
|
||||
- Inspector:`BeginComponentSection`
|
||||
- 对话框与 tooltip:`DrawDialogActionRow`、`BeginTitledPopup`、`BeginTitledTooltip`
|
||||
- Console:`DrawConsoleLogRow`
|
||||
|
||||
## 设计说明
|
||||
|
||||
这类文件在商业编辑器里通常非常关键,因为它决定了“多个面板是否共享同一种交互语言”。
|
||||
比如:
|
||||
|
||||
- Hierarchy 节点的点击、展开和双击
|
||||
- Project 资源网格的卡片样式
|
||||
- Inspector 组件区块的标题和右键菜单
|
||||
|
||||
如果这些都散落在各个面板里,最终 UI 行为会越来越不一致。
|
||||
|
||||
## 当前实现特征
|
||||
|
||||
- `MenuCommand` 把菜单项和分隔线统一成一个小数据结构
|
||||
- `AssetTileResult`、`HierarchyNodeResult` 等结果结构让调用方更容易写流程判断
|
||||
- 组件区块与工具栏、搜索框都已经形成可复用构件
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 仍然是 header inline helpers,而不是独立 widget 类库
|
||||
- 某些 widget 仍然高度耦合当前编辑器视觉风格
|
||||
- 还没有更高级的虚拟列表、树过滤高亮或多列资源浏览控件
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [UI](../UI.md)
|
||||
- [Core](../Core/Core.md)
|
||||
- [StyleTokens](../StyleTokens/StyleTokens.md)
|
||||
- [HierarchyPanel](../../panels/HierarchyPanel/HierarchyPanel.md)
|
||||
- [ProjectPanel](../../panels/ProjectPanel/ProjectPanel.md)
|
||||
@@ -0,0 +1,40 @@
|
||||
# SceneEditorUtils
|
||||
|
||||
**命名空间**: `XCEngine::Editor::SceneEditorUtils`
|
||||
|
||||
**类型**: `header utility set`
|
||||
|
||||
**源文件**: `editor/src/Utils/SceneEditorUtils.h`
|
||||
|
||||
**描述**: 提供场景编辑相关辅助函数,包括 UTF-8/UTF-16 转换、场景文件对话框、当前场景保存和切换确认逻辑。
|
||||
|
||||
## 概述
|
||||
|
||||
`SceneEditorUtils.h` 当前是一组围绕“场景文件工作流”组织起来的 inline 工具函数。
|
||||
|
||||
主要能力包括:
|
||||
|
||||
- UTF-8 / Wide 字符串转换
|
||||
- 场景文件名清洗
|
||||
- 打开 / 保存场景文件对话框
|
||||
- 保存当前场景
|
||||
- 切换场景前确认是否保存脏场景
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- 文件对话框走 Win32 `GetOpenFileNameW` / `GetSaveFileNameW`。
|
||||
- 默认场景目录是 `<Project>/Assets/Scenes`。
|
||||
- 支持 `.xc`,并兼容部分 legacy scene 扩展名过滤。
|
||||
- `ConfirmSceneSwitch()` 在场景脏时会弹出 `Yes / No / Cancel` 对话框。
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 当前是明显的 Windows 工具函数集合。
|
||||
- 对话框 owner window 来自 `GetActiveWindow()` / `GetForegroundWindow()`。
|
||||
- 工具函数直接依赖 `IEditorContext`,不是无状态纯工具库。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Utils](../Utils.md)
|
||||
- [SceneCommands](../../Commands/SceneCommands/SceneCommands.md)
|
||||
- [IEditorContext](../../Core/IEditorContext/IEditorContext.md)
|
||||
35
docs/api/XCEngine/Editor/Utils/UndoUtils/UndoUtils.md
Normal file
35
docs/api/XCEngine/Editor/Utils/UndoUtils/UndoUtils.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# UndoUtils
|
||||
|
||||
**命名空间**: `XCEngine::Editor::UndoUtils`
|
||||
|
||||
**类型**: `header utility set`
|
||||
|
||||
**源文件**: `editor/src/Utils/UndoUtils.h`
|
||||
|
||||
**描述**: 提供把任意编辑操作包裹进撤销历史的辅助模板函数。
|
||||
|
||||
## 概述
|
||||
|
||||
`UndoUtils.h` 当前核心就是一个模板工具:
|
||||
|
||||
- `ExecuteSceneCommand(IEditorContext&, const std::string&, Func&&)`
|
||||
|
||||
它的职责很直接:在执行某个编辑动作前后抓取状态快照,并自动把这次操作推入 undo 历史。
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- 若当前还有 pending interactive change,会先 finalize。
|
||||
- 先抓 `before` 快照。
|
||||
- 执行传入的 `func`。
|
||||
- 再抓 `after` 快照并调用 `PushCommand()`。
|
||||
- 同时兼容 `void` 返回和非 `void` 返回两种调用。
|
||||
|
||||
## 设计说明
|
||||
|
||||
这个工具很实用,因为它把“如何接入 undo”从按钮逻辑、菜单逻辑和命令逻辑里抽离出来了。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Utils](../Utils.md)
|
||||
- [IUndoManager](../../Core/IUndoManager/IUndoManager.md)
|
||||
- [SceneCommands](../../Commands/SceneCommands/SceneCommands.md)
|
||||
26
docs/api/XCEngine/Editor/Utils/Utils.md
Normal file
26
docs/api/XCEngine/Editor/Utils/Utils.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Utils
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `submodule`
|
||||
|
||||
**描述**: 编辑器辅助函数层,当前主要围绕场景切换确认、文件对话框和撤销相关辅助展开。
|
||||
|
||||
## 概述
|
||||
|
||||
当前 `Utils` 目录包括:
|
||||
|
||||
- `SceneEditorUtils.h`
|
||||
- `UndoUtils.h`
|
||||
|
||||
这些工具函数本身不构成一个很强的对象模型,但它们支撑了:
|
||||
|
||||
- 场景打开/保存对话框
|
||||
- 场景切换确认
|
||||
- 撤销与交互式修改配合
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Editor 模块](../Editor.md)
|
||||
- [Commands](../Commands/Commands.md)
|
||||
- [Core](../Core/Core.md)
|
||||
33
docs/api/XCEngine/Editor/panels/ConsolePanel/ConsolePanel.md
Normal file
33
docs/api/XCEngine/Editor/panels/ConsolePanel/ConsolePanel.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# ConsolePanel
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/panels/ConsolePanel.h`
|
||||
|
||||
**描述**: 控制台面板,负责根据过滤状态显示编辑器日志,并绘制日志工具栏。
|
||||
|
||||
## 概述
|
||||
|
||||
`ConsolePanel` 当前围绕两块逻辑展开:
|
||||
|
||||
- 一个 `UI::ConsoleFilterState`
|
||||
- 一个 `EditorConsoleSink` 日志源
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- 构造时面板名为 `"Console"`。
|
||||
- `Render()` 里会先绘制工具栏,再绘制日志滚动区域。
|
||||
- 日志行实际绘制和工具栏动作主要委托给 `Actions` 层。
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 当前控制台面板自身很薄,大部分行为来自 action router 和 `EditorConsoleSink`。
|
||||
- 当前过滤状态存在面板实例内,不是全局日志视图配置对象。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [panels](../panels.md)
|
||||
- [Actions](../../Actions/Actions.md)
|
||||
- [UI](../../UI/UI.md)
|
||||
@@ -0,0 +1,28 @@
|
||||
# GameViewPanel
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/panels/GameViewPanel.h`
|
||||
|
||||
**描述**: Game 视图面板,占位承载 Game 窗口并标记动作路由焦点。
|
||||
|
||||
## 概述
|
||||
|
||||
当前 `GameViewPanel` 和 [SceneViewPanel](../SceneViewPanel/SceneViewPanel.md) 一样,都属于轻量占位面板。
|
||||
|
||||
它目前主要做两件事:
|
||||
|
||||
- 以 `"Game"` 为名字打开一个面板窗口
|
||||
- 在该窗口激活时通知 `Actions` 层观察焦点路由
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 当前没有真正的 runtime frame 嵌入或 play mode 画面输出。
|
||||
- 它现在更像未来 Game View 能力的承载容器。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [panels](../panels.md)
|
||||
- [Actions](../../Actions/Actions.md)
|
||||
@@ -0,0 +1,50 @@
|
||||
# HierarchyPanel
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class + enum class`
|
||||
|
||||
**源文件**: `editor/src/panels/HierarchyPanel.h`
|
||||
|
||||
**描述**: 层级面板,负责显示场景对象树、搜索、排序、拖放层级调整以及内联重命名。
|
||||
|
||||
## 概述
|
||||
|
||||
`HierarchyPanel` 是当前编辑器里交互最丰富的面板之一。
|
||||
|
||||
它当前承载的功能包括:
|
||||
|
||||
- 订阅选择变化和重命名请求事件
|
||||
- 层级树渲染
|
||||
- 搜索过滤
|
||||
- 排序选项
|
||||
- 拖拽层级调整
|
||||
- 右键上下文菜单
|
||||
- 内联重命名
|
||||
|
||||
头文件里还定义了:
|
||||
|
||||
- `enum class SortMode { Name, ComponentCount, TransformFirst }`
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- `OnAttach()` 会订阅 `SelectionChangedEvent` 和 `EntityRenameRequestedEvent`。
|
||||
- 搜索过滤当前按名字子串匹配,并递归检查子节点。
|
||||
- 排序支持:
|
||||
- `Name`
|
||||
- `ComponentCount`
|
||||
- `TransformFirst`
|
||||
- 双击节点会进入重命名状态。
|
||||
- 背景点击、右键菜单和拖放逻辑主要委托给 `Actions` 层。
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 当前排序和过滤都在 UI 渲染阶段直接对实体列表做处理。
|
||||
- `TransformFirst` 排序实际上是“有 Transform 的对象优先”,而不是更复杂的 transform-aware hierarchy order。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [panels](../panels.md)
|
||||
- [SelectionManager](../../Core/SelectionManager/SelectionManager.md)
|
||||
- [SceneManager](../../Managers/SceneManager/SceneManager.md)
|
||||
- [EditorEvents](../../Core/EditorEvents/EditorEvents.md)
|
||||
@@ -0,0 +1,41 @@
|
||||
# InspectorPanel
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/panels/InspectorPanel.h`
|
||||
|
||||
**描述**: 检查器面板,负责显示当前选中对象的组件列表,并通过 `ComponentEditorRegistry` 渲染对应组件编辑 UI。
|
||||
|
||||
## 概述
|
||||
|
||||
`InspectorPanel` 是组件编辑系统的主要承载面板。
|
||||
|
||||
它当前的工作流是:
|
||||
|
||||
1. 订阅选择变化。
|
||||
2. 根据当前选中实体拿到 `GameObject`。
|
||||
3. 遍历其组件。
|
||||
4. 通过 `ComponentEditorRegistry` 找到对应的 `IComponentEditor`。
|
||||
5. 渲染每个组件 section。
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- 没有选中对象时会显示 empty state。
|
||||
- 若选中对象已失效,也会显示 empty state。
|
||||
- `RenderGameObject()` 里会绘制 Add Component 按钮和弹窗。
|
||||
- 若某个组件没有已注册 editor,会显示提示文本。
|
||||
- 组件 editor 返回 `true` 时,当前会标记场景为 dirty。
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 当前 Inspector 完全依赖组件 editor 注册表,不是基于反射自动生成 UI。
|
||||
- 组件 section 的移除、添加和交互式编辑配合主要通过 `Actions` 层完成。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [panels](../panels.md)
|
||||
- [IComponentEditor](../../ComponentEditors/IComponentEditor/IComponentEditor.md)
|
||||
- [ComponentEditorRegistry](../../ComponentEditors/ComponentEditorRegistry/ComponentEditorRegistry.md)
|
||||
- [SceneManager](../../Managers/SceneManager/SceneManager.md)
|
||||
31
docs/api/XCEngine/Editor/panels/MenuBar/MenuBar.md
Normal file
31
docs/api/XCEngine/Editor/panels/MenuBar/MenuBar.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# MenuBar
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/panels/MenuBar.h`
|
||||
|
||||
**描述**: 编辑器主菜单栏面板,负责绘制主菜单、处理菜单相关快捷键,并承载 About 弹窗状态。
|
||||
|
||||
## 概述
|
||||
|
||||
`MenuBar` 当前是最薄的一类面板:它自己不直接承载大量业务,而是把菜单相关逻辑委托给 `Actions` 层。
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- 构造时面板名为 `"MenuBar"`。
|
||||
- `Render()` 当前会:
|
||||
- 调用 `HandleMenuBarShortcuts(*m_context)`
|
||||
- 调用 `DrawMainMenuBar(*m_context, m_aboutPopup)`
|
||||
- 调用 `DrawMainMenuOverlays(m_context, m_aboutPopup)`
|
||||
|
||||
## 设计说明
|
||||
|
||||
这是合理的分层:菜单面板负责“我是菜单栏这个容器”,动作与绘制细节则交给 action router。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [panels](../panels.md)
|
||||
- [ActionBinding](../../Actions/ActionBinding/ActionBinding.md)
|
||||
- [SceneCommands](../../Commands/SceneCommands/SceneCommands.md)
|
||||
43
docs/api/XCEngine/Editor/panels/Panel/Panel.md
Normal file
43
docs/api/XCEngine/Editor/panels/Panel/Panel.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Panel
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class (abstract base)`
|
||||
|
||||
**源文件**: `editor/src/panels/Panel.h`
|
||||
|
||||
**描述**: 所有编辑器面板的抽象基类,定义 attach/detach/update/event/render 生命周期与上下文注入能力。
|
||||
|
||||
## 概述
|
||||
|
||||
`Panel` 当前是所有具体面板的共同基类。
|
||||
|
||||
它提供:
|
||||
|
||||
- 名称
|
||||
- 开关状态
|
||||
- `IEditorContext*`
|
||||
- 一组可覆写生命周期钩子
|
||||
|
||||
## 关键接口
|
||||
|
||||
| 方法 | 作用 |
|
||||
|------|------|
|
||||
| `OnAttach()` / `OnDetach()` | 面板挂接与拆除。 |
|
||||
| `OnUpdate(float)` | 每帧更新。 |
|
||||
| `OnEvent(void*)` | 处理外部事件。 |
|
||||
| `Render()` | 渲染面板 UI。 |
|
||||
| `GetName()` | 获取面板名。 |
|
||||
| `IsOpen()` / `SetOpen()` / `Toggle()` | 控制开关状态。 |
|
||||
| `SetContext()` / `GetContext()` / `HasContext()` | 管理编辑器上下文。 |
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- `SetContext()` 当前带断言,不允许重复设置上下文。
|
||||
- 事件参数是 `void*`,说明当前事件分发层还比较宽松,没有统一强类型 UI 事件基类。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [panels](../panels.md)
|
||||
- [PanelCollection](../PanelCollection/PanelCollection.md)
|
||||
- [IEditorContext](../../Core/IEditorContext/IEditorContext.md)
|
||||
@@ -0,0 +1,37 @@
|
||||
# PanelCollection
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/panels/PanelCollection.h`
|
||||
|
||||
**描述**: 负责持有一组 `Panel` 对象,并统一处理上下文注入、attach/detach、update、event dispatch 和 render。
|
||||
|
||||
## 概述
|
||||
|
||||
`PanelCollection` 是当前面板系统的统一调度容器。
|
||||
|
||||
它提供:
|
||||
|
||||
- `SetContext()` 给全部面板注入上下文
|
||||
- `Emplace<TPanel>()` 构造并注册新面板
|
||||
- `AttachAll()` / `DetachAll()`
|
||||
- `UpdateAll()` / `DispatchEvent()` / `RenderAll()`
|
||||
- `Clear()`
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- 面板以 `std::unique_ptr<Panel>` 保存在内部数组中。
|
||||
- `SetContext()` 会把上下文补发给之前尚未绑定上下文的面板。
|
||||
- `DetachAll()` 当前按逆序拆除面板,这个细节是合理的。
|
||||
|
||||
## 设计说明
|
||||
|
||||
在当前编辑器规模下,用一个简单容器统一驱动所有面板生命周期,比引入更复杂的窗口管理框架更务实。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [panels](../panels.md)
|
||||
- [Panel](../Panel/Panel.md)
|
||||
- [EditorWorkspace](../../Core/EditorWorkspace/EditorWorkspace.md)
|
||||
41
docs/api/XCEngine/Editor/panels/ProjectPanel/ProjectPanel.md
Normal file
41
docs/api/XCEngine/Editor/panels/ProjectPanel/ProjectPanel.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# ProjectPanel
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/panels/ProjectPanel.h`
|
||||
|
||||
**描述**: 项目面板,负责展示当前资产目录、面包屑导航、搜索、资产瓦片交互以及文件夹创建与上下文菜单。
|
||||
|
||||
## 概述
|
||||
|
||||
`ProjectPanel` 当前是 [ProjectManager](../../Managers/ProjectManager/ProjectManager.md) 的主要 UI 前端。
|
||||
|
||||
它负责:
|
||||
|
||||
- 初始化项目浏览器
|
||||
- 绘制工具栏与面包屑
|
||||
- 绘制资产网格
|
||||
- 搜索过滤
|
||||
- 资产点击、打开、拖放和右键菜单
|
||||
- 空白区域上下文菜单
|
||||
- 新建文件夹弹窗
|
||||
|
||||
## 当前实现说明
|
||||
|
||||
- `Initialize(projectPath)` 直接调用 `m_context->GetProjectManager().Initialize(projectPath)`。
|
||||
- `Render()` 中资产会按自适应列数排成网格。
|
||||
- 搜索当前按名字子串过滤。
|
||||
- 资产图标当前按 `isFolder` 区分 folder/file,再配合 action/router 决定交互。
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 当前搜索是前端过滤,不是索引搜索。
|
||||
- 资产预览目前还是轻量瓦片,不是完整导入数据库浏览器。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [panels](../panels.md)
|
||||
- [ProjectManager](../../Managers/ProjectManager/ProjectManager.md)
|
||||
- [AssetItem](../../Core/AssetItem/AssetItem.md)
|
||||
@@ -0,0 +1,28 @@
|
||||
# SceneViewPanel
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `class`
|
||||
|
||||
**源文件**: `editor/src/panels/SceneViewPanel.h`
|
||||
|
||||
**描述**: 场景视图面板,占位承载 Scene 视图窗口并标记动作路由焦点。
|
||||
|
||||
## 概述
|
||||
|
||||
当前 `SceneViewPanel` 还很轻。
|
||||
|
||||
它目前主要做两件事:
|
||||
|
||||
- 以 `"Scene"` 为名字打开一个面板窗口
|
||||
- 在该窗口激活时通知 `Actions` 层观察焦点路由
|
||||
|
||||
## 当前实现边界
|
||||
|
||||
- 当前没有真正的编辑器视口渲染、相机操控或 gizmo 逻辑。
|
||||
- 它现在更像后续 Scene View 功能的面板占位入口。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [panels](../panels.md)
|
||||
- [Actions](../../Actions/Actions.md)
|
||||
37
docs/api/XCEngine/Editor/panels/panels.md
Normal file
37
docs/api/XCEngine/Editor/panels/panels.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# panels
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `submodule`
|
||||
|
||||
**描述**: 编辑器面板基础设施与具体面板集合,当前以 `Panel` 基类和 `PanelCollection` 容器为核心。
|
||||
|
||||
## 概述
|
||||
|
||||
`editor/src/panels` 目录当前包含菜单栏、Hierarchy、SceneView、GameView、Inspector、Console、Project 等具体面板。
|
||||
|
||||
当前这组文档当前覆盖了:
|
||||
|
||||
- [Panel](Panel/Panel.md)
|
||||
- [PanelCollection](PanelCollection/PanelCollection.md)
|
||||
- [MenuBar](MenuBar/MenuBar.md)
|
||||
- [HierarchyPanel](HierarchyPanel/HierarchyPanel.md)
|
||||
- [ProjectPanel](ProjectPanel/ProjectPanel.md)
|
||||
- [InspectorPanel](InspectorPanel/InspectorPanel.md)
|
||||
- [ConsolePanel](ConsolePanel/ConsolePanel.md)
|
||||
- [SceneViewPanel](SceneViewPanel/SceneViewPanel.md)
|
||||
- [GameViewPanel](GameViewPanel/GameViewPanel.md)
|
||||
|
||||
## 设计说明
|
||||
|
||||
当前面板系统的思路很直接:
|
||||
|
||||
- 每个面板继承 `Panel`
|
||||
- 生命周期由 `PanelCollection` 统一调度
|
||||
- 上下文通过 `IEditorContext*` 注入到每个面板
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Editor 模块](../Editor.md)
|
||||
- [EditorWorkspace](../Core/EditorWorkspace/EditorWorkspace.md)
|
||||
- [Layers](../Layers/Layers.md)
|
||||
@@ -4,11 +4,13 @@
|
||||
|
||||
**类型**: `module-root`
|
||||
|
||||
**描述**: 与 `engine/include/XCEngine` 平行的 API 文档根目录。
|
||||
**描述**: 以 `XCEngine` 为统一入口的 API 文档根目录;主体与 `engine/include/XCEngine` 平行,同时承载独立编辑器应用 `editor/src` 的 `Editor` API 文档。
|
||||
|
||||
## 概览
|
||||
|
||||
该目录与 `XCEngine` 对应的 public headers 保持平行,用于承载唯一的 canonical API 文档入口。
|
||||
该目录的主体与 `engine/include/XCEngine` 对应的 public headers 保持平行,用于承载唯一的 canonical API 文档入口。
|
||||
|
||||
额外地,当前也在这里统一收纳了 [Editor](Editor/Editor.md) 应用层文档,用于描述独立编辑器程序 `editor/src/**` 的 API 与架构。
|
||||
|
||||
## 子目录
|
||||
|
||||
@@ -16,10 +18,12 @@
|
||||
- [Components](Components/Components.md)
|
||||
- [Core](Core/Core.md)
|
||||
- [Debug](Debug/Debug.md)
|
||||
- [Editor](Editor/Editor.md)
|
||||
- [Input](Input/Input.md)
|
||||
- [Memory](Memory/Memory.md)
|
||||
- [Platform](Platform/Platform.md)
|
||||
- [RHI](RHI/RHI.md)
|
||||
- [Rendering](Rendering/Rendering.md)
|
||||
- [Resources](Resources/Resources.md)
|
||||
- [Scene](Scene/Scene.md)
|
||||
- [Threading](Threading/Threading.md)
|
||||
|
||||
153
docs/api/_guides/Editor/Editor-Architecture-And-Workflow.md
Normal file
153
docs/api/_guides/Editor/Editor-Architecture-And-Workflow.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# Editor Architecture And Workflow
|
||||
|
||||
## 先建立正确心智模型
|
||||
|
||||
`docs/api/XCEngine/Editor/**` 对应的是编辑器应用层,而不是引擎运行时 public API。
|
||||
它更接近 Unity Editor、Unreal Editor 这类“工具壳层”的实现文档,而不是给游戏逻辑直接链接的稳定 SDK。
|
||||
|
||||
可以把当前架构粗略理解成六层:
|
||||
|
||||
1. `Platform` 负责 Win32 进程、窗口消息、崩溃日志和 D3D12 窗口渲染。
|
||||
2. `UI` 负责 ImGui 会话、主题、面板 chrome 和通用控件。
|
||||
3. `Core` 负责上下文、事件总线、动作路由、选择和撤销。
|
||||
4. `Managers` 负责项目和场景服务的默认实现。
|
||||
5. `Actions` 负责把按钮、菜单和快捷键翻译成“可执行动作”。
|
||||
6. `Commands` 负责真正修改项目、场景、实体和组件状态。
|
||||
|
||||
`panels`、`Layout` 和 `ComponentEditors` 则横向挂在这些层之间:
|
||||
|
||||
- `panels` 是用户直接看到的编辑器窗口
|
||||
- `Layout` 决定这些窗口如何 Dock
|
||||
- `ComponentEditors` 决定 Inspector 如何按组件类型渲染
|
||||
|
||||
## 为什么要拆成 Actions 和 Commands
|
||||
|
||||
这是当前 Editor 文档里最重要的一条设计线。
|
||||
如果不拆,最常见的退化就是:
|
||||
|
||||
- 菜单栏自己写一套保存逻辑
|
||||
- 快捷键自己写一套删除逻辑
|
||||
- 右键菜单再写一套复制粘贴逻辑
|
||||
|
||||
时间一长,你会得到三个入口、三份行为、三种 bug。
|
||||
|
||||
当前实现把它拆成:
|
||||
|
||||
- `EditorActions` 定义动作名称、快捷键和启用状态
|
||||
- `ActionRouting` 和 `EditorActionRoute` 决定当前动作应该作用在哪个面板上下文
|
||||
- `*ActionRouter` 负责具体入口的 UI 交互
|
||||
- `Commands` 负责真正修改状态
|
||||
|
||||
这就是商业编辑器很常见的分层方式。Unity 用户会很容易理解这件事:
|
||||
菜单项、快捷键和 Inspector 按钮看起来入口不同,但背后应该落到同一条编辑命令语义上。
|
||||
|
||||
## 为什么 Inspector 不走完全反射,而是组件专用 editor
|
||||
|
||||
当前 Inspector 采用的是:
|
||||
|
||||
- `IComponentEditor`
|
||||
- `ComponentEditorRegistry`
|
||||
- `TransformComponentEditor`
|
||||
- `CameraComponentEditor`
|
||||
- `LightComponentEditor`
|
||||
|
||||
这条路线更接近 Unity 的 custom inspector / property drawer 思想,而不是“把所有字段自动反射成一张表”。
|
||||
|
||||
这样做的好处是:
|
||||
|
||||
- 条件式 UI 更自然,例如 Camera 的透视/正交分支
|
||||
- 撤销、字段分组和按钮布局更可控
|
||||
- 组件编辑体验可以按照组件语义而不是成员变量顺序组织
|
||||
|
||||
代价是:
|
||||
|
||||
- 每个组件都要写专门 editor
|
||||
- 通用自动化程度较低
|
||||
|
||||
但对当前阶段的编辑器,这是更稳妥的商业级做法,因为它优先保证可解释性和可维护性。
|
||||
|
||||
## 从一次用户点击看整条链路
|
||||
|
||||
以 Hierarchy 中“右键删除实体”为例,当前主路径大致是:
|
||||
|
||||
1. `HierarchyPanel` 负责渲染树和弹出上下文菜单。
|
||||
2. `HierarchyActionRouter` 负责把“Delete”菜单项映射为删除动作。
|
||||
3. `EntityCommands::DeleteEntity` 负责发起真正的场景修改。
|
||||
4. `UndoUtils` 和 `UndoManager` 负责录制撤销快照。
|
||||
5. `SceneManager` 负责真正删除实体并发布事件。
|
||||
6. `SelectionManager`、`InspectorPanel` 等其它系统通过事件感知更新。
|
||||
|
||||
这条链路说明了一个核心原则:
|
||||
面板不应该直接修改场景,面板应该只描述用户意图。
|
||||
|
||||
## 为什么当前大量使用小型 helper header
|
||||
|
||||
很多用户第一次看会觉得:为什么 `UI`、`Actions`、`Commands` 下有这么多小头文件?
|
||||
|
||||
这是 Dear ImGui 风格编辑器常见的工程取舍。原因很现实:
|
||||
|
||||
- 即时模式 UI 很容易把一切都塞进 `Render()`
|
||||
- 一旦不拆 helper,单个面板 cpp 会迅速膨胀
|
||||
- 把“交互语义”“控件语义”“状态容器”拆成小头文件后,代码更容易复用和迁移
|
||||
|
||||
所以这些 header 不是“碎片化设计”,而是在对抗 UI 工具代码天然容易失控的问题。
|
||||
|
||||
## 当前架构最像 Unity 的部分
|
||||
|
||||
- `HierarchyPanel / ProjectPanel / InspectorPanel / ConsolePanel` 这组窗口组合很像 Unity Editor 的基本工作区。
|
||||
- `ComponentEditors` 很像 Unity 的 custom inspector。
|
||||
- `SceneCommands + UndoManager` 很像 Unity 编辑态里对场景对象做结构修改时的命令路径。
|
||||
|
||||
## 当前又明显还不像 Unity 的地方
|
||||
|
||||
- 当前只有 Windows + D3D12 + ImGui 主路径。
|
||||
- Project 面板还不是完整资产导入系统。
|
||||
- Inspector 还没有脚本组件、搜索式 Add Component、批量多选混合值等成熟体验。
|
||||
- Console 还是轻量列表,不是完整诊断中心。
|
||||
|
||||
所以更准确的表述应该是:
|
||||
它采用了很多 Unity 风格的编辑器设计理念,但当前实现仍然是一个处在快速重构期的、轻量但方向正确的编辑器壳层。
|
||||
|
||||
## 如果你要继续扩展这个编辑器,推荐从哪层下手
|
||||
|
||||
### 新增一个全新面板
|
||||
|
||||
通常顺序是:
|
||||
|
||||
1. 在 `panels` 下建立新 Panel 类型。
|
||||
2. 优先复用 `PanelWindowScope / PanelToolbarScope / PanelContentScope`。
|
||||
3. 如果面板需要上下文敏感快捷键,再接入 `ActionRouting`。
|
||||
4. 如果面板要真正修改数据,优先写 `Commands`,不要直接改 manager。
|
||||
|
||||
### 给 Inspector 新增一个组件编辑器
|
||||
|
||||
推荐顺序是:
|
||||
|
||||
1. 实现新的 `IComponentEditor`。
|
||||
2. 在 `ComponentEditorRegistry` 注册。
|
||||
3. 优先通过 `PropertyGrid`、`ScalarControls`、`VectorControls` 组装 UI。
|
||||
4. 涉及结构性变化时,通过 `ComponentCommands` 或新的命令 helper 进入撤销链。
|
||||
|
||||
### 给菜单栏或快捷键新增动作
|
||||
|
||||
推荐顺序是:
|
||||
|
||||
1. 在 `EditorActions` 中先定义动作描述。
|
||||
2. 在合适的 `*ActionRouter` 中接 UI 入口。
|
||||
3. 真实变更落到 `Commands`。
|
||||
4. 如果动作取决于当前焦点面板,再考虑是否需要新的 `EditorActionRoute`。
|
||||
|
||||
## 当前文档应该怎么读
|
||||
|
||||
如果你是第一次接触这一套代码,推荐按这个顺序:
|
||||
|
||||
1. [Editor](../../XCEngine/Editor/Editor.md)
|
||||
2. [Application](../../XCEngine/Editor/Application/Application.md)
|
||||
3. [Core](../../XCEngine/Editor/Core/Core.md)
|
||||
4. [Actions](../../XCEngine/Editor/Actions/Actions.md)
|
||||
5. [Commands](../../XCEngine/Editor/Commands/Commands.md)
|
||||
6. [panels](../../XCEngine/Editor/panels/panels.md)
|
||||
7. [ComponentEditors](../../XCEngine/Editor/ComponentEditors/ComponentEditors.md)
|
||||
8. [UI](../../XCEngine/Editor/UI/UI.md)
|
||||
|
||||
这能让你先看清系统骨架,再下钻到具体类型页,而不是一开始就陷进某个 helper 文件里。
|
||||
Reference in New Issue
Block a user