| Extended Stream Input | Contents | Index | Input Editing and Completion Facilities |
23 Presentation Types
23.1 Overview of Presentation Types
The core around which the CLIM application user interface model is built is the
concept of the application-defined user interface data type. Each application
has its own set of semantically significant user interface entities; a CAD
program for designing circuits has its various kinds of components (gates,
resistors, and so on), while a database manager has its relations and field
types. These entities have to be displayed to the user (possibly in more than
one displayed representation) and the user has to be able to interact with and
specify the entities via pointer gestures and keyboard input. Frequently each
user interface entity has a corresponding Lisp data type (such as an
application-specific structure or CLOS class definition), but this is not always
the case. The data representation for an interaction entity may be a primitive
Lisp data type. In fact, it is possible for several different user interface
entities to use the same Lisp data type for their internal representation, for
example, building floor numbers and employee vacation day totals could both be
represented internally as integers.
CLIM provides a framework for defining the appearance and behavior of these user interface entities via the presentation type mechanism. A presentation type can be thought of as a CLOS class that has some additional functionality pertaining to its roles in the user interface of an application. By defining a presentation type the application programmer defines all of the user interface components of the entity:
The set of presentation types forms a type lattice, an extension of the Common Lisp CLOS type lattice. When a new presentation type is defined as a subtype of another presentation type it inherits all the attributes of the supertype except those explicitly overridden in the definition.
| presentation | [Protocol Class] |
| presentationp | object | [Predicate] |
| standard-presentation | [Class] |
| :object | [Init arg] |
| :type | [Init arg] |
| :view | [Init arg] |
| :single-box | [Init arg] |
| :modifier | [Init arg] |
23.2.1 The Presentation Protocol
The following functions comprise the presentation protocol. All classes that
inherit from presentation must implement methods for these generic
functions.
| presentation-object | presentation | [Generic function] |
| (setf presentation-object) | object presentation | [Generic function] |
| presentation-type | presentation | [Generic function] |
| (setf presentation-type) | type presentation | [Generic function] |
| presentation-single-box | presentation | [Generic function] |
| (setf presentation-single-box) | single-box presentation | [Generic function] |
| presentation-modifier | presentation | [Generic function] |
23.3 Presentation Types
The type associated with a presentation is specified with a
presentation type specifier , an object matching one of the following
three patterns:
| name | |
| (name parameters... ) | |
| ((name parameters... ) options... ) | |
The parameters ``parameterize'' the type, just as in a Common Lisp type specifier. The function presentation-typep uses the parameters to check object membership in a type. Adding parameters to a presentation type specifier produces a subtype, which contains some, but not necessarily all, of the objects that are members of the unparameterized type. Thus the parameters can turn off the sensitivity of some presentations that would otherwise be sensitive.
The options are alternating keywords and values that affect the use or appearance of the presentation, but not its semantic meaning. The options have no effect on presentation sensitivity. (A programmer could choose to make a tester in a translator examine options, but this is not standard practice.) The standard option :description is accepted by all types; if it is a non-nil value, then the value must be a string that describes the type and overrides the description supplied by the type's definition.
Every presentation type is associated with a CLOS class. If name is a class object or the name of a class, and that class is not a built-in-class , that class is the associated class. Otherwise, define-presentation-type defines a class with metaclass presentation-type-class and superclasses determined by the presentation type definition. This class is not named name , since that could interfere with built-in Common Lisp types such as and , member , and integer . class-name of this class returns a list (presentation-type name ) . presentation-type-class is a subclass of standard-class .
Implementations are permitted to require programmers to evaluate the defclass form first in the case when the same name is used in both a defclass and a define-presentation-type .
Every CLOS class (except for built-in classes) is a presentation type, as is its name. If it has not been defined with define-presentation-type , it allows no parameters and no options.
Presentation type inheritance is used both to inherit methods (``what parser should be used for this type?''), and to establish the semantics for the type (``what objects are sensitive in this input context?''). Inheritance of methods is the same as in CLOS and thus depends only on the type name, not on the parameters and options.
During presentation method combination, presentation type inheritance arranges to translate the parameters of a subtype into a new set of parameters for its supertype, and translates the options of the subtype into a new set of options for the supertype.
23.3.1 Defining Presentation Types
| define-presentation-type | name parameters &key options inherit-from description history parameters-are-types | [Macro] |
options is a list of option specifiers. It defaults to nil . An option specifier is either a symbol or a list (symbol &optional default supplied-p presentation-type accept-options ), where symbol , default , and supplied-p are as in a normal lambda-list. If presentation-type and accept-options are present, they specify how to accept a new value for this option from the user. symbol can also be specified in the (keyword variable ) form allowed for Common Lisp lambda lists. symbol is a variable that is visible within inherit-from and within most of the methods created with define-presentation-method . The keyword corresponding to symbol can be used as an option in the third form of a presentation type specifier. An option specifier for the standard option :description is automatically added to options if an option with that keyword is not present, however it does not produce a visible variable binding.
Unsupplied optional or keyword parameters default to * (as in deftype ) if no default is specified in parameters . Unsupplied options default to nil if no default is specified in options .
inherit-from is a form that evaluates to a presentation type specifier for another type from which the new type inherits. inherit-from can access the parameter variables bound by the parameters lambda list and the option variables specified by options . If name is or names a CLOS class (other than a built-in-class ), then inherit-from must specify the class's direct superclasses (using and to specify multiple inheritance). It is useful to do this when you want to parameterize previously defined CLOS classes.
If inherit-from is unsupplied, it defaults as follows: If name is or names a CLOS class, then the type inherits from the presentation type corresponding to the direct superclasses of that CLOS class (using and to specify multiple inheritance). Otherwise, the type named by name inherits from standard-object .
description is a string or nil . This should be the term for an instance for the type being defined. If it is nil or unsupplied, a description is automatically generated; it will be a ``prettied up'' version of the type name, for example, small-integer would become "small integer" . You can also write a describe-presentation-type presentation method. description is implemented by the default describe-presentation-type method, so description only works in presentation types where that default method is not shadowed.
history can be t (the default), which means this type has its own history of previous inputs, nil , which means this type keeps no history, or the name of another presentation type, whose history is shared by this type. More complex histories can be specified by writing a presentation-type-history presentation method.
Every presentation type must define or inherit presentation methods for accept and present if the type is going to be used for input and output. For presentation types that are only going to be used for input via the pointer, the accept need not be defined.
If a presentation type has parameters , it must define presentation methods for presentation-typep and presentation-subtypep that handle the parameters, or inherit appropriate presentation methods. In many cases it should also define presentation methods for describe-presentation-type and presentation-type-specifier-p .
There are certain restrictions on the inherit-from form, to allow it to be analyzed at compile time. The form must be a simple substitution of parameters and options into positions in a fixed framework. It cannot involve conditionals or computations that depend on valid values for the parameters or options; for example, it cannot require parameter values to be numbers. It cannot depend on the dynamic or lexical environment. The form will be evaluated at compile time with uninterned symbols used as dummy values for the parameters and options. In the type specifier produced by evaluating the form, the type name must be a constant that names a type, the type parameters cannot derive from options of the type being defined, and the type options cannot derive from parameters of the type being defined. All presentation types mentioned must be already defined. and can be used for multiple inheritance, but or , not , and satisfies cannot be used.
None of the arguments, except inherit-from , is evaluated.
23.3.2 Presentation Type Abbreviations
| define-presentation-type-abbreviation | name parameters equivalent-type &key options | [Macro] |
name must be a symbol and must not be the name of a CLOS class.
The equivalent-type form might be evaluated at compile time if presentation type abbreviations are expanded by compiler optimizers. Unlike inherit-from , equivalent-type can perform arbitrary computations and is not called with dummy parameter and option values. The type specifier produced by evaluating equivalent-type can be a real presentation type or another abbreviation. If the type specifier doesn't include the standard option :description , the option is automatically copied from the abbreviation to its expansion.
Note that you cannot define any presentation methods on a presentation type abbreviation. If you need methods, use define-presentation-type instead.
define-presentation-type-abbreviation is used to name a commonly used cliche. For example, a presentation type to read an octal integer might be defined as
(define-presentation-type-abbreviation octal-integer (&optional low high)
`((integer ,low ,high) :base 8 :description "octal integer"))
None of the arguments, except equivalent-type , is evaluated.
| expand-presentation-type-abbreviation-1 | type &optional env | [Function] |
env is a macro-expansion environment, as for macroexpand .
| expand-presentation-type-abbreviation | type &optional env | [Function] |
23.3.3 Presentation Methods
Presentation methods inherit and combine in the same way as ordinary CLOS
methods. The reason presentation methods are not exactly the same as ordinary
CLOS methods revolves around the type argument. The parameter specializer
for type is handled in a special way, and presentation method inheritance
``massages'' the type parameters and options seen by each method. For example,
consider three types int , rrat , and num defined as follows:
(define-presentation-type int (low high) :inherit-from `(rrat ,high ,low))If the user were to evaluate the form (presentation-typep X '(int 1 5)) , then the type parameters will be (1 5) in the presentation-typep method for int , (5 1) in the method for rrat , and nil in the method for num . The value for type will be or ((int 1 5)) in each of the methods.(define-presentation-method presentation-typep :around (object (type int)) (and (call-next-method) (integerp object) (<= low object high)))
(define-presentation-type rrat (high low) :inherit-from `num)
(define-presentation-method presentation-typep :around (object (type rrat)) (and (call-next-method) (rationalp object) (<= low object high)))
(define-presentation-type num ())
(define-presentation-method presentation-typep (object (type num)) (numberp object))
| define-presentation-generic-function | generic-function-name presentation-function-name lambda-list &rest options | [Macro] |
There are some ``special'' arguments in lambda-list that are known about by the presentation type system. The first argument in lambda-list must be either type-key or type-class ; this argument is used by CLIM to implement method dispatching. The second argument may be parameters , meaning that, when the method is invoked, the type parameters will be passed to it. The third argument may be options , meaning that, when the method is invoked, the type options will be passed to it. Finally, an argument named type must be included in lambda-list ; when the method is called, type argument will be bound to the presentation type specifier.
For example, the accept presentation generic function might be defined as follows:
(define-presentation-generic-function present-method present (type-key parameters options object type stream view &key acceptably for-context-type))None of the arguments is evaluated.
| define-presentation-method | name qualifiers* specialized-lambda-list &body body | [Macro] |
body defines the body of the method. body may have zero or more declarations as its first forms.
All presentation methods have an argument named type that must be specialized with the name of a presentation type. The value of type is a presentation type specifier, which can be for a subtype that inherited the method.
All presentation methods except presentation-subtypep have lexical access to the parameters from the presentation type specifier. Presentation methods for the functions accept , present , describe-presentation-type , presentation-type-specifier-p , and accept-present-default also have lexical access to the options from the presentation type specifier.
| define-default-presentation-method | name qualifiers* specialized-lambda-list &body body | [Macro] |
| funcall-presentation-generic-function | presentation-function-name &rest arguments | [Macro] |
funcall-presentation-generic-function is analogous to funcall .
The presentation-function-name argument is not evaluated.
For example, to call the present presentation generic function, one might use the following:
(funcall-presentation-generic-function present object presentation-type stream view)
| apply-presentation-generic-function | presentation-function-name &rest arguments | [Macro] |
The presentation-function-name argument is not evaluated.
Here is a list of all of the standard presentation methods and their specialized lambda lists. For the meaning of the arguments to each presentation method, refer to the description of the function that calls that method.
For all of the presentation methods, the type will always be specialized. For those methods that take a view argument, implementors and programmers may specialize it as well. The other arguments are not typically specialized.
| present | object type stream view &key acceptably for-context-type | [Presentation Method] |
The present method can specialize on the view argument in order to define more than one view of the data. For example, a spreadsheet program might define a presentation type for revenue, which can be displayed either as a number or a bar of a certain length in a bar graph. Typically, at least one canonical view should be defined for a presentation type, for example, the present method for the textual-view view must be defined if the programmer wants to allow objects of that type to be displayed textually.
Implementation note: the actual argument list to the present method is
(type-key parameters options object type stream view &key acceptably for-context-type)
type-key is the object that is used to cause the appropriate methods to be
selected (an instance of the class that corresponds to the presentation type
type .).
parameters and options are the parameters and
options for the type on which the current method is specialized.
The other arguments are gotten from the arguments of the same name in present .
Implementation note: the actual generic function of the present method is an internal generic function, not the function whose name is present . Similar internal generic functions are used for all presentation methods.
| accept | type stream view &key default default-type | [Presentation Method] |
The accept method can specialize on the view argument in order to define more than one input view for the data. The accept method for the textual-view view must be defined if the programmer wants to allow objects of that type to entered via the keyboard.
Note that accept presentation methods can call accept recursively. In this case, the programmer should be careful to specify nil for :prompt and :display-default unless recursive prompting is really desired.
Implementation note: the actual argument list to the accept method is
(type-key parameters options type stream view &key default default-type)
| describe-presentation-type | type stream plural-count | [Presentation Method] |
Implementation note: the actual argument list to the
describe-presentation-type method is
(type-key parameters options type stream plural-count)
| presentation-type-specifier-p | type | [Presentation Method] |
Implementation note: the actual argument list to the
presentation-type-specifier-p method is
(type-key parameters options type)
| presentation-typep | object type | [Presentation Method] |
Implementation note: the actual argument list to the presentation-typep method is
(type-key parameters object type)
| presentation-subtypep | type putative-supertype | [Presentation Method] |
Unlike all other presentation methods, presentation-subtypep receives a type argument that has been translated to the presentation type for which the method is specialized; type is never a subtype. The method is only called if putative-supertype has parameters and the two presentation type specifiers do not have equal parameters. The method must return the two values that presentation-subtypep returns.
Since presentation-subtypep takes two type arguments, the parameters are not lexically available as variables in the body of a presentation method.
Implementation note: the actual argument list to the
presentation-subtypep method is
(type-key type putative-supertype)
| map-over-presentation-type-supertypes | function type | [Presentation Method] |
Implementation note: the actual argument list to the
map-over-presentation-type-supertypes method is
(type-class function type)
| accept-present-default | type stream view default default-supplied-p present-p query-identifier | [Presentation Method] |
The boolean default-supplied-p will be true only in the case when the :default option was explicitly supplied in the call to accept that invoked accept-present-default .
Implementation note: the actual argument list to the
accept-present-default method is
(type-key parameters options type stream view default default-supplied-p present-p query-identifier)
| presentation-type-history | type | [Presentation Method] |
Implementation note: the actual argument list to the
presentation-type-history method is
(type-key parameters type)
| presentation-default-preprocessor | default type &key default-type | [Presentation Method] |
Implementation note: the actual argument list to the
presentation-default-preprocessor method is
(type-key parameters default type &key default-type)
| presentation-refined-position-test | type record x y | [Presentation Method] |
Implementation note: the actual argument list to the
presentation-refined-position-test method is
(type-key parameters options type record x y)
| highlight-presentation | type record stream state | [Presentation Method] |
Implementation note: the actual argument list to the
highlight-presentation method is
(type-key parameters options type record stream state) 23.3.4 Presentation Type Functions
| describe-presentation-type | type &optional stream plural-count | [Function] |
type can be a presentation type abbreviation.
| presentation-type-parameters | type-name &optional env | [Function] |
| presentation-type-options | type-name &optional env | [Function] |
| with-presentation-type-decoded | (name-var &optional parameters-var options-var) type &body body | [Macro] |
The name-var , parameters-var , and options-var arguments are not evaluated. body may have zero or more declarations as its first forms.
| presentation-type-name | type | [Function] |
(defun presentation-type-name (type)
(with-presentation-type-decoded (name) type
name))
| with-presentation-type-parameters | (type-name type) &body body | [Macro] |
The value of the form type must be a presentation type specifier whose name is type-name . The type-name and type arguments are not evaluated. body may have zero or more declarations as its first forms.
| with-presentation-type-options | (type-name type) &body body | [Macro] |
The value of the form type must be a presentation type specifier whose name is type-name . The type-name and type arguments are not evaluated. body may have zero or more declarations as its first forms.
| presentation-type-specifier-p | object | [Function] |
| presentation-typep | object type | [Function] |
type may not be a presentation type abbreviation.
This is analogous to the Common Lisp typep function.
| presentation-type-of | object | [Function] |
If presentation-type-of cannot determine the presentation type of the object, it may return either expression or t .
This is analogous to the Common Lisp typep function.
| presentation-subtypep | type putative-supertype | [Function] |
type may not be a presentation type abbreviation.
This is analogous to the Common Lisp subtypep function.
| map-over-presentation-type-supertypes | function type | [Function] |
| presentation-type-direct-supertypes | type | [Function] |
| find-presentation-type-class | name &optional (errorp t ) environment | [Function] |
| class-presentation-type-name | class &optional environment | [Function] |
| default-describe-presentation-type | description stream plural-count | [Function] |
| make-presentation-type-specifier | type-name-and-parameters &rest options | [Function] |
23.4 Typed Output
An application can specify that all output done within a certain dynamic extent
should be associated with a given Lisp object and be declared to be of a
specified presentation type. The resulting output is saved in the window's
output history as a presentation. Specifically, the presentation remembers the
output that was performed (by saving the associated output record), the Lisp
object associated with the output, and the presentation type specified at output
time. The object can be any Lisp object.
| with-output-as-presentation | (stream object type &key modifier single-box allow-sensitive-inferiors parent record-type &allow-other-keys ) &body body | [Macro] |
The stream argument is not evaluated, and must be a symbol that is bound to an extended output stream or output recording stream. If stream is t , *standard-output* is used. body may have zero or more declarations as its first forms.
type may be a presentation type abbreviation.
modifier , which defaults to nil , is some sort of object that describes how the presentation object might be modified. For example, it might be a function of one argument (the new value) that can be called in order to store a new value for object after a user somehow ``edits'' the presentation. modifier must have indefinite extent.
single-box is used to specify the presentation-single-box component of the resulting presentation. It can take on the values described under presentation-single-box .
When the boolean allow-sensitive-inferiors is false , nested calls to present or with-output-as-presentation inside this one will not generate presentations. The default is true .
parent specifies what output record should serve as the parent for the newly created presentation. If unspecified, stream-current-output-record of stream will be used as the parent.
record-type specifies the class of the presentation output record to be created. It defaults to standard-presentation . This argument should only be supplied by a programmer if there is a new class of output record that supports the updating output record protocol.
All arguments of this macro are evaluated.
For example,
(with-output-as-presentation (stream #p"foo" 'pathname) (princ "FOO" stream))
| present | object &optional type &key stream view modifier acceptably for-context-type single-box allow-sensitive-inferiors sensitive record-type | [Function] |
The returned value of present is the presentation object that contains the output corresponding to the object.
present must be implemented by first expanding any presentation type abbreviations (type and for-context-type ), and then calling stream-present on stream , object , type , and the remaining keyword arguments, which are described below.
| stream-present | stream object type &key view modifier acceptably for-context-type single-box allow-sensitive-inferiors sensitive record-type | [Generic function] |
The object object of type type is presented to the stream stream by calling the type's present method for the supplied view view . The returned value is the presentation containing the output corresponding to the object.
type is a presentation type specifier. view is a view object that defaults to stream-default-view of stream .
for-context-type is a presentation type specifier that is passed to the present method for type , which can use it to tailor how the object will be presented. for-context-type defaults to type .
modifier , single-box , allow-sensitive-inferiors , and record-type are the same as for with-output-as-presentation .
acceptably defaults to nil , which requests the present method to produce text designed to be read by human beings. If acceptably is t , it requests the present method to produce text that is recognized by the accept method for for-context-type . This makes no difference to most presentation types.
The boolean sensitive defaults to true . If it is false , no presentation is produced.
| present-to-string | object &optional type &key view acceptably for-context-type string index | [Function] |
The first returned value is the string. When string is supplied, a second value is returned, the updated index .
23.5 Context-dependent (Typed) Input
Associating semantics with output is only half of the user interface equation.
The presentation type system also supports the input side of the user
interaction. When an application wishes to solicit from the user input of a
particular presentation type, it establishes an input context for that
type. CLIM will then automatically allow the user to satisfy the input request
by pointing at a visible presentation of the requested type (or a valid subtype)
and pressing a pointer button. Only the presentations that ``match'' the input
context will be ``sensitive'' (that is, highlighted when the pointer is moved
over them) and accepted as input, thus the presentation-based input mechanism
supports context-dependent input .
| *input-context* | [Variable] |
The exact format of the elements in the list is unspecified, but will typically be a list of a presentation type and a tag that corresponds to the point in the control structure of CLIM at which the input context was establish. *input-context* and the elements in it may have dynamic extent.
| input-context-type | context-entry | [Function] |
| with-input-context | (type &key override) (&optional object-var type-var event-var options-var) form &body pointer-cases | [Macro] |
type can be a presentation type abbreviation.
After establishing the new input context, form is evaluated. If no pointer gestures are made by the user during the evaluation of form , the values of form are returned. Otherwise, one of the pointer-cases is executed (based on the presentation type of the object that was clicked on) and the value of that is returned. (See the descriptions of call-presentation-menu and throw-highlighted-presentation .) pointer-cases is constructed like a typecase statement clause list whose keys are presentation types; the first clause whose key satisfies the condition (presentation-subtypep type key ) is the one that is chosen.
During the execution of one of the pointer-cases , object-var is bound to the object that was clicked on (the first returned value from the presentation translator that was invoked), type-var is bound to its presentation type (the second returned value from the translator), and event-var is bound to the pointer button event that was used. options-var is bound to any options that a presentation translator might have returned (the third value from the translator), and will be either nil or a list of keyword-value pairs. object-var , type-var , event-var , and options-var must all be symbols.
type , stream , and override are evaluated, the others are not.
For example,
(with-input-context ('pathname)
(path)
(read)
(pathname
(format t "~&The pathname ~A was clicked on." path)))
| accept | type &key stream view default default-type provide-default insert-default replace-input history active-p prompt prompt-mode display-default query-identifier activation-gestures additional-activation-gestures delimiter-gestures additional-delimiter-gestures | [Function] |
accept must be implemented by first expanding any presentation type abbreviations (type , default-type , and history ), handling the interactions between the default, default type, and presentation history, prompting the user by calling prompt-for-accept , and then calling stream-accept on stream , type , and the remaining keyword arguments.
| stream-accept | stream type &key view default default-type provide-default insert-default replace-input history active-p prompt prompt-mode display-default query-identifier activation-gestures additional-activation-gestures delimiter-gestures additional-delimiter-gestures | [Generic function] |
The arguments and overall behavior of stream-accept are as for accept-1 .
Rationale: the reason accept is specified as a three-function ``trampoline'' is to allow close tailoring of the behavior of accept . accept itself is the function that should be called by application programmers. CLIM implementors will specialize stream-accept on a per-stream basis. (For example, the behavior of accepting-values can be implemented by creating a special class of stream that turns calls to accept into fields of a dialog.) accept-1 is provided as a convenient function for the stream-accept methods to call when they require the default behavior.
| accept-1 | stream type &key view default default-type provide-default insert-default replace-input history active-p prompt prompt-mode display-default query-identifier activation-gestures additional-activation-gestures delimiter-gestures additional-delimiter-gestures | [Function] |
accept-1 establishes an input context via with-input-context , and then calls the accept presentation method for type and view . When called on an interactive stream, accept must allow input editing; see Chapter Input Editing and Completion Facilities for a discussion of input editing. The call to accept will be terminated when the accept method returns, or the user clicks on a sensitive presentation. The typing of an activation and delimiter character is typically one way in which a call to an accept method is terminated.
A top-level accept satisfied by keyboard input discards the terminating keyboard gesture (which will be either a delimiter or an activation gesture). A nested call to accept leaves the terminating gesture unread.
If the user clicked on a matching presentation, accept-1 will insert the object into the input buffer by calling presentation-replace-input on the object and type returned by the presentation translator, unless either the boolean replace-input is false or the presentation translator returned an :echo option of false . replace-input defaults to true , but this default is overridden by the translator explicitly returning an :echo option of false .
If default is supplied, then it and default-type are returned as values from accept-1 when the input is empty. default-type must be a presentation type specifier. If default is not supplied and provide-default is true (the default is false ), then the default is determined by taking the most recent item from the presentation type history specified by history . If insert-default is true and there is a default, the default will be inserted into the input stream by calling presentation-replace-input .
history must be either nil , meaning that no presentation type history will be used, or a presentation type (or abbreviation) that names a history to be used for the call to accept . history defaults to type .
prompt can be t , which prompts by describing the type, nil , which suppresses prompting, or a string, which is displayed as a prompt (via write-string ). The default is t , which produces ``Enter a type :'' in a top-level call to accept or ``(type )'' in a nested call to accept .
If the boolean display-default is true , the default is displayed (if one was supplied). If display-default is false , the default is not displayed. display-default defaults to true if prompt was provided, otherwise it defaults to false .
prompt-mode can be :normal (the default) or :raw , which suppresses putting a colon after the prompt and/or default in a top-level accept and suppresses putting parentheses around the prompt and/or default in a nested accept .
query-identifier is used within accepting-values to identify the field within the dialog. The active-p argument (which defaults to t ) can be used to control whether a field within an accepting-values is active; when false , the field will not be active, that is, it will not be available for input. Some CLIM implementations will provide a visual cue that the field is inactive, for instance, by ``graying out'' the field.
activation-gestures is a list of gesture names that will override the current activation gestures (which are stored in *activation-gestures* ). Alternatively, additional-activation-gestures can be supplied to add activation gestures without overriding the current ones. See Chapter Input Editing and Completion Facilities for a discussion of activation gestures.
delimiter-gestures is a list of gesture names that will override the current delimiter gestures (which are stored in *delimiter-gestures* ). Alternatively, additional-delimiter-gestures can be supplied to add delimiter gestures without overriding the current ones. See Chapter Input Editing and Completion Facilities for a discussion of delimiter gestures.
| accept-from-string | type string &key view default default-type start end | [Function] |
accept-from-string returns an object and a presentation type (as in accept ), but also returns a third value, the index at which input terminated.
| prompt-for-accept | stream type view &rest accept-args &key | [Generic function] |
| prompt-for-accept-1 | stream type &key default default-type display-default prompt prompt-mode &allow-other-keys | [Function] |
If the boolean display-default is true , then the default is displayed; otherwise, the default is not displayed. When the default is being displayed, default and default-type are the taken as the object and presentation type of the default to display. display-default defaults to true if prompt is non-nil , otherwise it defaults to false .
If prompt is nil , no prompt is displayed. If it is a string, that string is displayed as the prompt. If prompt is t (the default), the prompt is generated by calling describe-presentation-type to produce a prompt of the form ``Enter a type :'' in a top-level call to accept , or ``(type )'' in a nested call to accept .
prompt-mode can be :normal (the default) or :raw , which suppresses putting a colon after the prompt and/or default in a top-level accept and suppresses putting parentheses around the prompt and/or default in a nested accept .
23.6 Views
accept and present methods can specialize on the view argument
in order to define more than one view of the data. For example, a spreadsheet
program might define a presentation type for quarterly earnings, which can be
displayed as a floating point number or as a bar of some length in a bar graph.
These two views might be implemented by specializing the view arguments for the
textual-view class and the user-defined bar-graph-view class.
| view | [Protocol Class] |
| viewp | object | [Predicate] |
| textual-view | [Class] |
| textual-menu-view | [Class] |
| textual-dialog-view | [Class] |
| gadget-view | [Class] |
| gadget-menu-view | [Class] |
| gadget-dialog-view | [Class] |
| pointer-documentation-view | [Class] |
| +textual-view+ | [Constant] |
| +textual-menu-view+ | [Constant] |
| +textual-dialog-view+ | [Constant] |
| +gadget-view+ | [Constant] |
| +gadget-menu-view+ | [Constant] |
| +gadget-dialog-view+ | [Constant] |
| +pointer-documentation-view+ | [Constant] |
| stream-default-view | stream | [Generic function] |
| (setf stream-default-view) | view stream | [Generic function] |
23.7 Presentation Translators
CLIM provides a mechanism for translating between types. In other
words, within an input context for presentation type A the translator
mechanism allows a programmer to define a translation from presentations of some
other type B to objects that are of type A.
Note that the exact representation of a presentation translator has been left explicitly unspecified.
23.7.1 Defining Presentation Translators
| define-presentation-translator | name (from-type to-type command-table &key gesture tester tester-definitive documentation pointer-documentation menu priority) arglist &body body | [Macro] |
command-table is a command table designator . The translator created by this invocation of define-presentation-translator will be stored in the command table command-table .
gesture is a gesture name that names a pointer gesture (described in Section Gestures and Gesture Names ). The body of the translator will be run only if the translator is applicable and gesture used by the user matches the gesture name in the translator. (We will explain applicability , or matching , in detail below.) gesture defaults to :select .
tester is either a function or a list of the form
(tester-arglist . tester-body)
where tester-arglist takes the same form as arglist (see below), and
tester-body is the body of the tester. The tester must return either
true or false . If it returns false , then the translator is
definitely not applicable. If it returns true , then the translator might
be applicable, and the body of the translator might be run (if
tester-definitive is false ) in order to definitively decide if the
translator is applicable (this is described in more detail below). If no tester
is supplied, CLIM supplies a tester that always returns true .
When the boolean tester-definitive is true , the body of the translator will never be run in order to decide if the translator is applicable, that is, the tester is assumed to definitively decide whether the translator applies. The default for tester-definitive is false . When there is no explicitly supplied tester, the tester supplied by CLIM is assumed to be definitive.
Both documentation and pointer-documentation are objects that will
be used for documenting the translator. pointer-documentation will be
used to generate documentation for the pointer documentation window; the
documentation generated by pointer-documentation should be very brief and
computing it should be very fast and preferably not cons. documentation is used to generate such things as items in the :menu -gesture menu. If the
object is a string, the string itself will be used as the documentation.
Otherwise, the object must be the name of a function or a list of the form
(doc-arglist . doc-body)
where doc-arglist takes the same form as arglist , but includes a
named (keyword) stream argument as well (see below), and doc-body is the body of the documentation function. The body of the documentation
function should write the documentation to stream . The default for
documentation is nil , meaning that there is no explicitly supplied
documentation; in this case, CLIM is free to generate the documentation in
other ways. The default for pointer-documentation is documentation .
menu must be t or nil . When it is t , the translator will be included in the :menu -gesture menu if it matches. When it is nil , the translator will not be included in the :menu -gesture menu. Other non-nil values are reserved for future extensions to allow multiple presentation translator menus.
priority is either nil (the default, which corresponds to 0) or an integer that represents the priority of the translator. When there are several translators that match for the same gesture, the one with the highest priority is chosen.
arglist , tester-arglist , and doc-arglist are each an argument
list that must ``match'' the following ``canonical'' argument list.
(object &key presentation context-type frame event window x y)
In order to ``match'' the canonical argument list, there must be a single
positional argument that corresponds to the presentation's object, and
several named arguments that must match the canonical names above (using
string-equal to do the comparison).
In the body of the translator (or the tester), the positional object argument will be bound to the presentation's object. The named arguments presentation will be bound to the presentation that was clicked on, context-type will be bound to the presentation type of the context that actually matched, frame will be bound to the application frame that is currently active (usually *application-frame* ), event will be bound to the pointer button event that the user used, window will be bound to the window stream from which the event came, and x and y will be bound to the x and y positions within window that the pointer was at when the event occurred. The special variable *input-context* will be bound to the current input context. Note that, in many implementations context-type and *input-context* will have dynamic extent, so programmers should not store without first copying them.
body is the body of the translator, and is run in the context of the application. body may have zero or more declarations as its first forms. It should return either one, two, or three values. The first value is an object which must be presentation-typep of to-type , and the second value is a presentation type that must be presentation-subtypep of to-type . The consequences are unspecified if the object is not presentation-typep of to-type or the type is not presentation-subtypep of to-type . The first two returned values of body are used, in effect, as the returned values for the call to accept that established the matching input context.
The third value returned by body must either be nil or a list of options (as keyword-value pairs) that will be interpreted by accept . The only option defined so far is :echo , whose value must be either true (the default) or false . If it is true , the object returned by the translator will be ``echoed'' by accept , which will use presentation-replace-input to insert the textual representation of the object into the input buffer. If it is false , the object will not be echoed.
None of define-presentation-translator 's arguments is evaluated.
| define-presentation-to-command-translator | name (from-type command-name command-table &key gesture tester documentation pointer-documentation menu priority echo) arglist &body body | [Macro] |
The echo option is a boolean value (the default is true ) that indicates whether the command line should be echoed when a user invokes the translator.
The other arguments to define-presentation-to-command-translator are the same as for define-presentation-translator . Note that the tester for command translators is always assumed to be definitive, so there is no :tester-definitive option. The default for pointer-documentation is the string command-name with dash characters replaced by spaces, and each word capitalized (as in add-command-to-command-table ).
The body of the translator must return a list of the arguments to the command named by command-name . body is run in the context of the application. The returned value of the body, appended to the command name, are eventually passed to execute-frame-command . body may have zero or more declarations as its first forms.
None of define-presentation-to-command-translator 's arguments is evaluated.
| define-presentation-action | name (from-type to-type command-table &key gesture tester documentation pointer-documentation menu priority) arglist &body body | [Macro] |
A presentation action does not satisfy a request for input the way an ordinary translator does. Instead, an action is something that happens while waiting for input. After the action has been executed, the program continues to wait for the same input that it was waiting for prior to executing the action.
The other arguments to define-presentation-action are the same as for define-presentation-translator . Note that the tester for presentation actions is always assumed to be definitive.
None of define-presentation-action 's arguments is evaluated.
| define-drag-and-drop-translator | name (from-type to-type destination-type command-table &key gesture tester documentation pointer-documentation menu priority feedback highlighting) arglist &body body | [Macro] |
The interaction style used by these translators is that a user points to a ``from presentation'' with the pointer, picks it up by pressing a pointer button matching gesture , drags the ``from presentation'' to a ``to presentation'' by moving the pointer, and then drops the ``from presentation'' onto the ``to presentation''. The dropping might be accomplished by either releasing the pointer button or clicking again, depending on the frame manager. When the pointer button is released, the translator whose destination-type matches the presentation type of the ``to presentation'' is chosen. For example, dragging a file to the TrashCan on a Macintosh could be implemented by a drag and drop translator.
While the pointer is being dragged, the function specified by feedback is invoked to provide feedback to the user. The function is called with eight arguments: the application frame object, the ``from presentation'', the stream, the initial x and y positions of the pointer, the current x and y positions of the pointer, and a feedback state (either :highlight to draw feedback, or :unhighlight to erase it). The feedback function is called to draw some feedback the first time pointer moves, and is then called twice each time the pointer moves thereafter (once to erase the previous feedback, and then to draw the new feedback). It is called a final time to erase the last feedback when the pointer button is released. feedback defaults to frame-drag-and-drop-feedback .
When the ``from presentation'' is dragged over any other presentation that has a direct manipulation translator, the function specified by highlighting is invoked to highlight that object. The function is called with four arguments: the application frame object, the ``to presentation'' to be highlighted or unhighlighted, the stream, and a highlighting state (either :highlight or :unhighlight ). highlighting defaults to frame-drag-and-drop-highlighting .
Note that it is possible for there to be more than one drag and drop translator that applies to the same from-type, to-type, and gesture. In this case, the exact translator that is chosen for use during the dragging phase is unspecified. If these translators have different feedback, highlighting, documentation, or pointer documentation, the exact behavior is unspecified.
The other arguments to define-drag-and-drop-translator are the same as for define-presentation-translator .
23.7.2 Presentation Translator Functions
| find-presentation-translators | from-type to-type command-table | [Function] |
Implementation note: Because find-presentation-translators is called during pointer sensitivity computations (that is, whenever the user mouses the pointer around in any CLIM pane), it should cache its result in order to avoid consing. Therefore, the resulting list of translators should not be modified; the consequences of doing so are unspecified.
Implementation note: The ordering of the list of translators is left unspecified, but implementations may find it convenient to return the list using the ordering specified for find-applicable-translators .
| test-presentation-translator | translator presentation context-type frame window x y &key event modifier-state for-menu | [Function] |
event and modifier-state are a pointer button event and modifier state (see event-modifier-key-state ), and are compared against the translator's gesture. event defaults to nil , and modifier-state defaults to 0, meaning that no modifier keys are held down. Only one of event or modifier-state may be supplied; it is unspecified what will happen if both are supplied.
If for-menu is true , the comparison against event and modifier-state is not done.
presentation , context-type , frame , window , x , y , and event are passed along to the translator's tester if and when the tester is called.
test-presentation-translator is responsible for matching type parameters and calling the translator's tester. Under some circumstances, test-presentation-translator may also call the body of the translator to ensure that its value matches to-type .
| find-applicable-translators | presentation input-context frame window x y &key event modifier-state for-menu fastp | [Function] |
Since input contexts can be nested, find-applicable-translators must iterate over all the contexts in input-context . window , x , and y are as for test-presentation-translator . event and modifier-state (which default to nil and the current modifier state for window , respectively) are used to further restrict the set of applicable translators. (Only one of event or modifier-state may be supplied; it is unspecified what will happen if both are supplied.)
Presentations can also be nested. The ordering of the translators returned by find-applicable-translators is that translators matching inner contexts should precede translators matching outer contexts, and, in the same input context, inner presentations precede outer presentations.
When for-menu is non-nil , this matches the value of for-menu against the presentation's menu specification, and returns only those translators that match. event and modifier-state are disregarded in this case. for-menu defaults to nil .
When the boolean fastp is true , find-applicable-translators will simply return true if there are any translators. fastp defaults to false .
When fastp is false , the list of translators returned by find-applicable-translators must be in order of their ``desirability'', that is, translators having more specific from-types and/or higher priorities must precede translators having less specific from-types and lower priorities.
The rules used for ordering the translators returned by find-applicable-translators are as follows (in order):
Translators with a more specific ``from type'' precede translators with a less specific ``from type''.
Translators with a higher ``low order'' priority precede translators with a lower ``low order'' priority. This allows programmers to break ties between translators that translate from the same type.
Translators from the current command table precede translators inherited from superior command tables.
| presentation-matches-context-type | presentation context-type frame window x y &key event modifier-state | [Function] |
If there are no applicable translators, presentation-matches-context-type will return false .
| call-presentation-translator | translator presentation context-type frame event window x y | [Function] |
The returned values are the same as the values returned by the body of the translator, namely, the translated object and the translated type.
| document-presentation-translator | translator presentation context-type frame event window x y &key (stream *standard-output* ) documentation-type | [Function] |
documentation-type must be either :normal or :pointer . If it is :normal , the usual translator documentation function is called. If it is :pointer , the translator's pointer documentation is called.
| call-presentation-menu | presentation input-context frame window x y &key for-menu label | [Function] |
window , x , y , and event are as for find-applicable-translators . for-menu , which defaults to t , is used to decide which of the applicable translators will go into the menu; only those translators whose :menu option matches menu will be included.
label is either a string to use as a label for the menu, or is nil (the default), meaning the menu will not be labelled.
23.7.3 Finding Applicable Presentations
| find-innermost-applicable-presentation | input-context window x y &key frame modifier-state event | [Function] |
event and modifier-state are a pointer button event and modifier state (see event-modifier-key-state ). event defaults to nil , and modifier-state defaults to the current modifier state for window . Only one of event or modifier-state may be supplied; it is unspecified what will happen if both are supplied.
frame defaults to the current frame, *application-frame* .
The default method for frame-find-innermost-applicable-presentation will call this function.
| throw-highlighted-presentation | presentation input-context button-press-event | [Function] |
Note that it is possible that more than one translator having the same gesture may be applicable to presentation in the specified input context. In this case, the translator having the highest priority will be chosen. If there is more than one having the same priority, it is unspecified what translator will be chosen.
| highlight-applicable-presentation |