diff --git a/docs/TODO.txt b/docs/TODO.txt index 114bd995f..01b547161 100644 --- a/docs/TODO.txt +++ b/docs/TODO.txt @@ -72,8 +72,11 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - input text: add discard flag (e.g. ImGuiInputTextFlags_DiscardActiveBuffer) or make it easier to clear active focus for text replacement during edition (#725) - input text: display bug when clicking a drag/slider after an input text in a different window has all-selected text (order dependent). actually a very old bug but no one appears to have noticed it. - input text: allow centering/positioning text so that ctrl+clicking Drag or Slider keeps the textual value at the same pixel position. - - input text: what's the easiest way to implement a nice IP/Mac address input editor? - - input text: Global callback system so user can plug in an expression evaluator easily. + - input text: decorrelate layout from inputs - e.g. what's the easiest way to implement a nice IP/Mac address input editor? + - input text: global callback system so user can plug in an expression evaluator easily. + - input text: force scroll to end or scroll to a given line/contents (so user can implement a log or a search feature) + - input text: a side bar that could e.g. preview where errors are. probably left to the user to draw but we'd need to give them the info there. + - input text: a way for the user to provide syntax coloring. - input text multi-line: don't directly call AddText() which does an unnecessary vertex reserve for character count prior to clipping. and/or more line-based clipping to AddText(). and/or reorganize TextUnformatted/RenderText for more efficiency for large text (e.g TextUnformatted could clip and log separately, etc). - input text multi-line: support for cut/paste without selection (cut/paste the current line) - input text multi-line: line numbers? status bar? (follow up on #200) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 1fb7dd6db..57cd25a3f 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -3212,13 +3212,14 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 const bool focus_requested_by_tab = focus_requested && !focus_requested_by_code; const bool user_clicked = hovered && io.MouseClicked[0]; - const bool user_scrolled = is_multiline && g.ActiveId == 0 && edit_state.ID == id && g.ActiveIdPreviousFrame == GetScrollbarID(draw_window, ImGuiAxis_Y); const bool user_nav_input_start = (g.ActiveId != id) && ((g.NavInputId == id) || (g.NavActivateId == id && g.NavInputSource == ImGuiInputSource_NavKeyboard)); + const bool user_scroll_finish = is_multiline && edit_state.ID == id && g.ActiveId == 0 && g.ActiveIdPreviousFrame == GetScrollbarID(draw_window, ImGuiAxis_Y); + const bool user_scroll_active = is_multiline && edit_state.ID == id && g.ActiveId == GetScrollbarID(draw_window, ImGuiAxis_Y); bool clear_active_id = false; bool select_all = (g.ActiveId != id) && ((flags & ImGuiInputTextFlags_AutoSelectAll) != 0 || user_nav_input_start) && (!is_multiline); - if (focus_requested || user_clicked || user_scrolled || user_nav_input_start) + if (focus_requested || user_clicked || user_scroll_finish || user_nav_input_start) { if (g.ActiveId != id) { @@ -3624,9 +3625,9 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 const ImVec4 clip_rect(frame_bb.Min.x, frame_bb.Min.y, frame_bb.Min.x + size.x, frame_bb.Min.y + size.y); // Not using frame_bb.Max because we have adjusted size ImVec2 render_pos = is_multiline ? draw_window->DC.CursorPos : frame_bb.Min + style.FramePadding; ImVec2 text_size(0.f, 0.f); - const bool is_currently_scrolling = (edit_state.ID == id && is_multiline && g.ActiveId == GetScrollbarID(draw_window, ImGuiAxis_Y)); - if (g.ActiveId == id || is_currently_scrolling) + if (g.ActiveId == id || user_scroll_active) { + // Animate cursor edit_state.CursorAnim += io.DeltaTime; // This is going to be messy. We need to: @@ -3707,7 +3708,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 scroll_y = ImMax(0.0f, cursor_offset.y - g.FontSize); else if (cursor_offset.y - size.y >= scroll_y) scroll_y = cursor_offset.y - size.y; - draw_window->DC.CursorPos.y += (draw_window->Scroll.y - scroll_y); // To avoid a frame of lag + draw_window->DC.CursorPos.y += (draw_window->Scroll.y - scroll_y); // Manipulate cursor pos immediately avoid a frame of lag draw_window->Scroll.y = scroll_y; render_pos.y = draw_window->DC.CursorPos.y; } @@ -3751,6 +3752,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 } } + // We test for 'buf_display_max_length' as a way to avoid some pathological cases (e.g. single-line 1 MB string) which would make ImDrawList crash. const int buf_display_len = edit_state.CurLenA; if (is_multiline || buf_display_len < buf_display_max_length) draw_window->DrawList->AddText(g.Font, g.FontSize, render_pos - render_scroll, GetColorU32(ImGuiCol_Text), buf_display, buf_display + buf_display_len, 0.0f, is_multiline ? NULL : &clip_rect);