mirror of
				https://github.com/ocornut/imgui.git
				synced 2025-11-04 01:34:32 +00:00 
			
		
		
		
	Settings: Made it possible to load window .ini data mid-frame. Added clear and post-read handlers. (#2573)
This commit is contained in:
		
							
								
								
									
										40
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								imgui.cpp
									
									
									
									
									
								
							@@ -917,6 +917,8 @@ static void             AddWindowToSortBuffer(ImVector<ImGuiWindow*>* out_sorted
 | 
				
			|||||||
static ImRect           GetViewportRect();
 | 
					static ImRect           GetViewportRect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Settings
 | 
					// Settings
 | 
				
			||||||
 | 
					static void             WindowSettingsHandler_ClearAll(ImGuiContext*, ImGuiSettingsHandler*);
 | 
				
			||||||
 | 
					static void             WindowSettingsHandler_ApplyAll(ImGuiContext*, ImGuiSettingsHandler*);
 | 
				
			||||||
static void*            WindowSettingsHandler_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name);
 | 
					static void*            WindowSettingsHandler_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name);
 | 
				
			||||||
static void             WindowSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler*, void* entry, const char* line);
 | 
					static void             WindowSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler*, void* entry, const char* line);
 | 
				
			||||||
static void             WindowSettingsHandler_WriteAll(ImGuiContext*, ImGuiSettingsHandler*, ImGuiTextBuffer* buf);
 | 
					static void             WindowSettingsHandler_WriteAll(ImGuiContext*, ImGuiSettingsHandler*, ImGuiTextBuffer* buf);
 | 
				
			||||||
@@ -3941,6 +3943,8 @@ void ImGui::Initialize(ImGuiContext* context)
 | 
				
			|||||||
        ImGuiSettingsHandler ini_handler;
 | 
					        ImGuiSettingsHandler ini_handler;
 | 
				
			||||||
        ini_handler.TypeName = "Window";
 | 
					        ini_handler.TypeName = "Window";
 | 
				
			||||||
        ini_handler.TypeHash = ImHashStr("Window");
 | 
					        ini_handler.TypeHash = ImHashStr("Window");
 | 
				
			||||||
 | 
					        ini_handler.ClearAllFn = WindowSettingsHandler_ClearAll;
 | 
				
			||||||
 | 
					        ini_handler.ApplyAllFn = WindowSettingsHandler_ApplyAll;
 | 
				
			||||||
        ini_handler.ReadOpenFn = WindowSettingsHandler_ReadOpen;
 | 
					        ini_handler.ReadOpenFn = WindowSettingsHandler_ReadOpen;
 | 
				
			||||||
        ini_handler.ReadLineFn = WindowSettingsHandler_ReadLine;
 | 
					        ini_handler.ReadLineFn = WindowSettingsHandler_ReadLine;
 | 
				
			||||||
        ini_handler.WriteAllFn = WindowSettingsHandler_WriteAll;
 | 
					        ini_handler.WriteAllFn = WindowSettingsHandler_WriteAll;
 | 
				
			||||||
@@ -9707,9 +9711,9 @@ void ImGui::ClearIniSettings()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    ImGuiContext& g = *GImGui;
 | 
					    ImGuiContext& g = *GImGui;
 | 
				
			||||||
    g.SettingsIniData.clear();
 | 
					    g.SettingsIniData.clear();
 | 
				
			||||||
    for (int i = 0; i != g.Windows.Size; i++)
 | 
					    for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++)
 | 
				
			||||||
        g.Windows[i]->SettingsOffset = -1;
 | 
					        if (g.SettingsHandlers[handler_n].ClearAllFn)
 | 
				
			||||||
    g.SettingsWindows.clear();
 | 
					            g.SettingsHandlers[handler_n].ClearAllFn(&g, &g.SettingsHandlers[handler_n]);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ImGui::LoadIniSettingsFromDisk(const char* ini_filename)
 | 
					void ImGui::LoadIniSettingsFromDisk(const char* ini_filename)
 | 
				
			||||||
@@ -9727,7 +9731,8 @@ void ImGui::LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    ImGuiContext& g = *GImGui;
 | 
					    ImGuiContext& g = *GImGui;
 | 
				
			||||||
    IM_ASSERT(g.Initialized);
 | 
					    IM_ASSERT(g.Initialized);
 | 
				
			||||||
    IM_ASSERT(g.SettingsLoaded == false && g.FrameCount == 0);
 | 
					    //IM_ASSERT(!g.WithinFrameScope && "Cannot be called between NewFrame() and EndFrame()");
 | 
				
			||||||
 | 
					    //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 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..
 | 
					    // 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..
 | 
				
			||||||
