7.1 Conceptual Overview of Defining a New Presentation Type
A presentation type calledticket
is defined. The accept method has two recursive calls to accept, one to read the name of a candidate for president and another to read the name of the running mate. We provide two possible accept methods; in order to compare them, you will have to compile first one and then the other. The first reads the two names separated by a comma on the same line. The second reads the two names on separate lines, delimited byRETURN
. 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 the names were separated by a 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 :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))))
Generated with Harlequin WebMaker