Project

Profile

Help

How to connect?
Download (4.48 KB) Statistics View on GitHub Reload from mirrored respository
| Branch: | Tag: | Revision:

github / src / scripting / key.py @ 13e86181

1
# Copyright (c) 2016, LE GOFF Vincent
2
# All rights reserved.
3

    
4
# Redistribution and use in source and binary forms, with or without
5
# modification, are permitted provided that the following conditions are met:
6

    
7
# * Redistributions of source code must retain the above copyright notice, this
8
#   list of conditions and the following disclaimer.
9

    
10
# * Redistributions in binary form must reproduce the above copyright notice,
11
#   this list of conditions and the following disclaimer in the documentation
12
#   and/or other materials provided with the distribution.
13

    
14
# * Neither the name of ytranslate nor the names of its
15
#   contributors may be used to endorse or promote products derived from
16
#   this software without specific prior written permission.
17

    
18
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28

    
29
"""Module containing functions to handle the keyboard."""
30

    
31
## Constants
32

    
33
# Modifiers
34
MOD_ALT = 1
35
MOD_CTRL = 2
36
MOD_SHIFT = 4
37

    
38
# Key codes
39
CODE_TO_KEY = {
40
    8: "Backspace",
41
    13: "Enter",
42
    27: "Escape",
43
    32: "Space",
44
    310: "Pause",
45
    324: "PavNum0",
46
    325: "PavNum1",
47
    326: "PavNum2",
48
    327: "PavNum3",
49
    328: "PavNum4",
50
    329: "PavNum5",
51
    330: "PavNum6",
52
    331: "PavNum7",
53
    332: "PavNum8",
54
    333: "PavNum9",
55
    340: "F1",
56
    341: "F2",
57
    342: "F3",
58
    343: "F4",
59
    344: "F5",
60
    345: "F6",
61
    346: "F7",
62
    347: "F8",
63
    348: "F9",
64
    349: "F10",
65
    350: "F11",
66
    351: "F12",
67
    364: "NumLock",
68
    387: "PavNum*",
69
    388: "PavNum+",
70
    390: "PavNum-",
71
    391: "PavNum.",
72
    392: "PavNum/",
73
    398: "PavNum-",
74
}
75

    
76
KEY_TO_CODE = {}
77
for code, key in CODE_TO_KEY.items():
78
    KEY_TO_CODE[key.lower()] = code
79

    
80
# Add a few keys in the KEY_TO_CODE dictionary, as names may differ
81
KEY_TO_CODE["esc"] = 27
82
KEY_TO_CODE["back"] = 8
83
KEY_TO_CODE["return"] = 13
84
KEY_TO_CODE["pavnumlock"] = 364
85
KEY_TO_CODE["pavlock"] = 364
86

    
87
## Functions
88
def key_name(code, modifiers):
89
    """Return the key name, if found."""
90
    if code in CODE_TO_KEY:
91
        name = CODE_TO_KEY[code]
92
    elif 0 < code < 256:
93
        name = chr(code).upper()
94
    else:
95
        return ""
96

    
97
    ctrl = modifiers & MOD_CTRL != 0
98
    alt = modifiers & MOD_ALT != 0
99
    shift = modifiers & MOD_SHIFT != 0
100
    if shift:
101
        name = "Shift + " + name
102
    if alt:
103
        name = "Alt + " + name
104
    if ctrl:
105
        name = "Ctrl + " + name
106

    
107
    return name
108

    
109
def key_code(name):
110
    """Return the key code as a tuple.
111

112
    The returned key code is a tuple containing two integers:
113
        code: The key code as present in the constants
114
        modifiers: A binary value of active modifiers
115

116
    For example:
117
        (8, 0) means Backspace (no modifiers)
118
        (340, 1) means Alt + F1
119
        (13, 6) means Ctrl + Shift + Enter
120
        (107, 2) means Ctrl + K
121

122
    """
123
    # Remove spaces
124
    name = name.replace(" ", "").lower()
125

    
126
    # Scan for modifiers
127
    modifiers = ("shift", "ctrl", "control", "alt")
128
    active_modifiers = 0
129
    while name:
130
        found = False
131
        for modifier in modifiers:
132
            if name.startswith(modifier):
133
                name = name[len(modifier):]
134
                if modifier == "alt":
135
                    active_modifiers = active_modifiers | MOD_ALT
136
                elif modifier in ("ctrl", "control"):
137
                    active_modifiers = active_modifiers | MOD_CTRL
138
                elif modifier == "shift":
139
                    active_modifiers = active_modifiers | MOD_SHIFT
140

    
141
                found = True
142
                break
143

    
144
        if name and name[0] in "+-":
145
            name = name[1:]
146

    
147
        if not found:
148
            break
149

    
150
    if len(name) == 1:
151
        code = ord(name.upper())
152
    elif name not in KEY_TO_CODE:
153
        raise ValueError("The key {} cannot be found".format(
154
                repr(name)))
155
    else:
156
        code = KEY_TO_CODE[name]
157

    
158
    return (code, active_modifiers)
(3-3/5)