# HG changeset patch # User Goffi # Date 1279107400 -28800 # Node ID 983840425a555008d066650ddda24c9989759cce # Parent 024b79b61a315c79ecc101ba45a4b9fc2fc4a955 Primitivus: menu is now working /!\ tooltips not managed yet, doesn't manage properly menu when it's displayed on several rows /!\ still need to manage other menus (chat menu) diff -r 024b79b61a31 -r 983840425a55 frontends/primitivus/custom_widgets.py --- a/frontends/primitivus/custom_widgets.py Tue Jul 13 02:24:59 2010 +0800 +++ b/frontends/primitivus/custom_widgets.py Wed Jul 14 19:36:40 2010 +0800 @@ -342,18 +342,87 @@ ## MISC ## +class MenuBox(urwid.WidgetWrap): + signals = ['click'] + + def __init__(self,parent,items): + self.parent = parent + self.selected = None + content = urwid.SimpleListWalker([ClickableText(text,default_attr='menuitem') for text in items]) + for wid in content: + urwid.connect_signal(wid, 'click', self.onClick) + + self.listBox = urwid.ListBox(content) + menubox = urwid.LineBox(urwid.BoxAdapter(self.listBox,len(items))) + urwid.WidgetWrap.__init__(self,menubox) + + def getValue(self): + return self.selected + + def keypress(self, size, key): + if key=='up': + if self.listBox.get_focus()[1] == 0: + self.parent.keypress(size, key) + elif key=='left' or key=='right': + self.parent.keypress(size,'up') + self.parent.keypress(size,key) + return super(MenuBox,self).keypress(size,key) + + def onClick(self, wid): + self.selected = wid.getValue() + self._emit('click') + class Menu(urwid.FlowWidget): - def __init__(self): + def __init__(self,loop): super(Menu, self).__init__() - self.menu_keys = ['test'] - self.menu = {'test':[('top',None)]} + self.loop = loop + self.menu_keys = [] + self.menu = {} self.shortcuts = {} #keyboard shortcuts + self.focus_menu = 0 + self.save_bottom = None + + def selectable(self): + return True + + def __buildOverlay(self,menu_key,columns): + """Build the overlay menu which show menuitems + @param menu_key: name of the category + @colums: column number where the menubox must be displayed""" + max_len = 0 + for item in self.menu[menu_key]: + if len(item[0]) > max_len: + max_len = len(item[0]) + + self.save_bottom = self.loop.widget + menu_box = MenuBox(self,[item[0] for item in self.menu[menu_key]]) + urwid.connect_signal(menu_box, 'click', self.onClick) + + self.loop.widget = urwid.Overlay(urwid.AttrMap(menu_box,'menubar'),self.save_bottom,('fixed left', columns),max_len+2,('fixed top',1),None) + + def keypress(self, size, key): + if key == 'right' and self.focus_menu < len(self.menu)-1: + self.focus_menu += 1 + self._invalidate() + elif key == 'left' and self.focus_menu > 0: + self.focus_menu -= 1 + self._invalidate() + elif key == 'down': + if not self.save_bottom: + column = sum([len(menu)+4 for menu in self.menu_keys[0:self.focus_menu]],self.focus_menu+1) + self.__buildOverlay(self.menu_keys[self.focus_menu],column) + elif key == 'up': + if self.save_bottom: + self.loop.widget = self.save_bottom + self.save_bottom = None + + return key def checkShortcuts(self, key): for shortcut in self.shortcuts.keys(): if key == shortcut: - category, item, callback = self.shortcuts[shortcuts] + category, item, callback = self.shortcuts[shortcut] callback((category, item)) return key @@ -365,7 +434,7 @@ if not category in self.menu.keys(): self.menu_keys.append(category) self.menu[category] = [] - self.menu[category].append[(item, callback)] + self.menu[category].append((item, callback)) if shortcut: assert(shortcut not in self.shortcuts.keys()) self.shortcuts[shortcut] = (category, item, callback) @@ -378,10 +447,27 @@ def display_widget(self, size, focus): render_txt = [] + idx = 0 for menu in self.menu_keys: - render_txt.append('[ %s ] ' % menu) + if focus and idx == self.focus_menu: + render_txt.append(('selected_menu', '[ %s ]' % menu)) + render_txt.append(' ') + else: + render_txt.append('[ %s ] ' % menu) + idx += 1 return urwid.AttrMap(urwid.Text(render_txt), 'menubar') + def onClick(self, widget): + category = self.menu_keys[self.focus_menu] + item = widget.getValue() + for menu_item in self.menu[category]: + if item == menu_item[0]: + callback = menu_item[1] + break + if callback: + self.keypress(None,'up') + callback((category, item)) + ## DIALOGS ##