Refactor editor UI architecture
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
#include "Actions/EditorActions.h"
|
||||
#include "Commands/EntityCommands.h"
|
||||
#include "HierarchyPanel.h"
|
||||
#include "Core/IEditorContext.h"
|
||||
#include "Core/ISceneManager.h"
|
||||
@@ -5,25 +7,13 @@
|
||||
#include "Core/IUndoManager.h"
|
||||
#include "Core/EditorEvents.h"
|
||||
#include "Core/EventBus.h"
|
||||
#include "UI/Core.h"
|
||||
#include "UI/PanelChrome.h"
|
||||
#include "Utils/UndoUtils.h"
|
||||
#include <XCEngine/Core/Math/Vector3.h>
|
||||
#include <XCEngine/Core/Math/Quaternion.h>
|
||||
#include <XCEngine/Components/CameraComponent.h>
|
||||
#include <XCEngine/Components/LightComponent.h>
|
||||
#include "UI/UI.h"
|
||||
#include <imgui.h>
|
||||
#include <cstring>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Editor {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr float kHierarchyToolbarHeight = 34.0f;
|
||||
|
||||
} // namespace
|
||||
|
||||
HierarchyPanel::HierarchyPanel() : Panel("Hierarchy") {
|
||||
}
|
||||
|
||||
@@ -76,9 +66,9 @@ void HierarchyPanel::Render() {
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopupContextWindow("HierarchyContextMenu", ImGuiPopupFlags_MouseButtonRight)) {
|
||||
if (UI::BeginPopupContextWindow("HierarchyContextMenu", ImGuiPopupFlags_MouseButtonRight)) {
|
||||
RenderCreateMenu(nullptr);
|
||||
ImGui::EndPopup();
|
||||
UI::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::InvisibleButton("##DragTarget", ImVec2(-1, -1));
|
||||
@@ -86,20 +76,7 @@ void HierarchyPanel::Render() {
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("ENTITY_PTR")) {
|
||||
::XCEngine::Components::GameObject* sourceGameObject = *(::XCEngine::Components::GameObject**)payload->Data;
|
||||
if (sourceGameObject && sourceGameObject->GetParent() != nullptr) {
|
||||
auto& sceneManager = m_context->GetSceneManager();
|
||||
UndoUtils::ExecuteSceneCommand(*m_context, "Reparent Entity", [&]() {
|
||||
auto* srcTransform = sourceGameObject->GetTransform();
|
||||
Math::Vector3 worldPos = srcTransform->GetPosition();
|
||||
Math::Quaternion worldRot = srcTransform->GetRotation();
|
||||
Math::Vector3 worldScale = srcTransform->GetScale();
|
||||
|
||||
sceneManager.MoveEntity(sourceGameObject->GetID(), 0);
|
||||
|
||||
srcTransform->SetPosition(worldPos);
|
||||
srcTransform->SetRotation(worldRot);
|
||||
srcTransform->SetScale(worldScale);
|
||||
sceneManager.MarkSceneDirty();
|
||||
});
|
||||
Commands::ReparentEntityPreserveWorldTransform(*m_context, sourceGameObject, 0);
|
||||
}
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
@@ -108,36 +85,47 @@ void HierarchyPanel::Render() {
|
||||
}
|
||||
|
||||
void HierarchyPanel::RenderSearchBar() {
|
||||
UI::PanelToolbarScope toolbar("HierarchyToolbar", kHierarchyToolbarHeight);
|
||||
UI::PanelToolbarScope toolbar("HierarchyToolbar", UI::StandardPanelToolbarHeight());
|
||||
if (!toolbar.IsOpen()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(7.0f, 4.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 2.0f);
|
||||
|
||||
const float buttonWidth = 26.0f;
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - buttonWidth - 4.0f);
|
||||
ImGui::InputTextWithHint("##Search", "Search hierarchy", m_searchBuffer, sizeof(m_searchBuffer));
|
||||
const float buttonWidth = UI::HierarchyOverflowButtonWidth();
|
||||
UI::ToolbarSearchField(
|
||||
"##Search",
|
||||
"Search hierarchy",
|
||||
m_searchBuffer,
|
||||
sizeof(m_searchBuffer),
|
||||
buttonWidth + UI::ToolbarSearchTrailingSpacing());
|
||||
ImGui::SameLine();
|
||||
if (UI::ToolbarButton("...", false, ImVec2(buttonWidth, 0.0f))) {
|
||||
ImGui::OpenPopup("HierarchyOptions");
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopup("HierarchyOptions")) {
|
||||
if (ImGui::MenuItem("Sort By Name", nullptr, m_sortMode == SortMode::Name)) {
|
||||
m_sortMode = SortMode::Name;
|
||||
}
|
||||
if (ImGui::MenuItem("Sort By Component Count", nullptr, m_sortMode == SortMode::ComponentCount)) {
|
||||
m_sortMode = SortMode::ComponentCount;
|
||||
}
|
||||
if (ImGui::MenuItem("Transform First", nullptr, m_sortMode == SortMode::TransformFirst)) {
|
||||
m_sortMode = SortMode::TransformFirst;
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
if (UI::BeginPopup("HierarchyOptions")) {
|
||||
const UI::MenuCommand commands[] = {
|
||||
UI::MenuCommand::Action("Sort By Name", nullptr, m_sortMode == SortMode::Name),
|
||||
UI::MenuCommand::Action("Sort By Component Count", nullptr, m_sortMode == SortMode::ComponentCount),
|
||||
UI::MenuCommand::Action("Transform First", nullptr, m_sortMode == SortMode::TransformFirst)
|
||||
};
|
||||
|
||||
ImGui::PopStyleVar(2);
|
||||
UI::DrawMenuCommands(commands, [&](size_t index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
m_sortMode = SortMode::Name;
|
||||
break;
|
||||
case 1:
|
||||
m_sortMode = SortMode::ComponentCount;
|
||||
break;
|
||||
case 2:
|
||||
m_sortMode = SortMode::TransformFirst;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
UI::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
void HierarchyPanel::RenderEntity(::XCEngine::Components::GameObject* gameObject, const std::string& filter) {
|
||||
@@ -148,20 +136,7 @@ void HierarchyPanel::RenderEntity(::XCEngine::Components::GameObject* gameObject
|
||||
}
|
||||
|
||||
ImGui::PushID(static_cast<int>(gameObject->GetID()));
|
||||
|
||||
ImGuiTreeNodeFlags flags =
|
||||
ImGuiTreeNodeFlags_OpenOnArrow |
|
||||
ImGuiTreeNodeFlags_SpanAvailWidth |
|
||||
ImGuiTreeNodeFlags_FramePadding;
|
||||
|
||||
if (gameObject->GetChildCount() == 0) {
|
||||
flags |= ImGuiTreeNodeFlags_Leaf;
|
||||
}
|
||||
|
||||
if (m_context->GetSelectionManager().IsSelected(gameObject->GetID())) {
|
||||
flags |= ImGuiTreeNodeFlags_Selected;
|
||||
}
|
||||
|
||||
|
||||
if (m_renaming && m_renamingEntity == gameObject) {
|
||||
if (m_renameJustStarted) {
|
||||
ImGui::SetKeyboardFocusHere();
|
||||
@@ -170,30 +145,22 @@ void HierarchyPanel::RenderEntity(::XCEngine::Components::GameObject* gameObject
|
||||
|
||||
ImGui::SetNextItemWidth(-1);
|
||||
if (ImGui::InputText("##Rename", m_renameBuffer, sizeof(m_renameBuffer), ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) {
|
||||
if (strlen(m_renameBuffer) > 0) {
|
||||
UndoUtils::ExecuteSceneCommand(*m_context, "Rename Entity", [&]() {
|
||||
m_context->GetSceneManager().RenameEntity(gameObject->GetID(), m_renameBuffer);
|
||||
});
|
||||
}
|
||||
m_renaming = false;
|
||||
m_renamingEntity = nullptr;
|
||||
CommitRename();
|
||||
}
|
||||
|
||||
if (!ImGui::IsItemActive() && ImGui::IsMouseClicked(0)) {
|
||||
if (strlen(m_renameBuffer) > 0) {
|
||||
UndoUtils::ExecuteSceneCommand(*m_context, "Rename Entity", [&]() {
|
||||
m_context->GetSceneManager().RenameEntity(gameObject->GetID(), m_renameBuffer);
|
||||
});
|
||||
}
|
||||
m_renaming = false;
|
||||
m_renamingEntity = nullptr;
|
||||
|
||||
if (ImGui::IsItemActive() && ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
||||
CancelRename();
|
||||
} else if (!ImGui::IsItemActive() && ImGui::IsMouseClicked(0)) {
|
||||
CommitRename();
|
||||
}
|
||||
} else {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4.0f, 3.0f));
|
||||
bool isOpen = ImGui::TreeNodeEx((void*)gameObject->GetUUID(), flags, "%s", gameObject->GetName().c_str());
|
||||
ImGui::PopStyleVar();
|
||||
const UI::HierarchyNodeResult node = UI::DrawHierarchyNode(
|
||||
(void*)gameObject->GetUUID(),
|
||||
gameObject->GetName().c_str(),
|
||||
m_context->GetSelectionManager().IsSelected(gameObject->GetID()),
|
||||
gameObject->GetChildCount() == 0);
|
||||
|
||||
if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) {
|
||||
if (node.clicked) {
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (io.KeyCtrl) {
|
||||
if (!m_context->GetSelectionManager().IsSelected(gameObject->GetID())) {
|
||||
@@ -204,25 +171,22 @@ void HierarchyPanel::RenderEntity(::XCEngine::Components::GameObject* gameObject
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) {
|
||||
m_renaming = true;
|
||||
m_renamingEntity = gameObject;
|
||||
strcpy_s(m_renameBuffer, gameObject->GetName().c_str());
|
||||
m_renameJustStarted = true;
|
||||
if (node.doubleClicked) {
|
||||
BeginRename(gameObject);
|
||||
}
|
||||
|
||||
HandleDragDrop(gameObject);
|
||||
|
||||
if (ImGui::BeginPopupContextItem("EntityContextMenu")) {
|
||||
if (UI::BeginPopupContextItem("EntityContextMenu")) {
|
||||
RenderContextMenu(gameObject);
|
||||
ImGui::EndPopup();
|
||||
UI::EndPopup();
|
||||
}
|
||||
|
||||
if (isOpen) {
|
||||
if (node.open) {
|
||||
for (size_t i = 0; i < gameObject->GetChildCount(); i++) {
|
||||
RenderEntity(gameObject->GetChild(i), filter);
|
||||
}
|
||||
ImGui::TreePop();
|
||||
UI::EndHierarchyNode();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,132 +194,87 @@ void HierarchyPanel::RenderEntity(::XCEngine::Components::GameObject* gameObject
|
||||
}
|
||||
|
||||
void HierarchyPanel::RenderContextMenu(::XCEngine::Components::GameObject* gameObject) {
|
||||
auto& sceneManager = m_context->GetSceneManager();
|
||||
auto& selectionManager = m_context->GetSelectionManager();
|
||||
|
||||
if (ImGui::BeginMenu("Create")) {
|
||||
if (UI::DrawMenuScope("Create", [&]() {
|
||||
RenderCreateMenu(gameObject);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (gameObject != nullptr && ImGui::MenuItem("Create Child")) {
|
||||
UndoUtils::ExecuteSceneCommand(*m_context, "Create Child", [&]() {
|
||||
auto* child = sceneManager.CreateEntity("GameObject", gameObject);
|
||||
selectionManager.SetSelectedEntity(child->GetID());
|
||||
});
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (gameObject != nullptr && gameObject->GetParent() != nullptr) {
|
||||
if (ImGui::MenuItem("Detach from Parent")) {
|
||||
UndoUtils::ExecuteSceneCommand(*m_context, "Reparent Entity", [&]() {
|
||||
sceneManager.MoveEntity(gameObject->GetID(), 0);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Rename", "F2")) {
|
||||
if (gameObject) {
|
||||
m_renaming = true;
|
||||
m_renamingEntity = gameObject;
|
||||
strcpy_s(m_renameBuffer, gameObject->GetName().c_str());
|
||||
m_renameJustStarted = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Delete", "Delete")) {
|
||||
UndoUtils::ExecuteSceneCommand(*m_context, "Delete Entity", [&]() {
|
||||
sceneManager.DeleteEntity(gameObject->GetID());
|
||||
});
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem("Copy", "Ctrl+C")) {
|
||||
sceneManager.CopyEntity(gameObject->GetID());
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Paste", "Ctrl+V", false, sceneManager.HasClipboardData())) {
|
||||
UndoUtils::ExecuteSceneCommand(*m_context, "Paste Entity", [&]() {
|
||||
const uint64_t newId = sceneManager.PasteEntity(gameObject->GetID());
|
||||
if (newId != 0) {
|
||||
selectionManager.SetSelectedEntity(newId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Duplicate", "Ctrl+D")) {
|
||||
uint64_t newId = 0;
|
||||
UndoUtils::ExecuteSceneCommand(*m_context, "Duplicate Entity", [&]() {
|
||||
newId = sceneManager.DuplicateEntity(gameObject->GetID());
|
||||
if (newId != 0) {
|
||||
selectionManager.SetSelectedEntity(newId);
|
||||
}
|
||||
});
|
||||
if (newId != 0) {
|
||||
}
|
||||
})) {
|
||||
}
|
||||
|
||||
Actions::DrawMenuAction(Actions::MakeCreateChildEntityAction(gameObject), [&]() {
|
||||
Commands::CreateEmptyEntity(*m_context, gameObject, "Create Child", "GameObject");
|
||||
});
|
||||
Actions::DrawMenuSeparator();
|
||||
Actions::DrawMenuAction(Actions::MakeDetachEntityAction(gameObject), [&]() {
|
||||
Commands::DetachEntity(*m_context, gameObject);
|
||||
});
|
||||
Actions::DrawMenuAction(Actions::MakeRenameEntityAction(gameObject), [&]() {
|
||||
BeginRename(gameObject);
|
||||
});
|
||||
Actions::DrawMenuAction(Actions::MakeDeleteEntityAction(gameObject), [&]() {
|
||||
Commands::DeleteEntity(*m_context, gameObject->GetID());
|
||||
});
|
||||
Actions::DrawMenuSeparator();
|
||||
Actions::DrawMenuAction(Actions::MakeCopyEntityAction(gameObject), [&]() {
|
||||
Commands::CopyEntity(*m_context, gameObject->GetID());
|
||||
});
|
||||
Actions::DrawMenuAction(Actions::MakePasteEntityAction(*m_context), [&]() {
|
||||
Commands::PasteEntity(*m_context, gameObject->GetID());
|
||||
});
|
||||
Actions::DrawMenuAction(Actions::MakeDuplicateEntityAction(gameObject), [&]() {
|
||||
Commands::DuplicateEntity(*m_context, gameObject->GetID());
|
||||
});
|
||||
}
|
||||
|
||||
void HierarchyPanel::RenderCreateMenu(::XCEngine::Components::GameObject* parent) {
|
||||
auto& sceneManager = m_context->GetSceneManager();
|
||||
auto& selectionManager = m_context->GetSelectionManager();
|
||||
|
||||
if (ImGui::MenuItem("Empty Object")) {
|
||||
UndoUtils::ExecuteSceneCommand(*m_context, "Create Entity", [&]() {
|
||||
auto* newEntity = sceneManager.CreateEntity("GameObject", parent);
|
||||
selectionManager.SetSelectedEntity(newEntity->GetID());
|
||||
});
|
||||
Actions::DrawMenuAction(Actions::MakeCreateEmptyEntityAction(), [&]() {
|
||||
Commands::CreateEmptyEntity(*m_context, parent, "Create Entity", "GameObject");
|
||||
});
|
||||
Actions::DrawMenuSeparator();
|
||||
Actions::DrawMenuAction(Actions::MakeCreateCameraEntityAction(), [&]() {
|
||||
Commands::CreateCameraEntity(*m_context, parent);
|
||||
});
|
||||
Actions::DrawMenuAction(Actions::MakeCreateLightEntityAction(), [&]() {
|
||||
Commands::CreateLightEntity(*m_context, parent);
|
||||
});
|
||||
Actions::DrawMenuSeparator();
|
||||
Actions::DrawMenuAction(Actions::MakeCreateCubeEntityAction(), [&]() {
|
||||
Commands::CreateEmptyEntity(*m_context, parent, "Create Cube", "Cube");
|
||||
});
|
||||
Actions::DrawMenuAction(Actions::MakeCreateSphereEntityAction(), [&]() {
|
||||
Commands::CreateEmptyEntity(*m_context, parent, "Create Sphere", "Sphere");
|
||||
});
|
||||
Actions::DrawMenuAction(Actions::MakeCreatePlaneEntityAction(), [&]() {
|
||||
Commands::CreateEmptyEntity(*m_context, parent, "Create Plane", "Plane");
|
||||
});
|
||||
}
|
||||
|
||||
void HierarchyPanel::BeginRename(::XCEngine::Components::GameObject* gameObject) {
|
||||
if (!gameObject) {
|
||||
CancelRename();
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem("Camera")) {
|
||||
UndoUtils::ExecuteSceneCommand(*m_context, "Create Camera", [&]() {
|
||||
auto* newEntity = sceneManager.CreateEntity("Camera", parent);
|
||||
newEntity->AddComponent<::XCEngine::Components::CameraComponent>();
|
||||
sceneManager.MarkSceneDirty();
|
||||
selectionManager.SetSelectedEntity(newEntity->GetID());
|
||||
});
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Light")) {
|
||||
UndoUtils::ExecuteSceneCommand(*m_context, "Create Light", [&]() {
|
||||
auto* newEntity = sceneManager.CreateEntity("Light", parent);
|
||||
newEntity->AddComponent<::XCEngine::Components::LightComponent>();
|
||||
sceneManager.MarkSceneDirty();
|
||||
selectionManager.SetSelectedEntity(newEntity->GetID());
|
||||
});
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem("Cube")) {
|
||||
UndoUtils::ExecuteSceneCommand(*m_context, "Create Cube", [&]() {
|
||||
auto* newEntity = sceneManager.CreateEntity("Cube", parent);
|
||||
selectionManager.SetSelectedEntity(newEntity->GetID());
|
||||
});
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Sphere")) {
|
||||
UndoUtils::ExecuteSceneCommand(*m_context, "Create Sphere", [&]() {
|
||||
auto* newEntity = sceneManager.CreateEntity("Sphere", parent);
|
||||
selectionManager.SetSelectedEntity(newEntity->GetID());
|
||||
});
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Plane")) {
|
||||
UndoUtils::ExecuteSceneCommand(*m_context, "Create Plane", [&]() {
|
||||
auto* newEntity = sceneManager.CreateEntity("Plane", parent);
|
||||
selectionManager.SetSelectedEntity(newEntity->GetID());
|
||||
});
|
||||
|
||||
m_renaming = true;
|
||||
m_renamingEntity = gameObject;
|
||||
strcpy_s(m_renameBuffer, gameObject->GetName().c_str());
|
||||
m_renameJustStarted = true;
|
||||
}
|
||||
|
||||
void HierarchyPanel::CommitRename() {
|
||||
if (m_renamingEntity && strlen(m_renameBuffer) > 0) {
|
||||
Commands::RenameEntity(*m_context, m_renamingEntity->GetID(), m_renameBuffer);
|
||||
}
|
||||
|
||||
CancelRename();
|
||||
}
|
||||
|
||||
void HierarchyPanel::CancelRename() {
|
||||
m_renaming = false;
|
||||
m_renamingEntity = nullptr;
|
||||
m_renameBuffer[0] = '\0';
|
||||
m_renameJustStarted = false;
|
||||
}
|
||||
|
||||
void HierarchyPanel::HandleDragDrop(::XCEngine::Components::GameObject* gameObject) {
|
||||
auto& sceneManager = m_context->GetSceneManager();
|
||||
|
||||
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) {
|
||||
ImGui::SetDragDropPayload("ENTITY_PTR", &gameObject, sizeof(::XCEngine::Components::GameObject*));
|
||||
ImGui::Text("%s", gameObject->GetName().c_str());
|
||||
@@ -365,32 +284,8 @@ void HierarchyPanel::HandleDragDrop(::XCEngine::Components::GameObject* gameObje
|
||||
if (ImGui::BeginDragDropTarget()) {
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("ENTITY_PTR")) {
|
||||
::XCEngine::Components::GameObject* sourceGameObject = *(::XCEngine::Components::GameObject**)payload->Data;
|
||||
if (sourceGameObject != gameObject && sourceGameObject != nullptr) {
|
||||
bool isValidMove = true;
|
||||
::XCEngine::Components::GameObject* checkParent = gameObject;
|
||||
while (checkParent != nullptr) {
|
||||
if (checkParent == sourceGameObject) {
|
||||
isValidMove = false;
|
||||
break;
|
||||
}
|
||||
checkParent = checkParent->GetParent();
|
||||
}
|
||||
|
||||
if (isValidMove) {
|
||||
UndoUtils::ExecuteSceneCommand(*m_context, "Reparent Entity", [&]() {
|
||||
auto* srcTransform = sourceGameObject->GetTransform();
|
||||
Math::Vector3 worldPos = srcTransform->GetPosition();
|
||||
Math::Quaternion worldRot = srcTransform->GetRotation();
|
||||
Math::Vector3 worldScale = srcTransform->GetScale();
|
||||
|
||||
sceneManager.MoveEntity(sourceGameObject->GetID(), gameObject->GetID());
|
||||
|
||||
srcTransform->SetPosition(worldPos);
|
||||
srcTransform->SetRotation(worldRot);
|
||||
srcTransform->SetScale(worldScale);
|
||||
sceneManager.MarkSceneDirty();
|
||||
});
|
||||
}
|
||||
if (sourceGameObject != gameObject && Commands::CanReparentEntity(sourceGameObject, gameObject)) {
|
||||
Commands::ReparentEntityPreserveWorldTransform(*m_context, sourceGameObject, gameObject->GetID());
|
||||
}
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
@@ -404,53 +299,21 @@ void HierarchyPanel::HandleKeyboardShortcuts() {
|
||||
::XCEngine::Components::GameObject* selectedGameObject = sceneManager.GetEntity(selectionManager.GetSelectedEntity());
|
||||
|
||||
if (ImGui::IsWindowFocused()) {
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_Delete)) {
|
||||
if (selectedGameObject != nullptr) {
|
||||
UndoUtils::ExecuteSceneCommand(*m_context, "Delete Entity", [&]() {
|
||||
sceneManager.DeleteEntity(selectedGameObject->GetID());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_F2)) {
|
||||
if (selectedGameObject != nullptr) {
|
||||
m_renaming = true;
|
||||
m_renamingEntity = selectedGameObject;
|
||||
strcpy_s(m_renameBuffer, selectedGameObject->GetName().c_str());
|
||||
m_renameJustStarted = true;
|
||||
}
|
||||
}
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (io.KeyCtrl) {
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_C)) {
|
||||
if (selectedGameObject != nullptr) {
|
||||
sceneManager.CopyEntity(selectedGameObject->GetID());
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_V)) {
|
||||
if (sceneManager.HasClipboardData()) {
|
||||
UndoUtils::ExecuteSceneCommand(*m_context, "Paste Entity", [&]() {
|
||||
const uint64_t newId = sceneManager.PasteEntity(selectedGameObject ? selectedGameObject->GetID() : 0);
|
||||
if (newId != 0) {
|
||||
selectionManager.SetSelectedEntity(newId);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_D)) {
|
||||
if (selectedGameObject != nullptr) {
|
||||
UndoUtils::ExecuteSceneCommand(*m_context, "Duplicate Entity", [&]() {
|
||||
const uint64_t newId = sceneManager.DuplicateEntity(selectedGameObject->GetID());
|
||||
if (newId != 0) {
|
||||
selectionManager.SetSelectedEntity(newId);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Actions::HandleShortcut(Actions::MakeDeleteEntityAction(selectedGameObject), [&]() {
|
||||
Commands::DeleteEntity(*m_context, selectedGameObject->GetID());
|
||||
});
|
||||
Actions::HandleShortcut(Actions::MakeRenameEntityAction(selectedGameObject), [&]() {
|
||||
BeginRename(selectedGameObject);
|
||||
});
|
||||
Actions::HandleShortcut(Actions::MakeCopyEntityAction(selectedGameObject), [&]() {
|
||||
Commands::CopyEntity(*m_context, selectedGameObject->GetID());
|
||||
});
|
||||
Actions::HandleShortcut(Actions::MakePasteEntityAction(*m_context), [&]() {
|
||||
Commands::PasteEntity(*m_context, selectedGameObject ? selectedGameObject->GetID() : 0);
|
||||
});
|
||||
Actions::HandleShortcut(Actions::MakeDuplicateEntityAction(selectedGameObject), [&]() {
|
||||
Commands::DuplicateEntity(*m_context, selectedGameObject->GetID());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user