ibitfit/electric_sieve/pgfw/Input.py

205 lines
7.1 KiB
Python

from time import time as get_secs
from pygame import joystick as joy
from pygame.key import get_pressed
from pygame.locals import *
from GameChild import *
class Input(GameChild):
def __init__(self, game):
GameChild.__init__(self, game)
self.last_mouse_down_left = None
self.joystick = Joystick()
self.delegate = self.get_delegate()
self.load_configuration()
self.set_any_press_ignore_list()
self.unsuppress()
self.subscribe_to_events()
self.build_key_map()
self.build_joy_button_map()
def load_configuration(self):
self.release_suffix = self.get_configuration("input", "release-suffix")
self.key_commands = self.get_configuration().items("keys")
self.double_click_time_limit = self.get_configuration(
"mouse", "double-click-time-limit")
def set_any_press_ignore_list(self):
self.any_press_ignored = set(["capture-screen", "toggle-fullscreen",
"reset-game", "record-video", "quit",
"mute", "toggle-interpolator"])
self.any_press_ignored_keys = set()
def unsuppress(self):
self.suppressed = False
def subscribe_to_events(self):
self.subscribe(self.translate_key, KEYDOWN)
self.subscribe(self.translate_key, KEYUP)
self.subscribe(self.translate_joy_button, JOYBUTTONDOWN)
self.subscribe(self.translate_joy_button, JOYBUTTONUP)
self.subscribe(self.translate_axis_motion, JOYAXISMOTION)
self.subscribe(self.translate_mouse_input, MOUSEBUTTONDOWN)
self.subscribe(self.translate_mouse_input, MOUSEBUTTONUP)
def build_key_map(self):
key_map = {}
for command, keys in self.key_commands:
key_map[command] = []
if type(keys) == str:
keys = [keys]
for key in keys:
key_map[command].append(globals()[key])
self.key_map = key_map
def build_joy_button_map(self):
self.joy_button_map = self.get_configuration("joy")
def suppress(self):
self.suppressed = True
def translate_key(self, event):
if not self.suppressed:
cancel = event.type == KEYUP
posted = None
key = event.key
for cmd, keys in self.key_map.iteritems():
if key in keys:
self.post_command(cmd, cancel=cancel)
posted = cmd
if (not posted or posted not in self.any_press_ignored) and \
key not in self.any_press_ignored_keys:
self.post_any_command(key, cancel)
def post_command(self, cmd, **attributes):
self.delegate.post(cmd, **attributes)
def post_any_command(self, id, cancel=False):
self.post_command("any", id=id, cancel=cancel)
def translate_joy_button(self, event):
if not self.suppressed:
cancel = event.type == JOYBUTTONUP
posted = None
for command, button in self.joy_button_map.iteritems():
if button == event.button:
self.post_command(command, cancel=cancel)
posted = command
if not posted or posted not in self.any_press_ignored:
self.post_any_command(event.button, cancel)
def translate_axis_motion(self, event):
if not self.suppressed:
axis = event.axis
value = event.value
if not value:
for command in "up", "right", "down", "left":
self.post_command(command, cancel=True)
if command not in self.any_press_ignored:
self.post_any_command(command, True)
else:
if axis == 1:
if value < 0:
command = "up"
elif value > 0:
command = "down"
else:
if value > 0:
command = "right"
elif value < 0:
command = "left"
self.post_command(command)
if command not in self.any_press_ignored:
self.post_any_command(command)
def is_command_active(self, command):
if not self.suppressed:
if self.is_key_pressed(command):
return True
joystick = self.joystick
joy_map = self.joy_button_map
if command in joy_map and joystick.get_button(joy_map[command]):
return True
if command == "up":
return joystick.is_direction_pressed(Joystick.up)
elif command == "right":
return joystick.is_direction_pressed(Joystick.right)
elif command == "down":
return joystick.is_direction_pressed(Joystick.down)
elif command == "left":
return joystick.is_direction_pressed(Joystick.left)
def is_key_pressed(self, command):
poll = get_pressed()
for key in self.key_map[command]:
if poll[key]:
return True
def translate_mouse_input(self, event):
button = event.button
pos = event.pos
post = self.post_command
if event.type == MOUSEBUTTONDOWN:
if button == 1:
last = self.last_mouse_down_left
if last:
limit = self.double_click_time_limit
if get_secs() - last < limit:
post("mouse-double-click-left", pos=pos)
last = get_secs()
self.last_mouse_down_left = last
def get_axes(self):
axes = {}
for direction in "up", "right", "down", "left":
axes[direction] = self.is_command_active(direction)
return axes
def register_any_press_ignore(self, *args, **attributes):
self.any_press_ignored.update(args)
self.any_press_ignored_keys.update(self.extract_keys(attributes))
def extract_keys(self, attributes):
keys = []
if "keys" in attributes:
keys = attributes["keys"]
if type(keys) == int:
keys = [keys]
return keys
def unregister_any_press_ignore(self, *args, **attributes):
self.any_press_ignored.difference_update(args)
self.any_press_ignored_keys.difference_update(
self.extract_keys(attributes))
class Joystick:
(up, right, down, left) = range(4)
def __init__(self):
js = None
if joy.get_count() > 0:
js = joy.Joystick(0)
js.init()
self.js = js
def is_direction_pressed(self, direction):
js = self.js
if not js or direction > 4:
return False
if direction == 0:
return js.get_axis(1) < 0
elif direction == 1:
return js.get_axis(0) > 0
elif direction == 2:
return js.get_axis(1) > 0
elif direction == 3:
return js.get_axis(0) < 0
def get_button(self, id):
if self.js:
return self.js.get_button(id)