Browse Source

Widgets: Sliders: Skip custom stb_sprintf.h format flags (', #, _) in RoundScalarWithFormatT() as they break ImAtof()/ImAtoi() and cause Drag*()/Slider*() widgets display incorrect values. (#3604)
Widgets: Sliders: Fix a bug where numbers after format specifier (eg. %d123) would cause RoundScalarWithFormatT() return incorrect value.

Rokas Kupstys 4 years ago
parent
commit
8ee77f1b65
2 changed files with 30 additions and 2 deletions
  1. 6 2
      docs/CHANGELOG.txt
  2. 24 0
      imgui_widgets.cpp

+ 6 - 2
docs/CHANGELOG.txt

@@ -46,11 +46,15 @@ Breaking Changes:
 
 Other Changes:
 
-- DragScalar: Fixed crash when using DragScalar() directly (not via common wrapper like DragFloat() etc.)
-  with ImGuiSliderFlags_AlwaysClamp + only one of either p_min or p_max set. (#3824) [@harry75369]
 - Window: Shrink close button hit-testing region when it covers an abnormally high portion of the window visible
   area (e.g. when window is collapsed + moved in a corner) to facilitate moving the window away. (#3825)
 - Window, Nav: Fixed crash when calling SetWindowFocus(NULL) as the time a new window appears. (#3865) [@nem0]
+- DragScalar: Fixed crash when using DragScalar() directly (not via common wrapper like DragFloat() etc.)
+  with ImGuiSliderFlags_AlwaysClamp + only one of either p_min or p_max set. (#3824) [@harry75369]
+- Drags, Sliders: Fixed a bug where editing value would use wrong number if there were digits right after 
+  format specifier (e.g. using "%f123" as a format string). [@rokups]
+- Drags, Sliders: Fixed a bug where using custom formatting flags (',$,_) supported by stb_sprintf.h 
+  would cause incorrect value to be displayed. (#3604) [@rokups]
 - Tables: Fixed unaligned accesses when using TableSetBgColor(ImGuiTableBgTarget_CellBg). (#3872)
 - IsItemHovered(): fixed return value false positive when used after EndChild(), EndGroup() or widgets using
   either of them, when the hovered location is located within a child window, e.g. InputTextMultiline().

+ 24 - 0
imgui_widgets.cpp

@@ -2084,6 +2084,30 @@ TYPE ImGui::RoundScalarWithFormatT(const char* format, ImGuiDataType data_type,
     if (fmt_start[0] != '%' || fmt_start[1] == '%') // Don't apply if the value is not visible in the format string
         return v;
     char v_str[64];
+    char fmt[32];
+    const char* fmt_end = ImParseFormatFindEnd(fmt_start);
+    IM_ASSERT(fmt_end - fmt_start < IM_ARRAYSIZE(fmt) && "Number format is too long!");
+#ifdef IMGUI_USE_STB_SPRINTF
+    // stb_sprintf.h supports several new modifiers which format numbers in a way that makes them incompatible with
+    // ImAtof()/ImAtoi(). Copy format string omitting incompatible modifiers and anything past the end of format specifier.
+    int fmt_len = 0;
+    for (int i = 0, end = fmt_end - fmt_start; i < end; i++)
+    {
+        char c = fmt_start[i];
+        if (c == '\'' || c == '$' || c == '_')                                  // Custom flags provided by stb_sprintf.h
+            continue;
+        fmt[fmt_len++] = c;
+    }
+    fmt[fmt_len] = 0;
+    fmt_start = fmt;
+#else
+    // Extra characters after format specifier may confuse ImAtof()/ImAtoi(), therefore copying is performed, excluding anything beyond.
+    if (*fmt_end != 0)
+    {
+        ImStrncpy(fmt, fmt_start, fmt_end - fmt_start + 1);
+        fmt_start = fmt;
+    }
+#endif
     ImFormatString(v_str, IM_ARRAYSIZE(v_str), fmt_start, v);
     const char* p = v_str;
     while (*p == ' ')