PRO qImage_cw_Box, state, box, get=get, put=put, polar=polar, $ p_box=p_box, smeifov=smeifov, fullsize=fullsize, center=center ;+ ; NAME: ; qImage_cw_Box ; PURPOSE: ; Set or retrieve the values of the current box boundaries ; CATEGORY: ; Compound widget qImage_cw ; CALLING SEQUENCE: ; qImage_cw_Box, state, box, fullsize=fullsize, oldbox=oldbox, get=get, nobox=nobox ; qImage_cw_Box, state, box, /center ; INPUTS: ; state array[1]; type: structure ; qImage_cw state structure ; box array[2,2]; type: integer ; defines two corners of box in the form [ [x1,y1], [x2,y2] ] ; OPTIONAL INPUT PARAMETERS: ; /polar get a box in polar coordinates; then use it to update ; the box widgets. ; The box in polar coordinates is selected as ; - keyword p_box if /put is set ; - set to the SMEI fov is /smeifov is set ; - read from the polar box widgets in the SMEI widget section ; The polar box is then used to update all box widgets as if ; /put was set. ; ; If /put and /polar are set: ; ; p_box=p_box array[2,2]; float ; limiting values in azimuth and radius of the wedge-shaped ; area corresponding to the two corners of 'box' ; in the form [[angle1,radius1],[angle2,radius2]]. ; Angle1 and angle2 are in radians between [-!pi,+!pi]. ; The wedge runs counterclockwise from 'angle1' to 'angle2' ; over less than 180 degrees: either angle2 > angle1 with ; angle2-angle1 < !pi or angle2 < angle1 with ; angle+2*!pi-angle1 < !pi. Always radius1 < radius2. ; ; The pixel coordinates of the two corners are rounded to the ; nearest integer value. ; ; /smeifov setting /smeifov, implies setting /polar and /put. ; Selects the full SMEI fov (retrieved from the widget). ; ; /fullsize setting this keyword is the same as setting box to the full size of the ; image: box = [ [0,0], [state.img_size-1] ] ; /get retrieves the current settings, and returns them in 'box' ; /put updates the current setting using the values in 'box' ; (this is the default if neither /put nor /get are set) ; /center if set then the center for polar transformations is returned ; (with the state.img_offset subtracted) in 'box'. ; 'p_box' returns the full SMEI FOV. ; ; OUTPUTS: ; If keyword /get is set: ; ; box array[2,2]; type: integer ; defines two corners of box in the form [ [x1,y1], [x2,y2] ] ; p_box=p_box array[2,2]; float ; limiting values in azimuth and radius of the wedge-shaped ; area corresponding to the two corners of 'box' ; in the form [[angle1,radius1],[angle2,radius2]]. ; Angle1 and angle2 are in radians between [-!pi,+!pi]. ; The wedge runs counterclockwise from 'angle1' to 'angle2' ; over less than 180 degrees: either angle2 > angle1 with ; angle2-angle1 < !pi or angle2 < angle1 with ; angle+2*!pi-angle1 < !pi. Always radius1 < radius2. ; ; If keyword /center is set: ; ; box array[2]; type: integer ; the pixel coordinates of the center used for polar transformations ; p_box=p_box array[2,2]; float ; limiting values in azimuth and radius of the fov ; in the form [[angle1,radius1],[angle2,radius2]]. ; Angle1 and angle2 are in radians between [-!pi,+!pi]. ; The fov runs counterclockwise from 'angle1' to 'angle2'. ; INCLUDE: @compile_opt.pro ; On error, return to caller ; CALLS: ; InitVar ; SIDE EFFECTS: ; The pixel values displayed in the widget are usually pixel coordinates in the draw widget ; where the image is displayed. If state.img_offset is set to a non-zero value this will ; be added to the displayed numbers. ; ; Generally the state.img_offset is set by the calling widget to a non-zero value when ; the image fed to qImage_cw is a portion of a bigger image, and the user wants to see ; pixel location in the bigger array displayed by qImage_cw (rather than pixel ; locations in the smaller subimage). ; PROCEDURE: ; > Modification and retrieval of values in the widgets controlling the position of the box ; should be made with this routine only !!! ; > All sanity checks are made when the fields are updated. Retrieval is just a matter of ; reading the values of the wid_xyz[0:3] widgets. ; ; > The numbers in the x,y widget represent a square section in the image, specified as ; minimum and maximum x and y values. The values are usually input by two mouse ; clicks, i.e. two opposite corners of the square as pairs [x1,y1] and [x2,y2]. ; The point are then stored in the appropriate minimum and maximum x,y widgets. ; ; > The two corners of the box define a wedge-shaped area. The area is bounded by two ; circles and two radii (defined relative to the image center defined in the widget). ; Two of the corners of the wedge coincide with the two corners of 'box'. ; STATE INFO USED: ; widget_control, state.wid_xyz[0], get_value=get_value0 ; widget_control, state.wid_xyz[1], get_value=get_value2 ; widget_control, state.wid_xyz[2], get_value=get_value1 ; widget_control, state.wid_xyz[3], get_value=get_value3 ; ; state.img_size dimensions of array on display ; state.img_offset an offset between the pixel numbers displayed in the ; x,y widgets and the pixel coordinate in the image ; (see SIDE EFFECTS above). ; STATE INFO MODIFIED: ; widget_control, state.wid_xyz[0], set_value=set_value[0] ; widget_control, state.wid_xyz[2], set_value=set_value[1] ; widget_control, state.wid_xyz[1], set_value=set_value[2] ; widget_control, state.wid_xyz[3], set_value=set_value[3] ; MODIFICATION HISTORY: ; FEB-2000, Paul Hick (UCSD/CASS; pphick@ucsd.edu) ;- InitVar, center, /keyw InitVar, noflip, /key checkflip = 1-noflip widget_control, state.wid_smei, get_uvalue=smei_set IF center THEN BEGIN ; Retrieve the center for the polar transformation, and limits of the ; SMEI fov in polar coordinates. Note that these widgets exist only if the ; SMEI section of the widget is active (smei_set=1). widget_control, state.wid_center[0], get_value=x widget_control, state.wid_center[1], get_value=y box = [x,y]-state.img_offset widget_control, state.wid_corner[0], get_value=phi_b & phi_b = phi_b/!radeg widget_control, state.wid_corner[2], get_value=phi_e & phi_e = phi_e/!radeg widget_control, state.wid_corner[1], get_value=rad_b widget_control, state.wid_corner[3], get_value=rad_e p_box = [[phi_b,rad_b], [phi_e, rad_e]] RETURN ENDIF InitVar, fullsize , /key InitVar, smeifov , /key InitVar, polar , /key InitVar, get , /key InitVar, put , /key IF smeifov THEN polar = 1B IF (polar+get EQ 0) OR fullsize THEN put = 1B fullbox = [[0,0],[state.img_size-1]] nobox = [[0,0],[-1,-1]] IF polar THEN BEGIN CASE 1 OF put : box = p_box smeifov: BEGIN widget_control, state.wid_corner[0], get_value=phi_b & phi_b = phi_b/!radeg widget_control, state.wid_corner[2], get_value=phi_e & phi_e = phi_e/!radeg widget_control, state.wid_corner[1], get_value=rad_b widget_control, state.wid_corner[3], get_value=rad_e box = [[phi_b,rad_b], [phi_e, rad_e]] END ELSE: BEGIN widget_control, state.wid_phi[0], get_value=phi_b & phi_b = phi_b/!radeg widget_control, state.wid_phi[1], get_value=phi_e & phi_e = phi_e/!radeg widget_control, state.wid_rad[0], get_value=rad_b widget_control, state.wid_rad[1], get_value=rad_e box = [[phi_b,rad_b],[phi_e,rad_e]] END ENDCASE widget_control, state.wid_center[0], get_value=x widget_control, state.wid_center[1], get_value=y box = ([x,y]-state.img_offset)#[1,1]+cv_coord(from_polar=box, /to_rect) box = round(box) put = 1B ENDIF ; If no old box is specified read it from the widgets CASE get OF 0: put = 1B 1: BEGIN ; Read the widget values ;put = 0B CASE fullsize OF 0: BEGIN widget_control, state.wid_xyz[0], get_value=get_value0 widget_control, state.wid_xyz[1], get_value=get_value2 widget_control, state.wid_xyz[2], get_value=get_value1 widget_control, state.wid_xyz[3], get_value=get_value3 box = [ [get_value0, get_value1], [get_value2, get_value3]] no_box = (where(box NE nobox))[0] EQ -1 CASE no_box OF 0: box = box-state.img_offset#[1,1] 1: BEGIN box = fullbox put = 1B ; Needs to be put in widget END ENDCASE END 1: BEGIN box = full_box put = 1B ; Needs to be put in widget END ENDCASE END ENDCASE IF put THEN BEGIN ; Updating widgets ; nobox = 1 should only happen on the first pass, when this routine is called ; by qImage_cw_Set_Value after state.img_size has been set. ; A 'fullsize' request overrides the input box value InitVar, box, fullbox ;IF n_elements(box) EQ 0 THEN box = fullbox no_box = (where(box NE nobox))[0] EQ -1 IF no_box OR fullsize THEN box = fullbox no_box = (where(box NE nobox))[0] EQ -1 IF NOT no_box THEN BEGIN ; Make sure that the values are all in valid range ; (want to get rid of these two lines) ;no_img = (where(state.img_size EQ 0))[0] EQ 2 ;IF NOT no_img THEN box = (box > 0) < (state.img_size-1)#[1,1] IF smei_set THEN BEGIN widget_control, state.wid_center[0], get_value=x widget_control, state.wid_center[1], get_value=y p_box = cv_coord(from_rect=box-([x,y]-state.img_offset)#[1,1], /to_polar) IF p_box[2] LT p_box[0] THEN p_box[[0,2]] = p_box[[2,0]] IF p_box[3] LT p_box[1] THEN p_box[[1,3]] = p_box[[3,1]] ; Assume that the arc intended goes over less than 180 degrees ; Note that rad is not flipped if phi is: we need rad[0] < rad[1] IF p_box[2]-p_box[0] GT !pi THEN p_box[[0,2]] = p_box[[2,0]] widget_control, state.wid_phi[0], set_value= p_box[0]*!radeg widget_control, state.wid_phi[1], set_value= p_box[2]*!radeg widget_control, state.wid_rad[0], set_value= p_box[1] widget_control, state.wid_rad[1], set_value= p_box[3] ENDIF ; Make sure the the mimimum value is less than the maximum value. IF box[2] LT box[0] THEN box[[0,2]] = box[[2,0]] IF box[3] LT box[1] THEN box[[1,3]] = box[[3,1]] set_value = state.img_offset#[1,1]+box widget_control, state.wid_xyz[0], set_value=set_value[0] widget_control, state.wid_xyz[2], set_value=set_value[1] widget_control, state.wid_xyz[1], set_value=set_value[2] widget_control, state.wid_xyz[3], set_value=set_value[3] ENDIF ENDIF IF get AND smei_set THEN BEGIN widget_control, state.wid_phi[0], get_value= phi_b & phi_b = phi_b/!radeg widget_control, state.wid_phi[1], get_value= phi_e & phi_e = phi_e/!radeg widget_control, state.wid_rad[0], get_value= rad_b widget_control, state.wid_rad[1], get_value= rad_e p_box = [ [phi_b,rad_b], [phi_e,rad_e] ] ENDIF RETURN & END