Docking: Extracted some of BeginDocked() into a DockContextBindNodeToWindow() function.

Moved one of the undocking blurb to favor fast path.
(Commit intended to have no functional side effects)
docking
omar 5 years ago
parent 27431dcc6b
commit 10a202422a

@ -11197,6 +11197,7 @@ namespace ImGui
static void DockContextProcessUndockNode(ImGuiContext* ctx, ImGuiDockNode* node); static void DockContextProcessUndockNode(ImGuiContext* ctx, ImGuiDockNode* node);
static void DockContextPruneUnusedSettingsNodes(ImGuiContext* ctx); static void DockContextPruneUnusedSettingsNodes(ImGuiContext* ctx);
static ImGuiDockNode* DockContextFindNodeByID(ImGuiContext* ctx, ImGuiID id); static ImGuiDockNode* DockContextFindNodeByID(ImGuiContext* ctx, ImGuiID id);
static ImGuiDockNode* DockContextBindNodeToWindow(ImGuiContext* ctx, ImGuiWindow* window);
static void DockContextClearNodes(ImGuiContext* ctx, ImGuiID root_id, bool clear_persistent_docking_refs); // Use root_id==0 to clear all static void DockContextClearNodes(ImGuiContext* ctx, ImGuiID root_id, bool clear_persistent_docking_refs); // Use root_id==0 to clear all
static void DockContextBuildNodesFromSettings(ImGuiContext* ctx, ImGuiDockNodeSettings* node_settings_array, int node_settings_count); static void DockContextBuildNodesFromSettings(ImGuiContext* ctx, ImGuiDockNodeSettings* node_settings_array, int node_settings_count);
static void DockContextBuildAddWindowsToNodes(ImGuiContext* ctx, ImGuiID root_id); // Use root_id==0 to add all static void DockContextBuildAddWindowsToNodes(ImGuiContext* ctx, ImGuiID root_id); // Use root_id==0 to add all
@ -11208,6 +11209,7 @@ namespace ImGui
static void DockNodeApplyPosSizeToWindows(ImGuiDockNode* node); static void DockNodeApplyPosSizeToWindows(ImGuiDockNode* node);
static void DockNodeRemoveWindow(ImGuiDockNode* node, ImGuiWindow* window, ImGuiID save_dock_id); static void DockNodeRemoveWindow(ImGuiDockNode* node, ImGuiWindow* window, ImGuiID save_dock_id);
static void DockNodeHideHostWindow(ImGuiDockNode* node); static void DockNodeHideHostWindow(ImGuiDockNode* node);
static ImGuiWindow* DockNodeFindWindowByID(ImGuiDockNode* node, ImGuiID id);
static void DockNodeUpdate(ImGuiDockNode* node); static void DockNodeUpdate(ImGuiDockNode* node);
static void DockNodeUpdateVisibleFlagAndInactiveChilds(ImGuiDockNode* node); static void DockNodeUpdateVisibleFlagAndInactiveChilds(ImGuiDockNode* node);
static void DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_window); static void DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_window);
@ -11261,6 +11263,7 @@ namespace ImGui
// - DockContextUpdateUndocking() // - DockContextUpdateUndocking()
// - DockContextUpdateDocking() // - DockContextUpdateDocking()
// - DockContextFindNodeByID() // - DockContextFindNodeByID()
// - DockContextBindNodeToWindow()
// - DockContextGenNodeID() // - DockContextGenNodeID()
// - DockContextAddNode() // - DockContextAddNode()
// - DockContextRemoveNode() // - DockContextRemoveNode()
@ -11800,7 +11803,7 @@ void ImGui::DockContextProcessUndockNode(ImGuiContext* ctx, ImGuiDockNode* node)
} }
else else
{ {
// Otherwise delete the previous node by merging the other sibling back into the parent node. // Otherwise extract our node and merging our sibling back into the parent node.
IM_ASSERT(node->ParentNode->ChildNodes[0] == node || node->ParentNode->ChildNodes[1] == node); IM_ASSERT(node->ParentNode->ChildNodes[0] == node || node->ParentNode->ChildNodes[1] == node);
int index_in_parent = (node->ParentNode->ChildNodes[0] == node) ? 0 : 1; int index_in_parent = (node->ParentNode->ChildNodes[0] == node) ? 0 : 1;
node->ParentNode->ChildNodes[index_in_parent] = NULL; node->ParentNode->ChildNodes[index_in_parent] = NULL;
@ -12295,6 +12298,7 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
const ImGuiDockNodeFlags node_flags = node->GetMergedFlags(); const ImGuiDockNodeFlags node_flags = node->GetMergedFlags();
// Bind or create host window
ImGuiWindow* host_window = NULL; ImGuiWindow* host_window = NULL;
bool beginned_into_host_window = false; bool beginned_into_host_window = false;
if (node->IsDockSpace()) if (node->IsDockSpace())
@ -14042,46 +14046,17 @@ bool ImGui::GetWindowAlwaysWantOwnTabBar(ImGuiWindow* window)
return false; return false;
} }
void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open) static ImGuiDockNode* ImGui::DockContextBindNodeToWindow(ImGuiContext* ctx, ImGuiWindow* window)
{ {
ImGuiContext* ctx = GImGui;
ImGuiContext& g = *ctx; ImGuiContext& g = *ctx;
ImGuiDockNode* node = DockContextFindNodeByID(ctx, window->DockId);
const bool auto_dock_node = GetWindowAlwaysWantOwnTabBar(window);
if (auto_dock_node)
{
if (window->DockId == 0)
{
IM_ASSERT(window->DockNode == NULL); IM_ASSERT(window->DockNode == NULL);
window->DockId = DockContextGenNodeID(ctx);
}
}
else
{
// Calling SetNextWindowPos() undock windows by default (by setting PosUndock)
bool want_undock = false;
want_undock |= (window->Flags & ImGuiWindowFlags_NoDocking) != 0;
want_undock |= (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasPos) && (window->SetWindowPosAllowFlags & g.NextWindowData.PosCond) && g.NextWindowData.PosUndock;
if (want_undock)
{
DockContextProcessUndockWindow(ctx, window);
return;
}
}
// Bind to our dock node
ImGuiDockNode* node = window->DockNode;
if (node != NULL)
IM_ASSERT(window->DockId == node->ID);
if (window->DockId != 0 && node == NULL)
{
node = DockContextFindNodeByID(ctx, window->DockId);
// We should not be docking into a split node (SetWindowDock should avoid this) // We should not be docking into a split node (SetWindowDock should avoid this)
if (node && node->IsSplitNode()) if (node && node->IsSplitNode())
{ {
DockContextProcessUndockWindow(ctx, window); DockContextProcessUndockWindow(ctx, window);
return; return NULL;
} }
// Create node // Create node
@ -14092,7 +14067,7 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
node->LastFrameAlive = g.FrameCount; node->LastFrameAlive = g.FrameCount;
} }
// If the node just turned visible, it doesn't have a Size assigned by DockNodeTreeUpdatePosSize() yet, // If the node just turned visible and is part of a hierarchy, it doesn't have a Size assigned by DockNodeTreeUpdatePosSize() yet,
// so we're forcing a Pos/Size update from the first ancestor that is already visible (often it will be the root node). // so we're forcing a Pos/Size update from the first ancestor that is already visible (often it will be the root node).
// If we don't do this, the window will be assigned a zero-size on its first frame, which won't ideally warm up the layout. // If we don't do this, the window will be assigned a zero-size on its first frame, which won't ideally warm up the layout.
// This is a little wonky because we don't normally update the Pos/Size of visible node mid-frame. // This is a little wonky because we don't normally update the Pos/Size of visible node mid-frame.
@ -14113,6 +14088,45 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
// Add window to node // Add window to node
DockNodeAddWindow(node, window, true); DockNodeAddWindow(node, window, true);
IM_ASSERT(node == window->DockNode); IM_ASSERT(node == window->DockNode);
return node;
}
void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
{
ImGuiContext* ctx = GImGui;
ImGuiContext& g = *ctx;
const bool auto_dock_node = GetWindowAlwaysWantOwnTabBar(window);
if (auto_dock_node)
{
if (window->DockId == 0)
{
IM_ASSERT(window->DockNode == NULL);
window->DockId = DockContextGenNodeID(ctx);
}
}
else
{
// Calling SetNextWindowPos() undock windows by default (by setting PosUndock)
bool want_undock = false;
want_undock |= (window->Flags & ImGuiWindowFlags_NoDocking) != 0;
want_undock |= (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasPos) && (window->SetWindowPosAllowFlags & g.NextWindowData.PosCond) && g.NextWindowData.PosUndock;
if (want_undock)
{
DockContextProcessUndockWindow(ctx, window);
return;
}
}
// Bind to our dock node
ImGuiDockNode* node = window->DockNode;
if (node != NULL)
IM_ASSERT(window->DockId == node->ID);
if (window->DockId != 0 && node == NULL)
{
node = DockContextBindNodeToWindow(ctx, window);
if (node == NULL)
return;
} }
#if 0 #if 0
@ -14142,23 +14156,26 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
return; return;
} }
// Undock if we are submitted earlier than the host window // Fast path return. It is common for windows to hold on a persistent DockId but be the only visible window,
if (node->HostWindow && window->BeginOrderWithinContext < node->HostWindow->BeginOrderWithinContext) // and never create neither a host window neither a tab bar.
{
DockContextProcessUndockWindow(ctx, window);
return;
}
// FIXME-DOCK: replace ->HostWindow NULL compare with something more explicit (~was initially intended as a first frame test) // FIXME-DOCK: replace ->HostWindow NULL compare with something more explicit (~was initially intended as a first frame test)
if (node->HostWindow == NULL) if (node->HostWindow == NULL)
{ {
window->DockTabIsVisible = false; window->DockTabIsVisible = false;
return; return;
} }
IM_ASSERT(node->HostWindow); IM_ASSERT(node->HostWindow);
IM_ASSERT(node->IsLeafNode()); IM_ASSERT(node->IsLeafNode());
IM_ASSERT(node->Size.x > 0.0f && node->Size.y > 0.0f); IM_ASSERT(node->Size.x > 0.0f && node->Size.y > 0.0f);
// Undock if we are submitted earlier than the host window
if (window->BeginOrderWithinContext < node->HostWindow->BeginOrderWithinContext)
{
DockContextProcessUndockWindow(ctx, window);
return;
}
// Position window // Position window
SetNextWindowPos(node->Pos); SetNextWindowPos(node->Pos);
SetNextWindowSize(node->Size); SetNextWindowSize(node->Size);

Loading…
Cancel
Save