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 Lesser 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 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
23 * file for a list of people on the GTK+ Team. See the ChangeLog
24 * files for a list of changes. These files are distributed with
25 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
28 #include "gtkbutton.h"
29 #include "gtktogglebutton.h"
30 #include "gtkradiobutton.h"
34 #include "gtktoolbar.h"
36 #include "gtkiconfactory.h"
38 #include "gtksettings.h"
42 #define DEFAULT_IPADDING 0
43 #define DEFAULT_SPACE_SIZE 5
44 #define DEFAULT_SPACE_STYLE GTK_TOOLBAR_SPACE_LINE
46 #define DEFAULT_ICON_SIZE GTK_ICON_SIZE_LARGE_TOOLBAR
48 #define SPACE_LINE_DIVISION 10
49 #define SPACE_LINE_START 3
50 #define SPACE_LINE_END 7
64 typedef struct _GtkToolbarChildSpace GtkToolbarChildSpace;
65 struct _GtkToolbarChildSpace
67 GtkToolbarChild child;
69 gint alloc_x, alloc_y;
72 static void gtk_toolbar_class_init (GtkToolbarClass *class);
73 static void gtk_toolbar_init (GtkToolbar *toolbar);
74 static void gtk_toolbar_finalize (GObject *object);
75 static void gtk_toolbar_set_property (GObject *object,
79 static void gtk_toolbar_get_property (GObject *object,
83 static void gtk_toolbar_destroy (GtkObject *object);
84 static void gtk_toolbar_map (GtkWidget *widget);
85 static void gtk_toolbar_unmap (GtkWidget *widget);
86 static gint gtk_toolbar_expose (GtkWidget *widget,
87 GdkEventExpose *event);
88 static void gtk_toolbar_size_request (GtkWidget *widget,
89 GtkRequisition *requisition);
90 static void gtk_toolbar_size_allocate (GtkWidget *widget,
91 GtkAllocation *allocation);
92 static void gtk_toolbar_style_set (GtkWidget *widget,
93 GtkStyle *prev_style);
94 static gboolean gtk_toolbar_focus (GtkWidget *widget,
95 GtkDirectionType dir);
96 static void gtk_toolbar_show_all (GtkWidget *widget);
97 static void gtk_toolbar_add (GtkContainer *container,
99 static void gtk_toolbar_remove (GtkContainer *container,
101 static void gtk_toolbar_forall (GtkContainer *container,
102 gboolean include_internals,
103 GtkCallback callback,
104 gpointer callback_data);
106 static void gtk_real_toolbar_orientation_changed (GtkToolbar *toolbar,
107 GtkOrientation orientation);
108 static void gtk_real_toolbar_style_changed (GtkToolbar *toolbar,
109 GtkToolbarStyle style);
111 static GtkWidget * gtk_toolbar_internal_insert_element (GtkToolbar *toolbar,
112 GtkToolbarChildType type,
115 const char *tooltip_text,
116 const char *tooltip_private_text,
118 GtkSignalFunc callback,
121 gboolean has_mnemonic);
123 static GtkWidget * gtk_toolbar_internal_insert_item (GtkToolbar *toolbar,
125 const char *tooltip_text,
126 const char *tooltip_private_text,
128 GtkSignalFunc callback,
131 gboolean has_mnemonic);
133 static void gtk_toolbar_update_button_relief (GtkToolbar *toolbar);
135 static GtkReliefStyle get_button_relief (GtkToolbar *toolbar);
136 static gint get_space_size (GtkToolbar *toolbar);
137 static GtkToolbarSpaceStyle get_space_style (GtkToolbar *toolbar);
140 static GtkContainerClass *parent_class;
142 static guint toolbar_signals[LAST_SIGNAL] = { 0 };
146 gtk_toolbar_get_type (void)
148 static GtkType toolbar_type = 0;
152 static const GtkTypeInfo toolbar_info =
156 sizeof (GtkToolbarClass),
157 (GtkClassInitFunc) gtk_toolbar_class_init,
158 (GtkObjectInitFunc) gtk_toolbar_init,
159 /* reserved_1 */ NULL,
160 /* reserved_2 */ NULL,
161 (GtkClassInitFunc) NULL,
164 toolbar_type = gtk_type_unique (gtk_container_get_type (), &toolbar_info);
171 gtk_toolbar_class_init (GtkToolbarClass *class)
173 GObjectClass *gobject_class;
174 GtkObjectClass *object_class;
175 GtkWidgetClass *widget_class;
176 GtkContainerClass *container_class;
178 gobject_class = G_OBJECT_CLASS (class);
179 object_class = (GtkObjectClass *) class;
180 widget_class = (GtkWidgetClass *) class;
181 container_class = (GtkContainerClass *) class;
183 parent_class = gtk_type_class (gtk_container_get_type ());
185 gobject_class->finalize = gtk_toolbar_finalize;
187 object_class->destroy = gtk_toolbar_destroy;
188 gobject_class->set_property = gtk_toolbar_set_property;
189 gobject_class->get_property = gtk_toolbar_get_property;
191 widget_class->map = gtk_toolbar_map;
192 widget_class->unmap = gtk_toolbar_unmap;
193 widget_class->expose_event = gtk_toolbar_expose;
194 widget_class->size_request = gtk_toolbar_size_request;
195 widget_class->size_allocate = gtk_toolbar_size_allocate;
196 widget_class->style_set = gtk_toolbar_style_set;
197 widget_class->show_all = gtk_toolbar_show_all;
198 widget_class->focus = gtk_toolbar_focus;
200 container_class->add = gtk_toolbar_add;
201 container_class->remove = gtk_toolbar_remove;
202 container_class->forall = gtk_toolbar_forall;
204 class->orientation_changed = gtk_real_toolbar_orientation_changed;
205 class->style_changed = gtk_real_toolbar_style_changed;
207 toolbar_signals[ORIENTATION_CHANGED] =
208 gtk_signal_new ("orientation_changed",
210 GTK_CLASS_TYPE (object_class),
211 GTK_SIGNAL_OFFSET (GtkToolbarClass, orientation_changed),
212 gtk_marshal_VOID__INT,
215 toolbar_signals[STYLE_CHANGED] =
216 gtk_signal_new ("style_changed",
218 GTK_CLASS_TYPE (object_class),
219 GTK_SIGNAL_OFFSET (GtkToolbarClass, style_changed),
220 gtk_marshal_VOID__INT,
224 g_object_class_install_property (gobject_class,
226 g_param_spec_enum ("orientation",
228 _("The orientation of the toolbar"),
229 GTK_TYPE_ORIENTATION,
230 GTK_ORIENTATION_HORIZONTAL,
233 g_object_class_install_property (gobject_class,
235 g_param_spec_enum ("toolbar_style",
237 _("How to draw the toolbar"),
238 GTK_TYPE_TOOLBAR_STYLE,
243 gtk_widget_class_install_style_property (widget_class,
244 g_param_spec_int ("space_size",
246 _("Size of spacers"),
252 gtk_widget_class_install_style_property (widget_class,
253 g_param_spec_int ("internal_padding",
254 _("Internal padding"),
255 _("Amount of border space between the toolbar shadow and the buttons"),
261 gtk_widget_class_install_style_property (widget_class,
262 g_param_spec_enum ("space_style",
264 _("Whether spacers are vertical lines or just blank"),
265 GTK_TYPE_TOOLBAR_SPACE_STYLE,
270 gtk_widget_class_install_style_property (widget_class,
271 g_param_spec_enum ("button_relief",
273 _("Type of bevel around toolbar buttons"),
274 GTK_TYPE_RELIEF_STYLE,
278 gtk_widget_class_install_style_property (widget_class,
279 g_param_spec_enum ("shadow_type",
281 _("Style of bevel around the toolbar"),
282 GTK_TYPE_SHADOW_TYPE,
286 gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-style",
288 _("Whether default toolbars have text only, text and icons, icons only, etc."),
289 GTK_TYPE_TOOLBAR_STYLE,
293 gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-icon-size",
294 _("Toolbar icon size"),
295 _("Size of icons in default toolbars"),
297 GTK_ICON_SIZE_LARGE_TOOLBAR,
302 style_change_notify (GObject *object,
308 toolbar = GTK_TOOLBAR (data);
310 if (!toolbar->style_set)
312 /* pretend it was set, then unset, thus reverting to new default */
313 toolbar->style_set = TRUE;
314 gtk_toolbar_unset_style (toolbar);
319 icon_size_change_notify (GObject *object,
325 toolbar = GTK_TOOLBAR (data);
327 if (!toolbar->icon_size_set)
329 /* pretend it was set, then unset, thus reverting to new default */
330 toolbar->icon_size_set = TRUE;
331 gtk_toolbar_unset_icon_size (toolbar);
336 gtk_toolbar_init (GtkToolbar *toolbar)
338 GTK_WIDGET_SET_FLAGS (toolbar, GTK_NO_WINDOW);
339 GTK_WIDGET_UNSET_FLAGS (toolbar, GTK_CAN_FOCUS);
341 toolbar->num_children = 0;
342 toolbar->children = NULL;
343 toolbar->orientation = GTK_ORIENTATION_HORIZONTAL;
344 toolbar->icon_size = DEFAULT_ICON_SIZE;
345 toolbar->tooltips = gtk_tooltips_new ();
346 toolbar->button_maxw = 0;
347 toolbar->button_maxh = 0;
349 toolbar->style_set = FALSE;
350 toolbar->icon_size_set = FALSE;
351 g_object_get (gtk_settings_get_default (),
352 "gtk-toolbar-icon-size",
358 toolbar->style_set_connection =
359 g_signal_connect (G_OBJECT (gtk_settings_get_default ()),
360 "notify::gtk-toolbar-style",
361 G_CALLBACK (style_change_notify),
364 toolbar->icon_size_connection =
365 g_signal_connect (G_OBJECT (gtk_settings_get_default ()),
366 "notify::gtk-toolbar-icon-size",
367 G_CALLBACK (icon_size_change_notify),
372 gtk_toolbar_finalize (GObject *object)
376 toolbar = GTK_TOOLBAR (object);
378 g_signal_handler_disconnect (G_OBJECT (gtk_settings_get_default ()),
379 toolbar->style_set_connection);
380 g_signal_handler_disconnect (G_OBJECT (gtk_settings_get_default ()),
381 toolbar->icon_size_connection);
383 G_OBJECT_CLASS (parent_class)->finalize (object);
387 gtk_toolbar_set_property (GObject *object,
392 GtkToolbar *toolbar = GTK_TOOLBAR (object);
396 case PROP_ORIENTATION:
397 gtk_toolbar_set_orientation (toolbar, g_value_get_enum (value));
399 case PROP_TOOLBAR_STYLE:
400 gtk_toolbar_set_style (toolbar, g_value_get_enum (value));
406 gtk_toolbar_get_property (GObject *object,
411 GtkToolbar *toolbar = GTK_TOOLBAR (object);
415 case PROP_ORIENTATION:
416 g_value_set_enum (value, toolbar->orientation);
418 case PROP_TOOLBAR_STYLE:
419 g_value_set_enum (value, toolbar->style);
422 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
428 gtk_toolbar_new (void)
432 toolbar = gtk_type_new (gtk_toolbar_get_type ());
434 return GTK_WIDGET (toolbar);
438 gtk_toolbar_destroy (GtkObject *object)
443 g_return_if_fail (GTK_IS_TOOLBAR (object));
445 toolbar = GTK_TOOLBAR (object);
447 if (toolbar->tooltips)
449 gtk_object_unref (GTK_OBJECT (toolbar->tooltips));
450 toolbar->tooltips = NULL;
453 for (children = toolbar->children; children; children = children->next)
455 GtkToolbarChild *child;
457 child = children->data;
459 if (child->type != GTK_TOOLBAR_CHILD_SPACE)
461 gtk_widget_ref (child->widget);
462 gtk_widget_unparent (child->widget);
463 gtk_widget_destroy (child->widget);
464 gtk_widget_unref (child->widget);
469 g_list_free (toolbar->children);
470 toolbar->children = NULL;
472 GTK_OBJECT_CLASS (parent_class)->destroy (object);
476 gtk_toolbar_map (GtkWidget *widget)
480 GtkToolbarChild *child;
482 g_return_if_fail (GTK_IS_TOOLBAR (widget));
484 toolbar = GTK_TOOLBAR (widget);
485 GTK_WIDGET_SET_FLAGS (toolbar, GTK_MAPPED);
487 for (children = toolbar->children; children; children = children->next)
489 child = children->data;
491 if ((child->type != GTK_TOOLBAR_CHILD_SPACE)
492 && GTK_WIDGET_VISIBLE (child->widget) && !GTK_WIDGET_MAPPED (child->widget))
493 gtk_widget_map (child->widget);
498 gtk_toolbar_unmap (GtkWidget *widget)
502 GtkToolbarChild *child;
504 g_return_if_fail (GTK_IS_TOOLBAR (widget));
506 toolbar = GTK_TOOLBAR (widget);
507 GTK_WIDGET_UNSET_FLAGS (toolbar, GTK_MAPPED);
509 for (children = toolbar->children; children; children = children->next)
511 child = children->data;
513 if ((child->type != GTK_TOOLBAR_CHILD_SPACE)
514 && GTK_WIDGET_VISIBLE (child->widget) && GTK_WIDGET_MAPPED (child->widget))
515 gtk_widget_unmap (child->widget);
520 gtk_toolbar_paint_space_line (GtkWidget *widget,
522 GtkToolbarChild *child)
525 GtkToolbarChildSpace *child_space;
528 g_return_if_fail (GTK_IS_TOOLBAR (widget));
529 g_return_if_fail (child != NULL);
530 g_return_if_fail (child->type == GTK_TOOLBAR_CHILD_SPACE);
532 toolbar = GTK_TOOLBAR (widget);
534 child_space = (GtkToolbarChildSpace *) child;
535 space_size = get_space_size (toolbar);
537 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
538 gtk_paint_vline (widget->style, widget->window,
539 GTK_WIDGET_STATE (widget), area, widget,
541 child_space->alloc_y + toolbar->button_maxh *
542 SPACE_LINE_START / SPACE_LINE_DIVISION,
543 child_space->alloc_y + toolbar->button_maxh *
544 SPACE_LINE_END / SPACE_LINE_DIVISION,
545 child_space->alloc_x +
547 widget->style->xthickness) / 2);
549 gtk_paint_hline (widget->style, widget->window,
550 GTK_WIDGET_STATE (widget), area, widget,
552 child_space->alloc_x + toolbar->button_maxw *
553 SPACE_LINE_START / SPACE_LINE_DIVISION,
554 child_space->alloc_x + toolbar->button_maxw *
555 SPACE_LINE_END / SPACE_LINE_DIVISION,
556 child_space->alloc_y +
558 widget->style->ythickness) / 2);
562 gtk_toolbar_expose (GtkWidget *widget,
563 GdkEventExpose *event)
567 GtkToolbarChild *child;
570 g_return_val_if_fail (GTK_IS_TOOLBAR (widget), FALSE);
571 g_return_val_if_fail (event != NULL, FALSE);
573 border_width = GTK_CONTAINER (widget)->border_width;
575 if (GTK_WIDGET_DRAWABLE (widget))
577 GtkShadowType shadow_type;
579 toolbar = GTK_TOOLBAR (widget);
581 gtk_widget_style_get (widget, "shadow_type", &shadow_type, NULL);
583 gtk_paint_box (widget->style,
585 GTK_WIDGET_STATE (widget),
587 &event->area, widget, "toolbar",
588 widget->allocation.x + border_width,
589 widget->allocation.y + border_width,
590 widget->allocation.width - border_width,
591 widget->allocation.height - border_width);
593 for (children = toolbar->children; children; children = children->next)
595 child = children->data;
597 if (child->type == GTK_TOOLBAR_CHILD_SPACE)
599 if (get_space_style (toolbar) == GTK_TOOLBAR_SPACE_LINE)
600 gtk_toolbar_paint_space_line (widget, &event->area, child);
603 gtk_container_propagate_expose (GTK_CONTAINER (widget),
613 gtk_toolbar_size_request (GtkWidget *widget,
614 GtkRequisition *requisition)
618 GtkToolbarChild *child;
620 gint button_maxw, button_maxh;
621 gint widget_maxw, widget_maxh;
622 GtkRequisition child_requisition;
626 g_return_if_fail (GTK_IS_TOOLBAR (widget));
627 g_return_if_fail (requisition != NULL);
629 toolbar = GTK_TOOLBAR (widget);
631 requisition->width = GTK_CONTAINER (toolbar)->border_width * 2;
632 requisition->height = GTK_CONTAINER (toolbar)->border_width * 2;
639 space_size = get_space_size (toolbar);
641 for (children = toolbar->children; children; children = children->next)
643 child = children->data;
647 case GTK_TOOLBAR_CHILD_SPACE:
648 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
649 requisition->width += space_size;
651 requisition->height += space_size;
655 case GTK_TOOLBAR_CHILD_BUTTON:
656 case GTK_TOOLBAR_CHILD_RADIOBUTTON:
657 case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
658 if (GTK_WIDGET_VISIBLE (child->widget))
660 gtk_widget_size_request (child->widget, &child_requisition);
663 button_maxw = MAX (button_maxw, child_requisition.width);
664 button_maxh = MAX (button_maxh, child_requisition.height);
669 case GTK_TOOLBAR_CHILD_WIDGET:
670 if (GTK_WIDGET_VISIBLE (child->widget))
672 gtk_widget_size_request (child->widget, &child_requisition);
674 widget_maxw = MAX (widget_maxw, child_requisition.width);
675 widget_maxh = MAX (widget_maxh, child_requisition.height);
677 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
678 requisition->width += child_requisition.width;
680 requisition->height += child_requisition.height;
686 g_assert_not_reached ();
690 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
692 requisition->width += nbuttons * button_maxw;
693 requisition->height += MAX (button_maxh, widget_maxh);
697 requisition->width += MAX (button_maxw, widget_maxw);
698 requisition->height += nbuttons * button_maxh;
702 gtk_widget_style_get (widget, "internal_padding", &ipadding, NULL);
704 requisition->width += 2 * (widget->style->xthickness + ipadding);
705 requisition->height += 2 * (widget->style->ythickness + ipadding);
707 toolbar->button_maxw = button_maxw;
708 toolbar->button_maxh = button_maxh;
712 gtk_toolbar_size_allocate (GtkWidget *widget,
713 GtkAllocation *allocation)
717 GtkToolbarChild *child;
718 GtkToolbarChildSpace *child_space;
720 GtkRequisition child_requisition;
721 gint x_border_width, y_border_width;
725 g_return_if_fail (GTK_IS_TOOLBAR (widget));
726 g_return_if_fail (allocation != NULL);
728 toolbar = GTK_TOOLBAR (widget);
729 widget->allocation = *allocation;
731 x_border_width = GTK_CONTAINER (toolbar)->border_width;
732 y_border_width = GTK_CONTAINER (toolbar)->border_width;
734 gtk_widget_style_get (widget, "internal_padding", &ipadding, NULL);
736 x_border_width += 2 * (widget->style->xthickness + ipadding);
737 y_border_width += 2 * (widget->style->ythickness + ipadding);
739 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
740 alloc.x = allocation->x + x_border_width;
742 alloc.y = allocation->y + y_border_width;
744 space_size = get_space_size (toolbar);
746 for (children = toolbar->children; children; children = children->next)
748 child = children->data;
752 case GTK_TOOLBAR_CHILD_SPACE:
754 child_space = (GtkToolbarChildSpace *) child;
756 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
758 child_space->alloc_x = alloc.x;
759 child_space->alloc_y = allocation->y + (allocation->height - toolbar->button_maxh) / 2;
760 alloc.x += space_size;
764 child_space->alloc_x = allocation->x + (allocation->width - toolbar->button_maxw) / 2;
765 child_space->alloc_y = alloc.y;
766 alloc.y += space_size;
771 case GTK_TOOLBAR_CHILD_BUTTON:
772 case GTK_TOOLBAR_CHILD_RADIOBUTTON:
773 case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
774 if (!GTK_WIDGET_VISIBLE (child->widget))
777 alloc.width = toolbar->button_maxw;
778 alloc.height = toolbar->button_maxh;
780 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
781 alloc.y = allocation->y + (allocation->height - toolbar->button_maxh) / 2;
783 alloc.x = allocation->x + (allocation->width - toolbar->button_maxw) / 2;
785 gtk_widget_size_allocate (child->widget, &alloc);
787 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
788 alloc.x += toolbar->button_maxw;
790 alloc.y += toolbar->button_maxh;
794 case GTK_TOOLBAR_CHILD_WIDGET:
795 if (!GTK_WIDGET_VISIBLE (child->widget))
798 gtk_widget_get_child_requisition (child->widget, &child_requisition);
800 alloc.width = child_requisition.width;
801 alloc.height = child_requisition.height;
803 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
804 alloc.y = allocation->y + (allocation->height - child_requisition.height) / 2;
806 alloc.x = allocation->x + (allocation->width - child_requisition.width) / 2;
808 gtk_widget_size_allocate (child->widget, &alloc);
810 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
811 alloc.x += child_requisition.width;
813 alloc.y += child_requisition.height;
818 g_assert_not_reached ();
824 gtk_toolbar_style_set (GtkWidget *widget,
825 GtkStyle *prev_style)
828 gtk_toolbar_update_button_relief (GTK_TOOLBAR (widget));
832 gtk_toolbar_focus (GtkWidget *widget,
833 GtkDirectionType dir)
835 /* Focus can't go in toolbars */
841 child_show_all (GtkWidget *widget)
843 /* Don't show our own children, since that would
844 * show labels we may intend to hide in icons-only mode
846 if (!g_object_get_data (G_OBJECT (widget),
847 "gtk-toolbar-is-child"))
848 gtk_widget_show_all (widget);
852 gtk_toolbar_show_all (GtkWidget *widget)
854 gtk_container_foreach (GTK_CONTAINER (widget),
855 (GtkCallback) child_show_all,
857 gtk_widget_show (widget);
861 gtk_toolbar_add (GtkContainer *container,
864 g_return_if_fail (GTK_IS_TOOLBAR (container));
865 g_return_if_fail (widget != NULL);
867 gtk_toolbar_append_widget (GTK_TOOLBAR (container), widget, NULL, NULL);
871 gtk_toolbar_remove (GtkContainer *container,
876 GtkToolbarChild *child;
878 g_return_if_fail (GTK_IS_TOOLBAR (container));
879 g_return_if_fail (widget != NULL);
881 toolbar = GTK_TOOLBAR (container);
883 for (children = toolbar->children; children; children = children->next)
885 child = children->data;
887 if ((child->type != GTK_TOOLBAR_CHILD_SPACE) && (child->widget == widget))
889 gboolean was_visible;
891 was_visible = GTK_WIDGET_VISIBLE (widget);
892 gtk_widget_unparent (widget);
894 toolbar->children = g_list_remove_link (toolbar->children, children);
896 g_list_free (children);
897 toolbar->num_children--;
899 if (was_visible && GTK_WIDGET_VISIBLE (container))
900 gtk_widget_queue_resize (GTK_WIDGET (container));
908 gtk_toolbar_forall (GtkContainer *container,
909 gboolean include_internals,
910 GtkCallback callback,
911 gpointer callback_data)
915 GtkToolbarChild *child;
917 g_return_if_fail (GTK_IS_TOOLBAR (container));
918 g_return_if_fail (callback != NULL);
920 toolbar = GTK_TOOLBAR (container);
922 for (children = toolbar->children; children; children = children->next)
924 child = children->data;
926 if (child->type != GTK_TOOLBAR_CHILD_SPACE)
927 (*callback) (child->widget, callback_data);
932 gtk_toolbar_append_item (GtkToolbar *toolbar,
934 const char *tooltip_text,
935 const char *tooltip_private_text,
937 GtkSignalFunc callback,
940 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
942 tooltip_text, tooltip_private_text,
943 icon, callback, user_data,
944 toolbar->num_children);
948 gtk_toolbar_prepend_item (GtkToolbar *toolbar,
950 const char *tooltip_text,
951 const char *tooltip_private_text,
953 GtkSignalFunc callback,
956 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
958 tooltip_text, tooltip_private_text,
959 icon, callback, user_data,
964 gtk_toolbar_internal_insert_item (GtkToolbar *toolbar,
966 const char *tooltip_text,
967 const char *tooltip_private_text,
969 GtkSignalFunc callback,
972 gboolean has_mnemonic)
974 return gtk_toolbar_internal_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
976 tooltip_text, tooltip_private_text,
977 icon, callback, user_data,
978 position, has_mnemonic);
982 gtk_toolbar_insert_item (GtkToolbar *toolbar,
984 const char *tooltip_text,
985 const char *tooltip_private_text,
987 GtkSignalFunc callback,
991 return gtk_toolbar_internal_insert_item (toolbar,
992 text, tooltip_text, tooltip_private_text,
993 icon, callback, user_data,
998 * gtk_toolbar_set_icon_size:
999 * @toolbar: A #GtkToolbar
1000 * @icon_size: The #GtkIconSize that stock icons in the toolbar shall have.
1002 * This function sets the size of stock icons in the toolbar. You
1003 * can call it both before you add the icons and after they've been
1004 * added. The size you set will override user preferences for the default
1008 gtk_toolbar_set_icon_size (GtkToolbar *toolbar,
1009 GtkIconSize icon_size)
1012 GtkToolbarChild *child;
1016 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1018 toolbar->icon_size_set = TRUE;
1020 if (toolbar->icon_size == icon_size)
1023 toolbar->icon_size = icon_size;
1025 for (children = toolbar->children; children; children = children->next)
1027 child = children->data;
1028 if (child->type == GTK_TOOLBAR_CHILD_BUTTON &&
1029 GTK_IS_IMAGE (child->icon))
1031 image = GTK_IMAGE (child->icon);
1032 if (gtk_image_get_storage_type (image) == GTK_IMAGE_STOCK)
1034 gtk_image_get_stock (image, &stock_id, NULL);
1035 stock_id = g_strdup (stock_id);
1036 gtk_image_set_from_stock (image,
1044 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
1048 * gtk_toolbar_get_icon_size:
1049 * @toolbar: a #GtkToolbar
1051 * Retrieves the icon size fo the toolbar. See gtk_toolbar_set_icon_size().
1053 * Return value: the current icon size for the icons on the toolbar.
1056 gtk_toolbar_get_icon_size (GtkToolbar *toolbar)
1058 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_ICON_SIZE_LARGE_TOOLBAR);
1060 return toolbar->icon_size;
1064 * gtk_toolbar_unset_icon_size:
1065 * @toolbar: a #GtkToolbar
1067 * Unsets toolbar icon size set with gtk_toolbar_set_icon_size(), so that
1068 * user preferences will be used to determine the icon size.
1071 gtk_toolbar_unset_icon_size (GtkToolbar *toolbar)
1075 if (toolbar->icon_size_set)
1077 g_object_get (gtk_settings_get_default (),
1078 "gtk-toolbar-icon-size",
1081 if (size != toolbar->icon_size)
1082 gtk_toolbar_set_icon_size (toolbar, size);
1084 toolbar->icon_size_set = FALSE;
1089 * gtk_toolbar_insert_stock:
1090 * @toolbar: A #GtkToolbar
1091 * @stock_id: The id of the stock item you want to insert
1092 * @tooltip_text: The text in the tooltip of the toolbar button
1093 * @tooltip_private_text: The private text of the tooltip
1094 * @callback: The callback called when the toolbar button is clicked.
1095 * @user_data: user data passed to callback
1096 * @position: The position the button shall be inserted at.
1097 * -1 means at the end.
1099 * Inserts a stock item at the specified position of the toolbar. If
1100 * @stock_id is not a known stock item ID, it's inserted verbatim,
1101 * except that underscores are used to mark mnemonics (see
1102 * gtk_label_new_with_mnemonic()).
1104 * Returns: the inserted widget
1107 gtk_toolbar_insert_stock (GtkToolbar *toolbar,
1108 const gchar *stock_id,
1109 const char *tooltip_text,
1110 const char *tooltip_private_text,
1111 GtkSignalFunc callback,
1118 if (gtk_stock_lookup (stock_id, &item))
1120 image = gtk_image_new_from_stock (stock_id, toolbar->icon_size);
1122 return gtk_toolbar_internal_insert_item (toolbar,
1125 tooltip_private_text,
1133 return gtk_toolbar_internal_insert_item (toolbar,
1136 tooltip_private_text,
1147 gtk_toolbar_append_space (GtkToolbar *toolbar)
1149 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
1153 toolbar->num_children);
1157 gtk_toolbar_prepend_space (GtkToolbar *toolbar)
1159 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
1167 gtk_toolbar_insert_space (GtkToolbar *toolbar,
1170 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
1178 gtk_toolbar_remove_space (GtkToolbar *toolbar,
1182 GtkToolbarChild *child;
1185 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1188 for (children = toolbar->children; children; children = children->next)
1190 child = children->data;
1194 if (child->type == GTK_TOOLBAR_CHILD_SPACE)
1196 toolbar->children = g_list_remove_link (toolbar->children, children);
1198 g_list_free (children);
1199 toolbar->num_children--;
1201 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
1205 g_warning ("Toolbar position %d is not a space", position);
1214 g_warning ("Toolbar position %d doesn't exist", position);
1218 gtk_toolbar_append_widget (GtkToolbar *toolbar,
1220 const gchar *tooltip_text,
1221 const gchar *tooltip_private_text)
1223 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
1225 tooltip_text, tooltip_private_text,
1227 toolbar->num_children);
1231 gtk_toolbar_prepend_widget (GtkToolbar *toolbar,
1233 const gchar *tooltip_text,
1234 const gchar *tooltip_private_text)
1236 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
1238 tooltip_text, tooltip_private_text,
1244 gtk_toolbar_insert_widget (GtkToolbar *toolbar,
1246 const char *tooltip_text,
1247 const char *tooltip_private_text,
1250 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
1252 tooltip_text, tooltip_private_text,
1258 gtk_toolbar_append_element (GtkToolbar *toolbar,
1259 GtkToolbarChildType type,
1262 const char *tooltip_text,
1263 const char *tooltip_private_text,
1265 GtkSignalFunc callback,
1268 return gtk_toolbar_insert_element (toolbar, type, widget, text,
1269 tooltip_text, tooltip_private_text,
1270 icon, callback, user_data,
1271 toolbar->num_children);
1275 gtk_toolbar_prepend_element (GtkToolbar *toolbar,
1276 GtkToolbarChildType type,
1279 const char *tooltip_text,
1280 const char *tooltip_private_text,
1282 GtkSignalFunc callback,
1285 return gtk_toolbar_insert_element (toolbar, type, widget, text,
1286 tooltip_text, tooltip_private_text,
1287 icon, callback, user_data, 0);
1291 gtk_toolbar_insert_element (GtkToolbar *toolbar,
1292 GtkToolbarChildType type,
1295 const char *tooltip_text,
1296 const char *tooltip_private_text,
1298 GtkSignalFunc callback,
1302 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
1303 if (type == GTK_TOOLBAR_CHILD_WIDGET)
1305 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
1307 else if (type != GTK_TOOLBAR_CHILD_RADIOBUTTON)
1308 g_return_val_if_fail (widget == NULL, NULL);
1310 return gtk_toolbar_internal_insert_element (toolbar, type, widget, text,
1311 tooltip_text, tooltip_private_text,
1312 icon, callback, user_data,
1317 gtk_toolbar_internal_insert_element (GtkToolbar *toolbar,
1318 GtkToolbarChildType type,
1321 const char *tooltip_text,
1322 const char *tooltip_private_text,
1324 GtkSignalFunc callback,
1327 gboolean has_mnemonic)
1329 GtkToolbarChild *child;
1332 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
1333 if (type == GTK_TOOLBAR_CHILD_WIDGET)
1335 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
1337 else if (type != GTK_TOOLBAR_CHILD_RADIOBUTTON)
1338 g_return_val_if_fail (widget == NULL, NULL);
1340 if (type == GTK_TOOLBAR_CHILD_SPACE)
1341 child = (GtkToolbarChild *) g_new (GtkToolbarChildSpace, 1);
1343 child = g_new (GtkToolbarChild, 1);
1347 child->label = NULL;
1351 case GTK_TOOLBAR_CHILD_SPACE:
1352 child->widget = NULL;
1353 ((GtkToolbarChildSpace *) child)->alloc_x =
1354 ((GtkToolbarChildSpace *) child)->alloc_y = 0;
1357 case GTK_TOOLBAR_CHILD_WIDGET:
1358 child->widget = widget;
1361 case GTK_TOOLBAR_CHILD_BUTTON:
1362 case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
1363 case GTK_TOOLBAR_CHILD_RADIOBUTTON:
1364 if (type == GTK_TOOLBAR_CHILD_BUTTON)
1366 child->widget = gtk_button_new ();
1367 gtk_button_set_relief (GTK_BUTTON (child->widget), get_button_relief (toolbar));
1369 else if (type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
1371 child->widget = gtk_toggle_button_new ();
1372 gtk_button_set_relief (GTK_BUTTON (child->widget), get_button_relief (toolbar));
1373 gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (child->widget),
1378 child->widget = gtk_radio_button_new (widget
1379 ? gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget))
1381 gtk_button_set_relief (GTK_BUTTON (child->widget), get_button_relief (toolbar));
1382 gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (child->widget), FALSE);
1385 GTK_WIDGET_UNSET_FLAGS (child->widget, GTK_CAN_FOCUS);
1388 gtk_signal_connect (GTK_OBJECT (child->widget), "clicked",
1389 callback, user_data);
1391 if (toolbar->style == GTK_TOOLBAR_BOTH_HORIZ)
1392 box = gtk_hbox_new (FALSE, 0);
1394 box = gtk_vbox_new (FALSE, 0);
1395 gtk_container_add (GTK_CONTAINER (child->widget), box);
1396 gtk_widget_show (box);
1401 child->label = gtk_label_new_with_mnemonic (text);
1403 child->label = gtk_label_new (text);
1404 gtk_box_pack_end (GTK_BOX (box), child->label, FALSE, FALSE, 0);
1405 if (toolbar->style != GTK_TOOLBAR_ICONS)
1406 gtk_widget_show (child->label);
1411 child->icon = GTK_WIDGET (icon);
1412 gtk_box_pack_end (GTK_BOX (box), child->icon, FALSE, FALSE, 0);
1413 if (toolbar->style != GTK_TOOLBAR_TEXT)
1414 gtk_widget_show (child->icon);
1417 if (type != GTK_TOOLBAR_CHILD_WIDGET)
1419 /* Mark child as ours */
1420 g_object_set_data (G_OBJECT (child->widget),
1421 "gtk-toolbar-is-child",
1422 GINT_TO_POINTER (TRUE));
1424 gtk_widget_show (child->widget);
1428 g_assert_not_reached ();
1431 if ((type != GTK_TOOLBAR_CHILD_SPACE) && tooltip_text)
1432 gtk_tooltips_set_tip (toolbar->tooltips, child->widget,
1433 tooltip_text, tooltip_private_text);
1435 toolbar->children = g_list_insert (toolbar->children, child, position);
1436 toolbar->num_children++;
1438 if (type != GTK_TOOLBAR_CHILD_SPACE)
1440 gtk_widget_set_parent (child->widget, GTK_WIDGET (toolbar));
1442 if (GTK_WIDGET_REALIZED (child->widget->parent))
1443 gtk_widget_realize (child->widget);
1445 if (GTK_WIDGET_VISIBLE (child->widget->parent) && GTK_WIDGET_VISIBLE (child->widget))
1447 if (GTK_WIDGET_MAPPED (child->widget->parent))
1448 gtk_widget_map (child->widget);
1450 gtk_widget_queue_resize (child->widget);
1454 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
1456 return child->widget;
1460 gtk_toolbar_set_orientation (GtkToolbar *toolbar,
1461 GtkOrientation orientation)
1463 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1465 gtk_signal_emit (GTK_OBJECT (toolbar), toolbar_signals[ORIENTATION_CHANGED], orientation);
1469 * gtk_toolbar_get_orientation:
1470 * @toolbar: a #GtkToolbar
1472 * Retrieves the current orientation of the toolbar. See
1473 * gtk_toolbar_set_orientation().
1475 * Return value: the orientation
1478 gtk_toolbar_get_orientation (GtkToolbar *toolbar)
1480 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_ORIENTATION_HORIZONTAL);
1482 return toolbar->orientation;
1486 gtk_toolbar_set_style (GtkToolbar *toolbar,
1487 GtkToolbarStyle style)
1489 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1491 toolbar->style_set = TRUE;
1492 gtk_signal_emit (GTK_OBJECT (toolbar), toolbar_signals[STYLE_CHANGED], style);
1496 * gtk_toolbar_get_style:
1497 * @toolbar: a #GtkToolbar
1499 * Retrieves whether the toolbar has text, icons, or both . See
1500 * gtk_toolbar_set_style().
1502 * Return value: the current style of @toolbar
1505 gtk_toolbar_get_style (GtkToolbar *toolbar)
1507 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH);
1509 return toolbar->style;
1513 * gtk_toolbar_unset_style:
1514 * @toolbar: a #GtkToolbar
1516 * Unsets a toolbar style set with gtk_toolbar_set_style(), so that
1517 * user preferences will be used to determine the toolbar style.
1520 gtk_toolbar_unset_style (GtkToolbar *toolbar)
1522 GtkToolbarStyle style;
1524 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1526 if (toolbar->style_set)
1528 g_object_get (gtk_settings_get_default (),
1529 "gtk-toolbar-style",
1533 if (style != toolbar->style)
1534 gtk_signal_emit (GTK_OBJECT (toolbar), toolbar_signals[STYLE_CHANGED], style);
1536 toolbar->style_set = FALSE;
1541 gtk_toolbar_set_tooltips (GtkToolbar *toolbar,
1544 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1547 gtk_tooltips_enable (toolbar->tooltips);
1549 gtk_tooltips_disable (toolbar->tooltips);
1553 * gtk_toolbar_get_tooltips:
1554 * @toolbar: a #GtkToolbar
1556 * Retrieves whether tooltips are enabled. See
1557 * gtk_toolbar_set_tooltips().
1559 * Return value: %TRUE if tooltips are enabled
1562 gtk_toolbar_get_tooltips (GtkToolbar *toolbar)
1564 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
1566 return toolbar->tooltips->enabled;
1570 gtk_toolbar_update_button_relief (GtkToolbar *toolbar)
1573 GtkToolbarChild *child;
1574 GtkReliefStyle relief;
1576 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1578 relief = get_button_relief (toolbar);
1580 for (children = toolbar->children; children; children = children->next)
1582 child = children->data;
1583 if (child->type == GTK_TOOLBAR_CHILD_BUTTON ||
1584 child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
1585 child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
1586 gtk_button_set_relief (GTK_BUTTON (child->widget), relief);
1591 gtk_real_toolbar_orientation_changed (GtkToolbar *toolbar,
1592 GtkOrientation orientation)
1594 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1596 if (toolbar->orientation != orientation)
1598 toolbar->orientation = orientation;
1599 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
1600 g_object_notify (G_OBJECT (toolbar), "orientation");
1605 gtk_real_toolbar_style_changed (GtkToolbar *toolbar,
1606 GtkToolbarStyle style)
1609 GtkToolbarChild *child;
1610 GtkWidget* box = NULL;
1612 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1614 if (toolbar->style != style)
1616 toolbar->style = style;
1618 for (children = toolbar->children; children; children = children->next)
1620 child = children->data;
1622 if (child->type == GTK_TOOLBAR_CHILD_BUTTON ||
1623 child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
1624 child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
1627 case GTK_TOOLBAR_ICONS:
1628 if (child->icon && !GTK_WIDGET_VISIBLE (child->icon))
1629 gtk_widget_show (child->icon);
1631 if (child->label && GTK_WIDGET_VISIBLE (child->label))
1632 gtk_widget_hide (child->label);
1636 case GTK_TOOLBAR_TEXT:
1637 if (child->icon && GTK_WIDGET_VISIBLE (child->icon))
1638 gtk_widget_hide (child->icon);
1640 if (child->label && !GTK_WIDGET_VISIBLE (child->label))
1641 gtk_widget_show (child->label);
1645 case GTK_TOOLBAR_BOTH:
1646 if (child->icon && !GTK_WIDGET_VISIBLE (child->icon))
1647 gtk_widget_show (child->icon);
1649 if (child->label && !GTK_WIDGET_VISIBLE (child->label))
1650 gtk_widget_show (child->label);
1652 box = (GtkWidget*)gtk_container_children (GTK_CONTAINER (child->widget))->data;
1654 if (GTK_IS_HBOX (box))
1658 gtk_object_ref (GTK_OBJECT (child->icon));
1659 gtk_container_remove (GTK_CONTAINER (box),
1664 gtk_object_ref (GTK_OBJECT (child->label));
1665 gtk_container_remove (GTK_CONTAINER (box),
1668 gtk_container_remove (GTK_CONTAINER (child->widget),
1671 box = gtk_vbox_new (FALSE, 0);
1672 gtk_widget_show (box);
1676 gtk_box_pack_end (GTK_BOX (box), child->label, FALSE, FALSE, 0);
1677 gtk_object_unref (GTK_OBJECT (child->label));
1681 gtk_box_pack_end (GTK_BOX (box), child->icon, FALSE, FALSE, 0);
1682 gtk_object_unref (GTK_OBJECT (child->icon));
1684 gtk_container_add (GTK_CONTAINER (child->widget),
1690 case GTK_TOOLBAR_BOTH_HORIZ:
1691 if (child->icon && !GTK_WIDGET_VISIBLE (child->icon))
1692 gtk_widget_show (child->icon);
1693 if (child->label && !GTK_WIDGET_VISIBLE (child->label))
1694 gtk_widget_show (child->label);
1696 box = (GtkWidget*)gtk_container_children (GTK_CONTAINER (child->widget))->data;
1698 if (GTK_IS_VBOX (box))
1702 gtk_object_ref (GTK_OBJECT (child->icon));
1703 gtk_container_remove (GTK_CONTAINER (box),
1708 gtk_object_ref (GTK_OBJECT (child->label));
1709 gtk_container_remove (GTK_CONTAINER (box),
1712 gtk_container_remove (GTK_CONTAINER (child->widget),
1715 box = gtk_hbox_new (FALSE, 0);
1716 gtk_widget_show (box);
1720 gtk_box_pack_end (GTK_BOX (box), child->label, TRUE, TRUE, 0);
1721 gtk_object_unref (GTK_OBJECT (child->label));
1725 gtk_box_pack_end (GTK_BOX (box), child->icon, FALSE, FALSE, 0);
1726 gtk_object_unref (GTK_OBJECT (child->icon));
1728 gtk_container_add (GTK_CONTAINER (child->widget), box);
1735 g_assert_not_reached ();
1739 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
1740 g_object_notify (G_OBJECT (toolbar), "toolbar_style");
1745 static GtkReliefStyle
1746 get_button_relief (GtkToolbar *toolbar)
1748 GtkReliefStyle button_relief = GTK_RELIEF_NORMAL;
1750 gtk_widget_style_get (GTK_WIDGET (toolbar),
1751 "button_relief", &button_relief,
1754 return button_relief;
1758 get_space_size (GtkToolbar *toolbar)
1760 gint space_size = DEFAULT_SPACE_SIZE;
1762 gtk_widget_style_get (GTK_WIDGET (toolbar),
1763 "space_size", &space_size,
1769 static GtkToolbarSpaceStyle
1770 get_space_style (GtkToolbar *toolbar)
1772 GtkToolbarSpaceStyle space_style = DEFAULT_SPACE_STYLE;
1774 gtk_widget_style_get (GTK_WIDGET (toolbar),
1775 "space_style", &space_style,