InputText: Merged bits from Navigation branch (inc. g.ActiveIdIsJustActivated is only set on the toggle).

This commit is contained in:
omar 2017-08-29 18:40:14 +08:00
parent 35e4fa7b85
commit 96d2942373

View File

@ -1868,11 +1868,10 @@ ImGuiWindow* ImGui::GetParentWindow()
void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window) void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
g.ActiveIdIsJustActivated = (g.ActiveId != id);
g.ActiveId = id; g.ActiveId = id;
g.ActiveIdAllowOverlap = false; g.ActiveIdAllowOverlap = false;
g.ActiveIdIsJustActivated = true; g.ActiveIdIsAlive |= (id != 0);
if (id)
g.ActiveIdIsAlive = true;
g.ActiveIdWindow = window; 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_clicked = hovered && io.MouseClicked[0];
const bool user_scrolled = is_multiline && g.ActiveId == 0 && edit_state.Id == id && g.ActiveIdPreviousFrame == draw_window->GetIDNoKeepAlive("#SCROLLY"); 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; bool select_all = (g.ActiveId != id) && (flags & ImGuiInputTextFlags_AutoSelectAll) != 0;
if (focus_requested || user_clicked || user_scrolled) 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]) else if (io.MouseClicked[0])
{ {
// Release focus when we click outside // Release focus when we click outside
if (g.ActiveId == id) clear_active_id = true;
ClearActiveID();
} }
bool value_changed = false; bool value_changed = false;
@ -7948,9 +7948,12 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
// Consume characters // Consume characters
memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters)); 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 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_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 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; 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)) if (!is_multiline || (ctrl_enter_for_new_line && !io.KeyCtrl) || (!ctrl_enter_for_new_line && io.KeyCtrl))
{ {
ClearActiveID(); enter_pressed = clear_active_id = true;
enter_pressed = true;
} }
else if (is_editable) 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)) if (InputTextFilterCharacter(&c, flags, callback, user_data))
edit_state.OnKeyPressed((int)c); 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_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_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; } 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); ImGui::MemFree(clipboard_filtered);
} }
} }
}
if (g.ActiveId == id)
{
if (cancel_edit) if (cancel_edit)
{ {
// Restore initial value // Restore initial value
@ -8057,7 +8062,11 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
value_changed = true; 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 // 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 // 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 // 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. // 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.TempTextBuffer.Data : buf; buf = NULL;