Browse Source

InputText: fixed cursor navigation when pressing Up Arrow on the last character of a multiline buffer which doesn't end with a carriage return. (#6000)

Simplify stb_textedit_find_charpos(). Leaving that to simmer for a while before attempting an upstream PR.
ocornut 2 years ago
parent
commit
57a5b73a4c
4 changed files with 17 additions and 24 deletions
  1. 2 0
      docs/CHANGELOG.txt
  2. 1 1
      imgui.h
  3. 1 0
      imgui_widgets.cpp
  4. 13 23
      imstb_textedit.h

+ 2 - 0
docs/CHANGELOG.txt

@@ -62,6 +62,8 @@ Other changes:
   and when backend/OS is emitting dual-axis wheeling inputs (typically touch pads on macOS).
   and when backend/OS is emitting dual-axis wheeling inputs (typically touch pads on macOS).
   We now select a primary axis based on recent events, and select a target window based on it.
   We now select a primary axis based on recent events, and select a target window based on it.
   We expect this behavior to be further improved/tweaked. (#3795, #4559) [@ocornut, @folays]
   We expect this behavior to be further improved/tweaked. (#3795, #4559) [@ocornut, @folays]
+- InputText: fixed cursor navigation when pressing Up Arrow on the last character of a
+  multiline buffer which doesn't end with a carriage return. (#6000)
 - Text: fixed layouting of wrapped-text block when the last source line is above the
 - Text: fixed layouting of wrapped-text block when the last source line is above the
   clipping region. Regression added in 1.89. (#5720, #5919)
   clipping region. Regression added in 1.89. (#5720, #5919)
 - Misc: added GetItemID() in public API. It is not often expected that you would use this,
 - Misc: added GetItemID() in public API. It is not often expected that you would use this,

+ 1 - 1
imgui.h

@@ -23,7 +23,7 @@
 // Library Version
 // Library Version
 // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM > 12345')
 // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM > 12345')
 #define IMGUI_VERSION               "1.89.2 WIP"
 #define IMGUI_VERSION               "1.89.2 WIP"
-#define IMGUI_VERSION_NUM           18916
+#define IMGUI_VERSION_NUM           18917
 #define IMGUI_HAS_TABLE
 #define IMGUI_HAS_TABLE
 
 
 /*
 /*

+ 1 - 0
imgui_widgets.cpp

@@ -4858,6 +4858,7 @@ void ImGui::DebugNodeInputTextState(ImGuiInputTextState* state)
     Text("ID: 0x%08X, ActiveID: 0x%08X", state->ID, g.ActiveId);
     Text("ID: 0x%08X, ActiveID: 0x%08X", state->ID, g.ActiveId);
     DebugLocateItemOnHover(state->ID);
     DebugLocateItemOnHover(state->ID);
     Text("CurLenW: %d, CurLenA: %d, Cursor: %d, Selection: %d..%d", state->CurLenA, state->CurLenW, stb_state->cursor, stb_state->select_start, stb_state->select_end);
     Text("CurLenW: %d, CurLenA: %d, Cursor: %d, Selection: %d..%d", state->CurLenA, state->CurLenW, stb_state->cursor, stb_state->select_start, stb_state->select_end);
+    Text("has_preferred_x: %d (%.2f)", stb_state->has_preferred_x, stb_state->preferred_x);
     Text("undo_point: %d, redo_point: %d, undo_char_point: %d, redo_char_point: %d", undo_state->undo_point, undo_state->redo_point, undo_state->undo_char_point, undo_state->redo_char_point);
     Text("undo_point: %d, redo_point: %d, undo_char_point: %d, redo_char_point: %d", undo_state->undo_point, undo_state->redo_point, undo_state->undo_char_point, undo_state->redo_char_point);
     if (BeginChild("undopoints", ImVec2(0.0f, GetTextLineHeight() * 15), true)) // Visualize undo state
     if (BeginChild("undopoints", ImVec2(0.0f, GetTextLineHeight() * 15), true)) // Visualize undo state
     {
     {

+ 13 - 23
imstb_textedit.h

@@ -2,6 +2,7 @@
 // This is a slightly modified version of stb_textedit.h 1.14.
 // This is a slightly modified version of stb_textedit.h 1.14.
 // Those changes would need to be pushed into nothings/stb:
 // Those changes would need to be pushed into nothings/stb:
 // - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321)
 // - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321)
+// - Fix in stb_textedit_find_charpos to handle last line (see https://github.com/ocornut/imgui/issues/6000)
 // Grep for [DEAR IMGUI] to find the changes.
 // Grep for [DEAR IMGUI] to find the changes.
 
 
 // stb_textedit.h - v1.14  - public domain - Sean Barrett
 // stb_textedit.h - v1.14  - public domain - Sean Barrett
@@ -524,29 +525,14 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s
    int z = STB_TEXTEDIT_STRINGLEN(str);
    int z = STB_TEXTEDIT_STRINGLEN(str);
    int i=0, first;
    int i=0, first;
 
 
-   if (n == z) {
-      // if it's at the end, then find the last line -- simpler than trying to
-      // explicitly handle this case in the regular code
-      if (single_line) {
-         STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
-         find->y = 0;
-         find->first_char = 0;
-         find->length = z;
-         find->height = r.ymax - r.ymin;
-         find->x = r.x1;
-      } else {
-         find->y = 0;
-         find->x = 0;
-         find->height = 1;
-         while (i < z) {
-            STB_TEXTEDIT_LAYOUTROW(&r, str, i);
-            prev_start = i;
-            i += r.num_chars;
-         }
-         find->first_char = i;
-         find->length = 0;
-         find->prev_first = prev_start;
-      }
+   if (n == z && single_line) {
+      // special case if it's at the end (may not be needed?)
+      STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
+      find->y = 0;
+      find->first_char = 0;
+      find->length = z;
+      find->height = r.ymax - r.ymin;
+      find->x = r.x1;
       return;
       return;
    }
    }
 
 
@@ -557,9 +543,13 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s
       STB_TEXTEDIT_LAYOUTROW(&r, str, i);
       STB_TEXTEDIT_LAYOUTROW(&r, str, i);
       if (n < i + r.num_chars)
       if (n < i + r.num_chars)
          break;
          break;
+      if (i + r.num_chars == z && z > 0 && STB_TEXTEDIT_GETCHAR(str, z - 1) != STB_TEXTEDIT_NEWLINE)  // [DEAR IMGUI] special handling for last line
+         break;   // [DEAR IMGUI]
       prev_start = i;
       prev_start = i;
       i += r.num_chars;
       i += r.num_chars;
       find->y += r.baseline_y_delta;
       find->y += r.baseline_y_delta;
+      if (i == z) // [DEAR IMGUI]
+         break;   // [DEAR IMGUI]
    }
    }
 
 
    find->first_char = first = i;
    find->first_char = first = i;