From 3997e8b555ebb2b263dde7dce0d626d9a08fca29 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 7 Jan 2019 22:46:42 +0100 Subject: [PATCH] Fixed animated window titles from being updated when displayed in the CTRL+Tab list. + Adding overkill helpers for reusing buffers. (#787) --- docs/CHANGELOG.txt | 1 + imgui.cpp | 39 ++++++++++++++++++++++++++++++++++----- imgui_internal.h | 2 ++ 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 42cccf765..053c8ea2c 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -66,6 +66,7 @@ Other Changes: - InputFloat: When using ImGuiInputTextFlags_ReadOnly the step buttons are disabled. (#2257) - Nav: Fixed an keyboard issue where holding Activate/Space for longer than two frames on a button would unnecessary keep the focus on the parent window, which could steal it from newly appearing windows. (#787) +- Nav: Fixed animated window titles from being updated when displayed in the CTRL+Tab list. (#787) - Error recovery: Extraneous/undesired calls to End() are now being caught by an assert in the End() function closer to the user call site (instead of being reported in EndFrame). Past the assert, they don't lead to crashes any more. (#1651) Missing calls to End(), past the assert, should not lead to crashes or to the fallback Debug window appearing on screen. diff --git a/imgui.cpp b/imgui.cpp index a1c641936..3f9ce8beb 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1259,11 +1259,25 @@ void ImStrncpy(char* dst, const char* src, size_t count) dst[count-1] = 0; } -char* ImStrdup(const char *str) +char* ImStrdup(const char* str) { - size_t len = strlen(str) + 1; - void* buf = ImGui::MemAlloc(len); - return (char*)memcpy(buf, (const void*)str, len); + size_t len = strlen(str); + void* buf = ImGui::MemAlloc(len + 1); + return (char*)memcpy(buf, (const void*)str, len + 1); +} + +char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* src) +{ + size_t dst_buf_size = p_dst_size ? *p_dst_size : strlen(dst) + 1; + size_t src_size = strlen(src) + 1; + if (dst_buf_size < src_size) + { + ImGui::MemFree(dst); + dst = (char*)ImGui::MemAlloc(src_size); + if (p_dst_size) + *p_dst_size = src_size; + } + return (char*)memcpy(dst, (const void*)src, src_size); } const char* ImStrchrRange(const char* str, const char* str_end, char c) @@ -1367,7 +1381,9 @@ int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) } #endif // #ifdef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS -// Pass data_size==0 for zero-terminated strings +// Pass data_size == 0 for zero-terminated strings, data_size > 0 for non-string data. +// Pay attention that data_size==0 will yield different results than passing strlen(data) because the zero-terminated codepath handles ###. +// This should technically be split into two distinct functions (ImHashData/ImHashStr), perhaps once we remove the silly static variable. // FIXME-OPT: Replace with e.g. FNV1a hash? CRC32 pretty much randomly access 1KB. Need to do proper measurements. ImU32 ImHash(const void* data, int data_size, ImU32 seed) { @@ -2391,6 +2407,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) WindowPadding = ImVec2(0.0f, 0.0f); WindowRounding = 0.0f; WindowBorderSize = 0.0f; + NameBufLen = (int)strlen(name) + 1; MoveId = GetID("#MOVE"); ChildId = 0; Scroll = ImVec2(0.0f, 0.0f); @@ -4802,6 +4819,18 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->LastFrameActive = current_frame; window->IDStack.resize(1); + // Update stored window name when it changes (which can _only_ happen with the "###" operator, so the ID would stay unchanged). + // The title bar always display the 'name' parameter, so we only update the string storage if it needs to be visible to the end-user elsewhere. + bool window_title_visible_elsewhere = false; + if (g.NavWindowingList != NULL && (window->Flags & ImGuiWindowFlags_NoNavFocus) == 0) // Window titles visible when using CTRL+TAB + window_title_visible_elsewhere = true; + if (window_title_visible_elsewhere && !window_just_created && strcmp(name, window->Name) != 0) + { + size_t buf_len = (size_t)window->NameBufLen; + window->Name = ImStrdupcpy(window->Name, &buf_len, name); + window->NameBufLen = (int)buf_len; + } + // UPDATE CONTENTS SIZE, UPDATE HIDDEN STATUS // Update contents size from last frame for auto-fitting (or use explicit size) diff --git a/imgui_internal.h b/imgui_internal.h index f035854a9..213ef3dc8 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -143,6 +143,7 @@ IMGUI_API int ImStricmp(const char* str1, const char* str2); IMGUI_API int ImStrnicmp(const char* str1, const char* str2, size_t count); IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count); IMGUI_API char* ImStrdup(const char* str); +IMGUI_API char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* str); IMGUI_API const char* ImStrchrRange(const char* str_begin, const char* str_end, char c); IMGUI_API int ImStrlenW(const ImWchar* str); IMGUI_API const char* ImStreolRange(const char* str, const char* str_end); // End end-of-line @@ -1071,6 +1072,7 @@ struct IMGUI_API ImGuiWindow ImVec2 WindowPadding; // Window padding at the time of begin. float WindowRounding; // Window rounding at the time of begin. float WindowBorderSize; // Window border size at the time of begin. + int NameBufLen; // Size of buffer storing Name. May be larger than strlen(Name)! ImGuiID MoveId; // == window->GetID("#MOVE") ImGuiID ChildId; // ID of corresponding item in parent window (for navigation to return from child window to parent window) ImVec2 Scroll;