EDITF.DLG:
BEGIN 0 5.00 5.00 4.50 16.00 v Edit Feature PBUT -101 0.00 0.00 1.50 8.00 v Add PBUT -102 0.00 8.00 1.50 8.00 v Delete PBUT -103 1.50 0.00 1.50 8.00 v Move PBUT -104 1.50 8.00 1.50 8.00 v Copy PBUT -105 3.00 0.00 1.50 8.00 v PBUT -106 3.00 8.00 1.50 8.00 v Change...ARC.DLG:
BEGIN 0 11.25 5.00 4.50 16.00 v Arc PBUT -111 0.00 0.00 1.50 8.00 v Split PBUT -112 0.00 8.00 1.50 8.00 v Unsplit PBUT -113 1.50 0.00 1.50 8.00 v Reshape PBUT -114 1.50 8.00 1.50 8.00 v Spline PBUT -115 3.00 0.00 1.50 8.00 v Flip PBUT -116 3.00 8.00 1.50 8.00 v Vertex...VERTEX.DLG:
BEGIN 0 11.25 22.00 3.00 16.00 v Vertex PBUT -121 0.00 0.00 1.50 8.00 v Draw PBUT -122 0.00 8.00 1.50 8.00 v Move PBUT -123 1.50 0.00 1.50 8.00 v Add PBUT -124 1.50 8.00 1.50 8.00 v DeleteANNO.DLG:
BEGIN 0 11.25 5.00 3.00 16.00 v Anno PBUT -111 0.00 0.00 1.50 8.00 v Adjust PBUT -112 0.00 8.00 1.50 8.00 v Text... PBUT -113 1.50 0.00 1.50 8.00 v SetArrow PBUT -114 1.50 8.00 1.50 8.00 v DelArrowTo keep things simple we'll ignore the possible presence of any drawing or selection tools. Now let's assume that these dialog definition files are already sitting in %WKSP% waiting to be used. The following routine contains the necessary code to support them:
&routine etool &define resp -1 &var &define editf -11 &var &define wksp -19 &var &define winrtn 1 &var SHOW EDITFEATURE [editf] &if &eq [editf] NONE &do &return &end &value [wksp] WKSP WIN DB C [wksp]editf.dlg &if &eq [editf] ARC &do WIN DB C [wksp]arc.dlg 2 WIN DB C [wksp]vertex.dlg 3 &elseif &eq [editf] ANNOTATION &do WIN DB C [wksp]anno.dlg 2 &end &sv [resp] 1 &while &ne [resp] -1 &do &if &eq [editf] ANNOTATION &do &sv -2 ANNO... &sv -3 E &elseif &eq [editf] ARC &do &sv -2 ARC... &sv -3 E &else &sv -2 [editf] &sv -3 G &end &openw [wksp]t$ef.cmd &write "S 105 %-2" &write "%-3 105" &closew WIN DB R [wksp]t$ef.cmd &sv [resp] [winrtn] &if &eq [resp] 101 &do SHOW ANNOITEM -2 0 &if &eq [editf] ANNOTATION &and &eq %-2 KEYBOARD &do &r annoadd &else ADD &end &elseif &eq [resp] 102 &do DELETE &elseif &eq [resp] 103 &do MOVE &elseif &eq [resp] 104 &do COPY &elseif &eq [resp] 105 &do &if &eq [editf] ARC &do WIN DB C [wksp]arc.dlg 2 WIN DB C [wksp]vertex.dlg 3 &else WIN DB C [wksp]anno.dlg 2 &end &elseif &eq [resp] 106 &do &r setfeat SHOW EDITFEATURE [editf] &if &eq [editf] NONE &do &sv [resp] -1 &elseif &eq [editf] ARC &do WIN DB C [wksp]arc.dlg 2 WIN DB C [wksp]vertex.dlg 3 &elseif &eq [editf] ANNOTATION &do WIN DB C [wksp]anno.dlg 2 WIN DB D 3 &else WIN DB D 2 WIN DB D 3 &end &elseif &eq [resp] 111 &do &if &eq [editf] ARC &do SPLIT &else REPOS &end &elseif &eq [resp] 112 &do &if &eq [editf] ARC &do UNSPLIT &else &r annotext &end &elseif &eq [resp] 113 &do &if &eq [editf] ARC &do RESHAPE &else SETARROW &end &elseif &eq [resp] 114 &do &if &eq [editf] ARC &do SPLINE &else DELETEARROW &end &elseif &eq [resp] 115 &do FLIP &elseif &eq [resp] 116 &do WIN DB C [wksp]vertex.dlg 3 &elseif &eq [resp] 121 &do V DRAW &elseif &eq [resp] 122 &do V MOVE &elseif &eq [resp] 123 &do V ADD &elseif &eq [resp] 124 &do V DELETE &end &end WIN DB D 3 WIN DB D 2 WIN DB D 1 & DEL [wksp]t$ef.cmd &returnIn the first part of the routine, the "Edit Feature" toolbox and any feature-associated toolboxes are invoked. For edit feature ARC the collection looks like this:
The "ARC..." and "Vertex..." buttons restore the respective toolboxes should they be closed. For edit feature ANNO the collection looks like this:
The "ANNO..." button restores the annotation toolbox. For other edit features, the feature toolbox button is grayed:
The main drawback of the above example is that if the "Edit Feature" toolbox is closed, there is no way to recover it within the routine. Typically, a menu-driven application will embed code to handle all the possible menu entries and nonmodal return widgets in a master handling routine[1], and might have a "Tools" submenu to enable the user to reinvoke killed toolboxes at will.
Question: So what do I do if I want to create a modal dialog box (i.e. having sole focus) without having to dismiss and then recreate the existing (nonmodal) ones? Answer: Use dialog box groups.[2]
If pin mode is set (WIN DB P), dialog boxes created in the new group will be positioned according to the corresponding boxes in the previous group. To force positioning according to the BEGIN line, you may issue the WIN DB U command; you will, however, want to set WIN DB P again after WIN DB E is issued.
Note that WIN DB B and WIN DB E will work even if there are no current dialog boxes. Thus a routine (e.g. to change the edit feature) may be written using those commands and launched from different routine levels without worry.
In the above example, there are three routines called by ETOOL that create a new dialog box group. Let's look at routine ANNOADD and see how it handles the situation:
&routine annoadd &define just -5 &var &define line -6 &var &define pos -7 &var &define type -8 &var &define coo -9 &var &define x -11 &var &define y -12 &var &define wksp -18 &var &define temp -19 &var &define winrtn 1 &var SHOW ANNOSIZE [line] SHOW ANNOPOSITION [pos] SHOW ANNOTYPE [type] SHOW COORDINATE [coo] &value [wksp] WKSP &rem **** hide current db group WIN DB BH &rem **** create annotation dialog box &openw [wksp]t$anno.dlg &write "BEGIN 0 5.00 5.00 10.00 34.00 v Add Anno" &write "LTEXT 0 0.50 1.00 1.00 5.00 v Text:" &write "EBOX 101 0.50 6.00 1.50 27.00 v" &write "CBOX 102 2.50 1.00 1.00 12.00 v Add Arrow" &write "CBOX 103 3.50 1.00 1.00 12.00 v Keep Text" &write "RTEXT 0 3.50 15.00 1.00 8.00 v Spacing:" &write "EBOX 104 3.00 24.00 1.50 6.00 v" &write "GBOX 0 4.75 1.00 2.75 26.00 v Justification" &write "RBUT -105 6.00 2.00 1.00 6.00 v Left" &write "RBUT -106 6.00 9.00 1.00 8.00 v Center" &write "RBUT -107 6.00 18.00 1.00 8.00 v Right" &write "PBUT -108 8.00 1.00 1.50 8.00 v Place" &write "PBUT -109 8.00 9.00 1.50 8.00 v Add Line" &write "PBUT -110 8.00 17.00 1.50 8.00 v Set..." &write "PBUT -111 8.00 25.00 1.50 8.00 v Done" &write "END" &rem **** set justification according to current annopos &value [temp] [pos] 2 2 &if &eq [temp] L &do &write "C 105" &elseif &eq [temp] C &do &write "C 106" &else &write "C 107" &end &write "S 104 1.5" &write "G 109" &closew WIN DB C [wksp]t$anno.dlg & DEL [wksp]t$anno.dlg &rem **** process responses &while &do WIN DB R [wksp]t$anno.cmd &if &fn [wksp]t$anno.cmd &do & DEL [wksp]t$anno.cmd &end &if &eq [winrtn] 105 &do &value [temp] [pos] 1 1 &sv [pos] [temp]L ANNOPOS [pos] &elseif &eq [winrtn] 106 &do &value [temp] [pos] 1 1 &sv [pos] [temp]C ANNOPOS [pos] &elseif &eq [winrtn] 107 &do &value [temp] [pos] 1 1 &sv [pos] [temp]R ANNOPOS [pos] &elseif &eq [winrtn] 108 &and &ne "x%101" "x" &do &openw [wksp]t$anno.cmd &rem **** annotype must be POINT1 and annosize > 0 &rem **** to enable stacked anno &if &eq [type] POINT1 &and &ne [line] 0 &do &type "Enter starting coordinate:" &getxym [x] [y] [temp] WIN FOCUS T COO KEY &sv [temp] ADD %101 1 [x] [y] [temp] COO [coo] &write "E 109" &else &sv [temp] ADD %101 [temp] &end &if &eq %102 1 &do SETARROW &end &if &eq %103 0 &do &write "S 101" &end &write "F 101" &closew &elseif &eq [winrtn] 109 &and &ne "x%101" "x" &do &openw [wksp]t$anno.cmd &sv [temp] &cv [y] [y] - ( [line] * %104 ) - ( [line] * 0.2 ) COO KEY ADD %101 1 [x] [y] [temp] COO [coo] &if &eq %103 0 &do &write "S 101" &end &write "F 101" &closew &rem **** begin modal code block &elseif &eq [winrtn] 110 &do WIN DB BI &r annoinit 1 &openw [wksp]t$init.cmd &write "G 127" &closew WIN DB R [wksp]t$init.cmd & DEL [wksp]t$init.cmd &if &eq [winrtn] 128 &do ANNOTYPE %121 ANNOPOS %122 ANNOFIT %123 ANNOLEVEL %124 ANNOSYMBOL %125 &if &eq "%126" "*" &do &type "ANNOSIZE:" &end ANNOSIZE %126 &end WIN DB E SHOW ANNOSIZE [line] SHOW ANNOPOSITION [pos] SHOW ANNOTYPE [type] &openw [wksp]t$anno.cmd &if &ne [type] POINT1 &or &eq [line] 0 &do &write "G 109" &end &value [temp] [pos] 2 2 &if &eq [temp] L &do &write "C 105" &elseif &eq [temp] C &do &write "C 106" &else &write "C 107" &end &closew &rem **** end modal code block &else WIN DB E &return &end &end &returnAfter querying current annotation parameters, WIN DB BH is executed to save and hide the current dialog box group. Then the dialog box is created:
Note the "Set..." button (ID 110), which calls yet another modal dialog box to set annotation parameters:
The "Item" edit box is grayed because ANNOADD only works with ANNOITEM KEYBOARD. Routine ANNOINIT creates and initializes the dialog box:
&routine annoinit &define num -1 &var &define wksp -18 &var &define temp -19 &var &define winrtn 1 &var &value [wksp] WKSP &openw [wksp]annoenv.dlg &write "BEGIN 0 5.00 40.00 8.50 33.00 v Anno Environment" &write "LTEXT 0 0.25 1.00 1.00 5.00 v Type" &write "DROP 121 1.50 1.00 5.00 9.00 f" &write "LTEXT 0 0.25 11.00 1.00 6.00 v Posit." &write "DROP 122 1.50 11.00 11.00 6.00 f" &write "LTEXT 0 0.25 18.00 1.00 4.00 v Fit" &write "DROP 123 1.50 18.00 4.00 6.00 f" &write "LTEXT 0 0.25 25.00 1.00 7.00 v Level" &write "EBOX 124 1.50 25.00 1.50 7.00 f" &write "LTEXT 0 3.25 1.00 1.00 7.00 v Symbol" &write "EBOX 125 4.50 1.00 1.50 7.00 v" &write "LTEXT 0 3.25 9.00 1.50 8.00 v Size" &write "EBOX 126 4.50 9.00 1.50 8.00 f" &write "LTEXT 0 3.25 18.00 1.50 8.00 v Item" &write "EBOX 127 4.50 18.00 1.50 14.00 f" &write "PBUT -128 6.50 1.00 1.50 8.00 v Apply" &write "END" &rem **** fill in values &write "L 121" &write "POINT1" &write "POINT2" &write "LINE" &write " " SHOW ANNOTYPE [temp] &write "S 121 [temp]" &write "L 122" &write "LL" &write "LC" &write "LR" &write "CL" &write "CC" &write "CR" &write "UL" &write "UC" &write "UR" &write " " SHOW ANNOPOS [temp] &write "S 122 [temp]" &write "L 123" &write "ON" &write "OFF" &write " " SHOW ANNOFIT [temp] &write "S 123 [temp]" &write "B 124 3 4" SHOW ANNOLEVEL [temp] &write "S 124 [temp]" &write "B 125 3 4" SHOW ANNOSYMBOL [temp] &write "S 125 [temp]" &rem &write "B 126 12 4" SHOW ANNOSIZE [temp] &write "S 126 [temp]" &sv -2 SHOW ANNOITEM [temp] -2 &sv [temp] "[temp] %-2" &write "S 127 [temp]" &closew WIN DB C [wksp]annoenv.dlg [num] & DEL [wksp]annoenv.dlg &returnIt is possible to revise ANNOADD to support the "Anno Environment" dialog box nonmodally by replacing the "modal code block" with the following:
&rem **** begin nonmodal code block &elseif &eq [winrtn] 110 &do &r annoinit 2 &openw [wksp]t$anno.cmd &write "G 127" &closew &elseif &eq [winrtn] 128 &do ANNOTYPE %121 ANNOPOS %122 ANNOFIT %123 ANNOLEVEL %124 ANNOSYMBOL %125 &if &eq "%126" "*" &do &type "ANNOSIZE:" &end ANNOSIZE %126 SHOW ANNOSIZE [line] SHOW ANNOPOSITION [pos] SHOW ANNOTYPE [type] &openw [wksp]t$anno.cmd &if &ne [type] POINT1 &or &eq [line] 0 &do &write "G 109" &end &value [temp] [pos] 2 2 &if &eq [temp] L &do &write "C 105" &elseif &eq [temp] C &do &write "C 106" &else &write "C 107" &end &rem **** reset annoenv editboxes SHOW ANNOLEV [temp] &write "S 124 [temp]" SHOW ANNOSYM [temp] &write "S 125 [temp]" &write "S 126 [line]" &closew &rem **** end nonmodal code blockMost notable is the addition of lines to reset the edit box widgets in the "Anno Environment" dialog box. This is especially useful for viewing instantly the results of an ANNOSIZE * command.
Handling multiple dialog boxes can be a challenge. It takes careful deliberation to implement nonmodal and modal dialog boxes, and to avoid widget collision. It can be especially difficult to design code to handle adequately all of the possible widgets in a given situation. Fortunately, there is an excellent utility included with PC ARC/INFO 3.5.X that greatly simplifies the task of testing and coding application interfaces.
[2]Commands such as WIN FILE and WIN MB automatically create a modal dialog box, so dialog box groups are not necessary. Any active dialog boxes will be set idle until the modal box is dismissed.
[3]Optionally, you may specify the number of a current dialog box to pass on to the new group as the initial dialog box.