;+ ; NAME: ; qImage_cw ; PURPOSE: ; Also contains qImage_cw_Event ; Display and manipulate single image ; CATEGORY: ; Compound widget qImage_cw ; CALLING SEQUENCE: ; wid = qImage_cw(wid_parent, uvalue=uvalue) ; INPUTS: ; wid_parent scalar; type: long integer ; ID of the parent widget ; OPTIONAL INPUT PARAMETERS: ; uvalue=uvalue anything; user-defined ; OUTPUTS: ; (none) ; CALLS: ; qImage_cw_Update, qImage_cw_Mouse, qImage_cw_CrossSection, qImage_cw_Box ; qImage_cw_Slider, qImage_cw_SMEI, qImage_cw_ZUpdate ; qImage_cw_WedgeSection, qImage_cw_Set_Value, qImage_cw_Zoom, ; qImage_cw_SmeiMask, qImage_cw_Where ; InitVar, IsType ; EXTERNAL: ; qImage_cw_state__define ; PROCEDURE: ; The state structure used is the following: ; ; state = {STATE_QIMAGE_CW, $ ; ; wid_win : lonarr( 2), $ cw_field's for window size (horizontal and vertical) ; user value: actual size of current window ; wid_xyz : lonarr(10), $ cw_field's for positional and intensity (z-value) ; image information ; user value: none ; wid_xyz[8] x-coordinate of center of mass (centroid) ; user value: array[2]; type: double: the centroid again ; wid_xyz[9] y-coordinate of center of mass (centroid) ; user value: array[3]; type: float; background used for centroid ; calculation, # pixels in center area, # pixels in background area ; wid_draw_wrap : 0L, $ ; wid_draw : 0L, $ draw widget; main display ; wid_blowup : 0L, $ draw widget; displays a small blowup centered on the current box ; user value: none ; wid_xcross : 0L, $ draw widget; displays horizontal cross section ; user value: none ; wid_ycross : 0L, $ draw widget: displays vertical cross section ; user value: none ; wid_image : 0L, $ base widget; 2nd child of the root widget ; user value: array[*,*,2], the image ; wid_xslide : 0L, $ slider for moving the center of the display horizontally ; user value: scalar; horizontal index of pixel in magnified image ; at lower left corner of window ; wid_yslide : 0L, $ slider for moving the center of the display vertically ; user value: scalar; vertical index of pixel in magnified image ; at lower left corner of window ; ; wid_tool : 0L, $ non-exclusive button: on/off button for tool widget ; user value: the state of the tool widget ; wid_smei : 0L, $ non-exclusive button; on/off button for using wedge instead of square ; user value: 0 or 1; updated when button is pressed ; wid_smei_base : 0L, $ ; wid_prorate : lonarr(3), $ non-exclusive button: on/off button for pro-rating z-values ; user value: 0 or 1; updated when button is pressed ; wid_center : lonarr(2), $ cw_field's for the center of the SMEI fov ; get: qimage_cw_box, qimage_zupdate ; user value: none ; wid_phi : lonarr(4), $ cw_field's for setting the azimuthal extent of a wedge ; (min- and max azimuth, azimuth step size ; [0:1]: min & max azimuth: get/set in qimage_cw_box ; [2 ] azimuthal step size: get in qimage_cw_wedgesection ; [3 ]: centroid azimuth : set in qimage_cw_zupdate ; user value: none ; wid_rad : lonarr(4), $ cw_field's for setting the radial extent of a wedge ; (min- and max radius, radial step size ; [0:1]: min & max radius : get/set in qimage_cw_box ; [2 ]: radial step size : get in qimage_cw_wedgesection ; [3 ]: centroid radius : set in qimage_cw_zupdate ; user value: none ; wid_azimuthal : 0L, $ button for initiating qLine widget for azimuthal section ; user value: none ; wid_radial : 0L, $ button for initiating qLine widget for radial section ; user value: none ; wid_smeifov : 0L, $ button for resetting wedge size to the full SMEI fov ; user value: none ; wid_smeimask : 0L, $ user value: none ; button for writing mask for SMEI fov to file ; wid_cos : 0L, $ non-exclusive button for activating cosine correction ; user-value: current setting ; wid_axis : lonarr(2), $ cw_field widgets for position of optical axis ; user value: none ; wid_background : 0L, $ cw_field widgets for constant pedestal ; user value: extra pedestal used for centroid calculation ; wid_zavg2back : 0L, $ button for transferring current average to wid_background ; user value: none ; img_size : intarr(2), $ array[2]; dimensions of the image on display ; set: qImage_cw, qImage_cw_Set_Value ; img_offset : intarr(2) $ array[2]; position of lower left corner of image ; on display if extracted from a larger image ; the offset iz [0,0] unless set by the widget ; calling qImage_cw ; } ; MODIFICATION HISTORY: ; JAN-2000, Paul Hick (UCSD/CASS; pphick@ucsd.edu) ;- FUNCTION qImage_cw_Event, event @compile_opt.pro ; On error, return to caller wid_self = event.handler wid_child = widget_info(wid_self, /child) widget_control, wid_child, get_uvalue=state, /no_copy set_image_value = 0B ; First check for pseudo events event_name = tag_names(event, /structure_name) CASE event.id OF ; ID of widget that generated the message ; The only events from wid_self should be be QIMAGE_CW_UPDATE events generated ; by the qImage_cw_Set_Value procedure wid_self : qImage_cw_Update, state, /fresh ; Process click and motion events from the draw widget state.wid_draw: BEGIN right_button = event.press EQ 4 OR event.release EQ 4 CASE right_button OF 0: qImage_cw_Mouse, state, event 1: set_image_value = qImage_cw_Where(state, event) ; Ped,drk,etc. ENDCASE END state.wid_xcross: IF event.type EQ 0 THEN qImage_cw_CrossSection, state state.wid_ycross: IF event.type EQ 0 THEN qImage_cw_CrossSection, state state.wid_win[0]: set_image_value = event.update state.wid_win[1]: set_image_value = event.update state.wid_xyz[0]: IF event.update THEN BEGIN & qImage_cw_Box, state, /get, /put & qImage_cw_Update, state & ENDIF state.wid_xyz[1]: IF event.update THEN BEGIN & qImage_cw_Box, state, /get, /put & qImage_cw_Update, state & ENDIF state.wid_xyz[2]: IF event.update THEN BEGIN & qImage_cw_Box, state, /get, /put & qImage_cw_Update, state & ENDIF state.wid_xyz[3]: IF event.update THEN BEGIN & qImage_cw_Box, state, /get, /put & qImage_cw_Update, state & ENDIF state.wid_phi[0]: IF event.update THEN BEGIN & qImage_cw_Box, state, /polar & qImage_cw_Update, state & ENDIF state.wid_phi[1]: IF event.update THEN BEGIN & qImage_cw_Box, state, /polar & qImage_cw_Update, state & ENDIF state.wid_rad[0]: IF event.update THEN BEGIN & qImage_cw_Box, state, /polar & qImage_cw_Update, state & ENDIF state.wid_rad[1]: IF event.update THEN BEGIN & qImage_cw_Box, state, /polar & qImage_cw_Update, state & ENDIF state.wid_center[0]: IF event.update THEN BEGIN & qImage_cw_Box, state, /polar & qImage_cw_Update, state & ENDIF state.wid_center[1]: IF event.update THEN BEGIN & qImage_cw_Box, state, /polar & qImage_cw_Update, state & ENDIF ;state.wid_fixzoom : BEGIN ; CASE event.select OF ; 0: widget_control, state.wid_fixzoom, get_uvalue=anchor, /no_copy ; 1: BEGIN ; qImage_cw_Box, state, anchor, /get ; Center of current box is used to anchor the zoom ; anchor = qImage_cw_Transform(state, fromimage=0.5*total(anchor,2), /toscreen) ; widget_control, state.wid_fixzoom, set_uvalue=anchor, /no_copy ; END ; ENDCASE ;END state.wid_xslide : set_image_value = qImage_cw_Slider(state) state.wid_yslide : set_image_value = qImage_cw_Slider(state) state.wid_smei : set_image_value = qImage_cw_SMEI(state, event) state.wid_showfov : BEGIN widget_control, state.wid_showfov, set_uvalue=event.select widget_control, state.wid_smei, get_uvalue=smei_set IF smei_set THEN BEGIN CASE event.select OF 0: set_image_value = 1B 1: qImage_cw_Update, state, /no_zupdate ENDCASE ENDIF END state.wid_zavg2back: BEGIN widget_control, state.wid_xyz[6], get_value=value widget_control, state.wid_background, set_value=value qImage_cw_ZUpdate, state END state.wid_background: qImage_cw_ZUpdate, state state.wid_prorate[0]: BEGIN widget_control, state.wid_prorate[2], get_uvalue=set IF set THEN qImage_cw_ZUpdate, state END state.wid_prorate[1]: BEGIN widget_control, state.wid_prorate[2], get_uvalue=set IF set THEN qImage_cw_ZUpdate, state END state.wid_prorate[2]: BEGIN widget_control, state.wid_prorate[2], set_uvalue=event.select qImage_cw_ZUpdate, state END state.wid_cos: BEGIN widget_control, state.wid_cos, set_uvalue=event.select set_image_value = 1B END state.wid_axis [0]: widget_control, state.wid_cos, get_uvalue=set_image_value state.wid_axis [1]: widget_control, state.wid_cos, get_uvalue=set_image_value state.wid_corner[0]: widget_control, state.wid_cos, get_uvalue=set_image_value state.wid_corner[1]: widget_control, state.wid_cos, get_uvalue=set_image_value state.wid_corner[2]: widget_control, state.wid_cos, get_uvalue=set_image_value state.wid_corner[3]: widget_control, state.wid_cos, get_uvalue=set_image_value state.wid_azimuthal: qImage_cw_WedgeSection, state, /azimuthal state.wid_radial : qImage_cw_WedgeSection, state, /radial state.wid_show : state.wid_tool : set_image_value = qImage_cw_Tool (state, event) state.wid_ephem : set_image_value = qImage_cw_Ephem(state, event) state.wid_save : qImage_cw_Save, state, event state.wid_smeifov : BEGIN qImage_cw_Box, state, /smeifov qImage_cw_Update, state END state.wid_smeimask : qImage_cw_SmeiMask, state, event ELSE: unexpected_event, event ENDCASE wid_image = state.wid_image widget_control, wid_child, set_uvalue=state, /no_copy IF set_image_value THEN BEGIN widget_control, wid_image, get_uvalue=image, /no_copy IF IsType(image, /defined) THEN widget_control, wid_self, set_value=image ENDIF ; A QIMAGE_CW_UPDATE event (issued after a new image has been put on the ; display by qImage_cw_Set_Value) is passed to the event handler of the parent ; widget. All other events are absorbed here. IF event_name NE 'QIMAGE_CW_UPDATE' THEN event = 0L RETURN, event & END FUNCTION qImage_cw, wid_parent, uvalue=uvalue @compile_opt.pro ; On error, return to caller IF IsType(wid_parent, /undefined) THEN message, 'No parent widget specified' ; State structure ; The state structure is stored as user value to the first child widget. ; If the ID of the root widget is known the state can be retrieved by ; ; wid_child = widget_info( id_root, /child) ; widget_control, wid_child, get_uvalue=state ; ; The state consist of: ; - the widget id of all widgets making up the compound widget ; state = {qimage_cw_state} ; Create state structure ; Set the user value if not specified InitVar, uvalue, -1 wid_self = widget_base(wid_parent, uvalue=uvalue, /column , $ event_func = 'qImage_cw_Event' , $ pro_set_value = 'qImage_cw_Set_Value' ) ; Called when setting value state.wid_self = wid_self state.wid_parent = wid_parent nx = 0 ny = 0 zmin = 0. zmax = 0. zave = 0. zstd = 0. ; The first child widget contains widgets for defining a box in the input image ; (This is the widget where the state structure is stored as user value) ; dummy = widget_label(wid_img_xyz,xsize=15,value='') wid_img_xyz = widget_base(wid_self, /column, frame=1) dummy1 = widget_base(wid_img_xyz, /row) lxsize = 30 dummy = widget_base(dummy1, /column) state.wid_win[0] = cw_field(dummy, value= 0, /integer, title='X-sz', /row, xsize=6, /all_ev, lxsize=lxsize) state.wid_win[1] = cw_field(dummy, value= 0, /integer, title='Y-sz', /row, xsize=6, /all_ev, lxsize=lxsize) dummy = widget_base(dummy1, /column) state.wid_xyz[0] = cw_field(dummy, value= 0, /integer, title='X-min', /row, xsize=6, /all_ev, lxsize=lxsize) state.wid_xyz[2] = cw_field(dummy, value= 0, /integer, title='Y-min', /row, xsize=6, /all_ev, lxsize=lxsize) dummy = widget_base(dummy1, /column) state.wid_xyz[1] = cw_field(dummy, value=nx-1, /integer, title='X-max', /row, xsize=6, /all_ev, lxsize=lxsize) state.wid_xyz[3] = cw_field(dummy, value=ny-1, /integer, title='Y-max', /row, xsize=6, /all_ev, lxsize=lxsize) dummy = widget_base(dummy1, /column) state.wid_xyz[8] = cw_field(dummy, value= 0, /floating, title='X-com', /row, xsize=6, /all_ev, lxsize=lxsize) state.wid_xyz[9] = cw_field(dummy, value= 0, /floating, title='Y-com', /row, xsize=6, /all_ev, lxsize=lxsize) dummy = widget_base(dummy1, /column) state.wid_xyz[4] = cw_field(dummy, value=zmin, /floating, title='Z-min' ,/row,xsize=6, /noedit, lxsize=lxsize) state.wid_xyz[5] = cw_field(dummy, value=zmax, /floating, title='Z-max' ,/row,xsize=6, /noedit, lxsize=lxsize) dummy = widget_base(dummy1, /column) state.wid_xyz[6] = cw_field(dummy, value=zave, /floating, title='Z-avg' ,/row,xsize=6, /noedit, lxsize=lxsize) state.wid_xyz[7] = cw_field(dummy, value=zstd, /floating, title='Z-std' ,/row,xsize=6, /noedit, lxsize=lxsize) ; The second child widget contain widgets to manipulate the state of the image ; The user value of this widget is used to store the image wid_image = widget_base(wid_self, /row) ;dummy = widget_base(wid_image, /row, /nonexclusive) ; state.wid_whitebox = widget_button(dummy, value='White', uvalue=0) dummy = widget_label(wid_image, xsize=15, value='') ;dummy = widget_base(wid_image, /row, /nonexclusive) ; state.wid_fixzoom = widget_button(dummy, value='Anchor') dummy = widget_label(wid_image, xsize=5, value='') state.wid_zavg2back = widget_button(wid_image, value='Z-avg -->') state.wid_background = cw_field(wid_image, /floating, title='Pedestal', value=0, uvalue=0, xsize=6, lxsize=lxsize+18, /return_ev) dummy = widget_base(wid_image, /row, /nonexclusive) state.wid_show = widget_button(dummy, value='Show') state.wid_tool = widget_button(dummy, value='Tool') state.wid_save = widget_button(dummy, value='Save') state.wid_ephem = widget_button(dummy, value='Ephem' , kill_notify='qImage_cw_EphemKill') state.wid_smei = widget_button(dummy, value='SMEI' , uvalue=0) state.wid_showfov = widget_button(dummy, value='Show fov', uvalue=0) widget_control, state.wid_tool, kill_notify='qImage_cw_ToolKill', set_uvalue= $ {qImage_cw_Tool_state , $ wid_base : 0L , $ wid_send : state.wid_tool , $ ;on : 0 , $ ;update : 0 , $ img_box : ptr_new(/allocate) , $ mouse : replicate(-1L,5) , $ send : qTool_State() } state.wid_image = wid_image state.img_size = [nx,ny] state.img_offset = [0,0] ; Store the state structure in the user value of the first child widget widget_control, widget_info(wid_self, /child), set_uvalue=state, /no_copy ; Return the widget ID of the root widget RETURN, wid_self & END