From 2785ac0ee342d5cbcab0d546d773e7492a1e3cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BE=E8=B5=B7=E5=A8=81?= Date: Wed, 11 Nov 2020 11:35:47 +0100 Subject: [PATCH] InputText: Fixed updating cursor/selection position when a callback alters the buffer in a way where the byte count is unchanged but the decoded character count changes. (#3587) --- docs/CHANGELOG.txt | 4 +++- imgui_widgets.cpp | 9 +++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 7b8254ac..8dc2aa48 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -64,9 +64,11 @@ Other Changes: - Drag and Drop: Fix drag and drop to tie same-size drop targets by choosen the later one. Fixes dragging into a full-window-sized dockspace inside a zero-padded window. (#3519, #2717) [@Black-Cat] - Checkbox: Added CheckboxFlags() helper with int* type. +- InputText: Fixed updating cursor/selection position when a callback altered the buffer in a way + where the byte count is unchanged but the decoded character count changes. (#3587) [@gqw] - Metrics: Fixed mishandling of ImDrawCmd::VtxOffset in wireframe mesh renderer. - Misc: Replaced UTF-8 decoder by branchless one by Christopher Wellons (30~40% faster). [@rokups] - Super minor fix handling incomplete UTF-8 contents: if input does not contain enough bytes, decoder + Super minor fix handling incomplete UTF-8 contents: if input does not contain enough bytes, decoder returns IM_UNICODE_CODEPOINT_INVALID and consume remaining bytes (vs old decoded consumed only 1 byte). - Backends: OpenGL3: Use glGetString(GL_VERSION) query instead of glGetIntegerv(GL_MAJOR_VERSION, ...) when the later returns zero (e.g. Desktop GL 2.x). (#3530) [@xndcn] diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 2c5e1814..d8f88f9e 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -4273,10 +4273,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ IM_ASSERT(callback_data.Buf == state->TextA.Data); // Invalid to modify those fields IM_ASSERT(callback_data.BufSize == state->BufCapacityA); IM_ASSERT(callback_data.Flags == flags); - if (callback_data.CursorPos != utf8_cursor_pos) { state->Stb.cursor = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.CursorPos); state->CursorFollow = true; } - if (callback_data.SelectionStart != utf8_selection_start) { state->Stb.select_start = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionStart); } - if (callback_data.SelectionEnd != utf8_selection_end) { state->Stb.select_end = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionEnd); } - if (callback_data.BufDirty) + const bool buf_dirty = callback_data.BufDirty; + if (callback_data.CursorPos != utf8_cursor_pos || buf_dirty) { state->Stb.cursor = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.CursorPos); state->CursorFollow = true; } + if (callback_data.SelectionStart != utf8_selection_start || buf_dirty) { state->Stb.select_start = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionStart); } + if (callback_data.SelectionEnd != utf8_selection_end || buf_dirty) { state->Stb.select_end = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionEnd); } + if (buf_dirty) { IM_ASSERT(callback_data.BufTextLen == (int)strlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text! if (callback_data.BufTextLen > backup_current_text_length && is_resizable)