changeset 137:227394eb080c

Primitivus: menu are now managed and fully working - new class MenuRoller for manager different menus - Chat window now create is own menu - some menu items added for general/contact menus
author Goffi <goffi@goffi.org>
date Fri, 16 Jul 2010 20:25:06 +0800
parents d6c0fe7489af
children 2f8c86488b05
files frontends/primitivus/chat.py frontends/primitivus/custom_widgets.py frontends/primitivus/primitivus
diffstat 3 files changed, 133 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/frontends/primitivus/chat.py	Fri Jul 16 20:17:01 2010 +0800
+++ b/frontends/primitivus/chat.py	Fri Jul 16 20:25:06 2010 +0800
@@ -121,6 +121,14 @@
 
 
         return super(Chat, self).keypress(size, key) 
+    
+    def getMenu(self):
+        """Return Menu bar"""
+        menu = custom_widgets.Menu(self.host.loop)
+        if self.type == 'group':
+            game = _("Game")
+            menu.addMenu(game, "Tarot", self.onTarotRequest)
+        return menu
 
     def setType(self, type):
         QuickChat.setType(self, type)
@@ -201,3 +209,11 @@
         self.content.append(ChatText(self, timestamp or None, my_jid, from_jid, msg))
         self.text_list.set_focus(len(self.content)-1)
         self.host.redraw()
+
+    #MENU EVENTS#
+    def onTarotRequest(self, menu):
+        if len(self.occupants) != 4:
+            self.host.debug()
+            self.host.showPopUp(custom_widgets.Alert(_("Can't start game"), _("You need to be exactly 4 peoples in the room to start a Tarot game"), ok_cb=self.host.removePopUp)) 
+        else:
+            self.host.bridge.tarotGameCreate(self.id, list(self.occupants), self.host.profile)
--- a/frontends/primitivus/custom_widgets.py	Fri Jul 16 20:17:01 2010 +0800
+++ b/frontends/primitivus/custom_widgets.py	Fri Jul 16 20:25:06 2010 +0800
@@ -374,18 +374,26 @@
 
 class Menu(urwid.FlowWidget):
 
-    def __init__(self,loop):
+    def __init__(self,loop, x_orig=0):
+        """Menu widget
+        @param loop: main loop of urwid
+        @param x_orig: absolute start of the abscissa
+        """
         super(Menu, self).__init__()
         self.loop = loop
         self.menu_keys = []
         self.menu = {}
+        self.x_orig = x_orig
         self.shortcuts = {} #keyboard shortcuts
         self.focus_menu = 0
         self.save_bottom = None
 
     def selectable(self):
         return True
