From 0d540c8b57792acb0bdc77bd1a61912d81f53d79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Tue, 8 May 2018 08:23:45 -0700 Subject: [PATCH] Updated ImGui. --- 3rdparty/dear-imgui/imgui.cpp | 108 ++++++++++++++------------- 3rdparty/dear-imgui/imgui.h | 15 +++- 3rdparty/dear-imgui/imgui_demo.cpp | 3 +- 3rdparty/dear-imgui/imgui_draw.cpp | 25 ++++++- 3rdparty/dear-imgui/imgui_internal.h | 11 +-- 5 files changed, 98 insertions(+), 64 deletions(-) diff --git a/3rdparty/dear-imgui/imgui.cpp b/3rdparty/dear-imgui/imgui.cpp index 4b8f243af..4b2a2869b 100644 --- a/3rdparty/dear-imgui/imgui.cpp +++ b/3rdparty/dear-imgui/imgui.cpp @@ -736,12 +736,6 @@ static void AddWindowToSortedBuffer(ImVector* out_sort static ImGuiWindowSettings* AddWindowSettings(const char* name); -static void LoadIniSettingsFromDisk(const char* ini_filename); -static void LoadIniSettingsFromMemory(const char* buf); -static void SaveIniSettingsToDisk(const char* ini_filename); -static void SaveIniSettingsToMemory(ImVector& out_buf); -static void MarkIniSettingsDirty(ImGuiWindow* window); - static ImRect GetViewportRect(); static void ClosePopupToLevel(int remaining); @@ -1458,7 +1452,7 @@ FILE* ImFileOpen(const char* filename, const char* mode) // Load file content into memory // Memory allocated with ImGui::MemAlloc(), must be freed by user using ImGui::MemFree() -void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, int* out_file_size, int padding_bytes) +void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, size_t* out_file_size, int padding_bytes) { IM_ASSERT(filename && file_open_mode); if (out_file_size) @@ -1475,14 +1469,14 @@ void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, int* return NULL; } - int file_size = (int)file_size_signed; - void* file_data = ImGui::MemAlloc((size_t)(file_size + padding_bytes)); + size_t file_size = (size_t)file_size_signed; + void* file_data = ImGui::MemAlloc(file_size + padding_bytes); if (file_data == NULL) { fclose(f); return NULL; } - if (fread(file_data, 1, (size_t)file_size, f) != (size_t)file_size) + if (fread(file_data, 1, file_size, f) != file_size) { fclose(f); ImGui::MemFree(file_data); @@ -2603,10 +2597,10 @@ float ImGui::CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x) //----------------------------------------------------------------------------- -void* ImGui::MemAlloc(size_t sz) +void* ImGui::MemAlloc(size_t size) { GImAllocatorActiveAllocationsCount++; - return GImAllocatorAllocFunc(sz, GImAllocatorUserData); + return GImAllocatorAllocFunc(size, GImAllocatorUserData); } void ImGui::MemFree(void* ptr) @@ -3447,20 +3441,27 @@ void ImGui::NewFrame() if (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) IM_ASSERT(g.IO.KeyMap[ImGuiKey_Space] != -1 && "ImGuiKey_Space is not mapped, required for keyboard navigation."); - // Load settings on first frame + // Load settings on first frame (if not explicitly loaded manually before) if (!g.SettingsLoaded) { IM_ASSERT(g.SettingsWindows.empty()); - LoadIniSettingsFromDisk(g.IO.IniFilename); + if (g.IO.IniFilename) + LoadIniSettingsFromDisk(g.IO.IniFilename); g.SettingsLoaded = true; } - // Save settings (with a delay so we don't spam disk too much) + // Save settings (with a delay after the last modification, so we don't spam disk too much) if (g.SettingsDirtyTimer > 0.0f) { g.SettingsDirtyTimer -= g.IO.DeltaTime; if (g.SettingsDirtyTimer <= 0.0f) - SaveIniSettingsToDisk(g.IO.IniFilename); + { + if (g.IO.IniFilename != NULL) + SaveIniSettingsToDisk(g.IO.IniFilename); + else + g.IO.WantSaveIniSettings = true; // Let user know they can call SaveIniSettingsToMemory(). user will need to clear io.WantSaveIniSettings themselves. + g.SettingsDirtyTimer = 0.0f; + } } g.Time += g.IO.DeltaTime; @@ -3672,7 +3673,6 @@ void ImGui::Initialize(ImGuiContext* context) { ImGuiContext& g = *context; IM_ASSERT(!g.Initialized && !g.SettingsLoaded); - g.LogClipboard = IM_NEW(ImGuiTextBuffer)(); // Add .ini handle for ImGuiWindow type ImGuiSettingsHandler ini_handler; @@ -3689,19 +3689,18 @@ void ImGui::Initialize(ImGuiContext* context) // This function is merely here to free heap allocations. void ImGui::Shutdown(ImGuiContext* context) { - ImGuiContext& g = *context; - // The fonts atlas can be used prior to calling NewFrame(), so we clear it even if g.Initialized is FALSE (which would happen if we never called NewFrame) + ImGuiContext& g = *context; if (g.IO.Fonts && g.FontAtlasOwnedByContext) IM_DELETE(g.IO.Fonts); g.IO.Fonts = NULL; - // Cleanup of other data are conditional on actually having initialize ImGui. + // Cleanup of other data are conditional on actually having initialized ImGui. if (!g.Initialized) return; // Save settings (unless we haven't attempted to load them: CreateContext/DestroyContext without a call to NewFrame shouldn't save an empty file) - if (g.SettingsLoaded) + if (g.SettingsLoaded && g.IO.IniFilename != NULL) SaveIniSettingsToDisk(g.IO.IniFilename); // Clear everything else @@ -3739,9 +3738,7 @@ void ImGui::Shutdown(ImGuiContext* context) fclose(g.LogFile); g.LogFile = NULL; } - if (g.LogClipboard) - IM_DELETE(g.LogClipboard); - g.LogClipboard = NULL; + g.LogClipboard.clear(); g.Initialized = false; } @@ -3765,14 +3762,13 @@ static ImGuiWindowSettings* AddWindowSettings(const char* name) return settings; } -static void LoadIniSettingsFromDisk(const char* ini_filename) +void ImGui::LoadIniSettingsFromDisk(const char* ini_filename) { - if (!ini_filename) - return; - char* file_data = (char*)ImFileLoadToMemory(ini_filename, "rb", NULL, +1); + size_t file_data_size = 0; + char* file_data = (char*)ImFileLoadToMemory(ini_filename, "rb", &file_data_size); if (!file_data) return; - LoadIniSettingsFromMemory(file_data); + LoadIniSettingsFromMemory(file_data, (size_t)file_data_size); ImGui::MemFree(file_data); } @@ -3787,13 +3783,21 @@ ImGuiSettingsHandler* ImGui::FindSettingsHandler(const char* type_name) } // Zero-tolerance, no error reporting, cheap .ini parsing -static void LoadIniSettingsFromMemory(const char* buf_readonly) +void ImGui::LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size) { - // For convenience and to make the code simpler, we'll write zero terminators inside the buffer. So let's create a writable copy. - char* buf = ImStrdup(buf_readonly); - char* buf_end = buf + strlen(buf); - 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; @@ -3826,7 +3830,7 @@ static void LoadIniSettingsFromMemory(const char* buf_readonly) *type_end = 0; // Overwrite first ']' name_start++; // Skip second '[' } - entry_handler = ImGui::FindSettingsHandler(type_start); + 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) @@ -3839,37 +3843,37 @@ static void LoadIniSettingsFromMemory(const char* buf_readonly) g.SettingsLoaded = true; } -static void SaveIniSettingsToDisk(const char* ini_filename) +void ImGui::SaveIniSettingsToDisk(const char* ini_filename) { ImGuiContext& g = *GImGui; g.SettingsDirtyTimer = 0.0f; if (!ini_filename) return; - ImVector buf; - SaveIniSettingsToMemory(buf); - + size_t ini_data_size = 0; + const char* ini_data = SaveIniSettingsToMemory(&ini_data_size); FILE* f = ImFileOpen(ini_filename, "wt"); if (!f) return; - fwrite(buf.Data, sizeof(char), (size_t)buf.Size, f); + fwrite(ini_data, sizeof(char), ini_data_size, f); fclose(f); } -static void SaveIniSettingsToMemory(ImVector& out_buf) +// 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; - - ImGuiTextBuffer buf; + 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, &buf); + handler->WriteAllFn(&g, handler, &g.SettingsIniData); } - - buf.Buf.pop_back(); // Remove extra zero-terminator used by ImGuiTextBuffer - out_buf.swap(buf.Buf); + if (out_size) + *out_size = (size_t)g.SettingsIniData.size(); + return g.SettingsIniData.c_str(); } void ImGui::MarkIniSettingsDirty() @@ -3879,7 +3883,7 @@ void ImGui::MarkIniSettingsDirty() g.SettingsDirtyTimer = g.IO.IniSavingRate; } -static void MarkIniSettingsDirty(ImGuiWindow* window) +void ImGui::MarkIniSettingsDirty(ImGuiWindow* window) { ImGuiContext& g = *GImGui; if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings)) @@ -4182,7 +4186,7 @@ void ImGui::LogText(const char* fmt, ...) if (g.LogFile) vfprintf(g.LogFile, fmt, args); else - g.LogClipboard->appendfv(fmt, args); + g.LogClipboard.appendfv(fmt, args); va_end(args); } @@ -7977,10 +7981,10 @@ void ImGui::LogFinish() fclose(g.LogFile); g.LogFile = NULL; } - if (g.LogClipboard->size() > 1) + if (g.LogClipboard.size() > 1) { - SetClipboardText(g.LogClipboard->begin()); - g.LogClipboard->clear(); + SetClipboardText(g.LogClipboard.begin()); + g.LogClipboard.clear(); } g.LogEnabled = false; } diff --git a/3rdparty/dear-imgui/imgui.h b/3rdparty/dear-imgui/imgui.h index 0497256b2..dac6b6593 100644 --- a/3rdparty/dear-imgui/imgui.h +++ b/3rdparty/dear-imgui/imgui.h @@ -543,6 +543,14 @@ namespace ImGui IMGUI_API const char* GetClipboardText(); IMGUI_API void SetClipboardText(const char* text); + // Settings/.Ini Utilities + // The disk functions are automatically called if io.IniFilename != NULL (default is "imgui.ini"). + // Set io.IniFilename to NULL to load/save manually. Read io.WantSaveIniSettings description about handling .ini saving manually. + IMGUI_API void LoadIniSettingsFromDisk(const char* ini_filename); // call after CreateContext() and before the first call to NewFrame(). NewFrame() automatically calls LoadIniSettingsFromDisk(io.IniFilename). + IMGUI_API void LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size=0); // call after CreateContext() and before the first call to NewFrame() to provide .ini data from your own data source. + IMGUI_API void SaveIniSettingsToDisk(const char* ini_filename); + IMGUI_API const char* SaveIniSettingsToMemory(size_t* out_ini_size = NULL); // return a zero-terminated string with the .ini data which you can save by your own mean. call when io.WantSaveIniSettings is set, then save data by your own mean and clear io.WantSaveIniSettings. + // Memory Utilities // All those functions are not reliant on the current context. // If you reload the contents of imgui.cpp at runtime, you may need to call SetCurrentContext() + SetAllocatorFunctions() again. @@ -1004,11 +1012,11 @@ struct ImGuiIO //------------------------------------------------------------------ ImGuiConfigFlags ConfigFlags; // = 0 // See ImGuiConfigFlags_ enum. Set by user/application. Gamepad/keyboard navigation options, etc. - ImGuiBackendFlags BackendFlags; // = 0 // Set ImGuiBackendFlags_ enum. Set by imgui_impl_xxx files or custom back-end. + ImGuiBackendFlags BackendFlags; // = 0 // Set ImGuiBackendFlags_ enum. Set by imgui_impl_xxx files or custom back-end to communicate features supported by the back-end. ImVec2 DisplaySize; // // Display size, in pixels. For clamping windows positions. float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds. - float IniSavingRate; // = 5.0f // Maximum time between saving positions/sizes to .ini file, in seconds. - const char* IniFilename; // = "imgui.ini" // Path to .ini file. NULL to disable .ini saving. + float IniSavingRate; // = 5.0f // Minimum time between saving positions/sizes to .ini file, in seconds. + const char* IniFilename; // = "imgui.ini" // Path to .ini file. Set NULL to disable automatic .ini loading/saving, if e.g. you want to manually load/save from memory. const char* LogFilename; // = "imgui_log.txt" // Path to .log file (default parameter to ImGui::LogToFile when no file is specified). float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds. float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels. @@ -1084,6 +1092,7 @@ struct ImGuiIO bool WantCaptureKeyboard; // When io.WantCaptureKeyboard is true, imgui will use the keyboard inputs, do not dispatch them to your main game/application (in both cases, always pass keyboard inputs to imgui). (e.g. InputText active, or an imgui window is focused and navigation is enabled, etc.). bool WantTextInput; // Mobile/console: when io.WantTextInput is true, you may display an on-screen keyboard. This is set by ImGui when it wants textual keyboard input to happen (e.g. when a InputText widget is active). bool WantSetMousePos; // MousePos has been altered, back-end should reposition mouse on next frame. Set only when ImGuiConfigFlags_NavEnableSetMousePos flag is enabled. + bool WantSaveIniSettings; // When manual .ini load/save is active (io.IniFilename == NULL), this will be set to notify your application that you can call SaveIniSettingsToMemory() and save yourself. IMPORTANT: You need to clear io.WantSaveIniSettings yourself. bool NavActive; // Directional navigation is currently allowed (will handle ImGuiKey_NavXXX events) = a window is focused and it doesn't use the ImGuiWindowFlags_NoNavInputs flag. bool NavVisible; // Directional navigation is visible and allowed (will handle ImGuiKey_NavXXX events). float Framerate; // Application framerate estimation, in frame per second. Solely for convenience. Rolling average estimation based on IO.DeltaTime over 120 frames diff --git a/3rdparty/dear-imgui/imgui_demo.cpp b/3rdparty/dear-imgui/imgui_demo.cpp index 6717aaaa8..2960d3716 100644 --- a/3rdparty/dear-imgui/imgui_demo.cpp +++ b/3rdparty/dear-imgui/imgui_demo.cpp @@ -2288,7 +2288,8 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImVec2 cell_p2(cell_p1.x + cell_size, cell_p1.y + cell_size); const ImFontGlyph* glyph = font->FindGlyphNoFallback((ImWchar)(base+n)); draw_list->AddRect(cell_p1, cell_p2, glyph ? IM_COL32(255,255,255,100) : IM_COL32(255,255,255,50)); - font->RenderChar(draw_list, cell_size, cell_p1, ImGui::GetColorU32(ImGuiCol_Text), (ImWchar)(base+n)); // We use ImFont::RenderChar as a shortcut because we don't have UTF-8 conversion functions available to generate a string. + if (glyph) + font->RenderChar(draw_list, cell_size, cell_p1, ImGui::GetColorU32(ImGuiCol_Text), (ImWchar)(base+n)); // We use ImFont::RenderChar as a shortcut because we don't have UTF-8 conversion functions available to generate a string. if (glyph && ImGui::IsMouseHoveringRect(cell_p1, cell_p2)) { ImGui::BeginTooltip(); diff --git a/3rdparty/dear-imgui/imgui_draw.cpp b/3rdparty/dear-imgui/imgui_draw.cpp index 5ea4b13a4..83f23774a 100644 --- a/3rdparty/dear-imgui/imgui_draw.cpp +++ b/3rdparty/dear-imgui/imgui_draw.cpp @@ -91,6 +91,7 @@ namespace IMGUI_STB_NAMESPACE #pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers #endif +#ifndef STB_RECT_PACK_IMPLEMENTATION // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds) #ifndef IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION #define STBRP_STATIC #define STBRP_ASSERT(x) IM_ASSERT(x) @@ -101,7 +102,9 @@ namespace IMGUI_STB_NAMESPACE #else #include "stb_rect_pack.h" #endif +#endif +#ifndef STB_TRUETYPE_IMPLEMENTATION // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds) #ifndef IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION #define STBTT_malloc(x,u) ((void)(u), ImGui::MemAlloc(x)) #define STBTT_free(x,u) ((void)(u), ImGui::MemFree(x)) @@ -116,6 +119,7 @@ namespace IMGUI_STB_NAMESPACE #else #include "stb_truetype.h" #endif +#endif #ifdef __GNUC__ #pragma GCC diagnostic pop @@ -1543,7 +1547,7 @@ ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg_template) ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges) { - int data_size = 0; + size_t data_size = 0; void* data = ImFileLoadToMemory(filename, "rb", &data_size, 0); if (!data) { @@ -1558,7 +1562,7 @@ ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels, for (p = filename + strlen(filename); p > filename && p[-1] != '/' && p[-1] != '\\'; p--) {} ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "%s, %.0fpx", p, size_pixels); } - return AddFontFromMemoryTTF(data, data_size, size_pixels, &font_cfg, glyph_ranges); + return AddFontFromMemoryTTF(data, (int)data_size, size_pixels, &font_cfg, glyph_ranges); } // NB: Transfer ownership of 'ttf_data' to ImFontAtlas, unless font_cfg_template->FontDataOwnedByAtlas == false. Owned TTF buffer will be deleted after Build(). @@ -1776,19 +1780,34 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) buf_packedchars_n += range.num_chars; } - // Pack + // Gather the sizes of all rectangle we need tmp.Rects = buf_rects + buf_rects_n; tmp.RectsCount = font_glyphs_count; buf_rects_n += font_glyphs_count; stbtt_PackSetOversampling(&spc, cfg.OversampleH, cfg.OversampleV); int n = stbtt_PackFontRangesGatherRects(&spc, &tmp.FontInfo, tmp.Ranges, tmp.RangesCount, tmp.Rects); IM_ASSERT(n == font_glyphs_count); + + // Detect missing glyphs and replace them with a zero-sized box instead of relying on the default glyphs + // This allows us merging overlapping icon fonts more easily. + int rect_i = 0; + for (int range_i = 0; range_i < tmp.RangesCount; range_i++) + for (int char_i = 0; char_i < tmp.Ranges[range_i].num_chars; char_i++, rect_i++) + if (stbtt_FindGlyphIndex(&tmp.FontInfo, tmp.Ranges[range_i].first_unicode_codepoint_in_range + char_i) == 0) + tmp.Rects[rect_i].w = tmp.Rects[rect_i].h = 0; + + // Pack stbrp_pack_rects((stbrp_context*)spc.pack_info, tmp.Rects, n); // Extend texture height + // Also mark missing glyphs as non-packed so we don't attempt to render into them for (int i = 0; i < n; i++) + { + if (tmp.Rects[i].w == 0 && tmp.Rects[i].h == 0) + tmp.Rects[i].was_packed = 0; if (tmp.Rects[i].was_packed) atlas->TexHeight = ImMax(atlas->TexHeight, tmp.Rects[i].y + tmp.Rects[i].h); + } } IM_ASSERT(buf_rects_n == total_glyphs_count); IM_ASSERT(buf_packedchars_n == total_glyphs_count); diff --git a/3rdparty/dear-imgui/imgui_internal.h b/3rdparty/dear-imgui/imgui_internal.h index 411db886e..031ff82cb 100644 --- a/3rdparty/dear-imgui/imgui_internal.h +++ b/3rdparty/dear-imgui/imgui_internal.h @@ -96,7 +96,7 @@ IMGUI_API int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, cons // Helpers: Misc IMGUI_API ImU32 ImHash(const void* data, int data_size, ImU32 seed = 0); // Pass data_size==0 for zero-terminated strings -IMGUI_API void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, int* out_file_size = NULL, int padding_bytes = 0); +IMGUI_API void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, size_t* out_file_size = NULL, int padding_bytes = 0); IMGUI_API FILE* ImFileOpen(const char* filename, const char* file_open_mode); static inline bool ImCharIsSpace(unsigned int c) { return c == ' ' || c == '\t' || c == 0x3000; } static inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; } @@ -676,14 +676,15 @@ struct ImGuiContext // Settings bool SettingsLoaded; - float SettingsDirtyTimer; // Save .ini Settings on disk when time reaches zero - ImVector SettingsWindows; // .ini settings for ImGuiWindow + float SettingsDirtyTimer; // Save .ini Settings to memory when time reaches zero + ImGuiTextBuffer SettingsIniData; // In memory .ini settings ImVector SettingsHandlers; // List of .ini settings handlers + ImVector SettingsWindows; // ImGuiWindow .ini settings entries (parsed from the last loaded .ini file and maintained on saving) // Logging bool LogEnabled; FILE* LogFile; // If != NULL log to stdout/ file - ImGuiTextBuffer* LogClipboard; // Else log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators. + ImGuiTextBuffer LogClipboard; // Accumulation buffer when log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators. int LogStartDepth; int LogAutoExpandMaxDepth; @@ -783,7 +784,6 @@ struct ImGuiContext LogEnabled = false; LogFile = NULL; - LogClipboard = NULL; LogStartDepth = 0; LogAutoExpandMaxDepth = 2; @@ -1023,6 +1023,7 @@ namespace ImGui IMGUI_API void NewFrameUpdateHoveredWindowAndCaptureFlags(); IMGUI_API void MarkIniSettingsDirty(); + IMGUI_API void MarkIniSettingsDirty(ImGuiWindow* window); IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(const char* type_name); IMGUI_API ImGuiWindowSettings* FindWindowSettings(ImGuiID id);