Viewing contents of file '../idllib/contrib/buie/cw_tplat.pro'
;+
; NAME:
;    cw_tplat
; PURPOSE: (one line)
;    Create a photometry template widget.
; DESCRIPTION:
;    This compound widget is invoked on a Top Level Base (from The Template
; Manager) and represents an individual template.
;    Each template managed by The Template Manager has its own TLB and
; appears as a separate widget.
;    The template structure for each template is stored in the user-value of
; its TLB.
; CATEGORY:
;    Compound Widgets
; CALLING SEQUENCE:
;
; INPUTS:
;    parent : ID of parent base.
; OPTIONAL INPUT PARAMETERS:
;
; KEYWORD PARAMETERS:
;    UVALUE = Optional user-value.
;    VALUE  = The 'value' of the widget. Defined to be the template structure.
;             This value may be obtained, or set, by using the widget_control
;             procedure with its appropriate keywords. The value structure is:
;                {numobj:0, mode:0B, modified:0B, new:[1B], $
;                 objnam:['<default>'], x:[0.0], y:[0.0] }
; OUTPUTS:
;
; COMMON BLOCKS:
;
; SIDE EFFECTS:
;
; RESTRICTIONS:
;
; PROCEDURE:
;
; MODIFICATION HISTORY:
;    Written by Doug Loucks, Lowell Observatory, June 24, 1994. Adapted from
; a previous section of code in the main template manager procedure.
;    96/01/16 - MWB, fixed bug that crashed template manager after deleting
;                 objects from template.
;-
; ------------------------------------------------------------------------------
; Function cw_tplat_fmt
; Format the object names and coordinates for the list widget.
; ------------------------------------------------------------------------------
FUNCTION cw_tplat_fmt, tplate

IF tplate.numobj GT 0 THEN BEGIN
   ;Return the formatted object list.
   RETURN, STRING( INDGEN( tplate.numobj ), FORMAT='(I3)' ) + $
           STRING( tplate.objnam, FORMAT='(A20)' ) + $
           STRING( tplate.x, FORMAT='(F10.3)' ) + $
           STRING( tplate.y, FORMAT='(F10.3)' )
ENDIF ELSE BEGIN
   ;Return a null string.
   RETURN, ''
ENDELSE

END


; ------------------------------------------------------------------------------
; Function cw_tplat_gvl
; Get_value function.
; ------------------------------------------------------------------------------
FUNCTION cw_tplat_gvl, id
stash = WIDGET_INFO( id, /CHILD )
WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY

WIDGET_CONTROL, state.tplateid, GET_UVALUE=tplate

WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY

RETURN, tplate
END


; ------------------------------------------------------------------------------
; Procedure cw_tplat_svl
; Set_value procedure.
; ------------------------------------------------------------------------------
PRO cw_tplat_svl, id, tplate
stash = WIDGET_INFO( id, /CHILD )
WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY

WIDGET_CONTROL, state.tplateid, SET_UVALUE=tplate

IF tplate.numobj GT 0 THEN BEGIN
   WIDGET_CONTROL, state.objlistid, SET_VALUE=cw_tplat_fmt(tplate)
ENDIF ELSE BEGIN
   WIDGET_CONTROL, state.objlistid, SET_VALUE=''
ENDELSE

WIDGET_CONTROL, state.editid, SET_VALUE=''

WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY
END


; ------------------------------------------------------------------------------
; Function cw_tplat_eve
; Event Handler.
; ------------------------------------------------------------------------------
FUNCTION cw_tplat_eve, event
WIDGET_CONTROL, event.id, /HOURGLASS

bel = STRING(7B)

stash = WIDGET_INFO( event.handler, /CHILD )

WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY

out_event = 0

