diff frontends/primitivus/primitivus @ 159:2fa58703f1b7

Primitivus: notification bar, first draft - popup queue is now managed - notifications can auto-hide when nothing to show - ctrl-n show next notification Primitivus: ctrl-s allow to temporarily hide a popup Primitivus: cards in card_game now answer to mouse click Primitivus: notification is shown when invalid card is played in card_game Primitivus: SelectableText has now methods get_text and set_text
author Goffi <goffi@goffi.org>
date Wed, 04 Aug 2010 17:57:51 +0800
parents 13888bdb72b6
children b318d2b58887
line wrap: on
line diff
--- a/frontends/primitivus/primitivus	Wed Aug 04 17:53:20 2010 +0800
+++ b/frontends/primitivus/primitivus	Wed Aug 04 17:57:51 2010 +0800
@@ -57,6 +57,7 @@
                  ('selected_menu', 'light gray,bold', 'dark green'),
                  ('menuitem', 'light gray,bold', 'dark red'),
                  ('menuitem_focus', 'light gray,bold', 'dark green'),
+                 ('notifs', 'black,bold', 'yellow'),
                  ('card_neutral', 'dark gray', 'white', 'standout,underline'),
                  ('card_neutral_selected', 'dark gray', 'dark green', 'standout,underline'),
                  ('card_special', 'brown', 'white', 'standout,underline'),
@@ -80,7 +81,7 @@
     
     def __init__(self):
         self.CM = QuickContactManagement() #FIXME: not the best place
-        QuickApp.__init__(self)  #XXX: yes it's an unusual place for the constructor of a parent class, but the init order is important
+        QuickApp.__init__(self) 
         
         ## main loop setup ##
         self.main_widget = ProfileManager(self)
@@ -88,6 +89,9 @@
 
         ##misc setup##
         self.chat_wins=ChatList(self)
+        self.notBar = custom_widgets.NotificationBar()
+        urwid.connect_signal(self.notBar,'change',self.onNotification)
+        self.__saved_overlay = None
     
     def debug(self):
         """convenient method to reset screen and launch pdb"""
@@ -111,6 +115,8 @@
         self.loop.run()
 
     def inputFilter(self, input, raw):
+        if self.__saved_overlay and input != ['ctrl s']:
+            return
         for i in input:
             if isinstance(i,tuple):
                 if i[0] == 'mouse press':
@@ -129,6 +135,19 @@
                     self.main_widget.header = None
             except AttributeError:
                 pass
+        elif input == 'ctrl n':
+            """User wants to see next notification"""
+            self.notBar.showNext()
+        elif input == 'ctrl s':
+            """User wants to (un)hide overlay window"""
+            if isinstance(self.loop.widget,urwid.Overlay):
+                self.__saved_overlay = self.loop.widget
+                self.loop.widget = self.main_widget
+            else:
+                if self.__saved_overlay:
+                    self.loop.widget = self.__saved_overlay
+                    self.__saved_overlay = None
+
         elif input == 'ctrl d' and 'D' in self.bridge.getVersion(): #Debug only for dev versions
             self.debug()
         elif input == 'f2': #user wants to (un)hide the contact_list
@@ -190,10 +209,10 @@
         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.editBar = custom_widgets.AdvancedEdit('> ')
+        urwid.connect_signal(self.editBar,'click',self.onTextEntered)
         self.menu_roller = self.__buildMenuRoller()
-        self.main_widget = custom_widgets.FocusFrame(self.center_part, header=self.menu_roller, footer=editBar, focus_part='footer')
+        self.main_widget = custom_widgets.FocusFrame(self.center_part, header=self.menu_roller, footer=self.editBar, focus_part='footer')
         return self.main_widget
 
     def plug_profile(self, profile_key='@DEFAULT@'):
@@ -201,11 +220,23 @@
         QuickApp.plug_profile(self, profile_key)
     
     def removePopUp(self, widget=None):
+        "Remove current pop-up, and if there is other in queue, show it"
         self.loop.widget = self.main_widget
+        next_popup = self.notBar.getNextPopup()
+        if next_popup:
+            #we still have popup to show, we display it
+            self.showPopUp(next_popup)
 
     def showPopUp(self, pop_up_widget):
-        display_widget = urwid.Overlay(pop_up_widget, self.main_widget, 'center', ('relative', 40), 'middle', ('relative', 40))
-        self.loop.widget = display_widget
+        "Show a pop-up window if possible, else put it in queue"
+        if not isinstance(self.loop.widget,urwid.Overlay):
+            display_widget = urwid.Overlay(pop_up_widget, self.main_widget, 'center', ('relative', 40), 'middle', ('relative', 40))
+            self.loop.widget = display_widget
+        else:
+            self.notBar.addPopUp(pop_up_widget)
+
+    def notify(self, message):
+        self.notBar.addMessage(message)
 
     def contactSelected(self, contact_list):
         contact = contact_list.get_contact()
@@ -233,6 +264,24 @@
         if JID(self.contactList.selected).short != sender.short:
             self.contactList.putAlert(sender)
 
+    def onNotification(self, notBar):
+        """Called when a new notification has been received"""
+        if not isinstance(self.main_widget, custom_widgets.FocusFrame):
+            #if we are not in the main configuration, we ignore the notifications bar
+            return
+        if isinstance(self.main_widget.footer,custom_widgets.AdvancedEdit):
+            if not self.notBar.canHide():
+                #the notification bar is not visible and has usefull informations, we show it
+                pile = urwid.Pile([self.notBar, self.editBar])
+                self.main_widget.footer = pile
+        else:
+            if not isinstance(self.main_widget.footer, urwid.Pile):
+                error(_("INTERNAL ERROR: Unexpected class for main widget's footer"))
+                assert(False)
+            if self.notBar.canHide():
+                #No notification left, we can hide the bar
+                self.main_widget.footer = self.editBar
+
     def actionResult(self, type, id, data):
         if not id in self.current_action_ids:
             debug (_('unknown id, ignoring'))