[nyx/master] Replace get_label() with attributes

commit aafe5f8014311f3f401e8c329a6fb71d83050155 Author: Damian Johnson <atagar@torproject.org> Date: Tue Aug 9 09:59:22 2016 -0700 Replace get_label() with attributes More of a lateral move at this point, but replacing our get_label() methods with prefix, label, and suffix attributes. --- nyx/menu.py | 402 +++++++++++++++++++++++++++++------------------------------- 1 file changed, 196 insertions(+), 206 deletions(-) diff --git a/nyx/menu.py b/nyx/menu.py index 35831b3..4a756c4 100644 --- a/nyx/menu.py +++ b/nyx/menu.py @@ -30,6 +30,198 @@ CONFIG = conf.config_dict('nyx', { }) +class MenuItem(object): + """ + Drop-down menu item. + + :var str prefix: text coming before our label + :var str label: text we display + :var str suffix: text coming after our label + """ + + def __init__(self, label, callback): + self.label = label + self.suffix = '' + + self._callback = callback + self._parent = None + + @property + def prefix(self): + return '' + + def get_parent(self): + """ + Provides the Submenu we're contained within. + """ + + return self._parent + + def get_hierarchy(self): + """ + Provides a list with all of our parents, up to the root. + """ + + my_hierarchy = [self] + while my_hierarchy[-1].get_parent(): + my_hierarchy.append(my_hierarchy[-1].get_parent()) + + my_hierarchy.reverse() + return my_hierarchy + + def get_root(self): + """ + Provides the base submenu we belong to. + """ + + if self._parent: + return self._parent.get_root() + else: + return self + + def select(self): + """ + Performs the callback for the menu item, returning true if we should close + the menu and false otherwise. + """ + + if self._callback: + control = nyx.controller.get_controller() + control.redraw() + self._callback() + + return True + + def next(self): + """ + Provides the next option for the submenu we're in, raising a ValueError + if we don't have a parent. + """ + + return self._get_sibling(1) + + def prev(self): + """ + Provides the previous option for the submenu we're in, raising a ValueError + if we don't have a parent. + """ + + return self._get_sibling(-1) + + def _get_sibling(self, offset): + """ + Provides our sibling with a given index offset from us, raising a + ValueError if we don't have a parent. + + Arguments: + offset - index offset for the sibling to be returned + """ + + if self._parent: + my_siblings = self._parent.get_children() + + try: + my_index = my_siblings.index(self) + return my_siblings[(my_index + offset) % len(my_siblings)] + except ValueError: + # We expect a bidirectional references between submenus and their + # children. If we don't have this then our menu's screwed up. + + msg = "The '%s' submenu doesn't contain '%s' (children: '%s')" % (self, self._parent, "', '".join(my_siblings)) + raise ValueError(msg) + else: + raise ValueError("Menu option '%s' doesn't have a parent" % self) + + def __str__(self): + return self.label + + +class Submenu(MenuItem): + """ + Menu item that lists other menu options. + """ + + def __init__(self, label): + MenuItem.__init__(self, label, None) + self.suffix = ' >' + self._children = [] + + def add(self, menu_item): + """ + Adds the given menu item to our listing. This raises a ValueError if the + item already has a parent. + + Arguments: + menu_item - menu option to be added + """ + + if menu_item.get_parent(): + raise ValueError("Menu option '%s' already has a parent" % menu_item) + else: + menu_item._parent = self + self._children.append(menu_item) + + def get_children(self): + """ + Provides the menu and submenus we contain. + """ + + return list(self._children) + + def is_empty(self): + """ + True if we have no children, false otherwise. + """ + + return not bool(self._children) + + def select(self): + return False + + +class RadioMenuItem(MenuItem): + """ + Menu item with an associated group which determines the selection. This is + for the common single argument getter/setter pattern. + """ + + def __init__(self, label, group, arg): + MenuItem.__init__(self, label, None) + self._group = group + self._arg = arg + + @property + def prefix(self): + return '[X] ' if self.is_selected() else '[ ] ' + + def is_selected(self): + """ + True if we're the selected item, false otherwise. + """ + + return self._arg == self._group.selected_arg + + def select(self): + """ + Performs the group's setter action with our argument. + """ + + if not self.is_selected(): + self._group.action(self._arg) + + return True + + +class RadioGroup(object): + """ + Radio button groups that RadioMenuItems can belong to. + """ + + def __init__(self, action, selected_arg): + self.action = action + self.selected_arg = selected_arg + + def make_menu(): """ Constructs the base menu and all of its contents. @@ -388,7 +580,7 @@ def show_menu(): else: attr = NORMAL - x = subwindow.addstr(x, 0, ' %s ' % top_level_item.get_label()[1], BOLD, attr) + x = subwindow.addstr(x, 0, ' %s ' % top_level_item.label, BOLD, attr) subwindow.vline(x, 0, 1) x += 1 @@ -432,7 +624,7 @@ def _draw_submenu(cursor, level, top, left): # gets the size of the prefix, middle, and suffix columns - all_label_sets = [entry.get_label() for entry in submenu.get_children()] + all_label_sets = [(entry.prefix, entry.label, entry.suffix) for entry in submenu.get_children()] prefix_col_size = max([len(entry[0]) for entry in all_label_sets]) middle_col_size = max([len(entry[1]) for entry in all_label_sets]) suffix_col_size = max([len(entry[2]) for entry in all_label_sets]) @@ -446,212 +638,10 @@ def _draw_submenu(cursor, level, top, left): def _render(subwindow): for y, menu_item in enumerate(submenu.get_children()): if menu_item == selection: - subwindow.addstr(0, y, label_format % menu_item.get_label(), WHITE, BOLD) + subwindow.addstr(0, y, label_format % (menu_item.prefix, menu_item.label, menu_item.suffix), WHITE, BOLD) else: - subwindow.addstr(0, y, label_format % menu_item.get_label()) + subwindow.addstr(0, y, label_format % (menu_item.prefix, menu_item.label, menu_item.suffix)) with nyx.curses.CURSES_LOCK: nyx.curses.draw(_render, top = top, left = left, width = menu_width, height = len(submenu.get_children()), background = RED) _draw_submenu(cursor, level + 1, top + selection_top, left + menu_width) - - -class MenuItem(): - """ - Option in a drop-down menu. - """ - - def __init__(self, label, callback): - self._label = label - self._callback = callback - self._parent = None - - def get_label(self): - """ - Provides a tuple of three strings representing the prefix, label, and - suffix for this item. - """ - - return ('', self._label, '') - - def get_parent(self): - """ - Provides the Submenu we're contained within. - """ - - return self._parent - - def get_hierarchy(self): - """ - Provides a list with all of our parents, up to the root. - """ - - my_hierarchy = [self] - while my_hierarchy[-1].get_parent(): - my_hierarchy.append(my_hierarchy[-1].get_parent()) - - my_hierarchy.reverse() - return my_hierarchy - - def get_root(self): - """ - Provides the base submenu we belong to. - """ - - if self._parent: - return self._parent.get_root() - else: - return self - - def select(self): - """ - Performs the callback for the menu item, returning true if we should close - the menu and false otherwise. - """ - - if self._callback: - control = nyx.controller.get_controller() - control.redraw() - self._callback() - - return True - - def next(self): - """ - Provides the next option for the submenu we're in, raising a ValueError - if we don't have a parent. - """ - - return self._get_sibling(1) - - def prev(self): - """ - Provides the previous option for the submenu we're in, raising a ValueError - if we don't have a parent. - """ - - return self._get_sibling(-1) - - def _get_sibling(self, offset): - """ - Provides our sibling with a given index offset from us, raising a - ValueError if we don't have a parent. - - Arguments: - offset - index offset for the sibling to be returned - """ - - if self._parent: - my_siblings = self._parent.get_children() - - try: - my_index = my_siblings.index(self) - return my_siblings[(my_index + offset) % len(my_siblings)] - except ValueError: - # We expect a bidirectional references between submenus and their - # children. If we don't have this then our menu's screwed up. - - msg = "The '%s' submenu doesn't contain '%s' (children: '%s')" % (self, self._parent, "', '".join(my_siblings)) - raise ValueError(msg) - else: - raise ValueError("Menu option '%s' doesn't have a parent" % self) - - def __str__(self): - return self._label - - -class Submenu(MenuItem): - """ - Menu item that lists other menu options. - """ - - def __init__(self, label): - MenuItem.__init__(self, label, None) - self._children = [] - - def get_label(self): - """ - Provides our label with a '>' suffix to indicate that we have suboptions. - """ - - my_label = MenuItem.get_label(self)[1] - return ('', my_label, ' >') - - def add(self, menu_item): - """ - Adds the given menu item to our listing. This raises a ValueError if the - item already has a parent. - - Arguments: - menu_item - menu option to be added - """ - - if menu_item.get_parent(): - raise ValueError("Menu option '%s' already has a parent" % menu_item) - else: - menu_item._parent = self - self._children.append(menu_item) - - def get_children(self): - """ - Provides the menu and submenus we contain. - """ - - return list(self._children) - - def is_empty(self): - """ - True if we have no children, false otherwise. - """ - - return not bool(self._children) - - def select(self): - return False - - -class RadioGroup(): - """ - Radio button groups that RadioMenuItems can belong to. - """ - - def __init__(self, action, selected_arg): - self.action = action - self.selected_arg = selected_arg - - -class RadioMenuItem(MenuItem): - """ - Menu item with an associated group which determines the selection. This is - for the common single argument getter/setter pattern. - """ - - def __init__(self, label, group, arg): - MenuItem.__init__(self, label, None) - self._group = group - self._arg = arg - - def is_selected(self): - """ - True if we're the selected item, false otherwise. - """ - - return self._arg == self._group.selected_arg - - def get_label(self): - """ - Provides our label with a '[X]' prefix if selected and '[ ]' if not. - """ - - my_label = MenuItem.get_label(self)[1] - my_prefix = '[X] ' if self.is_selected() else '[ ] ' - return (my_prefix, my_label, '') - - def select(self): - """ - Performs the group's setter action with our argument. - """ - - if not self.is_selected(): - self._group.action(self._arg) - - return True
participants (1)
-
atagar@torproject.org