7.1 Organizing panes in columns and rows

You will frequently need to organize a number of different elements in rows and columns. The
column-layout
and
row-layout
elements are provided to make this easy.

The following is a simple example showing the use of
column-layout
.

(contain (make-instance 'column-layout

:description (list

(make-instance 'text-input-pane)

(make-instance 'list-panel

:items '(1 2 3 4 5)))))

Figure 7.1 An example of using
column-layout

Define the following elements:

(setq button1 (make-instance 'push-button

:data "Button 1"

:callback 'test-callback))

(setq button2 (make-instance 'push-button

:data "Button 2"

:callback 'test-callback))

(setq editor (make-instance 'editor-pane

:text "An editor pane"))

(setq message (make-instance 'display-pane

:text "A display pane"))

(setq text (make-instance 'text-input-pane

:title "Text: "

:title-position :left

:callback 'test-callback))

These will be used in the examples throughout the rest of this chapter.

To arrange any number of elements in a column, create a layout using
column-layout
, listing the elements you wish to use. For instance, to display
title
, followed by
text
and
button1
, enter the following into a Listener:

(contain (make-instance 'column-layout

:description

(list text button1)))

Figure 7.2 A number of elements displayed in a column

To arrange the same elements in a row, simply replace
column-layout
in the example above with
row-layout
. If you run this example, close the column layout window first: each CAPI element can only be on the screen once at any time.

Layouts can be given horizontal and vertical scroll bars, if desired; the keywords
:horizontal-scroll and
:vertical-scroll can be set to
t
or
nil
, as necessary.

When creating panes which can be resized (for instance, list panels, editor panes and so on) you can specify the size of each pane relative to the others by listing the proportions of each. This can be done via either the
:y-ratios keyword (for column layouts) or the
:x-ratios keyword (for row layouts).

(contain (make-instance 'column-layout

:description (list

(make-instance 'display-pane)

(make-instance 'editor-pane)

(make-instance 'listener-pane))

:y-ratios '(1 5 3)))

You may need to resize this window in order to see the size of each pane.

Note that the heights of the three panes are in the proportions specified. The
:x-ratios
initarg will adjust the width of panes in a row layout in a similar way.

It is also possible to specify that some panes are fixed at their minimum size whilst others in the same row or column adjust proportionately when the interface is resized:

(contain

(make-instance

'column-layout

:description

(list

(make-instance 'editor-pane

:text "Resizable"

:visible-min-height '(:character 1))

(make-instance 'editor-pane

:text "Fixed"

:visible-min-height '(:character 1))

(make-instance 'editor-pane

:text

(format nil "Resizable~%Resizable~%Resizable")

:visible-min-height '(:character 3)))

:y-ratios '(1 nil 3)

))

To arrange panes in your row or column layout with constant gaps between them, use the
:gap
initarg:

(contain

(make-instance

'column-layout

:description (list

(make-instance 'output-pane

:background :red)

(make-instance 'output-pane

:background :white)

(make-instance 'output-pane

:background :blue))

:gap 20

:title "Try resizing this window vertically"

:background :grey))

To create resizable spaces between panes in your row or column layout, use the special value
nil
in the layout
description
: