]> Pileus Git - ~andy/gtk/blob - gtk/gtkbox.c
Bug 408244 – add GtkDialog::content-area-spacing
[~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->spacing_set = FALSE;
159   box->homogeneous = FALSE;
160 }
161
162 static void 
163 gtk_box_set_property (GObject         *object,
164                       guint            prop_id,
165                       const GValue    *value,
166                       GParamSpec      *pspec)
167 {
168   GtkBox *box;
169
170   box = GTK_BOX (object);
171
172   switch (prop_id)
173     {
174     case PROP_SPACING:
175       gtk_box_set_spacing (box, g_value_get_int (value));
176       break;
177     case PROP_HOMOGENEOUS:
178       gtk_box_set_homogeneous (box, g_value_get_boolean (value));
179       break;
180     default:
181       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
182       break;
183     }
184 }
185
186 static void gtk_box_get_property (GObject         *object,
187                                   guint            prop_id,
188                                   GValue          *value,
189                                   GParamSpec      *pspec)
190 {
191   GtkBox *box;
192
193   box = GTK_BOX (object);
194
195   switch (prop_id)
196     {
197     case PROP_SPACING:
198       g_value_set_int (value, box->spacing);
199       break;
200     case PROP_HOMOGENEOUS:
201       g_value_set_boolean (value, box->homogeneous);
202       break;
203     default:
204       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
205       break;
206     }
207 }
208
209 static GType
210 gtk_box_child_type (GtkContainer   *container)
211 {
212   return GTK_TYPE_WIDGET;
213 }
214
215 static void
216 gtk_box_set_child_property (GtkContainer    *container,
217                             GtkWidget       *child,
218                             guint            property_id,
219                             const GValue    *value,
220                             GParamSpec      *pspec)
221 {
222   gboolean expand = 0;
223   gboolean fill = 0;
224   guint padding = 0;
225   GtkPackType pack_type = 0;
226
227   if (property_id != CHILD_PROP_POSITION)
228     gtk_box_query_child_packing (GTK_BOX (container),
229                                  child,
230                                  &expand,
231                                  &fill,
232                                  &padding,
233                                  &pack_type);
234   switch (property_id)
235     {
236     case CHILD_PROP_EXPAND:
237       gtk_box_set_child_packing (GTK_BOX (container),
238                                  child,
239                                  g_value_get_boolean (value),
240                                  fill,
241                                  padding,
242                                  pack_type);
243       break;
244     case CHILD_PROP_FILL:
245       gtk_box_set_child_packing (GTK_BOX (container),
246                                  child,
247                                  expand,
248                                  g_value_get_boolean (value),
249                                  padding,
250                                  pack_type);
251       break;
252     case CHILD_PROP_PADDING:
253       gtk_box_set_child_packing (GTK_BOX (container),
254                                  child,
255                                  expand,
256                                  fill,
257                                  g_value_get_uint (value),
258                                  pack_type);
259       break;
260     case CHILD_PROP_PACK_TYPE:
261       gtk_box_set_child_packing (GTK_BOX (container),
262                                  child,
263                                  expand,
264                                  fill,
265                                  padding,
266                                  g_value_get_enum (value));
267       break;
268     case CHILD_PROP_POSITION:
269       gtk_box_reorder_child (GTK_BOX (container),
270                              child,
271                              g_value_get_int (value));
272       break;
273     default:
274       GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
275       break;
276     }
277 }
278
279 static void
280 gtk_box_get_child_property (GtkContainer *container,
281                             GtkWidget    *child,
282                             guint         property_id,
283                             GValue       *value,
284                             GParamSpec   *pspec)
285 {
286   gboolean expand = 0;
287   gboolean fill = 0;
288   guint padding = 0;
289   GtkPackType pack_type = 0;
290   GList *list;
291
292   if (property_id != CHILD_PROP_POSITION)
293     gtk_box_query_child_packing (GTK_BOX (container),
294                                  child,
295                                  &expand,
296                                  &fill,
297                                  &padding,
298                                  &pack_type);
299   switch (property_id)
300     {
301       guint i;
302     case CHILD_PROP_EXPAND:
303       g_value_set_boolean (value, expand);
304       break;
305     case CHILD_PROP_FILL:
306       g_value_set_boolean (value, fill);
307       break;
308     case CHILD_PROP_PADDING:
309       g_value_set_uint (value, padding);
310       break;
311     case CHILD_PROP_PACK_TYPE:
312       g_value_set_enum (value, pack_type);
313       break;
314     case CHILD_PROP_POSITION:
315       i = 0;
316       for (list = GTK_BOX (container)->children; list; list = list->next)
317         {
318           GtkBoxChild *child_entry;
319
320           child_entry = list->data;
321           if (child_entry->widget == child)
322             break;
323           i++;
324         }
325       g_value_set_int (value, list ? i : -1);
326       break;
327     default:
328       GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
329       break;
330     }
331 }
332
333 static void
334 gtk_box_pack (GtkBox      *box,
335               GtkWidget   *child,
336               gboolean     expand,
337               gboolean     fill,
338               guint        padding,
339               GtkPackType  pack_type)
340 {
341   GtkBoxChild *child_info;
342
343   g_return_if_fail (GTK_IS_BOX (box));
344   g_return_if_fail (GTK_IS_WIDGET (child));
345   g_return_if_fail (child->parent == NULL);
346
347   child_info = g_new (GtkBoxChild, 1);
348   child_info->widget = child;
349   child_info->padding = padding;
350   child_info->expand = expand ? TRUE : FALSE;
351   child_info->fill = fill ? TRUE : FALSE;
352   child_info->pack = pack_type;
353   child_info->is_secondary = FALSE;
354
355   box->children = g_list_append (box->children, child_info);
356
357   gtk_widget_freeze_child_notify (child);
358
359   gtk_widget_set_parent (child, GTK_WIDGET (box));
360   
361   gtk_widget_child_notify (child, "expand");
362   gtk_widget_child_notify (child, "fill");
363   gtk_widget_child_notify (child, "padding");
364   gtk_widget_child_notify (child, "pack-type");
365   gtk_widget_child_notify (child, "position");
366   gtk_widget_thaw_child_notify (child);
367 }
368
369 /**
370  * gtk_box_pack_start:
371  * @box: a #GtkBox
372  * @child: the #GtkWidget to be added to @box
373  * @expand: %TRUE if the new child is to be given extra space allocated to
374  * @box.  The extra space will be divided evenly between all children of
375  * @box that use this option
376  * @fill: %TRUE if space given to @child by the @expand option is
377  *   actually allocated to @child, rather than just padding it.  This
378  *   parameter has no effect if @expand is set to %FALSE.  A child is
379  *   always allocated the full height of a #GtkHBox and the full width 
380  *   of a #GtkVBox. This option affects the other dimension
381  * @padding: extra space in pixels to put between this child and its
382  *   neighbors, over and above the global amount specified by
383  *   #GtkBox:spacing property.  If @child is a widget at one of the 
384  *   reference ends of @box, then @padding pixels are also put between 
385  *   @child and the reference edge of @box
386  *
387  * Adds @child to @box, packed with reference to the start of @box.
388  * The @child is packed after any other child packed with reference 
389  * to the start of @box.
390  */
391 void
392 gtk_box_pack_start (GtkBox    *box,
393                     GtkWidget *child,
394                     gboolean   expand,
395                     gboolean   fill,
396                     guint      padding)
397 {
398   gtk_box_pack (box, child, expand, fill, padding, GTK_PACK_START);
399 }
400
401 /**
402  * gtk_box_pack_end:
403  * @box: a #GtkBox
404  * @child: the #GtkWidget to be added to @box
405  * @expand: %TRUE if the new child is to be given extra space allocated 
406  *   to @box. The extra space will be divided evenly between all children 
407  *   of @box that use this option
408  * @fill: %TRUE if space given to @child by the @expand option is
409  *   actually allocated to @child, rather than just padding it.  This
410  *   parameter has no effect if @expand is set to %FALSE.  A child is
411  *   always allocated the full height of a #GtkHBox and the full width 
412  *   of a #GtkVBox.  This option affects the other dimension
413  * @padding: extra space in pixels to put between this child and its
414  *   neighbors, over and above the global amount specified by
415  *   #GtkBox:spacing property.  If @child is a widget at one of the 
416  *   reference ends of @box, then @padding pixels are also put between 
417  *   @child and the reference edge of @box
418  *
419  * Adds @child to @box, packed with reference to the end of @box.  
420  * The @child is packed after (away from end of) any other child 
421  * packed with reference to the end of @box.
422  */
423 void
424 gtk_box_pack_end (GtkBox    *box,
425                   GtkWidget *child,
426                   gboolean   expand,
427                   gboolean   fill,
428                   guint      padding)
429 {
430   gtk_box_pack (box, child, expand, fill, padding, GTK_PACK_END);
431 }
432
433 /**
434  * gtk_box_pack_start_defaults:
435  * @box: a #GtkBox
436  * @widget: the #GtkWidget to be added to @box
437  *
438  * Adds @widget to @box, packed with reference to the start of @box.
439  * The child is packed after any other child packed with reference 
440  * to the start of @box. 
441  * 
442  * Parameters for how to pack the child @widget, #GtkBox:expand, 
443  * #GtkBox:fill and #GtkBox:padding, are given their default
444  * values, %TRUE, %TRUE, and 0, respectively.
445  *
446  * Deprecated: 2.14: Use gtk_box_pack_start()
447  */
448 void
449 gtk_box_pack_start_defaults (GtkBox    *box,
450                              GtkWidget *child)
451 {
452   gtk_box_pack_start (box, child, TRUE, TRUE, 0);
453 }
454
455 /**
456  * gtk_box_pack_end_defaults:
457  * @box: a #GtkBox
458  * @widget: the #GtkWidget to be added to @box
459  *
460  * Adds @widget to @box, packed with reference to the end of @box.
461  * The child is packed after any other child packed with reference 
462  * to the start of @box. 
463  * 
464  * Parameters for how to pack the child @widget, #GtkBox:expand, 
465  * #GtkBox:fill and #GtkBox:padding, are given their default
466  * values, %TRUE, %TRUE, and 0, respectively.
467  *
468  * Deprecated: 2.14: Use gtk_box_pack_end()
469  */
470 void
471 gtk_box_pack_end_defaults (GtkBox    *box,
472                            GtkWidget *child)
473 {
474   gtk_box_pack_end (box, child, TRUE, TRUE, 0);
475 }
476
477 /**
478  * gtk_box_set_homogeneous:
479  * @box: a #GtkBox
480  * @homogeneous: a boolean value, %TRUE to create equal allotments,
481  *   %FALSE for variable allotments
482  * 
483  * Sets the #GtkBox:homogeneous property of @box, controlling 
484  * whether or not all children of @box are given equal space 
485  * in the box.
486  */
487 void
488 gtk_box_set_homogeneous (GtkBox  *box,
489                          gboolean homogeneous)
490 {
491   g_return_if_fail (GTK_IS_BOX (box));
492
493   if ((homogeneous ? TRUE : FALSE) != box->homogeneous)
494     {
495       box->homogeneous = homogeneous ? TRUE : FALSE;
496       g_object_notify (G_OBJECT (box), "homogeneous");
497       gtk_widget_queue_resize (GTK_WIDGET (box));
498     }
499 }
500
501 /**
502  * gtk_box_get_homogeneous:
503  * @box: a #GtkBox
504  *
505  * Returns whether the box is homogeneous (all children are the
506  * same size). See gtk_box_set_homogeneous().
507  *
508  * Return value: %TRUE if the box is homogeneous.
509  **/
510 gboolean
511 gtk_box_get_homogeneous (GtkBox *box)
512 {
513   g_return_val_if_fail (GTK_IS_BOX (box), FALSE);
514
515   return box->homogeneous;
516 }
517
518 /**
519  * gtk_box_set_spacing:
520  * @box: a #GtkBox
521  * @spacing: the number of pixels to put between children
522  *
523  * Sets the #GtkBox:spacing property of @box, which is the 
524  * number of pixels to place between children of @box.
525  */
526 void
527 gtk_box_set_spacing (GtkBox *box,
528                      gint    spacing)
529 {
530   g_return_if_fail (GTK_IS_BOX (box));
531
532   if (spacing != box->spacing)
533     {
534       box->spacing = spacing;
535       box->spacing_set = TRUE;
536
537       g_object_notify (G_OBJECT (box), "spacing");
538
539       gtk_widget_queue_resize (GTK_WIDGET (box));
540     }
541 }
542
543 /**
544  * gtk_box_get_spacing:
545  * @box: a #GtkBox
546  * 
547  * Gets the value set by gtk_box_set_spacing().
548  * 
549  * Return value: spacing between children
550  **/
551 gint
552 gtk_box_get_spacing (GtkBox *box)
553 {
554   g_return_val_if_fail (GTK_IS_BOX (box), 0);
555
556   return box->spacing;
557 }
558
559 void
560 _gtk_box_set_spacing_set (GtkBox  *box,
561                           gboolean spacing_set)
562 {
563   g_return_if_fail (GTK_IS_BOX (box));
564
565   box->spacing_set = spacing_set;
566 }
567
568 gboolean
569 _gtk_box_get_spacing_set (GtkBox *box)
570 {
571   g_return_val_if_fail (GTK_IS_BOX (box), FALSE);
572
573   return box->spacing_set;
574 }
575
576 /**
577  * gtk_box_reorder_child:
578  * @box: a #GtkBox
579  * @child: the #GtkWidget to move
580  * @position: the new position for @child in the list of children 
581  *   of @box, starting from 0. If negative, indicates the end of 
582  *   the list
583  *
584  * Moves @child to a new @position in the list of @box children.  
585  * The list is the <structfield>children</structfield> field of
586  * #GtkBox-struct, and contains both widgets packed #GTK_PACK_START 
587  * as well as widgets packed #GTK_PACK_END, in the order that these 
588  * widgets were added to @box.
589  * 
590  * A widget's position in the @box children list determines where 
591  * the widget is packed into @box.  A child widget at some position 
592  * in the list will be packed just after all other widgets of the 
593  * same packing type that appear earlier in the list.
594  */ 
595 void
596 gtk_box_reorder_child (GtkBox    *box,
597                        GtkWidget *child,
598                        gint       position)
599 {
600   GList *old_link;
601   GList *new_link;
602   GtkBoxChild *child_info = NULL;
603   gint old_position;
604
605   g_return_if_fail (GTK_IS_BOX (box));
606   g_return_if_fail (GTK_IS_WIDGET (child));
607
608   old_link = box->children;
609   old_position = 0;
610   while (old_link)
611     {
612       child_info = old_link->data;
613       if (child_info->widget == child)
614         break;
615
616       old_link = old_link->next;
617       old_position++;
618     }
619
620   g_return_if_fail (old_link != NULL);
621
622   if (position == old_position)
623     return;
624
625   box->children = g_list_delete_link (box->children, old_link);
626
627   if (position < 0)
628     new_link = NULL;
629   else
630     new_link = g_list_nth (box->children, position);
631
632   box->children = g_list_insert_before (box->children, new_link, child_info);
633
634   gtk_widget_child_notify (child, "position");
635   if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (box))
636     gtk_widget_queue_resize (child);
637 }
638
639 /**
640  * gtk_box_query_child_packing:
641  * @box: a #GtkBox
642  * @child: the #GtkWidget of the child to query
643  * @expand: pointer to return location for #GtkBox:expand child property 
644  * @fill: pointer to return location for #GtkBox:fill child property 
645  * @padding: pointer to return location for #GtkBox:padding child property 
646  * @pack_type: pointer to return location for #GtkBox:pack-type child property 
647  * 
648  * Obtains information about how @child is packed into @box.
649  */
650 void
651 gtk_box_query_child_packing (GtkBox      *box,
652                              GtkWidget   *child,
653                              gboolean    *expand,
654                              gboolean    *fill,
655                              guint       *padding,
656                              GtkPackType *pack_type)
657 {
658   GList *list;
659   GtkBoxChild *child_info = NULL;
660
661   g_return_if_fail (GTK_IS_BOX (box));
662   g_return_if_fail (GTK_IS_WIDGET (child));
663
664   list = box->children;
665   while (list)
666     {
667       child_info = list->data;
668       if (child_info->widget == child)
669         break;
670
671       list = list->next;
672     }
673
674   if (list)
675     {
676       if (expand)
677         *expand = child_info->expand;
678       if (fill)
679         *fill = child_info->fill;
680       if (padding)
681         *padding = child_info->padding;
682       if (pack_type)
683         *pack_type = child_info->pack;
684     }
685 }
686
687 /**
688  * gtk_box_set_child_packing:
689  * @box: a #GtkBox
690  * @child: the #GtkWidget of the child to set
691  * @expand: the new value of the #GtkBox:expand child property 
692  * @fill: the new value of the #GtkBox:fill child property
693  * @padding: the new value of the #GtkBox:padding child property
694  * @pack_type: the new value of the #GtkBox:pack-type child property
695  *
696  * Sets the way @child is packed into @box.
697  */
698 void
699 gtk_box_set_child_packing (GtkBox      *box,
700                            GtkWidget   *child,
701                            gboolean     expand,
702                            gboolean     fill,
703                            guint        padding,
704                            GtkPackType  pack_type)
705 {
706   GList *list;
707   GtkBoxChild *child_info = NULL;
708
709   g_return_if_fail (GTK_IS_BOX (box));
710   g_return_if_fail (GTK_IS_WIDGET (child));
711
712   list = box->children;
713   while (list)
714     {
715       child_info = list->data;
716       if (child_info->widget == child)
717         break;
718
719       list = list->next;
720     }
721
722   gtk_widget_freeze_child_notify (child);
723   if (list)
724     {
725       child_info->expand = expand != FALSE;
726       gtk_widget_child_notify (child, "expand");
727       child_info->fill = fill != FALSE;
728       gtk_widget_child_notify (child, "fill");
729       child_info->padding = padding;
730       gtk_widget_child_notify (child, "padding");
731       if (pack_type == GTK_PACK_END)
732         child_info->pack = GTK_PACK_END;
733       else
734         child_info->pack = GTK_PACK_START;
735       gtk_widget_child_notify (child, "pack-type");
736
737       if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (box))
738         gtk_widget_queue_resize (child);
739     }
740   gtk_widget_thaw_child_notify (child);
741 }
742
743 static void
744 gtk_box_add (GtkContainer *container,
745              GtkWidget    *widget)
746 {
747   gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
748 }
749
750 static void
751 gtk_box_remove (GtkContainer *container,
752                 GtkWidget    *widget)
753 {
754   GtkBox *box = GTK_BOX (container);
755   GtkBoxChild *child;
756   GList *children;
757
758   children = box->children;
759   while (children)
760     {
761       child = children->data;
762
763       if (child->widget == widget)
764         {
765           gboolean was_visible;
766
767           was_visible = GTK_WIDGET_VISIBLE (widget);
768           gtk_widget_unparent (widget);
769
770           box->children = g_list_remove_link (box->children, children);
771           g_list_free (children);
772           g_free (child);
773
774           /* queue resize regardless of GTK_WIDGET_VISIBLE (container),
775            * since that's what is needed by toplevels.
776            */
777           if (was_visible)
778             gtk_widget_queue_resize (GTK_WIDGET (container));
779
780           break;
781         }
782
783       children = children->next;
784     }
785 }
786
787 static void
788 gtk_box_forall (GtkContainer *container,
789                 gboolean      include_internals,
790                 GtkCallback   callback,
791                 gpointer      callback_data)
792 {
793   GtkBox *box = GTK_BOX (container);
794   GtkBoxChild *child;
795   GList *children;
796
797   children = box->children;
798   while (children)
799     {
800       child = children->data;
801       children = children->next;
802
803       if (child->pack == GTK_PACK_START)
804         (* callback) (child->widget, callback_data);
805     }
806
807   children = g_list_last (box->children);
808   while (children)
809     {
810       child = children->data;
811       children = children->prev;
812
813       if (child->pack == GTK_PACK_END)
814         (* callback) (child->widget, callback_data);
815     }
816 }
817
818 #define __GTK_BOX_C__
819 #include "gtkaliasdef.c"