2026-03-27 14:40:29 +08:00
|
|
|
|
# ProjectActionRouter
|
|
|
|
|
|
|
|
|
|
|
|
**命名空间**: `XCEngine::Editor::Actions`
|
|
|
|
|
|
|
|
|
|
|
|
**类型**: `header-helper`
|
|
|
|
|
|
|
|
|
|
|
|
**源文件**: `editor/src/Actions/ProjectActionRouter.h`
|
|
|
|
|
|
|
2026-04-08 16:07:03 +08:00
|
|
|
|
**描述**: Project 面板交互路由 helper,负责资源拖拽载荷、资源打开、返回上级导航、背景清选和项目项右键菜单目标建立。
|
2026-03-27 14:40:29 +08:00
|
|
|
|
|
|
|
|
|
|
## 概述
|
|
|
|
|
|
|
2026-04-08 16:07:03 +08:00
|
|
|
|
`ProjectActionRouter` 当前不是一个“大而全的项目面板行为中心”,而是一组比较薄的交互 helper。
|
2026-03-27 14:40:29 +08:00
|
|
|
|
|
2026-04-08 16:07:03 +08:00
|
|
|
|
它的职责边界和 [ProjectPanel](../../panels/ProjectPanel/ProjectPanel.md) / [ProjectCommands](../../Commands/ProjectCommands/ProjectCommands.md) 的分工很明确:
|
2026-03-27 14:40:29 +08:00
|
|
|
|
|
2026-04-08 16:07:03 +08:00
|
|
|
|
- `ProjectPanel` 负责目录树、面包屑、资源网格和上下文菜单的具体布局
|
|
|
|
|
|
- `ProjectActionRouter` 负责把少量通用交互翻译成稳定动作
|
|
|
|
|
|
- `ProjectCommands` 负责真正修改项目内容
|
2026-03-27 14:40:29 +08:00
|
|
|
|
|
2026-04-08 16:07:03 +08:00
|
|
|
|
因此当前这页不应再描述成“承载创建文件夹弹窗、重命名、复制粘贴等完整资源 workflow”。那些语义如今主要已经在面板层和命令层展开了。
|
2026-03-27 14:40:29 +08:00
|
|
|
|
|
2026-04-08 16:07:03 +08:00
|
|
|
|
## 当前覆盖的能力
|
|
|
|
|
|
|
|
|
|
|
|
按 `editor/src/Actions/ProjectActionRouter.h` 当前实现,这组 helper 主要覆盖:
|
|
|
|
|
|
|
|
|
|
|
|
- 资源拖拽 payload 协议
|
|
|
|
|
|
- 判断某个资源是否正处于拖拽中
|
|
|
|
|
|
- 打开资源
|
|
|
|
|
|
- 工具栏返回上级导航
|
|
|
|
|
|
- Project 背景左键清选
|
|
|
|
|
|
- Project 空白区右键菜单请求
|
|
|
|
|
|
- Project 资源项右键菜单目标记录
|
|
|
|
|
|
|
|
|
|
|
|
## 关键 helper
|
|
|
|
|
|
|
|
|
|
|
|
### 拖拽载荷
|
|
|
|
|
|
|
|
|
|
|
|
当前项目资源拖拽协议固定为:
|
|
|
|
|
|
|
|
|
|
|
|
- `ProjectAssetPayloadType() -> "ASSET_ITEM"`
|
|
|
|
|
|
|
|
|
|
|
|
拖拽数据本身不是 `AssetItemPtr`,而是:
|
|
|
|
|
|
|
|
|
|
|
|
- `item->fullPath.c_str()`
|
|
|
|
|
|
|
|
|
|
|
|
也就是说,当前 Project 拖拽协议使用的是“资源全路径字符串载荷”,而不是对象指针。
|
|
|
|
|
|
|
|
|
|
|
|
这和 Hierarchy 里的实体拖拽不同,也更适合项目资源这种需要跨刷新定位的对象。
|
|
|
|
|
|
|
|
|
|
|
|
相关 helper 包括:
|
|
|
|
|
|
|
|
|
|
|
|
- `GetDraggedProjectAssetPath()`
|
|
|
|
|
|
- `IsProjectAssetBeingDragged(item)`
|
|
|
|
|
|
- `BeginProjectAssetDrag(item, iconKind)`
|
|
|
|
|
|
|
|
|
|
|
|
### 打开资源
|
|
|
|
|
|
|
|
|
|
|
|
`OpenProjectAsset(...)` 当前只是一个薄封装:
|
|
|
|
|
|
|
|
|
|
|
|
1. 先调用 `Commands::CanOpenAsset(item)`
|
|
|
|
|
|
2. 合法时再调用 `Commands::OpenAsset(context, item)`
|
|
|
|
|
|
|
|
|
|
|
|
因此“什么资源可以打开”的判定权并不在 action router,而在命令层。
|
|
|
|
|
|
|
|
|
|
|
|
### 返回上级
|
|
|
|
|
|
|
|
|
|
|
|
`DrawProjectNavigateBackAction(...)` 当前负责:
|
|
|
|
|
|
|
|
|
|
|
|
- 基于 `projectManager.CanNavigateBack()` 计算按钮是否启用
|
|
|
|
|
|
- 点击后调用 `projectManager.NavigateBack()`
|
|
|
|
|
|
|
|
|
|
|
|
这是 Project 工具栏里少量直接在 action 层完成的导航动作之一。
|
|
|
|
|
|
|
|
|
|
|
|
### 背景清选
|
|
|
|
|
|
|
|
|
|
|
|
`HandleProjectBackgroundPrimaryClick(...)` 的当前语义是:
|
|
|
|
|
|
|
|
|
|
|
|
- 只有窗口悬停
|
|
|
|
|
|
- 左键点击
|
|
|
|
|
|
- 当前没有悬停任意 item
|
|
|
|
|
|
- 当前不处于 rename 状态
|
|
|
|
|
|
|
|
|
|
|
|
时,才调用:
|
|
|
|
|
|
|
|
|
|
|
|
- `projectManager.ClearSelection()`
|
|
|
|
|
|
|
|
|
|
|
|
这让 ProjectPanel 可以在“空白处点一下取消选中”和“行内重命名期间不要误清选”之间保持一致行为。
|
|
|
|
|
|
|
|
|
|
|
|
### 右键菜单目标
|
|
|
|
|
|
|
|
|
|
|
|
当前 router 提供了两组与上下文菜单相关的 helper:
|
|
|
|
|
|
|
|
|
|
|
|
- `RequestProjectEmptyContextPopup(...)`
|
|
|
|
|
|
- `HandleProjectItemContextRequest(...)`
|
|
|
|
|
|
|
|
|
|
|
|
前者只负责在空白区域右键时请求 popup;后者则会:
|
|
|
|
|
|
|
|
|
|
|
|
1. 先把该项设为当前选中资源
|
|
|
|
|
|
2. 再把它写入 [`TargetedPopupState<AssetItemPtr>`](../../UI/PopupState/TargetedPopupState.md)
|
|
|
|
|
|
|
|
|
|
|
|
这样项目项右键菜单在打开时,选择状态和 popup target 是同步的。
|
|
|
|
|
|
|
|
|
|
|
|
## 当前没有负责什么
|
|
|
|
|
|
|
|
|
|
|
|
为了避免和旧文档混淆,需要明确当前这组 helper **不** 负责:
|
|
|
|
|
|
|
|
|
|
|
|
- 资源重命名提交
|
|
|
|
|
|
- 创建文件夹 / 创建材质
|
|
|
|
|
|
- 删除资源
|
|
|
|
|
|
- 移动资源到目录
|
|
|
|
|
|
- 复制路径
|
|
|
|
|
|
|
|
|
|
|
|
这些行为如今分别在:
|
|
|
|
|
|
|
|
|
|
|
|
- [ProjectPanel](../../panels/ProjectPanel/ProjectPanel.md)
|
|
|
|
|
|
- [ProjectCommands](../../Commands/ProjectCommands/ProjectCommands.md)
|
|
|
|
|
|
|
|
|
|
|
|
中完成。
|
2026-03-27 14:40:29 +08:00
|
|
|
|
|
|
|
|
|
|
## 设计说明
|
|
|
|
|
|
|
2026-04-08 16:07:03 +08:00
|
|
|
|
当前 `ProjectActionRouter` 的设计取向是合理的,因为它只保留那些真正适合抽成共享交互协议的部分:
|
2026-03-27 14:40:29 +08:00
|
|
|
|
|
2026-04-08 16:07:03 +08:00
|
|
|
|
- 拖拽 payload
|
|
|
|
|
|
- 打开资源入口
|
|
|
|
|
|
- 背景清选
|
|
|
|
|
|
- 右键菜单目标建立
|
2026-03-27 14:40:29 +08:00
|
|
|
|
|
2026-04-08 16:07:03 +08:00
|
|
|
|
而把更强业务语义留给 ProjectPanel 和命令层。这比把所有资源 workflow 都堆进一个 router header 更容易维护。
|
2026-03-27 14:40:29 +08:00
|
|
|
|
|
|
|
|
|
|
## 当前限制
|
|
|
|
|
|
|
2026-04-08 16:07:03 +08:00
|
|
|
|
- 当前动作层本身不提供资源复制 / 粘贴协议。
|
|
|
|
|
|
- `iconKind` 参数在 `BeginProjectAssetDrag(...)` 里当前没有实际参与绘制,拖拽预览被关闭。
|
|
|
|
|
|
- 这组 helper 仍然假设调用点位于 Project 面板即时模式 UI 主循环中。
|
2026-03-27 14:40:29 +08:00
|
|
|
|
|
|
|
|
|
|
## 相关文档
|
|
|
|
|
|
|
|
|
|
|
|
- [Actions](../Actions.md)
|
|
|
|
|
|
- [ProjectPanel](../../panels/ProjectPanel/ProjectPanel.md)
|
|
|
|
|
|
- [ProjectCommands](../../Commands/ProjectCommands/ProjectCommands.md)
|
|
|
|
|
|
- [PopupState](../../UI/PopupState/PopupState.md)
|