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