Package pyraf :: Module urwutil
[hide private]
[frames] | no frames]

Source Code for Module pyraf.urwutil

  1  # 
  2  # Urwid example similar to dialog(1) program 
  3  #    Copyright (C) 2004-2007  Ian Ward 
  4  # 
  5  #    This library is free software; you can redistribute it and/or 
  6  #    modify it under the terms of the GNU Lesser General Public 
  7  #    License as published by the Free Software Foundation; either 
  8  #    version 2.1 of the License, or (at your option) any later version. 
  9  # 
 10  #    This library is distributed in the hope that it will be useful, 
 11  #    but WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
 13  #    Lesser General Public License for more details. 
 14  # 
 15  #    You should have received a copy of the GNU Lesser General Public 
 16  #    License along with this library; if not, write to the Free Software 
 17  #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 18  # 
 19  # Urwid web site: http://excess.org/urwid/ 
 20   
 21  """ 
 22  July 2008 - taken from the urwid example script "dialog.py", for the use of 
 23  the DialogDisplay and the InputDialogDisplay classes.  Unsure why this 
 24  functionality is not delivered with a standard urwid installation, so we will 
 25  include this file until it comes with urwid.  This is slightly modified. 
 26   
 27  $Id: urwutil.py 1030 2009-06-17 22:37:25Z sontag $ 
 28  """ 
 29  from __future__ import division # confidence high 
 30   
 31  import sys 
 32  import urwid 
 33  import urwid.raw_display 
 34   
 35   
