From fc06a4babcc75b6827c569fa59b71209997e67cc Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Thu, 21 Jan 2016 15:58:27 +0100 Subject: [PATCH] Editor keyboard shortcuts: Ctrl+S to save the currently selected entity file (iterates to the base parent) Ctrl+N to create a new empty entity under the selection Ctrl+O to import an entity file Del to delete an entity --- include/Engine/Core/EKeyDown.h | 3 + include/Engine/Core/EKeyUp.h | 3 + include/Engine/Editor/EditorGUI.h | 38 +++- .../Schema/Entities/EditorWidgetRotate.xml | 3 - .../Schema/Entities/EditorWidgetTranslate.xml | 3 - src/Engine/Core/EntityWrapper.cpp | 6 +- src/Engine/Core/InputManager.cpp | 6 + src/Engine/Editor/EditorGUI.cpp | 193 ++++++++++++++---- src/Engine/Editor/EditorSystem.cpp | 22 +- 9 files changed, 210 insertions(+), 67 deletions(-) diff --git a/include/Engine/Core/EKeyDown.h b/include/Engine/Core/EKeyDown.h index 3a506bf4..2745fdef 100644 --- a/include/Engine/Core/EKeyDown.h +++ b/include/Engine/Core/EKeyDown.h @@ -11,6 +11,9 @@ struct KeyDown : Event { /** GLFW key code */ int KeyCode; + bool ModCtrl; + bool ModAlt; + bool ModShift; }; } diff --git a/include/Engine/Core/EKeyUp.h b/include/Engine/Core/EKeyUp.h index c7531a01..2d34f04e 100644 --- a/include/Engine/Core/EKeyUp.h +++ b/include/Engine/Core/EKeyUp.h @@ -11,6 +11,9 @@ struct KeyUp : Event { /** GLFW key code */ int KeyCode; + bool ModCtrl; + bool ModAlt; + bool ModShift; }; } diff --git a/include/Engine/Editor/EditorGUI.h b/include/Engine/Editor/EditorGUI.h index 49e0f8ab..973f6a90 100644 --- a/include/Engine/Editor/EditorGUI.h +++ b/include/Engine/Editor/EditorGUI.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "../Common.h" #include "../GLM.h" #include @@ -16,6 +17,7 @@ #include "../Core/EntityWrapper.h" #include "../Core/ResourceManager.h" #include "../Core/EPause.h" +#include "../Core/EKeyDown.h" #include "../Rendering/Texture.h" class EditorGUI @@ -33,6 +35,7 @@ public: void Draw(); void SelectEntity(EntityWrapper entity); + void SetDirty(EntityWrapper entity); // Called when an entity is selected in the entity tree typedef std::function OnEntitySelectedCallback_t; @@ -75,15 +78,23 @@ private: World* m_World; EventBroker* m_EventBroker; + struct EntityFileInfo + { + boost::filesystem::path Path; + bool Dirty = false; + }; + // Config variables const boost::filesystem::path m_DefaultEntityPath = boost::filesystem::path("Schema") / boost::filesystem::path("Entities"); - // State variables + // State EntityWrapper m_CurrentSelection = EntityWrapper::Invalid; - std::unordered_map m_EntityFiles; + std::unordered_map m_EntityFiles; EntityWrapper m_CurrentlyDragging = EntityWrapper::Invalid; std::string m_LastErrorMessage; WidgetMode m_CurrentWidgetMode = WidgetMode::Translate; + std::set m_ModalsToOpen; + std::map m_ModalData; // Callbacks OnEntitySelectedCallback_t m_OnEntitySelected = nullptr; @@ -97,11 +108,16 @@ private: OnComponentDelete_t m_OnComponentDelete = nullptr; OnWidgetMode_t m_OnWidgetMode = nullptr; + // Events + EventRelay m_EKeyDown; + bool OnKeyDown(const Events::KeyDown& e); + // Utility functions boost::filesystem::path fileOpenDialog(); boost::filesystem::path fileSaveDialog(); const std::string formatEntityName(EntityWrapper entity); GLuint tryLoadTexture(std::string filePath); + void openModal(const std::string& modal); // Entity file handling methods void entityImport(World* world); @@ -118,15 +134,15 @@ private: bool drawEntityNode(EntityWrapper entity); void drawComponents(EntityWrapper entity); bool drawComponentNode(EntityWrapper entity, const ComponentInfo& componentType); - void drawComponentField(ComponentWrapper& c, const ComponentInfo::Field_t& field); - void drawComponentField_Vector(ComponentWrapper &c, const ComponentInfo::Field_t &field); - void drawComponentField_Color(ComponentWrapper &c, const ComponentInfo::Field_t &field); - void drawComponentField_int(ComponentWrapper &c, const ComponentInfo::Field_t &field); - void drawComponentField_enum(ComponentWrapper &c, const ComponentInfo::Field_t &field); - void drawComponentField_float(ComponentWrapper &c, const ComponentInfo::Field_t &field); - void drawComponentField_double(ComponentWrapper &c, const ComponentInfo::Field_t &field); - void drawComponentField_bool(ComponentWrapper &c, const ComponentInfo::Field_t &field); - void drawComponentField_string(ComponentWrapper &c, const ComponentInfo::Field_t &field); + bool drawComponentField(ComponentWrapper& c, const ComponentInfo::Field_t& field); + bool drawComponentField_Vector(ComponentWrapper &c, const ComponentInfo::Field_t &field); + bool drawComponentField_Color(ComponentWrapper &c, const ComponentInfo::Field_t &field); + bool drawComponentField_int(ComponentWrapper &c, const ComponentInfo::Field_t &field); + bool drawComponentField_enum(ComponentWrapper &c, const ComponentInfo::Field_t &field); + bool drawComponentField_float(ComponentWrapper &c, const ComponentInfo::Field_t &field); + bool drawComponentField_double(ComponentWrapper &c, const ComponentInfo::Field_t &field); + bool drawComponentField_bool(ComponentWrapper &c, const ComponentInfo::Field_t &field); + bool drawComponentField_string(ComponentWrapper &c, const ComponentInfo::Field_t &field); void drawModals(); // Custom UI elements diff --git a/resources/Schema/Entities/EditorWidgetRotate.xml b/resources/Schema/Entities/EditorWidgetRotate.xml index 0a8f06b8..6a5f72ea 100644 --- a/resources/Schema/Entities/EditorWidgetRotate.xml +++ b/resources/Schema/Entities/EditorWidgetRotate.xml @@ -9,7 +9,6 @@ - @@ -25,7 +24,6 @@ - @@ -41,7 +39,6 @@ - diff --git a/resources/Schema/Entities/EditorWidgetTranslate.xml b/resources/Schema/Entities/EditorWidgetTranslate.xml index 70ca09a8..75d96a51 100644 --- a/resources/Schema/Entities/EditorWidgetTranslate.xml +++ b/resources/Schema/Entities/EditorWidgetTranslate.xml @@ -12,7 +12,6 @@ - @@ -25,7 +24,6 @@ - @@ -38,7 +36,6 @@ - diff --git a/src/Engine/Core/EntityWrapper.cpp b/src/Engine/Core/EntityWrapper.cpp index 58dd1ee6..98b9c7d4 100644 --- a/src/Engine/Core/EntityWrapper.cpp +++ b/src/Engine/Core/EntityWrapper.cpp @@ -10,7 +10,11 @@ bool EntityWrapper::HasComponent(const std::string& componentName) EntityWrapper EntityWrapper::Parent() { - return EntityWrapper(World, World->GetParent(ID)); + if (this->World == nullptr || this->ID == EntityID_Invalid) { + return EntityWrapper::Invalid; + } else { + return EntityWrapper(this->World, this->World->GetParent(this->ID)); + } } bool EntityWrapper::Valid() diff --git a/src/Engine/Core/InputManager.cpp b/src/Engine/Core/InputManager.cpp index 50dcac7c..941cc223 100644 --- a/src/Engine/Core/InputManager.cpp +++ b/src/Engine/Core/InputManager.cpp @@ -34,10 +34,16 @@ void InputManager::Update(double dt) if (m_CurrentKeyState[i]) { Events::KeyDown e; e.KeyCode = i; + e.ModCtrl = glfwGetKey(m_GLFWWindow, GLFW_KEY_LEFT_CONTROL) || glfwGetKey(m_GLFWWindow, GLFW_KEY_RIGHT_CONTROL); + e.ModAlt = glfwGetKey(m_GLFWWindow, GLFW_KEY_LEFT_ALT) || glfwGetKey(m_GLFWWindow, GLFW_KEY_RIGHT_ALT); + e.ModShift = glfwGetKey(m_GLFWWindow, GLFW_KEY_LEFT_SHIFT) || glfwGetKey(m_GLFWWindow, GLFW_KEY_RIGHT_SHIFT); m_EventBroker->Publish(e); } else { Events::KeyUp e; e.KeyCode = i; + e.ModCtrl = glfwGetKey(m_GLFWWindow, GLFW_KEY_LEFT_CONTROL) || glfwGetKey(m_GLFWWindow, GLFW_KEY_RIGHT_CONTROL); + e.ModAlt = glfwGetKey(m_GLFWWindow, GLFW_KEY_LEFT_ALT) || glfwGetKey(m_GLFWWindow, GLFW_KEY_RIGHT_ALT); + e.ModShift = glfwGetKey(m_GLFWWindow, GLFW_KEY_LEFT_SHIFT) || glfwGetKey(m_GLFWWindow, GLFW_KEY_RIGHT_SHIFT); m_EventBroker->Publish(e); } } diff --git a/src/Engine/Editor/EditorGUI.cpp b/src/Engine/Editor/EditorGUI.cpp index d5638d31..390e69a5 100644 --- a/src/Engine/Editor/EditorGUI.cpp +++ b/src/Engine/Editor/EditorGUI.cpp @@ -4,7 +4,7 @@ EditorGUI::EditorGUI(World* world, EventBroker* eventBroker) : m_World(world) , m_EventBroker(eventBroker) { - + EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &EditorGUI::OnKeyDown); } void EditorGUI::Draw() @@ -14,6 +14,7 @@ void EditorGUI::Draw() drawTools(); drawEntities(m_World); drawComponents(m_CurrentSelection); + drawModals(); } void EditorGUI::SelectEntity(EntityWrapper entity) @@ -111,6 +112,7 @@ void EditorGUI::drawEntities(World* world) if (m_CurrentSelection.Valid()) { if (m_OnEntityChangeName != nullptr) { m_OnEntityChangeName(m_CurrentSelection, std::string(buffer)); + SetDirty(m_CurrentSelection); } } } @@ -120,8 +122,6 @@ void EditorGUI::drawEntities(World* world) drawEntitiesRecursive(world, EntityID_Invalid); - // Draw any potential modals before ending this scope - drawModals(); ImGui::End(); } @@ -167,10 +167,10 @@ bool EditorGUI::drawEntityNode(EntityWrapper entity) ImGui::Text(formatEntityName(entity).c_str()); ImGui::End(); } - } else if (m_CurrentlyDragging == entity) { + }/* else if (m_CurrentlyDragging == entity) { LOG_DEBUG("Stopped dragging %i", entity.ID); m_CurrentlyDragging = EntityWrapper::Invalid; - } + }*/ // Entity context menu std::string contextMenuUniqueID = std::string("EntityContextMenu") + std::to_string(entity.ID); if (hovered && ImGui::IsMouseClicked(1)) { @@ -190,7 +190,6 @@ bool EditorGUI::drawEntityNode(EntityWrapper entity) if (ImGui::MenuItem("Move to root")) { entityChangeParent(entity, EntityWrapper::Invalid); } - drawModals(); ImGui::EndPopup(); } @@ -242,6 +241,7 @@ void EditorGUI::drawComponents(EntityWrapper entity) if (m_OnComponentAttach != nullptr) { std::string chosenComponentType(componentTypes.at(selectedItem)); m_OnComponentAttach(entity, chosenComponentType); + SetDirty(entity); } } } @@ -287,7 +287,10 @@ bool EditorGUI::drawComponentNode(EntityWrapper entity, const ComponentInfo& ci) const ComponentInfo::Field_t& field = kv.second; // Draw the field widget based on its type - drawComponentField(component, field); + bool dirty = drawComponentField(component, field); + if (dirty) { + SetDirty(entity); + } ImGui::SameLine(); // Draw field name ImGui::Text(fieldName.c_str()); @@ -305,70 +308,76 @@ bool EditorGUI::drawComponentNode(EntityWrapper entity, const ComponentInfo& ci) return true; } -void EditorGUI::drawComponentField(ComponentWrapper& c, const ComponentInfo::Field_t& field) +bool EditorGUI::drawComponentField(ComponentWrapper& c, const ComponentInfo::Field_t& field) { // Push an unique widget id so different components with fields with equal names are still counted as different ImGui::PushID((c.Info.Name + field.Name).c_str()); + bool dirty = false; + if (field.Type == "Vector") { - drawComponentField_Vector(c, field); + dirty = drawComponentField_Vector(c, field); } else if (field.Type == "Color") { - drawComponentField_Color(c, field); + dirty = drawComponentField_Color(c, field); //} else if (field.Type == "Quaternion") { } else if (field.Type == "int") { - drawComponentField_int(c, field); + dirty = drawComponentField_int(c, field); } else if (field.Type == "enum") { - drawComponentField_enum(c, field); + dirty = drawComponentField_enum(c, field); } else if (field.Type == "float") { - drawComponentField_float(c, field); + dirty = drawComponentField_float(c, field); } else if (field.Type == "double") { - drawComponentField_double(c, field); + dirty = drawComponentField_double(c, field); } else if (field.Type == "bool") { - drawComponentField_bool(c, field); + dirty = drawComponentField_bool(c, field); } else if (field.Type == "string") { - drawComponentField_string(c, field); + dirty = drawComponentField_string(c, field); } else { ImGui::TextDisabled(field.Type.c_str()); } ImGui::PopID(); + + return dirty; } -void EditorGUI::drawComponentField_Vector(ComponentWrapper &c, const ComponentInfo::Field_t &field) +bool EditorGUI::drawComponentField_Vector(ComponentWrapper &c, const ComponentInfo::Field_t &field) { auto& val = c.Field(field.Name); if (field.Name == "Scale") { // Limit scale values to a minimum of 0 - ImGui::DragFloat3("", glm::value_ptr(val), 0.1f, 0.f, std::numeric_limits::max()); + return ImGui::DragFloat3("", glm::value_ptr(val), 0.1f, 0.f, std::numeric_limits::max()); } else if (field.Name == "Orientation") { // Make orentations have a period of 2*Pi glm::vec3 tempVal = glm::fmod(val, glm::vec3(glm::two_pi())); if (ImGui::SliderFloat3("", glm::value_ptr(tempVal), 0.f, glm::two_pi())) { val = tempVal; + return true; + } else { + return false; } } else { - ImGui::DragFloat3("", glm::value_ptr(val), 0.1f, std::numeric_limits::lowest(), std::numeric_limits::max()); + return ImGui::DragFloat3("", glm::value_ptr(val), 0.1f, std::numeric_limits::lowest(), std::numeric_limits::max()); } } -void EditorGUI::drawComponentField_Color(ComponentWrapper &c, const ComponentInfo::Field_t &field) +bool EditorGUI::drawComponentField_Color(ComponentWrapper &c, const ComponentInfo::Field_t &field) { auto& val = c.Field(field.Name); - ImGui::ColorEdit4("", glm::value_ptr(val), true); + return ImGui::ColorEdit4("", glm::value_ptr(val), true); } -void EditorGUI::drawComponentField_int(ComponentWrapper &c, const ComponentInfo::Field_t &field) +bool EditorGUI::drawComponentField_int(ComponentWrapper &c, const ComponentInfo::Field_t &field) { auto& val = c.Field(field.Name); - ImGui::InputInt("", &val); + return ImGui::InputInt("", &val); } -void EditorGUI::drawComponentField_enum(ComponentWrapper &c, const ComponentInfo::Field_t &field) +bool EditorGUI::drawComponentField_enum(ComponentWrapper &c, const ComponentInfo::Field_t &field) { auto fieldEnumDefIt = c.Info.Meta->FieldEnumDefinitions.find(field.Name); if (fieldEnumDefIt == c.Info.Meta->FieldEnumDefinitions.end()) { - drawComponentField_int(c, field); - return; + return drawComponentField_int(c, field); } auto& val = c.Field(field.Name); @@ -386,30 +395,36 @@ void EditorGUI::drawComponentField_enum(ComponentWrapper &c, const ComponentInfo } if (ImGui::Combo("", &selectedItem, enumKeys.str().c_str())) { val = enumValues.at(selectedItem); + return true; + } else { + return false; } } -void EditorGUI::drawComponentField_float(ComponentWrapper &c, const ComponentInfo::Field_t &field) +bool EditorGUI::drawComponentField_float(ComponentWrapper &c, const ComponentInfo::Field_t &field) { auto& val = c.Field(field.Name); - ImGui::InputFloat("", &val, 0.01f, 1.f); + return ImGui::InputFloat("", &val, 0.01f, 1.f); } -void EditorGUI::drawComponentField_double(ComponentWrapper &c, const ComponentInfo::Field_t &field) +bool EditorGUI::drawComponentField_double(ComponentWrapper &c, const ComponentInfo::Field_t &field) { float tempVal = static_cast(c.Field(field.Name)); if (ImGui::InputFloat("", &tempVal, 0.01f, 1.f)) { c.SetField(field.Name, static_cast(tempVal)); + return true; + } else { + return false; } } -void EditorGUI::drawComponentField_bool(ComponentWrapper &c, const ComponentInfo::Field_t &field) +bool EditorGUI::drawComponentField_bool(ComponentWrapper &c, const ComponentInfo::Field_t &field) { auto& val = c.Field(field.Name); - ImGui::Checkbox("", &val); + return ImGui::Checkbox("", &val); } -void EditorGUI::drawComponentField_string(ComponentWrapper &c, const ComponentInfo::Field_t &field) +bool EditorGUI::drawComponentField_string(ComponentWrapper &c, const ComponentInfo::Field_t &field) { auto& val = c.Field(field.Name); char tempString[1024]; // Let's just hope this is an sufficiently large buffer for strings :) @@ -418,12 +433,20 @@ void EditorGUI::drawComponentField_string(ComponentWrapper &c, const ComponentIn memcpy(tempString, val.c_str(), std::min(val.length() + 1, sizeof(tempString) - 1)); if (ImGui::InputText("", tempString, sizeof(tempString))) { val = std::string(tempString); + return true; + } else { + return false; } // TODO: Handle drag and drop of files } void EditorGUI::drawModals() { + for (auto& modal : m_ModalsToOpen) { + ImGui::OpenPopup(modal.c_str()); + } + m_ModalsToOpen.clear(); + if (ImGui::BeginPopupModal("Import failed", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { ImGui::Text("Entity import failed. Check console for more information.\n\n"); ImGui::SetCursorPosX(ImGui::GetContentRegionAvailWidth() - 120); @@ -441,6 +464,26 @@ void EditorGUI::drawModals() } ImGui::EndPopup(); } + + if (ImGui::BeginPopupModal("Confirm deletion", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { + if (m_ModalData.count("Confirm deletion") == 0) { + ImGui::CloseCurrentPopup(); + } + + ImGui::Text("Are you sure you want to delete entity \"%s\"?", formatEntityName(m_CurrentSelection).c_str()); + ImGui::ItemSize(ImVec2(5.f, 0.f)); + ImGui::SetCursorPosX(ImGui::GetContentRegionAvailWidth() - 2*60); + if (ImGui::Button("Delete (Del)", ImVec2(60, 0))) { + entityDelete(boost::any_cast(m_ModalData.at("Confirm deletion"))); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::Button("Cancel", ImVec2(60, 0))) { + m_ModalData.erase("Confirm deletion"); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } } bool EditorGUI::createDeleteButton(const std::string& componentType) @@ -492,6 +535,35 @@ void EditorGUI::createWidgetToolButton(WidgetMode mode) } } +bool EditorGUI::OnKeyDown(const Events::KeyDown& e) +{ + if (e.ModCtrl && e.KeyCode == GLFW_KEY_S) { + if (m_CurrentSelection.Valid()) { + EntityWrapper baseParent = m_CurrentSelection; + while (baseParent.Parent().Valid()) { + baseParent = baseParent.Parent(); + } + entitySave(baseParent); + } + } + + if (e.ModCtrl && e.KeyCode == GLFW_KEY_N) { + entityCreate(m_World, m_CurrentSelection); + } + + if (e.ModCtrl && e.KeyCode == GLFW_KEY_O) { + entityImport(m_World); + } + + if (e.KeyCode == GLFW_KEY_DELETE) { + if (m_CurrentSelection.Valid()) { + entityDelete(m_CurrentSelection); + } + } + + return true; +} + boost::filesystem::path EditorGUI::fileOpenDialog() { namespace bfs = boost::filesystem; @@ -540,7 +612,10 @@ const std::string EditorGUI::formatEntityName(EntityWrapper entity) } if (m_EntityFiles.count(entity) == 1) { - name << " (" << m_EntityFiles.at(entity).filename().string() << ")"; + name << " (" << m_EntityFiles.at(entity).Path.filename().string() << ")"; + if (m_EntityFiles.at(entity).Dirty) { + name << "*"; + } } return name.str(); @@ -555,6 +630,22 @@ GLuint EditorGUI::tryLoadTexture(std::string filePath) return texture; } +void EditorGUI::openModal(const std::string& modal) +{ + m_ModalsToOpen.insert(modal); +} + +void EditorGUI::SetDirty(EntityWrapper entity) +{ + EntityWrapper baseParent = entity; + while (baseParent.Parent().Valid()) { + baseParent = baseParent.Parent(); + } + if (m_EntityFiles.find(baseParent) != m_EntityFiles.end()) { + m_EntityFiles.at(baseParent).Dirty = true; + } +} + void EditorGUI::entityImport(World* world) { boost::filesystem::path filePath = fileOpenDialog(); @@ -564,10 +655,10 @@ void EditorGUI::entityImport(World* world) EntityWrapper entity = m_OnEntityImport(EntityWrapper(world, EntityID_Invalid), filePath); if (entity.Valid()) { - m_EntityFiles[entity] = filePath; + m_EntityFiles[entity].Path = filePath; SelectEntity(entity); } else { - ImGui::OpenPopup("Import failed"); + openModal("Import failed"); } } @@ -575,7 +666,7 @@ void EditorGUI::entitySave(EntityWrapper entity, bool saveAs /* = false */) { boost::filesystem::path filePath; if (!saveAs && m_EntityFiles.count(entity) == 1) { - filePath = m_EntityFiles.at(entity); + filePath = m_EntityFiles.at(entity).Path; } else { filePath = fileSaveDialog(); } @@ -586,10 +677,11 @@ void EditorGUI::entitySave(EntityWrapper entity, bool saveAs /* = false */) try { m_OnEntitySave(entity, filePath); - m_EntityFiles[entity] = filePath; + m_EntityFiles[entity].Path = filePath; + m_EntityFiles[entity].Dirty = false; } catch (const std::exception& e) { m_LastErrorMessage = e.what(); - ImGui::OpenPopup("Save failed"); + openModal("Save failed"); } } @@ -607,12 +699,24 @@ void EditorGUI::entityCreate(World* world, EntityWrapper parent) void EditorGUI::entityDelete(EntityWrapper entity) { - if (m_OnEntityDelete != nullptr) { - m_OnEntityDelete(entity); - m_EntityFiles.erase(entity); - } - if (!m_CurrentSelection.Valid()) { - SelectEntity(EntityWrapper::Invalid); + std::string modalName = "Confirm deletion"; + + if (m_ModalData.count(modalName) == 0) { + m_ModalData[modalName] = entity; + openModal(modalName); + } else { + if (boost::any_cast(m_ModalData[modalName]) == entity) { + EntityWrapper parent = entity.Parent(); + if (m_OnEntityDelete != nullptr) { + SetDirty(entity); + m_OnEntityDelete(entity); + m_EntityFiles.erase(entity); + } + if (!m_CurrentSelection.Valid()) { + SelectEntity(parent); + } + } + m_ModalData.erase(modalName); } } @@ -623,6 +727,7 @@ void EditorGUI::entityChangeParent(EntityWrapper entity, EntityWrapper parent) } if (m_OnEntityChangeParent != nullptr) { + SetDirty(entity); m_OnEntityChangeParent(entity, parent); LOG_DEBUG("Changed parent of %i to %i", entity.ID, parent.ID); } diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index 13d74a65..116ad4cc 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -52,6 +52,7 @@ EditorSystem::~EditorSystem() void EditorSystem::Update(double dt) { + m_EventBroker->Process(); m_EditorGUI->Draw(); m_EditorStats->Draw(dt); @@ -87,27 +88,37 @@ EntityWrapper EditorSystem::OnEntityCreate(EntityWrapper parent) void EditorSystem::OnEntityDelete(EntityWrapper entity) { - entity.World->DeleteEntity(entity.ID); + if (entity.Valid()) { + entity.World->DeleteEntity(entity.ID); + } } void EditorSystem::OnEntityChangeParent(EntityWrapper entity, EntityWrapper parent) { - entity.World->SetParent(entity.ID, parent.ID); + if (entity.Valid()) { + entity.World->SetParent(entity.ID, parent.ID); + } } void EditorSystem::OnEntityChangeName(EntityWrapper entity, const std::string& name) { - entity.World->SetName(entity.ID, name); + if (entity.Valid()) { + entity.World->SetName(entity.ID, name); + } } void EditorSystem::OnComponentAttach(EntityWrapper entity, const std::string& componentType) { - entity.World->AttachComponent(entity.ID, componentType); + if (entity.Valid()) { + entity.World->AttachComponent(entity.ID, componentType); + } } void EditorSystem::OnComponentDelete(EntityWrapper entity, const std::string& componentType) { - entity.World->DeleteComponent(entity.ID, componentType); + if (entity.Valid()) { + entity.World->DeleteComponent(entity.ID, componentType); + } } bool EditorSystem::OnMouseRelease(const Events::MouseRelease& e) @@ -126,6 +137,7 @@ bool EditorSystem::OnWidgetDelta(const Events::WidgetDelta& e) { if (m_CurrentSelection.Valid()) { (glm::vec3&)m_CurrentSelection["Transform"]["Position"] += glm::inverse(Transform::AbsoluteOrientation(m_CurrentSelection.World, m_CurrentSelection.ID)) * e.Translation; + m_EditorGUI->SetDirty(m_CurrentSelection); } return true; }