]> Pileus Git - ~andy/gtk/blob - gtk/gtkvbox.c
Revert name change
[~andy/gtk] / gtk / gtkvbox.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 "gtkvbox.h"
29 #include "gtkintl.h"
30 #include "gtkalias.h"
31
32
33 static void gtk_vbox_size_request  (GtkWidget      *widget,
34                                     GtkRequisition *requisition);
35 static void gtk_vbox_size_allocate (GtkWidget      *widget,
36                                     GtkAllocation  *allocation);
37
38 G_DEFINE_TYPE (GtkVBox, gtk_vbox, GTK_TYPE_BOX)
39
40 static void
41 gtk_vbox_class_init (GtkVBoxClass *class)
42 {
43   GtkWidgetClass *widget_class;
44
45   widget_class = (GtkWidgetClass*) class;
46
47   widget_class->size_request = gtk_vbox_size_request;
48   widget_class->size_allocate = gtk_vbox_size_allocate;
49 }
50
51 static void
52 gtk_vbox_init (GtkVBox *vbox)
53 {
54 }
55
56 GtkWidget*
57 gtk_vbox_new (gboolean homogeneous,
58               gint spacing)
59 {
60   GtkVBox *vbox;
61
62   vbox = g_object_new (GTK_TYPE_VBOX, NULL);
63
64   GTK_BOX (vbox)->spacing = spacing;
65   GTK_BOX (vbox)->homogeneous = homogeneous ? TRUE : FALSE;
66
67   return GTK_WIDGET (vbox);
68 }
69
70
71 static void
72 gtk_vbox_size_request (GtkWidget      *widget,
73                        GtkRequisition *requisition)
74 {
75   GtkBox *box;
76   GtkBoxChild *child;
77   GtkRequisition child_requisition;
78   GList *children;
79   gint nvis_children;
80   gint height;
81
82   box = GTK_BOX (widget);
83   requisition->width = 0;
84   requisition->height = 0;
85   nvis_children = 0;
86
87   children = box->children;
88   while (children)
89     {
90       child = children->data;
91       children = children->next;
92
93       if (GTK_WIDGET_VISIBLE (child->widget))
94         {
95           gtk_widget_size_request (child->widget, &child_requisition);
96
97           if (box->homogeneous)
98             {
99               height = child_requisition.height + child->padding * 2;
100               requisition->height = MAX (requisition->height, height);
101             }
102           else
103             {
104               requisition->height += child_requisition.height + child->padding * 2;
105             }
106
107           requisition->width = MAX (requisition->width, child_requisition.width);
108
109           nvis_children += 1;
110         }
111     }
112
113   if (nvis_children > 0)
114     {
115       if (box->homogeneous)
116         requisition->height *= nvis_children;
117       requisition->height += (nvis_children - 1) * box->spacing;
118     }
119
120   requisition->width += GTK_CONTAINER (box)->border_width * 2;
121   requisition->height += GTK_CONTAINER (box)->border_width * 2;
122 }
123
124 static void
125 gtk_vbox_size_allocate (GtkWidget     *widget,
126                         GtkAllocation *allocation)
127 {
128   GtkBox *box;
129   GtkBoxChild *child;
130   GList *children;
131   GtkAllocation child_allocation;
132   gint nvis_children;
133   gint nexpand_children;
134   gint child_height;
135   gint height;
136   gint extra;
137   gint y;
138
139   box = GTK_BOX (widget);
140   widget->allocation = *allocation;
141
142   nvis_children = 0;
143   nexpand_children = 0;
144   children = box->children;
145
146   while (children)
147     {
148       child = children->data;
149       children = children->next;
150
151       if (GTK_WIDGET_VISIBLE (child->widget))
152         {
153           nvis_children += 1;
154           if (child->expand)
155             nexpand_children += 1;
156         }
157     }
158
159   if (nvis_children > 0)
160     {
161       if (box->homogeneous)
162         {
163           height = (allocation->height -
164                    GTK_CONTAINER (box)->border_width * 2 -
165                    (nvis_children - 1) * box->spacing);
166           extra = height / nvis_children;
167         }
168       else if (nexpand_children > 0)
169         {
170           height = (gint) allocation->height - (gint) widget->requisition.height;
171           extra = height / nexpand_children;
172         }
173       else
174         {
175           height = 0;
176           extra = 0;
177         }
178
179       y = allocation->y + GTK_CONTAINER (box)->border_width;
180       child_allocation.x = allocation->x + GTK_CONTAINER (box)->border_width;
181       child_allocation.width = MAX (1, (gint) allocation->width - (gint) GTK_CONTAINER (box)->border_width * 2);
182
183       children = box->children;
184       while (children)
185         {
186           child = children->data;
187           children = children->next;
188
189           if ((child->pack == GTK_PACK_START) && GTK_WIDGET_VISIBLE (child->widget))
190             {
191               if (box->homogeneous)
192                 {
193                   if (nvis_children == 1)
194                     child_height = height;
195                   else
196                     child_height = extra;
197
198                   nvis_children -= 1;
199                   height -= extra;
200                 }
201               else
202                 {
203                   GtkRequisition child_requisition;
204
205                   gtk_widget_get_child_requisition (child->widget, &child_requisition);
206                   child_height = child_requisition.height + child->padding * 2;
207
208                   if (child->expand)
209                     {
210                       if (nexpand_children == 1)
211                         child_height += height;
212                       else
213                         child_height += extra;
214
215                       nexpand_children -= 1;
216                       height -= extra;
217                     }
218                 }
219
220               if (child->fill)
221                 {
222                   child_allocation.height = MAX (1, child_height - (gint)child->padding * 2);
223                   child_allocation.y = y + child->padding;
224                 }
225               else
226                 {
227                   GtkRequisition child_requisition;
228
229                   gtk_widget_get_child_requisition (child->widget, &child_requisition);
230                   child_allocation.height = child_requisition.height;
231                   child_allocation.y = y + (child_height - child_allocation.height) / 2;
232                 }
233
234               gtk_widget_size_allocate (child->widget, &child_allocation);
235
236               y += child_height + box->spacing;
237             }
238         }
239
240       y = allocation->y + allocation->height - GTK_CONTAINER (box)->border_width;
241
242       children = box->children;
243       while (children)
244         {
245           child = children->data;
246           children = children->next;
247
248           if ((child->pack == GTK_PACK_END) && GTK_WIDGET_VISIBLE (child->widget))
249             {
250               GtkRequisition child_requisition;
251               gtk_widget_get_child_requisition (child->widget, &child_requisition);
252
253               if (box->homogeneous)
254                 {
255                   if (nvis_children == 1)
256                     child_height = height;
257                   else
258                     child_height = extra;
259
260                   nvis_children -= 1;
261                   height -= extra;
262                 }
263               else
264                 {
265                   child_height = child_requisition.height + child->padding * 2;
266
267                   if (child->expand)
268                     {
269                       if (nexpand_children == 1)
270                         child_height += height;
271                       else
272                         child_height += extra;
273
274                       nexpand_children -= 1;
275                       height -= extra;
276                     }
277                 }
278
279               if (child->fill)
280                 {
281                   child_allocation.height = MAX (1, child_height - (gint)child->padding * 2);
282                   child_allocation.y = y + child->padding - child_height;
283                 }
284               else
285                 {
286                   child_allocation.height = child_requisition.height;
287                   child_allocation.y = y + (child_height - child_allocation.height) / 2 - child_height;
288                 }
289
290               gtk_widget_size_allocate (child->widget, &child_allocation);
291
292               y -= (child_height + box->spacing);
293             }
294         }
295     }
296 }
297
298 #define __GTK_VBOX_C__
299 #include "gtkaliasdef.c"