;+ ; NAME: ; XWINDOW ; ; PURPOSE: ; This routine implements a "smart" resizeable graphics window. ; It is used as a wrapper for built-in IDL graphics procedures ; such as SURFACE, CONTOUR, PLOT, SHADE_SURF, etc. In additon, ; it can be used to display any user-written graphics procedure ; so long as that procedure follows three simple rules: (1) It ; does not open it's own graphics windows, (2) It is defined with ; no more than ten positional arguments (an unlimited number ; of keyword arguments are allowed), and (3) It is defined ; with an _EXTRA keyword. ; ; Keyword arguments permit the window to have its own portion ; of a color table and to be able to change the colors loaded in ; that portion of the color table. Colors are updated ; automatically on both 8-bit and 24-bit color displays. In ; addition, the window colors can "protect" themselves. I mean ; by this that the window can re-load its own colors into the ; color table when the cursor is moved over the window. This ; prevents other applications from changing the colors used to ; display data in this window. (This is an issue mainly in ; IDL 5.x applications where widget applications can run ; concurrently with commands from the IDL command line.) ; ; Keyword arguments also permit the window to create output ; files of its contents. These files can be color and ; gray-scale PostScript, GIF, TIFF, or JPEG files. ; ; AUTHOR: ; ************* CM 19 Jan 1999 VERSION ********** ; Craig B. Markwardt, NASA/GSFC Code 662, Greenbelt, MD 20770 ; craigm@lheamail.gsfc.nasa.gov ; ; Originally by: ; FANNING SOFTWARE CONSULTING ; David Fanning, Ph.D. ; 2642 Bradbury Court ; Fort Collins, CO 80521 USA ; Phone: 970-221-0438 ; E-mail: davidf@dfanning.com ; Coyote's Guide to IDL Programming: http://www.dfanning.com ; ; CATEGORY: ; Widgets, Graphics. ; ; CALLING SEQUENCE: ; XWINDOW, command, P1, P2, ... , keywords=..., ... ; ; REQUIRED INPUTS: ; COMMAND: The graphics procedure command to be executed. This parameter ; must be a STRING. Examples are 'SURFACE', 'CONTOUR', 'PLOT', etc. ; ; OPTIONAL INPUTS: ; Pn: A positional parameter appropriate for the graphics command. ; Any number of parameters between 0 and 10 may be given. ; ; INPUT KEYWORD PARAMETERS: ; CPMENU: Setting this keyword adds a "Color Protection" button to the ; "Controls" menu. Color protection can then be turned ON or OFF for the ; window. Otherwise, the color protection scheme used to open the window ; cannot be changed once the window is open. (See the PROTECT keyword.) ; The default is to have this keyword OFF. ; ; ERASE: Setting this keyword "erases" the contents of the current ; graphics window before re-executing the graphics command. For example, ; this keyword might need to be set if the graphics "command" is TVSCL. ; The default is to NOT erase the display before reissuing the graphics ; command. ; ; _EXTRA: This keyword forms an anonymous structure of any unrecognized ; keywords passed to the program. The keywords must be appropriate ; for the graphics command being executed. ; ; GROUP_LEADER: The group leader for this program. When the group leader ; is destroyed, this program will be destroyed. ; ; OUTPUT: Set this keyword if you want a "File Output" menu on ; the menu bar. The default is to have this item turned OFF. ; ; JUST_REGISTER: If this keyword is set, the XWINDOW program is just ; registered with XMANAGER, but XMANAGER doesn't run. This is ; useful, for example, if you want to open an XWINDOW window in ; the widget definition module of another widget program. ; ; NO_CHANGE_CONFIG: Normally as the XWINDOW graphics window is resized ; the size (or aspect ratio, in the case of PostScript) of the ; hardware configuration dialogs change to reflect the new size of ; the graphics window. This results in file output that resembles ; the current graphics window in size and aspect ratio. If you want ; the file output dialogs to remember their current configuration ; even as the window is resized, set this keyword. ; ; NOMENU: Setting this keyword results in a graphics window without ; menu items. The default is to have a "Controls" menu item in the ; window menu bar with a "Quit" button. Setting this keyword ; automatically turns of the COLORS, OUTPUT, and CPMENU menu ; choices. (Note that the values specified by the COLORS keyword ; will still be valid for color protection, but no "Change Colors..." ; menu item will appear.) ; ; PROTECT: If this keyword is set, color protection for the draw ; widget is turned ON. What this means is that the window colors ; (see the XCOLOR keyword) will be restored when the cursor enters ; the draw widget window. This prevents someone at the IDL command ; line in IDL 5.0 from changing the window display colors permanently. ; ; WTITLE: This is the window title. It is the string "Resizeable ; COMMAND Window (1)" by default, where COMMAND is the input ; parameter. And the number (1 in this case) is the window ; index number of the draw widget. ; ; WXPOS: This is the initial X offset of the window. Default is to ; position the window in the approximate middle of the display. ; ; WYPOS: This is the initial Y offset of the window. Default is to ; position the window in the approximate middle of the display. ; ; WXSIZE: This is the initial X size of the window. Default is 400 ; pixels. ; ; WYSIZE: This is the initial Y size of the window. Default is 400 ; pixels. ; ; XCOLORS: Using this keyword adds a "Change Colors..." button to the ; "Controls" menu. Set this keyword to the number of colors available ; in the window and the starting index of the first color. For example, ; to allow the window access to 100 colors, starting at color index 50 ; (i.e., color indices 50 to 149), use XColor=[100, 50]. If you use the ; keyword syntax "/XColor", all the colors available will be used, not just ; one color. If the keyword is set to a scalar value greater than 1, the ; starting color index is set to 0. The default value for this keyword ; is [(!D.N_COLORS < 256), 0]. Note that color "protection" may be ; turned on (via the PROTECT keyword) even if this keyword is NOT used. ; ; OUTPUT KEYWORD PARAMETERS: ; DRAWID: This keyword returns the draw widget identifier of the draw ; widget created in XWINDOW. ; ; TOP: This keyword returns the identifier of the top-level base widget ; created by XWINDOW. ; ; WID: This keyword returns the window index number of the draw widget ; created in XWINDOW. ; ; COMMON BLOCKS: ; None. ; ; SIDE EFFECTS: ; If color protection is ON, the window colors are reloaded when the ; cursor enters the XWINDOW graphics windows. ; ; RESTRICTIONS: This program requires three additional programs from ; the Fanning Software Consulting library: PSWINDOW, PS_FORM (CM ; version; available at ; http://astrog.physics.wisc.edu/~craigm/idl), and XCOLORS. You ; might also want to get the program TVIMAGE if you will be ; displaying images in XWINDOW graphics windows. ; ; If the "command" program requires keywords that are also keywords ; to XWINDOW, then you must use the keyword twice on the command line. ; ; EXAMPLE: ; To display a surface in the window, type: ; ; XWINDOW, 'SURFACE', Dist(20), Charsize=1.5 ; ; To enable the Change Colors and File Output menu items, type: ; ; XWINDOW, 'SHADE_SURF', Dist(30), /XColors, /Output ; ; MODIFICATION HISTORY: ; Written by: David Fanning, October 96. ; XSIZE and YSIZE keywords changed to WXSIZE and WYSIZE so as not to ; conflict with these keywords on other programs. 14 April 1997, DWF. ; Updated as non-blocking widget for IDL 5.0. 14 April 1997, DWF. ; Extensively modified to work on either 8-bit or 24-bit displays, ; to enable color protection schemes, to send the contents to a ; number of different output files, and to give the user choices ; about which menu items to enable. 21 April 1997, DWF. ; Renamed COLORS keyword to XCOLORS and fixed a problem cancelling ; out of File Configuration dialogs. 23 April 1997, DWF. ; Modification: Craig Markwardt, 21 October 1997 ; Added capability for up to ten positional parameters ; Modification: CM 15 May 1998 ; PS_FORM dependencies are not hardcoded now. Requires ; CM version of PS_FORM function. ; Modification: CM 19 Jan 1999 ; Added Parent keyword to widget invocation of PS_FORM, and ; make widgets MODAL-safe. ;- ; Compose the command thisCommand = proName FOR i = 2, np DO $ thisCommand = thisCommand + ', plotObj.param' +STRTRIM(i-1, 2) ; If any extra keywords are present, put them on the command line IF extraFlag THEN $ thisCommand = thisCommand + ', _EXTRA=plotObj.extra' ELSE $ extra = 0 ; We need to make sure that all of the parameters are set, at least to 0, ; so that they can be entered into the plotobj structure. IF NOT KEYWORD_SET(param1) then param1 = 0 IF NOT KEYWORD_SET(param2) then param2 = 0 IF NOT KEYWORD_SET(param3) then param3 = 0 IF NOT KEYWORD_SET(param4) then param4 = 0 IF NOT KEYWORD_SET(param5) then param5 = 0 IF NOT KEYWORD_SET(param6) then param6 = 0 IF NOT KEYWORD_SET(param7) then param7 = 0 IF NOT KEYWORD_SET(param8) then param8 = 0 IF NOT KEYWORD_SET(param9) then param9 = 0 IF NOT KEYWORD_SET(param10) then param10 = 0 plotObj = { thisCommand:thisCommand, extra:extra, $ param1:param1, param2:param2, param3:param3, param4:param4, $ param5:param5, param6:param6, param7:param7, param8:param8, $ param9:param9, param10:param10 } ; Store the Plot Object at a pointer location. plotObjPtr = HANDLE_CREATE() ; Create the widgets for this program. DEVICE, GET_SCREEN_SIZE=screenSize IF N_ELEMENTS(wxpos) EQ 0 THEN wxpos = (screenSize(0) - xsize) / 2. IF N_ELEMENTS(wypos) EQ 0 THEN wypos = (screenSize(1) - ysize) / 2. IF NOT nomenu THEN BEGIN tlb = WIDGET_BASE(TLB_SIZE_EVENTS=1, $ XOFFSET=wxpos, YOFFSET=wypos, MBar=menubase) controls = Widget_Button(menubase, Value='Controls', /Menu) ; Need a COLORS button? IF needColors THEN BEGIN colorsID = WIDGET_BUTTON(controls, Value='Change Colors...', $ Event_Pro='XWINDOW_COLORS', UValue=colors) ENDIF ; Need color protection buttons? IF cpmenu THEN BEGIN cprotect = Widget_Button(controls, Value='Color Protection', $ /Menu, Event_Pro='XWindow_Color_Protection') cprotectON = Widget_Button(cprotect, Value='ON', UVALUE='ON') cprotectOFF = Widget_Button(cprotect, Value='OFF', UVALUE='OFF') ENDIF ELSE BEGIN cprotectON = -1L cprotectOFF = -1L ENDELSE ; Need FILE OUTPUT button? IF needOutput THEN BEGIN outputButton = WIDGET_BUTTON(menubase, Value='File Output', $ /Menu, Event_Pro='XWindow_Create_Files') psID = WIDGET_BUTTON(outputButton, Value='Create PostScript File') gifID = WIDGET_BUTTON(outputButton, Value='Create GIF File') tiffID = WIDGET_BUTTON(outputButton, Value='Create TIFF File') jpegID = WIDGET_BUTTON(outputButton, Value='Create JPEG File') configure = WIDGET_BUTTON(outputButton, Value='Configure Output File', $ /Menu, /Separator, Event_Pro='XWindow_Configure_Files') ps_config = WIDGET_BUTTON(configure, Value='Configure PostScript File...') gif_config = WIDGET_BUTTON(configure, Value='Configure GIF File...') tiff_config = WIDGET_BUTTON(configure, Value='Configure TIFF File...') jpeg_config = WIDGET_BUTTON(configure, Value='Configure JPEG File...') ENDIF ELSE BEGIN psID = -1L gifID = -1L tiffID = -1L jpegID = -1L ENDELSE quit = Widget_Button(controls, Value='Quit', Event_Pro='XWindow_Quit') ENDIF ELSE tlb = WIDGET_BASE(TLB_SIZE_EVENTS=1, $ XOFFSET=wxpos, YOFFSET=wypos) drawID = WIDGET_DRAW(tlb, XSIZE=xsize, YSIZE=ysize, $ Event_Pro='XWindow_Draw_Event', Tracking_Events=protect) WIDGET_CONTROL, tlb, /REALIZE WIDGET_CONTROL, drawID, GET_VALUE=wid WSET, wid ; Give each window a unique title. wtitle = wtitle + ' (' + STRTRIM(wid,2) + ')' Widget_Control, tlb, TLB_SET_TITLE=wtitle ; Set color protection button sensitivity. IF cpmenu THEN BEGIN IF protect THEN BEGIN WIDGET_CONTROL, cprotectON, Sensitive=0 WIDGET_CONTROL, cprotectOFF, Sensitive=1 ENDIF ELSE BEGIN WIDGET_CONTROL, cprotectON, Sensitive=1 WIDGET_CONTROL, cprotectOFF, Sensitive=0 ENDELSE ENDIF ; If something goes wrong executing the command, trap it. CATCH, error IF error NE 0 THEN BEGIN ok = WIDGET_MESSAGE(["There is a problem executing the command", $ "string in XWINDOW. Please check keyword", $ "spelling and command syntax. Returning..."]) HANDLE_FREE, plotObjPtr WIDGET_CONTROL, tlb, /DESTROY RETURN ENDIF ok = EXECUTE(plotObj.thisCommand) IF NOT ok THEN BEGIN ok = WIDGET_MESSAGE(["There is a problem executing the command", $ "string in XWINDOW. Please check keyword", $ "spelling and command syntax. Returning..."]) HANDLE_FREE, plotObjPtr WIDGET_CONTROL, tlb, /DESTROY RETURN ENDIF CATCH, /CANCEL ; Store the Plot Object in its pointer. HANDLE_VALUE, plotObjPtr, plotObj, /SET, /NO_COPY ; Create an info structure. info = { top:tlb, $ ; Top level widget xsize:xsize, $ ; X size of window. ysize:ysize, $ ; Y size of window. wid:wid, $ ; Window index number. drawID:drawID, $ ; Draw widget identifier. cprotectON:cprotectON, $ ; Color protection ON button. cprotectOFF:cprotectOFF, $ ; Color protection OFF button. wtitle:wtitle, $ ; Window title. r:r, $ ; Red colors in window. g:g, $ ; Green colors in window. b:b, $ ; Blue colors in window. wcolors:wcolors, $ ; Number of window colors. gifID:gifID, $ ; ID of Create GIF file button. tiffID:tiffID, $ ; ID of Create TIFF file button. jpegID:jpegID, $ ; ID of Create JPEG file button. psID:psID, $ ; ID of Create PS file button. bottom:bottom, $ ; Starting color index. protect:protect, $ ; Protect colors flag. nomenu:nomenu, $ ; No menu flag. nochange:nochange, $ ; No change flag. erase:Keyword_Set(erase), $ ; Need erasure flag. ncolors:(!D.N_Colors < 256), $ ; Size of color table. plotObjPtr:plotObjPtr, $ ; Pointer to plot object. output:needOutput } ; File Output menu flag. ; File Output configuration structures, if needed. IF Keyword_Set(output) THEN BEGIN CD, Current=thisDir ps = ps_form(/init, filename=FilePath(Root_Dir=thisDir,'xwindow.ps')) pslocal = ps_form(/init, filename=FilePath(Root_Dir=thisDir,'xwindow.ps'), $ xsize=10., xoff=0.5, ysize=7.5, yoff=0.5, color=1, $ landscape=1) gif = {XWINDOW_GIF,XSIZE:400, YSIZE:400, COLOR:1, $ FILENAME:FilePath(Root_Dir=thisDir,'xwindow.gif'), $ ORDER:0, QUALITY:-1} jpeg = {XWINDOW_JPEG,XSIZE:400, YSIZE:400, COLOR:1, $ FILENAME:FilePath(Root_Dir=thisDir,'xwindow.jpg'), $ ORDER:0, QUALITY:75} tiff = {XWINDOW_TIFF,XSIZE:400, YSIZE:400, COLOR:1, $ FILENAME:FilePath(Root_Dir=thisDir,'xwindow.tif'), $ ORDER:1, QUALITY:-1} info = CREATE_STRUCT(info, 'PS', ps, 'PSLOCAL', pslocal, 'GIF', gif, $ 'JPEG', jpeg, 'TIFF', tiff) ENDIF ; Store the info structure in the TLB. WIDGET_CONTROL, tlb, SET_UVALUE=info, /NO_COPY ; Register the program as on-blocking in 5.0. thisRelease = StrMid(!Version.Release, 0, 1) IF thisRelease EQ '5' THEN $ XManager, 'xwindow', tlb, EVENT_HANDLER='XWINDOW_RESIZE_EVENTS', $ CLEANUP='XWINDOW_CLEANUP', GROUP_LEADER=group, $ JUST_REG=justRegister, /No_Block ELSE $ XManager, 'xwindow', tlb, EVENT_HANDLER='XWINDOW_RESIZE_EVENTS', $ CLEANUP='XWINDOW_CLEANUP', GROUP_LEADER=group, JUST_REG=justRegister END