changeset 131:6cad483a6d84

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)
author Goffi <goffi@goffi.org>
date Wed, 14 Jul 2010 19:36:40 +0800
parents 5a88ad24ccc0
children a86607e5cf38
files frontends/primitivus/custom_widgets.py frontends/primitivus/primitivus
diffstat 2 files changed, 124 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- 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 ##
 
--- 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()