Prompting with a Default Option

Introduction

This tutorial describes various ways in which to prompt for user input whilst offering a default option available for selection by the user pressing ENTER, SPACE or right-clicking at the prompt.

Note 1: On Prompt String Format

In order to create a professional looking program, I usually try to closely match the standard prompting format utilised by AutoCAD. The idea is to create an application that can be cleanly integrated into the AutoCAD environment with minimal user training.

To achieve correct display of available options when Dynamic Input is enabled (i.e. DYNMODE = 1 toggled with F12), the prompt string must be formatted in the following way:

[Option1/Option2/Option3] <Option1>

In the above example, Options 1, 2 & 3 are available for user selection with Option 1 as a default option - selected upon the user pressing Enter.

Note 2: On Global Variables

In the examples that follow, global variables are used to effectively 'remember' a default option after program completion. To indicate where global variables are utilised, the variable names are prefixed with global:; this furthermore decreases the risk of variable names clashing with unlocalised variables from other programs.

I would note that the prefixes are used for no other purpose: in AutoLISP, they constitute standard variable names.

Read my tutorial on Localising Variables to understand the possible consequences of using duplicate unlocalised variable names between programs.


Case 1: Forcing User Input (No Default)

This is the simplest case in which there is no default option available. I use the initget function with bit code 1 to force the user to make a selection from the available options; hence in this case no conditional error trapping is required to ensure user input, since the only way the user can bypass the prompt is to exit the program using ESC.

(initget 1 "Alpha Beta Gamma")
(setq ans (getkword "\nChoose [Alpha/Beta/Gamma]: "))

Bit code 1 of the initget function prevents the user from responding to the request by pressing ENTER, thus forcing the user to select from the Alpha, Beta & Gamma options.


Case 2: Preset Default Option

In this case, a default option is available, however it is the same option everytime. The default option is hard-coded into the prompt string and may be selected by the user pressing ENTER at the prompt.

Version 1

(initget "Alpha Beta Gamma")
(setq ans (cond ((getkword "\nChoose [Alpha/Beta/Gamma] <Alpha>: ")) ("Alpha")))

In the above code, the option Alpha is hard-coded as the default option.

If the user presses ENTER at the prompt, the getkword expression returns nil and so the cond function moves on to evaluate the next test condition: this is the default string "Alpha" which is a non-nil value and is hence returned by the cond function.

Version 2

(initget "Alpha Beta Gamma")
(if (null (setq ans (getkword "\nChoose [Alpha/Beta/Gamma] <Alpha>: ")))
    (setq ans "Alpha")
)

This second version uses the same logic as the first, however the conditional operator cond is replaced by an if statement. Hence, if the variable ans is nil, the default option is bound to it.


Case 3: Dynamic Default

In this case, the variable global:ans is intended to be global (not localised in the function definition in which it is used). Since it is global, it does not lose any value bound to it following program completion.

(if (null global:ans)
    (setq global:ans "Alpha")
)
(initget "Alpha Beta Gamma")
(if (setq tmp (getkword (strcat "\nChoose [Alpha/Beta/Gamma] <" global:ans ">: ")))
    (setq global:ans tmp)
)

In the above code, the variable global:ans is first checked for a non-nil value: this is to ensure that, upon the first run of the program there is a default to be offered to the user.

Upon the first run of the program, the variable global:ans will be nil and so the if statement will bind the value "Alpha" to it - this will be the first-time default.

The if statement which follows reverses the logic used in the previous examples: if the user has responded with some input (i.e. the getkword function has returned a non-nil value), the global variable global:ans is updated to store the new input (even if the user may have explicitly selected the same option as the default).

Conversely, if the user has pressed ENTER at the prompt, the getkword function will return nil and the global:ans variable will retain its existing value as the default option selected by the user.

If the program is then run a second time, the variable global:ans now has a value, and so the test expression in the first if statement returns nil. Therefore, in the expressions that follow, the last selected option as held by the global:ans variable is used as the default.


Beyond the Examples

In all of the above the examples, I have used the getkword function to prompt the user to select one of a predefined set of options, however, the methods & logic illustrated above could equally be applied to the other getXXX user input functions (e.g. getreal, getdist etc.) with the exception of getstring which returns an empty string ("") on null input.

The only additional consideration when generalising to other functions is the required conversion from the data type of the default value to the string which is used to display the user prompt.

For example, when prompting the user to specify an integer value, the itoa (integer-to-ASCII) function must be used so that the default value may be concatenated with the user prompt using the strcat (string concatenation) function:

(if (null global:int)
    (setq global:int 1)
)
(initget 6)
(if (setq tmp (getint (strcat "\nEnter a positive non-zero integer <" (itoa global:int) ">: ")))
    (setq global:int tmp)
)

Similarly, in the following example, the numerical value of the global variable is converted to a string formatted in decimal format to 3 decimal places using the rtos (real to string) function:

(if (null global:dis)
    (setq global:dis (+ pi pi))
)
(initget 4)
(if (setq tmp (getdist (strcat "\nSpecify circumference <" (rtos global:dis 2 3) ">: ")))
    (setq global:dis tmp)
)

textsize

increase · reset · decrease

Designed & Created by Lee Mac © 2010