From 6cdedf58347b9b267383ef06096e09e9fcc34e18 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 9 May 2023 12:04:04 +0200 Subject: [PATCH] Drag, Sliders: if the format string doesn't contain any %, when using CTRL+Click to input we use a default format. (#6405) --- docs/CHANGELOG.txt | 3 +++ imgui.h | 2 +- imgui_demo.cpp | 4 ++-- imgui_widgets.cpp | 14 ++++++++++---- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index ba15f843..112987d5 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -48,6 +48,9 @@ Other changes: initialized on VS2013. Unsure if due to a bug or UB/standard conformance). (#6377) - InputText: Avoid setting io.WantTextInputNextFrame during the deactivation frame. (#6341) [@lukaasm] +- Drag, Sliders: if the format string doesn't contain any %, CTRL+Click to input text will + use the default format specifier for the type. Allow display/input of raw value when using + "enums" patterns (display label instead of value) + allow using when value is hidden. (#6405) - Nav: Fixed navigation within tables/columns where item boundaries goes beyond columns limits, unclipped bounding boxes would interfere with other columns. (#2221) [@zzzyap, @ocornut] - Nav: Fixed CTRL+Tab into a root window with only childs with _NavFlattened flags diff --git a/imgui.h b/imgui.h index a450ffe2..2d71f854 100644 --- a/imgui.h +++ b/imgui.h @@ -23,7 +23,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM > 12345') #define IMGUI_VERSION "1.89.6 WIP" -#define IMGUI_VERSION_NUM 18954 +#define IMGUI_VERSION_NUM 18955 #define IMGUI_HAS_TABLE /* diff --git a/imgui_demo.cpp b/imgui_demo.cpp index af3000e4..908381e7 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -631,7 +631,7 @@ static void ShowDemoWindowWidgets() ImGui::Text("Tooltips:"); ImGui::SameLine(); - ImGui::SmallButton("Button"); + ImGui::SmallButton("Basic"); if (ImGui::IsItemHovered()) ImGui::SetTooltip("I am a tooltip"); @@ -744,7 +744,7 @@ static void ShowDemoWindowWidgets() static int elem = Element_Fire; const char* elems_names[Element_COUNT] = { "Fire", "Earth", "Air", "Water" }; const char* elem_name = (elem >= 0 && elem < Element_COUNT) ? elems_names[elem] : "Unknown"; - ImGui::SliderInt("slider enum", &elem, 0, Element_COUNT - 1, elem_name); + ImGui::SliderInt("slider enum", &elem, 0, Element_COUNT - 1, elem_name); // Use ImGuiSliderFlags_NoInput flag to disable CTRL+Click here. ImGui::SameLine(); HelpMarker("Using the format string parameter to display a name instead of the underlying integer."); } diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 31a1fa68..b7c5fca4 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -2090,7 +2090,8 @@ bool ImGui::DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void memcpy(&data_backup, p_data, type_info->Size); // Sanitize format - // For float/double we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in, so force them into %f and %lf + // - For float/double we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in, so force them into %f and %lf + // - In theory could treat empty format as using default, but this would only cover rare/bizarre case of using InputScalar() + integer + format string without %. char format_sanitized[32]; if (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) format = type_info->ScanFmt; @@ -3273,7 +3274,7 @@ const char* ImParseFormatFindEnd(const char* fmt) } // Extract the format out of a format string with leading or trailing decorations -// fmt = "blah blah" -> return fmt +// fmt = "blah blah" -> return "" // fmt = "%.3f" -> return fmt // fmt = "hello %.3f" -> return fmt + 6 // fmt = "%.3f hello" -> return buf written with "%.3f" @@ -3281,7 +3282,7 @@ const char* ImParseFormatTrimDecorations(const char* fmt, char* buf, size_t buf_ { const char* fmt_start = ImParseFormatFindStart(fmt); if (fmt_start[0] != '%') - return fmt; + return ""; const char* fmt_end = ImParseFormatFindEnd(fmt_start); if (fmt_end[0] == 0) // If we only have leading decoration, we don't need to copy the data. return fmt_start; @@ -3399,9 +3400,14 @@ static inline ImGuiInputTextFlags InputScalar_DefaultCharsFilter(ImGuiDataType d // However this may not be ideal for all uses, as some user code may break on out of bound values. bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* p_data, const char* format, const void* p_clamp_min, const void* p_clamp_max) { + // FIXME: May need to clarify display behavior if format doesn't contain %. + // "%d" -> "%d" / "There are %d items" -> "%d" / "items" -> "%d" (fallback). Also see #6405 + const ImGuiDataTypeInfo* type_info = DataTypeGetInfo(data_type); char fmt_buf[32]; char data_buf[32]; format = ImParseFormatTrimDecorations(format, fmt_buf, IM_ARRAYSIZE(fmt_buf)); + if (format[0] == 0) + format = type_info->PrintFmt; DataTypeFormatString(data_buf, IM_ARRAYSIZE(data_buf), data_type, p_data, format); ImStrTrimBlanks(data_buf); @@ -3412,7 +3418,7 @@ bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImG if (TempInputText(bb, id, label, data_buf, IM_ARRAYSIZE(data_buf), flags)) { // Backup old value - size_t data_type_size = DataTypeGetInfo(data_type)->Size; + size_t data_type_size = type_info->Size; ImGuiDataTypeTempStorage data_backup; memcpy(&data_backup, p_data, data_type_size);