Description
Version/Branch of Dear ImGui:
v1.91.1 WIP Docking
Back-ends:
imgui_impl_sdl2.h, imgui_impl_opengl3.h
Compiler, OS:
Windows 64 mingw, windows 32 mingw, Linux 64 gcc, Linux 32 gcc, Emscripten llvm
Full config/build information:
Dear ImGui 1.91.1 WIP (19101)
--------------------------------
sizeof(size_t): 4, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=201103
define: __linux__
define: __GNUC__=13
define: IMGUI_HAS_VIEWPORT
define: IMGUI_HAS_DOCK
--------------------------------
io.BackendPlatformName: imgui_impl_sdl2
io.BackendRendererName: imgui_impl_opengl3
io.ConfigFlags: 0x00000081
NavEnableKeyboard
DockingEnable
io.ConfigViewportsNoDecoration
io.ConfigInputTextCursorBlink
io.ConfigWindowsResizeFromEdges
io.ConfigMemoryCompactTimer = 60.0
io.BackendFlags: 0x00001C0E
HasMouseCursors
HasSetMousePos
PlatformHasViewports
HasMouseHoveredViewport
RendererHasVtxOffset
RendererHasViewports
--------------------------------
io.Fonts: 1 fonts, Flags: 0x00000000, TexSize: 512,64
io.DisplaySize: 1280.00,721.00
io.DisplayFramebufferScale: 1.00,1.00
--------------------------------
style.WindowPadding: 8.00,8.00
style.WindowBorderSize: 1.00
style.FramePadding: 4.00,3.00
style.FrameRounding: 4.00
style.FrameBorderSize: 1.00
style.ItemSpacing: 8.00,4.00
style.ItemInnerSpacing: 4.00,4.00
Details:
I have an issue with an imgui docking window. I am trying to create a right hand side docking window which is split in two horizontally. The split is set initially at 50/50, but it shouldn't matter, because I am changing the size of the node split depending on the content of the top docking window (or at least that's what I'm attempting to do)
This does sort of work, but not as I would expect it, and I don't know what to attribute the strange behaviour. The dock window is in fact changing the height of the split window, but it's not exactly taking my values into account, it's using some other parameters to determine what size the node should be. Also, I've observed some strange exponential height changes toward the extreme (ver small and very large dock size)
Is this logic supported, to scale the dock dynamically based on content? I want the card to always be fully visible in the Preview window, at the cost of the other docked window in that vertical split group
Screenshots/Video:
vlc-record-2025-02-09-21h41m31s-2025-02-09.21-40-21.mkv-.mp4
Minimal, Complete and Verifiable Example code:
ImGuiViewport* viewport;
ImGuiID dockspace_id, dockspace_right_id, dockspace_left_id, dockspace_bottom_right_id, dockspace_top_right_id;
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_PassthruCentralNode;
void Interface::setupDocking() {
static bool first_time = true;
viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->Pos);
ImGui::SetNextWindowSize(viewport->Size);
ImGui::SetNextWindowViewport(viewport->ID);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
ImGui::Begin("DockSpace", nullptr, window_flags);
ImGui::PopStyleVar(3);
dockspace_id = ImGui::GetID("MyDockSpace");
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
if (first_time) {
ImGui::DockBuilderRemoveNode(dockspace_id); // clear any previous layout
ImGui::DockBuilderAddNode(dockspace_id, dockspace_flags | ImGuiDockNodeFlags_DockSpace);
ImGui::DockBuilderSetNodeSize(dockspace_id, viewport->Size);
dockspace_right_id = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Right, 0.2f, nullptr, &dockspace_id);
ImGui::DockBuilderSetNodeSize(dockspace_right_id, ImVec2(viewport->Size.x * 0.2f, viewport->Size.y));
dockspace_top_right_id = ImGui::DockBuilderSplitNode(dockspace_right_id, ImGuiDir_Up, 0.5f, nullptr, &dockspace_right_id);
dockspace_bottom_right_id = ImGui::DockBuilderSplitNode(dockspace_right_id, ImGuiDir_Down, 0.5f, nullptr, &dockspace_right_id);
ImGui::DockBuilderDockWindow("Search", dockspace_bottom_right_id);
ImGui::DockBuilderDockWindow("Preview", dockspace_top_right_id);
ImGui::DockBuilderFinish(dockspace_id);
first_time = false;
}
void Interface::drawCardWindow(const Card* card, const std::string& cardName) {
ImGui::Begin("Preview");
// Get the size of the preview window. We use it to set the texture size and update the dock node size.
ImVec2 windowSize = ImGui::GetWindowSize();
float width = windowSize.x;
float height = width * 1.395973154362416f;
if (ImGui::IsWindowDocked()) {
ImGuiID dockID = ImGui::GetWindowDockID();
ImGuiDockNode* dockNode = ImGui::DockBuilderGetNode(dockID);
if (dockNode) {
ImGui::DockBuilderSetNodeSize(dockID, ImVec2(width, height*1.5));
}
}
// Set the texture size based on the window size
ImGui::Image((void*)(intptr_t)card->getFrontTexture()->getID(), ImVec2(width - ImGui::GetStyle().WindowPadding.x * 2, height));
ImGui::End();
}
basically I get the window width,
multiply the width by the aspect ratio of the image to get the height,
and modify the dock window node size to match the height.
You may notice height*1.5 in the DockBuilderSetNodeSize, that's just because I was playing around with the values. Changing that value affects the initial placement of the split after loading the preview window, but doesn't affect anything once we start scaling the docking window horizontally
Activity