@ -1997,14 +1997,13 @@ TYPE ImGui::RoundScalarWithFormatT(const char* format, ImGuiDataType data_type,
// This is called by DragBehavior() when the widget is active (held by mouse or being manipulated with Nav controls)
// This is called by DragBehavior() when the widget is active (held by mouse or being manipulated with Nav controls)
template < typename TYPE , typename SIGNEDTYPE , typename FLOATTYPE >
template < typename TYPE , typename SIGNEDTYPE , typename FLOATTYPE >
bool ImGui : : DragBehaviorT ( ImGuiDataType data_type , TYPE * v , float v_speed , const TYPE v_min , const TYPE v_max , const char * format , float power , ImGuiDragFlags flags )
bool ImGui : : DragBehaviorT ( ImGuiDataType data_type , TYPE * v , float v_speed , const TYPE v_min , const TYPE v_max , const char * format , ImGuiDragFlags flags )
{
{
ImGuiContext & g = * GImGui ;
ImGuiContext & g = * GImGui ;
const ImGuiAxis axis = ( flags & ImGuiDragFlags_Vertical ) ? ImGuiAxis_Y : ImGuiAxis_X ;
const ImGuiAxis axis = ( flags & ImGuiDragFlags_Vertical ) ? ImGuiAxis_Y : ImGuiAxis_X ;
const bool is_decimal = ( data_type = = ImGuiDataType_Float ) | | ( data_type = = ImGuiDataType_Double ) ;
const bool is_decimal = ( data_type = = ImGuiDataType_Float ) | | ( data_type = = ImGuiDataType_Double ) ;
const bool is_clamped = ( v_min < v_max ) ;
const bool is_clamped = ( v_min < v_max ) ;
const bool is_logarithmic = ( flags & ImGuiDragFlags_Logarithmic ) & & is_decimal ;
const bool is_logarithmic = ( flags & ImGuiDragFlags_Logarithmic ) & & is_decimal ;
const bool is_power = ( power ! = 1.0f & & ! is_logarithmic & & is_decimal & & is_clamped & & ( v_max - v_min < FLT_MAX ) ) ;
const bool is_locked = ( v_min > v_max ) ;
const bool is_locked = ( v_min > v_max ) ;
if ( is_locked )
if ( is_locked )
return false ;
return false ;
@ -2043,8 +2042,7 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
// Avoid altering values and clamping when we are _already_ past the limits and heading in the same direction, so e.g. if range is 0..255, current value is 300 and we are pushing to the right side, keep the 300.
// Avoid altering values and clamping when we are _already_ past the limits and heading in the same direction, so e.g. if range is 0..255, current value is 300 and we are pushing to the right side, keep the 300.
bool is_just_activated = g . ActiveIdIsJustActivated ;
bool is_just_activated = g . ActiveIdIsJustActivated ;
bool is_already_past_limits_and_pushing_outward = is_clamped & & ( ( * v > = v_max & & adjust_delta > 0.0f ) | | ( * v < = v_min & & adjust_delta < 0.0f ) ) ;
bool is_already_past_limits_and_pushing_outward = is_clamped & & ( ( * v > = v_max & & adjust_delta > 0.0f ) | | ( * v < = v_min & & adjust_delta < 0.0f ) ) ;
bool is_drag_direction_change_with_power = is_power & & ( ( adjust_delta < 0 & & g . DragCurrentAccum > 0 ) | | ( adjust_delta > 0 & & g . DragCurrentAccum < 0 ) ) ;
if ( is_just_activated | | is_already_past_limits_and_pushing_outward )
if ( is_just_activated | | is_already_past_limits_and_pushing_outward | | is_drag_direction_change_with_power )
{
{
g . DragCurrentAccum = 0.0f ;
g . DragCurrentAccum = 0.0f ;
g . DragCurrentAccumDirty = false ;
g . DragCurrentAccumDirty = false ;
@ -2069,20 +2067,11 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
logarithmic_zero_epsilon = ImPow ( 0.1f , ( float ) decimal_precision ) ;
logarithmic_zero_epsilon = ImPow ( 0.1f , ( float ) decimal_precision ) ;
// Convert to parametric space, apply delta, convert back
// Convert to parametric space, apply delta, convert back
// We pass 0.0f as linear_zero_pos because we know we are never in power mode here and so don't need it
float v_old_parametric = SliderCalcRatioFromValueT < TYPE , FLOATTYPE > ( data_type , v_cur , v_min , v_max , logarithmic_zero_epsilon , flags ) ;
float v_old_parametric = SliderCalcRatioFromValueT < TYPE , FLOATTYPE > ( data_type , v_cur , v_min , v_max , power , /*linear_zero_pos*/ 0.0f , logarithmic_zero_epsilon , flags ) ;
float v_new_parametric = v_old_parametric + g . DragCurrentAccum ;
float v_new_parametric = v_old_parametric + g . DragCurrentAccum ;
v_cur = SliderCalcValueFromRatioT < TYPE , FLOATTYPE > ( data_type , v_new_parametric , v_min , v_max , power, /*linear_zero_pos*/ 0.0f , logarithmic_zero_epsilon, flags ) ;
v_cur = SliderCalcValueFromRatioT < TYPE , FLOATTYPE > ( data_type , v_new_parametric , v_min , v_max , logarithmic_zero_epsilon, flags ) ;
v_old_ref_for_accum_remainder = v_old_parametric ;
v_old_ref_for_accum_remainder = v_old_parametric ;
}
}
else 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
FLOATTYPE v_old_norm_curved = ImPow ( ( FLOATTYPE ) ( v_cur - v_min ) / ( FLOATTYPE ) ( v_max - v_min ) , ( FLOATTYPE ) 1.0f / power ) ;
FLOATTYPE v_new_norm_curved = v_old_norm_curved + ( g . DragCurrentAccum / ( v_max - v_min ) ) ;
v_cur = v_min + ( SIGNEDTYPE ) ImPow ( ImSaturate ( ( float ) v_new_norm_curved ) , power ) * ( v_max - v_min ) ;
v_old_ref_for_accum_remainder = v_old_norm_curved ;
}
else
else
{
{
v_cur + = ( SIGNEDTYPE ) g . DragCurrentAccum ;
v_cur + = ( SIGNEDTYPE ) g . DragCurrentAccum ;
@ -2096,15 +2085,9 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
if ( is_logarithmic )
if ( is_logarithmic )
{
{
// Convert to parametric space, apply delta, convert back
// Convert to parametric space, apply delta, convert back
// We pass 0.0f as linear_zero_pos because we know we are never in power mode here and so don't need it
float v_new_parametric = SliderCalcRatioFromValueT < TYPE , FLOATTYPE > ( data_type , v_cur , v_min , v_max , logarithmic_zero_epsilon , flags ) ;
float v_new_parametric = SliderCalcRatioFromValueT < TYPE , FLOATTYPE > ( data_type , v_cur , v_min , v_max , power , /*linear_zero_pos*/ 0.0f , logarithmic_zero_epsilon , flags ) ;
g . DragCurrentAccum - = ( float ) ( v_new_parametric - v_old_ref_for_accum_remainder ) ;
g . DragCurrentAccum - = ( float ) ( v_new_parametric - v_old_ref_for_accum_remainder ) ;
}
}
else if ( is_power )
{
FLOATTYPE v_cur_norm_curved = ImPow ( ( FLOATTYPE ) ( v_cur - v_min ) / ( FLOATTYPE ) ( v_max - v_min ) , ( FLOATTYPE ) 1.0f / power ) ;
g . DragCurrentAccum - = ( float ) ( v_cur_norm_curved - v_old_ref_for_accum_remainder ) ;
}
else
else
{
{
g . DragCurrentAccum - = ( float ) ( ( SIGNEDTYPE ) v_cur - ( SIGNEDTYPE ) * v ) ;
g . DragCurrentAccum - = ( float ) ( ( SIGNEDTYPE ) v_cur - ( SIGNEDTYPE ) * v ) ;
@ -2130,9 +2113,10 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
return true ;
return true ;
}
}
bool ImGui : : DragBehavior ( ImGuiID id , ImGuiDataType data_type , void * p_v , float v_speed , const void * p_min , const void * p_max , const char * format , float power , ImGuiDragFlags flags )
bool ImGui : : DragBehavior ( ImGuiID id , ImGuiDataType data_type , void * p_v , float v_speed , const void * p_min , const void * p_max , const char * format , ImGuiDragFlags flags )
{
{
IM_ASSERT ( ( flags = = 1 | | ( flags & ImGuiDragFlags_InvalidMask_ ) = = 0 ) & & " Invalid ImGuiDragFlags flags! Has a power term been mistakenly cast to flags? " ) ;
// Read imgui.cpp "API BREAKING CHANGES" section for 1.78 if you hit this assert.
IM_ASSERT ( ( flags = = 1 | | ( flags & ImGuiDragFlags_InvalidMask_ ) = = 0 ) & & " Invalid ImGuiDragFlags flags! Has the 'float power' argument been mistakenly cast to flags? Call function with ImGuiDragFlags_Logarithmic flags instead. " ) ;
ImGuiContext & g = * GImGui ;
ImGuiContext & g = * GImGui ;
if ( g . ActiveId = = id )
if ( g . ActiveId = = id )
@ -2149,32 +2133,30 @@ bool ImGui::DragBehavior(ImGuiID id, ImGuiDataType data_type, void* p_v, float v
switch ( data_type )
switch ( data_type )
{
{
case ImGuiDataType_S8 : { ImS32 v32 = ( ImS32 ) * ( ImS8 * ) p_v ; bool r = DragBehaviorT < ImS32 , ImS32 , float > ( ImGuiDataType_S32 , & v32 , v_speed , p_min ? * ( const ImS8 * ) p_min : IM_S8_MIN , p_max ? * ( const ImS8 * ) p_max : IM_S8_MAX , format , power, flags) ; if ( r ) * ( ImS8 * ) p_v = ( ImS8 ) v32 ; return r ; }
case ImGuiDataType_S8 : { ImS32 v32 = ( ImS32 ) * ( ImS8 * ) p_v ; bool r = DragBehaviorT < ImS32 , ImS32 , float > ( ImGuiDataType_S32 , & v32 , v_speed , p_min ? * ( const ImS8 * ) p_min : IM_S8_MIN , p_max ? * ( const ImS8 * ) p_max : IM_S8_MAX , format , flags) ; if ( r ) * ( ImS8 * ) p_v = ( ImS8 ) v32 ; return r ; }
case ImGuiDataType_U8 : { ImU32 v32 = ( ImU32 ) * ( ImU8 * ) p_v ; bool r = DragBehaviorT < ImU32 , ImS32 , float > ( ImGuiDataType_U32 , & v32 , v_speed , p_min ? * ( const ImU8 * ) p_min : IM_U8_MIN , p_max ? * ( const ImU8 * ) p_max : IM_U8_MAX , format , power, flags) ; if ( r ) * ( ImU8 * ) p_v = ( ImU8 ) v32 ; return r ; }
case ImGuiDataType_U8 : { ImU32 v32 = ( ImU32 ) * ( ImU8 * ) p_v ; bool r = DragBehaviorT < ImU32 , ImS32 , float > ( ImGuiDataType_U32 , & v32 , v_speed , p_min ? * ( const ImU8 * ) p_min : IM_U8_MIN , p_max ? * ( const ImU8 * ) p_max : IM_U8_MAX , format , flags) ; if ( r ) * ( ImU8 * ) p_v = ( ImU8 ) v32 ; return r ; }
case ImGuiDataType_S16 : { ImS32 v32 = ( ImS32 ) * ( ImS16 * ) p_v ; bool r = DragBehaviorT < ImS32 , ImS32 , float > ( ImGuiDataType_S32 , & v32 , v_speed , p_min ? * ( const ImS16 * ) p_min : IM_S16_MIN , p_max ? * ( const ImS16 * ) p_max : IM_S16_MAX , format , power, flags) ; if ( r ) * ( ImS16 * ) p_v = ( ImS16 ) v32 ; return r ; }
case ImGuiDataType_S16 : { ImS32 v32 = ( ImS32 ) * ( ImS16 * ) p_v ; bool r = DragBehaviorT < ImS32 , ImS32 , float > ( ImGuiDataType_S32 , & v32 , v_speed , p_min ? * ( const ImS16 * ) p_min : IM_S16_MIN , p_max ? * ( const ImS16 * ) p_max : IM_S16_MAX , format , flags) ; if ( r ) * ( ImS16 * ) p_v = ( ImS16 ) v32 ; return r ; }
case ImGuiDataType_U16 : { ImU32 v32 = ( ImU32 ) * ( ImU16 * ) p_v ; bool r = DragBehaviorT < ImU32 , ImS32 , float > ( ImGuiDataType_U32 , & v32 , v_speed , p_min ? * ( const ImU16 * ) p_min : IM_U16_MIN , p_max ? * ( const ImU16 * ) p_max : IM_U16_MAX , format , power, flags) ; if ( r ) * ( ImU16 * ) p_v = ( ImU16 ) v32 ; return r ; }
case ImGuiDataType_U16 : { ImU32 v32 = ( ImU32 ) * ( ImU16 * ) p_v ; bool r = DragBehaviorT < ImU32 , ImS32 , float > ( ImGuiDataType_U32 , & v32 , v_speed , p_min ? * ( const ImU16 * ) p_min : IM_U16_MIN , p_max ? * ( const ImU16 * ) p_max : IM_U16_MAX , format , flags) ; if ( r ) * ( ImU16 * ) p_v = ( ImU16 ) v32 ; return r ; }
case ImGuiDataType_S32 : return DragBehaviorT < ImS32 , ImS32 , float > ( data_type , ( ImS32 * ) p_v , v_speed , p_min ? * ( const ImS32 * ) p_min : IM_S32_MIN , p_max ? * ( const ImS32 * ) p_max : IM_S32_MAX , format , power, flags) ;
case ImGuiDataType_S32 : return DragBehaviorT < ImS32 , ImS32 , float > ( data_type , ( ImS32 * ) p_v , v_speed , p_min ? * ( const ImS32 * ) p_min : IM_S32_MIN , p_max ? * ( const ImS32 * ) p_max : IM_S32_MAX , format , flags) ;
case ImGuiDataType_U32 : return DragBehaviorT < ImU32 , ImS32 , float > ( data_type , ( ImU32 * ) p_v , v_speed , p_min ? * ( const ImU32 * ) p_min : IM_U32_MIN , p_max ? * ( const ImU32 * ) p_max : IM_U32_MAX , format , power, flags) ;
case ImGuiDataType_U32 : return DragBehaviorT < ImU32 , ImS32 , float > ( data_type , ( ImU32 * ) p_v , v_speed , p_min ? * ( const ImU32 * ) p_min : IM_U32_MIN , p_max ? * ( const ImU32 * ) p_max : IM_U32_MAX , format , flags) ;
case ImGuiDataType_S64 : return DragBehaviorT < ImS64 , ImS64 , double > ( data_type , ( ImS64 * ) p_v , v_speed , p_min ? * ( const ImS64 * ) p_min : IM_S64_MIN , p_max ? * ( const ImS64 * ) p_max : IM_S64_MAX , format , power, flags) ;
case ImGuiDataType_S64 : return DragBehaviorT < ImS64 , ImS64 , double > ( data_type , ( ImS64 * ) p_v , v_speed , p_min ? * ( const ImS64 * ) p_min : IM_S64_MIN , p_max ? * ( const ImS64 * ) p_max : IM_S64_MAX , format , flags) ;
case ImGuiDataType_U64 : return DragBehaviorT < ImU64 , ImS64 , double > ( data_type , ( ImU64 * ) p_v , v_speed , p_min ? * ( const ImU64 * ) p_min : IM_U64_MIN , p_max ? * ( const ImU64 * ) p_max : IM_U64_MAX , format , power, flags) ;
case ImGuiDataType_U64 : return DragBehaviorT < ImU64 , ImS64 , double > ( data_type , ( ImU64 * ) p_v , v_speed , p_min ? * ( const ImU64 * ) p_min : IM_U64_MIN , p_max ? * ( const ImU64 * ) p_max : IM_U64_MAX , format , flags) ;
case ImGuiDataType_Float : return DragBehaviorT < float , float , float > ( data_type , ( float * ) p_v , v_speed , p_min ? * ( const float * ) p_min : - FLT_MAX , p_max ? * ( const float * ) p_max : FLT_MAX , format , power, flags) ;
case ImGuiDataType_Float : return DragBehaviorT < float , float , float > ( data_type , ( float * ) p_v , v_speed , p_min ? * ( const float * ) p_min : - FLT_MAX , p_max ? * ( const float * ) p_max : FLT_MAX , format , flags) ;
case ImGuiDataType_Double : return DragBehaviorT < double , double , double > ( data_type , ( double * ) p_v , v_speed , p_min ? * ( const double * ) p_min : - DBL_MAX , p_max ? * ( const double * ) p_max : DBL_MAX , format , power, flags) ;
case ImGuiDataType_Double : return DragBehaviorT < double , double , double > ( data_type , ( double * ) p_v , v_speed , p_min ? * ( const double * ) p_min : - DBL_MAX , p_max ? * ( const double * ) p_max : DBL_MAX , format , flags) ;
case ImGuiDataType_COUNT : break ;
case ImGuiDataType_COUNT : break ;
}
}
IM_ASSERT ( 0 ) ;
IM_ASSERT ( 0 ) ;
return false ;
return false ;
}
}
// Internal implementation - see below for entry points
// Note: p_data, p_min and p_max are _pointers_ to a memory address holding the data. For a Drag widget, p_min and p_max are optional.
bool ImGui : : DragScalarInternal ( const char * label , ImGuiDataType data_type , void * p_data , float v_speed , const void * p_min , const void * p_max , const char * format , float power , ImGuiDragFlags flags )
// Read code of e.g. DragFloat(), DragInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly.
bool ImGui : : DragScalar ( const char * label , ImGuiDataType data_type , void * p_data , float v_speed , const void * p_min , const void * p_max , const char * format , ImGuiDragFlags flags )
{
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
ImGuiWindow * window = GetCurrentWindow ( ) ;
if ( window - > SkipItems )
if ( window - > SkipItems )
return false ;
return false ;
if ( power ! = 1.0f )
IM_ASSERT ( p_min ! = NULL & & p_max ! = NULL ) ; // When using a power curve the drag needs to have known bounds
ImGuiContext & g = * GImGui ;
ImGuiContext & g = * GImGui ;
const ImGuiStyle & style = g . Style ;
const ImGuiStyle & style = g . Style ;
const ImGuiID id = window - > GetID ( label ) ;
const ImGuiID id = window - > GetID ( label ) ;
@ -2225,7 +2207,7 @@ bool ImGui::DragScalarInternal(const char* label, ImGuiDataType data_type, void*
RenderFrame ( frame_bb . Min , frame_bb . Max , frame_col , true , style . FrameRounding ) ;
RenderFrame ( frame_bb . Min , frame_bb . Max , frame_col , true , style . FrameRounding ) ;
// Drag behavior
// Drag behavior
const bool value_changed = DragBehavior ( id , data_type , p_data , v_speed , p_min , p_max , format , power, flags) ;
const bool value_changed = DragBehavior ( id , data_type , p_data , v_speed , p_min , p_max , format , flags) ;
if ( value_changed )
if ( value_changed )
MarkItemEdited ( id ) ;
MarkItemEdited ( id ) ;
@ -2241,15 +2223,7 @@ bool ImGui::DragScalarInternal(const char* label, ImGuiDataType data_type, void*
return value_changed ;
return value_changed ;
}
}
// Note: p_data, p_min and p_max are _pointers_ to a memory address holding the data. For a Drag widget, p_min and p_max are optional.
bool ImGui : : DragScalarN ( const char * label , ImGuiDataType data_type , void * p_data , int components , float v_speed , const void * p_min , const void * p_max , const char * format , ImGuiDragFlags flags )
// Read code of e.g. SliderFloat(), SliderInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly.
bool ImGui : : DragScalar ( const char * label , ImGuiDataType data_type , void * p_data , float v_speed , const void * p_min , const void * p_max , const char * format , ImGuiDragFlags flags )
{
return DragScalarInternal ( label , data_type , p_data , v_speed , p_min , p_max , format , 1.0f , flags ) ;
}
// Internal implementation - see below for entry points
bool ImGui : : DragScalarNInternal ( const char * label , ImGuiDataType data_type , void * p_data , int components , float v_speed , const void * p_min , const void * p_max , const char * format , float power , ImGuiDragFlags flags )
{
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
ImGuiWindow * window = GetCurrentWindow ( ) ;
if ( window - > SkipItems )
if ( window - > SkipItems )
@ -2266,7 +2240,7 @@ bool ImGui::DragScalarNInternal(const char* label, ImGuiDataType data_type, void
PushID ( i ) ;
PushID ( i ) ;
if ( i > 0 )
if ( i > 0 )
SameLine ( 0 , g . Style . ItemInnerSpacing . x ) ;
SameLine ( 0 , g . Style . ItemInnerSpacing . x ) ;
value_changed | = DragScalar Internal ( " " , data_type , p_data , v_speed , p_min , p_max , format , power , flags ) ;
value_changed | = DragScalar ( " " , data_type , p_data , v_speed , p_min , p_max , format , flags ) ;
PopID ( ) ;
PopID ( ) ;
PopItemWidth ( ) ;
PopItemWidth ( ) ;
p_data = ( void * ) ( ( char * ) p_data + type_size ) ;
p_data = ( void * ) ( ( char * ) p_data + type_size ) ;
@ -2284,11 +2258,6 @@ bool ImGui::DragScalarNInternal(const char* label, ImGuiDataType data_type, void
return value_changed ;
return value_changed ;
}
}
bool ImGui : : DragScalarN ( const char * label , ImGuiDataType data_type , void * p_data , int components , float v_speed , const void * p_min , const void * p_max , const char * format , ImGuiDragFlags flags )
{
return DragScalarNInternal ( label , data_type , p_data , components , v_speed , p_min , p_max , format , 1.0f , flags ) ;
}
bool ImGui : : DragFloat ( const char * label , float * v , float v_speed , float v_min , float v_max , const char * format , ImGuiDragFlags flags )
bool ImGui : : DragFloat ( const char * label , float * v , float v_speed , float v_min , float v_max , const char * format , ImGuiDragFlags flags )
{
{
return DragScalar ( label , ImGuiDataType_Float , v , v_speed , & v_min , & v_max , format , flags ) ;
return DragScalar ( label , ImGuiDataType_Float , v , v_speed , & v_min , & v_max , format , flags ) ;
@ -2309,8 +2278,7 @@ bool ImGui::DragFloat4(const char* label, float v[4], float v_speed, float v_min
return DragScalarN ( label , ImGuiDataType_Float , v , 4 , v_speed , & v_min , & v_max , format , flags ) ;
return DragScalarN ( label , ImGuiDataType_Float , v , 4 , v_speed , & v_min , & v_max , format , flags ) ;
}
}
// Internal implementation
bool ImGui : : DragFloatRange2 ( const char * label , float * v_current_min , float * v_current_max , float v_speed , float v_min , float v_max , const char * format , const char * format_max , ImGuiDragFlags flags )
bool ImGui : : DragFloatRange2Internal ( const char * label , float * v_current_min , float * v_current_max , float v_speed , float v_min , float v_max , const char * format , const char * format_max , float power , ImGuiDragFlags flags )
{
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
ImGuiWindow * window = GetCurrentWindow ( ) ;
if ( window - > SkipItems )
if ( window - > SkipItems )
@ -2324,14 +2292,14 @@ bool ImGui::DragFloatRange2Internal(const char* label, float* v_current_min, flo
float min = ( v_min > = v_max ) ? - FLT_MAX : v_min ;
float min = ( v_min > = v_max ) ? - FLT_MAX : v_min ;
float max = ( v_min > = v_max ) ? * v_current_max : ImMin ( v_max , * v_current_max ) ;
float max = ( v_min > = v_max ) ? * v_current_max : ImMin ( v_max , * v_current_max ) ;
if ( min = = max ) { min = FLT_MAX ; max = - FLT_MAX ; } // Lock edit
if ( min = = max ) { min = FLT_MAX ; max = - FLT_MAX ; } // Lock edit
bool value_changed = DragScalar Internal ( " ##min " , ImGuiDataType_Float , v_current_min , v_speed , & min , & max , format , power , flags ) ;
bool value_changed = DragScalar ( " ##min " , ImGuiDataType_Float , v_current_min , v_speed , & min , & max , format , flags ) ;
PopItemWidth ( ) ;
PopItemWidth ( ) ;
SameLine ( 0 , g . Style . ItemInnerSpacing . x ) ;
SameLine ( 0 , g . Style . ItemInnerSpacing . x ) ;
min = ( v_min > = v_max ) ? * v_current_min : ImMax ( v_min , * v_current_min ) ;
min = ( v_min > = v_max ) ? * v_current_min : ImMax ( v_min , * v_current_min ) ;
max = ( v_min > = v_max ) ? FLT_MAX : v_max ;
max = ( v_min > = v_max ) ? FLT_MAX : v_max ;
if ( min = = max ) { min = FLT_MAX ; max = - FLT_MAX ; } // Lock edit
if ( min = = max ) { min = FLT_MAX ; max = - FLT_MAX ; } // Lock edit
value_changed | = DragScalar Internal ( " ##max " , ImGuiDataType_Float , v_current_max , v_speed , & min , & max , format_max ? format_max : format , power , flags ) ;
value_changed | = DragScalar ( " ##max " , ImGuiDataType_Float , v_current_max , v_speed , & min , & max , format_max ? format_max : format , flags ) ;
PopItemWidth ( ) ;
PopItemWidth ( ) ;
SameLine ( 0 , g . Style . ItemInnerSpacing . x ) ;
SameLine ( 0 , g . Style . ItemInnerSpacing . x ) ;
@ -2341,11 +2309,6 @@ bool ImGui::DragFloatRange2Internal(const char* label, float* v_current_min, flo
return value_changed ;
return value_changed ;
}
}
bool ImGui : : DragFloatRange2 ( const char * label , float * v_current_min , float * v_current_max , float v_speed , float v_min , float v_max , const char * format , const char * format_max , ImGuiDragFlags flags )
{
return DragFloatRange2Internal ( label , v_current_min , v_current_max , v_speed , v_min , v_max , format , format_max , 1.0f , flags ) ;
}
// NB: v_speed is float to allow adjusting the drag speed with more precision
// NB: v_speed is float to allow adjusting the drag speed with more precision
bool ImGui : : DragInt ( const char * label , int * v , float v_speed , int v_min , int v_max , const char * format , ImGuiDragFlags flags )
bool ImGui : : DragInt ( const char * label , int * v , float v_speed , int v_min , int v_max , const char * format , ImGuiDragFlags flags )
{
{
@ -2401,40 +2364,29 @@ bool ImGui::DragIntRange2(const char* label, int* v_current_min, int* v_current_
# ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
# ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
// Obsolete versions with power parameter
// Obsolete versions with power parameter . See https://github.com/ocornut/imgui/issues/3361 for details.
bool ImGui : : DragScalar ( const char * label , ImGuiDataType data_type , void * p_data , float v_speed , const void * p_min , const void * p_max , const char * format , float power )
bool ImGui : : DragScalar ( const char * label , ImGuiDataType data_type , void * p_data , float v_speed , const void * p_min , const void * p_max , const char * format , float power )
{
{
return DragScalarInternal ( label , data_type , p_data , v_speed , p_min , p_max , format , power , ImGuiDragFlags_None ) ;
ImGuiDragFlags drag_flags = ImGuiDragFlags_None ;
if ( power ! = 1.0f )
{
IM_ASSERT ( power = = 1.0f & & " Call function with ImGuiDragFlags_Logarithmic flags instead of using the old 'float power' function! " ) ;
IM_ASSERT ( p_min ! = NULL & & p_max ! = NULL ) ; // When using a power curve the drag needs to have known bounds
drag_flags | = ImGuiDragFlags_Logarithmic ; // Fallback for non-asserting paths
}
return DragScalar ( label , data_type , p_data , v_speed , p_min , p_max , format , drag_flags ) ;
}
}
bool ImGui : : DragScalarN ( const char * label , ImGuiDataType data_type , void * p_data , int components , float v_speed , const void * p_min , const void * p_max , const char * format , float power )
bool ImGui : : DragScalarN ( const char * label , ImGuiDataType data_type , void * p_data , int components , float v_speed , const void * p_min , const void * p_max , const char * format , float power )
{
{
return DragScalarNInternal ( label , data_type , p_data , components , v_speed , p_min , p_max , format , power ) ;
ImGuiDragFlags drag_flags = ImGuiDragFlags_None ;
}
if ( power ! = 1.0f )
{
bool ImGui : : DragFloat ( const char * label , float * v , float v_speed , float v_min , float v_max , const char * format , float power )
IM_ASSERT ( power = = 1.0f & & " Call function with ImGuiDragFlags_Logarithmic flags instead of using the old 'float power' function! " ) ;
{
IM_ASSERT ( p_min ! = NULL & & p_max ! = NULL ) ; // When using a power curve the drag needs to have known bounds
return DragScalar ( label , ImGuiDataType_Float , v , v_speed , & v_min , & v_max , format , power ) ;
drag_flags | = ImGuiDragFlags_Logarithmic ; // Fallback for non-asserting paths
}
}
return DragScalarN ( label , data_type , p_data , components , v_speed , p_min , p_max , format , drag_flags ) ;
bool ImGui : : DragFloat2 ( const char * label , float v [ 2 ] , float v_speed , float v_min , float v_max , const char * format , float power )
{
return DragScalarN ( label , ImGuiDataType_Float , v , 2 , v_speed , & v_min , & v_max , format , power ) ;
}
bool ImGui : : DragFloat3 ( const char * label , float v [ 3 ] , float v_speed , float v_min , float v_max , const char * format , float power )
{
return DragScalarN ( label , ImGuiDataType_Float , v , 3 , v_speed , & v_min , & v_max , format , power ) ;
}
bool ImGui : : DragFloat4 ( const char * label , float v [ 4 ] , float v_speed , float v_min , float v_max , const char * format , float power )
{
return DragScalarN ( label , ImGuiDataType_Float , v , 4 , v_speed , & v_min , & v_max , format , power ) ;
}
bool ImGui : : DragFloatRange2 ( const char * label , float * v_current_min , float * v_current_max , float v_speed , float v_min , float v_max , const char * format , const char * format_max , float power )
{
return DragFloatRange2Internal ( label , v_current_min , v_current_max , v_speed , v_min , v_max , format , format_max , power ) ;
}
}
# endif // IMGUI_DISABLE_OBSOLETE_FUNCTIONS
# endif // IMGUI_DISABLE_OBSOLETE_FUNCTIONS
@ -2462,13 +2414,12 @@ bool ImGui::DragFloatRange2(const char* label, float* v_current_min, float* v_cu
// Convert a value v in the output space of a slider into a parametric position on the slider itself (the logical opposite of SliderCalcValueFromRatioT)
// Convert a value v in the output space of a slider into a parametric position on the slider itself (the logical opposite of SliderCalcValueFromRatioT)
template < typename TYPE , typename FLOATTYPE >
template < typename TYPE , typename FLOATTYPE >
float ImGui : : SliderCalcRatioFromValueT ( ImGuiDataType data_type , TYPE v , TYPE v_min , TYPE v_max , float power, float linear_zero_pos , float logarithmic_zero_epsilon, ImGuiSliderFlags flags )
float ImGui : : SliderCalcRatioFromValueT ( ImGuiDataType data_type , TYPE v , TYPE v_min , TYPE v_max , float logarithmic_zero_epsilon, ImGuiSliderFlags flags )
{
{
if ( v_min = = v_max )
if ( v_min = = v_max )
return 0.0f ;
return 0.0f ;
const bool is_logarithmic = ( flags & ImGuiSliderFlags_Logarithmic ) & & ( data_type = = ImGuiDataType_Float | | data_type = = ImGuiDataType_Double ) ;
const bool is_logarithmic = ( flags & ImGuiSliderFlags_Logarithmic ) & & ( data_type = = ImGuiDataType_Float | | data_type = = ImGuiDataType_Double ) ;
const bool is_power = ( power ! = 1.0f ) & & ( data_type = = ImGuiDataType_Float | | data_type = = ImGuiDataType_Double ) & & ( ! is_logarithmic ) ;
const TYPE v_clamped = ( v_min < v_max ) ? ImClamp ( v , v_min , v_max ) : ImClamp ( v , v_max , v_min ) ;
const TYPE v_clamped = ( v_min < v_max ) ? ImClamp ( v , v_min , v_max ) : ImClamp ( v , v_max , v_min ) ;
if ( is_logarithmic )
if ( is_logarithmic )
{
{
@ -2510,19 +2461,6 @@ float ImGui::SliderCalcRatioFromValueT(ImGuiDataType data_type, TYPE v, TYPE v_m
return flipped ? ( 1.0f - result ) : result ;
return flipped ? ( 1.0f - result ) : result ;
}
}
else if ( is_power )
{
if ( v_clamped < 0.0f )
{
const float f = 1.0f - ( float ) ( ( v_clamped - v_min ) / ( ImMin ( ( TYPE ) 0 , v_max ) - v_min ) ) ;
return ( 1.0f - ImPow ( f , 1.0f / power ) ) * linear_zero_pos ;
}
else
{
const float f = ( float ) ( ( v_clamped - ImMax ( ( TYPE ) 0 , v_min ) ) / ( v_max - ImMax ( ( TYPE ) 0 , v_min ) ) ) ;
return linear_zero_pos + ImPow ( f , 1.0f / power ) * ( 1.0f - linear_zero_pos ) ;
}
}
// Linear slider
// Linear slider
return ( float ) ( ( FLOATTYPE ) ( v_clamped - v_min ) / ( FLOATTYPE ) ( v_max - v_min ) ) ;
return ( float ) ( ( FLOATTYPE ) ( v_clamped - v_min ) / ( FLOATTYPE ) ( v_max - v_min ) ) ;
@ -2530,14 +2468,13 @@ float ImGui::SliderCalcRatioFromValueT(ImGuiDataType data_type, TYPE v, TYPE v_m
// Convert a parametric position on a slider into a value v in the output space (the logical opposite of SliderCalcRatioFromValueT)
// Convert a parametric position on a slider into a value v in the output space (the logical opposite of SliderCalcRatioFromValueT)
template < typename TYPE , typename FLOATTYPE >
template < typename TYPE , typename FLOATTYPE >
TYPE ImGui : : SliderCalcValueFromRatioT ( ImGuiDataType data_type , float t , TYPE v_min , TYPE v_max , float power, float linear_zero_pos , float logarithmic_zero_epsilon, ImGuiSliderFlags flags )
TYPE ImGui : : SliderCalcValueFromRatioT ( ImGuiDataType data_type , float t , TYPE v_min , TYPE v_max , float logarithmic_zero_epsilon, ImGuiSliderFlags flags )
{
{
if ( v_min = = v_max )
if ( v_min = = v_max )
return ( TYPE ) 0.0f ;
return ( TYPE ) 0.0f ;
const bool is_decimal = ( data_type = = ImGuiDataType_Float ) | | ( data_type = = ImGuiDataType_Double ) ;
const bool is_decimal = ( data_type = = ImGuiDataType_Float ) | | ( data_type = = ImGuiDataType_Double ) ;
const bool is_logarithmic = ( flags & ImGuiSliderFlags_Logarithmic ) & & ( data_type = = ImGuiDataType_Float | | data_type = = ImGuiDataType_Double ) ;
const bool is_logarithmic = ( flags & ImGuiSliderFlags_Logarithmic ) & & ( data_type = = ImGuiDataType_Float | | data_type = = ImGuiDataType_Double ) ;
const bool is_power = ( power ! = 1.0f ) & & ( data_type = = ImGuiDataType_Float | | data_type = = ImGuiDataType_Double ) & & ( ! is_logarithmic ) ;
TYPE result ;
TYPE result ;
if ( is_logarithmic )
if ( is_logarithmic )
@ -2580,28 +2517,6 @@ TYPE ImGui::SliderCalcValueFromRatioT(ImGuiDataType data_type, float t, TYPE v_m
result = ( TYPE ) ( v_min_fudged * ImPow ( v_max_fudged / v_min_fudged , ( FLOATTYPE ) t_with_flip ) ) ;
result = ( TYPE ) ( v_min_fudged * ImPow ( v_max_fudged / v_min_fudged , ( FLOATTYPE ) t_with_flip ) ) ;
}
}
}
}
else if ( is_power )
{
// Account for power curve scale on both sides of the zero
if ( t < linear_zero_pos )
{
// Negative: rescale to the negative range before powering
float a = 1.0f - ( t / linear_zero_pos ) ;
a = ImPow ( a , power ) ;
result = ImLerp ( ImMin ( v_max , ( TYPE ) 0 ) , v_min , a ) ;
}
else
{
// Positive: rescale to the positive range before powering
float a ;
if ( ImFabs ( linear_zero_pos - 1.0f ) > 1.e-6 f )
a = ( t - linear_zero_pos ) / ( 1.0f - linear_zero_pos ) ;
else
a = t ;
a = ImPow ( a , power ) ;
result = ImLerp ( ImMax ( v_min , ( TYPE ) 0 ) , v_max , a ) ;
}
}
else
else
{
{
// Linear slider
// Linear slider
@ -2628,7 +2543,7 @@ TYPE ImGui::SliderCalcValueFromRatioT(ImGuiDataType data_type, float t, TYPE v_m
// FIXME: Move some of the code into SliderBehavior(). Current responsibility is larger than what the equivalent DragBehaviorT<> does, we also do some rendering, etc.
// FIXME: Move some of the code into SliderBehavior(). Current responsibility is larger than what the equivalent DragBehaviorT<> does, we also do some rendering, etc.
template < typename TYPE , typename SIGNEDTYPE , typename FLOATTYPE >
template < typename TYPE , typename SIGNEDTYPE , typename FLOATTYPE >
bool ImGui : : SliderBehaviorT ( const ImRect & bb , ImGuiID id , ImGuiDataType data_type , TYPE * v , const TYPE v_min , const TYPE v_max , const char * format , float power , ImGuiSliderFlags flags , ImRect * out_grab_bb )
bool ImGui : : SliderBehaviorT ( const ImRect & bb , ImGuiID id , ImGuiDataType data_type , TYPE * v , const TYPE v_min , const TYPE v_max , const char * format , ImGuiSliderFlags flags , ImRect * out_grab_bb )
{
{
ImGuiContext & g = * GImGui ;
ImGuiContext & g = * GImGui ;
const ImGuiStyle & style = g . Style ;
const ImGuiStyle & style = g . Style ;
@ -2636,7 +2551,6 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
const ImGuiAxis axis = ( flags & ImGuiSliderFlags_Vertical ) ? ImGuiAxis_Y : ImGuiAxis_X ;
const ImGuiAxis axis = ( flags & ImGuiSliderFlags_Vertical ) ? ImGuiAxis_Y : ImGuiAxis_X ;
const bool is_decimal = ( data_type = = ImGuiDataType_Float ) | | ( data_type = = ImGuiDataType_Double ) ;
const bool is_decimal = ( data_type = = ImGuiDataType_Float ) | | ( data_type = = ImGuiDataType_Double ) ;
const bool is_logarithmic = ( flags & ImGuiSliderFlags_Logarithmic ) & & is_decimal ;
const bool is_logarithmic = ( flags & ImGuiSliderFlags_Logarithmic ) & & is_decimal ;
const bool is_power = ( power ! = 1.0f ) & & is_decimal & & ( ! is_logarithmic ) ;
const float grab_padding = 2.0f ;
const float grab_padding = 2.0f ;
const float slider_sz = ( bb . Max [ axis ] - bb . Min [ axis ] ) - grab_padding * 2.0f ;
const float slider_sz = ( bb . Max [ axis ] - bb . Min [ axis ] ) - grab_padding * 2.0f ;
@ -2649,21 +2563,6 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
const float slider_usable_pos_min = bb . Min [ axis ] + grab_padding + grab_sz * 0.5f ;
const float slider_usable_pos_min = bb . Min [ axis ] + grab_padding + grab_sz * 0.5f ;
const float slider_usable_pos_max = bb . Max [ axis ] - grab_padding - grab_sz * 0.5f ;
const float slider_usable_pos_max = bb . Max [ axis ] - grab_padding - grab_sz * 0.5f ;
// For power curve sliders that cross over sign boundary we want the curve to be symmetric around 0.0f
float linear_zero_pos ; // 0.0->1.0f
if ( is_power & & v_min * v_max < 0.0f )
{
// Different sign
const FLOATTYPE linear_dist_min_to_0 = ImPow ( v_min > = 0 ? ( FLOATTYPE ) v_min : - ( FLOATTYPE ) v_min , ( FLOATTYPE ) 1.0f / power ) ;
const FLOATTYPE linear_dist_max_to_0 = ImPow ( v_max > = 0 ? ( FLOATTYPE ) v_max : - ( FLOATTYPE ) v_max , ( FLOATTYPE ) 1.0f / power ) ;
linear_zero_pos = ( float ) ( linear_dist_min_to_0 / ( linear_dist_min_to_0 + linear_dist_max_to_0 ) ) ;
}
else
{
// Same sign
linear_zero_pos = v_min < 0.0f ? 1.0f : 0.0f ;
}
float logarithmic_zero_epsilon = 0.0f ; // Only valid when is_logarithmic is true
float logarithmic_zero_epsilon = 0.0f ; // Only valid when is_logarithmic is true
if ( is_logarithmic )
if ( is_logarithmic )
{
{
@ -2703,9 +2602,9 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
}
}
else if ( delta ! = 0.0f )
else if ( delta ! = 0.0f )
{
{
clicked_t = SliderCalcRatioFromValueT < TYPE , FLOATTYPE > ( data_type , * v , v_min , v_max , power, linear_zero_pos , logarithmic_zero_epsilon, flags ) ;
clicked_t = SliderCalcRatioFromValueT < TYPE , FLOATTYPE > ( data_type , * v , v_min , v_max , logarithmic_zero_epsilon, flags ) ;
const int decimal_precision = is_decimal ? ImParseFormatPrecision ( format , 3 ) : 0 ;
const int decimal_precision = is_decimal ? ImParseFormatPrecision ( format , 3 ) : 0 ;
if ( ( decimal_precision > 0 ) | | is_power )
if ( decimal_precision > 0 )
{
{
delta / = 100.0f ; // Gamepad/keyboard tweak speeds in % of slider bounds
delta / = 100.0f ; // Gamepad/keyboard tweak speeds in % of slider bounds
if ( IsNavInputDown ( ImGuiNavInput_TweakSlow ) )
if ( IsNavInputDown ( ImGuiNavInput_TweakSlow ) )
@ -2730,7 +2629,7 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
if ( set_new_value )
if ( set_new_value )
{
{
TYPE v_new = SliderCalcValueFromRatioT < TYPE , FLOATTYPE > ( data_type , clicked_t , v_min , v_max , power, linear_zero_pos , logarithmic_zero_epsilon, flags ) ;
TYPE v_new = SliderCalcValueFromRatioT < TYPE , FLOATTYPE > ( data_type , clicked_t , v_min , v_max , logarithmic_zero_epsilon, flags ) ;
// Round to user desired precision based on format string
// Round to user desired precision based on format string
v_new = RoundScalarWithFormatT < TYPE , SIGNEDTYPE > ( format , data_type , v_new ) ;
v_new = RoundScalarWithFormatT < TYPE , SIGNEDTYPE > ( format , data_type , v_new ) ;
@ -2751,7 +2650,7 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
else
else
{
{
// Output grab position so it can be displayed by the caller
// Output grab position so it can be displayed by the caller
float grab_t = SliderCalcRatioFromValueT < TYPE , FLOATTYPE > ( data_type , * v , v_min , v_max , power, linear_zero_pos , logarithmic_zero_epsilon, flags ) ;
float grab_t = SliderCalcRatioFromValueT < TYPE , FLOATTYPE > ( data_type , * v , v_min , v_max , logarithmic_zero_epsilon, flags ) ;
if ( axis = = ImGuiAxis_Y )
if ( axis = = ImGuiAxis_Y )
grab_t = 1.0f - grab_t ;
grab_t = 1.0f - grab_t ;
const float grab_pos = ImLerp ( slider_usable_pos_min , slider_usable_pos_max , grab_t ) ;
const float grab_pos = ImLerp ( slider_usable_pos_min , slider_usable_pos_max , grab_t ) ;
@ -2767,9 +2666,10 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
// For 32-bit and larger types, slider bounds are limited to half the natural type range.
// For 32-bit and larger types, slider bounds are limited to half the natural type range.
// So e.g. an integer Slider between INT_MAX-10 and INT_MAX will fail, but an integer Slider between INT_MAX/2-10 and INT_MAX/2 will be ok.
// So e.g. an integer Slider between INT_MAX-10 and INT_MAX will fail, but an integer Slider between INT_MAX/2-10 and INT_MAX/2 will be ok.
// It would be possible to lift that limitation with some work but it doesn't seem to be worth it for sliders.
// It would be possible to lift that limitation with some work but it doesn't seem to be worth it for sliders.
bool ImGui : : SliderBehavior ( const ImRect & bb , ImGuiID id , ImGuiDataType data_type , void * p_v , const void * p_min , const void * p_max , const char * format , float power , ImGuiSliderFlags flags , ImRect * out_grab_bb )
bool ImGui : : SliderBehavior ( const ImRect & bb , ImGuiID id , ImGuiDataType data_type , void * p_v , const void * p_min , const void * p_max , const char * format , ImGuiSliderFlags flags , ImRect * out_grab_bb )
{
{
IM_ASSERT ( ( flags = = 1 | | ( flags & ImGuiSliderFlags_InvalidMask_ ) = = 0 ) & & " Invalid ImGuiSliderFlags flag! Has a power term been mistakenly cast to flags? " ) ;
// Read imgui.cpp "API BREAKING CHANGES" section for 1.78 if you hit this assert.
IM_ASSERT ( ( flags = = 1 | | ( flags & ImGuiSliderFlags_InvalidMask_ ) = = 0 ) & & " Invalid ImGuiSliderFlags flag! Has the 'float power' argument been mistakenly cast to flags? Call function with ImGuiSliderFlags_Logarithmic flags instead. " ) ;
ImGuiContext & g = * GImGui ;
ImGuiContext & g = * GImGui ;
if ( g . CurrentWindow - > DC . ItemFlags & ImGuiItemFlags_ReadOnly )
if ( g . CurrentWindow - > DC . ItemFlags & ImGuiItemFlags_ReadOnly )
@ -2777,36 +2677,37 @@ bool ImGui::SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type
switch ( data_type )
switch ( data_type )
{
{
case ImGuiDataType_S8 : { ImS32 v32 = ( ImS32 ) * ( ImS8 * ) p_v ; bool r = SliderBehaviorT < ImS32 , ImS32 , float > ( bb , id , ImGuiDataType_S32 , & v32 , * ( const ImS8 * ) p_min , * ( const ImS8 * ) p_max , format , power, flags, out_grab_bb ) ; if ( r ) * ( ImS8 * ) p_v = ( ImS8 ) v32 ; return r ; }
case ImGuiDataType_S8 : { ImS32 v32 = ( ImS32 ) * ( ImS8 * ) p_v ; bool r = SliderBehaviorT < ImS32 , ImS32 , float > ( bb , id , ImGuiDataType_S32 , & v32 , * ( const ImS8 * ) p_min , * ( const ImS8 * ) p_max , format , flags, out_grab_bb ) ; if ( r ) * ( ImS8 * ) p_v = ( ImS8 ) v32 ; return r ; }
case ImGuiDataType_U8 : { ImU32 v32 = ( ImU32 ) * ( ImU8 * ) p_v ; bool r = SliderBehaviorT < ImU32 , ImS32 , float > ( bb , id , ImGuiDataType_U32 , & v32 , * ( const ImU8 * ) p_min , * ( const ImU8 * ) p_max , format , power, flags, out_grab_bb ) ; if ( r ) * ( ImU8 * ) p_v = ( ImU8 ) v32 ; return r ; }
case ImGuiDataType_U8 : { ImU32 v32 = ( ImU32 ) * ( ImU8 * ) p_v ; bool r = SliderBehaviorT < ImU32 , ImS32 , float > ( bb , id , ImGuiDataType_U32 , & v32 , * ( const ImU8 * ) p_min , * ( const ImU8 * ) p_max , format , flags, out_grab_bb ) ; if ( r ) * ( ImU8 * ) p_v = ( ImU8 ) v32 ; return r ; }
case ImGuiDataType_S16 : { ImS32 v32 = ( ImS32 ) * ( ImS16 * ) p_v ; bool r = SliderBehaviorT < ImS32 , ImS32 , float > ( bb , id , ImGuiDataType_S32 , & v32 , * ( const ImS16 * ) p_min , * ( const ImS16 * ) p_max , format , power, flags, out_grab_bb ) ; if ( r ) * ( ImS16 * ) p_v = ( ImS16 ) v32 ; return r ; }
case ImGuiDataType_S16 : { ImS32 v32 = ( ImS32 ) * ( ImS16 * ) p_v ; bool r = SliderBehaviorT < ImS32 , ImS32 , float > ( bb , id , ImGuiDataType_S32 , & v32 , * ( const ImS16 * ) p_min , * ( const ImS16 * ) p_max , format , flags, out_grab_bb ) ; if ( r ) * ( ImS16 * ) p_v = ( ImS16 ) v32 ; return r ; }
case ImGuiDataType_U16 : { ImU32 v32 = ( ImU32 ) * ( ImU16 * ) p_v ; bool r = SliderBehaviorT < ImU32 , ImS32 , float > ( bb , id , ImGuiDataType_U32 , & v32 , * ( const ImU16 * ) p_min , * ( const ImU16 * ) p_max , format , power, flags, out_grab_bb ) ; if ( r ) * ( ImU16 * ) p_v = ( ImU16 ) v32 ; return r ; }
case ImGuiDataType_U16 : { ImU32 v32 = ( ImU32 ) * ( ImU16 * ) p_v ; bool r = SliderBehaviorT < ImU32 , ImS32 , float > ( bb , id , ImGuiDataType_U32 , & v32 , * ( const ImU16 * ) p_min , * ( const ImU16 * ) p_max , format , flags, out_grab_bb ) ; if ( r ) * ( ImU16 * ) p_v = ( ImU16 ) v32 ; return r ; }
case ImGuiDataType_S32 :
case ImGuiDataType_S32 :
IM_ASSERT ( * ( const ImS32 * ) p_min > = IM_S32_MIN / 2 & & * ( const ImS32 * ) p_max < = IM_S32_MAX / 2 ) ;
IM_ASSERT ( * ( const ImS32 * ) p_min > = IM_S32_MIN / 2 & & * ( const ImS32 * ) p_max < = IM_S32_MAX / 2 ) ;
return SliderBehaviorT < ImS32 , ImS32 , float > ( bb , id , data_type , ( ImS32 * ) p_v , * ( const ImS32 * ) p_min , * ( const ImS32 * ) p_max , format , power, flags, out_grab_bb ) ;
return SliderBehaviorT < ImS32 , ImS32 , float > ( bb , id , data_type , ( ImS32 * ) p_v , * ( const ImS32 * ) p_min , * ( const ImS32 * ) p_max , format , flags, out_grab_bb ) ;
case ImGuiDataType_U32 :
case ImGuiDataType_U32 :
IM_ASSERT ( * ( const ImU32 * ) p_max < = IM_U32_MAX / 2 ) ;
IM_ASSERT ( * ( const ImU32 * ) p_max < = IM_U32_MAX / 2 ) ;
return SliderBehaviorT < ImU32 , ImS32 , float > ( bb , id , data_type , ( ImU32 * ) p_v , * ( const ImU32 * ) p_min , * ( const ImU32 * ) p_max , format , power, flags, out_grab_bb ) ;
return SliderBehaviorT < ImU32 , ImS32 , float > ( bb , id , data_type , ( ImU32 * ) p_v , * ( const ImU32 * ) p_min , * ( const ImU32 * ) p_max , format , flags, out_grab_bb ) ;
case ImGuiDataType_S64 :
case ImGuiDataType_S64 :
IM_ASSERT ( * ( const ImS64 * ) p_min > = IM_S64_MIN / 2 & & * ( const ImS64 * ) p_max < = IM_S64_MAX / 2 ) ;
IM_ASSERT ( * ( const ImS64 * ) p_min > = IM_S64_MIN / 2 & & * ( const ImS64 * ) p_max < = IM_S64_MAX / 2 ) ;
return SliderBehaviorT < ImS64 , ImS64 , double > ( bb , id , data_type , ( ImS64 * ) p_v , * ( const ImS64 * ) p_min , * ( const ImS64 * ) p_max , format , power, flags, out_grab_bb ) ;
return SliderBehaviorT < ImS64 , ImS64 , double > ( bb , id , data_type , ( ImS64 * ) p_v , * ( const ImS64 * ) p_min , * ( const ImS64 * ) p_max , format , flags, out_grab_bb ) ;
case ImGuiDataType_U64 :
case ImGuiDataType_U64 :
IM_ASSERT ( * ( const ImU64 * ) p_max < = IM_U64_MAX / 2 ) ;
IM_ASSERT ( * ( const ImU64 * ) p_max < = IM_U64_MAX / 2 ) ;
return SliderBehaviorT < ImU64 , ImS64 , double > ( bb , id , data_type , ( ImU64 * ) p_v , * ( const ImU64 * ) p_min , * ( const ImU64 * ) p_max , format , power, flags, out_grab_bb ) ;
return SliderBehaviorT < ImU64 , ImS64 , double > ( bb , id , data_type , ( ImU64 * ) p_v , * ( const ImU64 * ) p_min , * ( const ImU64 * ) p_max , format , flags, out_grab_bb ) ;
case ImGuiDataType_Float :
case ImGuiDataType_Float :
IM_ASSERT ( * ( const float * ) p_min > = - FLT_MAX / 2.0f & & * ( const float * ) p_max < = FLT_MAX / 2.0f ) ;
IM_ASSERT ( * ( const float * ) p_min > = - FLT_MAX / 2.0f & & * ( const float * ) p_max < = FLT_MAX / 2.0f ) ;
return SliderBehaviorT < float , float , float > ( bb , id , data_type , ( float * ) p_v , * ( const float * ) p_min , * ( const float * ) p_max , format , power, flags, out_grab_bb ) ;
return SliderBehaviorT < float , float , float > ( bb , id , data_type , ( float * ) p_v , * ( const float * ) p_min , * ( const float * ) p_max , format , flags, out_grab_bb ) ;
case ImGuiDataType_Double :
case ImGuiDataType_Double :
IM_ASSERT ( * ( const double * ) p_min > = - DBL_MAX / 2.0f & & * ( const double * ) p_max < = DBL_MAX / 2.0f ) ;
IM_ASSERT ( * ( const double * ) p_min > = - DBL_MAX / 2.0f & & * ( const double * ) p_max < = DBL_MAX / 2.0f ) ;
return SliderBehaviorT < double , double , double > ( bb , id , data_type , ( double * ) p_v , * ( const double * ) p_min , * ( const double * ) p_max , format , power, flags, out_grab_bb ) ;
return SliderBehaviorT < double , double , double > ( bb , id , data_type , ( double * ) p_v , * ( const double * ) p_min , * ( const double * ) p_max , format , flags, out_grab_bb ) ;
case ImGuiDataType_COUNT : break ;
case ImGuiDataType_COUNT : break ;
}
}
IM_ASSERT ( 0 ) ;
IM_ASSERT ( 0 ) ;
return false ;
return false ;
}
}
// Internal implementation
// Note: p_data, p_min and p_max are _pointers_ to a memory address holding the data. For a slider, they are all required.
bool ImGui : : SliderScalarInternal ( const char * label , ImGuiDataType data_type , void * p_data , const void * p_min , const void * p_max , const char * format , float power , ImGuiSliderFlags flags )
// Read code of e.g. SliderFloat(), SliderInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly.
bool ImGui : : SliderScalar ( const char * label , ImGuiDataType data_type , void * p_data , const void * p_min , const void * p_max , const char * format , ImGuiSliderFlags flags )
{
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
ImGuiWindow * window = GetCurrentWindow ( ) ;
if ( window - > SkipItems )
if ( window - > SkipItems )
@ -2863,7 +2764,7 @@ bool ImGui::SliderScalarInternal(const char* label, ImGuiDataType data_type, voi
// Slider behavior
// Slider behavior
ImRect grab_bb ;
ImRect grab_bb ;
const bool value_changed = SliderBehavior ( frame_bb , id , data_type , p_data , p_min , p_max , format , power, flags, & grab_bb ) ;
const bool value_changed = SliderBehavior ( frame_bb , id , data_type , p_data , p_min , p_max , format , flags, & grab_bb ) ;
if ( value_changed )
if ( value_changed )
MarkItemEdited ( id ) ;
MarkItemEdited ( id ) ;
@ -2883,14 +2784,8 @@ bool ImGui::SliderScalarInternal(const char* label, ImGuiDataType data_type, voi
return value_changed ;
return value_changed ;
}
}
// Note: p_data, p_min and p_max are _pointers_ to a memory address holding the data. For a slider, they are all required.
// Add multiple sliders on 1 line for compact edition of multiple components
// Read code of e.g. SliderFloat(), SliderInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly.
bool ImGui : : SliderScalarN ( const char * label , ImGuiDataType data_type , void * v , int components , const void * v_min , const void * v_max , const char * format , ImGuiSliderFlags flags )
bool ImGui : : SliderScalar ( const char * label , ImGuiDataType data_type , void * p_data , const void * p_min , const void * p_max , const char * format , ImGuiSliderFlags flags )
{
return SliderScalarInternal ( label , data_type , p_data , p_min , p_max , format , 1.0f , flags ) ;
}
bool ImGui : : SliderScalarNInternal ( const char * label , ImGuiDataType data_type , void * v , int components , const void * v_min , const void * v_max , const char * format , float power , ImGuiSliderFlags flags )
{
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
ImGuiWindow * window = GetCurrentWindow ( ) ;
if ( window - > SkipItems )
if ( window - > SkipItems )
@ -2907,7 +2802,7 @@ bool ImGui::SliderScalarNInternal(const char* label, ImGuiDataType data_type, vo
PushID ( i ) ;
PushID ( i ) ;
if ( i > 0 )
if ( i > 0 )
SameLine ( 0 , g . Style . ItemInnerSpacing . x ) ;
SameLine ( 0 , g . Style . ItemInnerSpacing . x ) ;
value_changed | = SliderScalar Internal ( " " , data_type , v , v_min , v_max , format , power , flags ) ;
value_changed | = SliderScalar ( " " , data_type , v , v_min , v_max , format , flags ) ;
PopID ( ) ;
PopID ( ) ;
PopItemWidth ( ) ;
PopItemWidth ( ) ;
v = ( void * ) ( ( char * ) v + type_size ) ;
v = ( void * ) ( ( char * ) v + type_size ) ;
@ -2925,12 +2820,6 @@ bool ImGui::SliderScalarNInternal(const char* label, ImGuiDataType data_type, vo
return value_changed ;
return value_changed ;
}
}
// Add multiple sliders on 1 line for compact edition of multiple components
bool ImGui : : SliderScalarN ( const char * label , ImGuiDataType data_type , void * v , int components , const void * v_min , const void * v_max , const char * format , ImGuiSliderFlags flags )
{
return SliderScalarNInternal ( label , data_type , v , components , v_min , v_max , format , 1.0f , flags ) ;
}
bool ImGui : : SliderFloat ( const char * label , float * v , float v_min , float v_max , const char * format , ImGuiSliderFlags flags )
bool ImGui : : SliderFloat ( const char * label , float * v , float v_min , float v_max , const char * format , ImGuiSliderFlags flags )
{
{
return SliderScalar ( label , ImGuiDataType_Float , v , & v_min , & v_max , format , flags ) ;
return SliderScalar ( label , ImGuiDataType_Float , v , & v_min , & v_max , format , flags ) ;
@ -2981,8 +2870,7 @@ bool ImGui::SliderInt4(const char* label, int v[4], int v_min, int v_max, const
return SliderScalarN ( label , ImGuiDataType_S32 , v , 4 , & v_min , & v_max , format , flags ) ;
return SliderScalarN ( label , ImGuiDataType_S32 , v , 4 , & v_min , & v_max , format , flags ) ;
}
}
// Internal implementation
bool ImGui : : VSliderScalar ( const char * label , const ImVec2 & size , ImGuiDataType data_type , void * p_data , const void * p_min , const void * p_max , const char * format , ImGuiSliderFlags flags )
bool ImGui : : VSliderScalarInternal ( const char * label , const ImVec2 & size , ImGuiDataType data_type , void * p_data , const void * p_min , const void * p_max , const char * format , float power , ImGuiSliderFlags flags )
{
{
ImGuiWindow * window = GetCurrentWindow ( ) ;
ImGuiWindow * window = GetCurrentWindow ( ) ;
if ( window - > SkipItems )
if ( window - > SkipItems )
@ -3022,7 +2910,7 @@ bool ImGui::VSliderScalarInternal(const char* label, const ImVec2& size, ImGuiDa
// Slider behavior
// Slider behavior
ImRect grab_bb ;
ImRect grab_bb ;
const bool value_changed = SliderBehavior ( frame_bb , id , data_type , p_data , p_min , p_max , format , power, flags | ImGuiSliderFlags_Vertical , & grab_bb ) ;
const bool value_changed = SliderBehavior ( frame_bb , id , data_type , p_data , p_min , p_max , format , flags | ImGuiSliderFlags_Vertical , & grab_bb ) ;
if ( value_changed )
if ( value_changed )
MarkItemEdited ( id ) ;
MarkItemEdited ( id ) ;
@ -3041,11 +2929,6 @@ bool ImGui::VSliderScalarInternal(const char* label, const ImVec2& size, ImGuiDa
return value_changed ;
return value_changed ;
}
}
bool ImGui : : VSliderScalar ( const char * label , const ImVec2 & size , ImGuiDataType data_type , void * p_data , const void * p_min , const void * p_max , const char * format , ImGuiSliderFlags flags )
{
return VSliderScalarInternal ( label , size , data_type , p_data , p_min , p_max , format , 1.0f , flags ) ;
}
bool ImGui : : VSliderFloat ( const char * label , const ImVec2 & size , float * v , float v_min , float v_max , const char * format , ImGuiSliderFlags flags )
bool ImGui : : VSliderFloat ( const char * label , const ImVec2 & size , float * v , float v_min , float v_max , const char * format , ImGuiSliderFlags flags )
{
{
return VSliderScalar ( label , size , ImGuiDataType_Float , v , & v_min , & v_max , format , flags ) ;
return VSliderScalar ( label , size , ImGuiDataType_Float , v , & v_min , & v_max , format , flags ) ;
@ -3058,45 +2941,27 @@ bool ImGui::VSliderInt(const char* label, const ImVec2& size, int* v, int v_min,
# ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
# ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
// Obsolete versions with power parameter
// Obsolete versions with power parameter . See https://github.com/ocornut/imgui/issues/3361 for details.
bool ImGui : : SliderScalar ( const char * label , ImGuiDataType data_type , void * p_data , const void * p_min , const void * p_max , const char * format , float power )
bool ImGui : : SliderScalar ( const char * label , ImGuiDataType data_type , void * p_data , const void * p_min , const void * p_max , const char * format , float power )
{
{
return SliderScalarInternal ( label , data_type , p_data , p_min , p_max , format , power ) ;
ImGuiSliderFlags slider_flags = ImGuiSliderFlags_None ;
if ( power ! = 1.0f )
{
IM_ASSERT ( power = = 1.0f & & " Call function with ImGuiSliderFlags_Logarithmic flags instead of using the old 'float power' function! " ) ;
slider_flags | = ImGuiSliderFlags_Logarithmic ; // Fallback for non-asserting paths
}
return SliderScalar ( label , data_type , p_data , p_min , p_max , format , slider_flags ) ;
}
}
bool ImGui : : SliderScalarN ( const char * label , ImGuiDataType data_type , void * v , int components , const void * v_min , const void * v_max , const char * format , float power )
bool ImGui : : SliderScalarN ( const char * label , ImGuiDataType data_type , void * v , int components , const void * v_min , const void * v_max , const char * format , float power )
{
{
return SliderScalarNInternal ( label , data_type , v , components , v_min , v_max , format , power ) ;
ImGuiSliderFlags slider_flags = ImGuiSliderFlags_None ;
}
if ( power ! = 1.0f )
{
bool ImGui : : SliderFloat ( const char * label , float * v , float v_min , float v_max , const char * format , float power )
IM_ASSERT ( power = = 1.0f & & " Call function with ImGuiSliderFlags_Logarithmic flags instead of using the old 'float power' function! " ) ;
{
slider_flags | = ImGuiSliderFlags_Logarithmic ; // Fallback for non-asserting paths
return SliderScalar ( label , ImGuiDataType_Float , v , & v_min , & v_max , format , power ) ;
}
}
return SliderScalarN ( label , data_type , v , components , v_min , v_max , format , slider_flags ) ;
bool ImGui : : SliderFloat2 ( const char * label , float v [ 2 ] , float v_min , float v_max , const char * format , float power )
{
return SliderScalarN ( label , ImGuiDataType_Float , v , 2 , & v_min , & v_max , format , power ) ;
}
bool ImGui : : SliderFloat3 ( const char * label , float v [ 3 ] , float v_min , float v_max , const char * format , float power )
{
return SliderScalarN ( label , ImGuiDataType_Float , v , 3 , & v_min , & v_max , format , power ) ;
}
bool ImGui : : SliderFloat4 ( const char * label , float v [ 4 ] , float v_min , float v_max , const char * format , float power )
{
return SliderScalarN ( label , ImGuiDataType_Float , v , 4 , & v_min , & v_max , format , power ) ;
}
bool ImGui : : VSliderScalar ( const char * label , const ImVec2 & size , ImGuiDataType data_type , void * p_data , const void * p_min , const void * p_max , const char * format , float power )
{
return VSliderScalarInternal ( label , size , data_type , p_data , p_min , p_max , format , power ) ;
}
bool ImGui : : VSliderFloat ( const char * label , const ImVec2 & size , float * v , float v_min , float v_max , const char * format , float power )
{
return VSliderScalar ( label , size , ImGuiDataType_Float , v , & v_min , & v_max , format , power ) ;
}
}
# endif // IMGUI_DISABLE_OBSOLETE_FUNCTIONS
# endif // IMGUI_DISABLE_OBSOLETE_FUNCTIONS