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
This commit is contained in:
Goffi 2010-07-30 18:43:09 +08:00
commit a4734f5868

View file

@ -96,8 +96,6 @@ class SurroundedText(urwid.FlowWidget):
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 @@ class SelectableText(urwid.FlowWidget):
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 @@ class ClickableText(SelectableText):
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 @@ class List(urwid.FlowWidget):
## 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 @@ class MenuRoller(urwid.WidgetWrap):
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 @@ class MenuRoller(urwid.WidgetWrap):
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 @@ class FocusFrame(urwid.Frame):
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 LabelLine(urwid.LineBox):
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: