From 11aa026b8e2dd28bac2a0b1b9d1fc554d73f66e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Tue, 19 Mar 2024 15:46:20 +0100 Subject: [PATCH] Try to add overlay. --- include/frame/gui/draw_gui_interface.h | 15 +++- src/frame/opengl/gui/sdl_opengl_draw_gui.cpp | 86 +++++++++++++++----- src/frame/opengl/gui/sdl_opengl_draw_gui.h | 22 ++++- 3 files changed, 99 insertions(+), 24 deletions(-) diff --git a/include/frame/gui/draw_gui_interface.h b/include/frame/gui/draw_gui_interface.h index d629b29..95363c5 100644 --- a/include/frame/gui/draw_gui_interface.h +++ b/include/frame/gui/draw_gui_interface.h @@ -23,6 +23,19 @@ class DrawGuiInterface : public PluginInterface * @param callback: A window callback that can add buttons, etc. */ virtual void AddWindow(std::unique_ptr callback) = 0; + /** + * @brief Add a overlay window. + * @param position: The position of the window. + * @param callback: A window callback that can add buttons, etc. + * + * Overlay window are drawn on top of the main window and are not + * affected. Also note that they are only display when the main window + * is fullscreen. + */ + virtual void AddOverlayWindow( + glm::vec2 position, + glm::vec2 size, + std::unique_ptr callback) = 0; /** * @brief Add a modal window. * @param callback: A window callback that can add buttons, etc. @@ -46,7 +59,7 @@ class DrawGuiInterface : public PluginInterface virtual std::vector GetWindowTitles() const = 0; /** * @brief Delete a sub window. - * @param name: the name of the window to be deleted. + * @param name: the name of the window or overlay to be deleted. */ virtual void DeleteWindow(const std::string& name) = 0; /** diff --git a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp index 406890e..978ebf6 100644 --- a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp +++ b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp @@ -103,11 +103,11 @@ bool SDL2OpenGLDrawGui::Update(DeviceInterface& device, double dt) { ImGui::DockSpaceOverViewport(ImGui::GetMainViewport()); // Make the other window visible. - for (const auto& pair : callbacks_) + for (const auto& pair : window_callbacks_) { // Call the callback! - ImGui::Begin(pair.second->GetName().c_str()); - if (!pair.second->DrawCallback()) + ImGui::Begin(pair.second.callback->GetName().c_str()); + if (!pair.second.callback->DrawCallback()) returned_value = false; ImGui::End(); } @@ -130,19 +130,7 @@ bool SDL2OpenGLDrawGui::Update(DeviceInterface& device, double dt) ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); original_image_size_ = texture.GetSize(); } - // This is in window addition to the main window. - bool is_invisible_window = name_[0] == '#' && name_[1] == '#'; - if (is_invisible_window && is_default_output) - { - ImGui::SetNextWindowPos( - ImVec2( - static_cast(next_window_position_.x), - static_cast(next_window_position_.y))); - ImGui::SetNextWindowSize( - ImVec2( - static_cast(original_image_size_.x), - static_cast(original_image_size_.y))); - } + // If the window are not visible and it is not the main window then // bail out. if (!is_visible_ && !is_default_output) @@ -224,6 +212,30 @@ bool SDL2OpenGLDrawGui::Update(DeviceInterface& device, double dt) } } + if (!is_visible_) + { + for (const auto& pair : overlay_callbacks_) + { + ImGui::SetNextWindowPos( + ImVec2( + static_cast(pair.second.position.x), + static_cast(pair.second.position.y))); + ImGui::SetNextWindowSize( + ImVec2( + static_cast(pair.second.size.x), + static_cast(pair.second.size.y))); + // Setup overlay window with appropriate flags + ImGui::Begin( + pair.first.c_str(), + nullptr, + ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoTitleBar | + ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoMove | + ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoInputs); + pair.second.callback->DrawCallback(); + ImGui::End(); + } + } + // Rendering ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); @@ -251,10 +263,27 @@ void SDL2OpenGLDrawGui::AddWindow( { throw std::runtime_error("Cannot create a sub window without a name!"); } - callbacks_.insert({name, std::move(callback)}); + window_callbacks_.insert( + {name, {std::move(callback), {0.0f, 0.0f}, {0.0f, 0.0f}}}); +} + +void SDL2OpenGLDrawGui::AddOverlayWindow( + glm::vec2 position, + glm::vec2 size, + std::unique_ptr callback) +{ + std::string name = callback->GetName(); + if (name.empty()) + { + throw std::runtime_error( + "Cannot create a sub window without a name!"); + } + overlay_callbacks_.insert( + {name, {std::move(callback), position, size}}); } -void SDL2OpenGLDrawGui::AddModalWindow(std::unique_ptr callback) +void SDL2OpenGLDrawGui::AddModalWindow( + std::unique_ptr callback) { modal_callback_ = std::move(callback); } @@ -262,7 +291,7 @@ void SDL2OpenGLDrawGui::AddModalWindow(std::unique_ptr SDL2OpenGLDrawGui::GetWindowTitles() const { std::vector name_list; - for (const auto& [name, _] : callbacks_) + for (const auto& [name, _] : window_callbacks_) { name_list.push_back(name); } @@ -271,7 +300,14 @@ std::vector SDL2OpenGLDrawGui::GetWindowTitles() const void SDL2OpenGLDrawGui::DeleteWindow(const std::string& name) { - callbacks_.erase(name); + if (window_callbacks_.contains(name)) + { + window_callbacks_.erase(name); + } + if (overlay_callbacks_.contains(name)) + { + overlay_callbacks_.erase(name); + } } bool SDL2OpenGLDrawGui::PollEvent(void* event) @@ -294,7 +330,15 @@ bool SDL2OpenGLDrawGui::PollEvent(void* event) frame::gui::GuiWindowInterface& SDL2OpenGLDrawGui::GetWindow( const std::string& name) { - return *callbacks_.at(name).get(); + if (window_callbacks_.contains(name)) + { + return *window_callbacks_.at(name).callback.get(); + } + if (overlay_callbacks_.contains(name)) + { + return *overlay_callbacks_.at(name).callback.get(); + } + throw std::runtime_error("Cannot find the window with the name: " + name); } } // End namespace frame::opengl::gui. diff --git a/src/frame/opengl/gui/sdl_opengl_draw_gui.h b/src/frame/opengl/gui/sdl_opengl_draw_gui.h index 7eddc46..cd34cc3 100644 --- a/src/frame/opengl/gui/sdl_opengl_draw_gui.h +++ b/src/frame/opengl/gui/sdl_opengl_draw_gui.h @@ -107,6 +107,19 @@ class SDL2OpenGLDrawGui : public frame::gui::DrawGuiInterface */ void AddWindow( std::unique_ptr callback) override; + /** + * @brief Add a overlay window. + * @param position: The position of the window. + * @param callback: A window callback that can add buttons, etc. + * + * Overlay window are drawn on top of the main window and are not + * affected. Also note that they are only display when the main window + * is fullscreen. + */ + void AddOverlayWindow( + glm::vec2 position, + glm::vec2 size, + std::unique_ptr callback) override; /** * @brief Add a modal window. * @param callback: A window callback that can add buttons, etc. @@ -153,8 +166,13 @@ class SDL2OpenGLDrawGui : public frame::gui::DrawGuiInterface bool PollEvent(void* event) override; protected: - std::map> - callbacks_ = {}; + struct CallbackData { + std::unique_ptr callback = nullptr; + glm::vec2 position = { 0.0f, 0.0f }; + glm::vec2 size = { 0.0f, 0.0f }; + }; + std::map window_callbacks_ = {}; + std::map overlay_callbacks_ = {}; std::unique_ptr modal_callback_ = nullptr; bool start_modal_ = false; std::filesystem::path font_path_;