diff --git a/include/NazaraEditor/Core.hpp b/include/NazaraEditor/Core.hpp index bb8f7ce..0f9d4c0 100644 --- a/include/NazaraEditor/Core.hpp +++ b/include/NazaraEditor/Core.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/include/NazaraEditor/Core/Application/BaseApplication.hpp b/include/NazaraEditor/Core/Application/BaseApplication.hpp index b4587d8..49cf672 100644 --- a/include/NazaraEditor/Core/Application/BaseApplication.hpp +++ b/include/NazaraEditor/Core/Application/BaseApplication.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -71,6 +72,8 @@ namespace Nz std::filesystem::path m_resourceFolder; Nz::ActionStack m_actionStack; + Nz::EditorPopupManager m_popupManager; + Nz::Level m_level; }; } \ No newline at end of file diff --git a/include/NazaraEditor/Core/UI/PopupManager.hpp b/include/NazaraEditor/Core/UI/PopupManager.hpp new file mode 100644 index 0000000..3622ba9 --- /dev/null +++ b/include/NazaraEditor/Core/UI/PopupManager.hpp @@ -0,0 +1,67 @@ +#pragma once + +#include + +#include +#include + +namespace Nz +{ + struct EditorPopupParameters + { + struct Choice + { + std::string name; + std::function callback; + }; + std::string title; + std::string description; + std::vector choices; + }; + + class EditorPopup + : public Nz::ImguiHandler + { + public: + EditorPopup(uint64_t id, const EditorPopupParameters& parameters); + ~EditorPopup(); + + void OnRenderImgui() override; + + uint64_t GetId() const { return m_id; } + + private: + uint64_t m_id; + EditorPopupParameters m_parameters; + }; + + class NAZARAEDITOR_CORE_API EditorPopupManager + { + public: + static EditorPopupManager* Instance(); + + void Update(); + + uint64_t CreatePopup(const EditorPopupParameters& parameters); + void DestroyPopup(uint64_t popupId); + + private: + EditorPopupManager(); + ~EditorPopupManager(); + + EditorPopupManager(const EditorPopupManager&) = delete; + EditorPopupManager& operator=(const EditorPopupManager&) = delete; + + EditorPopupManager(EditorPopup&&) noexcept = delete; + EditorPopupManager& operator=(EditorPopup&&) = delete; + + void DestroyPopupInternal(uint64_t popupId); + + uint64_t m_currentIndex; + std::vector> m_popups; + std::vector m_popupsToDelete; + + static EditorPopupManager* s_instance; + friend class EditorBaseApplication; + }; +} \ No newline at end of file diff --git a/src/NazaraEditor/Core/Application/BaseApplication.cpp b/src/NazaraEditor/Core/Application/BaseApplication.cpp index 77611e5..00a885d 100644 --- a/src/NazaraEditor/Core/Application/BaseApplication.cpp +++ b/src/NazaraEditor/Core/Application/BaseApplication.cpp @@ -36,6 +36,8 @@ namespace Nz window.ProcessEvents(); + m_popupManager.Update(); + Nz::RenderFrame frame = m_windowSwapchain->AcquireFrame(); if (!frame) return; diff --git a/src/NazaraEditor/Core/UI/PopupManager.cpp b/src/NazaraEditor/Core/UI/PopupManager.cpp new file mode 100644 index 0000000..4a13e83 --- /dev/null +++ b/src/NazaraEditor/Core/UI/PopupManager.cpp @@ -0,0 +1,87 @@ +#include + +namespace Nz +{ + + EditorPopup::EditorPopup(uint64_t id, const EditorPopupParameters& parameters) + : m_id(id) + , m_parameters(parameters) + { + Nz::Imgui::Instance()->AddHandler(this); + } + + EditorPopup::~EditorPopup() + { + Nz::Imgui::Instance()->RemoveHandler(this); + } + + void EditorPopup::OnRenderImgui() + { + ImGui::OpenPopup(m_parameters.title.c_str()); + if (ImGui::BeginPopupModal(m_parameters.title.c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse)) + { + ImGui::Text(m_parameters.description.c_str()); + + for (auto&& choice : m_parameters.choices) + { + if (ImGui::Button(choice.name.c_str())) + { + if (choice.callback) + choice.callback(); + + EditorPopupManager::Instance()->DestroyPopup(m_id); + } + ImGui::SameLine(); + } + + ImGui::EndPopup(); + } + } + + EditorPopupManager* EditorPopupManager::s_instance = nullptr; + EditorPopupManager* EditorPopupManager::Instance() + { + return s_instance; + } + + EditorPopupManager::EditorPopupManager() + : m_currentIndex(0) + { + NazaraAssert(s_instance == nullptr, "EditorPopupManager already exists"); + s_instance = this; + } + + EditorPopupManager::~EditorPopupManager() + { + s_instance = nullptr; + } + + void EditorPopupManager::Update() + { + for (uint64_t id : m_popupsToDelete) + DestroyPopupInternal(id); + m_popupsToDelete.clear(); + } + + uint64_t EditorPopupManager::CreatePopup(const EditorPopupParameters& parameters) + { + int64_t currentIndex = m_currentIndex++; + m_popups.push_back(std::make_unique(currentIndex, parameters)); + return currentIndex; + } + + void EditorPopupManager::DestroyPopup(uint64_t popupId) + { + m_popupsToDelete.push_back(popupId); + } + + void EditorPopupManager::DestroyPopupInternal(uint64_t popupId) + { + auto it = std::find_if(m_popups.begin(), m_popups.end(), [popupId](auto&& popup) { return popup->GetId() == popupId; }); + if (it == m_popups.end()) + return; + + m_popups.erase(it); + } + +} \ No newline at end of file