1
0
mirror of https://github.com/Drezil/imgui.git synced 2025-04-26 13:04:00 +00:00

DragFloat/SliderFloat internal InputScalar relies on the user supplied format string to format and parse value. ()

The trailing text after the format will be displayed in the InputText but not affect back parsing. Ideally we can try to strip it later.
This commit is contained in:
omar 2018-04-30 11:08:45 +02:00
parent 429f48bb4f
commit d7e24416dd
2 changed files with 27 additions and 37 deletions

@ -748,7 +748,6 @@ static int InputTextCalcTextLenAndLineCount(const char* text_begin,
static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL, ImVec2* out_offset = NULL, bool stop_on_new_line = false); static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL, ImVec2* out_offset = NULL, bool stop_on_new_line = false);
static inline int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* data_ptr, const char* format); static inline int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* data_ptr, const char* format);
static inline int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* data_ptr, int decimal_precision);
static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, void* arg_1, const void* arg_2); static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, void* arg_1, const void* arg_2);
static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* format); static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* format);
@ -8454,30 +8453,6 @@ static inline int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType da
return 0; return 0;
} }
static inline int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* data_ptr, int decimal_precision)
{
if (decimal_precision < 0)
{
if (data_type == ImGuiDataType_Int)
return ImFormatString(buf, buf_size, "%d", *(const int*)data_ptr);
if (data_type == ImGuiDataType_Float)
return ImFormatString(buf, buf_size, "%f", *(const float*)data_ptr); // Ideally we'd have a minimum decimal precision of 1 to visually denote that it is a float, while hiding non-significant digits?
if (data_type == ImGuiDataType_Double)
return ImFormatString(buf, buf_size, "%f", *(const double*)data_ptr);
}
else
{
if (data_type == ImGuiDataType_Int)
return ImFormatString(buf, buf_size, "%.*d", decimal_precision, *(const int*)data_ptr);
if (data_type == ImGuiDataType_Float)
return ImFormatString(buf, buf_size, "%.*f", decimal_precision, *(const float*)data_ptr);
if (data_type == ImGuiDataType_Double)
return ImFormatString(buf, buf_size, "%.*g", decimal_precision, *(const double*)data_ptr);
}
IM_ASSERT(0);
return 0;
}
static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, void* arg1, const void* arg2) static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, void* arg1, const void* arg2)
{ {
IM_ASSERT(op == '+' || op == '-'); IM_ASSERT(op == '+' || op == '-');
@ -8582,7 +8557,7 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
// Create text input in place of a slider (when CTRL+Clicking on slider) // Create text input in place of a slider (when CTRL+Clicking on slider)
// FIXME: Logic is messy and confusing. // FIXME: Logic is messy and confusing.
bool ImGui::InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision) bool ImGui::InputScalarAsWidgetReplacement(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* data_ptr, const char* format)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
@ -8595,9 +8570,10 @@ bool ImGui::InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label
FocusableItemUnregister(window); FocusableItemUnregister(window);
char buf[32]; char buf[32];
DataTypeFormatString(buf, IM_ARRAYSIZE(buf), data_type, data_ptr, decimal_precision); format = ParseFormatSkipLeadingText(format);
DataTypeFormatString(buf, IM_ARRAYSIZE(buf), data_type, data_ptr, format);
ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | ((data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) ? ImGuiInputTextFlags_CharsScientific : ImGuiInputTextFlags_CharsDecimal); ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | ((data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) ? ImGuiInputTextFlags_CharsScientific : ImGuiInputTextFlags_CharsDecimal);
bool text_value_changed = InputTextEx(label, buf, IM_ARRAYSIZE(buf), aabb.GetSize(), flags); bool text_value_changed = InputTextEx(label, buf, IM_ARRAYSIZE(buf), bb.GetSize(), flags);
if (g.ScalarAsInputTextId == 0) // First frame we started displaying the InputText widget if (g.ScalarAsInputTextId == 0) // First frame we started displaying the InputText widget
{ {
IM_ASSERT(g.ActiveId == id); // InputText ID expected to match the Slider ID (else we'd need to store them both, which is also possible) IM_ASSERT(g.ActiveId == id); // InputText ID expected to match the Slider ID (else we'd need to store them both, which is also possible)
@ -8609,6 +8585,19 @@ bool ImGui::InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label
return false; return false;
} }
const char* ImGui::ParseFormatSkipLeadingText(const char* fmt)
{
if (fmt[0] == '%')
return fmt;
while (char c = fmt[0])
{
if (c == '%' && fmt[1] != '%')
return fmt;
fmt++;
}
return fmt;
}
// Parse display precision back from the display format string // Parse display precision back from the display format string
int ImGui::ParseFormatPrecision(const char* fmt, int default_precision) int ImGui::ParseFormatPrecision(const char* fmt, int default_precision)
{ {
@ -8880,7 +8869,7 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c
} }
} }
if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id)) if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id))
return InputScalarAsWidgetReplacement(frame_bb, label, ImGuiDataType_Float, v, id, decimal_precision); return InputScalarAsWidgetReplacement(frame_bb, id, label, ImGuiDataType_Float, v, format);
// Actual slider behavior + render grab // Actual slider behavior + render grab
ItemSize(total_bb, style.FramePadding.y); ItemSize(total_bb, style.FramePadding.y);
@ -9189,7 +9178,7 @@ bool ImGui::DragFloat(const char* label, float* v, float v_speed, float v_min, f
} }
} }
if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id)) if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id))
return InputScalarAsWidgetReplacement(frame_bb, label, ImGuiDataType_Float, v, id, decimal_precision); return InputScalarAsWidgetReplacement(frame_bb, id, label, ImGuiDataType_Float, v, format);
// Actual drag behavior // Actual drag behavior
ItemSize(total_bb, style.FramePadding.y); ItemSize(total_bb, style.FramePadding.y);

