summaryrefslogtreecommitdiff
path: root/key.py
blob: dc960c1fff18499b1ab29edd771a9d1b3a791b6f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
ESC = '\x1b'

def assert_type(thing,_type):
    ''' if thing is not of type _type raise an exception '''
    if type(thing) is not _type:
        raise TypeError,
            "%s is of %s, should be of %s" %
                (str(thing),type(thing),_type)

class Key:
    ''' a keyboard keypress object '''

    def __init__(self,name,*modifiers):
        assert_type(name,str)
        for m in modifiers:
            assert isinstance(m,Key),
                "Modifiers expected to be instances of Key"
        self.name = name
        self.modifiers = list(modifiers)
        self.modifiers.sort()

    def __eq__(self,other):
        if not isinstance(Key,other): return False
        return str(self) == str(other)

    def __ne__(self,other):
        if isinstance(Key,other): return True
        return str(self) != str(other)

    def __str__(self):
        to_return = str()
        for m in self.modifiers:
            to_return += '%s ' % str(m)
        to_return += self.name
        return to_return

    def has_modifier(self,modifier):
        ''' does this object have the modifier? '''
        if modifier in self.modifiers:
            return True
        return False

    def modify(self,modifier):
        ''' add a modifier '''
        if modifier not in self.modifiers:
            self.modifiers.append(modifier)
        self.modifiers.sort()
        return self

ALT = Key('Alt')
CTRL = Key('Control')

table = {
        ESC : Key('Escape'),
        '\t': Key('Tab'),
        ' ': Key('Space'),
        '\n': Key('Enter'),
        '\x7f' : Key('Backspace'),
        '%sOF' % ESC: Key('End'),
        '%sOH' % ESC: Key('Home'),
        '%s[3~' % ESC: Key('Del'),
        '%s[2~' % ESC: Key('Insert'),
        '%s[5~' % ESC: Key('PageUp'),
        '%s[6~' % ESC: Key('PageDown'),
        '%sOP' % ESC: Key('F1'),
        '%sOQ' % ESC: Key('F2'),
        '%sOR' % ESC: Key('F3'),
        '%sOS' % ESC: Key('F4'),
        '%s[15~' % ESC: Key('F5'),
        '%s[17~' % ESC: Key('F6'),
        '%s[18~' % ESC: Key('F7'),
        '%s[19~' % ESC: Key('F8'),
        '%s[20~' % ESC: Key('F9'),
        '%s[21~' % ESC: Key('F10'),
        '%s[23~' % ESC: Key('F11'),
        '%s[24~' % ESC: Key('F12'),
        '%s[A' % ESC: Key('Up'),
        '%s[B' % ESC: Key('Down'),
        '%s[D' % ESC: Key('Left'),
        '%s[C' % ESC: Key('Right'),
    }

def is_alt(code):
    ''' is this the code of a combination modified by Alt? '''
    assert_type(name,str)
    if len(code) == 2 and code[0] == ESC:
        return True
    return False

def is_ctrl_alpha(code):
    ''' is this the code of a combination modified by Ctrl? '''
    assert_type(name,str)
    if code < '\x20': return True
    return False

def get_ctrl_alpha(code):
    ''' get alphabetic key modified by Ctrl '''
    assert_type(name,str)
    letter = chr(ord(code) + 0x40)
    return Key(letter,CTRL)

def parse_code(code):
    ''' get Key object from code '''
    assert_type(name,str)
    if code in table.keys(): return table[code]
    elif is_alt(code): return from_keycode(code[1:]).modify(ALT)
    elif is_ctrl_alpha(code): return get_ctrl_alpha(code)
    else: return Key(code)