mirror of
https://github.com/Drezil/imgui.git
synced 2025-01-19 03:16:35 +00:00
Docking: Fix generalizing the transition from loose windows to dock node so we can switch to single window dock node while transferring viewports (vs creating two viewports and dropping one). + Extracted DockContextGenNodeID out of DockContextAddNode().
This commit is contained in:
parent
ac10889bde
commit
2da200fc16
29
imgui.cpp
29
imgui.cpp
@ -9818,6 +9818,7 @@ namespace ImGui
|
|||||||
{
|
{
|
||||||
// ImGuiDockContext
|
// ImGuiDockContext
|
||||||
static ImGuiDockNode* DockContextAddNode(ImGuiContext* ctx, ImGuiID id);
|
static ImGuiDockNode* DockContextAddNode(ImGuiContext* ctx, ImGuiID id);
|
||||||
|
static ImGuiID DockContextGenNodeID(ImGuiContext* ctx);
|
||||||
static void DockContextRemoveNode(ImGuiContext* ctx, ImGuiDockNode* node, bool merge_sibling_into_parent_node);
|
static void DockContextRemoveNode(ImGuiContext* ctx, ImGuiDockNode* node, bool merge_sibling_into_parent_node);
|
||||||
static void DockContextQueueDock(ImGuiContext* ctx, ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload, ImGuiDir split_dir, float split_ratio, bool split_outer);
|
static void DockContextQueueDock(ImGuiContext* ctx, ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload, ImGuiDir split_dir, float split_ratio, bool split_outer);
|
||||||
static void DockContextQueueNotifyRemovedNode(ImGuiContext* ctx, ImGuiDockNode* node);
|
static void DockContextQueueNotifyRemovedNode(ImGuiContext* ctx, ImGuiDockNode* node);
|
||||||
@ -10008,17 +10009,23 @@ static ImGuiDockNode* ImGui::DockContextFindNodeByID(ImGuiContext* ctx, ImGuiID
|
|||||||
return (ImGuiDockNode*)ctx->DockContext->Nodes.GetVoidPtr(id);
|
return (ImGuiDockNode*)ctx->DockContext->Nodes.GetVoidPtr(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ImGuiID ImGui::DockContextGenNodeID(ImGuiContext* ctx)
|
||||||
|
{
|
||||||
|
// Generate an ID for new node (the exact ID value doesn't matter as long as it is not already used)
|
||||||
|
// FIXME-OPT: This is suboptimal, even if the node count is small enough not to be a worry. We should poke in ctx->Nodes to find a suitable ID faster.
|
||||||
|
ImGuiID id = 0x0001;
|
||||||
|
while (DockContextFindNodeByID(ctx, id) != NULL)
|
||||||
|
id++;
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
static ImGuiDockNode* ImGui::DockContextAddNode(ImGuiContext* ctx, ImGuiID id)
|
static ImGuiDockNode* ImGui::DockContextAddNode(ImGuiContext* ctx, ImGuiID id)
|
||||||
{
|
{
|
||||||
// Generate an ID for the new node (the exact ID value doesn't matter as long as it is not already used) and add the first window.
|
// Generate an ID for the new node (the exact ID value doesn't matter as long as it is not already used) and add the first window.
|
||||||
if (id == 0)
|
if (id == 0)
|
||||||
{
|
id = DockContextGenNodeID(ctx);
|
||||||
// FIXME-OPT: This is suboptimal, even if the node count is small enough not to be a worry. We could poke in ctx->Nodes to find a suitable ID faster.
|
else
|
||||||
id = 0x0001;
|
IM_ASSERT(DockContextFindNodeByID(ctx, id) == NULL);
|
||||||
while (DockContextFindNodeByID(ctx, id) != NULL)
|
|
||||||
id++;
|
|
||||||
}
|
|
||||||
IM_ASSERT(DockContextFindNodeByID(ctx, id) == NULL);
|
|
||||||
ImGuiDockNode* node = IM_NEW(ImGuiDockNode)(id);
|
ImGuiDockNode* node = IM_NEW(ImGuiDockNode)(id);
|
||||||
node->InitFromFirstWindowPosSize = node->InitFromFirstWindowViewport = true;
|
node->InitFromFirstWindowPosSize = node->InitFromFirstWindowViewport = true;
|
||||||
ctx->DockContext->Nodes.SetVoidPtr(node->ID, node);
|
ctx->DockContext->Nodes.SetVoidPtr(node->ID, node);
|
||||||
@ -10436,14 +10443,15 @@ static void ImGui::DockNodeAddWindow(ImGuiDockNode* node, ImGuiWindow* window, b
|
|||||||
|
|
||||||
// If 2+ windows appeared on the same frame, creating a new DockNode+TabBar from the second window,
|
// If 2+ windows appeared on the same frame, creating a new DockNode+TabBar from the second window,
|
||||||
// then we need to hide the first one after the fact otherwise it would be visible as a standalone window for one frame.
|
// then we need to hide the first one after the fact otherwise it would be visible as a standalone window for one frame.
|
||||||
if (node->Windows.Size == 2 && node->HostWindow == NULL && node->Windows[0]->WasActive == false)
|
if (node->HostWindow == NULL && node->Windows.Size == 2 && node->Windows[0]->WasActive == false)
|
||||||
{
|
{
|
||||||
node->Windows[0]->Hidden = true;
|
node->Windows[0]->Hidden = true;
|
||||||
node->Windows[0]->HiddenFramesRegular = 1;
|
node->Windows[0]->HiddenFramesRegular = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// When reactivating a node from two loose window, the target window pos/size are authoritative
|
// When reactivating a node with one or two loose window, the window pos/size/viewport are authoritative over the node storage.
|
||||||
if (node->Windows.Size == 2 && !node->IsDockSpace)
|
// In particular it is important we init the viewport from the first window so we don't create two viewports and drop one.
|
||||||
|
if (node->HostWindow == NULL && !node->IsDockSpace && node->IsRootNode())
|
||||||
node->InitFromFirstWindowPosSize = node->InitFromFirstWindowViewport = true;
|
node->InitFromFirstWindowPosSize = node->InitFromFirstWindowViewport = true;
|
||||||
|
|
||||||
// Add to tab bar if requested
|
// Add to tab bar if requested
|
||||||
@ -10817,7 +10825,6 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
|
|||||||
}
|
}
|
||||||
else if (node->HostWindow == NULL)
|
else if (node->HostWindow == NULL)
|
||||||
{
|
{
|
||||||
// Leaf
|
|
||||||
SetNextWindowPos(node->Pos);
|
SetNextWindowPos(node->Pos);
|
||||||
SetNextWindowSize(node->Size);
|
SetNextWindowSize(node->Size);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user