From 96d2942373c650dcd40979c60ec53a795497d648 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 29 Aug 2017 18:40:14 +0800 Subject: [PATCH] InputText: Merged bits from Navigation branch (inc. g.ActiveIdIsJustActivated is only set on the toggle). --- imgui.cpp | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4004a6285..a94546e04 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1868,11 +1868,10 @@ ImGuiWindow* ImGui::GetParentWindow() void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window) { ImGuiContext& g = *GImGui; + g.ActiveIdIsJustActivated = (g.ActiveId != id); g.ActiveId = id; g.ActiveIdAllowOverlap = false; - g.ActiveIdIsJustActivated = true; - if (id) - g.ActiveIdIsAlive = true; + g.ActiveIdIsAlive |= (id != 0); g.ActiveIdWindow = window; } @@ -7829,6 +7828,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 const bool user_clicked = hovered && io.MouseClicked[0]; const bool user_scrolled = is_multiline && g.ActiveId == 0 && edit_state.Id == id && g.ActiveIdPreviousFrame == draw_window->GetIDNoKeepAlive("#SCROLLY"); + bool clear_active_id = false; + bool select_all = (g.ActiveId != id) && (flags & ImGuiInputTextFlags_AutoSelectAll) != 0; if (focus_requested || user_clicked || user_scrolled) { @@ -7874,8 +7875,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 else if (io.MouseClicked[0]) { // Release focus when we click outside - if (g.ActiveId == id) - ClearActiveID(); + clear_active_id = true; } bool value_changed = false; @@ -7948,9 +7948,12 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Consume characters memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters)); } + } - // Handle various key-presses - bool cancel_edit = false; + bool cancel_edit = false; + if (g.ActiveId == id && !g.ActiveIdIsJustActivated && !clear_active_id) + { + // Handle key-presses const int k_mask = (io.KeyShift ? STB_TEXTEDIT_K_SHIFT : 0); const bool is_shortcut_key_only = (io.OSXBehaviors ? (io.KeySuper && !io.KeyCtrl) : (io.KeyCtrl && !io.KeySuper)) && !io.KeyAlt && !io.KeyShift; // OS X style: Shortcuts using Cmd/Super instead of Ctrl const bool is_wordmove_key_down = io.OSXBehaviors ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl @@ -7977,8 +7980,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 bool ctrl_enter_for_new_line = (flags & ImGuiInputTextFlags_CtrlEnterForNewLine) != 0; if (!is_multiline || (ctrl_enter_for_new_line && !io.KeyCtrl) || (!ctrl_enter_for_new_line && io.KeyCtrl)) { - ClearActiveID(); - enter_pressed = true; + enter_pressed = clear_active_id = true; } else if (is_editable) { @@ -7993,7 +7995,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 if (InputTextFilterCharacter(&c, flags, callback, user_data)) edit_state.OnKeyPressed((int)c); } - else if (IsKeyPressedMap(ImGuiKey_Escape)) { ClearActiveID(); cancel_edit = true; } + else if (IsKeyPressedMap(ImGuiKey_Escape)) { clear_active_id = cancel_edit = true; } else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Z) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); edit_state.ClearSelection(); } else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Y) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); edit_state.ClearSelection(); } else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); edit_state.CursorFollow = true; } @@ -8047,7 +8049,10 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 ImGui::MemFree(clipboard_filtered); } } + } + if (g.ActiveId == id) + { if (cancel_edit) { // Restore initial value @@ -8057,7 +8062,11 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 value_changed = true; } } - else + + // When using 'ImGuiInputTextFlags_EnterReturnsTrue' as a special case we reapply the live buffer back to the input buffer before clearing ActiveId, even though strictly speaking it wasn't modified on this frame. + // If we didn't do that, code like InputInt() with ImGuiInputTextFlags_EnterReturnsTrue would fail. Also this allows the user to use InputText() with ImGuiInputTextFlags_EnterReturnsTrue without maintaining any user-side storage. + bool apply_edit_back_to_user_buffer = !cancel_edit || (enter_pressed && (flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0); + if (apply_edit_back_to_user_buffer) { // Apply new value immediately - copy modified buffer back // Note that as soon as the input box is active, the in-widget value gets priority over any underlying modification of the input buffer @@ -8145,6 +8154,10 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 } } + // Release active ID at the end of the function (so e.g. pressing Return still does a final application of the value) + if (clear_active_id && g.ActiveId == id) + ClearActiveID(); + // 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;