Internal: InputText: Minor changes (intended to have side-effect but clarify next commit, however there is rarely such a thing as zero side effect in InputText land!)

This commit is contained in:
omar 2019-02-26 12:22:58 +01:00
parent 439f726945
commit b7b82520b4
2 changed files with 25 additions and 20 deletions

View File

@ -104,6 +104,8 @@ namespace ImStb
#define STB_TEXTEDIT_STRING ImGuiInputTextState #define STB_TEXTEDIT_STRING ImGuiInputTextState
#define STB_TEXTEDIT_CHARTYPE ImWchar #define STB_TEXTEDIT_CHARTYPE ImWchar
#define STB_TEXTEDIT_GETWIDTH_NEWLINE -1.0f #define STB_TEXTEDIT_GETWIDTH_NEWLINE -1.0f
#define STB_TEXTEDIT_UNDOSTATECOUNT 99
#define STB_TEXTEDIT_UNDOCHARCOUNT 999
#include "imstb_textedit.h" #include "imstb_textedit.h"
} // namespace ImStb } // namespace ImStb
@ -593,6 +595,8 @@ struct IMGUI_API ImGuiInputTextState
bool HasSelection() const { return Stb.select_start != Stb.select_end; } bool HasSelection() const { return Stb.select_start != Stb.select_end; }
void ClearSelection() { Stb.select_start = Stb.select_end = Stb.cursor; } void ClearSelection() { Stb.select_start = Stb.select_end = Stb.cursor; }
void SelectAll() { Stb.select_start = 0; Stb.cursor = Stb.select_end = CurLenW; Stb.has_preferred_x = 0; } void SelectAll() { Stb.select_start = 0; Stb.cursor = Stb.select_end = CurLenW; Stb.has_preferred_x = 0; }
int GetUndoAvailCount() const { return Stb.undostate.undo_point; }
int GetRedoAvailCount() const { return STB_TEXTEDIT_UNDOSTATECOUNT - Stb.undostate.redo_point; }
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
}; };

View File

@ -3277,32 +3277,33 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
g.ActiveIdAllowNavDirFlags = ((1 << ImGuiDir_Up) | (1 << ImGuiDir_Down)); g.ActiveIdAllowNavDirFlags = ((1 << ImGuiDir_Up) | (1 << ImGuiDir_Down));
} }
// We have an edge case if ActiveId was set through another widget (e.g. widget being swapped), clear id immediately (don't wait until the end of the function)
if (g.ActiveId == id && state == NULL)
ClearActiveID();
// Release focus when we click outside // Release focus when we click outside
if (!init_make_active && io.MouseClicked[0]) if (!init_make_active && io.MouseClicked[0])
clear_active_id = true; clear_active_id = true;
// We have an edge case if ActiveId was set through another widget (e.g. widget being swapped)
if (g.ActiveId == id && state == NULL)
ClearActiveID();
bool value_changed = false; bool value_changed = false;
bool enter_pressed = false; bool enter_pressed = false;
int backup_current_text_length = 0; int backup_current_text_length = 0;
// Process mouse inputs and character inputs // When read-only we always use the live data passed to the function
if (g.ActiveId == id) if (g.ActiveId == id && is_readonly && !g.ActiveIdIsJustActivated)
{ {
IM_ASSERT(state != NULL); IM_ASSERT(state != NULL);
if (is_readonly && !g.ActiveIdIsJustActivated)
{
// When read-only we always use the live data passed to the function
const char* buf_end = NULL; const char* buf_end = NULL;
state->TextW.resize(buf_size+1); state->TextW.resize(buf_size + 1);
state->CurLenW = ImTextStrFromUtf8(state->TextW.Data, state->TextW.Size, buf, NULL, &buf_end); state->CurLenW = ImTextStrFromUtf8(state->TextW.Data, state->TextW.Size, buf, NULL, &buf_end);
state->CurLenA = (int)(buf_end - buf); state->CurLenA = (int)(buf_end - buf);
state->CursorClamp(); state->CursorClamp();
} }
// Process mouse inputs and character inputs
if (g.ActiveId == id)
{
IM_ASSERT(state != NULL);
backup_current_text_length = state->CurLenA; backup_current_text_length = state->CurLenA;
state->BufCapacityA = buf_size; state->BufCapacityA = buf_size;
state->UserFlags = flags; state->UserFlags = flags;
@ -3653,7 +3654,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
// Render text. We currently only render selection when the widget is active or while scrolling. // Render text. We currently only render selection when the widget is active or while scrolling.
// FIXME: We could remove the '&& render_cursor' to keep rendering selection when inactive. // FIXME: We could remove the '&& render_cursor' to keep rendering selection when inactive.
const bool render_cursor = (g.ActiveId == id) || user_scroll_active; const bool render_cursor = (g.ActiveId == id) || (state && user_scroll_active);
const bool render_selection = state && state->HasSelection() && (RENDER_SELECTION_WHEN_INACTIVE || render_cursor); const bool render_selection = state && state->HasSelection() && (RENDER_SELECTION_WHEN_INACTIVE || render_cursor);
if (render_cursor || render_selection) if (render_cursor || render_selection)
{ {
@ -3811,13 +3812,13 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
else else
{ {
// Render text only (no selection, no cursor) // Render text only (no selection, no cursor)
const char* buf_end = NULL; const char* buf_display_end = NULL;
if (is_multiline) if (is_multiline)
text_size = ImVec2(size.x, InputTextCalcTextLenAndLineCount(buf_display, &buf_end) * g.FontSize); // We don't need width text_size = ImVec2(size.x, InputTextCalcTextLenAndLineCount(buf_display, &buf_display_end) * g.FontSize); // We don't need width
else else
buf_end = buf_display + strlen(buf_display); buf_display_end = buf_display + strlen(buf_display);
if (is_multiline || (buf_end - buf_display) < buf_display_max_length) if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length)
draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos, GetColorU32(ImGuiCol_Text), buf_display, buf_end, 0.0f, is_multiline ? NULL : &clip_rect); draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos, GetColorU32(ImGuiCol_Text), buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect);
} }
if (is_multiline) if (is_multiline)