From 1d3862b6b3fad2cf7b2e934b95d5710f38632b32 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 3 Oct 2018 14:51:31 +0200 Subject: [PATCH] Docking: Added ImGuiDockNodeFlags_NoDockingInsideDocRootNode flag. Honoring ImGuiDockNodeFlags_NoSplit in child node is already split (so we can use DockBuilder and then lock the layout). Added those options to the demo. (#2109) --- imgui.cpp | 13 +++++++++++++ imgui.h | 3 ++- imgui_demo.cpp | 44 +++++++++++++++++++++++++------------------- 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4ae4cec72..411a60b33 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10452,6 +10452,10 @@ static void ImGui::DockNodeUpdateVisibleFlagAndInactiveChilds(ImGuiDockNode* nod IM_ASSERT(node->ParentNode == NULL || node->ParentNode->ChildNodes[0] == node || node->ParentNode->ChildNodes[1] == node); + // Inherit flags + if (node->ParentNode) + node->Flags = node->ParentNode->Flags; + // Recurse into children // There is the possibility that one of our child becoming empty will delete itself and moving its sibling contents into 'node'. // If 'node->ChildNode[0]' delete itself, then 'node->ChildNode[1]->Windows' will be moved into 'node' @@ -11055,6 +11059,8 @@ static bool ImGui::DockNodePreviewDockCalc(ImGuiWindow* host_window, ImGuiDockNo data->IsCenterAvailable = !is_outer_docking; if (src_is_visibly_splitted && (!host_node || !host_node->IsEmpty())) data->IsCenterAvailable = false; + if (host_node && (host_node->Flags & ImGuiDockNodeFlags_NoDockingInsideDocRootNode) && host_node->IsDocumentRoot) + data->IsCenterAvailable = false; data->IsSidesAvailable = true; if (host_node && (host_node->Flags & ImGuiDockNodeFlags_NoSplit)) @@ -11946,6 +11952,13 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open) g.NextWindowData.PosUndock = false; } + // Undock if the ImGuiDockNodeFlags_NoDockingInDocRootNode got set + if (dock_node->IsDocumentRoot && (dock_node->Flags & ImGuiDockNodeFlags_NoDockingInsideDocRootNode)) + { + DockContextProcessUndockWindow(ctx, window); + return; + } + // Undock if our dockspace node disappeared // Note how we are testing for LastFrameAlive and NOT LastFrameActive. A DockSpace node can be maintained alive while being inactive with ImGuiDockNodeFlags_KeepAliveOnly. if (dock_node->LastFrameAlive < g.FrameCount) diff --git a/imgui.h b/imgui.h index 6527623c0..d7828a742 100644 --- a/imgui.h +++ b/imgui.h @@ -797,7 +797,8 @@ enum ImGuiDockNodeFlags_ { ImGuiDockNodeFlags_None = 0, ImGuiDockNodeFlags_KeepAliveOnly = 1 << 0, // Don't display the dockspace node but keep it alive. Windows docked into this dockspace node won't be undocked. - ImGuiDockNodeFlags_NoSplit = 1 << 1 // Disable splitting the node into smaller nodes. Useful e.g. when embedding dockspaces into a main root one (the root one may have splitting disableed to reduce confusion) + ImGuiDockNodeFlags_NoSplit = 1 << 1, // Disable splitting the node into smaller nodes. Useful e.g. when embedding dockspaces into a main root one (the root one may have splitting disabled to reduce confusion) + ImGuiDockNodeFlags_NoDockingInsideDocRootNode = 1 << 2 // Disable docking inside the DocumentRoot node. Useful if it is kept empty and invisible. }; // Flags for ImGui::IsWindowFocused() diff --git a/imgui_demo.cpp b/imgui_demo.cpp index ef9d680e4..3e52d6606 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -3732,25 +3732,42 @@ void ShowExampleAppDockSpace(bool* p_open) flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove; flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus; } + + static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None; ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); ImGui::Begin("DockSpace Demo", p_open, flags); ImGui::PopStyleVar(); + // Dockspace + 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); + } + else + { + ShowDockingDisabledMessage(); + } + if (ImGui::BeginMenuBar()) { - if (ImGui::BeginMenu("Docking")) + if (ImGui::BeginMenu("Options")) { if (ImGui::MenuItem("Remove DockSpace", NULL, false, p_open != NULL)) *p_open = false; + ImGui::Separator(); + + if (ImGui::MenuItem("Flag: NoSplit", "", (dockspace_flags & ImGuiDockNodeFlags_NoSplit) != 0)) + dockspace_flags ^= ImGuiDockNodeFlags_NoSplit; + if (ImGui::MenuItem("Flag: NoDockingInsideDocRootNode", "", (dockspace_flags & ImGuiDockNodeFlags_NoDockingInsideDocRootNode) != 0)) + dockspace_flags ^= ImGuiDockNodeFlags_NoDockingInsideDocRootNode; + + // Disabling fullscreen would allow the window to be moved to the front of other windows, + // which we can't undo at the moment without finer window depth/z control. + //ImGui::MenuItem("Fullscreen", NULL, &opt_fullscreen_persistant); ImGui::EndMenu(); } - // Disabling fullscreen would allow the window to be moved to the front of other windows, - // which we can't undo at the moment without finer window depth/z control. - /*if (ImGui::BeginMenu("Options")) - { - ImGui::MenuItem("Fullscreen", NULL, &opt_fullscreen_persistant); - ImGui::EndMenu(); - }*/ ShowHelpMarker( "You can _always_ dock _any_ window into another by holding the SHIFT key while moving a window. Try it now!" "\n" "This demo app has nothing to do with it!" "\n\n" @@ -3762,17 +3779,6 @@ void ShowExampleAppDockSpace(bool* p_open) ImGui::EndMenuBar(); } - ImGuiIO& io = ImGui::GetIO(); - if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable) - { - ImGuiID dockspace_id = ImGui::GetID("MyDockspace"); - ImGui::DockSpace(dockspace_id); - } - else - { - ShowDockingDisabledMessage(); - } - ImGui::End(); if (opt_fullscreen) ImGui::PopStyleVar();