




An output pane is a pane whose display and input behavior can be controlled by the programmer.
titled-object
simple-pane
gp:graphics-port-mixin
A function that knows how to redisplay the pane.
A list of input specifications, otherwise known as a command table.
A function called when the pane is scrolled, or 
nil
. The default is 
nil
.
A generalized boolean specifying whether the pane itself is responsible for drawing into the visible area.
A function called when the pane gets or loses the input focus, or 
nil
. The default is 
nil
.
A function called when the pane is resized, or 
nil
. The default is 
nil
.
A function called just after the pane is created.
A function called just before the pane is destroyed.
A platform-specific plist of options controlling how graphics are drawn.
output-pane-display-callback
output-pane-focus-callback
output-pane-resize-callback
output-pane-scroll-callback
output-pane-create-callback
output-pane-destroy-callback
The class 
output-pane
 is a subclass of 
gp:graphics-port-mixin
 which means that it supports many of the graphics ports drawing operations. When the CAPI needs to redisplay a region of the output pane, the 
display-callback
 gets called with the 
output-pane
 and the 
x
, 
y
, 
width
 and 
height
 of the region that needs redrawing. The 
display-callback
 should then use graphics port operations to redisplay that area. To force an area to be re-displayed, use the function invalidate-rectangle. 
The input-model provides a means to get callbacks on mouse and keyboard gestures. An input-model is a list of mappings from gesture to callback, where each mapping is a list
(
gesture
 
callback
 . 
extra-callback-args
)
gesture specifies the type of gesture, which can be gesture spec, character, button, key, command or motion.
In a gesture spec mapping, 
gesture
 can be simply the keyword 
:gesture-spec
, which matches any keyboard input. For specific mappings, 
gesture
 is a list
(:gesture-spec data [modifier]* )
in which 
data
 is a character object or an integer between 0 and 
char-code-limit
 (interpreted as the character object obtained by 
code-char
), or a keyword naming a function key, and each 
modifier
 is one of the keywords 
:shift
, 
:control
 and 
:meta
. Note that the 
:meta
 modifier is received only when the keys style is 
:emacs
 (see interface-keys-style). On Cocoa, the 
modifier
 value 
:hyper
 is interpreted as the 
Command
 key for mouse input (though note that 
Command
 is reserved for menu accelerators in interfaces). So to match the mouse gesture 
Command+Click
 you would use:
(:button-1 :press :hyper)
as the gesture in the mapping.
Also 
data
 can be a string which is interpreted as a gesture spec as if by 
sys:coerce-to-gesture-spec
. See the 
LispWorks Reference Manual
 for a description of this and other functions for manipulating gesture spec objects.
In a character mapping, 
gesture
 can be simply the keyword 
:character
, which matches any character input. For specific mappings, 
gesture
 can be a list containing a single character object 
char
, or a list
Note: where input would match both a gesture spec mapping and a character mapping, the gesture spec mapping takes precedence.
In a button mapping, gesture should be list
( button action [modifiers]* )
where 
button
 is one of 
:button-1
, 
:button-2
 or 
:button-3
 denoting the mouse buttons. 
action
 is one of 
:press
, 
:release
, 
:second-press
, 
:third-press
, 
:nth-press
 and 
:motion
, and each 
modifier
 is one of the keywords 
:shift
, 
:control
 and 
:meta
. However, 
:meta
 gestures are not generated in non-IDE windows on Cocoa.
:third-press
 and 
:nth-press
 are supported only on Cocoa and Motif.
In a key mapping, 
gesture
 should contain the key in question (or the keyword 
:key
 meaning any key) along with an optional action (one of 
:press
 or 
:release
) and zero or more keyboard modifiers. 
In a motion mapping, 
gesture
 can either be defined in terms of dragging a button (in which case it is defined as a button gesture with 
action
 
:motion
), or it can be defined for motions whilst no button is down by just specifying the keyword 
:motion
 with no additional arguments. 
In a command mapping, gesture should be a command which is defined using define-command, and provides an alias for a gesture. The following commands are predefined:
(:button-3 :release)
 on Microsoft Windows.
(:button-1 :press :control)
 on Mac OS X.
(:button-3 :press :control)
 on Microsoft Windows, Motif and Mac OS X.
(:gesture-spec :f10 :shift)
 on Microsoft Windows, Motif and Mac OS X.
Note that it is recommended you follow the style guidelines and conventions of the platform you are developing for when mapping gestures to results.
When user input matches 
gesture
, 
callback
 is called with standard arguments and any 
extra-callback-args
 as extra arguments. The standard arguments are the 
output-pane
, the x cursor position, the y cursor position, and in the case of gesture spec, character or key mappings, the input object that matched.
Button mappings with 
action
 
:press
 are matched on the first button click, and they pass the standard arguments to their 
callback
. Button mappings with 
action
 
:second-press
 and 
:third-press
 are matched on the second and third button click made in quick succession, and again they pass the standard arguments to their 
callback
. Button mappings with 
action
 
:nth-press
 are matched on the 
n
th button click made in quick succession when there is not a more specific match with 
:press
, 
:second-press
 or 
:third-press
. Then the integer 
n
 is also passed as the fourth argument to 
callback
, representing the number of times that the button has been pressed in quick succession. If there is a 
:press
, 
:second-press
 or 
:third-press
 handler then that is invoked instead of 
:nth-press
 for the corresponding number of presses.
Note:
 mouse gestures with 
:press
, 
:second-press
, 
:third-press
 and 
