The Input subsystem provides keyboard, mouse, joystick and touch input both via a polled interface and events. This subsystem is also used for querying whether the application window has input focus or is minimized.
The subsystem is always instantiated, even in headless mode, but is active only once the application window has been created. Once active, the subsystem takes over the operating system mouse cursor. It will be hidden by default, so the UI should be used to render a software cursor if necessary. For editor-like applications the operating system cursor can be made visible by calling SetMouseVisible().
The input events include:
- E_MOUSEBUTTONUP: a mouse button was released.
- E_MOUSEBUTTONDOWN: a mouse button was pressed.
- E_MOUSEMOVE: the mouse moved.
- E_MOUSEWHEEL: the mouse wheel moved.
- E_KEYUP: a key was released.
- E_KEYDOWN: a key was pressed.
- E_TEXTINPUT: a string of translated text input in UTF8 format. May contain a single character or several.
- E_JOYSTICKCONNECTED: a joystick was plugged in.
- E_JOYSTICKDISCONNECTED: a joystick was disconnected.
- E_JOYSTICKBUTTONDOWN: a joystick button was pressed.
- E_JOYSTICKBUTTONUP: a joystick button was released.
- E_JOYSTICKAXISMOVE: a joystick axis was moved.
- E_JOYSTICKHATMOVE: a joystick POV hat was moved.
- E_TOUCHBEGIN: a finger touched the screen.
- E_TOUCHEND: a finger was lifted from the screen.
- E_TOUCHMOVE: a finger moved on the screen.
- E_GESTURERECORDED : recording a touch gesture is complete.
- E_GESTUREINPUT : a touch gesture was recognized.
- E_MULTIGESTURE : a multi-finger pinch/rotation touch gesture is underway.
- E_DROPFILE : a file was drag-dropped on the application window.
- E_INPUTFOCUS : application input focus or window minimization state changed.
- E_MOUSEVISIBLECHANGED : the visibility of the operating system mouse cursor was changed.
- E_EXITREQUESTED : application exit was requested (eg. with the window close button.)
Key events include both the symbolic keycode ("Key") that depends on the keyboard layout, the layout- and operating system-independent SDL scancode ("Scancode"), and the true operating system-specific raw keycode ("Raw").
The input polling API differentiates between the initiation of a key/mouse button press, and holding the key or button down. GetKeyPress() and GetMouseButtonPress() return true only for one frame (the initiation) while GetKeyDown() and GetMouseButtonDown() return true as long as the key or button is held down. To check whether keys are down or pressed by scancode, use GetScancodeDown() and GetScancodePress(). Functions also exist for converting keycodes to scancodes or vice versa, or getting key names. See for example GetKeyName() and GetKeyFromScancode().
In AngelScript, the polling API is accessed via properties: input.keyDown, input.keyPress, input.scancodeDown, input.scancodePress, input.mouseButtonDown, input.mouseButtonPress, input.mouseMove, input.mousePosition.
The operating system mouse cursor can be used in four modes which can be switched with SetMouseMode().
- MM_ABSOLUTE is the default behaviour, allowing the toggling of operating system cursor visibility and allowing the cursor to escape the window when visible. When the operating system cursor is invisible in absolute mouse mode, the mouse is confined to the window. If the operating system and UI cursors are both invisible, interaction with the user interface will be limited (eg: drag move / drag end events will not trigger). SetMouseMode(MM_ABSOLUTE) will call SetMouseGrabbed(false).
- MM_RELATIVE sets the operating system cursor to invisible and confines the cursor to the window. The operating system cursor cannot be set to be visible in this mode via SetMouseVisible(), however changes are tracked and will be restored when another mouse mode is set. When the virtual cursor is also invisible, UI interaction will still function as normal (eg: drag events will trigger). SetMouseMode(MM_RELATIVE) will call SetMouseGrabbed(true).
- MM_WRAP grabs the mouse from the operating system and confines the operating system cursor to the window, wrapping the cursor when it is near the edges. SetMouseMode(MM_WRAP) will call SetMouseGrabbed(true).
- MM_FREE does not grab/confine the mouse cursor even when it is hidden. This can be used for cases where the cursor should render using the operating system outside the window, and perform custom rendering (with SetMouseVisible(false)) inside.
Plugged in joysticks will begin sending input events automatically. Each joystick will be assigned a joystick ID which will be used in subsequent joystick events, as well as for retrieving the joystick state. Use GetJoystick() to retrieve the joystick state by ID. In case you do not have the ID, you can also use GetJoystickByIndex() which uses a zero-based index; see GetNumJoysticks() for the number of currently connected joysticks. The ID, as well as the joystick name, can be looked up from the joystick state.
If the joystick model is recognized by SDL as a game controller the buttons and axes mappings utilize known constants such as CONTROLLER_BUTTON_A or CONTROLLER_AXIS_LEFTX without having to guess them. Use IsController() to distinguish between a game controller and an unrecognized joystick.
On platforms that support the accelerometer, it will appear as a "virtual" joystick.
On platforms where touch input is available, touch begin/end/move events will be sent, as well as multi-gesture events with pinch/rotation delta values when more than one finger is pressed down. The current finger touches can also be accessed via a polling API: GetNumTouches() and GetTouch().
Touch gestures can be recorded using SDL's inbuilt $1 gesture recognition system. Use RecordGesture() to start recording. The following finger movements will be recorded until the finger is lifted, at which point the recording ends and the E_GESTURERECORDED event is sent with the hash ID of the new gesture. The current in-memory gesture(s) can be saved or loaded as binary data using the SaveGestures(), SaveGesture(), LoadGestures() functions.
Whenever a recognized gesture is entered by the user, the E_GESTUREINPUT event will be sent. In addition to the ID of the best matched gesture, it contains the center position and an error metric (lower = better) to help filter out false gestures.
Note that all recorded (whether saved or not) and loaded gestures are held in-memory. Two additional functions are available to clear them: RemoveGesture() to selectively clear a gesture by its ID and RemoveAllGestures() to clear them all.
Touch input can also emulate a virtual joystick by displaying on-screen buttons. See the function AddScreenJoystick().
Touch emulation can be used to test mobile applications on a desktop machine without a touch screen. See SetTouchEmulation(). When touch emulation is enabled, actual mouse events are no longer sent and the operating system mouse cursor is forced visible. The left mouse button acts as a moving finger, while the rest of the mouse buttons act as stationary fingers for multi-finger gestures. For example pressing down both left and right mouse buttons, then dragging the mouse with the buttons still pressed would emulate a two-finger pinch zoom-in gesture.
On platforms that support it (such as Android) an on-screen virtual keyboard can be shown or hidden. When shown, keypresses from the virtual keyboard will be sent as text input events just as if typed from an actual keyboard. Show or hide it by calling SetScreenKeyboardVisible(). The UI subsystem can also automatically show the virtual keyboard when a LineEdit element is focused, and hide it when defocused. This behavior can be controlled by calling SetUseScreenKeyboard().
On Windows the user must first touch the screen once before touch input is activated. Trying to record or load touch gestures will fail before that.