Viewing contents of file '../idllib/idl_5.2/lib/box_cursor.pro'
; $Id: box_cursor.pro,v 1.8.4.1 1999/01/16 16:37:31 scottm Exp $
;
; Copyright (c) 1990-1999, Research Systems, Inc. All rights reserved.
; Unauthorized reproduction prohibited.
;
pro box_cursor, x0, y0, nx, ny, INIT = init, FIXED_SIZE = fixed_size, $
MESSAGE = message
;+
; NAME:
; BOX_CURSOR
;
; PURPOSE:
; Emulate the operation of a variable-sized box cursor (also known as
; a "marquee" selector).
;
; CATEGORY:
; Interactive graphics.
;
; CALLING SEQUENCE:
; BOX_CURSOR, x0, y0, nx, ny [, INIT = init] [, FIXED_SIZE = fixed_size]
;
; INPUTS:
; No required input parameters.
;
; OPTIONAL INPUT PARAMETERS:
; 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.
;
; KEYWORD PARAMETERS:
; 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.
;
; 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.
;
; COMMON BLOCKS:
; None.
;
; SIDE EFFECTS:
; A box is drawn in the currently active window. It is erased
; 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.
; June, 1993 - Bill Thompson
; prevented the box from having a negative size.
; SJL, Nov, 1997. Formatted, conform to IDL style guide.
; Prevented crash from unitialized corner.
; RJF, Feb, 1998. Replaced !ERROR_STATE.CODE w/ !MOUSE.BUTTON and
; fixed some problems w/sizing when a corner might swap.
;-
DEVICE, GET_GRAPHICS = old, SET_GRAPHICS = 6 ;Set xor
col = !D.N_COLORS -1
corner = 0
if KEYWORD_SET(message) then begin
print, "Drag Left button to move box."
print, "Drag Middle button 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
old_button = 1
goto, middle
while(1) do begin
old_button = button
cursor, x, y, 2, /DEV ;Wait for a button
button = !MOUSE.BUTTON
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 (!MOUSE.BUTTON eq 1) then begin ;Drag entire box?
x0 = x00 + x - mx0
y0 = y00 + y - my0
endif
;;New size?
if ((!MOUSE.BUTTON eq 2) and (KEYWORD_SET(fixed_size) eq 0)) $
then begin
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
if ((old_button ne 0) or (button ne 0)) then begin
plots, px, py, COL=col, /DEV, THICK=1, LINES=0 ;Erase previous box
empty ;Decwindow bug
endif
if (!MOUSE.BUTTON eq 4) then begin ;Quitting?
DEVICE,SET_GRAPHICS = old
return
endif
middle:
if (nx lt 0) then begin
x0 = x0 + nx
nx = -nx
case corner of
0: corner = 1
1: corner = 0
2: corner = 3
3: corner = 2
endcase
; reset the starting drag point...
mx0 = x & my0 = y
x00 = x0 & y00 = y0
nx0 = nx & ny0 = ny
endif
if (ny lt 0) then begin
y0 = y0 + ny
ny = -ny
case corner of
0: corner = 3
3: corner = 0
1: corner = 2
2: corner = 1
endcase
; reset the starting drag point...
mx0 = x & my0 = y
x00 = x0 & y00 = y0
nx0 = nx & ny0 = 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
if ((old_button ne 0) or (button ne 0)) then begin
plots,px, py, COL=col, /DEV, THICK=1, LINES=0 ;Draw the box
empty ;Decwindow bug
endif
wait, .1 ;Dont hog it all
endwhile
end