Viewing contents of file '../idllib/contrib/tappin/graffer/graffer.pro'
;+
; GRAFFER
; Simple interactive data plotter.
;
; Usage:
; graffer[, group=group]
;
; Argument:
; file string input The initial filename for the graph
; file
;
; Keywords:
; group long input The group leader of the widget tree.
; xsize int input The x dimension of the draw widget
; ysize int input The y dimension of the draw widget
; debug input If set, then run in debugging mode.
; compact input 0: Use the standard full-size layout
; 1: Use the compact overlayed layout
; Not set: Use the full-sized layout if
; it will fit on the screen, but use the
; comapct form if it won't.
; pop_menus input If set, then popup menus will spring
; to the front every 2 seconds.
;
; History:
; Original: 27/7/95; SJT
; V2.00 - Start knocking ideas around, (1) break up the
; xsty and ysty tags of pdefs (which are horribly
; overloaded in V1.05) into structures.
; (2) Reform file into a TAG:VALUE format for
; greater flexibility.
; - Increase error bar possibilities
; - Upgrade function fitting routines
; - Rename some routines so that the first 8 chars
; are unique (for small-minded systems that only
; allow 8.3 filenames).
; - Add settings for POSITION (a precursor to
; multiple plots on one page?)
; - Start to farm out menu panels to procedures in
; order to facilitate keeping the standard &
; compact versions in step.
; - More farming out of bits of the menus
; - Modify compact format to put the graphics
; window in an independent base (suggestion from
; Phil Williams [Children's Hospital Medical
; Center, Cincinnati OH]) -- reviving the
; original intention of the compact mode.
; - Add support for 2-D datasets. Functions F(x,y)
; and Z datasets. Display by contours or as an
; "image". Also add options to re-order the
; datasets, and to write them to a file.
; - Add "resource='Graffer'" to all top-level
; widgets.
; - Make the colour selector in the text-editor
; widget into a pull-down like the one on the
; dataset menu.
; - Major improvements to PostScript options
; settings to allow offsets to be adjusted.
; - Add an on-line help system
; - Extensive changes to popups so that cancelled
; operations don't trigger redrawing or set the
; changed flag.
; - Add options to allow a dataset to be plotted
; "Unclipped"
; - Display index of current dataset as well as
; descriptor.
; - Add tracking events to the message box so that
; taking the cursor out of it clears the message.
; - Add support for Binary GRAFFER files and make
; autosave files always binary.
; - Improve file handling in several ways:
; 1) Check if the agument to GRAFFER is a
; directory and if so then use it as a
; path in the picker.
; 2) Don't try to find files in a
; non-existent or unscannable directory.
; 3) Put up a prompt when "Save as" or "Open
; new" attempt to overwrite an existing
; file.
; - Solved problem of setting values in a "Stated"
; pulldown for the axis style settings. I think
; they now reflect correctly the settings of the
; current file.
; - Add code to allow draw window to popup as soon
; as it is entered in compact mode. Also force
; the two windows to be reasonably
; well-separated (>125 pixels if possible).
; - Start to move some of the event handling
; routines out.
; - Separate definition of symbol from joining
; method and provide extra symbols.
; - Move the restoration of the plot state to a
; "KILL_NOTIFY" procedure (keep the state in
; common block - not ideal). Also make the two
; windows of compact mode mutually destroy each
; other.
; - Make the generation code of GRAFFER into
; GRAFFER_ONE, thus eliminating a goto and
; saving some code duplication. Actually
; implement the GROUP key which always existed
; but doesn't appear to have been implemented.
; - Add new dataset property to define mouse
; editability (so that it is possible to shut
; out the possibility of accidentally changing a
; data set). Move that along with sorting &
; clipping into a "Extras" pulldown in the
; dataset menus. Also make the dataset selection
; menus into a 1-liner.
; - Modify fit dataset to make it safer and to
; return to "system" versions of routines.
; - Add a "changed" indicator in a suitable bit of
; unused space.
; - Fix compact mode event generation so that the
; menu panel auto-exposes properly?
; - Add a system for putting a key on the
; plot. Also in the process invent "Frame"
; coordinates (like normalized but measured
; relative to the corners of the axis box rather
; than the viewport). Make this system available
; for anchoring text as well.
; - Add "piecewise linear" fits to the "Fit
; dataset" options.
; - Add a CAPTURE_INPUT key to GRAFF_ENTER and use
; it in most input situations.
; - Extensive reconstruction of GR_PICKFILE to
; make it look & feel more like the rest of GRAFFER.
; - Improve the autosave facility in several ways:
; - Big operations (e.g. editing a dataset)
; count as more than one operation.
; - The handling of the files if improved so
; that a prompt is given if the requested
; operation isn't what GRAFFER thinks you
; should do.
; - The flagging of deleting the autosave file
; is fixed.
; - Add new key option.
; - Fix problem with unidentified tags in binary
; files.
; Version 2.01:
; - Add space for a general comment on the plot.
; - Add GRAFF_PROPS to allow programs to set
; global values (e.g. axis ranges, titles etc.)
; Version 2.02:
; - Make Ndata fields LONG.
; - Modify file picker to prevent duplicated
; directory name being returned in some cases.
;-
pro Graff_event, event
base = widget_info(/child, event.top)
widget_control, base, get_uvalue = pdefs, /no_copy
sp = size(pdefs)
if (sp(sp(0)+1) eq 3) then begin
widget_control, base, set_uvalue = pdefs
base = widget_info(/child, pdefs)
widget_control, base, get_uvalue = pdefs, /no_copy
end else if (sp(sp(0)+1) ne 8) then begin
message, /continue, "** O U C H ** Corrupted internal data - " + $
"bailing out"
widget_control, event.top, /destroy
return
endif
if (base ne event.id) then widget_control, event.id, get_uvalue = object $
else object = 'SHOWC'
idraw_flag = 1
ichange = 1b
track_flag = strpos(tag_names(event, /struct), 'TRACK') ne -1
nch = 1
if (track_flag) then begin
idraw_flag = 0
ichange = 0b
if (event.enter eq 0) then begin
graff_msg, pdefs.ids.hlptxt, ''
case object of ; Special actions for exit events
'AUTOSAVE': graff_msg, pdefs.ids.message, ''
'SHOWC': pdefs.transient.showid = pdefs.ids.graffer2
'SHOWD': pdefs.transient.showid = pdefs.ids.graffer
Else:
endcase
goto, miss_case
endif
endif
case object of
'SHOWC': if (pdefs.transient.showid eq event.top) then begin
widget_control, event.top, /show
pdefs.transient.showid= 0l
idraw_flag = 0
ichange = 0b
endif
'SHOWD': if (pdefs.transient.showid eq event.top) then begin
widget_control, event.top, /show
pdefs.transient.showid = 0l
idraw_flag = 0
ichange = 0b
endif
'DESC': if (track_flag) then $
graff_msg, pdefs.ids.hlptxt, 'Give the current data set a ' + $
'memorable description' $
else begin
handle_value, pdefs.data, data, /no_copy
data(pdefs.cset).descript = event.value
handle_value, pdefs.data, data, /no_copy, /set
idraw_flag = pdefs.key.use
; if (event.cr) then grf_focus_enter, pdefs.ids.symsize
end
'TEXT': if (track_flag) then begin
graff_msg, pdefs.ids.hlptxt, 'Toggle between drawing and text ' + $
'modes'
endif else begin
gr_td_mode, event.value, pdefs
ichange = 0b
idraw_flag = 0b
end
'QSAVE': if (track_flag) then $
graff_msg, pdefs.ids.hlptxt, 'Save plot to currently selected ' + $
'filename in binary form' $
else begin
gr_bin_save, pdefs
ichange = 0b
idraw_flag = 0
end
'DRAW': begin ; Draw widget in graph mode
if (track_flag and $
widget_info(pdefs.ids.graffer2, /valid) and $
pdefs.transient.showid eq event.top) then begin
widget_control, event.top, /show
pdefs.transient.showid = 0l
endif
ichange = graff_draw(pdefs, event, track_flag)
idraw_flag = ichange
if (ichange) then nch = 21
end
'WRITE': begin ; Draw widget in text mode
if (track_flag and $
widget_info(pdefs.ids.graffer2, /valid) and $
pdefs.transient.showid eq event.top) then begin
widget_control, event.top, /show
pdefs.transient.showid = 0l
endif
ichange = graff_write(pdefs, event, track_flag)
idraw_flag = ichange
if (ichange) then nch = 21
end
'MOTION': if (track_flag) then $
graff_msg, pdefs.ids.hlptxt, 'Toggle use of crosshairs and ' + $
'cursor position monitor' $
else begin
widget_control, pdefs.ids.draw, draw_motion_events = $
event.value
ichange = 0b
end
'AUTOSAVE': if (not track_flag) then begin
gr_bin_save, pdefs, /auto
ichange = 0b
idraw_flag = 0
widget_control, event.id, timer = pdefs.opts.auto_delay
end
Else: begin
graff_msg, pdefs.ids.message, 'Unknown UVALUE: '+object
help, /structure, event
ichange = 0b
idraw_flag = 0
end
endcase
if (idraw_flag and (pdefs.opts.update eq 0)) then gr_plot_object, pdefs
if (ichange) then begin
pdefs.chflag = 1b
pdefs.transient.changes = pdefs.transient.changes+nch
if (pdefs.transient.changes gt 20) then begin
gr_bin_save, pdefs, /auto
if (pdefs.opts.update eq 1) then gr_plot_object, pdefs
endif
endif
widget_control, pdefs.ids.chtick, map = pdefs.chflag
Miss_case:
widget_control, base, set_uvalue = pdefs, /no_copy
end
pro Graffer, file, group=group, xsize=xsize, ysize=ysize, debug=debug, $
recover=recover, compact=compact, pop_menus=pop_menus
common Gr_psym_maps, psym_bm
common Gr_entry_state, pstate, xstate, ystate, zstate, qstate, rstate, $
gstate, bstate, gdstate
if ((!D.flags and 65536) eq 0) then begin
print, "GRAFFER needs widgets; current device (", !D.name, $
") does not support them."
return
endif
; Save the plotting system variables
gdstate = !D.name
pstate = !P
xstate = !X
ystate = !Y
zstate = !Z ; Not touched at present in graffer
; but if & when GRAFFER for surfaces is
; done then it may be
tvlct, rstate, gstate, bstate, /get
qstate = !Quiet
if (keyword_set(debug)) then begin
!Quiet = 0
on_error, 0 ; stop at error
endif else on_error, 2 ; Return to caller on error
!P.multi = 0 ; Clear plot positioning settings.
!P.region = 0
!P.position = 0
!P.font = -1
if (n_elements(file) eq 0) then $
file = gr_pickfile(/read, filter = '*.grf', $
title = 'Graffer Select') $
else if (gr_isadir(file)) then begin
file = gr_get_full_dir(file)
file = gr_pickfile(/read, filter = '*.grf', $
title = 'Graffer Select', path = file)
endif else if ((strpos(file, '*') > strpos(file, '?')) ne -1) then begin
f = file
gr_split_dir, f, dir
dir = gr_get_full_dir(dir)
file = gr_pickfile(/read, filter = f, title = 'Graffer Select', $
path = dir)
endif
if (file eq '') then return
; Define the data control structure
version = [2, 02]
graff_init, pdefs, file, version = version
pdefs.popflag = keyword_set(pop_menus)
igot = graff_get(pdefs, file, /no_set, recover = recover, /no_warn)
gr_disp_man, /initialize ; Initialize the online help system
; If the screen is too small for the whole widget, or if the
; user has explicitly asked for a compact plot widget, then use
; the GRAFFER_TWO procedure to define the layout (N.B. This
; still uses the same handler which has been compiled here.)
device, get_screen_size = scrs
if (n_elements(compact) eq 0) then $
compact = scrs(0) lt 1000 or scrs(1) lt 900
Start_make:
if (compact) then $
graff_two, pdefs, base, group = group, xsize = xsize, ysize = ysize $
else begin
graff_one, pdefs, base, group = group, xsize = xsize, ysize = ysize
; Make sure it does actually fit.
widget_control, pdefs.ids.graffer, tlb_get_size = grsize
if (grsize(0) gt scrs(0)-30 or $
grsize(1) gt scrs(1)-40) then begin
compact = 1
goto, start_make
endif
endelse
; gr_check_box, pdefs.ids.chtick
widget_control, pdefs.ids.draw, get_value = windex
wset, windex
pdefs.ids.windex = windex
graff_colours, pdefs
graff_set_vals, pdefs ; Set up the values of the text
; widgets etc.
tmid = pdefs.ids.message
auto_delay = pdefs.opts.auto_delay
widget_control, base, set_uvalue = pdefs, /no_copy
widget_control, tmid, timer = auto_delay
xmanager, 'graff', base
end