source: trunk/third/gtk/gtk/gtkvbox.c @ 14482

Revision 14482, 8.1 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r14481, which included commits to RCS files with non-trunk default branches.
Line 
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 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.
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 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library 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-1999.  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 "gtkvbox.h"
28
29
30static void gtk_vbox_class_init    (GtkVBoxClass   *klass);
31static void gtk_vbox_init          (GtkVBox        *box);
32static void gtk_vbox_size_request  (GtkWidget      *widget,
33                                    GtkRequisition *requisition);
34static void gtk_vbox_size_allocate (GtkWidget      *widget,
35                                    GtkAllocation  *allocation);
36
37
38GtkType
39gtk_vbox_get_type (void)
40{
41  static GtkType vbox_type = 0;
42
43  if (!vbox_type)
44    {
45      static const GtkTypeInfo vbox_info =
46      {
47        "GtkVBox",
48        sizeof (GtkVBox),
49        sizeof (GtkVBoxClass),
50        (GtkClassInitFunc) gtk_vbox_class_init,
51        (GtkObjectInitFunc) gtk_vbox_init,
52        /* reserved_1 */ NULL,
53        /* reserved_2 */ NULL,
54        (GtkClassInitFunc) NULL,
55      };
56
57      vbox_type = gtk_type_unique (GTK_TYPE_BOX, &vbox_info);
58    }
59
60  return vbox_type;
61}
62
63static void
64gtk_vbox_class_init (GtkVBoxClass *class)
65{
66  GtkWidgetClass *widget_class;
67
68  widget_class = (GtkWidgetClass*) class;
69
70  widget_class->size_request = gtk_vbox_size_request;
71  widget_class->size_allocate = gtk_vbox_size_allocate;
72}
73
74static void
75gtk_vbox_init (GtkVBox *vbox)
76{
77}
78
79GtkWidget*
80gtk_vbox_new (gboolean homogeneous,
81              gint spacing)
82{
83  GtkVBox *vbox;
84
85  vbox = gtk_type_new (gtk_vbox_get_type ());
86
87  GTK_BOX (vbox)->spacing = spacing;
88  GTK_BOX (vbox)->homogeneous = homogeneous ? TRUE : FALSE;
89
90  return GTK_WIDGET (vbox);
91}
92
93
94static void
95gtk_vbox_size_request (GtkWidget      *widget,
96                       GtkRequisition *requisition)
97{
98  GtkBox *box;
99  GtkBoxChild *child;
100  GtkRequisition child_requisition;
101  GList *children;
102  gint nvis_children;
103  gint height;
104
105  g_return_if_fail (widget != NULL);
106  g_return_if_fail (GTK_IS_VBOX (widget));
107  g_return_if_fail (requisition != NULL);
108
109  box = GTK_BOX (widget);
110  requisition->width = 0;
111  requisition->height = 0;
112  nvis_children = 0;
113
114  children = box->children;
115  while (children)
116    {
117      child = children->data;
118      children = children->next;
119
120      if (GTK_WIDGET_VISIBLE (child->widget))
121        {
122          gtk_widget_size_request (child->widget, &child_requisition);
123
124          if (box->homogeneous)
125            {
126              height = child_requisition.height + child->padding * 2;
127              requisition->height = MAX (requisition->height, height);
128            }
129          else
130            {
131              requisition->height += child_requisition.height + child->padding * 2;
132            }
133
134          requisition->width = MAX (requisition->width, child_requisition.width);
135
136          nvis_children += 1;
137        }
138    }
139
140  if (nvis_children > 0)
141    {
142      if (box->homogeneous)
143        requisition->height *= nvis_children;
144      requisition->height += (nvis_children - 1) * box->spacing;
145    }
146
147  requisition->width += GTK_CONTAINER (box)->border_width * 2;
148  requisition->height += GTK_CONTAINER (box)->border_width * 2;
149}
150
151static void
152gtk_vbox_size_allocate (GtkWidget     *widget,
153                        GtkAllocation *allocation)
154{
155  GtkBox *box;
156  GtkBoxChild *child;
157  GList *children;
158  GtkAllocation child_allocation;
159  gint nvis_children;
160  gint nexpand_children;
161  gint child_height;
162  gint height;
163  gint extra;
164  gint y;
165
166  g_return_if_fail (widget != NULL);
167  g_return_if_fail (GTK_IS_VBOX (widget));
168  g_return_if_fail (allocation != NULL);
169
170  box = GTK_BOX (widget);
171  widget->allocation = *allocation;
172
173  nvis_children = 0;
174  nexpand_children = 0;
175  children = box->children;
176
177  while (children)
178    {
179      child = children->data;
180      children = children->next;
181
182      if (GTK_WIDGET_VISIBLE (child->widget))
183        {
184          nvis_children += 1;
185          if (child->expand)
186            nexpand_children += 1;
187        }
188    }
189
190  if (nvis_children > 0)
191    {
192      if (box->homogeneous)
193        {
194          height = (allocation->height -
195                   GTK_CONTAINER (box)->border_width * 2 -
196                   (nvis_children - 1) * box->spacing);
197          extra = height / nvis_children;
198        }
199      else if (nexpand_children > 0)
200        {
201          height = (gint) allocation->height - (gint) widget->requisition.height;
202          extra = height / nexpand_children;
203        }
204      else
205        {
206          height = 0;
207          extra = 0;
208        }
209
210      y = allocation->y + GTK_CONTAINER (box)->border_width;
211      child_allocation.x = allocation->x + GTK_CONTAINER (box)->border_width;
212      child_allocation.width = MAX (1, (gint) allocation->width - (gint) GTK_CONTAINER (box)->border_width * 2);
213
214      children = box->children;
215      while (children)
216        {
217          child = children->data;
218          children = children->next;
219
220          if ((child->pack == GTK_PACK_START) && GTK_WIDGET_VISIBLE (child->widget))
221            {
222              if (box->homogeneous)
223                {
224                  if (nvis_children == 1)
225                    child_height = height;
226                  else
227                    child_height = extra;
228
229                  nvis_children -= 1;
230                  height -= extra;
231                }
232              else
233                {
234                  GtkRequisition child_requisition;
235
236                  gtk_widget_get_child_requisition (child->widget, &child_requisition);
237                  child_height = child_requisition.height + child->padding * 2;
238
239                  if (child->expand)
240                    {
241                      if (nexpand_children == 1)
242                        child_height += height;
243                      else
244                        child_height += extra;
245
246                      nexpand_children -= 1;
247                      height -= extra;
248                    }
249                }
250
251              if (child->fill)
252                {
253                  child_allocation.height = MAX (1, child_height - (gint)child->padding * 2);
254                  child_allocation.y = y + child->padding;
255                }
256              else
257                {
258                  GtkRequisition child_requisition;
259
260                  gtk_widget_get_child_requisition (child->widget, &child_requisition);
261                  child_allocation.height = child_requisition.height;
262                  child_allocation.y = y + (child_height - child_allocation.height) / 2;
263                }
264
265              gtk_widget_size_allocate (child->widget, &child_allocation);
266
267              y += child_height + box->spacing;
268            }
269        }
270
271      y = allocation->y + allocation->height - GTK_CONTAINER (box)->border_width;
272
273      children = box->children;
274      while (children)
275        {
276          child = children->data;
277          children = children->next;
278
279          if ((child->pack == GTK_PACK_END) && GTK_WIDGET_VISIBLE (child->widget))
280            {
281              GtkRequisition child_requisition;
282              gtk_widget_get_child_requisition (child->widget, &child_requisition);
283
284              if (box->homogeneous)
285                {
286                  if (nvis_children == 1)
287                    child_height = height;
288                  else
289                    child_height = extra;
290
291                  nvis_children -= 1;
292                  height -= extra;
293                }
294              else
295                {
296                  child_height = child_requisition.height + child->padding * 2;
297
298                  if (child->expand)
299                    {
300                      if (nexpand_children == 1)
301                        child_height += height;
302                      else
303                        child_height += extra;
304
305                      nexpand_children -= 1;
306                      height -= extra;
307                    }
308                }
309
310              if (child->fill)
311                {
312                  child_allocation.height = MAX (1, child_height - (gint)child->padding * 2);
313                  child_allocation.y = y + child->padding - child_height;
314                }
315              else
316                {
317                  child_allocation.height = child_requisition.height;
318                  child_allocation.y = y + (child_height - child_allocation.height) / 2 - child_height;
319                }
320
321              gtk_widget_size_allocate (child->widget, &child_allocation);
322
323              y -= (child_height + box->spacing);
324            }
325        }
326    }
327}
Note: See TracBrowser for help on using the repository browser.