skip to main content NIST Center for Neutron Research NIST Center for Neutron Research National Institute of Standards and Technology
Home Live Data Instruments CHRNS Proposals

DAVE Programming and Hierarchy

(How to make your non-modal IDL widget programs DAVE-compatible)


In an effort to make the the transition from your IDL data analysis, reduction, and/or visualization programs to DAVE-compatible programs, I present below how one can do this with a simple example.

There are drastic differences in how one can incorporate modal and non-modal widget programs into DAVE. Modal widgets are very simple but non-modal widgets require some work. The advantage of writing a non-modal widget program for data analysis, etc., is that menu bars are allowed in non-modal widget programs but not in modal widget programs.

As an example, let's see how we can incorporate a simple "Hello World" type widget into DAVE. The current version of DAVE on the DAVE computer incorporates this simple widget program so you can see how it runs.

The first place to start is with the "Hello World" code. Shown below is a simple widget program that will NOT work in the DAVE hierarchy, called HWWidget.pro. This works as a standalone routine.

;;;;;;;;;; pro HWCleanup,tlb
widget_control,tlb,get_uvalue = pState
ptr_free,pState
return
end
;;;;;;;;;;
pro HWQuit,event
widget_control,event.top,/destroy
return
end
;;;;;;;;;;
pro HWDo,event
widget_control,event.top,get_uvalue = pState
widget_control,(*pState).name,get_value = name
strout = name[0]
void = dialog_message(dialog_parent = event.top,strout,/information)
return
end
;;;;;;;;;;
pro HWWidget
butsize = 160
tlb = widget_base(/col,tlb_frame_attr = 1, mbar = bar)
filemenu = widget_button(bar,value = 'File',/menu)
menuQuit = widget_button(filemenu,value = 'Quit',event_pro = 'HWQuit')
name = widget_text(tlb,/editable,value = 'Type our name here, then return',event_pro = 'HWDo')
hwbutton = widget_button(tlb,value = 'Do Something',event_pro = 'HWDo')
buttonQuit = widget_button(tlb,xsize = butsize,value = 'Quit’,event_pro = 'HWQuit')
widget_control,tlb,/realize
state = {name:name}
pState = ptr_new(state,/no_copy)
widget_control,tlb,set_uvalue = pState
xmanager,'HWWidget',tlb,cleanup = 'HWCleanup'
return
end

Note that there is a FILE menu has an option to quit. This is a non-modal widget program since only non-modal widget programs allow you to have a menu bar in the top-level base.

The modified "Hello World" code which can work within DAVE or as a standalone program is shown below. It is called daveHWWidget.pro and changes from HWWidget.pro are shown in boldface. Some things to notice in particular are that the Quit procedure (called daveHWQuit) generates a pseudo-event that is sent up to DAVE.pro. This is how DAVE.PRO is notified that you have exited the program daveHWWidget. Also, the DAVE data pointer called pState in DAVE.PRO is passed directly into daveHWWidget via the INPTR keyword. Any changes that are made within daveHWWidget to INPTR will be reflected in all other subsequent programs that use the data pointer since it is global in scope (i.e. it is persistent). As you can imagine, this is a very useful bit of functionality when manipulating data.

;;;;;;;;;;
pro daveHWCleanup,tlb
widget_control,tlb,get_uvalue = pState
s = size((*pState).notifyIDs)
if n_elements((*pState).notifyIDs) gt 1 then begin
if s[0] eq 1 then count = 0 else count = s[2]-1
for j = 0,count do begin
daveHWInfo = {daveHWEvent,$
ID:(*pState).notifyIDs[0,j],$
Top:(*pState).notifyIDs[1,j],$
Handler:0l}
if widget_info((*pState).notifyIDs[0,j],/valid_id) then begin $
widget_control,(*pState).notifyIDs[0,j],send_event = daveHWInfo
endif
endfor
endif else begin
ptr_free,(*pState).inPtr
endelse
ptr_free,pState
return
end
;;;;;;;;;;
pro daveHWQuit,event
widget_control,event.top,/destroy
return
end
;;;;;;;;;;
pro daveHWDo,event
widget_control,event.top,get_uvalue = pState
widget_control,(*pState).name,get_value = name
strout = name[0]
void = dialog_message(dialog_parent = event.top,strout,/information)
return
end
;;;;;;;;;;
pro daveHWWidget,notifyIDs = notifyIDs,inPtr = inPtr,group_leader = group_leader
butsize = 160
if n_elements(notifyIDs) eq 2 then begin
tlb = widget_base(/col,tlb_frame_attr = 1, mbar = bar,group_leader = group_leader)
endif else begin
notifyIDs = 0
inPtr = ptr_new(/allocate_heap)
tlb = widget_base(/col,tlb_frame_attr = 1, mbar = bar)
endelse
filemenu = widget_button(bar,value = 'File',/menu)
menuQuit = widget_button(filemenu,value = 'Quit',event_pro = 'daveHWQuit')
name = widget_text(tlb,/editable,value='Type our name here, then return',event_pro='daveHWDo')
buttonQuit = widget_button(tlb,xsize = butsize,value = 'Quit',event_pro = 'daveHWQuit')
widget_control,tlb,/realize
state = {name:name,$
inptr:inPtr,$
notifyIDs:notifyIDs}
pState = ptr_new(state,/no_copy)
widget_control,tlb,set_uvalue = pState
xmanager,'daveHWWidget',tlb,cleanup = 'daveHWCleanup'
return
end

Next let's look at how to modify the DAVE.PRO code to accomodate the "Hello World" widget discussed above. I have listed the (abridged) code for DAVE.PRO below with the appropriate addition in boldface type.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro dave
; Widget definition module
tlb = widget_base(/row,tlb_frame_attr = 1,mbar = bar,$
title = 'DAVE: Data Analysis and Visualization Environment')
win = widget_draw(tlb,xsize = winxsize,ysize = winysize)
filemenu = widget_button(bar,value = 'File',/menu)
void = widget_button(filemenu,value = 'Define current directory',$
xsize = butsize,event_pro = 'fdaveSelCurrentDirectory')
void = widget_button(filemenu,value = 'Select raw data directory',$
xsize = butsize,event_pro = 'fdaveSelDataDirectory')
void = widget_button(filemenu,value = 'Select working directory',$
xsize = butsize,event_pro = 'fdaveSelWorkDirectory')
void = widget_button(filemenu,value = 'Display directories',$
xsize = butsize,event_pro = 'fdaveDisplayDirectories')
void = widget_button(filemenu,value = 'Select pdf reader',$
xsize = butsize,event_pro = 'fdaveSELpdfreader')
void = widget_button(filemenu,value = 'Demo program',event_pro = 'daveLaunchDemo',$
xsize = butsize)
void = widget_button(filemenu,value = 'Exit',event_pro = 'fdaveQuit',$
xsize = butsize)
device,/cursor_original
commonStr = {instrument:'',$
histPtr:ptr_new(/allocate_heap),$
xlabel:'',$
ylabel:'',$
xtype:'',$
ytype:'',$
xunits: '',$
yunits: '',$
histLabel:'',$
histUnits:'',$
treatmentPtr:ptr_new(/allocate_heap),$
commonStrPtr:ptr_new()}
dataStr = {commonStr:commonStr,$
specificPtr:ptr_new(/allocate_heap)}
state = {dataStrPtr:ptr_new(dataStr)}
pState = ptr_new(state,/no_copy)
widget_control,tlb,set_uvalue = pState,/no_copy
xmanager,'dave',tlb,cleanup = 'daveCleanup',/no_block
return
end

The final program necessary to run daveHWWidget, called daveLaunchDemo.pro, is listed below. This short program notifies the top level of DAVE if you are exiting or entering this top level program module and applies the appropriate sensitization/desensitization.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro daveLaunchDemo,event
widget_control,event.top,get_uvalue = pState
thisEvent = tag_names(event,/structure_name)
case thisEvent of
'WIDGET_BUTTON': $
begin
widget_control,event.top,sensitive = 0
daveHWWidget,notifyIDs = [event.id,event.top],$
group_leader = event.top,$
inPtr = pState
end
'DAVEHWEVENT': $
begin
widget_control,event.top,sensitive = 1
end
else:
endcase
return
end


Last modified 16-July-2002 by website owner: NCNR (attn: Richard Azuah)