@ -452,7 +452,8 @@
- settings : write more decent code to allow saving / loading new fields
- settings : write more decent code to allow saving / loading new fields
- settings : api for per - tool simple persistent data ( bool , int , float , columns sizes , etc . ) in . ini file
- settings : api for per - tool simple persistent data ( bool , int , float , columns sizes , etc . ) in . ini file
- style : store rounded corners in texture to use 1 quad per corner ( filled and wireframe ) . so rounding have minor cost .
- style : store rounded corners in texture to use 1 quad per corner ( filled and wireframe ) . so rounding have minor cost .
- style : colorbox not always square ?
- style : color - box not always square ?
- style : a concept of " compact style " that the end - user can easily rely on ( e . g . PushStyleCompact ( ) ? ) that maps that other settings ?
- text : simple markup language for color change ?
- text : simple markup language for color change ?
- log : LogButtons ( ) options for specifying depth and / or hiding depth slider
- log : LogButtons ( ) options for specifying depth and / or hiding depth slider
- log : have more control over the log scope ( e . g . stop logging when leaving current tree node scope )
- log : have more control over the log scope ( e . g . stop logging when leaving current tree node scope )
@ -7032,6 +7033,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
const ImGuiID id = window - > GetID ( label ) ;
const ImGuiID id = window - > GetID ( label ) ;
const bool is_multiline = ( flags & ImGuiInputTextFlags_Multiline ) ! = 0 ;
const bool is_multiline = ( flags & ImGuiInputTextFlags_Multiline ) ! = 0 ;
const bool is_editable = ( flags & ImGuiInputTextFlags_ReadOnly ) = = 0 ;
ImVec2 label_size = ImGui : : CalcTextSize ( label , NULL , true ) ;
ImVec2 label_size = ImGui : : CalcTextSize ( label , NULL , true ) ;
ImVec2 size = CalcItemSize ( size_arg , CalcItemWidth ( ) , is_multiline ? ImGui : : GetTextLineHeight ( ) * 8.0f : label_size . y ) ; // Arbitrary default of 8 lines high for multi-line
ImVec2 size = CalcItemSize ( size_arg , CalcItemWidth ( ) , is_multiline ? ImGui : : GetTextLineHeight ( ) * 8.0f : label_size . y ) ; // Arbitrary default of 8 lines high for multi-line
@ -7163,7 +7165,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
if ( g . IO . InputCharacters [ 0 ] )
if ( g . IO . InputCharacters [ 0 ] )
{
{
// Process text input (before we check for Return because using some IME will effectively send a Return?)
// Process text input (before we check for Return because using some IME will effectively send a Return?)
if ( ! is_ctrl_down & & ! is_alt_down )
if ( ! is_ctrl_down & & ! is_alt_down & & is_editable )
{
{
for ( int n = 0 ; n < IM_ARRAYSIZE ( g . IO . InputCharacters ) & & g . IO . InputCharacters [ n ] ; n + + )
for ( int n = 0 ; n < IM_ARRAYSIZE ( g . IO . InputCharacters ) & & g . IO . InputCharacters [ n ] ; n + + )
if ( unsigned int c = ( unsigned int ) g . IO . InputCharacters [ n ] )
if ( unsigned int c = ( unsigned int ) g . IO . InputCharacters [ n ] )
@ -7187,8 +7189,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
else if ( is_multiline & & IsKeyPressedMap ( ImGuiKey_DownArrow ) ) { if ( is_ctrl_down ) SetWindowScrollY ( draw_window , draw_window - > Scroll . y + g . FontSize ) ; else edit_state . OnKeyPressed ( STB_TEXTEDIT_K_DOWN | k_mask ) ; }
else if ( is_multiline & & IsKeyPressedMap ( ImGuiKey_DownArrow ) ) { if ( is_ctrl_down ) SetWindowScrollY ( draw_window , draw_window - > Scroll . y + g . FontSize ) ; else edit_state . OnKeyPressed ( STB_TEXTEDIT_K_DOWN | k_mask ) ; }
else if ( IsKeyPressedMap ( ImGuiKey_Home ) ) { edit_state . OnKeyPressed ( is_ctrl_down ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask ) ; }
else if ( IsKeyPressedMap ( ImGuiKey_Home ) ) { edit_state . OnKeyPressed ( is_ctrl_down ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask ) ; }
else if ( IsKeyPressedMap ( ImGuiKey_End ) ) { edit_state . OnKeyPressed ( is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask ) ; }
else if ( IsKeyPressedMap ( ImGuiKey_End ) ) { edit_state . OnKeyPressed ( is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask ) ; }
else if ( IsKeyPressedMap ( ImGuiKey_Delete ) ) { edit_state . OnKeyPressed ( STB_TEXTEDIT_K_DELETE | k_mask ) ; }
else if ( IsKeyPressedMap ( ImGuiKey_Delete ) & & is_editable ) { edit_state . OnKeyPressed ( STB_TEXTEDIT_K_DELETE | k_mask ) ; }
else if ( IsKeyPressedMap ( ImGuiKey_Backspace ) ) { edit_state . OnKeyPressed ( STB_TEXTEDIT_K_BACKSPACE | k_mask ) ; }
else if ( IsKeyPressedMap ( ImGuiKey_Backspace ) & & is_editable ) { edit_state . OnKeyPressed ( STB_TEXTEDIT_K_BACKSPACE | k_mask ) ; }
else if ( IsKeyPressedMap ( ImGuiKey_Enter ) )
else if ( IsKeyPressedMap ( ImGuiKey_Enter ) )
{
{
bool ctrl_enter_for_new_line = ( flags & ImGuiInputTextFlags_CtrlEnterForNewLine ) ! = 0 ;
bool ctrl_enter_for_new_line = ( flags & ImGuiInputTextFlags_CtrlEnterForNewLine ) ! = 0 ;
@ -7197,24 +7199,24 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
SetActiveID ( 0 ) ;
SetActiveID ( 0 ) ;
enter_pressed = true ;
enter_pressed = true ;
}
}
else // New line
else if ( is_editable ) // New line
{
{
unsigned int c = ' \n ' ;
unsigned int c = ' \n ' ;
if ( InputTextFilterCharacter ( & c , flags , callback , user_data ) )
if ( InputTextFilterCharacter ( & c , flags , callback , user_data ) )
edit_state . OnKeyPressed ( ( int ) c ) ;
edit_state . OnKeyPressed ( ( int ) c ) ;
}
}
}
}
else if ( ( flags & ImGuiInputTextFlags_AllowTabInput ) & & IsKeyPressedMap ( ImGuiKey_Tab ) & & ! is_ctrl_down & & ! is_shift_down & & ! is_alt_down )
else if ( ( flags & ImGuiInputTextFlags_AllowTabInput ) & & IsKeyPressedMap ( ImGuiKey_Tab ) & & ! is_ctrl_down & & ! is_shift_down & & ! is_alt_down & & is_editable )
{
{
unsigned int c = ' \t ' ;
unsigned int c = ' \t ' ;
if ( InputTextFilterCharacter ( & c , flags , callback , user_data ) )
if ( InputTextFilterCharacter ( & c , flags , callback , user_data ) )
edit_state . OnKeyPressed ( ( int ) c ) ;
edit_state . OnKeyPressed ( ( int ) c ) ;
}
}
else if ( IsKeyPressedMap ( ImGuiKey_Escape ) ) { SetActiveID ( 0 ) ; cancel_edit = true ; }
else if ( IsKeyPressedMap ( ImGuiKey_Escape ) ) { SetActiveID ( 0 ) ; cancel_edit = true ; }
else if ( is_ctrl_only & & IsKeyPressedMap ( ImGuiKey_Z ) ) { edit_state . OnKeyPressed ( STB_TEXTEDIT_K_UNDO ) ; edit_state . ClearSelection ( ) ; }
else if ( is_ctrl_only & & IsKeyPressedMap ( ImGuiKey_Z ) & & is_editable ) { edit_state . OnKeyPressed ( STB_TEXTEDIT_K_UNDO ) ; edit_state . ClearSelection ( ) ; }
else if ( is_ctrl_only & & IsKeyPressedMap ( ImGuiKey_Y ) ) { edit_state . OnKeyPressed ( STB_TEXTEDIT_K_REDO ) ; edit_state . ClearSelection ( ) ; }
else if ( is_ctrl_only & & IsKeyPressedMap ( ImGuiKey_Y ) & & is_editable ) { edit_state . OnKeyPressed ( STB_TEXTEDIT_K_REDO ) ; edit_state . ClearSelection ( ) ; }
else if ( is_ctrl_only & & IsKeyPressedMap ( ImGuiKey_A ) ) { edit_state . SelectAll ( ) ; edit_state . CursorFollow = true ; }
else if ( is_ctrl_only & & IsKeyPressedMap ( ImGuiKey_A ) ) { edit_state . SelectAll ( ) ; edit_state . CursorFollow = true ; }
else if ( is_ctrl_only & & ( IsKeyPressedMap ( ImGuiKey_X ) | | IsKeyPressedMap ( ImGuiKey_C ) ) & & ( ! is_multiline | | edit_state . HasSelection ( ) ) )
else if ( is_ctrl_only & & ( ( IsKeyPressedMap ( ImGuiKey_X ) & & is_editable ) | | IsKeyPressedMap ( ImGuiKey_C ) ) & & ( ! is_multiline | | edit_state . HasSelection ( ) ) )
{
{
// Cut, Copy
// Cut, Copy
const bool cut = IsKeyPressedMap ( ImGuiKey_X ) ;
const bool cut = IsKeyPressedMap ( ImGuiKey_X ) ;
@ -7236,7 +7238,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
stb_textedit_cut ( & edit_state , & edit_state . StbState ) ;
stb_textedit_cut ( & edit_state , & edit_state . StbState ) ;
}
}
}
}
else if ( is_ctrl_only & & IsKeyPressedMap ( ImGuiKey_V ) )
else if ( is_ctrl_only & & IsKeyPressedMap ( ImGuiKey_V ) & & is_editable )
{
{
// Paste
// Paste
if ( g . IO . GetClipboardTextFn )
if ( g . IO . GetClipboardTextFn )
@ -7271,8 +7273,11 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
if ( cancel_edit )
if ( cancel_edit )
{
{
// Restore initial value
// Restore initial value
ImFormatString ( buf , buf_size , " %s " , edit_state . InitialText . Data ) ;
if ( is_editable )
value_changed = true ;
{
ImFormatString ( buf , buf_size , " %s " , edit_state . InitialText . Data ) ;
value_changed = true ;
}
}
}
else
else
{
{
@ -7280,8 +7285,11 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
// Note that as soon as we can focus into the input box, the in-widget value gets priority over any underlying modification of the input buffer
// Note that as soon as we can focus into the input box, the in-widget value gets priority over any underlying modification of the input buffer
// FIXME: We actually always render 'buf' in RenderTextScrolledClipped
// FIXME: We actually always render 'buf' in RenderTextScrolledClipped
// FIXME-OPT: CPU waste to do this every time the widget is active, should mark dirty state from the stb_textedit callbacks
// FIXME-OPT: CPU waste to do this every time the widget is active, should mark dirty state from the stb_textedit callbacks
edit_state . TempTextBuffer . resize ( edit_state . Text . Size * 4 ) ;
if ( is_editable )
ImTextStrToUtf8 ( edit_state . TempTextBuffer . Data , edit_state . TempTextBuffer . Size , edit_state . Text . Data , NULL ) ;
{
edit_state . TempTextBuffer . resize ( edit_state . Text . Size * 4 ) ;
ImTextStrToUtf8 ( edit_state . TempTextBuffer . Data , edit_state . TempTextBuffer . Size , edit_state . Text . Data , NULL ) ;
}
// User callback
// User callback
if ( ( flags & ( ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory | ImGuiInputTextFlags_CallbackAlways ) ) ! = 0 )
if ( ( flags & ( ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory | ImGuiInputTextFlags_CallbackAlways ) ) ! = 0 )
@ -7311,12 +7319,14 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
{
{
ImGuiTextEditCallbackData callback_data ;
ImGuiTextEditCallbackData callback_data ;
callback_data . EventFlag = event_flag ;
callback_data . EventFlag = event_flag ;
callback_data . Flags = flags ;
callback_data . UserData = user_data ;
callback_data . ReadOnly = ! is_editable ;
callback_data . EventKey = event_key ;
callback_data . EventKey = event_key ;
callback_data . Buf = edit_state . TempTextBuffer . Data ;
callback_data . Buf = edit_state . TempTextBuffer . Data ;
callback_data . BufSize = edit_state . BufSizeA ;
callback_data . BufSize = edit_state . BufSizeA ;
callback_data . BufDirty = false ;
callback_data . BufDirty = false ;
callback_data . Flags = flags ;
callback_data . UserData = user_data ;
// We have to convert from position from wchar to UTF-8 positions
// We have to convert from position from wchar to UTF-8 positions
ImWchar * text = edit_state . Text . Data ;
ImWchar * text = edit_state . Text . Data ;
@ -7343,7 +7353,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
}
}
}
}
if ( strcmp( edit_state . TempTextBuffer . Data , buf ) ! = 0 )
if ( is_editable & & strcmp( edit_state . TempTextBuffer . Data , buf ) ! = 0 )
{
{
ImFormatString ( buf , buf_size , " %s " , edit_state . TempTextBuffer . Data ) ;
ImFormatString ( buf , buf_size , " %s " , edit_state . TempTextBuffer . Data ) ;
value_changed = true ;
value_changed = true ;
@ -7366,7 +7376,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
// - Display the text (this can be more easily clipped)
// - Display the text (this can be more easily clipped)
// - Handle scrolling, highlight selection, display cursor (those all requires some form of 1d->2d cursor position calculation)
// - Handle scrolling, highlight selection, display cursor (those all requires some form of 1d->2d cursor position calculation)
// - Measure text height (for scrollbar)
// - Measure text height (for scrollbar)
// We are attempting to do most of that in one main pass to minimize the computation cost (non-negligible for large amount of text) + 2nd pass for selection rendering (we could merge them by an extra refactoring effort)
// We are attempting to do most of that in ** one main pass** to minimize the computation cost (non-negligible for large amount of text) + 2nd pass for selection rendering (we could merge them by an extra refactoring effort)
const ImWchar * text_begin = edit_state . Text . Data ;
const ImWchar * text_begin = edit_state . Text . Data ;
const ImWchar * text_end = text_begin + edit_state . CurLenW ;
const ImWchar * text_end = text_begin + edit_state . CurLenW ;
ImVec2 cursor_offset , select_start_offset ;
ImVec2 cursor_offset , select_start_offset ;
@ -7485,7 +7495,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
draw_window - > DrawList - > AddLine ( cursor_screen_pos + ImVec2 ( 0.0f , - g . FontSize + 0.5f ) , cursor_screen_pos + ImVec2 ( 0.0f , - 1.5f ) , window - > Color ( ImGuiCol_Text ) ) ;
draw_window - > DrawList - > AddLine ( cursor_screen_pos + ImVec2 ( 0.0f , - g . FontSize + 0.5f ) , cursor_screen_pos + ImVec2 ( 0.0f , - 1.5f ) , window - > Color ( ImGuiCol_Text ) ) ;
// Notify OS of text input position for advanced IME
// Notify OS of text input position for advanced IME
if ( i o. ImeSetInputScreenPosFn & & ImLengthSqr ( edit_state . InputCursorScreenPos - cursor_screen_pos ) > 0.0001f )
if ( i s_editable & & i o. ImeSetInputScreenPosFn & & ImLengthSqr ( edit_state . InputCursorScreenPos - cursor_screen_pos ) > 0.0001f )
io . ImeSetInputScreenPosFn ( ( int ) cursor_screen_pos . x - 1 , ( int ) ( cursor_screen_pos . y - g . FontSize ) ) ; // -1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety.
io . ImeSetInputScreenPosFn ( ( int ) cursor_screen_pos . x - 1 , ( int ) ( cursor_screen_pos . y - g . FontSize ) ) ; // -1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety.
edit_state . InputCursorScreenPos = cursor_screen_pos ;
edit_state . InputCursorScreenPos = cursor_screen_pos ;