]>
Commit | Line | Data |
---|---|---|
1df30f07 | 1 | # -*- coding: utf-8 -*- |
189bf90c | 2 | from pygame import * |
8f88a3e4 IB |
3 | |
4 | class Action: | |
5 | action_types = [ | |
6 | 'pause', | |
7 | 'play', | |
8 | 'run', | |
9 | 'stop', | |
10 | 'volume', | |
11 | 'wait', | |
12 | ] | |
13 | ||
14 | def __init__(self, action, **kwargs): | |
15 | if action in self.action_types: | |
16 | self.action = action | |
17 | else: | |
18 | raise Exception("Unknown action {}".format(action)) | |
19 | ||
20 | self.arguments = kwargs | |
21 | ||
22 | def run(self, callback): | |
23 | getattr(self, self.action)(callback, **self.arguments) | |
24 | ||
25 | def stop(self, callback, musique = None, fade_out = 0): | |
26 | print('stopping') | |
27 | return callback() | |
189bf90c IB |
28 | |
29 | class Key: | |
30 | row_positions = { | |
31 | 'first': 5, | |
32 | 'second': 55, | |
33 | 'third': 105, | |
34 | 'fourth': 155, | |
35 | 'fifth': 205, | |
36 | 'sixth': 255, | |
37 | } | |
38 | ||
39 | default_outer_color = (120, 120, 120) | |
40 | lighter_outer_color = (200, 200, 200) | |
41 | default_inner_color = (255, 255, 255) | |
8f88a3e4 | 42 | mapped_inner_color = ( 0, 255, 0) |
189bf90c IB |
43 | |
44 | def __init__(self, key_name, key_sym, top, left, width = 48, height = 48, disabled = False): | |
45 | self.key_name = key_name | |
46 | self.key_sym = key_sym | |
47 | ||
48 | if isinstance(top, str): | |
49 | self.top = self.row_positions[top] | |
50 | else: | |
51 | self.top = top | |
52 | ||
53 | self.left = left | |
54 | self.width = width | |
55 | self.height = height | |
56 | ||
57 | self.bottom = self.top + self.height | |
58 | self.right = self.left + self.width | |
59 | ||
60 | self.rect = (self.left, self.top, self.right, self.bottom) | |
61 | self.position = (self.left, self.top) | |
62 | ||
63 | if disabled: | |
64 | self.outer_color = self.lighter_outer_color | |
65 | self.linewidth = 1 | |
66 | else: | |
67 | self.outer_color = self.default_outer_color | |
68 | self.linewidth = 3 | |
69 | ||
70 | self.inner_color = self.default_inner_color | |
8f88a3e4 | 71 | self.actions = [] |
189bf90c IB |
72 | |
73 | def square(self): | |
8f88a3e4 IB |
74 | if self.has_action(): |
75 | self.inner_color = self.mapped_inner_color | |
76 | ||
189bf90c IB |
77 | return RoundedRect((0, 0, self.width, self.height), |
78 | self.outer_color, self.inner_color, self.linewidth) | |
79 | ||
80 | def collidepoint(self, position): | |
81 | return self.surface.get_rect().collidepoint( | |
82 | position[0] - self.position[0], | |
83 | position[1] - self.position[1] | |
84 | ) | |
85 | ||
86 | def draw(self, background_surface): | |
87 | self.surface = self.square().surface() | |
88 | ||
89 | police = font.Font(None, 20) | |
90 | text = police.render(self.key_sym, True, (0,0,0)) | |
91 | self.surface.blit(text, (5,5)) | |
92 | background_surface.blit(self.surface, self.position) | |
93 | ||
8f88a3e4 IB |
94 | def has_action(self): |
95 | return len(self.actions) > 0 | |
96 | ||
97 | def add_action(self, action_name, **arguments): | |
98 | self.actions.append(Action(action_name, **arguments)) | |
99 | ||
100 | def next_action(self): | |
101 | print("running next action") | |
102 | ||
189bf90c | 103 | def do_actions(self): |
8f88a3e4 IB |
104 | self.current_action = 0 |
105 | print("running actions for {}".format(self.key_sym)) | |
106 | if len(self.actions) > 0: | |
107 | self.actions[0].run(self.next_action) | |
108 | ||
109 | def find_from_unicode(key_sym): | |
110 | for key in Mapping.KEYS: | |
111 | if Mapping.KEYS[key].key_sym == key_sym: | |
112 | return Mapping.KEYS[key] | |
113 | return None | |
114 | ||
115 | class Mapping: | |
116 | KEYS = { | |
117 | K_ESCAPE: Key(K_ESCAPE, 'ESC', 'first', 0), | |
118 | ||
119 | K_F1: Key(K_F1, 'F1', 'first', 100), | |
120 | K_F2: Key(K_F2, 'F2', 'first', 150), | |
121 | K_F3: Key(K_F3, 'F3', 'first', 200), | |
122 | K_F4: Key(K_F4, 'F4', 'first', 250), | |
123 | ||
124 | K_F5: Key(K_F5, 'F5', 'first', 325), | |
125 | K_F6: Key(K_F6, 'F6', 'first', 375), | |
126 | K_F7: Key(K_F7, 'F7', 'first', 425), | |
127 | K_F8: Key(K_F8, 'F8', 'first', 475), | |
128 | ||
129 | K_F9: Key(K_F9, 'F9', 'first', 550), | |
130 | K_F10: Key(K_F10, 'F10', 'first', 600), | |
131 | K_F11: Key(K_F11, 'F11', 'first', 650), | |
132 | K_F12: Key(K_F12, 'F12', 'first', 700), | |
133 | ||
134 | ||
135 | 178: Key(178, '²', 'second', 0), | |
136 | K_AMPERSAND: Key(K_AMPERSAND, '&', 'second', 50), | |
137 | 233: Key(233, 'é', 'second', 100), | |
138 | K_QUOTEDBL: Key(K_QUOTEDBL, '"', 'second', 150), | |
139 | K_QUOTE: Key(K_QUOTE, "'", 'second', 200), | |
140 | K_LEFTPAREN: Key(K_LEFTPAREN, '(', 'second', 250), | |
141 | K_MINUS: Key(K_MINUS, '-', 'second', 300), | |
142 | 232: Key(232, 'è', 'second', 350), | |
143 | K_UNDERSCORE: Key(K_UNDERSCORE, '_', 'second', 400), | |
144 | 231: Key(231, 'ç', 'second', 450), | |
145 | 224: Key(224, 'à', 'second', 500), | |
146 | K_RIGHTPAREN: Key(K_RIGHTPAREN, ')', 'second', 550), | |
147 | K_EQUALS: Key(K_EQUALS, '=', 'second', 600), | |
148 | ||
149 | K_BACKSPACE: Key(K_BACKSPACE, '<-', 'second', 650, width = 98), | |
150 | ||
151 | ||
152 | K_TAB: Key(K_TAB, 'tab', 'third', 0, width = 73), | |
153 | K_a: Key(K_a, 'a', 'third', 75), | |
154 | K_z: Key(K_z, 'z', 'third', 125), | |
155 | K_e: Key(K_e, 'e', 'third', 175), | |
156 | K_r: Key(K_r, 'r', 'third', 225), | |
157 | K_t: Key(K_t, 't', 'third', 275), | |
158 | K_y: Key(K_y, 'y', 'third', 325), | |
159 | K_u: Key(K_u, 'u', 'third', 375), | |
160 | K_i: Key(K_i, 'i', 'third', 425), | |
161 | K_o: Key(K_o, 'o', 'third', 475), | |
162 | K_p: Key(K_p, 'p', 'third', 525), | |
163 | K_CARET: Key(K_CARET, '^', 'third', 575), | |
164 | K_DOLLAR: Key(K_DOLLAR, '$', 'third', 625), | |
165 | ||
166 | K_RETURN: Key(K_RETURN, 'Enter', 'third', 692, width = 56, height = 98), | |
167 | ||
168 | K_CAPSLOCK: Key(K_CAPSLOCK, 'CAPS', 'fourth', 0, width = 88, disabled = True), | |
169 | ||
170 | K_q: Key(K_q, 'q', 'fourth', 90), | |
171 | K_s: Key(K_s, 's', 'fourth', 140), | |
172 | K_d: Key(K_d, 'd', 'fourth', 190), | |
173 | K_f: Key(K_f, 'f', 'fourth', 240), | |
174 | K_g: Key(K_g, 'g', 'fourth', 290), | |
175 | K_h: Key(K_h, 'h', 'fourth', 340), | |
176 | K_j: Key(K_j, 'j', 'fourth', 390), | |
177 | K_k: Key(K_k, 'k', 'fourth', 440), | |
178 | K_l: Key(K_l, 'l', 'fourth', 490), | |
179 | K_m: Key(K_m, 'm', 'fourth', 540), | |
180 | 249: Key(249, 'ù', 'fourth', 590), | |
181 | K_ASTERISK: Key(K_ASTERISK, '*', 'fourth', 640), | |
182 | ||
183 | ||
184 | K_LSHIFT: Key(K_LSHIFT, 'LShift', 'fifth', 0, width = 63, disabled = True), | |
185 | ||
186 | K_LESS: Key(K_LESS, '<', 'fifth', 65), | |
187 | K_w: Key(K_w, 'w', 'fifth', 115), | |
188 | K_x: Key(K_x, 'x', 'fifth', 165), | |
189 | K_c: Key(K_c, 'c', 'fifth', 215), | |
190 | K_v: Key(K_v, 'v', 'fifth', 265), | |
191 | K_b: Key(K_b, 'b', 'fifth', 315), | |
192 | K_n: Key(K_n, 'n', 'fifth', 365), | |
193 | K_COMMA: Key(K_COMMA, ',', 'fifth', 415), | |
194 | K_SEMICOLON: Key(K_SEMICOLON, ';', 'fifth', 465), | |
195 | K_COLON: Key(K_COLON, ':', 'fifth', 515), | |
196 | K_EXCLAIM: Key(K_EXCLAIM, '!', 'fifth', 565), | |
197 | ||
198 | K_RSHIFT: Key(K_RSHIFT, 'RShift', 'fifth', 615, width = 133, disabled = True), | |
199 | ||
200 | K_LCTRL: Key(K_LCTRL, 'LCtrl', 'sixth', 0, width = 63, disabled = True), | |
201 | K_LSUPER: Key(K_LSUPER, 'LSuper', 'sixth', 115, disabled = True), | |
202 | K_LALT: Key(K_LALT, 'LAlt', 'sixth', 165, disabled = True), | |
203 | K_SPACE: Key(K_SPACE, 'Espace', 'sixth', 215, width = 248), | |
204 | K_MODE: Key(K_MODE, 'AltGr', 'sixth', 465, disabled = True), | |
205 | 314: Key(314, 'Compose', 'sixth', 515, disabled = True), | |
206 | K_RCTRL: Key(K_RCTRL, 'RCtrl', 'sixth', 565, width = 63, disabled = True), | |
207 | ||
208 | ||
209 | K_INSERT: Key(K_INSERT, 'ins', 'second', 755), | |
210 | K_HOME: Key(K_HOME, 'home', 'second', 805), | |
211 | K_PAGEUP: Key(K_PAGEUP, 'pg_u', 'second', 855), | |
212 | K_DELETE: Key(K_DELETE, 'del', 'third', 755), | |
213 | K_END: Key(K_END, 'end', 'third', 805), | |
214 | K_PAGEDOWN: Key(K_PAGEDOWN, 'pg_d', 'third', 855), | |
215 | ||
216 | ||
217 | K_UP: Key(K_UP, 'up', 'fifth', 805), | |
218 | K_DOWN: Key(K_DOWN, 'down', 'sixth', 805), | |
219 | K_LEFT: Key(K_LEFT, 'left', 'sixth', 755), | |
220 | K_RIGHT: Key(K_RIGHT, 'right', 'sixth', 855), | |
221 | } | |
222 | ||
223 | class MusicFile: | |
224 | def __init__(self, filename): | |
225 | self.filename = filename | |
189bf90c IB |
226 | |
227 | class RoundedRect: | |
228 | def __init__(self, rect, outer_color, inner_color, linewidth = 2, radius = 0.4): | |
229 | self.rect = Rect(rect) | |
230 | self.outer_color = Color(*outer_color) | |
231 | self.inner_color = Color(*inner_color) | |
232 | self.linewidth = linewidth | |
233 | self.radius = radius | |
234 | ||
235 | def surface(self): | |
1df30f07 | 236 | rectangle = self.filledRoundedRect(self.rect, self.outer_color, self.radius) |
189bf90c IB |
237 | |
238 | inner_rect = Rect(( | |
239 | self.rect.left + 2 * self.linewidth, | |
240 | self.rect.top + 2 * self.linewidth, | |
241 | self.rect.right - 2 * self.linewidth, | |
242 | self.rect.bottom - 2 * self.linewidth | |
243 | )) | |
244 | ||
245 | inner_rectangle = self.filledRoundedRect(inner_rect, self.inner_color, self.radius) | |
246 | ||
247 | rectangle.blit(inner_rectangle, (self.linewidth, self.linewidth)) | |
248 | ||
249 | return rectangle | |
250 | ||
251 | def filledRoundedRect(self, rect, color, radius=0.4): | |
252 | """ | |
253 | filledRoundedRect(rect,color,radius=0.4) | |
254 | ||
255 | rect : rectangle | |
256 | color : rgb or rgba | |
257 | radius : 0 <= radius <= 1 | |
258 | """ | |
259 | ||
260 | alpha = color.a | |
261 | color.a = 0 | |
262 | pos = rect.topleft | |
263 | rect.topleft = 0,0 | |
264 | rectangle = Surface(rect.size,SRCALPHA) | |
265 | ||
266 | circle = Surface([min(rect.size)*3]*2,SRCALPHA) | |
267 | draw.ellipse(circle,(0,0,0),circle.get_rect(),0) | |
268 | circle = transform.smoothscale(circle,[int(min(rect.size)*radius)]*2) | |
269 | ||
270 | radius = rectangle.blit(circle,(0,0)) | |
271 | radius.bottomright = rect.bottomright | |
272 | rectangle.blit(circle,radius) | |
273 | radius.topright = rect.topright | |
274 | rectangle.blit(circle,radius) | |
275 | radius.bottomleft = rect.bottomleft | |
276 | rectangle.blit(circle,radius) | |
277 | ||
278 | rectangle.fill((0,0,0),rect.inflate(-radius.w,0)) | |
279 | rectangle.fill((0,0,0),rect.inflate(0,-radius.h)) | |
280 | ||
281 | rectangle.fill(color,special_flags=BLEND_RGBA_MAX) | |
282 | rectangle.fill((255,255,255,alpha),special_flags=BLEND_RGBA_MIN) | |
283 | ||
284 | return rectangle | |
8f88a3e4 IB |
285 | |
286 | ||
287 | def parse_config(): | |
288 | import yaml | |
289 | stream = open("config.yml", "r") | |
290 | config = yaml.load(stream) | |
291 | stream.close() | |
292 | ||
293 | aliases = config['aliases'] | |
294 | seen_files = {} | |
295 | ||
296 | for mapped_key in config['keys']: | |
297 | key = Key.find_from_unicode(mapped_key) | |
298 | if key is None: | |
299 | continue | |
300 | ||
301 | for action in config['keys'][mapped_key]: | |
302 | action_name = list(action)[0] | |
303 | action_args = {} | |
304 | if action[action_name] is None: | |
305 | action[action_name] = [] | |
306 | ||
307 | for argument in action[action_name]: | |
308 | if argument == 'include': | |
309 | included = action[action_name]['include'] | |
310 | if isinstance(included, str): | |
311 | action_args.update(aliases[included]) | |
312 | else: | |
313 | for included_ in included: | |
314 | action_args.update(aliases[included_]) | |
315 | elif argument == 'file': | |
316 | filename = action[action_name]['file'] | |
317 | if filename not in seen_files: | |
318 | seen_files[filename] = MusicFile.new(filename) | |
319 | ||
320 | action_args['file'] = seen_files[filename] | |
321 | ||
322 | else: | |
323 | action_args[argument] = action[action_name][argument] | |
324 | ||
325 | key.add_action(action_name, **action_args) |