Glusoft

Handling Keyboard and Mouse Events with SDL3

Use the keyboard and mouse

Initializations

The window and the renderer

We initialize SDL3 and SDL3_ttf after that we need to create the window and the renderer.

SDL_Init(SDL_INIT_VIDEO);
TTF_Init();

SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;

if (!SDL_CreateWindowAndRenderer("SDL3 Keyboard", 800, 600, 0, &window, &renderer)) {
    SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
    return SDL_APP_FAILURE;
}

Load the font

The next thing to do is load the font.

// Load font
TTF_Font *font = TTF_OpenFont("FreeSans.ttf", 24);
if (!font) {
    SDL_Log("Font load error: %s", SDL_GetError());
    return 1;
}

The event loop for the keyboard events

Before starting the event loop we must indicate to SDL3 to use the keyboard for inputs with SDL_StartTextInput(window);

The event SDL_EVENT_KEY_DOWN

We want to quit the app when the user press Escape:

case SDL_EVENT_KEY_DOWN:
    if (event.key.key == SDLK_ESCAPE)
        running = false;
    break;

Here we used a keycode for the key escape but you can also use scancode if you need the physical position of a key.

Keycode (SDL_Keycode)

Scancode (SDL_Scancode)

You can access allthese values for a key press or a key release event:

SDL_EventType type;     // SDL_EVENT_KEY_DOWN or SDL_EVENT_KEY_UP
Uint64 timestamp;       // In nanoseconds, populated using SDL_GetTicksNS()
SDL_WindowID windowID;  // The window with keyboard focus, if any
SDL_KeyboardID which;   // The keyboard instance id, or 0 if unknown or virtual
SDL_Scancode scancode;  // SDL physical key code
SDL_Keycode key;        // SDL virtual key code
SDL_Keymod mod;         // current key modifiers
Uint16 raw;             // The platform dependent scancode for this event
bool down;              // true if the key is pressed
bool repeat;            // true if this is a key repeat

The event SDL_EVENT_TEXT_INPUT

Whe can process the input when the user type something and store it inside a text variable.

case SDL_EVENT_TEXT_INPUT:
    text = text + event.text.text;
    break;

Implementing the backspace event to remove texts

As an exercice you can implement the backspace event.


Solution

case SDL_EVENT_KEY_DOWN:
    if (event.key.key == SDLK_BACKSPACE && text.size() > 0) {
        text.pop_back();
    }
    break;

The events for the mouse

The motion event: SDL_EVENT_MOUSE_MOTION

This event is tigered when the use move the mouse,if we want to display the coordinate:

case SDL_EVENT_MOUSE_MOTION:
    printf("Mouse moved to (%d, %d)\n",
            event.motion.x, event.motion.y);
    break;

You can acess all these values inside the mothion event:

SDL_EventType type; // SDL_EVENT_MOUSE_MOTION
Uint64 timestamp;   // In nanoseconds, populated using SDL_GetTicksNS()
SDL_WindowID windowID; // The window with mouse focus, if any
SDL_MouseID which;  // The mouse instance id in relative mode, SDL_TOUCH_MOUSEID for touch events, or 0
SDL_MouseButtonFlags state;       // The current button state
float x;            // X coordinate, relative to window
float y;            // Y coordinate, relative to window
float xrel;         // The relative motion in the X direction
float yrel;         // The relative motion in the Y direction

The button press and release event: SDL_EVENT_MOUSE_BUTTON_DOWN and SDL_EVENT_MOUSE_BUTTON_UP

We want to display the button and the coordinate of the cursor

case SDL_EVENT_MOUSE_BUTTON_DOWN:
printf("Mouse button %d down at (%d, %d)\n",
        event.button.button,
        event.button.x, event.button.y);
break;

We want to do the same for the mouse release event

case SDL_EVENT_MOUSE_BUTTON_UP:
    printf("Mouse button %d up at (%d, %d)\n",
        event.button.button,
        event.button.x, event.button.y);
    break;

Inside this event you can access:

SDL_EventType type; // SDL_EVENT_MOUSE_BUTTON_DOWN or SDL_EVENT_MOUSE_BUTTON_UP
Uint64 timestamp;   // In nanoseconds, populated using SDL_GetTicksNS()
SDL_WindowID windowID; // The window with mouse focus, if any
SDL_MouseID which;  // The mouse instance id in relative mode, SDL_TOUCH_MOUSEID for touch events, or 0
Uint8 button;       // The mouse button index
bool down;          // true if the button is pressed
Uint8 clicks;       // 1 for single-click, 2 for double-click, etc.
float x;            // X coordinate, relative to window
float y;            // Y coordinate, relative to window

The muse wheel event: SDL_EVENT_MOUSE_WHEEL

Here we want to display the coordinate of the mouse wheel.

case SDL_EVENT_MOUSE_WHEEL:
    printf("Mouse wheel: (%d, %d)\n",
            event.wheel.x, event.wheel.y);
    break;

You can have access to all these values :

SDL_EventType type; // SDL_EVENT_MOUSE_WHEEL
Uint64 timestamp;   // In nanoseconds, populated using SDL_GetTicksNS()
SDL_WindowID windowID; // The window with mouse focus, if any
SDL_MouseID which;  // The mouse instance id in relative mode or 0
float x;            // The amount scrolled horizontally, positive to the right and negative to the left
float y;            // The amount scrolled vertically, positive away from the user and negative toward the user
SDL_MouseWheelDirection direction; // Set to one of the SDL_MOUSEWHEEL_* defines. When FLIPPED the values in X and Y will be opposite. Multiply by -1 to change them back
float mouse_x;      // X coordinate, relative to window
float mouse_y;      // Y coordinate, relative to window
Sint32 integer_x;   // The amount scrolled horizontally, accumulated to whole scroll "ticks"
Sint32 integer_y;   // The amount scrolled vertically, accumulated to whole scroll "ticks"

The rendering

Clear the screen

SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); // White SDL_RenderClear(renderer);

Render the texts

Create the texture of text

SDL_Color black = {0, 0, 0};
SDL_Surface *surface = TTF_RenderText_Blended(font, text.c_str(), text.size(), black);
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);

Render the texture

float texW = 0, texH = 0;
SDL_GetTextureSize(texture, &texW, &texH);
SDL_FRect dst = {50, 50, texW, texH};

SDL_RenderTexture(renderer, texture, NULL, &dst);

Cleanup

SDL_DestroyTexture(texture);
SDL_DestroySurface(surface);

Download the full project : Handling Keyboard and Mouse Events with SDL3

Need another OS ? => Windows, Mac, Linux