18 if type(item)
in (TupleType, ListType):
20 elif item
is not None:
30 def __init__( self, master=None, cnf={}, **kw ):
33 Initialize the Tk base class, and squirel away the stream id,
34 so that we will be able to ensure that future draw requests
35 show up in the right place."""
37 Widget.__init__( self, master,
'plframe', cnf, kw )
42 "Invoke a subcommand on the plframe widget."
43 apply( s.tk.call, (s._w,
'cmd',) +
_flatten(args) )
46 return s.tk.call( s._w,
'info', what )
55 def plenv( s, xmin, xmax, ymin, ymax, i, j ):
56 s.cmd(
'plenv', xmin, xmax, ymin, ymax, i, j )
61 def pllab( s, xlab, ylab, tlab ):
62 s.cmd(
'pllab', xlab, ylab, tlab )
78 """This class provides the same facilities as the Plframe, plus
79 several additional facilities for advanced plot interaction, which
80 are provided through menus and bindings."""
85 Configure the widget database, and then set up the internal
86 members. Namely, a menubar and a contained Plframe."""
88 Frame.__init__( s, master )
103 s.rowconfigure( 0, weight=0, minsize=0 )
104 s.rowconfigure( 1, weight=1, minsize=0 )
105 s.rowconfigure( 2, weight=0, minsize=0 )
115 s.columnconfigure( 0, weight=1, minsize=0 )
116 s.columnconfigure( 1, weight=0, minsize=0 )
125 s.plf.grid( row=1, column=0, sticky=NSEW )
142 s.saveopt_dev =
"psc"
152 s.zxl = [ 0. ]; s.zyl = [ 0. ]
153 s.zxr = [ 1. ]; s.zyr = [ 1. ]
156 s.plf.bind(
"<Any-KeyPress>", s.key_filter )
157 s.plf.bind(
"<Any-ButtonPress>", s.user_mouse )
158 s.plf.bind(
"<Any-Enter>", s.set_focus )
165 "Create the menubar at the top of the PlXframe"
168 s.ftop.grid( row=0, columnspan=2, sticky=
'ew' )
170 s.ftop.plot = Menubutton( s.ftop, text=
"Plot", underline=0,
172 s.ftop.plot.m = Menu( s.ftop.plot )
173 s.ftop.plot[
"menu"] = s.ftop.plot.m
175 s.ftop.plot.pack( side=LEFT )
177 s.create_menu_print( s.ftop.plot.m )
178 s.create_menu_save( s.ftop.plot.m )
179 s.create_menu_orient( s.ftop.plot.m )
180 s.create_menu_zoom( s.ftop.plot.m )
181 s.create_menu_page( s.ftop.plot.m )
182 s.create_menu_options( s.ftop.plot.m )
183 s.create_menu_debug ( s.ftop.plot.m )
185 s.ftop.eop = Button( s.ftop, text=
"Clear",
186 command=s.clearpage )
187 s.ftop.eop.pack( side=RIGHT )
189 s.ftop.lstat = Label( s.ftop, anchor=W, relief=RAISED )
190 s.ftop.lstat.pack( side=RIGHT, expand=1, fill=BOTH )
193 m.add(
"command", label=
"Print", command=s.cmd_print )
196 """Create the menu which lets us control the whole business of
197 saving plots to disk."""
200 pmenu.add(
"cascade", label=
'Save', menu=m )
204 m.add(
"command", label=
"As", command=s.save_as )
208 m.add(
"command", label=
"Again", command=s.save_again,
213 m.add(
"command", label=
"Close", command=s.save_close,
221 m.add(
"cascade", label=
"Set device", menu=m.sdev )
227 devnames = s.plf.info(
"devnames" )
228 devkeys = s.plf.info(
"devkeys" )
236 print "devnamlst = ", devnamlst
237 print "devkeylst = ", devkeylst
238 print "len(devnamlst) = ", len(devnamlst)
263 m.add(
"cascade", label=
"Set file type", menu=m.sfile )
265 m.sfile.add(
"radio", label=
"Single file (one plot/file)",
266 variable=s.saveopt_file, value=0 )
267 m.sfile.add(
"radio", label=
"Archive file( many plots/file)",
268 variable=s.saveopt_file, value=1 )
274 pmenu.add(
"cascade", label=
'Orient', menu=m )
276 m.config( postcommand=
lambda o=s, x=m: o.update_orient(x) )
280 m.add(
'radio', label=
"0 degrees",
281 command=
lambda o=s: o.orient(0) )
285 m.add(
'radio', label=
"90 degrees",
286 command=
lambda o=s: o.orient(1) )
290 m.add(
'radio', label=
"180 degrees",
291 command=
lambda o=s: o.orient(2) )
295 m.add(
'radio', label=
"270 degrees",
296 command=
lambda o=s: o.orient(3) )
300 pmenu.add(
"cascade", label=
'Zoom', menu=m )
302 m.config( postcommand=
lambda o=s, x=m: o.update_zoom(x) )
306 m.add(
'command', label=
"Select",
307 command=
lambda o=s: o.zoom_select() )
311 m.add(
'command', label=
"Back",
312 command=
lambda o=s: o.zoom_back(),
317 m.add(
'command', label=
"Forward",
318 command=
lambda o=s: o.zoom_forward(),
323 m.add(
'command', label=
"Enter bounds..",
324 command=
lambda o=s: o.zoom_enter() )
328 m.add(
'command', label=
"Reset",
329 command=
lambda o=s: o.zoom_reset() )
334 m.add(
'cascade', label=
"Options", menu=zom )
336 s.zoomopts_asp = IntVar()
337 s.zoomopts_sel = IntVar()
339 zom.add(
'check', label=
"Preserve aspect ratio",
340 variable=s.zoomopts_asp )
342 zom.add(
'separator' )
344 zom.add(
'radio', label=
"Start from corner",
345 variable=s.zoomopts_sel, value=0 )
347 zom.add(
'radio', label=
"Start from center",
348 variable=s.zoomopts_sel, value=1 )
358 pmenu.add(
"cascade", label=
'Page', menu=m )
362 m.add(
'command', label=
"Setup..", command=s.page_enter )
366 m.add(
'command', label=
"Reset", command=s.page_reset )
370 pmenu.add(
'cascade', label=
"Options", menu=m )
372 m.add(
'command', label=
"Palette 0", command=s.plcmap0_edit )
373 m.add(
'command', label=
"Palette 1", command=s.plcmap1_edit )
376 pmenu.add(
"command", label=
"Debug PlXframe", command=s.debug )
381 """Process keystroke events, and parcell out to various control
399 print "in user_mouse"
404 s.label_set(
"Printing plot..." )
405 s.tk.call( s.plf._w,
'print' )
409 """A sucky save menu thing. Needs to be enhanced to work like
410 the one in Tcl/Itcl."""
412 s.tk.call( s.plf._w,
'save',
'as',
'ps',
'xx.ps' )
413 s.tk.call( s.plf._w,
'save',
'close' )
414 print "Plot saved to xx.ps"
421 """Configure zoom menu.
423 Responsible for making sure zoom menu entries are normal or
424 disabled as appropriate. In particular, that 'Back' or 'Forward'
425 are only displayed if it is possible to traverse the zoom windows
426 list in that direction."""
428 zframes = len( s.zxl )
432 m.entryconfig( 2, state=DISABLED )
435 m.entryconfig( 2, state=ACTIVE )
437 if s.zidx == zframes-1:
439 m.entryconfig( 3, state=DISABLED )
442 m.entryconfig( 3, state=ACTIVE )
445 "Zooms plot in response to mouse selection."
456 if s.zoomopts_sel == 0:
457 s.label_set(
"Click on one corner of zoom region." )
458 elif s.zoomopts_sel == 1:
459 s.label_set(
"Click on center of zoom region." )
461 s.plf.bind(
"<ButtonPress>", s.zoom_start )
481 s.tk.call( s.plf._w,
'view',
'reset' )
483 if s.hscroll_exists
and atoi( s.tk.call(
'winfo',
'ismapped',
485 s.hscroll.grid_forget()
487 if s.vscroll_exists
and atoi( s.tk.call(
'winfo',
'ismapped',
489 s.vscroll.grid_forget()
494 s.zxl = [ 0. ]; s.zyl = [ 0. ]
495 s.zxr = [ 1. ]; s.zyr = [ 1. ]
499 r = s.tk.call( s.plf._w,
'orient' )
514 """Set the orientation of the plframe, but check to make sure
515 we only do this if the new orientation is different from the
518 oldori = s.tk.call( s.plf._w,
'orient' )
519 oldf = atof( oldori )
520 oldn = atoi(
"%.0f" % oldf ) % 4
524 s.tk.call( s.plf._w,
'orient', rots )
527 print "in page_enter"
530 print "in page_reset"
548 s.plf.bind(
"<ButtonPress>",
None )
552 s.label_set(
"Select zoom region by dragging mouse, then release." )
554 s.tk.call( s.plf._w,
'draw',
'init' )
555 s.plf.bind(
"<B1-Motion>", s.zoom_mouse_draw )
556 s.plf.bind(
"<B1-ButtonRelease>", s.zoom_mouse_end )
590 Lx = s.plf.winfo_width()
591 Ly = s.plf.winfo_height()
595 bounds = split( s.tk.call( s.plf._w,
'view',
'bounds' ) )
596 xmin = Lx * atof( bounds[0] )
597 ymin = Ly * atof( bounds[1] )
598 xmax = Lx * atof( bounds[2] )
599 ymax = Ly * atof( bounds[3] )
601 x1 =
max( xmin,
min( xmax, x1 ) )
602 y1 =
max( ymin,
min( ymax, y1 ) )
606 if s.zoomopts_sel == 0:
630 if s.zoomopts_asp == 1:
697 if xl < xmin: dx = x0 - xmin
698 if xr > xmax: dx = xmax - x0
699 if yl < ymin: dy = y0 - ymin
700 if yr > ymax: dy = ymax - y0
704 if s.zoomopts_asp == 1:
758 wyl = 1.0 - float(yr) / Ly
759 wyr = 1.0 - float(yl) / Ly
766 return wxl, wyl, wxr, wyr
769 "Draws zoom box in response to mouse motion (with button held down)."
771 coords = s.zoom_coords( s.wx, s.wy, e.x, e.y, 0 )
773 s.tk.call( s.plf._w,
'draw',
'rect',
774 coords[0], coords[1], coords[2], coords[3] )
777 "Performs actual zoom, invoked when user releases mouse button."
781 s.plf.bind(
"<B1-ButtonRelease>" )
782 s.plf.bind(
"<B1-Motion>" )
786 s.tk.call( s.plf._w,
'draw',
'end' )
790 coords = s.zoom_coords( s.wx, s.wy, e.x, e.y, 1 )
792 s.view_zoom( coords[0], coords[1], coords[2], coords[3] )
866 "Handles zoom. Given in relative device coordinates."
881 if (xr - xl) < .02
and (yr - yl) < .02:
882 nxl = xl - .5 * stdzoom
883 nxr = xl + .5 * stdzoom
893 nyl = yl - .5 * stdzoom
894 nyr = yl + .5 * stdzoom
906 bounds = split( s.tk.call( s.plf._w,
'view',
'bounds' ) )
907 xmin = atof( bounds[0] )
908 ymin = atof( bounds[1] )
909 xmax = atof( bounds[2] )
910 ymax = atof( bounds[3] )
912 xl =
max( xmin,
min( xmax, xl ) )
913 yl =
max( ymin,
min( ymax, yl ) )
914 xr =
max( xmin,
min( xmax, xr ) )
915 yr =
max( ymin,
min( ymax, yr ) )
919 hscroll, vscroll = 0, 0
920 if xl != xmin
or xr != xmax: hscroll = 1
921 if yl != ymin
or yr != ymax: vscroll = 1
923 if not (hscroll
or yscroll):
924 s.tk.call( s.plf._w,
'redraw' )
929 s.tk.call( s.plf._w,
'view',
'zoom', xl, yl, xr, yr )
933 s.fixview( hscroll, vscroll )
937 coords = split( s.tk.call( s.plf._w,
'view' ) )
941 if s.zidx == len( s.zxl ):
943 s.zxl.append( atof( coords[0] ) )
944 s.zyl.append( atof( coords[1] ) )
945 s.zxr.append( atof( coords[2] ) )
946 s.zyr.append( atof( coords[3] ) )
949 s.zxl[ s.zidx ] = atof( coords[0] )
950 s.zyl[ s.zidx ] = atof( coords[1] )
951 s.zxr[ s.zidx ] = atof( coords[2] )
952 s.zyr[ s.zidx ] = atof( coords[3] )
954 if s.zidx < len( s.zxl ) - 1:
956 s.zxl = s.zxl[0:s.zidx+1]
957 s.zyl = s.zyl[0:s.zidx+1]
958 s.zxr = s.zxr[0:s.zidx+1]
959 s.zyr = s.zyr[0:s.zidx+1]
962 "Traverse the zoom windows list backward."
967 xl = s.zxl[ s.zidx ]; yl = s.zyl[ s.zidx ]
968 xr = s.zxr[ s.zidx ]; yr = s.zyr[ s.zidx ]
972 s.tk.call( s.plf._w,
'view',
'select', xl, yl, xr, yr )
975 "Traverse the zoom windows list forward."
977 zframes = len( s.zxl )
979 if zframes == 1
or s.zidx == zframes-1:
984 xl = s.zxl[ s.zidx ]; yl = s.zyl[ s.zidx ]
985 xr = s.zxr[ s.zidx ]; yr = s.zyr[ s.zidx ]
989 s.tk.call( s.plf._w,
'view',
'select', xl, yl, xr, yr )
992 print "in view_scroll"
995 "Handles updates of scrollbars & plot after view change."
1000 if hscroll
and not s.hscroll_exists:
1001 s.hscroll = Scrollbar( s, relief=SUNKEN, orient=HORIZONTAL )
1002 s.hscroll[
'command'] = ( s.plf._w,
'xscroll' )
1003 s.plf.config( xscroll=( s.hscroll,
'set' ) )
1004 s.hscroll_exists = 1
1007 if vscroll
and not s.vscroll_exists:
1008 s.vscroll = Scrollbar( s, relief=SUNKEN, orient=VERTICAL )
1009 s.vscroll[
'command'] = ( s.plf._w,
'yscroll' )
1010 s.plf.config( yscroll=( s.vscroll,
'set' ) )
1011 s.vscroll_exists = 1
1020 s.plf.grid( row=1, column=0, sticky=
'nsew' )
1026 if hscroll
and not atoi( s.tk.call(
'winfo',
'ismapped',
1028 or vscroll
and not atoi( s.tk.call(
'winfo',
'ismapped',
1033 s.hscroll.grid( row=2, column=0, sticky=
'ew' )
1035 s.vscroll.grid( row=1, column=1, sticky=
'ns' )
1036 s.plf.grid( row=1, column=0, sticky=
'nsew' )
1038 s.tk.call( s.plf._w,
'redraw' )
1059 s.after( 2500, s.label_reset )
1062 s.ftop.lstat.config( text=
'' )
1065 s.ftop.lstat.config( text=msg )
1068 print "in plcmap0_edit"
1071 print "in plcmap1_edit"
1077 "Invoke a subcommand on the plframe widget."
1078 apply( s.tk.call, (s.plf._w,
'cmd',) +
_flatten(args) )
1081 s.cmd(
'pladv', page )
1083 def plaxes( s, x0, y0, xopt, xtick, nxsub, yopt, ytick, nysub ):
1084 s.cmd(
'plaxes', x0, y0, xopt, xtick, nxsub, yopt, ytick, nysub )
1090 def plbox( s, xopt, xtick, nxsub, yopt, ytick, nysub ):
1091 s.cmd(
'plbox', xopt, xtick, nxsub, yopt, ytick, nysub )
1093 def plbox3( s, xopt, xlabel, xtick, nsubx,
1094 yopt, ylabel, ytick, nsuby,
1095 zopt, zlabel, ztick, nsubz ):
1097 xopt, xlabel, xtick, nsubx,
1098 yopt, ylabel, ytick, nsuby,
1099 zopt, zlabel, ztick, nsubz )
1102 s.cmd(
'plcol0', col0 )
1105 s.cmd(
'plcol1', col1 )
1115 apply( plcont, args )
1120 def plenv( s, xmin, xmax, ymin, ymax, i, j ):
1121 s.cmd(
'plenv', xmin, xmax, ymin, ymax, i, j )
1126 s.plf.setvar(
'wv',
'0' )
1127 s.label_set(
"Plotting paused ... (Hit Clear to continue)" )
1129 s.plf.waitvar(
'wv' )
1135 s.plf.setvar(
'wv', 1 )
1142 s.cmd(
'plfont', ifnt )
1145 s.cmd(
'plfontld', fnt )
1147 def plhist( s, data, datmin, datmax, nbin, oldwin ):
1149 plhist( data, datmin, datmax, nbin, oldwin )
1152 s.cmd(
'plhls', h, l, sat )
1155 s.cmd(
'pljoin', x1, y1, x2, y2 )
1157 def pllab( s, xlab, ylab, tlab ):
1158 s.cmd(
'pllab', xlab, ylab, tlab )
1169 s.cmd(
'pllsty', lin )
1177 def plmtex( s, side, disp, pos, just, text ):
1178 s.cmd(
'plmtex', side, disp, pos, just, text )
1188 def plpoin( s, xs, ys, mark ):
1201 s.cmd(
'plprec', setp, prec )
1204 s.cmd(
'plpsty', patt )
1207 s.cmd(
'plptex', x, y, dx, dy, just, text )
1213 s.cmd(
'plrgb', r, g, b )
1216 s.cmd(
'plrgb1', r, g, b )
1219 s.cmd(
'plschr', dflt, scale )
1221 def plshade( s, z, xmin, xmax, ymin, ymax,
1222 sh_min, sh_max, sh_cmap, sh_color, sh_width,
1223 min_col, min_wid, max_col, max_wid, rect,
1224 pltr=
'pltr0', xg=
None, yg=
None, wrap=0 ):
1225 "Color filled shad plot."
1228 plshade( z, xmin, xmax, ymin, ymax,
1229 sh_min, sh_max, sh_cmap, sh_color, sh_width,
1230 min_col, min_wid, max_col, max_wid, rect,
1231 pltr, xg, yg, wrap )
1251 s.cmd(
'plssub', nx, ny )
1254 s.cmd(
'plssym', dflt, scale )
1261 s.cmd(
'plsvpa', xmin, xmax, ymin, ymax )
1264 s.cmd(
'plsxax', digmax, digits )
1267 s.cmd(
'plsyax', digmax, digits )
1274 s.cmd(
'plszax', digmax, digits )
1277 s.cmd(
'plvasp', aspect )
1279 def plvpas( s, xmin, xmax, ymin, ymax, aspect ):
1280 s.cmd(
'plvpas', xmin, xmax, ymin, ymax, aspect )
1283 s.cmd(
'plvpor', xmin, xmax, ymin, ymax )
1288 def plw3d( s, basex, basey, height, xmin0,
1289 xmax0, ymin0, ymax0, zmin0, zmax0, alt, az):
1291 basex, basey, height, xmin0,
1292 xmax0, ymin0, ymax0, zmin0, zmax0, alt, az)
1295 s.cmd(
'plwid', width )
1298 s.cmd(
'plwind', xmin, xmax, ymin, ymax )
1301 print "Debugging dump for PlXframe:"
1302 print "s.saveopt_dev = ", s.saveopt_dev