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

NextPrevUpTopContentsIndex

define-interface

Macro
Summary

Defines subclasses of interface.

Package

capi

Signature

define-interface name superclasses slots &rest options

Description

The macro define-interface is used to define subclasses of interface, which when created with make-instance has the specified panes, layouts and menus created automatically. The slots and superclasses are used to describe the slots and superclasses of name as in the defclass macro, except that if superclasses is non-nil it must include interface or a subclass of it.

define-interface accepts the same options as defclass, plus the following extra options:

:panes

Descriptions of the interface's panes.

:layouts

Descriptions of the interface's layouts.

:menus

Descriptions of the interface's menus.

:menu-bar

A list of menus for the interface's menu bar.

:definition

Options to alter define-interface.

The class options :panes, :layouts and :menus add extra slots to the class that will contain the CAPI object described in their description. Within the scope of the extra options, the slots themselves are available by referencing the name of the slot, and the interface itself is available with the variable capi:interface. Each of the slots can be made to have readers, writers, accessors or documentation by passing the appropriate defclass keyword as one of the optional arguments in the description. Therefore, if you need to find a pane within an interface instance, you can provide an accessor, or simply use with-slots.

The option :panes is a list of pane descriptions of the following form

(:panes
  (slot-name
 pane-class
 initargs
)
  ...
  (slot-name
 pane-class
 initargs
)
)

where slot-name is a name for the slot, pane-class is the class of the pane being included in the interface, and initargs are the initialization arguments for the pane - the allowed forms are described below.

The option :layouts is a list of layout descriptions of the following form

(:layouts
  (slot-name
 layout-class
 children
 initargs
)
  ...
  (slot-name
 layout-class
 children
 initargs
)
)

where slot-name is a name for the slot, layout-class specifies the type of layout, children is a list of children for the layout, and initargs are the initialization arguments for the layout - the allowed forms are described below. The primary layout for the interface defaults to the first layout described, but can be specified as the :layout initarg to the interface. If no layouts are specified, then the CAPI will place all of the defined panes into a column layout and make that the primary layout.

The option :menus is a list of menu and menu component descriptions of the following form

(:menus
  (slot-name
 title
 descriptions
 initargs
)
  ...
  (slot-name
 title
 descriptions
 initargs
)
)

slot-name is the slot name for each menu or menu component.

title is the menu's title, the keyword :menu, or the keyword :component. For an example showing how you can specify mnemonics for menu titles, see Mnemonics in menus.

descriptions is a list of menu item descriptions. Each menu item description is either a title, a slot name for a menu, or a list of items containing a title, descriptions, and a list of initialization arguments for the menu item. descriptions should nil if you specify the :items-function initarg.

initargs are the initialization arguments for the menu.

The values given in initargs under :panes, :layouts and :menus can be lists of the form

(:initarg keyword-name
)
(:initarg key-spec
)
(:initarg key-spec
 initarg-value
)
 
key-spec
 := var
 | (var
) | (var
 initform
) | ((keyword-name
 var
)) | ((keyword-name
 var
) initform
)
 
keyword-name
 := any keyword

key-spec is interpreted as in the &key symbol of ordinary Common Lisp lambda lists. When this form of value is used, the specified keyword-name is added as an extra initarg to the class defined by the define-interface form.

If key-spec is followed by initarg-value , then its value is used as the initarg of the pane. Otherwise the value from key-spec is used.

Additionally initargs may contain the keyword argument :make-instance-extra-apply-args which is useful when you want to supply initargs to the pane slot-name when the interface is initialized. The value make-instance-extra-apply-args should be a keyword which becomes an extra initarg to the interface class name . The value of that initarg should be a list of pane initargs and values which is passed when the pane is initialized. For an example, see:

(example-edit-file "capi/applications/argument-passing")

The option :menu-bar is a list of slot names, where each slot referred to contains a menu that should appear on the menu bar.

The option :definition is a property list of arguments which define-interface uses to change the way that it behaves. Currently there is only one definition option:

:interface-variable

