@ -3679,17 +3679,18 @@ static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, ImGuiInputTextState* ob
}
// When ImGuiInputTextFlags_Password is set, we don't want actions such as CTRL+Arrow to leak the fact that underlying data are blanks or separators.
static bool is_separator ( unsigned int c ) { return ImCharIsBlankW ( c ) | | c = = ' , ' | | c = = ' ; ' | | c = = ' ( ' | | c = = ' ) ' | | c = = ' { ' | | c = = ' } ' | | c = = ' [ ' | | c = = ' ] ' | | c = = ' | ' ; }
static bool is_separator ( unsigned int c ) { return ImCharIsBlankW ( c ) | | c = = ' , ' | | c = = ' ; ' | | c = = ' ( ' | | c = = ' ) ' | | c = = ' { ' | | c = = ' } ' | | c = = ' [ ' | | c = = ' ] ' | | c = = ' | ' | | c = = ' \n ' | | c = = ' \r ' ; }
static int is_word_boundary_from_right ( ImGuiInputTextState * obj , int idx ) { if ( obj - > Flags & ImGuiInputTextFlags_Password ) return 0 ; return idx > 0 ? ( is_separator ( obj - > TextW [ idx - 1 ] ) & & ! is_separator ( obj - > TextW [ idx ] ) ) : 1 ; }
static int is_word_boundary_from_left ( ImGuiInputTextState * obj , int idx ) { if ( obj - > Flags & ImGuiInputTextFlags_Password ) return 0 ; return idx > 0 ? ( ! is_separator ( obj - > TextW [ idx - 1 ] ) & & is_separator ( obj - > TextW [ idx ] ) ) : 1 ; }
static int STB_TEXTEDIT_MOVEWORDLEFT_IMPL ( ImGuiInputTextState * obj , int idx ) { idx - - ; while ( idx > = 0 & & ! is_word_boundary_from_right ( obj , idx ) ) idx - - ; return idx < 0 ? 0 : idx ; }
static int STB_TEXTEDIT_MOVEWORDRIGHT_MAC ( ImGuiInputTextState * obj , int idx ) { idx + + ; int len = obj - > CurLenW ; while ( idx < len & & ! is_word_boundary_from_left ( obj , idx ) ) idx + + ; return idx > len ? len : idx ; }
static int STB_TEXTEDIT_MOVEWORDRIGHT_WIN ( ImGuiInputTextState * obj , int idx ) { idx + + ; int len = obj - > CurLenW ; while ( idx < len & & ! is_word_boundary_from_right ( obj , idx ) ) idx + + ; return idx > len ? len : idx ; }
# define STB_TEXTEDIT_MOVEWORDLEFT STB_TEXTEDIT_MOVEWORDLEFT_IMPL // They need to be #define for stb_textedit.h
# ifdef __APPLE__ // FIXME: Move setting to IO structure
static int is_word_boundary_from_left ( ImGuiInputTextState * obj , int idx ) { if ( obj - > Flags & ImGuiInputTextFlags_Password ) return 0 ; return idx > 0 ? ( ! is_separator ( obj - > TextW [ idx - 1 ] ) & & is_separator ( obj - > TextW [ idx ] ) ) : 1 ; }
static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL ( ImGuiInputTextState * obj , int idx ) { idx + + ; int len = obj - > CurLenW ; while ( idx < len & & ! is_word_boundary_from_left ( obj , idx ) ) idx + + ; return idx > len ? len : idx ; }
# define STB_TEXTEDIT_MOVEWORDRIGHT STB_TEXTEDIT_MOVEWORDRIGHT_MAC
# else
static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL ( ImGuiInputTextState * obj , int idx ) { idx + + ; int len = obj - > CurLenW ; while ( idx < len & & ! is_word_boundary_from_right ( obj , idx ) ) idx + + ; return idx > len ? len : idx ; }
# define STB_TEXTEDIT_MOVEWORDRIGHT STB_TEXTEDIT_MOVEWORDRIGHT_WIN
# endif
# define STB_TEXTEDIT_MOVEWORDLEFT STB_TEXTEDIT_MOVEWORDLEFT_IMPL // They need to be #define for stb_textedit.h
# define STB_TEXTEDIT_MOVEWORDRIGHT STB_TEXTEDIT_MOVEWORDRIGHT_IMPL
static void STB_TEXTEDIT_DELETECHARS ( ImGuiInputTextState * obj , int pos , int n )
{
@ -3881,11 +3882,12 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f
// Generic named filters
if ( apply_named_filters & & ( flags & ( ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_CharsScientific ) ) )
{
// The libc allows overriding locale, with e.g. 'setlocale(LC_NUMERIC, "de_DE.UTF-8");' which affect the output/input of printf/scanf.
// The libc allows overriding locale, with e.g. 'setlocale(LC_NUMERIC, "de_DE.UTF-8");' which affect the output/input of printf/scanf to use e.g. ',' instead of '.' .
// The standard mandate that programs starts in the "C" locale where the decimal point is '.'.
// We don't really intend to provide widespread support for it, but out of empathy for people stuck with using odd API, we support the bare minimum aka overriding the decimal point.
// Change the default decimal_point with:
// ImGui::GetCurrentContext()->PlatformLocaleDecimalPoint = *localeconv()->decimal_point;
// Users of non-default decimal point (in particular ',') may be affected by word-selection logic (is_word_boundary_from_right/is_word_boundary_from_left) functions.
ImGuiContext & g = * GImGui ;
const unsigned c_decimal_point = ( unsigned int ) g . PlatformLocaleDecimalPoint ;
@ -4176,19 +4178,41 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
const float mouse_y = ( is_multiline ? ( io . MousePos . y - draw_window - > DC . CursorPos . y ) : ( g . FontSize * 0.5f ) ) ;
const bool is_osx = io . ConfigMacOSXBehaviors ;
if ( select_all | | ( hovered & & ! is_osx & & io . MouseClickedCount [ 0 ] = = 2 ) )
if ( select_all )
{
state - > SelectAll ( ) ;
state - > SelectedAllMouseLock = true ;
}
else if ( hovered & & is_osx & & io . MouseClickedCount [ 0 ] = = 2 )
else if ( hovered & & io . MouseClickedCount [ 0 ] > = 2 & & ! io . KeyShift )
{
// Double-click select a word only, OS X style (by simulating keystrokes)
state - > OnKeyPressed ( STB_TEXTEDIT_K_WORDLEFT ) ;
state - > OnKeyPressed ( STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT ) ;
stb_textedit_click ( state , & state - > Stb , mouse_x , mouse_y ) ;
const int multiclick_count = ( io . MouseClickedCount [ 0 ] - 2 ) ;
if ( ( multiclick_count % 2 ) = = 0 )
{
// Double-click: Select word
// We always use the "Mac" word advance for double-click select vs CTRL+Right which use the platform dependent variant:
// FIXME: There are likely many ways to improve this behavior, but there's no "right" behavior (depends on use-case, software, OS)
const bool is_bol = ( state - > Stb . cursor = = 0 ) | | ImStb : : STB_TEXTEDIT_GETCHAR ( state , state - > Stb . cursor - 1 ) = = ' \n ' ;
if ( STB_TEXT_HAS_SELECTION ( & state - > Stb ) | | ! is_bol )
state - > OnKeyPressed ( STB_TEXTEDIT_K_WORDLEFT ) ;
//state->OnKeyPressed(STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT);
if ( ! STB_TEXT_HAS_SELECTION ( & state - > Stb ) )
ImStb : : stb_textedit_prep_selection_at_cursor ( & state - > Stb ) ;
state - > Stb . cursor = ImStb : : STB_TEXTEDIT_MOVEWORDRIGHT_MAC ( state , state - > Stb . cursor ) ;
state - > Stb . select_end = state - > Stb . cursor ;
ImStb : : stb_textedit_clamp ( state , & state - > Stb ) ;
}
else
{
// Triple-click: Select line
state - > OnKeyPressed ( STB_TEXTEDIT_K_LINESTART ) ;
state - > OnKeyPressed ( STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT ) ;
}
state - > CursorAnimReset ( ) ;
}
else if ( io . MouseClicked [ 0 ] & & ! state - > SelectedAllMouseLock )
{
// FIXME: unselect on late click could be done release?
if ( hovered )
{
stb_textedit_click ( state , & state - > Stb , mouse_x , mouse_y ) ;