diff frontends/primitivus/custom_widgets.py @ 15:8241b3157699

Primitivus: custom_widgets imrpovments - new container: TabsContainer - menu roller can now remove a menu - new Button: CustomButton (use ClickableText, and we can define the borders) - SelectableText now manage mouse events
author Goffi <goffi@goffi.org>
date Fri, 30 Jul 2010 18:43:09 +0800
parents f7d24eff1272
children 263fe4d067ad
line wrap: on
line diff
--- a/frontends/primitivus/custom_widgets.py	Mon Jul 26 19:43:44 2010 +0800
+++ b/frontends/primitivus/custom_widgets.py	Fri Jul 30 18:43:09 2010 +0800
@@ -96,8 +96,6 @@
         render_text = middle * self.car + self.text + (maxcol - len(self.text) - middle) * self.car
         return urwid.Text(render_text)
 
-
-
 class SelectableText(urwid.FlowWidget):
     """Text which can be selected with space"""
     signals = ['change']
@@ -150,6 +148,13 @@
         else:
             return key
 
+    def mouse_event(self, size, event, button, x, y, focus):
+        if urwid.is_mouse_press(event) and button == 1:
+            self.setState(not self.__selected)
+            return True
+        
+        return False
+   
     def rows(self,size,focus=False):
         return self.display_widget(size, focus).rows(size, focus)
 
@@ -176,6 +181,23 @@
     def setState(self, selected, invisible=False):
         self._emit('click')
 
+class CustomButton(ClickableText):
+
+    def __init__(self, label, on_press=None, user_data=None, left_border = "[ ", right_border = " ]"):
+        self.label = label
+        render_txt = "%s%s%s" % (left_border, label, right_border)
+        self.size = len(render_txt)
+        super(CustomButton, self).__init__(render_txt) 
+        if on_press:
+            urwid.connect_signal(self, 'click', on_press, user_data)
+
+    def getSize(self):
+        """Return representation size of the button"""
+        return self.size
+
+    def get_label(self):
+        return self.label
+
 class GenericList(urwid.WidgetWrap):
     signals = ['click','change']
 
@@ -337,6 +359,7 @@
 ## MISC ##
 
 class MenuBox(urwid.WidgetWrap):
+    """Show menu items of a category in a box"""
     signals = ['click']
     
     def __init__(self,parent,items):
@@ -515,7 +538,7 @@
                 self.__showSelected()
         elif key=='right':
             if self.columns.get_focus_column()==0 and \
-                (self.columns.widget_list[1].__class__ == urwid.Text or \
+                (isinstance(self.columns.widget_list[1], urwid.Text) or \
                 self.menus[self.name_list[self.selected]].getMenuSize()==0):
                 return #if we have no menu or the menu is empty, we don't go the right column
 
@@ -529,6 +552,14 @@
         if self.name_list[self.selected] == name:
             self.__showSelected() #if we are on the menu, we update it
 
+    def removeMenu(self, name):
+        if name in self.name_list:
+            self.name_list.remove(name)
+        if name in self.menus.keys():
+            del self.menus[name]
+        self.selected = 0
+        self.__showSelected()
+
     def checkShortcuts(self, key):
         for menu in self.name_list:
             key = self.menus[menu].checkShortcuts(key)
@@ -601,6 +632,58 @@
 
         return urwid.Frame.keypress(self, size, key)
 
+class TabsContainer(urwid.WidgetWrap):
+    signals = ['click']
+
+    def __init__(self):
+        #self._current_tab = 0
+        self._buttons_cont = urwid.GridFlow([],19,1,0,'left')
+        self.tabs = []
+        self.__frame = urwid.Frame(urwid.Text(''),urwid.Pile([self._buttons_cont,urwid.Divider(u"─")]))
+        urwid.WidgetWrap.__init__(self, self.__frame)
+
+    """def selectable(self):
+        return True
+    
+    def keypress(self, size, key):
+        return key"""
+
+    def __buttonClicked(self, button, invisible=False):
+        """Called when a button on the tab is changed,
+        change the page
+        @param button: button clicked
+        @param invisible: emit signal only if False"""
+        tab_name = button.get_label()
+        for tab in self.tabs:
+            if tab[0] == tab_name:
+                break
+        if tab[0] != tab_name:
+            error(_("INTERNAL ERROR: Tab not found"))
+            assert(False)
+        self.__frame.body = tab[1]
+        if not invisible:
+            self._emit('click')
+
+    def __appendButton(self, name):
+        """Append a button to the frame header,
+        and link it to the page change method"""
+        button = CustomButton(name, self.__buttonClicked, left_border = '', right_border=' |')
+        self._buttons_cont.cells.append(button)
+        if len(self._buttons_cont.cells):
+            #first button: we set the focus and the body
+            self._buttons_cont.set_focus(0)
+            self.__buttonClicked(button,True)
+
+    def addTab(self,name,content=[]):
+        """Add a page to the container
+        @param name: name of the page (what appear on the tab)
+        @param content: content of the page
+        @return: ListBox (content of the page)"""
+        listbox = urwid.ListBox(urwid.SimpleListWalker(content))
+        self.tabs.append([name,listbox])
+        self.__appendButton(name)
+        return listbox
+
 ## DECORATORS ##
 class LabelLine(urwid.LineBox):
     """Like LineBox, but with a Label centered in the top line"""
@@ -612,7 +695,7 @@
 
 class VerticalSeparator(urwid.WidgetDecoration, urwid.WidgetWrap):
     def __init__(self, original_widget, left_char = utf8decode("│"), right_char = ''):
-        """Draw a separator on left and/or of original_widget."""
+        """Draw a separator on left and/or right of original_widget."""
         
         widgets = [original_widget]
         if left_char: