InputText: paste does a truncate when not fitting instead of ignoring it. (#9029)

This commit is contained in:
ocornut
2025-10-23 20:53:29 +02:00
parent b7e45b3a48
commit e6125361f9
2 changed files with 21 additions and 11 deletions

View File

@@ -47,6 +47,8 @@ Other Changes:
result in temporarily incorrect state, which would lead to bugs to side effects result in temporarily incorrect state, which would lead to bugs to side effects
in various locations, e.g. GetContentRegionAvail() calls or using clipper. (#9005) in various locations, e.g. GetContentRegionAvail() calls or using clipper. (#9005)
EndTable() was mistakenly restoring a wrong current table. EndTable() was mistakenly restoring a wrong current table.
- InputText: when buffer is not resizable, trying to paste contents that
cannot fit will now truncate text instead of ignoring the paste. (#9029)
- InputText: avoid continuously overwriting ownership of ImGuiKey_Enter/_KeypadEnter - InputText: avoid continuously overwriting ownership of ImGuiKey_Enter/_KeypadEnter
keys in order to allow e.g. external Shortcut override behavior. (#9004) keys in order to allow e.g. external Shortcut override behavior. (#9004)
- InputText: when using a callback to reduce/manipulate the value of BufTextLen, - InputText: when using a callback to reduce/manipulate the value of BufTextLen,

View File

@@ -4148,15 +4148,17 @@ static int STB_TEXTEDIT_INSERTCHARS(ImGuiInputTextState* obj, int pos, const cha
const int text_len = obj->TextLen; const int text_len = obj->TextLen;
IM_ASSERT(pos <= text_len); IM_ASSERT(pos <= text_len);
if (!is_resizable && (new_text_len + obj->TextLen + 1 > obj->BufCapacity)) // We support partial insertion (with a mod in stb_textedit.h)
const int avail = obj->BufCapacity - 1 - obj->TextLen;
if (!is_resizable && new_text_len > avail)
new_text_len = avail; // 0
if (new_text_len == 0)
return 0; return 0;
// Grow internal buffer if needed // Grow internal buffer if needed
IM_ASSERT(obj->TextSrc == obj->TextA.Data); IM_ASSERT(obj->TextSrc == obj->TextA.Data);
if (new_text_len + text_len + 1 > obj->TextA.Size) if (text_len + new_text_len + 1 > obj->TextA.Size && is_resizable)
{ {
if (!is_resizable)
return 0;
obj->TextA.resize(text_len + ImClamp(new_text_len, 32, ImMax(256, new_text_len)) + 1); obj->TextA.resize(text_len + ImClamp(new_text_len, 32, ImMax(256, new_text_len)) + 1);
obj->TextSrc = obj->TextA.Data; obj->TextSrc = obj->TextA.Data;
} }
@@ -4205,7 +4207,8 @@ static void stb_textedit_replace(ImGuiInputTextState* str, STB_TexteditState* st
state->cursor = state->select_start = state->select_end = 0; state->cursor = state->select_start = state->select_end = 0;
if (text_len <= 0) if (text_len <= 0)
return; return;
if (ImStb::STB_TEXTEDIT_INSERTCHARS(str, 0, text, text_len)) int text_len_inserted = ImStb::STB_TEXTEDIT_INSERTCHARS(str, 0, text, text_len);
if (text_len_inserted > 0)
{ {
state->cursor = state->select_start = state->select_end = text_len; state->cursor = state->select_start = state->select_end = text_len;
state->has_preferred_x = 0; state->has_preferred_x = 0;
@@ -4300,15 +4303,20 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons
ImGuiContext& g = *Ctx; ImGuiContext& g = *Ctx;
ImGuiInputTextState* obj = &g.InputTextState; ImGuiInputTextState* obj = &g.InputTextState;
IM_ASSERT(obj->ID != 0 && g.ActiveId == obj->ID); IM_ASSERT(obj->ID != 0 && g.ActiveId == obj->ID);
const bool is_resizable = (Flags & ImGuiInputTextFlags_CallbackResize) != 0;
const bool is_readonly = (Flags & ImGuiInputTextFlags_ReadOnly) != 0;
int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)ImStrlen(new_text);
// We support partial insertion (with a mod in stb_textedit.h)
const int avail = BufSize - 1 - BufTextLen;
if (!is_resizable && new_text_len > avail)
new_text_len = avail; // 0
if (new_text_len == 0)
return;
// Grow internal buffer if needed // Grow internal buffer if needed
const bool is_resizable = (Flags & ImGuiInputTextFlags_CallbackResize) != 0; if (new_text_len + BufTextLen + 1 > obj->TextA.Size && is_resizable && !is_readonly)
const int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)ImStrlen(new_text);
if (new_text_len + BufTextLen + 1 > obj->TextA.Size && (Flags & ImGuiInputTextFlags_ReadOnly) == 0)
{ {
if (!is_resizable)
return;
IM_ASSERT(Buf == obj->TextA.Data); IM_ASSERT(Buf == obj->TextA.Data);
int new_buf_size = BufTextLen + ImClamp(new_text_len * 4, 32, ImMax(256, new_text_len)) + 1; int new_buf_size = BufTextLen + ImClamp(new_text_len * 4, 32, ImMax(256, new_text_len)) + 1;
obj->TextA.resize(new_buf_size + 1); obj->TextA.resize(new_buf_size + 1);