Mercurial > urwid-satext
comparison urwid_satext/sat_widgets.py @ 66:287ff3e1edd1
removed trailing spaces
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 21 Dec 2013 16:51:14 +0100 |
parents | 090f3e0754d3 |
children | c270867a80f9 |
comparison
equal
deleted
inserted
replaced
65:090f3e0754d3 | 66:287ff3e1edd1 |
---|---|
39 """Define method called when completion is asked | 39 """Define method called when completion is asked |
40 @callback: method with 2 arguments: | 40 @callback: method with 2 arguments: |
41 - the text to complete | 41 - the text to complete |
42 - if there was already a completion, a dict with | 42 - if there was already a completion, a dict with |
43 - 'completed':last completion | 43 - 'completed':last completion |
44 - 'completion_pos': cursor position where the completion starts | 44 - 'completion_pos': cursor position where the completion starts |
45 - 'position': last completion cursor position | 45 - 'position': last completion cursor position |
46 this dict must be used (and can be filled) to find next completion) | 46 this dict must be used (and can be filled) to find next completion) |
47 and which return the full text completed""" | 47 and which return the full text completed""" |
48 self.completion_cb = callback | 48 self.completion_cb = callback |
49 self.completion_data = {} | 49 self.completion_data = {} |
55 elif key == 'ctrl e': | 55 elif key == 'ctrl e': |
56 key = 'end' | 56 key = 'end' |
57 elif key == 'ctrl k': | 57 elif key == 'ctrl k': |
58 self._delete_highlighted() | 58 self._delete_highlighted() |
59 self.set_edit_text(self.edit_text[:self.edit_pos]) | 59 self.set_edit_text(self.edit_text[:self.edit_pos]) |
60 elif key == 'ctrl w': | 60 elif key == 'ctrl w': |
61 before = self.edit_text[:self.edit_pos] | 61 before = self.edit_text[:self.edit_pos] |
62 pos = before.rstrip().rfind(" ")+1 | 62 pos = before.rstrip().rfind(" ")+1 |
63 self.set_edit_text(before[:pos] + self.edit_text[self.edit_pos:]) | 63 self.set_edit_text(before[:pos] + self.edit_text[self.edit_pos:]) |
64 self.set_edit_pos(pos) | 64 self.set_edit_pos(pos) |
65 elif key == 'enter': | 65 elif key == 'enter': |
81 self.completion_data['position'] = self.edit_pos | 81 self.completion_data['position'] = self.edit_pos |
82 return | 82 return |
83 except AttributeError: | 83 except AttributeError: |
84 #No completion method defined | 84 #No completion method defined |
85 pass | 85 pass |
86 return super(AdvancedEdit, self).keypress(size, key) | 86 return super(AdvancedEdit, self).keypress(size, key) |
87 | 87 |
88 class Password(AdvancedEdit): | 88 class Password(AdvancedEdit): |
89 """Edit box which doesn't show what is entered (show '*' or other char instead)""" | 89 """Edit box which doesn't show what is entered (show '*' or other char instead)""" |
90 | 90 |
91 def __init__(self, *args, **kwargs): | 91 def __init__(self, *args, **kwargs): |
108 self._edit_text = self.__real_text | 108 self._edit_text = self.__real_text |
109 super(Password,self).insert_text(text) | 109 super(Password,self).insert_text(text) |
110 | 110 |
111 def render(self, size, focus=False): | 111 def render(self, size, focus=False): |
112 return super(Password, self).render(size, focus) | 112 return super(Password, self).render(size, focus) |
113 | 113 |
114 class ModalEdit(AdvancedEdit): | 114 class ModalEdit(AdvancedEdit): |
115 """AdvancedEdit with vi-like mode management | 115 """AdvancedEdit with vi-like mode management |
116 - there is a new 'mode' property wich can be changed with properties | 116 - there is a new 'mode' property wich can be changed with properties |
117 specified during init | 117 specified during init |
118 - completion callback received a new 'mode' argument | 118 - completion callback received a new 'mode' argument |
138 mode_key = None | 138 mode_key = None |
139 for key in self._modes: | 139 for key in self._modes: |
140 if self._modes[key][0] == value: | 140 if self._modes[key][0] == value: |
141 mode_key = key | 141 mode_key = key |
142 break | 142 break |
143 | 143 |
144 mode, caption = self._modes[mode_key] | 144 mode, caption = self._modes[mode_key] |
145 self._mode = mode | 145 self._mode = mode |
146 self.set_caption(caption) | 146 self.set_caption(caption) |
147 if not mode_key: #we are in NORMAL mode | 147 if not mode_key: #we are in NORMAL mode |
148 self.set_edit_text('') | 148 self.set_edit_text('') |
156 self.mode = "NORMAL" | 156 self.mode = "NORMAL" |
157 return | 157 return |
158 if self._mode == 'NORMAL' and key in self._modes: | 158 if self._mode == 'NORMAL' and key in self._modes: |
159 self.mode = self._modes[key][0] | 159 self.mode = self._modes[key][0] |
160 return | 160 return |
161 return super(ModalEdit, self).keypress(size, key) | 161 return super(ModalEdit, self).keypress(size, key) |
162 | 162 |
163 class SurroundedText(urwid.FlowWidget): | 163 class SurroundedText(urwid.FlowWidget): |
164 """Text centered on a repeated character (like a Divider, but with a text in the center)""" | 164 """Text centered on a repeated character (like a Divider, but with a text in the center)""" |
165 | 165 |
166 def __init__(self,text,car=utf8decode('─')): | 166 def __init__(self,text,car=utf8decode('─')): |
180 return urwid.Text(render_text) | 180 return urwid.Text(render_text) |
181 | 181 |
182 class SelectableText(urwid.WidgetWrap): | 182 class SelectableText(urwid.WidgetWrap): |
183 """Text which can be selected with space""" | 183 """Text which can be selected with space""" |
184 signals = ['change'] | 184 signals = ['change'] |
185 | 185 |
186 def __init__(self, text, align='left', header='', focus_attr='default_focus', selected_text=None, selected=False, data=None): | 186 def __init__(self, text, align='left', header='', focus_attr='default_focus', selected_text=None, selected=False, data=None): |
187 """@param text: same as urwid.Text's text parameter | 187 """@param text: same as urwid.Text's text parameter |
188 @param align: same as urwid.Text's align parameter | 188 @param align: same as urwid.Text's align parameter |
189 @select_attr: attrbute to use when selected | 189 @select_attr: attrbute to use when selected |
190 @param selected: is the text selected ?""" | 190 @param selected: is the text selected ?""" |
252 txt_list.extend(txt) | 252 txt_list.extend(txt) |
253 else: | 253 else: |
254 txt_list.append(txt) | 254 txt_list.append(txt) |
255 self._w.base_widget.set_text(txt_list) | 255 self._w.base_widget.set_text(txt_list) |
256 | 256 |
257 | 257 |
258 def setState(self, selected, invisible=False): | 258 def setState(self, selected, invisible=False): |
259 """Change state | 259 """Change state |
260 @param selected: boolean state value | 260 @param selected: boolean state value |
261 @param invisible: don't emit change signal if True""" | 261 @param invisible: don't emit change signal if True""" |
262 assert(type(selected)==bool) | 262 assert(type(selected)==bool) |
264 self.__set_txt() | 264 self.__set_txt() |
265 self.__was_focused = False | 265 self.__was_focused = False |
266 self._invalidate() | 266 self._invalidate() |
267 if not invisible: | 267 if not invisible: |
268 self._emit("change", self.__selected) | 268 self._emit("change", self.__selected) |
269 | 269 |
270 def getState(self): | 270 def getState(self): |
271 return self.__selected | 271 return self.__selected |
272 | 272 |
273 def selectable(self): | 273 def selectable(self): |
274 return True | 274 return True |
281 | 281 |
282 def mouse_event(self, size, event, button, x, y, focus): | 282 def mouse_event(self, size, event, button, x, y, focus): |
283 if is_mouse_press(event) and button == 1: | 283 if is_mouse_press(event) and button == 1: |
284 self.setState(not self.__selected) | 284 self.setState(not self.__selected) |
285 return True | 285 return True |
286 | 286 |
287 return False | 287 return False |
288 | 288 |
289 def render(self, size, focus=False): | 289 def render(self, size, focus=False): |
290 attr_list = self._w.base_widget._attrib | 290 attr_list = self._w.base_widget._attrib |
291 if not focus: | 291 if not focus: |
292 if self.__was_focused: | 292 if self.__was_focused: |
293 self.__set_txt() | 293 self.__set_txt() |
310 self.__was_focused = True #bloody ugly hack :) | 310 self.__was_focused = True #bloody ugly hack :) |
311 return self._w.render(size, focus) | 311 return self._w.render(size, focus) |
312 | 312 |
313 class ClickableText(SelectableText): | 313 class ClickableText(SelectableText): |
314 signals = SelectableText.signals + ['click'] | 314 signals = SelectableText.signals + ['click'] |
315 | 315 |
316 def setState(self, selected, invisible=False): | 316 def setState(self, selected, invisible=False): |
317 super(ClickableText,self).setState(False,True) | 317 super(ClickableText,self).setState(False,True) |
318 if not invisible: | 318 if not invisible: |
319 self._emit('click') | 319 self._emit('click') |
320 | 320 |
322 | 322 |
323 def __init__(self, label, on_press=None, user_data=None, left_border = "[ ", right_border = " ]"): | 323 def __init__(self, label, on_press=None, user_data=None, left_border = "[ ", right_border = " ]"): |
324 self.label = label | 324 self.label = label |
325 self.left_border = left_border | 325 self.left_border = left_border |
326 self.right_border = right_border | 326 self.right_border = right_border |
327 super(CustomButton, self).__init__([left_border, label, right_border]) | 327 super(CustomButton, self).__init__([left_border, label, right_border]) |
328 self.size = len(self.get_text()) | 328 self.size = len(self.get_text()) |
329 if on_press: | 329 if on_press: |
330 urwid.connect_signal(self, 'click', on_press, user_data) | 330 urwid.connect_signal(self, 'click', on_press, user_data) |
331 | 331 |
332 def getSize(self): | 332 def getSize(self): |
347 """ | 347 """ |
348 Widget managing list of string and their selection | 348 Widget managing list of string and their selection |
349 @param options: list of strings used for options | 349 @param options: list of strings used for options |
350 @param style: list of string: | 350 @param style: list of string: |
351 - 'single' if only one must be selected | 351 - 'single' if only one must be selected |
352 - 'no_first_select' nothing selected when list is first displayed | 352 - 'no_first_select' nothing selected when list is first displayed |
353 - 'can_select_none' if we can select nothing | 353 - 'can_select_none' if we can select nothing |
354 @param align: alignement of text inside the list | 354 @param align: alignement of text inside the list |
355 @param on_click: method called when click signal is emited | 355 @param on_click: method called when click signal is emited |
356 @param user_data: data sent to the callback for click signal | 356 @param user_data: data sent to the callback for click signal |
357 """ | 357 """ |
359 self.no_first_select = 'no_first_select' in style | 359 self.no_first_select = 'no_first_select' in style |
360 self.can_select_none = 'can_select_none' in style | 360 self.can_select_none = 'can_select_none' in style |
361 self.align = align | 361 self.align = align |
362 self.option_type = option_type | 362 self.option_type = option_type |
363 self.first_display = True | 363 self.first_display = True |
364 | 364 |
365 if on_click: | 365 if on_click: |
366 urwid.connect_signal(self, 'click', on_click, user_data) | 366 urwid.connect_signal(self, 'click', on_click, user_data) |
367 | 367 |
368 if on_change: | 368 if on_change: |
369 urwid.connect_signal(self, 'change', on_change, user_data) | 369 urwid.connect_signal(self, 'change', on_change, user_data) |
370 | 370 |
371 self.content = urwid.SimpleListWalker([]) | 371 self.content = urwid.SimpleListWalker([]) |
372 self.list_box = urwid.ListBox(self.content) | 372 self.list_box = urwid.ListBox(self.content) |
373 urwid.WidgetWrap.__init__(self, self.list_box) | 373 urwid.WidgetWrap.__init__(self, self.list_box) |
374 self.changeValues(options) | 374 self.changeValues(options) |
375 | 375 |
441 if self.first_display and self.single and new_values and not self.no_first_select: | 441 if self.first_display and self.single and new_values and not self.no_first_select: |
442 self.content[0].setState(True) | 442 self.content[0].setState(True) |
443 display_widget = self.getDisplayWidget() | 443 display_widget = self.getDisplayWidget() |
444 self._set_w(display_widget) | 444 self._set_w(display_widget) |
445 self._emit('change') | 445 self._emit('change') |
446 self.first_display = False | 446 self.first_display = False |
447 | 447 |
448 def selectValue(self, value): | 448 def selectValue(self, value): |
449 """Select the first item which has the given value""" | 449 """Select the first item which has the given value""" |
450 self.unselectAll() | 450 self.unselectAll() |
451 idx = 0 | 451 idx = 0 |
460 """FlowWidget list, same arguments as GenericList, with an additional one 'max_height'""" | 460 """FlowWidget list, same arguments as GenericList, with an additional one 'max_height'""" |
461 signals = ['click','change'] | 461 signals = ['click','change'] |
462 | 462 |
463 def __init__(self, options, style=[], max_height=5, align='left', option_type = SelectableText, on_click=None, on_change=None, user_data=None): | 463 def __init__(self, options, style=[], max_height=5, align='left', option_type = SelectableText, on_click=None, on_change=None, user_data=None): |
464 self.genericList = GenericList(options, style, align, option_type, on_click, on_change, user_data) | 464 self.genericList = GenericList(options, style, align, option_type, on_click, on_change, user_data) |
465 self.max_height = max_height | 465 self.max_height = max_height |
466 | 466 |
467 def selectable(self): | 467 def selectable(self): |
468 return True | 468 return True |
469 | 469 |
470 def keypress(self, size, key): | 470 def keypress(self, size, key): |
471 return self.displayWidget(size,True).keypress(size, key) | 471 return self.displayWidget(size,True).keypress(size, key) |
472 | 472 |
473 def unselectAll(self, invisible=False): | 473 def unselectAll(self, invisible=False): |
474 return self.genericList.unselectAll(invisible) | 474 return self.genericList.unselectAll(invisible) |
475 | 475 |
476 def deleteValue(self, value): | 476 def deleteValue(self, value): |
477 return self.genericList.deleteValue(value) | 477 return self.genericList.deleteValue(value) |
478 | 478 |
479 def getSelectedValue(self): | 479 def getSelectedValue(self): |
480 return self.genericList.getSelectedValue() | 480 return self.genericList.getSelectedValue() |
491 def selectValue(self, value): | 491 def selectValue(self, value): |
492 return self.genericList.selectValue(value) | 492 return self.genericList.selectValue(value) |
493 | 493 |
494 def render(self, size, focus=False): | 494 def render(self, size, focus=False): |
495 return self.displayWidget(size, focus).render(size, focus) | 495 return self.displayWidget(size, focus).render(size, focus) |
496 | 496 |
497 def rows(self, size, focus=False): | 497 def rows(self, size, focus=False): |
498 return self.displayWidget(size, focus).rows(size, focus) | 498 return self.displayWidget(size, focus).rows(size, focus) |
499 | 499 |
500 def displayWidget(self, size, focus): | 500 def displayWidget(self, size, focus): |
501 list_size = sum([wid.rows(size, focus) for wid in self.genericList.content]) | 501 list_size = sum([wid.rows(size, focus) for wid in self.genericList.content]) |
502 height = min(list_size,self.max_height) or 1 | 502 height = min(list_size,self.max_height) or 1 |
503 return urwid.BoxAdapter(self.genericList, height) | 503 return urwid.BoxAdapter(self.genericList, height) |
504 | 504 |
505 ## MISC ## | 505 ## MISC ## |
506 | 506 |
507 class NotificationBar(urwid.WidgetWrap): | 507 class NotificationBar(urwid.WidgetWrap): |
514 urwid.connect_signal(self.message, 'click', lambda wid: self.showNext()) | 514 urwid.connect_signal(self.message, 'click', lambda wid: self.showNext()) |
515 self.progress = ClickableText('') | 515 self.progress = ClickableText('') |
516 self.columns = urwid.Columns([('fixed',6,self.waitNotifs),self.message,('fixed',4,self.progress)]) | 516 self.columns = urwid.Columns([('fixed',6,self.waitNotifs),self.message,('fixed',4,self.progress)]) |
517 urwid.WidgetWrap.__init__(self, urwid.AttrMap(self.columns,'notifs')) | 517 urwid.WidgetWrap.__init__(self, urwid.AttrMap(self.columns,'notifs')) |
518 self.notifs = [] | 518 self.notifs = [] |
519 | 519 |
520 def __modQueue(self): | 520 def __modQueue(self): |
521 """must be called each time the notifications queue is changed""" | 521 """must be called each time the notifications queue is changed""" |
522 self.waitNotifs.set_text(('notifs',"(%i)" % len(self.notifs) if self.notifs else '')) | 522 self.waitNotifs.set_text(('notifs',"(%i)" % len(self.notifs) if self.notifs else '')) |
523 self._emit('change') | 523 self._emit('change') |
524 | 524 |
582 | 582 |
583 | 583 |
584 class MenuBox(urwid.WidgetWrap): | 584 class MenuBox(urwid.WidgetWrap): |
585 """Show menu items of a category in a box""" | 585 """Show menu items of a category in a box""" |
586 signals = ['click'] | 586 signals = ['click'] |
587 | 587 |
588 def __init__(self,parent,items): | 588 def __init__(self,parent,items): |
589 self.parent = parent | 589 self.parent = parent |
590 self.selected = None | 590 self.selected = None |
591 content = urwid.SimpleListWalker([ClickableText(('menuitem',text)) for text in items]) | 591 content = urwid.SimpleListWalker([ClickableText(('menuitem',text)) for text in items]) |
592 for wid in content: | 592 for wid in content: |
596 menubox = urwid.LineBox(urwid.BoxAdapter(self.listBox,len(items))) | 596 menubox = urwid.LineBox(urwid.BoxAdapter(self.listBox,len(items))) |
597 urwid.WidgetWrap.__init__(self,menubox) | 597 urwid.WidgetWrap.__init__(self,menubox) |
598 | 598 |
599 def getValue(self): | 599 def getValue(self): |
600 return self.selected | 600 return self.selected |
601 | 601 |
602 def keypress(self, size, key): | 602 def keypress(self, size, key): |
603 if key=='up': | 603 if key=='up': |
604 if self.listBox.get_focus()[1] == 0: | 604 if self.listBox.get_focus()[1] == 0: |
605 self.parent.keypress(size, key) | 605 self.parent.keypress(size, key) |
606 elif key=='left' or key=='right': | 606 elif key=='left' or key=='right': |
607 self.parent.keypress(size,'up') | 607 self.parent.keypress(size,'up') |
608 self.parent.keypress(size,key) | 608 self.parent.keypress(size,key) |
609 return super(MenuBox,self).keypress(size,key) | 609 return super(MenuBox,self).keypress(size,key) |
610 | 610 |
611 def mouse_event(self, size, event, button, x, y, focus): | 611 def mouse_event(self, size, event, button, x, y, focus): |
612 if button == 3: | 612 if button == 3: |
613 self.parent.keypress(size,'up') | 613 self.parent.keypress(size,'up') |
614 return True | 614 return True |
615 return super(MenuBox,self).mouse_event(size, event, button, x, y, focus) | 615 return super(MenuBox,self).mouse_event(size, event, button, x, y, focus) |
631 self.x_orig = x_orig | 631 self.x_orig = x_orig |
632 self.shortcuts = {} #keyboard shortcuts | 632 self.shortcuts = {} #keyboard shortcuts |
633 self.save_bottom = None | 633 self.save_bottom = None |
634 col_rol = ColumnsRoller() | 634 col_rol = ColumnsRoller() |
635 urwid.WidgetWrap.__init__(self, urwid.AttrMap(col_rol,'menubar')) | 635 urwid.WidgetWrap.__init__(self, urwid.AttrMap(col_rol,'menubar')) |
636 | 636 |
637 def selectable(self): | 637 def selectable(self): |
638 return True | 638 return True |
639 | 639 |
640 def getMenuSize(self): | 640 def getMenuSize(self): |
641 """return the current number of categories in this menu""" | 641 """return the current number of categories in this menu""" |
642 return len(self.menu_keys) | 642 return len(self.menu_keys) |
643 | 643 |
644 def setOrigX(self, orig_x): | 644 def setOrigX(self, orig_x): |
645 self.x_orig = orig_x | 645 self.x_orig = orig_x |
646 | 646 |
647 def __buildOverlay(self,menu_key,columns): | 647 def __buildOverlay(self,menu_key,columns): |
648 """Build the overlay menu which show menuitems | 648 """Build the overlay menu which show menuitems |
654 max_len = len(item[0]) | 654 max_len = len(item[0]) |
655 | 655 |
656 self.save_bottom = self.loop.widget | 656 self.save_bottom = self.loop.widget |
657 menu_box = MenuBox(self,[item[0] for item in self.menu[menu_key]]) | 657 menu_box = MenuBox(self,[item[0] for item in self.menu[menu_key]]) |
658 urwid.connect_signal(menu_box, 'click', self.onItemClick) | 658 urwid.connect_signal(menu_box, 'click', self.onItemClick) |
659 | 659 |
660 self.loop.widget = urwid.Overlay(urwid.AttrMap(menu_box,'menubar'),self.save_bottom,('fixed left', columns),max_len+2,('fixed top',1),None) | 660 self.loop.widget = urwid.Overlay(urwid.AttrMap(menu_box,'menubar'),self.save_bottom,('fixed left', columns),max_len+2,('fixed top',1),None) |
661 | 661 |
662 def keypress(self, size, key): | 662 def keypress(self, size, key): |
663 if key == 'down': | 663 if key == 'down': |
664 key = 'enter' | 664 key = 'enter' |
665 elif key == 'up': | 665 elif key == 'up': |
666 if self.save_bottom: | 666 if self.save_bottom: |
667 self.loop.widget = self.save_bottom | 667 self.loop.widget = self.save_bottom |
668 self.save_bottom = None | 668 self.save_bottom = None |
669 | 669 |
670 return self._w.base_widget.keypress(size, key) | 670 return self._w.base_widget.keypress(size, key) |
671 | 671 |
672 def checkShortcuts(self, key): | 672 def checkShortcuts(self, key): |
673 for shortcut in self.shortcuts.keys(): | 673 for shortcut in self.shortcuts.keys(): |
674 if key == shortcut: | 674 if key == shortcut: |
675 category, item, callback = self.shortcuts[shortcut] | 675 category, item, callback = self.shortcuts[shortcut] |
676 callback((category, item)) | 676 callback((category, item)) |
702 callback = menu_item[1] | 702 callback = menu_item[1] |
703 break | 703 break |
704 if callback: | 704 if callback: |
705 self.keypress(None,'up') | 705 self.keypress(None,'up') |
706 callback((category, item)) | 706 callback((category, item)) |
707 | 707 |
708 def onCategoryClick(self, button): | 708 def onCategoryClick(self, button): |
709 self.__buildOverlay(button.get_label(), | 709 self.__buildOverlay(button.get_label(), |
710 self.x_orig + self._w.base_widget.getStartCol(button)) | 710 self.x_orig + self._w.base_widget.getStartCol(button)) |
711 | 711 |
712 | 712 |
713 class MenuRoller(urwid.WidgetWrap): | 713 class MenuRoller(urwid.WidgetWrap): |
714 | 714 |
715 def __init__(self,menus_list): | 715 def __init__(self,menus_list): |
716 """Create a MenuRoller | 716 """Create a MenuRoller |
718 """ | 718 """ |
719 assert (menus_list) | 719 assert (menus_list) |
720 self.selected = 0 | 720 self.selected = 0 |
721 self.name_list = [] | 721 self.name_list = [] |
722 self.menus = {} | 722 self.menus = {} |
723 | 723 |
724 self.columns = urwid.Columns([urwid.Text(''),urwid.Text('')]) | 724 self.columns = urwid.Columns([urwid.Text(''),urwid.Text('')]) |
725 urwid.WidgetWrap.__init__(self, self.columns) | 725 urwid.WidgetWrap.__init__(self, self.columns) |
726 | 726 |
727 for menu_tuple in menus_list: | 727 for menu_tuple in menus_list: |
728 name,menu = menu_tuple | 728 name,menu = menu_tuple |
729 self.addMenu(name, menu) | 729 self.addMenu(name, menu) |
730 | 730 |
731 def __showSelected(self): | 731 def __showSelected(self): |
732 """show menu selected""" | 732 """show menu selected""" |
733 name_txt = u'\u21c9 '+self.name_list[self.selected]+u' \u21c7 ' | 733 name_txt = u'\u21c9 '+self.name_list[self.selected]+u' \u21c7 ' |
734 current_name = ClickableText(name_txt) | 734 current_name = ClickableText(name_txt) |
735 name_len = len(name_txt) | 735 name_len = len(name_txt) |
736 current_menu = self.menus[self.name_list[self.selected]] | 736 current_menu = self.menus[self.name_list[self.selected]] |
737 current_menu.setOrigX(name_len) | 737 current_menu.setOrigX(name_len) |
738 self.columns.contents[0] = (current_name, ('given', name_len, False)) | 738 self.columns.contents[0] = (current_name, ('given', name_len, False)) |
739 self.columns.contents[1] = (current_menu, ('weight', 1, False)) | 739 self.columns.contents[1] = (current_menu, ('weight', 1, False)) |
773 | 773 |
774 def checkShortcuts(self, key): | 774 def checkShortcuts(self, key): |
775 for menu in self.name_list: | 775 for menu in self.name_list: |
776 key = self.menus[menu].checkShortcuts(key) | 776 key = self.menus[menu].checkShortcuts(key) |
777 return key | 777 return key |
778 | 778 |
779 | 779 |
780 ## DIALOGS ## | 780 ## DIALOGS ## |
781 | 781 |
782 class GenericDialog(urwid.WidgetWrap): | 782 class GenericDialog(urwid.WidgetWrap): |
783 | 783 |
784 def __init__(self, widgets_lst, title, style=[], **kwargs): | 784 def __init__(self, widgets_lst, title, style=[], **kwargs): |
785 frame_header = urwid.AttrMap(urwid.Text(title,'center'),'title') | 785 frame_header = urwid.AttrMap(urwid.Text(title,'center'),'title') |
786 | 786 |
787 buttons = None | 787 buttons = None |
788 | 788 |
789 if "OK/CANCEL" in style: | 789 if "OK/CANCEL" in style: |
790 cancel_arg = [kwargs['cancel_value']] if kwargs.has_key('cancel_value') else [] | 790 cancel_arg = [kwargs['cancel_value']] if kwargs.has_key('cancel_value') else [] |
791 ok_arg = [kwargs['ok_value']] if kwargs.has_key('ok_value') else [] | 791 ok_arg = [kwargs['ok_value']] if kwargs.has_key('ok_value') else [] |
831 GenericDialog.__init__(self, [urwid.Text(message, 'center')], title, style, ok_value=None, **kwargs) | 831 GenericDialog.__init__(self, [urwid.Text(message, 'center')], title, style, ok_value=None, **kwargs) |
832 | 832 |
833 ## CONTAINERS ## | 833 ## CONTAINERS ## |
834 | 834 |
835 class ColumnsRoller(urwid.FlowWidget): | 835 class ColumnsRoller(urwid.FlowWidget): |
836 | 836 |
837 def __init__(self, widget_list = None, focus_column=0): | 837 def __init__(self, widget_list = None, focus_column=0): |
838 self.widget_list = widget_list or [] | 838 self.widget_list = widget_list or [] |
839 self.focus_column = focus_column | 839 self.focus_column = focus_column |
840 self.__start = 0 | 840 self.__start = 0 |
841 self.__next = False | 841 self.__next = False |
857 def selectable(self): | 857 def selectable(self): |
858 try: | 858 try: |
859 return self.widget_list[self.focus_column][1].selectable() | 859 return self.widget_list[self.focus_column][1].selectable() |
860 except IndexError: | 860 except IndexError: |
861 return False | 861 return False |
862 | 862 |
863 def keypress(self, size, key): | 863 def keypress(self, size, key): |
864 if key=='left': | 864 if key=='left': |
865 if self.focus_column>0: | 865 if self.focus_column>0: |
866 self.focus_column-=1 | 866 self.focus_column-=1 |
867 self._invalidate() | 867 self._invalidate() |
890 def __calculate_limits(self, size): | 890 def __calculate_limits(self, size): |
891 (maxcol,) = size | 891 (maxcol,) = size |
892 _prev = _next = False | 892 _prev = _next = False |
893 start_wid = 0 | 893 start_wid = 0 |
894 end_wid = len(self.widget_list)-1 | 894 end_wid = len(self.widget_list)-1 |
895 | 895 |
896 total_wid = sum([w[0] for w in self.widget_list]) | 896 total_wid = sum([w[0] for w in self.widget_list]) |
897 while total_wid > maxcol: | 897 while total_wid > maxcol: |
898 if self.focus_column == end_wid: | 898 if self.focus_column == end_wid: |
899 if not _prev: | 899 if not _prev: |
900 total_wid+=1 | 900 total_wid+=1 |
905 if not _next: | 905 if not _next: |
906 total_wid+=1 | 906 total_wid+=1 |
907 _next = True | 907 _next = True |
908 total_wid-=self.widget_list[end_wid][0] | 908 total_wid-=self.widget_list[end_wid][0] |
909 end_wid-=1 | 909 end_wid-=1 |
910 | 910 |
911 cols_left = maxcol - total_wid | 911 cols_left = maxcol - total_wid |
912 self.__start = start_wid #we need to keep it for getStartCol | 912 self.__start = start_wid #we need to keep it for getStartCol |
913 return _prev,_next,start_wid,end_wid,cols_left | 913 return _prev,_next,start_wid,end_wid,cols_left |
914 | 914 |
915 | 915 |
916 def mouse_event(self, size, event, button, x, y, focus): | 916 def mouse_event(self, size, event, button, x, y, focus): |
917 (maxcol,)=size | 917 (maxcol,)=size |
918 | 918 |
919 if is_mouse_press(event) and button == 1: | 919 if is_mouse_press(event) and button == 1: |
922 self.keypress(size,'left') | 922 self.keypress(size,'left') |
923 return True | 923 return True |
924 if x==maxcol-1 and _next: | 924 if x==maxcol-1 and _next: |
925 self.keypress(size,'right') | 925 self.keypress(size,'right') |
926 return True | 926 return True |
927 | 927 |
928 current_pos = 1 if _prev else 0 | 928 current_pos = 1 if _prev else 0 |
929 idx = 0 | 929 idx = 0 |
930 while current_pos<x and idx<len(self.widget_list): | 930 while current_pos<x and idx<len(self.widget_list): |
931 width,widget = self.widget_list[idx] | 931 width,widget = self.widget_list[idx] |
932 if x<=current_pos+width: | 932 if x<=current_pos+width: |
933 self.focus_column = idx | 933 self.focus_column = idx |
934 self._invalidate() | 934 self._invalidate() |
935 if not hasattr(widget,'mouse_event'): | 935 if not hasattr(widget,'mouse_event'): |
936 return False | 936 return False |
937 return widget.mouse_event((width,0), event, button, | 937 return widget.mouse_event((width,0), event, button, |
938 x-current_pos, 0, focus) | 938 x-current_pos, 0, focus) |
939 | 939 |
940 current_pos+=self.widget_list[idx][0] | 940 current_pos+=self.widget_list[idx][0] |
941 idx+=1 | 941 idx+=1 |
942 | 942 |
943 return False | 943 return False |
944 | 944 |
945 def render(self, size, focus=False): | 945 def render(self, size, focus=False): |
946 if not self.widget_list: | 946 if not self.widget_list: |
947 return SolidCanvas(" ", size[0], 1) | 947 return SolidCanvas(" ", size[0], 1) |
948 | 948 |
949 _prev,_next,start_wid,end_wid,cols_left = self.__calculate_limits(size) | 949 _prev,_next,start_wid,end_wid,cols_left = self.__calculate_limits(size) |
950 | 950 |
951 idx=start_wid | 951 idx=start_wid |
952 render = [] | 952 render = [] |
953 | 953 |
954 for width,widget in self.widget_list[start_wid:end_wid+1]: | 954 for width,widget in self.widget_list[start_wid:end_wid+1]: |
955 _focus = idx == self.focus_column and focus | 955 _focus = idx == self.focus_column and focus |
970 | 970 |
971 def keypress(self, size, key): | 971 def keypress(self, size, key): |
972 ret = urwid.Frame.keypress(self, size, key) | 972 ret = urwid.Frame.keypress(self, size, key) |
973 if not ret: | 973 if not ret: |
974 return | 974 return |
975 | 975 |
976 if key == 'tab': | 976 if key == 'tab': |
977 focus_list = ('header','body','footer') | 977 focus_list = ('header','body','footer') |
978 focus_idx = focus_list.index(self.focus_part) | 978 focus_idx = focus_list.index(self.focus_part) |
979 for i in range(2): | 979 for i in range(2): |
980 focus_idx = (focus_idx + 1) % len(focus_list) | 980 focus_idx = (focus_idx + 1) % len(focus_list) |
981 focus_name = focus_list[focus_idx] | 981 focus_name = focus_list[focus_idx] |
982 widget = getattr(self,'_'+focus_name) | 982 widget = getattr(self,'_'+focus_name) |
983 if widget!=None and widget.selectable(): | 983 if widget!=None and widget.selectable(): |
984 self.set_focus(focus_name) | 984 self.set_focus(focus_name) |
985 | 985 |
986 return ret | 986 return ret |
987 | 987 |
988 class TabsContainer(urwid.WidgetWrap): | 988 class TabsContainer(urwid.WidgetWrap): |
989 signals = ['click'] | 989 signals = ['click'] |
990 | 990 |
991 def __init__(self): | 991 def __init__(self): |
1043 | 1043 |
1044 def addFooter(self, widget): | 1044 def addFooter(self, widget): |
1045 """Add a widget on the bottom of the tab (will be displayed on all pages) | 1045 """Add a widget on the bottom of the tab (will be displayed on all pages) |
1046 @param widget: FlowWidget""" | 1046 @param widget: FlowWidget""" |
1047 self._w.footer = widget | 1047 self._w.footer = widget |
1048 | 1048 |
1049 | 1049 |
1050 ## DECORATORS ## | 1050 ## DECORATORS ## |
1051 class LabelLine(urwid.LineBox): | 1051 class LabelLine(urwid.LineBox): |
1052 """Like LineBox, but with a Label centered in the top line""" | 1052 """Like LineBox, but with a Label centered in the top line""" |
1053 | 1053 |
1057 top_columns.widget_list[1] = label_widget | 1057 top_columns.widget_list[1] = label_widget |
1058 | 1058 |
1059 class VerticalSeparator(urwid.WidgetDecoration, urwid.WidgetWrap): | 1059 class VerticalSeparator(urwid.WidgetDecoration, urwid.WidgetWrap): |
1060 def __init__(self, original_widget, left_char = u"│", right_char = ''): | 1060 def __init__(self, original_widget, left_char = u"│", right_char = ''): |
1061 """Draw a separator on left and/or right of original_widget.""" | 1061 """Draw a separator on left and/or right of original_widget.""" |
1062 | 1062 |
1063 widgets = [original_widget] | 1063 widgets = [original_widget] |
1064 if left_char: | 1064 if left_char: |
1065 widgets.insert(0, ('fixed', 1, urwid.SolidFill(left_char))) | 1065 widgets.insert(0, ('fixed', 1, urwid.SolidFill(left_char))) |
1066 if right_char: | 1066 if right_char: |
1067 widgets.append(('fixed', 1, urwid.SolidFill(right_char))) | 1067 widgets.append(('fixed', 1, urwid.SolidFill(right_char))) |
1068 columns = urwid.Columns(widgets, box_columns = [0,2], focus_column = 1) | 1068 columns = urwid.Columns(widgets, box_columns = [0,2], focus_column = 1) |
1069 urwid.WidgetDecoration.__init__(self, original_widget) | 1069 urwid.WidgetDecoration.__init__(self, original_widget) |
1070 urwid.WidgetWrap.__init__(self, columns) | 1070 urwid.WidgetWrap.__init__(self, columns) |
1071 | 1071 |
1072 | 1072 |