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
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, and the 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 of a gesture and a callback and optional arguments to be passed to the callback. The gesture itself is a list specifying the type of gesture, which can be a button, key, character or motion gesture, along with optional arguments specifying keyboard modifiers ( :shift
, :control
and :meta
) and actions associated with the gesture ( :press
, :release
, :second-press
and :motion
). These options can be specified in any order, and if the list is only one item long then the gesture can be specified as just the item itself.
A button gesture should contain the button in question (either :button-1
, :button-2
or :button-3
) along with an optional action (one of :press
, :release
, :second-press
or :motion
) and zero or more keyboard modifiers.
A key 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.
A character gesture is a simple gesture, and can be either the character to be checked for, or the keyword :character
meaning any character.
Finally, a motion gesture can either be defined in terms of dragging a button (in which case it is defined as a button gesture with the action :motion
), or it can be defined for motions whilst no button is down by just specifying the keyword :motion
with no additional arguments.
An input-model
also accepts a command instead of a gesture, where a command is defined using define-command
, and provides an alias for a gesture.
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 the output pane is scrolled, the CAPI calls the scroll-callback
. The arguments of the scroll callback are the output-pane,
the direction ( :vertical
or :horizontal
), 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
. See the following CAPI example files:
output-panes/scroll-test.lisp
output-panes/scrolling-without-bar.lisp
graphics/scrolling-test.lisp
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)
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)
Finally, here is an example showing how to use the motion gesture.
(capi:contain (make-instance
'capi:output-pane
:title "Drag button-1 across this pane:"
:input-model '(((:motion :button-1)
gp:draw-point)))
:best-width 200 :best-height 200)