|
@@ -2094,9 +2094,9 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
|
|
|
logarithmic_zero_epsilon = ImPow(0.1f, (float)decimal_precision);
|
|
|
|
|
|
// Convert to parametric space, apply delta, convert back
|
|
|
- float v_old_parametric = ScaleRatioFromValueT<TYPE, FLOATTYPE>(data_type, v_cur, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
|
|
+ float v_old_parametric = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, v_cur, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
|
|
float v_new_parametric = v_old_parametric + g.DragCurrentAccum;
|
|
|
- v_cur = ScaleValueFromRatioT<TYPE, FLOATTYPE>(data_type, v_new_parametric, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
|
|
+ v_cur = ScaleValueFromRatioT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, v_new_parametric, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
|
|
v_old_ref_for_accum_remainder = v_old_parametric;
|
|
|
}
|
|
|
else
|
|
@@ -2113,7 +2113,7 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
|
|
|
if (is_logarithmic)
|
|
|
{
|
|
|
// Convert to parametric space, apply delta, convert back
|
|
|
- float v_new_parametric = ScaleRatioFromValueT<TYPE, FLOATTYPE>(data_type, v_cur, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
|
|
+ float v_new_parametric = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, v_cur, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
|
|
g.DragCurrentAccum -= (float)(v_new_parametric - v_old_ref_for_accum_remainder);
|
|
|
}
|
|
|
else
|
|
@@ -2449,7 +2449,7 @@ bool ImGui::DragScalarN(const char* label, ImGuiDataType data_type, void* p_data
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
|
// Convert a value v in the output space of a slider into a parametric position on the slider itself (the logical opposite of ScaleValueFromRatioT)
|
|
|
-template<typename TYPE, typename FLOATTYPE>
|
|
|
+template<typename TYPE, typename SIGNEDTYPE, typename FLOATTYPE>
|
|
|
float ImGui::ScaleRatioFromValueT(ImGuiDataType data_type, TYPE v, TYPE v_min, TYPE v_max, bool is_logarithmic, float logarithmic_zero_epsilon, float zero_deadzone_halfsize)
|
|
|
{
|
|
|
if (v_min == v_max)
|
|
@@ -2501,11 +2501,11 @@ float ImGui::ScaleRatioFromValueT(ImGuiDataType data_type, TYPE v, TYPE v_min, T
|
|
|
}
|
|
|
|
|
|
// Linear slider
|
|
|
- return (float)((FLOATTYPE)(v_clamped - v_min) / (FLOATTYPE)(v_max - v_min));
|
|
|
+ return (float)((FLOATTYPE)(SIGNEDTYPE)(v_clamped - v_min) / (FLOATTYPE)(SIGNEDTYPE)(v_max - v_min));
|
|
|
}
|
|
|
|
|
|
// Convert a parametric position on a slider into a value v in the output space (the logical opposite of ScaleRatioFromValueT)
|
|
|
-template<typename TYPE, typename FLOATTYPE>
|
|
|
+template<typename TYPE, typename SIGNEDTYPE, typename FLOATTYPE>
|
|
|
TYPE ImGui::ScaleValueFromRatioT(ImGuiDataType data_type, float t, TYPE v_min, TYPE v_max, bool is_logarithmic, float logarithmic_zero_epsilon, float zero_deadzone_halfsize)
|
|
|
{
|
|
|
if (v_min == v_max)
|
|
@@ -2564,15 +2564,19 @@ TYPE ImGui::ScaleValueFromRatioT(ImGuiDataType data_type, float t, TYPE v_min, T
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- // For integer values we want the clicking position to match the grab box so we round above
|
|
|
- // This code is carefully tuned to work with large values (e.g. high ranges of U64) while preserving this property..
|
|
|
- FLOATTYPE v_new_off_f = (v_max - v_min) * t;
|
|
|
- TYPE v_new_off_floor = (TYPE)(v_new_off_f);
|
|
|
- TYPE v_new_off_round = (TYPE)(v_new_off_f + (FLOATTYPE)0.5);
|
|
|
- if (v_new_off_floor < v_new_off_round)
|
|
|
- result = v_min + v_new_off_round;
|
|
|
+ // - For integer values we want the clicking position to match the grab box so we round above
|
|
|
+ // This code is carefully tuned to work with large values (e.g. high ranges of U64) while preserving this property..
|
|
|
+ // - Not doing a *1.0 multiply at the end of a range as it tends to be lossy. While absolute aiming at a large s64/u64
|
|
|
+ // range is going to be imprecise anyway, with this check we at least make the edge values matches expected limits.
|
|
|
+ if (t < 1.0)
|
|
|
+ {
|
|
|
+ FLOATTYPE v_new_off_f = (SIGNEDTYPE)(v_max - v_min) * t;
|
|
|
+ result = (TYPE)((SIGNEDTYPE)v_min + (SIGNEDTYPE)(v_new_off_f + (FLOATTYPE)(v_min > v_max ? -0.5 : 0.5)));
|
|
|
+ }
|
|
|
else
|
|
|
- result = v_min + v_new_off_floor;
|
|
|
+ {
|
|
|
+ result = v_max;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -2672,7 +2676,7 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
|
|
|
}
|
|
|
else if (g.SliderCurrentAccumDirty)
|
|
|
{
|
|
|
- clicked_t = ScaleRatioFromValueT<TYPE, FLOATTYPE>(data_type, *v, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
|
|
+ clicked_t = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, *v, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
|
|
|
|
|
if ((clicked_t >= 1.0f && delta > 0.0f) || (clicked_t <= 0.0f && delta < 0.0f)) // This is to avoid applying the saturation when already past the limits
|
|
|
{
|
|
@@ -2686,10 +2690,10 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
|
|
|
clicked_t = ImSaturate(clicked_t + delta);
|
|
|
|
|
|
// Calculate what our "new" clicked_t will be, and thus how far we actually moved the slider, and subtract this from the accumulator
|
|
|
- TYPE v_new = ScaleValueFromRatioT<TYPE, FLOATTYPE>(data_type, clicked_t, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
|
|
+ TYPE v_new = ScaleValueFromRatioT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, clicked_t, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
|
|
if (!(flags & ImGuiSliderFlags_NoRoundToFormat))
|
|
|
v_new = RoundScalarWithFormatT<TYPE, SIGNEDTYPE>(format, data_type, v_new);
|
|
|
- float new_clicked_t = ScaleRatioFromValueT<TYPE, FLOATTYPE>(data_type, v_new, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
|
|
+ float new_clicked_t = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, v_new, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
|
|
|
|
|
if (delta > 0)
|
|
|
g.SliderCurrentAccum -= ImMin(new_clicked_t - old_clicked_t, delta);
|
|
@@ -2703,7 +2707,7 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
|
|
|
|
|
|
if (set_new_value)
|
|
|
{
|
|
|
- TYPE v_new = ScaleValueFromRatioT<TYPE, FLOATTYPE>(data_type, clicked_t, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
|
|
+ TYPE v_new = ScaleValueFromRatioT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, clicked_t, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
|
|
|
|
|
// Round to user desired precision based on format string
|
|
|
if (!(flags & ImGuiSliderFlags_NoRoundToFormat))
|
|
@@ -2725,7 +2729,7 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
|
|
|
else
|
|
|
{
|
|
|
// Output grab position so it can be displayed by the caller
|
|
|
- float grab_t = ScaleRatioFromValueT<TYPE, FLOATTYPE>(data_type, *v, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
|
|
+ float grab_t = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, *v, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
|
|
if (axis == ImGuiAxis_Y)
|
|
|
grab_t = 1.0f - grab_t;
|
|
|
const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t);
|