Mercurial > libervia-backend
comparison frontends/primitivus/custom_widgets.py @ 192:879beacb8e16
Primitivus: major changes in SelectableText, menu can now be used with mouse, TabsContainer show wich tab is selected
- SelectableText is a WidgetWrap of urwid.Text, and manage attributes and complexe combination like urwid.Text (list of tuples (attribute,text))
- Menu now use a ColumnsRoller, and can't anymore be displayed on 2 rows, avoiding potential bug when display MenuBox
- Mouse can be used in menu. Right click on MenuBox make it disappear
- Tab container now display which tab is selected by putting a 'title' attribute on the corresponding button
/!\ as SelectableText is heavily used, there can be regressions
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 19 Aug 2010 21:11:22 +0800 |
parents | 33e618d385cf |
children | 92e4ddd580ae |
comparison
equal
deleted
inserted
replaced
191:1438a1337732 | 192:879beacb8e16 |
---|---|
19 along with this program. If not, see <http://www.gnu.org/licenses/>. | 19 along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 """ | 20 """ |
21 | 21 |
22 import urwid | 22 import urwid |
23 from urwid.escape import utf8decode | 23 from urwid.escape import utf8decode |
24 from logging import debug, info, warning, error | |
24 | 25 |
25 class Password(urwid.Edit): | 26 class Password(urwid.Edit): |
26 """Edit box which doesn't show what is entered (show '*' or other char instead)""" | 27 """Edit box which doesn't show what is entered (show '*' or other char instead)""" |
27 | 28 |
28 def __init__(self, *args, **kwargs): | 29 def __init__(self, *args, **kwargs): |
126 (maxcol,) = size | 127 (maxcol,) = size |
127 middle = (maxcol-len(self.text))/2 | 128 middle = (maxcol-len(self.text))/2 |
128 render_text = middle * self.car + self.text + (maxcol - len(self.text) - middle) * self.car | 129 render_text = middle * self.car + self.text + (maxcol - len(self.text) - middle) * self.car |
129 return urwid.Text(render_text) | 130 return urwid.Text(render_text) |
130 | 131 |
131 class SelectableText(urwid.FlowWidget): | 132 class SelectableText(urwid.WidgetWrap): |
132 """Text which can be selected with space""" | 133 """Text which can be selected with space""" |
133 signals = ['change'] | 134 signals = ['change'] |
134 | 135 |
135 def __init__(self, text, align='left', header='', select_attr=None, default_attr=None, selected = False, data=None): | 136 def __init__(self, text, align='left', header='', focus_attr='default_focus', selected_text=None, selected=False, data=None): |
136 self.text=unicode(text) | 137 """@param text: same as urwid.Text's text parameter |
137 self.header=header | 138 @param align: same as urwid.Text's align parameter |
138 if data: | 139 @select_attr: attrbute to use when selected |
139 self.data=data | 140 @param selected: is the text selected ?""" |
140 if select_attr: | 141 self.focus_attr = focus_attr |
141 self.selected = select_attr | 142 self.__selected = False |
142 if default_attr: | 143 self.__was_focused = False |
143 self.default = default_attr | 144 self.header = self.__valid_text(header) |
144 self.align = align | 145 self.default_txt = self.__valid_text(text) |
145 self.__selected=selected | 146 urwid.WidgetWrap.__init__(self, urwid.Text("",align=align)) |
147 self.setSelectedText(selected_text) | |
148 self.setState(selected) | |
149 | |
150 def __valid_text(self, text): | |
151 """Tmp method needed until dbus and urwid are more friends""" | |
152 if isinstance(text,basestring): | |
153 return unicode(text) | |
154 elif isinstance(text,tuple): | |
155 return (unicode(text[0]),text[1]) | |
156 elif isinstance(text,list): | |
157 for idx in range(len(text)): | |
158 elem = text[idx] | |
159 if isinstance(elem,basestring): | |
160 text[idx] = unicode(elem) | |
161 if isinstance(elem,tuple): | |
162 text[idx] = (unicode(elem[0]),elem[1]) | |
163 else: | |
164 warning (_('WARNING: unknown text type')) | |
165 return text | |
146 | 166 |
147 def getValue(self): | 167 def getValue(self): |
148 return self.text | 168 if isinstance(self.default_txt,basestring): |
169 return self.default_txt | |
170 list_attr = self.default_txt if isinstance(self.default_txt, list) else [self.default_txt] | |
171 txt = "" | |
172 for attr in list_attr: | |
173 if isinstance(attr,tuple): | |
174 txt+=attr[1] | |
175 else: | |
176 txt+=attr | |
177 return txt | |
149 | 178 |
150 def get_text(self): | 179 def get_text(self): |
151 """for compatibility with urwid.Text""" | 180 """for compatibility with urwid.Text""" |
152 return self.getValue() | 181 return self.getValue() |
153 | 182 |
154 def set_text(self, text): | 183 def set_text(self, text): |
155 self.text=unicode(text) | 184 """/!\ set_text doesn't change self.selected_txt !""" |
156 self._invalidate() | 185 self.default_txt = self.__valid_text(text) |
157 | 186 self.setState(self.__selected,invisible=True) |
158 def setAttribute(self, name, value): | 187 |
159 """Change attribut used for rendering widget | 188 def setSelectedText(self, text=None): |
160 @param name: one of | 189 """Text to display when selected |
161 -default: when not selected | 190 @text: text as in urwid.Text or None for default value""" |
162 -selected: when selected | 191 if text == None: |
163 @param value: name of the attribute | 192 text = ('selected',self.default_txt) |
164 /!\ the attribute name followed by _focus is used when widget has focus""" | 193 self.selected_txt = self.__valid_text(text) |
165 assert name in ['default', 'selected'] | 194 if self.__selected: |
166 self.__setattr__(name,value) | 195 self.setState(self.__selected) |
167 self._invalidate() | 196 |
197 | |
198 def __set_txt(self): | |
199 txt_list = [self.header] | |
200 txt = self.selected_txt if self.__selected else self.default_txt | |
201 if isinstance(txt,list): | |
202 txt_list.extend(txt) | |
203 else: | |
204 txt_list.append(txt) | |
205 self._w.base_widget.set_text(txt_list) | |
206 | |
168 | 207 |
169 def setState(self, selected, invisible=False): | 208 def setState(self, selected, invisible=False): |
170 """Change state | 209 """Change state |
171 @param selected: boolean state value | 210 @param selected: boolean state value |
172 @param invisible: don't emit change signal if True""" | 211 @param invisible: don't emit change signal if True""" |
173 assert(type(selected)==bool) | 212 assert(type(selected)==bool) |
174 self.__selected=selected | 213 self.__selected=selected |
214 self.__set_txt() | |
215 self.__was_focused = False | |
175 self._invalidate() | 216 self._invalidate() |
176 if not invisible: | 217 if not invisible: |
177 self._emit("change", self.__selected) | 218 self._emit("change", self.__selected) |
178 | 219 |
179 def getState(self): | 220 def getState(self): |
193 self.setState(not self.__selected) | 234 self.setState(not self.__selected) |
194 return True | 235 return True |
195 | 236 |
196 return False | 237 return False |
197 | 238 |
198 def rows(self,size,focus=False): | |
199 return self.display_widget(size, focus).rows(size, focus) | |
200 | |
201 def render(self, size, focus=False): | 239 def render(self, size, focus=False): |
202 return self.display_widget(size, focus).render(size, focus) | 240 attr_list = self._w.base_widget._attrib |
203 | 241 if not focus: |
204 def display_widget(self, size, focus): | 242 if self.__was_focused: |
205 try: | 243 self.__set_txt() |
206 select_attr = self.selected | 244 self.__was_focused = False |
207 except AttributeError: | 245 else: |
208 select_attr = 'selected' | 246 if not self.__was_focused: |
209 try: | 247 if not attr_list: |
210 default_attr = self.default | 248 attr_list.append((self.focus_attr,len(self._w.base_widget.text))) |
211 except AttributeError: | 249 else: |
212 default_attr = 'default' | 250 for idx in range(len(attr_list)): |
213 attr = select_attr if self.__selected else default_attr | 251 attr,attr_len = attr_list[idx] |
214 if focus: | 252 if attr == None: |
215 attr+="_focus" | 253 attr = self.focus_attr |
216 return urwid.Text((attr,self.header+self.text), align=self.align) | 254 attr_list[idx] = (attr,attr_len) |
255 else: | |
256 if not attr.endswith('_focus'): | |
257 attr+="_focus" | |
258 attr_list[idx] = (attr,attr_len) | |
259 self._w.base_widget._invalidate() | |
260 self.__was_focused = True #bloody ugly hack :) | |
261 return self._w.render(size, focus) | |
217 | 262 |
218 class ClickableText(SelectableText): | 263 class ClickableText(SelectableText): |
219 signals = SelectableText.signals + ['click'] | 264 signals = SelectableText.signals + ['click'] |
220 | 265 |
221 def setState(self, selected, invisible=False): | 266 def setState(self, selected, invisible=False): |
222 self._emit('click') | 267 super(ClickableText,self).setState(False,True) |
268 if not invisible: | |
269 self._emit('click') | |
223 | 270 |
224 class CustomButton(ClickableText): | 271 class CustomButton(ClickableText): |
225 | 272 |
226 def __init__(self, label, on_press=None, user_data=None, left_border = "[ ", right_border = " ]"): | 273 def __init__(self, label, on_press=None, user_data=None, left_border = "[ ", right_border = " ]"): |
227 self.label = label | 274 self.label = label |
228 render_txt = "%s%s%s" % (left_border, label, right_border) | 275 self.left_border = left_border |
229 self.size = len(render_txt) | 276 self.right_border = right_border |
230 super(CustomButton, self).__init__(render_txt) | 277 super(CustomButton, self).__init__([left_border, label, right_border]) |
278 self.size = len(self.get_text()) | |
231 if on_press: | 279 if on_press: |
232 urwid.connect_signal(self, 'click', on_press, user_data) | 280 urwid.connect_signal(self, 'click', on_press, user_data) |
233 | 281 |
234 def getSize(self): | 282 def getSize(self): |
235 """Return representation size of the button""" | 283 """Return representation size of the button""" |
236 return self.size | 284 return self.size |
237 | 285 |
238 def get_label(self): | 286 def get_label(self): |
239 return self.label | 287 return self.label[1] if isinstance(self.label,tuple) else self.label |
288 | |
289 def set_label(self, label): | |
290 self.label = label | |
291 self.set_text([self.left_border, label, self.right_border]) | |
240 | 292 |
241 class GenericList(urwid.WidgetWrap): | 293 class GenericList(urwid.WidgetWrap): |
242 signals = ['click','change'] | 294 signals = ['click','change'] |
243 | 295 |
244 def __init__(self, options, style=[], align='left', option_type = SelectableText, on_click=None, on_change=None, user_data=None): | 296 def __init__(self, options, style=[], align='left', option_type = SelectableText, on_click=None, on_change=None, user_data=None): |
402 """Bar used to show misc information to user""" | 454 """Bar used to show misc information to user""" |
403 signals = ['change'] | 455 signals = ['change'] |
404 | 456 |
405 def __init__(self): | 457 def __init__(self): |
406 self.waitNotifs = urwid.Text('') | 458 self.waitNotifs = urwid.Text('') |
407 self.message = ClickableText('', default_attr='notifs') | 459 self.message = ClickableText('') |
408 urwid.connect_signal(self.message, 'click', lambda wid: self.showNext()) | 460 urwid.connect_signal(self.message, 'click', lambda wid: self.showNext()) |
409 self.progress = ClickableText('', default_attr='notifs') | 461 self.progress = ClickableText('') |
410 self.columns = urwid.Columns([('fixed',6,self.waitNotifs),self.message,('fixed',4,self.progress)]) | 462 self.columns = urwid.Columns([('fixed',6,self.waitNotifs),self.message,('fixed',4,self.progress)]) |
411 urwid.WidgetWrap.__init__(self, urwid.AttrMap(self.columns,'notifs')) | 463 urwid.WidgetWrap.__init__(self, urwid.AttrMap(self.columns,'notifs')) |
412 self.notifs = [] | 464 self.notifs = [] |
413 | 465 |
414 def __modQueue(self): | 466 def __modQueue(self): |
415 """must be called each time the notifications queue is changed""" | 467 """must be called each time the notifications queue is changed""" |
416 self.waitNotifs.set_text("(%i)" % len(self.notifs) if self.notifs else '') | 468 self.waitNotifs.set_text(('notifs',"(%i)" % len(self.notifs) if self.notifs else '')) |
417 self._emit('change') | 469 self._emit('change') |
418 | 470 |
419 def setProgress(self,percentage): | 471 def setProgress(self,percentage): |
420 """Define the progression to show on the right side of the bar""" | 472 """Define the progression to show on the right side of the bar""" |
421 if percentage == None: | 473 if percentage == None: |
422 self.progress.set_text('') | 474 self.progress.set_text('') |
423 else: | 475 else: |
424 self.progress.set_text('%02i%%' % percentage) | 476 self.progress.set_text(('notifs','%02i%%' % percentage)) |
425 self._emit('change') | 477 self._emit('change') |
426 | 478 |
427 def addPopUp(self, pop_up_widget): | 479 def addPopUp(self, pop_up_widget): |
428 """Add a popup to the waiting queue""" | 480 """Add a popup to the waiting queue""" |
429 self.notifs.append(('popup',pop_up_widget)) | 481 self.notifs.append(('popup',pop_up_widget)) |
430 self.__modQueue() | 482 self.__modQueue() |
431 | 483 |
432 def addMessage(self, message): | 484 def addMessage(self, message): |
433 "Add a message to the notificatio bar" | 485 "Add a message to the notificatio bar" |
434 if not self.message.get_text(): | 486 if not self.message.get_text(): |
435 self.message.set_text(message) | 487 self.message.set_text(('notifs',message)) |
436 self._invalidate() | 488 self._invalidate() |
437 self._emit('change') | 489 self._emit('change') |
438 else: | 490 else: |
439 self.notifs.append(('message',message)) | 491 self.notifs.append(('message',message)) |
440 self.__modQueue() | 492 self.__modQueue() |
446 if notif[0] == "message": | 498 if notif[0] == "message": |
447 found = notif | 499 found = notif |
448 break | 500 break |
449 if found: | 501 if found: |
450 self.notifs.remove(found) | 502 self.notifs.remove(found) |
451 self.message.set_text(found[1]) | 503 self.message.set_text(('notifs',found[1])) |
452 self.__modQueue() | 504 self.__modQueue() |
453 else: | 505 else: |
454 self.message.set_text('') | 506 self.message.set_text('') |
455 self._emit('change') | 507 self._emit('change') |
456 | 508 |
480 signals = ['click'] | 532 signals = ['click'] |
481 | 533 |
482 def __init__(self,parent,items): | 534 def __init__(self,parent,items): |
483 self.parent = parent | 535 self.parent = parent |
484 self.selected = None | 536 self.selected = None |
485 content = urwid.SimpleListWalker([ClickableText(text,default_attr='menuitem') for text in items]) | 537 content = urwid.SimpleListWalker([ClickableText(('menuitem',text)) for text in items]) |
486 for wid in content: | 538 for wid in content: |
487 urwid.connect_signal(wid, 'click', self.onClick) | 539 urwid.connect_signal(wid, 'click', self.onClick) |
488 | 540 |
489 self.listBox = urwid.ListBox(content) | 541 self.listBox = urwid.ListBox(content) |
490 menubox = urwid.LineBox(urwid.BoxAdapter(self.listBox,len(items))) | 542 menubox = urwid.LineBox(urwid.BoxAdapter(self.listBox,len(items))) |
499 self.parent.keypress(size, key) | 551 self.parent.keypress(size, key) |
500 elif key=='left' or key=='right': | 552 elif key=='left' or key=='right': |
501 self.parent.keypress(size,'up') | 553 self.parent.keypress(size,'up') |
502 self.parent.keypress(size,key) | 554 self.parent.keypress(size,key) |
503 return super(MenuBox,self).keypress(size,key) | 555 return super(MenuBox,self).keypress(size,key) |
556 | |
557 def mouse_event(self, size, event, button, x, y, focus): | |
558 if button == 3: | |
559 self.parent.keypress(size,'up') | |
560 return True | |
561 return super(MenuBox,self).mouse_event(size, event, button, x, y, focus) | |
504 | 562 |
505 def onClick(self, wid): | 563 def onClick(self, wid): |
506 self.selected = wid.getValue() | 564 self.selected = wid.getValue() |
507 self._emit('click') | 565 self._emit('click') |
508 | 566 |
509 class Menu(urwid.FlowWidget): | 567 class Menu(urwid.WidgetWrap): |
510 | 568 |
511 def __init__(self,loop, x_orig=0): | 569 def __init__(self,loop, x_orig=0): |
512 """Menu widget | 570 """Menu widget |
513 @param loop: main loop of urwid | 571 @param loop: main loop of urwid |
514 @param x_orig: absolute start of the abscissa | 572 @param x_orig: absolute start of the abscissa |
515 """ | 573 """ |
516 super(Menu, self).__init__() | |
517 self.loop = loop | 574 self.loop = loop |
518 self.menu_keys = [] | 575 self.menu_keys = [] |
519 self.menu = {} | 576 self.menu = {} |
520 self.x_orig = x_orig | 577 self.x_orig = x_orig |
521 self.shortcuts = {} #keyboard shortcuts | 578 self.shortcuts = {} #keyboard shortcuts |
522 self.focus_menu = 0 | |
523 self.save_bottom = None | 579 self.save_bottom = None |
524 | 580 col_rol = ColumnsRoller() |
581 urwid.WidgetWrap.__init__(self, urwid.AttrMap(col_rol,'menubar')) | |
582 | |
525 def selectable(self): | 583 def selectable(self): |
526 return True | 584 return True |
527 | 585 |
528 def getMenuSize(self): | 586 def getMenuSize(self): |
529 """return the current number of categories in this menu""" | 587 """return the current number of categories in this menu""" |
541 if len(item[0]) > max_len: | 599 if len(item[0]) > max_len: |
542 max_len = len(item[0]) | 600 max_len = len(item[0]) |
543 | 601 |
544 self.save_bottom = self.loop.widget | 602 self.save_bottom = self.loop.widget |
545 menu_box = MenuBox(self,[item[0] for item in self.menu[menu_key]]) | 603 menu_box = MenuBox(self,[item[0] for item in self.menu[menu_key]]) |
546 urwid.connect_signal(menu_box, 'click', self.onClick) | 604 urwid.connect_signal(menu_box, 'click', self.onItemClick) |
547 | 605 |
548 self.loop.widget = urwid.Overlay(urwid.AttrMap(menu_box,'menubar'),self.save_bottom,('fixed left', columns),max_len+2,('fixed top',1),None) | 606 self.loop.widget = urwid.Overlay(urwid.AttrMap(menu_box,'menubar'),self.save_bottom,('fixed left', columns),max_len+2,('fixed top',1),None) |
549 | 607 |
550 def keypress(self, size, key): | 608 def keypress(self, size, key): |
551 if key == 'right' and self.focus_menu < len(self.menu)-1: | 609 if key == 'down': |
552 self.focus_menu += 1 | 610 key = 'enter' |
553 self._invalidate() | |
554 elif key == 'left' and self.focus_menu > 0: | |
555 self.focus_menu -= 1 | |
556 self._invalidate() | |
557 return | |
558 elif key == 'down': | |
559 if self.menu_keys and not self.save_bottom: | |
560 column = sum([len(menu)+4 for menu in self.menu_keys[0:self.focus_menu]],self.focus_menu+self.x_orig) | |
561 self.__buildOverlay(self.menu_keys[self.focus_menu],column) | |
562 elif key == 'up': | 611 elif key == 'up': |
563 if self.save_bottom: | 612 if self.save_bottom: |
564 self.loop.widget = self.save_bottom | 613 self.loop.widget = self.save_bottom |
565 self.save_bottom = None | 614 self.save_bottom = None |
566 | 615 |
567 return key | 616 return self._w.base_widget.keypress(size, key) |
568 | 617 |
569 def checkShortcuts(self, key): | 618 def checkShortcuts(self, key): |
570 for shortcut in self.shortcuts.keys(): | 619 for shortcut in self.shortcuts.keys(): |
571 if key == shortcut: | 620 if key == shortcut: |
572 category, item, callback = self.shortcuts[shortcut] | 621 category, item, callback = self.shortcuts[shortcut] |
573 callback((category, item)) | 622 callback((category, item)) |
579 @param item: menu item (e.g. new/close/about) | 628 @param item: menu item (e.g. new/close/about) |
580 @callback: method to call when item is selected""" | 629 @callback: method to call when item is selected""" |
581 if not category in self.menu.keys(): | 630 if not category in self.menu.keys(): |
582 self.menu_keys.append(category) | 631 self.menu_keys.append(category) |
583 self.menu[category] = [] | 632 self.menu[category] = [] |
633 button = CustomButton(('menubar',category), self.onCategoryClick, | |
634 left_border = ('menubar',"[ "), | |
635 right_border = ('menubar'," ]")) | |
636 self._w.base_widget.addWidget(button,button.getSize()) | |
584 self.menu[category].append((item, callback)) | 637 self.menu[category].append((item, callback)) |
585 if shortcut: | 638 if shortcut: |
586 assert(shortcut not in self.shortcuts.keys()) | 639 assert(shortcut not in self.shortcuts.keys()) |
587 self.shortcuts[shortcut] = (category, item, callback) | 640 self.shortcuts[shortcut] = (category, item, callback) |
588 | 641 |
589 def rows(self,size,focus=False): | 642 def onItemClick(self, widget): |
590 return self.display_widget(size, focus).rows(size, focus) | 643 category = self._w.base_widget.getSelected().get_label() |
591 | |
592 def render(self, size, focus=False): | |
593 return self.display_widget(size, focus).render(size, focus) | |
594 | |
595 def display_widget(self, size, focus): | |
596 render_txt = [] | |
597 idx = 0 | |
598 for menu in self.menu_keys: | |
599 if focus and idx == self.focus_menu: | |
600 render_txt.append(('selected_menu', '[ %s ]' % menu)) | |
601 render_txt.append(' ') | |
602 else: | |
603 render_txt.append('[ %s ] ' % menu) | |
604 idx += 1 | |
605 return urwid.AttrMap(urwid.Text(render_txt), 'menubar') | |
606 | |
607 def onClick(self, widget): | |
608 category = self.menu_keys[self.focus_menu] | |
609 item = widget.getValue() | 644 item = widget.getValue() |
645 callback = None | |
610 for menu_item in self.menu[category]: | 646 for menu_item in self.menu[category]: |
611 if item == menu_item[0]: | 647 if item == menu_item[0]: |
612 callback = menu_item[1] | 648 callback = menu_item[1] |
613 break | 649 break |
614 if callback: | 650 if callback: |
615 self.keypress(None,'up') | 651 self.keypress(None,'up') |
616 callback((category, item)) | 652 callback((category, item)) |
653 | |
654 def onCategoryClick(self, button): | |
655 self.__buildOverlay(button.get_label(), | |
656 self.x_orig + self._w.base_widget.getStartCol(button)) | |
657 | |
617 | 658 |
618 class MenuRoller(urwid.WidgetWrap): | 659 class MenuRoller(urwid.WidgetWrap): |
619 | 660 |
620 def __init__(self,menus_list): | 661 def __init__(self,menus_list): |
621 """Create a MenuRoller | 662 """Create a MenuRoller |
749 def addWidget(self, widget, width): | 790 def addWidget(self, widget, width): |
750 self.widget_list.append((width,widget)) | 791 self.widget_list.append((width,widget)) |
751 if len(self.widget_list) == 1: | 792 if len(self.widget_list) == 1: |
752 self.set_focus(0) | 793 self.set_focus(0) |
753 | 794 |
795 def getStartCol(self, widget): | |
796 """Return the column of the left corner of the widget""" | |
797 start_col = 0 | |
798 for wid in self.widget_list[self.__start:]: | |
799 if wid[1] == widget: | |
800 return start_col | |
801 start_col+=wid[0] | |
802 return None | |
803 | |
754 def selectable(self): | 804 def selectable(self): |
755 try: | 805 try: |
756 return self.widget_list[self.focus_column][1].selectable() | 806 return self.widget_list[self.focus_column][1].selectable() |
757 except IndexError: | 807 except IndexError: |
758 return False | 808 return False |
770 return | 820 return |
771 if self.focus_column<len(self.widget_list): | 821 if self.focus_column<len(self.widget_list): |
772 return self.widget_list[self.focus_column][1].keypress(size,key) | 822 return self.widget_list[self.focus_column][1].keypress(size,key) |
773 return key | 823 return key |
774 | 824 |
825 def getSelected(self): | |
826 """Return selected widget""" | |
827 return self.widget_list[self.focus_column][1] | |
828 | |
775 def set_focus(self, idx): | 829 def set_focus(self, idx): |
776 if idx>len(self.widget_list)-1: | 830 if idx>len(self.widget_list)-1: |
777 idx = len(self.widget_list)-1 | 831 idx = len(self.widget_list)-1 |
778 self.focus_column = idx | 832 self.focus_column = idx |
779 | 833 |
800 _next = True | 854 _next = True |
801 total_wid-=self.widget_list[end_wid][0] | 855 total_wid-=self.widget_list[end_wid][0] |
802 end_wid-=1 | 856 end_wid-=1 |
803 | 857 |
804 cols_left = maxcol - total_wid | 858 cols_left = maxcol - total_wid |
805 | 859 self.__start = start_wid #we need to keep it for getStartCol |
806 return _prev,_next,start_wid,end_wid,cols_left | 860 return _prev,_next,start_wid,end_wid,cols_left |
807 | 861 |
808 | 862 |
809 def mouse_event(self, size, event, button, x, y, focus): | 863 def mouse_event(self, size, event, button, x, y, focus): |
810 (maxcol,)=size | 864 (maxcol,)=size |
880 | 934 |
881 class TabsContainer(urwid.WidgetWrap): | 935 class TabsContainer(urwid.WidgetWrap): |
882 signals = ['click'] | 936 signals = ['click'] |
883 | 937 |
884 def __init__(self): | 938 def __init__(self): |
885 #self._current_tab = 0 | 939 self._current_tab = None |
886 self._buttons_cont = ColumnsRoller() | 940 self._buttons_cont = ColumnsRoller() |
887 self.tabs = [] | 941 self.tabs = [] |
888 self.__frame = FocusFrame(urwid.Filler(urwid.Text('')),urwid.Pile([self._buttons_cont,urwid.Divider(u"─")])) | 942 self.__frame = FocusFrame(urwid.Filler(urwid.Text('')),urwid.Pile([self._buttons_cont,urwid.Divider(u"─")])) |
889 urwid.WidgetWrap.__init__(self, self.__frame) | 943 urwid.WidgetWrap.__init__(self, self.__frame) |
890 | 944 |
905 break | 959 break |
906 if tab[0] != tab_name: | 960 if tab[0] != tab_name: |
907 error(_("INTERNAL ERROR: Tab not found")) | 961 error(_("INTERNAL ERROR: Tab not found")) |
908 assert(False) | 962 assert(False) |
909 self.__frame.body = tab[1] | 963 self.__frame.body = tab[1] |
964 button.set_label(('title',button.get_label())) | |
965 if self._current_tab: | |
966 self._current_tab.set_label(self._current_tab.get_label()) | |
967 self._current_tab = button | |
910 if not invisible: | 968 if not invisible: |
911 self._emit('click') | 969 self._emit('click') |
912 | 970 |
913 def __appendButton(self, name): | 971 def __appendButton(self, name): |
914 """Append a button to the frame header, | 972 """Append a button to the frame header, |