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 "gtkbutton.h"
23 #include "gtktoolbar.h"
26 #define DEFAULT_SPACE_SIZE 5
36 static void gtk_toolbar_class_init (GtkToolbarClass *class);
37 static void gtk_toolbar_init (GtkToolbar *toolbar);
38 static void gtk_toolbar_destroy (GtkObject *object);
39 static void gtk_toolbar_map (GtkWidget *widget);
40 static void gtk_toolbar_unmap (GtkWidget *widget);
41 static void gtk_toolbar_draw (GtkWidget *widget,
43 static void gtk_toolbar_size_request (GtkWidget *widget,
44 GtkRequisition *requisition);
45 static void gtk_toolbar_size_allocate (GtkWidget *widget,
46 GtkAllocation *allocation);
47 static void gtk_toolbar_add (GtkContainer *container,
49 static void gtk_toolbar_foreach (GtkContainer *container,
51 gpointer callback_data);
53 static GtkContainerClass *parent_class;
57 gtk_toolbar_get_type(void)
59 static guint toolbar_type = 0;
62 GtkTypeInfo toolbar_info = {
65 sizeof(GtkToolbarClass),
66 (GtkClassInitFunc) gtk_toolbar_class_init,
67 (GtkObjectInitFunc) gtk_toolbar_init,
71 toolbar_type = gtk_type_unique(gtk_container_get_type(), &toolbar_info);
78 gtk_toolbar_class_init(GtkToolbarClass *class)
80 GtkObjectClass *object_class;
81 GtkWidgetClass *widget_class;
82 GtkContainerClass *container_class;
84 object_class = (GtkObjectClass *) class;
85 widget_class = (GtkWidgetClass *) class;
86 container_class = (GtkContainerClass *) class;
88 parent_class = gtk_type_class(gtk_container_get_type());
90 object_class->destroy = gtk_toolbar_destroy;
92 widget_class->map = gtk_toolbar_map;
93 widget_class->unmap = gtk_toolbar_unmap;
94 widget_class->draw = gtk_toolbar_draw;
95 widget_class->size_request = gtk_toolbar_size_request;
96 widget_class->size_allocate = gtk_toolbar_size_allocate;
98 container_class->add = gtk_toolbar_add;
99 container_class->foreach = gtk_toolbar_foreach;
103 gtk_toolbar_init(GtkToolbar *toolbar)
105 GTK_WIDGET_SET_FLAGS(toolbar, GTK_NO_WINDOW);
107 toolbar->num_children = 0;
108 toolbar->children = NULL;
109 toolbar->orientation = GTK_ORIENTATION_HORIZONTAL;
110 toolbar->style = GTK_TOOLBAR_ICONS;
111 toolbar->space_size = DEFAULT_SPACE_SIZE;
112 toolbar->tooltips = gtk_tooltips_new();
116 gtk_toolbar_new(GtkOrientation orientation,
117 GtkToolbarStyle style)
121 toolbar = gtk_type_new(gtk_toolbar_get_type());
123 toolbar->orientation = orientation;
124 toolbar->style = style;
126 return GTK_WIDGET(toolbar);
131 gtk_toolbar_destroy(GtkObject *object)
137 g_return_if_fail(object != NULL);
138 g_return_if_fail(GTK_IS_TOOLBAR(object));
140 toolbar = GTK_TOOLBAR(object);
142 gtk_tooltips_unref(toolbar->tooltips); /* XXX: do I have to unref the tooltips? */
144 for (children = toolbar->children; children; children = children->next) {
145 child = children->data;
147 /* NULL child means it is a space in the toolbar, rather than a button */
149 child->button->parent = NULL;
150 gtk_object_unref(GTK_OBJECT(child->button));
151 gtk_widget_destroy(child->button);
156 g_list_free(toolbar->children);
158 if (GTK_OBJECT_CLASS(parent_class)->destroy)
159 (* GTK_OBJECT_CLASS(parent_class)->destroy) (object);
163 gtk_toolbar_map(GtkWidget *widget)
169 g_return_if_fail(widget != NULL);
170 g_return_if_fail(GTK_IS_TOOLBAR(widget));
172 toolbar = GTK_TOOLBAR(widget);
173 GTK_WIDGET_SET_FLAGS(toolbar, GTK_MAPPED);
175 for (children = toolbar->children; children; children = children->next) {
176 child = children->data;
178 if (child && GTK_WIDGET_VISIBLE(child->button) && !GTK_WIDGET_MAPPED(child->button))
179 gtk_widget_map(child->button);
184 gtk_toolbar_unmap(GtkWidget *widget)
190 g_return_if_fail(widget != NULL);
191 g_return_if_fail(GTK_IS_TOOLBAR(widget));
193 toolbar = GTK_TOOLBAR(widget);
194 GTK_WIDGET_UNSET_FLAGS(toolbar, GTK_MAPPED);
196 for (children = toolbar->children; children; children = children->next) {
197 child = children->data;
199 if (child && GTK_WIDGET_VISIBLE(child->button) && GTK_WIDGET_MAPPED(child->button))
200 gtk_widget_unmap(child->button);
205 gtk_toolbar_draw(GtkWidget *widget,
211 GdkRectangle child_area;
213 g_return_if_fail(widget != NULL);
214 g_return_if_fail(GTK_IS_TOOLBAR(widget));
216 if (GTK_WIDGET_DRAWABLE(widget)) {
217 toolbar = GTK_TOOLBAR(widget);
219 for (children = toolbar->children; children; children = children->next) {
220 child = children->data;
222 if (child && gtk_widget_intersect(child->button, area, &child_area))
223 gtk_widget_draw(child->button, &child_area);
229 gtk_toolbar_size_request(GtkWidget *widget,
230 GtkRequisition *requisition)
237 g_return_if_fail(widget != NULL);
238 g_return_if_fail(GTK_IS_TOOLBAR(widget));
239 g_return_if_fail(requisition != NULL);
241 toolbar = GTK_TOOLBAR(widget);
243 requisition->width = GTK_CONTAINER(toolbar)->border_width * 2;
244 requisition->height = GTK_CONTAINER(toolbar)->border_width * 2;
246 toolbar->child_maxw = 0;
247 toolbar->child_maxh = 0;
249 for (children = toolbar->children; children; children = children->next) {
250 child = children->data;
255 gtk_widget_size_request(child->button, &child->button->requisition);
257 toolbar->child_maxw = MAX(toolbar->child_maxw, child->button->requisition.width);
258 toolbar->child_maxh = MAX(toolbar->child_maxh, child->button->requisition.height);
260 /* NULL child means it is a space in the toolbar, rather than a button */
261 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
262 requisition->width += toolbar->space_size;
264 requisition->height += toolbar->space_size;
267 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL) {
268 requisition->width += nchildren * toolbar->child_maxw;
269 requisition->height += toolbar->child_maxh;
271 requisition->width += toolbar->child_maxw;
272 requisition->height += nchildren * toolbar->child_maxh;
277 gtk_toolbar_size_allocate(GtkWidget *widget,
278 GtkAllocation *allocation)
285 g_return_if_fail(widget != NULL);
286 g_return_if_fail(GTK_IS_TOOLBAR(widget));
287 g_return_if_fail(allocation != NULL);
289 toolbar = GTK_TOOLBAR(widget);
290 widget->allocation = *allocation;
292 alloc.x = allocation->x + GTK_CONTAINER(toolbar)->border_width;
293 alloc.y = allocation->y + GTK_CONTAINER(toolbar)->border_width;
294 alloc.width = toolbar->child_maxw;
295 alloc.height = toolbar->child_maxh;
297 for (children = toolbar->children; children; children = children->next) {
298 child = children->data;
301 gtk_widget_size_allocate(child->button, &alloc);
303 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
304 alloc.x += toolbar->child_maxw;
306 alloc.y += toolbar->child_maxh;
308 /* NULL child means it is a space in the toolbar, rather than a button */
309 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
310 alloc.x += toolbar->space_size;
312 alloc.y += toolbar->space_size;
317 gtk_toolbar_add(GtkContainer *container,
320 g_warning("gtk_toolbar_add: use gtk_toolbar_add_item() instead!");
324 gtk_toolbar_foreach(GtkContainer *container,
325 GtkCallback callback,
326 gpointer callback_data)
332 g_return_if_fail(container != NULL);
333 g_return_if_fail(GTK_IS_TOOLBAR(container));
334 g_return_if_fail(callback != NULL);
336 toolbar = GTK_TOOLBAR(container);
338 for (children = toolbar->children; children; children = children->next) {
339 child = children->data;
342 (*callback) (child->button, callback_data);
347 gtk_toolbar_append_item(GtkToolbar *toolbar,
349 const char *tooltip_text,
351 GtkSignalFunc callback,
354 gtk_toolbar_insert_item(toolbar, text, tooltip_text, icon,
355 callback, user_data, toolbar->num_children);
359 gtk_toolbar_prepend_item(GtkToolbar *toolbar,
361 const char *tooltip_text,
363 GtkSignalFunc callback,
366 gtk_toolbar_insert_item(toolbar, text, tooltip_text, icon,
367 callback, user_data, 0);
371 gtk_toolbar_insert_item(GtkToolbar *toolbar,
373 const char *tooltip_text,
375 GtkSignalFunc callback,
382 g_return_if_fail(toolbar != NULL);
383 g_return_if_fail(GTK_IS_TOOLBAR(toolbar));
385 child = g_new(Child, 1);
387 child->button = gtk_button_new();
390 gtk_signal_connect(GTK_OBJECT(child->button), "clicked",
391 callback, user_data);
394 child->label = gtk_label_new(text);
398 child->icon = GTK_WIDGET(icon);
400 vbox = gtk_vbox_new(FALSE, 0);
401 gtk_container_add(GTK_CONTAINER(child->button), vbox);
402 gtk_widget_show(vbox);
405 gtk_box_pack_start(GTK_BOX(vbox), child->icon, FALSE, FALSE, 0);
408 gtk_box_pack_start(GTK_BOX(vbox), child->label, FALSE, FALSE, 0);
410 switch (toolbar->style) {
411 case GTK_TOOLBAR_ICONS:
413 gtk_widget_show(child->icon);
416 case GTK_TOOLBAR_TEXT:
418 gtk_widget_show(child->label);
421 case GTK_TOOLBAR_BOTH:
423 gtk_widget_show(child->icon);
426 gtk_widget_show(child->label);
431 g_assert_not_reached();
434 gtk_widget_show(child->button);
436 toolbar->children = g_list_insert(toolbar->children, child, position);
437 toolbar->num_children++;
439 gtk_widget_set_parent(child->button, GTK_WIDGET(toolbar));
441 if (GTK_WIDGET_VISIBLE(toolbar)) {
442 if (GTK_WIDGET_REALIZED(toolbar)
443 && !GTK_WIDGET_REALIZED(child->button))
444 gtk_widget_realize(child->button);
446 if (GTK_WIDGET_MAPPED(toolbar)
447 && !GTK_WIDGET_MAPPED(child->button))
448 gtk_widget_map(child->button);
451 if (GTK_WIDGET_VISIBLE(child->button) && GTK_WIDGET_VISIBLE(toolbar))
452 gtk_widget_queue_resize(child->button);
456 gtk_toolbar_append_space(GtkToolbar *toolbar)
458 gtk_toolbar_insert_space(toolbar, toolbar->num_children);
462 gtk_toolbar_prepend_space(GtkToolbar *toolbar)
464 gtk_toolbar_insert_space(toolbar, 0);
468 gtk_toolbar_insert_space(GtkToolbar *toolbar,
471 g_return_if_fail(toolbar != NULL);
472 g_return_if_fail(GTK_IS_TOOLBAR(toolbar));
474 /* NULL child means it is a space in the toolbar, rather than a button */
476 toolbar->children = g_list_insert(toolbar->children, NULL, position);
477 toolbar->num_children++;
479 if (GTK_WIDGET_VISIBLE(toolbar))
480 gtk_widget_queue_resize(GTK_WIDGET(toolbar));