;Id: demo.pro,v 1.100 1998/09/08 23:09:20 paulcs Exp $ ; ; Copyright (c) 1997-2001, Research Systems, Inc. All rights reserved. ; Unauthorized reproduction prohibited. ; ;+ ; FILE: ; demo.pro ; ; CALLING SEQUENCE: demo ; ; PURPOSE: ; Main demo shell. ; ; MAJOR TOPICS: All topics in IDL. ; ; CATEGORY: ; IDL demo system. ; ; INTERNAL FUNCTIONS and PROCEDURES: ; func demoTempMsg - Display a temporary message ; pro demoTimer - Print times & update current time ; pro demoDoAScreen - Write image to file ; pro demoSaveScreens - Write images to save file ; func demoPReadScreen - Return a pointer to an image ; pro demoSplashStart - Set up the splash screen ; pro demoSplashEnd - Take down the splash screen ; pro demoResetSysVars - Reset system variables ; pro demoButtonGroup - Build demo buttons ; pro demoButtonDef - Define demo buttons ; pro demoMenuDef - Define demo menus ; func demoXFindFont - Look for a font ; pro demoButtonCreate - Create the buttons ; pro demoShowScreen - Display a screen ; pro demoStartInsight - Start the Insight Application ; pro demoStartHelp - Start the Online Help system ; pro demoStartApp - Start a demo application ; func demoFuncsumCleanup - Cleanup ; func demoFuncsumEvent - Event handler ; func demoFuncsum - Display IDL functional summary text ; func demoGetScreenSize - Get the screen size ; func demoInit - Set up the demo system ; pro demoCleanup - Cleanup ; pro demoEvent - Event handler ; pro demo - Main routine ; ; EXTERNAL FUNCTIONS, PROCEDURES, and FILES: ; ; REFERENCE: IDL Reference Guide, IDL User's Guide ; ; NAMED STRUCTURES: ; none. ; ; COMMON BLOCS: ; none. ; ; MODIFICATION HISTORY: ; 3/97, ACY - Modified ;- ;---------------------------------------------------------------------------- ; ; Purpose: Display a message. ; function demoTempMsg, $ string ; IN: message string message = ["Not yet implemented..."," ", $ "When implemented, will go to", " " + string] temp = DIALOG_MESSAGE ( message ) end ;---------------------------------------------------------------------------- pro demoTimer, text, t0 ;Print times & update current time t1 = systime(1) print, text, ' ', t1 - t0 t0 = t1 end ;---------------------------------------------------------------------------- Function demoMakeCache, $ cache ; OUT. Anonymous structure. ; ;Purpose: Fabricate and return a structure to be used as a cache for ;screen .png files. ; ;Here is a snapshot of the filenames we expect to find: ;screen00.png: mainScreen ;screen01.png: analysisScreen ;screen02.png: appdevScreen ;screen03.png: callrsiScreen ;screen04.png: earthScreen ;screen05.png: engineerScreen ;screen06.png: medicalScreen ;screen07.png: rsiprodScreen ;screen08.png: spaceScreen ;screen09.png: vizScreen ;screen10.png: enviScreen ;screen11.png: vipScreen ;screen12.png: dataminerScreen ;screen13.png: riverScreen ;screen14.png: ionScreen ;screen15.png: activexScreen ;screen16.png: devenvScreen ;screen17.png: oopScreen ;screen18.png: noesScreen ;screen19.png: vhScreen ;screen20.png: splashImg ; Always last. ; filename = findfile( $ demo_filepath( $ (['screen??.png', 'screen%%.png']) $ [!version.os_family eq 'vms'], $ subdir=["examples", "demo", "demodata"] $ ) $ ) if filename[0] eq '' then begin void = dialog_message('No screen .png files were found.', /error) return, -1 end n = n_elements(filename) cache = { $ filename: filename, $ count: 0L, $ colortb: ptrarr(n), $ cache: ptrarr(n), $ time: lonarr(n) $ } return, 1 end ;---------------------------------------------------------------------------- Function demoPReadScreen, Index, Header, Colortable, NO_CACHE=no_cache, $ DEBUG = debug ; Return a pointer to an image for screen number Index. ; Return colortable in Colortable ; Null = ptr_new() Nkeep = 3 ;# of images to keep in cache Header.count = Header.count + 1 ;Keep track of time if Header.cache[Index] ne Null then begin ;Already there? Result = Header.cache[Index] Colortable = *(Header.colortb[Index]) ; if keyword_set(debug) then print,'cached ', Index endif else begin in = where(header.cache ne Null, count) if count ge Nkeep then begin ;Must get rid of an image junk = min(header.time[in], Toss);Find image that been in the longest toss = in[toss] ; if keyword_set(debug) then print, 'Removed ', toss ptr_free, Header.cache[toss] Header.cache[toss] = Null endif result = ptr_new(READ_PNG(header.filename[Index], r, g, b)) Colortable = transpose([transpose(r), transpose(g), transpose(b)]) Header.colortb[Index] = PTR_NEW(Colortable) if keyword_set(no_cache) eq 0 then Header.cache[Index] = result ; if keyword_set(debug) then print, 'Read ', index endelse Header.time[Index] = Header.count Return, Result ;Return the pointer to the image end ;---------------------------------------------------------------------------- ; ; Purpose: Set up the splash screens. ; pro demoSplashStart, $ fullScrXsize, $ ; IN: X monitor size fullScrYsize, $ ; IN: Y monitor size splashImage, $ ; IN: Image to display splashColors, $ ; IN: Colortable for image splashBase, $ ; OUT: Splash base ID startSplash ; OUT: Starting time s = size(splashImage) nx = s[1] ny = s[2] splashXoffset = (fullScrXsize-nx)/2 splashYoffset = (fullScrYsize-ny)/2 splashBase = WIDGET_BASE ( tlb_frame_attr=31, $ xoffset=splashXoffset, yoffset=splashYoffset ) splashDraw = widget_draw ( splashBase, xsize=nx, ysize=ny ) WIDGET_CONTROL, splashBase, map=0 WIDGET_CONTROL, splashBase, /realize TVLCT, SplashColors WIDGET_CONTROL, splashDraw, GET_VALUE=splashDrawID WSET, splashDrawID TV, splashImage splashImage = 0 ;Don't need it anymore WIDGET_CONTROL, splashBase, map=1 startSplash = systime ( 1 ) end ;---------------------------------------------------------------------------- ; ; Purpose: End the display of the splash screen ; pro demoSplashEnd, $ startSplash, $ ; IN: Starting time splashBase, $ ; IN: Splash base ID debug ; IN: Debug mode 1=on, 0= off ; End the display of the splash screen ; endSplash = systime ( 1 ) deltaSplash = endSplash - startSplash if (deltaSplash LT 0.5) THEN WAIT, 0 > (0.5 - deltaSplash) < 1 if ( debug eq 1 ) then begin print, " Elapsed time for splash screen =====", deltaSplash end ; while ( deltaSplash le 4.0 ) do begin ; print, 'In wait loop ...' ; wait, 0.25 ; deltaSplash = systime ( 1 ) - endSplash ; endwhile WIDGET_CONTROL, splashBase, /destroy ;if ( debug eq 1 ) then begin ;print, " Total elapsed time for splash screen ", deltaSplash ;end end ;---------------------------------------------------------------------------- ; ; Purpose: Reset the system variables. ; pro demoResetSysVars Set_Shading, LIGHT=[0.0, 0.0, 1.0], /REJECT, /GOURAUD, $ VALUES=[0, (!D.Table_Size-1L)] T3d, /RESET !P.T3d = 0 !P.Position = [0.0, 0.0, 0.0, 0.0] !P.Clip = [0L, 0L, (!D.X_Size-1L), (!D.Y_Size-1L), 0L, 0L] !P.Region = [0.0, 0.0, 0.0, 0.0] !P.Background = 0L !P.Charsize = 8.0 / Float(!D.X_Ch_Size) !P.Charthick = 0.0 !P.Color = !D.N_Colors - 1L !P.Font = (-1L) !P.Linestyle = 0L !P.Multi = [0L, 0L, 0L, 0L, 0L] !P.Noclip = 0L !P.Noerase = 0L !P.Nsum = 0L !P.Psym = 0L !P.Subtitle = '' !P.Symsize = 0.0 !P.Thick = 0.0 !P.Title = '' !P.Ticklen = 0.02 !P.Channel = 0 !X.S = [0.0, 1.0] !X.Style = 0L !X.Range = 0 !X.Type = 0L !X.Ticks = 0L !X.Ticklen = 0.0 !X.Thick = 0.0 !X.Crange = 0.0 !X.Omargin = 0.0 !X.Window = 0.0 !X.Region = 0.0 !X.Charsize = 0.0 !X.Minor = 0L !X.Tickv = 0.0 !X.Tickname = '' !X.Gridstyle = 0L !X.Tickformat = '' !Y = !X !Z = !X !X.Margin = [10.0, 3.0] ;.Margin is different for x,y,z !Y.Margin = [4.0, 2.0] !Z.Margin = 0 end pro demoButtonGroup, buttons, index, x0, y0, ydelta, screen, Names, DEFINE=ndefine ; Define a column of buttons. ; Inputs: buttons = array of button structures. ; Index = index of next button to define. On exit, index is incremented. ; x0, y0 = starting coordinate for the first button. y0 is output as ; the starting coordinate for the next button. ; ydelta = vertical spacing between buttons. ; screen = screen index of button. ; Names = [2,n] array of Button values and uvalues. n = n_elements(names)/2 xsize = 145 ysize = 23 for i=0, n-1 do begin s = { d5btn_s, $ Value: Names[i*2], $ Uvalue: Names[i*2+1], $ xsize: xsize, $ ysize: ysize, $ xoffset: fix(x0), $ yoffset: fix(y0), $ screenNum: fix(screen), $ btnbase: 0L$ } if index eq 0 then $ ;Define array? buttons = replicate(s, ndefine) buttons[index] = s y0 = y0 + ydelta index = index + 1 endfor end ;---------------------------------------------------------------------------- ; ; Purpose: Define (not create) the push down ; buttons within the splash screens. ; pro demoButtonDef, buttons numButtons = 84 index = 0 ; Main level buttons, screen 0, group 1 ystart = 115 demoButtonGroup, buttons, index, 16, ystart, 27, 0, DEFINE=numButtons, $ ['Earth Sciences', '.4', $ ; Main level buttons, screen 0, group 1 'Engineering', '.5', $ 'Medical', '.6', $ 'Space/Physics', '.8'] ; Main level buttons, screen 0, group 2 ystart = 243 demoButtonGroup, buttons, index, 470, ystart, 27, 0, $ ['Visualization', '.9', $ 'Data Analysis', '.1', $ 'Application Development', '.2', $ 'Live Tools', 'D_LIVETOOL'] ; Main level buttons, screen 0, group 3 ystart = 300 demoButtonGroup, buttons, index, 16, ystart, 27, 0, $ [ 'IDL Overview', 'FUNCSUM', $ 'Other RSI Products', '.7', $ 'Contact RSI', '.3'] ; Second Level Buttons, screens are listed in alphabetical order, ; not screen order. Vertical Spacing is 29 pixels. demoButtonGroup, buttons, index, 30, 70, 29, 1, $ [ 'Math and Statistics', 'D_MATHSTAT', $; Analysis Buttons, screen 1 'Principal Components', 'D_PCA', $ 'Forecasting', 'D_FORECAST', $ 'Minimization', 'D_OPTIMIZE', $ 'Signal Processing', 'FILTER-SIGNAL'] demoButtonGroup, buttons, index, 200, 70, 29, 1, $ [ 'Image Processing', 'D_IMAGPROC', $ 'Warping and Morphing', 'D_PEOPLE', $ 'Wavelets', 'D_WAVELET', $ 'Regions of Interest', 'XROI', $ 'Return to Main Screen', '.0'] demoButtonGroup, buttons, index, 330, 200, 29, 2, $ [ 'Database Connectivity','.12', $ 'Development Environment','.16', $ 'OO Programming', '.17', $ 'ActiveX Control', '.15', $ 'Return to Main Screen', '.0'] ; Contact screen buttons demoButtonGroup, buttons, index, 363, 208, 29, 3, $ ['Outside North America', '<1030|idl_demo.hlp'] demoButtonGroup, buttons, index, 363, 324, 29, 3, $ ['Return to Main Screen', '.0'] demoButtonGroup, buttons, index, 85, 25, 29, 4, $ ['Mapping', 'D_MAP', $ ; Earth Buttons, screen 4 'Globe', 'D_GLOBE', $ 'Flythrough', 'D_FLYTHRU', $ 'Thunderstorm', 'D_VECTRACK', $ 'Orbiting Satellite', 'D_ORBIT', $ 'Environmental Modeling', 'D_TANKLEAK', $ 'ENVI', '.10', $ 'RiverTools', '.13', $ 'Noesys', '.18', $ 'Return to Main Screen', '.0'] demoButtonGroup, buttons, index, 66, 57, 29, 5, $ ['Fourier Filtering', 'FILTER-ENGR', $ ; Engineering Buttons, screen 5 'Pressure Field Animation', 'D_CFD', $ 'Time Series', 'D_T_SERIES', $ 'Return to Main Screen', '.0'] demoButtonGroup, buttons, index, 402, 92, 29, 6, $ ['Reconstruction', 'D_RECONSTR', $ ; Medical Buttons, screen 6 'Image Animation', 'D_GATED', $ 'Beating Heart', 'D_HEART', $ 'Volumes', 'D_VOLRENDR', $ 'Visible Human', '.19', $ 'Return to Main Screen', '.0'] demoButtonGroup, buttons, index, 410, 70, 29, 7, $ ['ION', '.14', $ ; RSI Product Buttons, screen 7, group 1 'ENVI', '.10', $ 'Noesys', '.18', $ 'IDL DataMiner', '.12', $ 'RiverTools', '.13', $ 'VIP', '.11' $ ] demoButtonGroup, buttons, index, 410, 365, 29, 7, $ ['Return to Main Screen', '.0'] ;RSI Product Buttons, screen 7, group 2 demoButtonGroup, buttons, index, 29, 261, 29, 8, $ ['Fourier Filtering', 'FILTER-SPACE', $ ; Space Buttons, screen 8 'ROI Segmentation', 'ROI-SPACE', $ 'Hydrogen Atom', 'D_HYDROGEN', $ 'Return to Main Screen', '.0'] demoButtonGroup, buttons, index, 53, 160, 29, 9, $ ['2D Plotting', 'D_PLOT2D', $ ; Viz Buttons, screen 9, group 1 'Contouring', 'D_CONTOUR', $ 'Object World', 'D_OBJWORLD2', $ '3D Geometry', 'D_OBJ', $ 'Surface Objects', 'D_SURFVIEW', $ 'Volumes', 'D_VOLRENDR', $ 'US Census', 'D_USCENSUS'] demoButtonGroup, buttons, index, 390, 125, 29, 9, $ ['Mapping', 'D_MAP', $ ; Viz Buttons, screen 9, group 2 'Gridding', 'D_GRIDDING', $ 'Matrix Data', 'D_MATRIX', $ 'Flythrough', 'D_FLYTHRU', $ 'Thunderstorm', 'D_VECTRACK', $ 'Slicer', 'D_SLICE', $ 'Return to Main Screen', '.0'] demoButtonGroup, buttons, index, 20, 375, 29, 10, $ ; ENVI Buttons, screen 10 ['Back','.-'] demoButtonGroup, buttons, index, 20, 355, 29, 11, $ ; VIP Buttons, screen 11 ['Back','.-'] demoButtonGroup, buttons, index, 20, 375, 29, 12, $ ; DataMiner Buttons, screen 12 ['Back','.-'] ;demoButtonGroup, buttons, index, 120, 275, 29, 13, $ ; Insight Buttons, screen 13 ; ['Start IDL Insight','INSIGHT-START'] demoButtonGroup, buttons, index, 20, 375, 29, 13, $ ['Back','.-'] demoButtonGroup, buttons, index, 20, 375, 29, 14, $ ;ION, screen 14 ['Back', '.-'] demoButtonGroup, buttons, index, 410, 375, 29, 15, $ ;Active X, screen 15 ['Back', '.-'] demoButtonGroup, buttons, index, 55, 330, 29, 16, $ ;Dev Env, screen 16 [ 'Example Application', 'D_WIDGETS', $ ; 'Back', '.-'] demoButtonGroup, buttons, index, 35, 370, 29, 17, $ ;OO Prog, screen 17 ['Back', '.-'] demoButtonGroup, buttons, index, 20, 375, 29, 18, $ ['Back','.-'] demoButtonGroup, buttons, index, 20, 375, 29, 19, $ ; VisHuman screen 19 ['Back','.-'] end pro demoMenuDef, MenuDescription ;Define the menu string arrays. MenuDescription = $ [ '1\File', '', $ '2\Quit', 'quit', $ '1\Applications', '', $ '1\Earth Sciences', '', $ '0\Mapping', 'D_MAP', $ '0\Globe', 'D_GLOBE', $ '0\Flythrough', 'D_FLYTHRU', $ '0\Thunderstorm', 'D_VECTRACK', $ '0\Orbiting Satellite', 'D_ORBIT', $ '0\Environmental Modeling', 'D_TANKLEAK', $ '0\ENVI', '.10', $ '0\RiverTools', '.13', $ '2\Noesys', '.18', $ '1\Engineering', '', $ '0\Fourier Filtering', 'FILTER-ENGR', $ '0\Pressure Field Animation', 'D_CFD', $ '2\Time Series', 'D_T_SERIES', $ '1\Medical', '', $ '0\Image Reconstruction', 'D_RECONSTR', $ '0\Image Animation', 'D_GATED', $ '0\Beating Heart', 'D_HEART', $ '0\Volume Visualization', 'D_VOLRENDR', $ '2\Visible Human CDs', '.19'] MenuDescription = $ ;Cause strings are too long to concatenate [ MenuDescription, $ '1\Physics and Space Sciences', '', $ '0\Fourier Filtering', 'FILTER-SPACE', $ '0\ROI Segmentation', 'ROI-SPACE', $ '2\Hydrogen Atom', 'D_HYDROGEN', $ '3\Other RSI Products', '', $ '0\ION', '.14', $ '0\ENVI', '.10', $ '0\Noesys', '.18', $ '0\IDL Dataminer', '.12', $ '0\RiverTools', '.13', $ '2\VIP', '.11', $ '1\Features', '', $ '1\Visualization', '', $ '0\2D Plotting', 'D_PLOT2D', $ '0\Contouring', 'D_CONTOUR', $ '0\Object World', 'D_OBJWORLD2', $ '0\3D Geometry Viewing', 'D_OBJ', $ '0\Surface Objects', 'D_SURFVIEW', $ '0\Volume Visualization', 'D_VOLRENDR', $ '0\US Census', 'D_USCENSUS', $ '0\Mapping', 'D_MAP', $ '0\Gridding and Interpolation', 'D_GRIDDING', $ '0\Matrix Data', 'D_MATRIX', $ '0\Flythrough', 'D_FLYTHRU', $ '0\Thunderstorm', 'D_VECTRACK', $ '2\Slicer', 'D_SLICE', $ '1\Data Analysis', '', $ '0\Math and Statistics', 'D_MATHSTAT', $ '0\Principal Components', 'D_PCA', $ '0\Forecasting', 'D_FORECAST', $ '0\Minimization', 'D_OPTIMIZE', $ '0\Signal Processing', 'FILTER-SIGNAL', $ '0\Image Processing', 'D_IMAGPROC', $ '0\Warping and Morphing', 'D_PEOPLE', $ '0\Wavelets', 'D_WAVELET', $ '2\Regions of Interest', 'XROI', $ '1\Application Development', '',$ '0\GUI Development', 'D_WIDGETS', $ '0\Database Connectivity', '.12', $ '1\Development Environment', '.16', $ '2\Example Application', 'D_WIDGETS', $ '2\Object Oriented Programming', '.17', $ '2\Live Tools', 'D_LIVETOOL'] MenuDescription = $ ;Cause strings are too long to concatenate [ MenuDescription, $ '1\Help', '', $ '2\IDL Online Help Navigator', '?NOARG', $ '1\About', '', $ '0\About the IDL Demo', '<10|idl_demo.hlp', $ '1\About Research Systems', '', $ '0\History of Research Systems', '<1020|idl_demo.hlp', $ '0\Contact Information', "<1030|idl_demo.hlp", $ '0\Training Courses', '<1040|idl_demo.hlp', $ '0\Consulting', '<1050|idl_demo.hlp', $ '0\Academic Programs', '<1060|idl_demo.hlp', $ '0\IDL Information', '<1070|idl_demo.hlp', $ '0\IDL Functional Summary', 'FUNCSUM', $ '0\ENVI Information', '<1080|idl_demo.hlp', $ '0\RiverTools Information', '<1085|idl_demo.hlp', $ '0\ION Information', '<1090|idl_demo.hlp', $ '2\Visible Human CD Information', '<1100|idl_demo.hlp'] end ;demoMenuDef Function demoXFindFont, FontNames ; See if a font can be found. FontNames = an array of font names. On exit ; the function value is either the first found font, or the null string. for i=0, n_elements(FontNames)-1 do begin ;Search for a font Device, Font=FontNames[i], Get_Fontnum=fontnum, GET_FONTNAME=s if fontnum gt 0 then return, s[0] endfor return, '' ;Couldn't find the font. end ;---------------------------------------------------------------------------- ; ; Purpose: Create the push down buttons. ; pro demoButtonCreate, $ mainWinBase, $ ; IN: Main window base ID buttons ; IN: buttons created bu demoButtonDef routine. case !VERSION.OS_FAMILY of ; Don't set it for Windows or Mac, the systems defaults are fine 'Windows' : 'MacOS' : ELSE: $ ; Find a font for Unix and VMS button_font = demoXFindFont(['-adobe-helvetica-medium-r-normal--10-*-*-*', $ '-misc-fixed-medium-r-normal--10-*-*-*']) ENDCASE for i=0, N_ELEMENTS(buttons)-1 do begin buttons[i].btnbase = WIDGET_BASE(mainWinBase, MAP=0, $ xoffset = buttons[i].xoffset, $ yoffset = buttons[i].yoffset) buttonId = WIDGET_BUTTON(buttons[i].btnbase, $ VALUE=buttons[i].value, $ UVALUE=buttons[i].uvalue, $ XSIZE=buttons[i].xsize, $ YSIZE=buttons[i].ysize, $ UNAME="demo:" + buttons[i].value, $ FONT=button_font) endfor end ;---------------------------------------------------------------------------- ; ; Purpose: read the required image index newScreen, and display it. ; pro demoShowScreen, newScreen, state t0 = systime(1) WSET, state.mainDrawID Header = state.png_header Image = demoPReadScreen(newScreen, header, colortb, DEBUG=state.debug) state.png_header = Header ;Restore status WIDGET_CONTROL, state.imageBase, MAP=0, SENS=0 ;If we rearrange order of ; operations, this seems unnecessary. TVLCT, colortb TV, *image ;show it for i=0, N_ELEMENTS(state.buttons)-1 do $ ;Map buttons for this screen WIDGET_CONTROL, state.buttons[i].btnBase, $ MAP= state.buttons[i].screenNum eq newScreen if max(state.curScreenNum eq [0, 4, 5, 6, 8, 9, 1, 2, 7, 3]) gt 0 then begin state.prevScreenNum = state.curScreenNum endif state.curScreenNum = newScreen WIDGET_CONTROL, state.imageBase, /MAP WIDGET_CONTROL, state.imageBase, /SENS if state.debug then demoTimer, 'demoShowScreen ', t0 end ;---------------------------------------------------------------------------- ; ; Purpose: Start the INSIGHT tool. ; pro demoStartInsight, top if (lmgr(/embedded) GT 0) then begin result = DIALOG_MESSAGE(/QUESTION, $ DIALOG_PARENT=top, $ 'Enter a time-limited IDL Insight session ?') if (strupcase(result) EQ 'YES') then begin tmp=lmgr(/force_demo) insight endif endif else insight end ;---------------------------------------------------------------------------- ; ; Purpose: This routine is used to start the online ; help system. The user value (uval) can come ; from either a button or the pulldown menu ; pro demoStartHelp, $ uval, $ ; IN: user value top ; IN: top level base result = DIALOG_MESSAGE(/QUESTION, $ DIALOG_PARENT=top, $ ['This choice will start the Online Help system.', $ '', $ 'Do you want to continue ?']) if (strupcase(result) EQ 'NO') then RETURN case uval of ; Start the online help system with the default screen ; 'NOARG': online_help endcase end ;---------------------------------------------------------------------------- ; ; Purpose: This routine is used to start all demos. ; Name must be the name of the procedure to call. ; a button or the pulldown menu ; pro demoStartApp, $ Name, $ ;Name of demo state, $ ; IN: state structure top, $ ; IN: top level base EXTRA = extra ;Extra keyword parameter structure (optional) if (WIDGET_INFO(state.apptlb, /VALID)) then begin result = DIALOG_MESSAGE('Only one demo may run at a time') RETURN endif if state.slow and (total(name eq state.slow_demos) gt 0) then begin result = $ DIALOG_MESSAGE(['This demo utilizes computationally intensive', $ 'graphics. Response on this machine may be', $ 'unacceptably slow.', $ 'Continue anyway?'], $ DIALOG_PARENT=top, $ /QUESTION) ;Only display once state.slow_demos[where(state.slow_demos eq name)] = 'XXXX' if result eq 'No' then return endif WIDGET_CONTROL, /HOURGLASS demoResetSysVars resolve_routine, Name ;Be sure its compiled/loaded state.demo_name = Name ;Save name of demo WIDGET_CONTROL, state.mainWinBase, map=0 ;Unmap menu if !Version.Os_Family EQ 'MacOS' then WAIT, .1 if state.debug then begin ;Clean up our memory first, we should ;have nothing allocated except the ;pointers for the screen cache. ptr_free, state.png_header.cache ;Free our screens state.png_header.cache = ptr_new() ;by clearing the cache... state.memory = memory() ;Save memory state endif if n_elements(extra) gt 0 then $ ;Call it call_procedure, $ Name, $ GROUP=top, $ APPTLB = appTLB, $ RECORD_TO_FILENAME=state.record_to_filename, $ _EXTRA=extra $ else call_procedure, $ Name, $ GROUP=top, $ APPTLB = appTLB, $ RECORD_TO_FILENAME=state.record_to_filename if state.debug then begin endif if n_elements(appTLB) then state.appTlb = appTLB $ else state.appTlb = 0L end ;---------------------------------------------------------------------------- ; ; Purpose: Display IDL functional summary in text widgets pro demoFuncsumCleanup, wTopBase end pro demoFuncsumEvent, sEvent if (TAG_NAMES(sEvent, /STRUCTURE_NAME) EQ $ 'WIDGET_KILL_REQUEST') then begin WIDGET_CONTROL, sEvent.top, /DESTROY RETURN endif WIDGET_CONTROL, sEvent.top, GET_UVALUE=sStateFuncsum, /NO_COPY WIDGET_CONTROL, sEvent.id, GET_UVALUE= uvalue case uvalue of 'LIST': begin index = sevent.index indexStr = strtrim(index, 2) topicNum = (fix(indexStr)+2)*10 + 5000 online_help, topicNum, /CONTEXT, $ book=demo_filepath("idl_demo.hlp", $ SUBDIR=['examples','demo','demohelp']), $ /FULL_PATH end 'QUIT' : BEGIN WIDGET_CONTROL, sEvent.top, SET_UVALUE=sStateFuncsum, /NO_COPY WIDGET_CONTROL, sEvent.top, /DESTROY RETURN end ; of QUIT ELSE: help, /str, sEvent endcase WIDGET_CONTROL, sEvent.top, SET_UVALUE=sStateFuncsum, /NO_COPY end PRO demoFuncsum, $ GROUP=group, $ ; IN: (opt) group identifier APPTLB = appTLB ; OUT: (opt) TLB of this application ; Check the validity of the group identifier. ; ngroup = N_ELEMENTS(group) if (ngroup NE 0) then begin check = WIDGET_INFO(group, /VALID_ID) if (check NE 1) then begin print,'Error, the group identifier is not valid' print, 'Return to the main application' RETURN endif groupBase = group endif else groupBase = 0L ; Read the topics for the list OPENR, lun, /get_lun, demo_filepath("funcsum_topics.txt", $ SUBDIR=['examples','demo','demotext']) line='' readf, lun, line topicList = [line] while not eof(lun) do begin readf, lun, line topicList = [topicList, line] endwhile free_lun, lun ; Create widgets. ; if (N_ELEMENTS(group) EQ 0) then begin wTopBase = WIDGET_BASE(/COLUMN, $ TITLE="IDL Functional Summary", $ XPAD=0, YPAD=0, $ /TLB_KILL_REQUEST_EVENTS, $ TLB_FRAME_ATTR=1, MBAR=barBase) endif else begin wTopBase = WIDGET_BASE(/COLUMN, $ TITLE="IDL Functional Summary", $ XPAD=0, YPAD=0, $ /TLB_KILL_REQUEST_EVENTS, $ GROUP_LEADER=group, $ /FLOATING, $ TLB_FRAME_ATTR=1, MBAR=barBase) endelse ; Create the menu bar. It contains the file/quit, ; edit/ shade-style, help/about. ; wFileButton = WIDGET_BUTTON(barBase, VALUE='File', /MENU) wQuitButton = WIDGET_BUTTON(wFileButton, $ VALUE='Quit', UVALUE='QUIT', $ UNAME='demo:quit') ; Create a sub base of the top base (wTopBase) ; subBase = WIDGET_BASE(wTopBase, /COLUMN) wLabel = WIDGET_LABEL(subBase, value= $ 'For detailed information select a topic.') wList = WIDGET_LIST(subBase, value=topicList, $ uvalue="LIST", $ ysize=n_elements(topicList)) ; Realize the base widget. ; WIDGET_CONTROL, wTopBase, /REALIZE ; Returns the top level base in the appTLB keyword ; appTLB = wTopBase ; Create the state structure. ; sStateFuncsum = { $ topicList: topicList, $ wTopBase : wTopbase, $ ; Top level base groupBase: groupBase $ ; Base of Group Leader } WIDGET_CONTROL, wTopBase, SET_UVALUE=sStateFuncsum, /NO_COPY XMANAGER, 'demoFuncsum', wTopBase, $ EVENT_HANDLER='demoFuncsumEvent', $ /NO_BLOCK, $ CLEANUP='demoFuncsumCleanup' end ; ;---------------------------------------------------------------------------- ; ; Purpose: Get the screen size. Returns failure (0) if the ; screen size is too small, returns 1 (success) ; otherwise. ; function demoGetScreenSize, $ DesiredX, $ DesiredY, $ ActualX, $ ActualY DEVICE, GET_SCREEN_SIZE=scr_size ActualX = scr_size[0] ActualY = scr_size[1] if ((DesiredX LE ActualX) AND (DesiredY LE ActualY)) then RETURN, 1 str_x = Strtrim(String(DesiredX), 2) str_y = Strtrim(String(DesiredY), 2) junk = DIALOG_MESSAGE(['The screen resolution must be at least', $ '640 by 480 to run this demo.']) RETURN, 0 end ;---------------------------------------------------------------------------- ; ; Purpose: Initilize the main demo. Show the start up ; screen. ; function demoInit, $ fullScrXsize, $ ; IN: X monitor size fullScrYsize, $ ; IN: Y monitor size savedDecomposed ; OUT: Original setting of decomposed setting of device case !Version.Os_Family OF 'vms': add = '' 'Windows': add = '\EXAMPLES\DEMO;' 'MacOS': add = ':Examples:Demo,' ELSE: add = '/examples/demo:' endcase if add ne '' and strpos(!path, add) lt 0 then $ ;Add our path? !Path = !Dir + add + !Path if ((!D.Flags AND (2L^16)) NE (2L^16)) then begin Print, ' ' Print, 'Unable to start the IDL demo.' Print, 'The current device does not support widgets.' Print, 'See the "SET_PLOT" command for more information.' Print, ' ' RETURN, -1 endif ; Test for the presence of one of the demo save files to determine ; if the demos have been installed. (The main demo.sav file is ; always installed on some systems.) If the file is not present, ; exit with a warning. openr, Lun, DEMO_FILEPATH('d_animate.sav', SUBDIR=['examples','demo']), $ /GET_LUN, ERROR=i if (i Lt 0) then begin tmp = DIALOG_MESSAGE( /ERROR, [ $ 'This IDL Demo application is missing files which are normally', $ 'installed with the demo option of the installation.', $ '', $ 'See your installation guide for details on installing the demo.']) RETURN, -1 endif Free_Lun, Lun ; Initialize the device. ; if (((!D.Name EQ 'X') OR (!D.NAME EQ 'MAC')) AND $ (!D.N_Colors GE 256L)) then DEVICE, Pseudo_Color=8 DEVICE, GET_DECOMPOSED=savedDecomposed DEVICE, Decomposed=0 DEVICE, Bypass_Translation=0 ; This is needed since the screens are unmapped and then mapped. ; DEVICE, RETAIN=2 ; Determine the Screen Size ; if !Version.Os_Family EQ 'MacOS' then begin minXsize = 640 minYsize = 400 endif else begin minXsize = 640 minYsize = 480 endelse if not(demoGetScreenSize(minXsize, minYsize, fullScrXsize, fullScrYsize)) $ then RETURN, -1 ; Set default font for text in widgets ; CASE !Version.OS_Family OF ; Don't set it for Windows or Mac, the systems defaults are fine 'Windows': 'MacOS': ELSE: BEGIN ; Find a font for Unix and VMS. save_wind = !D.Window Window, /Free, Xsize=4, Ysize=4, /Pixmap, Retain=2 pix_win = !D.Window Font = demoXFindFont(['-adobe-helvetica-medium-r-normal--12-*-*-*', $ '9x15']) wdelete, pix_win wset, save_wind IF (font ne '') THEN Widget_Control, Default_Font= Font ENDCASE ENDCASE RETURN, 1 ; Return 1 for success. end ;---------------------------------------------------------------------------- ; ; Purpose: Cleanup procedure. ; pro demoCleanup, $ tlb ; IN: Top level base WIDGET_CONTROL, tlb, GET_UVALUE=state, /NO_COPY ; Restore the previous color table. ; TVLCT, state.colorTable ptr_free, state.png_header.cache ptr_free, state.png_header.colortb ; If the livetools demo was run, there are special heap ; variables that persist until destroyed with the ; /ENVIRONMENT keyword. If another LIVE_* or insight ; process is up when we call LIVE_DESTROY, the environment ; will not be destroyed and an error message will result. ; Ignore the error message. ; LIVE_DESTROY, /ENVIRONMENT, ERROR=void ; !quiet = state.quiet !order = state.order DEVICE, DECOMPOSED=state.savedDecomposed if state.debug then begin print, "Looking for heap vars, windows, file units: help, /heap help, /files print, '!d.window: ', !d.window end end ; demoCleanup ;---------------------------------------------------------------------------- ; ; Purpose: Main event handler. ; ; The uvalue (or in the case of pulldown menus, the uvalue is saved in ; state.MenuActions) is encoded as follows: ; quit = quit ; INSIGHT-START = start insight. ; >FileName|Title = display the file FileName in the demotext ; directory, with the given title. ; ' then begin ;Display a file parts = strtok(rest, '|', /extract) ;Get file name & title xdisplayfile, demo_filepath(parts[0] + '.txt', $ SUBDIR=['examples','demo','demotext']), $ group=group, HEIGHT=35, WIDTH=75, $ font=state.xdisplayfile_text_font, $ title= parts[1] endif else if char eq '<' then begin ;Display a topic from online help parts = strtok(rest, '|', /extract) ;Get file name & book topicNum = fix(parts[0]) book = parts[1] if (book EQ 'idl_demo.hlp') then begin book=demo_filepath("idl_demo.hlp", $ SUBDIR=['examples','demo','demohelp']) online_help, topicNum, /CONTEXT, $ book=book, $ /FULL_PATH endif else begin online_help, topicNum, /CONTEXT, $ book=book endelse endif else if char eq '?' then begin demoStartHelp, rest, event.top endif else begin ;Must be a demoStartApp if uval eq 'quit' then begin ;Quit is a special case WIDGET_CONTROL, event.top, SET_UVALUE=state ;Restore our state WIDGET_CONTROL, event.top, /destroy return endif else if uval eq 'INSIGHT-START' then begin if keyword_set(state.record_to_filename) then $ void = dialog_message([$ 'The IDL Demo System''s RECORD functionality', $ 'is not able to record Insight events.', $ 'Insight events will not be included in the ', $ 'current recording.' $ ]) demoStartInsight, event.top endif else begin ;Just call the app if keyword_set(state.record_to_filename) then begin if max( $ strupcase(uval) $ eq ['D_CONTOUR', 'D_FLYTHRU', 'D_IMAGPROC', $ 'D_MAP', 'D_MATHSTAT', 'D_OBJWORLD2', $ 'D_PLOT2D', 'D_SURFVIEW', 'D_T_SERIES', $ 'D_USCENSUS','D_VECTRACK', 'D_VOLRENDR', $ 'D_WAVELET'] $ ) $ eq 0 then begin void = dialog_message( $ ['The ' + uval + ' application requires code ', $ 'modifications to be recordable. The file to', $ 'which you are currently recording, ', $ state.record_to_filename +', will not contain events',$ 'for ' + uval + ', and may cause errors if', $ 'it is run via the IDL Demo Tour without', $ 'modification.'], $ DIALOG_PARENT=event.top $ ) end end case uval of ;Check for special cases 'FUNCSUM': demoFuncsum, group=event.top 'ROI-SPACE' : demoStartApp, 'D_ROI', state, event.top, $ EXTRA={ASTRO:1} 'FILTER-SIGNAL' : demoStartApp, 'D_FILTER', state, event.top, $ EXTRA={FILENAME: 'damp_sn.dat'} 'FILTER-ENGR': demoStartApp, 'D_FILTER', state, event.top, $ EXTRA={FILENAME: 'damp_sn.dat'} 'FILTER-SPACE': demoStartApp, 'D_FILTER', state, event.top, $ EXTRA={FILENAME:'galaxy.dat'} 'XROI': demoStartApp, 'XROI', state, event.top, $ EXTRA={TEST:1} else : demoStartApp, uval, state, event.top ;Normal demo endcase endelse endelse WIDGET_CONTROL, event.top, SET_UVALUE=state, /NO_COPY ;Restore our state END ; demoEvent ;---------------------------------------------------------------------------- ; ; Purpose: Main procedure for IDL demo. ; pro demo, debug=debug, record=record on_error, 2 ; Return to caller on error. if lmgr(/demo) and keyword_set(record) then $ message, 'Recording functionality is not available ' + $ 'in IDL timed demo mode.' ; This is a list of demos that are slow. If we judge the machine to ; be slow, and we run one of these demos, a message is displayed the ; first time the demo is run. slow_demos = [ 'D_GLOBE', 'D_HEART', 'D_OBJ', 'D_ORBIT', $ 'D_SURFVIEW', 'D_TANKLEAK', 'D_FLYTHRU', 'D_USCENSUS', $ 'D_VOLRENDR', 'D_VECTRACK'] debug = keyword_set(debug) t0 = systime(1) tstart = t0 quietsave = !quiet !quiet = 1 ;Remove obnoxious messages if ( xregistered ( "demo" ) NE 0 ) then RETURN ; make sure images are displayed properly saveOrder = !order !order = 0 if (demoInit(fullScrXsize, fullScrYsize, savedDecomposed) LT 0) then return resolve_routine, 'd_animate' ;Cause it contains multiple files if debug then demoTimer, 'demoInit', t0 ; Get the current color table. ; It will be restored when exiting. ; TVLCT, colorTable, savedG, savedB, /GET colorTable=[[colorTable],[savedG],[savedB]] If demoMakeCache(Header) lt 0 then $ return ;If we cant find screens file, adios. ; Read and display the splash screen Image = demoPReadScreen( $ n_elements(Header.filename)-1, $ ;Index of splash. Header, $ Colortb, $ /NO_CACHE $ ) demoSplashStart, $ fullScrXsize, $ fullScrYsize, $ *Image, $ ; Display splash. colortb, $ splashBase, $ startSplash Ptr_Free, Image ;No longer required if debug then demoTimer, 'demoSplashStart', t0 WIDGET_CONTROL, /HOURGLASS ; Setup the Main Window and Pull Down Menus. if ((!version.os_family EQ 'MacOS') AND $ (fullScrXsize LT 700 OR fullScrYsize LT 560)) then begin ; Use a scrolling base to allow access to all of demo screen on MacOS ; with small screen xPad = 20 yPad = 20 mainWinBase = WIDGET_BASE ( TITLE="IDL Demo", /COLUMN, $ /ALIGN_CENTER, $ XSIZE=640, YSIZE=480, $ X_SCROLL_SIZE=fullScrXsize - xPad, $ Y_SCROLL_SIZE=fullScrYsize - yPad, $ MBAR=mainWinMenuBase, TLB_FRAME_ATTR=1, $ /TLB_KILL_REQUEST_EVENTS, $ UNAME='demo:mainWinBase', $ MAP=0 ) endif else begin mainWinBase = WIDGET_BASE ( TITLE="IDL Demo", /COLUMN, $ /ALIGN_CENTER, $ MBAR=mainWinMenuBase, TLB_FRAME_ATTR=1, $ /TLB_KILL_REQUEST_EVENTS, $ UNAME='demo:mainWinBase', $ MAP=0 ) endelse demoMenuDef, MenuDescription nmenus = n_elements(MenuDescription) /2 ;# of menu items. MenuDescription = REFORM(MenuDescription, 2, nmenus, /OVERWRITE) mainWinMenu = CW_PDMENU ( mainWinMenuBase, MenuDescription[0,*], $ /RETURN_INDEX, /MBAR, UVALUE='MAIN_PULLDOWN' ) WIDGET_CONTROL, mainWinMenu, SET_UNAME='demo:main_pulldown' ; Create the base for the images and buttons. imageBase = WIDGET_BASE(mainWinBase, XSIZE=630, YSIZE=410) ; Create the status message area. startMainStatus = "Welcome to the IDL Demo: Please select a topic..." currMainStatus = startMainStatus statusAreaBase = WIDGET_BASE ( mainWinBase, frame=3 ) statusAreaMsg = WIDGET_LABEL(statusAreaBase, VALUE=startMainStatus, $ /ALIGN_LEFT ) if debug then demoTimer, 'MainWindowCreate', t0 ; Do as much as possible to load the main image before ending splash screen. demoButtonDef, buttons if debug then demoTimer, 'demoButtonDef', t0 demoButtonCreate, imageBase, buttons if debug then demoTimer, 'demoButtonCreate', t0 newMainDraw = WIDGET_DRAW(imageBase, XSIZE=630, YSIZE=410) WIDGET_CONTROL, mainWinBase, /REALIZE, MAP=0 WIDGET_CONTROL, newMainDraw, GET_VALUE=mainDrawID WSET, mainDrawID ; for X, the device call in demoXFindFont must be done ; when a window is active. Save this fontname for later use. case !Version.Os_Family OF 'Windows': xdisplayfile_text_font = 'Courier*10' 'MacOS': xdisplayfile_text_font = 'Monaco*10' ELSE: xdisplayfile_text_font = $ demoXFindFont(['-misc-fixed-medium-r-normal--10-*-*-*']) endcase if keyword_set(record) then begin master_filenames = findfile( $ demo_filepath( $ (['recording??.txt', 'recording%%.txt']) $ [!version.os_family eq 'vms'], $ subdir=["examples", "demo", "demodata"] $ ) $ ) if master_filenames[0] eq '' then $ record_to_filename = 'recording00.txt' $ else begin master_filenames = master_filenames[reverse(sort(master_filenames))] record_to_filename = 'recording' $ + string( $ fix( $ strmid( $ master_filenames[0], $ strlen(master_filenames[0]) - 6, $ 2 $ ) $ ) + 1, $ format='(i2.2)' $ ) $ + '.txt end end $ else $ record_to_filename = '' ; Take down the splash screen. ; demoSplashEnd, startSplash, splashBase, debug if debug then demoTimer, 'SplashEnd', t0 mainWinInfo = { $ ; Create the main state structure. mainWinBase:mainWinBase, $ imageBase : imageBase, $ buttons: buttons, $ mainDrawID: mainDrawID, $ apptlb : 0L, $ curScreenNum: 0L, $ prevScreenNum: 0L, $ MenuActions : MenuDescription[1,*], $ colorTable: colorTable, $ ; Color table to restore quiet: quietsave, $ png_header: temporary(header), $ slow : 0, $ demo_name: '', $ memory : memory(), $ debug : debug, $ slow_demos : slow_demos, $ order: saveOrder, $ xdisplayfile_text_font: xdisplayfile_text_font, $ record_to_filename: record_to_filename, $ savedDecomposed: savedDecomposed $ } MenuDescription = 0 ;All done with the menu demoShowScreen, 0, mainWinInfo WIDGET_CONTROL, mainWinBase, /map ;Is this machine slow? Very approximate... mainWinInfo.slow = (systime(1) - tstart ) gt 5 ; Save state in top base uvalue WIDGET_CONTROL, mainWinBase, SET_UVALUE=mainWinInfo, /no_copy ; Register program with XManager. ; if debug then demoTimer, 'Total Time', tstart XMANAGER, "demo", mainWinBase, $ EVENT_HANDLER="demoEvent", $ /NO_BLOCK, $ CLEANUP="demoCleanup" end ; demo ; * Main Procedure for embedded mode. PRO MAIN DEMO END