gale.input_handler module

This file contains InputHandler, an observer-pattern-based dispatcher mapping keyboard (including modifier combos), mouse (clicks, wheel, motion), and gamepad (buttons, axes, hotplug) input to named actions, notifying every registered InputListener when one fires — plus every KEY_*/MOUSE_*/GAMEPAD_* constant and *Data class involved.

Author: Alejandro Mujica (aledrums@gmail.com)

exception gale.input_handler.InvalidListenerException[source]

Bases: Exception

class gale.input_handler.KeyboardData(event)[source]

Bases: object

Group the data associated to a keyboad input event.

Parameters:

event (Event)

static get_action_key(event)[source]
Parameters:

event (Event)

Return type:

Tuple[int, int]

static get_action_name()[source]
class gale.input_handler.MouseClickData(event)[source]

Bases: object

Group the data associated to a mouse click event.

Parameters:

event (Event)

static get_action_key(event)[source]
Parameters:

event (Event)

Return type:

int

static get_action_name()[source]
class gale.input_handler.MouseWheelData(event)[source]

Bases: object

Group the data associated to a mouse wheel event.

Parameters:

event (Event)

static get_action_key(event)[source]
Parameters:

event (Event)

Return type:

Tuple[int, int]

static get_action_name()[source]
class gale.input_handler.MouseMotionData(event)[source]

Bases: object

Group the data associated to a mouse motion event.

Parameters:

event (Event)

static get_action_key(event)[source]
Parameters:

event (Event)

Return type:

Tuple[int, int]

static get_action_name()[source]
class gale.input_handler.GamepadButtonData(event)[source]

Bases: object

Group the data associated to a gamepad button event. Uses SDL’s “game controller” abstraction (pygame’s CONTROLLER* events, not the lower-level, per-device JOY* ones), so button meaning (A, B, the D-pad, the shoulders…) is consistent across controller brands (Xbox, PlayStation, generic…) instead of varying by raw button index.

Parameters:

event (Event)

static get_action_key(event)[source]
Parameters:

event (Event)

Return type:

Tuple[int, int]

static get_action_name()[source]
class gale.input_handler.GamepadAxisData(event)[source]

Bases: object

Group the data associated to a gamepad axis motion event (an analog stick or a trigger). Fired continuously as the axis moves, the same way MouseMotionData is: bind it once with set_gamepad_axis_action and read value every time it is notified, rather than expecting a single discrete event.

Parameters:

event (Event)

static get_action_key(event)[source]
Parameters:

event (Event)

Return type:

Tuple[int, int]

static get_action_name()[source]
class gale.input_handler.InputListener[source]

Bases: object

This is an interface to any class that need to be an input listener.

on_input(input_id, input_data)[source]
Parameters:
  • input_id (str)

  • input_data (InputData)

Return type:

NoReturn

gale.input_handler.apply_deadzone(value, threshold=0.15)[source]

Analog sticks rarely rest at exactly 0.0 (a bit of drift is normal), so a raw GamepadAxisData.value is usually run through this before acting on it.

Parameters:
  • value (float) – A raw axis value, typically GamepadAxisData.value.

  • threshold (float) – Values whose magnitude is at or below this are snapped to 0.0. The default value is 0.15.

Returns:

0.0 if abs(value) <= threshold, otherwise value unchanged.

Return type:

float

class gale.input_handler.InputHandler[source]

Bases: object

This class is to handle inputs.

It has an input_binding dictionary where you need to add the desired input associate to an input id by keeping the following rules:

  • Any pair ((modifiers, key), input_id) should be added to input_binding[“keyboard”].

  • Any pair (mouse_button, input_id) should be added to input_binding[“mouse_click”].

  • Any pair (mouse_wheel, input_id) should be added to input_binding[“mouse_wheel”].

  • Any pair (mouse_motion, input_id) should be added to input_binding[“mouse_motion”].

  • Any pair ((gamepad_id, button), input_id) should be added to input_binding[“gamepad_button”].

  • Any pair ((gamepad_id, axis), input_id) should be added to input_binding[“gamepad_axis”].

Keyboard bindings support combos with the modifier keys Shift, Ctrl, Alt, and Meta (also known as Super/Windows/Command key). Use set_keyboard_action passing a combination of MOD_SHIFT, MOD_CTRL, MOD_ALT, and/or MOD_META (joined with the bitwise or operator) through the modifiers argument, for instance:

InputHandler.set_keyboard_action(KEY_s, “save”, modifiers=MOD_CTRL) InputHandler.set_keyboard_action(

KEY_s, “save_as”, modifiers=MOD_CTRL | MOD_SHIFT

)

A binding registered without modifiers (the default) is triggered regardless of which modifiers are held, as long as there is no more specific binding matching the exact combo that is currently pressed.

