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)
This commit is contained in:
Goffi 2010-07-14 19:36:40 +08:00
commit ded8314a26
2 changed files with 124 additions and 15 deletions

View file

@ -342,18 +342,87 @@ class List(urwid.FlowWidget):
## 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 @@ class Menu(urwid.FlowWidget):
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 @@ class Menu(urwid.FlowWidget):
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 ##

View file

@ -66,6 +66,9 @@ const_PALETTE = [('title', 'black', 'light gray', 'standout,underline'),
('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 @@ class PrimitivusApp(QuickApp):
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 @@ class PrimitivusApp(QuickApp):
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 @@ class PrimitivusApp(QuickApp):
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 @@ class PrimitivusApp(QuickApp):
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 @@ class PrimitivusApp(QuickApp):
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()