All symbols of Gtk+ binding in cl-gtk2 reside in gtk package.

Gtk+ Main loop
**************

     [file gtk.main_loop.texi not included]

Widgets
*******

     [file gtk.widgets.texi not included]

Gtk+ Interfaces
***************

     [file gtk.interfaces.texi not included]

Gtk+ Objects
************

     [file gtk.objects.texi not included]

Gtk+ Structs
************

     [file gtk.structs.texi not included]

Gtk+ Enums
**********

     [file gtk.enums.texi not included]

Gtk+ Flags
**********

     [file gtk.flags.texi not included]

Gtk+ Embedded UI Mini-language
******************************

For convenience of specifying widgets hierarchy in Lisp code, the let-ui macro is introduced.

let-ui

     (let-ui ui-description &body body)

     ui-description ::= widget
     widget ::= (class properties child*)
     properties ::= {:prop-name prop-value}*
     child ::= widget properties
     child ::= (:expr expr) properties

CLASS
     Name of class of a widget

:PROP-NAME
     Name of class's slot or a :var for specifying the variable name to which the object will be bound

PROP-VALUE
     A Lisp expression that will be evaluated to obtain the initarg for slot of a class; or a symbol if :prop-name is :var

EXPR
     An expression that will be evaluated to obtain the widget

This macro creates widgets and evaluates the BODY. Widgets that have :var specified are bound to lexical variables with specified names.

UI-DESCRIPTION specifies the hierarchy of widgets in a window. It can specify either the entire top-level window or other kind of widgets. UI-DESCRIPTION is a mini-language for specifying widgets. let-ui creates specified widgets, lexically binds specified variables to widgets and evaluates the BODY. The BODY my refer to these widgets.

WIDGET is the specification of a single widget. It may specify some properties (slots of objects) and their values (the expressions to be evaluated), a variable name that will be bound to the widget (the :var property whose PROP-VALUE must be a symbol) and widget's children.

CLASS specifies the class of the widget (e.g., label, button, gtk-window). :PROP-NAME may be any slot of the class. If :VAR property is specified, then corresponding variable is accessible in BODY and its value is the widget on which it is specified as :VAR.

Container widgets may specify their CHILDREN along with their CHILD PROPERTIES. Child properties specify how CHILDREN are used in WIDGET. They are specific to the type of the container:

  * box specifies :expand, :fill. See box-pack-start for information.

  * paned specifies :resize, :shrink. See paned-pack-1 for information.

  * table specifies :left, :right, :top, :bottom, :x-options, :y-options, x-padding, y-padding. Of these, :left, :right, :top and :bottom are mandatory. See table-attach for information.

An example:

     (let-ui (gtk-window :title "Hello" :position :center :var w
                         (v-box
                          (label :label "Hello, world!")
                          (button :label "gtk-ok" :use-stock t) :expand nil))
       (widget-show w))

produces this output:

More complex example from demo of cl-gtk2-gtk-glext:

     (let-ui (v-paned :var v
                      (:expr (opengl-window-drawing-area window))
                      :resize t :shrink nil
                      (v-box
                       (h-paned
                        (scrolled-window
                         :hscrollbar-policy :automatic
                         :vscrollbar-policy :automatic
                         (:expr (opengl-window-expose-fn-text-view window)))
                        :resize t :shrink nil
                        (scrolled-window
                         :hscrollbar-policy :automatic
                         :vscrollbar-policy :automatic
                         (:expr (opengl-window-resize-fn-text-view window)))
                        :resize t :shrink nil)
                       (h-box
                        (button :label "Update functions" :var update-fns-button) :expand nil
                        (button :label "Redraw" :var redraw-button) :expand nil)
                       :expand nil)
                      :resize t :shrink nil)
       (container-add window v)
       (connect-signal update-fns-button "clicked"
                       (lambda (b)
                         (declare (ignore b))
                         (update-fns window)))
       (connect-signal redraw-button "clicked"
                       (lambda (b)
                         (declare (ignore b))
                         (widget-queue-draw (opengl-window-drawing-area window))))
       (let ((area (opengl-window-drawing-area window)))
         (setf (gl-drawing-area-on-expose area)
               (lambda (w e)
                 (declare (ignore w e))
                 (opengl-interactive-on-expose window))
               (gl-drawing-area-on-resize area)
               (lambda (widget w h)
                 (declare (ignore widget))
                 (opengl-interactive-on-resize window w h)))))

produces this output:

In this example, not top-level window, but a widget is created and then added to already existing window. This UI also uses some already created widgets: (:expr (opengl-window-resize-fn-text-view window)).