FORWARD_FUNCTION cwimg_preview, cwimg_preview_event, $ cwimg_preview_set_value, cwimg_preview_get_value ;;----------------------------------------------------------------------------- ;; PURPOSE: ;; Creates a widget that shows a preview of a FITS image. This widget can ;; either be embedded in an existing window by specifying parent, or ;; can be a new window which apprears to the right of the window ;; containing the group_leader. If the preview is in a seperate window, ;; resizing the window causes the image to shrink/expand ;; ;; CALLING SEQUENCE: ;; ID = cwimg_preview(parent, UNAME=uname, UVALUE=uvalue, VALUE=value, $ ;; XSIZE=xsize, YSIZE=ysize, TITLE=title, RETAIN=retain, $ ;; ORDER=order, GROUP_LEADER=group_leader, /NO_COPY, $ ;; KILL_NOTIFY=kill_notify) ;; ;; REQUIRED INPUTS: ;; ;; OUTPUTS: ;; The widget ID of the compound widget ;; ;; OPTIONAL INPUT KEYWORDS: ;; parent - The parent of this widget. If not specified, a new window is ;; created ;; UNAME - User name ;; UVALUE - User value ;; VALUE - The image to display ;; XSIZE - The display width of the image (default = 256) ;; YSIZE - The display height of the image (default = 256) ;; TITLE - Title for the new window if it is created ;; RETAIN - Passed directly to the draw_widget function ;; ORDER - Passed directly to the TV procedure ;; GROUP_LEADER - The leader of the group this widget belongs to ;; NO_COPY - If a copy of value and uvalue should be made on creation ;; KILL_NOTIFY - Procedure to call when the widget is destroyed ;; ;; EVENTS PRODUCED: ;; No event is returned ;; ;; EXAMPLE: ;; IDL> preview = cwimg_preview(GROUP_LEADER=main) ;; ;; PROCEDURES USED (i.e. called directly!): ;; ;; MODIFICATION HISTORY: ;; 2004-07-30 M. Desnoyer Created ;; ;;----------------------------------------------------------------------------- ;;--------------------------- ;; Event Handler ;;--------------------------- PRO cwimg_preview_event, ev ;; Get the data we need from the object draw = widget_info(ev.handler, /child) widget_control, draw, get_uvalue=uval, /no_copy type = tag_names(ev, /structure_name) IF type EQ 'WIDGET_BASE' THEN BEGIN ;; Resize event ;; Make sure we're allowed to resize IF uval.doResize EQ 0 THEN BEGIN GOTO, ret ENDIF ;; Create a timer so that resizing doesn't occur too quickly widget_control, ev.ID, timer=0.05 uval.doResize = 0 ;; Resize the draw area draw = widget_info(ev.handler, /child) widget_control, draw, get_value=drawWind, xsize=ev.x, ysize=ev.y ;; Redraw the image curWind = !D.WINDOW stretch = congrid(uval.img, ev.x, ev.y) wset, drawWind tv, stretch, order=uval.order wset, curWind ENDIF ELSE IF type EQ 'WIDGET_TIMER' THEN BEGIN uval.doResize = 1 ENDIF ret: ;; Cleanup widget_control, draw, set_uvalue=uval, /no_copy RETURN END ;;--------------------------- ;; Set Value Handler ;;--------------------------- PRO cwimg_preview_set_value, id, value ;; Get the draw window draw = widget_info(id, /child) n = n_elements(value) h = histogram(value, reverse=r) tot = total(h, /cumulative, /nan) mini = where(tot LT n/100) maxi = where(tot GT n/100*99) minScl = max(value[r[r[mini[0]:mini[n_elements(mini)-1]]]]) maxScl = min(value[r[r[maxi[0]:maxi[n_elements(maxi)-1]]]]) scaled = (value-minScl)*!D.TABLE_SIZE/(maxScl-minScl) ;; Set the value widget_control, draw, set_uvalue={img:scaled,scl:[minScl,maxScl],doresize:1B}, $ /no_copy ;; Get the window to resize geom = widget_info(id, /geometry) cwimg_preview_event, {WIDGET_BASE, ID:id, TOP:id, HANDLER:id, X:geom.xsize, $ Y:geom.ysize} RETURN END ;;--------------------------- ;; Get Value Handler ;;--------------------------- FUNCTION cwimg_preview_get_value, id, value ;; Get the internal values draw = widget_info(id, /CHILD) widget_control, draw, get_uvalue=vals, /no_copy ;; Convert the internal scaled version to original out = vals.img*(scl[1]-sc[0])/255+scl[0] ;;Replace the internal values widget_control, draw, set_uvalue=vals, /no_copy RETURN, out END ;;--------------------------- ;; Handle color table changes ;;--------------------------- PRO cwimg_preview_refresh, id ;; Make sure we're in greater than 256 colors and need to redraw Device, Get_visual_depth=visDep IF visDep LE 8 THEN RETURN device, decomposed=0 ;; The data is the widget ID of the top level geom = widget_info(id, /geometry) ;; Fake a resize event (which will cause the picture to be redrawn) cwimg_preview_event, {WIDGET_BASE, ID:id, TOP:id, HANDLER:id, X:geom.xsize, $ Y:geom.ysize} END ;;--------------------------- ;; Widget Creation Function ;;--------------------------- FUNCTION cwimg_preview, parent, UNAME=uname, UVALUE=uvalue, VALUE=value, $ XSIZE=xsize, YSIZE=ysize, TITLE=title, RETAIN=retain, ORDER=order, $ GROUP_LEADER=group_leader, NO_COPY=no_copy, KILL_NOTIFY=kill_notify ;; Default the keywords IF NOT keyword_set(UVALUE) THEN uvalue=0 IF NOT keyword_set(UNAME) THEN uname='CWIMG_PREVIEW' IF NOT keyword_set(VALUE) THEN value=0 IF NOT keyword_set(XSIZE) THEN xsize=256 IF NOT keyword_set(YSIZE) THEN ysize=256 IF NOT keyword_set(TITLE) THEN title='Image Preview' IF NOT keyword_set(ORDER) THEN order=!order ;; Get the current window curWind = !D.WINDOW ;; Figure out where the window should be placed IF keyword_set(GROUP_LEADER) THEN BEGIN geom = widget_info(group_leader, /geometry) xoffset = geom.scr_xsize + geom.xoffset + geom.xpad ENDIF ;; Create the widget IF n_params() EQ 0 THEN $ base = widget_base( uname=uname, uvalue=uvalue, title=title, $ group_leader=group_leader, no_copy=no_copy, $ pro_set_value='cwimg_preview_set_value', xoffset=xoffset,$ func_get_value='cwimg_preview_get_value', /tlb_size_events, $ kill_notify=kill_notify) $ ELSE IF n_params() EQ 1 THEN $ base = widget_base(parent, uname=uname, uvalue=uvalue, title=title, $ group_leader=group_leader, no_copy=no_copy, $ pro_set_value='cwimg_preview_set_value', xoffset=xoffset, $ func_get_value='cwimg_preview_get_value', $ kill_notify=kill_notify)$ ELSE message, 'Invalid number of parameters' ;; Remove the outlier values from the image minScl = min(value,/nan) maxScl = max(value,/nan) scaled = (value-minScl)*!D.TABLE_SIZE/(maxScl-minScl) ;; Draw the image stretch = congrid(scaled, xsize,ysize) draw = widget_draw(base, uvalue={img:scaled,scl:[minScl,maxScl],doresize:1B, $ order:order}, /no_copy, retain=retain, xsize=xsize, ysize=ysize, $ uname='draw') ;; Display the picture widget_control, base, /realize widget_control, draw, get_value=drawWind wset, drawWind tv, stretch, order=order ;; Set up the xmanager for the resize events xmanager, 'CWIMG_PREVIEW', base, event_handler='cwimg_preview_event', $ group_leader=group_leader, /NO_BLOCK wset, curWind RETURN, base END