Primitivus: new widget ColumnsRoller which show FlowWidgets on the same row, and can roll between them if there is not enough space
This commit is contained in:
parent
d2644f1258
commit
7e80cd7658
1 changed files with 125 additions and 5 deletions
|
|
@ -692,6 +692,126 @@ class Alert(GenericDialog):
|
|||
|
||||
## 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 @@ class TabsContainer(urwid.WidgetWrap):
|
|||
|
||||
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 @@ class TabsContainer(urwid.WidgetWrap):
|
|||
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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue