comparison 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
comparison
equal deleted inserted replaced
17:222aa33716ad 18:bdc83e857093
690 def __init__(self, title, message, style=['OK'], **kwargs): 690 def __init__(self, title, message, style=['OK'], **kwargs):
691 GenericDialog.__init__(self, [urwid.Text(message, 'center')], title, style, ok_value=None, **kwargs) 691 GenericDialog.__init__(self, [urwid.Text(message, 'center')], title, style, ok_value=None, **kwargs)
692 692
693 ## CONTAINERS ## 693 ## CONTAINERS ##
694 694
695 class ColumnsRoller(urwid.FlowWidget):
696
697 def __init__(self, widget_list = None, focus_column=0):
698 self.widget_list = widget_list or []
699 self.focus_column = focus_column
700 self.__start = 0
701 self.__next = False
702
703 def addWidget(self, widget, width):
704 self.widget_list.append((width,widget))
705 if len(self.widget_list) == 1:
706 self.set_focus(0)
707
708 def selectable(self):
709 try:
710 return self.widget_list[self.focus_column][1].selectable()
711 except IndexError:
712 return False
713
714 def keypress(self, size, key):
715 if key=='left':
716 if self.focus_column>0:
717 self.focus_column-=1
718 self._invalidate()
719 return
720 if key=='right':
721 if self.focus_column<len(self.widget_list)-1:
722 self.focus_column+=1
723 self._invalidate()
724 return
725 if self.focus_column<len(self.widget_list):
726 return self.widget_list[self.focus_column][1].keypress(size,key)
727 return key
728
729 def set_focus(self, idx):
730 if idx>len(self.widget_list)-1:
731 idx = len(self.widget_list)-1
732 self.focus_column = idx
733
734 def rows(self,size,focus=False):
735 return 1
736
737 def __calculate_limits(self, size):
738 (maxcol,) = size
739 _prev = _next = False
740 start_wid = 0
741 end_wid = len(self.widget_list)-1
742
743 total_wid = sum([w[0] for w in self.widget_list])
744 while total_wid > maxcol:
745 if self.focus_column == end_wid:
746 if not _prev:
747 total_wid+=1
748 _prev = True
749 total_wid-=self.widget_list[start_wid][0]
750 start_wid+=1
751 else:
752 if not _next:
753 total_wid+=1
754 _next = True
755 total_wid-=self.widget_list[end_wid][0]
756 end_wid-=1
757
758 cols_left = maxcol - total_wid
759
760 return _prev,_next,start_wid,end_wid,cols_left
761
762
763 def mouse_event(self, size, event, button, x, y, focus):
764 (maxcol,)=size
765
766 if urwid.is_mouse_press(event) and button == 1:
767 _prev,_next,start_wid,end_wid,cols_left = self.__calculate_limits(size)
768 if x==0 and _prev:
769 self.keypress(size,'left')
770 return True
771 if x==maxcol-1 and _next:
772 self.keypress(size,'right')
773 return True
774
775 current_pos = 1 if _prev else 0
776 idx = 0
777 while current_pos<x and idx<len(self.widget_list):
778 width,widget = self.widget_list[idx]
779 if x<=current_pos+width:
780 self.focus_column = idx
781 self._invalidate()
782 if not hasattr(widget,'mouse_event'):
783 return False
784 return widget.mouse_event((width,0), event, button,
785 x-current_pos, 0, focus)
786
787 current_pos+=self.widget_list[idx][0]
788 idx+=1
789
790 return False
791
792 def render(self, size, focus=False):
793 if not self.widget_list:
794 return SolidCanvas(" ", size[0], 1)
795
796 _prev,_next,start_wid,end_wid,cols_left = self.__calculate_limits(size)
797
798 idx=start_wid
799 render = []
800
801 for width,widget in self.widget_list[start_wid:end_wid+1]:
802 _focus = idx == self.focus_column and focus
803 render.append((widget.render((width,),_focus),False,_focus,width))
804 idx+=1
805 if _prev:
806 render.insert(0,(urwid.Text([u"◀"]).render((1,),False),False,False,1))
807 if _next:
808 render.append((urwid.Text([u"▶"],align='right').render((1+cols_left,),False),False,False,1+cols_left))
809 else:
810 render.append((urwid.SolidCanvas(" "*cols_left, size[0], 1),False,False,cols_left))
811
812 return urwid.CanvasJoin(render)
813
814
695 class FocusFrame(urwid.Frame): 815 class FocusFrame(urwid.Frame):
696 """Frame which manage 'tab' key""" 816 """Frame which manage 'tab' key"""
697 817
698 def keypress(self, size, key): 818 def keypress(self, size, key):
699 if key == 'tab': 819 if key == 'tab':
711 class TabsContainer(urwid.WidgetWrap): 831 class TabsContainer(urwid.WidgetWrap):
712 signals = ['click'] 832 signals = ['click']
713 833
714 def __init__(self): 834 def __init__(self):
715 #self._current_tab = 0 835 #self._current_tab = 0
716 self._buttons_cont = urwid.GridFlow([],19,1,0,'left') 836 self._buttons_cont = ColumnsRoller()
717 self.tabs = [] 837 self.tabs = []
718 self.__frame = urwid.Frame(urwid.Text(''),urwid.Pile([self._buttons_cont,urwid.Divider(u"─")])) 838 self.__frame = urwid.Frame(urwid.Filler(urwid.Text('')),urwid.Pile([self._buttons_cont,urwid.Divider(u"─")]))
719 urwid.WidgetWrap.__init__(self, self.__frame) 839 urwid.WidgetWrap.__init__(self, self.__frame)
720 840
721 """def selectable(self): 841 """def selectable(self):
722 return True 842 return True
723 843
741 self._emit('click') 861 self._emit('click')
742 862
743 def __appendButton(self, name): 863 def __appendButton(self, name):
744 """Append a button to the frame header, 864 """Append a button to the frame header,
745 and link it to the page change method""" 865 and link it to the page change method"""
746 button = CustomButton(name, self.__buttonClicked, left_border = '', right_border=' |') 866 button = CustomButton(name, self.__buttonClicked, left_border = '', right_border=' | ')
747 self._buttons_cont.cells.append(button) 867 self._buttons_cont.addWidget(button, button.getSize())
748 if len(self._buttons_cont.cells): 868 if len(self._buttons_cont.widget_list) == 1:
749 #first button: we set the focus and the body 869 #first button: we set the focus and the body
750 self._buttons_cont.set_focus(0) 870 self._buttons_cont.set_focus(0)
751 self.__buttonClicked(button,True) 871 self.__buttonClicked(button,True)
752 872
753 def addTab(self,name,content=[]): 873 def addTab(self,name,content=[]):