|
24 | 24 | from numpy.typing import ArrayLike, NDArray
|
25 | 25 |
|
26 | 26 | __all__ = (
|
| 27 | + "Capitalization", |
27 | 28 | "FlashOperation",
|
| 29 | + "TextInputType", |
28 | 30 | "Window",
|
29 | 31 | "WindowFlags",
|
30 | 32 | "get_grabbed_window",
|
@@ -89,6 +91,56 @@ class FlashOperation(enum.IntEnum):
|
89 | 91 | """Flash until focus is gained."""
|
90 | 92 |
|
91 | 93 |
|
| 94 | +class TextInputType(enum.IntEnum): |
| 95 | + """SDL input types for text input. |
| 96 | +
|
| 97 | + .. seealso:: |
| 98 | + :any:`Window.start_text_input` |
| 99 | + https://wiki.libsdl.org/SDL3/SDL_TextInputType |
| 100 | +
|
| 101 | + .. versionadded:: Unreleased |
| 102 | + """ |
| 103 | + |
| 104 | + TEXT = lib.SDL_TEXTINPUT_TYPE_TEXT |
| 105 | + """The input is text.""" |
| 106 | + TEXT_NAME = lib.SDL_TEXTINPUT_TYPE_TEXT_NAME |
| 107 | + """The input is a person's name.""" |
| 108 | + TEXT_EMAIL = lib.SDL_TEXTINPUT_TYPE_TEXT_EMAIL |
| 109 | + """The input is an e-mail address.""" |
| 110 | + TEXT_USERNAME = lib.SDL_TEXTINPUT_TYPE_TEXT_USERNAME |
| 111 | + """The input is a username.""" |
| 112 | + TEXT_PASSWORD_HIDDEN = lib.SDL_TEXTINPUT_TYPE_TEXT_PASSWORD_HIDDEN |
| 113 | + """The input is a secure password that is hidden.""" |
| 114 | + TEXT_PASSWORD_VISIBLE = lib.SDL_TEXTINPUT_TYPE_TEXT_PASSWORD_VISIBLE |
| 115 | + """The input is a secure password that is visible.""" |
| 116 | + NUMBER = lib.SDL_TEXTINPUT_TYPE_NUMBER |
| 117 | + """The input is a number.""" |
| 118 | + NUMBER_PASSWORD_HIDDEN = lib.SDL_TEXTINPUT_TYPE_NUMBER_PASSWORD_HIDDEN |
| 119 | + """The input is a secure PIN that is hidden.""" |
| 120 | + NUMBER_PASSWORD_VISIBLE = lib.SDL_TEXTINPUT_TYPE_NUMBER_PASSWORD_VISIBLE |
| 121 | + """The input is a secure PIN that is visible.""" |
| 122 | + |
| 123 | + |
| 124 | +class Capitalization(enum.IntEnum): |
| 125 | + """Text capitalization for text input. |
| 126 | +
|
| 127 | + .. seealso:: |
| 128 | + :any:`Window.start_text_input` |
| 129 | + https://wiki.libsdl.org/SDL3/SDL_Capitalization |
| 130 | +
|
| 131 | + .. versionadded:: Unreleased |
| 132 | + """ |
| 133 | + |
| 134 | + NONE = lib.SDL_CAPITALIZE_NONE |
| 135 | + """No auto-capitalization will be done.""" |
| 136 | + SENTENCES = lib.SDL_CAPITALIZE_SENTENCES |
| 137 | + """The first letter of sentences will be capitalized.""" |
| 138 | + WORDS = lib.SDL_CAPITALIZE_WORDS |
| 139 | + """The first letter of words will be capitalized.""" |
| 140 | + LETTERS = lib.SDL_CAPITALIZE_LETTERS |
| 141 | + """All letters will be capitalized.""" |
| 142 | + |
| 143 | + |
92 | 144 | class _TempSurface:
|
93 | 145 | """Holds a temporary surface derived from a NumPy array."""
|
94 | 146 |
|
@@ -133,6 +185,9 @@ def __eq__(self, other: object) -> bool:
|
133 | 185 | return NotImplemented
|
134 | 186 | return bool(self.p == other.p)
|
135 | 187 |
|
| 188 | + def __hash__(self) -> int: |
| 189 | + return hash(self.p) |
| 190 | + |
136 | 191 | def _as_property_pointer(self) -> Any: # noqa: ANN401
|
137 | 192 | return self.p
|
138 | 193 |
|
@@ -369,6 +424,67 @@ def relative_mouse_mode(self) -> bool:
|
369 | 424 | def relative_mouse_mode(self, enable: bool, /) -> None:
|
370 | 425 | _check(lib.SDL_SetWindowRelativeMouseMode(self.p, enable))
|
371 | 426 |
|
| 427 | + def start_text_input( |
| 428 | + self, |
| 429 | + *, |
| 430 | + type: TextInputType = TextInputType.TEXT, # noqa: A002 |
| 431 | + capitalization: Capitalization | None = None, |
| 432 | + autocorrect: bool = True, |
| 433 | + multiline: bool | None = None, |
| 434 | + android_type: int | None = None, |
| 435 | + ) -> None: |
| 436 | + """Start receiving text input events supporting Unicode. This may open an on-screen keyboard. |
| 437 | +
|
| 438 | + Args: |
| 439 | + type: Type of text being inputted, see :any:`TextInputType` |
| 440 | + capitalization: Capitalization hint, default is based on `type` given, see :any:`Capitalization`. |
| 441 | + autocorrect: Enable auto completion and auto correction. |
| 442 | + multiline: Allow multiple lines of text. |
| 443 | + android_type: Input type for Android, see SDL docs. |
| 444 | +
|
| 445 | + .. seealso:: |
| 446 | + :any:`stop_text_input` |
| 447 | + :any:`set_text_input_area` |
| 448 | + https://wiki.libsdl.org/SDL3/SDL_StartTextInputWithProperties |
| 449 | +
|
| 450 | + .. versionadded:: Unreleased |
| 451 | + """ |
| 452 | + props = Properties() |
| 453 | + props[("SDL_PROP_TEXTINPUT_TYPE_NUMBER", int)] = int(type) |
| 454 | + if capitalization is not None: |
| 455 | + props[("SDL_PROP_TEXTINPUT_CAPITALIZATION_NUMBER", int)] = int(capitalization) |
| 456 | + props[("SDL_PROP_TEXTINPUT_AUTOCORRECT_BOOLEAN", bool)] = autocorrect |
| 457 | + if multiline is not None: |
| 458 | + props[("SDL_PROP_TEXTINPUT_MULTILINE_BOOLEAN", bool)] = multiline |
| 459 | + if android_type is not None: |
| 460 | + props[("SDL_PROP_TEXTINPUT_ANDROID_INPUTTYPE_NUMBER", int)] = int(android_type) |
| 461 | + _check(lib.SDL_StartTextInputWithProperties(self.p, props.p)) |
| 462 | + |
| 463 | + def set_text_input_area(self, rect: tuple[int, int, int, int], cursor: int) -> None: |
| 464 | + """Assign the area used for entering Unicode text input. |
| 465 | +
|
| 466 | + Args: |
| 467 | + rect: `(x, y, width, height)` rectangle used for text input |
| 468 | + cursor: Cursor X position, relative to `rect[0]` |
| 469 | +
|
| 470 | + .. seealso:: |
| 471 | + :any:`start_text_input` |
| 472 | + https://wiki.libsdl.org/SDL3/SDL_SetTextInputArea |
| 473 | +
|
| 474 | + .. versionadded:: Unreleased |
| 475 | + """ |
| 476 | + _check(lib.SDL_SetTextInputArea(self.p, (rect,), cursor)) |
| 477 | + |
| 478 | + def stop_text_input(self) -> None: |
| 479 | + """Stop receiving text events for this window and close relevant on-screen keyboards. |
| 480 | +
|
| 481 | + .. seealso:: |
| 482 | + :any:`start_text_input` |
| 483 | +
|
| 484 | + .. versionadded:: Unreleased |
| 485 | + """ |
| 486 | + _check(lib.SDL_StopTextInput(self.p)) |
| 487 | + |
372 | 488 |
|
373 | 489 | def new_window( # noqa: PLR0913
|
374 | 490 | width: int,
|
|
0 commit comments