diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index 82d25f0a..688a2e7b 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -60,12 +60,14 @@ set(HDR_GL_DRAW source/scwx/qt/gl/draw/draw_item.hpp set(SRC_GL_DRAW source/scwx/qt/gl/draw/draw_item.cpp source/scwx/qt/gl/draw/geo_line.cpp source/scwx/qt/gl/draw/rectangle.cpp) -set(HDR_MANAGER source/scwx/qt/manager/radar_product_manager.hpp +set(HDR_MANAGER source/scwx/qt/manager/imgui_manager.hpp + source/scwx/qt/manager/radar_product_manager.hpp source/scwx/qt/manager/radar_product_manager_notifier.hpp source/scwx/qt/manager/resource_manager.hpp source/scwx/qt/manager/settings_manager.hpp source/scwx/qt/manager/text_event_manager.hpp) -set(SRC_MANAGER source/scwx/qt/manager/radar_product_manager.cpp +set(SRC_MANAGER source/scwx/qt/manager/imgui_manager.cpp + source/scwx/qt/manager/radar_product_manager.cpp source/scwx/qt/manager/radar_product_manager_notifier.cpp source/scwx/qt/manager/resource_manager.cpp source/scwx/qt/manager/settings_manager.cpp diff --git a/scwx-qt/source/scwx/qt/manager/imgui_manager.cpp b/scwx-qt/source/scwx/qt/manager/imgui_manager.cpp new file mode 100644 index 00000000..254ec47a --- /dev/null +++ b/scwx-qt/source/scwx/qt/manager/imgui_manager.cpp @@ -0,0 +1,92 @@ +#include +#include + +#include + +namespace scwx +{ +namespace qt +{ +namespace manager +{ + +static const std::string logPrefix_ = "scwx::qt::manager::imgui_manager"; +static const auto logger_ = scwx::util::Logger::Create(logPrefix_); + +class ImGuiManagerImpl +{ +public: + explicit ImGuiManagerImpl() {} + + ~ImGuiManagerImpl() = default; + + std::vector contexts_ {}; +}; + +ImGuiManager::ImGuiManager() : + QObject(nullptr), p {std::make_unique()} +{ +} + +ImGuiManager::~ImGuiManager() {} + +ImGuiContext* ImGuiManager::CreateContext(const std::string& name) +{ + ImGuiContext* context = ImGui::CreateContext(); + ImGui::SetCurrentContext(context); + + // ImGui Configuration + auto& io = ImGui::GetIO(); + + // Disable automatic configuration loading/saving + io.IniFilename = nullptr; + + // Style + auto& style = ImGui::GetStyle(); + style.WindowMinSize = {10.0f, 10.0f}; + + // Register context + static size_t nextId_ {0}; + p->contexts_.emplace_back(ImGuiContextInfo {nextId_++, name, context}); + + // Inform observers contexts have been updated + emit ContextsUpdated(); + + return context; +} + +void ImGuiManager::DestroyContext(const std::string& name) +{ + // Find context from registry + auto it = std::find_if(p->contexts_.begin(), + p->contexts_.end(), + [&](auto& info) { return info.name_ == name; }); + + if (it != p->contexts_.end()) + { + // Destroy context and erase from index + ImGui::SetCurrentContext(it->context_); + ImGui::DestroyContext(); + p->contexts_.erase(it); + + // Inform observers contexts have been updated + emit ContextsUpdated(); + } +} + +std::vector ImGuiManager::contexts() const +{ + return p->contexts_; +} + +ImGuiManager& ImGuiManager::Instance() +{ + static ImGuiManager instance_; + return instance_; +} + +bool ImGuiContextInfo::operator==(const ImGuiContextInfo& o) const = default; + +} // namespace manager +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/manager/imgui_manager.hpp b/scwx-qt/source/scwx/qt/manager/imgui_manager.hpp new file mode 100644 index 00000000..975a9231 --- /dev/null +++ b/scwx-qt/source/scwx/qt/manager/imgui_manager.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include +#include + +#include + +struct ImGuiContext; + +namespace scwx +{ +namespace qt +{ +namespace manager +{ + +class ImGuiManagerImpl; + +struct ImGuiContextInfo +{ + size_t id_ {}; + std::string name_ {}; + ImGuiContext* context_ {}; + + bool operator==(const ImGuiContextInfo& o) const; +}; + +class ImGuiManager : public QObject +{ +private: + Q_OBJECT + Q_DISABLE_COPY(ImGuiManager) + +public: + explicit ImGuiManager(); + ~ImGuiManager(); + + ImGuiContext* CreateContext(const std::string& name); + void DestroyContext(const std::string& name); + + std::vector contexts() const; + + static ImGuiManager& Instance(); + +signals: + void ContextsUpdated(); + +private: + friend class ImGuiManagerImpl; + std::unique_ptr p; +}; + +} // namespace manager +} // namespace qt +} // namespace scwx diff --git a/test/source/scwx/qt/manager/imgui_manager.test.cpp b/test/source/scwx/qt/manager/imgui_manager.test.cpp new file mode 100644 index 00000000..e25cee22 --- /dev/null +++ b/test/source/scwx/qt/manager/imgui_manager.test.cpp @@ -0,0 +1,44 @@ +#include + +#include + +namespace scwx +{ +namespace qt +{ +namespace manager +{ + +TEST(ImGuiManagerTest, State) +{ + auto& ImGuiManager = ImGuiManager::Instance(); + + ImGuiManager.CreateContext("Context One"); + ImGuiManager.CreateContext("Context Two"); + ImGuiManager.CreateContext("Context Three"); + + auto contexts = ImGuiManager.contexts(); + + ASSERT_EQ(contexts.size(), 3u); + EXPECT_EQ(contexts.at(0).id_, 0u); + EXPECT_EQ(contexts.at(1).id_, 1u); + EXPECT_EQ(contexts.at(2).id_, 2u); + EXPECT_EQ(contexts.at(0).name_, "Context One"); + EXPECT_EQ(contexts.at(1).name_, "Context Two"); + EXPECT_EQ(contexts.at(2).name_, "Context Three"); + EXPECT_NE(contexts.at(0).context_, nullptr); + EXPECT_NE(contexts.at(1).context_, nullptr); + EXPECT_NE(contexts.at(2).context_, nullptr); + + ImGuiManager.DestroyContext("Context Two"); + + auto contexts2 = ImGuiManager.contexts(); + + ASSERT_EQ(contexts2.size(), 2u); + EXPECT_EQ(contexts2.at(0), contexts.at(0)); + EXPECT_EQ(contexts2.at(1), contexts.at(2)); +} + +} // namespace manager +} // namespace qt +} // namespace scwx diff --git a/test/test.cmake b/test/test.cmake index 76984a3a..812a70da 100644 --- a/test/test.cmake +++ b/test/test.cmake @@ -21,7 +21,8 @@ set(SRC_PROVIDER_TESTS source/scwx/provider/aws_level2_data_provider.test.cpp source/scwx/provider/warnings_provider.test.cpp) set(SRC_QT_CONFIG_TESTS source/scwx/qt/config/county_database.test.cpp source/scwx/qt/config/radar_site.test.cpp) -set(SRC_QT_MANAGER_TESTS source/scwx/qt/manager/settings_manager.test.cpp) +set(SRC_QT_MANAGER_TESTS source/scwx/qt/manager/imgui_manager.test.cpp + source/scwx/qt/manager/settings_manager.test.cpp) set(SRC_UTIL_TESTS source/scwx/util/float.test.cpp source/scwx/util/rangebuf.test.cpp source/scwx/util/streams.test.cpp