1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 * GtkToolbar copyright (C) Federico Mena
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free
17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include "gtktoolbar.h"
23 #define DEFAULT_SPACE_SIZE 5
33 static void gtk_toolbar_class_init (GtkToolbarClass *class);
34 static void gtk_toolbar_init (GtkToolbar *toolbar);
35 static void gtk_toolbar_destroy (GtkObject *object);
36 static void gtk_toolbar_map (GtkWidget *widget);
37 static void gtk_toolbar_unmap (GtkWidget *widget);
38 static void gtk_toolbar_draw (GtkWidget *widget,
40 static void gtk_toolbar_size_request (GtkWidget *widget,
41 GtkRequisition *requisition);
42 static void gtk_toolbar_size_allocate (GtkWidget *widget,
43 GtkAllocation *allocation);
44 static void gtk_toolbar_add (GtkContainer *container,
47 static GtkContainerClass *parent_class;
51 gtk_toolbar_get_type(void)
53 static guint toolbar_type = 0;
56 GtkTypeInfo toolbar_info = {
59 sizeof(GtkToolbarClass),
60 (GtkClassInitFunc) gtk_toolbar_class_init,
61 (GtkObjectInitFunc) gtk_toolbar_init,
65 toolbar_type = gtk_type_unique(gtk_container_get_type(), &toolbar_info);
72 gtk_toolbar_class_init(GtkToolbarClass *class)
74 GtkObjectClass *object_class;
75 GtkWidgetClass *widget_class;
76 GtkContainerClass *container_class;
78 object_class = (GtkObjectClass *) class;
79 widget_class = (GtkWidgetClass *) class;
80 container_class = (GtkContainerClass *) class;
82 parent_class = gtk_type_class(gtk_container_get_type());
84 object_class->destroy = gtk_toolbar_destroy;
86 widget_class->map = gtk_toolbar_map;
87 widget_class->unmap = gtk_toolbar_unmap;
88 widget_class->draw = gtk_toolbar_draw;
89 widget_class->size_request = gtk_toolbar_size_request;
90 widget_class->size_allocate = gtk_toolbar_size_allocate;
92 container_class->add = gtk_toolbar_add;
96 gtk_toolbar_init(GtkToolbar *toolbar)
98 GTK_WIDGET_SET_FLAGS(toolbar, GTK_NO_WINDOW);
100 toolbar->num_children = 0;
101 toolbar->children = NULL;
102 toolbar->orientation = GTK_ORIENTATION_HORIZONTAL;
103 toolbar->style = GTK_TOOLBAR_ICONS;
104 toolbar->space_size = DEFAULT_SPACE_SIZE;
108 gtk_toolbar_new(GtkOrientation orientation,
109 GtkToolbarStyle style)
113 toolbar = gtk_type_new(gtk_toolbar_get_type());
115 toolbar->orientation = orientation;
116 toolbar->style = style;
121 gtk_toolbar_destroy(GtkObject *object)
127 g_return_if_fail(object != NULL);
128 g_return_if_fail(GTK_IS_TOOLBAR(object));
130 toolbar = GTK_TOOLBAR(object);
132 for (children = toolbar->children; children; children = children->next) {
133 child = children->data;
135 /* NULL child means it is a space in the toolbar, rather than a button */
137 child->button->parent = NULL;
138 gtk_object_unref(GTK_OBJECT(child->button));
139 gtk_widget_destroy(child->button);
144 g_list_free(toolbar->children);
146 if (GTK_OBJECT_CLASS(parent_class)->destroy)
147 (* GTK_OBJECT_CLASS(parent_class)->destroy) (object);
151 gtk_toolbar_map(GtkWidget *widget)
157 g_return_if_fail(widget != NULL);
158 g_return_if_fail(GTK_IS_TOOLBAR(widget));
160 toolbar = GTK_TOOLBAR(widget);
161 GTK_WIDGET_SET_FLAGS(toolbar, GTK_MAPPED);
163 for (children = toolbar->children; children; children = children->next) {
164 child = children->data;
166 if (child && GTK_WIDGET_VISIBLE(child->button) && !GTK_WIDGET_MAPPED(child->button))
167 gtk_widget_map(child->button);
172 gtk_toolbar_unmap(GtkWidget *widget)
178 g_return_if_fail(widget != NULL);
179 g_return_if_fail(GTK_IS_TOOLBAR(widget));
181 toolbar = GTK_TOOLBAR(widget);
182 GTK_WIDGET_UNSET_FLAGS(toolbar, GTK_MAPPED);
184 for (children = toolbar->children; children; children = children->next) {
185 child = children->data;
187 if (child && GTK_WIDGET_VISIBLE(child->button) && GTK_WIDGET_MAPPED(child->button))
188 gtk_widget_unmap(child->button);
193 gtk_toolbar_draw(GtkWidget *widget,
199 GdkRectangle child_area;
201 g_return_if_fail(widget != NULL);
202 g_return_if_fail(GTK_IS_TOOLBAR(widget));
204 if (GTK_WIDGET_DRAWABLE(widget)) {
205 toolbar = GTK_TOOLBAR(widget);
207 for (children = toolbar->children; children; children = children->next) {
208 child = children->data;
210 if (child && gtk_widget_intersect(child->button, area, &child_area))
211 gtk_widget_draw(child->button, &child_area);
217 gtk_toolbar_size_request(GtkWidget *widget,
218 GtkRequisition *requisition)
225 g_return_if_fail(widget != NULL);
226 g_return_if_fail(GTK_IS_TOOLBAR(widget));
227 g_return_if_fail(requisition != NULL);
229 toolbar = GTK_TOOLBAR(widget);
231 requisition->width = GTK_CONTAINER(toolbar)->border_width * 2;
232 requisition->height = GTK_CONTAINER(toolbar)->border_width * 2;
234 toolbar->child_maxw = 0;
235 toolbar->child_maxh = 0;
237 for (children = toolbar->children; children; children = children->next) {
238 child = children->data;
243 gtk_widget_size_request(child->button, &child->button->requisition);
245 toolbar->child_maxw = MAX(toolbar->child_maxw, child->button->requisition->width);
246 toolbar->child_maxh = MAX(toolbar->child_maxh, child->button->requisition->height);
248 /* NULL child means it is a space in the toolbar, rather than a button */
249 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
250 requisition->width += toolbar->space_size;
252 requisition->height += toolbar->space_size;
255 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL) {
256 requisition->width += nchildren * toolbar->child_maxw;
257 requisition->height += toolbar->child_maxh;
259 requisition->width += toolbar->child_maxw;
260 requisition->height += nchildren * toolbar->child_maxh;
265 gtk_toolbar_size_allocate(GtkWidget *widget,
266 GtkAllocation *allocation)
273 g_return_if_fail(widget != NULL);
274 g_return_if_fail(GTK_IS_TOOLBAR(widget));
275 g_return_if_fail(allocation != NULL);
277 toolbar = GTK_TOOLBAR(widget);
278 widget->allocation = *allocation;
280 alloc.x = allocation->x + GTK_CONTAINER(toolbar)->border_width;
281 alloc.y = allocation->y + GTK_CONTAINER(toolbar)->border_width;
282 alloc.width = toolbar->child_maxw;
283 alloc.height = toolbar->child_maxh;
285 for (children = toolbar->children; children; children = children->next) {
286 child = children->data;
289 gtk_widget_size_allocate(child->button, &alloc);
291 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
292 alloc.x += toolbar->child_maxw;
294 alloc.y += toolbar->child_maxh;
296 /* NULL child means it is a space in the toolbar, rather than a button */
297 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
298 alloc.x += toolbar->space_size;
300 alloc.y += toolbar->space_size;
305 gtk_toolbar_add(GtkContainer *container,
308 g_warning("gtk_toolbar_add: use gtk_toolbar_add_item() instead!");
312 gtk_toolbar_append_item(GtkToolbar *toolbar,
314 const char *tooltip_text,
317 gtk_toolbar_insert_item(toolbar, text, tooltip_text, icon, toolbar->num_children);
321 gtk_toolbar_prepend_item(GtkToolbar *toolbar,
323 const char *tooltip_text,
326 gtk_toolbar_insert_item(toolbar, text, tooltip_text, icon, 0);
330 gtk_toolbar_insert_item(GtkToolbar *toolbar,
332 const char *tooltip_text,
340 g_return_if_fail(toolbar != NULL);
341 g_return_if_fail(GTK_IS_TOOLBAR(toolbar));
343 child = g_new(Child, 1);
345 child->button = gtk_button_new();
348 child->label = gtk_label_new(text);
354 vbox = gtk_vbox_new(FALSE, 0);
355 gtk_container_add(GTK_CONTAINER(button), vbox);
356 gtk_widget_show(vbox);
359 gtk_box_pack_start(GTK_BOX(vbox), child->icon);
362 gtk_box_pack_start(GTK_BOX(vbox), child->label);
364 switch (toolbar->style) {
365 case GTK_TOOLBAR_ICONS:
367 gtk_widget_show(child->icon);
370 case GTK_TOOLBAR_TEXT:
372 gtk_widget_show(child->label);
375 case GTK_TOOLBAR_BOTH:
377 gtk_widget_show(child->icon);
380 gtk_widget_show(child->label);
385 g_assert_not_reached();
388 gtk_widget_show(child->button);
390 toolbar->children = g_list_insert(toolbar->children, child, position);
391 toolbar->num_children++;
393 gtk_widget_set_parent(child->button, toolbar);
395 if (GTK_WIDGET_VISIBLE(toolbar)) {
396 if (GTK_WIDGET_REALIZED(toolbar)
397 && !GTK_WIDGET_REALIZED(button))
398 gtk_widget_realize(button);
400 if (GTK_WIDGET_MAPPED(toolbar)
401 && !GTK_WIDGET_MAPPED(button))
402 gtk_widget_map(button);
405 if (GTK_WIDGET_VISIBLE(button) && GTK_WIDGET_VISIBLE(toolbar))
406 gtk_widget_queue_resize(button);
410 gtk_toolbar_append_space(GtkToolbar *toolbar)
412 gtk_toolbar_insert_space(toolbar, toolbar->num_children);
416 gtk_toolbar_prepend_space(GtkToolbar *toolbar)
418 gtk_toolbar_insert_space(toolbar, 0);
422 gtk_toolbar_insert_space(GtkToolbar *toolbar,
425 g_return_if_fail(toolbar != NULL);
426 g_return_if_fail(GTK_IS_TOOLBAR(toolbar));
428 /* NULL child means it is a space in the toolbar, rather than a button */
430 toolbar->children = g_list_insert(toolbar->children, NULL);
432 if (GTK_WIDGET_VISIBLE(toolbar))
433 gtk_widget_queue_resize(GTK_WIDGET(toolbar));