]> Pileus Git - ~andy/gtk/blob - gtk/gtkhbbox.c
cf7932723564e48eb173058fe2f1a55a10e8e9f4
[~andy/gtk] / gtk / gtkhbbox.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 "gtkhbbox.h"
28
29
30 static void gtk_hbutton_box_class_init    (GtkHButtonBoxClass   *klass);
31 static void gtk_hbutton_box_init          (GtkHButtonBox        *box);
32 static void gtk_hbutton_box_size_request  (GtkWidget      *widget,
33                                            GtkRequisition *requisition);
34 static void gtk_hbutton_box_size_allocate (GtkWidget      *widget,
35                                            GtkAllocation  *allocation);
36
37 static gint default_spacing = 30;
38 static gint default_layout_style = GTK_BUTTONBOX_EDGE;
39
40 GType
41 gtk_hbutton_box_get_type (void)
42 {
43   static GType hbutton_box_type = 0;
44
45   if (!hbutton_box_type)
46     {
47       static const GTypeInfo hbutton_box_info =
48       {
49         sizeof (GtkHButtonBoxClass),
50         NULL,           /* base_init */
51         NULL,           /* base_finalize */
52         (GClassInitFunc) gtk_hbutton_box_class_init,
53         NULL,           /* class_finalize */
54         NULL,           /* class_data */
55         sizeof (GtkHButtonBox),
56         0,              /* n_preallocs */
57         (GInstanceInitFunc) gtk_hbutton_box_init,
58       };
59
60       hbutton_box_type =
61         g_type_register_static (GTK_TYPE_BUTTON_BOX, "GtkHButtonBox",
62                                 &hbutton_box_info, 0);
63     }
64
65   return hbutton_box_type;
66 }
67
68 static void
69 gtk_hbutton_box_class_init (GtkHButtonBoxClass *class)
70 {
71   GtkWidgetClass *widget_class;
72
73   widget_class = (GtkWidgetClass*) class;
74
75   widget_class->size_request = gtk_hbutton_box_size_request;
76   widget_class->size_allocate = gtk_hbutton_box_size_allocate;
77 }
78
79 static void
80 gtk_hbutton_box_init (GtkHButtonBox *hbutton_box)
81 {
82         /* button_box_init has done everything allready */
83 }
84
85 GtkWidget*
86 gtk_hbutton_box_new (void)
87 {
88   GtkHButtonBox *hbutton_box;
89
90   hbutton_box = g_object_new (GTK_TYPE_HBUTTON_BOX, NULL);
91
92   return GTK_WIDGET (hbutton_box);
93 }
94
95
96 /* set default value for spacing */
97
98 void 
99 gtk_hbutton_box_set_spacing_default (gint spacing)
100 {
101   default_spacing = spacing;
102 }
103
104
105 /* set default value for layout style */
106
107 void 
108 gtk_hbutton_box_set_layout_default (GtkButtonBoxStyle layout)
109 {
110   g_return_if_fail (layout >= GTK_BUTTONBOX_DEFAULT_STYLE &&
111                     layout <= GTK_BUTTONBOX_END);
112
113   default_layout_style = layout;
114 }
115
116 /* get default value for spacing */
117
118 gint 
119 gtk_hbutton_box_get_spacing_default (void)
120 {
121   return default_spacing;
122 }
123
124
125 /* get default value for layout style */
126
127 GtkButtonBoxStyle
128 gtk_hbutton_box_get_layout_default (void)
129 {
130   return default_layout_style;
131 }
132
133
134   
135 static void
136 gtk_hbutton_box_size_request (GtkWidget      *widget,
137                               GtkRequisition *requisition)
138 {
139   GtkBox *box;
140   GtkButtonBox *bbox;
141   gint nvis_children;
142   gint child_width;
143   gint child_height;
144   gint spacing;
145   GtkButtonBoxStyle layout;
146   
147   box = GTK_BOX (widget);
148   bbox = GTK_BUTTON_BOX (widget);
149
150   spacing = box->spacing;
151   layout = bbox->layout_style != GTK_BUTTONBOX_DEFAULT_STYLE
152           ? bbox->layout_style : default_layout_style;
153   
154   _gtk_button_box_child_requisition (widget,
155                                      &nvis_children,
156                                      NULL,
157                                      &child_width,
158                                      &child_height);
159
160   if (nvis_children == 0)
161   {
162     requisition->width = 0; 
163     requisition->height = 0;
164   }
165   else
166   {
167     switch (layout)
168     {
169     case GTK_BUTTONBOX_SPREAD:
170       requisition->width =
171               nvis_children*child_width + ((nvis_children+1)*spacing);
172       break;
173     case GTK_BUTTONBOX_EDGE:
174     case GTK_BUTTONBOX_START:
175     case GTK_BUTTONBOX_END:
176       requisition->width = nvis_children*child_width + ((nvis_children-1)*spacing);
177       break;
178     default:
179       g_assert_not_reached();
180       break;
181     }
182           
183     requisition->height = child_height;
184   }
185           
186   requisition->width += GTK_CONTAINER (box)->border_width * 2;
187   requisition->height += GTK_CONTAINER (box)->border_width * 2;
188 }
189
190
191
192 static void
193 gtk_hbutton_box_size_allocate (GtkWidget     *widget,
194                                GtkAllocation *allocation)
195 {
196   GtkBox *base_box;
197   GtkButtonBox *box;
198   GtkHButtonBox *hbox;
199   GtkBoxChild *child;
200   GList *children;
201   GtkAllocation child_allocation;
202   gint nvis_children;
203   gint n_secondaries;
204   gint child_width;
205   gint child_height;
206   gint x = 0;
207   gint secondary_x = 0;
208   gint y = 0;
209   gint width;
210   gint childspace;
211   gint childspacing = 0;
212   GtkButtonBoxStyle layout;
213   gint spacing;
214   
215   base_box = GTK_BOX (widget);
216   box = GTK_BUTTON_BOX (widget);
217   hbox = GTK_HBUTTON_BOX (widget);
218   spacing = base_box->spacing;
219   layout = box->layout_style != GTK_BUTTONBOX_DEFAULT_STYLE
220           ? box->layout_style : default_layout_style;
221   _gtk_button_box_child_requisition (widget,
222                                      &nvis_children,
223                                      &n_secondaries,
224                                      &child_width,
225                                      &child_height);
226   widget->allocation = *allocation;
227   width = allocation->width - GTK_CONTAINER (box)->border_width*2;
228   switch (layout)
229   {
230   case GTK_BUTTONBOX_SPREAD:
231     childspacing = (width - (nvis_children * child_width)) / (nvis_children + 1);
232     x = allocation->x + GTK_CONTAINER (box)->border_width + childspacing;
233     secondary_x = x + ((nvis_children - n_secondaries) * (child_width + childspacing));
234     break;
235   case GTK_BUTTONBOX_EDGE:
236     if (nvis_children >= 2)
237       {
238         childspacing = (width - (nvis_children * child_width)) / (nvis_children - 1);
239         x = allocation->x + GTK_CONTAINER (box)->border_width;
240         secondary_x = x + ((nvis_children - n_secondaries) * (child_width + childspacing));
241       }
242     else
243       {
244         /* one or zero children, just center */
245         childspacing = width;
246         x = secondary_x = allocation->x + (allocation->width - child_width) / 2;
247       }
248     break;
249   case GTK_BUTTONBOX_START:
250     childspacing = spacing;
251     x = allocation->x + GTK_CONTAINER (box)->border_width;
252     secondary_x = allocation->x + allocation->width 
253       - child_width * n_secondaries
254       - spacing * (n_secondaries - 1)
255       - GTK_CONTAINER (box)->border_width;
256     break;
257   case GTK_BUTTONBOX_END:
258     childspacing = spacing;
259     x = allocation->x + allocation->width 
260       - child_width * (nvis_children - n_secondaries)
261       - spacing * (nvis_children - n_secondaries - 1)
262       - GTK_CONTAINER (box)->border_width;
263     secondary_x = allocation->x + GTK_CONTAINER (box)->border_width;
264     break;
265   default:
266     g_assert_not_reached();
267     break;
268   }
269
270                   
271   y = allocation->y + (allocation->height - child_height) / 2;
272   childspace = child_width + childspacing;
273
274   children = GTK_BOX (box)->children;
275           
276   while (children)
277     {
278       child = children->data;
279       children = children->next;
280
281       if (GTK_WIDGET_VISIBLE (child->widget))
282         {
283           child_allocation.width = child_width;
284           child_allocation.height = child_height;
285           child_allocation.y = y;
286           
287           if (child->is_secondary)
288             {
289               child_allocation.x = secondary_x;
290               secondary_x += childspace;
291             }
292           else
293             {
294               child_allocation.x = x;
295               x += childspace;
296             }
297
298           if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
299             child_allocation.x = (allocation->x + allocation->width) - (child_allocation.x + child_width - allocation->x);
300           
301           gtk_widget_size_allocate (child->widget, &child_allocation);
302         }
303     }
304 }
305