Mercurial > urwid-satext
diff frontends/primitivus/custom_widgets.py @ 18:bdc83e857093
Primitivus: new widget ColumnsRoller which show FlowWidgets on the same row, and can roll between them if there is not enough space
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 09 Aug 2010 19:09:13 +0800 |
parents | 222aa33716ad |
children | 0b83dd2b15d1 |
line wrap: on
line diff
--- a/frontends/primitivus/custom_widgets.py Fri Aug 06 12:18:50 2010 +0800 +++ b/frontends/primitivus/custom_widgets.py Mon Aug 09 19:09:13 2010 +0800 @@ -692,6 +692,126 @@ ## CONTAINERS ## +class ColumnsRoller(urwid.FlowWidget): + + def __init__(self, widget_list = None, focus_column=0): + self.widget_list = widget_list or [] + self.focus_column = focus_column + self.__start = 0 + self.__next = False + + def addWidget(self, widget, width): + self.widget_list.append((width,widget)) + if len(self.widget_list) == 1: + self.set_focus(0) + + def selectable(self): + try: + return self.widget_list[self.focus_column][1].selectable() + except IndexError: + return False + + def keypress(self, size, key): + if key=='left': + if self.focus_column>0: + self.focus_column-=1 + self._invalidate() + return + if key=='right': + if self.focus_column<len(self.widget_list)-1: + self.focus_column+=1 + self._invalidate() + return + if self.focus_column<len(self.widget_list): + return self.widget_list[self.focus_column][1].keypress(size,key) + return key + + def set_focus(self, idx): + if idx>len(self.widget_list)-1: + idx = len(self.widget_list)-1 + self.focus_column = idx + + def rows(self,size,focus=False): + return 1 + + def __calculate_limits(self, size): + (maxcol,) = size + _prev = _next = False + start_wid = 0 + end_wid = len(self.widget_list)-1 + + total_wid = sum([w[0] for w in self.widget_list]) + while total_wid > maxcol: + if self.focus_column == end_wid: + if not _prev: + total_wid+=1 + _prev = True + total_wid-=self.widget_list[start_wid][0] + start_wid+=1 + else: + if not _next: + total_wid+=1 + _next = True + total_wid-=self.widget_list[end_wid][0] + end_wid-=1 + + cols_left = maxcol - total_wid + + return _prev,_next,start_wid,end_wid,cols_left + + + def mouse_event(self, size, event, button, x, y, focus): + (maxcol,)=size + + if urwid.is_mouse_press(event) and button == 1: + _prev,_next,start_wid,end_wid,cols_left = self.__calculate_limits(size) + if x==0 and _prev: + self.keypress(size,'left') + return True + if x==maxcol-1 and _next: + self.keypress(size,'right') + return True + + current_pos = 1 if _prev else 0 + idx = 0 + while current_pos<x and idx<len(self.widget_list): + width,widget = self.widget_list[idx] + if x<=current_pos+width: + self.focus_column = idx + self._invalidate() + if not hasattr(widget,'mouse_event'): + return False + return widget.mouse_event((width,0), event, button, + x-current_pos, 0, focus) + + current_pos+=self.widget_list[idx][0] + idx+=1 + + return False + + def render(self, size, focus=False): + if not self.widget_list: + return SolidCanvas(" ", size[0], 1) + + _prev,_next,start_wid,end_wid,cols_left = self.__calculate_limits(size) + + idx=start_wid + render = [] + + for width,widget in self.widget_list[start_wid:end_wid+1]: + _focus = idx == self.focus_column and focus + render.append((widget.render((width,),_focus),False,_focus,width)) + idx+=1 + if _prev: + render.insert(0,(urwid.Text([u"◀"]).render((1,),False),False,False,1)) + if _next: + render.append((urwid.Text([u"▶"],align='right').render((1+cols_left,),False),False,False,1+cols_left)) + else: + render.append((urwid.SolidCanvas(" "*cols_left, size[0], 1),False,False,cols_left)) + + return urwid.CanvasJoin(render) + + class FocusFrame(urwid.Frame): """Frame which manage 'tab' key""" @@ -713,9 +833,9 @@ def __init__(self): #self._current_tab = 0 - self._buttons_cont = urwid.GridFlow([],19,1,0,'left') + self._buttons_cont = ColumnsRoller() self.tabs = [] - self.__frame = urwid.Frame(urwid.Text(''),urwid.Pile([self._buttons_cont,urwid.Divider(u"─")])) + self.__frame = urwid.Frame(urwid.Filler(urwid.Text('')),urwid.Pile([self._buttons_cont,urwid.Divider(u"─")])) urwid.WidgetWrap.__init__(self, self.__frame) """def selectable(self): @@ -743,9 +863,9 @@ 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): + button = CustomButton(name, self.__buttonClicked, left_border = '', right_border=' | ') + self._buttons_cont.addWidget(button, button.getSize()) + if len(self._buttons_cont.widget_list) == 1: #first button: we set the focus and the body self._buttons_cont.set_focus(0) self.__buttonClicked(button,True)