:nth-press
 actions can each be expected to be followed by a 
:release
 action.
Note: In some circumstances 
:motion
 events can be received even when the 
output-pane
 does not have the input focus. See window style 
:motion-events-without-focus
 under interface for details.
If 
pane-can-scroll
 is true then the pane is responsible for handling scrolling, by redrawing. It should draw into the visible area according to the scroll parameters. This is known as internal scrolling and an example is editor-pane. If 
pane-can-scroll
 is 
nil
, then the CAPI is responsible for scrolling over the data range. The default value is 
nil
. This is known as ordinary scrolling and there is an example in 
output-panes/scroll-test.lisp
.
When the output pane is scrolled, the CAPI calls the 
scroll-callback
 if this is non-
nil
. The arguments of the scroll callback are the 
output-pane,
 the direction (
:vertical
, 
:horizontal
 or 
:pan
), the scroll operation (
:move
, 
:drag
, 
:step
 or 
:page
), the amount of scrolling (an integer), and a keyword argument 
:interactive
. This has value 
t
 if the scroll was invoked interactively, and value 
nil
 if the scroll was programmatic, such as via the function scroll. In the Mac OS X Cocoa implementation the direction is always 
:pan
. See the following CAPI example files:
output-panes/scroll-test.lisp
output-panes/scrolling-without-bar.lisp
graphics/scrolling-test.lisp
focus-callback
, if non-
nil
, is a function of two arguments. The first argument is the 
output-pane
 itself, and the second is a boolean. When the 
output-pane
 gets the focus, 
focus-callback
 is called with second argument 
t
, and when the 
output-pane
 loses the focus, 
focus-callback
 is called with second argument 
nil
.
resize-callback
, if non-
nil
, is a function of five arguments called when the 
output-pane
 is resized. The first argument is the 
output-pane
 itself, and the rest are its new geometry: 
x
, 
y
, 
width
 and 
height
.
create-callback
, if non-
nil
, is a function of one argument which is called just after the pane is created (but before it becomes visible). The argument is the pane itself. This function can perform initialization such as loading images.
destroy-callback
, if non-
nil
, is a function of one argument which is called just before the pane is destroyed, for example when the window is closed or the pane is removed from its layout. The argument is the pane itself. This function can perform cleanup operations (though note that images associated with the pane are automatically freed).
graphics-options
 is currently only used by the Mac OS X Cocoa implementation. The single option defined is 
:text-rendering
, with allowed values:
Draw glyphs directly using Core Graphics. This only draws characters with glyphs in the chosen font.
Draw using ATSUI APIs where possible.This is slower but can handle more characters.
Firstly, here is an example that draws a circle in an output pane.
(defun display-circle (self x y width height)
(declare (ignore x y width height))
(gp:draw-circle self 200 200 200 :filled t))
(capi:contain (make-instance
'capi:output-pane
:display-callback 'display-circle)
:best-width 200 :best-height 200)
Here is an example that shows how to use a button gesture.
(defun test-callback (self x y)
(capi:display-message
"Pressed button 1 at (~S,~S) in ~S" x y self))
(capi:contain
(make-instance
'capi:output-pane
:title "Press button 1:"
:input-model `(((:button-1 :press)
test-callback)))
:best-width 200 :best-height 200)
This example illustrates gesture spec mappings.
(defun draw-input (self x y gspec)
(let ((data (sys:gesture-spec-data gspec))
(mods (sys:gesture-spec-modifiers gspec)))
(gp:draw-string
self
(with-output-to-string (ss)
(sys:print-pretty-gesture-spec
gspec ss :force-shift-for-upcase nil))
x y)))
(capi:contain
(make-instance
'capi:output-pane
:title "Press keys in the pane..."
:input-model '((:gesture-spec
draw-input)))
:best-width 200 :best-height 200)
(capi:contain
(make-instance
'capi:output-pane
:title "Press Control-a in the pane..."
:input-model '(((:gesture-spec "Control-a")
draw-input)))
:best-width 200 :best-height 200)
Here is a simple example that draws the character typed at the cursor point.
(defun draw-character (self x y character)
(gp:draw-character self character x y))
(capi:contain
(make-instance
'capi:output-pane
:title "Press keys in the pane..."
:input-model '((:character draw-character)))
:best-width 200 :best-height 200)
This example shows how to use the motion gesture.
(defun draw-red-blob (self x y)
(gp:draw-circle self x y 3
:filled t
:foreground :red))
(capi:contain
(make-instance
'capi:output-pane
:title "Drag button-1 across this pane."
:input-model '(((:button-1 :motion)
gp:draw-point)
((:button-1 :motion :control)
draw-red-blob)))
:best-width 200 :best-height 200)
This example illustrates the use of focus-callback :
(capi:contain
(make-instance
'capi:output-pane
:focus-callback
#'(lambda (x y)
(format t
"Pane ~a ~:[lost~;got~] the focus~%"
x y))))
This example illustrates the use of graphics-options to specify ATSUI drawing on Cocoa:
(defvar *string*
(coerce (loop for i from 0 below 60
collect (code-char (* 5 i)))
'text-string))
(capi:contain
(make-instance 'capi:output-pane
:visible-min-width 400
:visible-max-height 50
:display-callback
#'(lambda (pane x y w h)
(gp:draw-string pane
*string*
10 10))
:graphics-options
'(:text-rendering :atsui)))
There are further examples in the directory 
examples/capi/output-panes/
.