def __init__(self, user_config, reactor=reactor): super(UI, self).__init__() self.user_config = user_config self.reactor = reactor self.player = Player(initial_volume=user_config.persistent.volume) self.progress_bar = ProgressBar( self.user_config.appearance.progress_bar) self.time_check = TimeCheck() self.status_bar = HorizontalContainer( (self.progress_bar, self.time_check)) self.terminal = Terminal() self.key_bindings = self._create_key_bindings()
class UI(PyampBase): def __init__(self, user_config, reactor=reactor): super(UI, self).__init__() self.user_config = user_config self.reactor = reactor self.player = Player(initial_volume=user_config.persistent.volume) self.progress_bar = ProgressBar( self.user_config.appearance.progress_bar) self.time_check = TimeCheck() self.status_bar = HorizontalContainer( (self.progress_bar, self.time_check)) self.terminal = Terminal() self.key_bindings = self._create_key_bindings() def _create_bindable_funcs_map(self): bindable_funcs = {} for obj in self, self.player: for name in dir(obj): func = getattr(obj, name) if is_bindable(func): bindable_funcs[name] = func return bindable_funcs def _create_key_bindings(self): bindable_funcs = self._create_bindable_funcs_map() key_bindings = {} for func_name, keys in self.user_config.key_bindings: if isinstance(keys, basestring): keys = [keys] for key in keys: key = ' '.join(key.split()) if func_name in bindable_funcs: key_bindings[key] = bindable_funcs[func_name] else: self.log.warning( 'Warning: {} is not a bindable pyamp function'.format( func_name)) return key_bindings def update(self): try: self.player.update() except StopIteration: self.quit() self.draw() def draw(self): #print self.terminal.clear() if self.player.playing: position = (self.player.get_position() or 0) / gst.SECOND duration = (self.player.get_duration() or 0) / gst.SECOND if duration: self.progress_bar.fraction = position / duration self.time_check.position = position self.time_check.duration = duration total_width = self.terminal.width - 2 with self.terminal.location(0, self.terminal.height - 2): print self.player.tags['title'].center(self.terminal.width) print self.status_bar.draw(total_width, 1).center( self.terminal.width), sys.stdout.flush() def _handle_sigint(self, signal, frame): self.quit() def handle_input(self, char): action = self.key_bindings.get(char, lambda: None) action() @bindable @gst_log_calls def quit(self): def clean_up(): self.player.stop() self.reactor.stop() if self.player.playing: fade_out_time = 1 self.player.fade_out(fade_out_time) reactor.callLater(fade_out_time + 0.1, clean_up) else: clean_up() def run(self): with self.terminal.fullscreen(): with self.terminal.hidden_cursor(): with self.terminal.unbuffered_input(): signal.signal(signal.SIGINT, self._handle_sigint) signal.signal(signal.SIGTSTP, self.terminal.handle_sigtstp) self.looping_call = task.LoopingCall(self.update) self.looping_call.start(1 / 20) stdio.StandardIO(InputReader(self)) self.reactor.run()