mirror of
https://github.com/Drezil/imgui.git
synced 2025-07-04 03:58:47 +02:00
Internals: InputText: Renaming. Comments.
This commit is contained in:
72
imgui.cpp
72
imgui.cpp
@ -4147,9 +4147,9 @@ void ImGui::Shutdown(ImGuiContext* context)
|
||||
g.DrawDataBuilder.ClearFreeMemory();
|
||||
g.OverlayDrawList.ClearFreeMemory();
|
||||
g.PrivateClipboard.clear();
|
||||
g.InputTextState.Text.clear();
|
||||
g.InputTextState.TextW.clear();
|
||||
g.InputTextState.InitialText.clear();
|
||||
g.InputTextState.TempTextBuffer.clear();
|
||||
g.InputTextState.TempBuffer.clear();
|
||||
|
||||
for (int i = 0; i < g.SettingsWindows.Size; i++)
|
||||
IM_DELETE(g.SettingsWindows[i].Name);
|
||||
@ -10490,13 +10490,13 @@ namespace ImGuiStb
|
||||
{
|
||||
|
||||
static int STB_TEXTEDIT_STRINGLEN(const STB_TEXTEDIT_STRING* obj) { return obj->CurLenW; }
|
||||
static ImWchar STB_TEXTEDIT_GETCHAR(const STB_TEXTEDIT_STRING* obj, int idx) { return obj->Text[idx]; }
|
||||
static float STB_TEXTEDIT_GETWIDTH(STB_TEXTEDIT_STRING* obj, int line_start_idx, int char_idx) { ImWchar c = obj->Text[line_start_idx+char_idx]; if (c == '\n') return STB_TEXTEDIT_GETWIDTH_NEWLINE; return GImGui->Font->GetCharAdvance(c) * (GImGui->FontSize / GImGui->Font->FontSize); }
|
||||
static ImWchar STB_TEXTEDIT_GETCHAR(const STB_TEXTEDIT_STRING* obj, int idx) { return obj->TextW[idx]; }
|
||||
static float STB_TEXTEDIT_GETWIDTH(STB_TEXTEDIT_STRING* obj, int line_start_idx, int char_idx) { ImWchar c = obj->TextW[line_start_idx+char_idx]; if (c == '\n') return STB_TEXTEDIT_GETWIDTH_NEWLINE; return GImGui->Font->GetCharAdvance(c) * (GImGui->FontSize / GImGui->Font->FontSize); }
|
||||
static int STB_TEXTEDIT_KEYTOTEXT(int key) { return key >= 0x10000 ? 0 : key; }
|
||||
static ImWchar STB_TEXTEDIT_NEWLINE = '\n';
|
||||
static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, STB_TEXTEDIT_STRING* obj, int line_start_idx)
|
||||
{
|
||||
const ImWchar* text = obj->Text.Data;
|
||||
const ImWchar* text = obj->TextW.Data;
|
||||
const ImWchar* text_remaining = NULL;
|
||||
const ImVec2 size = InputTextCalcTextSizeW(text + line_start_idx, text + obj->CurLenW, &text_remaining, NULL, true);
|
||||
r->x0 = 0.0f;
|
||||
@ -10508,10 +10508,10 @@ static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, STB_TEXTEDIT_STRING* ob
|
||||
}
|
||||
|
||||
static bool is_separator(unsigned int c) { return ImCharIsBlankW(c) || c==',' || c==';' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='|'; }
|
||||
static int is_word_boundary_from_right(STB_TEXTEDIT_STRING* obj, int idx) { return idx > 0 ? (is_separator( obj->Text[idx-1] ) && !is_separator( obj->Text[idx] ) ) : 1; }
|
||||
static int is_word_boundary_from_right(STB_TEXTEDIT_STRING* obj, int idx) { return idx > 0 ? (is_separator( obj->TextW[idx-1] ) && !is_separator( obj->TextW[idx] ) ) : 1; }
|
||||
static int STB_TEXTEDIT_MOVEWORDLEFT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) { idx--; while (idx >= 0 && !is_word_boundary_from_right(obj, idx)) idx--; return idx < 0 ? 0 : idx; }
|
||||
#ifdef __APPLE__ // FIXME: Move setting to IO structure
|
||||
static int is_word_boundary_from_left(STB_TEXTEDIT_STRING* obj, int idx) { return idx > 0 ? (!is_separator( obj->Text[idx-1] ) && is_separator( obj->Text[idx] ) ) : 1; }
|
||||
static int is_word_boundary_from_left(STB_TEXTEDIT_STRING* obj, int idx) { return idx > 0 ? (!is_separator( obj->TextW[idx-1] ) && is_separator( obj->TextW[idx] ) ) : 1; }
|
||||
static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_left(obj, idx)) idx++; return idx > len ? len : idx; }
|
||||
#else
|
||||
static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_right(obj, idx)) idx++; return idx > len ? len : idx; }
|
||||
@ -10521,14 +10521,14 @@ static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(STB_TEXTEDIT_STRING* obj, int idx)
|
||||
|
||||
static void STB_TEXTEDIT_DELETECHARS(STB_TEXTEDIT_STRING* obj, int pos, int n)
|
||||
{
|
||||
ImWchar* dst = obj->Text.Data + pos;
|
||||
ImWchar* dst = obj->TextW.Data + pos;
|
||||
|
||||
// We maintain our buffer length in both UTF-8 and wchar formats
|
||||
obj->CurLenA -= ImTextCountUtf8BytesFromStr(dst, dst + n);
|
||||
obj->CurLenW -= n;
|
||||
|
||||
// Offset remaining text
|
||||
const ImWchar* src = obj->Text.Data + pos + n;
|
||||
const ImWchar* src = obj->TextW.Data + pos + n;
|
||||
while (ImWchar c = *src++)
|
||||
*dst++ = c;
|
||||
*dst = '\0';
|
||||
@ -10545,22 +10545,22 @@ static bool STB_TEXTEDIT_INSERTCHARS(STB_TEXTEDIT_STRING* obj, int pos, const Im
|
||||
return false;
|
||||
|
||||
// Grow internal buffer if needed
|
||||
if (new_text_len + text_len + 1 > obj->Text.Size)
|
||||
if (new_text_len + text_len + 1 > obj->TextW.Size)
|
||||
{
|
||||
if (!is_resizable)
|
||||
return false;
|
||||
IM_ASSERT(text_len < obj->Text.Size);
|
||||
obj->Text.resize(text_len + ImClamp(new_text_len * 4, 32, ImMax(256, new_text_len)) + 1);
|
||||
IM_ASSERT(text_len < obj->TextW.Size);
|
||||
obj->TextW.resize(text_len + ImClamp(new_text_len * 4, 32, ImMax(256, new_text_len)) + 1);
|
||||
}
|
||||
|
||||
ImWchar* text = obj->Text.Data;
|
||||
ImWchar* text = obj->TextW.Data;
|
||||
if (pos != text_len)
|
||||
memmove(text + pos + new_text_len, text + pos, (size_t)(text_len - pos) * sizeof(ImWchar));
|
||||
memcpy(text + pos, new_text, (size_t)new_text_len * sizeof(ImWchar));
|
||||
|
||||
obj->CurLenW += new_text_len;
|
||||
obj->CurLenA += new_text_len_utf8;
|
||||
obj->Text[obj->CurLenW] = '\0';
|
||||
obj->TextW[obj->CurLenW] = '\0';
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -10697,7 +10697,10 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f
|
||||
}
|
||||
|
||||
// Edit a string of text
|
||||
// NB: when active, hold on a privately held copy of the text (and apply back to 'buf'). So changing 'buf' while active has no effect.
|
||||
// - buf_size account for the zero-terminator, so a buf_size of 6 can hold "Hello" but not "Hello!".
|
||||
// This is so we can easily call InputText() on static arrays using ARRAYSIZE() and to match
|
||||
// Note that in std::string world, capacity() would omit 1 byte used by the zero-terminator.
|
||||
// - When active, hold on a privately held copy of the text (and apply back to 'buf'). So changing 'buf' while the InputText is active has no effect.
|
||||
// FIXME: Rather messy function partly because we are doing UTF8 > u16 > UTF8 conversions on the go to more easily handle stb_textedit calls. Ideally we should stay in UTF-8 all the time. See https://github.com/nothings/stb/issues/188
|
||||
bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* callback_user_data)
|
||||
{
|
||||
@ -10705,7 +10708,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
IM_ASSERT(!((flags & ImGuiInputTextFlags_CallbackHistory) && (flags & ImGuiInputTextFlags_Multiline))); // Can't use both together (they both use up/down keys)
|
||||
IM_ASSERT(!((flags & ImGuiInputTextFlags_CallbackHistory) && (flags & ImGuiInputTextFlags_Multiline))); // Can't use both together (they both use up/down keys)
|
||||
IM_ASSERT(!((flags & ImGuiInputTextFlags_CallbackCompletion) && (flags & ImGuiInputTextFlags_AllowTabInput))); // Can't use both together (they both use tab key)
|
||||
if (flags & ImGuiInputTextFlags_CallbackResize)
|
||||
IM_ASSERT(callback != NULL);
|
||||
@ -10790,11 +10793,11 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
// Take a copy of the initial buffer value (both in original UTF-8 format and converted to wchar)
|
||||
// From the moment we focused we are ignoring the content of 'buf' (unless we are in read-only mode)
|
||||
const int prev_len_w = edit_state.CurLenW;
|
||||
edit_state.Text.resize(buf_size+1); // wchar count <= UTF-8 count. we use +1 to make sure that .Data isn't NULL so it doesn't crash.
|
||||
edit_state.TextW.resize(buf_size+1); // wchar count <= UTF-8 count. we use +1 to make sure that .Data isn't NULL so it doesn't crash.
|
||||
edit_state.InitialText.resize(buf_size+1); // UTF-8. we use +1 to make sure that .Data isn't NULL so it doesn't crash.
|
||||
ImStrncpy(edit_state.InitialText.Data, buf, buf_size);
|
||||
const char* buf_end = NULL;
|
||||
edit_state.CurLenW = ImTextStrFromUtf8(edit_state.Text.Data, buf_size, buf, NULL, &buf_end);
|
||||
edit_state.CurLenW = ImTextStrFromUtf8(edit_state.TextW.Data, buf_size, buf, NULL, &buf_end);
|
||||
edit_state.CurLenA = (int)(buf_end - buf); // We can't get the result from ImStrncpy() above because it is not UTF-8 aware. Here we'll cut off malformed UTF-8.
|
||||
edit_state.CursorAnimReset();
|
||||
|
||||
@ -10841,9 +10844,9 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
if (!is_editable && !g.ActiveIdIsJustActivated)
|
||||
{
|
||||
// When read-only we always use the live data passed to the function
|
||||
edit_state.Text.resize(buf_size+1);
|
||||
edit_state.TextW.resize(buf_size+1);
|
||||
const char* buf_end = NULL;
|
||||
edit_state.CurLenW = ImTextStrFromUtf8(edit_state.Text.Data, edit_state.Text.Size, buf, NULL, &buf_end);
|
||||
edit_state.CurLenW = ImTextStrFromUtf8(edit_state.TextW.Data, edit_state.TextW.Size, buf, NULL, &buf_end);
|
||||
edit_state.CurLenA = (int)(buf_end - buf);
|
||||
edit_state.CursorClamp();
|
||||
}
|
||||
@ -10987,9 +10990,9 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
{
|
||||
const int ib = edit_state.HasSelection() ? ImMin(edit_state.StbState.select_start, edit_state.StbState.select_end) : 0;
|
||||
const int ie = edit_state.HasSelection() ? ImMax(edit_state.StbState.select_start, edit_state.StbState.select_end) : edit_state.CurLenW;
|
||||
edit_state.TempTextBuffer.resize((ie-ib) * 4 + 1);
|
||||
ImTextStrToUtf8(edit_state.TempTextBuffer.Data, edit_state.TempTextBuffer.Size, edit_state.Text.Data+ib, edit_state.Text.Data+ie);
|
||||
SetClipboardText(edit_state.TempTextBuffer.Data);
|
||||
edit_state.TempBuffer.resize((ie-ib) * 4 + 1);
|
||||
ImTextStrToUtf8(edit_state.TempBuffer.Data, edit_state.TempBuffer.Size, edit_state.TextW.Data+ib, edit_state.TextW.Data+ie);
|
||||
SetClipboardText(edit_state.TempBuffer.Data);
|
||||
}
|
||||
if (is_cut)
|
||||
{
|
||||
@ -11053,8 +11056,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
// FIXME-OPT: CPU waste to do this every time the widget is active, should mark dirty state from the stb_textedit callbacks.
|
||||
if (is_editable)
|
||||
{
|
||||
edit_state.TempTextBuffer.resize(edit_state.Text.Size * 4);
|
||||
ImTextStrToUtf8(edit_state.TempTextBuffer.Data, edit_state.TempTextBuffer.Size, edit_state.Text.Data, NULL);
|
||||
edit_state.TempBuffer.resize(edit_state.TextW.Size * 4);
|
||||
ImTextStrToUtf8(edit_state.TempBuffer.Data, edit_state.TempBuffer.Size, edit_state.TextW.Data, NULL);
|
||||
}
|
||||
|
||||
// User callback
|
||||
@ -11092,13 +11095,13 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
callback_data.UserData = callback_user_data;
|
||||
|
||||
callback_data.EventKey = event_key;
|
||||
callback_data.Buf = edit_state.TempTextBuffer.Data;
|
||||
callback_data.Buf = edit_state.TempBuffer.Data;
|
||||
callback_data.BufTextLen = edit_state.CurLenA;
|
||||
callback_data.BufSize = edit_state.BufCapacityA;
|
||||
callback_data.BufDirty = false;
|
||||
|
||||
// We have to convert from wchar-positions to UTF-8-positions, which can be pretty slow (an incentive to ditch the ImWchar buffer, see https://github.com/nothings/stb/issues/188)
|
||||
ImWchar* text = edit_state.Text.Data;
|
||||
ImWchar* text = edit_state.TextW.Data;
|
||||
const int utf8_cursor_pos = callback_data.CursorPos = ImTextCountUtf8BytesFromStr(text, text + edit_state.StbState.cursor);
|
||||
const int utf8_selection_start = callback_data.SelectionStart = ImTextCountUtf8BytesFromStr(text, text + edit_state.StbState.select_start);
|
||||
const int utf8_selection_end = callback_data.SelectionEnd = ImTextCountUtf8BytesFromStr(text, text + edit_state.StbState.select_end);
|
||||
@ -11107,7 +11110,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
callback(&callback_data);
|
||||
|
||||
// Read back what user may have modified
|
||||
IM_ASSERT(callback_data.Buf == edit_state.TempTextBuffer.Data); // Invalid to modify those fields
|
||||
IM_ASSERT(callback_data.Buf == edit_state.TempBuffer.Data); // Invalid to modify those fields
|
||||
IM_ASSERT(callback_data.BufSize == edit_state.BufCapacityA);
|
||||
IM_ASSERT(callback_data.Flags == flags);
|
||||
if (callback_data.CursorPos != utf8_cursor_pos) edit_state.StbState.cursor = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.CursorPos);
|
||||
@ -11116,7 +11119,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
if (callback_data.BufDirty)
|
||||
{
|
||||
IM_ASSERT(callback_data.BufTextLen == (int)strlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text!
|
||||
edit_state.CurLenW = ImTextStrFromUtf8(edit_state.Text.Data, edit_state.Text.Size, callback_data.Buf, NULL);
|
||||
edit_state.CurLenW = ImTextStrFromUtf8(edit_state.TextW.Data, edit_state.TextW.Size, callback_data.Buf, NULL);
|
||||
edit_state.CurLenA = callback_data.BufTextLen; // Assume correct length and valid UTF-8 from user, saves us an extra strlen()
|
||||
edit_state.CursorAnimReset();
|
||||
}
|
||||
@ -11124,9 +11127,9 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
}
|
||||
|
||||
// Will copy result string if modified
|
||||
if (is_editable && strcmp(edit_state.TempTextBuffer.Data, buf) != 0)
|
||||
if (is_editable && strcmp(edit_state.TempBuffer.Data, buf) != 0)
|
||||
{
|
||||
apply_new_text = edit_state.TempTextBuffer.Data;
|
||||
apply_new_text = edit_state.TempBuffer.Data;
|
||||
apply_new_text_length = edit_state.CurLenA;
|
||||
}
|
||||
}
|
||||
@ -11149,7 +11152,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
buf_size = callback_data.BufSize;
|
||||
}
|
||||
IM_ASSERT(apply_new_text_length <= buf_size);
|
||||
ImStrncpy(buf, edit_state.TempTextBuffer.Data, apply_new_text_length + 1);
|
||||
ImStrncpy(buf, edit_state.TempBuffer.Data, apply_new_text_length + 1);
|
||||
value_changed = true;
|
||||
}
|
||||
|
||||
@ -11165,7 +11168,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
|
||||
// Render
|
||||
// Select which buffer we are going to display. When ImGuiInputTextFlags_NoLiveEdit is set 'buf' might still be the old value. We set buf to NULL to prevent accidental usage from now on.
|
||||
const char* buf_display = (g.ActiveId == id && is_editable) ? edit_state.TempTextBuffer.Data : buf; buf = NULL;
|
||||
const char* buf_display = (g.ActiveId == id && is_editable) ? edit_state.TempBuffer.Data : buf; buf = NULL;
|
||||
|
||||
if (!is_multiline)
|
||||
{
|
||||
@ -11187,7 +11190,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
// - Measure text height (for scrollbar)
|
||||
// We are attempting to do most of that in **one main pass** to minimize the computation cost (non-negligible for large amount of text) + 2nd pass for selection rendering (we could merge them by an extra refactoring effort)
|
||||
// FIXME: This should occur on buf_display but we'd need to maintain cursor/select_start/select_end for UTF-8.
|
||||
const ImWchar* text_begin = edit_state.Text.Data;
|
||||
const ImWchar* text_begin = edit_state.TextW.Data;
|
||||
ImVec2 cursor_offset, select_start_offset;
|
||||
|
||||
{
|
||||
@ -11300,6 +11303,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME-OPT: We should coarse clip very large text on this end (even though the low-level ImFont::RenderText perform line-based will do it, it will lead us to temporary vertex allocations)
|
||||
draw_window->DrawList->AddText(g.Font, g.FontSize, render_pos - render_scroll, GetColorU32(ImGuiCol_Text), buf_display, buf_display + edit_state.CurLenA, 0.0f, is_multiline ? NULL : &clip_rect);
|
||||
|
||||
// Draw blinking cursor
|
||||
|
Reference in New Issue
Block a user