NextPrevUpTopContentsIndex

10.5.2 Using popup-confirmer

The function popup-confirmer is a higher level function provided to add the standard buttons to user dialogs, and it is nearly always used in preference to display-dialog . In order to create a dialog using popup-confirmer , all you need to do is to supply a pane to be placed inside the dialog along with the buttons and the title. The function also expects a title, like all of the prompter functions described earlier.

(popup-confirmer
 (make-instance
  'text-input-pane
  :callback-type :data
  :callback 'exit-dialog)
 "Enter a string")

A common thing to want to do with a dialog is to get the return value from some state in the pane specified. For instance, in order to create a dialog that prompts for an integer the string entered into the text-input-pane would need to be converted into an integer. It is possible to do this once the dialog has returned, but popup-confirmer has a more convenient mechanism. The function provides a keyword argument, :value-function , which gets passed the pane, and this function should return the value to return from the dialog. It can also indicate that the dialog cannot return by returning a second value which is non- nil .

In order to do this conversion, popup-confirmer provides an alternative exit function to the usual exit-dialog . This is called exit-confirmer , and it does all of the necessary work on exiting.

You now have enough information to write a primitive version of prompt-for-integer .

(defun text-input-pane-integer (pane)
 (let* ((text
         (text-input-pane-text pane))
        (integer
         (parse-integer
          text
          :junk-allowed t)))
   (or (and (integerp integer) integer)
       (values nil t))))
(popup-confirmer
  (make-instance 
   'text-input-pane
   :callback 'exit-confirmer)
  "Enter an integer:"
  :value-function 'text-input-pane-integer)

Figure 10.10 A example using popup-confirmer

Note that the dialog's OK button never becomes activated, yet pressing Return once you have entered a valid integer will return the correct value. This is because the OK button is not being dynamically updated on each keystroke in the text-input-pane so that it activates when the text-input-pane contains a valid integer. The activation of the OK button is recalculated by the function redisplay-interface , and the CAPI provides a standard callback, :redisplay-interface , which calls this as appropriate.

Thus, to have an OK button that becomes activated and deactivated dynamically, you need to specify the change-callback for the text-input-pane to be :redisplay-interface .

(popup-confirmer
 (make-instance
  'text-input-pane
   :change-callback :redisplay-interface
  :callback 'exit-confirmer)
 "Enter an integer:"
 :value-function 'text-input-pane-integer)

Note that the OK button now changes dynamically so that it is only ever active when the text in the text-input-pane is a valid integer.

Note that the Escape key activates the Cancel button - this too was set up by popup-confirmer .

The next thing that you might want to do with your integer prompter is to make it accept only certain values. For instance, you may only want to accept negative numbers. This can be specified to popup-confirmer by providing a validation function with the keyword argument :ok-check . This function receives the potential return value (the value returned by the value function) and it must return non- nil if that value is valid. Thus to accept only negative numbers we could pass minusp as the :ok-check .

(popup-confirmer
 (make-instance
  'text-input-pane
  :change-callback :redisplay-interface
  :callback 'exit-confirmer)
 "Enter an integer:"
 :value-function 'text-input-pane-integer
 :ok-check 'minusp)

LispWorks CAPI User Guide (Macintosh version) - 17 Mar 2008

NextPrevUpTopContentsIndex