@ -1097,18 +1097,18 @@ namespace ImGui
IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos, float radius); IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos, float radius);
IMGUI_API bool SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, ImGuiSliderFlags flags = 0); IMGUI_API bool SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, ImGuiSliderFlags flags = 0);
IMGUI_API bool SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* display_format, float power); IMGUI_API bool SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* format, float power);
IMGUI_API bool SliderIntN(const char* label, int* v, int components, int v_min, int v_max, const char* display_format); IMGUI_API bool SliderIntN(const char* label, int* v, int components, int v_min, int v_max, const char* format);
IMGUI_API bool DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_speed, float v_min, float v_max, int decimal_precision, float power); IMGUI_API bool DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_speed, float v_min, float v_max, int decimal_precision, float power);
IMGUI_API bool DragFloatN(const char* label, float* v, int components, float v_speed, float v_min, float v_max, const char* display_format, float power); IMGUI_API bool DragFloatN(const char* label, float* v, int components, float v_speed, float v_min, float v_max, const char* format, float power);
IMGUI_API bool DragIntN(const char* label, int* v, int components, float v_speed, int v_min, int v_max, const char* display_format); IMGUI_API bool DragIntN(const char* label, int* v, int components, float v_speed, int v_min, int v_max, const char* format);
IMGUI_API bool InputTextEx(const char* label, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback = NULL, void* user_data = NULL); IMGUI_API bool InputTextEx(const char* label, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback = NULL, void* user_data = NULL);
IMGUI_API bool InputFloatN(const char* label, float* v, int components, const char* format, ImGuiInputTextFlags extra_flags); IMGUI_API bool InputFloatN(const char* label, float* v, int components, const char* format, ImGuiInputTextFlags extra_flags);
IMGUI_API bool InputIntN(const char* label, int* v, int components, ImGuiInputTextFlags extra_flags); IMGUI_API bool InputIntN(const char* label, int* v, int components, ImGuiInputTextFlags extra_flags);
IMGUI_API bool InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* scalar_format, ImGuiInputTextFlags extra_flags); IMGUI_API bool InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* format, ImGuiInputTextFlags extra_flags);
IMGUI_API bool InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision); IMGUI_API bool InputScalarAsWidgetReplacement(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* data_ptr, const char* format);
IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags); IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags);
IMGUI_API void ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags); IMGUI_API void ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags);
@ -1119,7 +1119,8 @@ namespace ImGui
IMGUI_API void PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size); IMGUI_API void PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size);
IMGUI_API int ParseFormatPrecision(const char* fmt, int default_value); IMGUI_API const char* ParseFormatSkipLeadingText(const char* format);
IMGUI_API int ParseFormatPrecision(const char* format, int default_value);
IMGUI_API float RoundScalar(float value, int decimal_precision); IMGUI_API float RoundScalar(float value, int decimal_precision);
// Shade functions (write over already created vertices) // Shade functions (write over already created vertices)