mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-17 07:29:20 +02:00
feat(ui): panels can be docked together and dragged out of the simulator window into windows of their own (imgui multi-viewports, ui.viewports yes by default, off where the renderer or the platform can't do it, e.g. wayland); imgui coordinates kept relative to the main window by the glfw backend, so the overlays, picking and gizmo of the editor work unchanged; overlays of the 3d view drawn on the main viewport; keys pressed in the separate windows passed on to the simulator, so the shortcuts of the editor work there too
This commit is contained in:
@@ -23,6 +23,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "imgui/imgui_impl_glfw.h"
|
||||
|
||||
GLFWwindow *ui_layer::m_window{nullptr};
|
||||
GLFWwindow *ui_layer::m_keywindow{nullptr};
|
||||
ImGuiIO *ui_layer::m_imguiio{nullptr};
|
||||
GLint ui_layer::m_textureunit{GL_TEXTURE0};
|
||||
bool ui_layer::m_cursorvisible;
|
||||
@@ -108,7 +109,7 @@ ui_layer::~ui_layer() {}
|
||||
|
||||
bool ui_layer::key_callback(int key, int scancode, int action, int mods)
|
||||
{
|
||||
ImGui_ImplGlfw_KeyCallback(m_window, key, scancode, action, mods);
|
||||
ImGui_ImplGlfw_KeyCallback(m_keywindow != nullptr ? m_keywindow : m_window, key, scancode, action, mods);
|
||||
return m_imguiio->WantCaptureKeyboard;
|
||||
}
|
||||
|
||||
@@ -152,6 +153,27 @@ void ui_layer::focus_callback(int focused)
|
||||
ImGui_ImplGlfw_WindowFocusCallback(m_window, focused);
|
||||
}
|
||||
|
||||
void ui_layer::viewport_key_callback(GLFWwindow *Window, int key, int scancode, int action, int mods)
|
||||
{
|
||||
// imgui gets the key with the window it came from (the state of modifiers is read from it), the simulator gets it unless imgui takes it
|
||||
m_keywindow = Window;
|
||||
Application.on_key(key, scancode, action, mods);
|
||||
m_keywindow = nullptr;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
// window creation of the glfw backend, wrapped to give the new windows the key callback of the simulator
|
||||
void (*imgui_create_window)(ImGuiViewport *Viewport){nullptr};
|
||||
|
||||
void create_viewport_window(ImGuiViewport *Viewport)
|
||||
{
|
||||
imgui_create_window(Viewport);
|
||||
if (Viewport->PlatformHandle != nullptr)
|
||||
glfwSetKeyCallback(static_cast<GLFWwindow *>(Viewport->PlatformHandle), ui_layer::viewport_key_callback);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void ui_layer::imgui_style()
|
||||
{
|
||||
// palette shared with the MaSzyna starter: flat dark panels, thin borders, green accents
|
||||
@@ -341,6 +363,20 @@ bool ui_layer::init(GLFWwindow *Window)
|
||||
return false;
|
||||
}
|
||||
|
||||
// panels can be docked together, and dragged out of the simulator window into windows of their own (e.g. on another monitor)
|
||||
// when both backends can do it. glfw can't place windows under wayland. both flags have to be set before the first frame
|
||||
m_imguiio->ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||
auto const viewportsupport{(m_imguiio->BackendFlags & ImGuiBackendFlags_PlatformHasViewports) && (m_imguiio->BackendFlags & ImGuiBackendFlags_RendererHasViewports) &&
|
||||
glfwGetPlatform() != GLFW_PLATFORM_WAYLAND};
|
||||
if (Global.ui_viewports && viewportsupport)
|
||||
{
|
||||
m_imguiio->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
|
||||
auto &platformio{ImGui::GetPlatformIO()};
|
||||
imgui_create_window = platformio.Platform_CreateWindow;
|
||||
platformio.Platform_CreateWindow = create_viewport_window;
|
||||
}
|
||||
WriteLog(std::string("ui: panels in separate windows ") + ((m_imguiio->ConfigFlags & ImGuiConfigFlags_ViewportsEnable) ? "enabled" : (viewportsupport ? "disabled in settings" : "not supported here")));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -440,6 +476,15 @@ void ui_layer::render_internal()
|
||||
{
|
||||
ImGui::Render();
|
||||
GfxRenderer->GetImguiRenderer()->Render();
|
||||
|
||||
if (m_imguiio->ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
// panels outside of the main window are drawn in their own windows, whose gl contexts are shared with the main one
|
||||
auto *context{glfwGetCurrentContext()};
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
glfwMakeContextCurrent(context);
|
||||
}
|
||||
}
|
||||
|
||||
void ui_layer::begin_ui_frame()
|
||||
@@ -670,5 +715,5 @@ void ui_layer::render_background()
|
||||
ImVec2 end_position(start_position.x + image_size.x, start_position.y + image_size.y);
|
||||
|
||||
// obrazek jest odwrócony w pionie – odwracamy UV
|
||||
ImGui::GetBackgroundDrawList()->AddImage((ImTextureID)(intptr_t)(tex.get_id()), start_position, end_position, ImVec2(0, 1), ImVec2(1, 0));
|
||||
ImGui::GetBackgroundDrawList(ImGui::GetMainViewport())->AddImage((ImTextureID)(intptr_t)(tex.get_id()), start_position, end_position, ImVec2(0, 1), ImVec2(1, 0));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user