|
@@ -1,4 +1,4 @@
|
|
|
-// dear imgui, v1.91.1
|
|
|
+// dear imgui, v1.91.2 WIP
|
|
|
// (widgets code)
|
|
|
|
|
|
/*
|
|
@@ -1466,7 +1466,7 @@ void ImGui::TextLinkOpenURL(const char* label, const char* url)
|
|
|
if (TextLink(label))
|
|
|
if (g.PlatformIO.Platform_OpenInShellFn != NULL)
|
|
|
g.PlatformIO.Platform_OpenInShellFn(&g, url);
|
|
|
- SetItemTooltip("%s", url); // It is more reassuring for user to _always_ display URL when we same as label
|
|
|
+ SetItemTooltip(LocalizeGetMsg(ImGuiLocKey_OpenLink_s), url); // It is more reassuring for user to _always_ display URL when we same as label
|
|
|
if (BeginPopupContextItem())
|
|
|
{
|
|
|
if (MenuItem(LocalizeGetMsg(ImGuiLocKey_CopyLink)))
|
|
@@ -3792,6 +3792,7 @@ bool ImGui::InputDouble(const char* label, double* v, double step, double step_f
|
|
|
//-------------------------------------------------------------------------
|
|
|
// [SECTION] Widgets: InputText, InputTextMultiline, InputTextWithHint
|
|
|
//-------------------------------------------------------------------------
|
|
|
+// - imstb_textedit.h include
|
|
|
// - InputText()
|
|
|
// - InputTextWithHint()
|
|
|
// - InputTextMultiline()
|
|
@@ -3802,6 +3803,11 @@ bool ImGui::InputDouble(const char* label, double* v, double step, double step_f
|
|
|
// - DebugNodeInputTextState() [Internal]
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
|
+namespace ImStb
|
|
|
+{
|
|
|
+#include "imstb_textedit.h"
|
|
|
+}
|
|
|
+
|
|
|
bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
|
|
|
{
|
|
|
IM_ASSERT(!(flags & ImGuiInputTextFlags_Multiline)); // call InputTextMultiline()
|
|
@@ -3900,9 +3906,18 @@ static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, ImGuiInputTextState* ob
|
|
|
r->num_chars = (int)(text_remaining - (text + line_start_idx));
|
|
|
}
|
|
|
|
|
|
-static bool is_separator(unsigned int c)
|
|
|
+static bool ImCharIsSeparatorW(unsigned int c)
|
|
|
{
|
|
|
- return c==',' || c==';' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='|' || c=='\n' || c=='\r' || c=='.' || c=='!' || c=='\\' || c=='/';
|
|
|
+ static const unsigned int separator_list[] =
|
|
|
+ {
|
|
|
+ ',', 0x3001, '.', 0x3002, ';', 0xFF1B, '(', 0xFF08, ')', 0xFF09, '{', 0xFF5B, '}', 0xFF5D,
|
|
|
+ '[', 0x300C, ']', 0x300D, '|', 0xFF5C, '!', 0xFF01, '\\', 0xFFE5, '/', 0x30FB, 0xFF0F,
|
|
|
+ '\n', '\r',
|
|
|
+ };
|
|
|
+ for (unsigned int separator : separator_list)
|
|
|
+ if (c == separator)
|
|
|
+ return true;
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
static int is_word_boundary_from_right(ImGuiInputTextState* obj, int idx)
|
|
@@ -3912,9 +3927,9 @@ static int is_word_boundary_from_right(ImGuiInputTextState* obj, int idx)
|
|
|
return 0;
|
|
|
|
|
|
bool prev_white = ImCharIsBlankW(obj->TextW[idx - 1]);
|
|
|
- bool prev_separ = is_separator(obj->TextW[idx - 1]);
|
|
|
+ bool prev_separ = ImCharIsSeparatorW(obj->TextW[idx - 1]);
|
|
|
bool curr_white = ImCharIsBlankW(obj->TextW[idx]);
|
|
|
- bool curr_separ = is_separator(obj->TextW[idx]);
|
|
|
+ bool curr_separ = ImCharIsSeparatorW(obj->TextW[idx]);
|
|
|
return ((prev_white || prev_separ) && !(curr_separ || curr_white)) || (curr_separ && !prev_separ);
|
|
|
}
|
|
|
static int is_word_boundary_from_left(ImGuiInputTextState* obj, int idx)
|
|
@@ -3923,9 +3938,9 @@ static int is_word_boundary_from_left(ImGuiInputTextState* obj, int idx)
|
|
|
return 0;
|
|
|
|
|
|
bool prev_white = ImCharIsBlankW(obj->TextW[idx]);
|
|
|
- bool prev_separ = is_separator(obj->TextW[idx]);
|
|
|
+ bool prev_separ = ImCharIsSeparatorW(obj->TextW[idx]);
|
|
|
bool curr_white = ImCharIsBlankW(obj->TextW[idx - 1]);
|
|
|
- bool curr_separ = is_separator(obj->TextW[idx - 1]);
|
|
|
+ bool curr_separ = ImCharIsSeparatorW(obj->TextW[idx - 1]);
|
|
|
return ((prev_white) && !(curr_separ || curr_white)) || (curr_separ && !prev_separ);
|
|
|
}
|
|
|
static int STB_TEXTEDIT_MOVEWORDLEFT_IMPL(ImGuiInputTextState* obj, int idx) { idx--; while (idx >= 0 && !is_word_boundary_from_right(obj, idx)) idx--; return idx < 0 ? 0 : idx; }
|
|
@@ -4026,13 +4041,38 @@ static void stb_textedit_replace(ImGuiInputTextState* str, STB_TexteditState* st
|
|
|
|
|
|
} // namespace ImStb
|
|
|
|
|
|
+// We added an extra indirection where 'Stb' is heap-allocated, in order facilitate the work of bindings generators.
|
|
|
+ImGuiInputTextState::ImGuiInputTextState()
|
|
|
+{
|
|
|
+ memset(this, 0, sizeof(*this));
|
|
|
+ Stb = IM_NEW(ImStbTexteditState);
|
|
|
+}
|
|
|
+
|
|
|
+ImGuiInputTextState::~ImGuiInputTextState()
|
|
|
+{
|
|
|
+ IM_DELETE(Stb);
|
|
|
+}
|
|
|
+
|
|
|
void ImGuiInputTextState::OnKeyPressed(int key)
|
|
|
{
|
|
|
- stb_textedit_key(this, &Stb, key);
|
|
|
+ stb_textedit_key(this, Stb, key);
|
|
|
CursorFollow = true;
|
|
|
CursorAnimReset();
|
|
|
}
|
|
|
|
|
|
+// 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::CursorClamp() { Stb->cursor = ImMin(Stb->cursor, CurLenW); Stb->select_start = ImMin(Stb->select_start, CurLenW); Stb->select_end = ImMin(Stb->select_end, CurLenW); }
|
|
|
+bool ImGuiInputTextState::HasSelection() const { return Stb->select_start != Stb->select_end; }
|
|
|
+void ImGuiInputTextState::ClearSelection() { Stb->select_start = Stb->select_end = Stb->cursor; }
|
|
|
+int ImGuiInputTextState::GetCursorPos() const { return Stb->cursor; }
|
|
|
+int ImGuiInputTextState::GetSelectionStart() const { return Stb->select_start; }
|
|
|
+int ImGuiInputTextState::GetSelectionEnd() const { return Stb->select_end; }
|
|
|
+void ImGuiInputTextState::SelectAll() { Stb->select_start = 0; Stb->cursor = Stb->select_end = CurLenW; Stb->has_preferred_x = 0; }
|
|
|
+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::ReloadUserBufAndMoveToEnd() { ReloadUserBuf = true; ReloadSelectionStart = ReloadSelectionEnd = INT_MAX; }
|
|
|
+
|
|
|
ImGuiInputTextCallbackData::ImGuiInputTextCallbackData()
|
|
|
{
|
|
|
memset(this, 0, sizeof(*this));
|
|
@@ -4226,7 +4266,7 @@ static void InputTextReconcileUndoStateAfterUserCallback(ImGuiInputTextState* st
|
|
|
const int insert_len = new_last_diff - first_diff + 1;
|
|
|
const int delete_len = old_last_diff - first_diff + 1;
|
|
|
if (insert_len > 0 || delete_len > 0)
|
|
|
- if (IMSTB_TEXTEDIT_CHARTYPE* p = stb_text_createundo(&state->Stb.undostate, first_diff, delete_len, insert_len))
|
|
|
+ if (IMSTB_TEXTEDIT_CHARTYPE* p = stb_text_createundo(&state->Stb->undostate, first_diff, delete_len, insert_len))
|
|
|
for (int i = 0; i < delete_len; i++)
|
|
|
p[i] = ImStb::STB_TEXTEDIT_GETCHAR(state, first_diff + i);
|
|
|
}
|
|
@@ -4368,7 +4408,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|
|
float scroll_y = is_multiline ? draw_window->Scroll.y : FLT_MAX;
|
|
|
|
|
|
const bool init_reload_from_user_buf = (state != NULL && state->ReloadUserBuf);
|
|
|
- const bool init_changed_specs = (state != NULL && state->Stb.single_line != !is_multiline); // state != NULL means its our state.
|
|
|
+ const bool init_changed_specs = (state != NULL && state->Stb->single_line != !is_multiline); // state != NULL means its our state.
|
|
|
const bool init_make_active = (user_clicked || user_scroll_finish || input_requested_by_nav);
|
|
|
const bool init_state = (init_make_active || user_scroll_active);
|
|
|
if ((init_state && g.ActiveId != id) || init_changed_specs || init_reload_from_user_buf)
|
|
@@ -4414,13 +4454,13 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|
|
else
|
|
|
{
|
|
|
state->Scroll = ImVec2(0.0f, 0.0f);
|
|
|
- stb_textedit_initialize_state(&state->Stb, !is_multiline);
|
|
|
+ stb_textedit_initialize_state(state->Stb, !is_multiline);
|
|
|
}
|
|
|
|
|
|
if (init_reload_from_user_buf)
|
|
|
{
|
|
|
- state->Stb.select_start = state->ReloadSelectionStart;
|
|
|
- state->Stb.cursor = state->Stb.select_end = state->ReloadSelectionEnd;
|
|
|
+ state->Stb->select_start = state->ReloadSelectionStart;
|
|
|
+ state->Stb->cursor = state->Stb->select_end = state->ReloadSelectionEnd;
|
|
|
state->CursorClamp();
|
|
|
}
|
|
|
else if (!is_multiline)
|
|
@@ -4434,7 +4474,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|
|
}
|
|
|
|
|
|
if (flags & ImGuiInputTextFlags_AlwaysOverwrite)
|
|
|
- state->Stb.insert_mode = 1; // stb field name is indeed incorrect (see #2863)
|
|
|
+ state->Stb->insert_mode = 1; // stb field name is indeed incorrect (see #2863)
|
|
|
}
|
|
|
|
|
|
const bool is_osx = io.ConfigMacOSXBehaviors;
|
|
@@ -4542,34 +4582,34 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|
|
}
|
|
|
else if (hovered && io.MouseClickedCount[0] >= 2 && !io.KeyShift)
|
|
|
{
|
|
|
- stb_textedit_click(state, &state->Stb, mouse_x, mouse_y);
|
|
|
+ stb_textedit_click(state, state->Stb, mouse_x, mouse_y);
|
|
|
const int multiclick_count = (io.MouseClickedCount[0] - 2);
|
|
|
if ((multiclick_count % 2) == 0)
|
|
|
{
|
|
|
// Double-click: Select word
|
|
|
// We always use the "Mac" word advance for double-click select vs CTRL+Right which use the platform dependent variant:
|
|
|
// FIXME: There are likely many ways to improve this behavior, but there's no "right" behavior (depends on use-case, software, OS)
|
|
|
- const bool is_bol = (state->Stb.cursor == 0) || ImStb::STB_TEXTEDIT_GETCHAR(state, state->Stb.cursor - 1) == '\n';
|
|
|
- if (STB_TEXT_HAS_SELECTION(&state->Stb) || !is_bol)
|
|
|
+ const bool is_bol = (state->Stb->cursor == 0) || ImStb::STB_TEXTEDIT_GETCHAR(state, state->Stb->cursor - 1) == '\n';
|
|
|
+ if (STB_TEXT_HAS_SELECTION(state->Stb) || !is_bol)
|
|
|
state->OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT);
|
|
|
//state->OnKeyPressed(STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT);
|
|
|
- if (!STB_TEXT_HAS_SELECTION(&state->Stb))
|
|
|
- ImStb::stb_textedit_prep_selection_at_cursor(&state->Stb);
|
|
|
- state->Stb.cursor = ImStb::STB_TEXTEDIT_MOVEWORDRIGHT_MAC(state, state->Stb.cursor);
|
|
|
- state->Stb.select_end = state->Stb.cursor;
|
|
|
- ImStb::stb_textedit_clamp(state, &state->Stb);
|
|
|
+ if (!STB_TEXT_HAS_SELECTION(state->Stb))
|
|
|
+ ImStb::stb_textedit_prep_selection_at_cursor(state->Stb);
|
|
|
+ state->Stb->cursor = ImStb::STB_TEXTEDIT_MOVEWORDRIGHT_MAC(state, state->Stb->cursor);
|
|
|
+ state->Stb->select_end = state->Stb->cursor;
|
|
|
+ ImStb::stb_textedit_clamp(state, state->Stb);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// Triple-click: Select line
|
|
|
- const bool is_eol = ImStb::STB_TEXTEDIT_GETCHAR(state, state->Stb.cursor) == '\n';
|
|
|
+ const bool is_eol = ImStb::STB_TEXTEDIT_GETCHAR(state, state->Stb->cursor) == '\n';
|
|
|
state->OnKeyPressed(STB_TEXTEDIT_K_LINESTART);
|
|
|
state->OnKeyPressed(STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT);
|
|
|
state->OnKeyPressed(STB_TEXTEDIT_K_RIGHT | STB_TEXTEDIT_K_SHIFT);
|
|
|
if (!is_eol && is_multiline)
|
|
|
{
|
|
|
- ImSwap(state->Stb.select_start, state->Stb.select_end);
|
|
|
- state->Stb.cursor = state->Stb.select_end;
|
|
|
+ ImSwap(state->Stb->select_start, state->Stb->select_end);
|
|
|
+ state->Stb->cursor = state->Stb->select_end;
|
|
|
}
|
|
|
state->CursorFollow = false;
|
|
|
}
|
|
@@ -4580,15 +4620,15 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|
|
if (hovered)
|
|
|
{
|
|
|
if (io.KeyShift)
|
|
|
- stb_textedit_drag(state, &state->Stb, mouse_x, mouse_y);
|
|
|
+ stb_textedit_drag(state, state->Stb, mouse_x, mouse_y);
|
|
|
else
|
|
|
- stb_textedit_click(state, &state->Stb, mouse_x, mouse_y);
|
|
|
+ stb_textedit_click(state, state->Stb, mouse_x, mouse_y);
|
|
|
state->CursorAnimReset();
|
|
|
}
|
|
|
}
|
|
|
else if (io.MouseDown[0] && !state->SelectedAllMouseLock && (io.MouseDelta.x != 0.0f || io.MouseDelta.y != 0.0f))
|
|
|
{
|
|
|
- stb_textedit_drag(state, &state->Stb, mouse_x, mouse_y);
|
|
|
+ stb_textedit_drag(state, state->Stb, mouse_x, mouse_y);
|
|
|
state->CursorAnimReset();
|
|
|
state->CursorFollow = true;
|
|
|
}
|
|
@@ -4641,7 +4681,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|
|
IM_ASSERT(state != NULL);
|
|
|
|
|
|
const int row_count_per_page = ImMax((int)((inner_size.y - style.FramePadding.y) / g.FontSize), 1);
|
|
|
- state->Stb.row_count_per_page = row_count_per_page;
|
|
|
+ state->Stb->row_count_per_page = row_count_per_page;
|
|
|
|
|
|
const int k_mask = (io.KeyShift ? STB_TEXTEDIT_K_SHIFT : 0);
|
|
|
const bool is_wordmove_key_down = is_osx ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl
|
|
@@ -4748,8 +4788,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|
|
// Cut, Copy
|
|
|
if (g.PlatformIO.Platform_SetClipboardTextFn != NULL)
|
|
|
{
|
|
|
- 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->CurLenW;
|
|
|
+ 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->CurLenW;
|
|
|
const int clipboard_data_len = ImTextCountUtf8BytesFromStr(state->TextW.Data + ib, state->TextW.Data + ie) + 1;
|
|
|
char* clipboard_data = (char*)IM_ALLOC(clipboard_data_len * sizeof(char));
|
|
|
ImTextStrToUtf8(clipboard_data, clipboard_data_len, state->TextW.Data + ib, state->TextW.Data + ie);
|
|
@@ -4761,7 +4801,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|
|
if (!state->HasSelection())
|
|
|
state->SelectAll();
|
|
|
state->CursorFollow = true;
|
|
|
- stb_textedit_cut(state, &state->Stb);
|
|
|
+ stb_textedit_cut(state, state->Stb);
|
|
|
}
|
|
|
}
|
|
|
else if (is_paste)
|
|
@@ -4783,7 +4823,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|
|
clipboard_filtered[clipboard_filtered_len] = 0;
|
|
|
if (clipboard_filtered_len > 0) // If everything was filtered, ignore the pasting operation
|
|
|
{
|
|
|
- stb_textedit_paste(state, &state->Stb, clipboard_filtered, clipboard_filtered_len);
|
|
|
+ stb_textedit_paste(state, state->Stb, clipboard_filtered, clipboard_filtered_len);
|
|
|
state->CursorFollow = true;
|
|
|
}
|
|
|
MemFree(clipboard_filtered);
|
|
@@ -4810,7 +4850,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|
|
apply_new_text_length = 0;
|
|
|
value_changed = true;
|
|
|
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)
|
|
|
{
|
|
@@ -4825,7 +4865,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|
|
w_text.resize(ImTextCountCharsFromUtf8(apply_new_text, apply_new_text + apply_new_text_length) + 1);
|
|
|
ImTextStrFromUtf8(w_text.Data, w_text.Size, apply_new_text, apply_new_text + apply_new_text_length);
|
|
|
}
|
|
|
- stb_textedit_replace(state, &state->Stb, w_text.Data, (apply_new_text_length > 0) ? (w_text.Size - 1) : 0);
|
|
|
+ stb_textedit_replace(state, state->Stb, w_text.Data, (apply_new_text_length > 0) ? (w_text.Size - 1) : 0);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -4900,9 +4940,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|
|
|
|
|
// 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 = state->TextW.Data;
|
|
|
- const int utf8_cursor_pos = callback_data.CursorPos = ImTextCountUtf8BytesFromStr(text, text + state->Stb.cursor);
|
|
|
- const int utf8_selection_start = callback_data.SelectionStart = ImTextCountUtf8BytesFromStr(text, text + state->Stb.select_start);
|
|
|
- const int utf8_selection_end = callback_data.SelectionEnd = ImTextCountUtf8BytesFromStr(text, text + state->Stb.select_end);
|
|
|
+ const int utf8_cursor_pos = callback_data.CursorPos = ImTextCountUtf8BytesFromStr(text, text + state->Stb->cursor);
|
|
|
+ const int utf8_selection_start = callback_data.SelectionStart = ImTextCountUtf8BytesFromStr(text, text + state->Stb->select_start);
|
|
|
+ const int utf8_selection_end = callback_data.SelectionEnd = ImTextCountUtf8BytesFromStr(text, text + state->Stb->select_end);
|
|
|
|
|
|
// Call user code
|
|
|
callback(&callback_data);
|
|
@@ -4913,9 +4953,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|
|
IM_ASSERT(callback_data.BufSize == state->BufCapacityA);
|
|
|
IM_ASSERT(callback_data.Flags == flags);
|
|
|
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 = (callback_data.SelectionStart == callback_data.CursorPos) ? state->Stb.cursor : ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionStart); }
|
|
|
- if (callback_data.SelectionEnd != utf8_selection_end || buf_dirty) { state->Stb.select_end = (callback_data.SelectionEnd == callback_data.SelectionStart) ? state->Stb.select_start : ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionEnd); }
|
|
|
+ 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 = (callback_data.SelectionStart == callback_data.CursorPos) ? state->Stb->cursor : ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionStart); }
|
|
|
+ if (callback_data.SelectionEnd != utf8_selection_end || buf_dirty) { state->Stb->select_end = (callback_data.SelectionEnd == callback_data.SelectionStart) ? state->Stb->select_start : ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionEnd); }
|
|
|
if (buf_dirty)
|
|
|
{
|
|
|
// Callback may update buffer and thus set buf_dirty even in read-only mode.
|
|
@@ -5037,13 +5077,13 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|
|
int searches_remaining = 0;
|
|
|
if (render_cursor)
|
|
|
{
|
|
|
- searches_input_ptr[0] = text_begin + state->Stb.cursor;
|
|
|
+ searches_input_ptr[0] = text_begin + state->Stb->cursor;
|
|
|
searches_result_line_no[0] = -1;
|
|
|
searches_remaining++;
|
|
|
}
|
|
|
if (render_selection)
|
|
|
{
|
|
|
- searches_input_ptr[1] = text_begin + ImMin(state->Stb.select_start, state->Stb.select_end);
|
|
|
+ searches_input_ptr[1] = text_begin + ImMin(state->Stb->select_start, state->Stb->select_end);
|
|
|
searches_result_line_no[1] = -1;
|
|
|
searches_remaining++;
|
|
|
}
|
|
@@ -5119,8 +5159,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|
|
const ImVec2 draw_scroll = ImVec2(state->Scroll.x, 0.0f);
|
|
|
if (render_selection)
|
|
|
{
|
|
|
- const ImWchar* text_selected_begin = text_begin + ImMin(state->Stb.select_start, state->Stb.select_end);
|
|
|
- const ImWchar* text_selected_end = text_begin + ImMax(state->Stb.select_start, state->Stb.select_end);
|
|
|
+ const ImWchar* text_selected_begin = text_begin + ImMin(state->Stb->select_start, state->Stb->select_end);
|
|
|
+ const ImWchar* text_selected_end = text_begin + ImMax(state->Stb->select_start, state->Stb->select_end);
|
|
|
|
|
|
ImU32 bg_color = GetColorU32(ImGuiCol_TextSelectedBg, render_cursor ? 1.0f : 0.6f); // FIXME: current code flow mandate that render_cursor is always true here, we are leaving the transparent one for tests.
|
|
|
float bg_offy_up = is_multiline ? 0.0f : -1.0f; // FIXME: those offsets should be part of the style? they don't play so well with multi-line selection.
|
|
@@ -5203,7 +5243,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|
|
{
|
|
|
// For focus requests to work on our multiline we need to ensure our child ItemAdd() call specifies the ImGuiItemFlags_Inputable (see #4761, #7870)...
|
|
|
Dummy(ImVec2(text_size.x, text_size.y + style.FramePadding.y));
|
|
|
- g.NextItemData.ItemFlags |= ImGuiItemFlags_Inputable | ImGuiItemFlags_NoTabStop;
|
|
|
+ g.NextItemData.ItemFlags |= (ImGuiItemFlags)ImGuiItemFlags_Inputable | ImGuiItemFlags_NoTabStop;
|
|
|
EndChild();
|
|
|
item_data_backup.StatusFlags |= (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HoveredWindow);
|
|
|
|
|
@@ -5242,7 +5282,7 @@ void ImGui::DebugNodeInputTextState(ImGuiInputTextState* state)
|
|
|
{
|
|
|
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
- ImStb::STB_TexteditState* stb_state = &state->Stb;
|
|
|
+ ImStb::STB_TexteditState* stb_state = state->Stb;
|
|
|
ImStb::StbUndoState* undo_state = &stb_state->undostate;
|
|
|
Text("ID: 0x%08X, ActiveID: 0x%08X", state->ID, g.ActiveId);
|
|
|
DebugLocateItemOnHover(state->ID);
|