]> Pileus Git - ~andy/gtk/blob - gtk/gtkvbbox.c
8c9860ecb10edcd27876413c7cfadb8573b70102
[~andy/gtk] / gtk / gtkvbbox.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 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 #include "gtkvbbox.h"
20
21
22 static void gtk_vbutton_box_class_init    (GtkVButtonBoxClass   *klass);
23 static void gtk_vbutton_box_init          (GtkVButtonBox        *box);
24 static void gtk_vbutton_box_size_request  (GtkWidget      *widget,
25                                            GtkRequisition *requisition);
26 static void gtk_vbutton_box_size_allocate (GtkWidget      *widget,
27                                            GtkAllocation  *allocation);
28
29 static gint default_spacing = 10;
30 static GtkButtonBoxStyle default_layout_style = GTK_BUTTONBOX_EDGE;
31
32 guint
33 gtk_vbutton_box_get_type (void)
34 {
35   static guint vbutton_box_type = 0;
36
37   if (!vbutton_box_type)
38     {
39       GtkTypeInfo vbutton_box_info =
40       {
41         "GtkVButtonBox",
42         sizeof (GtkVButtonBox),
43         sizeof (GtkVButtonBoxClass),
44         (GtkClassInitFunc) gtk_vbutton_box_class_init,
45         (GtkObjectInitFunc) gtk_vbutton_box_init,
46         (GtkArgSetFunc) NULL,
47         (GtkArgGetFunc) NULL,
48       };
49
50       vbutton_box_type = gtk_type_unique (gtk_button_box_get_type (), &vbutton_box_info);
51     }
52
53   return vbutton_box_type;
54 }
55
56 static void
57 gtk_vbutton_box_class_init (GtkVButtonBoxClass *class)
58 {
59   GtkWidgetClass *widget_class;
60
61   widget_class = (GtkWidgetClass*) class;
62
63   widget_class->size_request = gtk_vbutton_box_size_request;
64   widget_class->size_allocate = gtk_vbutton_box_size_allocate;
65 }
66
67 static void
68 gtk_vbutton_box_init (GtkVButtonBox *vbutton_box)
69 {
70   /* button_box_init has done everything allready */
71 }
72
73 GtkWidget*
74 gtk_vbutton_box_new (void)
75 {
76   GtkVButtonBox *vbutton_box;
77
78   vbutton_box = gtk_type_new (gtk_vbutton_box_get_type ());
79   return GTK_WIDGET (vbutton_box);
80 }
81
82
83
84 /* set default value for spacing */
85
86 void gtk_vbutton_box_set_spacing_default (gint spacing)
87 {
88   default_spacing = spacing;
89 }
90
91
92 /* set default value for layout style */
93
94 void gtk_vbutton_box_set_layout_default (GtkButtonBoxStyle layout)
95 {
96   g_return_if_fail (layout >= GTK_BUTTONBOX_DEFAULT_STYLE &&
97                     layout <= GTK_BUTTONBOX_END);
98
99   default_layout_style = layout;
100 }
101
102 /* get default value for spacing */
103
104 gint gtk_vbutton_box_get_spacing_default (void)
105 {
106   return default_spacing;
107 }
108
109
110
111 /* get default value for layout style */
112
113 GtkButtonBoxStyle gtk_vbutton_box_get_layout_default (void)
114 {
115   return default_layout_style;
116 }
117
118
119
120
121 static void
122 gtk_vbutton_box_size_request (GtkWidget      *widget,
123                               GtkRequisition *requisition)
124 {
125   GtkBox *box;
126   GtkButtonBox *bbox;
127   gint nvis_children;
128   gint child_width;
129   gint child_height;
130   gint spacing;
131   GtkButtonBoxStyle layout;
132   
133   g_return_if_fail (widget != NULL);
134   g_return_if_fail (GTK_IS_VBUTTON_BOX (widget));
135   g_return_if_fail (requisition != NULL);
136
137   box = GTK_BOX (widget);
138   bbox = GTK_BUTTON_BOX (widget);
139
140   spacing = bbox->spacing != GTK_BUTTONBOX_DEFAULT
141           ? bbox->spacing : default_spacing;
142   layout = bbox->layout_style != GTK_BUTTONBOX_DEFAULT_STYLE
143           ? bbox->layout_style : default_layout_style;
144   
145   gtk_button_box_child_requisition (widget,
146                                     &nvis_children,
147                                     &child_width,
148                                     &child_height);
149
150   if (nvis_children == 0)
151     {
152       requisition->width = 0; 
153       requisition->height = 0;
154     }
155   else
156     {
157       switch (layout)
158       {
159       case GTK_BUTTONBOX_SPREAD:
160         requisition->height =
161                 nvis_children*child_height + ((nvis_children+1)*spacing);
162         break;
163       case GTK_BUTTONBOX_EDGE:
164       case GTK_BUTTONBOX_START:
165       case GTK_BUTTONBOX_END:
166         requisition->height =
167                 nvis_children*child_height + ((nvis_children-1)*spacing);
168         break;
169       default:
170             g_assert_not_reached();
171             break;
172       }
173           
174       requisition->width = child_width;
175     }
176           
177   requisition->width += GTK_CONTAINER (box)->border_width * 2;
178   requisition->height += GTK_CONTAINER (box)->border_width * 2;
179 }
180
181
182
183 static void
184 gtk_vbutton_box_size_allocate (GtkWidget     *widget,
185                                GtkAllocation *allocation)
186 {
187   GtkButtonBox *box;
188   GtkVButtonBox *hbox;
189   GtkBoxChild *child;
190   GList *children;
191   GtkAllocation child_allocation;
192   gint nvis_children;
193   gint child_width;
194   gint child_height;
195   gint x = 0;
196   gint y = 0;
197   gint height;
198   gint childspace;
199   gint childspacing = 0;
200   GtkButtonBoxStyle layout;
201   gint spacing;
202   
203   g_return_if_fail (widget != NULL);
204   g_return_if_fail (GTK_IS_VBUTTON_BOX (widget));
205   g_return_if_fail (allocation != NULL);
206
207   box = GTK_BUTTON_BOX (widget);
208   hbox = GTK_VBUTTON_BOX (widget);
209   spacing = box->spacing != GTK_BUTTONBOX_DEFAULT
210           ? box->spacing : default_spacing;
211   layout = box->layout_style != GTK_BUTTONBOX_DEFAULT_STYLE
212           ? box->layout_style : default_layout_style;
213   gtk_button_box_child_requisition (widget,
214                                     &nvis_children,
215                                     &child_width,
216                                     &child_height);
217   widget->allocation = *allocation;
218   height = allocation->height - GTK_CONTAINER (box)->border_width*2;
219   switch (layout)
220   {
221   case GTK_BUTTONBOX_SPREAD:
222     childspacing = (height - (nvis_children*child_height)) / (nvis_children+1);
223     y = allocation->y + GTK_CONTAINER (box)->border_width + childspacing;
224     break;
225   case GTK_BUTTONBOX_EDGE:
226     if (nvis_children >= 2)
227       {
228         childspacing =
229                 (height - (nvis_children*child_height)) / (nvis_children-1);
230         y = allocation->y + GTK_CONTAINER (box)->border_width;
231       }
232     else
233       {
234                       /* one or zero children, just center */
235               childspacing = height;
236               y = allocation->y + (allocation->height - child_height) / 2;
237       }
238     break;
239   case GTK_BUTTONBOX_START:
240     childspacing = spacing;
241     y = allocation->y + GTK_CONTAINER (box)->border_width;
242     break;
243   case GTK_BUTTONBOX_END:
244     childspacing = spacing;
245     y = allocation->x + allocation->height - child_height * nvis_children
246             - spacing * (nvis_children-1)
247             - GTK_CONTAINER (box)->border_width;
248     break;
249   default:
250     g_assert_not_reached();
251     break;
252   }
253                   
254   
255   x = allocation->x + (allocation->width - child_width) / 2;
256   childspace = child_height + childspacing;
257
258   children = GTK_BOX (box)->children;
259           
260   while (children)
261     {
262       child = children->data;
263       children = children->next;
264
265       if (GTK_WIDGET_VISIBLE (child->widget))
266         {
267           child_allocation.width = child_width;
268           child_allocation.height = child_height;
269           child_allocation.x = x;
270           child_allocation.y = y;
271           gtk_widget_size_allocate (child->widget, &child_allocation);
272           y += childspace;
273         }
274     }
275 }
276   
277