@@ -9779,6 +9784,11 @@ void ImGui::LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // [DEBUG] Restore untouched copy so it can be browsed in Metrics (not strictly necessary)
 | 
					    // [DEBUG] Restore untouched copy so it can be browsed in Metrics (not strictly necessary)
 | 
				
			||||||
    memcpy(buf, ini_data, ini_size);
 | 
					    memcpy(buf, ini_data, ini_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Call post-read handlers
 | 
				
			||||||
 | 
					    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]);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ImGui::SaveIniSettingsToDisk(const char* ini_filename)
 | 
					void ImGui::SaveIniSettingsToDisk(const char* ini_filename)
 | 
				
			||||||
@@ -9814,11 +9824,33 @@ const char* ImGui::SaveIniSettingsToMemory(size_t* out_size)
 | 
				
			|||||||
    return g.SettingsIniData.c_str();
 | 
					    return g.SettingsIniData.c_str();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void WindowSettingsHandler_ClearAll(ImGuiContext* ctx, ImGuiSettingsHandler*)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ImGuiContext& g = *ctx;
 | 
				
			||||||
 | 
					    for (int i = 0; i != g.Windows.Size; i++)
 | 
				
			||||||
 | 
					        g.Windows[i]->SettingsOffset = -1;
 | 
				
			||||||
 | 
					    g.SettingsWindows.clear();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Apply to existing windows (if any)
 | 
				
			||||||
 | 
					static void WindowSettingsHandler_ApplyAll(ImGuiContext* ctx, ImGuiSettingsHandler*)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ImGuiContext& g = *ctx;
 | 
				
			||||||
 | 
					    for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings))
 | 
				
			||||||
 | 
					        if (settings->WantApply)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (ImGuiWindow* window = ImGui::FindWindowByID(settings->ID))
 | 
				
			||||||
 | 
					                ApplyWindowSettings(window, settings);
 | 
				
			||||||
 | 
					            settings->WantApply = false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void* WindowSettingsHandler_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name)
 | 
					static void* WindowSettingsHandler_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ImGuiWindowSettings* settings = ImGui::FindWindowSettings(ImHashStr(name));
 | 
					    ImGuiWindowSettings* settings = ImGui::FindWindowSettings(ImHashStr(name));
 | 
				
			||||||
    if (!settings)
 | 
					    if (!settings)
 | 
				
			||||||
        settings = ImGui::CreateNewWindowSettings(name);
 | 
					        settings = ImGui::CreateNewWindowSettings(name);
 | 
				
			||||||
 | 
					    settings->WantApply = true;
 | 
				
			||||||
    return (void*)settings;
 | 
					    return (void*)settings;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -824,8 +824,9 @@ struct ImGuiWindowSettings
 | 
				
			|||||||
    ImVec2ih    Pos;
 | 
					    ImVec2ih    Pos;
 | 
				
			||||||
    ImVec2ih    Size;
 | 
					    ImVec2ih    Size;
 | 
				
			||||||
    bool        Collapsed;
 | 
					    bool        Collapsed;
 | 
				
			||||||
 | 
					    bool        WantApply;      // Set when loaded from .ini data (to enable merging/loading .ini data into an already running context)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ImGuiWindowSettings()       { ID = 0; Pos = Size = ImVec2ih(0, 0); Collapsed = false; }
 | 
					    ImGuiWindowSettings()       { ID = 0; Pos = Size = ImVec2ih(0, 0); Collapsed = WantApply = false; }
 | 
				
			||||||
    char* GetName()             { return (char*)(this + 1); }
 | 
					    char* GetName()             { return (char*)(this + 1); }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -833,6 +834,8 @@ struct ImGuiSettingsHandler
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    const char* TypeName;       // Short description stored in .ini file. Disallowed characters: '[' ']'
 | 
					    const char* TypeName;       // Short description stored in .ini file. Disallowed characters: '[' ']'
 | 
				
			||||||
    ImGuiID     TypeHash;       // == ImHashStr(TypeName)
 | 
					    ImGuiID     TypeHash;       // == ImHashStr(TypeName)
 | 
				
			||||||
 | 
					    void        (*ClearAllFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler);                                // Clear all settings data
 | 
				
			||||||
 | 
					    void        (*ApplyAllFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler);                                // Read: Called after reading (in registration order)
 | 
				
			||||||
    void*       (*ReadOpenFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, const char* name);              // Read: Called when entering into a new ini entry e.g. "[Window][Name]"
 | 
					    void*       (*ReadOpenFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, const char* name);              // Read: Called when entering into a new ini entry e.g. "[Window][Name]"
 | 
				
			||||||
    void        (*ReadLineFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, void* entry, const char* line); // Read: Called for every line of text within an ini entry
 | 
					    void        (*ReadLineFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, void* entry, const char* line); // Read: Called for every line of text within an ini entry
 | 
				
			||||||
    void        (*WriteAllFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* out_buf);      // Write: Output every entries into 'out_buf'
 | 
					    void        (*WriteAllFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* out_buf);      // Write: Output every entries into 'out_buf'
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user