1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
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.
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.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 static void gtk_box_class_init (GtkBoxClass *klass);
22 static void gtk_box_init (GtkBox *box);
23 static void gtk_box_destroy (GtkObject *object);
24 static void gtk_box_map (GtkWidget *widget);
25 static void gtk_box_unmap (GtkWidget *widget);
26 static void gtk_box_draw (GtkWidget *widget,
28 static gint gtk_box_expose (GtkWidget *widget,
29 GdkEventExpose *event);
30 static void gtk_box_add (GtkContainer *container,
32 static void gtk_box_remove (GtkContainer *container,
34 static void gtk_box_foreach (GtkContainer *container,
36 gpointer callback_data);
39 static GtkContainerClass *parent_class = NULL;
45 static guint box_type = 0;
49 GtkTypeInfo box_info =
54 (GtkClassInitFunc) gtk_box_class_init,
55 (GtkObjectInitFunc) gtk_box_init,
59 box_type = gtk_type_unique (gtk_container_get_type (), &box_info);
66 gtk_box_class_init (GtkBoxClass *class)
68 GtkObjectClass *object_class;
69 GtkWidgetClass *widget_class;
70 GtkContainerClass *container_class;
72 object_class = (GtkObjectClass*) class;
73 widget_class = (GtkWidgetClass*) class;
74 container_class = (GtkContainerClass*) class;
76 parent_class = gtk_type_class (gtk_container_get_type ());
78 object_class->destroy = gtk_box_destroy;
80 widget_class->map = gtk_box_map;
81 widget_class->unmap = gtk_box_unmap;
82 widget_class->draw = gtk_box_draw;
83 widget_class->expose_event = gtk_box_expose;
85 container_class->add = gtk_box_add;
86 container_class->remove = gtk_box_remove;
87 container_class->foreach = gtk_box_foreach;
91 gtk_box_init (GtkBox *box)
93 GTK_WIDGET_SET_FLAGS (box, GTK_NO_WINDOW | GTK_BASIC);
97 box->homogeneous = FALSE;
101 gtk_box_pack_start (GtkBox *box,
107 GtkBoxChild *child_info;
109 g_return_if_fail (box != NULL);
110 g_return_if_fail (GTK_IS_BOX (box));
111 g_return_if_fail (child != NULL);
113 child_info = g_new (GtkBoxChild, 1);
114 child_info->widget = child;
115 child_info->padding = padding;
116 child_info->expand = expand ? TRUE : FALSE;
117 child_info->fill = fill ? TRUE : FALSE;
118 child_info->pack = GTK_PACK_START;
120 box->children = g_list_append (box->children, child_info);
122 gtk_widget_set_parent (child, GTK_WIDGET (box));
124 if (GTK_WIDGET_VISIBLE (GTK_WIDGET (box)))
126 if (GTK_WIDGET_REALIZED (GTK_WIDGET (box)) &&
127 !GTK_WIDGET_REALIZED (child))
128 gtk_widget_realize (child);
130 if (GTK_WIDGET_MAPPED (GTK_WIDGET (box)) &&
131 !GTK_WIDGET_MAPPED (child))
132 gtk_widget_map (child);
135 if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (box))
136 gtk_widget_queue_resize (child);
140 gtk_box_pack_end (GtkBox *box,
146 GtkBoxChild *child_info;
148 g_return_if_fail (box != NULL);
149 g_return_if_fail (GTK_IS_BOX (box));
150 g_return_if_fail (child != NULL);
152 child_info = g_new (GtkBoxChild, 1);
153 child_info->widget = child;
154 child_info->padding = padding;
155 child_info->expand = expand ? TRUE : FALSE;
156 child_info->fill = fill ? TRUE : FALSE;
157 child_info->pack = GTK_PACK_END;
159 box->children = g_list_append (box->children, child_info);
161 gtk_widget_set_parent (child, GTK_WIDGET (box));
163 if (GTK_WIDGET_VISIBLE (GTK_WIDGET (box)))
165 if (GTK_WIDGET_REALIZED (GTK_WIDGET (box)) &&
166 !GTK_WIDGET_REALIZED (child))
167 gtk_widget_realize (child);
169 if (GTK_WIDGET_MAPPED (GTK_WIDGET (box)) &&
170 !GTK_WIDGET_MAPPED (child))
171 gtk_widget_map (child);
174 if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (box))
175 gtk_widget_queue_resize (child);
179 gtk_box_pack_start_defaults (GtkBox *box,
182 g_return_if_fail (box != NULL);
183 g_return_if_fail (GTK_IS_BOX (box));
184 g_return_if_fail (child != NULL);
186 gtk_box_pack_start (box, child, TRUE, TRUE, 0);
190 gtk_box_pack_end_defaults (GtkBox *box,
193 g_return_if_fail (box != NULL);
194 g_return_if_fail (GTK_IS_BOX (box));
195 g_return_if_fail (child != NULL);
197 gtk_box_pack_end (box, child, TRUE, TRUE, 0);
201 gtk_box_set_homogeneous (GtkBox *box,
204 g_return_if_fail (box != NULL);
205 g_return_if_fail (GTK_IS_BOX (box));
207 if ((homogeneous ? TRUE : FALSE) != box->homogeneous)
209 box->homogeneous = homogeneous ? TRUE : FALSE;
210 gtk_widget_queue_resize (GTK_WIDGET (box));
215 gtk_box_set_spacing (GtkBox *box,
218 g_return_if_fail (box != NULL);
219 g_return_if_fail (GTK_IS_BOX (box));
221 if (spacing != box->spacing)
223 box->spacing = spacing;
224 gtk_widget_queue_resize (GTK_WIDGET (box));
230 gtk_box_destroy (GtkObject *object)
236 g_return_if_fail (object != NULL);
237 g_return_if_fail (GTK_IS_BOX (object));
239 box = GTK_BOX (object);
241 children = box->children;
244 child = children->data;
245 children = children->next;
247 child->widget->parent = NULL;
248 gtk_object_unref (GTK_OBJECT (child->widget));
249 gtk_widget_destroy (child->widget);
253 g_list_free (box->children);
255 if (GTK_OBJECT_CLASS (parent_class)->destroy)
256 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
260 gtk_box_map (GtkWidget *widget)
266 g_return_if_fail (widget != NULL);
267 g_return_if_fail (GTK_IS_BOX (widget));
269 box = GTK_BOX (widget);
270 GTK_WIDGET_SET_FLAGS (box, GTK_MAPPED);
272 children = box->children;
275 child = children->data;
276 children = children->next;
278 if (GTK_WIDGET_VISIBLE (child->widget) &&
279 !GTK_WIDGET_MAPPED (child->widget))
280 gtk_widget_map (child->widget);
285 gtk_box_unmap (GtkWidget *widget)
291 g_return_if_fail (widget != NULL);
292 g_return_if_fail (GTK_IS_BOX (widget));
294 box = GTK_BOX (widget);
295 GTK_WIDGET_UNSET_FLAGS (box, GTK_MAPPED);
297 children = box->children;
300 child = children->data;
301 children = children->next;
303 if (GTK_WIDGET_VISIBLE (child->widget) &&
304 GTK_WIDGET_MAPPED (child->widget))
305 gtk_widget_unmap (child->widget);
310 gtk_box_draw (GtkWidget *widget,
315 GdkRectangle child_area;
318 g_return_if_fail (widget != NULL);
319 g_return_if_fail (GTK_IS_BOX (widget));
321 if (GTK_WIDGET_DRAWABLE (widget))
323 box = GTK_BOX (widget);
325 children = box->children;
328 child = children->data;
329 children = children->next;
331 if (gtk_widget_intersect (child->widget, area, &child_area))
332 gtk_widget_draw (child->widget, &child_area);
338 gtk_box_expose (GtkWidget *widget,
339 GdkEventExpose *event)
343 GdkEventExpose child_event;
346 g_return_val_if_fail (widget != NULL, FALSE);
347 g_return_val_if_fail (GTK_IS_BOX (widget), FALSE);
348 g_return_val_if_fail (event != NULL, FALSE);
350 if (GTK_WIDGET_DRAWABLE (widget))
352 box = GTK_BOX (widget);
354 child_event = *event;
356 children = box->children;
359 child = children->data;
360 children = children->next;
362 if (GTK_WIDGET_NO_WINDOW (child->widget) &&
363 gtk_widget_intersect (child->widget, &event->area, &child_event.area))
364 gtk_widget_event (child->widget, (GdkEvent*) &child_event);
372 gtk_box_add (GtkContainer *container,
375 g_return_if_fail (container != NULL);
376 g_return_if_fail (GTK_IS_BOX (container));
377 g_return_if_fail (widget != NULL);
379 gtk_box_pack_start_defaults (GTK_BOX (container), widget);
383 gtk_box_remove (GtkContainer *container,
390 g_return_if_fail (container != NULL);
391 g_return_if_fail (GTK_IS_BOX (container));
392 g_return_if_fail (widget != NULL);
394 box = GTK_BOX (container);
396 children = box->children;
399 child = children->data;
401 if (child->widget == widget)
403 gtk_widget_unparent (widget);
405 box->children = g_list_remove_link (box->children, children);
406 g_list_free (children);
409 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
410 gtk_widget_queue_resize (GTK_WIDGET (container));
415 children = children->next;
420 gtk_box_foreach (GtkContainer *container,
421 GtkCallback callback,
422 gpointer callback_data)
428 g_return_if_fail (container != NULL);
429 g_return_if_fail (GTK_IS_BOX (container));
430 g_return_if_fail (callback != NULL);
432 box = GTK_BOX (container);
434 children = box->children;
437 child = children->data;
438 children = children->next;
440 if (child->pack == GTK_PACK_START)
441 (* callback) (child->widget, callback_data);
444 children = g_list_last (box->children);
447 child = children->data;
448 children = children->prev;
450 if (child->pack == GTK_PACK_END)
451 (* callback) (child->widget, callback_data);