All Manuals > CAPI User Guide and Reference Manual > 21 CAPI Reference Entries

output-pane Class

Summary

An output pane is a pane whose display and input behavior can be controlled by the programmer.

Package

capi

Superclasses

titled-object
simple-pane
graphics-port-mixin

Subclasses

pinboard-layout
editor-pane

Initargs
:display-callback
A function called to redisplay the pane.
:drawing-mode
A keyword controlling quality of drawing, especially anti-aliasing of text.
:graphics-options
A platform-specific plist of options controlling how graphics are drawn.
:draw-with-buffer
A boolean controlling whether output is buffered, on Microsoft Windows and Motif.
:input-model
A list of input specifications, otherwise known as a command table.
:scroll-callback
A function called when the pane is scrolled, or nil. The default is nil.
:coordinate-origin
Either :scrolled, :fixed or :fixed-graphics.
:focus-callback
A function called when the pane gets or loses the input focus, or nil. The default is nil.
:resize-callback
A function called when the pane is resized, or nil. The default is nil.
:create-callback
A function called just after the pane is created.
:destroy-callback
A function called just before the pane is destroyed.
:use-native-input-method
Controls whether to use native input method to interpret keyboard input. Currently this has an effect only on GTK+.
:composition-callback
This is called for various events related to composition, which here means composing input characters into other characters by an input method.
Accessors

output-pane-display-callback
output-pane-focus-callback
output-pane-resize-callback
output-pane-scroll-callback
output-pane-create-callback
output-pane-destroy-callback
output-pane-composition-callback
output-pane-input-model

Readers

output-pane-graphics-options
output-pane-coordinate-origin

Description

The class output-pane is a subclass of gp:graphics-port-mixin which means that it supports the graphics ports drawing operations such as draw-image, draw-string and draw-path.

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 Ports functions to redisplay that area. To force an area to be re-displayed, use the function invalidate-rectangle.

Note: if you need to temporarily prevent the display-callback from running, for example because it is slow, then use the Cached Display interface so that the pane still redraws. See output-pane-cache-display for the details.

drawing-mode should be either :compatible which causes drawing to be the same as in LispWorks 6.0, or :quality which causes all the drawing to be transformed properly, and allows control over anti-aliasing on Microsoft Windows and GTK+. The default value of drawing-mode is :quality.

For more information about drawing-mode, see 13.2.1 The drawing mode and anti-aliasing.

graphics-options is currently only used by the macOS Cocoa implementation. The single option defined is :text-rendering, with allowed values:

:glyph
Draw glyphs directly using Core Graphics. This only draws characters with glyphs in the chosen font.
:atsui
Draw using ATSUI APIs where possible.This is slower but can handle more characters.

When draw-with-buffer is true, display of the output-pane (that is drawing the background and calling the display-callback) is done by first drawing to a pixmap buffer, and then drawing from that buffer. This is useful to avoid flickering if the display is complex. The default value of draw-with-buffer is nil.

The input-model provides a means to get callbacks on m ouse 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 (representing keyboard input), character, mouse button (including multiple clicks made in quick succession), modifier change, key, command or cursor motion. On Microsoft Windows and Cocoa gesture can also specify multi-touch gestures that come from trackpad or touchscreen devices, including zoom, rotate, pan and more.

gesture can match specific input such as uppercase A with the Control key pressed, or a general class of input such as any character.

input-model can be set before the pane is displayed, but changes after that are ignored. cl:initialize-instance is the natural place for subclasses to modify the existing input-model, using the output-pane accessor output-pane-input-model. Note that since the mappings are processed in order, prepending to an existing input-model overrides it when there are clashes, while appending affects only gestures for which the original input-model did not have a match.

For all the details of input-model syntax and the precedence and interpretation of the various gesture types, see 12.2.1 Detailed description of the input model.

When coordinate-origin is :scrolled, which is the default, then the CAPI is responsible for scrolling over the scroll range, and the origin for all the coordinates in callbacks and drawing is scrolling when the user scrolls the pane. This is known as ordinary scrolling, and is what you normally use.

When coordinate-origin is :fixed, then the user code is responsible for handling scrolling inside the scroll-callback of the output-pane, and the origin for all coordinates is fixed relative to the top left of the visible area.

When coordinate-origin is :fixed-graphics, the behavior is like :fixed, except that the origin for all CAPI callbacks and function is scrolled (like the ordinary case). Note that in this case, the CAPI coordinates do not match the coordinates used when drawing.