36 -class DialogExit(Exception):
37 pass
38 39
40 -class DialogDisplay:
41 palette = [ 42 ('body','black','light gray', 'standout'), 43 ('border','black','dark blue'), 44 ('shadow','white','black'), 45 ('selectable','black', 'dark cyan'), 46 ('focus','white','dark blue','bold'), 47 ('focustext','light gray','dark blue'), 48 ] 49
50 - def __init__(self, text, height, width, body=None):
51 width = int(width) 52 if width <= 0: 53 width = ('relative', 80) 54 height = int(height) 55 if height <= 0: 56 height = ('relative', 80) 57 58 self.body = body 59 if body is None: 60 # fill space with nothing 61 body = urwid.Filler(urwid.Divider(),'top') 62 63 self.frame = urwid.Frame( body, focus_part='footer') 64 if text is not None: 65 self.frame.header = urwid.Pile( [urwid.Text(text), 66 urwid.Divider()] ) 67 w = self.frame 68 69 # pad area around listbox 70 w = urwid.Padding(w, ('fixed left',2), ('fixed right',2)) 71 w = urwid.Filler(w, ('fixed top',1), ('fixed bottom',1)) 72 w = urwid.AttrWrap(w, 'body') 73 74 # "shadow" effect 75 w = urwid.Columns( [w,('fixed', 2, urwid.AttrWrap( 76 urwid.Filler(urwid.Text(('border',' ')), "top") 77 ,'shadow'))]) 78 w = urwid.Frame( w, footer = 79 urwid.AttrWrap(urwid.Text(('border',' ')),'shadow')) 80 81 # outermost border area 82 w = urwid.Padding(w, 'center', width ) 83 w = urwid.Filler(w, 'middle', height ) 84 w = urwid.AttrWrap( w, 'border' ) 85 86 self.view = w
87 88
89 - def add_buttons(self, buttons):
90 l = [] 91 for name, exitcode in buttons: 92 b = urwid.Button( name, self.button_press ) 93 b.exitcode = exitcode 94 b = urwid.AttrWrap( b, 'selectable','focus' ) 95 l.append( b ) 96 self.buttons = urwid.GridFlow(l, 10, 3, 1, 'center') 97 self.frame.footer = urwid.Pile( [ urwid.Divider(), 98 self.buttons ], focus_item = 1)
99
100 - def button_press(self, button):
101 raise DialogExit(button.exitcode)
102
103 - def main(self):
104 self.ui = urwid.raw_display.Screen() 105 self.ui.register_palette( self.palette ) 106 return self.ui.run_wrapper( self.run )
107
108 - def run(self):
109 self.ui.set_mouse_tracking() 110 size = self.ui.get_cols_rows() 111 try: 112 while True: 113 canvas = self.view.render( size, focus=True ) 114 self.ui.draw_screen( size, canvas ) 115 keys = None 116 while not keys: 117 keys = self.ui.get_input() 118 for k in keys: 119 if urwid.is_mouse_event(k): 120 event, button, col, row = k 121 self.view.mouse_event( size, 122 event, button, col, row, 123 focus=True) 124 if k == 'window resize': 125 size = self.ui.get_cols_rows() 126 k = self.view.keypress( size, k ) 127 128 if k: 129 self.unhandled_key( size, k) 130 except DialogExit, e: 131 return self.on_exit( e.args[0] )
132
133 - def on_exit(self, exitcode):
134 return exitcode, ""
135
136 - def unhandled_key(self, size, key):
137 pass
138 139
140 -class InputDialogDisplay(DialogDisplay):
141 - def __init__(self, text, height, width):
142 self.edit = urwid.Edit() 143 body = urwid.ListBox([self.edit]) 144 body = urwid.AttrWrap(body, 'selectable','focustext') 145 146 DialogDisplay.__init__(self, text, height, width, body) 147 148 self.frame.set_focus('body')
149
150 - def unhandled_key(self, size, k):
151 if k in ('up','page up'): 152 self.frame.set_focus('body') 153 if k in ('down','page down'): 154 self.frame.set_focus('footer') 155 if k == 'enter' or k == 'ctrl m': # STScI change ! add ctrl-m for OSX 156 # pass enter to the "ok" button 157 self.frame.set_focus('footer') 158 self.view.keypress( size, 'enter' )
159
160 - def on_exit(self, exitcode):
161 return exitcode, self.edit.get_edit_text()
162 163 164 # 165 # ListDialogDisplay example: 166 # 167 # choices = ['a','b','c','d'] 168 # import urwutil 169 # import urwid 170 # def mmm(tag, state): return urwutil.MenuItem(tag) 171 # chcs = [] 172 # for itm in choices: 173 # chcs.append(itm) 174 # chcs.append('') # empty state 175 # dlg=urwutil.ListDialogDisplay("select: ", len(choices)+7, 176 # 75, mmm, tuple(chcs), False) 177 # dlg.add_buttons([ ("Cancel",1), ]) 178 # rv, item = dlg.main() # use item if rv == 0 179 # 180
181 -class ListDialogDisplay(DialogDisplay):
182 - def __init__(self, text, height, width, constr, items, has_default):
183 j = [] 184 if has_default: 185 k, tail = 3, () 186 else: 187 k, tail = 2, ("no",) 188 while items: 189 j.append( items[:k] + tail ) 190 items = items[k:] 191 192 l = [] 193 self.items = [] 194 for tag, item, default in j: 195 w = constr( tag, default=="on" ) 196 self.items.append(w) 197 w = urwid.Columns( [('fixed', 12, w), 198 urwid.Text(item)], 2 ) 199 w = urwid.AttrWrap(w, 'selectable','focus') 200 l.append(w) 201 202 lb = urwid.ListBox(l) 203 lb = urwid.AttrWrap( lb, "selectable" ) 204 DialogDisplay.__init__(self, text, height, width, lb ) 205 206 self.frame.set_focus('body')
207
208 - def unhandled_key(self, size, k):
209 if k in ('up','page up'): 210 self.frame.set_focus('body') 211 if k in ('down','page down'): 212 self.frame.set_focus('footer') 213 if k == 'enter': 214 # pass enter to the "ok" button 215 self.frame.set_focus('footer') 216 self.buttons.set_focus(0) 217 self.view.keypress( size, k )
218
219 - def on_exit(self, exitcode):
220 """Print the tag of the item selected.""" 221 if exitcode != 0: 222 return exitcode, "" 223 s = "" 224 for i in self.items: 225 if i.get_state(): 226 s = i.get_label() 227 break 228 return exitcode, s
229 230 255 256
257 -def show_usage():
258 """ 259 Display a helpful usage message. 260 """ 261 sys.stdout.write(__doc__ +"\n\t"+sys.argv[0]+" text height width\n" \ 262 + """ 263 264 height and width may be set to 0 to auto-size. 265 list-height and menu-height are currently ignored. 266 status may be either on or off. 267 """ )
268 269 270 if __name__=="__main__": 271 272 if len(sys.argv) < 4: 273 show_usage() 274 sys.exit(1) 275 276 # Create a DialogDisplay instance 277 d = InputDialogDisplay(sys.argv[1], sys.argv[2], sys.argv[3]) 278 # for simple yes/no dialog: d = DialogDisplay(text, height, width) 279 d.add_buttons([ ("OK",0), ("Cancel",1) ]) 280 281 # Run it 282 exitcode, exitstring = d.main() 283 284 # Exit 285 if exitstring: sys.stderr.write(exitstring+"\n") 286 sys.exit(exitcode) 287