@ -3929,46 +3929,39 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f
return true ;
}
static inline void InputTextUpdateUndoStateAfterUserCallback ( ImGuiInputTextState * state , const char * new_buf ) {
// Find the shortest single replacement we can make to get the new text
// from the old text.
ImWchar * old_buf = state - > TextW . Data ;
int old_length = state - > CurLenW ;
int new_length = ImTextCountCharsFromUtf8 ( new_buf , NULL ) ;
int shorter_length = ImMin ( old_length , new_length ) ;
int where = 0 ;
while ( where < shorter_length ) {
unsigned int b ;
ImTextCharFromUtf8 ( & b , new_buf + where , NULL ) ;
if ( old_buf [ where ] ! = b )
// Find the shortest single replacement we can make to get the new text from the old text.
// Important: needs to be run before TextW is rewritten with the new characters because calling STB_TEXTEDIT_GETCHAR() at the end.
// FIXME: Ideally we should transition toward (1) making InsertChars()/DeleteChars() update undo-stack (2) discourage (and keep reconcile) or obsolete (and remove reconcile) accessing buffer directly.
static void InputTextReconcileUndoStateAfterUserCallback ( ImGuiInputTextState * state , const char * new_buf_a , int new_length_a )
{
ImGuiContext & g = * GImGui ;
const ImWchar * old_buf = state - > TextW . Data ;
const int old_length = state - > CurLenW ;
const int new_length = ImTextCountCharsFromUtf8 ( new_buf_a , new_buf_a + new_length_a ) ;
g . TempBuffer . reserve_discard ( ( new_length + 1 ) * sizeof ( ImWchar ) ) ;
ImWchar * new_buf = ( ImWchar * ) ( void * ) g . TempBuffer . Data ;
ImTextStrFromUtf8 ( new_buf , new_length + 1 , new_buf_a , new_buf_a + new_length_a ) ;
const int shorter_length = ImMin ( old_length , new_length ) ;
int first_diff ;
for ( first_diff = 0 ; first_diff < shorter_length ; first_diff + + )
if ( old_buf [ first_diff ] ! = new_buf [ first_diff ] )
break ;
where + = 1 ;
}
if ( first_diff = = old_length & & first_diff = = new_length )
return ;
int old_last_diff = old_length - 1 ;
int new_last_diff = new_length - 1 ;
while ( old_last_diff > = where & & new_last_diff > = 0 ) {
unsigned int b ;
ImTextCharFromUtf8 ( & b , new_buf + new_last_diff , NULL ) ;
if ( old_buf [ old_last_diff ] ! = b )
for ( ; old_last_diff > = first_diff & & new_last_diff > = first_diff ; old_last_diff - - , new_last_diff - - )
if ( old_buf [ old_last_diff ] ! = new_buf [ new_last_diff ] )
break ;
old_last_diff - = 1 ;
new_last_diff - = 1 ;
}
int insert_len = new_last_diff - where + 1 ;
int delete_len = old_last_diff - where + 1 ;
if ( insert_len > 0 | | delete_len > 0 ) {
STB_TEXTEDIT_CHARTYPE * p = stb_text_createundo ( & state - > Stb . undostate , where , delete_len , insert_len ) ;
if ( p ) {
for ( int i = 0 ; i < delete_len ; + + i )
p [ i ] = ImStb : : STB_TEXTEDIT_GETCHAR ( state , where + i ) ;
}
}
const int insert_len = new_last_diff - first_diff + 1 ;
const int delete_len = old_last_diff - first_diff + 1 ;
if ( insert_len > 0 | | delete_len > 0 )
if ( STB_TEXTEDIT_CHARTYPE * p = stb_text_createundo ( & state - > Stb . undostate , first_diff , delete_len , insert_len ) )
for ( int i = 0 ; i < delete_len ; i + + )
p [ i ] = ImStb : : STB_TEXTEDIT_GETCHAR ( state , first_diff + i ) ;
}
// Edit a string of text
@ -4558,9 +4551,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
if ( buf_dirty )
{
IM_ASSERT ( callback_data . BufTextLen = = ( int ) strlen ( callback_data . Buf ) ) ; // You need to maintain BufTextLen if you change the text!
InputTextUpdat eUndoStateAfterUserCallback ( state , callback_data . Buf ) ;
InputTextReconcil eUndoStateAfterUserCallback ( state , callback_data . Buf , callback_data . BufTextLen ) ; // FIXME: Move the rest of this block inside function and rename to InputTextReconcileStateAfterUserCallback() ?
if ( callback_data . BufTextLen > backup_current_text_length & & is_resizable )
state - > TextW . resize ( state - > TextW . Size + ( callback_data . BufTextLen - backup_current_text_length ) ) ;
state - > TextW . resize ( state - > TextW . Size + ( callback_data . BufTextLen - backup_current_text_length ) ) ; // Worse case scenario resize
state - > CurLenW = ImTextStrFromUtf8 ( state - > TextW . Data , state - > TextW . Size , callback_data . Buf , NULL ) ;
state - > CurLenA = callback_data . BufTextLen ; // Assume correct length and valid UTF-8 from user, saves us an extra strlen()
state - > CursorAnimReset ( ) ;