twblue/src/keyboard_handler/main.py

89 lines
2.6 KiB
Python

import platform
import time
class KeyboardHandlerError (Exception): pass
class KeyboardHandler(object):
def __init__(self, repeat_rate=0.0, *args, **kwargs):
self.repeat_rate = repeat_rate #How long between accepting the same keystroke?
self._last_key = None
self._last_keypress_time = 0
super(KeyboardHandler, self).__init__(*args, **kwargs)
self.active_keys = {}
if not hasattr(self, 'replacement_mods'):
self.replacement_mods = {}
if not hasattr(self, 'replacement_keys'):
self.replacement_keys = {}
def register_key (self, key, function):
if key in self.active_keys:
raise KeyboardHandlerError, "Key %s is already registered to a function" % key
if not callable(function):
raise TypeError, "Must provide a callable to be invoked upon keypress"
self.active_keys[key] = function
def unregister_key (self, key, function):
try:
if self.active_keys[key] != function:
raise KeyboardHandlerError, "key %s is not registered to that function" % key
except KeyError:
raise KeyboardHandlerError, "Key %s not currently registered"
del(self.active_keys[key])
def unregister_all_keys(self):
for key in list(self.active_keys):
self.unregister_key(key, self.active_keys[key])
def handle_key (self, key):
if self.repeat_rate and key == self._last_key and time.time() - self._last_keypress_time < self.repeat_rate:
return
try:
function = self.active_keys[key]
except KeyError:
return
self._last_key = key
self._last_keypress_time = time.time()
return function()
def register_keys(self, keys):
"""Given a mapping of keystrokes to functions, registers all keystrokes"""
for k in keys:
self.register_key(k, keys[k])
def unregister_keys(self, keys):
"""Given a mapping of keys to their functions, unregisters all provided keys."""
for k in keys:
self.unregister_key(k, keys[k])
def standardize_key(self, key):
"""Takes a keystroke and places it in a standard case and order in a list."""
working = key.split('+')
working = [i.lower() for i in working]
answer = []
if "control" in working:
answer.append("control")
if "win" in working:
answer.append("win")
if "alt" in working:
answer.append("alt")
if "shift" in working:
answer.append("shift")
if working[-1] not in answer:
answer.append(working[-1])
return answer
def standardize_keymap(self, keymap):
"""Given a keymap, returns the keymap standardized."""
full = {}
for i in keymap:
answer = ""
new = self.standardize_key(keymap[i])
for (c, j) in enumerate(new):
if c < len(new)-1:
answer = "%s%s+" % (answer, j)
else:
answer = "%s%s" % (answer, j)
full[i] = answer
return full