CLIM mail archive

[Prev][Next][Index][Thread]

Nested accepting-values



   Date: Tue, 18 Aug 92 18:12:41 EDT
   From: jclose@chesapeake.ads.com (Jeff Close)
   Reply-To: jclose@ads.com

      Do you really mean nested ACCEPTING-VALUES calls, or nested calls to
      ACCEPT?

   Thanks for the response.  What I need is the best way to define an
   accept for a structure (instance) with several fields, then use that
   accept within another similar accept call.  E.g.:

   Accept for type X includes several accept calls -- need those be
   sequential accepts within the accept method for X, could they be in an
   accepting-values?  -- anyways, I then want to define an accept for
   type Y that includes multiple accepts of type X.  Is this specific
   enough?  If not, I'll send you some code.

Here is some sample code that may do what you want.  It defines a
presentation type called TICKET.  The ACCEPT method has two recursive
calls to ACCEPT, one to read a president name and another for the
vice-president.  There are two versions of the ACCEPT method (you will
have to incrementally compile the one you want to contrast them).  The
first reads the two names separated by a comma on the same line.  The
second reads the two names on separate lines, delimited by Return.
They both do completion within the field.  That is, if you do

  (accept 'ticket :stream win)

with the first ACCEPT method, and type
"Bu,Qu<Return>"

the screen appearance will be

"Bush,Quayle"

and the return value will be (BUSH QUAYLE).

If you use the second ACCEPT method and type

"Cl
Go
"

The window will contain

"Clinton
Gore"

and the return value will be (CLINTON GORE).

This example also demonstrates simple cross-field constraints by
insisting that the two candidates be of the same party.

For key implementation details, read the comments in the code.



(in-package :clim-user)

(define-presentation-type ticket ())

(setf (get 'bush 'party) 'republican)
(setf (get 'quayle 'party) 'republican)
(setf (get 'clinton 'party) 'democrat)
(setf (get 'gore 'party) 'democrat)

;;; separated by comma version
(define-presentation-method accept ((type ticket) stream view &key &allow-other-keys)
  (declare (ignore view))
  (let ((president (accept '(member bush clinton) :stream stream :prompt nil
			   ;; add comma as a completing delimiter
			   :blip-characters '(#\,))))
    ;; Make sure that they names were separated by comma
    (unless (eql (read-gesture :stream stream) #\,)
      (simple-parse-error "Ticket members must be separated by commas"))
    (let ((veep (accept '(member quayle gore) :stream stream :prompt nil)))
      ;; Validate party affiliations
      (unless (eql (get president 'party) (get veep 'party))
	(simple-parse-error "Ticket members must be of the same party"))
      (list president veep))))

;;; Separated by Return version
(define-presentation-method accept ((type ticket) stream view &key &allow-other-keys)
  (declare (ignore view))
  (let ((president (accept '(member bush clinton) :stream stream :prompt nil
			   ;; Remove Newline from activation characters
			   ;; (can't say NIL here due to stupid bug, so pick some
			   ;; character we aren't likely to type)
			   :activation-characters `(~)
			   ;; Add Newline as a delimiter, so that we get completion
			   ;; and move-to-next-field behavior when Return is typed.
			   :blip-characters `(#\Return #\Newline))))
    (unless (eql (read-gesture :stream stream) #\Newline)
      (simple-parse-error "Ticket members must be entered on separate lines "))
    (let ((veep (accept '(member quayle gore) :stream stream :prompt nil)))
      ;; Validate party affiliations
      (unless (eql (get president 'party) (get veep 'party))
	(simple-parse-error "Ticket members must be of the same party"))
      (list president veep))))


Follow-Ups: References:

Main Index | Thread Index