Programming with exceptions
Chapter 7 Data entry
AutoLISP has a number of user data entry functions using the AutoCAD
command line. These functions are identified by their names that start with the prefix get. This is not the only way to communicate with the user. Applications increasingly tend to display dialog boxes where, instead of sequentially entering the data, the user can select the appropriate options from various types of
controls such as text boxes, action buttons, image buttons, etc.
We will cover in this chapter the command line entries, which is how AutoCAD commands traditionally operate. Future chapters will discuss the
implementation of Graphical User Interfaces (GUI) using two procedures:
dialog boxes programmed in DCL language and OpenDCL, an open source application platform for Visual LISP that implements the use of Windows user interface components.
7.1. Integrated error control.
The get... functions include data type control, avoiding user entries of data which are not compatible with the program’s requirements. A function like
getreal aimed at obtaining a real number rejects anything that is not a number, which if integer is converted to real.
Command: (getreal "Specify a real number: ") Specify a real number: a
Requires numeric value.
Specify a real number: 5 5.0
As shown in the previous example, get... functions accept as an optional argument a string that will be presented to the user as a prompt in the command line. As shown in the example, a loop is begun that can end in one of two ways:
by entering an integer or real number, that will always be converted into real or by pressing ENTER to finish without entering any data.
Command: (getstring "Specify a string: ") Specify a string: asdf
"asdf"
Command: (getstring "Specify a string: ") Specify a string:
""
On pressing ENTER the get... functions return nil, except getstring, that returns an empty string represented by two quotation marks with no space in between.
7.2. Default Values.
This value returned on pressing ENTER can often be used to accept the program’s default values. The usual AutoCAD command prompts usually display default values surrounded by the characters "<" and ">". For example, the OFFSET command presents the default offset distance this way.
Command: _OFFSET
Current settings: Erase source=No Layer=Source OFFSETGAPTYPE=0 Specify offset distance or [Through/Erase/Layer] <1.0000>:
We can develop a generic function (see Listing 7.1) to be used for all of the
get... functions (except getstring) that reproduces this behavior. This function takes as arguments the name of the get... function to use (always preceded by quote), the message to be used as prompt and the default value.
The function returns this value if ENTER is pressed. Otherwise, it returns the value entered if it matches the function’s expected data type. In case an
incompatible data type is entered, the value is prompted for again.
(defun default-value (func message value / tmp) (if (setq tmp
Listing 7.1. User input request including default values.
Testing it with getreal we obtain the following results, in this case entering number 22:
Command: (default-value 'getreal "Specify a real number " 15.0) Specify a real number <15.0>: 22
22.0
Command: (default-value 'getreal "Specify a real number " 15.0)
Specify a real number <15.0>:
15.0
Other get... functions accept points picked on the screen as user input. For example getdist accepts a number or picking two points on the screen as a distance input.
Command: (default-value 'getdist "Specify distance " 100.0) Specify distance <100.0>: Specify second point: 63.1624
In the previous case a point was picked and getdist then prompted for a second point. In case ENTER is pressed the default value will be returned:
Command: (default-value 'getdist "Specify distance " 100.0) Specify distance <100.0>:
100.0
The default-value function used with getstring would not work properly because pressing ENTER would return "" instead of nil. It would therefore be necessary to design a function we shall call default-string (see Listing 7.2) for these specific cases.
(defun default-string (message value / tmp) (setq tmp (apply
Listing 7.2. Prompting for a string with default value.
With which we would get the same result as with default-value as shown in the following examples:
Command: (default-string "Specify text " "SAMPLE") Specify text <SAMPLE>: abcd
"abcd"
Command: (default-string "Specify text " "SAMPLE") Specify text <SAMPLE>:
"SAMPLE"
In this case it is not necessary to provide the function name as an argument, as it can only be getstring. If the argument value is not a string an error will be returned.
7.3. Prompting for data with options.
Many AutoCAD commands in addition to providing default values, allow choosing between option keywords. The keywords that allow you to access the various options are usually surrounded by brackets ("[" and "]" characters).
Command: ARC Specify start point of arc or [Center]:
Usually the options provided are alternatives to the normal input, in the case shown a starting point for the arc is prompted for and the alternative of picking instead the center of the arc is offered as an option, alternative that can be activated typing its abbreviation "C" (shown in upper case) or else the word
"center" or part thereof.
The options enclosed in brackets will appear in the contextual (right-click) menu from which they can also be selected.
In this case as the basic request is that of a point, the input function to use would be getpoint, but with modifications to its behavior introduced by preceding it with the evaluation of the initget function which sets the desired behavior’s parameters.
_$ (initget "Center") nil
_$ (getpoint "Specify the arc's first point or [Center] :") (0.498113 0.751347 0.0)
_$ (initget "Center") nil
_$ (getpoint "Specify the arc's first point or [Center] :")
"Center"
_$
The first of the examples shown above displays the value returned by picking a point on the screen, the second the value returned by typing the letter "C" or selecting Center from the contextual menu.
In the same way we designed the generic function default-value we can develop a function which admits options.
(defun value-with-options (func message options / tmp) (initget options)
(if (setq
tmp (apply func
(list (strcat message " ["
(replace " " "/" options) "]: "))))
tmp))
Listing 7.3. Prompting for data including options.
When it is necessary to include several options, they are passed to initget as a single string where keywords are separated by spaces and have one or more uppercase letters that indicate their abbreviation. This abbreviation is usually the first character, but if more than one keyword begins with the same, other keyword characters (one or more consecutive characters) can be used. For example "Center ciRcumference clOsure" would be a valid initget
option string. This string is represented in the listed function by the argument
options. But in the prompt displayed in the command line the options should be separated by slashes.
To transform the options argument string with one in which the keywords are separated by slashes we can use the vl-string-translate function that replaces a set of characters in a string with another one. This function will return the string of options properly configured for the user prompt:
_$ (vl-string-translate " " "/" "Height Width Depth")
"Height/Width/Depth"
_$
This way we will have designed a new function which we can use whenever we must include prompts for data presenting alternative options.
Command: (value-with-options 'getdist
"Specify distance" "Height Width Depth") Specify distance [Height/Width/Depth]: w
"Width"
An application can check the value returned to choose the appropriate action according to the user’s input. Besides the get... functions, initget defined keywords are also admitted by the entity selection functions entsel, nentsel, and nentselp, some of which will be discussed later.