Files
XCEngine/editor/src/Actions/EditActionRouter.h

221 lines
7.9 KiB
C++

#pragma once
#include "ActionBinding.h"
#include "EditorActions.h"
#include "Commands/EntityCommands.h"
#include "Commands/ProjectCommands.h"
#include "Core/EventBus.h"
#include "Core/EditorEvents.h"
#include "Core/IEditorContext.h"
#include "UI/UI.h"
namespace XCEngine {
namespace Editor {
namespace Actions {
struct EditActionTarget {
EditorActionRoute route = EditorActionRoute::None;
::XCEngine::Components::GameObject* selectedGameObject = nullptr;
AssetItemPtr selectedAssetItem;
};
inline EditActionTarget ResolveEditActionTarget(IEditorContext& context) {
EditActionTarget target;
target.route = context.GetActiveActionRoute();
target.selectedGameObject = GetSelectedGameObject(context);
target.selectedAssetItem = GetSelectedAssetItem(context);
return target;
}
inline ActionBinding MakeDisabledPasteAction() {
return MakeAction("Paste", "Ctrl+V", false, false);
}
inline ActionBinding MakeOpenSelectionAction(const EditActionTarget& target) {
return MakeOpenAssetAction(target.route == EditorActionRoute::Project && Commands::CanOpenAsset(target.selectedAssetItem));
}
inline ActionBinding MakeDeleteSelectionAction(const EditActionTarget& target) {
if (target.route == EditorActionRoute::Project) {
return MakeDeleteAssetAction(target.selectedAssetItem != nullptr);
}
return MakeDeleteEntityAction(target.route == EditorActionRoute::Hierarchy ? target.selectedGameObject : nullptr);
}
inline ActionBinding MakeRenameSelectionAction(const EditActionTarget& target) {
return MakeRenameEntityAction(target.route == EditorActionRoute::Hierarchy ? target.selectedGameObject : nullptr);
}
inline ActionBinding MakeCopySelectionAction(const EditActionTarget& target) {
return MakeCopyEntityAction(target.route == EditorActionRoute::Hierarchy ? target.selectedGameObject : nullptr);
}
inline ActionBinding MakePasteSelectionAction(IEditorContext& context, const EditActionTarget& target) {
return target.route == EditorActionRoute::Hierarchy ? MakePasteEntityAction(context) : MakeDisabledPasteAction();
}
inline ActionBinding MakeDuplicateSelectionAction(const EditActionTarget& target) {
return MakeDuplicateEntityAction(target.route == EditorActionRoute::Hierarchy ? target.selectedGameObject : nullptr);
}
inline ActionBinding MakeNavigateBackSelectionAction(IEditorContext& context, const EditActionTarget& target) {
const bool enabled =
target.route == EditorActionRoute::Project && context.GetProjectManager().CanNavigateBack();
return MakeNavigateBackAction(enabled);
}
inline bool ExecuteOpenSelection(IEditorContext& context, const EditActionTarget& target) {
if (target.route != EditorActionRoute::Project || !Commands::CanOpenAsset(target.selectedAssetItem)) {
return false;
}
Commands::OpenAsset(context, target.selectedAssetItem);
return true;
}
inline bool ExecuteDeleteSelection(IEditorContext& context, const EditActionTarget& target) {
if (target.route == EditorActionRoute::Project) {
auto& projectManager = context.GetProjectManager();
if (!target.selectedAssetItem) {
return false;
}
return Commands::DeleteAsset(projectManager, target.selectedAssetItem);
}
if (target.route != EditorActionRoute::Hierarchy || !target.selectedGameObject) {
return false;
}
Commands::DeleteEntity(context, target.selectedGameObject->GetID());
return true;
}
inline bool ExecuteNavigateBackSelection(IEditorContext& context, const EditActionTarget& target) {
if (target.route != EditorActionRoute::Project) {
return false;
}
auto& projectManager = context.GetProjectManager();
if (!projectManager.CanNavigateBack()) {
return false;
}
projectManager.NavigateBack();
return true;
}
inline bool ExecuteRenameSelection(IEditorContext& context, const EditActionTarget& target) {
if (target.route != EditorActionRoute::Hierarchy || !target.selectedGameObject) {
return false;
}
context.GetEventBus().Publish(EntityRenameRequestedEvent{ target.selectedGameObject->GetID() });
return true;
}
inline bool ExecuteCopySelection(IEditorContext& context, const EditActionTarget& target) {
if (target.route != EditorActionRoute::Hierarchy || !target.selectedGameObject) {
return false;
}
Commands::CopyEntity(context, target.selectedGameObject->GetID());
return true;
}
inline bool ExecutePasteSelection(IEditorContext& context, const EditActionTarget& target) {
if (target.route != EditorActionRoute::Hierarchy || !context.GetSceneManager().HasClipboardData()) {
return false;
}
Commands::PasteEntity(context, target.selectedGameObject ? target.selectedGameObject->GetID() : 0);
return true;
}
inline bool ExecuteDuplicateSelection(IEditorContext& context, const EditActionTarget& target) {
if (target.route != EditorActionRoute::Hierarchy || !target.selectedGameObject) {
return false;
}
Commands::DuplicateEntity(context, target.selectedGameObject->GetID());
return true;
}
inline void HandleEditShortcuts(IEditorContext& context, const ShortcutContext& shortcutContext) {
const EditActionTarget target = ResolveEditActionTarget(context);
HandleShortcut(MakeNavigateBackSelectionAction(context, target), shortcutContext, [&]() {
ExecuteNavigateBackSelection(context, target);
});
HandleShortcut(MakeOpenSelectionAction(target), shortcutContext, [&]() {
ExecuteOpenSelection(context, target);
});
HandleShortcut(MakeDeleteSelectionAction(target), shortcutContext, [&]() {
ExecuteDeleteSelection(context, target);
});
HandleShortcut(MakeRenameSelectionAction(target), shortcutContext, [&]() {
ExecuteRenameSelection(context, target);
});
HandleShortcut(MakeCopySelectionAction(target), shortcutContext, [&]() {
ExecuteCopySelection(context, target);
});
HandleShortcut(MakePasteSelectionAction(context, target), shortcutContext, [&]() {
ExecutePasteSelection(context, target);
});
HandleShortcut(MakeDuplicateSelectionAction(target), shortcutContext, [&]() {
ExecuteDuplicateSelection(context, target);
});
}
inline void DrawProjectEditActions(IEditorContext& context, const EditActionTarget& target) {
DrawMenuAction(MakeOpenSelectionAction(target), [&]() {
ExecuteOpenSelection(context, target);
});
DrawMenuAction(MakeDeleteSelectionAction(target), [&]() {
ExecuteDeleteSelection(context, target);
});
DrawMenuSeparator();
DrawMenuAction(MakeNavigateBackSelectionAction(context, target), [&]() {
ExecuteNavigateBackSelection(context, target);
});
}
inline void DrawHierarchyEditActions(IEditorContext& context, const EditActionTarget& target) {
DrawMenuAction(MakeCutAction(false), []() {});
DrawMenuAction(MakeCopySelectionAction(target), [&]() {
ExecuteCopySelection(context, target);
});
DrawMenuAction(MakePasteSelectionAction(context, target), [&]() {
ExecutePasteSelection(context, target);
});
DrawMenuAction(MakeDuplicateSelectionAction(target), [&]() {
ExecuteDuplicateSelection(context, target);
});
DrawMenuAction(MakeDeleteSelectionAction(target), [&]() {
ExecuteDeleteSelection(context, target);
});
DrawMenuAction(MakeRenameSelectionAction(target), [&]() {
ExecuteRenameSelection(context, target);
});
}
inline void DrawEditActions(IEditorContext& context) {
const EditActionTarget target = ResolveEditActionTarget(context);
DrawMenuAction(MakeUndoAction(context), [&]() { context.GetUndoManager().Undo(); });
DrawMenuAction(MakeRedoAction(context), [&]() { context.GetUndoManager().Redo(); });
DrawMenuSeparator();
if (target.route == EditorActionRoute::Project) {
DrawProjectEditActions(context, target);
return;
}
DrawHierarchyEditActions(context, target);
}
} // namespace Actions
} // namespace Editor
} // namespace XCEngine