@ -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 ) / ( FLOAT TYPE) ( v_max - v_min ) ) ;
return ( float ) ( ( FLOATTYPE ) ( SIGNEDTYPE) ( v_clamped - v_min ) / ( FLOAT TYPE) ( SIGNED TYPE) ( 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
// - 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 ;
// - 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 ) ;