[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3. Packing Widgets


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.1 Packing Boxes

When creating an application, it is necessary to put more than one widget inside a window. The first Hello world example only used one button so it could simply use the function gtk-container-add to "pack" the button into the window. But when more than one widget must be put into a window packing comes in.

Packing is done by creating boxes or grids. Grids are more general and powerful than boxes. Grids are explained later in this tutorial. Boxes are invisible widget containers that can pack widgets into, which come in two forms, a horizontal box, and a vertical box. When packing widgets into a horizontal box, the objects are inserted horizontally from left to right or right to left depending on the call used. In a vertical box, widgets are packed from top to bottom or vice versa. You may use any combination of boxes inside or beside other boxes to create the desired effect.

To create a new box of the type gtk-box, the function gtk-box-new or the call (make-instance 'gtk-box) is used. The first argument of the function gtk-box-new takes a keyword of the enumeration type GtkOrientation, which, in the Lisp binding, is implemented as gtk-orientation with the values :horizontal or :vertical to determine a horizontal or a vertical box. Because gtk-box implements the interface gtk-orientable an instance of gtk-box has the property "orientiation" of type gtk-orientation.

Function

Description

gtk-box-new

Creates a new gtk-box container.

gtk-box-homogeneous

Accessor of the "homogeneous" property

gtk-box-spacing

Accessor of the "spacing" property

gtk-box-pack-start

Adds a child to the box, packed with reference to the start of box.

gtk-box-pack-end

Adds a child to the box, packed with reference to the end of box.

Table 3.1: Functions for the gtk-box class.

The following examples show two equivalent ways to create an instance of a horizontal box. The first argument of the function gtk-box-new takes the value of the property "orientation". The second argument is the value of the property "spacing", which is described in Details of Boxes.

  (let ((box (gtk-box-new :horizontal 3)))
    ... )

or

  (let ((box (make-instance 'gtk-box
                            :orientation :horizontal
                            :spacing 3)))
    ... )

The functions gtk-box-pack-start and gtk-box-pack-end are used to place widgets inside of boxes. The function gtk-box-pack-start function starts at the top and works its way down in a vertical box, and packs left to right in a horizontal box. The function gtk-box-pack-end does the opposite, packing from bottom to top in a vertical box, and right to left in a horizontal box. The widgets, which are packed into a box, can be containers, which are composed of other widgets. Using the functions for packing widgets in boxes allows to right justify or left justify the widgets. The functions can be mixed in any way to achieve the desired effect. Most of the examples in this tutorial use the function gtk-box-pack-start. In the following example a vertical box is created. Then two label widgets are packed into the box with the function gtk-box-pack-start.

  (let ((box (gtk-box-new :vertical 3)))
    (gtk-box-pack-start box (gtk-label-new "LABEL 1"))
    (gtk-box-pack-start box (gtk-label-new "LABEL 2"))
    ... )

By using boxes, GTK+ knows where to place the widgets so GTK+ can do automatic resizing and other nifty things. A number of options control as to how the widgets should be packed into boxes. This method of packing boxes gives the user quite a bit of flexibility when placing widgets.

Note

The classes gtk-hbox for horizontal and gtk-vbox for vertical boxes are deprecated, but still present in GTK+ 3. In this tutorial these classes are not used. In addition a single-row or single-column gtk-grid provides exactly the same functionality as gtk-box. See Packing Using Grids for examples to replace gtk-box with gtk-grid.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.2 Details of Boxes

Because of the flexibility, packing boxes in GTK+ can be confusing at first. A lot of options control the packing of boxes, and it is not immediately obvious how the options all fit together. In the end, however, basically five different styles are available.

Boxes have the properties "homogeneous" and "spacing". The generic functions gtk-box-homogeneous and gtk-box-spacing are used to write and read the properties. The property "homogeneous" controls whether each widget in the box has the same width in a horizontal box or the same height in a vertical box. The property "spacing" controls the amount of space between children in the box. A complete example for creating a box is therefore

  (let ((box (make-instance 'gtk-box
                            :orientation :vertical
                            :spacing 3
                            :homogeneous t)))
    ... )

figures/box-packing629x323

Figure 3.1: Example Box Packing with a spacing of 3

figure-box-packing shows an example of packing buttons into horizontal boxes. The buttons have a small spacing of 3. Each line of the example contains one horizontal box with several buttons. The first button represents the call of the function gtk-box-pack-start and the following buttons represent the arguments of the function. The first two arguments are box for the box and child for the child widgets to put into the box, which are in our example buttons. The further arguments of gtk-box-pack-start are in the C implementation expand, fill and padding. In the Lisp binding to GTK+ these arguments are defined as the keyword arguments :expand and :fill, which both have a default value of true, and :padding with a default value of 0. The keyword arguments can be omitted, in which case the default values will be used.

The keyword argument :expand with a value true to the functions gtk-box-pack-start and gtk-box-pack-end controls whether the widgets are laid out in the box to fill in all the extra space in the box so the box is expanded to fill the area allotted to it; or with a value nil the box is shrunk to just fit the widgets. Setting expand to nil allows to do right and left justification of the widgets. Otherwise, the widgets expand to fit into the box. The same effect can be achieved by using only one of the functions gtk-box-pack-start or gtk-box-pack-end.

The keyword argument :fill with a value true to the gtk-box-pack functions control whether the extra space is allocated to the objects themselves, or with a value nil as extra padding in the box around these objects. It only has an effect if the keyword argument expand is also true.

The difference between spacing, set when the box is created, and padding, set when elements are packed, is, that spacing is added between objects, and padding is added on either side of a child widget.

The code for figure-box-packing is shown in example-box-packing. The function example-box-packing takes an optional argument spacing, which has the default value 0 and controls the spacing of the buttons in the boxes.

The example uses two widgets which are not introduced up to now. The first one is the gtk-label widget, which is described in Labels and is used to display text. The second one is the gtk-separator widget, which draws a horizontal or vertical line. The orientation of the line depends on the only argument to the function gtk-separator-new, which is of the enumeration type gtk-orientation with the values :horizontal for a horizontal line and :vertical for a vertical line.

Example 3.1: Example Packing Boxes

(defun make-box (homogeneous spacing expand fill padding)
  (let ((box (make-instance 'gtk-box
                            :orientation :horizontal
                            :homogeneous homogeneous
                            :spacing spacing)))
    (gtk-box-pack-start box
                        (gtk-button-new-with-label "gtk-box-pack")
                        :expand expand
                        :fill fill
                        :padding padding)
    (gtk-box-pack-start box
                        (gtk-button-new-with-label "box")
                        :expand expand
                        :fill fill
                        :padding padding)
    (gtk-box-pack-start box
                        (gtk-button-new-with-label "button")
                        :expand expand
                        :fill fill
                        :padding padding)
    (gtk-box-pack-start box
                        (if expand
                            (gtk-button-new-with-label "T")
                            (gtk-button-new-with-label "NIL"))
                        :expand expand
                        :fill fill
                        :padding padding)
    (gtk-box-pack-start box
                        (if fill
                            (gtk-button-new-with-label "T")
                            (gtk-button-new-with-label "NIL"))
                        :expand expand
                        :fill fill
                        :padding padding)
    (gtk-box-pack-start box
                        (gtk-button-new-with-label (format nil "~A" padding))
                        :expand expand
                        :fill fill
                        :padding padding)
    box))

(defun example-box-packing (&optional (spacing 0))
  (within-main-loop
    (let ((window (make-instance 'gtk-window
                                 :title "Example Box Packing"
                                 :type :toplevel
                                 :border-width 12))
          (vbox (make-instance 'gtk-box
                               :orientation :vertical
                               :spacing 6))
          (button (make-instance 'gtk-button
                                 :label "Quit"))
          (quitbox (make-instance 'gtk-box
                                  :orientation :horizontal)))
      (g-signal-connect button "clicked"
                        (lambda (widget)
                          (declare (ignore widget))
                          (gtk-widget-destroy window)))
      (g-signal-connect window "destroy"
                        (lambda (widget)
                          (declare (ignore widget))
                          (leave-gtk-main)))
      (gtk-box-pack-start vbox
                          (make-instance 'gtk-label
                                         :label
                                         (format nil
                                          "GtkBox   ~
                                           :orientation :horizontal   ~
                                           :homogeneous nil   ~
                                           :spacing ~A"
                                          spacing)
                                         :xalign 0)
                          :expand nil)
      (gtk-box-pack-start vbox
                          (make-box nil spacing nil nil 0)
                          :expand nil)
      (gtk-box-pack-start vbox
                          (make-box nil spacing t nil 0)
                          :expand nil)
      (gtk-box-pack-start vbox
                          (make-box nil spacing t t 0)
                          :expand nil)
      (gtk-box-pack-start vbox
                          (make-instance 'gtk-label
                                         :label
                                         (format nil
                                            "GtkBox   ~
                                             :orientation :horizontal   ~
                                             :homogeneous t   ~
                                             :spacing ~A"
                                            spacing)
                                         :xalign 0)
                          :expand nil
                          :padding 6)
      (gtk-box-pack-start vbox
                          (make-box t spacing t nil 0)
                          :expand nil)
      (gtk-box-pack-start vbox
                          (make-box t spacing t t 0)
                          :expand nil)
      (gtk-box-pack-start vbox
                          (gtk-separator-new :horizontal)
                          :expand nil
                          :padding 6)
      ;; Align the quit-button on the right side
      (gtk-box-pack-end quitbox button :expand nil)
      (gtk-box-pack-start vbox quitbox :expand nil)
      (gtk-container-add window vbox)
      (gtk-widget-show-all window))))

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.3 Packing Using Tables

Tables are another way of packing widgets and can be extremely useful in certain situations. Using tables a grid is created that widgets can placed in. The widgets may take up as many spaces as specified. Tables can be created with the function gtk-table-new. The function takes three arguments which set the properties of a table. Alternatively, the table is created with the function make-instance.

The first argument of gtk-table-new is the number of rows to make in the table, while the second is the number of columns. The last argument homogeneous has to do with how the boxes of the table are sized. If homogeneous is T, the table boxes are resized to the size of the largest widget in the table. If homogeneous is NIL, the size of a table boxes is dictated by the tallest widget in its same row, and the widest widget in its column. The rows and columns are laid out from 0 to n, where n is the number specified in the call to the function gtk-table-new. For rows = 2 and columns = 2, the layout is shown in figure-table-layout. Note that the coordinate system starts in the upper left hand corner.

 0          1          2
0+----------+----------+
 |          |          |
1+----------+----------+
 |          |          |
2+----------+----------+

Figure 3.2: Layout of a 2 x 2 table

To place a widget into a table, the function gtk-table-attach can be used. The arguments are listed in table-gtk-table-attach. The first argument table is the table you have created and the second child the widget you wish to place into the table. The left and right attach arguments specify where to place the widget, and how many boxes to use. If you want a button in the lower right table entry of a 2 x 2 table, and want it to fill that entry only, left-attach is = 1, right-attach = 2, top-attach = 1, bottom-attach = 2. Now, if you wanted a widget to take up the whole top row of a 2 x 2 table, you would use left-attach = 0, right-attach = 2, top-attach = 0, bottom-attach = 1.

Table 3.2: Arguments of the function gtk-table-attach

table

The GtkTable to add a new widget to.

child

The widget to add.

left-attach

The column number to attach the left side of a child widget to.

right-attach

The column number to attach the right side of a child widget to.

top-attach

The row number to attach the top of a child widget to.

bottom-attach

The row number to attach the bottom of a child widget to.

:xoptions

Used to specify the properties of the child widget when the table is resized. The default value is '(:expand :fill).

:yoptions

The same as xoptions, except this field determines behavior of vertical resizing. The default value is '(:expand :fill).

:xpadding

An integer value specifying the padding on the left and right of the widget being added to the table. The default value is 0.

:ypadding

The amount of padding above and below the child widget. The default value is 0.

The arguments :xoptions and :yoptions are of the enumeration type gtk-attach-options and used to specify packing options. The packing options can be OR'ed together to allow multiple options. In the Lisp binding a list of options is used to combine multiple options. Possible values of the enumeration type gtk-attach-options are listed in table-GtkAttachOptions.

Padding is just like in boxes, creating a clear area around the widget specified in pixels and is controlled with the arguments :xpadding and :ypadding.

Table 3.3: Values of the type GtkAttachOptions

:fill

If the table box is larger than the widget, and :fill is specified, the widget will expand to use all the room available.

:shrink

If the table widget was allocated less space then was requested (usually by the user resizing the window), then the widgets would normally just be pushed off the bottom of the window and disappear. If :shrink is specified, the widgets will shrink with the table.

:expand

This will cause the table to expand to use up any remaining space in the window.

In the Lisp binding the arguments :xoptions, :yoptions, :xpadding, and :ypadding of the function gtk-table-attach are defined as keyword arguments with default values as shown in table-gtk-table-attach. In the C library this is realized with a second function gtk_table_attach_defaults(). In the Lisp binding the function gtk-table-attach-defaults is a second equivalent implementation of gtk-table-attach, when using the default values of the keyword arguments.

The functions gtk-table-set-row-spacing and gtk-table-set-col-spacing places spacing between the rows at the specified row or column. The first argument of the functions is a gtk-table, the second argument a row or a column and the third argument the spacing. Note that for columns, the space goes to the right of the column, and for rows, the space goes below the row.

You can also set a consistent spacing of all rows and columns with the functions gtk-table-set-row-spacings and gtk-table-set-col-spacings. Both functions take a gtk-table as the first argument and the desired spacing spacing as the second argument. Note that with these calls, the last row and last column do not get any spacing.

Note:

gtk-table has been deprecated since GTK+ 3.4. It is recommended to use gtk-grid instead. gtk-grid provides the same capabilities as gtk-table for arranging widgets in a rectangular grid, but does support height-for-width geometry management, which is newly introduced for widgets in GTK+ 3. This chapter will vanish in the near future.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.4 Table Packing Example

figure-table-packing is a window with three buttons in a 2 x 2 table. The first two buttons are placed in the upper row. A third, quit button, is placed in the lower row, spanning both columns. The code of this example is shown in example-table-packing.

figures/table-packing306x108

Figure 3.3: Table packing

Example 3.2: Table Packing

(defun example-table-packing ()
  (within-main-loop
    (let ((window (make-instance 'gtk-window
                                 :type :toplevel
                                 :title "Example Table Packing"
                                 :border-width 12
                                 :default-width 300))
          (table (make-instance 'gtk-table
                                :n-columns 2
                                :n-rows 2
                                :homogeneous t))
          (button1 (make-instance 'gtk-button
                                  :label "Button 1"))
          (button2 (make-instance 'gtk-button
                                  :label "Button 2"))
          (quit (make-instance 'gtk-button
                               :label "Quit")))
      (g-signal-connect window "destroy"
                        (lambda (widget)
                          (declare (ignore widget))
                          (leave-gtk-main)))
      (g-signal-connect quit "clicked"
                        (lambda (widget)
                          (declare (ignore widget))
                          (gtk-widget-destroy window)))
      (gtk-table-attach table button1 0 1 0 1)
      (gtk-table-attach table button2 1 2 0 1)
      (gtk-table-attach table quit    0 2 1 2)
      (gtk-container-add window table)
      (gtk-widget-show-all window))))

figure-table-packing-2 is an extended example to show the possibility to increase the spacing of the rows and columns. This is implemented through two toggle buttons which increase and decrease the spacings. Toggle buttons are described in Toggle Buttons later in this tutorial. The code of figure-table-packing-2 is shown in example-table-packing-2.

figures/table-packing-2-306x120

Figure 3.4: Table packing with more spacing

Example 3.3: Table Packing with more spacing

(defun example-table-packing-2 ()
  (within-main-loop
    (let ((window (make-instance 'gtk-window
                                 :type :toplevel
                                 :title "Example Table Packing"
                                 :border-width 12
                                 :default-width 300))
          (table (make-instance 'gtk-table
                                :n-columns 2
                                :n-rows 2
                                :homogeneous t))
          (button1 (make-instance 'gtk-toggle-button
                                  :label "More Row Spacing"))
          (button2 (make-instance 'gtk-toggle-button
                                  :label "More Col Spacing"))
          (quit (make-instance 'gtk-button
                               :label "Quit")))
      (g-signal-connect window "destroy"
                        (lambda (widget)
                          (declare (ignore widget))
                          (leave-gtk-main)))
      (g-signal-connect button1 "toggled"
         (lambda (widget)
           (if (gtk-toggle-button-active widget)
               (progn
                 (gtk-table-set-row-spacings table 12)
                 (setf (gtk-button-label widget) "Less Row Spacing"))
               (progn
                 (gtk-table-set-row-spacings table 0)
                 (setf (gtk-button-label widget) "More Row Spacing")))))
      (g-signal-connect button2 "toggled"
         (lambda (widget)
           (if (gtk-toggle-button-active widget)
               (progn
                 (gtk-table-set-col-spacings table 12)
                 (setf (gtk-button-label widget) "Less Col Spacing"))
               (progn
                 (gtk-table-set-col-spacings table 0)
                 (setf (gtk-button-label widget) "More Col Spacing")))))
      (g-signal-connect quit "clicked"
                        (lambda (widget)
                          (declare (ignore widget))
                          (gtk-widget-destroy window)))
      (gtk-table-attach table button1 0 1 0 1)
      (gtk-table-attach table button2 1 2 0 1)
      (gtk-table-attach table quit    0 2 1 2)
      (gtk-container-add window table)
      (gtk-widget-show-all window))))

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.5 Packing Using Grids

gtk-grid is an attempt to write a comprehensive, legacy-free, box-layout container that is flexible enough to replace gtk-box, gtk-table and the like.

The layout model of gtk-grid is to arrange its children in rows and columns. This is done by assigning positions on a two-dimensions grid that stretches arbitrarily far in all directions. Children can span multiple rows or columns.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.5.1 GtkBox versus GtkGrid - packing

gtk-box works by arranging child widgets in a single line, either horizontally or vertically. It allows packing children from the beginning or end, using gtk-box-pack-start and gtk-box-pack-end.

The following code creates a simple box with two labels:

  (let ((box (gtk-box-new :horizontal 0)))
    (gtk-box-pack-start box (gtk-label-new "ONE") nil nil 0)
    (gtk-box-pack-start box (gtk-label-new "TWO") nil nil 0)
    [...] )

This can be done with gtk-grid as follows:

  (let ((grid (gtk-grid-new))
        (child1 (gtk-label-new "ONE"))
        (child2 (gtk-label-new "TWO")))
    (gtk-grid-attach grid child1 0 0 1 1)
    (gtk-grid-attach-next-to grid child2 child1 :right 1 1)
    [...]  )

And similarly for gtk-box-pack-end. In that case, you would use :left to place the grid children from left to right.

If you only need to pack children from the start, using gtk-container-add is an even simpler alternative. gtk-grid places children added with gtk-container-add in a single row or column according to its "orientation".

One difference to keep in mind is that the gtk-box-pack-start and gtk-box-pack-end functions allow you to place an arbitrary number of children from either end without ever 'colliding in the middle'. With gtk-grid, you have to leave enough space between the two ends, if you want to combine packing from both ends towards the middle. In practice, this should be easy to avoid; and gtk-grid simply ignores entirely empty rows or columns for layout and spacing.

On the other hand, gtk-grid is more flexible in that its grid extends indefinitively in both directions - there is no problem with using negative numbers for the grid positions. So, if you discover that you need to place a widget before your existing arrangement, you always can.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.5.2 GtkBox versus GtkGrid: sizing

When adding a child to a gtk-box, there are two hard-to-remember parameters (child properties, more exactly) named expand and fill that determine how the child size behaves in the main direction of the box. If expand is set, the box allows the position occupied by the child to grow when extra space is available. If fill is also set, the extra space is allocated to the child widget itself. Otherwise it is left 'free'. There is no control about the 'minor' direction; children are always given the full size in the minor direction.

gtk-grid does not have any custom child properties for controlling size allocation to children. Instead, it fully supports the newly introduced hexpand, vexpand, halign and valign properties for widgets.

The hexpand and vexpand properties operate in a similar way to the expand child properties of gtk-box. As soon as a column contains a hexpanding child, gtk-grid allows the column to grow when extra space is available (similar for rows and vexpand). In contrast to gtk-box, all the extra space is always allocated to the child widget, there are no 'free' areas.

To replace the functionality of the fill child properties, you can set the halign and valign properties. An align value of :fill has the same effect as setting fill to true, a value of :center has the same effect as setting fill to nil.

Expansion and alignment with gtk-box:

  (let ((box (gtk-box-new :horizontal 0)))
    (gtk-box-pack-start box (gtk-label-new "ONE") t nil 0)
    (gtk-box-pack-start box (gtk-label-new "TWO") t t 0)
    [...] )

This can be done with gtk-grid as follows:

  (let ((grid (gtk-grid-new))
        (child1 (make-instance 'gtk-label
                               :label "ONE"
                               :hexpand t
                               :halign :center))
        (child2 (make-instance 'gtk-label
                               :label "TWO"
                               :hexpand t
                               :halign :fill))
    (gtk-grid-attach grid child1 0 0 1 1)
    (gtk-grid-attach-next-to grid child2 child1 :right 1 1)
    [...] )

One difference between the new gtk-widget expand properties and the gtk-box child property of the same name is that widget expandability is 'inherited' from children. What this means is that a container will become itself expanding as soon as it has an expanding child. This is typically what you want, it lets you e. g. mark the content pane of your application window as expanding, and all the intermediate containers between the content pane and the toplevel window will automatically do the right thing. This automatism can be overridden at any point by setting the expand flags on a container explicitly.

Another difference between gtk-box and gtk-grid with respect to expandability is when there are no expanding children at all. In this case, gtk-box will forcibly expand all children whereas gtk-grid will not. In practice, the effect of this is typically that a grid will 'stick to the corner' when the toplevel containing it is grown, instead of spreading out its children over the entire area. The problem can be fixed by setting some or all of the children to expand.

When you set the homogeneous property on a gtk-box, it reserves the same space for all its children. gtk-grid does this in a very similar way, with row-homogeneous and column-homogeneous properties which control whether all rows have the same height and whether all columns have the same width.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.5.3 GtkBox versus GtkGrid - spacing

With gtk-box, you have to specify the "spacing" when you construct it. This property specifies the space that separates the children from each other. Additionally, you can specify extra space to put around each child individually, using the padding child property.

gtk-grid is very similar when it comes to spacing between the children, except that it has two separate properties, row-spacing and column-spacing, for the space to leave between rows and columns. Note that row-spacing is the space between rows, not inside a row. So, if you doing a horizontal layout, you need to set column-spacing.

gtk-grid does not have any custom child properties to specify per-child padding; instead you can use the margin property. You can also set different padding on each side with the margin-left, margin-right, margin-top and margin-bottom properties.

Example with spacing in boxes:

  (let ((box (gtk-box-new :vertical 6))
        (child (gtk-label-new "Child")))
    (gtk-box-pack-start box child nil nil 12)
    [...] )

This can be done with gtk-grid as follows:

  (let ((grid (gtk-grid-new))
        (child (make-instance 'gtk-label
                              :label "Child"
                              :margin 12)))
    (gtk-grid-attach box child 0 0 1 1)
    [...] )

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.6 Grid Packing Examples

We repeat the implementation of example-box-packing and example-table-packing using GtkGrid. The first example-grid-packing shows how to replace gtk-box with gtk-grid to create vertical and horizontal boxes. In the second example-grid-packing-2 gtk-table is replaced with gtk-grid. See figure-box-packing and figure-table-packing for the output of the example programs.

Example 3.4: example-box-packing using gtk-grid

(defun make-grid (homogeneous spacing expand align margin)
  (let ((box (make-instance 'gtk-grid
                            :orientation :horizontal
                            :column-homogeneous homogeneous
                            :column-spacing spacing)))
    (gtk-container-add box
                       (make-instance 'gtk-button
                                      :label "gtk-container-add"
                                      :hexpand expand
                                      :halgin align
                                      :margin margin))
    (gtk-container-add box
                       (make-instance 'gtk-button
                                      :label "box"
                                      :hexpand expand
                                      :halign align
                                      :margin margin))
    (gtk-container-add box
                       (make-instance 'gtk-button
                                      :label "button"
                                      :hexpand expand
                                      :halign align
                                      :margin margin))
    (gtk-container-add box
                       (make-instance 'gtk-button
                                      :label (if expand "T" "NIL")
                                      :hexpand expand
                                      :halign align
                                      :margin margin))
    (gtk-container-add box
                       (make-instance 'gtk-button
                                      :label (format nil "~A" align)
                                      :hexpand expand
                                      :halign align
                                      :margin margin))
    (gtk-container-add box
                       (make-instance 'gtk-button
                                      :label (format nil "~A" margin)
                                      :hexpand expand
                                      :halign align
                                      :margin margin))
    box))

(defun example-grid-packing (&optional (spacing 0))
  (within-main-loop
    (let ((window (make-instance 'gtk-window
                                 :title "Example Grid Packing"
                                 :type :toplevel
                                 :border-width 12
                                 :default-height 200
                                 :default-width 300))
          (vbox (make-instance 'gtk-grid
                               :orientation :vertical
                               :row-spacing 6))
          (button (make-instance 'gtk-button
                                 :label "Quit"))
          (quitbox (make-instance 'gtk-box
                                  :orientation :horizontal)))
      (g-signal-connect button "clicked"
                        (lambda (widget)
                          (declare (ignore widget))
                          (gtk-widget-destroy window)))
      (g-signal-connect window "destroy"
                        (lambda (widget)
                          (declare (ignore widget))
                          (leave-gtk-main)))
      (gtk-container-add vbox
                         (make-instance 'gtk-label
                                        :label
                                        (format nil
                                         "GtkGrid homogeneous nil spacing ~A"
                                         spacing)
                                        :xalign 0
                                        :yalign 0
                                        :vexpand nil
                                        :valign :start))
      (gtk-container-add vbox (gtk-separator-new :horizontal))
      (gtk-container-add vbox (make-grid nil spacing nil :center 0))
      (gtk-container-add vbox (make-grid nil spacing t :center 0))
      (gtk-container-add vbox (make-grid nil spacing t :fill 0))
      (gtk-container-add vbox (gtk-separator-new :horizontal))
      (gtk-container-add vbox
                         (make-instance 'gtk-label
                                        :label
                                        (format nil
                                           "GtkGrid homogeneous t spacing ~A"
                                           spacing)
                                         :xalign 0
                                         :yalign 0
                                         :vexpand nil
                                         :valign :start
                                         :margin 6))
      (gtk-container-add vbox (gtk-separator-new :horizontal))
      (gtk-container-add vbox (make-grid t spacing t :center 0))
      (gtk-container-add vbox (make-grid t spacing t :fill 0))
      (gtk-container-add vbox (gtk-separator-new :horizontal))
      (gtk-container-add quitbox button)
      (gtk-container-add vbox quitbox)
      (gtk-container-add window vbox)
      (gtk-widget-show-all window))))

Example 3.5: example-table-packing using gtk-grid

(defun example-grid-packing-2 ()
  (within-main-loop
    (let ((window (make-instance 'gtk-window
                                 :type :toplevel
                                 :title "Example Grid Packing"
                                 :border-width 12
                                 :default-width 300))
          (grid (make-instance 'gtk-grid
                                :column-homogeneous t
                                :row-homogeneous t))
          (button1 (make-instance 'gtk-button
                                  :label "Button 1"))
          (button2 (make-instance 'gtk-button
                                  :label "Button 2"))
          (quit (make-instance 'gtk-button
                               :label "Quit")))
      (g-signal-connect window "destroy"
                        (lambda (widget)
                          (declare (ignore widget))
                          (leave-gtk-main)))
      (g-signal-connect quit "clicked"
                        (lambda (widget)
                          (declare (ignore widget))
                          (gtk-widget-destroy window)))
      (gtk-grid-attach grid button1 0 1 1 1)
      (gtk-grid-attach grid button2 1 1 1 1)
      (gtk-grid-attach grid quit    0 2 2 1)
      (gtk-container-add window grid)
      (gtk-widget-show-all window))))

[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Crategus on January, 10 2016 using texi2html 1.76.