Refactor: Internals: Moved Settings functions in imgui.cpp in their own section. (#2036)
diff --git a/imgui.cpp b/imgui.cpp
index eead7f2..8bf530d 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -865,7 +865,6 @@
static void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond);
static void FindHoveredWindow();
static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFlags flags);
-static ImGuiWindowSettings* CreateNewWindowSettings(const char* name);
static void CheckStacksSize(ImGuiWindow* window, bool write);
static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool snap_on_edges);
@@ -875,6 +874,11 @@
static ImRect GetViewportRect();
+// Settings
+static void* SettingsHandlerWindow_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name);
+static void SettingsHandlerWindow_ReadLine(ImGuiContext*, ImGuiSettingsHandler*, void* entry, const char* line);
+static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf);
+
namespace ImGui
{
static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags flags);
@@ -3922,65 +3926,6 @@
Begin("Debug##Default");
}
-static void* SettingsHandlerWindow_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name)
-{
- ImGuiWindowSettings* settings = ImGui::FindWindowSettings(ImHash(name, 0));
- if (!settings)
- settings = CreateNewWindowSettings(name);
- return (void*)settings;
-}
-
-static void SettingsHandlerWindow_ReadLine(ImGuiContext*, ImGuiSettingsHandler*, void* entry, const char* line)
-{
- ImGuiWindowSettings* settings = (ImGuiWindowSettings*)entry;
- float x, y;
- int i;
- if (sscanf(line, "Pos=%f,%f", &x, &y) == 2) settings->Pos = ImVec2(x, y);
- else if (sscanf(line, "Size=%f,%f", &x, &y) == 2) settings->Size = ImMax(ImVec2(x, y), GImGui->Style.WindowMinSize);
- else if (sscanf(line, "Collapsed=%d", &i) == 1) settings->Collapsed = (i != 0);
-}
-
-static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf)
-{
- // Gather data from windows that were active during this session
- ImGuiContext& g = *imgui_ctx;
- for (int i = 0; i != g.Windows.Size; i++)
- {
- ImGuiWindow* window = g.Windows[i];
- if (window->Flags & ImGuiWindowFlags_NoSavedSettings)
- continue;
-
- ImGuiWindowSettings* settings = (window->SettingsIdx != -1) ? &g.SettingsWindows[window->SettingsIdx] : ImGui::FindWindowSettings(window->ID);
- if (!settings)
- {
- settings = CreateNewWindowSettings(window->Name);
- window->SettingsIdx = g.SettingsWindows.index_from_pointer(settings);
- }
- IM_ASSERT(settings->ID == window->ID);
- settings->Pos = window->Pos;
- settings->Size = window->SizeFull;
- settings->Collapsed = window->Collapsed;
- }
-
- // Write a buffer
- // If a window wasn't opened in this session we preserve its settings
- buf->reserve(buf->size() + g.SettingsWindows.Size * 96); // ballpark reserve
- for (int i = 0; i != g.SettingsWindows.Size; i++)
- {
- const ImGuiWindowSettings* settings = &g.SettingsWindows[i];
- if (settings->Pos.x == FLT_MAX)
- continue;
- const char* name = settings->Name;
- if (const char* p = strstr(name, "###")) // Skip to the "###" marker if any. We don't skip past to match the behavior of GetID()
- name = p;
- buf->appendf("[%s][%s]\n", handler->TypeName, name);
- buf->appendf("Pos=%d,%d\n", (int)settings->Pos.x, (int)settings->Pos.y);
- buf->appendf("Size=%d,%d\n", (int)settings->Size.x, (int)settings->Size.y);
- buf->appendf("Collapsed=%d\n", settings->Collapsed);
- buf->appendf("\n");
- }
-}
-
void ImGui::Initialize(ImGuiContext* context)
{
ImGuiContext& g = *context;
@@ -4055,154 +4000,6 @@
g.Initialized = false;
}
-ImGuiWindowSettings* ImGui::FindWindowSettings(ImGuiID id)
-{
- ImGuiContext& g = *GImGui;
- for (int i = 0; i != g.SettingsWindows.Size; i++)
- if (g.SettingsWindows[i].ID == id)
- return &g.SettingsWindows[i];
- return NULL;
-}
-
-static ImGuiWindowSettings* CreateNewWindowSettings(const char* name)
-{
- ImGuiContext& g = *GImGui;
- g.SettingsWindows.push_back(ImGuiWindowSettings());
- ImGuiWindowSettings* settings = &g.SettingsWindows.back();
- settings->Name = ImStrdup(name);
- settings->ID = ImHash(name, 0);
- return settings;
-}
-
-void ImGui::LoadIniSettingsFromDisk(const char* ini_filename)
-{
- size_t file_data_size = 0;
- char* file_data = (char*)ImFileLoadToMemory(ini_filename, "rb", &file_data_size);
- if (!file_data)
- return;
- LoadIniSettingsFromMemory(file_data, (size_t)file_data_size);
- ImGui::MemFree(file_data);
-}
-
-ImGuiSettingsHandler* ImGui::FindSettingsHandler(const char* type_name)
-{
- ImGuiContext& g = *GImGui;
- const ImGuiID type_hash = ImHash(type_name, 0, 0);
- for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++)
- if (g.SettingsHandlers[handler_n].TypeHash == type_hash)
- return &g.SettingsHandlers[handler_n];
- return NULL;
-}
-
-// Zero-tolerance, no error reporting, cheap .ini parsing
-void ImGui::LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size)
-{
- ImGuiContext& g = *GImGui;
- IM_ASSERT(g.Initialized);
- IM_ASSERT(g.SettingsLoaded == false && g.FrameCount == 0);
-
- // For user convenience, we allow passing a non zero-terminated string (hence the ini_size parameter).
- // For our convenience and to make the code simpler, we'll also write zero-terminators within the buffer. So let's create a writable copy..
- if (ini_size == 0)
- ini_size = strlen(ini_data);
- char* buf = (char*)ImGui::MemAlloc(ini_size + 1);
- char* buf_end = buf + ini_size;
- memcpy(buf, ini_data, ini_size);
- buf[ini_size] = 0;
-
- void* entry_data = NULL;
- ImGuiSettingsHandler* entry_handler = NULL;
-
- char* line_end = NULL;
- for (char* line = buf; line < buf_end; line = line_end + 1)
- {
- // Skip new lines markers, then find end of the line
- while (*line == '\n' || *line == '\r')
- line++;
- line_end = line;
- while (line_end < buf_end && *line_end != '\n' && *line_end != '\r')
- line_end++;
- line_end[0] = 0;
-
- if (line[0] == '[' && line_end > line && line_end[-1] == ']')
- {
- // Parse "[Type][Name]". Note that 'Name' can itself contains [] characters, which is acceptable with the current format and parsing code.
- line_end[-1] = 0;
- const char* name_end = line_end - 1;
- const char* type_start = line + 1;
- char* type_end = (char*)(intptr_t)ImStrchrRange(type_start, name_end, ']');
- const char* name_start = type_end ? ImStrchrRange(type_end + 1, name_end, '[') : NULL;
- if (!type_end || !name_start)
- {
- name_start = type_start; // Import legacy entries that have no type
- type_start = "Window";
- }
- else
- {
- *type_end = 0; // Overwrite first ']'
- name_start++; // Skip second '['
- }
- entry_handler = FindSettingsHandler(type_start);
- entry_data = entry_handler ? entry_handler->ReadOpenFn(&g, entry_handler, name_start) : NULL;
- }
- else if (entry_handler != NULL && entry_data != NULL)
- {
- // Let type handler parse the line
- entry_handler->ReadLineFn(&g, entry_handler, entry_data, line);
- }
- }
- ImGui::MemFree(buf);
- g.SettingsLoaded = true;
-}
-
-void ImGui::SaveIniSettingsToDisk(const char* ini_filename)
-{
- ImGuiContext& g = *GImGui;
- g.SettingsDirtyTimer = 0.0f;
- if (!ini_filename)
- return;
-
- size_t ini_data_size = 0;
- const char* ini_data = SaveIniSettingsToMemory(&ini_data_size);
- FILE* f = ImFileOpen(ini_filename, "wt");
- if (!f)
- return;
- fwrite(ini_data, sizeof(char), ini_data_size, f);
- fclose(f);
-}
-
-// Call registered handlers (e.g. SettingsHandlerWindow_WriteAll() + custom handlers) to write their stuff into a text buffer
-const char* ImGui::SaveIniSettingsToMemory(size_t* out_size)
-{
- ImGuiContext& g = *GImGui;
- g.SettingsDirtyTimer = 0.0f;
- g.SettingsIniData.Buf.resize(0);
- g.SettingsIniData.Buf.push_back(0);
- for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++)
- {
- ImGuiSettingsHandler* handler = &g.SettingsHandlers[handler_n];
- handler->WriteAllFn(&g, handler, &g.SettingsIniData);
- }
- if (out_size)
- *out_size = (size_t)g.SettingsIniData.size();
- return g.SettingsIniData.c_str();
-}
-
-void ImGui::MarkIniSettingsDirty()
-{
- ImGuiContext& g = *GImGui;
- if (g.SettingsDirtyTimer <= 0.0f)
- g.SettingsDirtyTimer = g.IO.IniSavingRate;
-}
-
-void ImGui::MarkIniSettingsDirty(ImGuiWindow* window)
-{
- ImGuiContext& g = *GImGui;
- if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings))
- if (g.SettingsDirtyTimer <= 0.0f)
- g.SettingsDirtyTimer = g.IO.IniSavingRate;
-}
-
// FIXME: Add a more explicit sort order in the window structure.
static int IMGUI_CDECL ChildWindowComparer(const void* lhs, const void* rhs)
{
@@ -8839,6 +8636,217 @@
}
//-----------------------------------------------------------------------------
+// SETTINGS
+//-----------------------------------------------------------------------------
+
+void ImGui::MarkIniSettingsDirty()
+{
+ ImGuiContext& g = *GImGui;
+ if (g.SettingsDirtyTimer <= 0.0f)
+ g.SettingsDirtyTimer = g.IO.IniSavingRate;
+}
+
+void ImGui::MarkIniSettingsDirty(ImGuiWindow* window)
+{
+ ImGuiContext& g = *GImGui;
+ if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings))
+ if (g.SettingsDirtyTimer <= 0.0f)
+ g.SettingsDirtyTimer = g.IO.IniSavingRate;
+}
+
+static ImGuiWindowSettings* CreateNewWindowSettings(const char* name)
+{
+ ImGuiContext& g = *GImGui;
+ g.SettingsWindows.push_back(ImGuiWindowSettings());
+ ImGuiWindowSettings* settings = &g.SettingsWindows.back();
+ settings->Name = ImStrdup(name);
+ settings->ID = ImHash(name, 0);
+ return settings;
+}
+
+ImGuiWindowSettings* ImGui::FindWindowSettings(ImGuiID id)
+{
+ ImGuiContext& g = *GImGui;
+ for (int i = 0; i != g.SettingsWindows.Size; i++)
+ if (g.SettingsWindows[i].ID == id)
+ return &g.SettingsWindows[i];
+ return NULL;
+}
+
+void ImGui::LoadIniSettingsFromDisk(const char* ini_filename)
+{
+ size_t file_data_size = 0;
+ char* file_data = (char*)ImFileLoadToMemory(ini_filename, "rb", &file_data_size);
+ if (!file_data)
+ return;
+ LoadIniSettingsFromMemory(file_data, (size_t)file_data_size);
+ ImGui::MemFree(file_data);
+}
+
+ImGuiSettingsHandler* ImGui::FindSettingsHandler(const char* type_name)
+{
+ ImGuiContext& g = *GImGui;
+ const ImGuiID type_hash = ImHash(type_name, 0, 0);
+ for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++)
+ if (g.SettingsHandlers[handler_n].TypeHash == type_hash)
+ return &g.SettingsHandlers[handler_n];
+ return NULL;
+}
+
+// Zero-tolerance, no error reporting, cheap .ini parsing
+void ImGui::LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size)
+{
+ ImGuiContext& g = *GImGui;
+ IM_ASSERT(g.Initialized);
+ IM_ASSERT(g.SettingsLoaded == false && g.FrameCount == 0);
+
+ // For user convenience, we allow passing a non zero-terminated string (hence the ini_size parameter).
+ // For our convenience and to make the code simpler, we'll also write zero-terminators within the buffer. So let's create a writable copy..
+ if (ini_size == 0)
+ ini_size = strlen(ini_data);
+ char* buf = (char*)ImGui::MemAlloc(ini_size + 1);
+ char* buf_end = buf + ini_size;
+ memcpy(buf, ini_data, ini_size);
+ buf[ini_size] = 0;
+
+ void* entry_data = NULL;
+ ImGuiSettingsHandler* entry_handler = NULL;
+
+ char* line_end = NULL;
+ for (char* line = buf; line < buf_end; line = line_end + 1)
+ {
+ // Skip new lines markers, then find end of the line
+ while (*line == '\n' || *line == '\r')
+ line++;
+ line_end = line;
+ while (line_end < buf_end && *line_end != '\n' && *line_end != '\r')
+ line_end++;
+ line_end[0] = 0;
+
+ if (line[0] == '[' && line_end > line && line_end[-1] == ']')
+ {
+ // Parse "[Type][Name]". Note that 'Name' can itself contains [] characters, which is acceptable with the current format and parsing code.
+ line_end[-1] = 0;
+ const char* name_end = line_end - 1;
+ const char* type_start = line + 1;
+ char* type_end = (char*)(intptr_t)ImStrchrRange(type_start, name_end, ']');
+ const char* name_start = type_end ? ImStrchrRange(type_end + 1, name_end, '[') : NULL;
+ if (!type_end || !name_start)
+ {
+ name_start = type_start; // Import legacy entries that have no type
+ type_start = "Window";
+ }
+ else
+ {
+ *type_end = 0; // Overwrite first ']'
+ name_start++; // Skip second '['
+ }
+ entry_handler = FindSettingsHandler(type_start);
+ entry_data = entry_handler ? entry_handler->ReadOpenFn(&g, entry_handler, name_start) : NULL;
+ }
+ else if (entry_handler != NULL && entry_data != NULL)
+ {
+ // Let type handler parse the line
+ entry_handler->ReadLineFn(&g, entry_handler, entry_data, line);
+ }
+ }
+ ImGui::MemFree(buf);
+ g.SettingsLoaded = true;
+}
+
+void ImGui::SaveIniSettingsToDisk(const char* ini_filename)
+{
+ ImGuiContext& g = *GImGui;
+ g.SettingsDirtyTimer = 0.0f;
+ if (!ini_filename)
+ return;
+
+ size_t ini_data_size = 0;
+ const char* ini_data = SaveIniSettingsToMemory(&ini_data_size);
+ FILE* f = ImFileOpen(ini_filename, "wt");
+ if (!f)
+ return;
+ fwrite(ini_data, sizeof(char), ini_data_size, f);
+ fclose(f);
+}
+
+// Call registered handlers (e.g. SettingsHandlerWindow_WriteAll() + custom handlers) to write their stuff into a text buffer
+const char* ImGui::SaveIniSettingsToMemory(size_t* out_size)
+{
+ ImGuiContext& g = *GImGui;
+ g.SettingsDirtyTimer = 0.0f;
+ g.SettingsIniData.Buf.resize(0);
+ g.SettingsIniData.Buf.push_back(0);
+ for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++)
+ {
+ ImGuiSettingsHandler* handler = &g.SettingsHandlers[handler_n];
+ handler->WriteAllFn(&g, handler, &g.SettingsIniData);
+ }
+ if (out_size)
+ *out_size = (size_t)g.SettingsIniData.size();
+ return g.SettingsIniData.c_str();
+}
+
+static void* SettingsHandlerWindow_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name)
+{
+ ImGuiWindowSettings* settings = ImGui::FindWindowSettings(ImHash(name, 0));
+ if (!settings)
+ settings = CreateNewWindowSettings(name);
+ return (void*)settings;
+}
+
+static void SettingsHandlerWindow_ReadLine(ImGuiContext*, ImGuiSettingsHandler*, void* entry, const char* line)
+{
+ ImGuiWindowSettings* settings = (ImGuiWindowSettings*)entry;
+ float x, y;
+ int i;
+ if (sscanf(line, "Pos=%f,%f", &x, &y) == 2) settings->Pos = ImVec2(x, y);
+ else if (sscanf(line, "Size=%f,%f", &x, &y) == 2) settings->Size = ImMax(ImVec2(x, y), GImGui->Style.WindowMinSize);
+ else if (sscanf(line, "Collapsed=%d", &i) == 1) settings->Collapsed = (i != 0);
+}
+
+static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf)
+{
+ // Gather data from windows that were active during this session
+ ImGuiContext& g = *imgui_ctx;
+ for (int i = 0; i != g.Windows.Size; i++)
+ {
+ ImGuiWindow* window = g.Windows[i];
+ if (window->Flags & ImGuiWindowFlags_NoSavedSettings)
+ continue;
+
+ ImGuiWindowSettings* settings = (window->SettingsIdx != -1) ? &g.SettingsWindows[window->SettingsIdx] : ImGui::FindWindowSettings(window->ID);
+ if (!settings)
+ {
+ settings = CreateNewWindowSettings(window->Name);
+ window->SettingsIdx = g.SettingsWindows.index_from_pointer(settings);
+ }
+ IM_ASSERT(settings->ID == window->ID);
+ settings->Pos = window->Pos;
+ settings->Size = window->SizeFull;
+ settings->Collapsed = window->Collapsed;
+ }
+
+ // Write a buffer
+ // If a window wasn't opened in this session we preserve its settings
+ buf->reserve(buf->size() + g.SettingsWindows.Size * 96); // ballpark reserve
+ for (int i = 0; i != g.SettingsWindows.Size; i++)
+ {
+ const ImGuiWindowSettings* settings = &g.SettingsWindows[i];
+ if (settings->Pos.x == FLT_MAX)
+ continue;
+ const char* name = settings->Name;
+ if (const char* p = strstr(name, "###")) // Skip to the "###" marker if any. We don't skip past to match the behavior of GetID()
+ name = p;
+ buf->appendf("[%s][%s]\n", handler->TypeName, name);
+ buf->appendf("Pos=%d,%d\n", (int)settings->Pos.x, (int)settings->Pos.y);
+ buf->appendf("Size=%d,%d\n", (int)settings->Size.x, (int)settings->Size.y);
+ buf->appendf("Collapsed=%d\n", settings->Collapsed);
+ buf->appendf("\n");
+ }
+}
+
+//-----------------------------------------------------------------------------
// PLATFORM DEPENDENT HELPERS
//-----------------------------------------------------------------------------
diff --git a/imgui_internal.h b/imgui_internal.h
index 9bdb567..affdd30 100644
--- a/imgui_internal.h
+++ b/imgui_internal.h
@@ -1137,8 +1137,9 @@
// Settings
IMGUI_API void MarkIniSettingsDirty();
IMGUI_API void MarkIniSettingsDirty(ImGuiWindow* window);
- IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(const char* type_name);
+ IMGUI_API ImGuiWindowSettings* CreateNewWindowSettings(const char* name);
IMGUI_API ImGuiWindowSettings* FindWindowSettings(ImGuiID id);
+ IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(const char* type_name);
// Basic Accessors
inline ImGuiID GetItemID() { ImGuiContext& g = *GImGui; return g.CurrentWindow->DC.LastItemId; }