|
93 | 93 | from tcod.event_constants import * # noqa: F4 |
94 | 94 | from tcod.event_constants import KMOD_ALT, KMOD_CTRL, KMOD_GUI, KMOD_SHIFT |
95 | 95 | from tcod.loader import ffi, lib |
| 96 | +from tcod.sdl.joystick import _HAT_DIRECTIONS |
96 | 97 |
|
97 | 98 | T = TypeVar("T") |
98 | 99 |
|
@@ -303,7 +304,7 @@ def from_sdl_event(cls, sdl_event: Any) -> Event: |
303 | 304 | raise NotImplementedError() |
304 | 305 |
|
305 | 306 | def __str__(self) -> str: |
306 | | - return "<type=%r>" % (self.type,) |
| 307 | + return f"<type={self.type!r}>" |
307 | 308 |
|
308 | 309 |
|
309 | 310 | class Quit(Event): |
@@ -779,6 +780,199 @@ def __str__(self) -> str: |
779 | 780 | ) |
780 | 781 |
|
781 | 782 |
|
| 783 | +class JoystickEvent(Event): |
| 784 | + """A base class for joystick events. |
| 785 | +
|
| 786 | + .. versionadded:: Unreleased |
| 787 | + """ |
| 788 | + |
| 789 | + def __init__(self, type: str, which: int): |
| 790 | + super().__init__(type) |
| 791 | + self.which = which |
| 792 | + """The ID of the joystick this event is for.""" |
| 793 | + |
| 794 | + def __repr__(self) -> str: |
| 795 | + return f"tcod.event.{self.__class__.__name__}" f"(type={self.type!r}, which={self.which})" |
| 796 | + |
| 797 | + def __str__(self) -> str: |
| 798 | + prefix = super().__str__().strip("<>") |
| 799 | + return f"<{prefix}, which={self.which}>" |
| 800 | + |
| 801 | + |
| 802 | +class JoystickAxis(JoystickEvent): |
| 803 | + """When a joystick axis changes in value. |
| 804 | +
|
| 805 | + .. versionadded:: Unreleased |
| 806 | +
|
| 807 | + .. seealso:: |
| 808 | + :any:`tcod.sdl.joystick` |
| 809 | + """ |
| 810 | + |
| 811 | + which: int |
| 812 | + """The ID of the joystick this event is for.""" |
| 813 | + |
| 814 | + def __init__(self, type: str, which: int, axis: int, value: int): |
| 815 | + super().__init__(type, which) |
| 816 | + self.axis = axis |
| 817 | + """The index of the changed axis.""" |
| 818 | + self.value = value |
| 819 | + """The raw value of the axis in the range -32768 to 32767.""" |
| 820 | + |
| 821 | + @classmethod |
| 822 | + def from_sdl_event(cls, sdl_event: Any) -> JoystickAxis: |
| 823 | + return cls("JOYAXISMOTION", sdl_event.jaxis.which, sdl_event.jaxis.axis, sdl_event.jaxis.value) |
| 824 | + |
| 825 | + def __repr__(self) -> str: |
| 826 | + return ( |
| 827 | + f"tcod.event.{self.__class__.__name__}" |
| 828 | + f"(type={self.type!r}, which={self.which}, axis={self.axis}, value={self.value})" |
| 829 | + ) |
| 830 | + |
| 831 | + def __str__(self) -> str: |
| 832 | + prefix = super().__str__().strip("<>") |
| 833 | + return f"<{prefix}, axis={self.axis}, value={self.value}>" |
| 834 | + |
| 835 | + |
| 836 | +class JoystickBall(JoystickEvent): |
| 837 | + """When a joystick ball is moved. |
| 838 | +
|
| 839 | + .. versionadded:: Unreleased |
| 840 | +
|
| 841 | + .. seealso:: |
| 842 | + :any:`tcod.sdl.joystick` |
| 843 | + """ |
| 844 | + |
| 845 | + which: int |
| 846 | + """The ID of the joystick this event is for.""" |
| 847 | + |
| 848 | + def __init__(self, type: str, which: int, ball: int, dx: int, dy: int): |
| 849 | + super().__init__(type, which) |
| 850 | + self.ball = ball |
| 851 | + """The index of the moved ball.""" |
| 852 | + self.dx = dx |
| 853 | + """The X motion of the ball.""" |
| 854 | + self.dy = dy |
| 855 | + """The Y motion of the ball.""" |
| 856 | + |
| 857 | + @classmethod |
| 858 | + def from_sdl_event(cls, sdl_event: Any) -> JoystickBall: |
| 859 | + return cls( |
| 860 | + "JOYBALLMOTION", sdl_event.jball.which, sdl_event.jball.ball, sdl_event.jball.xrel, sdl_event.jball.yrel |
| 861 | + ) |
| 862 | + |
| 863 | + def __repr__(self) -> str: |
| 864 | + return ( |
| 865 | + f"tcod.event.{self.__class__.__name__}" |
| 866 | + f"(type={self.type!r}, which={self.which}, ball={self.ball}, dx={self.dx}, dy={self.dy})" |
| 867 | + ) |
| 868 | + |
| 869 | + def __str__(self) -> str: |
| 870 | + prefix = super().__str__().strip("<>") |
| 871 | + return f"<{prefix}, ball={self.ball}, dx={self.dx}, dy={self.dy}>" |
| 872 | + |
| 873 | + |
| 874 | +class JoystickHat(JoystickEvent): |
| 875 | + """When a joystick hat changes direction. |
| 876 | +
|
| 877 | + .. versionadded:: Unreleased |
| 878 | +
|
| 879 | + .. seealso:: |
| 880 | + :any:`tcod.sdl.joystick` |
| 881 | + """ |
| 882 | + |
| 883 | + which: int |
| 884 | + """The ID of the joystick this event is for.""" |
| 885 | + |
| 886 | + def __init__(self, type: str, which: int, x: Literal[-1, 0, 1], y: Literal[-1, 0, 1]): |
| 887 | + super().__init__(type, which) |
| 888 | + self.x = x |
| 889 | + """The new X direction of the hat.""" |
| 890 | + self.y = y |
| 891 | + """The new Y direction of the hat.""" |
| 892 | + |
| 893 | + @classmethod |
| 894 | + def from_sdl_event(cls, sdl_event: Any) -> JoystickHat: |
| 895 | + return cls("JOYHATMOTION", sdl_event.jhat.which, *_HAT_DIRECTIONS[sdl_event.jhat.hat]) |
| 896 | + |
| 897 | + def __repr__(self) -> str: |
| 898 | + return ( |
| 899 | + f"tcod.event.{self.__class__.__name__}" f"(type={self.type!r}, which={self.which}, x={self.x}, y={self.y})" |
| 900 | + ) |
| 901 | + |
| 902 | + def __str__(self) -> str: |
| 903 | + prefix = super().__str__().strip("<>") |
| 904 | + return f"<{prefix}, x={self.x}, y={self.y}>" |
| 905 | + |
| 906 | + |
| 907 | +class JoystickButton(JoystickEvent): |
| 908 | + """When a joystick button is pressed or released. |
| 909 | +
|
| 910 | + .. versionadded:: Unreleased |
| 911 | +
|
| 912 | + Example:: |
| 913 | +
|
| 914 | + for event in tcod.event.get(): |
| 915 | + match event: |
| 916 | + case JoystickButton(which=which, button=button, pressed=True): |
| 917 | + print(f"Pressed {button=} on controller {which}.") |
| 918 | + case JoystickButton(which=which, button=button, pressed=False): |
| 919 | + print(f"Released {button=} on controller {which}.") |
| 920 | + """ |
| 921 | + |
| 922 | + which: int |
| 923 | + """The ID of the joystick this event is for.""" |
| 924 | + |
| 925 | + def __init__(self, type: str, which: int, button: int): |
| 926 | + super().__init__(type, which) |
| 927 | + self.button = button |
| 928 | + """The index of the button this event is for.""" |
| 929 | + |
| 930 | + @property |
| 931 | + def pressed(self) -> bool: |
| 932 | + """True if the joystick button has been pressed, False when the button was released.""" |
| 933 | + return self.type == "JOYBUTTONDOWN" |
| 934 | + |
| 935 | + @classmethod |
| 936 | + def from_sdl_event(cls, sdl_event: Any) -> JoystickButton: |
| 937 | + type = {lib.SDL_JOYBUTTONDOWN: "JOYBUTTONDOWN", lib.SDL_JOYBUTTONUP: "JOYBUTTONUP"}[sdl_event.type] |
| 938 | + return cls(type, sdl_event.jbutton.which, sdl_event.jbutton.button) |
| 939 | + |
| 940 | + def __repr__(self) -> str: |
| 941 | + return f"tcod.event.{self.__class__.__name__}" f"(type={self.type!r}, which={self.which}, button={self.button})" |
| 942 | + |
| 943 | + def __str__(self) -> str: |
| 944 | + prefix = super().__str__().strip("<>") |
| 945 | + return f"<{prefix}, button={self.button}>" |
| 946 | + |
| 947 | + |
| 948 | +class JoystickDevice(JoystickEvent): |
| 949 | + """An event for when a joystick is added or removed. |
| 950 | +
|
| 951 | + .. versionadded:: Unreleased |
| 952 | +
|
| 953 | + Example:: |
| 954 | +
|
| 955 | + joysticks: dict[int, tcod.sdl.joystick.Joystick] = {} |
| 956 | + for event in tcod.event.get(): |
| 957 | + match event: |
| 958 | + case tcod.event.JoystickDevice(type="JOYDEVICEADDED", which=device_id): |
| 959 | + new_joystick = tcod.sdl.joystick.Joystick(device_id) |
| 960 | + joysticks[new_joystick.id] = new_joystick |
| 961 | + case tcod.event.JoystickDevice(type="JOYDEVICEREMOVED", which=which): |
| 962 | + del joysticks[which] |
| 963 | + """ |
| 964 | + |
| 965 | + which: int |
| 966 | + """When type="JOYDEVICEADDED" this is the device ID. |
| 967 | + When type="JOYDEVICEREMOVED" this is the instance ID. |
| 968 | + """ |
| 969 | + |
| 970 | + @classmethod |
| 971 | + def from_sdl_event(cls, sdl_event: Any) -> JoystickDevice: |
| 972 | + type = {lib.SDL_JOYDEVICEADDED: "JOYDEVICEADDED", lib.SDL_JOYDEVICEREMOVED: "JOYDEVICEREMOVED"}[sdl_event.type] |
| 973 | + return cls(type, sdl_event.jdevice.which) |
| 974 | + |
| 975 | + |
782 | 976 | class Undefined(Event): |
783 | 977 | """This class is a place holder for SDL events without their own tcod.event |
784 | 978 | class. |
@@ -809,6 +1003,13 @@ def __str__(self) -> str: |
809 | 1003 | lib.SDL_MOUSEWHEEL: MouseWheel, |
810 | 1004 | lib.SDL_TEXTINPUT: TextInput, |
811 | 1005 | lib.SDL_WINDOWEVENT: WindowEvent, |
| 1006 | + lib.SDL_JOYAXISMOTION: JoystickAxis, |
| 1007 | + lib.SDL_JOYBALLMOTION: JoystickBall, |
| 1008 | + lib.SDL_JOYHATMOTION: JoystickHat, |
| 1009 | + lib.SDL_JOYBUTTONDOWN: JoystickButton, |
| 1010 | + lib.SDL_JOYBUTTONUP: JoystickButton, |
| 1011 | + lib.SDL_JOYDEVICEADDED: JoystickDevice, |
| 1012 | + lib.SDL_JOYDEVICEREMOVED: JoystickDevice, |
812 | 1013 | } |
813 | 1014 |
|
814 | 1015 |
|
@@ -1076,6 +1277,41 @@ def ev_windowtakefocus(self, event: tcod.event.WindowEvent) -> Optional[T]: |
1076 | 1277 | def ev_windowhittest(self, event: tcod.event.WindowEvent) -> Optional[T]: |
1077 | 1278 | pass |
1078 | 1279 |
|
| 1280 | + def ev_joyaxismotion(self, event: tcod.event.JoystickAxis) -> Optional[T]: |
| 1281 | + """ |
| 1282 | + .. versionadded:: Unreleased |
| 1283 | + """ |
| 1284 | + |
| 1285 | + def ev_joyballmotion(self, event: tcod.event.JoystickBall) -> Optional[T]: |
| 1286 | + """ |
| 1287 | + .. versionadded:: Unreleased |
| 1288 | + """ |
| 1289 | + |
| 1290 | + def ev_joyhatmotion(self, event: tcod.event.JoystickHat) -> Optional[T]: |
| 1291 | + """ |
| 1292 | + .. versionadded:: Unreleased |
| 1293 | + """ |
| 1294 | + |
| 1295 | + def ev_joybuttondown(self, event: tcod.event.JoystickButton) -> Optional[T]: |
| 1296 | + """ |
| 1297 | + .. versionadded:: Unreleased |
| 1298 | + """ |
| 1299 | + |
| 1300 | + def ev_joybuttonup(self, event: tcod.event.JoystickButton) -> Optional[T]: |
| 1301 | + """ |
| 1302 | + .. versionadded:: Unreleased |
| 1303 | + """ |
| 1304 | + |
| 1305 | + def ev_joydeviceadded(self, event: tcod.event.JoystickDevice) -> Optional[T]: |
| 1306 | + """ |
| 1307 | + .. versionadded:: Unreleased |
| 1308 | + """ |
| 1309 | + |
| 1310 | + def ev_joydeviceremoved(self, event: tcod.event.JoystickDevice) -> Optional[T]: |
| 1311 | + """ |
| 1312 | + .. versionadded:: Unreleased |
| 1313 | + """ |
| 1314 | + |
1079 | 1315 | def ev_(self, event: Any) -> Optional[T]: |
1080 | 1316 | pass |
1081 | 1317 |
|
@@ -2326,6 +2562,12 @@ def __repr__(self) -> str: |
2326 | 2562 | "WindowEvent", |
2327 | 2563 | "WindowMoved", |
2328 | 2564 | "WindowResized", |
| 2565 | + "JoystickEvent", |
| 2566 | + "JoystickAxis", |
| 2567 | + "JoystickBall", |
| 2568 | + "JoystickHat", |
| 2569 | + "JoystickButton", |
| 2570 | + "JoystickDevice", |
2329 | 2571 | "Undefined", |
2330 | 2572 | "get", |
2331 | 2573 | "wait", |
|
0 commit comments