Create an explicit dockspace node within an existing window. Also expose dock node flags and creates a CentralNode by default. The Central Node is always displayed even when empty and shrink/extend according to the requested size of its neighbors. DockSpace() needs to be submitted _before_ any window they can host. If you use a dockspace, submit it early in your app.
| 17148 | // The Central Node is always displayed even when empty and shrink/extend according to the requested size of its neighbors. |
| 17149 | // DockSpace() needs to be submitted _before_ any window they can host. If you use a dockspace, submit it early in your app. |
| 17150 | ImGuiID ImGui::DockSpace(ImGuiID id, const ImVec2& size_arg, ImGuiDockNodeFlags flags, const ImGuiWindowClass* window_class) |
| 17151 | { |
| 17152 | ImGuiContext* ctx = GImGui; |
| 17153 | ImGuiContext& g = *ctx; |
| 17154 | ImGuiWindow* window = GetCurrentWindow(); |
| 17155 | if (!(g.IO.ConfigFlags & ImGuiConfigFlags_DockingEnable)) |
| 17156 | return 0; |
| 17157 | |
| 17158 | // Early out if parent window is hidden/collapsed |
| 17159 | // This is faster but also DockNodeUpdateTabBar() relies on TabBarLayout() running (which won't if SkipItems=true) to set NextSelectedTabId = 0). See #2960. |
| 17160 | // If for whichever reason this is causing problem we would need to ensure that DockNodeUpdateTabBar() ends up clearing NextSelectedTabId even if SkipItems=true. |
| 17161 | if (window->SkipItems) |
| 17162 | flags |= ImGuiDockNodeFlags_KeepAliveOnly; |
| 17163 | |
| 17164 | IM_ASSERT((flags & ImGuiDockNodeFlags_DockSpace) == 0); |
| 17165 | IM_ASSERT(id != 0); |
| 17166 | ImGuiDockNode* node = DockContextFindNodeByID(ctx, id); |
| 17167 | if (!node) |
| 17168 | { |
| 17169 | IMGUI_DEBUG_LOG_DOCKING("[docking] DockSpace: dockspace node 0x%08X created\n", id); |
| 17170 | node = DockContextAddNode(ctx, id); |
| 17171 | node->SetLocalFlags(ImGuiDockNodeFlags_CentralNode); |
| 17172 | } |
| 17173 | if (window_class && window_class->ClassId != node->WindowClass.ClassId) |
| 17174 | IMGUI_DEBUG_LOG_DOCKING("[docking] DockSpace: dockspace node 0x%08X: setup WindowClass 0x%08X -> 0x%08X\n", id, node->WindowClass.ClassId, window_class->ClassId); |
| 17175 | node->SharedFlags = flags; |
| 17176 | node->WindowClass = window_class ? *window_class : ImGuiWindowClass(); |
| 17177 | |
| 17178 | // When a DockSpace transitioned form implicit to explicit this may be called a second time |
| 17179 | // It is possible that the node has already been claimed by a docked window which appeared before the DockSpace() node, so we overwrite IsDockSpace again. |
| 17180 | if (node->LastFrameActive == g.FrameCount && !(flags & ImGuiDockNodeFlags_KeepAliveOnly)) |
| 17181 | { |
| 17182 | IM_ASSERT(node->IsDockSpace() == false && "Cannot call DockSpace() twice a frame with the same ID"); |
| 17183 | node->SetLocalFlags(node->LocalFlags | ImGuiDockNodeFlags_DockSpace); |
| 17184 | return id; |
| 17185 | } |
| 17186 | node->SetLocalFlags(node->LocalFlags | ImGuiDockNodeFlags_DockSpace); |
| 17187 | |
| 17188 | // Keep alive mode, this is allow windows docked into this node so stay docked even if they are not visible |
| 17189 | if (flags & ImGuiDockNodeFlags_KeepAliveOnly) |
| 17190 | { |
| 17191 | node->LastFrameAlive = g.FrameCount; |
| 17192 | return id; |
| 17193 | } |
| 17194 | |
| 17195 | const ImVec2 content_avail = GetContentRegionAvail(); |
| 17196 | ImVec2 size = ImFloor(size_arg); |
| 17197 | if (size.x <= 0.0f) |
| 17198 | size.x = ImMax(content_avail.x + size.x, 4.0f); // Arbitrary minimum child size (0.0f causing too much issues) |
| 17199 | if (size.y <= 0.0f) |
| 17200 | size.y = ImMax(content_avail.y + size.y, 4.0f); |
| 17201 | IM_ASSERT(size.x > 0.0f && size.y > 0.0f); |
| 17202 | |
| 17203 | node->Pos = window->DC.CursorPos; |
| 17204 | node->Size = node->SizeRef = size; |
| 17205 | SetNextWindowPos(node->Pos); |
| 17206 | SetNextWindowSize(node->Size); |
| 17207 | g.NextWindowData.PosUndock = false; |
nothing calls this directly
no test coverage detected