-    
+   
+    def setOrigX(self, orig_x):
+        self.x_orig = orig_x
+
     def __buildOverlay(self,menu_key,columns):
         """Build the overlay menu which show menuitems
         @param menu_key: name of the category
@@ -408,9 +416,10 @@
         elif key == 'left' and self.focus_menu > 0:
             self.focus_menu -= 1
             self._invalidate()
+            return
         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)
+            if self.menu_keys and not self.save_bottom:
+                column = sum([len(menu)+4 for menu in self.menu_keys[0:self.focus_menu]],self.focus_menu+self.x_orig)
                 self.__buildOverlay(self.menu_keys[self.focus_menu],column)
         elif key == 'up':
             if  self.save_bottom:
@@ -468,6 +477,60 @@
             self.keypress(None,'up')
             callback((category, item))
 
+class MenuRoller(urwid.WidgetWrap):
+
+    def __init__(self,menus_list):
+        """Create a MenuRoller
+        @param menus_list: list of tuple with (name, Menu_instance), name can be None
+        """
+        assert (menus_list)
+        self.selected = 0
+        self.name_list = []
+        self.menus = {}
+             
+        self.columns = urwid.Columns([urwid.Text(''),urwid.Text('')]) 
+        urwid.WidgetWrap.__init__(self, self.columns)
+        
+        for menu_tuple in menus_list:
+            name,menu = menu_tuple
+            self.addMenu(name, menu)
+
+    def __showSelected(self):
+        """show menu selected"""
+        name_txt = u'\u21c9 '+self.name_list[self.selected]+u' \u21c7 '
+        current_name = ClickableText(name_txt) 
+        name_len = len(name_txt)
+        current_menu = self.menus[self.name_list[self.selected]]
+        current_menu.setOrigX(name_len)
+        self.columns.widget_list[0] = current_name
+        self.columns.column_types[0]=('fixed', name_len)
+        self.columns.widget_list[1] = current_menu
+
+    def keypress(self, size, key):
+        if key=='up':
+            if self.columns.get_focus_column()==0 and self.selected > 0:
+                self.selected -= 1
+                self.__showSelected()
+        elif key=='down':
+            if self.columns.get_focus_column()==0 and self.selected < len(self.name_list)-1:
+                self.selected += 1
+                self.__showSelected()
+
+        return super(MenuRoller, self).keypress(size, key)
+
+    def addMenu(self, name_param, menu):
+        name = name_param or ''
+        if name not in self.name_list:
+            self.name_list.append(name)
+        self.menus[name] = menu
+        if self.name_list[self.selected] == name:
+            self.__showSelected() #if we are on the menu, we update it
+
+    def checkShortcuts(self, key):
+        for menu in self.name_list:
+            key = self.menus[menu].checkShortcuts(key)
+        return key
+        
 
 ## DIALOGS ##
 
--- a/frontends/primitivus/primitivus	Fri Jul 16 20:17:01 2010 +0800
+++ b/frontends/primitivus/primitivus	Fri Jul 16 20:25:06 2010 +0800
@@ -129,7 +129,7 @@
         if input == 'meta m':
             try:
                 if self.main_widget.header == None:
-                    self.main_widget.header = self.menu
+                    self.main_widget.header = self.menu_roller
                 else:
                     self.main_widget.header = None
             except AttributeError:
@@ -160,19 +160,24 @@
                     self.loop.widget = self.save_main_widget
                     del self.save_main_widget
         try:
-            return self.menu.checkShortcuts(input)
+            return self.menu_roller.checkShortcuts(input)
         except AttributeError:
             return input
 
-    def __buildMainMenu(self):
+    def __buildMenuRoller(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')
+        general = _("General")
+        menu.addMenu(general, _("Connect"), self.onConnectRequest)
+        menu.addMenu(general, _("Disconnect"), self.onDisconnectRequest)
+        menu.addMenu(general, _("About"), self.onAboutRequest)
+        menu.addMenu(general, _("Exit"), self.onExitRequest, 'ctrl x')
+        contact = _("Contact")
+        menu.addMenu(contact, _("Add contact"), self.onAddContactRequest)
+        menu.addMenu(contact, _("Remove contact"), self.onRemoveContactRequest)
         communication = _("Communication")
         menu.addMenu(communication, _("Join room"), self.onJoinRoomRequest, 'meta j')
-        return menu 
+        menu_roller = custom_widgets.MenuRoller([(_('Main menu'),menu)])
+        return menu_roller 
 
     def __buildMainWidget(self):
         self.contactList = ContactList(self, self.CM, on_click = self.contactSelected, on_change=lambda w: self.redraw())
@@ -180,8 +185,8 @@
         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 = self.__buildMainMenu()
-        self.main_widget = custom_widgets.FocusFrame(self.center_part, header=self.menu, footer=editBar, focus_part='footer')
+        self.menu_roller = self.__buildMenuRoller()
+        self.main_widget = custom_widgets.FocusFrame(self.center_part, header=self.menu_roller, footer=editBar, focus_part='footer')
         return self.main_widget
 
     def plug_profile(self, profile_key='@DEFAULT@'):
@@ -199,9 +204,8 @@
         contact = contact_list.get_contact()
         if contact:
             assert(len(self.center_part.widget_list)==2)
-            #self.center_part.widget_list.append(self.chat_wins[contact])
-            #self.center_part.column_types.append(('weight',8))
             self.center_part.widget_list[1] = self.chat_wins[contact]
+            self.menu_roller.addMenu(_('Chat Menu'), self.chat_wins[contact].getMenu())
 
     def onTextEntered(self, editBar):
         """Called when text is entered in the main edit bar"""
@@ -232,6 +236,21 @@
             error (message)
             custom_widgets.Alert(_("Error"), message, ok_cb=self.removePopUp)        
 
+    def onAddContact(self, button, edit):
+        self.removePopUp()
+        jid=JID(edit.get_edit_text())
+        if jid.is_valid():
+            self.bridge.addContact(jid.short, profile_key=self.profile)
+        else:
+            message = _("'%s' is an invalid JID !") % jid
+            error (message)
+            custom_widgets.Alert(_("Error"), message, ok_cb=self.removePopUp)
+
+    def onRemoveContact(self, button):
+        self.removePopUp()
+        info(_("Unsubscribing %s presence"),self.contactList.get_contact())
+        self.bridge.delContact(self.contactList.get_contact(), profile_key=self.profile)
+
     #Menu events#
     def onConnectRequest(self, menu):
         self.bridge.connect(self.profile)
@@ -247,6 +266,25 @@
         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)
 
+    def onAddContactRequest(self, menu):
+        pop_up_widget = custom_widgets.InputDialog(_("Adding a contact"), _("Please enter new contact JID"), default_txt = 'name@server.tld', cancel_cb=self.removePopUp, ok_cb=self.onAddContact)
+        self.showPopUp(pop_up_widget)
+
+    def onRemoveContactRequest(self, menu):
+        contact = self.contactList.get_contact()
+        if not contact:
+            self.showPopUp(custom_widgets.Alert(_("Error"), _("You have not selected any contact to delete !"), ok_cb=self.removePopUp))
+        else:
+            pop_up_widget = custom_widgets.ConfirmDialog(_("Are you sure you want to delete the contact [%s] ?" % contact), yes_cb=self.onRemoveContact, no_cb=self.removePopUp)
+            self.showPopUp(pop_up_widget)
+
+
+
+
+    def onAboutRequest(self, menu):
+        self.showPopUp(custom_widgets.Alert(_("About"), const_APP_NAME + " v" + self.bridge.getVersion(), ok_cb=self.removePopUp)) 
+        
+
 sat = PrimitivusApp()
 sat.start()