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:
parent
20a88f9909
commit
a4734f5868
1 changed files with 87 additions and 4 deletions
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Reference in a new issue