]> Pileus Git - ~andy/gtk/blob - gtk/gtkbox.c
Update docs Deprecate gtk_widget_{ref,unref}
[~andy/gtk] / gtk / gtkbox.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include <config.h>
28 #include "gtkbox.h"
29 #include "gtkprivate.h"
30 #include "gtkintl.h"
31 #include "gtkalias.h"
32
33 enum {
34   PROP_0,
35   PROP_SPACING,
36   PROP_HOMOGENEOUS
37 };
38
39 enum {
40   CHILD_PROP_0,
41   CHILD_PROP_EXPAND,
42   CHILD_PROP_FILL,
43   CHILD_PROP_PADDING,
44   CHILD_PROP_PACK_TYPE,
45   CHILD_PROP_POSITION
46 };
47
48 static void gtk_box_set_property (GObject         *object,
49                                   guint            prop_id,
50                                   const GValue    *value,
51                                   GParamSpec      *pspec);
52 static void gtk_box_get_property (GObject         *object,
53                                   guint            prop_id,
54                                   GValue          *value,
55                                   GParamSpec      *pspec);
56 static void gtk_box_add        (GtkContainer   *container,
57                                 GtkWidget      *widget);
58 static void gtk_box_remove     (GtkContainer   *container,
59                                 GtkWidget      *widget);
60 static void gtk_box_forall     (GtkContainer   *container,
61                                 gboolean        include_internals,
62                                 GtkCallback     callback,
63                                 gpointer        callback_data);
64 static void gtk_box_set_child_property (GtkContainer    *container,
65                                         GtkWidget       *child,
66                                         guint            property_id,
67                                         const GValue    *value,
68                                         GParamSpec      *pspec);
69 static void gtk_box_get_child_property (GtkContainer    *container,
70                                         GtkWidget       *child,
71                                         guint            property_id,
72                                         GValue          *value,
73                                         GParamSpec      *pspec);
74 static GType gtk_box_child_type (GtkContainer   *container);
75      
76
77 G_DEFINE_ABSTRACT_TYPE (GtkBox, gtk_box, GTK_TYPE_CONTAINER)
78
79 static void
80 gtk_box_class_init (GtkBoxClass *class)
81 {
82   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
83   GtkContainerClass *container_class = GTK_CONTAINER_CLASS (class);
84
85   gobject_class->set_property = gtk_box_set_property;
86   gobject_class->get_property = gtk_box_get_property;
87    
88   container_class->add = gtk_box_add;
89   container_class->remove = gtk_box_remove;
90   container_class->forall = gtk_box_forall;
91   container_class->child_type = gtk_box_child_type;
92   container_class->set_child_property = gtk_box_set_child_property;
93   container_class->get_child_property = gtk_box_get_child_property;
94
95   g_object_class_install_property (gobject_class,
96                                    PROP_SPACING,
97                                    g_param_spec_int ("spacing",
98                                                      P_("Spacing"),
99                                                      P_("The amount of space between children"),
100                                                      0,
101                                                      G_MAXINT,
102                                                      0,
103                                                      GTK_PARAM_READWRITE));
104   
105   g_object_class_install_property (gobject_class,
106                                    PROP_HOMOGENEOUS,
107                                    g_param_spec_boolean ("homogeneous",
108                                                          P_("Homogeneous"),
109                                                          P_("Whether the children should all be the same size"),
110                                                          FALSE,
111                                                          GTK_PARAM_READWRITE));
112
113   gtk_container_class_install_child_property (container_class,
114                                               CHILD_PROP_EXPAND,
115                                               g_param_spec_boolean ("expand", 
116                                                                     P_("Expand"), 
117                                                                     P_("Whether the child should receive extra space when the parent grows"),
118                                                                     TRUE,
119                                                                     GTK_PARAM_READWRITE));
120   gtk_container_class_install_child_property (container_class,
121                                               CHILD_PROP_FILL,
122                                               g_param_spec_boolean ("fill", 
123                                                                     P_("Fill"), 
124                                                                     P_("Whether extra space given to the child should be allocated to the child or used as padding"),
125                                                                     TRUE,
126                                                                     GTK_PARAM_READWRITE));
127   gtk_container_class_install_child_property (container_class,
128                                               CHILD_PROP_PADDING,
129                                               g_param_spec_uint ("padding", 
130                                                                  P_("Padding"), 
131                                                                  P_("Extra space to put between the child and its neighbors, in pixels"),
132                                                                  0, G_MAXINT, 0,
133                                                                  GTK_PARAM_READWRITE));
134   gtk_container_class_install_child_property (container_class,
135                                               CHILD_PROP_PACK_TYPE,
136                                               g_param_spec_enum ("pack-type", 
137                                                                  P_("Pack type"), 
138                                                                  P_("A GtkPackType indicating whether the child is packed with reference to the start or end of the parent"),
139                                                                  GTK_TYPE_PACK_TYPE, GTK_PACK_START,
140                                                                  GTK_PARAM_READWRITE));
141   gtk_container_class_install_child_property (container_class,
142                                               CHILD_PROP_POSITION,
143                                               g_param_spec_int ("position", 
144                                                                 P_("Position"), 
145                                                                 P_("The index of the child in the parent"),
146                                                                 -1, G_MAXINT, 0,
147                                                                 GTK_PARAM_READWRITE));
148 }
149
150 static void
151 gtk_box_init (GtkBox *box)
152 {
153   GTK_WIDGET_SET_FLAGS (box, GTK_NO_WINDOW);
154   gtk_widget_set_redraw_on_allocate (GTK_WIDGET (box), FALSE);
155   
156   box->children = NULL;
157   box->spacing = 0;
158   box->homogeneous = FALSE;
159 }
160
161 static void 
162 gtk_box_set_property (GObject         *object,
163                       guint            prop_id,
164                       const GValue    *value,
165                       GParamSpec      *pspec)
166 {
167   GtkBox *box;
168
169   box = GTK_BOX (object);
170
171   switch (prop_id)
172     {
173     case PROP_SPACING:
174       gtk_box_set_spacing (box, g_value_get_int (value));
175       break;
176     case PROP_HOMOGENEOUS:
177       gtk_box_set_homogeneous (box, g_value_get_boolean (value));
178       break;
179     default:
180       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
181       break;
182     }
183 }
184
185 static void gtk_box_get_property (GObject         *object,
186                                   guint            prop_id,
187                                   GValue          *value,
188                                   GParamSpec      *pspec)
189 {
190   GtkBox *box;
191
192   box = GTK_BOX (object);
193
194   switch (prop_id)
195     {
196     case PROP_SPACING:
197       g_value_set_int (value, box->spacing);
198       break;
199     case PROP_HOMOGENEOUS:
200       g_value_set_boolean (value, box->homogeneous);
201       break;
202     default:
203       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
204       break;
205     }
206 }
207
208 static GType
209 gtk_box_child_type (GtkContainer   *container)
210 {
211   return GTK_TYPE_WIDGET;
212 }
213
214 static void
215 gtk_box_set_child_property (GtkContainer    *container,
216                             GtkWidget       *child,
217                             guint            property_id,
218                             const GValue    *value,
219                             GParamSpec      *pspec)
220 {
221   gboolean expand = 0;
222   gboolean fill = 0;
223   guint padding = 0;
224   GtkPackType pack_type = 0;
225
226   if (property_id != CHILD_PROP_POSITION)
227     gtk_box_query_child_packing (GTK_BOX (container),
228                                  child,
229                                  &expand,
230                                  &fill,
231                                  &padding,
232                                  &pack_type);
233   switch (property_id)
234     {
235     case CHILD_PROP_EXPAND:
236       gtk_box_set_child_packing (GTK_BOX (container),
237                                  child,
238                                  g_value_get_boolean (value),
239                                  fill,
240                                  padding,
241                                  pack_type);
242       break;
243     case CHILD_PROP_FILL:
244       gtk_box_set_child_packing (GTK_BOX (container),
245                                  child,
246                                  expand,
247                                  g_value_get_boolean (value),
248                                  padding,
249                                  pack_type);
250       break;
251     case CHILD_PROP_PADDING:
252       gtk_box_set_child_packing (GTK_BOX (container),
253                                  child,
254                                  expand,
255                                  fill,
256                                  g_value_get_uint (value),
257                                  pack_type);
258       break;
259     case CHILD_PROP_PACK_TYPE:
260       gtk_box_set_child_packing (GTK_BOX (container),
261                                  child,
262                                  expand,
263                                  fill,
264                                  padding,
265                                  g_value_get_enum (value));
266       break;
267     case CHILD_PROP_POSITION:
268       gtk_box_reorder_child (GTK_BOX (container),
269                              child,
270                              g_value_get_int (value));
271       break;
272     default:
273       GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
274       break;
275     }
276 }
277
278 static void
279 gtk_box_get_child_property (GtkContainer *container,
280                             GtkWidget    *child,
281                             guint         property_id,
282                             GValue       *value,
283                             GParamSpec   *pspec)
284 {
285   gboolean expand = 0;
286   gboolean fill = 0;
287   guint padding = 0;
288   GtkPackType pack_type = 0;
289   GList *list;
290
291   if (property_id != CHILD_PROP_POSITION)
292     gtk_box_query_child_packing (GTK_BOX (container),
293                                  child,
294                                  &expand,
295                                  &fill,
296                                  &padding,
297                                  &pack_type);
298   switch (property_id)
299     {
300       guint i;
301     case CHILD_PROP_EXPAND:
302       g_value_set_boolean (value, expand);
303       break;
304     case CHILD_PROP_FILL:
305       g_value_set_boolean (value, fill);
306       break;
307     case CHILD_PROP_PADDING:
308       g_value_set_uint (value, padding);
309       break;
310     case CHILD_PROP_PACK_TYPE:
311       g_value_set_enum (value, pack_type);
312       break;
313     case CHILD_PROP_POSITION:
314       i = 0;
315       for (list = GTK_BOX (container)->children; list; list = list->next)
316         {
317           GtkBoxChild *child_entry;
318
319           child_entry = list->data;
320           if (child_entry->widget == child)
321             break;
322           i++;
323         }
324       g_value_set_int (value, list ? i : -1);
325       break;
326     default:
327       GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
328       break;
329     }
330 }
331
332 /**
333  * gtk_box_pack_start:
334  * @box: a #GtkBox
335  * @child: the #GtkWidget to be added to @box
336  * @expand: %TRUE if the new child is to be given extra space allocated to
337  * @box.  The extra space will be divided evenly between all children of
338  * @box that use this option
339  * @fill: %TRUE if space given to @child by the @expand option is
340  *   actually allocated to @child, rather than just padding it.  This
341  *   parameter has no effect if @expand is set to %FALSE.  A child is
342  *   always allocated the full height of a #GtkHBox and the full width 
343  *   of a #GtkVBox. This option affects the other dimension
344  * @padding: extra space in pixels to put between this child and its
345  *   neighbors, over and above the global amount specified by
346  *   #GtkBox:spacing property.  If @child is a widget at one of the 
347  *   reference ends of @box, then @padding pixels are also put between 
348  *   @child and the reference edge of @box
349  *
350  * Adds @child to @box, packed with reference to the start of @box.
351  * The @child is packed after any other child packed with reference 
352  * to the start of @box.
353  */
354 void
355 gtk_box_pack_start (GtkBox    *box,
356                     GtkWidget *child,
357                     gboolean   expand,
358                     gboolean   fill,
359                     guint      padding)
360 {
361   GtkBoxChild *child_info;
362
363   g_return_if_fail (GTK_IS_BOX (box));
364   g_return_if_fail (GTK_IS_WIDGET (child));
365   g_return_if_fail (child->parent == NULL);
366
367   child_info = g_new (GtkBoxChild, 1);
368   child_info->widget = child;
369   child_info->padding = padding;
370   child_info->expand = expand ? TRUE : FALSE;
371   child_info->fill = fill ? TRUE : FALSE;
372   child_info->pack = GTK_PACK_START;
373   child_info->is_secondary = FALSE;
374
375   box->children = g_list_append (box->children, child_info);
376
377   gtk_widget_freeze_child_notify (child);
378
379   gtk_widget_set_parent (child, GTK_WIDGET (box));
380   
381   gtk_widget_child_notify (child, "expand");
382   gtk_widget_child_notify (child, "fill");
383   gtk_widget_child_notify (child, "padding");
384   gtk_widget_child_notify (child, "pack-type");
385   gtk_widget_child_notify (child, "position");
386   gtk_widget_thaw_child_notify (child);
387 }
388
389 /**
390  * gtk_box_pack_end:
391  * @box: a #GtkBox
392  * @child: the #GtkWidget to be added to @box
393  * @expand: %TRUE if the new child is to be given extra space allocated 
394  *   to @box. The extra space will be divided evenly between all children 
395  *   of @box that use this option
396  * @fill: %TRUE if space given to @child by the @expand option is
397  *   actually allocated to @child, rather than just padding it.  This
398  *   parameter has no effect if @expand is set to %FALSE.  A child is
399  *   always allocated the full height of a #GtkHBox and the full width 
400  *   of a #GtkVBox.  This option affects the other dimension
401  * @padding: extra space in pixels to put between this child and its
402  *   neighbors, over and above the global amount specified by
403  *   #GtkBox:spacing property.  If @child is a widget at one of the 
404  *   reference ends of @box, then @padding pixels are also put between 
405  *   @child and the reference edge of @box
406  *
407  * Adds @child to @box, packed with reference to the end of @box.  
408  * The @child is packed after (away from end of) any other child 
409  * packed with reference to the end of @box.
410  */
411 void
412 gtk_box_pack_end (GtkBox    *box,
413                   GtkWidget *child,
414                   gboolean   expand,
415                   gboolean   fill,
416                   guint      padding)
417 {
418   GtkBoxChild *child_info;
419
420   g_return_if_fail (GTK_IS_BOX (box));
421   g_return_if_fail (GTK_IS_WIDGET (child));
422   g_return_if_fail (child->parent == NULL);
423
424   child_info = g_new (GtkBoxChild, 1);
425   child_info->widget = child;
426   child_info->padding = padding;
427   child_info->expand = expand ? TRUE : FALSE;
428   child_info->fill = fill ? TRUE : FALSE;
429   child_info->pack = GTK_PACK_END;
430   child_info->is_secondary = FALSE;
431
432   box->children = g_list_append (box->children, child_info);
433
434   gtk_widget_freeze_child_notify (child);
435
436   gtk_widget_set_parent (child, GTK_WIDGET (box));
437
438   gtk_widget_child_notify (child, "expand");
439   gtk_widget_child_notify (child, "fill");
440   gtk_widget_child_notify (child, "padding");
441   gtk_widget_child_notify (child, "pack-type");
442   gtk_widget_child_notify (child, "position");
443   gtk_widget_thaw_child_notify (child);
444 }
445
446 /**
447  * gtk_box_pack_start_defaults:
448  * @box: a #GtkBox
449  * @widget: the #GtkWidget to be added to @box
450  *
451  * Adds @widget to @box, packed with reference to the start of @box.
452  * The child is packed after any other child packed with reference 
453  * to the start of @box. 
454  * 
455  * Parameters for how to pack the child @widget, #GtkBox:expand, 
456  * #GtkBox:fill and #GtkBox:padding, are given their default
457  * values, %TRUE, %TRUE, and 0, respectively.
458  */
459 void
460 gtk_box_pack_start_defaults (GtkBox    *box,
461                              GtkWidget *child)
462 {
463   gtk_box_pack_start (box, child, TRUE, TRUE, 0);
464 }
465
466 /**
467  * gtk_box_pack_end_defaults:
468  * @box: a #GtkBox
469  * @widget: the #GtkWidget to be added to @box
470  *
471  * Adds @widget to @box, packed with reference to the end of @box.
472  * The child is packed after any other child packed with reference 
473  * to the start of @box. 
474  * 
475  * Parameters for how to pack the child @widget, #GtkBox:expand, 
476  * #GtkBox:fill and #GtkBox:padding, are given their default
477  * values, %TRUE, %TRUE, and 0, respectively.
478  */
479 void
480 gtk_box_pack_end_defaults (GtkBox    *box,
481                            GtkWidget *child)
482 {
483   gtk_box_pack_end (box, child, TRUE, TRUE, 0);
484 }
485
486 /**
487  * gtk_box_set_homogeneous:
488  * @box: a #GtkBox
489  * @homogeneous: a boolean value, %TRUE to create equal allotments,
490  *   %FALSE for variable allotments
491  * 
492  * Sets the #GtkBox:homogeneous property of @box, controlling 
493  * whether or not all children of @box are given equal space 
494  * in the box.
495  */
496 void
497 gtk_box_set_homogeneous (GtkBox  *box,
498                          gboolean homogeneous)
499 {
500   g_return_if_fail (GTK_IS_BOX (box));
501
502   if ((homogeneous ? TRUE : FALSE) != box->homogeneous)
503     {
504       box->homogeneous = homogeneous ? TRUE : FALSE;
505       g_object_notify (G_OBJECT (box), "homogeneous");
506       gtk_widget_queue_resize (GTK_WIDGET (box));
507     }
508 }
509
510 /**
511  * gtk_box_get_homogeneous:
512  * @box: a #GtkBox
513  *
514  * Returns whether the box is homogeneous (all children are the
515  * same size). See gtk_box_set_homogeneous().
516  *
517  * Return value: %TRUE if the box is homogeneous.
518  **/
519 gboolean
520 gtk_box_get_homogeneous (GtkBox *box)
521 {
522   g_return_val_if_fail (GTK_IS_BOX (box), FALSE);
523
524   return box->homogeneous;
525 }
526
527 /**
528  * gtk_box_set_spacing:
529  * @box: a #GtkBox
530  * @spacing: the number of pixels to put between children
531  *
532  * Sets the #GtkBox:spacing property of @box, which is the 
533  * number of pixels to place between children of @box.
534  */
535 void
536 gtk_box_set_spacing (GtkBox *box,
537                      gint    spacing)
538 {
539   g_return_if_fail (GTK_IS_BOX (box));
540
541   if (spacing != box->spacing)
542     {
543       box->spacing = spacing;
544       g_object_notify (G_OBJECT (box), "spacing");
545       gtk_widget_queue_resize (GTK_WIDGET (box));
546     }
547 }
548
549 /**
550  * gtk_box_get_spacing:
551  * @box: a #GtkBox
552  * 
553  * Gets the value set by gtk_box_set_spacing().
554  * 
555  * Return value: spacing between children
556  **/
557 gint
558 gtk_box_get_spacing (GtkBox *box)
559 {
560   g_return_val_if_fail (GTK_IS_BOX (box), 0);
561
562   return box->spacing;
563 }
564
565 /**
566  * gtk_box_reorder_child:
567  * @box: a #GtkBox
568  * @child: the #GtkWidget to move
569  * @position: the new position for @child in the list of children 
570  *   of @box, starting from 0. If negative, indicates the end of 
571  *   the list
572  *
573  * Moves @child to a new @position in the list of @box children.  
574  * The list is the <structfield>children</structfield> field of
575  * #GtkBox-struct, and contains both widgets packed #GTK_PACK_START 
576  * as well as widgets packed #GTK_PACK_END, in the order that these 
577  * widgets were added to @box.
578  * 
579  * A widget's position in the @box children list determines where 
580  * the widget is packed into @box.  A child widget at some position 
581  * in the list will be packed just after all other widgets of the 
582  * same packing type that appear earlier in the list.
583  */ 
584 void
585 gtk_box_reorder_child (GtkBox    *box,
586                        GtkWidget *child,
587                        gint       position)
588 {
589   GList *old_link;
590   GList *new_link;
591   GtkBoxChild *child_info = NULL;
592   gint old_position;
593
594   g_return_if_fail (GTK_IS_BOX (box));
595   g_return_if_fail (GTK_IS_WIDGET (child));
596
597   old_link = box->children;
598   old_position = 0;
599   while (old_link)
600     {
601       child_info = old_link->data;
602       if (child_info->widget == child)
603         break;
604
605       old_link = old_link->next;
606       old_position++;
607     }
608
609   g_return_if_fail (old_link != NULL);
610
611   if (position == old_position)
612     return;
613
614   box->children = g_list_delete_link (box->children, old_link);
615
616   if (position < 0)
617     new_link = NULL;
618   else
619     new_link = g_list_nth (box->children, position);
620
621   box->children = g_list_insert_before (box->children, new_link, child_info);
622
623   gtk_widget_child_notify (child, "position");
624   if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (box))
625     gtk_widget_queue_resize (child);
626 }
627
628 /**
629  * gtk_box_query_child_packing:
630  * @box: a #GtkBox
631  * @child: the #GtkWidget of the child to query
632  * @expand: pointer to return location for #GtkBox:expand child property 
633  * @fill: pointer to return location for #GtkBox:fill child property 
634  * @padding: pointer to return location for #GtkBox:padding child property 
635  * @pack_type: pointer to return location for #GtkBox:pack-type child property 
636  * 
637  * Obtains information about how @child is packed into @box.
638  */
639 void
640 gtk_box_query_child_packing (GtkBox      *box,
641                              GtkWidget   *child,
642                              gboolean    *expand,
643                              gboolean    *fill,
644                              guint       *padding,
645                              GtkPackType *pack_type)
646 {
647   GList *list;
648   GtkBoxChild *child_info = NULL;
649
650   g_return_if_fail (GTK_IS_BOX (box));
651   g_return_if_fail (GTK_IS_WIDGET (child));
652
653   list = box->children;
654   while (list)
655     {
656       child_info = list->data;
657       if (child_info->widget == child)
658         break;
659
660       list = list->next;
661     }
662
663   if (list)
664     {
665       if (expand)
666         *expand = child_info->expand;
667       if (fill)
668         *fill = child_info->fill;
669       if (padding)
670         *padding = child_info->padding;
671       if (pack_type)
672         *pack_type = child_info->pack;
673     }
674 }
675
676 /**
677  * gtk_box_set_child_packing:
678  * @box: a #GtkBox
679  * @child: the #GtkWidget of the child to set
680  * @expand: the new value of the #GtkBox:expand child property 
681  * @fill: the new value of the #GtkBox:fill child property
682  * @padding: the new value of the #GtkBox:padding child property
683  * @pack_type: the new value of the #GtkBox:pack-type child property
684  *
685  * Sets the way @child is packed into @box.
686  */
687 void
688 gtk_box_set_child_packing (GtkBox      *box,
689                            GtkWidget   *child,
690                            gboolean     expand,
691                            gboolean     fill,
692                            guint        padding,
693                            GtkPackType  pack_type)
694 {
695   GList *list;
696   GtkBoxChild *child_info = NULL;
697
698   g_return_if_fail (GTK_IS_BOX (box));
699   g_return_if_fail (GTK_IS_WIDGET (child));
700
701   list = box->children;
702   while (list)
703     {
704       child_info = list->data;
705       if (child_info->widget == child)
706         break;
707
708       list = list->next;
709     }
710
711   gtk_widget_freeze_child_notify (child);
712   if (list)
713     {
714       child_info->expand = expand != FALSE;
715       gtk_widget_child_notify (child, "expand");
716       child_info->fill = fill != FALSE;
717       gtk_widget_child_notify (child, "fill");
718       child_info->padding = padding;
719       gtk_widget_child_notify (child, "padding");
720       if (pack_type == GTK_PACK_END)
721         child_info->pack = GTK_PACK_END;
722       else
723         child_info->pack = GTK_PACK_START;
724       gtk_widget_child_notify (child, "pack-type");
725
726       if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (box))
727         gtk_widget_queue_resize (child);
728     }
729   gtk_widget_thaw_child_notify (child);
730 }
731
732 static void
733 gtk_box_add (GtkContainer *container,
734              GtkWidget    *widget)
735 {
736   gtk_box_pack_start_defaults (GTK_BOX (container), widget);
737 }
738
739 static void
740 gtk_box_remove (GtkContainer *container,
741                 GtkWidget    *widget)
742 {
743   GtkBox *box;
744   GtkBoxChild *child;
745   GList *children;
746
747   box = GTK_BOX (container);
748
749   children = box->children;
750   while (children)
751     {
752       child = children->data;
753
754       if (child->widget == widget)
755         {
756           gboolean was_visible;
757
758           was_visible = GTK_WIDGET_VISIBLE (widget);
759           gtk_widget_unparent (widget);
760
761           box->children = g_list_remove_link (box->children, children);
762           g_list_free (children);
763           g_free (child);
764
765           /* queue resize regardless of GTK_WIDGET_VISIBLE (container),
766            * since that's what is needed by toplevels.
767            */
768           if (was_visible)
769             gtk_widget_queue_resize (GTK_WIDGET (container));
770
771           break;
772         }
773
774       children = children->next;
775     }
776 }
777
778 static void
779 gtk_box_forall (GtkContainer *container,
780                 gboolean      include_internals,
781                 GtkCallback   callback,
782                 gpointer      callback_data)
783 {
784   GtkBox *box;
785   GtkBoxChild *child;
786   GList *children;
787
788   g_return_if_fail (callback != NULL);
789
790   box = GTK_BOX (container);
791
792   children = box->children;
793   while (children)
794     {
795       child = children->data;
796       children = children->next;
797
798       if (child->pack == GTK_PACK_START)
799         (* callback) (child->widget, callback_data);
800     }
801
802   children = g_list_last (box->children);
803   while (children)
804     {
805       child = children->data;
806       children = children->prev;
807
808       if (child->pack == GTK_PACK_END)
809         (* callback) (child->widget, callback_data);
810     }
811 }
812
813 #define __GTK_BOX_C__
814 #include "gtkaliasdef.c"