@ -725,7 +725,7 @@ static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const
static inline void DataTypeFormatString ( ImGuiDataType data_type , void * data_ptr , const char * display_format , char * buf , int buf_size ) ;
static inline void DataTypeFormatString ( ImGuiDataType data_type , void * data_ptr , int decimal_precision , char * buf , int buf_size ) ;
static void DataTypeApplyOp ( ImGuiDataType data_type , int op , void * value1, const void * value 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 * scalar_format ) ;
namespace ImGui
@ -8380,6 +8380,8 @@ static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr,
ImFormatString ( buf , buf_size , display_format , * ( int * ) data_ptr ) ;
else if ( data_type = = ImGuiDataType_Float )
ImFormatString ( buf , buf_size , display_format , * ( float * ) data_ptr ) ;
else if ( data_type = = ImGuiDataType_Double )
ImFormatString ( buf , buf_size , display_format , * ( double * ) data_ptr ) ;
}
static inline void DataTypeFormatString ( ImGuiDataType data_type , void * data_ptr , int decimal_precision , char * buf , int buf_size )
@ -8398,27 +8400,45 @@ static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr,
else
ImFormatString ( buf , buf_size , " %.*f " , decimal_precision , * ( float * ) data_ptr ) ;
}
else if ( data_type = = ImGuiDataType_Double )
{
if ( decimal_precision < 0 )
ImFormatString ( buf , buf_size , " %f " , * ( double * ) data_ptr ) ;
else
ImFormatString ( buf , buf_size , " %.*f " , decimal_precision , * ( double * ) data_ptr ) ;
}
}
static void DataTypeApplyOp ( ImGuiDataType data_type , int op , void * value1 , const void * value2 ) // Store into value1
static void DataTypeApplyOp ( ImGuiDataType data_type , int op , void * output, void * arg1 , const void * arg2 )
{
IM_ASSERT ( op = = ' + ' | | op = = ' - ' ) ;
if ( data_type = = ImGuiDataType_Int )
{
if ( op = = ' + ' )
* ( int * ) value1 = * ( int * ) value1 + * ( const int * ) value2 ;
else if ( op = = ' - ' )
* ( int * ) value1 = * ( int * ) value1 - * ( const int * ) value2 ;
if ( op = = ' + ' ) * ( int * ) output = * ( int * ) arg1 + * ( const int * ) arg2 ;
else if ( op = = ' - ' ) * ( int * ) output = * ( int * ) arg1 - * ( const int * ) arg2 ;
}
else if ( data_type = = ImGuiDataType_Float )
{
if ( op = = ' + ' )
* ( float * ) value1 = * ( float * ) value1 + * ( const float * ) value2 ;
else if ( op = = ' - ' )
* ( float * ) value1 = * ( float * ) value1 - * ( const float * ) value2 ;
if ( op = = ' + ' ) * ( float * ) output = * ( float * ) arg1 + * ( const float * ) arg2 ;
else if ( op = = ' - ' ) * ( float * ) output = * ( float * ) arg1 - * ( const float * ) arg2 ;
}
else if ( data_type = = ImGuiDataType_Double )
{
if ( op = = ' + ' ) * ( double * ) output = * ( double * ) arg1 + * ( const double * ) arg2 ;
else if ( op = = ' - ' ) * ( double * ) output = * ( double * ) arg1 - * ( const double * ) arg2 ;
}
}
static size_t GDataTypeSize [ ImGuiDataType_COUNT ] =
{
sizeof ( int ) ,
sizeof ( float ) ,
sizeof ( double ) ,
sizeof ( float ) * 2 ,
} ;
// User can input math operators (e.g. +100) to edit a numerical values.
// NB: This is _not_ a full expression evaluator. We should probably add one though..
static bool DataTypeApplyOpFromText ( const char * buf , const char * initial_value_buf , ImGuiDataType data_type , void * data_ptr , const char * scalar_format )
{
while ( ImCharIsSpace ( * buf ) )
@ -8440,45 +8460,56 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
if ( ! buf [ 0 ] )
return false ;
IM_ASSERT ( data_type < ImGuiDataType_COUNT ) ;
int data_backup [ 2 ] ;
IM_ASSERT ( GDataTypeSize [ data_type ] < = sizeof ( data_backup ) ) ;
memcpy ( data_backup , data_ptr , GDataTypeSize [ data_type ] ) ;
if ( data_type = = ImGuiDataType_Int )
{
if ( ! scalar_format )
scalar_format = " %d " ;
int * v = ( int * ) data_ptr ;
const int old_v = * v ;
int arg0i = * v ;
if ( op & & sscanf ( initial_value_buf , scalar_format , & arg0i ) < 1 )
return false ;
// Store operand in a float so we can use fractional value for multipliers (*1.1), but constant always parsed as integer so we can fit big integers (e.g. 2000000003) past float precision
float arg1f = 0.0f ;
if ( op = = ' + ' ) { if ( sscanf ( buf , " %f " , & arg1f ) = = 1 ) * v = ( int ) ( arg0i + arg1f ) ; } // Add (use "+-" to subtract)
else if ( op = = ' * ' ) { if ( sscanf ( buf , " %f " , & arg1f ) = = 1 ) * v = ( int ) ( arg0i * arg1f ) ; } // Multiply
else if ( op = = ' / ' ) { if ( sscanf ( buf , " %f " , & arg1f ) = = 1 & & arg1f ! = 0.0f ) * v = ( int ) ( arg0i / arg1f ) ; } // Divide
else { if ( sscanf ( buf , scalar_format , & arg0i ) = = 1 ) * v = arg0i ; } // Assign constant (read as integer so big values are not lossy)
return ( old_v ! = * v ) ;
else { if ( sscanf ( buf , scalar_format , & arg0i ) = = 1 ) * v = arg0i ; } // Assign integer constant
}
else if ( data_type = = ImGuiDataType_Float )
{
// For floats we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in
scalar_format = " %f " ;
float * v = ( float * ) data_ptr ;
const float old_v = * v ;
float arg0f = * v ;
float arg0f = * v , arg1f = 0.0f ;
if ( op & & sscanf ( initial_value_buf , scalar_format , & arg0f ) < 1 )
return false ;
float arg1f = 0.0f ;
if ( sscanf ( buf , scalar_format , & arg1f ) < 1 )
return false ;
if ( op = = ' + ' ) { * v = arg0f + arg1f ; } // Add (use "+-" to subtract)
else if ( op = = ' * ' ) { * v = arg0f * arg1f ; } // Multiply
else if ( op = = ' / ' ) { if ( arg1f ! = 0.0f ) * v = arg0f / arg1f ; } // Divide
else { * v = arg1f ; } // Assign constant
return ( old_v ! = * v ) ;
}
return false ;
else if ( data_type = = ImGuiDataType_Double )
{
scalar_format = " %lf " ;
double * v = ( double * ) data_ptr ;
double arg0f = * v , arg1f = 0.0f ;
if ( op & & sscanf ( initial_value_buf , scalar_format , & arg0f ) < 1 )
return false ;
if ( sscanf ( buf , scalar_format , & arg1f ) < 1 )
return false ;
if ( op = = ' + ' ) { * v = arg0f + arg1f ; } // Add (use "+-" to subtract)
else if ( op = = ' * ' ) { * v = arg0f * arg1f ; } // Multiply
else if ( op = = ' / ' ) { if ( arg1f ! = 0.0f ) * v = arg0f / arg1f ; } // Divide
else { * v = arg1f ; } // Assign constant
}
return memcmp ( data_backup , data_ptr , GDataTypeSize [ data_type ] ) ! = 0 ;
}
// Create text input in place of a slider (when CTRL+Clicking on slider)
@ -10463,13 +10494,13 @@ bool ImGui::InputScalarEx(const char* label, ImGuiDataType data_type, void* data
SameLine ( 0 , style . ItemInnerSpacing . x ) ;
if ( ButtonEx ( " - " , button_sz , ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups ) )
{
DataTypeApplyOp ( data_type , ' - ' , data_ptr , g. IO . KeyCtrl & & step_fast_ptr ? step_fast_ptr : step_ptr ) ;
DataTypeApplyOp ( data_type , ' - ' , data_ptr , data_ptr, g. IO . KeyCtrl & & step_fast_ptr ? step_fast_ptr : step_ptr ) ;
value_changed = true ;
}
SameLine ( 0 , style . ItemInnerSpacing . x ) ;
if ( ButtonEx ( " + " , button_sz , ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups ) )
{
DataTypeApplyOp ( data_type , ' + ' , data_ptr , g. IO . KeyCtrl & & step_fast_ptr ? step_fast_ptr : step_ptr ) ;
DataTypeApplyOp ( data_type , ' + ' , data_ptr , data_ptr, g. IO . KeyCtrl & & step_fast_ptr ? step_fast_ptr : step_ptr ) ;
value_changed = true ;
}
}
@ -10488,13 +10519,24 @@ bool ImGui::InputScalarEx(const char* label, ImGuiDataType data_type, void* data
bool ImGui : : InputFloat ( const char * label , float * v , float step , float step_fast , int decimal_precision , ImGuiInputTextFlags extra_flags )
{
char display_format [ 16 ] ;
extra_flags | = ImGuiInputTextFlags_CharsScientific ;
if ( decimal_precision < 0 )
strcpy ( display_format , " %f " ) ; // Ideally we'd have a minimum decimal precision of 1 to visually denote that this is a float, while hiding non-significant digits? %f doesn't have a minimum of 1
{
// Ideally we'd have a minimum decimal precision of 1 to visually denote that this is a float, while hiding non-significant digits? %f doesn't have a minimum of 1
return InputScalarEx ( label , ImGuiDataType_Float , ( void * ) v , ( void * ) ( step > 0.0f ? & step : NULL ) , ( void * ) ( step_fast > 0.0f ? & step_fast : NULL ) , " %f " , extra_flags ) ;
}
else
{
char display_format [ 16 ] ;
ImFormatString ( display_format , IM_ARRAYSIZE ( display_format ) , " %%.%df " , decimal_precision ) ;
return InputScalarEx ( label , ImGuiDataType_Float , ( void * ) v , ( void * ) ( step > 0.0f ? & step : NULL ) , ( void * ) ( step_fast > 0.0f ? & step_fast : NULL ) , display_format , extra_flags ) ;
}
}
bool ImGui : : InputDouble ( const char * label , double * v , double step , double step_fast , const char * display_format , ImGuiInputTextFlags extra_flags )
{
extra_flags | = ImGuiInputTextFlags_CharsScientific ;
return InputScalarEx ( label , ImGuiDataType_Float , ( void * ) v , ( void * ) ( step > 0.0f ? & step : NULL ) , ( void * ) ( step_fast > 0.0f ? & step_fast : NULL ) , display_format , extra_flags ) ;
return InputScalarEx ( label , ImGuiDataType_ Double , ( void * ) v , ( void * ) ( step > 0.0 ? & step : NULL ) , ( void * ) ( step_fast > 0.0 ? & step_fast : NULL ) , display_format , extra_flags ) ;
}
bool ImGui : : InputInt ( const char * label , int * v , int step , int step_fast , ImGuiInputTextFlags extra_flags )