from kivy.uix.widget import Widget from kivy.properties import AliasProperty, BooleanProperty, \ ListProperty, StringProperty from kivy.clock import Clock from kivy.uix.behaviors import ButtonBehavior from .action import * from . import debug_print import time class Key(ButtonBehavior, Widget): key_sym = StringProperty(None) custom_color = ListProperty([0, 1, 0, 1]) custom_unready_color = ListProperty([0, 1, 0, 100/255]) description_title = StringProperty("") description = ListProperty([]) is_key_ready = BooleanProperty(True) def get_color(self): if not self.has_actions: return [1, 1, 1, 1] elif self.all_actions_ready: return self.custom_color else: return self.custom_unready_color def set_color(self): pass color = AliasProperty(get_color, set_color, bind=['is_key_ready']) def __init__(self, **kwargs): super(Key, self).__init__(**kwargs) self.actions = [] def on_key_sym(self, key, key_sym): if key_sym in self.parent.key_config: self.is_key_ready = False self.config = self.parent.key_config[key_sym] self.actions = [] for key_action in self.config['actions']: self.add_action(key_action[0], **key_action[1]) if 'description' in self.config['properties']: key.set_description(self.config['properties']['description']) if 'color' in self.config['properties']: key.set_color(self.config['properties']['color']) Clock.schedule_interval(self.check_all_active, 1) def check_all_active(self, dt): if self.all_actions_ready: self.is_key_ready = True return False def set_description(self, description): if description[0] is not None: self.description_title = str(description[0]) for desc in description[1 :]: if desc is None: self.description.append("") else: self.description.append(str(desc).replace(" ", " ")) def set_color(self, color): color = [x / 255 for x in color] color.append(1) self.custom_color = color color[3] = 100 / 255 self.custom_unready_color = tuple(color) @property def has_actions(self): return len(self.actions) > 0 @property def all_actions_ready(self): return all(action.ready() for action in self.actions) def add_action(self, action_name, **arguments): self.actions.append(Action(action_name, self, **arguments)) def interrupt_action(self): self.current_action.interrupt() def do_actions(self): if not self.enabled: return None self.parent.parent.ids['KeyList'].append(self.key_sym) debug_print("running actions for {}".format(self.key_sym)) start_time = time.time() self.parent.start_running(self, start_time) action_number = 0 for self.current_action in self.actions: if self.parent.keep_running(self, start_time): self.list_actions(action_number=action_number + 0.5) self.current_action.run() action_number += 1 self.list_actions(action_number=action_number) self.parent.finished_running(self, start_time) def list_actions(self, action_number=0): self.parent.parent.ids['ActionList'].update_list(self, action_number) def on_press(self): self.list_actions()