; $Id: box_cursor.pro,v 1.2 1993/07/22 18:04:56 Moglie Exp $ 
 
pro bx_cursor, x0, y0, nx, ny, INIT = init, COLOR=color, FIXED_SIZE = fixed_size, $ 
	MESSAGE = message 
;+ 
; NAME: 
;	BX_CURSOR 
; 
; LAST CHANGED: -------------------------- 23-feb-00 
; 
; PURPOSE: 
;	Emulate the operation of a variable-sized box cursor (also known as 
;	a "marquee" selector). 
; (aph) (26-may-97) adapted to swap left and middle button functionality 
; 
; 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: Resize the box by dragging.  The corner 
;		             nearest the initial mouse position is moved. 
;	Middle mouse button: Move the box by dragging.  ! IF 3-button mouse !! 
;	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. 
;	May, 1997  - Adam Hitchcock : swap left and middle button 
; (23-feb-00 aph) axis standard documentation 
;- 
 
device, get_graphics = old, set_graphics = 6  ;Set xor 
col = !d.n_colors -1 
    ; IDL's approach 
if KEYWORD_SET(COLOR) THEN col=color 
 
if keyword_set(message) then begin 
	print, "Drag  Left   button near a corner to resize box." 
	print, "Drag  Middle button (if exists) to move box." 
	print, "click 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 
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 !err eq 2 then begin  ;Drag entire box? 
		x0 = x00 + x - mx0 
		y0 = y00 + y - my0 
		endif 
	if (!err eq 1) and (keyword_set(fixed_size) eq 0) 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 !err eq 4 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 
