InputText: Internals: rename CurLenA->TextLen, InitialTextA->TextToRevertTo.
Follow the refactors in #7925.
This commit is contained in:
parent
be2d006e2e
commit
63234f8dd0
@ -1109,11 +1109,11 @@ struct IMGUI_API ImGuiInputTextState
|
|||||||
ImGuiContext* Ctx; // parent UI context (needs to be set explicitly by parent).
|
ImGuiContext* Ctx; // parent UI context (needs to be set explicitly by parent).
|
||||||
ImStbTexteditState* Stb; // State for stb_textedit.h
|
ImStbTexteditState* Stb; // State for stb_textedit.h
|
||||||
ImGuiID ID; // widget id owning the text state
|
ImGuiID ID; // widget id owning the text state
|
||||||
int CurLenA; // UTF-8 length of the string in TextA (in bytes)
|
int TextLen; // UTF-8 length of the string in TextA (in bytes)
|
||||||
ImVector<char> TextA; // main UTF8 buffer. TextA.Size is a buffer size! Should always be >= buf_size passed by user (and of course >= CurLenA + 1).
|
ImVector<char> TextA; // main UTF8 buffer. TextA.Size is a buffer size! Should always be >= buf_size passed by user (and of course >= CurLenA + 1).
|
||||||
ImVector<char> InitialTextA; // value to revert to when pressing Escape = backup of end-user buffer at the time of focus (in UTF-8, unaltered)
|
ImVector<char> TextToRevertTo; // value to revert to when pressing Escape = backup of end-user buffer at the time of focus (in UTF-8, unaltered)
|
||||||
ImVector<char> CallbackTextBackup; // temporary storage for callback to support automatic reconcile of undo-stack
|
ImVector<char> CallbackTextBackup; // temporary storage for callback to support automatic reconcile of undo-stack
|
||||||
int BufCapacityA; // end-user buffer capacity
|
int BufCapacity; // end-user buffer capacity (include zero terminator)
|
||||||
ImVec2 Scroll; // horizontal offset (managed manually) + vertical scrolling (pulled from child window's own Scroll.y)
|
ImVec2 Scroll; // horizontal offset (managed manually) + vertical scrolling (pulled from child window's own Scroll.y)
|
||||||
float CursorAnim; // timer for cursor blink, reset on every user action so the cursor reappears immediately
|
float CursorAnim; // timer for cursor blink, reset on every user action so the cursor reappears immediately
|
||||||
bool CursorFollow; // set when we want scrolling to follow the current cursor position (not always!)
|
bool CursorFollow; // set when we want scrolling to follow the current cursor position (not always!)
|
||||||
@ -1126,8 +1126,8 @@ struct IMGUI_API ImGuiInputTextState
|
|||||||
|
|
||||||
ImGuiInputTextState();
|
ImGuiInputTextState();
|
||||||
~ImGuiInputTextState();
|
~ImGuiInputTextState();
|
||||||
void ClearText() { CurLenA = 0; TextA[0] = 0; CursorClamp(); }
|
void ClearText() { TextLen = 0; TextA[0] = 0; CursorClamp(); }
|
||||||
void ClearFreeMemory() { TextA.clear(); InitialTextA.clear(); }
|
void ClearFreeMemory() { TextA.clear(); TextToRevertTo.clear(); }
|
||||||
void OnKeyPressed(int key); // Cannot be inline because we call in code in stb_textedit.h implementation
|
void OnKeyPressed(int key); // Cannot be inline because we call in code in stb_textedit.h implementation
|
||||||
void OnCharPressed(unsigned int c);
|
void OnCharPressed(unsigned int c);
|
||||||
|
|
||||||
|
@ -3928,15 +3928,15 @@ static ImVec2 InputTextCalcTextSize(ImGuiContext* ctx, const char* text_begin, c
|
|||||||
// - ...but we don't use that feature.
|
// - ...but we don't use that feature.
|
||||||
namespace ImStb
|
namespace ImStb
|
||||||
{
|
{
|
||||||
static int STB_TEXTEDIT_STRINGLEN(const ImGuiInputTextState* obj) { return obj->CurLenA; }
|
static int STB_TEXTEDIT_STRINGLEN(const ImGuiInputTextState* obj) { return obj->TextLen; }
|
||||||
static char STB_TEXTEDIT_GETCHAR(const ImGuiInputTextState* obj, int idx) { IM_ASSERT(idx <= obj->CurLenA); return obj->TextA[idx]; }
|
static char STB_TEXTEDIT_GETCHAR(const ImGuiInputTextState* obj, int idx) { IM_ASSERT(idx <= obj->TextLen); return obj->TextA[idx]; }
|
||||||
static float STB_TEXTEDIT_GETWIDTH(ImGuiInputTextState* obj, int line_start_idx, int char_idx) { unsigned int c; ImTextCharFromUtf8(&c, obj->TextA.Data + line_start_idx + char_idx, obj->TextA.Data + obj->CurLenA); if ((ImWchar)c == '\n') return IMSTB_TEXTEDIT_GETWIDTH_NEWLINE; ImGuiContext& g = *obj->Ctx; return g.Font->GetCharAdvance((ImWchar)c) * g.FontScale; }
|
static float STB_TEXTEDIT_GETWIDTH(ImGuiInputTextState* obj, int line_start_idx, int char_idx) { unsigned int c; ImTextCharFromUtf8(&c, obj->TextA.Data + line_start_idx + char_idx, obj->TextA.Data + obj->TextLen); if ((ImWchar)c == '\n') return IMSTB_TEXTEDIT_GETWIDTH_NEWLINE; ImGuiContext& g = *obj->Ctx; return g.Font->GetCharAdvance((ImWchar)c) * g.FontScale; }
|
||||||
static char STB_TEXTEDIT_NEWLINE = '\n';
|
static char STB_TEXTEDIT_NEWLINE = '\n';
|
||||||
static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, ImGuiInputTextState* obj, int line_start_idx)
|
static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, ImGuiInputTextState* obj, int line_start_idx)
|
||||||
{
|
{
|
||||||
const char* text = obj->TextA.Data;
|
const char* text = obj->TextA.Data;
|
||||||
const char* text_remaining = NULL;
|
const char* text_remaining = NULL;
|
||||||
const ImVec2 size = InputTextCalcTextSize(obj->Ctx, text + line_start_idx, text + obj->CurLenA, &text_remaining, NULL, true);
|
const ImVec2 size = InputTextCalcTextSize(obj->Ctx, text + line_start_idx, text + obj->TextLen, &text_remaining, NULL, true);
|
||||||
r->x0 = 0.0f;
|
r->x0 = 0.0f;
|
||||||
r->x1 = size.x;
|
r->x1 = size.x;
|
||||||
r->baseline_y_delta = size.y;
|
r->baseline_y_delta = size.y;
|
||||||
@ -3950,10 +3950,10 @@ static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, ImGuiInputTextState* ob
|
|||||||
|
|
||||||
static int IMSTB_TEXTEDIT_GETNEXTCHARINDEX_IMPL(ImGuiInputTextState* obj, int idx)
|
static int IMSTB_TEXTEDIT_GETNEXTCHARINDEX_IMPL(ImGuiInputTextState* obj, int idx)
|
||||||
{
|
{
|
||||||
if (idx >= obj->CurLenA)
|
if (idx >= obj->TextLen)
|
||||||
return obj->CurLenA + 1;
|
return obj->TextLen + 1;
|
||||||
unsigned int c;
|
unsigned int c;
|
||||||
return idx + ImTextCharFromUtf8(&c, obj->TextA.Data + idx, obj->TextA.Data + obj->CurLenA);
|
return idx + ImTextCharFromUtf8(&c, obj->TextA.Data + idx, obj->TextA.Data + obj->TextLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int IMSTB_TEXTEDIT_GETPREVCHARINDEX_IMPL(ImGuiInputTextState* obj, int idx)
|
static int IMSTB_TEXTEDIT_GETPREVCHARINDEX_IMPL(ImGuiInputTextState* obj, int idx)
|
||||||
@ -3986,8 +3986,8 @@ static int is_word_boundary_from_right(ImGuiInputTextState* obj, int idx)
|
|||||||
|
|
||||||
const char* curr_p = obj->TextA.Data + idx;
|
const char* curr_p = obj->TextA.Data + idx;
|
||||||
const char* prev_p = ImTextFindPreviousUtf8Codepoint(obj->TextA.Data, curr_p);
|
const char* prev_p = ImTextFindPreviousUtf8Codepoint(obj->TextA.Data, curr_p);
|
||||||
unsigned int curr_c; ImTextCharFromUtf8(&curr_c, curr_p, obj->TextA.Data + obj->CurLenA);
|
unsigned int curr_c; ImTextCharFromUtf8(&curr_c, curr_p, obj->TextA.Data + obj->TextLen);
|
||||||
unsigned int prev_c; ImTextCharFromUtf8(&prev_c, prev_p, obj->TextA.Data + obj->CurLenA);
|
unsigned int prev_c; ImTextCharFromUtf8(&prev_c, prev_p, obj->TextA.Data + obj->TextLen);
|
||||||
|
|
||||||
bool prev_white = ImCharIsBlankW(prev_c);
|
bool prev_white = ImCharIsBlankW(prev_c);
|
||||||
bool prev_separ = ImCharIsSeparatorW(prev_c);
|
bool prev_separ = ImCharIsSeparatorW(prev_c);
|
||||||
@ -4002,8 +4002,8 @@ static int is_word_boundary_from_left(ImGuiInputTextState* obj, int idx)
|
|||||||
|
|
||||||
const char* curr_p = obj->TextA.Data + idx;
|
const char* curr_p = obj->TextA.Data + idx;
|
||||||
const char* prev_p = ImTextFindPreviousUtf8Codepoint(obj->TextA.Data, curr_p);
|
const char* prev_p = ImTextFindPreviousUtf8Codepoint(obj->TextA.Data, curr_p);
|
||||||
unsigned int prev_c; ImTextCharFromUtf8(&prev_c, curr_p, obj->TextA.Data + obj->CurLenA);
|
unsigned int prev_c; ImTextCharFromUtf8(&prev_c, curr_p, obj->TextA.Data + obj->TextLen);
|
||||||
unsigned int curr_c; ImTextCharFromUtf8(&curr_c, prev_p, obj->TextA.Data + obj->CurLenA);
|
unsigned int curr_c; ImTextCharFromUtf8(&curr_c, prev_p, obj->TextA.Data + obj->TextLen);
|
||||||
|
|
||||||
bool prev_white = ImCharIsBlankW(prev_c);
|
bool prev_white = ImCharIsBlankW(prev_c);
|
||||||
bool prev_separ = ImCharIsSeparatorW(prev_c);
|
bool prev_separ = ImCharIsSeparatorW(prev_c);
|
||||||
@ -4020,7 +4020,7 @@ static int STB_TEXTEDIT_MOVEWORDLEFT_IMPL(ImGuiInputTextState* obj, int idx)
|
|||||||
}
|
}
|
||||||
static int STB_TEXTEDIT_MOVEWORDRIGHT_MAC(ImGuiInputTextState* obj, int idx)
|
static int STB_TEXTEDIT_MOVEWORDRIGHT_MAC(ImGuiInputTextState* obj, int idx)
|
||||||
{
|
{
|
||||||
int len = obj->CurLenA;
|
int len = obj->TextLen;
|
||||||
idx = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(obj, idx);
|
idx = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(obj, idx);
|
||||||
while (idx < len && !is_word_boundary_from_left(obj, idx))
|
while (idx < len && !is_word_boundary_from_left(obj, idx))
|
||||||
idx = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(obj, idx);
|
idx = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(obj, idx);
|
||||||
@ -4029,7 +4029,7 @@ static int STB_TEXTEDIT_MOVEWORDRIGHT_MAC(ImGuiInputTextState* obj, int idx)
|
|||||||
static int STB_TEXTEDIT_MOVEWORDRIGHT_WIN(ImGuiInputTextState* obj, int idx)
|
static int STB_TEXTEDIT_MOVEWORDRIGHT_WIN(ImGuiInputTextState* obj, int idx)
|
||||||
{
|
{
|
||||||
idx = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(obj, idx);
|
idx = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(obj, idx);
|
||||||
int len = obj->CurLenA;
|
int len = obj->TextLen;
|
||||||
while (idx < len && !is_word_boundary_from_right(obj, idx))
|
while (idx < len && !is_word_boundary_from_right(obj, idx))
|
||||||
idx = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(obj, idx);
|
idx = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(obj, idx);
|
||||||
return idx > len ? len : idx;
|
return idx > len ? len : idx;
|
||||||
@ -4043,7 +4043,7 @@ static void STB_TEXTEDIT_DELETECHARS(ImGuiInputTextState* obj, int pos, int n)
|
|||||||
char* dst = obj->TextA.Data + pos;
|
char* dst = obj->TextA.Data + pos;
|
||||||
|
|
||||||
obj->Edited = true;
|
obj->Edited = true;
|
||||||
obj->CurLenA -= n;
|
obj->TextLen -= n;
|
||||||
|
|
||||||
// Offset remaining text (FIXME-OPT: Use memmove)
|
// Offset remaining text (FIXME-OPT: Use memmove)
|
||||||
const char* src = obj->TextA.Data + pos + n;
|
const char* src = obj->TextA.Data + pos + n;
|
||||||
@ -4055,10 +4055,10 @@ static void STB_TEXTEDIT_DELETECHARS(ImGuiInputTextState* obj, int pos, int n)
|
|||||||
static bool STB_TEXTEDIT_INSERTCHARS(ImGuiInputTextState* obj, int pos, const char* new_text, int new_text_len)
|
static bool STB_TEXTEDIT_INSERTCHARS(ImGuiInputTextState* obj, int pos, const char* new_text, int new_text_len)
|
||||||
{
|
{
|
||||||
const bool is_resizable = (obj->Flags & ImGuiInputTextFlags_CallbackResize) != 0;
|
const bool is_resizable = (obj->Flags & ImGuiInputTextFlags_CallbackResize) != 0;
|
||||||
const int text_len = obj->CurLenA;
|
const int text_len = obj->TextLen;
|
||||||
IM_ASSERT(pos <= text_len);
|
IM_ASSERT(pos <= text_len);
|
||||||
|
|
||||||
if (!is_resizable && (new_text_len + obj->CurLenA + 1 > obj->BufCapacityA))
|
if (!is_resizable && (new_text_len + obj->TextLen + 1 > obj->BufCapacity))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Grow internal buffer if needed
|
// Grow internal buffer if needed
|
||||||
@ -4075,8 +4075,8 @@ static bool STB_TEXTEDIT_INSERTCHARS(ImGuiInputTextState* obj, int pos, const ch
|
|||||||
memcpy(text + pos, new_text, (size_t)new_text_len);
|
memcpy(text + pos, new_text, (size_t)new_text_len);
|
||||||
|
|
||||||
obj->Edited = true;
|
obj->Edited = true;
|
||||||
obj->CurLenA += new_text_len;
|
obj->TextLen += new_text_len;
|
||||||
obj->TextA[obj->CurLenA] = '\0';
|
obj->TextA[obj->TextLen] = '\0';
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -4108,8 +4108,8 @@ static bool STB_TEXTEDIT_INSERTCHARS(ImGuiInputTextState* obj, int pos, const ch
|
|||||||
// the stb_textedit_paste() function creates two separate records, so we perform it manually. (FIXME: Report to nothings/stb?)
|
// the stb_textedit_paste() function creates two separate records, so we perform it manually. (FIXME: Report to nothings/stb?)
|
||||||
static void stb_textedit_replace(ImGuiInputTextState* str, STB_TexteditState* state, const IMSTB_TEXTEDIT_CHARTYPE* text, int text_len)
|
static void stb_textedit_replace(ImGuiInputTextState* str, STB_TexteditState* state, const IMSTB_TEXTEDIT_CHARTYPE* text, int text_len)
|
||||||
{
|
{
|
||||||
stb_text_makeundo_replace(str, state, 0, str->CurLenA, text_len);
|
stb_text_makeundo_replace(str, state, 0, str->TextLen, text_len);
|
||||||
ImStb::STB_TEXTEDIT_DELETECHARS(str, 0, str->CurLenA);
|
ImStb::STB_TEXTEDIT_DELETECHARS(str, 0, str->TextLen);
|
||||||
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;
|
||||||
@ -4157,13 +4157,13 @@ void ImGuiInputTextState::OnCharPressed(unsigned int c)
|
|||||||
|
|
||||||
// Those functions are not inlined in imgui_internal.h, allowing us to hide ImStbTexteditState from that header.
|
// Those functions are not inlined in imgui_internal.h, allowing us to hide ImStbTexteditState from that header.
|
||||||
void ImGuiInputTextState::CursorAnimReset() { CursorAnim = -0.30f; } // After a user-input the cursor stays on for a while without blinking
|
void ImGuiInputTextState::CursorAnimReset() { CursorAnim = -0.30f; } // After a user-input the cursor stays on for a while without blinking
|
||||||
void ImGuiInputTextState::CursorClamp() { Stb->cursor = ImMin(Stb->cursor, CurLenA); Stb->select_start = ImMin(Stb->select_start, CurLenA); Stb->select_end = ImMin(Stb->select_end, CurLenA); }
|
void ImGuiInputTextState::CursorClamp() { Stb->cursor = ImMin(Stb->cursor, TextLen); Stb->select_start = ImMin(Stb->select_start, TextLen); Stb->select_end = ImMin(Stb->select_end, TextLen); }
|
||||||
bool ImGuiInputTextState::HasSelection() const { return Stb->select_start != Stb->select_end; }
|
bool ImGuiInputTextState::HasSelection() const { return Stb->select_start != Stb->select_end; }
|
||||||
void ImGuiInputTextState::ClearSelection() { Stb->select_start = Stb->select_end = Stb->cursor; }
|
void ImGuiInputTextState::ClearSelection() { Stb->select_start = Stb->select_end = Stb->cursor; }
|
||||||
int ImGuiInputTextState::GetCursorPos() const { return Stb->cursor; }
|
int ImGuiInputTextState::GetCursorPos() const { return Stb->cursor; }
|
||||||
int ImGuiInputTextState::GetSelectionStart() const { return Stb->select_start; }
|
int ImGuiInputTextState::GetSelectionStart() const { return Stb->select_start; }
|
||||||
int ImGuiInputTextState::GetSelectionEnd() const { return Stb->select_end; }
|
int ImGuiInputTextState::GetSelectionEnd() const { return Stb->select_end; }
|
||||||
void ImGuiInputTextState::SelectAll() { Stb->select_start = 0; Stb->cursor = Stb->select_end = CurLenA; Stb->has_preferred_x = 0; }
|
void ImGuiInputTextState::SelectAll() { Stb->select_start = 0; Stb->cursor = Stb->select_end = TextLen; Stb->has_preferred_x = 0; }
|
||||||
void ImGuiInputTextState::ReloadUserBufAndSelectAll() { ReloadUserBuf = true; ReloadSelectionStart = 0; ReloadSelectionEnd = INT_MAX; }
|
void ImGuiInputTextState::ReloadUserBufAndSelectAll() { ReloadUserBuf = true; ReloadSelectionStart = 0; ReloadSelectionEnd = INT_MAX; }
|
||||||
void ImGuiInputTextState::ReloadUserBufAndKeepSelection() { ReloadUserBuf = true; ReloadSelectionStart = Stb->select_start; ReloadSelectionEnd = Stb->select_end; }
|
void ImGuiInputTextState::ReloadUserBufAndKeepSelection() { ReloadUserBuf = true; ReloadSelectionStart = Stb->select_start; ReloadSelectionEnd = Stb->select_end; }
|
||||||
void ImGuiInputTextState::ReloadUserBufAndMoveToEnd() { ReloadUserBuf = true; ReloadSelectionStart = ReloadSelectionEnd = INT_MAX; }
|
void ImGuiInputTextState::ReloadUserBufAndMoveToEnd() { ReloadUserBuf = true; ReloadSelectionStart = ReloadSelectionEnd = INT_MAX; }
|
||||||
@ -4216,7 +4216,7 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons
|
|||||||
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;
|
||||||
edit_state->TextA.resize(new_buf_size + 1);
|
edit_state->TextA.resize(new_buf_size + 1);
|
||||||
Buf = edit_state->TextA.Data;
|
Buf = edit_state->TextA.Data;
|
||||||
BufSize = edit_state->BufCapacityA = new_buf_size;
|
BufSize = edit_state->BufCapacity = new_buf_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BufTextLen != pos)
|
if (BufTextLen != pos)
|
||||||
@ -4380,8 +4380,8 @@ void ImGui::InputTextDeactivateHook(ImGuiID id)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
IM_ASSERT(state->TextA.Data != 0);
|
IM_ASSERT(state->TextA.Data != 0);
|
||||||
g.InputTextDeactivatedState.TextA.resize(state->CurLenA + 1);
|
g.InputTextDeactivatedState.TextA.resize(state->TextLen + 1);
|
||||||
memcpy(g.InputTextDeactivatedState.TextA.Data, state->TextA.Data, state->CurLenA + 1);
|
memcpy(g.InputTextDeactivatedState.TextA.Data, state->TextA.Data, state->TextLen + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4521,21 +4521,21 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
if (!init_reload_from_user_buf)
|
if (!init_reload_from_user_buf)
|
||||||
{
|
{
|
||||||
// Take a copy of the initial buffer value.
|
// Take a copy of the initial buffer value.
|
||||||
state->InitialTextA.resize(buf_len + 1); // UTF-8. we use +1 to make sure that .Data is always pointing to at least an empty string.
|
state->TextToRevertTo.resize(buf_len + 1); // UTF-8. we use +1 to make sure that .Data is always pointing to at least an empty string.
|
||||||
memcpy(state->InitialTextA.Data, buf, buf_len + 1);
|
memcpy(state->TextToRevertTo.Data, buf, buf_len + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preserve cursor position and undo/redo stack if we come back to same widget
|
// Preserve cursor position and undo/redo stack if we come back to same widget
|
||||||
// FIXME: Since we reworked this on 2022/06, may want to differentiate recycle_cursor vs recycle_undostate?
|
// FIXME: Since we reworked this on 2022/06, may want to differentiate recycle_cursor vs recycle_undostate?
|
||||||
bool recycle_state = (state->ID == id && !init_changed_specs && !init_reload_from_user_buf);
|
bool recycle_state = (state->ID == id && !init_changed_specs && !init_reload_from_user_buf);
|
||||||
if (recycle_state && (state->CurLenA != buf_len || (strncmp(state->TextA.Data, buf, buf_len) != 0)))
|
if (recycle_state && (state->TextLen != buf_len || (strncmp(state->TextA.Data, buf, buf_len) != 0)))
|
||||||
recycle_state = false;
|
recycle_state = false;
|
||||||
|
|
||||||
// Start edition
|
// Start edition
|
||||||
state->ID = id;
|
state->ID = id;
|
||||||
state->TextA.resize(buf_size + 1); // we use +1 to make sure that .Data is always pointing to at least an empty string.
|
state->TextA.resize(buf_size + 1); // we use +1 to make sure that .Data is always pointing to at least an empty string.
|
||||||
state->CurLenA = (int)strlen(buf);
|
state->TextLen = (int)strlen(buf);
|
||||||
memcpy(state->TextA.Data, buf, state->CurLenA + 1);
|
memcpy(state->TextA.Data, buf, state->TextLen + 1);
|
||||||
|
|
||||||
if (recycle_state)
|
if (recycle_state)
|
||||||
{
|
{
|
||||||
@ -4646,7 +4646,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
{
|
{
|
||||||
IM_ASSERT(state != NULL);
|
IM_ASSERT(state != NULL);
|
||||||
state->Edited = false;
|
state->Edited = false;
|
||||||
state->BufCapacityA = buf_size;
|
state->BufCapacity = buf_size;
|
||||||
state->Flags = flags;
|
state->Flags = flags;
|
||||||
|
|
||||||
// Although we are active we don't prevent mouse from hovering other elements unless we are interacting right now with the widget.
|
// Although we are active we don't prevent mouse from hovering other elements unless we are interacting right now with the widget.
|
||||||
@ -4871,7 +4871,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
if (g.PlatformIO.Platform_SetClipboardTextFn != NULL)
|
if (g.PlatformIO.Platform_SetClipboardTextFn != NULL)
|
||||||
{
|
{
|
||||||
const int ib = state->HasSelection() ? ImMin(state->Stb->select_start, state->Stb->select_end) : 0;
|
const int ib = state->HasSelection() ? ImMin(state->Stb->select_start, state->Stb->select_end) : 0;
|
||||||
const int ie = state->HasSelection() ? ImMax(state->Stb->select_start, state->Stb->select_end) : state->CurLenA;
|
const int ie = state->HasSelection() ? ImMax(state->Stb->select_start, state->Stb->select_end) : state->TextLen;
|
||||||
|
|
||||||
char backup = state->TextA.Data[ie];
|
char backup = state->TextA.Data[ie];
|
||||||
state->TextA.Data[ie] = 0; // A bit of a hack since SetClipboardText only takes null terminated strings
|
state->TextA.Data[ie] = 0; // A bit of a hack since SetClipboardText only takes null terminated strings
|
||||||
@ -4936,15 +4936,15 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
IMSTB_TEXTEDIT_CHARTYPE empty_string;
|
IMSTB_TEXTEDIT_CHARTYPE empty_string;
|
||||||
stb_textedit_replace(state, state->Stb, &empty_string, 0);
|
stb_textedit_replace(state, state->Stb, &empty_string, 0);
|
||||||
}
|
}
|
||||||
else if (strcmp(buf, state->InitialTextA.Data) != 0)
|
else if (strcmp(buf, state->TextToRevertTo.Data) != 0)
|
||||||
{
|
{
|
||||||
apply_new_text = state->InitialTextA.Data;
|
apply_new_text = state->TextToRevertTo.Data;
|
||||||
apply_new_text_length = state->InitialTextA.Size - 1;
|
apply_new_text_length = state->TextToRevertTo.Size - 1;
|
||||||
|
|
||||||
// Restore initial value. Only return true if restoring to the initial value changes the current buffer contents.
|
// Restore initial value. Only return true if restoring to the initial value changes the current buffer contents.
|
||||||
// Push records into the undo stack so we can CTRL+Z the revert operation itself
|
// Push records into the undo stack so we can CTRL+Z the revert operation itself
|
||||||
value_changed = true;
|
value_changed = true;
|
||||||
stb_textedit_replace(state, state->Stb, state->InitialTextA.Data, state->InitialTextA.Size - 1);
|
stb_textedit_replace(state, state->Stb, state->TextToRevertTo.Data, state->TextToRevertTo.Size - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5003,14 +5003,14 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
callback_data.UserData = callback_user_data;
|
callback_data.UserData = callback_user_data;
|
||||||
|
|
||||||
// FIXME-OPT: Undo stack reconcile needs a backup of the data until we rework API, see #7925
|
// FIXME-OPT: Undo stack reconcile needs a backup of the data until we rework API, see #7925
|
||||||
state->CallbackTextBackup.resize(state->CurLenA + 1);
|
state->CallbackTextBackup.resize(state->TextLen + 1);
|
||||||
memcpy(state->CallbackTextBackup.Data, state->TextA.Data, state->CurLenA + 1);
|
memcpy(state->CallbackTextBackup.Data, state->TextA.Data, state->TextLen + 1);
|
||||||
|
|
||||||
char* callback_buf = is_readonly ? buf : state->TextA.Data;
|
char* callback_buf = is_readonly ? buf : state->TextA.Data;
|
||||||
callback_data.EventKey = event_key;
|
callback_data.EventKey = event_key;
|
||||||
callback_data.Buf = callback_buf;
|
callback_data.Buf = callback_buf;
|
||||||
callback_data.BufTextLen = state->CurLenA;
|
callback_data.BufTextLen = state->TextLen;
|
||||||
callback_data.BufSize = state->BufCapacityA;
|
callback_data.BufSize = state->BufCapacity;
|
||||||
callback_data.BufDirty = false;
|
callback_data.BufDirty = false;
|
||||||
|
|
||||||
const int utf8_cursor_pos = callback_data.CursorPos = state->Stb->cursor;
|
const int utf8_cursor_pos = callback_data.CursorPos = state->Stb->cursor;
|
||||||
@ -5023,7 +5023,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
// Read back what user may have modified
|
// Read back what user may have modified
|
||||||
callback_buf = is_readonly ? buf : state->TextA.Data; // Pointer may have been invalidated by a resize callback
|
callback_buf = is_readonly ? buf : state->TextA.Data; // Pointer may have been invalidated by a resize callback
|
||||||
IM_ASSERT(callback_data.Buf == callback_buf); // Invalid to modify those fields
|
IM_ASSERT(callback_data.Buf == callback_buf); // Invalid to modify those fields
|
||||||
IM_ASSERT(callback_data.BufSize == state->BufCapacityA);
|
IM_ASSERT(callback_data.BufSize == state->BufCapacity);
|
||||||
IM_ASSERT(callback_data.Flags == flags);
|
IM_ASSERT(callback_data.Flags == flags);
|
||||||
const bool buf_dirty = callback_data.BufDirty;
|
const bool buf_dirty = callback_data.BufDirty;
|
||||||
if (callback_data.CursorPos != utf8_cursor_pos || buf_dirty) { state->Stb->cursor = callback_data.CursorPos; state->CursorFollow = true; }
|
if (callback_data.CursorPos != utf8_cursor_pos || buf_dirty) { state->Stb->cursor = callback_data.CursorPos; state->CursorFollow = true; }
|
||||||
@ -5034,7 +5034,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
// Callback may update buffer and thus set buf_dirty even in read-only mode.
|
// Callback may update buffer and thus set buf_dirty even in read-only mode.
|
||||||
IM_ASSERT(callback_data.BufTextLen == (int)strlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text!
|
IM_ASSERT(callback_data.BufTextLen == (int)strlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text!
|
||||||
InputTextReconcileUndoStateAfterUserCallback(state, callback_data.Buf, callback_data.BufTextLen); // FIXME: Move the rest of this block inside function and rename to InputTextReconcileStateAfterUserCallback() ?
|
InputTextReconcileUndoStateAfterUserCallback(state, callback_data.Buf, callback_data.BufTextLen); // FIXME: Move the rest of this block inside function and rename to InputTextReconcileStateAfterUserCallback() ?
|
||||||
state->CurLenA = callback_data.BufTextLen; // Assume correct length and valid UTF-8 from user, saves us an extra strlen()
|
state->TextLen = callback_data.BufTextLen; // Assume correct length and valid UTF-8 from user, saves us an extra strlen()
|
||||||
state->CursorAnimReset();
|
state->CursorAnimReset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5044,7 +5044,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
if (!is_readonly && strcmp(state->TextA.Data, buf) != 0)
|
if (!is_readonly && strcmp(state->TextA.Data, buf) != 0)
|
||||||
{
|
{
|
||||||
apply_new_text = state->TextA.Data;
|
apply_new_text = state->TextA.Data;
|
||||||
apply_new_text_length = state->CurLenA;
|
apply_new_text_length = state->TextLen;
|
||||||
value_changed = true;
|
value_changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5128,7 +5128,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
{
|
{
|
||||||
IM_ASSERT(state != NULL);
|
IM_ASSERT(state != NULL);
|
||||||
if (!is_displaying_hint)
|
if (!is_displaying_hint)
|
||||||
buf_display_end = buf_display + state->CurLenA;
|
buf_display_end = buf_display + state->TextLen;
|
||||||
|
|
||||||
// Render text (with cursor and selection)
|
// Render text (with cursor and selection)
|
||||||
// This is going to be messy. We need to:
|
// This is going to be messy. We need to:
|
||||||
@ -5138,7 +5138,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
// 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)
|
// 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.
|
// FIXME: This should occur on buf_display but we'd need to maintain cursor/select_start/select_end for UTF-8.
|
||||||
const char* text_begin = state->TextA.Data;
|
const char* text_begin = state->TextA.Data;
|
||||||
const char* text_end = text_begin + state->CurLenA;
|
const char* text_end = text_begin + state->TextLen;
|
||||||
ImVec2 cursor_offset, select_start_offset;
|
ImVec2 cursor_offset, select_start_offset;
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -5280,7 +5280,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
if (is_multiline)
|
if (is_multiline)
|
||||||
text_size = ImVec2(inner_size.x, InputTextCalcTextLenAndLineCount(buf_display, &buf_display_end) * g.FontSize); // We don't need width
|
text_size = ImVec2(inner_size.x, InputTextCalcTextLenAndLineCount(buf_display, &buf_display_end) * g.FontSize); // We don't need width
|
||||||
else if (!is_displaying_hint && g.ActiveId == id)
|
else if (!is_displaying_hint && g.ActiveId == id)
|
||||||
buf_display_end = buf_display + state->CurLenA;
|
buf_display_end = buf_display + state->TextLen;
|
||||||
else if (!is_displaying_hint)
|
else if (!is_displaying_hint)
|
||||||
buf_display_end = buf_display + strlen(buf_display);
|
buf_display_end = buf_display + strlen(buf_display);
|
||||||
|
|
||||||
@ -5341,8 +5341,8 @@ void ImGui::DebugNodeInputTextState(ImGuiInputTextState* state)
|
|||||||
ImStb::StbUndoState* undo_state = &stb_state->undostate;
|
ImStb::StbUndoState* undo_state = &stb_state->undostate;
|
||||||
Text("ID: 0x%08X, ActiveID: 0x%08X", state->ID, g.ActiveId);
|
Text("ID: 0x%08X, ActiveID: 0x%08X", state->ID, g.ActiveId);
|
||||||
DebugLocateItemOnHover(state->ID);
|
DebugLocateItemOnHover(state->ID);
|
||||||
Text("CurLenA: %d, Cursor: %d, Selection: %d..%d", state->CurLenA, stb_state->cursor, stb_state->select_start, stb_state->select_end);
|
Text("CurLenA: %d, Cursor: %d, Selection: %d..%d", state->TextLen, stb_state->cursor, stb_state->select_start, stb_state->select_end);
|
||||||
Text("BufCapacityA: %d", state->BufCapacityA);
|
Text("BufCapacityA: %d", state->BufCapacity);
|
||||||
Text("(Internal Buffer: TextA Size: %d, Capacity: %d)", state->TextA.Size, state->TextA.Capacity);
|
Text("(Internal Buffer: TextA Size: %d, Capacity: %d)", state->TextA.Size, state->TextA.Capacity);
|
||||||
Text("has_preferred_x: %d (%.2f)", stb_state->has_preferred_x, stb_state->preferred_x);
|
Text("has_preferred_x: %d (%.2f)", stb_state->has_preferred_x, stb_state->preferred_x);
|
||||||
Text("undo_point: %d, redo_point: %d, undo_char_point: %d, redo_char_point: %d", undo_state->undo_point, undo_state->redo_point, undo_state->undo_char_point, undo_state->redo_char_point);
|
Text("undo_point: %d, redo_point: %d, undo_char_point: %d, redo_char_point: %d", undo_state->undo_point, undo_state->redo_point, undo_state->undo_char_point, undo_state->redo_char_point);
|
||||||
|
Loading…
Reference in New Issue
Block a user