X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=helpers%2F__init__.py;h=eb948f25ae5aa86b01f8b666624bcf39b4787d1c;hb=8612c5f8bb0fc9529bc489a6719654d4474db6d5;hp=c42b378817aa26e8898b2920e0d2989048494e1e;hpb=94b508ae92f42e61e5f4c4b1c3a06e58694ca8ef;p=perso%2FImmae%2FProjets%2FPython%2FMusicSampler.git diff --git a/helpers/__init__.py b/helpers/__init__.py index c42b378..eb948f2 100644 --- a/helpers/__init__.py +++ b/helpers/__init__.py @@ -1,326 +1,85 @@ # -*- coding: utf-8 -*- -from pygame import * +from .music_file import * +from .mapping import * +from .lock import * +from .font import * +import yaml -class Action: - action_types = [ - 'command', - 'pause', - 'play', - 'stop', - 'volume', - 'wait', - ] - - def __init__(self, action, **kwargs): - if action in self.action_types: - self.action = action - else: - raise Exception("Unknown action {}".format(action)) - - self.arguments = kwargs - - def run(self, callback): - getattr(self, self.action)(callback, **self.arguments) - - def command(self, callback, command = "", **kwargs): - pass - - def pause(self, callback, music = None, **kwargs): - pass - - def play(self, callback, - music = None, - fade_in = 0, - restart_if_running = False, - volume = 100, - **kwargs): - pass - - def stop(self, callback, music = None, fade_out = 0, **kwargs): - print('stopping') - return callback() - - def volume(self, callback, music = None, value = 100, **kwargs): - pass - - def wait(self, callback, time = 0, **kwargs): - pass - -class Key: - row_positions = { - 'first': 5, - 'second': 55, - 'third': 105, - 'fourth': 155, - 'fifth': 205, - 'sixth': 255, - } - - default_outer_color = (120, 120, 120) - lighter_outer_color = (200, 200, 200) - default_inner_color = (255, 255, 255) - mapped_inner_color = ( 0, 255, 0) - - def __init__(self, key_name, key_sym, top, left, width = 48, height = 48, disabled = False): - self.key_name = key_name - self.key_sym = key_sym - - if isinstance(top, str): - self.top = self.row_positions[top] - else: - self.top = top - - self.left = left - self.width = width - self.height = height - - self.bottom = self.top + self.height - self.right = self.left + self.width - - self.rect = (self.left, self.top, self.right, self.bottom) - self.position = (self.left, self.top) - - if disabled: - self.outer_color = self.lighter_outer_color - self.linewidth = 1 - else: - self.outer_color = self.default_outer_color - self.linewidth = 3 - - self.inner_color = self.default_inner_color - self.actions = [] - - def square(self): - if self.has_action(): - self.inner_color = self.mapped_inner_color - - return RoundedRect((0, 0, self.width, self.height), - self.outer_color, self.inner_color, self.linewidth) - - def collidepoint(self, position): - return self.surface.get_rect().collidepoint( - position[0] - self.position[0], - position[1] - self.position[1] - ) - - def draw(self, background_surface): - self.surface = self.square().surface() - - police = font.Font("Ubuntu-Regular.ttf", 14) - text = police.render(self.key_sym, True, (0,0,0)) - self.surface.blit(text, (5,5)) - background_surface.blit(self.surface, self.position) - - def has_action(self): - return len(self.actions) > 0 - - def add_action(self, action_name, **arguments): - self.actions.append(Action(action_name, **arguments)) - - def next_action(self): - print("running next action") - - def do_actions(self): - self.current_action = 0 - print("running actions for {}".format(self.key_sym)) - if len(self.actions) > 0: - self.actions[0].run(self.next_action) - - def list_actions(self, surface): - print("bouh", self.key_sym) - surface.fill((255, 0, 0)) - - def find_by_key_num(key_num): - if key_num in Mapping.KEYS: - return Mapping.KEYS[key_num] - return None - - def find_by_collidepoint(position): - for key in Mapping.KEYS: - if Mapping.KEYS[key].collidepoint(position): - return Mapping.KEYS[key] - return None - - def find_by_unicode(key_sym): - for key in Mapping.KEYS: - if Mapping.KEYS[key].key_sym == key_sym: - return Mapping.KEYS[key] - return None - -class Mapping: - KEYS = { - K_ESCAPE: Key(K_ESCAPE, 'ESC', 'first', 0), - - K_F1: Key(K_F1, 'F1', 'first', 100), - K_F2: Key(K_F2, 'F2', 'first', 150), - K_F3: Key(K_F3, 'F3', 'first', 200), - K_F4: Key(K_F4, 'F4', 'first', 250), - - K_F5: Key(K_F5, 'F5', 'first', 325), - K_F6: Key(K_F6, 'F6', 'first', 375), - K_F7: Key(K_F7, 'F7', 'first', 425), - K_F8: Key(K_F8, 'F8', 'first', 475), - - K_F9: Key(K_F9, 'F9', 'first', 550), - K_F10: Key(K_F10, 'F10', 'first', 600), - K_F11: Key(K_F11, 'F11', 'first', 650), - K_F12: Key(K_F12, 'F12', 'first', 700), - - - 178: Key(178, '²', 'second', 0), - K_AMPERSAND: Key(K_AMPERSAND, '&', 'second', 50), - 233: Key(233, 'é', 'second', 100), - K_QUOTEDBL: Key(K_QUOTEDBL, '"', 'second', 150), - K_QUOTE: Key(K_QUOTE, "'", 'second', 200), - K_LEFTPAREN: Key(K_LEFTPAREN, '(', 'second', 250), - K_MINUS: Key(K_MINUS, '-', 'second', 300), - 232: Key(232, 'è', 'second', 350), - K_UNDERSCORE: Key(K_UNDERSCORE, '_', 'second', 400), - 231: Key(231, 'ç', 'second', 450), - 224: Key(224, 'à', 'second', 500), - K_RIGHTPAREN: Key(K_RIGHTPAREN, ')', 'second', 550), - K_EQUALS: Key(K_EQUALS, '=', 'second', 600), - - K_BACKSPACE: Key(K_BACKSPACE, '<-', 'second', 650, width = 98), - - - K_TAB: Key(K_TAB, 'tab', 'third', 0, width = 73), - K_a: Key(K_a, 'a', 'third', 75), - K_z: Key(K_z, 'z', 'third', 125), - K_e: Key(K_e, 'e', 'third', 175), - K_r: Key(K_r, 'r', 'third', 225), - K_t: Key(K_t, 't', 'third', 275), - K_y: Key(K_y, 'y', 'third', 325), - K_u: Key(K_u, 'u', 'third', 375), - K_i: Key(K_i, 'i', 'third', 425), - K_o: Key(K_o, 'o', 'third', 475), - K_p: Key(K_p, 'p', 'third', 525), - K_CARET: Key(K_CARET, '^', 'third', 575), - K_DOLLAR: Key(K_DOLLAR, '$', 'third', 625), - - K_RETURN: Key(K_RETURN, 'Enter', 'third', 692, width = 56, height = 98), - - K_CAPSLOCK: Key(K_CAPSLOCK, 'CAPS', 'fourth', 0, width = 88, disabled = True), - - K_q: Key(K_q, 'q', 'fourth', 90), - K_s: Key(K_s, 's', 'fourth', 140), - K_d: Key(K_d, 'd', 'fourth', 190), - K_f: Key(K_f, 'f', 'fourth', 240), - K_g: Key(K_g, 'g', 'fourth', 290), - K_h: Key(K_h, 'h', 'fourth', 340), - K_j: Key(K_j, 'j', 'fourth', 390), - K_k: Key(K_k, 'k', 'fourth', 440), - K_l: Key(K_l, 'l', 'fourth', 490), - K_m: Key(K_m, 'm', 'fourth', 540), - 249: Key(249, 'ù', 'fourth', 590), - K_ASTERISK: Key(K_ASTERISK, '*', 'fourth', 640), - - - K_LSHIFT: Key(K_LSHIFT, 'LShift', 'fifth', 0, width = 63, disabled = True), - - K_LESS: Key(K_LESS, '<', 'fifth', 65), - K_w: Key(K_w, 'w', 'fifth', 115), - K_x: Key(K_x, 'x', 'fifth', 165), - K_c: Key(K_c, 'c', 'fifth', 215), - K_v: Key(K_v, 'v', 'fifth', 265), - K_b: Key(K_b, 'b', 'fifth', 315), - K_n: Key(K_n, 'n', 'fifth', 365), - K_COMMA: Key(K_COMMA, ',', 'fifth', 415), - K_SEMICOLON: Key(K_SEMICOLON, ';', 'fifth', 465), - K_COLON: Key(K_COLON, ':', 'fifth', 515), - K_EXCLAIM: Key(K_EXCLAIM, '!', 'fifth', 565), - - K_RSHIFT: Key(K_RSHIFT, 'RShift', 'fifth', 615, width = 133, disabled = True), - - K_LCTRL: Key(K_LCTRL, 'LCtrl', 'sixth', 0, width = 63, disabled = True), - K_LSUPER: Key(K_LSUPER, 'LSuper', 'sixth', 115, disabled = True), - K_LALT: Key(K_LALT, 'LAlt', 'sixth', 165, disabled = True), - K_SPACE: Key(K_SPACE, 'Espace', 'sixth', 215, width = 248), - K_MODE: Key(K_MODE, 'AltGr', 'sixth', 465, disabled = True), - 314: Key(314, 'Compose', 'sixth', 515, disabled = True), - K_RCTRL: Key(K_RCTRL, 'RCtrl', 'sixth', 565, width = 63, disabled = True), - - - K_INSERT: Key(K_INSERT, 'ins', 'second', 755), - K_HOME: Key(K_HOME, 'home', 'second', 805), - K_PAGEUP: Key(K_PAGEUP, 'pg_u', 'second', 855), - K_DELETE: Key(K_DELETE, 'del', 'third', 755), - K_END: Key(K_END, 'end', 'third', 805), - K_PAGEDOWN: Key(K_PAGEDOWN, 'pg_d', 'third', 855), - - - K_UP: Key(K_UP, 'up', 'fifth', 805), - K_DOWN: Key(K_DOWN, 'down', 'sixth', 805), - K_LEFT: Key(K_LEFT, 'left', 'sixth', 755), - K_RIGHT: Key(K_RIGHT, 'right', 'sixth', 855), - } - -class MusicFile: - def __init__(self, filename): - self.filename = filename - -class RoundedRect: - def __init__(self, rect, outer_color, inner_color, linewidth = 2, radius = 0.4): - self.rect = Rect(rect) - self.outer_color = Color(*outer_color) - self.inner_color = Color(*inner_color) - self.linewidth = linewidth - self.radius = radius - - def surface(self): - rectangle = self.filledRoundedRect(self.rect, self.outer_color, self.radius) +def parse_config2(): + stream = open("config.yml", "r") + config = yaml.load(stream) + stream.close() - inner_rect = Rect(( - self.rect.left + 2 * self.linewidth, - self.rect.top + 2 * self.linewidth, - self.rect.right - 2 * self.linewidth, - self.rect.bottom - 2 * self.linewidth - )) + aliases = config['aliases'] + seen_files = {} - inner_rectangle = self.filledRoundedRect(inner_rect, self.inner_color, self.radius) + file_lock = Lock("file") - rectangle.blit(inner_rectangle, (self.linewidth, self.linewidth)) + channel_id = 0 - return rectangle + key_properties = {} - def filledRoundedRect(self, rect, color, radius=0.4): - """ - filledRoundedRect(rect,color,radius=0.4) + for key in config['key_properties']: + if key not in key_properties: + key_properties[key] = { + "actions": [], + "properties": config['key_properties'][key], + "files": [] + } - rect : rectangle - color : rgb or rgba - radius : 0 <= radius <= 1 - """ + for mapped_key in config['keys']: + if mapped_key not in key_properties: + key_properties[mapped_key] = { + "actions": [], + "properties": {}, + "files": [] + } + for action in config['keys'][mapped_key]: + action_name = list(action)[0] + action_args = {} + if action[action_name] is None: + action[action_name] = [] - alpha = color.a - color.a = 0 - pos = rect.topleft - rect.topleft = 0,0 - rectangle = Surface(rect.size,SRCALPHA) + if 'include' in action[action_name]: + included = action[action_name]['include'] + del(action[action_name]['include']) - circle = Surface([min(rect.size)*3]*2,SRCALPHA) - draw.ellipse(circle,(0,0,0),circle.get_rect(),0) - circle = transform.smoothscale(circle,[int(min(rect.size)*radius)]*2) + if isinstance(included, str): + action[action_name].update(aliases[included], **action[action_name]) + else: + for included_ in included: + action[action_name].update(aliases[included_], **action[action_name]) - radius = rectangle.blit(circle,(0,0)) - radius.bottomright = rect.bottomright - rectangle.blit(circle,radius) - radius.topright = rect.topright - rectangle.blit(circle,radius) - radius.bottomleft = rect.bottomleft - rectangle.blit(circle,radius) + for argument in action[action_name]: + if argument == 'file': + filename = action[action_name]['file'] + if filename not in seen_files: + if filename in config['music_properties']: + seen_files[filename] = MusicFile( + filename, + file_lock, + channel_id, + **config['music_properties'][filename]) + else: + seen_files[filename] = MusicFile( + filename, + file_lock, + channel_id) + channel_id = channel_id + 1 + + if filename not in key_properties[mapped_key]['files']: + key_properties[mapped_key]['files'].append(seen_files[filename]) - rectangle.fill((0,0,0),rect.inflate(-radius.w,0)) - rectangle.fill((0,0,0),rect.inflate(0,-radius.h)) + action_args['music'] = seen_files[filename] - rectangle.fill(color,special_flags=BLEND_RGBA_MAX) - rectangle.fill((255,255,255,alpha),special_flags=BLEND_RGBA_MIN) + else: + action_args[argument] = action[action_name][argument] - return rectangle + key_properties[mapped_key]['actions'].append([action_name, action_args]) + return (key_properties, channel_id + 1, seen_files) -def parse_config(): - import yaml +def parse_config(mapping): stream = open("config.yml", "r") config = yaml.load(stream) stream.close() @@ -328,8 +87,12 @@ def parse_config(): aliases = config['aliases'] seen_files = {} + file_lock = Lock("file") + + channel_id = 0 + for mapped_key in config['keys']: - key = Key.find_by_unicode(mapped_key) + key = mapping.find_by_unicode(mapped_key) if key is None: continue @@ -339,18 +102,32 @@ def parse_config(): if action[action_name] is None: action[action_name] = [] + if 'include' in action[action_name]: + included = action[action_name]['include'] + del(action[action_name]['include']) + + if isinstance(included, str): + action[action_name].update(aliases[included], **action[action_name]) + else: + for included_ in included: + action[action_name].update(aliases[included_], **action[action_name]) + for argument in action[action_name]: - if argument == 'include': - included = action[action_name]['include'] - if isinstance(included, str): - action_args.update(aliases[included]) - else: - for included_ in included: - action_args.update(aliases[included_]) - elif argument == 'file': + if argument == 'file': filename = action[action_name]['file'] if filename not in seen_files: - seen_files[filename] = MusicFile.new(filename) + if filename in config['music_properties']: + seen_files[filename] = MusicFile( + filename, + file_lock, + channel_id, + **config['music_properties'][filename]) + else: + seen_files[filename] = MusicFile( + filename, + file_lock, + channel_id) + channel_id = channel_id + 1 action_args['music'] = seen_files[filename] @@ -358,3 +135,16 @@ def parse_config(): action_args[argument] = action[action_name][argument] key.add_action(action_name, **action_args) + + for key_property in config['key_properties']: + key = mapping.find_by_unicode(key_property) + if key is None: + continue + + if 'description' in config['key_properties'][key_property]: + key.set_description(config['key_properties'][key_property]['description']) + if 'color' in config['key_properties'][key_property]: + key.set_color(config['key_properties'][key_property]['color']) + + # Return the number of channels reserved + return (channel_id + 1, seen_files)