def __init__(self, util, listeners, voice_assistant): """ Initializer :param util: utility object :param listeners: listeners :param voice_assistant: voice assistant """ self.util = util self.config = util.config self.listeners = listeners self.factory = Factory(util) self.go_home = listeners[KEY_HOME] self.go_file_playback = listeners[KEY_PLAY_COLLECTION] dbutil = util.get_db_util() self.selector = Selector(dbutil) self.bounding_box = util.screen_rect layout = BorderLayout(self.bounding_box) layout.set_percent_constraints(PERCENT_TOP_HEIGHT, PERCENT_BOTTOM_HEIGHT, 0, 0) MenuScreen.__init__(self, util, listeners, ROWS, COLUMNS, voice_assistant, [ROWS, COLUMNS], self.turn_page, page_in_title=False, show_loading=False) m = self.factory.create_collection_menu_button font_size = int(((self.menu_layout.h / ROWS) / 100) * FONT_HEIGHT) self.collection_list_menu = MultiPageMenu(util, self.next_page, self.previous_page, self.set_title, self.reset_title, self.go_to_page, m, ROWS, COLUMNS, None, (0, 0, 0, 0), self.menu_layout, align=ALIGN_LEFT, font_size=font_size) self.set_menu(self.collection_list_menu) self.navigator = TopicDetailNavigator(self.util, self.layout.BOTTOM, listeners) self.add_component(self.navigator) self.current_item = None self.current_page_items = None self.first_item = None self.last_item = None self.collection_topic = None self.selection = None self.prev_page = 1 self.animated_title = True
def __init__(self, util, listeners, voice_assistant): """ Initializer :param util: utility object :param listeners: listeners :param voice_assistant: voice assistant """ self.util = util self.config = util.config self.listeners = listeners self.listeners[KEY_LIST] = self.set_list self.factory = Factory(util) dbutil = util.get_db_util() self.selector = Selector(dbutil) self.bounding_box = util.screen_rect layout = BorderLayout(self.bounding_box) layout.set_percent_constraints(PERCENT_TOP_HEIGHT, PERCENT_BOTTOM_HEIGHT, 0, 0) MenuScreen.__init__(self, util, listeners, ROWS, COLUMNS, voice_assistant, [ROWS, COLUMNS], self.turn_page, page_in_title=False, show_loading=False) m = self.factory.create_collection_menu_button self.topic_menu = MultiPageMenu(util, self.next_page, self.previous_page, self.set_title, self.reset_title, self.go_to_page, m, ROWS, COLUMNS, None, (0, 0, 0), self.menu_layout, align=ALIGN_LEFT) self.set_menu(self.topic_menu) self.navigator = TopicNavigator(self.util, self.layout.BOTTOM, listeners) self.components.append(self.navigator) self.current_topic = None self.current_item = None self.current_page_items = None self.first_item = None self.last_item = None self.collection_topic = None self.previous_page = 1 self.search_string = None self.source = None self.mode = KEY_LIST self.animated_title = True
def __init__(self, util, listeners, voice_assistant): """ Initializer :param util: utility object :param listeners: listeners :param voice_assistant: voice assistant """ self.util = util self.config = util.config self.listeners = listeners self.listeners[KEY_LIST] = self.set_list self.factory = Factory(util) dbutil = util.get_db_util() self.selector = Selector(dbutil) self.bounding_box = util.screen_rect layout = BorderLayout(self.bounding_box) layout.set_percent_constraints(PERCENT_TOP_HEIGHT, PERCENT_BOTTOM_HEIGHT, 0, 0) MenuScreen.__init__(self, util, listeners, ROWS, COLUMNS, voice_assistant, [ROWS, COLUMNS], self.turn_page, page_in_title=False, show_loading=False) m = self.factory.create_collection_menu_button font_size = int(((self.menu_layout.h / ROWS) / 100) * FONT_HEIGHT) h = self.config[HORIZONTAL_LAYOUT] bgr = self.config[BACKGROUND][MENU_BGR_COLOR] self.topic_menu = Menu(util, bgr, self.menu_layout, ROWS, COLUMNS, create_item_method=m, align=ALIGN_LEFT, horizontal_layout=h, font_size=font_size) self.set_menu(self.topic_menu) self.navigator = TopicNavigator(self.util, self.layout.BOTTOM, listeners) self.add_navigator(self.navigator) self.current_topic = None self.current_item = None self.current_page_items = None self.first_item = None self.last_item = None self.collection_topic = None self.previous_page = 1 self.search_string = None self.source = None self.mode = KEY_LIST self.animated_title = True
def say(ctx: Context, *, args: str): print(f"[{ctx.target.name if ctx.target else '@'}] ", end="") it = StrIterator(args) while c := it.peek(): if c == "@": s = Selector.convert(it) entities = s.apply(ctx) names = map(lambda e: e.name, entities) print(f"[{', '.join(names) if len(entities) > 0 else ''}]", end="") else: next(it) print(c, end="")
class TopicDetailScreen(MenuScreen): """ Topic Detail Screen """ def __init__(self, util, listeners, voice_assistant): """ Initializer :param util: utility object :param listeners: listeners :param voice_assistant: voice assistant """ self.util = util self.config = util.config self.listeners = listeners self.factory = Factory(util) self.go_home = listeners[KEY_HOME] self.go_file_playback = listeners[KEY_PLAY_COLLECTION] dbutil = util.get_db_util() self.selector = Selector(dbutil) self.bounding_box = util.screen_rect layout = BorderLayout(self.bounding_box) layout.set_percent_constraints(PERCENT_TOP_HEIGHT, PERCENT_BOTTOM_HEIGHT, 0, 0) MenuScreen.__init__(self, util, listeners, ROWS, COLUMNS, voice_assistant, [ROWS, COLUMNS], self.turn_page, page_in_title=False, show_loading=False) m = self.factory.create_collection_menu_button self.collection_list_menu = MultiPageMenu(util, self.next_page, self.previous_page, self.set_title, self.reset_title, self.go_to_page, m, ROWS, COLUMNS, None, (0, 0, 0), self.menu_layout, align=ALIGN_LEFT) self.set_menu(self.collection_list_menu) self.navigator = TopicDetailNavigator(self.util, self.layout.BOTTOM, listeners) self.components.append(self.navigator) self.current_item = None self.current_page_items = None self.first_item = None self.last_item = None self.collection_topic = None self.selection = None self.prev_page = 1 self.animated_title = True def set_current(self, state): """ Set current state :param state: button state """ source = getattr(state, KEY_SOURCE, None) if source == KEY_NAVIGATOR or source == KEY_BACK: return if hasattr(state, "collection_topic"): self.collection_topic = getattr(state, "collection_topic", "") if self.current_item and self.current_item[0] == getattr( state, "name", None): return if hasattr(state, "name"): self.selection = getattr(state, "name", "") self.title = self.config[LABELS][ self.collection_topic] + ": " + self.selection self.set_title(1) self.current_page = 1 self.prev_page = 1 self.navigator.left_button.change_label("0") self.navigator.right_button.change_label("0") self.set_loading(self.title) topic = self.get_topic() self.total_pages = self.selector.get_page_count_by_column( topic, self.selection, PAGE_SIZE) if self.total_pages == 0: self.reset_loading() return self.filename = None self.title = None if self.collection_topic == KEY_FILE: self.filename = state.name elif self.collection_topic == TITLE: self.title = state.name self.turn_page() self.reset_loading() def turn_page(self): """ Turn page """ topic = self.get_topic() self.current_page_items = self.selector.get_topic_detail_page( topic, self.selection, self.current_page, self.prev_page, self.first_item, self.last_item, PAGE_SIZE) self.prev_page = self.current_page if not self.current_page_items: self.current_page_items = [] return self.current_item = self.current_page_items[0] self.first_item = self.current_item self.last_item = self.current_page_items[len(self.current_page_items) - 1] p = {} for i, f in enumerate(self.current_page_items): s = State() s.index = i s.folder = f if "\x00" in f: f = f.replace("\x00", "") if "/" in f: parts = f.split("/") if len(parts) > 1: last = parts[len(parts) - 1] if len(last) > 6: f = last else: f = parts[len(parts) - 2] + "/" + last s.name = f s.l_name = s.name if self.filename: s.file_name = self.filename if self.title: s.title = self.title p[str(i)] = s self.collection_list_menu.set_items(p, 0, self.select_item, False) keys = list(p.keys()) if len(keys) != 0 and self.navigator and self.total_pages > 1: self.navigator.left_button.change_label(str(self.current_page - 1)) self.navigator.right_button.change_label( str(self.total_pages - self.current_page)) self.collection_list_menu.clean_draw_update() if hasattr(self, "update_observer"): self.collection_list_menu.add_menu_observers( self.update_observer, self.redraw_observer) self.collection_list_menu.unselect() for i, b in enumerate(self.collection_list_menu.buttons.values()): if self.current_item[0] == b.state.name: self.collection_list_menu.select_by_index(b.state.index) return index = (self.current_page - 1) * PAGE_SIZE self.collection_list_menu.select_by_index(index) def get_topic(self): """ Get topic :return: proper topic name """ topic = self.collection_topic if topic == KEY_AUDIO_FOLDER: topic = FOLDER elif topic == KEY_FILE: topic = FILENAME return topic def select_item(self, s=None): """ Select item from menu :param state: button state """ self.current_item = s.name state = State() state.folder = os.path.join(self.config[COLLECTION][BASE_FOLDER], s.folder[1:]) state.topic = self.collection_topic if state.topic == KEY_FILE: state.file_name = s.file_name elif state.topic == TITLE: state.file_name = self.selector.get_filename_by_title( s.folder, self.title) state.url = os.path.join(state.folder, state.file_name) else: files = self.util.get_audio_files_in_folder(state.folder, False) if files: f = files[0] state.file_name = f.file_name state.url = os.path.join(state.folder, state.file_name) else: state.file_name = None state.url = None state.source = "detail" self.collection_list_menu.select_by_index(s.index) self.go_file_playback(state) def add_screen_observers(self, update_observer, redraw_observer): """ Add screen observers :param update_observer: observer for updating the screen :param redraw_observer: observer to redraw the whole screen """ MenuScreen.add_screen_observers(self, update_observer, redraw_observer) self.update_observer = update_observer self.redraw_observer = redraw_observer self.add_loading_listener(redraw_observer) for b in self.navigator.menu_buttons: self.add_button_observers(b, update_observer, redraw_observer)
def data_entity(ctx: Context, target: Selector) -> Optional[Entity]: return target.apply_one(ctx)
def execute_as(ctx: Context, target: Selector): for e in target.apply(ctx): c = ctx.copy() c.target = e c.redirect(execute)
def kill(ctx: Context, target: Selector): for dead in target.apply(ctx): del ctx.world.entities[dead.uuid]
class TopicScreen(MenuScreen): """ Collection Topic Screen """ def __init__(self, util, listeners, voice_assistant): """ Initializer :param util: utility object :param listeners: listeners :param voice_assistant: voice assistant """ self.util = util self.config = util.config self.listeners = listeners self.listeners[KEY_LIST] = self.set_list self.factory = Factory(util) dbutil = util.get_db_util() self.selector = Selector(dbutil) self.bounding_box = util.screen_rect layout = BorderLayout(self.bounding_box) layout.set_percent_constraints(PERCENT_TOP_HEIGHT, PERCENT_BOTTOM_HEIGHT, 0, 0) MenuScreen.__init__(self, util, listeners, ROWS, COLUMNS, voice_assistant, [ROWS, COLUMNS], self.turn_page, page_in_title=False, show_loading=False) m = self.factory.create_collection_menu_button font_size = int(((self.menu_layout.h / ROWS) / 100) * FONT_HEIGHT) h = self.config[HORIZONTAL_LAYOUT] bgr = self.config[BACKGROUND][MENU_BGR_COLOR] self.topic_menu = Menu(util, bgr, self.menu_layout, ROWS, COLUMNS, create_item_method=m, align=ALIGN_LEFT, horizontal_layout=h, font_size=font_size) self.set_menu(self.topic_menu) self.navigator = TopicNavigator(self.util, self.layout.BOTTOM, listeners) self.add_navigator(self.navigator) self.current_topic = None self.current_item = None self.current_page_items = None self.first_item = None self.last_item = None self.collection_topic = None self.previous_page = 1 self.search_string = None self.source = None self.mode = KEY_LIST self.animated_title = True def set_current(self, state): """ Set current state :param state: button state """ self.source = getattr(state, KEY_SOURCE, None) if self.source: if self.source == KEY_ABC: self.mode = KEY_ABC elif self.source == KEY_SEARCH: self.mode = KEY_SEARCH elif self.source == KEY_LIST: self.mode = KEY_LIST if self.current_topic and (self.source == KEY_NAVIGATOR or self.source == KEY_BACK or self.source == None): return if self.source == KEY_MENU: self.config[COLLECTION_PLAYBACK][COLLECTION_TOPIC] = state.name self.mode = KEY_LIST if hasattr(state, "genre"): if self.current_topic == state.genre: return else: self.current_topic = state.genre self.current_item = None name = self.config[COLLECTION_PLAYBACK][COLLECTION_TOPIC] if self.source: if self.source == KEY_ABC: name = getattr(state, KEY_NAME, None) elif self.source == KEY_SEARCH: name = getattr(state, KEY_CALLBACK_VAR, None) if not self.source or not name: return if self.source != KEY_ABC and self.source != KEY_SEARCH: self.collection_topic = name self.search_string == None else: self.search_string = name self.navigator.set_buttons(self.collection_topic) self.navigator.left_button.change_label("0") self.navigator.right_button.change_label("0") self.navigator.set_parent_screen(self) self.current_page_items = None self.first_item = "" self.last_item = "" self.current_page = 1 self.previous_page = 1 if not self.current_topic: return self.title = self.get_title(name) self.set_title(1) self.set_loading(self.title) self.total_pages = self.get_total_pages(name) self.turn_page() self.reset_loading() def set_list(self, state=None): """ Set list view """ s = State() s.source = KEY_LIST s.name = self.collection_topic self.set_current(s) def get_title(self, search_string): """ Return title based on call source. The source can be: - Collection screen - ABC keyboard - Keyboard Search screen :param search_string: search string from keyboard :return: title which depends on call source """ title = None try: title = self.config[LABELS][self.collection_topic] except: pass if self.source == KEY_ABC: title = f"{title}. {search_string.strip()}" elif self.source == KEY_SEARCH: title = f"{title}. *{search_string.strip()}*" return title def get_total_pages(self, search_string): """ Return the number of total pages for defined search criteria :param search_string: search string from keyboard :return: total pages number """ mode = self.collection_topic if mode == KEY_AUDIO_FOLDER: mode = FOLDER elif mode == KEY_FILE: mode = FILENAME total_pages = 0 if self.source == KEY_ABC: total_pages = self.selector.get_page_count_by_char(mode, search_string.strip(), PAGE_SIZE) elif self.source == KEY_SEARCH: total_pages = self.selector.get_page_count_by_pattern(mode, search_string.strip(), PAGE_SIZE) else: total_pages = self.selector.get_page_count(mode, PAGE_SIZE) return total_pages def turn_page(self): """ Turn page """ if self.total_pages == 0: self.topic_menu.set_items({}, 0, self.select_item, False) self.link_borders() return p = self.prepare_page() self.topic_menu.set_items(p, 0, self.select_item, False) keys = list(p.keys()) if len(keys) != 0 and self.navigator and self.total_pages > 1: self.navigator.left_button.change_label(str(self.current_page - 1)) self.navigator.right_button.change_label(str(self.total_pages - self.current_page)) self.topic_menu.clean_draw_update() if hasattr(self, "update_observer"): self.topic_menu.add_menu_observers(self.update_observer, self.redraw_observer) for b in self.topic_menu.buttons.values(): b.parent_screen = self self.topic_menu.unselect() self.link_borders() if self.navigator.is_selected(): return for b in self.topic_menu.buttons.values(): b.parent_screen = self if self.current_item == b.state.name: self.topic_menu.select_by_index(b.state.index) return self.navigator.menu_button.set_selected(True) self.navigator.menu_button.clean_draw_update() def prepare_page(self): """ Prepare topic page :return: page dictionary """ page, self.first_item, self.last_item = self.get_current_page() p = {} for i, n in enumerate(page): s = State() s.index = i if "\x00" in n: n = n.replace("\x00", "") s.name = n s.l_name = n p[str(i)] = s return p def get_current_page(self): """ Get current page content :return: page content """ topic = self.collection_topic if topic == KEY_AUDIO_FOLDER: topic = FOLDER elif topic == KEY_FILE: topic = FILENAME page_items = self.selector.get_topic_page(self.mode, topic, self.search_string, self.current_page, self.previous_page, self.first_item, self.last_item, PAGE_SIZE) self.previous_page = self.current_page if not page_items: page_items = [] first_item = None last_item = None else: first_item = page_items[0] last_item = page_items[len(page_items) - 1] return (page_items, first_item, last_item) def select_item(self, s=None): """ Select item from menu :param s: button state """ if not s: return self.current_item = s.name s.collection_topic = self.collection_topic self.topic_menu.selected_index = s.index if self.collection_topic == KEY_AUDIO_FOLDER: s.folder = os.path.join(self.config[COLLECTION][BASE_FOLDER], s.name[1:]) s.source = KEY_MENU files = self.util.get_audio_files_in_folder(s.folder, False) if files: f = files[0] s.file_name = f.file_name s.url = os.path.join(s.folder, s.file_name) else: s.file_name = None s.url = None self.listeners[TOPIC_DETAIL](s) def add_screen_observers(self, update_observer, redraw_observer): """ Add screen observers :param update_observer: observer for updating the screen :param redraw_observer: observer to redraw the whole screen """ MenuScreen.add_screen_observers(self, update_observer, redraw_observer) self.update_observer = update_observer self.redraw_observer = redraw_observer self.add_loading_listener(redraw_observer) self.topic_menu.add_menu_observers(update_observer, redraw_observer) self.navigator.add_observers(update_observer, redraw_observer)
def __init__(self, util, listeners, voice_assistant): """ Initializer :param util: utility object :param listeners: listeners :param voice_assistant: voice assistant """ self.util = util self.config = util.config self.listeners = listeners self.factory = Factory(util) self.go_home = listeners[KEY_HOME] self.go_file_playback = listeners[KEY_PLAY_COLLECTION] dbutil = util.get_db_util() self.selector = Selector(dbutil) self.bounding_box = util.screen_rect layout = BorderLayout(self.bounding_box) layout.set_percent_constraints(PERCENT_TOP_HEIGHT, PERCENT_BOTTOM_HEIGHT, 0, 0) MenuScreen.__init__(self, util, listeners, ROWS, COLUMNS, voice_assistant, [ROWS, COLUMNS], self.turn_page, page_in_title=False, show_loading=False) self.navigator = TopicDetailNavigator(self.util, self.layout.BOTTOM, listeners) self.add_navigator(self.navigator) self.left_button = self.navigator.get_button_by_name(KEY_PAGE_DOWN) self.right_button = self.navigator.get_button_by_name(KEY_PAGE_UP) self.player_button = self.navigator.get_button_by_name(KEY_PLAYER) m = self.factory.create_collection_menu_button font_size = int(((self.menu_layout.h / ROWS) / 100) * FONT_HEIGHT) h = self.config[HORIZONTAL_LAYOUT] bgr = self.config[BACKGROUND][MENU_BGR_COLOR] self.collection_list_menu = Menu(util, bgr, self.menu_layout, ROWS, COLUMNS, create_item_method=m, align=ALIGN_LEFT, horizontal_layout=h, font_size=font_size) self.set_menu(self.collection_list_menu) self.current_item = None self.current_page_items = None self.first_item = None self.last_item = None self.collection_topic = None self.selection = None self.prev_page = 1 self.animated_title = True