PRO INTEGER_ONLY, event ; This event handler for text widgets only allows integers to be entered ; in the text widget. A maximum of four digits are allowed. ; Deal with simple one-character insertion events. IF event.type EQ 0 THEN BEGIN ; Get the current text in the widget and find its length. Widget_Control, event.id, Get_Value=text text = text(0) length = StrLen(text) ; Only react if the insertion character is a number and there ; are less than four characters already in the widget. IF Byte(event.ch) GE 48B AND Byte(event.ch) LE 57B AND length LT 4 THEN BEGIN ; Get the current text selection. selection = Widget_Info(event.id, /Text_Select) ; Insert the character at the proper location. Widget_Control, event.id, /Use_Text_Select, Set_Value=String(event.ch) ; Update the current insertion point in the text widget. Widget_Control, event.id, Set_Text_Select=event.offset + 1 ENDIF ENDIF ; of insertion event ; Deal with deletion events. IF event.type EQ 2 THEN BEGIN ; Get the current text in widget. Widget_Control, event.id, Get_Value=text text = text(0) length = StrLen(text) ; Put it back with the deletion subtracted. Widget_Control, event.id, Set_Value=StrMid(text, 0, length-event.length) ; Reset the text insertion point in the text widget. Widget_Control, event.id, Set_Text_Select=event.offset ENDIF END ; of INTEGER_ONLY event handler ************************************************* PRO NULL_EVENTS, event ; The purpose of this event handler is to do nothing and ignore all events that ; come to it. END ; of NULL_EVENTS event handler *************************************************** PRO GETIMAGE_EVENT, event ; The only events that can come here are button events. ; Get the info structure out of the user value of the top-level base. Widget_Control, event.top, Get_UValue=info ; There may be errors we can't anticipate. Catch them here, alert the ; user as to what the error was, and exit the event handler without ; doing any damage. Catch, error IF error NE 0 THEN BEGIN ok = Widget_Message(!Err_String) RETURN ENDIF ; Which button caused this event? Widget_Control, event.id, Get_Value=buttonValue CASE buttonValue OF 'Pick Filename': BEGIN ; Start in the directory listed in the directory text widget. ; Convert the text value to a scalar. Widget_Control, info.dirnameID, Get_Value=startDirectory startDirectory = startDirectory(0) ; If this directory doesn't exist, use the current directory. test = Findfile(startDirectory, Count=foundfile) IF foundfile NE 1 THEN CD, Current=startDirectory ; Use PICKFILE to pick a name. pick = Pickfile(Path=startDirectory, /NoConfirm, Get_Path=path, Filter='*.dat') ; Set the directory text widget with the name of the directory. ; Make sure the user didn't cancel out of PICKFILE. IF pick NE '' THEN BEGIN ; Find the lengths of the PICK and the PATH. pathLen = StrLen(path) picklen = StrLen(pick) ; Shorten the PATH to take off last file separator. path = StrMid(path,0,pathLen-1) ; Put the PATH in the directory location. Widget_Control, info.dirnameID, Set_Value=path ; Set the filename text widget with the name of the file. filename = StrMid(pick, pathlen, picklen-pathlen) Widget_Control, info.filenameID, Set_Value=filename ENDIF END ; of the Pick Filename button case 'Cancel': BEGIN ; Have to exit here gracefully. Null filename means "CANCEL". formdata = {filename:''} Handle_Value, info.ptrToFormData, formdata, /Set ; Out of here! Widget_Control, event.top, /Destroy END ; of the Cancel button case 'Accept': BEGIN ; Gather the form information. ; Put the directory and filename together to make a path. Widget_Control, info.dirnameID, Get_Value=directory Widget_Control, info.filenameID, Get_Value=file filename = Filepath(Root_Dir=directory(0),file(0)) ; Get the size and header info. Remember these are STRINGS! Widget_Control, info.headerID, Get_Value=header Widget_Control, info.xsizeID, Get_Value=xsize Widget_Control, info.ysizeID, Get_Value=ysize Widget_Control, info.frameID, Get_Value=frames header = Fix(header(0)) xsize = Fix(xsize(0)) ysize = Fix(ysize(0)) frames = Fix(frames(0)) ; Get the data type from the droplist widget. listIndex = Widget_Info(info.droplistID, /Droplist_Select) datatype = info.datatypes(listIndex) ; Get the format index from the formatlist widget. formatIndex = Widget_Info(info.formatlistID, /Droplist_Select) ; Create the formdata structure from the information you collected. formdata = {header:header, xsize:xsize, ysize:ysize, frames:frames, $ filename:filename, datatype:datatype, formatIndex:formatIndex} ; Store the formdata in the pointer location. Handle_Value, info.ptrToFormData, formdata, /Set ; Out of here! Widget_Control, event.top, /Destroy END ; of the Accept button case ENDCASE END ; of GETIMAGE_EVENT event handler ************************************************ FUNCTION GETIMAGE, filename, Directory=directory, XSize=xsize, YSize=ysize, $ Frames=frames, Header=header, XDR=xdr ; This is a function to specify the size, data type, and header information ; about an image that you would like to read. It reads the data and returns ; it as the result of the function. If an error occurs, the function returns a 0. ; Check for parameters and keywords. IF N_Params() EQ 0 THEN filename='ctscan.dat' ; If DIRECTORY keyword is not used, use the "training" directory. ; If that is not found, use the current directory. IF N_Elements(directory) EQ 0 THEN BEGIN startDirectory = Filepath('training') junk = Findfile(startDirectory, Count=foundfile) IF foundfile EQ 0 THEN CD, Current=startDirectory ENDIF ELSE startDirectory = directory ; Check for size and header keywords. These probably come in as ; numbers and you need strings to put them into text widgets. IF N_Elements(xsize) EQ 0 THEN xsize='256' ELSE xsize=StrTrim(xsize,2) IF N_Elements(ysize) EQ 0 THEN ysize='256' ELSE ysize=StrTrim(ysize,2) IF N_Elements(frames) EQ 0 THEN frames='0' ELSE frames=StrTrim(frames,2) IF N_Elements(header) EQ 0 THEN header='0' ELSE header=StrTrim(header,2) ; Create a top-level base. tlb = Widget_Base(Column=1, Title='Read Image Data') ; Create the directory widgets. dirnamebase = Widget_Base(tlb, Row=1) dirnamelabel = Widget_Label(dirnamebase, Value='Directory:') dirnameID = Widget_Text(dirnamebase, Value=startDirectory, /Editable, $ Event_Pro='NULL_EVENTS', XSize=Fix(2.5*StrLen(startDirectory) > 50)) ; Create the filename widgets. filenamebase = Widget_Base(tlb, Row=1) filenamelabel = Widget_Label(filenamebase, Value='Filename:') filenameID = Widget_Text(filenamebase, Value=filename, /Editable, $ Event_Pro='NULL_EVENTS', XSize=2.5*StrLen(filename) > 20) ; Create a button to allow user to pick a filename. pickbutton = Widget_Button(filenamebase, Value='Pick Filename') ; Create a droplist widget to select file data types. database = Widget_Base(tlb, Row=1) datatypes = ['Byte', 'Integer', 'Long', 'Float'] droplistID = Widget_Droplist(database, Value=datatypes, $ Title='Data Type: ', Event_Pro='NULL_EVENTS') ; Create a droplist widget to select file formats. formatlistID = Widget_Droplist(database, Value=['None', 'XDR'], $ Title='File Format: ', Event_Pro='NULL_EVENTS') ; Create a text widget to accept a header size. headlabel = Widget_Label(database, Value='Header Size:') headerID = Widget_Text(database, Value=header, All_Events=1, Editable=0, $ Event_Pro='INTEGER_ONLY', XSize=8) ; Create widgets to gather the required file sizes. sizebase = Widget_Base(tlb, Row=1) xlabel = Widget_Label(sizebase, Value='X Size:') xsizeID = Widget_Text(sizebase, Value=xsize, All_Events=1, Editable=0, $ Event_Pro='INTEGER_ONLY', XSize=8) ylabel = Widget_Label(sizebase, Value='Y Size:') ysizeID = Widget_Text(sizebase, Value=ysize, All_Events=1, Editable=0, $ Event_Pro='INTEGER_ONLY', XSize=8) zlabel = Widget_Label(sizebase, Value='Frames:') frameID = Widget_Text(sizebase, Value=frames, All_Events=1, Editable=0, $ Event_Pro='INTEGER_ONLY', XSize=8) ; Create cancel and accept buttons. cancelbase = Widget_Base(tlb, Column=2, Frame=1) cancel = Widget_Button(cancelbase, Value='Cancel') accept = Widget_Button(cancelbase, Value='Accept') ; Realize the program. Widget_Control, tlb, /Realize ; Create a pointer to store the information collected from the form. ptrToFormData = Handle_Create() ; Set the correct file format in the format droplist widget. Widget_Control, formatlistID, Set_Droplist_Select=Keyword_Set(xdr) ; Set the text insertion point at the end of the filename text widget. tip = [StrLen(filename),0] Widget_Control, filenameID, Input_Focus=1 Widget_Control, filenameID, Set_Text_Select=tip ; Create an info structure with program information. info = { filenameID:filenameID, $ dirnameID:dirnameID, $ xsizeID:xsizeID, $ ysizeID:ysizeID, $ frameID:frameID, $ headerID:headerID, $ droplistID:droplistID, $ formatlistID:formatlistID, $ datatypes:datatypes, $ ptrToFormData:ptrToFormData} ; Store the info structure in the user value of the top-level base. Widget_Control, tlb, Set_UValue=info ; The form will be a MODAL widget. This means we STOP at the ; following XManager call until the widget is destroyed. XManager, 'getimage', tlb, Event_Handler='GETIMAGE_EVENT', /Modal ; Get the form data that was collected by the form. Handle_Value, ptrToFormData, formdata ; If there is nothing here. Free the pointer and return. IF N_Elements(formdata) EQ 0 THEN BEGIN Handle_Free, ptrToFormData RETURN, 0 ENDIF ; Did the user cancel out of the form? If so, return a 0. IF formdata.filename EQ '' THEN BEGIN Handle_Free, ptrToFormData RETURN, 0 ENDIF ; Make the proper sized image array. Check for success. image = 0 IF formdata.frames EQ 0 THEN $ command = 'image = Make_Array(formdata.xsize, formdata.ysize, ' + $ formdata.datatype + '=1)' ELSE $ command = 'image = Make_Array(formdata.xsize, ' + $ 'formdata.ysize, formdata.frames, ' + formdata.datatype + '=1)' check = Execute(command) IF check EQ 0 THEN BEGIN ok = Widget_Message("Problem making image array. Returning 0.") RETURN, 0 ENDIF ; We can have all kinds of trouble reading data. Let's catch all ; input and output errors and alert user without crashing the program! Catch, error IF error NE 0 THEN BEGIN ; If we can't read the file for some reason, let the user know ; why, free the pointer and its information, check the logical ; unit number back in if it is checked out, and return a 0. ok = Widget_Message(!Err_String) Handle_Free, ptrToFormData IF N_ELements(lun) NE 0 THEN Free_Lun, lun RETURN, 0 ENDIF ; Read the data file. IF formdata.header GT 0 THEN header = BytArr(formdata.header) Get_Lun, lun OpenR, lun, formdata.filename, XDR=formdata.formatIndex IF formdata.header EQ 0 THEN ReadU, lun, image $ ELSE ReadU, lun, header, image Free_Lun, lun ; Free the pointer. Handle_Free, ptrToFormData RETURN, image END ; of GETIMAGE program ******************************************************