1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library 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.
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 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 static void gtk_vbox_class_init (GtkVBoxClass *klass);
22 static void gtk_vbox_init (GtkVBox *box);
23 static void gtk_vbox_size_request (GtkWidget *widget,
24 GtkRequisition *requisition);
25 static void gtk_vbox_size_allocate (GtkWidget *widget,
26 GtkAllocation *allocation);
32 static guint vbox_type = 0;
36 GtkTypeInfo vbox_info =
40 sizeof (GtkVBoxClass),
41 (GtkClassInitFunc) gtk_vbox_class_init,
42 (GtkObjectInitFunc) gtk_vbox_init,
46 vbox_type = gtk_type_unique (gtk_box_get_type (), &vbox_info);
53 gtk_vbox_class_init (GtkVBoxClass *class)
55 GtkWidgetClass *widget_class;
57 widget_class = (GtkWidgetClass*) class;
59 widget_class->size_request = gtk_vbox_size_request;
60 widget_class->size_allocate = gtk_vbox_size_allocate;
64 gtk_vbox_init (GtkVBox *vbox)
69 gtk_vbox_new (gint homogeneous,
74 vbox = gtk_type_new (gtk_vbox_get_type ());
76 GTK_BOX (vbox)->spacing = spacing;
77 GTK_BOX (vbox)->homogeneous = homogeneous ? TRUE : FALSE;
79 return GTK_WIDGET (vbox);
84 gtk_vbox_size_request (GtkWidget *widget,
85 GtkRequisition *requisition)
93 g_return_if_fail (widget != NULL);
94 g_return_if_fail (GTK_IS_VBOX (widget));
95 g_return_if_fail (requisition != NULL);
97 box = GTK_BOX (widget);
98 requisition->width = 0;
99 requisition->height = 0;
102 children = box->children;
105 child = children->data;
106 children = children->next;
108 if (GTK_WIDGET_VISIBLE (child->widget))
110 gtk_widget_size_request (child->widget, &child->widget->requisition);
112 if (box->homogeneous)
114 height = child->widget->requisition.height + child->padding * 2;
115 requisition->height = MAX (requisition->height, height);
119 requisition->height += child->widget->requisition.height + child->padding * 2;
122 requisition->width = MAX (requisition->width, child->widget->requisition.width);
128 if (nvis_children > 0)
130 if (box->homogeneous)
131 requisition->height *= nvis_children;
132 requisition->height += (nvis_children - 1) * box->spacing;
135 requisition->width += GTK_CONTAINER (box)->border_width * 2;
136 requisition->height += GTK_CONTAINER (box)->border_width * 2;
140 gtk_vbox_size_allocate (GtkWidget *widget,
141 GtkAllocation *allocation)
146 GtkAllocation child_allocation;
148 gint nexpand_children;
154 g_return_if_fail (widget != NULL);
155 g_return_if_fail (GTK_IS_VBOX (widget));
156 g_return_if_fail (allocation != NULL);
158 box = GTK_BOX (widget);
159 widget->allocation = *allocation;
162 nexpand_children = 0;
163 children = box->children;
167 child = children->data;
168 children = children->next;
170 if (GTK_WIDGET_VISIBLE (child->widget))
174 nexpand_children += 1;
178 if (nvis_children > 0)
180 if (box->homogeneous)
182 height = (allocation->height -
183 GTK_CONTAINER (box)->border_width * 2 -
184 (nvis_children - 1) * box->spacing);
185 extra = height / nvis_children;
187 else if (nexpand_children > 0)
189 height = allocation->height - widget->requisition.height;
190 extra = height / nexpand_children;
198 y = allocation->y + GTK_CONTAINER (box)->border_width;
199 child_allocation.x = allocation->x + GTK_CONTAINER (box)->border_width;
200 child_allocation.width = allocation->width - GTK_CONTAINER (box)->border_width * 2;
202 children = box->children;
205 child = children->data;
206 children = children->next;
208 if ((child->pack == GTK_PACK_START) && GTK_WIDGET_VISIBLE (child->widget))
210 if (box->homogeneous)
212 if (nvis_children == 1)
213 child_height = height;
215 child_height = extra;
222 child_height = child->widget->requisition.height + child->padding * 2;
226 if (nexpand_children == 1)
227 child_height += height;
229 child_height += extra;
231 nexpand_children -= 1;
238 child_allocation.height = child_height - child->padding * 2;
239 child_allocation.y = y + child->padding;
243 child_allocation.height = child->widget->requisition.height;
244 child_allocation.y = y + (child_height - child_allocation.height) / 2;
247 gtk_widget_size_allocate (child->widget, &child_allocation);
249 y += child_height + box->spacing;
253 y = allocation->y + allocation->height - GTK_CONTAINER (box)->border_width;
255 children = box->children;
258 child = children->data;
259 children = children->next;
261 if ((child->pack == GTK_PACK_END) && GTK_WIDGET_VISIBLE (child->widget))
263 if (box->homogeneous)
265 if (nvis_children == 1)
266 child_height = height;
268 child_height = extra;
275 child_height = child->widget->requisition.height + child->padding * 2;
279 if (nexpand_children == 1)
280 child_height += height;
282 child_height += extra;
284 nexpand_children -= 1;
291 child_allocation.height = child_height - child->padding * 2;
292 child_allocation.y = y + child->padding - child_height;
296 child_allocation.height = child->widget->requisition.height;
297 child_allocation.y = y + (child_height - child_allocation.height) / 2 - child_height;
300 gtk_widget_size_allocate (child->widget, &child_allocation);
302 y -= (child_height + box->spacing);