Allows you to specify the name of a variable which (lexically within the define-interface form) refers to the interface instance. By default this variable is capi:interface. See the example below.

Example

Firstly, a couple of pane examples:

(capi:define-interface test1 ()
  ()
  (:panes
    (text capi:text-input-pane))
  (:default-initargs :title "Test1"))
 
(capi:display (make-instance 'test1))
 
(capi:define-interface test2 ()
  ()
  (:panes
    (text capi:text-input-pane)
    (buttons capi:button-panel :items '(1 2 3)
             :reader test2-buttons))
  (:layouts
    (main-layout capi:column-layout '(text buttons)))
  (:default-initargs :title "Test2"))
 
(test2-buttons
 (capi:display (make-instance 'test2)))

Here are a couple of menu examples:

(capi:define-interface test3 ()
  ()
  (:menus
    (color-menu "Colors" (:red :green :blue)
       :print-function 'string-capitalize))
  (:menu-bar color-menu)
  (:default-initargs :title "Test3"))
(capi:display (make-instance 'test3))
(capi:define-interface test4 ()
  ()
  (:menus
   (colors-menu "Colors" 
                ((:component
                  (:red :green :blue)
                  :interaction :single-selection
                  :print-function 
                  'string-capitalize)
                 more-colors-menu))
   (more-colors-menu "More Colors"
                     (:pink :yellow :cyan)
                     :print-function 
                     'string-capitalize))
  (:menu-bar colors-menu)
  (:default-initargs :title "Test4"))
(capi:display (make-instance 'test4))

This example demonstrates inheritance amongst subclasses of interface:

(capi:define-interface test5 (test4 test1)
  ()
  (:default-initargs :title "Test5"))
(capi:display (make-instance 'test5))

The next three examples illustrate the use of :initarg in initarg specifications for :panes.

Here we initialize the :selected-items initarg of the pane foo to the value passed by :select when making the interface object, or nil otherwise:

(capi:define-interface init1 () ()
  (:panes
   (foo
    capi:list-panel
    :items '(0 1 2 3 4)
    :visible-min-height '(:character 5)
    :interaction :multiple-selection
    :selected-items (:initarg select))))
 
(capi:contain (make-instance 'init1 
                             :select '(1 3)))
 
(capi:contain (make-instance 'init1))

Here we initialize the :selected-items initarg of pane foo to the value passed by :select initarg when making the interface object, or (1 3) otherwise:

(capi:define-interface init2 () ()
  (:panes
   (foo
    capi:list-panel
    :items '(0 1 2 3 4)
    :visible-min-height '(:character 5)
    :interaction :multiple-selection
    :selected-items 
    (:initarg (select '(1 3))))))
 
(capi:contain (make-instance 'init2))

Here we increment the indices passed in the interface's :select initarg before passing them in the :selected-items initarg of pane foo:

(capi:define-interface init3 () ()
  (:panes
   (foo
    capi:list-panel
    :items '(0 1 2 3 4)
    :visible-min-height '(:character 5)
    :interaction :multiple-selection
    :selected-items 
    (:initarg select 
     (mapcar '1+ select)))))
 
(capi:contain (make-instance 'init3 
                             :select '(1 3)))

This example illustrates the use of :interface-variable. Both menu commands act on the interface itself, but they receive this argument in different ways:

(capi:define-interface foo () ()
  (:menus
   (menu "Run"
           (("Interface Variable"
             :callback (lambda () (test xxx))
             :callback-type :none)
           (":callback-type :interface"
            :callback 'test
            :callback-type :interface))))
  (:menu-bar menu)
  (:definition :interface-variable xxx))
 
(defmethod test ((foo foo))
  (capi:display-message "foo"))
 
(capi:display (make-instance 'foo))

There are many more examples in the LispWorks installation directory under examples/capi/.

See also

interface
layout
menu
Creating Menus
Defining Interface Classes - top level windows


CAPI User Guide and Reference Manual (Macintosh version) - 3 Aug 2017

NextPrevUpTopContentsIndex