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