9090from typing_extensions import Final , Literal
9191
9292import tcod .event_constants
93+ import tcod .sdl .joystick
9394from tcod .event_constants import * # noqa: F4
9495from tcod .event_constants import KMOD_ALT , KMOD_CTRL , KMOD_GUI , KMOD_SHIFT
9596from tcod .loader import ffi , lib
@@ -791,6 +792,12 @@ def __init__(self, type: str, which: int):
791792 self .which = which
792793 """The ID of the joystick this event is for."""
793794
795+ @property
796+ def joystick (self ) -> tcod .sdl .joystick .Joystick :
797+ if self .type == "JOYDEVICEADDED" :
798+ return tcod .sdl .joystick .Joystick ._open (self .which )
799+ return tcod .sdl .joystick .Joystick ._from_instance_id (self .which )
800+
794801 def __repr__ (self ) -> str :
795802 return f"tcod.event.{ self .__class__ .__name__ } " f"(type={ self .type !r} , which={ self .which } )"
796803
@@ -952,17 +959,16 @@ class JoystickDevice(JoystickEvent):
952959
953960 Example::
954961
955- joysticks: dict[int, tcod.sdl.joystick.Joystick] = {}
962+ joysticks: set[ tcod.sdl.joystick.Joystick] = {}
956963 for event in tcod.event.get():
957964 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]
965+ case tcod.event.JoystickDevice(type="JOYDEVICEADDED", joystick=new_joystick):
966+ joysticks.add(new_joystick)
967+ case tcod.event.JoystickDevice(type="JOYDEVICEREMOVED", joystick=joystick):
968+ joysticks.remove(joystick)
963969 """
964970
965- type = Final [Literal ["JOYDEVICEADDED" , "JOYDEVICEREMOVED" ]] # type: ignore[assignment, misc]
971+ type : Final [Literal ["JOYDEVICEADDED" , "JOYDEVICEREMOVED" ]] # type: ignore[misc]
966972
967973 which : int
968974 """When type="JOYDEVICEADDED" this is the device ID.
@@ -975,6 +981,126 @@ def from_sdl_event(cls, sdl_event: Any) -> JoystickDevice:
975981 return cls (type , sdl_event .jdevice .which )
976982
977983
984+ class ControllerEvent (Event ):
985+ """Base class for controller events.
986+
987+ .. versionadded:: Unreleased
988+ """
989+
990+ def __init__ (self , type : str , which : int ):
991+ super ().__init__ (type )
992+ self .which = which
993+ """The ID of the joystick this event is for."""
994+
995+ @property
996+ def controller (self ) -> tcod .sdl .joystick .GameController :
997+ """The :any:`GameController: for this event."""
998+ if self .type == "CONTROLLERDEVICEADDED" :
999+ return tcod .sdl .joystick .GameController ._open (self .which )
1000+ return tcod .sdl .joystick .GameController ._from_instance_id (self .which )
1001+
1002+ def __repr__ (self ) -> str :
1003+ return f"tcod.event.{ self .__class__ .__name__ } " f"(type={ self .type !r} , which={ self .which } )"
1004+
1005+ def __str__ (self ) -> str :
1006+ prefix = super ().__str__ ().strip ("<>" )
1007+ return f"<{ prefix } , which={ self .which } >"
1008+
1009+
1010+ class ControllerAxis (ControllerEvent ):
1011+ """When a controller axis is moved.
1012+
1013+ .. versionadded:: Unreleased
1014+ """
1015+
1016+ type : Final [Literal ["CONTROLLERAXISMOTION" ]] # type: ignore[misc]
1017+
1018+ def __init__ (self , type : str , which : int , axis : tcod .sdl .joystick .ControllerAxis , value : int ):
1019+ super ().__init__ (type , which )
1020+ self .axis = axis
1021+ """Which axis is being moved. One of :any:`ControllerAxis`."""
1022+ self .value = value
1023+ """The new value of this events axis.
1024+
1025+ This will be -32768 to 32767 for all axes except for triggers which are 0 to 32767 instead."""
1026+
1027+ @classmethod
1028+ def from_sdl_event (cls , sdl_event : Any ) -> ControllerAxis :
1029+ return cls (
1030+ "CONTROLLERAXISMOTION" ,
1031+ sdl_event .caxis .which ,
1032+ tcod .sdl .joystick .ControllerAxis (sdl_event .caxis .axis ),
1033+ sdl_event .caxis .value ,
1034+ )
1035+
1036+ def __repr__ (self ) -> str :
1037+ return (
1038+ f"tcod.event.{ self .__class__ .__name__ } "
1039+ f"(type={ self .type !r} , which={ self .which } , axis={ self .axis } , value={ self .value } )"
1040+ )
1041+
1042+ def __str__ (self ) -> str :
1043+ prefix = super ().__str__ ().strip ("<>" )
1044+ return f"<{ prefix } , axis={ self .axis } , value={ self .value } >"
1045+
1046+
1047+ class ControllerButton (ControllerEvent ):
1048+ """When a controller button is pressed or released.
1049+
1050+ .. versionadded:: Unreleased
1051+ """
1052+
1053+ type : Final [Literal ["CONTROLLERBUTTONDOWN" , "CONTROLLERBUTTONUP" ]] # type: ignore[misc]
1054+
1055+ def __init__ (self , type : str , which : int , button : tcod .sdl .joystick .ControllerButton , pressed : bool ):
1056+ super ().__init__ (type , which )
1057+ self .button = button
1058+ """The button for this event. One of :any:`ControllerButton`."""
1059+ self .pressed = pressed
1060+ """True if the button was pressed, False if it was released."""
1061+
1062+ @classmethod
1063+ def from_sdl_event (cls , sdl_event : Any ) -> ControllerButton :
1064+ type = {
1065+ lib .SDL_CONTROLLERBUTTONDOWN : "CONTROLLERBUTTONDOWN" ,
1066+ lib .SDL_CONTROLLERBUTTONUP : "CONTROLLERBUTTONUP" ,
1067+ }[sdl_event .type ]
1068+ return cls (
1069+ type ,
1070+ sdl_event .cbutton .which ,
1071+ tcod .sdl .joystick .ControllerButton (sdl_event .cbutton .button ),
1072+ sdl_event .cbutton .state == lib .SDL_PRESSED ,
1073+ )
1074+
1075+ def __repr__ (self ) -> str :
1076+ return (
1077+ f"tcod.event.{ self .__class__ .__name__ } "
1078+ f"(type={ self .type !r} , which={ self .which } , button={ self .button } , pressed={ self .pressed } )"
1079+ )
1080+
1081+ def __str__ (self ) -> str :
1082+ prefix = super ().__str__ ().strip ("<>" )
1083+ return f"<{ prefix } , button={ self .button } , pressed={ self .pressed } >"
1084+
1085+
1086+ class ControllerDevice (ControllerEvent ):
1087+ """When a controller is added, removed, or remapped.
1088+
1089+ .. versionadded:: Unreleased
1090+ """
1091+
1092+ type : Final [Literal ["CONTROLLERDEVICEADDED" , "CONTROLLERDEVICEREMOVED" , "CONTROLLERDEVICEREMAPPED" ]] # type: ignore[misc]
1093+
1094+ @classmethod
1095+ def from_sdl_event (cls , sdl_event : Any ) -> ControllerDevice :
1096+ type = {
1097+ lib .SDL_CONTROLLERDEVICEADDED : "CONTROLLERDEVICEADDED" ,
1098+ lib .SDL_CONTROLLERDEVICEREMOVED : "CONTROLLERDEVICEREMOVED" ,
1099+ lib .SDL_CONTROLLERDEVICEREMAPPED : "CONTROLLERDEVICEREMAPPED" ,
1100+ }[sdl_event .type ]
1101+ return cls (type , sdl_event .cdevice .which )
1102+
1103+
9781104class Undefined (Event ):
9791105 """This class is a place holder for SDL events without their own tcod.event
9801106 class.
@@ -1012,6 +1138,12 @@ def __str__(self) -> str:
10121138 lib .SDL_JOYBUTTONUP : JoystickButton ,
10131139 lib .SDL_JOYDEVICEADDED : JoystickDevice ,
10141140 lib .SDL_JOYDEVICEREMOVED : JoystickDevice ,
1141+ lib .SDL_CONTROLLERAXISMOTION : ControllerAxis ,
1142+ lib .SDL_CONTROLLERBUTTONDOWN : ControllerButton ,
1143+ lib .SDL_CONTROLLERBUTTONUP : ControllerButton ,
1144+ lib .SDL_CONTROLLERDEVICEADDED : ControllerDevice ,
1145+ lib .SDL_CONTROLLERDEVICEREMOVED : ControllerDevice ,
1146+ lib .SDL_CONTROLLERDEVICEREMAPPED : ControllerDevice ,
10151147}
10161148
10171149
0 commit comments