]> Pileus Git - ~andy/gtk/blob - docs/reference/gtk/migrating-GtkGrid.xml
stylecontext: Do invalidation on first resize container
[~andy/gtk] / docs / reference / gtk / migrating-GtkGrid.xml
1 <?xml version="1.0"?>
2 <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
3                "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
4 ]>
5 <chapter id="gtk-migrating-GtkGrid">
6
7   <title>Migrating from other containers to GtkGrid</title>
8
9   <para>
10     #GtkGrid is an attempt to write a comprehensive, legacy-free,
11     box-layout container that is flexible enough to replace #GtkBox,
12     #GtkTable and the like.
13   </para>
14
15   <para>
16     The layout model of GtkGrid is to arrange its children in rows and
17     columns. This is done by assigning positions on a two-dimentions
18     grid that stretches arbitrarily far in all directions.
19     Children can span multiple rows or columns, too.
20  </para>
21
22   <section>
23
24     <title>GtkBox versus GtkGrid: packing</title>
25
26     <para>
27       GtkBox works by arranging child widgets in a single line, either
28       horizontally or vertically. It allows packing children from the
29       beginning or end, using gtk_box_pack_start() and gtk_box_pack_end().
30     </para>
31
32     <inlinegraphic fileref="box-packing.png" format="PNG"></inlinegraphic>
33
34   <example>
35     <title>A simple box</title>
36     <programlisting>
37   box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
38
39   gtk_box_pack_start (GTK_BOX (box), gtk_label_new ("One"), FALSE, FALSE, 0);
40   gtk_box_pack_start (GTK_BOX (box), gtk_label_new ("Two"), FALSE, FALSE, 0);
41     </programlisting>
42     <para>This can be done with #GtkGrid as follows:</para>
43     <programlisting>
44   grid = gtk_grid_new ();
45
46   child1 = gtk_label_new ("One");
47   gtk_grid_attach (GTK_GRID (grid), child1, 0, 0, 1, 1);
48   child2 = gtk_label_new ("Two");
49   gtk_grid_attach_next_to (GTK_GRID (grid), child2, child1, GTK_POS_RIGHT, 1, 1);
50     </programlisting>
51     <para>
52       And similarly for gtk_box_pack_end(). In that case, you
53       would use #GTK_POS_LEFT to place the grid children from
54       left to right.
55     </para>
56     <para>
57       If you only need to pack children from the start, using
58       gtk_container_add() is an even simpler alternative. GtkGrid
59       places children added with gtk_container_add() in a single
60       row or column according to its #GtkOrientable:orientation.
61     </para>
62   </example>
63
64     <para>
65       One difference to keep in mind is that the gtk_box_pack_start/pack_end
66       functions allow you to place an arbitrary number of children from
67       either end without ever 'colliding in the middle'. With GtkGrid, you
68       have to leave enough space between the two ends, if you want to combine
69       packing from both ends towards the middle. In practice, this should be
70       easy to avoid; and GtkGrid simply ignores entirely empty rows or
71       columns for layout and spacing.
72     </para>
73     <para>
74       On the other hand, GtkGrid is more flexible in that its grid extends
75       indefinitively in both directions &mdash; there is no problem with
76       using negative numbers for the grid positions. So, if you discover
77       that you need to place a widget before your existing arrangement,
78       you always can.
79     </para>
80   </section>
81
82   <section>
83     <title>GtkBox versus GtkGrid: sizing</title>
84
85     <para>
86       When adding a child to a GtkBox, there are two hard-to-remember
87       parameters (child properties, more exactly) named expand and fill
88       that determine how the child size behaves in the main direction
89       of the box. If expand is set, the box allows the position occupied
90       by the child to grow when extra space is available. If fill is
91       also set, the extra space is allocated to the child widget itself.
92       Otherwise it is left 'free'.
93       There is no control about the 'minor' direction; children
94       are always given the full size in the minor direction.
95     </para>
96
97     <inlinegraphic fileref="box-expand.png" format="PNG"></inlinegraphic>
98
99     <para>
100       GtkGrid does not have any custom child properties for controlling
101       size allocation to children. Instead, it fully supports the newly
102       introduced #GtkWidget:hexpand, #GtkWidget:vexpand, #GtkWidget:halign
103       and #GtkWidget:valign properties.
104     </para>
105     <para>
106       The #GtkWidget:hexpand and #GtkWidget:vexpand properties operate
107       in a similar way to the expand child properties of #GtkBox. As soon
108       as a column contains a hexpanding child, GtkGrid allows the column
109       to grow when extra space is available (similar for rows and vexpand).
110       In contrast to GtkBox, all the extra space is always allocated
111       to the child widget, there are no 'free' areas.
112     </para>
113     <para>
114       To replace the functionality of the fill child properties, you can
115       set the #GtkWidget:halign and #GtkWidget:valign properties. An
116       align value of #GTK_ALIGN_FILL has the same effect as setting fill
117       to %TRUE, a value of #GTK_ALIGN_CENTER has the same effect as setting
118       fill to %FALSE. The image below shows the effect of various combinations
119       of halign and valign.
120     </para>
121
122     <inlinegraphic fileref="widget-hvalign.png" format="PNG"></inlinegraphic>
123
124     <example>
125       <title>Expansion and alignment</title>
126       <programlisting>
127   box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
128
129   gtk_box_pack_start (GTK_BOX (box), gtk_label_new ("One"), TRUE, FALSE, 0);
130   gtk_box_pack_start (GTK_BOX (box), gtk_label_new ("Two"), TRUE, TRUE, 0);
131       </programlisting>
132     <para>This can be done with #GtkGrid as follows:</para>
133     <programlisting>
134   grid = gtk_grid_new ();
135
136   child1 = gtk_label_new ("One");
137   gtk_widget_set_hexpand (child1, TRUE);
138   gtk_widget_set_halign (child1, GTK_ALIGN_CENTER);
139   gtk_grid_attach (GTK_GRID (grid), child1, 0, 0, 1, 1);
140   child2 = gtk_label_new ("Two");
141   gtk_widget_set_hexpand (child2, TRUE);
142   gtk_widget_set_halign (child1, GTK_ALIGN_FILL);
143   gtk_grid_attach_next_to (GTK_GRID (grid), child2, child1, GTK_POS_RIGHT, 1, 1);
144       </programlisting>
145     </example>
146     <para>
147       One difference between the new GtkWidget expand properties and
148       the GtkBox child property of the same name is that widget expandability
149       is 'inherited' from children. What this means is that a container
150       will become itself expanding as soon as it has
151       an expanding child. This is typically what you want, it lets
152       you e.g. mark the content pane of your application window as
153       expanding, and all the intermediate containers between the
154       content pane and the toplevel window will automatically do
155       the right thing. This automatism can be overridden at any
156       point by setting the expand flags on a container explicitly.
157     </para>
158     <para>
159       Another difference between GtkBox and GtkGrid with respect to
160       expandability is when there are no expanding children at all.
161       In this case, GtkBox will forcibly expand all children whereas
162       GtkGrid will not. In practice, the effect of this is typically
163       that a grid will 'stick to the corner' when the toplevel
164       containing it is grown, instead of spreading out its children
165       over the entire area. The problem can be fixed by setting some
166       or all of the children to expand.
167     </para>
168
169     <para>
170       When you set the #GtkBox:homogeneous property on a GtkBox,
171       it reserves the same space for all its children. GtkGrid does
172       this in a very similar way, with #GtkGrid:row-homogeneous and
173       #GtkGrid:column-homogeneous properties which control whether
174       all rows have the same height and whether all columns have
175       the same width.
176     </para>
177   </section>
178
179   <section>
180     <title>GtkBox versus GtkGrid: spacing</title>
181
182     <para>
183       With GtkBox, you have to specify the #GtkBox:spacing when
184       you construct it. This property specifies the space that
185       separates the children from each other. Additionally, you
186       can specify extra space to put around each child individually,
187       using the #GtkBox:padding child property.
188     </para>
189
190     <para>
191       GtkGrid is very similar when it comes to spacing between the
192       children, except that it has two separate properties,
193       #GtkGrid:row-spacing and #GtkGrid:column-spacing, for the
194       space to leave between rows and columns. Note that row-spacing
195       is the space <emphasis>between</emphasis> rows, not inside
196       a row. So, if you doing a horizontal layout, you need to set
197       #GtkGrid:column-spacing.
198     </para>
199     <para>
200       GtkGrid doesn't have any custom child properties to specify
201       per-child padding; instead you can use the #GtkWidget:margin
202       property. You can also set different padding on each side with
203       the  #GtkWidget:margin-left, #GtkWidget:margin-right,
204       #GtkWidget:margin-top and #GtkWidget:margin-bottom properties.
205     </para>
206
207     <example>
208       <title>Spacing in boxes</title>
209
210       <programlisting>
211          box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
212          gtk_box_pack_start (GTK_BOX (box), child, FALSE, FALSE, 12);
213       </programlisting>
214       <para>This can be done with #GtkGrid as follows:</para>
215       <programlisting>
216          grid = gtk_grid_new ();
217          gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
218          g_object_set (child, "margin", 12, NULL);
219          gtk_grid_attach (GTK_GRID (box), child, 0, 0, 1, 1);
220       </programlisting>
221     </example>
222   </section>
223
224 <!--
225   <section>
226     <title>GtkTable versus GtkGrid</title>
227     cover here: spanning, attachment points, grid size, attach options vs expand/align
228
229   </section>
230 -->
231 </chapter>