Programming with coordinate-origin :fixed or :fixed-graphics is more complex, but is also much more flexible. See 12.4 output-pane scrolling for full details.

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 macOS Cocoa implementation the direction is always :pan. See the following CAPI example files:

(example-edit-file "capi/output-panes/scrolling-without-bar.lisp")
(example-edit-file "capi/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).

use-native-input-method should be nil, t or :default. If use-native-input-method is not supplied, or is :default, the default is used, which is controlled by set-default-use-native-input-method. The default setting is always to use native input methods.

composition-callback is a function with signature:

composition-callback pane what

where pane is the output pane and what can be one of:

:start
The composition operation is starting.
:end
The composition ends.
A list
A plist describing the "preedit" string, which is a string containing the partial input that should be displayed while the composition is ongoing. These calls with a plist occur only when the underlying system does not display the partial input itself. Currently on Microsoft Windows the system always displays the preedit string itself, so these calls occur only on GTK+ and Cocoa.

During composition there will be repeated calls with a list, in general each time that the preedit string changes. Each call is a complete description of what needs to be displayed. The data from previous calls should be ignored.

The keys that can appear in the plist are currently:

:string-face-lists

The value is a list where each element is itself a list, where the first element is a string and the second a plist describing a face (a face plist). The strings are the strings that need to be displayed, and the face plist describing the face that the underlying GUI thinks that each string needs to be displayed. The face plist may contain any of the following keywords: :foreground, :background, :font, :bold-p, :italic-p, :underline-p. The argument string-face-lists may be nil, which means display nothing.

:cursor
The argument is an integer describing where the "cursor" should be displayed. The index is into the string that is concatenation of the strings in string-face-lists.
:selected-range

If present, the value specifies the selected range as a cons of start and length in characters. The start is an index into the string that is a concatenation of the strings in the string-face-lists.

:selection-needs-face

A boolean specifying whether the selected-range should have a different face to the unselected range.

The editor uses the :start call to position the composition window at the cursor by using set-composition-placement and the calls with a list to display the partial composition string.

Notes
  1. A composition session is initiated and managed by the underlying windowing system (not CAPI) when it is set to use input method which needs to compose characters from several keyboard gestures (mostly input methods for east Asian languages). Keyboard gestures that are used by the composition session are not visible to the application, but some keyboard gestures, typically gestures with modifiers, may be passed through.
  2. When the user commits the composition session, the user callbacks from the input-model are called on each character in the resulting string (as if the user typed each of these characters). The call to composition-callback with :start should typically use set-composition-placement to tell the system where the interaction should happen. The calls to composition-callback with a list do not always happen, the underlying system may do it all itself.
  3. You can stop an ongoing composition session by calling output-pane-stop-composition. That is useful for gestures like mouse clicks that may change the interaction such that it does not make sense to continue the composition.
  4. draw-with-buffer is typically useful for a pinboard-layout with large number of pinboard objects, or any other feature that may cause it to flicker.
  5. The GTK+ and Cocoa libraries always buffer, so draw-with-buffer is ignored on these platforms.
  6. In GTK+ versions before 2.12 the :start and :end calls are not reliable.
Compatibility note

In LispWorks 7.0 and earlier versions, the initarg :pane-can-scroll was used instead of :coordinate-origin. :pane-can-scroll can still be used, but it is deprecated. :pane-can-scroll nil is the same as :coordinate-origin :scrolled. :pane-can-scroll t is the same as :coordinate-origin :fixed-graphics. There was no documented equivalent to :coordinate-origin :fixed.

Examples

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)))

This example illustrates some effects of drawing-mode:

(example-edit-file "capi/graphics/catherine-wheel")

This example shows how to draw a rectangle indicating selection of objects in response to mouse movement:

(example-edit-file "capi/graphics/highlight-rectangle")

This example illustrate drawing the results of dynamic computation:

(example-edit-file "capi/graphics/plot-offline") 

There are further examples here:

(example-edit-file "capi/output-panes/")

See also 20 Self-contained examples.

See also

define-command
pane-modifiers-state
output-pane-resize
output-pane-stop-composition
pinboard-object
scroll
set-default-use-native-input-method
set-composition-placement
system:gesture-spec
3.12 Tooltips
7 Programming with CAPI Windows
8.12 Popup menus for panes
12 Creating Panes with Your Own Drawing and Input
13 Drawing - Graphics Ports
12.4 output-pane scrolling
16 Printing from the CAPIā€”the Hardcopy API
17 Drag and Drop


CAPI User Guide and Reference Manual (Macintosh version) - 01 Dec 2021 19:31:27