Browse Source

InputText: Word-Wrap: hide vertical scrollbar but takes its width into account. (#3237, #952, #1062, #7363)

Also increase IMGUI_VERSION_NUM for good measure, forgot to increase it when moving to public api.
ocornut 1 ngày trước cách đây
mục cha
commit
36133d8ac4
3 tập tin đã thay đổi với 14 bổ sung12 xóa
  1. 3 3
      docs/CHANGELOG.txt
  2. 3 3
      imgui.h
  3. 8 6
      imgui_widgets.cpp

+ 3 - 3
docs/CHANGELOG.txt

@@ -56,12 +56,12 @@ Other Changes:
   window has the ImGuiWindowFlags_NoNavFocus flag. (#8914)
 - Bullet: fixed tesselation amount which looked out of place in very large sizes.
 - InputText: added ImGuiInputTextFlags_WordWrap flag to word-wrap multi-line buffers.
-  (#3237, #952, #1062, #7363)
+  (#3237, #952, #1062, #7363). Current caveats:
   - This is marked as beta because not being tested enough.
     Please report any incorrect cursor movement, selection behavior etc. bug to #3237.
-  - Vertical scrollbar is made always visible.
-  - Wrapping points are not ideal. Wrapping of long words/sections (e.g. words
+  - Wrapping style is not ideal. Wrapping of long words/sections (e.g. words
     larger than total available width) may be particularly unpleasing.
+  - Wrapping width needs to always account for the possibility of a vertical scrollbar.
   - It is currently much slower than regular text fields.
     - Ballpark estimate of cost on my 2019 desktop PC:
       For a 100 KB text buffer: +~0.3 ms/+~1.0 ms (Optimized vs Debug builds).

+ 3 - 3
imgui.h

@@ -29,7 +29,7 @@
 // Library Version
 // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
 #define IMGUI_VERSION       "1.92.3 WIP"
-#define IMGUI_VERSION_NUM   19227
+#define IMGUI_VERSION_NUM   19228
 #define IMGUI_HAS_TABLE             // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
 #define IMGUI_HAS_TEXTURES          // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
 
@@ -1267,8 +1267,8 @@ enum ImGuiInputTextFlags_
 
     // Multi-line Word-Wrapping [BETA]
     // - Not well tested yet. Please report any incorrect cursor movement, selection behavior etc. bug to https://github.com/ocornut/imgui/issues/3237.
-    // - Vertical scrollbar is made always visible.
-    // - Wrapping points are not ideal. Wrapping of long words/sections (e.g. words larger than total available width) may be particularly unpleasing.
+    // - Wrapping style is not ideal. Wrapping of long words/sections (e.g. words larger than total available width) may be particularly unpleasing.
+    // - Wrapping width needs to always account for the possibility of a vertical scrollbar.
     // - It is much slower than regular text fields.
     //   Ballpark estimate of cost on my 2019 desktop PC: for a 100 KB text buffer: +~0.3 ms (Optimized) / +~1.0 ms (Debug build).
     //   The CPU cost is very roughly proportional to text length, so a 10 KB buffer should cost about ten times less.

+ 8 - 6
imgui_widgets.cpp

@@ -4672,10 +4672,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
         PushStyleVar(ImGuiStyleVar_ChildRounding, style.FrameRounding);
         PushStyleVar(ImGuiStyleVar_ChildBorderSize, style.FrameBorderSize);
         PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); // Ensure no clip rect so mouse hover can reach FramePadding edges
-        ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoMove;
-        if (flags & ImGuiInputTextFlags_WordWrap)
-            window_flags |= ImGuiWindowFlags_AlwaysVerticalScrollbar; // FIXME-WORDWRAP: Makes things much simpler. Otherwise requires more work to track cursor reliably and avoid one-frame glitch.
-        bool child_visible = BeginChildEx(label, id, frame_bb.GetSize(), ImGuiChildFlags_Borders, window_flags);
+        bool child_visible = BeginChildEx(label, id, frame_bb.GetSize(), ImGuiChildFlags_Borders, ImGuiWindowFlags_NoMove);
         g.NavActivateId = backup_activate_id;
         PopStyleVar(3);
         PopStyleColor();
@@ -4715,11 +4712,16 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
     const bool is_password = (flags & ImGuiInputTextFlags_Password) != 0;
     const bool is_undoable = (flags & ImGuiInputTextFlags_NoUndoRedo) == 0;
     const bool is_resizable = (flags & ImGuiInputTextFlags_CallbackResize) != 0;
-    const bool is_wordwrap = (flags & ImGuiInputTextFlags_WordWrap) != 0;
-    const float wrap_width = is_wordwrap ? GetContentRegionAvail().x : 0.0f;
     if (is_resizable)
         IM_ASSERT(callback != NULL); // Must provide a callback if you set the ImGuiInputTextFlags_CallbackResize flag!
 
+    // Word-wrapping: enforcing a fixed width not altered by vertical scrollbar makes things easier, notably to track cursor reliably and avoid one-frame glitches.
+    // Instead of using ImGuiWindowFlags_AlwaysVerticalScrollbar we account for that space if the scrollbar is not visible.
+    const bool is_wordwrap = (flags & ImGuiInputTextFlags_WordWrap) != 0;
+    float wrap_width = 0.0f;
+    if (is_wordwrap)
+        wrap_width = ImMax(1.0f, GetContentRegionAvail().x + (draw_window->ScrollbarY ? 0.0f : -g.Style.ScrollbarSize));
+
     const bool input_requested_by_nav = (g.ActiveId != id) && ((g.NavActivateId == id) && ((g.NavActivateFlags & ImGuiActivateFlags_PreferInput) || (g.NavInputSource == ImGuiInputSource_Keyboard)));
 
     const bool user_clicked = hovered && io.MouseClicked[0];