# HG changeset patch # User Goffi # Date 1279107400 -28800 # Node ID 6cad483a6d84a40b7ca735f7b6d7e5f8d8615a45 # Parent 5a88ad24ccc0064f449a2227a7d5348a9a812f33 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 5a88ad24ccc0 -r 6cad483a6d84 frontends/primitivus/custom_widgets.py --- a/frontends/primitivus/custom_widgets.py Wed Jul 14 16:14:48 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 ## diff -r 5a88ad24ccc0 -r 6cad483a6d84 frontends/primitivus/primitivus --- a/frontends/primitivus/primitivus Wed Jul 14 16:14:48 2010 +0800 +++ b/frontends/primitivus/primitivus Wed Jul 14 19:36:40 2010 +0800 @@ -66,6 +66,9 @@ ('my_nick', 'dark red,bold', 'default'), ('other_nick', 'dark cyan,bold', 'default'), ('menubar', 'light gray,bold', 'dark red'), + ('selected_menu', 'light gray,bold', 'dark green'), + ('menuitem', 'light gray,bold', 'dark red'), + ('menuitem_focus', 'light gray,bold', 'dark green'), ] class ChatList(QuickChatList): @@ -91,14 +94,14 @@ self.chat_wins=ChatList(self) def debug(self): - """convenience method to reset screen and launch pdb""" + """convenient method to reset screen and launch pdb""" import os os.system('reset') print 'Entered debug mode' pdb.set_trace() def write_log(self, log, file_name='/tmp/primitivus_log'): - #method to write log in a temporary file, useful for debugging + """method to write log in a temporary file, useful for debugging""" f=open(file_name, 'a') f.write(log+"\n") f.close() @@ -123,9 +126,7 @@ return input def keyHandler(self, input): - if input in ('q', 'Q') or input == 'ctrl x': - raise urwid.ExitMainLoop() - elif input == 'meta m': + if input == 'meta m': try: if self.main_widget.header == None: self.main_widget.header = self.menu @@ -135,9 +136,6 @@ pass elif input == 'ctrl d' and 'D' in self.bridge.getVersion(): #Debug only for dev versions self.debug() - elif input == 'meta j': #user wants to join a room - pop_up_widget = custom_widgets.InputDialog(_("Entering a MUC room"), _("Please enter MUC's JID"), default_txt = 'test@conference.necton2.int', cancel_cb=self.removePopUp, ok_cb=self.onJoinRoom) - self.showPopUp(pop_up_widget) elif input == 'f2': #user wants to (un)hide the contact_list try: center_widgets = self.center_part.widget_list @@ -166,13 +164,23 @@ except AttributeError: return input + def __buildMainMenu(self): + menu = custom_widgets.Menu(self.loop) + connect = _("Connect") + menu.addMenu(connect, connect, self.onConnectRequest) + menu.addMenu(connect, _("Disconnect"), self.onDisconnectRequest) + menu.addMenu(connect, _("Exit"), self.onExitRequest, 'ctrl x') + communication = _("Communication") + menu.addMenu(communication, _("Join room"), self.onJoinRoomRequest, 'meta j') + return menu + def __buildMainWidget(self): self.contactList = ContactList(self, self.CM, on_click = self.contactSelected, on_change=lambda w: self.redraw()) #self.center_part = urwid.Columns([('weight',2,self.contactList),('weight',8,Chat('',self))]) self.center_part = urwid.Columns([('weight',2,self.contactList), ('weight',8,urwid.Filler(urwid.Text('')))]) editBar = custom_widgets.AdvancedEdit('> ') urwid.connect_signal(editBar,'click',self.onTextEntered) - self.menu = custom_widgets.Menu() + self.menu = self.__buildMainMenu() self.main_widget = custom_widgets.FocusFrame(self.center_part, header=self.menu, footer=editBar, focus_part='footer') return self.main_widget @@ -224,6 +232,21 @@ error (message) custom_widgets.Alert(_("Error"), message, ok_cb=self.removePopUp) + #Menu events# + def onConnectRequest(self, menu): + self.bridge.connect(self.profile) + + def onDisconnectRequest(self, menu): + self.bridge.disconnect(self.profile) + + def onExitRequest(self, menu): + raise urwid.ExitMainLoop() + + def onJoinRoomRequest(self, menu): + """User wants to join a MUC room""" + pop_up_widget = custom_widgets.InputDialog(_("Entering a MUC room"), _("Please enter MUC's JID"), default_txt = 'test@conference.necton2.int', cancel_cb=self.removePopUp, ok_cb=self.onJoinRoom) + self.showPopUp(pop_up_widget) + sat = PrimitivusApp() sat.start()