Viewing contents of file '../idllib/contrib/esrg_ucsb/boxonmap.pro'
pro boxonmap, wx0, wy0, wx1, wy1, INIT = init, FIXED_SIZE = fixed_size, $
MESSAGE = message
;+
; ROUTINE:
; BOXONMAP, derived from IDL User Library Procedure BOX_CURSOR
;
; PURPOSE:
; Emulate the operation of a variable-sized box cursor (also known as
; a "marquee" selector).
;
; CATEGORY:
; Interactive graphics.
;
; CALLING SEQUENCE:
; BOXONMAP, wx0, wy0, wx1, wy1 [, INIT = init] [, FIXED_SIZE = fixed_size]
;
; INPUTS:
; No required input parameters.
;
; OPTIONAL INPUT PARAMETERS:
; wx0, wy0, wx1, and wy1 give the initial location of the lower left
; (wx0, wy0) and upper right (wnx, wny) corners of the box if the
; keyword INIT is set. Otherwise, the box is initially drawn in the
; center of the screen. Both input and output parameters are in
; Longitude (X) and Latitude (Y).
;
; KEYWORD PARAMETERS:
; INIT: If this keyword is set, wx0, wy0, wx1, and wy1 contain the
; initial parameters for the box.
;
; FIXED_SIZE: If this keyword is set, the initial parameters fix the
; size of the box. This size may not be changed by the user.
;
; MESSAGE: If this keyword is set, print a short message describing
; operation of the cursor.
;
; OUTPUTS:
; wx0: X value (Lon) of lower left corner of box.
; wy0: Y value (Lat) of lower left corner of box.
; wx1: X value (Lon) of upper right corner of box.
; wy1: Y value (Lat) of upper right corner of box.
;
; The box is also constrained to lie entirely within the window.
;
; COMMON BLOCKS:
; None.
;
; SIDE EFFECTS:
; A box is drawn in the currently active window. It is erased
; on exit.
; A window for display of numeric latitude and longitude is created.
; It is destroyed on exit.
;
; RESTRICTIONS:
; Works only with window system drivers.
;
; PROCEDURE:
; The graphics function is set to 6 for eXclusive OR. This
; allows the box to be drawn and erased without disturbing the
; contents of the window.
;
; Operation is as follows:
; Left mouse button: Move the box by dragging.
; Middle mouse button: Resize the box by dragging. The corner
; nearest the initial mouse position is moved.
; Right mouse button: Exit this procedure, returning the
; current box parameters.
;
; MODIFICATION HISTORY:
; DMS, April, 1990.
; DMS, April, 1992. Made dragging more intutitive.
; NFH, March, 1993, Warp box & use map coordinates,
; display Lat & Lon in text box.
; PJR/ESRG, March, 1994, display lat & lon in xmessage window
;-
device, get_graphics = old, set_graphics = 6 ;Set xor
col = !d.n_colors -1
if keyword_set(message) then begin
labels=replicate(" ",3)
xmessage,["Drag Left button to move box.",$
"Drag Middle button near a corner to resize box.",$
"Right button when done.",labels],wbase=wbase,wlabels=wlabels
endif
if keyword_set(init) eq 0 then begin ;Supply default values for box:
if keyword_set(fixed_size) eq 0 then begin
nx = !d.x_size/8 ;no fixed size.
ny = !d.x_size/8
endif
x0 = !d.x_size/2 - nx/2
y0 = !d.y_size/2 - ny/2
endif else begin ;translate supplied input parameters
result1 = convert_coord(wx0,wy0, /data, /to_device)
x0 = result1(0) & y0 = result1(1)
result2 = convert_coord(wx1,wy1, /data, /to_device)
x1 = result2(0) & y1 = result2(1)
nx = x1-x0 & ny = y1-y0
endelse
button = 0
wnx=0 & wny = 0
goto, middle
while 1 do begin
old_button = button
cursor, x, y, 2, /dev ;Wait for a button
button = !err
if (old_button eq 0) and (button ne 0) then begin
mx0 = x ;For dragging, mouse locn...
my0 = y
x00 = x0 ;Orig start of ll corner
y00 = y0
result1 = convert_coord(x,y, /device, /to_data)
result2 = convert_coord(x+nx,y+ny, /device, /to_data)
wx0 = result1(0) & wy0 = result1(1)
wx1 = result2(0) & wy1 = result2(1)
wnx = wx1-wx0 & wny = wy1-wy0
;Orig displacement of ur corner, in data units
endif
if !err eq 1 then begin ;Drag entire box?
xok = x0 & yok = y0
x0 = x00 + x - mx0
y0 = y00 + y - my0
result1 = convert_coord(x0,y0, /device, /to_data)
wx0 = result1(0) & wy0 = result1(1)
if abs(wx0) lt 720 and abs(wy0) lt 90 then begin
wx1 = wx0+wnx & wy1 = wy0+wny
result2 = convert_coord(wx1,wy1, /data, /to_device)
x1 = result2(0)
y1 = result2(1)
result2 = convert_coord(wx1,wy0, /data, /to_device)
x2 = result2(0) & y2 = result2(1) ; LR corner
result2 = convert_coord(wx0,wy1, /data, /to_device)
x3 = result2(0) & y3 = result2(1) ; UL corner
endif
if abs(wx0) le 720 and abs(wy0) le 90 and $
abs(wx1) le 720 and abs(wy1) le 90 and $
x2 gt x0 and y2 lt y1 and x3 lt x1 and y3 gt y0 and $
x0 gt 10 and y0 gt 10 and $
x1 lt !d.x_size-10 and y1 lt !d.y_size-10 then begin
nx = x1-x0 & ny = y1-y0 ; confirm change
endif else begin
x0 = xok & y0 = yok ; rescind change
endelse
endif
if (!err eq 2) and (keyword_set(fixed_size) eq 0) then begin ;New size?
px=[x0, x0+nx, x0+nx, x0, x0]
py=[y0, y0, y0+ny, y0+ny, y0]
if old_button eq 0 then begin ;Find closest corner
mind = 1e6
for i=0,3 do begin
d = float(px(i)-x)^2 + float(py(i)-y)^2
if d lt mind then begin
mind = d
corner = i
endif
endfor
nx0 = nx ;Save sizes.
ny0 = ny
endif
dx = x - mx0 & dy = y - my0 ;Distance dragged...
case corner of
0: begin & x0=x00+dx & y0=y00+dy & nx=nx0-dx & ny=ny0-dy & end
1: begin & y0=y00+dy & nx=nx0+dx & ny=ny0-dy & end
2: begin & nx=nx0+dx & ny=ny0+dy & end
3: begin & x0=x00+dx & nx=nx0-dx & ny=ny0+dy & end
endcase
endif
plots, pxw, pyw, col=col, /data, thick=1, lines=0 ;Erase the box
empty ;Decwindow bug
if !err eq 4 then begin ;Quitting?
device,set_graphics = old
result1 = convert_coord(x0,y0, /device, /to_data)
result2 = convert_coord(x0+nx,y0+ny, /device, /to_data)
wx0 = result1(0) & wy0 = result1(1)
wx1 = result2(0) & wy1 = result2(1)
if keyword_set(wbase) then xmessage,kill=wbase
return
endif
middle:
x1=x0+nx & y1=y0+ny
w = convert_coord(x0, y0, /device, /to_data)
wx0 = w(0) & wy0 = w(1)
w = convert_coord(x1, y1, /device, /to_data)
wx1 = w(0) & wy1 = w(1)
wx0=wx0>!map.out(2)
wx1=wx1<!map.out(3)
wy0=wy0>!map.out(4)
wy1=wy1<!map.out(5)
if wx0 gt 0 and wx1 lt 0 then wx1=wx1+360
xsegs = 1 > (abs(wx1-wx0)/5)
ysegs = 1 > (abs(wy1-wy0)/5)
segs = findgen(xsegs)/xsegs
pxa = interpolate([wx0, wx1], segs)
pya = interpolate([wy0, wy0], segs)
pxc = interpolate([wx1, wx0], segs)
pyc = interpolate([wy1, wy1], segs)
segs = findgen(ysegs)/ysegs
pxb = interpolate([wx1, wx1], segs)
pyb = interpolate([wy0, wy1], segs)
pyd = interpolate([wy1, wy0], segs)
pxd = interpolate([wx0, wx0], segs)
pxw = [wx0, pxa, pxb, pxc, pxd, wx0]
pyw = [wy0, pya, pyb, pyc, pyd, wy0]
plots, pxw, pyw, /data, thick=1, lines=0 ;Draw the box
ns='N' & ew='E'
if wy1 lt 0 then begin & ns='S' & wy1=-wy1 & endif
if keyword_set(message) then labels(0) = string(Format='(f7.2,a)',wy1,ns)
if wx0 gt 180 then wx0=wx0-360
if wx0 lt 0 then begin & ew='W' & wx0 =-wx0 & endif
if keyword_set(message) then labels(1) = string(Format='(f7.2,a)',wx0,ew)+' /'
ns='N' & ew='E'
if wx1 gt 180 then wx1=wx1-360
if wx1 lt 0 then begin & ew='W' & wx1 =-wx1 & endif
if keyword_set(message) then labels(1) = labels(1) + string(Format='(F7.2,a)',wx1,ew)
if wy0 lt 0 then begin & ns='S' & wy0=-wy0 & endif
if keyword_set(message) then labels(2) = string(Format='(f7.2,a)',wy0,ns)
if keyword_set(message) then xmessage,labels,relabel=wlabels(3:5)
wait, .1 ;Dont hog it all
endwhile
end
;********** END OF IDL CODE ************