Przeglądaj źródła

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)

omar 7 lat temu
rodzic
commit
1d3862b6b3
3 zmienionych plików z 40 dodań i 20 usunięć
  1. 13 0
      imgui.cpp
  2. 2 1
      imgui.h
  3. 25 19
      imgui_demo.cpp

+ 13 - 0
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)

+ 2 - 1
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()

+ 25 - 19
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();