;+ ; Project : SOHO - CDS ; ; Name : XSTRUCT ; ; Purpose : widget display of fields within an arbitrary structure ; ; Explanation : ; Arranges structures in a matrix format with the tag ; name in label widget and the tag value in a text widget. ; If wbase and wtags exist, then widget is just updated ; with input field values. ; ; Use : xstruct,stc ; ; Inputs : STC = structure name ; ; Opt. Inputs : None. ; ; Outputs : None. ; ; Opt. Outputs: None. ; ; Keywords : ; NX = # of columns by which to arrange widgets (def=2) ; WTAGS = text widget id's for each tag ; WBASE = parent widget base into which place structure ; GROUP = event id of widget that calls XSTRUCT ; JUST_REG = if set, then just register widget ; TITLE = optional widget title ; XOFF, YOFF = offset of structure base relative to calling widget ; EDITABLE = make fields editable ; ALL = generate events without return key ; XSIZE= text widget width [def = 10] ; RECUR = signals that XSTRUCT is being called recursively ; CENTER = center main base in screen (not relative to parent) ; NOFF = do not offset main base ; ACCEPT = name for accept button [def = commit] ; RETURN = force hitting return key to accept edits ; ; ; Calls : xmatrix ; ; Common : XSTRUCT_COM ; ; Restrictions: ; Input must be a structure. ; Cannot yet safely handle arrays of structures or nested structures ; ; Side effects: None. ; ; Category : Widgets ; ; Prev. Hist. : None. ; ; Written : Zarro (ARC/GSFC) 20 August 1994 ; ; Modified : ; ; Version : 1 ;- pro xstruct_event, event ;event driver routine common xstruct_com,cwtags,wstruct,recur_base,out_struct widget_control, event.id, get_uvalue = uservalue if (n_elements(uservalue) eq 0) then uservalue='' wtype=widget_info(event.id,/type) ;-- text events if (wtype eq 3) and exist(cwtags) then begin clook=where(cwtags eq event.id,cnt) sz=size(cwtags) if cnt gt 0 then begin two_d=0b if sz(0) eq 2 then begin two_d=1b ij=get_ij(clook(0),sz(1)) i=ij(0) & j=ij(1) field=wstruct(j).(i) endif else begin index=clook(0) field=wstruct.(index) endelse widget_control,event.id,get_value=value value=strcompress(strtrim(value,2)) if n_elements(field) eq 1 then value=value(0) else $ value=str2arr(value(0),delim=' ') if datatype(field) ne 'STC' then begin if two_d then wstruct(j).(i)=value else wstruct.(index)=value catch,error if error ne 0 then begin print,!err_string catch,/cancel endif endif endif endif ;-- button events if wtype eq 1 then begin bname=strtrim(uservalue,2) if (bname eq 'done') or (bname eq 'abort') or (bname eq 'commit') then begin if bname eq 'abort' then delvarx,out_struct if bname eq 'commit' then out_struct=wstruct xtext_reset,cwtags xkill,recur_base xkill,event.top endif endif return & end ;------------------------------------------------------------------------------ pro xstruct,struct,nx=nx,just_reg=just_reg,group=group,editable=editable,$ wbase=wbase,wtags=wtags,title=title,xoff=xoff,yoff=yoff,$ lfont=lfont,tfont=tfont,noff=noff,instruct=instruct,bfont=bfont,$ modal=modal,xsize=xsize,recur=recur,all=all,center=center,$ status=status,accept=accept,return_key=return_key common xstruct_com set_plot,'x' err_mess='input must be a structure' err='' if not exist(struct) then err=err_mess if not have_widgets() then begin message,'widgets unavailable',/cont return endif if (datatype(struct) ne 'STC') then err=err_mess if err ne '' then begin message,err,/cont return endif tags=tag_names(struct) ntags=n_elements(tags) ;-- keywords editable=keyword_set(editable) just_reg=keyword_set(just_reg) if not just_reg then begin caller=get_caller(stat) if (stat) and (not xalive(group)) then xkill,/all endif recur=keyword_set(recur) modal=keyword_set(modal) all=1-keyword_set(return_key) center=keyword_set(center) delvarx,wstruct,recur_base,cw_tags,out_struct if (editable) and (not just_reg) then wstruct=struct if (not just_reg) then delvarx,cwtags if (not recur) then delvarx,recur_base if (just_reg) and (not exist(wtags)) then xkill,wbase if n_elements(xoff) ne 0 then xoff_sav=xoff if n_elements(yoff) ne 0 then yoff_sav=yoff just_reg_sav=just_reg nstruct=n_elements(struct) last=nstruct-1 for i=0,last do begin ;-- JUST_REG all bases (except last) when more that one structure if (nstruct gt 1) then begin just_reg=0 update=0 & delvarx,wbase,wtags if i eq last then begin if n_elements(just_reg_sav) ne 0 then just_reg=just_reg_sav else just_reg=0 endif else just_reg=1 endif update=min(xalive(wbase)) eq 1 if update then begin if min(xalive(wtags)) eq 1 then begin if ntags ne n_elements(wtags) then begin xkill,wbase & update=0 endif endif endif if not update then begin ;-- make top level base mk_dfont,bfont=bfont,lfont=lfont if nstruct gt 1 then begin wtitle='XSTRUCT_('+strtrim(string(i),2)+')' endif else wtitle='XSTRUCT' if xalive(group) then addg=',group=group)' else addg=')' s=execute('wbase=widget_base(title=wtitle,/column'+addg) if not exist(recur_base) then recur_base=wbase else recur_base=[recur_base,wbase] ;-- put DONE button in first row if (not just_reg) then begin row=widget_base(wbase,/row,/frame) if editable then begin if datatype(accept) eq 'STR' then begin acc=trim(accept) first=strmid(acc,0,1) rest=strmid(acc,1,strlen(acc)) acc=strupcase(first)+strlowcase(rest) endif else acc='Commit' abortb=widget_button(row,value='Cancel',uvalue='abort',/no_release,/frame,font=bfont) commb=widget_button(row,value=acc,uvalue='commit',/no_release,/frame,font=bfont) endif else closeb=widget_button(row,value='Done',uvalue='done',/no_release,/frame,font=bfont) if datatype(instruct) eq 'STR' then begin row=widget_base(wbase,/row) for k=0,n_elements(instruct)-1 do begin insb=widget_label(row,value=instruct(k),font=lfont) endfor endif endif endif ;-- put matrix of tags in second row xmatrix,struct(i),wbase,nx=nx,wtags=wtags,title=title,editable=editable,$ xsize=xsize,all=all,lfont=lfont,tfont=tfont if editable then boost_array,cwtags,wtags ;-- realize and manage if not update then begin if (i eq 0) then begin if not keyword_set(noff) then $ offsets=get_cent_off(wbase,group,valid=valid,wsize=wsize,screen=center) else valid=0 if valid and ((not exist(xoff)) or (not exist(yoff))) then begin xoff=offsets(0) & yoff=offsets(1) endif endif else begin if (exist(xoff)) and (exist(yoff)) then begin frac=.03 xoff=xoff+frac*wsize(0) yoff=yoff+frac*wsize(1) endif endelse realized=widget_info(wbase,/realized) if (not exist(xoff)) or (not exist(yoff)) then begin widget_control,wbase,realize=(not realized),/map endif else begin widget_control,wbase,realize=(not realized),tlb_set_xoff=xoff,tlb_set_yoff=yoff,/map endelse widget_control,wbase,event_pro='xstruct_event' if not just_reg then xmanager,'xstruct',wbase,modal=(i eq last)*modal,just_reg=just_reg endif else xshow,wbase endfor xmanager_reset,wbase,just_reg=just_reg,modal=modal,group=group ;-- restore initial parameters if exist(xoff_sav) then xoff=xoff_sav if exist(yoff_sav) then yoff=yoff_sav if exist(just_reg_sav) then just_reg=just_reg_sav if datatype(out_struct) eq 'STC' then begin struct=out_struct status=1 endif else status=0 if exist(recur_base) then wbase=recur_base return & end