CASE event.id OF
   state.delobjid : BEGIN
      IF state.selected GE 1 THEN BEGIN
         ;Access the selected template.
         WIDGET_CONTROL, state.tplateid, GET_UVALUE=tplate, /NO_COPY
         con = qannounc( ['Delete selected object?'], $
               TITLE='Delete Object Confirmation', XSIZE=40, $
               TRUE='Yes, continue', FALSE='No, cancel request' )

         IF con THEN BEGIN
            ;Delete the object:
            ;Set the objnam to the null string as a flag for the WHERE. This
            ;is the ideal sentinal, because the object names are not allowed
            ;to be null (null entries are stored as '<default>').
            tplate.objnam[state.selected] = ''
            keep = WHERE( tplate.objnam NE '', count )
            IF count NE 0 THEN BEGIN
               ;There are objects to be kept. Extract them.
               numobj = count
               mode = tplate.mode
               modified = tplate.modified
               new = tplate.new[keep]
               objnam = tplate.objnam[keep]
               x = tplate.x[keep]
               y = tplate.y[keep]

               ;Re-build the template structure.
               tplate = {numobj:numobj, mode:mode, modified:modified,  $
                         new:new, objnam:objnam, x:x, y:y }
            ENDIF ELSE BEGIN
               ;There was only one object. Make it a skeleton.
               tplate.numobj   = 0
               tplate.mode     = 0B
               tplate.modified = 0B
               tplate.objnam   = ['<default>']
               tplate.new      = [0B]
               tplate.x  = [0.0]
               tplate.y  = [0.0]
            ENDELSE

            ;Refresh the object list widget.
            state.selected = -1
            WIDGET_CONTROL, state.objlistid, SET_VALUE=cw_tplat_fmt(tplate), $
               SET_LIST_SELECT=state.selected
         ENDIF
         WIDGET_CONTROL, state.tplateid, SET_UVALUE=tplate, /NO_COPY
      ENDIF
   END

   state.editid : BEGIN
      WIDGET_CONTROL, state.tplateid, GET_UVALUE=tplate, /NO_COPY
      IF state.selected GE 0 THEN BEGIN
         WIDGET_CONTROL, event.id, GET_VALUE=tobjnam
         objnam = STRTRIM( tobjnam[0], 2 )
         IF objnam EQ '' THEN objnam='<default>'
         tplate.objnam[state.selected] = objnam

         WIDGET_CONTROL, state.objlistid, SET_VALUE=cw_tplat_fmt(tplate), $
            SET_LIST_SELECT=state.selected
         tplate.modified = 1
      ENDIF ELSE BEGIN
         WIDGET_CONTROL, state.editid, SET_VALUE=''
      ENDELSE
      WIDGET_CONTROL, state.tplateid, SET_UVALUE=tplate, /NO_COPY
   END

   state.modeid : BEGIN
      WIDGET_CONTROL, state.tplateid, GET_UVALUE=tplate, /NO_COPY
      tplate.mode = event.value
      WIDGET_CONTROL, state.tplateid, SET_UVALUE=tplate, /NO_COPY
   END

   state.objlistid : BEGIN
      WIDGET_CONTROL, state.tplateid, GET_UVALUE=tplate, /NO_COPY
      state.selected = event.index
      objnam = tplate.objnam[event.index]
      IF objnam EQ '<default>' THEN objnam=''
      WIDGET_CONTROL, state.editid, SET_VALUE=objnam
      WIDGET_CONTROL, state.tplateid, SET_UVALUE=tplate, /NO_COPY
   END

   state.purgid : BEGIN
      WIDGET_CONTROL, state.tplateid, GET_UVALUE=tplate
      IF tplate.numobj GT 0 THEN BEGIN
         answer = qannounc( 'Purge the objects in this template?', $
         TRUELABEL='Yes, continue', XSIZE=40 )
         IF answer NE 0 THEN BEGIN
            ;Yes, purge the template.
            tplate = {numobj:0, mode:0B, modified:0B, new:[0B], $
                      objnam:['<default>'], x:[0.0], y:[0.0] }
            WIDGET_CONTROL, state.objlistid, SET_VALUE=''
            WIDGET_CONTROL, state.editid, SET_VALUE=''
            state.selected = -1
         ENDIF
      ENDIF
      WIDGET_CONTROL, state.tplateid, SET_UVALUE=tplate
   END

   ELSE : BEGIN
      ;Unknown event.
      MESSAGE, 'Unknown event:', /INFO
      HELP, event, /STRUCTURE
   END
ENDCASE

WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY

RETURN, out_event
END


; ------------------------------------------------------------------------------
; Function cw_tplat
; Create a template widget.
; The template, itself, is a structure, stored internally. It may be 'put'
; or 'retrieved' through the widget_control keywords set_value and get_value.
; ------------------------------------------------------------------------------
FUNCTION cw_tplat, parent, UVALUE=uvalue, VALUE=value

;Note: The 'value' of this compound widget is a structure which represents
;the template. It has the following format:
;  tplate = {numobj:0, mode:0B, modified:0B, new:[0B], $
;            objnam:['<default>'], x:[0.0], y:[0.0] }


state = { $
   debugid:0L, $
   delobjid:0L, $
   editid:0L, $
   initialid:0L, $
   modeid:0L, $
   objlistid:0L, $
   purgid:0L, $
   selected:-1, $
   tplateid:0L $
   }

IF KEYWORD_SET( uvalue ) THEN BEGIN
   mainbase = WIDGET_BASE( parent, COLUMN=1, EVENT_FUNC='cw_tplat_eve', $
              FUNC_GET_VALUE='cw_tplat_gvl', PRO_SET_VALUE='cw_tplat_svl', $
              UVALUE=uvalue )
ENDIF ELSE BEGIN
   mainbase = WIDGET_BASE( parent, COLUMN=1, EVENT_FUNC='cw_tplat_eve', $
              FUNC_GET_VALUE='cw_tplat_gvl', PRO_SET_VALUE='cw_tplat_svl' )
ENDELSE

IF KEYWORD_SET( value ) THEN BEGIN
   ;Force the template structure to be the incoming value.
   tplate = value
ENDIF ELSE BEGIN
   ;Create a skeleton template structure.
   tplate = {numobj:0, mode:0B, modified:0B, new:[0B], $
             objnam:['<default>'], x:[0.0], y:[0.0] }
ENDELSE

IF tplate.numobj GT 0 THEN tplate.mode=1B

wb = WIDGET_BASE( mainbase, ROW=1 )

state.modeid = cw_bgroup( wb, ['Add', 'Active'], /EXCLUSIVE, FRAME=1, $
               /NO_RELEASE, ROW=1, SET_VALUE=tplate.mode )

state.delobjid = WIDGET_BUTTON( wb, VALUE='Delete Object' )

state.purgid = WIDGET_BUTTON( wb, VALUE='Purge Objects' )

;This is where the template structure is stored.
state.tplateid = state.purgid

IF tplate.numobj GT 0 THEN BEGIN
   state.objlistid = WIDGET_LIST( mainbase, VALUE=cw_tplat_fmt(tplate), $
                     YSIZE=5 )
ENDIF ELSE BEGIN
   state.objlistid = WIDGET_LIST( mainbase, YSIZE=5 )
ENDELSE

state.editid = cw_field( mainbase, TITLE='Change name of selected object:', $
               /RETURN_EVENTS )

WIDGET_CONTROL, state.tplateid, SET_UVALUE=tplate, /NO_COPY

stash = WIDGET_INFO( mainbase, /CHILD )
WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY

RETURN, mainbase
END