PRO box_cursor2, x0, y0, nx, ny, INIT = init, FIXED_SIZE = fixed_size, $ message = message, color = color, anywhere=anywhere, $ event_pro=event_pro, stc4event=event DEVICE, get_graphics = old, set_graphics = 6 ; Set xor IF N_ELEMENTS(color) EQ 0 THEN color = !d.table_size -1 IF N_ELEMENTS(event_pro) NE 0 THEN BEGIN ok = datatype(event_pro) EQ 'STR' IF NOT ok THEN MESSAGE, 'Error in compiling the event procedure.', /cont ENDIF ELSE ok = 0 IF KEYWORD_SET(MESSAGE) THEN BEGIN IF KEYWORD_SET(fixed_size) THEN BEGIN PRINT, "Drag Left button to move box." PRINT, "Right button when done." ENDIF ELSE BEGIN PRINT, "Drag Left button to move box." PRINT, "Drag Middle button near a corner to resize box." PRINT, "Right button when done." ENDELSE 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 ;---------------------------------------- ; To make it work properly with widgets IF widget_info(/active) THEN widget = find_draw_widget(!d.window) $ ELSE widget = -1L IF widget NE -1L THEN BEGIN IF NOT widget_info(widget,/draw_button_events) OR $ NOT widget_info(widget,/draw_motion_events) THEN BEGIN message,"Motion/Button events turned on",/continue message,"They may have to be turned off after returning from "+$ "BOX_CURSOR",/continue widget_control,widget,/draw_button_events,$ /draw_motion_events END END ;---------------------------------------- GOTO, middle WHILE 1 DO BEGIN old_button = button IF widget NE -1L THEN BEGIN ;---------------------------------------- ; To make it work properly with widgets ev = widget_event(widget) x = ev.x y = ev.y IF ev.type EQ 0 THEN button = ev.press IF ev.type EQ 1 THEN button = 0 !err = button ;---------------------------------------- END ELSE BEGIN cursor, x, y, 2, /dev ;Wait for a button button = !err END 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 1 THEN BEGIN ;Drag entire box? x0 = x00 + x - mx0 y0 = y00 + y - my0 ENDIF IF (!err EQ 2) AND (KEYWORD_SET(fixed_size) EQ 0) THEN BEGIN ;New size? IF old_button EQ 0 THEN BEGIN ;Find closest corner min_d = 1e6 FOR i = 0,3 DO BEGIN d = FLOAT(px(i)-x)^2 + FLOAT(py(i)-y)^2 IF d LT min_d THEN BEGIN min_d = d corner = i ENDIF ENDFOR nx0 = nx ;Save sizes. ny0 = ny ENDIF dx = x-mx0 & dy = y-my0 ;Distance dragged... ;--------------------------------------------------------------------------- ; The major change was made here. After the closest corner is ; found, the opposite corner is fixed. This prevents the box ; from jumping around -- Liyun Wang, GSFC/ARC ;--------------------------------------------------------------------------- CASE corner OF 0: BEGIN IF (dx GT nx0) THEN BEGIN x0 = x00+nx0 nx = dx-nx0 ENDIF ELSE BEGIN x0 = x00+dx nx = nx0-dx ENDELSE IF (dy GT ny0) THEN BEGIN y0 = y00+ny0 ny = dy-ny0 ENDIF ELSE BEGIN y0 = y00+dy ny = ny0-dy ENDELSE END 1: BEGIN IF (dx LE -nx0) THEN BEGIN nx = -(nx0+dx) x0 = x00-nx ENDIF ELSE BEGIN nx = nx0+dx x0 = x00 ENDELSE IF (dy GT ny0) THEN BEGIN y0 = y00+ny0 ny = dy-ny0 ENDIF ELSE BEGIN y0 = y00+dy ny = ny0-dy ENDELSE END 2: BEGIN IF (dx LE -nx0) THEN BEGIN nx = -(nx0+dx) x0 = x00-nx ENDIF ELSE BEGIN nx = nx0+dx x0 = x00 ENDELSE IF (dy LE -ny0) THEN BEGIN ny = -(ny0+dy) y0 = y00-ny ENDIF ELSE BEGIN ny = ny0+dy y0 = y00 ENDELSE END 3: BEGIN IF (dx GT nx0) THEN BEGIN x0 = x00+nx0 nx = dx-nx0 ENDIF ELSE BEGIN x0 = x00+dx nx = nx0-dx ENDELSE IF (dy LE -ny0) THEN BEGIN ny = -(ny0+dy) y0 = y00-ny ENDIF ELSE BEGIN ny = ny0+dy y0 = y00 ENDELSE END ENDCASE ENDIF PLOTS, px, py, col=color, /dev, thick=1, lines=0 ;Erase previous box EMPTY ;Decwindow bug ;-- in case of a problem, set graphics device back (IDL ge 4) if idl_release(lower=4,/inc) then begin error_status=0 catch,error_status if (error_status ne 0) and (n_elements(old) ne 0) then begin device,set_graphics=old return endif endif IF !err EQ 4 THEN BEGIN ;Quitting? DEVICE,set_graphics = old RETURN ENDIF middle: IF NOT KEYWORD_SET(anywhere) THEN BEGIN ;--------------------------------------------------------------------------- ; Never allow the box to be outside window ;--------------------------------------------------------------------------- x0 = x0 > 0 y0 = y0 > 0 x0 = x0 < (!d.x_size-1 - nx) y0 = y0 < (!d.y_size-1 - ny) ENDIF ELSE BEGIN x0 = x0 > (-nx) y0 = y0 > (-ny) x0 = x0 < (!d.x_size-1) y0 = y0 < (!d.y_size-1) ENDELSE IF ok THEN BEGIN event.x = x0 event.y = y0 CALL_PROCEDURE, event_pro, event ENDIF px = [x0, x0 + nx, x0 + nx, x0, x0] ;X points py = [y0, y0, y0 + ny, y0 + ny, y0] ;Y values PLOTS,px, py, col=color, /dev, thick=1, lines=0 ;Draw the box wait, .1 ;Dont hog it all ENDWHILE END