I have a simple application with 2 dockable windows in a dockspace. One is sidebar and the other is the content.
I am using the docking branch of imgui
How do I make the content window fill up the remaining dockspace programmatically? Kind of like Visual Studio Code
Currently, there is some weird space between the sidebar and the content window
Current Output Expected Output, I got this by manually dragging the window and docking it
I do it like this
static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_PassthruCentralNode;
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDocking;
ImGuiViewport* 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);
window_flags |= ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove;
window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
if (dockspace_flags & ImGuiDockNodeFlags_PassthruCentralNode)
window_flags |= ImGuiWindowFlags_NoBackground;
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(1.0f, 0.0f));
ImGui::Begin("Root", nullptr, window_flags);
ImGui::PopStyleVar();
ImGui::PopStyleVar(2);
// Dockspace
if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable)
{
ImGuiID dockspace_id = ImGui::GetID("Root");
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
static auto first_time = true;
if (first_time)
{
first_time = false;
ImGui::DockBuilderRemoveNode(dockspace_id);
ImGui::DockBuilderAddNode(dockspace_id, dockspace_flags | ImGuiDockNodeFlags_DockSpace);
ImGui::DockBuilderSetNodeSize(dockspace_id, viewport->Size);
auto dock_id_left = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Left, 0.2f, nullptr, &dockspace_id);
auto dock_id_right = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Right, 1.0f, nullptr, &dockspace_id);
ImGui::DockBuilderDockWindow("Sidebar", dock_id_left);
ImGui::DockBuilderDockWindow("Content", dock_id_right);
ImGui::DockBuilderFinish(dockspace_id);
}
}
ImGui::Begin("Sidebar");
ImGui::Text("Text 1");
ImGui::Text("Text 2");
ImGui::Text("Text 3");
ImGui::End();
ImGui::Begin("Content");
ImGui::Button("Button 1");
ImGui::Button("Button 2");
ImGui::Button("Button 3");
ImGui::End();
I eventually figured this same issue out thanks to this comment on the docking thread. Intuitively you want to create a "dock node" for each space, but in ImGui terms we're really docking one window to the side and docking the other window to the central dock space which will make it take up the remaining space.
Therefore your code should look like this to get one docked side bar and one (or more) window(s) in the remaining space:
ImGuiIO& io = ImGui::GetIO();
if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable) {
ImGuiID dockspace_id = ImGui::GetID("MyDockspace");
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
static auto first_time = true;
if (first_time)
{
first_time = false;
// Clear out existing layout
ImGui::DockBuilderRemoveNode(dockspace_id);
// Add empty node
ImGui::DockBuilderAddNode(dockspace_id, dockspace_flags | ImGuiDockNodeFlags_DockSpace);
// Main node should cover entire window
ImGui::DockBuilderSetNodeSize(dockspace_id, ImGui::GetWindowSize());
// get id of main dock space area
ImGuiID dockspace_main_id = dockspace_id;
// Create a dock node for the right docked window
ImGuiID right = ImGui::DockBuilderSplitNode(dockspace_main_id, ImGuiDir_Right, 0.25f, nullptr, &dockspace_main_id);
ImGui::DockBuilderDockWindow("Content One", dockspace_main_id);
ImGui::DockBuilderDockWindow("Content Two", dockspace_main_id);
ImGui::DockBuilderDockWindow("Side Bar", right);
ImGui::DockBuilderFinish(dockspace_id);
}
}
When using two windows like this, they show up as tabbed window in the main space.