Commando
Volume Number: | | 6
|
Issue Number: | | 7
|
Column Tag: | | Programmer's Workshop
|
Commando Programming
By W. G. Powell, Salt Lake City, UT
Note: Source code files accompanying article are located on MacTech CD-ROM or source code disks.
With its combination of a programmable text processor, a mouse-based interactive text editor and a general command interpreter, the MPW shell is one of the most powerful and flexible development environments available on any computer. One feature of this environment is particularly Macintoshish: the ability to replace the text of a shell command with a more graphic modal dialog. The Commando tool, supplied with MPW version 2.0 and later, controls such dialogs according to behaviors specified by the programmer in resources of type cmdo.
In this article Id like to introduce some tricks and techniques Ive found useful for building these commando interfaces. Since commandos are fairly flexible, some examples presented here use commando as a means of convenient data entry beyond the direct application to command generation. A previous article on the MPW shell showed the effects of launching applications from within shell command scripts; in this one well see the used of Commando from within shell scripts.
Commands via Commando
The conventional use of commando is to replace the typing of a command and its arguments with a more user-friendly graphical equivalent. The commando dialog is an intuitive way to illustrate the modes of an action and the choices available to the user. Commando interfaces are helpful in two ways. First, presentation of all the options on the screen relieves the user of the burden of memorizing syntax and options. Second, the use of commando dependency rules (discussed later) can increase the correctness and success of commands initiated by the user, thereby enhancing the users productivity.
Commando interfaces are available for the commands built into the shell application itself. A commando interface may also be added to any MPW tool or shell script (TEXT) file with cmdo resources. A small shell script command with a few simple options will serve as a basic example of designing commando interfaces.
Example 1: A Scratch File Generator
Shell scripts of moderate complexity frequently require scratch files or windows for intermediate results and working space. As I wrote more shell scripts, I became less and less confident that I could code unique scratch file names into scripts, and feared I would ultimately overwrite some critical file by accident. A command which opens a scratch file and guarantees that it has a unique name was the obvious solution. The shell script NewTempFile, shown in the listings which follow, performs this function.
The command and its behavior
The NewTempFile command script works together with a few supporting facilities. A special directory is created, where all temporary files will reside. A shell variable defined in the MPW Startup or UserStartup scripts maintains the path to this directory. By convention, a temporary or scratch file is no longer needed when the command which creates the file terminates. When the user Quits the MPW shell, no commands are still active, so the Quit script contains commands to delete the contents of the temporary file directory. The appropriate commands are shown in the listings.
The first half of the script file for the NewTempFile command is a loop which reads, interprets and checks the command line arguments. The second half of the file is a loop which generates a unique file name and opens the file. The file name is formed by appending a number to a base name. A default base name is supplied unless the user provides an alternative as a command line argument. The first trial name is created by appending the count of files in the temporary file directory to the base name. If a file with that name already exists, a new trial name is formed by incrementing the number part by one. The incrementing process continues until an unused name is found. This method has always worked quickly for me in practice, but pathological cases exist which can cause a large number of trials before success. Readers are welcome to try better schemes.
Several command line options can be used to control the behavior of the command. As mentioned earlier, the user can specify a base name for the file on the command line. Normally, when a unique name is successfully found, it is opened as the active window; the -t option on the command line causes the file to be opened as the target window. NewTempFile usually produces no standard output, although error messages (if any) go to the Standard Diagnostic stream. Options -e or -q will echo the name of the new file on the Standard Output stream. Option -q will quote the name if it contains spaces or shell special characters, -e never quotes, and at most one of -e and -q may be specified (you cant have things both ways!).
Examining the script in detail, one may wonder why I test the file name with the Exists and then use New to open the file when a name is found. Since the New command must also test for the existence of the file anyway, and returns a nonzero shell {Status} if the file exists, it looks like I am doing the same test twice. Actually, my first attempt at writing NewTempFile tried the command New with each trial name, using a {Status} value 2 to indicate a need for incrementing and trying again. Careful testing uncovered the flaw in this technique. Under ordinary use the script worked fine, but a test where I place the command inside an infinite loop failed. The New command returns a {Status} value of 2 when the command fails because a file of the same name already exists, but it also returns a value of 2 when too many windows are already open. Once I opened enough windows to reach my systems limit, NewTempFile became an inefficient code to count to very high numbers instead of a convenient way to open new files. Thus the slightly more redundant, but less ambiguous test with Exists was added.
I digress to present this poignant example of one of my failures because it illustrates a common problem with devising shell command scripts. The description in the MPW reference manual of command status results is quite terse, and sometimes does not make clear all the cases which may produce the particular status value. The nature of the status results must be fully defined when they are used to control a script. As in any software development, successful scripting requires careful validation through testing.
The -e and -q options illustrate another useful detail of shell programming worthy of a short digression. After calling NewTempFile within a script, we will usually want to get the name of the new window for use in subsequent commands. Here are two code fragments that set the variable {WName} to the name of a window opened by NewTempFile.
#1
Set WName NewTempFile -q
or
#2
NewTempFile
If {Status} != 0
Echo Error>>Dev:StdErr
Else
Set WName {Active}
End
If NewTempFile fails, the first example sets {WName} to the empty string, and the second does not set {WName} at all. These two code snippets illustrate what I call the MPW Uncertainty Principle. You can use the standard output of a command in a script (via command substitution), OR you can use the status value returned by the command, but you cant use both. In an article on MPW scripting in MacTutor [April 87, p. 37], F. Alviani presents several shell scripts with constructs like:
#3
Set SomeVar `Request some text`
If {Status} != 0
etc.
The intention was apparently to use the If statement to take different actions depending upon whether the user hit the OK or Cancel button in the Request dialog. In reality, if the Request is cancelled, there is no standard output and the {Status} variable is set to value 2. Then the set command (successfully) sets the variable {SomeVar} to the empty string. Finally, the {Status} of 0 returned by the successful Set command is the value tested in the If expression. So the If sees a status of 0 no matter what status value is returned by the Request command. This script used the standard output of Request, so it couldnt use the status of the Request command.
Now that we have a command, and have defined its command line arguments, lets look in detail at the construction of its commando interface.
The commands commando
In discussing the commando interface for NewTempFile, I will refer frequently to the Rez input for the cmdo resource (file NewTempFile.Cmdo.R in the listings). This discussion will lead sequentially through the Rez code, so you may want to mark the page and follow along there. The appearance of the resulting dialog is shown in Figure 1.
The dialog of Figure 1 will be generally familiar to everyone who has already used the Commando tool. The dialog is divided into three rectangular regions. The uppermost options rectangle contains the programmed controls particular to this command and defined in the cmdo resource. The middle rectangle shows the equivalent command and argument text that fits the options selected by the user in the dialog; this text is changed automatically by Commando as the user changes controls in the options area. The third rectangle, labelled Help, shows descriptive text about the command and its options; the help text is changed to describe the appropriate options as the user clicks on the various controls. The placement and action of the controls, the command line options corresponding to the various controls, and the help text are all summarized in the cmdo resource.
The Rez input for the cmdo resource begins with the type and resource ID number of the resource. The specific resource data are then contained within braces. The resource description begins with an integer representing the height of the dialog box in pixels, and the default string of help text that appears in the Help box when no controls are being clicked by the user. The dialog box width is fixed at 480 pixels and the MPW Reference Manual recommends that the height be less than 295 pixels to insure visibility on the original size Macintosh screen. Since only the programmable controls in the options area vary in size, the options determine the necessary size of the dialog window. Letting h represent the height specified in the Rez description, the rectangle drawn around the options area in the dialog is {7, 5, h - 105, 475}. After the default help text, another set of braces encloses input for the variable number of items in the options area of the dialog.
The first item in the NewTempFile commando options is a set of radio buttons, which appear in the upper left of the dialog in Figure 1. This pair of radio buttons allows the user to toggle between causing the temporary window to open as the active or target window. For each button in the set, the Rez input lists the bounds rectangle for the control and its label in the dialog window, the label text to show in the dialog, the command line option corresponding to the control (if any), the help text explaining the control and its option, and the initial setting of the control. Note that when the button labelled Target is selected, the -t option is added to the command line, but when the Active button is selected, no option is added since this is the default case. Entering the empty string in the command line option field for this button signifies the absence of corresponding text on the command line. The behavior of radio buttons follows Apples Human Interface Guidelines.
The second item in the Rez input is a type called RegularEntry. This produces the editable text box in the dialog for entering an alternative base name for the files. The specific data required to build the commando dialog is similar to the radio buttons: Separate bounds rectangles for the label and the text edit box, the text of the label in the dialog, option text that must precede the user-entered text on the command line (if any), a default entry to ignore (if any) and a string of help text explaining the item and its effect on the command. If the user enters text with spaces or shell special characters, the text is automatically quoted on the command line. The behavior of regular entry items is similar to Text Edit items in a modal dialog. Note that RegularEntry items will never word-wrap. Therefore RegularEntry items need never be more than one line of text high (although the similar scrolling list item called MultiRegularEntry must be two or more lines high).
The third and fourth items in the Rez inputs are type CheckOption, which produce the check boxes seen in the upper right of Figure 1. These check boxes correspond to the -e and -q options for echoing the file name generated by the NewTempFile command. The information in the Rez input is quite similar to that required for a set of RadioButtons, but inexplicably must be listed in a different order. As with radio buttons, the input lists the bounds rectangle of the check box and its label, the text of the label, the text of the corresponding command line option, the help text describing the effect of the control, and the initial setting. The initial setting, defined by the constants Set or NotSet indicates whether the item is checked or unchecked when the dialog is first drawn. The command line text of the item is only added to the command when the user changes the state from its initial setting. This can be confusing to the neophyte commando writer. The initial setting of radio buttons also works this way.
Another dimension of the commando interface is also illustrated by the two CheckOption items: control dependency. The first field in each control item description is used to define a dependency of the current control on the states of other controls. Controls in the commando dialogs may be enabled or disabled depending upon the enable/disable status and settings of other controls in the dialog. A dependent control defines its dependency via a logical OR or logical AND of the states of a list of other items. The items are numbered according to their order in the Rez description. The check boxes in the NewTempFile Rez input are items 3 and 4; item 3 depends upon item 4 and vice versa. The negative signs of these items in the dependency lists indicates a logical negation of the dependency on that item. Thus item 4 is enabled any time item three is NOT both enabled and checked. If item 3 is enabled and checked, item 4 becomes disabled. This dependency allows the user to choose only one of options -e and -q, but not both simultaneously. The dependency in this case prevents the user from presenting an illegal combination of options.
The fifth and sixth items present pop-up menus to control the redirection of the Standard Output stream and the Standard Diagnostic stream respectively. The only choices by the programmer with these items is whether to include them and the position in the dialog window. The behavior of these items is the same every time they appear, so no further description is necessary. The NewTempFile example shows the Standard Output item is dependent upon a choice of one of the options -e or -q. Results are written on standard output only when these options are used, so the control is only relevant when one of the corresponding check boxes has been selected. This dependency prevents the user from making unnecessary (although legal) choices.
The final two items, type TextBox, are used to draw the labelled boxes around the radio button set and the redirection controls. Graphic elements are the strength of the Macintosh interface, and the Commando documentation encourages the use of labelled or unlabeled boxes, text in any typeface and style, icons and pictures to increase the visual clarity of the Commando interface. The description of the cmdo Rez input allows for convenient inclusion of these graphics.
This small example covers most of the basic technique in programming the Commando interface. Two features appear to distinguish good commando interfaces (and other dialog interfaces for that matter). First is good graphic design, with related elements grouped together, and less related elements differentiated by position and surrounding white space. Second is the use of control dependency to lead the user to correct choices.
Commando for Data Entry
The MPW Shell provides a number of facilities and tools for prompting the user for information or choices: Alert, Confirm, GetFileName, GetListItem and Request all serve this function. The Commando tool is sufficiently flexible that I now include commando dialogs as another mechanism for prompting the user from within menu choices and scripts. I find this usage results in a somewhat different mode of programming. When I want a commando dialog as a data-entry device, I will usually design and program the cmdo resource first, and then write a special shell script to capture the results from the dialog. Since the only output Commando generates is executable command lines, a particular shell command script must always be written to hold the cmdo resource. Shell scripts which will only be accessed through the commando interface can often be somewhat simpler than those meant to be true commands. In particular, because the commando dialog will always present options in the same order, simple position-dependent interpretation of the arguments is possible.
In his helpful article on MPW scripting [April 87, p. 37], F. Alviani presented a number of shell command scripts which prompted the user for necessary data and then wrote correctly formatted input for the resource compiler, Rez. Since Rez syntax is fairly intricate this is a useful application. The Alviani scripts used the Confirm and Request commands to prompt the user for input; I present here some alternative scripts which use the Commando interface as the facility for the input of necessary parameters.
The script for a WIND resource shows many features common to all the Rez formatting scripts, and serves as the first example. The script for a STR# resource is representative of special problems encountered with resources having a variable number of entries (other such resources are BNDL, PAT#, MENU). The STR# example shows the use of a Commando interface from within a running shell script file.
Example 2: Rez Formatter for WIND
The shell script to take command line arguments and build correctly-formatted window resource input for the Rez tool is shown as file RezC.WIND in the listings. The Rez input for the Commando interface for this script is shown in the listings as file RezC.WIND.Cmdo.R. My intention with all these Rez formatters is that they will only be operated through their commando interfaces. I normally access the Rez formatters via a menu selection. If the menu item is created by a command like
#4
AddMenu Rez WIND RezC.WIND
the ellipsis character in the command ensures the activation of the Commando dialog when the menu item is selected.
Commando Nested Dialogs
Figure 2 shows the Commando dialog (and its nested subdialogs) for the WIND Rez formatter. A commando item not encountered in the earlier example appears in the main dialog for the WIND command: the NestedDialog. This item appears as a rounded push button in the dialog, and it causes a nested commando subdialog to appear in front of the main commando dialog. The subdialog contains custom-programmed controls which can affect command line arguments and has an appearance identical to the main commando dialog, with options, command line text, and help text all shown. The nested dialog push buttons do not generate command line text; only the controls within the nested dialog affect the command line.
Rules regarding items become more complicated with nested dialogs. First, items in a commando dialog may be dependent only upon other items in the same dialog (whether that dialog is the main one or a subdialog). Item numbering for dependency expressions restarts with the first item in each subdialog. When the button for activating a subdialog shows a dependency, activation of the subdialog for user input is the only activity which is disabled. In particular, if the controls in a nested dialog are set to produce command line text, that text remainson the command line even if the nested dialog button is disabled. The order of command line arguments from nested dialogs is the same as the absolute order of the corresponding items in the cmdo resource description. The order of the nested dialog button itself has NO effect on the order of command line argument text.
Nested dialogs have several uses. A large number of closely related choices may be collected into one nested dialog. Nested dialogs can remove less important or subsidiary choices from the main dialog, thereby minimizing the users attention on those items. In the WIND example, there is a nested dialog for selection of resource attributes (Figure 2), one for standard and diagnostic output redirection (not shown) and one for selecting the type and appearance of the window (Figure 2). Each of these clearly contains a subset of closely-related choices too numerous to fit together on the main dialog.
Nested dialogs are most convenient when they contain rarely needed choices. The command line text related to the initial state of nested dialog controls appears even if the subdialog is not accessed by the user. The user need only access the nested dialog to change the initial state. The initial state of controls in a subdialog should therefore be the most common choice (see the defaults shown in the subdialogs of Figure 2). At the very least for user friendliness, the initial settings should ensure that a legal combination of options will result if the user does not access the dialog before executing the command.
Common elements
The upper portion of RezC.WINDs main commando dialog prompts for elements common to all resources: the resource ID number, the resource attributes and resource name. Since these elements will recur in commandos for all Rez formatters, the Rez text for these commando items is collected into a separate file named CmdoReztStart.R. Reproducing these commando elements with identical appearance in several Rez formatter scripts the becomes a simple matter of a Rez preprocessor #include statement. The two text edit boxes and two nested dialog push buttons at the top of the main commando dialog of Figure 2 (and Figure 3) are contained in this include file. Also the line separating these controls from the ones below is contained in this include file, for a total of five elements. I always put the #include statement for this file before all other items in the commando so the Resource ID item is the first in the dialog. Since a resource ID is always required, I make the resource-specific items dependent upon the user making an entry in this first item. This dependency emphasizes the required items.
The nested dialogs corresponding to the Attributes and Redirection buttons in the include file are always the same, so their contents are also collected into include files. These files are CmdoReztAttr.R and CmdoReztRdir.R respectively. These files must be included in a commando description file as the second and third dialogs respectively (as with control items, multiple dialogs are numbered in order of appearance in the cmdo resource). Resource-specific nested dialogs are placed as dialog 4 and later. See the RezC.WIND.Cmdo.R listing for the use of these include files.
Another need which occurs frequently, but not in all Rez formatters, is a way to enter Quickdraw rectangles. Resource types ALRT, CNTL, DITL, DLOG, nrct and WIND all need various bounding rectangles. On the left side of the main commando dialog for WIND resources is an entry area for the windows rectangle. This group of four RegularEntry text edit items and a bounding TextBox is collected into file CmdoRect.R for inclusion into various cmdo description files by the Rez preprocessor. Unlike the earlier examples of include files however, some of the information needed to complete the description of the five included items is not known until the compilation provides a context. The including file provides this context by defining Rez macros prior to including the file containing the Rect items. The position of the items in the dialog is set by defining the top left corner of the text box in macros RTop and RLeft. The title in the text box is defined with macro RTit. The rectangle entry area can be made dependent upon other controls by providing a control list in macro RDef. This method is illustrated in the WIND example: the necessary macros are defined in file RezC.WIND.Cmdo.R just prior to including file CmdoRect.R. Perusal of the listing of file CmdoRect.R should provide a clear example of the use of these macro definitions in item descriptions.
Structuring dependency
I arrange the item dependency in these commando interfaces with some distinct goals in mind. First, the dependency rules are set up to prevent the user from presenting incomplete or illegal inputs. This uses the dependency processing of the Commando tool itself instead of adding more conditional tests for correctness in the scripts that process and format the data. Second, where appropriate, dependency is used to produce an ordered hierarchy of input items. The user is prompted to enter or select the more important items before subsidiary choices are made available. The first level of the hierarchy in the Rez formatters is dependency of many items in the dialog on the resource ID number (which is always required).
The button in the lower right of the Commando dialog terminates the Commando and executes the Commando-generated command line. This button may be made dependent upon other items in the dialog by using an item of type DoItButton. The Rez formatters insure that the DoItButton is only enabled when a valid combination of options appears on the command line. In the case of the WIND formatter, the DoItButton is not enabled until all four elements of the window rectangle have been entered. The window rectangle items in turn are not enabled until the resource ID has been entered. The other options in the commando are always in a valid state, and the DoItButton is not dependent upon them. The logic in the WIND and STR# examples given here are fairly simple, but more complicated logical dependencies can be built up using Dummy items that have dependency, but no visible appearance and no command line text. The MPW documentation provides adequate discussion of dummy dependency. The scripts and commandos for type MENU show a more complicated dependency logic and use Dummy elements. These are included in the listings.
The RezC.WIND script
The command script containing the Commando is not elegant and offers no scripting features of special interest. It merely tests the arguments, in the order defined by the Commandos command line text. The formatted text input for Rez is written to the Standard Output stream. The logic is simple because the Commando dependency rules have taken the place of many tests for correctness or consistency of input.
Example 3: Rez Formatter for STR#
Some resources contain a lists of information of variable length. The archetype of this sort, the string list, could (dont try this at home kids) contain up to 10s of thousands of strings. The data to build a string list resource may be quite extensive, so it will not be too convenient to try to pack it all onto one command line.
My solution in the case of this type of resource is to invoke a commando within a loop in the command shell file. Figure 3 shows the main commando dialog that prompts for the resource ID and attributes and the first string, and a commando dialog for a subcommand invoked an indefinite number of times for entering subsequent strings. The STR# formatter script is file RezC.STRlist and the corresponding commando interface is described in the Rez input file RezC.STRlist.Cmdo.R. The command script RezC.STRlist.more, containing the commando resource described in file RezC.STRlist.more.Cmdo.R, is executed from a loop in file RezC.STRlist.
Invoking Commando within scripts.
We saw an example earlier of a menu choice which activates the commando interface for a command. A commando is invoked just as simply within any shell command script. An ellipsis character ( ) is added to the command line in the script file. At the appropriate point in the executing script, the Commando tool is activated. When the user completes the input and executes the commandos command line, that (nested) command is performed. The enclosing script then continues to execute as if the ellipsis-bearing command had been a normal command. The only important precaution is to insure that the outer shell script (the one which invokes the commando) has a proper behavior when the user clicks the Cancel button in the nested command instead of the Do It Button.
When processing input of indeterminate length, there must be a way to tell the script when all the input is complete. One way to do this is shown in the dialogs of Figure 3. The dialog for another string to add to the string list resource also contains radio buttons to use when the input is complete. The default radio button is the one labelled More strings. When this button is selected, the RezC.STRlist script will process the current string and then repeat the dialog for more input. If the Last string button is selected, the string in that dialog is processed, and the script exits the loop without prompting for further input with the commando dialog. If the third Already done button is selected, it means that the input was completed previously, the script exits the input loop and the string entered in the current dialog is NOT added to the string list. Selecting Cancel instead of the Do It button does not add a string to the string list, but the dialog will reappear for more input. If the RegularEntry field for the string is left blank, an empty string is added to the string list.
Output redirection is affected by the use of a commando inside a script. When the ellipsis character appears on a command line, the commando is invoked to prompt for command line arguments. Any arguments in the command line with the ellipsis are ignored. This includes arguments redirecting input and output. Suppose the following command line appears in a script, and the script is writing Standard Output to the active window.
#5
ACmd >>{Target}
The intention is to append to the target window the output of command ACmd (using options the user provides in the commando dialog). However, since the commando might include a redirection control, the redirection to the target window on the command line is ignored. If redirection is not selected or not available in the commando dialog, the output of this command goes to the standard output stream, following any redirection of the standard output of the enclosing script file. The desired redirection can be programmed by using an additional nesting level of command file. In the original outermost script file, replace the ACmd command line with
#6
BCmd >>{Target} #no ellipsis.
BCmd is a simple script containing only the following commands.
#7
Set Exit 0
ACmd
Set BStatus {Status}
Exit {BStatus}
The addition of another level of nested script provides the desired redirection and returns ACmds status to the outer calling script if needed. The scripts and commandos for the MENU Rez formatter use this redirection technique while collecting the item enable flags.
Miscellaneous Notes & Bugs
Usually an entire coupled set of radio buttons in a commando dialog is a single item in the commando resource. The MPW manual tells how to make items dependent upon a single button in the set, by packing a button selection into the 4 high order bits of the item number. Actually, only the first seven buttons (low 3 bits of high 4) in a radio button item can be individually recognized using this technique.
Hidden dialog items, located outside the window rectangle of the dialog, can be useful in some commando interfaces. Suppose for example that we want to toggle between two command line options (say -op1 and -op2) using a single check box. Normally a check box can only turn a command line option on or off, but a dependency relation with a hidden radio button produces the desired effect.
/* 8 */
/* Item X */
NotDependent {}, CheckOption {
NotSet,
/* inside the window */
{30,30,46,100},
Label text,
/* Command line option */
/* Use when checked */
-op2,
Help text },
/* X is Item Number of check box */
OR {{ X }}, RadioButtons {{
/* Hidden outside window */
{800,800,816,816},
Label text (never seen),
/* Command line option */
/* Use when unchecked */
-op1,
NotSet,
Help Text (never seen) }},
If the two toggling options must be in the same position on the command line, be sure the two items are adjacent in the cmdo resource, as shown above.
One minor behavior of the commando dialog varies from standard dialog behavior as described in the Apple Human Interface Guidelines book. The published guidelines say the outlined default button in a dialog should respond to the Return or the Enter key on the keyboard. The default button in the commando dialog (the DoIt button) responds to the Enter key. The return key causes the insertion point to jump from edit box to edit box (like the tab key) rather than activating the default button. This is consistent with the behavior of text windows in the shell, but contrary to standard dialog behavior. Another human interface standard bites the dust.
This article was written using MPW version 2.02. This version is still recommended for users with small systems, but the current version (as of this writing) is 3.0. The information in this article applies to both versions. The syntax for some of the resources in the type definition files provided with MPW have evolved with each version of MPW. In particular, the description of the SIZE resource is incompatible between the two versions. The Commando tool delivered with the MPW 3.0 system has a commando editor; it cannot be used to create cmdo resources, but can edit the commando dialogs after the resource is built with Rez.
The commando tool supplied with version 3.0 may not work when the name of the command contains spaces. The command name is apparently not quoted for the shell by the commando tool. The command generated by commando can be written to a window using command-option keys while clicking the commando dialogs DoIt button however, and quotes added manually. I do not recall having seen this problem with MPW 2.02 but I dont have that version handy to check.
Conclusion
The Rez formatters, using commandos for data entry, are the most convenient way I have found to enter most of the standard resources. Figure 4 shows some of the variety possible. Graphic resources like icons, patterns and pictures are better handled by a graphic editor like ResEdit of course. It is also much more convenient to build the dialog item lists graphically using ResEdit. The one resource which cannot be written conveniently by ResEdit or by my Rez formatters is unfortunately that for a commando interface. The MPW Reference manual suggests designing the graphics of a commando interface as a dialog item list via the DITL editor in ResEdit, then decompiling and editing the DITL resource to produce the Rez input for the cmdo. An alternative has become available from a surprising source: the dialog editor supplied with the new version of Microsoft Excel handles cmdo-like items such as text boxes and scrolling lists, and saves the users graphic design as text on the clipboard.
Figure 4. More sample commandos.
The Microsoft dialog editor allows the building of commando interfaces in a fairly convenient two-step process. A shell script prompts for the usual resource ID and attributes of the cmdo, and then launches the Dialog Editor (as discussed in MacTutor Jan. 88). The user designs the appearance of the options area of a commando dialog, then quits the editor. When the shell resumes, it takes the item information and writes the equivalent Rez input. All items at this stage have no dependency. In the second step, the user edits the dependency of the items manually. The process can be repeated for subdialogs. Ill leave the implementation of such a system as an exercise for the interested reader.
However you build them, commando interfaces bring MPW shell commands into line with Apples Human Interface Guidelines: the commando interface presents choices to the user, rather than requiring the user to memorize and present commands. Commandos designed with the users needs in mind can actually increase productivity by emphasizing the important choices, and preventing inconsistent or incorrect choices. I guess Commando is called Commando because it helps to bring the Macintosh revolution to command line shells.
Happy Commandoing!
Listings
###NewTempFile -- Open a window on a new temporary file.
###W. Powell, 1988
###Automatically insures unique file names.
Set Exit 0
Set TargMode 0
Set EchoMode 0
Unset BaseName
Set NameIn 0
Set ErrGen 0
# Check calling arguments
If {#} > 3
Echo ### NewTempFile -- bad arguments >>Dev:StdErr
Echo ### NewTempFile [-t] [-e | -q] [basename] >>Dev:StdErr
Exit 1
End
# Use the arguments
If {#} > 0
For NewArg In {Parameters}
If {NewArg} == -t
Set TargMode 1
Else If {NewArg} == -e
If {EchoMode}
Echo ### NewTempFile - only one of -e, -q allowed >>Dev:StdErr
Echo ### NewTempFile [-t] [-e | -q] [basename] >>Dev:StdErr
Exit 1
Else
Set EchoMode 1
Set Quote 0
End
Else If {NewArg} == -q
If {EchoMode}
Echo ### NewTempFile - only one of -e, -q allowed >>Dev:StdErr
Echo ### NewTempFile [-t] [-e | -q] [basename] >>Dev:StdErr
Exit 1
Else
Set EchoMode 1
Set Quote 1
End
Else
If {NameIn}
Echo ### NewTempFile -- bad arguments >>Dev:StdErr
Echo ### NewTempFile [-t] [-e | -q] [basename] >>Dev:StdErr
Exit 1
Else
Set NameIn 1
Set BaseName {NewArg}
End
End
End
End
# If basename not specified, use this default
If ¬ {NameIn}
Set BaseName TEMPzs
End
Unset NameIn
# Note: Directory for temp files defined by variable
# {TMP} defined in Startup script
Set TmpCnt Files {TMP} | Count -l
Set TmpCnt Evaluate {TmpCnt} + 1
#Create a unique new Temporary File
Loop # Until unique new file is opened
# Trial filename
Set uniq {TMP}{BaseName}{TmpCnt}
# Try to create file
If {uniq} == `Exists -f {uniq} `
# Not a unique name, so
# Increment and try again
Set TmpCnt Evaluate {TmpCnt} + 1
Else
# Found a good file name, try to open it.
New {uniq}
Set NewStat {Status}
If {NewStat}
Echo ### NewTempFile terminated Dev:StdErr
Exit {NewStat}
End
If {TargMode}
Open -t {uniq}
End
If {EchoMode}
If {Quote}
Quote {uniq}
Else
Echo {uniq}
End
End
Break # out of this loop
End
End
# Successful, Window is open
Exit 0
### End file NewTempFile
##############################
/* File: NewTempFile.cmdo.R */
/* Rez input for Commando interface for NewTempFile command */
#include Cmdo.r
Resource cmdo (200) {
{ 270, /* dialog box height */
NewTempFile opens a window on a scratch file with a unique name,
{ NotDependent {}, RadioButtons {
{{35,35,55,160},Active Window, , Set,
Open new temporary file as the active window,
{55,35,75,160}, Target Window, -t, NotSet,
Open new temporary file as the target window}
},
NotDependent {}, RegularEntry {
Base name for file:,
{85,50,105,180},
{85,183,105,430},
, keepCase,,
File name for temporary file; a number will be concatenated.
},
Or { {-4} }, CheckOption {
NotSet,
{30,195,50,445},
Echo File Name without Quoting,
-e,
Cause name of temporary file to be written to Standard Output; dont
quote special characters
},
Or { {-3} }, CheckOption {
NotSet,
{50,195,70,445},
Echo File Name with Quoting,
-q,
Cause name of temporary file to be written to Standard Output; quoting
special characters
},
Or {{3,4}}, Redirection {
StandardOutput,
{117,150},
},
NotDependent {}, Redirection {
DiagnosticOutput,
{117,290},
},
NotDependent {}, TextBox {
gray,
{115,30,156,450},
Redirection
},
NotDependent {}, TextBox {
gray,
{25,30,78,165},
Open As
},
}
}
} ;
/* End File NewTempFile.cmdo.R */
#############################################################
###File: NewTempFile.install
###Supporting facilities needed to use
###MPW Shell Script NewTempFile.
###To install the NewTempFile script in your MPW system,
###1. Place the script file NewTempFile into
###any directory in the {Commands} search path.
###2. Place the shell script fragments below into
###the standard MPW script files as indicated.
##############################################################
###Place the following lines into the
###Startup or one of the UserStartup files.
#{TMP} - Directory that contains temporary files.
Set TMP {MPW}tmp:
Export TMP
##############################################################
###Place the following lines into the
###Quit script file.
###Empty the scratch directory
Set OldExit {Exit}
Set Exit 0
# Dont want error messages when no windows open.
Close -n Files -f {TMP} Dev:Null
Set Exit {OldExit}
Delete -y -i {TMP}
NewFolder {TMP}
##############################################################
###Place the following lines into an
###appropriate file for the Help tool.
-
NewTempFile [-t] [-e | -q] [basename]
Create a temporary scratch file. Shell variable {TMP},
defined in Startup script, is the directory for new file.
-tOpens file as target window (default active window).
-e Echo the new file name without quoting.
-qEcho the new file name, quoting names with spaces and
special characters.
Cant use -q and -e together
-
###End File NewTempFile.install
#################################################
###################################
###File RezC.WIND
### Generate Rez input for WIND Resources
### W. Powell 1988
Set Exit 0
Set rid {1}
Shift 1
Echo -n Resource WIND ({rid}
If {1} == -nms
Set rname {2}
If ({rname} != )
Echo -n ,{rname}
End
Shift 2
End
If {1} == -t
Set tr {2}
Shift 2
Else
Echo ### {0} Error: Rectangle args out of order
>>Dev:StdErr
Exit 1
End
If {1} == -l
Set lr {2}
Shift 2
Else
Echo ### {0} Error: Rectangle args out of order
>>Dev:StdErr
Exit 1
End
If {1} == -b
Set br {2}
Shift 2
Else
Echo ### {0} Error: Rectangle args out of order
>>Dev:StdErr
Exit 1
End
If {1} == -r
Set rr {2}
Shift 2
Else
Echo ### {0} Error: Rectangle args out of order
>>Dev:StdErr
Exit 1
End
Set Vis {1}
Shift 1
If {1} == -const
Set RefCon {2}
Shift 2
Else
Set RefCon 0
End
If {1} == -title
Set Label {2}
Shift 2
Else
Set Label
End
If ( {1} == -sy ) ; Echo -n ,SysHeap ; Shift ; End
If ( {1} == -pu ) ; Echo -n ,Purgeable ; Shift ; End
If ( {1} == -lo ) ; Echo -n ,Locked ; Shift ; End
If ( {1} == -Pr ) ; Echo -n ,Protected ; Shift ; End
If ( {1} == -PL ) ; Echo -n ,PreLoad ; Shift ; End
Echo ) {
Set ProcID {1}
Set CloseOp {2}
Echo t{{tr},{lr},{br},{rr}},tt/* Bounds Rect */
Echo t{ProcID},tt/* Window Proc */
If {Vis} == -I
Echo tinvisible,
Else
Echo tvisible,
End
If {CloseOp} == -goAway
Echo tgoAway,
Else
Echo tnoGoAway,
End
Echo t{RefCon},tt/* RefCon */
Echo t{Label}t
Echo };
Exit 0
### End File RezC.WIND
####################################
/* File RezC.WIND.Cmdo.R */
/* Commando interface to build WIND Rez input */
/* W. Powell 1988 */
/* Rez definitions for Rez-building Commando interfaces */
#include Types.R
#include Cmdo.R
Resource cmdo (200) {
{ 285,
Rezc.WIND produces Rez input for a Window resource,
{
/* This include file has a standard arrangement of items
* common to all resources: ID#, attributes, name,
* and redirection of output from the Rezc. script */
#include CmdoReztStart.R
/* Set up parameters for a Rectangle entry area */
#define RTop 85
#define RLeft 30
#define RTit Window Rectangle
#define RDep {1}
/* This include file has a standard arrangement of edit boxes
* for input of rectangles*/
#include CmdoRect.R
/* other items particular to this case */
/* Item 11 */
OR {{1}}, NestedDialog {
4, /* Dialog number */
{85,250,106,370},
Window Type,
Select style of window. },
/* Item 12 */
OR {{1}}, RadioButtons {{
{80,380,96,460},
Visible,-V,NotSet,Make window visible.,
{97,380,113,460},
Invisible,-I,NotSet,Make window invisible.
}},
/* Item 13 */
OR {{1}}, RegularEntry {
RefCon:,
{123,250,139,310},
{123,315,139,430},
,keepCase,-const,
User-defined constant.\nHEX long word. },
/* Item 14 */
OR {{1}}, RegularEntry {
Title:,
{152,30,168,90},
{152,100,168,440},
,keepCase,-title,
Title for window. },
/* Item 15 */
AND {{6,7,8,9}}, DoItButton {},
},
/* Dialog 2 */
/* Include the standard resource attributes dialog */
#include CmdoReztAttr.R
/* Dialog 3 */
/* Include a redirection dialog */
#include CmdoReztRdir.R
/* Dialog 4 */
270,
Select style of window.,
{
/* Item 1 */
NotDependent {}, RadioButtons {{
{55,54,71,70},
,documentProc,NotSet,,
{55,156,71,172},
,dBoxProc,NotSet,
NOTE: This window type inhibits
MultiFinder context switching.,
{55,258,71,274},
,plainDBox,NotSet,,
{55,360,71,376},
,altDBoxProc,NotSet,,
{115,54,131,70},
,noGrowDocProc,NotSet,,
{115,156,131,172},
,zoomDocProc,NotSet,,
{115,258,131,274},
,zoomNoGrow,NotSet,,
{115,360,131,376},
,rDocProc,NotSet,
}},
/* Item 2 */
NotDependent{}, RadioButtons {{
{140,100,156,210},
Has Close Box,-goAway,NotSet,
Window has a close box.,
{140,280,156,390},
No Close Box,-NoGoAway,NotSet,
Window does not have a close box.
}},
/* Item 3 */
NotDependent {}, Box {
gray,
{135,80,160,400} },
/* Item 4 */
NotDependent {}, TextTitle {
plain,
{56,71,70,137},
3,9,
documentProc },
NotDependent {}, TextTitle {
plain,
{56,173,70,234},
3,9,
dBoxProc },
NotDependent {}, TextTitle {
plain,
{56,275,70,336},
3,9,
plainDBox },
NotDependent {}, TextTitle {
plain,
{56,377,70,438},
3,9,
altDBoxProc },
NotDependent {}, TextTitle {
plain,
{116,71,130,150},
3,9,
noGrowDocProc },
NotDependent {}, TextTitle {
plain,
{116,173,130,234},
3,9,
zoomDocProc },
NotDependent {}, TextTitle {
plain,
{116,275,130,336},
3,9,
zoomNoGrow },
NotDependent {}, TextTitle {
plain,
{116,377,130,438},
3,9,
rDocProc },
NotDependent {}, PictOrIcon {
Icon, 200, {20,70,52,102} },
NotDependent {}, PictOrIcon {
Icon, 201, {20,172,52,204} },
NotDependent {}, PictOrIcon {
Icon, 202, {20,274,52,306} },
NotDependent {}, PictOrIcon {
Icon, 203, {20,376,52,408} },
NotDependent {}, PictOrIcon {
Icon, 204, {80,70,112,102} },
NotDependent {}, PictOrIcon {
Icon, 205, {80,172,112,204} },
NotDependent {}, PictOrIcon {
Icon, 206, {80,274,112,306} },
NotDependent {}, PictOrIcon {
Icon, 207, {80,376,112,408} },
},
}
};
resource ICON (200, documentProc) {
$FFFF FFFF 8000 0001 BEFF FFF1 A200 0001"
$A2FF FFF1 A200 0001 BEFF FFF1 8000 0001"
$FFFF FFFF 8000 0041 8000 0001 8000 0041"
$8000 0001 8000 0041 8000 0001 8000 0041"
$8000 0001 8000 0041 8000 0001 8000 0041"
$8000 0001 8000 0041 8000 0001 8000 0041"
$8000 0001 D555 5555 8000 0001 8000 0041"
$8000 0001 8000 0041 8000 0001 FFFF FFFF
};
resource ICON (201, dBoxProc) {
$FFFF FFFF 8000 0001 8000 0001 9FFF FFF9"
$9FFF FFF9 9800 0019 9800 0019 9800 0019"
$9800 0019 9800 0019 9800 0019 9800 0019"
$9800 0019 9800 0019 9800 0019 9800 0019"
$9800 0019 9800 0019 9800 0019 9800 0019"
$9800 0019 9800 0019 9800 0019 9800 0019"
$9800 0019 9800 0019 9800 0019 9FFF FFF9"
$9FFF FFF9 8000 0001 8000 0001 FFFF FFFF
};
resource ICON (202, PlainDBox) {
$FFFF FFFF 8000 0001 8000 0001 8000 0001"
$8000 0001 8000 0001 8000 0001 8000 0001"
$8000 0001 8000 0001 8000 0001 8000 0001"
$8000 0001 8000 0001 8000 0001 8000 0001"
$8000 0001 8000 0001 8000 0001 8000 0001"
$8000 0001 8000 0001 8000 0001 8000 0001"
$8000 0001 8000 0001 8000 0001 8000 0001"
$8000 0001 8000 0001 8000 0001 FFFF FFFF
};
resource ICON (203, AltDBoxProc) {
$FFFF FFFE 8000 0003 8000 0003 8000 0003"
$8000 0003 8000 0003 8000 0003 8000 0003"
$8000 0003 8000 0003 8000 0003 8000 0003"
$8000 0003 8000 0003 8000 0003 8000 0003"
$8000 0003 8000 0003 8000 0003 8000 0003"
$8000 0003 8000 0003 8000 0003 8000 0003"
$8000 0003 8000 0003 8000 0003 8000 0003"
$8000 0003 8000 0003 FFFF FFFF 3FFF FFFF
};
resource ICON (204, noGrowDocProc) {
$FFFF FFFF 8000 0001 BEFF FFF1 A200 0001"
$A2FF FFF1 A200 0001 BEFF FFF1 8000 0001"
$FFFF FFFF 8000 0001 8000 0001 8000 0001"
$8000 0001 8000 0001 8000 0001 8000 0001"
$8000 0001 8000 0001 8000 0001 8000 0001"
$8000 0001 8000 0001 8000 0001 8000 0001"
$8000 0001 8000 0001 8000 0001 8000 0001"
$8000 0001 8000 0001 8000 0001 FFFF FFFF
};
resource ICON (205, zoomDocProc) {
$FFFF FFFF 8000 0001 BEFF FEF9 A200 0089"
$A2FF FE89 A200 0089 BEFF FEF9 8000 0001"
$FFFF FFFF 8000 0041 8000 0001 81FF 0041"
$8002 0001 8004 0041 8008 0001 8010 0041"
$8020 0001 8040 0041 8080 0001 81FF 0041"
$8000 0001 8000 0041 8000 0001 8000 0041"
$8000 0001 D555 5555 8000 0001 8000 0041"
$8000 0001 8000 0041 8000 0001 FFFF FFFF
};
resource ICON (206, zoomNoGrow) {
$FFFF FFFF 8000 0001 BEFF FEF9 A200 0089"
$A2FF FE89 A200 0089 BEFF FEF9 8000 0001"
$FFFF FFFF 8000 0001 8000 0001 8000 0001"
$8000 0001 803F F001 8000 2001 8000 4001"
$8000 8001 8001 0001 8002 0001 8004 0001"
$8008 0001 8010 0001 803F F001 8000 0001"
$8000 0001 8000 0001 8000 0001 8000 0001"
$8000 0001 8000 0001 8000 0001 FFFF FFFF
};
resource ICON (207, rDocProc) {
$0FFF FFF0 3FFF FFFC 707F FFFE 777F FFFE
$F77F FFFF F77F FFFF F07F FFFF FFFF FFFF
$8000 0001 8000 0001 8000 0001 8000 0001"
$8000 0001 8000 0001 8000 0001 8000 0001"
$8000 0001 8000 0001 8000 0001 8000 0001"
$8000 0001 8000 0001 8000 0001 8000 0001"
$8000 0001 8000 0001 8000 0001 8000 0001"
$4000 0002 4000 0002 3000 000C 0FFF FFF0"
};
/* End File RezC.WIND.Cmdo.R */
/* File CmdoReztStart.R */
/* W. Powell 1988 */
/* Include File to generate commando input for
* standard Resource ID and attributes */
/* This file is meant to be included in other Rez files
* This file contains 5 Commando control items*/
/* NOTE: The cmdo dialog for resource attributes is in
* include file CmdoReztAttr.R
The cmdo dialog for redirection is in include file
* CmdoReztRdir.R*/
/* Item 1 */
NotDependent {}, RegularEntry {
Resource ID#:,
{20,25,36,125},
{20,127,40,167},
, /* No default */
keepCase, ,
Enter the resource ID number.\nUsually 128 ¾ ID ¾
32767 (See I.M. I-108). },
/* Item 2 */
NotDependent {}, NestedDialog {
2, /* Nested dialog number */
{20,190,40,280},
Attributes,
Set resource attribute bits },
/* Item 3 */
OR { {1} }, RegularEntry {
Resource Name:,
{50,25,66,145},
{50,148,66,430},
, /* No default */
keepCase, -nms,
Enter a name for the resource (optional). },
/* Item 4 */
NotDependent {}, NestedDialog {
3,/* Nested Dialog number */
{20,300,40,420},
Redirection,
Specify output redirection.\n
Defaults to Active window. },
/* Item 5 */
NotDependent {}, Box {
Black, {73,45,74,410} },
/* End of file CmdoReztStart.R */
/* File CmdoReztAttr.R */
/* W. Powell, 1988 */
/* Include File to generate nested dialog for Rez
* resource attributes */
/* This file is meant to be included in other Rez files
* as a complete nested dialog.
* See Also file CmdoRezID.R (assumes this is dialog 2) */
/* Dialog 2 */
/* Resource attribute stuff */
270,
Select Attributes for the resource,
{
NotDependent {}, RadioButtons { {
{35,85,55,220},
Application Heap,
,Set,
Load resource into application heap ,
{35,260,55,400},
System Heap,
-sy,NotSet,
Load resource into system heap instead
of application heap }},
NotDependent {}, RadioButtons { {
{55,260,75,400},
Purgeable,
-pu,NotSet,
Make the resource initially purgeable.,
{55,85,75,220},
Not Purgeable,,NotSet,
Make resource initially unpurgeable
}},
NotDependent {}, RadioButtons { {
{75,85,95,220},
Unlocked,,Set,
Resource not initially locked in memory,
{75,260,95,400},
Locked,-lo,NotSet,
Lock resource in memory when loaded
} },
NotDependent {}, RadioButtons { {
{95,85,115,220},
Unprotected,,Set,
Marked as changeable in resource file,
{95,260,115,400},
Protected,-Pr,NotSet,
Protect resource in file from changes
} },
NotDependent {}, RadioButtons { {
{115,85,135,220},
No Pre-Load,,Set,
Require explicit command to load resource
into memory.,
{115,260,135,400},
Pre-load,-PL,NotSet,
Load resource when resource
fork is opened }}
},
/* End of file CmdoAttributes.R */
/* File CmdoReztRdir.R */
/* W. Powell 1988 */
/* Redirection Dialog for Output and Error */
/* This file is meant to be included in commandos for
building Rez input*/
160,
Redirect the Standard and Diagnostic outputs,
{
NotDependent {}, Redirection {
StandardOutput, {15,80} },
NotDependent {}, Redirection {
DiagnosticOutput, {15,270} }
},
/* End of File CmdoReztRdir.R */
/* File CmdoRect.R */
/* W. Powell, 1988 */
/* Include File to generate commando input for rectangles */
/* This file is meant to be included in other Rez files
* This file contains 5 Commando control items
* Parameters RLeft, RTop, RTit, RDep are to be defined in
* the calling source file.
* RTop = vertical component of top of the RECT dialog area
* RLeft= horizontal component of left of RECT input area
* RTit = short title to describe rectangle
* RDef = a control list enclosed in one set of {}s.
* The RECT input area has OR dependency on this
* set of controls. Build more complicated
* dependency with dummy items.
*/
#ifndef RTop
#printf (### CmdoRect.R Error:\n)
#printf (### Variable RTop (vert. coord of top left) undefined\n)
#endif
#ifndef RLeft
#printf (### CmdoRect.R Error:\n)
#printf (### Variable RLeft (horiz. coord. of top left) undefined\n)
#endif
#ifndef RDep
#printf (### CmdoRect.R Error:\n)
#printf (### Variable RDep (list of control dependencies) undefined\n)
#endif
#ifndef RTit
#define RTit
#endif
OR { RDep }, RegularEntry {
Top,
{RTop+7,RLeft+10,RTop+23,RLeft+50},
{RTop+27,RLeft+10,RTop+43,RLeft+50},
,keepCase,-t,
Top coordinate of rectangle },
OR { RDep }, RegularEntry {
Left,
{RTop+7,RLeft+60,RTop+23,RLeft+100},
{RTop+27,RLeft+60,RTop+43,RLeft+100},
,keepCase,-l,
Left coordinate of rectangle },
OR { RDep }, RegularEntry {
Bottom,
{RTop+7,RLeft+106,RTop+23,RLeft+156},
{RTop+27,RLeft+110,RTop+43,RLeft+150},
,keepCase,-b,
Bottom coordinate of rectangle },
OR { RDep }, RegularEntry {
Right,
{RTop+7,RLeft+162,RTop+23,RLeft+200},
{RTop+27,RLeft+160,RTop+43,RLeft+200},
,keepCase,-r,
Right coordinate of rectangle },
NotDependent {}, TextBox {
gray,
{RTop,RLeft,RTop+51,RLeft+210},
RTit
},
/* End of file CmdoRect.R */
###File: RezC.STRlist
### Generate Rez input for STR# Resources
### W. Powell 1988
Set Exit 0
Set rid {1}
Shift 1
Echo -n Resource STR# ({rid}
If {1} == -nms
Set rname {2}
If ({rname} != )
Echo -n ,{rname}
End
Shift 2
End
Set Str {1}
Shift 1
If ( {1} == -sy ) ; Echo -n ,SysHeap ; Shift ; End
If ( {1} == -pu ) ; Echo -n ,Purgeable ; Shift ; End
If ( {1} == -lo ) ; Echo -n ,Locked ; Shift ; End
If ( {1} == -Pr ) ; Echo -n ,Protected ; Shift ; End
If ( {1} == -PL ) ; Echo -n ,PreLoad ; Shift ; End
Echo ) { {
Echo -n t{Str}
Loop # for more strings
RezC.STRlist.more
Break If {Status} == 100
End
Echo t} };
Exit 0
### End File RezC.STRlist
##############################
### File RezC.STRlist.more
### Continuation of RezC.STRlist
### for generation of Rez input for STR# resources
### W. Powell 1988
Set Exit 0
If {1} == -OK || {1} == -LAST
If {#} == 2
Echo ;
Echo -n t{2}
Else
Echo ;
Echo -n t
End
End
If {1} == -LAST || {1} == -DONE
Exit 100
End
Exit 0
### End File RezC.STRlist.more
###############################
/* File RezC.STRlist.Cmdo.R */
/* Rez input for the Rezc.STRlist Commando interface */
/* W. Powell 1988 */
/* Rez definitions for Rez-building Commando interfaces */
#include Cmdo.R
Resource cmdo (200) {
{ 240,
Rezc.STRlist produces Rez input for a String resource.\n
New dialogs will prompt for further strings.,
{
/* This include file has a standard arrangement of items
* common to all resources: ID#, attributes, name,
* and redirection of output from the Rezc. script*/
#include CmdoReztStart.R
/* Item 6 */
OR {{1}}, RegularEntry {
First string:,
{80,30,96,120},
{99,30,115,450},
,keepCase,,
Enter the string.\nUse \\ to escape special characters. },
/* Item 7 */
AND {{6}}, DoItButton {},
},
/* Dialog 2 */
/* Include the standard resource attributes dialog */
#include CmdoReztAttr.R
/* Dialog 3 */
/* Include a redirection dialog */
#include CmdoReztRdir.R
}
};
/* End File RezC.STRlist.Cmdo.R */
/* File RezC.STRlist.more.Cmdo.R */
/* Rez input for the Rezc.STRlist.more Commando interface */
/* W. Powell 1988 */
/* Rez definitions for Rez-building Commando interfaces */
#include Cmdo.R
Resource cmdo (200) {
{ 220,
Enter the next string in the STR# string list.,
{
NotDependent {}, RadioButtons {{
{30,30,46,140},
More strings,-OK,NotSet,
This is not the last string in the list.
Continue prompting for more. ,
{30,170,46,270},
Last string,-LAST,NotSet,
This is the last string in the list.
Dont need to prompt for more.,
{30,300,46,410},
Already done,-DONE,NotSet,
Previous string was the last. Ignore any
input in this dialog.
}},
NotDependent {}, Box {
gray, {25,25,50,415} },
OR {{(3<<12)+1}}, Dummy {},
OR {{-3}}, RegularEntry {
String:,
{55,30,71,100},
{74,30,90,450},
,keepCase,,
Enter the string.\nUse \\ to escape special characters.
},
}
}
};
/* End File RezC.STRlist.more.Cmdo.R */
#########################################
###File RezC.MENU
### Generates Rez input for Menu resource
### W. Powell 1988
Set Exit 0
Set rid {1}
Echo -n Resource MENU ({rid}
Shift 1
If {1} == -nms
Echo -n ,{2}
Shift 2
End
# Menu state and title
Set enflg {1}
Set Title {2}
Set ProcID {3}
Shift 3
# Resource attributes
If ( {1} == -sy ) ; Echo -n ,SysHeap ; Shift ; End
If ( {1} == -pu ) ; Echo -n ,Purgeable ; Shift ; End
If ( {1} == -lo ) ; Echo -n ,Locked ; Shift ; End
If ( {1} == -Pr ) ; Echo -n ,Protected ; Shift ; End
If ( {1} == -PL ) ; Echo -n ,PreLoad ; Shift ; End
Echo ) {
Set OldActive {Active}
Set OldTarget {Target}
NewTempFile
If {Status} != 0
Echo ### {0} Error: Cant open temporary file.>>Dev:StdErr
Echo ###Try closing some windows or freeing disk space
>>Dev:StdErr
Exit 2
End
Set tempfil {Active}
### Restore original target/active
If {OldTarget} !=
Open {OldTarget}
End
Open {OldActive}
Unset OldTarget
Unset OldActive
Set FlgCnt 0
Set DoneFlg 0
Set bif # binary item flags
Loop
Set FlgCnt Evaluate {FlgCnt} + 1
RezC.MENU.sub1 >>{tempfil}
Set State {Status}
If {State} == 10 || {State} == 110
Set bif 0{bif}# disabled item
Else
Set bif 1{bif}# enabled item
End
If {State} >= 100
Set DoneFlg 1
Break
End
Break If {FlgCnt} >= 31
End
If {DoneFlg} == 0
Loop
RezC.MENU.sub2 >>{tempfil}
Break If {Status} >= 100
End
End
If {FlgCnt} < 31 # finish building enable flags
Loop
Set bif 1{bif}
Set FlgCnt Evaluate {FlgCnt} + 1
Break If {FlgCnt} >= 31
End
End
Echo t{rid},tt/* Menu ID */
Echo t{ProcID},t/* Menu DefProc ID */
Echo t0b{bif},t/* Item enable flags */
Echo t{enflg},tt/* Whole menu enable */
If {Title} == apple
Echo tapple,ntt{
Else
Echo t{Title},ntt{
End
Catenate {tempfil}
Echo tt}
Close -n {tempfil}
Echo t};
Exit 0
### End File RezC.MENU
#################################
########################
###File RezC.MENU.sub1
###Called by RezC.MENU
###W. Powell 1988
RezC.MENU1.more
Set State {Status}
Exit {State}
### End File RezC.MENU.sub1
###########################
########################
###File RezC.MENU.sub2
###Called by RezC.MENU
###W. Powell 1988
RezC.MENU2.more
Set State {Status}
Exit {State}
### End File RezC.MENU.sub2
###########################
#######################################
### File RezC.MENU1.more
### Called by RezC.MENU to generate partial Rez input
###for one menu item or hierarchical menu.
###W. Powell 1988
Set Exit 0
If {1} == -DONE # Done, no input
Exit 100
End
Echo t{1},
Shift 1
If {1} == -icon
Echo tt{2},t/* Icon */
Shift 2
Else
Echo ttnoIcon,t/* Icon */
End
If {1} == -key
Echo tt{2},t/* Cmd Key */
Shift 2
Else If {1} == hierarchicalMenu
Echo tthierarchicalMenu,t
Shift 1
Else
Echo ttnoKey,t/* Cmd Key */
End
If {1} == -mark
If {2} == noMark || {2} == check
Echo tt{2},t/* Marking Character */
Shift 2
Else
Echo tt{2},t/* Marking Character */
Shift 2
End
Else If {1} == -sub
Set dmv {2}
Shift 2
Set chars Echo -n {dmv} | Count -c
If {chars} == 0
Set dmv 000
Else If {chars} == 1
Set dmv 00{dmv}
Else If {chars} == 2
Set dmv 0{dmv}
End
Echo tt\0D{dmv},t/* SubMenu ID */
Else
Echo ttnoMark,t/* Marking Character */
End
If {1} == enabled
Set EStat 0
Else if {1} == disabled
Set EStat 10
Else
Set EStat 20 # Not allowed
End
Shift 1
If {1} == -LAST
Set EStat Evaluate {EStat} + 100
End
Shift 1
If {1} == +
Shift 1
End
Set TheStyle
For style In {Parameters}
Set TheStyle {TheStyle} {style}
End
Echo tt/* Typeface style */
Echo -n tt{TheStyle}
If {EStat} <= 10
Echo ,
End
Exit {EStat}
### End File RezC.MENU1.more
#############################
### File RezC.MENU2.more
### Called by RezC.MENU to generate partial Rez input
###for one menu item or hierarchical menu.
###W. Powell 1988
Set Exit 0
If {1} == -DONE # Done, no input
Exit 100
End
Echo t{1},
Shift 1
If {1} == -icon
Echo tt{2},t/* Icon */
Shift 2
Else
Echo ttnoIcon,t/* Icon */
End
If {1} == -key
Echo tt{2},t/* Cmd Key */
Shift 2
Else If {1} == hierarchicalMenu
Echo tthierarchicalMenu,t
Shift 1
Else
Echo ttnoKey,t/* Cmd Key */
End
If {1} == -mark
If {2} == noMark || {2} == check
Echo tt{2},t/* Marking Character */
Shift 2
Else
Echo tt{2},t/* Marking Character */
Shift 2
End
Else If {1} == -sub
Set dmv {2}
Shift 2
Set chars Echo -n {dmv} | Count -c
If {chars} == 0
Set dmv 000
Else If {chars} == 1
Set dmv 00{dmv}
Else If {chars} == 2
Set dmv 0{dmv}
End
Echo tt\0D{dmv},t/* SubMenu ID */
Else
Echo ttnoMark,t/* Marking Character */
End
Set EStat 0
If {1} == -LAST
Set EStat 100
End
Shift 1
If {1} == +
Shift 1
End
Set TheStyle
For style In {Parameters}
Set TheStyle {TheStyle} {style}
End
Echo tt/* Typeface style */
Echo -n tt{TheStyle}
If {EStat} <= 10
Echo ,
End
Exit {EStat}
### End File RezC.MENU2.more
#############################
/* File RezC.MENU.Cmdo.R */
/* Commando interface to build MENU Rez input */
/* W. Powell 1988 */
/* Rez definitions for Rez-building Commando interfaces */
#include Types.R
#include Cmdo.R
Resource cmdo (200) {
{ 265,
RezC.MENU produces Rez input for a Menu resource.\n
NOTE: Input of menu items continues in subsequent dialogs.,
{
/* This include file has a standard arrangement of items
* common to all resources: ID#, attributes, name,
* and redirection of output from the Rezc. script */
#include CmdoReztStart.R
/* other items particular to this case */
/* Item 6 */
OR {{1}}, RadioButtons {{
{132,160,148,235},
Enabled,enabled,NotSet,Entire menu is enabled.,
{132,250,148,325},
Disabled,disabled,NotSet,Entire menu is disabled.
}},
/* Item 7 */
AND {{1,-8}}, RegularEntry {
Menu Title:,
{85,30,101,110},
{85,115,101,330},
,keepCase,,
Title for menu.\nClick the apple for DA menu. },
/* Item 8 */
OR {{1}}, CheckOption {
NotSet, {85,340,101,440},
,apple,Click here to get apple DA menu. },
/* Item 9 */
OR {{1}}, RegularEntry {
Proc ID#:,
{112,45,128,105},
{112,115,128,235},
,keepCase,,
Menu Definition Proc ID # of this menu.\nNOTE:
Enter nothing to get default text menus. },
/* Item 10 */
OR {{-9}}, RadioButtons {{
{40,1000,41,1001},
,textMenuProc,NotSet, }},
/* Item 11 */
OR {{7,8}}, DoItButton {},
/* Item 11 */
OR { {1} }, TextTitle {
plain, {132,50,148,155},
systemFont, systemSize,
Entire menu is: },
},
/* Dialog 2 */
/* Include the standard resource attributes dialog */
#include CmdoReztAttr.R
/* Dialog 3 */
/* Include a redirection dialog */
#include CmdoReztRdir.R
}
};
/* End File RezC.MENU.Cmdo.R */
/* File RezC.MENU1.more.Cmdo.R */
/* Commando interface to build MENU Rez input */
/* W. Powell 1988 */
/* Rez definitions for Rez-building Commando interfaces */
#include Types.R
#include Cmdo.R
Resource cmdo (200) {
{ 295,
RezC.MENU1 produces Rez input for one item in a
MENU resource.\n
NOTE: Input of menu items continues in subsequent dialogs.,
{
/* other items particular to this case */
/* Item 1 */
OR {{-((3<<12)+16)}}, RegularEntry {
Item Text:,
{25,30,41,110},
{25,115,41,430},
,keepCase,,
Text of menu item. },
/* Item 2 */
OR {{1}}, RegularEntry {
Icon #,
{50,40,66,90},{69,40,85,90},
,keepCase,-icon,
Index number for icon.\nIndex = [ICON ID #] - 256 },
/* Item 3 */
AND {{1,-4}}, RegularEntry {
-Key,
{50,130,66,180},{69,130,85,180},
,keepCase,-key,
Command key equivalent. },
/* Item 4 */
OR {{1}}, CheckOption {
NotSet,{125,80,141,220},
Hierarchical Menu,hierarchicalMenu,
Check here if item is a hierarchical menu.} ;
/* Item 5 */
AND {{1,-6,-4}}, RegularEntry {
Mark,
{50,220,66,270},{69,220,85,270},
,keepCase,-mark,
Mark the item with this character.\nClick the
Check item to mark with a check. },
/* Item 6 */
AND {{1,-4}}, CheckOption {
NotSet,{90,215,106,277},
Check,-mark check,Mark item with check. },
/* Item 7 */
OR {{4}}, RegularEntry {
SubMenu ID:,
{125,250,141,350},
{125,355,141,405},
,keepCase,-sub,
Resource ID of Hierarchical submenu. },
/* Item 8 */
OR {{1}}, NestedDialog {
2,/* Dialog number */
{57,303,75,353},
Style ,
Select type style for items text.},
/* Item 9 */
OR {{1}}, RadioButtons {{
{67,380,83,455},
Enabled,enabled,NotSet,Menu item is initially enabled.,
{83,380,99,455},
Disabled,disabled,NotSet,Menu item is initially disabled.
}},
/* Item 10 */
NotDependent {}, TextBox {
gray, {57,375,104,460},Item is: },
/* Item 11 */
AND {{4,7}}, Dummy {},
/* Item 12 */
OR {{-4,11}}, Dummy {},
/* Item 13 */
AND { {1,12} }, Dummy {},
/* Item 14 */
OR {{13,(3<<12)+16}}, DoItButton {},
/* Item 15 */
NotDependent {}, Box {
gray, {117,45,149,435} },
/* Item 16 */
NotDependent {}, RadioButtons {{
{162,105,178,160},
More items,-OK,NotSet,
Continue prompting for items with more dialogs.,
{162,185,178,270},
Last item,-LAST,NotSet,
This is the last item on the menu.
Dont need to prompt for more.,
{162,295,178,345},
Done,-DONE,NotSet,
Previous string was the last. Ignore any
input in this dialog.
}},
/* Item 17 */
NotDependent {}, Box {
black, {159,90,181,390} },
},
/* Dialog 2 */
205,
Text style for menu item.,
{
/* Item 1 is hidden */
AND {{-3,-4,-5,-6,-7,-8,-9}}, RadioButtons {{
{30,1000,50,1001},
,plain,NotSet, }},
/* Item 2 */
NotDependent {}, CheckOption {
Set,{20,100,36,200},
Plain,,},
OR {{-2}}, CheckOption {
NotSet,{36,100,52,200},
Bold,+ bold,},
OR {{-2}}, CheckOption {
NotSet,{52,100,68,200},
Italic,+ italic,},
OR {{-2}}, CheckOption {
NotSet,{68,100,84,200},
Underline,+ underline,},
OR {{-2}}, CheckOption {
NotSet,{20,280,36,380},
Outline,+ outline,},
OR {{-2}}, CheckOption {
NotSet,{36,280,52,380},
Shadow,+ shadow,},
OR {{-2}}, CheckOption {
NotSet,{52,280,68,380},
Condense,+ condense,},
OR {{-2}}, CheckOption {
NotSet,{68,280,84,380},
Extend,+ extend,},
},
}
};
/* End File RezC.MENU1.more.Cmdo.R */
/* File RezC.MENU2.more.Cmdo.R */
/* Commando interface to build MENU Rez input */
/* W. Powell 1988 */
/* Rez definitions for Rez-building Commando interfaces */
#include Types.R
#include Cmdo.R
Resource cmdo (200) {
{ 295,
RezC.MENU2 produces Rez input for one item in a
MENU resource.\n
NOTE: Input of menu items continues in subsequent dialogs.,
{
/* other items particular to this case */
/* Item 1 */
OR {{-((3<<12)+17)}}, RegularEntry {
Item Text:,
{25,30,41,110},
{25,115,41,430},
,keepCase,,
Text of menu item. },
/* Item 2 */
OR {{1}}, RegularEntry {
Icon #,
{50,40,66,90},{69,40,85,90},
,keepCase,-icon,
Index number for icon.\nIndex = [ICON ID #] - 256 },
/* Item 3 */
AND {{1,-4}}, RegularEntry {
-Key,
{50,130,66,180},{69,130,85,180},
,keepCase,-key,
Command key equivalent. },
/* Item 4 */
OR {{1}}, CheckOption {
NotSet,{125,80,141,220},
Hierarchical Menu,hierarchicalMenu,
Check here if item is a hierarchical menu.} ;
/* Item 5 */
AND {{1,-6,-4}}, RegularEntry {
Mark,
{50,220,66,270},{69,220,85,270},
,keepCase,-mark,
Mark the item with this character.\nClick the
Check item to mark with a check. },
/* Item 6 */
AND {{1,-4}}, CheckOption {
NotSet,{90,215,106,277},
Check,-mark check,Mark item with check. },
/* Item 7 */
OR {{4}}, RegularEntry {
SubMenu ID:,
{125,250,141,350},
{125,355,141,405},
,keepCase,-sub,
Resource ID of Hierarchical submenu. },
/* Item 8 */
OR {{1}}, NestedDialog {
2,/* Dialog number */
{57,303,75,353},
Style ,
Select type style for items text.},
/* Item 9 */
NotDependent {}, RadioButtons {{
{67,380,83,455},
Enabled,,NotSet,
Items 32 and greater must always be enabled.
}},
/* Item 10 */
OR {{-9}}, RadioButtons {{
{83,380,99,455},
Disabled,,NotSet,
Items 32 and greater must always be enabled.
}},
/* Item 11 */
NotDependent {}, TextBox {
gray, {57,375,104,460},Item is: },
/* Item 12 */
AND {{4,7}}, Dummy {},
/* Item 13 */
OR {{-4,12}}, Dummy {},
/* Item 14 */
AND { {1,13} }, Dummy {},
/* Item 15 */
OR {{14,(3<<12)+17}}, DoItButton {},
/* Item 16 */
NotDependent {}, Box {
gray, {117,45,149,435} },
/* Item 17 */
NotDependent {}, RadioButtons {{
{162,105,178,160},
More items,-OK,NotSet,
Continue prompting for items with more dialogs.,
{162,185,178,270},
Last item,-LAST,NotSet,
This is the last item on the menu.
Dont need to prompt for more.,
{162,295,178,345},
Done,-DONE,NotSet,
Previous string was the last. Ignore any
input in this dialog.
}},
/* Item 18 */
NotDependent {}, Box {
black, {159,90,181,390} },
},
/* Dialog 2 */
205,
Text style for menu item.,
{
/* Item 1 is hidden */
AND {{-3,-4,-5,-6,-7,-8,-9}}, RadioButtons {{
{30,1000,50,1001},
,plain,NotSet, }},
/* Item 2 */
NotDependent {}, CheckOption {
Set,{20,100,36,200},
Plain,,},
OR {{-2}}, CheckOption {
NotSet,{36,100,52,200},
Bold,+ bold,},
OR {{-2}}, CheckOption {
NotSet,{52,100,68,200},
Italic,+ italic,},
OR {{-2}}, CheckOption {
NotSet,{68,100,84,200},
Underline,+ underline,},
OR {{-2}}, CheckOption {
NotSet,{20,280,36,380},
Outline,+ outline,},
OR {{-2}}, CheckOption {
NotSet,{36,280,52,380},
Shadow,+ shadow,},
OR {{-2}}, CheckOption {
NotSet,{52,280,68,380},
Condense,+ condense,},
OR {{-2}}, CheckOption {
NotSet,{68,280,84,380},
Extend,+ extend,},
},
}
};
/* End File RezC.MENU2.more.Cmdo.R */