From d030e8f6990fefeb97440efcfec6f33a64e43b93 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Tue, 19 Jan 2016 13:28:02 +0100 Subject: [PATCH] Editor widget selection and creation --- include/Engine/Editor/EditorGUI.h | 13 +++++ include/Engine/Editor/EditorSystem.h | 7 ++- include/Engine/Editor/EditorWidgetSystem.h | 6 +++ resources/Schema/Components/EditorWidget.xml | 2 +- resources/Schema/Components/EditorWidget.xsd | 7 ++- src/Engine/Editor/EditorGUI.cpp | 50 ++++++++++++++++++-- src/Engine/Editor/EditorSystem.cpp | 42 ++++++++++++++-- 7 files changed, 112 insertions(+), 15 deletions(-) create mode 100644 include/Engine/Editor/EditorWidgetSystem.h diff --git a/include/Engine/Editor/EditorGUI.h b/include/Engine/Editor/EditorGUI.h index 9d2712e1..104c6787 100644 --- a/include/Engine/Editor/EditorGUI.h +++ b/include/Engine/Editor/EditorGUI.h @@ -10,6 +10,7 @@ #include "../GLM.h" #include +#include "EditorWidgetSystem.h" #include "../Core/EventBroker.h" #include "../Core/World.h" #include "../Core/EntityWrapper.h" @@ -22,6 +23,13 @@ class EditorGUI public: EditorGUI(World* world, EventBroker* eventBroker); + enum class WidgetMode + { + Translate, + Rotate, + Scale + }; + void Draw(); void SelectEntity(EntityWrapper entity); @@ -59,6 +67,9 @@ public: // Called when the user means to delete a component off an entity. typedef std::function OnComponentDelete_t; void SetComponentDeleteCallback(OnComponentDelete_t f) { m_OnComponentDelete = f; } + // Called when the user selects a widget mode. + typedef std::function OnWidgetMode_t; + void SetWidgetModeCallback(OnWidgetMode_t f) { m_OnWidgetMode = f; } private: World* m_World; @@ -72,6 +83,7 @@ private: std::unordered_map m_EntityFiles; EntityWrapper m_CurrentlyDragging = EntityWrapper::Invalid; std::string m_LastErrorMessage; + WidgetMode m_CurrentWidgetMode = WidgetMode::Translate; // Callbacks OnEntitySelectedCallback_t m_OnEntitySelected = nullptr; @@ -83,6 +95,7 @@ private: OnEntityChangeName_t m_OnEntityChangeName = nullptr; OnComponentAttach_t m_OnComponentAttach = nullptr; OnComponentDelete_t m_OnComponentDelete = nullptr; + OnWidgetMode_t m_OnWidgetMode = nullptr; // Utility functions boost::filesystem::path fileOpenDialog(); diff --git a/include/Engine/Editor/EditorSystem.h b/include/Engine/Editor/EditorSystem.h index c0db917d..31d5064c 100644 --- a/include/Engine/Editor/EditorSystem.h +++ b/include/Engine/Editor/EditorSystem.h @@ -26,14 +26,19 @@ private: World* m_EditorWorld; SystemPipeline* m_EditorWorldSystemPipeline; Camera* m_EditorCamera; - EntityWrapper m_Widget = EntityWrapper::Invalid; EntityWrapper m_Camera = EntityWrapper::Invalid; DebugCameraInputController* m_DebugCameraInputController; EditorGUI* m_EditorGUI; EditorStats* m_EditorStats; + // State + EditorGUI::WidgetMode m_WidgetMode = EditorGUI::WidgetMode::Translate; + EntityWrapper m_Widget = EntityWrapper::Invalid; + EntityWrapper m_CurrentSelection = EntityWrapper::Invalid; + // Utility functions EntityWrapper importEntity(EntityWrapper parent, boost::filesystem::path filePath); + void setWidgetMode(EditorGUI::WidgetMode mode); // GUI callbacks void OnEntitySelected(EntityWrapper entity); diff --git a/include/Engine/Editor/EditorWidgetSystem.h b/include/Engine/Editor/EditorWidgetSystem.h new file mode 100644 index 00000000..2350d24b --- /dev/null +++ b/include/Engine/Editor/EditorWidgetSystem.h @@ -0,0 +1,6 @@ +#ifndef EditorWidgetSystem_h__ +#define EditorWidgetSystem_h__ + + + +#endif diff --git a/resources/Schema/Components/EditorWidget.xml b/resources/Schema/Components/EditorWidget.xml index 6a94d2f6..fed2f809 100644 --- a/resources/Schema/Components/EditorWidget.xml +++ b/resources/Schema/Components/EditorWidget.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/resources/Schema/Components/EditorWidget.xsd b/resources/Schema/Components/EditorWidget.xsd index e4c4ff71..3d08e82e 100644 --- a/resources/Schema/Components/EditorWidget.xsd +++ b/resources/Schema/Components/EditorWidget.xsd @@ -7,10 +7,9 @@ - - - - + + + diff --git a/src/Engine/Editor/EditorGUI.cpp b/src/Engine/Editor/EditorGUI.cpp index 1bf0f9e9..318e3199 100644 --- a/src/Engine/Editor/EditorGUI.cpp +++ b/src/Engine/Editor/EditorGUI.cpp @@ -36,13 +36,55 @@ void EditorGUI::drawTools() } // Translate widget button - ImGui::ImageButton((void*)tryLoadTexture("Textures/Icons/Translate.png"), ImVec2(24, 24), ImVec2(0, 1), ImVec2(1, 0)); + if (ImGui::ImageButton( + (void*)tryLoadTexture("Textures/Icons/Translate.png"), + ImVec2(24, 24), + ImVec2(0, 1), + ImVec2(1, 0), + -1, + ImVec4(0, 0, 0, 0), + (m_CurrentWidgetMode == WidgetMode::Translate) ? ImVec4(0, 1, 0, 1) : ImVec4(1, 1, 1, 1) + ) + ) { + m_CurrentWidgetMode = WidgetMode::Translate; + if (m_OnWidgetMode != nullptr) { + m_OnWidgetMode(m_CurrentWidgetMode); + } + } // Rotate widget button ImGui::SameLine(); - ImGui::ImageButton((void*)tryLoadTexture("Textures/Icons/Rotate.png"), ImVec2(24, 24), ImVec2(0, 1), ImVec2(1, 0)); + if (ImGui::ImageButton( + (void*)tryLoadTexture("Textures/Icons/Rotate.png"), + ImVec2(24, 24), + ImVec2(0, 1), + ImVec2(1, 0), + -1, + ImVec4(0, 0, 0, 0), + (m_CurrentWidgetMode == WidgetMode::Rotate) ? ImVec4(0, 1, 0, 1) : ImVec4(1, 1, 1, 1) + ) + ) { + m_CurrentWidgetMode = WidgetMode::Rotate; + if (m_OnWidgetMode != nullptr) { + m_OnWidgetMode(m_CurrentWidgetMode); + } + } // Scale widget button ImGui::SameLine(); - ImGui::ImageButton((void*)tryLoadTexture("Textures/Icons/Scale.png"), ImVec2(24, 24), ImVec2(0, 1), ImVec2(1, 0)); + if (ImGui::ImageButton( + (void*)tryLoadTexture("Textures/Icons/Scale.png"), + ImVec2(24, 24), + ImVec2(0, 1), + ImVec2(1, 0), + -1, + ImVec4(0, 0, 0, 0), + (m_CurrentWidgetMode == WidgetMode::Scale) ? ImVec4(0, 1, 0, 1) : ImVec4(1, 1, 1, 1) + ) + ) { + m_CurrentWidgetMode = WidgetMode::Scale; + if (m_OnWidgetMode != nullptr) { + m_OnWidgetMode(m_CurrentWidgetMode); + } + } ImGui::SameLine(); ImGui::ItemSize(ImVec2(5, 0)); @@ -83,7 +125,7 @@ void EditorGUI::drawEntities(World* world) entityImport(world); } ImGui::SameLine(0.f, 5.f); - ImGui::Button("Reference", ImVec2(buttonWidth, 0)); + ImGui::ButtonEx("Reference", ImVec2(buttonWidth, 0), ImGuiButtonFlags_Disabled); // Naming char buffer[256]; diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index 36f2baa4..03b90a37 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -12,9 +12,7 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re m_EditorWorldSystemPipeline->AddSystem(0); m_EditorWorldSystemPipeline->AddSystem(1, m_Renderer, m_RenderFrame); - m_Widget = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/EditorWidget.xml"); - - m_Camera = EntityWrapper(m_EditorWorld, m_EditorWorld->CreateEntity()); + m_Camera = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/Empty.xml"); m_EditorWorld->AttachComponent(m_Camera.ID, "Transform"); m_EditorWorld->AttachComponent(m_Camera.ID, "Camera"); m_DebugCameraInputController = new DebugCameraInputController(m_EventBroker, -1); @@ -29,6 +27,7 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re m_EditorGUI->SetEntityChangeNameCallback(std::bind(&EditorSystem::OnEntityChangeName, this, std::placeholders::_1, std::placeholders::_2)); m_EditorGUI->SetComponentAttachCallback(std::bind(&EditorSystem::OnComponentAttach, this, std::placeholders::_1, std::placeholders::_2)); m_EditorGUI->SetComponentDeleteCallback(std::bind(&EditorSystem::OnComponentDelete, this, std::placeholders::_1, std::placeholders::_2)); + m_EditorGUI->SetWidgetModeCallback(std::bind(&EditorSystem::setWidgetMode, this, std::placeholders::_1)); m_EditorStats = new EditorStats(); @@ -60,7 +59,8 @@ void EditorSystem::Update(double dt) void EditorSystem::OnEntitySelected(EntityWrapper entity) { - m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(entity.World, entity.ID); + m_CurrentSelection = entity; + setWidgetMode(m_WidgetMode); } void EditorSystem::OnEntitySave(EntityWrapper entity, boost::filesystem::path filePath) @@ -118,4 +118,36 @@ EntityWrapper EditorSystem::importEntity(EntityWrapper parent, boost::filesystem } catch (const std::exception&) { return EntityWrapper::Invalid; } -} \ No newline at end of file +} + +void EditorSystem::setWidgetMode(EditorGUI::WidgetMode mode) +{ + if (mode == m_WidgetMode && m_Widget.Valid() && m_CurrentSelection.Valid()) { + return; + } + + if (m_Widget.Valid()) { + m_Widget.World->DeleteEntity(m_Widget.ID); + m_Widget = EntityWrapper::Invalid; + } + + if (!m_CurrentSelection.Valid()) { + return; + } + + switch (mode) { + case EditorGUI::WidgetMode::Translate: + m_Widget = importEntity(EntityWrapper(m_World, EntityID_Invalid), "Schema/Entities/EditorWidgetTranslate.xml"); + break; + case EditorGUI::WidgetMode::Rotate: + m_Widget = importEntity(EntityWrapper(m_World, EntityID_Invalid), "Schema/Entities/EditorWidgetRotate.xml"); + break; + case EditorGUI::WidgetMode::Scale: + m_Widget = importEntity(EntityWrapper(m_World, EntityID_Invalid), "Schema/Entities/EditorWidgetScale.xml"); + break; + } + + m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(m_CurrentSelection.World, m_CurrentSelection.ID); + + m_WidgetMode = mode; +}