diff --git a/Resources/Editor/Textures/Move.png b/Resources/Editor/Textures/Move.png new file mode 100644 index 000000000..c39980c88 Binary files /dev/null and b/Resources/Editor/Textures/Move.png differ diff --git a/Resources/Editor/Textures/Rotate.png b/Resources/Editor/Textures/Rotate.png new file mode 100644 index 000000000..e13a66578 Binary files /dev/null and b/Resources/Editor/Textures/Rotate.png differ diff --git a/Resources/Editor/Textures/Scale.png b/Resources/Editor/Textures/Scale.png new file mode 100644 index 000000000..fb08552b2 Binary files /dev/null and b/Resources/Editor/Textures/Scale.png differ diff --git a/Sources/Overload/OvEditor/include/OvEditor/Core/EditorActions.h b/Sources/Overload/OvEditor/include/OvEditor/Core/EditorActions.h index e892026ef..7ed7fd4df 100644 --- a/Sources/Overload/OvEditor/include/OvEditor/Core/EditorActions.h +++ b/Sources/Overload/OvEditor/include/OvEditor/Core/EditorActions.h @@ -25,6 +25,8 @@ namespace tinyxml2 namespace OvEditor::Core { + enum class EGizmoOperation; + /** * A set of editor actions */ @@ -149,6 +151,19 @@ namespace OvEditor::Core void NextFrame(); #pragma endregion + #pragma region SCENE_VIEW + /** + * Sets the gizmo operation to use + * @param p_operation + */ + void SetGizmoOperation(EGizmoOperation p_operation); + + /** + * Returns the current gizmo operation + */ + EGizmoOperation GetGizmoOperation() const; + #pragma endregion + #pragma region ACTOR_CREATION_DESTRUCTION /** * Create an actor with the given component type @@ -394,6 +409,7 @@ namespace OvEditor::Core OvTools::Eventing::Event ActorSelectedEvent; OvTools::Eventing::Event ActorUnselectedEvent; OvTools::Eventing::Event EditorModeChangedEvent; + OvTools::Eventing::Event EditorOperationChanged; OvTools::Eventing::Event<> PlayEvent; private: diff --git a/Sources/Overload/OvEditor/include/OvEditor/Panels/SceneView.h b/Sources/Overload/OvEditor/include/OvEditor/Panels/SceneView.h index 2cd00f8f2..97965b0a0 100644 --- a/Sources/Overload/OvEditor/include/OvEditor/Panels/SceneView.h +++ b/Sources/Overload/OvEditor/include/OvEditor/Panels/SceneView.h @@ -9,6 +9,7 @@ #include #include #include +#include namespace OvEditor::Panels { @@ -42,6 +43,17 @@ namespace OvEditor::Panels */ virtual OvCore::SceneSystem::Scene* GetScene(); + /** + * Set the gizmo operation + * @param p_operation + */ + void SetGizmoOperation(Core::EGizmoOperation p_operation); + + /** + * Returns the current gizmo operation + */ + Core::EGizmoOperation GetGizmoOperation() const; + protected: virtual OvCore::Rendering::SceneRenderer::SceneDescriptor CreateSceneDescriptor() override; diff --git a/Sources/Overload/OvEditor/src/OvEditor/Core/EditorActions.cpp b/Sources/Overload/OvEditor/src/OvEditor/Core/EditorActions.cpp index bc82022ef..b6fcfe80c 100644 --- a/Sources/Overload/OvEditor/src/OvEditor/Core/EditorActions.cpp +++ b/Sources/Overload/OvEditor/src/OvEditor/Core/EditorActions.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -493,6 +494,18 @@ void OvEditor::Core::EditorActions::NextFrame() SetEditorMode(EEditorMode::FRAME_BY_FRAME); } +void OvEditor::Core::EditorActions::SetGizmoOperation(OvEditor::Core::EGizmoOperation p_operation) +{ + auto& sceneView = m_panelsManager.GetPanelAs("Scene View"); + sceneView.SetGizmoOperation(p_operation); +} + +OvEditor::Core::EGizmoOperation OvEditor::Core::EditorActions::GetGizmoOperation() const +{ + auto& sceneView = m_panelsManager.GetPanelAs("Scene View"); + return sceneView.GetGizmoOperation(); +} + OvMaths::FVector3 OvEditor::Core::EditorActions::CalculateActorSpawnPoint(float p_distanceToCamera) { auto& sceneView = m_panelsManager.GetPanelAs("Scene View"); diff --git a/Sources/Overload/OvEditor/src/OvEditor/Core/EditorResources.cpp b/Sources/Overload/OvEditor/src/OvEditor/Core/EditorResources.cpp index e8351b980..6af23e85b 100644 --- a/Sources/Overload/OvEditor/src/OvEditor/Core/EditorResources.cpp +++ b/Sources/Overload/OvEditor/src/OvEditor/Core/EditorResources.cpp @@ -89,6 +89,9 @@ OvEditor::Core::EditorResources::EditorResources(const std::string& p_editorAsse {"Stop", CreateTexture(texturesFolder / "Stop.png")}, {"Next", CreateTexture(texturesFolder / "Next.png")}, {"Refresh", CreateTexture(texturesFolder / "Refresh.png")}, + {"Move", CreateTexture(texturesFolder / "Move.png")}, + {"Rotate", CreateTexture(texturesFolder / "Rotate.png")}, + {"Scale", CreateTexture(texturesFolder / "Scale.png")}, {"File", CreateTexture(texturesFolder / "File.png")}, {"Folder", CreateTexture(texturesFolder / "Folder.png")}, {"Texture", CreateTexture(texturesFolder / "Texture.png")}, diff --git a/Sources/Overload/OvEditor/src/OvEditor/Panels/SceneView.cpp b/Sources/Overload/OvEditor/src/OvEditor/Panels/SceneView.cpp index 9c615d18a..6b1da60ce 100644 --- a/Sources/Overload/OvEditor/src/OvEditor/Panels/SceneView.cpp +++ b/Sources/Overload/OvEditor/src/OvEditor/Panels/SceneView.cpp @@ -83,17 +83,17 @@ void OvEditor::Panels::SceneView::Update(float p_deltaTime) { if (EDITOR_CONTEXT(inputManager)->IsKeyPressed(EKey::KEY_W)) { - m_currentOperation = OvEditor::Core::EGizmoOperation::TRANSLATE; + SetGizmoOperation(Core::EGizmoOperation::TRANSLATE); } if (EDITOR_CONTEXT(inputManager)->IsKeyPressed(EKey::KEY_E)) { - m_currentOperation = OvEditor::Core::EGizmoOperation::ROTATE; + SetGizmoOperation(Core::EGizmoOperation::ROTATE); } if (EDITOR_CONTEXT(inputManager)->IsKeyPressed(EKey::KEY_R)) { - m_currentOperation = OvEditor::Core::EGizmoOperation::SCALE; + SetGizmoOperation(Core::EGizmoOperation::SCALE); } } } @@ -122,6 +122,17 @@ OvCore::SceneSystem::Scene* OvEditor::Panels::SceneView::GetScene() return m_sceneManager.GetCurrentScene(); } +void OvEditor::Panels::SceneView::SetGizmoOperation(OvEditor::Core::EGizmoOperation p_operation) +{ + m_currentOperation = p_operation; + EDITOR_EVENT(EditorOperationChanged).Invoke(m_currentOperation); +} + +OvEditor::Core::EGizmoOperation OvEditor::Panels::SceneView::GetGizmoOperation() const +{ + return m_currentOperation; +} + OvCore::Rendering::SceneRenderer::SceneDescriptor OvEditor::Panels::SceneView::CreateSceneDescriptor() { auto descriptor = AViewControllable::CreateSceneDescriptor(); diff --git a/Sources/Overload/OvEditor/src/OvEditor/Panels/Toolbar.cpp b/Sources/Overload/OvEditor/src/OvEditor/Panels/Toolbar.cpp index 274d3fc2d..46b46d8aa 100644 --- a/Sources/Overload/OvEditor/src/OvEditor/Panels/Toolbar.cpp +++ b/Sources/Overload/OvEditor/src/OvEditor/Panels/Toolbar.cpp @@ -4,14 +4,25 @@ * @licence: MIT */ -#include - -#include "OvEditor/Panels/Toolbar.h" -#include "OvEditor/Core/EditorActions.h" - #include #include +#include +#include +#include + +#include + +namespace +{ + OvUI::Types::Color GetButtonTint(bool p_selected) + { + return p_selected ? + OvUI::Types::Color::Yellow : + OvUI::Types::Color::White; + } +} + OvEditor::Panels::Toolbar::Toolbar ( const std::string& p_title, @@ -19,65 +30,64 @@ OvEditor::Panels::Toolbar::Toolbar const OvUI::Settings::PanelWindowSettings& p_windowSettings ) : PanelWindow(p_title, p_opened, p_windowSettings) { - std::string iconFolder = ":Textures/Icons/"; + using namespace OvUI::Widgets; + using namespace OvUI::Widgets::Buttons; + const auto iconSize = OvMaths::FVector2{ 20, 20 }; auto& textureManager = OvCore::Global::ServiceLocator::Get(); + auto& editorResources = EDITOR_CONTEXT(editorResources); - m_playButton = &CreateWidget(EDITOR_CONTEXT(editorResources)->GetTexture("Play")->GetTexture().GetID(), OvMaths::FVector2{ 20, 20 }); - m_pauseButton = &CreateWidget(EDITOR_CONTEXT(editorResources)->GetTexture("Pause")->GetTexture().GetID(), OvMaths::FVector2{ 20, 20 }); - m_stopButton = &CreateWidget(EDITOR_CONTEXT(editorResources)->GetTexture("Stop")->GetTexture().GetID(), OvMaths::FVector2{ 20, 20 }); - m_nextButton = &CreateWidget(EDITOR_CONTEXT(editorResources)->GetTexture("Next")->GetTexture().GetID(), OvMaths::FVector2{ 20, 20 }); + auto& translate = CreateWidget(editorResources->GetTexture("Move")->GetTexture().GetID(), iconSize); + translate.lineBreak = false; + translate.ClickedEvent += []() { EDITOR_EXEC(SetGizmoOperation(OvEditor::Core::EGizmoOperation::TRANSLATE)); }; - CreateWidget(0).lineBreak = false; - auto& refreshButton = CreateWidget(EDITOR_CONTEXT(editorResources)->GetTexture("Refresh")->GetTexture().GetID(), OvMaths::FVector2{ 20, 20 }); + auto& rotate = CreateWidget(editorResources->GetTexture("Rotate")->GetTexture().GetID(), iconSize); + rotate.lineBreak = false; + rotate.ClickedEvent += []() { EDITOR_EXEC(SetGizmoOperation(OvEditor::Core::EGizmoOperation::ROTATE)); }; - m_playButton->lineBreak = false; - m_pauseButton->lineBreak = false; - m_stopButton->lineBreak = false; - m_nextButton->lineBreak = false; - refreshButton.lineBreak = false; + auto& scale = CreateWidget(editorResources->GetTexture("Scale")->GetTexture().GetID(), iconSize); + scale.lineBreak = false; + scale.ClickedEvent += []() { EDITOR_EXEC(SetGizmoOperation(OvEditor::Core::EGizmoOperation::SCALE)); }; - m_playButton->ClickedEvent += EDITOR_BIND(StartPlaying); - m_pauseButton->ClickedEvent += EDITOR_BIND(PauseGame); - m_stopButton->ClickedEvent += EDITOR_BIND(StopPlaying); - m_nextButton->ClickedEvent += EDITOR_BIND(NextFrame); - refreshButton.ClickedEvent += EDITOR_BIND(RefreshScripts); + auto updateGizmoOperation = [&translate, &rotate, &scale](Core::EGizmoOperation p_operation) { + using enum Core::EGizmoOperation; + translate.tint = GetButtonTint(p_operation == TRANSLATE); + rotate.tint = GetButtonTint(p_operation == ROTATE); + scale.tint = GetButtonTint(p_operation == SCALE); + }; - EDITOR_EVENT(EditorModeChangedEvent) += [this](OvEditor::Core::EditorActions::EEditorMode p_newMode) - { - auto enable = [](OvUI::Widgets::Buttons::ButtonImage* p_button, bool p_enable) - { - p_button->disabled = !p_enable; - p_button->tint = p_enable ? OvUI::Types::Color{ 1.0f, 1.0f, 1.0f, 1.0f} : OvUI::Types::Color{1.0f, 1.0f, 1.0f, 0.15f}; - }; - - switch (p_newMode) - { - case OvEditor::Core::EditorActions::EEditorMode::EDIT: - enable(m_playButton, true); - enable(m_pauseButton, false); - enable(m_stopButton, false); - enable(m_nextButton, false); - break; - case OvEditor::Core::EditorActions::EEditorMode::PLAY: - enable(m_playButton, false); - enable(m_pauseButton, true); - enable(m_stopButton, true); - enable(m_nextButton, true); - break; - case OvEditor::Core::EditorActions::EEditorMode::PAUSE: - enable(m_playButton, true); - enable(m_pauseButton, false); - enable(m_stopButton, true); - enable(m_nextButton, true); - break; - case OvEditor::Core::EditorActions::EEditorMode::FRAME_BY_FRAME: - enable(m_playButton, true); - enable(m_pauseButton, false); - enable(m_stopButton, true); - enable(m_nextButton, true); - break; - } + updateGizmoOperation(EDITOR_EXEC(GetGizmoOperation())); + + EDITOR_EVENT(EditorOperationChanged) += updateGizmoOperation; + + CreateWidget().lineBreak = false; + + m_playButton = &CreateWidget(editorResources->GetTexture("Play")->GetTexture().GetID(), iconSize); + m_pauseButton = &CreateWidget(editorResources->GetTexture("Pause")->GetTexture().GetID(), iconSize); + m_stopButton = &CreateWidget(editorResources->GetTexture("Stop")->GetTexture().GetID(), iconSize); + m_nextButton = &CreateWidget(editorResources->GetTexture("Next")->GetTexture().GetID(), iconSize); + + CreateWidget(0).lineBreak = false; + auto& refreshButton = CreateWidget(editorResources->GetTexture("Refresh")->GetTexture().GetID(), iconSize); + + m_playButton->lineBreak = false; + m_pauseButton->lineBreak = false; + m_stopButton->lineBreak = false; + m_nextButton->lineBreak = false; + refreshButton.lineBreak = false; + + m_playButton->ClickedEvent += EDITOR_BIND(StartPlaying); + m_pauseButton->ClickedEvent += EDITOR_BIND(PauseGame); + m_stopButton->ClickedEvent += EDITOR_BIND(StopPlaying); + m_nextButton->ClickedEvent += EDITOR_BIND(NextFrame); + refreshButton.ClickedEvent += EDITOR_BIND(RefreshScripts); + + EDITOR_EVENT(EditorModeChangedEvent) += [this](Core::EditorActions::EEditorMode p_mode) { + using enum Core::EditorActions::EEditorMode; + m_playButton->disabled = !(p_mode == EDIT || p_mode == FRAME_BY_FRAME || p_mode == PAUSE); + m_pauseButton->disabled = !(p_mode == PLAY); + m_stopButton->disabled = !(p_mode == PLAY || p_mode == FRAME_BY_FRAME || p_mode == PAUSE); + m_nextButton->disabled = !(p_mode == PLAY || p_mode == FRAME_BY_FRAME || p_mode == PAUSE); }; EDITOR_EXEC(SetEditorMode(OvEditor::Core::EditorActions::EEditorMode::EDIT));