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.
This commit is contained in:
Rokas Kupstys
2020-11-19 18:01:01 +02:00
committed by ocornut
parent fdebb2e093
commit 8ee77f1b65
2 changed files with 30 additions and 2 deletions

View File

@ -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 == ' ')