Viewing contents of file '../idllib/ssw/allpro/box_crs.pro'
pro box_crs, x0, y0, nx, ny, INIT = init, FIXED_SIZE = fixed_size, $
MESSAGE = message
;+
; Project : SOHO - CDS
;
; Name :
; BOX_CRS
; Purpose :
; Two-button equivalent of BOX_CURSOR for Microsoft Windows.
; Explanation :
; Emulates the operation of a variable-sized box cursor (also known as
; a "marquee" selector). Differs from BOX_CURSOR in that only two mouse
; buttons are used. This makes it useful for Microsoft Windows, where
; all three buttons are not always available.
;
; 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:
;
; To move box: Hold down either the left or middle mouse button while
; the cursor is inside the box, and drag the box to the
; desired position.
;
; To resize box: Hold down either the left or middle button mouse while
; the cursor is outside the box, and drag the box to the
; desired size. The corner nearest the initial mouse
; position is moved.
;
; To exit: Press the right mouse button to exit this procedure,
; returning the current box parameters.
;
; Use :
; BOX_CRS, x0, y0, nx, ny [, INIT = init] [, FIXED_SIZE = fixed_size]
; Inputs :
; No required input parameters.
; Opt. Inputs :
; X0, Y0, NX, and NY give the initial location (X0, Y0) and size (NX, NY)
; of the box if the keyword INIT is set. Otherwise, the box is initially
; drawn in the center of the screen.
; Outputs :
; X0: X value of lower left corner of box.
; Y0: Y value of lower left corner of box.
; NX: width of box in pixels.
; NY: height of box in pixels.
;
; The box is also constrained to lie entirely within the window.
;
; Opt. Outputs:
; None.
; Keywords :
; INIT: If this keyword is set, x0, y0, nx, and ny contain the initial
; parameters for the box.
;
; FIXED_SIZE: If this keyword is set, nx and ny contain the initial
; 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.
;
; Calls :
; None.
; Common :
; None.
; Restrictions:
; Works only with window system drivers.
; Side effects:
; A box is drawn in the currently active window. It is erased on exit.
; Category :
; Utilities, User_interface.
; Prev. Hist. :
; DMS, April, 1990.
; DMS, April, 1992. Made dragging more intutitive.
; William Thompson, GSFC, 11 June 1993.
; Changed to use two button operation, selecting moving or
; resizing based on whether or not the cursor is inside or
; outside the box. Renamed to BOX_CRS.
; Written :
; David M. Stern, RSI, April 1990.
; Modified :
; Version 1, William Thompson, GSFC, 25 June 1993.
; Incorporated into CDS library.
; Version 2, William Thompson, GSFC, 8 April 1998
; Changed !D.N_COLORS to !D.TABLE_SIZE for 24-bit displays
; Version :
; Version 2, 8 April 1998
;-
;
device, get_graphics = old, set_graphics = 6 ;Set xor
col = !d.table_size -1
if keyword_set(message) then begin
print, "Drag Left or Middle button inside box to move."
if not keyword_set(fixed_size) then $
print, "Or outside box near a corner to resize box."
print, "Right button when done."
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
button = 0
action = ''
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
endif
;
; If the button changed, then decide what the action should be.
;
if button ne old_button then begin
;
; If the right button was pressed, then the action is to quit.
;
if button eq 4 then begin
action = 'QUIT'
;
; Otherwise, if neither the right nor middle button was pressed, then the
; action is to do nothing.
;
end else if (button ne 1) and (button ne 2) then begin
action = ''
;
; Otherwise, if within the box, then the action is to drag the entire box, or
; if outside then the action is to resize the box, unless the FIXED_SIZE
; keyword is set.
;
end else begin
xmin = x0 < (x0 + nx) & xmax = x0 > (x0 + nx)
ymin = y0 < (y0 + ny) & ymax = y0 > (y0 + ny)
within = (x ge xmin) and (x le xmax) and (y ge ymin) $
and (y le ymax)
if within then begin
action = 'DRAG'
end else if not keyword_set(fixed_size) then begin
action = 'RESIZE'
end else action = ''
endelse
endif
;
; Act according to the selected action.
;
if action eq 'DRAG' then begin ;Drag entire box?
x0 = x00 + x - mx0
y0 = y00 + y - my0
endif
if action eq 'RESIZE' then begin ;New size?
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 & endcase
1: begin y0 = y00 + dy
nx = nx0 + dx & ny = ny0 - dy & endcase
2: begin nx = nx0 + dx & ny = ny0 + dy & endcase
3: begin x0 = x00 + dx
nx = nx0 - dx & ny = ny0 + dy & endcase
endcase
endif
plots, px, py, col=col, /dev, thick=1, lines=0 ;Erase previous box
empty ;Decwindow bug
if action eq 'QUIT' then begin ;Quitting?
device,set_graphics = old
return
endif
middle:
if nx lt 0 then begin
x0 = x0 + nx
nx = -nx
endif
if ny lt 0 then begin
y0 = y0 + ny
ny = -ny
endif
x0 = x0 > 0
y0 = y0 > 0
x0 = x0 < (!d.x_size-1 - nx) ;Never outside window
y0 = y0 < (!d.y_size-1 - ny)
px = [x0, x0 + nx, x0 + nx, x0, x0] ;X points
py = [y0, y0, y0 + ny, y0 + ny, y0] ;Y values
plots,px, py, col=col, /dev, thick=1, lines=0 ;Draw the box
wait, .1 ;Dont hog it all
endwhile
end