Gamepads need one extra call, once at startup, to be recognized at all (see init_gamepads); once that’s done, a game with a single local player typically leaves gamepad_id as None on every binding (the default), matching input from whichever gamepad is plugged in. Local multiplayer instead binds the same button/axis to a different action_id per player by passing each player’s own gamepad_id (see GamepadButtonData.gamepad_id/GamepadAxisData.gamepad_id to find out which gamepad a given event came from in the first place, e.g. while prompting “press A on your gamepad” during setup).

INPUT_DATA_TABLE: Dict[int, Type] = {768: <class 'gale.input_handler.KeyboardData'>, 769: <class 'gale.input_handler.KeyboardData'>, 1024: <class 'gale.input_handler.MouseMotionData'>, 1025: <class 'gale.input_handler.MouseClickData'>, 1026: <class 'gale.input_handler.MouseClickData'>, 1027: <class 'gale.input_handler.MouseWheelData'>, 1616: <class 'gale.input_handler.GamepadAxisData'>, 1617: <class 'gale.input_handler.GamepadButtonData'>, 1618: <class 'gale.input_handler.GamepadButtonData'>}
input_binding: Dict[str, Dict] = {'gamepad_axis': {}, 'gamepad_button': {}, 'keyboard': {}, 'mouse_click': {}, 'mouse_motion': {}, 'mouse_wheel': {}}
gamepads: Dict[int, Joystick] = {}
listeners: List[InputListener] = []
classmethod init_gamepads()[source]

Open every currently connected gamepad, and start reacting to CONTROLLERDEVICEADDED/CONTROLLERDEVICEREMOVED so gamepads plugged in or unplugged later are picked up/dropped automatically too. Call this once at startup, before any gamepad input is expected to work (uninitialized, gamepad events are never generated at all).

Return type:

None

classmethod register_listener(listener)[source]
Parameters:

listener (InputListener)

Return type:

None

classmethod unregister_listener(listener)[source]
Parameters:

listener (InputListener)

Return type:

None

classmethod notify(action_id, action_data)[source]
Parameters:
  • action_id (str)

  • action_data (InputData)

Return type:

None

classmethod set_keyboard_action(key, action_id, modifiers=0)[source]

Bind a keyboard key, optionally combined with modifiers, to an action.

Parameters:
  • key (int) – The key code (one of the KEY_* constants).

  • action_id (str) – The identifier of the action to notify.

  • modifiers (int) – A combination (bitwise or) of MOD_SHIFT, MOD_CTRL, MOD_ALT, and/or MOD_META that must be held for this binding to trigger. By default, MOD_NONE, meaning that the binding triggers regardless of the modifiers held, unless a more specific combo is also bound to the same key.

Return type:

None

classmethod set_mouse_click_action(button, action_id)[source]
Parameters:
  • button (int)

  • action_id (str)

Return type:

None

classmethod set_mouse_wheel_action(direction, action_id)[source]
Parameters:
  • direction (Tuple[int, int])

  • action_id (str)

Return type:

None

classmethod set_mouse_motion_action(direction, action_id)[source]
Parameters:
  • direction (Tuple[int, int] | None) – One of the MOUSE_MOTION_* constants, matched only when the raw motion is exactly that unit vector. Pass None instead to register a wildcard fired for every motion event that does not match a more specific direction binding (the usual choice for continuous mouse tracking, such as hovering over a widget in gale.ui, since real motion deltas rarely equal exactly (0, -1) and friends).

  • action_id (str) – The identifier of the action to notify.

Return type:

None

classmethod set_gamepad_button_action(button, action_id, gamepad_id=None)[source]
Parameters:
  • button (int) – One of the GAMEPAD_BUTTON_* constants.

  • action_id (str) – The identifier of the action to notify.

  • gamepad_id (int | None) – Restrict this binding to a single gamepad (its GamepadButtonData.gamepad_id, from an earlier event, e.g. while prompting a player to press a button during local co-op setup). The default value is None, matching this button on every connected gamepad, unless a more specific binding for the same button also exists for whichever gamepad triggered the event.

Return type:

None

classmethod set_gamepad_axis_action(axis, action_id, gamepad_id=None)[source]
Parameters:
  • axis (int) – One of the GAMEPAD_AXIS_* constants.

  • action_id (str) – The identifier of the action to notify.

  • gamepad_id (int | None) – Restrict this binding to a single gamepad. The default value is None, matching this axis on every connected gamepad, unless a more specific binding for the same axis also exists for whichever gamepad triggered the event. See set_gamepad_button_action for the local co-op use case this is for.

Return type:

None

classmethod handle_input(event)[source]
Parameters:

event (Event)

Return type:

None