comparison frontends/primitivus/custom_widgets.py @ 177:8f56238309d9

Primitivus: AdvancedEdit and Notification bar improved - AdvancedEdit now support a completion callback - Notification bar now show progressions
author Goffi <goffi@goffi.org>
date Mon, 16 Aug 2010 21:06:03 +0800
parents a50953ac6191
children 556c2bd7c344
comparison
equal deleted inserted replaced
176:a50953ac6191 177:8f56238309d9
55 - C-e: like 'end' 55 - C-e: like 'end'
56 - C-k: remove everything on the right of the cursor 56 - C-k: remove everything on the right of the cursor
57 - C-w: remove the word on the back 57 - C-w: remove the word on the back
58 new behaviour: emit a 'click' signal when enter is pressed""" 58 new behaviour: emit a 'click' signal when enter is pressed"""
59 signals = urwid.Edit.signals + ['click'] 59 signals = urwid.Edit.signals + ['click']
60
61 def setCompletionMethod(self, callback):
62 """Define method called when completion is asked
63 @callback: method with 2 arguments:
64 - the text to complete
65 - if there was already a completion, a dict with
66 - 'completed':last completion
67 - 'completion_pos': cursor position where the completion starts
68 - 'position': last completion cursor position
69 this dict must be used (and can be filled) to find next completion)
70 and which return the full text completed"""
71 self.completion_cb = callback
72 self.completion_data = {}
60 73
61 def keypress(self, size, key): 74 def keypress(self, size, key):
62 #TODO: insert mode is not managed yet 75 #TODO: insert mode is not managed yet
63 if key == 'ctrl a': 76 if key == 'ctrl a':
64 key = 'home' 77 key = 'home'
72 pos = before.rstrip().rfind(" ")+1 85 pos = before.rstrip().rfind(" ")+1
73 self.set_edit_text(before[:pos] + self.edit_text[self.edit_pos:]) 86 self.set_edit_text(before[:pos] + self.edit_text[self.edit_pos:])
74 self.set_edit_pos(pos) 87 self.set_edit_pos(pos)
75 elif key == 'enter': 88 elif key == 'enter':
76 self._emit('click') 89 self._emit('click')
90 elif key == 'shift tab':
91 try:
92 before = self.edit_text[:self.edit_pos]
93 if self.completion_data:
94 if (not self.completion_data['completed']
95 or self.completion_data['position'] != self.edit_pos
96 or not before.endswith(self.completion_data['completed'])):
97 self.completion_data.clear()
98 else:
99 before = before[:-len(self.completion_data['completed'])]
100 complet = self.completion_cb(before, self.completion_data)
101 self.completion_data['completed'] = complet[len(before):]
102 self.set_edit_text(complet+self.edit_text[self.edit_pos:])
103 self.set_edit_pos(len(complet))
104 self.completion_data['position'] = self.edit_pos
105 return
106 except AttributeError:
107 #No completion method defined
108 pass
77 return super(AdvancedEdit, self).keypress(size, key) 109 return super(AdvancedEdit, self).keypress(size, key)
78 110
79 111
80 class SurroundedText(urwid.FlowWidget): 112 class SurroundedText(urwid.FlowWidget):
81 """Text centered on a repeated character (like a Divider, but with a text in the center)""" 113 """Text centered on a repeated character (like a Divider, but with a text in the center)"""
370 """Bar used to show misc information to user""" 402 """Bar used to show misc information to user"""
371 signals = ['change'] 403 signals = ['change']
372 404
373 def __init__(self): 405 def __init__(self):
374 self.waitNotifs = urwid.Text('') 406 self.waitNotifs = urwid.Text('')
375 self.message = ClickableText('', default_attr='notifs', select_attr='notifs') 407 self.message = ClickableText('', default_attr='notifs')
376 urwid.connect_signal(self.message, 'click', lambda wid: self.showNext()) 408 urwid.connect_signal(self.message, 'click', lambda wid: self.showNext())
377 self.columns = urwid.Columns([('fixed',6,self.waitNotifs),self.message]) 409 self.progress = ClickableText('', default_attr='notifs')
410 self.columns = urwid.Columns([('fixed',6,self.waitNotifs),self.message,('fixed',4,self.progress)])
378 urwid.WidgetWrap.__init__(self, urwid.AttrMap(self.columns,'notifs')) 411 urwid.WidgetWrap.__init__(self, urwid.AttrMap(self.columns,'notifs'))
379 self.notifs = [] 412 self.notifs = []
380 413
381 def __modQueue(self): 414 def __modQueue(self):
382 """must be called each time the notifications queue is changed""" 415 """must be called each time the notifications queue is changed"""
383 self.waitNotifs.set_text("(%i)" % len(self.notifs) if self.notifs else '') 416 self.waitNotifs.set_text("(%i)" % len(self.notifs) if self.notifs else '')
417 self._emit('change')
418
419 def setProgress(self,percentage):
420 """Define the progression to show on the right side of the bar"""
421 if percentage == None:
422 self.progress.set_text('')
423 else:
424 self.progress.set_text('%02i%%' % percentage)
384 self._emit('change') 425 self._emit('change')
385 426
386 def addPopUp(self, pop_up_widget): 427 def addPopUp(self, pop_up_widget):
387 """Add a popup to the waiting queue""" 428 """Add a popup to the waiting queue"""
388 self.notifs.append(('popup',pop_up_widget)) 429 self.notifs.append(('popup',pop_up_widget))
429 def isQueueEmpty(self): 470 def isQueueEmpty(self):
430 return not bool(self.notifs) 471 return not bool(self.notifs)
431 472
432 def canHide(self): 473 def canHide(self):
433 """Return True if there is now important information to show""" 474 """Return True if there is now important information to show"""
434 return self.isQueueEmpty() and not self.message.get_text() 475 return self.isQueueEmpty() and not self.message.get_text() and not self.progress.get_text()
435 476
436 477
437 class MenuBox(urwid.WidgetWrap): 478 class MenuBox(urwid.WidgetWrap):
438 """Show menu items of a category in a box""" 479 """Show menu items of a category in a box"""
439 signals = ['click'] 480 signals = ['click']