mirror of
				https://github.com/ocornut/imgui.git
				synced 2025-10-26 12:27:30 +00:00 
			
		
		
		
	Refactor: Internals: Moved Settings functions in imgui.cpp in their own section. (#2036)
This commit is contained in:
		
							
								
								
									
										444
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										444
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -876,13 +876,17 @@ static void             SetWindowSize(ImGuiWindow* window, const ImVec2& size, I | |||||||
| static void             SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond); | static void             SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond); | ||||||
| static void             FindHoveredWindow(); | static void             FindHoveredWindow(); | ||||||
| static ImGuiWindow*     CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFlags flags); | static ImGuiWindow*     CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFlags flags); | ||||||
| static ImGuiWindowSettings* CreateNewWindowSettings(const char* name); |  | ||||||
| static void             CheckStacksSize(ImGuiWindow* window, bool write); | static void             CheckStacksSize(ImGuiWindow* window, bool write); | ||||||
| static ImVec2           CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool snap_on_edges); | static ImVec2           CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool snap_on_edges); | ||||||
|  |  | ||||||
| static void             AddDrawListToDrawData(ImVector<ImDrawList*>* out_list, ImDrawList* draw_list); | static void             AddDrawListToDrawData(ImVector<ImDrawList*>* out_list, ImDrawList* draw_list); | ||||||
| static void             AddWindowToSortedBuffer(ImVector<ImGuiWindow*>* out_sorted_windows, ImGuiWindow* window); | static void             AddWindowToSortedBuffer(ImVector<ImGuiWindow*>* out_sorted_windows, ImGuiWindow* window); | ||||||
|  |  | ||||||
|  | // 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 | namespace ImGui | ||||||
| { | { | ||||||
| static bool             BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags flags); | static bool             BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags flags); | ||||||
| @@ -4416,74 +4420,6 @@ void ImGui::NewFrame() | |||||||
|     Begin("Debug##Default"); |     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; |  | ||||||
|     ImU32 u1; |  | ||||||
|     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, "ViewportId=0x%08X", &u1) == 1)       { settings->ViewportId = u1; } |  | ||||||
|     else if (sscanf(line, "ViewportPos=%f,%f", &x, &y) == 2)    { settings->ViewportPos = ImVec2(x, y); } |  | ||||||
|     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 - window->ViewportPos; |  | ||||||
|         settings->Size = window->SizeFull; |  | ||||||
|         settings->ViewportId = window->ViewportId; |  | ||||||
|         settings->ViewportPos = window->ViewportPos; |  | ||||||
|         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]; |  | ||||||
|         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); |  | ||||||
|         if (settings->ViewportId != 0 && settings->ViewportId != ImGui::IMGUI_VIEWPORT_DEFAULT_ID) |  | ||||||
|         { |  | ||||||
|             buf->appendf("ViewportPos=%d,%d\n", (int)settings->ViewportPos.x, (int)settings->ViewportPos.y); |  | ||||||
|             buf->appendf("ViewportId=0x%08X\n", settings->ViewportId); |  | ||||||
|         } |  | ||||||
|         if (settings->Pos.x != 0.0f || settings->Pos.y != 0.0f || settings->ViewportId == ImGui::IMGUI_VIEWPORT_DEFAULT_ID) |  | ||||||
|             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) | void ImGui::Initialize(ImGuiContext* context) | ||||||
| { | { | ||||||
|     ImGuiContext& g = *context; |     ImGuiContext& g = *context; | ||||||
| @@ -4592,155 +4528,6 @@ void ImGui::Shutdown(ImGuiContext* context) | |||||||
|     g.Initialized = false; |     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. | // FIXME: Add a more explicit sort order in the window structure. | ||||||
| static int IMGUI_CDECL ChildWindowComparer(const void* lhs, const void* rhs) | static int IMGUI_CDECL ChildWindowComparer(const void* lhs, const void* rhs) | ||||||
| { | { | ||||||
| @@ -9849,6 +9636,227 @@ void ImGui::EndDragDropTarget() | |||||||
|     g.DragDropWithinSourceOrTarget = false; |     g.DragDropWithinSourceOrTarget = false; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | //----------------------------------------------------------------------------- | ||||||
|  | // 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; | ||||||
|  |     ImU32 u1; | ||||||
|  |     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, "ViewportId=0x%08X", &u1) == 1)       { settings->ViewportId = u1; } | ||||||
|  |     else if (sscanf(line, "ViewportPos=%f,%f", &x, &y) == 2)    { settings->ViewportPos = ImVec2(x, y); } | ||||||
|  |     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 - window->ViewportPos; | ||||||
|  |         settings->Size = window->SizeFull; | ||||||
|  |         settings->ViewportId = window->ViewportId; | ||||||
|  |         settings->ViewportPos = window->ViewportPos; | ||||||
|  |         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]; | ||||||
|  |         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); | ||||||
|  |         if (settings->ViewportId != 0 && settings->ViewportId != ImGui::IMGUI_VIEWPORT_DEFAULT_ID) | ||||||
|  |         { | ||||||
|  |             buf->appendf("ViewportPos=%d,%d\n", (int)settings->ViewportPos.x, (int)settings->ViewportPos.y); | ||||||
|  |             buf->appendf("ViewportId=0x%08X\n", settings->ViewportId); | ||||||
|  |         } | ||||||
|  |         if (settings->Pos.x != 0.0f || settings->Pos.y != 0.0f || settings->ViewportId == ImGui::IMGUI_VIEWPORT_DEFAULT_ID) | ||||||
|  |             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 | // PLATFORM DEPENDENT HELPERS | ||||||
| //----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||||
|   | |||||||
| @@ -1204,8 +1204,9 @@ namespace ImGui | |||||||
|     // Settings |     // Settings | ||||||
|     IMGUI_API void                  MarkIniSettingsDirty(); |     IMGUI_API void                  MarkIniSettingsDirty(); | ||||||
|     IMGUI_API void                  MarkIniSettingsDirty(ImGuiWindow* window); |     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 ImGuiWindowSettings*  FindWindowSettings(ImGuiID id); | ||||||
|  |     IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(const char* type_name); | ||||||
|  |  | ||||||
|     // Basic Accessors |     // Basic Accessors | ||||||
|     inline ImGuiID          GetItemID()     { ImGuiContext& g = *GImGui; return g.CurrentWindow->DC.LastItemId; } |     inline ImGuiID          GetItemID()     { ImGuiContext& g = *GImGui; return g.CurrentWindow->DC.LastItemId; } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 omar
					omar