diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 1d7d3e4b6..d2493daf8 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -41,6 +41,8 @@ Other Changes: accidental alteration of window position. We now round the provided size. (#2067) - Nav, Focus: Fixed ImGuiWindowFlags_NoBringToFrontOnFocus windows not being restoring focus properly after the main menu bar or last focused window is deactivated. +- DragFloat: Fixed a situation where dragging with value rounding enabled or with a power curve + erroneously wrapped the value to one of the min/max edge. (#2024, #708, #320, #2075). ----------------------------------------------------------------------- diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 7fe4c16e6..0d9a576c5 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1708,9 +1708,10 @@ template bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const TYPE v_min, const TYPE v_max, const char* format, float power) { ImGuiContext& g = *GImGui; + const bool is_decimal = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double); + const bool has_min_max = (v_min != v_max) && (v_max - v_max < FLT_MAX); // Default tweak speed - bool has_min_max = (v_min != v_max) && (v_max - v_max < FLT_MAX); if (v_speed == 0.0f && has_min_max) v_speed = (float)((v_max - v_min) * g.DragSpeedDefaultRatio); @@ -1720,14 +1721,14 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const { adjust_delta = g.IO.MouseDelta.x; if (g.IO.KeyAlt) - adjust_delta *= 1.0f/100.0f; + adjust_delta *= 1.0f / 100.0f; if (g.IO.KeyShift) adjust_delta *= 10.0f; } else if (g.ActiveIdSource == ImGuiInputSource_Nav) { - int decimal_precision = (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) ? ImParseFormatPrecision(format, 3) : 0; - adjust_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard|ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 1.0f/10.0f, 10.0f).x; + int decimal_precision = is_decimal ? ImParseFormatPrecision(format, 3) : 0; + adjust_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard | ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 1.0f / 10.0f, 10.0f).x; v_speed = ImMax(v_speed, GetMinimumStepAtDecimalPrecision(decimal_precision)); } adjust_delta *= v_speed; @@ -1753,7 +1754,7 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const TYPE v_cur = *v; FLOATTYPE v_old_ref_for_accum_remainder = (FLOATTYPE)0.0f; - const bool is_power = (power != 1.0f && (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) && has_min_max); + const bool is_power = (power != 1.0f && is_decimal && has_min_max); if (is_power) { // Offset + round to user desired precision, with a curve on the v_min..v_max range to get more precision on one side of the range @@ -1786,12 +1787,12 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const if (v_cur == (TYPE)-0) v_cur = (TYPE)0; - // Clamp values (handle overflow/wrap-around) + // Clamp values (+ handle overflow/wrap-around for integer types) if (*v != v_cur && has_min_max) { - if (v_cur < v_min || (v_cur > *v && adjust_delta < 0.0f)) + if (v_cur < v_min || (v_cur > *v && adjust_delta < 0.0f && !is_decimal)) v_cur = v_min; - if (v_cur > v_max || (v_cur < *v && adjust_delta > 0.0f)) + if (v_cur > v_max || (v_cur < *v && adjust_delta > 0.0f && !is_decimal)) v_cur = v_max; }