2025-07-06 20:43:53 +03:00
# include "InputManager.hpp"
# include <SDL3/SDL_clipboard.h>
# include <SDL3/SDL_keycode.h>
# include <optional>
2025-11-11 17:42:41 +03:00
# include "Server/CommandList.hpp"
2025-07-06 20:43:53 +03:00
# ifdef __EMSCRIPTEN__
# include <EmscriptenHelpers/emscripten_browser_clipboard.h>
extern " C " {
int isAcceptingInputEmscripten = 0 ;
EMSCRIPTEN_KEEPALIVE inline int is_text_input_happening ( ) {
return isAcceptingInputEmscripten ;
}
}
# endif
InputManager : : InputManager ( ) {
frame_reset ( { 0 , 0 } ) ;
defaultKeyAssignments [ { 0 , SDLK_W } ] = KEY_CAMERA_ROTATE_COUNTERCLOCKWISE ;
defaultKeyAssignments [ { 0 , SDLK_Q } ] = KEY_CAMERA_ROTATE_CLOCKWISE ;
defaultKeyAssignments [ { 0 , SDLK_DELETE } ] = KEY_DRAW_DELETE ;
defaultKeyAssignments [ { CTRL_MOD , SDLK_Z } ] = KEY_UNDO ;
defaultKeyAssignments [ { CTRL_MOD , SDLK_R } ] = KEY_REDO ;
defaultKeyAssignments [ { 0 , SDLK_TAB } ] = KEY_NOGUI ;
defaultKeyAssignments [ { 0 , SDLK_F11 } ] = KEY_FULLSCREEN ;
defaultKeyAssignments [ { CTRL_MOD , SDLK_S } ] = KEY_SAVE ;
defaultKeyAssignments [ { CTRL_MOD | SDL_KMOD_SHIFT , SDLK_S } ] = KEY_SAVE_AS ;
defaultKeyAssignments [ { CTRL_MOD , SDLK_C } ] = KEY_COPY ;
defaultKeyAssignments [ { CTRL_MOD , SDLK_X } ] = KEY_CUT ;
defaultKeyAssignments [ { CTRL_MOD , SDLK_V } ] = KEY_PASTE ;
defaultKeyAssignments [ { 0 , SDLK_B } ] = KEY_DRAW_TOOL_BRUSH ;
defaultKeyAssignments [ { 0 , SDLK_E } ] = KEY_DRAW_TOOL_ERASER ;
defaultKeyAssignments [ { 0 , SDLK_T } ] = KEY_DRAW_TOOL_TEXTBOX ;
defaultKeyAssignments [ { 0 , SDLK_R } ] = KEY_DRAW_TOOL_RECTANGLE ;
defaultKeyAssignments [ { 0 , SDLK_C } ] = KEY_DRAW_TOOL_ELLIPSE ;
defaultKeyAssignments [ { 0 , SDLK_X } ] = KEY_DRAW_TOOL_RECTSELECT ;
2025-08-05 12:11:50 +03:00
defaultKeyAssignments [ { 0 , SDLK_I } ] = KEY_DRAW_TOOL_EYEDROPPER ;
2025-07-06 20:43:53 +03:00
defaultKeyAssignments [ { 0 , SDLK_P } ] = KEY_DRAW_TOOL_SCREENSHOT ;
defaultKeyAssignments [ { 0 , SDLK_F1 } ] = KEY_OPEN_CHAT ;
defaultKeyAssignments [ { 0 , SDLK_F3 } ] = KEY_SHOW_METRICS ;
defaultKeyAssignments [ { 0 , SDLK_F2 } ] = KEY_SHOW_PLAYER_LIST ;
2025-09-28 18:25:46 +03:00
defaultKeyAssignments [ { 0 , SDLK_SPACE } ] = KEY_HOLD_TO_PAN ;
2025-07-06 20:43:53 +03:00
2025-11-11 22:21:25 +03:00
2025-07-06 20:43:53 +03:00
# ifdef __EMSCRIPTEN__
// Without this, SDL eats the CTRL-V event that initiates the paste event
// https://github.com/pthom/hello_imgui/issues/3#issuecomment-1564536870
EM_ASM ( {
window . addEventListener ( ' keydown ' , function ( event ) {
if ( event . ctrlKey & & event . key = = ' v ' ) {
if ( Module [ " ccall " ] ( ' is_text_input_happening ' , ' number ' , [ ] , [ ] ) = = = 1 )
event . stopImmediatePropagation ( ) ;
}
} , true ) ;
} ) ;
emscripten_browser_clipboard : : paste ( [ ] ( std : : string & & pasteData , void * callbackData ) {
InputManager * inMan = ( InputManager * ) callbackData ;
inMan - > clipboardPasteEventHappened = true ;
2025-11-11 18:48:08 +03:00
inMan - > clipboardPasteEventData [ " text/plain " ] = pasteData ;
2025-11-11 22:21:25 +03:00
inMan - > process_text_paste ( ) ;
} , this ) ;
2025-07-06 20:43:53 +03:00
# endif
keyAssignments = defaultKeyAssignments ;
}
void InputManager : : text_input_silence_everything ( ) {
text . set_accepting_input ( ) ;
for ( auto & p : keys ) {
p . pressed = false ;
p . repeat = false ;
2025-07-08 22:08:37 +03:00
// Not silencing p.held, as that causes double presses on some keyboards
2025-07-06 20:43:53 +03:00
}
text . newInput . clear ( ) ;
}
2025-11-10 14:45:51 +03:00
void InputManager : : Text : : set_rich_text_box_input ( const std : : shared_ptr < RichText : : TextBox > & nTextBox , const std : : shared_ptr < RichText : : TextBox : : Cursor > & nCursor , const std : : optional < RichText : : TextStyleModifier : : ModifierMap > & nModMap ) {
2025-10-16 21:22:08 +03:00
set_accepting_input ( ) ;
newTextBox = nTextBox ;
newCursor = nCursor ;
2025-11-09 16:24:40 +03:00
newModMap = nModMap ;
2025-10-16 21:22:08 +03:00
}
void InputManager : : Text : : add_text_to_textbox ( const std : : string & inputText ) {
if ( textBox )
2025-11-09 16:24:40 +03:00
textBox - > process_text_input ( * cursor , inputText , modMap ) ;
2025-10-16 21:22:08 +03:00
}
2025-07-06 20:43:53 +03:00
void InputManager : : Text : : set_accepting_input ( ) {
acceptingInputNew = true ;
}
bool InputManager : : Text : : get_accepting_input ( ) {
return acceptingInput ;
}
bool InputManager : : get_clipboard_paste_happened ( ) {
# ifdef __EMSCRIPTEN__
return clipboardPasteEventHappened ;
# else
return key ( KEY_TEXT_PASTE ) . repeat ;
# endif
}
std : : string InputManager : : get_clipboard_str ( ) {
# ifdef __EMSCRIPTEN__
2025-11-11 18:48:08 +03:00
auto it = clipboardPasteEventData . find ( " text/plain " ) ;
if ( it = = clipboardPasteEventData . end ( ) )
return " " ;
return it - > second ;
2025-07-06 20:43:53 +03:00
# else
char * data = SDL_GetClipboardText ( ) ;
std : : string toRet ( data ) ;
SDL_free ( data ) ;
return toRet ;
# endif
}
2025-11-11 17:42:41 +03:00
std : : string InputManager : : get_clipboard_data_for_mimetype ( const std : : string & mimeType ) {
2025-11-11 18:48:08 +03:00
# ifdef __EMSCRIPTEN__
auto it = clipboardPasteEventData . find ( mimeType ) ;
if ( it = = clipboardPasteEventData . end ( ) )
return " " ;
return it - > second ;
# else
2025-11-11 17:42:41 +03:00
size_t datSize = 0 ;
void * dat = SDL_GetClipboardData ( mimeType . c_str ( ) , & datSize ) ;
if ( ! dat )
return " " ;
return std : : string ( static_cast < char * > ( dat ) , datSize ) ;
2025-11-11 18:48:08 +03:00
# endif
2025-11-11 17:42:41 +03:00
}
2025-07-06 20:43:53 +03:00
void InputManager : : set_clipboard_str ( std : : string_view s ) {
# ifdef __EMSCRIPTEN__
emscripten_browser_clipboard : : copy ( std : : string ( s ) ) ;
# else
SDL_SetClipboardText ( s . data ( ) ) ;
# endif
}
2025-11-11 17:42:41 +03:00
std : : string InputManager : : get_infpnt_richtext_mimetype ( ) {
2025-11-11 22:21:25 +03:00
return " web text/infpnt " ;
2025-11-11 17:42:41 +03:00
}
void InputManager : : set_clipboard_plain_and_richtext_pair ( const std : : pair < std : : string , std : : string > & plainAndRichtextPair ) {
2025-11-11 22:21:25 +03:00
# ifdef __EMSCRIPTEN__
set_clipboard_str ( plainAndRichtextPair . first ) ;
# else
2025-11-11 17:42:41 +03:00
std : : unordered_map < std : : string , std : : string > clipboardData ;
clipboardData [ " text/plain " ] = plainAndRichtextPair . first ;
clipboardData [ get_infpnt_richtext_mimetype ( ) ] = plainAndRichtextPair . second ;
set_clipboard_data ( clipboardData ) ;
2025-11-11 22:21:25 +03:00
# endif
2025-11-11 17:42:41 +03:00
}
void InputManager : : set_clipboard_data ( const std : : unordered_map < std : : string , std : : string > & newClipboardData ) {
SDL_ClearClipboardData ( ) ;
clipboardData = newClipboardData ;
std : : vector < const char * > mimeTypes ;
for ( auto & [ k , v ] : clipboardData )
mimeTypes . emplace_back ( k . c_str ( ) ) ;
SDL_SetClipboardData (
[ ] ( void * userdata , const char * mime_type , size_t * size ) {
std : : unordered_map < std : : string , std : : string > & clipboardData = * static_cast < std : : unordered_map < std : : string , std : : string > * > ( userdata ) ;
std : : string mimeTypeStr ( mime_type ) ;
auto it = clipboardData . find ( mimeTypeStr ) ;
if ( it = = clipboardData . end ( ) )
return static_cast < const void * > ( nullptr ) ;
* size = it - > second . length ( ) ;
return static_cast < const void * > ( it - > second . c_str ( ) ) ;
} ,
[ ] ( void * userdata ) {
} ,
static_cast < void * > ( & clipboardData ) , mimeTypes . data ( ) , mimeTypes . size ( ) ) ;
}
2025-07-06 20:43:53 +03:00
std : : string InputManager : : key_assignment_to_str ( const Vector2ui32 & k ) {
std : : string toRet ;
if ( k . x ( ) & SDL_KMOD_CTRL )
toRet + = " CTRL+ " ;
if ( k . x ( ) & SDL_KMOD_ALT )
toRet + = " ALT+ " ;
if ( k . x ( ) & SDL_KMOD_SHIFT )
toRet + = " SHIFT+ " ;
if ( k . x ( ) & SDL_KMOD_GUI )
toRet + = " META+ " ;
toRet + = SDL_GetKeyName ( k . y ( ) ) ;
return toRet ;
}
Vector2ui32 InputManager : : key_assignment_from_str ( const std : : string & s ) {
Vector2ui32 toRet = { 0 , 0 } ;
if ( s . find ( " CTRL+ " ) ! = std : : string : : npos )
toRet . x ( ) | = SDL_KMOD_CTRL ;
if ( s . find ( " ALT+ " ) ! = std : : string : : npos )
toRet . x ( ) | = SDL_KMOD_ALT ;
if ( s . find ( " SHIFT+ " ) ! = std : : string : : npos )
toRet . x ( ) | = SDL_KMOD_SHIFT ;
if ( s . find ( " META+ " ) ! = std : : string : : npos )
toRet . x ( ) | = SDL_KMOD_GUI ;
size_t startInd = s . find_last_of ( " + " ) ;
if ( startInd = = std : : string : : npos )
startInd = 0 ;
else
startInd + + ;
toRet . y ( ) = SDL_GetKeyFromName ( s . substr ( startInd ) . c_str ( ) ) ;
if ( toRet . y ( ) = = 0 )
toRet . x ( ) = 0 ;
return toRet ;
}
const InputManager : : KeyData & InputManager : : key ( KeyCode kCode ) {
return keys [ kCode ] ;
}
void InputManager : : set_key_down ( const SDL_KeyboardEvent & e , KeyCode kCode ) {
auto & k = keys [ kCode ] ;
if ( ! k . held | | ( std : : chrono : : steady_clock : : now ( ) - k . lastPressTime ) > std : : chrono : : milliseconds ( 500 ) ) // Timer works around some systems that emit a keypress twice (a repeat and a press event)
k . repeat = true ;
if ( ! k . held ) { // We use if statements instead of setting booleans so that values arent forced to false
k . pressed = true ;
k . lastPressTime = std : : chrono : : steady_clock : : now ( ) ;
}
k . held = true ;
}
void InputManager : : set_key_up ( const SDL_KeyboardEvent & e , KeyCode kCode ) {
keys [ kCode ] . held = false ;
}
void InputManager : : set_pen_button_down ( const SDL_PenButtonEvent & e ) {
pen . buttons [ e . button ] . held = true ;
pen . buttons [ e . button ] . pressed = true ;
}
void InputManager : : set_pen_button_up ( const SDL_PenButtonEvent & e ) {
pen . buttons [ e . button ] . held = false ;
}
uint32_t InputManager : : make_generic_key_mod ( SDL_Keymod m ) {
uint32_t toRet = 0 ;
if ( m & SDL_KMOD_CTRL )
toRet | = SDL_KMOD_CTRL ;
if ( m & SDL_KMOD_ALT )
toRet | = SDL_KMOD_ALT ;
if ( m & SDL_KMOD_GUI )
toRet | = SDL_KMOD_GUI ;
if ( m & SDL_KMOD_SHIFT )
toRet | = SDL_KMOD_SHIFT ;
return toRet ;
}
void InputManager : : backend_key_down_update ( const SDL_KeyboardEvent & e ) {
auto kPress = e . key ;
auto kMod = e . mod ;
if ( kPress ! = SDLK_LSHIFT & & kPress ! = SDLK_RSHIFT & & kPress ! = SDLK_LCTRL & & kPress ! = SDLK_RCTRL & &
kPress ! = SDLK_LGUI & & kPress ! = SDLK_RGUI & &
kPress ! = SDLK_LALT & & kPress ! = SDLK_RALT ) {
lastPressedKeybind = { make_generic_key_mod ( kMod ) , kPress } ;
}
// e.key != SDLK_LMETA && e.key != SDLK_RMETA &&
if ( stopKeyInput )
return ;
switch ( kPress ) {
case SDLK_UP :
set_key_down ( e , KEY_TEXT_UP ) ;
2025-10-16 21:22:08 +03:00
if ( text . textBox & & key ( KEY_TEXT_UP ) . repeat )
2025-11-10 14:45:51 +03:00
text . textBox - > process_key_input ( * text . cursor , RichText : : TextBox : : InputKey : : UP , ctrl_or_meta_held ( ) , key ( KEY_GENERIC_LSHIFT ) . held , text . modMap ) ;
2025-07-06 20:43:53 +03:00
break ;
case SDLK_DOWN :
set_key_down ( e , KEY_TEXT_DOWN ) ;
2025-10-16 21:22:08 +03:00
if ( text . textBox & & key ( KEY_TEXT_DOWN ) . repeat )
2025-11-10 14:45:51 +03:00
text . textBox - > process_key_input ( * text . cursor , RichText : : TextBox : : InputKey : : DOWN , ctrl_or_meta_held ( ) , key ( KEY_GENERIC_LSHIFT ) . held , text . modMap ) ;
2025-07-06 20:43:53 +03:00
break ;
case SDLK_LEFT :
set_key_down ( e , KEY_TEXT_LEFT ) ;
2025-10-16 21:22:08 +03:00
if ( text . textBox & & key ( KEY_TEXT_LEFT ) . repeat )
2025-11-10 14:45:51 +03:00
text . textBox - > process_key_input ( * text . cursor , RichText : : TextBox : : InputKey : : LEFT , ctrl_or_meta_held ( ) , key ( KEY_GENERIC_LSHIFT ) . held , text . modMap ) ;
2025-07-06 20:43:53 +03:00
break ;
case SDLK_RIGHT :
set_key_down ( e , KEY_TEXT_RIGHT ) ;
2025-10-16 21:22:08 +03:00
if ( text . textBox & & key ( KEY_TEXT_RIGHT ) . repeat )
2025-11-10 14:45:51 +03:00
text . textBox - > process_key_input ( * text . cursor , RichText : : TextBox : : InputKey : : RIGHT , ctrl_or_meta_held ( ) , key ( KEY_GENERIC_LSHIFT ) . held , text . modMap ) ;
2025-07-06 20:43:53 +03:00
break ;
case SDLK_BACKSPACE :
set_key_down ( e , KEY_TEXT_BACKSPACE ) ;
2025-10-16 21:22:08 +03:00
if ( text . textBox & & key ( KEY_TEXT_BACKSPACE ) . repeat )
2025-11-10 14:45:51 +03:00
text . textBox - > process_key_input ( * text . cursor , RichText : : TextBox : : InputKey : : BACKSPACE , ctrl_or_meta_held ( ) , key ( KEY_GENERIC_LSHIFT ) . held , text . modMap ) ;
2025-07-06 20:43:53 +03:00
break ;
case SDLK_DELETE :
set_key_down ( e , KEY_TEXT_DELETE ) ;
2025-10-16 21:22:08 +03:00
if ( text . textBox & & key ( KEY_TEXT_DELETE ) . repeat )
2025-11-10 14:45:51 +03:00
text . textBox - > process_key_input ( * text . cursor , RichText : : TextBox : : InputKey : : DELETE , ctrl_or_meta_held ( ) , key ( KEY_GENERIC_LSHIFT ) . held , text . modMap ) ;
2025-07-06 20:43:53 +03:00
break ;
case SDLK_HOME :
set_key_down ( e , KEY_TEXT_HOME ) ;
2025-10-16 21:22:08 +03:00
if ( text . textBox & & key ( KEY_TEXT_HOME ) . repeat )
2025-11-10 14:45:51 +03:00
text . textBox - > process_key_input ( * text . cursor , RichText : : TextBox : : InputKey : : HOME , ctrl_or_meta_held ( ) , key ( KEY_GENERIC_LSHIFT ) . held , text . modMap ) ;
2025-10-16 21:22:08 +03:00
break ;
case SDLK_END :
set_key_down ( e , KEY_TEXT_END ) ;
if ( text . textBox & & key ( KEY_TEXT_END ) . repeat )
2025-11-10 14:45:51 +03:00
text . textBox - > process_key_input ( * text . cursor , RichText : : TextBox : : InputKey : : END , ctrl_or_meta_held ( ) , key ( KEY_GENERIC_LSHIFT ) . held , text . modMap ) ;
2025-07-06 20:43:53 +03:00
break ;
case SDLK_LSHIFT :
set_key_down ( e , KEY_TEXT_SHIFT ) ;
2025-08-05 19:04:47 +03:00
set_key_down ( e , KEY_GENERIC_LSHIFT ) ;
break ;
case SDLK_LALT :
set_key_down ( e , KEY_GENERIC_LALT ) ;
2025-07-06 20:43:53 +03:00
break ;
case SDLK_LCTRL :
set_key_down ( e , KEY_TEXT_CTRL ) ;
2025-08-05 19:04:47 +03:00
set_key_down ( e , KEY_GENERIC_LCTRL ) ;
2025-07-06 20:43:53 +03:00
break ;
2025-10-16 21:22:08 +03:00
case SDLK_LMETA :
set_key_down ( e , KEY_TEXT_META ) ;
set_key_down ( e , KEY_GENERIC_LMETA ) ;
break ;
2025-07-06 20:43:53 +03:00
case SDLK_C :
// Use either Ctrl or Meta (command for Mac) keys. We do either instead of checking, since checking can get complicated on Emscripten
if ( ( kMod & SDL_KMOD_GUI ) | | ( kMod & SDL_KMOD_CTRL ) )
set_key_down ( e , KEY_TEXT_COPY ) ;
2025-10-16 21:22:08 +03:00
if ( text . textBox & & key ( KEY_TEXT_COPY ) . repeat )
2025-11-11 17:42:41 +03:00
set_clipboard_plain_and_richtext_pair ( text . textBox - > process_copy ( * text . cursor ) ) ;
2025-07-06 20:43:53 +03:00
break ;
case SDLK_X :
if ( ( kMod & SDL_KMOD_GUI ) | | ( kMod & SDL_KMOD_CTRL ) )
set_key_down ( e , KEY_TEXT_CUT ) ;
2025-10-16 21:22:08 +03:00
if ( text . textBox & & key ( KEY_TEXT_CUT ) . repeat )
2025-11-11 17:42:41 +03:00
set_clipboard_plain_and_richtext_pair ( text . textBox - > process_cut ( * text . cursor ) ) ;
2025-07-06 20:43:53 +03:00
break ;
case SDLK_V :
if ( ( kMod & SDL_KMOD_GUI ) | | ( kMod & SDL_KMOD_CTRL ) )
set_key_down ( e , KEY_TEXT_PASTE ) ;
2025-11-11 22:21:25 +03:00
if ( text . textBox & & key ( KEY_TEXT_PASTE ) . repeat )
process_text_paste ( ) ;
2025-07-06 20:43:53 +03:00
break ;
case SDLK_A :
if ( ( kMod & SDL_KMOD_GUI ) | | ( kMod & SDL_KMOD_CTRL ) )
set_key_down ( e , KEY_TEXT_SELECTALL ) ;
2025-10-16 21:22:08 +03:00
if ( text . textBox & & key ( KEY_TEXT_SELECTALL ) . repeat )
2025-11-10 14:45:51 +03:00
text . textBox - > process_key_input ( * text . cursor , RichText : : TextBox : : InputKey : : SELECT_ALL , ctrl_or_meta_held ( ) , key ( KEY_GENERIC_LSHIFT ) . held , text . modMap ) ;
2025-07-06 20:43:53 +03:00
break ;
2025-10-16 21:22:08 +03:00
case SDLK_RETURN : {
2025-07-06 20:43:53 +03:00
set_key_down ( e , KEY_TEXT_ENTER ) ;
2025-10-16 21:22:08 +03:00
if ( text . textBox & & key ( KEY_TEXT_ENTER ) . repeat )
2025-11-10 14:45:51 +03:00
text . textBox - > process_key_input ( * text . cursor , RichText : : TextBox : : InputKey : : ENTER , ctrl_or_meta_held ( ) , key ( KEY_GENERIC_LSHIFT ) . held , text . modMap ) ;
2025-07-06 20:43:53 +03:00
break ;
2025-10-16 21:22:08 +03:00
}
2025-10-20 17:30:36 +03:00
case SDLK_TAB : {
set_key_down ( e , KEY_TEXT_TAB ) ;
if ( text . textBox & & key ( KEY_TEXT_TAB ) . repeat )
2025-11-10 14:45:51 +03:00
text . textBox - > process_key_input ( * text . cursor , RichText : : TextBox : : InputKey : : TAB , ctrl_or_meta_held ( ) , key ( KEY_GENERIC_LSHIFT ) . held , text . modMap ) ;
2025-10-20 17:30:36 +03:00
break ;
}
2025-07-06 20:43:53 +03:00
case SDLK_ESCAPE :
2025-09-29 15:15:16 +03:00
set_key_down ( e , KEY_GENERIC_ESCAPE ) ;
2025-07-06 20:43:53 +03:00
break ;
default :
break ;
}
if ( text . get_accepting_input ( ) )
return ;
auto f = keyAssignments . find ( { make_generic_key_mod ( kMod ) , kPress } ) ;
if ( f ! = keyAssignments . end ( ) )
set_key_down ( e , f - > second ) ;
}
2025-11-11 22:21:25 +03:00
void InputManager : : process_text_paste ( ) {
if ( text . textBox ) {
std : : string richTextClipboard = get_clipboard_data_for_mimetype ( get_infpnt_richtext_mimetype ( ) ) ;
if ( ! richTextClipboard . empty ( ) )
text . textBox - > process_rich_text_input ( * text . cursor , richTextClipboard ) ;
else
text . textBox - > process_text_input ( * text . cursor , get_clipboard_data_for_mimetype ( " text/plain " ) , text . modMap ) ;
}
}
2025-10-16 21:22:08 +03:00
bool InputManager : : ctrl_or_meta_held ( ) {
return key ( KEY_GENERIC_LCTRL ) . held | | key ( KEY_GENERIC_LMETA ) . held ;
}
2025-07-06 20:43:53 +03:00
void InputManager : : backend_key_up_update ( const SDL_KeyboardEvent & e ) {
auto kPress = e . key ;
//auto kMod = e.mod;
switch ( kPress ) {
case SDLK_UP :
set_key_up ( e , KEY_TEXT_UP ) ;
break ;
case SDLK_DOWN :
set_key_up ( e , KEY_TEXT_DOWN ) ;
break ;
case SDLK_LEFT :
set_key_up ( e , KEY_TEXT_LEFT ) ;
break ;
case SDLK_RIGHT :
set_key_up ( e , KEY_TEXT_RIGHT ) ;
break ;
case SDLK_BACKSPACE :
set_key_up ( e , KEY_TEXT_BACKSPACE ) ;
break ;
case SDLK_DELETE :
set_key_up ( e , KEY_TEXT_DELETE ) ;
break ;
case SDLK_HOME :
set_key_up ( e , KEY_TEXT_HOME ) ;
break ;
2025-10-16 21:22:08 +03:00
case SDLK_END :
set_key_up ( e , KEY_TEXT_END ) ;
break ;
2025-07-06 20:43:53 +03:00
case SDLK_LSHIFT :
set_key_up ( e , KEY_TEXT_SHIFT ) ;
2025-08-05 19:04:47 +03:00
set_key_up ( e , KEY_GENERIC_LSHIFT ) ;
break ;
case SDLK_LALT :
set_key_up ( e , KEY_GENERIC_LALT ) ;
2025-07-06 20:43:53 +03:00
break ;
case SDLK_LCTRL :
set_key_up ( e , KEY_TEXT_CTRL ) ;
2025-08-05 19:04:47 +03:00
set_key_up ( e , KEY_GENERIC_LCTRL ) ;
2025-07-06 20:43:53 +03:00
break ;
case SDLK_C :
set_key_up ( e , KEY_TEXT_COPY ) ;
break ;
case SDLK_X :
set_key_up ( e , KEY_TEXT_CUT ) ;
break ;
case SDLK_V :
set_key_up ( e , KEY_TEXT_PASTE ) ;
break ;
case SDLK_A :
set_key_up ( e , KEY_TEXT_SELECTALL ) ;
break ;
case SDLK_RETURN :
set_key_up ( e , KEY_TEXT_ENTER ) ;
break ;
2025-10-20 17:30:36 +03:00
case SDLK_TAB :
set_key_up ( e , KEY_TEXT_TAB ) ;
break ;
2025-07-06 20:43:53 +03:00
case SDLK_ESCAPE :
2025-09-29 15:15:16 +03:00
set_key_up ( e , KEY_GENERIC_ESCAPE ) ;
2025-07-06 20:43:53 +03:00
break ;
default :
break ;
}
for ( auto & p : keyAssignments ) {
if ( p . first . y ( ) = = kPress ) // Dont try matching modifiers when setting key to go up
set_key_up ( e , p . second ) ;
}
}
void InputManager : : stop_key_input ( ) {
stopKeyInput = 2 ;
}
void InputManager : : Mouse : : set_pos ( const Vector2f & newPos ) {
pos = newPos ;
move = newPos - lastPos ;
}
void InputManager : : frame_reset ( const Vector2i & windowSize ) {
mouse . lastPos = mouse . pos ;
mouse . move = Vector2f ( { 0.0f , 0.0f } ) ;
mouse . scrollAmount = Vector2f ( { 0.0f , 0.0f } ) ;
mouse . leftClicks = 0 ;
mouse . rightClicks = 0 ;
mouse . middleClicks = 0 ;
text . acceptingInput = text . acceptingInputNew ;
text . acceptingInputNew = false ;
2025-10-16 21:22:08 +03:00
text . cursor = text . newCursor ;
text . textBox = text . newTextBox ;
2025-11-09 16:24:40 +03:00
text . modMap = text . newModMap ;
2025-10-16 21:22:08 +03:00
text . newCursor = nullptr ;
text . newTextBox = nullptr ;
2025-07-06 20:43:53 +03:00
text . newInput . clear ( ) ;
droppedItems . clear ( ) ;
cursorIcon = SystemCursorType : : DEFAULT ;
for ( auto & p : keys ) {
p . pressed = false ;
p . repeat = false ;
}
for ( auto & p : pen . buttons )
p . pressed = false ;
lastPressedKeybind = std : : nullopt ;
if ( stopKeyInput )
stopKeyInput - - ;
toggleFullscreen = false ;
hideCursor = false ;
# ifdef __EMSCRIPTEN__
clipboardPasteEventHappened = false ;
clipboardPasteEventData . clear ( ) ;
isAcceptingInputEmscripten = text . acceptingInput ? 1 : 0 ;
# endif
}