|
| 1 | +from ctypes import c_int, byref |
1 | 2 | from ..stdinc import SDL_TRUE
|
2 | 3 | from ..keyboard import (
|
3 | 4 | SDL_GetKeyFromName, SDL_GetKeyName, SDL_StartTextInput, SDL_StopTextInput,
|
4 |
| - SDL_IsTextInputActive, |
| 5 | + SDL_IsTextInputActive, SDL_GetKeyboardState, SDL_GetScancodeFromName, |
5 | 6 | )
|
| 7 | +from ..scancode import SDL_SCANCODE_UNKNOWN, SDL_NUM_SCANCODES |
6 | 8 | from ..keycode import KMOD_ALT, KMOD_CTRL, KMOD_GUI, KMOD_SHIFT
|
7 | 9 | from ..mouse import (
|
8 | 10 | SDL_BUTTON_LEFT, SDL_BUTTON_RIGHT, SDL_BUTTON_MIDDLE,
|
9 | 11 | SDL_BUTTON_X1, SDL_BUTTON_X2,
|
10 | 12 | )
|
11 | 13 | from ..events import (
|
12 | 14 | SDL_KEYDOWN, SDL_KEYUP, SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONUP,
|
13 |
| - SDL_TEXTINPUT, |
| 15 | + SDL_TEXTINPUT, SDL_PumpEvents, |
14 | 16 | )
|
15 | 17 |
|
16 | 18 | from .compat import _is_text, byteify, isiterable
|
17 | 19 |
|
18 | 20 | __all__ = [
|
19 |
| - "key_pressed", "mouse_clicked", "get_clicks", "get_text_input", |
| 21 | + "key_pressed", "get_key_state", "mouse_clicked", "get_clicks", "get_text_input", |
20 | 22 | "start_text_input", "stop_text_input", "text_input_enabled",
|
21 | 23 | ]
|
22 | 24 |
|
@@ -197,6 +199,53 @@ def key_pressed(events, key=None, mod=None, released=False):
|
197 | 199 | return pressed
|
198 | 200 |
|
199 | 201 |
|
| 202 | +def get_key_state(key): |
| 203 | + """Checks the current state (pressed or released) of a given keyboard key. |
| 204 | +
|
| 205 | + Unlike :func:`key_pressed`, which checks an SDL event queue for key down |
| 206 | + and key up events, this function checks the current state of a given key |
| 207 | + directly. This can be helpful in certain situations, such as ignoring |
| 208 | + repeated keydown events from a held key:: |
| 209 | +
|
| 210 | + key_released = False |
| 211 | + while True: |
| 212 | + q = pump(True) |
| 213 | + if not key_released: |
| 214 | + # Ignore repeated keydown events from held down space bar by |
| 215 | + # requiring key be 'up' on at least one loop before a response |
| 216 | + # can be registered |
| 217 | + if get_key_state('space') == 0: |
| 218 | + key_released = True |
| 219 | + else: |
| 220 | + if key_pressed('space', queue=q): |
| 221 | + break |
| 222 | +
|
| 223 | + Args: |
| 224 | + key (int or str): The name (or SDL scancode) of the key to check. |
| 225 | +
|
| 226 | + Returns: |
| 227 | + int: 1 if the key is currently pressed, otherwise 0. |
| 228 | +
|
| 229 | + """ |
| 230 | + # If key given as string, get the corresponding scancode |
| 231 | + if _is_text(key): |
| 232 | + scancode = SDL_GetScancodeFromName(byteify(key)) |
| 233 | + if scancode == SDL_SCANCODE_UNKNOWN: |
| 234 | + e = "'{0}' is not a valid name for an SDL scancode." |
| 235 | + raise ValueError(e.format(key)) |
| 236 | + else: |
| 237 | + if key <= 0 or key >= SDL_NUM_SCANCODES: |
| 238 | + e = "'{0}' is not a valid SDL scancode constant." |
| 239 | + raise ValueError(e.format(key)) |
| 240 | + scancode = key |
| 241 | + |
| 242 | + # Check for and return the current key state |
| 243 | + SDL_PumpEvents() |
| 244 | + numkeys = c_int(0) |
| 245 | + keys = SDL_GetKeyboardState(byref(numkeys)) |
| 246 | + return keys[scancode] |
| 247 | + |
| 248 | + |
200 | 249 | def mouse_clicked(events, button=None, released=False):
|
201 | 250 | """Checks for any mouse clicks in a given event queue.
|
202 | 251 |
|
|
0 commit comments