From 51e568f9dc1dec33017376a6fa6a71b9ced6cda9 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 7 May 2020 22:46:06 +0200 Subject: [PATCH] Docking: Fix to allow basic reload of non-docking .ini data (following d33021d8) + moved settings blocks --- imgui.cpp | 113 ++++++++++++++++++++++------------------------- imgui_internal.h | 2 +- 2 files changed, 55 insertions(+), 60 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 27c713379..f0e76d5a5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5206,6 +5206,8 @@ ImGuiWindow* ImGui::FindWindowByName(const char* name) static void ApplyWindowSettings(ImGuiWindow* window, ImGuiWindowSettings* settings) { + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + window->ViewportPos = main_viewport->Pos; if (settings->ViewportId) { window->ViewportId = settings->ViewportId; @@ -5217,7 +5219,6 @@ static void ApplyWindowSettings(ImGuiWindow* window, ImGuiWindowSettings* settin window->Collapsed = settings->Collapsed; window->DockId = settings->DockId; window->DockOrder = settings->DockOrder; - } static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags) @@ -5233,6 +5234,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags) // Default/arbitrary window position. Use SetNextWindowPos() with the appropriate condition flag to change the initial position of a window. ImGuiViewport* main_viewport = ImGui::GetMainViewport(); window->Pos = main_viewport->Pos + ImVec2(60, 60); + window->ViewportPos = main_viewport->Pos; // User can disable loading and saving of settings. Tooltip and child windows also don't store settings. if (!(flags & ImGuiWindowFlags_NoSavedSettings)) @@ -5241,7 +5243,6 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags) // Retrieve settings from .ini file window->SettingsOffset = g.SettingsWindows.offset_from_ptr(settings); SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false); - window->ViewportPos = main_viewport->Pos; ApplyWindowSettings(window, settings); } window->DC.CursorStartPos = window->DC.CursorMaxPos = window->Pos; // So first call to CalcContentSize() doesn't return crazy values @@ -10564,8 +10565,6 @@ void ImGui::LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size) for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++) if (g.SettingsHandlers[handler_n].ApplyAllFn) g.SettingsHandlers[handler_n].ApplyAllFn(&g, &g.SettingsHandlers[handler_n]); - - DockContextOnLoadSettings(&g); } void ImGui::SaveIniSettingsToDisk(const char* ini_filename) @@ -10624,9 +10623,10 @@ static void WindowSettingsHandler_ApplyAll(ImGuiContext* ctx, ImGuiSettingsHandl static void* WindowSettingsHandler_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name) { - ImGuiWindowSettings* settings = ImGui::FindWindowSettings(ImHashStr(name)); - if (!settings) - settings = ImGui::CreateNewWindowSettings(name); + ImGuiWindowSettings* settings = ImGui::FindOrCreateWindowSettings(name); + ImGuiID id = settings->ID; + *settings = ImGuiWindowSettings(); + settings->ID = id; settings->WantApply = true; return (void*)settings; } @@ -11683,6 +11683,7 @@ namespace ImGui static void DockSettingsRenameNodeReferences(ImGuiID old_node_id, ImGuiID new_node_id); static void DockSettingsRemoveNodeReferences(ImGuiID* node_ids, int node_ids_count); static ImGuiDockNodeSettings* DockSettingsFindNodeSettings(ImGuiContext* ctx, ImGuiID node_id); + static void DockSettingsHandler_ApplyAll(ImGuiContext*, ImGuiSettingsHandler*); static void* DockSettingsHandler_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name); static void DockSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler*, void* entry, const char* line); static void DockSettingsHandler_WriteAll(ImGuiContext* imgui_ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf); @@ -11700,7 +11701,6 @@ namespace ImGui //----------------------------------------------------------------------------- // - DockContextInitialize() // - DockContextShutdown() -// - DockContextOnLoadSettings() // - DockContextClearNodes() // - DockContextRebuildNodes() // - DockContextUpdateUndocking() @@ -11726,6 +11726,7 @@ void ImGui::DockContextInitialize(ImGuiContext* ctx) ImGuiSettingsHandler ini_handler; ini_handler.TypeName = "Docking"; ini_handler.TypeHash = ImHashStr("Docking"); + ini_handler.ApplyAllFn = DockSettingsHandler_ApplyAll; ini_handler.ReadOpenFn = DockSettingsHandler_ReadOpen; ini_handler.ReadLineFn = DockSettingsHandler_ReadLine; ini_handler.WriteAllFn = DockSettingsHandler_WriteAll; @@ -11743,13 +11744,6 @@ void ImGui::DockContextShutdown(ImGuiContext* ctx) g.DockContext = NULL; } -void ImGui::DockContextOnLoadSettings(ImGuiContext* ctx) -{ - ImGuiDockContext* dc = ctx->DockContext; - DockContextPruneUnusedSettingsNodes(ctx); - DockContextBuildNodesFromSettings(ctx, dc->SettingsNodes.Data, dc->SettingsNodes.Size); -} - void ImGui::DockContextClearNodes(ImGuiContext* ctx, ImGuiID root_id, bool clear_persistent_docking_references) { IM_UNUSED(ctx); @@ -14251,6 +14245,7 @@ void ImGui::DockBuilderRemoveNode(ImGuiID node_id) DockContextRemoveNode(ctx, node, true); } +// root_id = 0 to remove all, root_id != 0 to remove child of given node. void ImGui::DockBuilderRemoveNodeChildNodes(ImGuiID root_id) { ImGuiContext* ctx = GImGui; @@ -14821,6 +14816,7 @@ void ImGui::BeginDockableDragDropTarget(ImGuiWindow* window) // - DockSettingsRenameNodeReferences() // - DockSettingsRemoveNodeReferences() // - DockSettingsFindNodeSettings() +// - DockSettingsHandler_ApplyAll() // - DockSettingsHandler_ReadOpen() // - DockSettingsHandler_ReadLine() // - DockSettingsHandler_DockNodeToSettings() @@ -14871,6 +14867,15 @@ static ImGuiDockNodeSettings* ImGui::DockSettingsFindNodeSettings(ImGuiContext* return NULL; } +static void ImGui::DockSettingsHandler_ApplyAll(ImGuiContext* ctx, ImGuiSettingsHandler*) +{ + // Prune settings at boot time only + ImGuiDockContext* dc = ctx->DockContext; + if (ctx->Windows.Size == 0) + DockContextPruneUnusedSettingsNodes(ctx); + DockContextBuildNodesFromSettings(ctx, dc->SettingsNodes.Data, dc->SettingsNodes.Size); +} + static void* ImGui::DockSettingsHandler_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name) { if (strcmp(name, "Data") != 0) @@ -15690,52 +15695,17 @@ void ImGui::ShowMetricsWindow(bool* p_open) // Details for Docking #ifdef IMGUI_HAS_DOCK - if (ImGui::TreeNode("Docking")) + if (ImGui::TreeNode("Dock nodes")) { ImGuiDockContext* dc = g.DockContext; ImGui::Checkbox("Ctrl shows window dock info", &show_docking_nodes); - - if (ImGui::TreeNode("Dock nodes")) - { - if (ImGui::SmallButton("Clear settings")) { DockContextClearNodes(&g, 0, true); } - ImGui::SameLine(); - if (ImGui::SmallButton("Rebuild all")) { dc->WantFullRebuild = true; } - for (int n = 0; n < dc->Nodes.Data.Size; n++) - if (ImGuiDockNode* node = (ImGuiDockNode*)dc->Nodes.Data[n].val_p) - if (node->IsRootNode()) - Funcs::NodeDockNode(node, "Node"); - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Settings")) - { - if (ImGui::SmallButton("Refresh")) - SaveIniSettingsToMemory(); - ImGui::SameLine(); - if (ImGui::SmallButton("Save to disk")) - SaveIniSettingsToDisk(g.IO.IniFilename); - ImGui::Separator(); - ImGui::Text("Docked Windows:"); - for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings)) - if (settings->DockId != 0) - ImGui::BulletText("Window '%s' -> DockId %08X", settings->GetName(), settings->DockId); - ImGui::Separator(); - ImGui::Text("Dock Nodes:"); - for (int n = 0; n < dc->SettingsNodes.Size; n++) - { - ImGuiDockNodeSettings* settings = &dc->SettingsNodes[n]; - const char* selected_tab_name = NULL; - if (settings->SelectedWindowId) - { - if (ImGuiWindow* window = FindWindowByID(settings->SelectedWindowId)) - selected_tab_name = window->Name; - else if (ImGuiWindowSettings* window_settings = FindWindowSettings(settings->SelectedWindowId)) - selected_tab_name = window_settings->GetName(); - } - ImGui::BulletText("Node %08X, Parent %08X, SelectedTab %08X ('%s')", settings->ID, settings->ParentNodeId, settings->SelectedWindowId, selected_tab_name ? selected_tab_name : settings->SelectedWindowId ? "N/A" : ""); - } - ImGui::TreePop(); - } + if (ImGui::SmallButton("Clear nodes")) { DockContextClearNodes(&g, 0, true); } + ImGui::SameLine(); + if (ImGui::SmallButton("Rebuild all")) { dc->WantFullRebuild = true; } + for (int n = 0; n < dc->Nodes.Data.Size; n++) + if (ImGuiDockNode* node = (ImGuiDockNode*)dc->Nodes.Data[n].val_p) + if (node->IsRootNode()) + Funcs::NodeDockNode(node, "Node"); ImGui::TreePop(); } #endif // #define IMGUI_HAS_DOCK @@ -15746,6 +15716,9 @@ void ImGui::ShowMetricsWindow(bool* p_open) if (ImGui::SmallButton("Clear")) ImGui::ClearIniSettings(); ImGui::SameLine(); + if (ImGui::SmallButton("Save to memory")) + ImGui::SaveIniSettingsToMemory(); + ImGui::SameLine(); if (ImGui::SmallButton("Save to disk")) ImGui::SaveIniSettingsToDisk(g.IO.IniFilename); ImGui::SameLine(); @@ -15757,7 +15730,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) if (ImGui::TreeNode("SettingsHandlers", "Settings handlers: (%d)", g.SettingsHandlers.Size)) { for (int n = 0; n < g.SettingsHandlers.Size; n++) - ImGui::TextUnformatted(g.SettingsHandlers[n].TypeName); + ImGui::BulletText("%s", g.SettingsHandlers[n].TypeName); ImGui::TreePop(); } if (ImGui::TreeNode("SettingsWindows", "Settings packed data: Windows: %d bytes", g.SettingsWindows.size())) @@ -15766,6 +15739,28 @@ void ImGui::ShowMetricsWindow(bool* p_open) Funcs::NodeWindowSettings(settings); ImGui::TreePop(); } + if (ImGui::TreeNode("SettingsDocking", "Settings packed data: Docking")) + { + ImGui::Text("In SettingsWindows:"); + for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings)) + if (settings->DockId != 0) + ImGui::BulletText("Window '%s' -> DockId %08X", settings->GetName(), settings->DockId); + ImGui::Text("In SettingsNodes:"); + for (int n = 0; n < g.DockContext->SettingsNodes.Size; n++) + { + ImGuiDockNodeSettings* settings = &g.DockContext->SettingsNodes[n]; + const char* selected_tab_name = NULL; + if (settings->SelectedWindowId) + { + if (ImGuiWindow* window = FindWindowByID(settings->SelectedWindowId)) + selected_tab_name = window->Name; + else if (ImGuiWindowSettings* window_settings = FindWindowSettings(settings->SelectedWindowId)) + selected_tab_name = window_settings->GetName(); + } + ImGui::BulletText("Node %08X, Parent %08X, SelectedTab %08X ('%s')", settings->ID, settings->ParentNodeId, settings->SelectedWindowId, selected_tab_name ? selected_tab_name : settings->SelectedWindowId ? "N/A" : ""); + } + ImGui::TreePop(); + } if (ImGui::TreeNode("SettingsIniData", "Settings unpacked data (.ini): %d bytes", g.SettingsIniData.size())) { char* buf = (char*)(void*)(g.SettingsIniData.Buf.Data ? g.SettingsIniData.Buf.Data : ""); diff --git a/imgui_internal.h b/imgui_internal.h index a3b766883..2f43e9b5d 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -2058,7 +2058,7 @@ namespace ImGui IMGUI_API ImGuiID DockBuilderAddNode(ImGuiID node_id = 0, ImGuiDockNodeFlags flags = 0); IMGUI_API void DockBuilderRemoveNode(ImGuiID node_id); // Remove node and all its child, undock all windows IMGUI_API void DockBuilderRemoveNodeDockedWindows(ImGuiID node_id, bool clear_persistent_docking_references = true); - IMGUI_API void DockBuilderRemoveNodeChildNodes(ImGuiID node_id); // Remove all split/hierarchy. All remaining docked windows will be re-docked to the root. + IMGUI_API void DockBuilderRemoveNodeChildNodes(ImGuiID node_id); // Remove all split/hierarchy. All remaining docked windows will be re-docked to the remaining root node (node_id). IMGUI_API void DockBuilderSetNodePos(ImGuiID node_id, ImVec2 pos); IMGUI_API void DockBuilderSetNodeSize(ImGuiID node_id, ImVec2 size); IMGUI_API ImGuiID DockBuilderSplitNode(ImGuiID node_id, ImGuiDir split_dir, float size_ratio_for_node_at_dir, ImGuiID* out_id_at_dir, ImGuiID* out_id_at_opposite_dir); // Create 2 child nodes in this parent node.