Viewing contents of file '../idllib/contrib/buie/cw_pixed.pro'
;+
; NAME:
; cw_pixed
; PURPOSE: (one line)
; Pixel editor.
; DESCRIPTION:
; This compound widget may be used to edit a grid of pixels in an array.
; Unless near the edge of the image, the grid is centered on (xpos, ypos).
; The left column and the bottom row display the y and x coordinates,
; respectively, for the grid. Xpos and ypos are enclosed in brackets,
; for identification.
; CATEGORY:
; Compound Widgets
; CALLING SEQUENCE:
; result = cw_pixed( parent, image, xpos, ypos )
; INPUTS:
; parent : The id of the parent widget.
; image : The array to be edited.
; xpos, ypos : The pixel at this location in the array, along with a
; collection of its neighbors, will be displayed as a grid of
; editable text widgets.
;
; OPTIONAL INPUT PARAMETERS:
;
; INPUT KEYWORD PARAMETERS:
; GRIDSIZE = The size of the grid of surrounding pixels. Default
; is 7 pixels (7X7 grid). Note: In order to maintain symmetry
; about the center pixel, the grid size needs to be odd.
; Therefore, even values will be increased by 1 pixel.
;
; OUTPUTS:
; result : The id of the compound widget.
; COMMON BLOCKS:
;
; SIDE EFFECTS:
; This compound widget generates events with the following structure:
; { id:0L, top:0L, handler:0L, type:0, count:0, x:0, y:0, value:v }
; where,
; type The event type (0=Done, 1=single pixel changed).
; count Specifies the number of elements in the remaining three tags
; x and y Coordinates of changed pixel(s).
; value Value(s) for changed pixel(s).
;
; The zero values in the above structure indicate the data types for the
; those tags, not the actual values. The 'value' tag will be the same type
; as the data in the array being edited.
;
; RESTRICTIONS:
;
; PROCEDURE:
;
; MODIFICATION HISTORY:
; Written by Doug Loucks, Lowell Observatory, April 28, 1994.
; 95/10/31, MWB, Fixed widget layout problem caused by IDL v4.0 changes.
;-
; ------------------------------------------------------------------------------
; Procedure cw_pixed_eve
; Event handler.
; ------------------------------------------------------------------------------
FUNCTION cw_pixed_eve, event
WIDGET_CONTROL, event.id, GET_VALUE=value, GET_UVALUE=uvalue, /HOURGLASS
stash = WIDGET_INFO( event.handler, /CHILD )
WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY
out_event = 0
CASE event.id OF
state.doneid : BEGIN
child = WIDGET_INFO( event.top, /CHILD )
WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY
WIDGET_CONTROL, event.top, MAP=0
WIDGET_CONTROL, child, /DESTROY
RETURN, 0
END
state.restoreid : BEGIN
w = WHERE( state.chgdids GT 0, count )
IF count GT 0 THEN BEGIN
x = INTARR( count )
y = INTARR( count )
v = REPLICATE( state.tval, count )
FOR j=0, count-1 DO BEGIN
WIDGET_CONTROL, state.chgdids[w[j]], GET_UVALUE=uv
x[j] = uv.x
y[j] = uv.y
v[j] = state.savgrid[ uv.x, uv.y ]
text = STRING( v[j], FORMAT=state.fmt )
WIDGET_CONTROL, state.chgdids[w[j]], SET_VALUE=text
state.chgdids[ w[j] ] = 0
ENDFOR
out_event = { id:event.handler, top:event.top, handler:0L, type:1, $
count:count, x:state.xset+x, y:state.yset+y, value:v }
ENDIF
END
ELSE : BEGIN
WIDGET_CONTROL, event.id, GET_VALUE=value, GET_UVALUE=uvalue
x = uvalue.x
y = uvalue.y
state.grid[ x, y ] = value[0]
out_event = { id:event.handler, top:event.top, handler:0L, type:1, $
count:1, x:[state.xset+x], y:[state.yset+y], value:[state.tval] }
state.chgdids[ x, y ] = event.id
out_event.value = value[0]
END
ENDCASE
WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY
RETURN, out_event
END
; ------------------------------------------------------------------------------
; Procedure cw_pixed
; Compound Widget Pixel Editor.
; ------------------------------------------------------------------------------
FUNCTION cw_pixed, parent, image, xpos, ypos, GRIDSIZE=in_gridsize, $
UVALUE=in_uvalue
stat = SIZE( image )
xsize = stat[1]
ysize = stat[2]
typecode = stat[3]
CASE typecode OF
1 : BEGIN
width = 4
fmt = '(I4)'
tval = 0B
END
2 : BEGIN
width = 6
fmt = '(I6)'
tval = 0
END
3 : BEGIN
width = 12
fmt = '(I12)'
tval = 0L
END
4 : BEGIN
width = 12
fmt = '(G0.0)'
tval = 0.0
END
5 : BEGIN
width = 14
fmt = '(G0.0)'
tval = 0.0
END
ELSE : BEGIN
MESSAGE, 'Error. Typecode ' + STRING(typecode,FORMAT='(G0.0)') + $
' not supported', /INFO
width = 12
fmt = '(G0.0)'
tval = 0.0
END
ENDCASE
IF KEYWORD_SET( in_gridsize ) THEN gridsize=in_gridsize ELSE gridsize=7
IF (gridsize MOD 2) EQ 0 THEN gridsize=gridsize+1
hw = gridsize / 2
xset = xpos - hw
yset = ypos - hw
IF xset LT 0 THEN xset = 0
IF yset LT 0 THEN yset = 0
IF xset+gridsize GE xsize THEN xset=xsize-gridsize
IF yset+gridsize GE ysize THEN yset=ysize-gridsize
IF !order EQ 0 THEN BEGIN
y1 = gridsize - 1
y2 = 0
dy = -1
ENDIF ELSE BEGIN
y1 = 0
y2 = gridsize - 1
dy = 1
ENDELSE
state = { chgdids:LONARR(gridsize, gridsize), doneid:0L, $
fmt:fmt, $
grid:REPLICATE( tval, gridsize, gridsize ), gridsize:gridsize, $
restoreid:0L, $
savgrid:REPLICATE( tval, gridsize, gridsize ), $
xset:xset, yset:yset, xpos:xpos, ypos:ypos, $
xids:LONARR(gridsize,/NOZERO), yids:LONARR(gridsize,/NOZERO), $
gridids:LONARR(gridsize, gridsize,/NOZERO), tval:tval }
state.grid = image[xset:xset+gridsize-1, yset:yset+gridsize-1 ]
state.savgrid = image[xset:xset+gridsize-1, yset:yset+gridsize-1 ]
IF KEYWORD_SET( in_uvalue ) THEN BEGIN
mainbase = WIDGET_BASE( parent, COLUMN=1, EVENT_FUNC='cw_pixed_eve', $
UVALUE=in_uvalue )
ENDIF ELSE BEGIN
mainbase = WIDGET_BASE( parent, COLUMN=1, EVENT_FUNC='cw_pixed_eve' )
ENDELSE
f = '(G0.0)'
wb = WIDGET_BASE( mainbase, ROW=1 )
state.doneid = WIDGET_BUTTON( wb, VALUE='Done' )
state.restoreid = WIDGET_BUTTON( wb, VALUE='Restore Initial Values' )
cba = WIDGET_BASE( mainbase, COLUMN=gridsize+1, /FRAME )
FOR j=y1, y2, dy DO BEGIN
text = STRING( yset+j, FORMAT=f )
mark = (yset+j) EQ ypos
IF mark THEN text = '[' + text + ']'
state.yids[j] = WIDGET_LABEL( cba, VALUE=text )
ENDFOR
w0 = WIDGET_LABEL( cba, VALUE=' ' )
FOR i=0, gridsize-1 DO BEGIN
FOR j=y1, y2, dy DO BEGIN
text = STRING( image[xset+i, yset+j], FORMAT=f )
w0 = WIDGET_TEXT( cba, VALUE=text, UVALUE={x:i, y:j}, XSIZE=width, /EDIT )
state.gridids[i,j] = w0
ENDFOR
text = STRING( xset+i, FORMAT=f )
mark = (xset+i) EQ xpos
IF mark THEN text = '[' + text + ']'
state.xids[i] = WIDGET_LABEL( cba, VALUE=text )
ENDFOR
;
; scan through all the items in this base and find the max x and y sizes.
max_xs=0
max_ys=0
t_b = WIDGET_INFO(cba, /CHILD) ; gets first child
WHILE (t_b NE 0L) DO BEGIN
geo = WIDGET_INFO(t_b, /GEOMETRY)
max_xs=max([max_xs,geo.scr_xsize])
max_ys=max([max_ys,geo.scr_ysize])
t_b = WIDGET_INFO(t_b, /SIBLING) ; gets next child (0=no more)
ENDWHILE
t_b = WIDGET_INFO(cba, /CHILD)
WHILE (t_b NE 0L) DO BEGIN
WIDGET_CONTROL, t_b, SCR_XSIZE=max_xs, SCR_YSIZE=max_ys
t_b = WIDGET_INFO(t_b, /SIBLING)
ENDWHILE
; -----------------------------
m = MEDIAN( state.grid )
xp = xpos - xset
yp = ypos - yset
x = INDGEN( gridsize )
ya = state.grid[ xp, * ]
yb = state.grid[ *, yp ]
w = WHERE( x NE xp, count )
coeff1 = goodpoly( x[w]+xpos, ya[w], 1, 3.0, yfit )
coeff2 = goodpoly( x[w]+ypos, yb[w], 1, 3.0, yfit )
ny1 = POLY( xpos, coeff1 )
ny2 = POLY( ypos, coeff2 )
text = STRING( 'Grid Median: ', m, ' Linear Interpolation, Row: ', ny2, $
' Column: ', ny1, FORMAT='(A,G0.0,A,G0.0,A,G0.0)' )
w0 = WIDGET_LABEL( mainbase, VALUE=text )
; -----------------------------
stash = WIDGET_INFO( mainbase, /CHILD )
WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY
RETURN, mainbase
END