Skip to main content

Overview

The keybinds utility provides a robust input handling system that manages keyboard and mouse events, including key states, keybind callbacks, and mouse tracking. It processes Windows messages and maintains state for all input devices.

Usage

Access the global input manager:
#include "utils/keybinds/keybinds.h"

// Use the global instance
g_input.add_keybind(VK_F1, [](bool pressed) {
    if (pressed) {
        // Handle key press
    }
});

Global Instance

g_input
input::impl
Global singleton instance of the input management system

Enumerations

key_state_t

Represents the state of a key or mouse button.
KEY_NONE
int
No state / default state
KEY_UP
int
Key is released
KEY_DOWN
int
Key is pressed down
KEY_RELEASED
int
Key was just released (transient state, 100ms window)

Class: input::impl

Properties

key_states
std::array<key_info_t, 256>
Array tracking the state and timestamp of all 256 virtual key codes
key_binds
std::deque<keybind>
Collection of registered keybind callbacks
mouse.pos
math::vec2<int>
Current mouse cursor position (x, y coordinates)
mouse.scroll_amt
int
Current mouse scroll amount (positive = scroll up, negative = scroll down)

Methods

think

Processes Windows input messages and updates key states. Call this from your window procedure.
msg
UINT
required
Windows message type (WM_KEYDOWN, WM_MOUSEMOVE, etc.)
wparam
WPARAM
required
Message-specific parameter
lparam
LPARAM
required
Message-specific parameter
// In your window procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    g_input.think(msg, wparam, lparam);
    // ... rest of window procedure
}

add_keybind

Registers a new keybind with a callback function.
virtual_key
std::uint8_t
required
Virtual key code (e.g., VK_F1, VK_SPACE, VK_LBUTTON)
callback
std::function<void(bool)>
required
Function to call when the key state changes. Parameter is true when pressed, false when released.
g_input.add_keybind(VK_F1, [](bool pressed) {
    if (pressed) {
        std::cout << "F1 pressed" << std::endl;
    } else {
        std::cout << "F1 released" << std::endl;
    }
});

remove_keybind

Removes all keybinds associated with a specific virtual key.
virtual_key
std::uint8_t
required
Virtual key code to remove keybinds for
// Remove all F1 keybinds
g_input.remove_keybind(VK_F1);

poll_keybind

Enters polling mode to wait for the user to press any key, useful for keybind configuration UIs.
callback
std::function<void(std::uint8_t, bool)>
required
Function called when a valid key is pressed. Receives the virtual key code and pressed state.
callback_fail
std::function<void(bool)>
Optional function called when polling is cancelled (ESC, mouse buttons)
g_input.poll_keybind(
    [](std::uint8_t key, bool pressed) {
        if (pressed) {
            std::cout << "Key selected: " << (int)key << std::endl;
        }
    },
    [](bool cancelled) {
        std::cout << "Polling cancelled" << std::endl;
    }
);

key_state

Checks if a key is in a specific state.
state
key_state_t
required
State to check for (KEY_UP, KEY_DOWN, KEY_RELEASED)
key_id
int
required
Virtual key code to check
return
bool
True if the key is in the specified state
if (g_input.key_state(input::KEY_DOWN, VK_SHIFT)) {
    // Shift is currently held down
}

if (g_input.key_state(input::KEY_RELEASED, VK_SPACE)) {
    // Space was just released (within 100ms)
}

key_to_char

Converts a virtual key code to a human-readable string.
virtual_key
std::uint8_t
required
Virtual key code to convert
return
char*
String representation of the key (e.g., “F1”, “SPACE”, “LBUTTON”)
char* key_name = g_input.key_to_char(VK_F1);
// Returns: "F1"

key_name = g_input.key_to_char(VK_LBUTTON);
// Returns: "LBUTTON"

Mouse Functions

in_params (Coordinates)

Checks if the mouse cursor is within a rectangular area.
x
int
required
X coordinate of the rectangle’s top-left corner
y
int
required
Y coordinate of the rectangle’s top-left corner
w
int
required
Width of the rectangle
h
int
required
Height of the rectangle
return
bool
True if the mouse is within the specified rectangle
if (g_input.mouse.in_params(100, 100, 200, 50)) {
    // Mouse is hovering over the button area
}

in_params (Vectors)

Checks if the mouse cursor is within a rectangular area using vector parameters.
m_pos
const math::vec2<int>&
required
Position vector (x, y) of the rectangle’s top-left corner
m_size
const math::vec2<int>&
required
Size vector (width, height) of the rectangle
return
bool
True if the mouse is within the specified rectangle
math::vec2<int> button_pos(100, 100);
math::vec2<int> button_size(200, 50);

if (g_input.mouse.in_params(button_pos, button_size)) {
    // Mouse is hovering over the button
}

Complete Examples

#include "utils/keybinds/keybinds.h"

void setup_basic_keybinds()
{
    // Toggle menu with INSERT key
    g_input.add_keybind(VK_INSERT, [](bool pressed) {
        if (pressed) {
            menu_open = !menu_open;
        }
    });
    
    // Panic key - remove all keybinds
    g_input.add_keybind(VK_END, [](bool pressed) {
        if (pressed) {
            // Clean up and exit
            cleanup_and_exit();
        }
    });
}

Supported Input Events

The think() method processes these Windows messages:
  • Keyboard: WM_KEYDOWN, WM_KEYUP
  • Mouse Buttons: WM_LBUTTONDOWN, WM_LBUTTONUP, WM_RBUTTONDOWN, WM_RBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP
  • Extra Mouse Buttons: WM_XBUTTONDOWN, WM_XBUTTONUP (XBUTTON1, XBUTTON2)
  • Mouse Movement: WM_MOUSEMOVE
  • Mouse Wheel: WM_MOUSEWHEEL
  • Focus: WM_KILLFOCUS, WM_SETFOCUS
The KEY_RELEASED state is transient and only returns true within 100ms of the key being released. This prevents missed release events in polling scenarios.
When polling for keybinds, VK_ESCAPE, VK_LBUTTON, and VK_RBUTTON are reserved for cancelling the poll operation and will not be passed to the callback.

Build docs developers (and LLMs) love