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 &returnNow we're going to take a look at how that information is maintained when opening and removing edit and back coverages. When opening an edit coverage, the user is automatically asked to set the edit feature, so the only change necessary is to add some lines at the end of routine SETEDITF:
*REM **** store edit feature &sv -2 1 SHOW EDITCOVER 0 -3 &while &rn %-2 1 4 &do SHOW EDITCOVER %-2 -4 &if &eq "x%-4" "x%-3" &do &value %<%-2 + 30> -1 &break &end &inc -2 &end &return %-1The four edit cover slots are searched for a match to editcover 0, and the edit feature (variable -1) is stored in the appropriate location. Also, the following line is placed at the end of the "*PICK SETCOV SETFEAT 106" entry in routine ETOOL:
&sv [saved] NOIn the last article some entries were added to E_MAIN.MNU to add back coverages and remove edit or back coverages; now we'll add some *PICK directives to routine ETOOL to support them:
*PICK REMCOV *OPEN remcov H EDIT *PICK BACKCOV *OPEN setbackc H &sv [saved] NO *PICK REMBACK *OPEN remcov H BACKLet's look at routine SETBACKC first. It uses a new dialog named E_SETBC.DLG:
BEGIN 0 0.00 0.00 6.00 24.00 v Back Coverage EBOX 101 0.50 1.00 1.50 20.00 v PBUT -102 0.50 21.50 1.50 1.50 v » LTEXT 0 2.50 1.00 1.00 8.00 v Symbol: EBOX 103 2.50 9.00 1.50 6.00 v 2 PBUT -104 2.50 15.50 1.50 1.50 v » PBUT -105 4.25 1.00 1.50 8.00 v OK PBUT -106 4.25 9.00 1.50 8.00 v Cancel
The code for routine SETBACKC is as follows:
*ROUTINE setbackc e_setbc.dlg 1 *REM **** get back cover &define i -10 &var &define pos -11 &var &sv [i] 1 &sv [pos] 0 &while &rn [i] 1 4 &do SHOW BACKCOVER %[i] -2 &if &eq "x%-2" "x" &do &cv [pos] 34 + [i] &break &end &inc [i] &end &if &eq [pos] 0 &do WIN MB 1 'No more room for back coverages' &return &end &sv -1 &sv -2 *OPEN e_setbc.dlg *PICK 102 *FILE 101 C * 'Enter coverage' *PICK 105 &sv -1 %101 &sv -2 %103 *CLOSE *PICK 106 *CLOSE *ENDPICK &if &eq "x%-1" "x" &do &return &end &if &eq "x%-2" "x" &do &sv -2 1 &end BACKC %-1 %-2 &value %[pos] -2 &sv [saved] NO &returnThe code is almost identical to routine SETEDITC save that it supports an extra widget (103) for the back symbol. (Support for widget 104, launching the symbol picker, will be discussed in the next article.) In fact, it would be more efficient to combine SETEDITC and SETBACKC, as is done in routine REMCOV. Routine REMCOV uses E_GETCC.DLG:
BEGIN 101 8.00 40.00 8.00 36.00 v CBOX 102 1.00 1.00 1.00 1.50 v LTEXT 103 1.00 4.00 1.00 31.00 v CBOX 104 2.00 1.00 1.00 1.50 v LTEXT 105 2.00 4.00 1.00 31.00 v CBOX 106 3.00 1.00 1.00 1.50 v LTEXT 107 3.00 4.00 1.00 31.00 v CBOX 108 4.00 1.00 1.00 1.50 v LTEXT 109 4.00 4.00 1.00 31.00 v PBUT -110 6.00 1.00 1.50 8.00 v OK PBUT -111 6.00 9.00 1.50 8.00 v Cancel
*ROUTINE remcov e_getcc.dlg 1 *REM **** remove edit or back cover &define type -8 &var &define i -9 &var &value [type] -1 &openw [winfile] &if &eq [type] EDIT &do *W S 101 Remove Edit Coverage(s) &else *W S 101 Remove Back Coverage(s) &end &sv [i] 1 &while &rn [i] 1 4 &do &if &eq [type] EDIT &do SHOW EDITCOV %[i] -1 &else SHOW BACKCOV %[i] -1 &end &if &eq "x%-1" "x" &do *W G %<[i] * 2 + 100> &else &value %<-10 - [i]> -1 &rem &value -2 -1 %First, the routine sets the title of the dialog box. Then it searches through the four slots of edit or back coverages: where one is filled, the appropriate text widget is assigned that value, otherwise the widget is left blank and the checkbox grayed. If a particular coverage is removed, its edit feature or back symbol variable is cleared.*W S %<[i] * 2 + 101> %-1 &end &inc [i] &end &closew &sv -1 CANCEL *OPEN e_getcc.dlg *PICK 110 &sv -1 OK *CLOSE *PICK 111 49 *CLOSE *ENDPICK &if &eq %-1 CANCEL &do &return &end &sv [i] 1 &while &rn [i] 1 4 &do &value -1 %<[i] * 2 + 100> &if &eq %-1 1 &do &value -2 %<-10 - [i]> &if &eq [type] EDIT &do REMOVEE %-2 &type " " Y &sv %<30 + [i]> NONE &else REMOVEB %-2 &sv %<34 + [i]> 0 &end &end &inc [i] &end &sv [saved] NO &return
ETSTART.SML, which should reside in %ARC%\UTOOL, contains the following code:
&value 51 -1 &sv 52 "ETP" arceditw etool QUITAll that's left is to write some code so that ETOOL knows a project is being launched. First, the following line in routine ETOOL:
DRAWE ARC LABEL NODE ERRORS TIC IDSis replaced with:
&r initRoutine INIT has the following code:
*ROUTINE init &sv -1 1 &while &rn %-1 1 4 &do &sv %<%-1 + 30> NONE &sv %<%-1 + 34> 0 &inc -1 &end &if &ne "x[saved]" "xETP" &do &sv [project] &end &if &ne "x[project]" "x" &do &r [project] &else DRAWE ARC LABEL NODE ERRORS TIC IDS BACKE ARC &end &sv [saved] YESThus, when a project file is opened in Explorer, its name is passed to ETSTART.SML, which assigns the filename to variable 51 and the "ETP" flag to 52. Routine INIT, after clearing the edit feature and back symbol variables, runs the project file if the "ETP" flag is set.