E_ITEMC.DLG BEGIN 101 0.00 0.00 11.00 18.00 v CBOX 102 0.50 1.50 1.00 1.50 v LTEXT 103 0.50 4.00 1.00 11.00 f CBOX 104 1.50 1.50 1.00 1.50 v LTEXT 105 1.50 4.00 1.00 11.00 f CBOX 106 2.50 1.50 1.00 1.50 v LTEXT 107 2.50 4.00 1.00 11.00 f CBOX 108 3.50 1.50 1.00 1.50 v LTEXT 109 3.50 4.00 1.00 11.00 f CBOX 110 4.50 1.50 1.00 1.50 v LTEXT 111 4.50 4.00 1.00 11.00 f CBOX 112 5.50 1.50 1.00 1.50 v LTEXT 113 5.50 4.00 1.00 11.00 f CBOX 114 6.50 1.50 1.00 1.50 v LTEXT 115 6.50 4.00 1.00 11.00 f CBOX 116 7.50 1.50 1.00 1.50 v LTEXT 117 7.50 4.00 1.00 11.00 f PBUT -118 0.50 15.00 1.00 2.00 v ^ PBUT -119 7.50 15.00 1.00 2.00 v v PBUT -120 9.25 1.00 1.50 8.00 v OK PBUT -121 9.25 9.00 1.50 8.00 v Cancel END If the list of items exceeds the size of the dialog box, the "^" and/or "v" buttons are enabled to allow the user to scroll through the list. (Another dialog box, E_ITEMR.DLG, replaces CBOX widgets with RBUT, enabling a single choice item picker.) Now let's use GUITOOL directives to create and populate the dialog and return the response:Thanks to GUITOOL, the only difficulty is maintaining the check state of the items, which is handled by routine CHKITEM:*ROUTINE getitem e_itemc.dlg 1 e_itemr.dlg 1 *REM arg1 = C or R (check box or radio button) *REM arg2 = title for dialog box &define i -9 &var &define wtype -11 &var &define title -12 &var &define numit -13 &var &define pos -14 &var &define resp -15 &var &define wksp -16 &var &define temp -19 &var &rem **** load items starting at variable 130 &extract [wtype] -1 1 &value [title] -2 &value [wksp] WKSP &openw [wksp]t$temp.lis ITEMS &closew &open [wksp]t$temp.lis error &sv [numit] 0 &while &do &read [temp] [break] &extract -1 [temp] 1 &if &nm %-1 &do &extract -2 [temp] 2 &extract -3 [temp] 3 &extract -4 [temp] 4 &extract -5 [temp] 5 &sv [temp] "%-2 %-3 %-4 %-5 0" &value %<[numit] + 130> [temp] &inc [numit] &end &end &close & DEL [wksp]t$temp.lis &rem **** initialize and open dialog &openw [winfile] *W S 101 [title] &sv [i] 1 &while &rn [i] 1 %<[numit] min 8> &do &extract [temp] %<[i] + 129> 1 *W S %<[i] * 2 + 101> [temp] &inc [i] &end &sv [pos] 1 *W G 118 &if &eq %<[numit] max 8> 8 &do *W G 119 &else *W E 119 &end &if &rn [numit] 1 7 &do &cv [i] [numit] + 1 &while &rn [i] 1 8 &do *W G %<[i] * 2 + 100> &inc [i] &end &end &closew &sv [resp] CANCEL &if &eq C [wtype] &do *OPEN e_itemc.dlg &else *OPEN e_itemr.dlg &end &rem **** pick loop *PICK 118 &openw [winfile] &if &eq %<[pos] min 7> [pos] &do &sv [temp] 1 &else &cv [temp] [pos] - 7 &end &if &eq [temp] 1 &do *W G 118 &end *W E 119 &r chkitem [pos] [temp] [wtype] [numit] &closew &sv [pos] [temp] *PICK 119 &openw [winfile] &if &eq %<( [pos] + 14 ) max [numit] > [numit] &do &cv [temp] [pos] + 7 &else &cv [temp] [numit] - 7 &end *W E 118 &if &eq %<[temp] + 7> [numit] &do *W G 119 &end &r chkitem [pos] [temp] [wtype] [numit] &closew &sv [pos] [temp] *PICK 120 &sv [resp] OK *CLOSE *PICK 121 *CLOSE *ENDPICK &rem **** generate reply &if &eq CANCEL [resp] &do &return [resp] &end &r chkitem [pos] [pos] [wtype] [numit] &sv [i] 1 &sv [resp] 0 &while &rn [i] 1 [numit] &do &extract [temp] %<[i] + 129> 5 &if &eq [temp] 1 &do &inc [resp] &extract -1 %<[i] + 129> 1 &extract -2 %<[i] + 129> 2 &extract -3 %<[i] + 129> 3 &extract -4 %<[i] + 129> 4 &sv %<[resp] + 500> "%-1 %-2 %-3 %-4" &end &inc [i] &end &return [resp] &rem **** I/O error trap &label error &type "I/O Error" &sv [resp] CANCEL &return [resp]
*ROUTINE chkitem *REM check and set state of items &define i -9 &var &define old -11 &var &define new -12 &var &define wtype -13 &var &define numit -14 &var &define name -15 &var &define state -16 &var &define unchk -17 &var &value [old] -1 &value [new] -2 &value [wtype] -3 &value [numit] -4 &sv [i] 1 &sv [unchk] 0 &while &rn [i] 1 8 &do &value -1 %<[i] * 2 + 100> &cv [unchk] [unchk] + %-1 &inc [i] &end &sv [i] 1 &while &rn [i] 1 [numit] &do &if &rn [i] [old] %<[old] + 7> &do &value [state] %<[i] - [old] * 2 + 102> &extract -1 %<[i] + 129> 1 &extract -2 %<[i] + 129> 2 &extract -3 %<[i] + 129> 3 &extract -4 %<[i] + 129> 4 &sv %<[i] + 129> "%-1 %-2 %-3 %-4 [state]" &elseif &eq R [wtype] &and &ne [unchk] 0 &do &extract -1 %<[i] + 129> 1 &extract -2 %<[i] + 129> 2 &extract -3 %<[i] + 129> 3 &extract -4 %<[i] + 129> 4 &sv %<[i] + 129> "%-1 %-2 %-3 %-4 0" &end &if &ne [old] [new] &and &rn [i] [new] %<[new] + 7> &do &extract [name] %<[i] + 129> 1 &extract [state] %<[i] + 129> 5 *W S %<[i] - [new] * 2 + 102> [state] *W S %<[i] - [new] * 2 + 103> [name] &end &inc [i] &end &returnThus when a dialog is scrolled, the check state of items is preserved:
Similarly, when the R option is used and an item is checked, the previously checked item is unchecked. Should the number of items be less than 8, the appropriate widgets are grayed:
When the "OK" button is clicked, GETITEM returns the number of items picked (0 if none) and loads those item names and definitions into SML variables starting at number 501 (a distinct advantage over the old method, which returned a string of item names that was limited to 80 characters). The number in turn may be passed to a FORMS or CALC routine.
One disadvantage of this approach is that a separate dialog box is required for a radio button list. Also, supporting the arrow buttons requires a bit of code. Nonetheless, by taking this approach I'm simplifying the dialog-related code, and by enhancing the returned information content I'm able to apply this routine to more situations.
The basic strategy is to restrict variable assignment as much as possible; if an application can read a value using &value or SHOW, there's no need to maintain a global variable. The following example applies the above approach to the ETOOL application developed in the previous issue (V6N4); only a few edit parameters are saved, just enough to give you an idea of what's involved. First, lets make some changes to the beginning of E_MAIN.MNU:
POPUP Project MENUI Open..., OPENP MENUI Save, SAVEP MENUI Save As..., SAVEPAS POPEND POPUP Cover MENUI Open..., SETCOV MENUI Save, SAVE MENUI Switch, SWITCH MENUI Remove, REMCOV MENUI Back Cover, BACKCOV MENUI Remove Back, REMBACK POPENDThen add some *PICK entries to the menu loop:
*PICK OPENP &r openp *PICK SAVEP &r savep *PICK SAVEPAS &r savepasAll three routines store the project file name in variable 51. Variable 52 is used as a flag to indicate whether changes have been made in pertinent project settings (e.g. setting an edit cover or back cover). Let's look at routine SAVEP first:
*ROUTINE savep *REM **** save session settings &define project 51 &var &define saved 52 &var &define i -11 &var &define editn -12 &var &define backn -13 &var &define temp -19 &var &define winrtn 1 &var &if &eq "x[project]" "x" &do WIN FILE 3 etp 'Save Project' &if &eq "x[winrtn]" "x" &do &return &end &value [project] [winrtn] &end &openw [project] *REM **** save editc and backc info &sv [i] 1 &sv [editn] 0 &sv [backn] 0 &while &rn [i] 1 4 &do SHOW BACKCOVER %[i] -1 &if &ne "x%-1" "x" &do &inc [backn] &value [temp] %<34 + [i]> *W BACKC %-1 [temp] *W &sv %<34 + [backn]> [temp] &end SHOW EDITCOVER %[i] -1 &if &ne "x%-1" "x" &do &inc [editn] &value [temp] %<30 + [i]> *W EDITC %-1 *W &sv %<30 + [editn]> [temp] &end &inc [i] &end &sv -1 X SHOW EDITCOVER 0 -1 SHOW EDITFEAT -2 &if &ne X %-1 &do *W EDITC %-1 *W EDITF %-2 &end *REM **** save draw settings SHOW DRAWE -1 -2 -3 -4 -5 *W DRAWE ARC %-1 NODE %-2 LABEL %-3 TIC %-4 ANNO %-5 SHOW SETDRAWS -1 -2 *W SETDRAWS %-1 *W SETDRAWS %-2 SHOW NODEC NODE -1 *W NODEC NODE %-1 SHOW NODEC DANGLE -1 *W NODEC DANGLE %-1 SHOW NODEC PSEUDO -1 *W NODEC PSEUDO %-1 SHOW BACKE -1 -2 -3 -4 -5 *W BACKE ARC %-1 NODE %-2 LABEL %-3 TIC %-4 ANNO %-5 SHOW LINESET -1 *W LINESET %-1 SHOW MARKERSET -1 *W MARKERSET %-1 SHOW TEXTSET -1 *W TEXTSET %-1 *REM **** save edit settings SHOW MAPE -1 -2 -3 -4 *W MAPE %-1 %-2 %-3 %-4 SHOW EDITD -5 SHOW SNAPD -6 SHOW WEED -7 SHOW GRAIN -8 MAPE ZOOM 2 SHOW EDITD -15 SHOW SNAPD -16 SHOW WEED -17 SHOW GRAIN -18 MAPE %-1 %-2 %-3 %-4 &if &ne %-5 %-15 &do &sv -5 DEFAULT &end &if &ne %-6 %-16 &do &sv -6 DEFAULT &end &if &ne %-7 %-17 &do &sv -7 DEFAULT &end &if &ne %-8 %-18 &do &sv -8 DEFAULT &end *W EDITD %-5 *W SNAPD %-6 *W WEED %-7 *W GRAIN %-8 *REM **** wrap up *W DRAW &closew &sv [saved] YES &returnIn this example, variables 31-34 store the current edit feature for each edit cover, and 35-38 store the symbol for each back cover (more on this in the next issue). Because SHOW only returns a number for the edit parameters EDITD, SNAPD, WEED, and GRAIN, the routine changes the map extent temporarily to see whether they are set to DEFAULT. Note also that the [winrtn] alias needs to be defined: if a *ROUTINE directive does not declare any dialogs, GUITOOL will not automatically define the [winrtn] and [winfile] aliases.
Since routine SAVEP saves an executable SML file, routine OPENP requires very little coding:
*ROUTINE openp &define project 51 &var &define saved 52 &var &define winrtn 1 &var &if &eq [saved] NO &do WIN MB 3 'Save Project Changes?' &if &eq [winrtn] YES &do &r savep &elseif &eq [winrtn] CANCEL &do &return &end &end WIN FILE 1 etp 'Load Project' &if &eq "x[winrtn]" "x" &do &return &end &value [project] [winrtn] &sv -1 1 &sv -2 .FALSE. &sv -3 .FALSE. &while &rn %-1 1 4 &do SHOW EDITCOV %-1 -4 &if &ne "x%-4" "x" &do &sv -2 .TRUE. &end SHOW BACKCOV %-1 -4 &if &ne "x%-4" "x" &do &sv -3 .TRUE. &end &inc -1 &end &if &eq %-2 .TRUE. &do REMOVEEDIT ALL Y &end &if &eq %-3 .TRUE. &do REMOVEBACK ALL &end &r [project] &sv [saved] YES &returnNote that the routine checks for the presence of edit and/or back coverages and removes them if necessary. Routine SAVEPAS requires even less code:
*ROUTINE savepas *REM **** save project settings as new file &define project 51 &var &define winrtn 1 &var WIN FILE 3 etp 'Save Project' &if &eq "x[winrtn]" "x" &do &return &else &value [project] [winrtn] &r savep &end &returnOops! I've just about run out of space. I'll continue this discussion in the next issue, showing some new tricks for maintaining edit and back coverages, as well as presenting a nifty way to launch project files through File Manager or Windows Explorer.