Foolproof Input For Amiga BASIC
Tom Bunker
Here's an extremely handy tool for Amiga BASIC programmers—a routine that creates edit field boxes for accepting various kinds of keyboard input. The routine also demonstrates how well-designed subprograms can, in effect, add new commands to Amiga BASIC.Amiga BASIC'S ability to use custom subprograms is one of its most valuable features: It allows programmers to accumulate a library of very useful routines that can be attached to virtually any BASIC program. The simple requester window subprogram presented in the March 1986 issue of COMPUTE! is just one example. Another subprogram that should be in every programmer's collection is a foolproof input routine.
The ideal input routine would simulate the Amiga operating system's own edit field boxes. An example of such an edit field appears when you select the Save as option in Amiga BASIC'S Project menu. A similar routine in BASIC would give your programs much more control than provided by the standard INPUT statement. It would be helpful, for instance, to be able to limit the number of characters that can be entered, or to limit numeric input to integers rather than print error messages after the fact. The input routine shown here has all of these capabilities and more.
Edit Fields In BASIC
The complete input routine consists of two subprograms: "Getline," which gets a line of input from the keyboard, and "Box," which Getline calls to draw an edit field box and cursor on the screen. The Box subprogram is very useful in its own right and can be used independently of Getline.
Getline lets you create the equivalent of an edit field box in Amiga BASIC, Here are some of its features:
•The main program which calls Getline sets the maximum length of input allowed.
•The Box subprogram draws an edit field box of appropriate size.
•The cursor inside the box can be flashing or nonflashing.
•The main program can select the type of input allowed: alphanumeric characters, real numbers, or integers.
•The range of alphanumeric characters accepted for input can be adjusted.
•Pressing the ESCape key aborts the input operation.
•A single keystroke can erase all input within the edit field box.
•The main program can display a default entry within the edit field box which the user can edit.
Getline can be used any time your program needs to accept input from the keyboard, for entry of data, filenames, or whatever. To use Getline, your program should first print any desired prompt message and leave the cursor at the point on the screen where input is to begin. Then you must call Getline using this general format:
CALL Getline (string$, maxlength%, inputtype%)
The string variable string$ holds whatever default text you want to display inside the edit field box for the user to edit, and also returns the input entered by the user. For instance, if Getline is called as part of a save-data-to-disk routine, you could suggest a default filename or use a filename which the user has previously indicated. If you don't want to display anything within the edit field box when it appears, set this string variable to a null string ("") before calling Getline. In any case, Getline returns the user's input in this string variable after the subprogram passes control back to your main program.
The second parameter (max-length%) is an integer which sets the maximum input length. For instance, if you want to limit input to 30 characters, you'd specify a 30 for this parameter by supplying either an integer variable or a constant.
The last parameter (inputtype%) is an integer which tells Getline which type of input to accept. There are three possible values:
0 accepts all alphanumeric characters without restriction.
1 accepts real numbers—the digits 0 to 9 and the decimal point.
2 accepts integers—only the digits 0 to 9.
The real and integer types also accept the plus and minus signs, but only in the first character position. Getline simply ignores all keystrokes that do not conform to the type of input selected.
CALLing Getline
Here are a couple of examples. Let's say you want the user to enter his or her name, up to 14 characters long, and you want your program to store the information in the string variable NAME$. The proper CALL would be.
CALL Getline (NAME$,14,0)
If you want the user to enter a three-digit integer number (perhaps a telephone area code), the proper CALL would be.
CALL Getline (NUMBER$,3,2)
Note that Getline always returns the user's input in a string variable. If the input you're seeking is an integer or real number, you can convert it from string to numeric form with the VAL function after Getline returns control to your main program.
Remember, too, that Amiga BASIC'S CALL statement has an alternate syntax: You can omit the CALL keyword if you delete the parentheses surrounding the arguments. The following statements work the same as the examples above:
Getline NAME$,14,0
Getline NUMBER$,3,2
This syntax saves a bit of program space, but also sacrifices a certain amount of program clarity. If you include the CALL keyword, it is always clear to others that the program is calling a subprogram.
Special Keystrokes
When called, the Getline subprogram first draws an edit field box the proper size to hold the input. If the string variable supplied in the call is not a null string (two quotes with nothing between them), the subprogram prints the string inside the box. A flashing cursor indicates that the program is awaiting keyboard input. Like the Amiga operating system's own edit fields, Getline recognizes the following special keystrokes:
• ESCape exits the edit field and leaves the string variable with the value it had when Getline was called.
• RETURN exits the edit field and assigns the user's entry to the string variable.
• BACKSPACE deletes the character to the left of the cursor.
• DEL deletes the entry currently in the edit field.
• CURSOR LEFT moves the cursor one space to the left.
• CURSOR RIGHT moves the cursor one space to the right.
The last four commands, of course, are valid only if at least one character is within the edit field.
Customizing Getline
Note that Getline is designed to work only when Amiga BASIC'S default font is used and Preferences is set to 80 columns. If you're using a 60-column screen or a different font, the text doesn't appear properly within the edit field box. You can modify the subprograms to solve this problem if you don't regularly use the default 80-column font.
If you don't want to bother with three parameters every time you call Getline, you can omit either the maximum string length or input type or both, as long as you also delete the corresponding items from the parameter list of the SUB statement. The Getline call can be made as simple as this:
Getline NAME$
In this case, the SUB statement would have to be changed to look for only one argument:
SUB Getline(inputstring$) STATIC
Getline substitutes default values for maxlength% or inputtype% when they are missing from the parameter list. Maxlength% defaults to 40, and inputtype% defaults to 0 (thus accepting all types of input). You can change these defaults too, if you wish.
Two variables in the Getline subprogram—asc.low and asc.high— determine the ASCII range of characters that are accepted in the edit field. You can change these variables to make the subprogram accept any range of characters desired, even to the extent of restricting input to only one key. They could also be declared in a SHARED statement and set by your main program.
The ESCape key aborts the input and exits the edit field. If your main program needs to know whether or not the edit field was terminated by ESCape (as opposed to a RETURN with no other input), add the following line to the Getline subprogram immediately following the SUB statement:
SHARED K
After the subprogram ends, your main program can test the value of K. If K=27, the ESCape key was pressed.
You can also program one or more of the special function keys to work in a similiar fashion by adding additional lines directly below the ESCape key line to test for any other ASCII value. For example, the addition of this line:
IF K>=129 AND K<=138 THEN EXIT SUB
makes all the function keys abort the input like ESCape. Your main program could then test to see if K is equal to the ASCII value of any of the function keys and take whatever action is desired.
By deleting a single line as instructed by comments within the subprogram, Getline will always start with an empty string. Other comments show how the flashing cursor can be changed to a non-flashing cursor and how the box around the edit field can be eliminated. To make these changes, it's not necessary to actually delete the lines which are indicated. Simply insert a REM at the beginning of the line to disable it; this has the same effect and is more easily reversed.
The Box Subprogram
To draw the box around the edit field, Getline calls the Box subprogram. This subprogram selects a rectangular area of the screen and alters it in one of four ways. You may find this technique useful for other purposes as well. Here is the general format of the Box subprogram call:
CALL Box (wide%, high%, border%, mode%)
or
Box wide%, high%, border%, mode'%
The first two parameters (wide% and high%) set the size of the boxed area by specifying the width and height in number of characters. The third parameter (border%) changes the size selected by increasing or decreasing the area on all four sides by the number of pixels specified. If this argument is 0, the perimeter of the area falls on the character boundaries. The last parameter (mode%) can range from 0 to 3:
0 fills the box interior using a PATTERN statement.
1 inverts the interior of the box.
2 outlines the area using the foreground color.
3 fills the box interior using the foreground color.
The Box subprogram can be very useful when you want to erase a word or clear any rectangular section of the screen. Consider this statement:
COLOR background#:Box 30,1,0,3 :COLOR foreground#
This erases a section of the screen 30 characters long without affecting any surrounding text. It sets the foreground color equal to the background color, fills the area, and resets the color. Of course, you can achieve the same effect by printing spaces, but the Box subprogram works much faster.
Getline Input Routine
Note: The left-arrow symbols In this listing indicate when to press RETURN at the end of each program line. Do not attempt to type the arrows themselves.