如何通过代码让ImGui可停靠窗口填满剩余dockspace?
问题
基于ImGui的docking分支开发应用,在dockspace中包含Sidebar(侧边栏)和Content(内容窗口)两个可停靠窗口。希望通过代码让Content窗口像VS Code一样自动填满dockspace剩余区域,无需手动拖拽;但当前侧边栏与内容窗口之间存在异常空隙,手动拖拽可实现预期效果。
当前实现代码
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();
解决方案
问题出在第二次调用ImGui::DockBuilderSplitNode:当你第一次拆分左侧节点后,剩余的dockspace_id已经是右侧的全部区域,不需要再以1.0f的比例拆分右侧——这个操作会创建无效节点,导致出现空隙。
直接将Content窗口停靠到第一次拆分后剩余的dockspace_id即可,修改后的dockspace构建代码如下:
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); // 只拆分左侧节点,剩余的dockspace_id就是右侧区域 auto dock_id_left = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Left, 0.2f, nullptr, &dockspace_id); ImGui::DockBuilderDockWindow("Sidebar", dock_id_left); // 将Content窗口停靠到剩余的dockspace_id(即右侧区域) ImGui::DockBuilderDockWindow("Content", dockspace_id); ImGui::DockBuilderFinish(dockspace_id); }
关键修改点
- 删除了
auto dock_id_right = ImGui::DockBuilderSplitNode(...)这一行无效拆分代码 - 将
ImGui::DockBuilderDockWindow("Content", dock_id_right)改为ImGui::DockBuilderDockWindow("Content", dockspace_id),直接使用第一次拆分后剩余的节点ID
这样Content窗口就会自动填满dockspace的剩余区域,和手动拖拽的效果一致。
内容的提问来源于stack exchange,提问作者Live Dojo
相关产品推荐
相关产品推荐

