|
@@ -9874,94 +9874,6 @@ static int IMGUI_CDECL DockNodeComparerDepthMostFirst(const void* lhs, const voi
|
|
|
return ImGui::DockNodeGetDepth(b) - ImGui::DockNodeGetDepth(a);
|
|
|
}
|
|
|
|
|
|
-void ImGui::DockBuilderRemoveNodeChildNodes(ImGuiContext* ctx, ImGuiID root_id)
|
|
|
-{
|
|
|
- ImGuiDockContext* dc = ctx->DockContext;
|
|
|
-
|
|
|
- ImGuiDockNode* root_node = root_id ? DockContextFindNodeByID(ctx, root_id) : NULL;
|
|
|
- if (root_id && root_node == NULL)
|
|
|
- return;
|
|
|
- bool has_document_root = false;
|
|
|
-
|
|
|
- // Process active windows
|
|
|
- ImVector<ImGuiDockNode*> nodes_to_remove;
|
|
|
- for (int n = 0; n < dc->Nodes.Data.Size; n++)
|
|
|
- if (ImGuiDockNode* node = (ImGuiDockNode*)dc->Nodes.Data[n].val_p)
|
|
|
- {
|
|
|
- bool want_removal = (root_id == 0) || (node->ID != root_id && DockNodeGetRootNode(node)->ID == root_id);
|
|
|
- if (want_removal)
|
|
|
- {
|
|
|
- if (node->IsDocumentRoot)
|
|
|
- has_document_root = true;
|
|
|
- if (root_id != 0)
|
|
|
- DockContextQueueNotifyRemovedNode(ctx, node);
|
|
|
- if (root_node)
|
|
|
- DockNodeMoveWindows(root_node, node);
|
|
|
- nodes_to_remove.push_back(node);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Apply to settings
|
|
|
- for (int settings_n = 0; settings_n < ctx->SettingsWindows.Size; settings_n++)
|
|
|
- if (ImGuiID window_settings_dock_id = ctx->SettingsWindows[settings_n].DockId)
|
|
|
- for (int n = 0; n < nodes_to_remove.Size; n++)
|
|
|
- if (nodes_to_remove[n]->ID == window_settings_dock_id)
|
|
|
- {
|
|
|
- ctx->SettingsWindows[settings_n].DockId = root_id;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- // Not really efficient, but easier to destroy a whole hierarchy considering DockContextRemoveNode is attempting to merge nodes
|
|
|
- if (nodes_to_remove.Size > 1)
|
|
|
- ImQsort(nodes_to_remove.Data, nodes_to_remove.Size, sizeof(ImGuiDockNode*), DockNodeComparerDepthMostFirst);
|
|
|
- for (int n = 0; n < nodes_to_remove.Size; n++)
|
|
|
- DockContextRemoveNode(ctx, nodes_to_remove[n], false);
|
|
|
-
|
|
|
- if (root_id == 0)
|
|
|
- {
|
|
|
- dc->Nodes.Clear();
|
|
|
- dc->Requests.clear();
|
|
|
- }
|
|
|
- else if (has_document_root)
|
|
|
- {
|
|
|
- root_node->IsDocumentRoot = true;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void ImGui::DockBuilderRemoveNodeDockedWindows(ImGuiContext* ctx, ImGuiID root_id, bool clear_persistent_docking_references)
|
|
|
-{
|
|
|
- // Clear references in settings
|
|
|
- ImGuiContext& g = *ctx;
|
|
|
- if (clear_persistent_docking_references)
|
|
|
- {
|
|
|
- for (int n = 0; n < g.SettingsWindows.Size; n++)
|
|
|
- {
|
|
|
- ImGuiWindowSettings* settings = &g.SettingsWindows[n];
|
|
|
- bool want_removal = (root_id == 0) || (settings->DockId == root_id);
|
|
|
- if (!want_removal && settings->DockId != 0)
|
|
|
- if (ImGuiDockNode* node = DockContextFindNodeByID(ctx, settings->DockId))
|
|
|
- if (DockNodeGetRootNode(node)->ID == root_id)
|
|
|
- want_removal = true;
|
|
|
- if (want_removal)
|
|
|
- settings->DockId = 0;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Clear references in windows
|
|
|
- for (int n = 0; n < g.Windows.Size; n++)
|
|
|
- {
|
|
|
- ImGuiWindow* window = g.Windows[n];
|
|
|
- bool want_removal = (root_id == 0) || (window->DockNode && DockNodeGetRootNode(window->DockNode)->ID == root_id) || (window->DockNodeAsHost && window->DockNodeAsHost->ID == root_id);
|
|
|
- if (want_removal)
|
|
|
- {
|
|
|
- ImGuiID backup_dock_id = window->DockId;
|
|
|
- DockContextProcessUndockWindow(ctx, window);
|
|
|
- if (!clear_persistent_docking_references)
|
|
|
- window->DockId = backup_dock_id;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
static void ImGui::DockContextGcUnusedSettingsNodes(ImGuiContext* ctx)
|
|
|
{
|
|
|
ImGuiContext& g = *ctx;
|
|
@@ -11488,22 +11400,21 @@ ImGuiDockNode* ImGui::DockNodeTreeFindNodeByPos(ImGuiDockNode* node, ImVec2 pos)
|
|
|
{
|
|
|
if (!node->IsVisible)
|
|
|
return NULL;
|
|
|
- if (node->IsSplitNode())
|
|
|
- {
|
|
|
- if (ImGuiDockNode* hovered_node = DockNodeTreeFindNodeByPos(node->ChildNodes[0], pos))
|
|
|
- return hovered_node;
|
|
|
- if (ImGuiDockNode* hovered_node = DockNodeTreeFindNodeByPos(node->ChildNodes[1], pos))
|
|
|
- return hovered_node;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- ImGuiContext& g = *GImGui;
|
|
|
- const float dock_spacing = g.Style.ItemInnerSpacing.x;
|
|
|
- ImRect r(node->Pos, node->Pos + node->Size);
|
|
|
- r.Expand(dock_spacing * 0.5f);
|
|
|
- if (r.Contains(pos))
|
|
|
- return node;
|
|
|
- }
|
|
|
+
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
+ const float dock_spacing = g.Style.ItemInnerSpacing.x;
|
|
|
+ ImRect r(node->Pos, node->Pos + node->Size);
|
|
|
+ r.Expand(dock_spacing * 0.5f);
|
|
|
+ bool inside = r.Contains(pos);
|
|
|
+ if (!inside)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ if (!node->IsSplitNode())
|
|
|
+ return node;
|
|
|
+ if (ImGuiDockNode* hovered_node = DockNodeTreeFindNodeByPos(node->ChildNodes[0], pos))
|
|
|
+ return hovered_node;
|
|
|
+ if (ImGuiDockNode* hovered_node = DockNodeTreeFindNodeByPos(node->ChildNodes[1], pos))
|
|
|
+ return hovered_node;
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
@@ -11601,6 +11512,7 @@ void ImGui::DockSpace(ImGuiID id, const ImVec2& size_arg, ImGuiDockNodeFlags doc
|
|
|
// Docking: Builder Functions
|
|
|
//-----------------------------------------------------------------------------
|
|
|
// Very early end-user API to manipulate dock nodes.
|
|
|
+// It is expected that those functions are all called _before_ the dockspace node submission.
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
void ImGui::DockBuilderDockWindow(ImGuiContext*, const char* window_name, ImGuiID node_id)
|
|
@@ -11621,8 +11533,7 @@ void ImGui::DockBuilderDockWindow(ImGuiContext*, const char* window_name, ImGuiI
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// Ensure a node is created
|
|
|
-void ImGui::DockBuilderCreateNode(ImGuiContext* ctx, ImGuiID id, ImVec2 ref_size, ImGuiDockNodeFlags flags)
|
|
|
+void ImGui::DockBuilderAddNode(ImGuiContext* ctx, ImGuiID id, ImVec2 ref_size, ImGuiDockNodeFlags flags)
|
|
|
{
|
|
|
DockSpace(id, ImVec2(0,0), flags | ImGuiDockNodeFlags_KeepAliveOnly);
|
|
|
ImGuiDockNode* node = DockContextFindNodeByID(ctx, id);
|
|
@@ -11630,6 +11541,106 @@ void ImGui::DockBuilderCreateNode(ImGuiContext* ctx, ImGuiID id, ImVec2 ref_size
|
|
|
node->LastFrameAlive = -1;
|
|
|
}
|
|
|
|
|
|
+void ImGui::DockBuilderRemoveNode(ImGuiContext* ctx, ImGuiID node_id)
|
|
|
+{
|
|
|
+ ImGuiDockNode* node = DockContextFindNodeByID(ctx, node_id);
|
|
|
+ if (node == NULL)
|
|
|
+ return;
|
|
|
+ DockBuilderRemoveNodeDockedWindows(ctx, node_id, true);
|
|
|
+ DockBuilderRemoveNodeChildNodes(ctx, node_id);
|
|
|
+ if (node->IsDocumentRoot && node->ParentNode)
|
|
|
+ node->ParentNode->IsDocumentRoot = true;
|
|
|
+ DockContextRemoveNode(ctx, node, true);
|
|
|
+}
|
|
|
+
|
|
|
+void ImGui::DockBuilderRemoveNodeChildNodes(ImGuiContext* ctx, ImGuiID root_id)
|
|
|
+{
|
|
|
+ ImGuiDockContext* dc = ctx->DockContext;
|
|
|
+
|
|
|
+ ImGuiDockNode* root_node = root_id ? DockContextFindNodeByID(ctx, root_id) : NULL;
|
|
|
+ if (root_id && root_node == NULL)
|
|
|
+ return;
|
|
|
+ bool has_document_root = false;
|
|
|
+
|
|
|
+ // Process active windows
|
|
|
+ ImVector<ImGuiDockNode*> nodes_to_remove;
|
|
|
+ for (int n = 0; n < dc->Nodes.Data.Size; n++)
|
|
|
+ if (ImGuiDockNode* node = (ImGuiDockNode*)dc->Nodes.Data[n].val_p)
|
|
|
+ {
|
|
|
+ bool want_removal = (root_id == 0) || (node->ID != root_id && DockNodeGetRootNode(node)->ID == root_id);
|
|
|
+ if (want_removal)
|
|
|
+ {
|
|
|
+ if (node->IsDocumentRoot)
|
|
|
+ has_document_root = true;
|
|
|
+ if (root_id != 0)
|
|
|
+ DockContextQueueNotifyRemovedNode(ctx, node);
|
|
|
+ if (root_node)
|
|
|
+ DockNodeMoveWindows(root_node, node);
|
|
|
+ nodes_to_remove.push_back(node);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Apply to settings
|
|
|
+ for (int settings_n = 0; settings_n < ctx->SettingsWindows.Size; settings_n++)
|
|
|
+ if (ImGuiID window_settings_dock_id = ctx->SettingsWindows[settings_n].DockId)
|
|
|
+ for (int n = 0; n < nodes_to_remove.Size; n++)
|
|
|
+ if (nodes_to_remove[n]->ID == window_settings_dock_id)
|
|
|
+ {
|
|
|
+ ctx->SettingsWindows[settings_n].DockId = root_id;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Not really efficient, but easier to destroy a whole hierarchy considering DockContextRemoveNode is attempting to merge nodes
|
|
|
+ if (nodes_to_remove.Size > 1)
|
|
|
+ ImQsort(nodes_to_remove.Data, nodes_to_remove.Size, sizeof(ImGuiDockNode*), DockNodeComparerDepthMostFirst);
|
|
|
+ for (int n = 0; n < nodes_to_remove.Size; n++)
|
|
|
+ DockContextRemoveNode(ctx, nodes_to_remove[n], false);
|
|
|
+
|
|
|
+ if (root_id == 0)
|
|
|
+ {
|
|
|
+ dc->Nodes.Clear();
|
|
|
+ dc->Requests.clear();
|
|
|
+ }
|
|
|
+ else if (has_document_root)
|
|
|
+ {
|
|
|
+ root_node->IsDocumentRoot = true;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void ImGui::DockBuilderRemoveNodeDockedWindows(ImGuiContext* ctx, ImGuiID root_id, bool clear_persistent_docking_references)
|
|
|
+{
|
|
|
+ // Clear references in settings
|
|
|
+ ImGuiContext& g = *ctx;
|
|
|
+ if (clear_persistent_docking_references)
|
|
|
+ {
|
|
|
+ for (int n = 0; n < g.SettingsWindows.Size; n++)
|
|
|
+ {
|
|
|
+ ImGuiWindowSettings* settings = &g.SettingsWindows[n];
|
|
|
+ bool want_removal = (root_id == 0) || (settings->DockId == root_id);
|
|
|
+ if (!want_removal && settings->DockId != 0)
|
|
|
+ if (ImGuiDockNode* node = DockContextFindNodeByID(ctx, settings->DockId))
|
|
|
+ if (DockNodeGetRootNode(node)->ID == root_id)
|
|
|
+ want_removal = true;
|
|
|
+ if (want_removal)
|
|
|
+ settings->DockId = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Clear references in windows
|
|
|
+ for (int n = 0; n < g.Windows.Size; n++)
|
|
|
+ {
|
|
|
+ ImGuiWindow* window = g.Windows[n];
|
|
|
+ bool want_removal = (root_id == 0) || (window->DockNode && DockNodeGetRootNode(window->DockNode)->ID == root_id) || (window->DockNodeAsHost && window->DockNodeAsHost->ID == root_id);
|
|
|
+ if (want_removal)
|
|
|
+ {
|
|
|
+ ImGuiID backup_dock_id = window->DockId;
|
|
|
+ DockContextProcessUndockWindow(ctx, window);
|
|
|
+ if (!clear_persistent_docking_references)
|
|
|
+ window->DockId = backup_dock_id;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
ImGuiID ImGui::DockBuilderSplitNode(ImGuiContext* ctx, ImGuiID id, ImGuiDir split_dir, float size_ratio_for_node_at_dir, ImGuiID* out_id_at_dir, ImGuiID* out_id_other)
|
|
|
{
|
|
|
IM_ASSERT(split_dir != ImGuiDir_None);
|