1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 * GtkToolbar copyright (C) Federico Mena
5 * Copyright (C) 2002 Anders Carlsson <andersca@codefactory.se>
6 * Copyright (C) 2002 James Henstridge <james@daa.com.au>
7 * Copyright (C) 2003 Soeren Sandmann <sandmann@daimi.au.dk>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
26 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
27 * file for a list of people on the GTK+ Team. See the ChangeLog
28 * files for a list of changes. These files are distributed with
29 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
32 #undef GTK_DISABLE_DEPRECATED
35 #include "gtktoolbar.h"
36 #include "gtkradiotoolbutton.h"
37 #include "gtkseparatortoolitem.h"
39 #include "gtkradiobutton.h"
40 #include "gtktoolbar.h"
41 #include "gtkbindings.h"
42 #include <gdk/gdkkeysyms.h>
43 #include "gtkmarshalers.h"
47 #include "gtkprivate.h"
51 #define DEFAULT_IPADDING 0
53 /* note: keep in sync with DEFAULT_SPACE_SIZE and DEFAULT_SPACE_STYLE in gtkseparatortoolitem.c */
54 #define DEFAULT_SPACE_SIZE 5
55 #define DEFAULT_SPACE_STYLE GTK_TOOLBAR_SPACE_LINE
57 #define DEFAULT_ICON_SIZE GTK_ICON_SIZE_LARGE_TOOLBAR
58 #define DEFAULT_TOOLBAR_STYLE GTK_TOOLBAR_BOTH
70 CHILD_PROP_HOMOGENEOUS,
83 static void gtk_toolbar_init (GtkToolbar *toolbar);
84 static void gtk_toolbar_class_init (GtkToolbarClass *klass);
86 static void gtk_toolbar_set_property (GObject *object,
90 static void gtk_toolbar_get_property (GObject *object,
95 static gint gtk_toolbar_expose (GtkWidget *widget,
96 GdkEventExpose *event);
97 static void gtk_toolbar_realize (GtkWidget *widget);
98 static void gtk_toolbar_unrealize (GtkWidget *widget);
99 static void gtk_toolbar_size_request (GtkWidget *widget,
100 GtkRequisition *requisition);
101 static void gtk_toolbar_size_allocate (GtkWidget *widget,
102 GtkAllocation *allocation);
103 static void gtk_toolbar_style_set (GtkWidget *widget,
104 GtkStyle *prev_style);
105 static void gtk_toolbar_direction_changed (GtkWidget *widget,
106 GtkTextDirection previous_direction);
107 static gboolean gtk_toolbar_focus (GtkWidget *widget,
108 GtkDirectionType dir);
109 static void gtk_toolbar_screen_changed (GtkWidget *widget,
110 GdkScreen *previous_screen);
111 static void gtk_toolbar_map (GtkWidget *widget);
112 static void gtk_toolbar_unmap (GtkWidget *widget);
114 static void gtk_toolbar_drag_leave (GtkWidget *widget,
115 GdkDragContext *context,
117 static gboolean gtk_toolbar_drag_motion (GtkWidget *widget,
118 GdkDragContext *context,
122 static void gtk_toolbar_set_child_property (GtkContainer *container,
127 static void gtk_toolbar_get_child_property (GtkContainer *container,
132 static void gtk_toolbar_finalize (GObject *object);
135 static void gtk_toolbar_add (GtkContainer *container,
137 static void gtk_toolbar_remove (GtkContainer *container,
139 static void gtk_toolbar_forall (GtkContainer *container,
140 gboolean include_internals,
141 GtkCallback callback,
142 gpointer callback_data);
143 static GType gtk_toolbar_child_type (GtkContainer *container);
145 static void gtk_toolbar_real_orientation_changed (GtkToolbar *toolbar,
146 GtkOrientation orientation);
147 static void gtk_toolbar_real_style_changed (GtkToolbar *toolbar,
148 GtkToolbarStyle style);
150 static gboolean gtk_toolbar_move_focus (GtkToolbar *toolbar,
151 GtkDirectionType dir);
152 static gboolean gtk_toolbar_focus_home_or_end (GtkToolbar *toolbar,
153 gboolean focus_home);
155 static gboolean gtk_toolbar_button_press (GtkWidget *toolbar,
156 GdkEventButton *event);
157 static gboolean gtk_toolbar_arrow_button_press (GtkWidget *button,
158 GdkEventButton *event,
159 GtkToolbar *toolbar);
160 static void gtk_toolbar_arrow_button_clicked (GtkWidget *button,
161 GtkToolbar *toolbar);
162 static void gtk_toolbar_update_button_relief (GtkToolbar *toolbar);
163 static GtkReliefStyle get_button_relief (GtkToolbar *toolbar);
164 static gint get_space_size (GtkToolbar *toolbar);
165 static gint get_internal_padding (GtkToolbar *toolbar);
166 static void gtk_toolbar_remove_tool_item (GtkToolbar *toolbar,
168 static gboolean gtk_toolbar_popup_menu (GtkWidget *toolbar);
170 static GtkWidget *gtk_toolbar_internal_insert_element (GtkToolbar *toolbar,
171 GtkToolbarChildType type,
174 const char *tooltip_text,
175 const char *tooltip_private_text,
177 GtkSignalFunc callback,
189 struct _GtkToolbarPrivate
194 GtkWidget *arrow_button;
199 GdkWindow *drag_highlight;
202 GdkWindow *event_window;
204 GtkSettings *settings;
207 static GtkContainerClass *parent_class = NULL;
208 static guint toolbar_signals [LAST_SIGNAL] = { 0 };
211 gtk_toolbar_get_type (void)
213 static GtkType type = 0;
217 static const GTypeInfo type_info =
219 sizeof (GtkToolbarClass),
220 (GBaseInitFunc) NULL,
221 (GBaseFinalizeFunc) NULL,
222 (GClassInitFunc) gtk_toolbar_class_init,
223 (GClassFinalizeFunc) NULL,
227 (GInstanceInitFunc) gtk_toolbar_init,
230 type = g_type_register_static (GTK_TYPE_CONTAINER,
239 add_arrow_bindings (GtkBindingSet *binding_set,
241 GtkDirectionType dir)
243 guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
245 gtk_binding_entry_add_signal (binding_set, keysym, 0,
247 GTK_TYPE_DIRECTION_TYPE, dir);
248 gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
250 GTK_TYPE_DIRECTION_TYPE, dir);
254 add_ctrl_tab_bindings (GtkBindingSet *binding_set,
255 GdkModifierType modifiers,
256 GtkDirectionType direction)
258 gtk_binding_entry_add_signal (binding_set,
259 GDK_Tab, GDK_CONTROL_MASK | modifiers,
261 GTK_TYPE_DIRECTION_TYPE, direction);
262 gtk_binding_entry_add_signal (binding_set,
263 GDK_KP_Tab, GDK_CONTROL_MASK | modifiers,
265 GTK_TYPE_DIRECTION_TYPE, direction);
269 gtk_toolbar_class_init (GtkToolbarClass *klass)
271 GObjectClass *gobject_class;
272 GtkWidgetClass *widget_class;
273 GtkContainerClass *container_class;
274 GtkBindingSet *binding_set;
276 parent_class = g_type_class_peek_parent (klass);
278 gobject_class = (GObjectClass *)klass;
279 widget_class = (GtkWidgetClass *)klass;
280 container_class = (GtkContainerClass *)klass;
282 gobject_class->set_property = gtk_toolbar_set_property;
283 gobject_class->get_property = gtk_toolbar_get_property;
284 gobject_class->finalize = gtk_toolbar_finalize;
286 widget_class->button_press_event = gtk_toolbar_button_press;
287 widget_class->expose_event = gtk_toolbar_expose;
288 widget_class->size_request = gtk_toolbar_size_request;
289 widget_class->size_allocate = gtk_toolbar_size_allocate;
290 widget_class->style_set = gtk_toolbar_style_set;
291 widget_class->direction_changed = gtk_toolbar_direction_changed;
292 widget_class->focus = gtk_toolbar_focus;
293 widget_class->screen_changed = gtk_toolbar_screen_changed;
294 widget_class->realize = gtk_toolbar_realize;
295 widget_class->unrealize = gtk_toolbar_unrealize;
296 widget_class->map = gtk_toolbar_map;
297 widget_class->unmap = gtk_toolbar_unmap;
298 widget_class->popup_menu = gtk_toolbar_popup_menu;
300 widget_class->drag_leave = gtk_toolbar_drag_leave;
301 widget_class->drag_motion = gtk_toolbar_drag_motion;
303 container_class->add = gtk_toolbar_add;
304 container_class->remove = gtk_toolbar_remove;
305 container_class->forall = gtk_toolbar_forall;
306 container_class->child_type = gtk_toolbar_child_type;
307 container_class->get_child_property = gtk_toolbar_get_child_property;
308 container_class->set_child_property = gtk_toolbar_set_child_property;
310 klass->orientation_changed = gtk_toolbar_real_orientation_changed;
311 klass->style_changed = gtk_toolbar_real_style_changed;
313 toolbar_signals[ORIENTATION_CHANGED] =
314 g_signal_new ("orientation_changed",
315 G_OBJECT_CLASS_TYPE (klass),
317 G_STRUCT_OFFSET (GtkToolbarClass, orientation_changed),
319 g_cclosure_marshal_VOID__ENUM,
321 GTK_TYPE_ORIENTATION);
322 toolbar_signals[STYLE_CHANGED] =
323 g_signal_new ("style_changed",
324 G_OBJECT_CLASS_TYPE (klass),
326 G_STRUCT_OFFSET (GtkToolbarClass, style_changed),
328 g_cclosure_marshal_VOID__ENUM,
330 GTK_TYPE_TOOLBAR_STYLE);
331 toolbar_signals[POPUP_CONTEXT_MENU] =
332 g_signal_new ("popup_context_menu",
333 G_OBJECT_CLASS_TYPE (klass),
335 G_STRUCT_OFFSET (GtkToolbarClass, popup_context_menu),
336 _gtk_boolean_handled_accumulator, NULL,
337 _gtk_marshal_BOOLEAN__INT_INT_INT,
339 G_TYPE_INT, G_TYPE_INT,
341 toolbar_signals[MOVE_FOCUS] =
342 _gtk_binding_signal_new ("move_focus",
343 G_TYPE_FROM_CLASS (klass),
344 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
345 G_CALLBACK (gtk_toolbar_move_focus),
347 _gtk_marshal_BOOLEAN__ENUM,
349 GTK_TYPE_DIRECTION_TYPE);
350 toolbar_signals[FOCUS_HOME_OR_END] =
351 _gtk_binding_signal_new ("focus_home_or_end",
352 G_OBJECT_CLASS_TYPE (klass),
353 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
354 G_CALLBACK (gtk_toolbar_focus_home_or_end),
356 _gtk_marshal_BOOLEAN__BOOLEAN,
361 g_object_class_install_property (gobject_class,
363 g_param_spec_enum ("orientation",
365 _("The orientation of the toolbar"),
366 GTK_TYPE_ORIENTATION,
367 GTK_ORIENTATION_HORIZONTAL,
370 g_object_class_install_property (gobject_class,
372 g_param_spec_enum ("toolbar_style",
374 _("How to draw the toolbar"),
375 GTK_TYPE_TOOLBAR_STYLE,
378 g_object_class_install_property (gobject_class,
380 g_param_spec_boolean ("show_arrow",
382 _("If an arrow should be shown if the toolbar doesn't fit"),
386 /* child properties */
387 gtk_container_class_install_child_property (container_class,
389 g_param_spec_boolean ("expand",
391 _("Whether the item should receive extra space when the toolbar grows"),
395 gtk_container_class_install_child_property (container_class,
396 CHILD_PROP_HOMOGENEOUS,
397 g_param_spec_boolean ("homogeneous",
399 _("Whether the item should be the same size as other homogeneous items"),
403 gtk_container_class_install_child_property (container_class,
405 g_param_spec_uint ("pack_end",
407 _("Whether the item is positioned at the end of the toolbar"),
411 /* style properties */
412 gtk_widget_class_install_style_property (widget_class,
413 g_param_spec_int ("space_size",
415 _("Size of spacers"),
421 gtk_widget_class_install_style_property (widget_class,
422 g_param_spec_int ("internal_padding",
423 _("Internal padding"),
424 _("Amount of border space between the toolbar shadow and the buttons"),
430 gtk_widget_class_install_style_property (widget_class,
431 g_param_spec_enum ("space_style",
433 _("Whether spacers are vertical lines or just blank"),
434 GTK_TYPE_TOOLBAR_SPACE_STYLE,
438 gtk_widget_class_install_style_property (widget_class,
439 g_param_spec_enum ("button_relief",
441 _("Type of bevel around toolbar buttons"),
442 GTK_TYPE_RELIEF_STYLE,
445 gtk_widget_class_install_style_property (widget_class,
446 g_param_spec_enum ("shadow_type",
448 _("Style of bevel around the toolbar"),
449 GTK_TYPE_SHADOW_TYPE,
453 gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-style",
455 _("Whether default toolbars have text only, text and icons, icons only, etc."),
456 GTK_TYPE_TOOLBAR_STYLE,
457 DEFAULT_TOOLBAR_STYLE,
460 gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-icon-size",
461 _("Toolbar icon size"),
462 _("Size of icons in default toolbars"),
467 binding_set = gtk_binding_set_by_class (klass);
469 add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
470 add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
471 add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
472 add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
474 gtk_binding_entry_add_signal (binding_set, GDK_KP_Home, 0,
475 "focus_home_or_end", 1,
476 G_TYPE_BOOLEAN, TRUE);
477 gtk_binding_entry_add_signal (binding_set, GDK_Home, 0,
478 "focus_home_or_end", 1,
479 G_TYPE_BOOLEAN, TRUE);
480 gtk_binding_entry_add_signal (binding_set, GDK_KP_End, 0,
481 "focus_home_or_end", 1,
482 G_TYPE_BOOLEAN, FALSE);
483 gtk_binding_entry_add_signal (binding_set, GDK_End, 0,
484 "focus_home_or_end", 1,
485 G_TYPE_BOOLEAN, FALSE);
487 add_ctrl_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
488 add_ctrl_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
490 g_type_class_add_private (gobject_class, sizeof (GtkToolbarPrivate));
494 gtk_toolbar_init (GtkToolbar *toolbar)
496 GtkToolbarPrivate *priv;
498 GTK_WIDGET_UNSET_FLAGS (toolbar, GTK_CAN_FOCUS);
499 GTK_WIDGET_SET_FLAGS (toolbar, GTK_NO_WINDOW);
501 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
503 toolbar->orientation = GTK_ORIENTATION_HORIZONTAL;
504 toolbar->style = DEFAULT_TOOLBAR_STYLE;
505 toolbar->icon_size = DEFAULT_ICON_SIZE;
506 toolbar->tooltips = gtk_tooltips_new ();
507 g_object_ref (toolbar->tooltips);
508 gtk_object_sink (GTK_OBJECT (toolbar->tooltips));
510 priv->arrow_button = gtk_toggle_button_new ();
511 g_signal_connect (priv->arrow_button, "button_press_event",
512 G_CALLBACK (gtk_toolbar_arrow_button_press), toolbar);
513 g_signal_connect (priv->arrow_button, "clicked",
514 G_CALLBACK (gtk_toolbar_arrow_button_clicked), toolbar);
515 gtk_button_set_relief (GTK_BUTTON (priv->arrow_button),
516 get_button_relief (toolbar));
518 priv->api_mode = DONT_KNOW;
520 gtk_button_set_focus_on_click (GTK_BUTTON (priv->arrow_button), FALSE);
522 priv->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
523 gtk_widget_show (priv->arrow);
524 gtk_container_add (GTK_CONTAINER (priv->arrow_button), priv->arrow);
526 gtk_widget_set_parent (priv->arrow_button, GTK_WIDGET (toolbar));
528 /* which child position a drop will occur at */
529 priv->drop_index = -1;
530 priv->drag_highlight = NULL;
534 priv->settings = NULL;
538 toolbar_item_visible (GtkToolbar *toolbar,
541 if (GTK_WIDGET_VISIBLE (item) &&
542 ((toolbar->orientation == GTK_ORIENTATION_HORIZONTAL && item->visible_horizontal) ||
543 (toolbar->orientation == GTK_ORIENTATION_VERTICAL && item->visible_vertical)))
545 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
547 /* With the old toolbar you could hide a button by calling gtk_widget_hide()
548 * on it. This doesn't work with the new API because the GtkToolItem will not be
551 if (priv->api_mode == OLD_API)
553 GtkWidget *bin_child = GTK_BIN (item)->child;
555 if (bin_child && !GTK_WIDGET_VISIBLE (bin_child))
566 gtk_toolbar_set_property (GObject *object,
571 GtkToolbar *toolbar = GTK_TOOLBAR (object);
575 case PROP_ORIENTATION:
576 gtk_toolbar_set_orientation (toolbar, g_value_get_enum (value));
578 case PROP_TOOLBAR_STYLE:
579 gtk_toolbar_set_style (toolbar, g_value_get_enum (value));
581 case PROP_SHOW_ARROW:
582 gtk_toolbar_set_show_arrow (toolbar, g_value_get_boolean (value));
585 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
591 gtk_toolbar_get_property (GObject *object,
596 GtkToolbar *toolbar = GTK_TOOLBAR (object);
597 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
601 case PROP_ORIENTATION:
602 g_value_set_enum (value, toolbar->orientation);
604 case PROP_TOOLBAR_STYLE:
605 g_value_set_enum (value, toolbar->style);
607 case PROP_SHOW_ARROW:
608 g_value_set_boolean (value, priv->show_arrow);
611 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
617 gtk_toolbar_map (GtkWidget *widget)
619 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
621 GTK_WIDGET_CLASS (parent_class)->map (widget);
623 if (priv->event_window)
624 gdk_window_show_unraised (priv->event_window);
628 gtk_toolbar_unmap (GtkWidget *widget)
630 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
632 if (priv->event_window)
633 gdk_window_hide (priv->event_window);
635 GTK_WIDGET_CLASS (parent_class)->unmap (widget);
639 gtk_toolbar_realize (GtkWidget *widget)
641 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
642 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
644 GdkWindowAttr attributes;
645 gint attributes_mask;
648 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
650 border_width = GTK_CONTAINER (widget)->border_width;
652 attributes.wclass = GDK_INPUT_ONLY;
653 attributes.window_type = GDK_WINDOW_CHILD;
654 attributes.x = widget->allocation.x + border_width;
655 attributes.y = widget->allocation.y + border_width;
656 attributes.width = widget->allocation.width - border_width * 2;
657 attributes.height = widget->allocation.height - border_width * 2;
658 attributes.event_mask = gtk_widget_get_events (widget);
659 /* FIXME: does GDK_EXPOSURE_MASK make sense for an input-only window?
660 * If it doesn't, then it should be removed here and in gtkbutton.c,
661 * gtkmenuitem.c, and maybe other places
663 attributes.event_mask |= (GDK_EXPOSURE_MASK |
664 GDK_BUTTON_PRESS_MASK |
665 GDK_BUTTON_RELEASE_MASK |
666 GDK_ENTER_NOTIFY_MASK |
667 GDK_LEAVE_NOTIFY_MASK);
669 attributes_mask = GDK_WA_X | GDK_WA_Y;
671 widget->window = gtk_widget_get_parent_window (widget);
672 g_object_ref (widget->window);
673 widget->style = gtk_style_attach (widget->style, widget->window);
675 priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget),
676 &attributes, attributes_mask);
677 gdk_window_set_user_data (priv->event_window, toolbar);
681 gtk_toolbar_unrealize (GtkWidget *widget)
683 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
685 if (priv->drag_highlight)
687 gdk_window_set_user_data (priv->drag_highlight, NULL);
688 gdk_window_destroy (priv->drag_highlight);
689 priv->drag_highlight = NULL;
692 if (priv->event_window)
694 gdk_window_set_user_data (priv->event_window, NULL);
695 gdk_window_destroy (priv->event_window);
696 priv->event_window = NULL;
699 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
700 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
704 gtk_toolbar_expose (GtkWidget *widget,
705 GdkEventExpose *event)
707 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
708 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
713 border_width = GTK_CONTAINER (widget)->border_width;
715 if (GTK_WIDGET_DRAWABLE (widget))
717 GtkShadowType shadow_type;
719 gtk_widget_style_get (widget, "shadow_type", &shadow_type, NULL);
721 gtk_paint_box (widget->style,
723 GTK_WIDGET_STATE (widget),
725 &event->area, widget, "toolbar",
726 border_width + widget->allocation.x,
727 border_width + widget->allocation.y,
728 widget->allocation.width - 2 * border_width,
729 widget->allocation.height - 2 * border_width);
735 GtkToolItem *item = GTK_TOOL_ITEM (items->data);
737 gtk_container_propagate_expose (GTK_CONTAINER (widget),
744 gtk_container_propagate_expose (GTK_CONTAINER (widget),
752 gtk_toolbar_size_request (GtkWidget *widget,
753 GtkRequisition *requisition)
755 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
756 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
757 gint space_size = get_space_size (toolbar);
759 gint max_child_height;
760 gint max_child_width;
761 gint max_homogeneous_child_width;
762 gint max_homogeneous_child_height;
763 gint homogeneous_size;
766 gint pack_front_size;
768 GtkRequisition arrow_requisition;
770 max_homogeneous_child_width = 0;
771 max_homogeneous_child_height = 0;
773 max_child_height = 0;
774 for (list = priv->items; list != NULL; list = list->next)
776 GtkRequisition requisition;
777 GtkToolItem *item = list->data;
779 if (!toolbar_item_visible (toolbar, item))
782 gtk_widget_size_request (GTK_WIDGET (item), &requisition);
784 max_child_width = MAX (max_child_width, requisition.width);
785 max_child_height = MAX (max_child_height, requisition.height);
787 if (GTK_TOOL_ITEM (item)->homogeneous && GTK_BIN (item)->child)
789 max_homogeneous_child_width = MAX (max_homogeneous_child_width, requisition.width);
790 max_homogeneous_child_height = MAX (max_homogeneous_child_height, requisition.height);
794 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
795 homogeneous_size = max_homogeneous_child_width;
797 homogeneous_size = max_homogeneous_child_height;
801 for (list = priv->items; list != NULL; list = list->next)
803 GtkToolItem *item = list->data;
806 if (!toolbar_item_visible (toolbar, item))
809 if (!GTK_BIN (item)->child)
813 else if (item->homogeneous)
815 size = homogeneous_size;
819 GtkRequisition requisition;
821 gtk_widget_size_request (GTK_WIDGET (item), &requisition);
823 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
824 size = requisition.width;
826 size = requisition.height;
830 pack_end_size += size;
832 pack_front_size += size;
835 if (priv->show_arrow)
837 gtk_widget_size_request (priv->arrow_button, &arrow_requisition);
839 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
840 long_req = arrow_requisition.width;
842 long_req = arrow_requisition.height;
844 /* There is no point requesting space for the arrow if that would take
845 * up more space than all the items combined
847 long_req = MIN (long_req, pack_front_size + pack_end_size);
851 arrow_requisition.height = 0;
852 arrow_requisition.width = 0;
854 long_req = pack_end_size + pack_front_size;
857 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
859 requisition->width = long_req;
860 requisition->height = MAX (max_child_height, arrow_requisition.height);
864 requisition->height = long_req;
865 requisition->width = MAX (max_child_width, arrow_requisition.width);
869 ipadding = get_internal_padding (toolbar);
871 requisition->width += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width);
872 requisition->height += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width);
874 toolbar->button_maxw = max_homogeneous_child_width;
875 toolbar->button_maxh = max_homogeneous_child_height;
879 fixup_allocation_for_rtl (gint total_size,
880 GtkAllocation *allocation)
882 allocation->x += (total_size - (2 * allocation->x + allocation->width));
886 fixup_allocation_for_vertical (GtkAllocation *allocation)
891 allocation->x = allocation->y;
894 tmp = allocation->width;
895 allocation->width = allocation->height;
896 allocation->height = tmp;
900 get_item_size (GtkToolbar *toolbar,
903 GtkRequisition requisition;
904 GtkToolItem *item = GTK_TOOL_ITEM (child);
906 if (!GTK_BIN (item)->child)
907 return get_space_size (toolbar);
909 gtk_widget_get_child_requisition (child, &requisition);
911 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
913 if (item->homogeneous)
914 return toolbar->button_maxw;
916 return requisition.width;
920 if (item->homogeneous)
921 return toolbar->button_maxh;
923 return requisition.height;
928 gtk_toolbar_size_allocate (GtkWidget *widget,
929 GtkAllocation *allocation)
931 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
932 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
934 GtkAllocation *allocations;
935 GtkAllocation arrow_allocation;
937 gint size, pos, short_size;
947 GtkRequisition arrow_requisition;
949 widget->allocation = *allocation;
951 space_size = get_space_size (toolbar);
953 border_width = GTK_CONTAINER (toolbar)->border_width;
955 if (GTK_WIDGET_REALIZED (widget))
957 gdk_window_move_resize (priv->event_window,
958 allocation->x + border_width,
959 allocation->y + border_width,
960 allocation->width - border_width * 2,
961 allocation->height - border_width * 2);
964 border_width += get_internal_padding (toolbar);
966 gtk_widget_get_child_requisition (GTK_WIDGET (priv->arrow_button),
969 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
971 available_size = size = allocation->width - 2 * border_width;
972 short_size = allocation->height - 2 * border_width;
973 arrow_size = arrow_requisition.width;
977 available_size = size = allocation->height - 2 * border_width;
978 short_size = allocation->width - 2 * border_width;
979 arrow_size = arrow_requisition.height;
982 n_items = g_list_length (priv->items);
983 allocations = g_new0 (GtkAllocation, n_items);
986 for (list = priv->items; list != NULL; list = list->next)
988 GtkToolItem *item = list->data;
990 if (toolbar_item_visible (toolbar, item))
991 needed_size += get_item_size (toolbar, GTK_WIDGET (item));
994 need_arrow = (needed_size > available_size) && priv->show_arrow;
997 size = available_size - arrow_size;
999 size = available_size;
1001 items = g_list_copy (priv->items);
1003 /* calculate widths of pack end items */
1004 for (list = g_list_last (items), i = 0; list != NULL; list = list->prev, ++i)
1006 GtkToolItem *item = list->data;
1007 GtkAllocation *allocation = &(allocations[n_items - i - 1]);
1010 if (!item->pack_end || !toolbar_item_visible (toolbar, item))
1013 item_size = get_item_size (toolbar, GTK_WIDGET (item));
1014 if (item_size <= size)
1017 allocation->width = item_size;
1018 item->overflow_item = FALSE;
1026 item->overflow_item = TRUE;
1034 /* calculate widths of pack front items */
1035 for (list = items, i = 0; list != NULL; list = list->next, ++i)
1037 GtkToolItem *item = list->data;
1040 if (item->pack_end || !toolbar_item_visible (toolbar, item))
1043 item_size = get_item_size (toolbar, GTK_WIDGET (item));
1044 if (item_size <= size)
1047 allocations[i].width = item_size;
1048 item->overflow_item = FALSE;
1055 if (!item->pack_end)
1056 item->overflow_item = TRUE;
1065 arrow_allocation.width = arrow_size;
1066 arrow_allocation.height = short_size;
1069 /* expand expandable items */
1071 for (list = priv->items; list != NULL; list = list->next)
1073 GtkToolItem *item = list->data;
1075 if (toolbar_item_visible (toolbar, item) && item->expand &&
1076 !item->overflow_item && GTK_BIN (item)->child)
1082 for (list = items, i = 0; list != NULL; list = list->next, ++i)
1084 GtkToolItem *item = list->data;
1086 if (toolbar_item_visible (toolbar, item) && item->expand &&
1087 !item->overflow_item && GTK_BIN (item)->child)
1089 gint extra = size / n_expand_items;
1090 if (size % n_expand_items != 0)
1093 allocations[i].width += extra;
1099 g_assert (n_expand_items == 0);
1101 /* position pack front items */
1103 for (list = items, i = 0; list != NULL; list = list->next, ++i)
1105 GtkToolItem *item = list->data;
1107 if (toolbar_item_visible (toolbar, item) && !item->overflow_item && !item->pack_end)
1109 allocations[i].x = pos;
1110 allocations[i].y = border_width;
1111 allocations[i].height = short_size;
1113 pos += allocations[i].width;
1117 /* position pack end items */
1118 pos = available_size + border_width;
1119 for (list = g_list_last (items), i = 0; list != NULL; list = list->prev, ++i)
1121 GtkToolItem *item = list->data;
1123 if (toolbar_item_visible (toolbar, item) && !item->overflow_item && item->pack_end)
1125 GtkAllocation *allocation = &(allocations[n_items - i - 1]);
1127 allocation->x = pos - allocation->width;
1128 allocation->y = border_width;
1129 allocation->height = short_size;
1131 pos -= allocation->width;
1135 /* position arrow */
1138 arrow_allocation.x = pos - arrow_allocation.width;
1139 arrow_allocation.y = border_width;
1142 /* fix up allocations in the vertical or RTL cases */
1143 if (toolbar->orientation == GTK_ORIENTATION_VERTICAL)
1145 for (i = 0; i < n_items; ++i)
1146 fixup_allocation_for_vertical (&(allocations[i]));
1149 fixup_allocation_for_vertical (&arrow_allocation);
1151 else if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
1153 for (i = 0; i < n_items; ++i)
1154 fixup_allocation_for_rtl (available_size, &(allocations[i]));
1157 fixup_allocation_for_rtl (available_size, &arrow_allocation);
1160 /* translate the items by allocation->(x,y) */
1161 for (i = 0; i < n_items; ++i)
1163 allocations[i].x += allocation->x;
1164 allocations[i].y += allocation->y;
1169 arrow_allocation.x += allocation->x;
1170 arrow_allocation.y += allocation->y;
1173 /* finally allocate the items */
1174 for (list = items, i = 0; list != NULL; list = list->next, i++)
1176 GtkToolItem *item = list->data;
1178 if (toolbar_item_visible (toolbar, item) && !item->overflow_item)
1180 gtk_widget_size_allocate (GTK_WIDGET (item), &(allocations[i]));
1181 gtk_widget_set_child_visible (GTK_WIDGET (item), TRUE);
1185 gtk_widget_set_child_visible (GTK_WIDGET (item), FALSE);
1191 gtk_widget_size_allocate (GTK_WIDGET (priv->arrow_button),
1193 gtk_widget_show (GTK_WIDGET (priv->arrow_button));
1197 gtk_widget_hide (GTK_WIDGET (priv->arrow_button));
1200 g_free (allocations);
1201 g_list_free (items);
1205 gtk_toolbar_style_set (GtkWidget *widget,
1206 GtkStyle *prev_style)
1208 if (GTK_WIDGET_REALIZED (widget))
1209 gtk_style_set_background (widget->style, widget->window, widget->state);
1212 gtk_toolbar_update_button_relief (GTK_TOOLBAR (widget));
1216 gtk_toolbar_direction_changed (GtkWidget *widget,
1217 GtkTextDirection previous_dir)
1219 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1220 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1222 if (toolbar->orientation == GTK_ORIENTATION_VERTICAL)
1224 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
1225 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
1227 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_LEFT, GTK_SHADOW_NONE);
1230 GTK_WIDGET_CLASS (parent_class)->direction_changed (widget, previous_dir);
1234 gtk_toolbar_list_children_in_focus_order (GtkToolbar *toolbar,
1235 GtkDirectionType dir)
1237 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1238 GList *result = NULL;
1242 /* generate list of children in reverse logical order */
1244 for (list = priv->items; list != NULL; list = list->next)
1246 GtkToolItem *item = list->data;
1247 if (!item->pack_end)
1248 result = g_list_prepend (result, item);
1251 for (list = priv->items; list != NULL; list = list->next)
1253 GtkToolItem *item = list->data;
1256 result = g_list_prepend (result, item);
1259 result = g_list_prepend (result, priv->arrow_button);
1261 rtl = (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL);
1263 /* move in logical order when
1265 * - dir is TAB_FORWARD
1267 * - in RTL mode and moving left or up
1269 * - in LTR mode and moving right or down
1271 if (dir == GTK_DIR_TAB_FORWARD ||
1272 (rtl && (dir == GTK_DIR_UP || dir == GTK_DIR_LEFT)) ||
1273 (!rtl && (dir == GTK_DIR_DOWN || dir == GTK_DIR_RIGHT)))
1275 result = g_list_reverse (result);
1282 gtk_toolbar_focus_home_or_end (GtkToolbar *toolbar,
1283 gboolean focus_home)
1285 GList *children, *list;
1286 GtkDirectionType dir = focus_home? GTK_DIR_RIGHT : GTK_DIR_LEFT;
1288 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1290 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
1292 children = g_list_reverse (children);
1294 dir = (dir == GTK_DIR_RIGHT)? GTK_DIR_LEFT : GTK_DIR_RIGHT;
1297 for (list = children; list != NULL; list = list->next)
1299 GtkWidget *child = list->data;
1301 if (GTK_CONTAINER (toolbar)->focus_child == child)
1304 if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1308 g_list_free (children);
1313 /* Keybinding handler. This function is called when the user presses
1314 * Ctrl TAB or an arrow key.
1317 gtk_toolbar_move_focus (GtkToolbar *toolbar,
1318 GtkDirectionType dir)
1321 gboolean try_focus = FALSE;
1323 GtkContainer *container = GTK_CONTAINER (toolbar);
1325 if (container->focus_child &&
1326 gtk_widget_child_focus (container->focus_child, dir))
1331 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1333 for (list = children; list != NULL; list = list->next)
1335 GtkWidget *child = list->data;
1337 if (try_focus && GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1340 if (child == GTK_CONTAINER (toolbar)->focus_child)
1344 g_list_free (children);
1349 /* The focus handler for the toolbar. It called when the user presses
1350 * TAB or otherwise tries to focus the toolbar.
1353 gtk_toolbar_focus (GtkWidget *widget,
1354 GtkDirectionType dir)
1356 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1357 GList *children, *list;
1359 /* if focus is already somewhere inside the toolbar then return FALSE.
1360 * The only way focus can stay inside the toolbar is when the user presses
1361 * arrow keys or Ctrl TAB (both of which are handled by the
1362 * gtk_toolbar_move_focus() keybinding function.
1364 if (GTK_CONTAINER (widget)->focus_child)
1367 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1369 for (list = children; list != NULL; list = list->next)
1371 GtkWidget *child = list->data;
1373 if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1377 g_list_free (children);
1383 style_change_notify (GtkToolbar *toolbar)
1385 if (!toolbar->style_set)
1387 /* pretend it was set, then unset, thus reverting to new default */
1388 toolbar->style_set = TRUE;
1389 gtk_toolbar_unset_style (toolbar);
1394 icon_size_change_notify (GtkToolbar *toolbar)
1396 if (!toolbar->icon_size_set)
1398 /* pretend it was set, then unset, thus reverting to new default */
1399 toolbar->icon_size_set = TRUE;
1400 gtk_toolbar_unset_icon_size (toolbar);
1404 static GtkSettings *
1405 toolbar_get_settings (GtkToolbar *toolbar)
1407 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1408 return priv->settings;
1412 gtk_toolbar_screen_changed (GtkWidget *widget,
1413 GdkScreen *previous_screen)
1415 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
1416 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1417 GtkSettings *old_settings = toolbar_get_settings (toolbar);
1418 GtkSettings *settings;
1420 if (gtk_widget_has_screen (GTK_WIDGET (toolbar)))
1421 settings = gtk_widget_get_settings (GTK_WIDGET (toolbar));
1425 if (settings == old_settings)
1430 g_signal_handler_disconnect (old_settings, toolbar->style_set_connection);
1431 g_signal_handler_disconnect (old_settings, toolbar->icon_size_connection);
1433 g_object_unref (old_settings);
1438 toolbar->style_set_connection =
1439 g_signal_connect_swapped (settings,
1440 "notify::gtk-toolbar-style",
1441 G_CALLBACK (style_change_notify),
1443 toolbar->icon_size_connection =
1444 g_signal_connect_swapped (settings,
1445 "notify::gtk-toolbar-icon-size",
1446 G_CALLBACK (icon_size_change_notify),
1449 g_object_ref (settings);
1450 priv->settings = settings;
1453 priv->settings = NULL;
1455 style_change_notify (toolbar);
1456 icon_size_change_notify (toolbar);
1460 find_drop_pos (GtkToolbar *toolbar,
1466 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1467 GtkOrientation orientation;
1468 GtkTextDirection direction;
1472 gint best_distance, best_pos, best_index, index;
1474 orientation = toolbar->orientation;
1475 direction = gtk_widget_get_direction (GTK_WIDGET (toolbar));
1476 border_width = GTK_CONTAINER (toolbar)->border_width + get_internal_padding (toolbar);
1478 items = priv->items;
1482 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1484 if (direction == GTK_TEXT_DIR_LTR)
1485 *drop_pos = border_width;
1487 *drop_pos = GTK_WIDGET (toolbar)->allocation.width - border_width;
1491 *drop_pos = border_width;
1496 /* initial conditions */
1497 item = GTK_TOOL_ITEM (items->data);
1499 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1501 if (direction == GTK_TEXT_DIR_LTR)
1502 best_pos = GTK_WIDGET (item)->allocation.x;
1504 best_pos = GTK_WIDGET (item)->allocation.x +
1505 GTK_WIDGET (item)->allocation.width;
1506 best_distance = ABS (best_pos - x);
1510 best_pos = GTK_WIDGET (item)->allocation.y;
1511 best_distance = ABS (best_pos - y);
1517 item = GTK_TOOL_ITEM (items->data);
1519 if (GTK_WIDGET_DRAWABLE (item) && !item->pack_end)
1523 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1525 if (direction == GTK_TEXT_DIR_LTR)
1526 pos = GTK_WIDGET (item)->allocation.x +
1527 GTK_WIDGET (item)->allocation.width;
1529 pos = GTK_WIDGET (item)->allocation.x;
1530 distance = ABS (pos - x);
1534 pos = GTK_WIDGET (item)->allocation.y +
1535 GTK_WIDGET (item)->allocation.height;
1536 distance = ABS (pos - y);
1538 if (distance < best_distance)
1542 best_distance = distance;
1545 items = items->next;
1547 *drop_index = best_index;
1548 *drop_pos = best_pos;
1552 gtk_toolbar_drag_leave (GtkWidget *widget,
1553 GdkDragContext *context,
1556 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1557 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1559 if (priv->drag_highlight)
1561 gdk_window_set_user_data (priv->drag_highlight, NULL);
1562 gdk_window_destroy (priv->drag_highlight);
1563 priv->drag_highlight = NULL;
1566 priv->drop_index = -1;
1570 gtk_toolbar_drag_motion (GtkWidget *widget,
1571 GdkDragContext *context,
1576 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1577 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1578 gint new_index, new_pos;
1580 find_drop_pos(toolbar, x, y, &new_index, &new_pos);
1582 if (!priv->drag_highlight)
1584 GdkWindowAttr attributes;
1585 guint attributes_mask;
1587 attributes.window_type = GDK_WINDOW_CHILD;
1588 attributes.wclass = GDK_INPUT_OUTPUT;
1589 attributes.visual = gtk_widget_get_visual (widget);
1590 attributes.colormap = gtk_widget_get_colormap (widget);
1591 attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK;
1592 attributes.width = 1;
1593 attributes.height = 1;
1594 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
1595 priv->drag_highlight = gdk_window_new (widget->window,
1596 &attributes, attributes_mask);
1597 gdk_window_set_user_data (priv->drag_highlight, widget);
1598 gdk_window_set_background (priv->drag_highlight,
1599 &widget->style->fg[widget->state]);
1602 if (priv->drop_index < 0 ||
1603 priv->drop_index != new_index)
1605 gint border_width = GTK_CONTAINER (toolbar)->border_width;
1606 priv->drop_index = new_index;
1607 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1609 gdk_window_move_resize (priv->drag_highlight,
1610 widget->allocation.x + new_pos - 1,
1611 widget->allocation.y + border_width,
1612 2, widget->allocation.height-border_width*2);
1616 gdk_window_move_resize (priv->drag_highlight,
1617 widget->allocation.x + border_width,
1618 widget->allocation.y + new_pos - 1,
1619 widget->allocation.width-border_width*2, 2);
1623 gdk_window_show (priv->drag_highlight);
1625 gdk_drag_status (context, context->suggested_action, time_);
1631 gtk_toolbar_get_child_property (GtkContainer *container,
1637 GtkToolItem *item = GTK_TOOL_ITEM (child);
1639 switch (property_id)
1641 case CHILD_PROP_PACK_END:
1642 g_value_set_boolean (value, item->pack_end);
1645 case CHILD_PROP_HOMOGENEOUS:
1646 g_value_set_boolean (value, item->homogeneous);
1649 case CHILD_PROP_EXPAND:
1650 g_value_set_boolean (value, item->expand);
1654 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
1660 gtk_toolbar_set_child_property (GtkContainer *container,
1663 const GValue *value,
1666 switch (property_id)
1668 case CHILD_PROP_PACK_END:
1669 gtk_tool_item_set_pack_end (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
1672 case CHILD_PROP_HOMOGENEOUS:
1673 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
1676 case CHILD_PROP_EXPAND:
1677 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
1681 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
1687 gtk_toolbar_add (GtkContainer *container,
1690 GtkToolbar *toolbar;
1692 g_return_if_fail (GTK_IS_TOOLBAR (container));
1693 g_return_if_fail (widget != NULL);
1695 toolbar = GTK_TOOLBAR (container);
1697 if (GTK_IS_TOOL_ITEM (widget))
1698 gtk_toolbar_insert (toolbar, GTK_TOOL_ITEM (widget), 0);
1700 gtk_toolbar_append_widget (toolbar, widget, NULL, NULL);
1704 gtk_toolbar_remove (GtkContainer *container,
1707 GtkToolbar *toolbar;
1708 GtkToolItem *item = NULL;
1710 g_return_if_fail (GTK_IS_TOOLBAR (container));
1711 g_return_if_fail (GTK_IS_WIDGET (widget));
1713 toolbar = GTK_TOOLBAR (container);
1715 if (GTK_IS_TOOL_ITEM (widget))
1717 item = GTK_TOOL_ITEM (widget);
1721 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1724 for (list = priv->items; list != NULL; list = list->next)
1726 if (GTK_BIN (list->data)->child == widget)
1734 g_return_if_fail (item != NULL);
1736 gtk_toolbar_remove_tool_item (GTK_TOOLBAR (container), item);
1740 gtk_toolbar_forall (GtkContainer *container,
1741 gboolean include_internals,
1742 GtkCallback callback,
1743 gpointer callback_data)
1745 GtkToolbar *toolbar = GTK_TOOLBAR (container);
1746 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1749 g_return_if_fail (callback != NULL);
1751 items = priv->items;
1755 GtkToolItem *item = GTK_TOOL_ITEM (items->data);
1757 items = items->next;
1759 (*callback) (GTK_WIDGET (item), callback_data);
1762 if (include_internals)
1763 (* callback) (priv->arrow_button, callback_data);
1767 gtk_toolbar_child_type (GtkContainer *container)
1769 return GTK_TYPE_TOOL_ITEM;
1773 gtk_toolbar_reconfigured (GtkToolbar *toolbar)
1775 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1778 items = priv->items;
1781 GtkToolItem *item = GTK_TOOL_ITEM (items->data);
1783 gtk_tool_item_toolbar_reconfigured (item);
1785 items = items->next;
1790 gtk_toolbar_real_orientation_changed (GtkToolbar *toolbar,
1791 GtkOrientation orientation)
1793 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1794 if (toolbar->orientation != orientation)
1796 toolbar->orientation = orientation;
1798 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1799 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_DOWN, GTK_SHADOW_NONE);
1800 else if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
1801 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
1803 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_LEFT, GTK_SHADOW_NONE);
1805 gtk_toolbar_reconfigured (toolbar);
1807 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
1808 g_object_notify (G_OBJECT (toolbar), "orientation");
1813 gtk_toolbar_real_style_changed (GtkToolbar *toolbar,
1814 GtkToolbarStyle style)
1816 if (toolbar->style != style)
1818 toolbar->style = style;
1820 gtk_toolbar_reconfigured (toolbar);
1822 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
1823 g_object_notify (G_OBJECT (toolbar), "toolbar_style");
1828 menu_position_func (GtkMenu *menu,
1834 GtkToolbar *toolbar = GTK_TOOLBAR (user_data);
1835 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1837 GtkRequisition menu_req;
1839 gdk_window_get_origin (GTK_BUTTON (priv->arrow_button)->event_window, x, y);
1840 gtk_widget_size_request (priv->arrow_button, &req);
1841 gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
1843 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1845 *y += priv->arrow_button->allocation.height;
1846 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
1847 *x += priv->arrow_button->allocation.width - req.width;
1849 *x += req.width - menu_req.width;
1853 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
1854 *x += priv->arrow_button->allocation.width;
1856 *x -= menu_req.width;
1857 *y += priv->arrow_button->allocation.height - req.height;
1864 menu_deactivated (GtkWidget *menu,
1865 GtkToolbar *toolbar)
1867 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1869 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->arrow_button), FALSE);
1873 remove_item (GtkWidget *menu_item,
1876 gtk_container_remove (GTK_CONTAINER (menu_item->parent), menu_item);
1880 show_menu (GtkToolbar *toolbar,
1881 GdkEventButton *event)
1883 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1888 gtk_container_foreach (GTK_CONTAINER (priv->menu), remove_item, NULL);
1889 gtk_widget_destroy (GTK_WIDGET (priv->menu));
1892 priv->menu = GTK_MENU (gtk_menu_new ());
1893 g_signal_connect (priv->menu, "deactivate", G_CALLBACK (menu_deactivated), toolbar);
1895 for (list = priv->items; list != NULL; list = list->next)
1897 GtkToolItem *item = list->data;
1899 if (toolbar_item_visible (toolbar, item) && item->overflow_item)
1901 GtkWidget *menu_item = gtk_tool_item_retrieve_proxy_menu_item (item);
1905 g_assert (GTK_IS_MENU_ITEM (menu_item));
1906 gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), menu_item);
1911 gtk_widget_show_all (GTK_WIDGET (priv->menu));
1913 gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL,
1914 menu_position_func, toolbar,
1915 event? event->button : 0, event? event->time : gtk_get_current_event_time());
1919 gtk_toolbar_arrow_button_clicked (GtkWidget *button,
1920 GtkToolbar *toolbar)
1922 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1924 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->arrow_button)) &&
1925 (!priv->menu || !GTK_WIDGET_VISIBLE (GTK_WIDGET (priv->menu))))
1927 /* We only get here when the button is clicked with the keybaord,
1928 * because mouse button presses result in the menu being shown so
1929 * that priv->menu would be non-NULL and visible.
1931 show_menu (toolbar, NULL);
1932 gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->menu), FALSE);
1937 gtk_toolbar_arrow_button_press (GtkWidget *button,
1938 GdkEventButton *event,
1939 GtkToolbar *toolbar)
1941 show_menu (toolbar, event);
1942 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
1948 gtk_toolbar_button_press (GtkWidget *toolbar,
1949 GdkEventButton *event)
1951 if (event->button == 3)
1953 gboolean return_value;
1955 g_signal_emit (toolbar, toolbar_signals[POPUP_CONTEXT_MENU], 0,
1956 (int)event->x_root, (int)event->y_root, event->button,
1959 return return_value;
1966 gtk_toolbar_popup_menu (GtkWidget *toolbar)
1968 gboolean return_value;
1969 /* This function is the handler for the "popup menu" keybinding,
1970 * ie., it is called when the user presses Shift F10
1972 g_signal_emit (toolbar, toolbar_signals[POPUP_CONTEXT_MENU], 0,
1973 -1, -1, -1, &return_value);
1975 return return_value;
1979 gtk_toolbar_update_button_relief (GtkToolbar *toolbar)
1981 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1983 gtk_toolbar_reconfigured (toolbar);
1985 gtk_button_set_relief (GTK_BUTTON (priv->arrow_button), get_button_relief (toolbar));
1988 static GtkReliefStyle
1989 get_button_relief (GtkToolbar *toolbar)
1991 GtkReliefStyle button_relief = GTK_RELIEF_NORMAL;
1993 gtk_widget_ensure_style (GTK_WIDGET (toolbar));
1995 gtk_widget_style_get (GTK_WIDGET (toolbar),
1996 "button_relief", &button_relief,
1999 return button_relief;
2003 get_space_size (GtkToolbar *toolbar)
2005 gint space_size = DEFAULT_SPACE_SIZE;
2007 gtk_widget_style_get (GTK_WIDGET (toolbar),
2008 "space_size", &space_size,
2015 get_internal_padding (GtkToolbar *toolbar)
2019 gtk_widget_style_get (GTK_WIDGET (toolbar),
2020 "internal_padding", &ipadding,
2027 gtk_toolbar_check_old_api (GtkToolbar *toolbar)
2029 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2031 if (priv->api_mode == NEW_API)
2033 g_warning ("mixing deprecated and non-deprecated GtkToolbar API is not allowed");
2037 priv->api_mode = OLD_API;
2042 gtk_toolbar_check_new_api (GtkToolbar *toolbar)
2044 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2046 if (priv->api_mode == OLD_API)
2048 g_warning ("mixing deprecated and non-deprecated GtkToolbar API is not allowed");
2052 priv->api_mode = NEW_API;
2057 gtk_toolbar_insert_tool_item (GtkToolbar *toolbar,
2061 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2063 priv->items = g_list_insert (priv->items, item, pos);
2064 toolbar->num_children++;
2066 gtk_widget_set_parent (GTK_WIDGET (item), GTK_WIDGET (toolbar));
2070 gtk_toolbar_remove_tool_item (GtkToolbar *toolbar,
2073 GtkToolbarPrivate *priv;
2077 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2078 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2079 g_return_if_fail (GTK_IS_TOOL_ITEM (item));
2080 g_return_if_fail (g_list_find (priv->items, item));
2084 for (tmp = priv->items; tmp != NULL; tmp = tmp->next)
2086 if (tmp->data == item)
2092 priv->items = g_list_remove (priv->items, item);
2094 gtk_widget_unparent (GTK_WIDGET (item));
2096 if (priv->api_mode == OLD_API)
2098 GtkToolbarChild *toolbar_child;
2100 toolbar_child = g_list_nth_data (toolbar->children, nth_child);
2101 toolbar->children = g_list_remove (toolbar->children, toolbar_child);
2103 g_free (toolbar_child);
2106 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2110 gtk_toolbar_new (void)
2112 GtkToolbar *toolbar;
2114 toolbar = g_object_new (GTK_TYPE_TOOLBAR, NULL);
2116 return GTK_WIDGET (toolbar);
2120 gtk_toolbar_insert (GtkToolbar *toolbar,
2124 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2125 g_return_if_fail (GTK_IS_TOOL_ITEM (item));
2127 if (!gtk_toolbar_check_new_api (toolbar))
2130 gtk_toolbar_insert_tool_item (toolbar, item, pos);
2134 gtk_toolbar_get_item_index (GtkToolbar *toolbar,
2137 GtkToolbarPrivate *priv;
2139 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
2140 g_return_val_if_fail (GTK_IS_TOOL_ITEM (item), -1);
2142 if (!gtk_toolbar_check_new_api (toolbar))
2145 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2146 g_return_val_if_fail (g_list_find (priv->items, item) != NULL, -1);
2148 return g_list_index (priv->items, item);
2152 gtk_toolbar_set_orientation (GtkToolbar *toolbar,
2153 GtkOrientation orientation)
2155 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2157 g_signal_emit (toolbar, toolbar_signals[ORIENTATION_CHANGED], 0, orientation);
2161 gtk_toolbar_get_orientation (GtkToolbar *toolbar)
2163 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_ORIENTATION_HORIZONTAL);
2165 return toolbar->orientation;
2169 gtk_toolbar_set_style (GtkToolbar *toolbar,
2170 GtkToolbarStyle style)
2172 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2174 toolbar->style_set = TRUE;
2175 g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
2181 gtk_toolbar_get_style (GtkToolbar *toolbar)
2183 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), DEFAULT_TOOLBAR_STYLE);
2185 return toolbar->style;
2189 gtk_toolbar_unset_style (GtkToolbar *toolbar)
2191 GtkToolbarStyle style;
2193 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2195 if (toolbar->style_set)
2197 GtkSettings *settings = toolbar_get_settings (toolbar);
2200 g_object_get (settings,
2201 "gtk-toolbar-style", &style,
2204 style = DEFAULT_TOOLBAR_STYLE;
2206 if (style != toolbar->style)
2207 g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
2209 toolbar->style_set = FALSE;
2214 gtk_toolbar_set_tooltips (GtkToolbar *toolbar,
2217 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2220 gtk_tooltips_enable (toolbar->tooltips);
2222 gtk_tooltips_disable (toolbar->tooltips);
2226 gtk_toolbar_get_tooltips (GtkToolbar *toolbar)
2228 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2230 return toolbar->tooltips->enabled;
2234 gtk_toolbar_get_n_items (GtkToolbar *toolbar)
2236 GtkToolbarPrivate *priv;
2238 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
2240 if (!gtk_toolbar_check_new_api (toolbar))
2243 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2245 return g_list_length (priv->items);
2249 * returns NULL if n is out of range
2252 gtk_toolbar_get_nth_item (GtkToolbar *toolbar,
2255 GtkToolbarPrivate *priv;
2257 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
2259 if (!gtk_toolbar_check_new_api (toolbar))
2262 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2264 return g_list_nth_data (priv->items, n);
2268 gtk_toolbar_set_icon_size (GtkToolbar *toolbar,
2269 GtkIconSize icon_size)
2271 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2273 toolbar->icon_size_set = TRUE;
2275 if (toolbar->icon_size == icon_size)
2278 toolbar->icon_size = icon_size;
2280 gtk_toolbar_reconfigured (toolbar);
2282 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2286 gtk_toolbar_get_icon_size (GtkToolbar *toolbar)
2288 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), DEFAULT_ICON_SIZE);
2290 return toolbar->icon_size;
2294 gtk_toolbar_get_relief_style (GtkToolbar *toolbar)
2296 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_RELIEF_NONE);
2298 return get_button_relief (toolbar);
2302 gtk_toolbar_unset_icon_size (GtkToolbar *toolbar)
2306 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2308 if (toolbar->icon_size_set)
2310 GtkSettings *settings = toolbar_get_settings (toolbar);
2314 g_object_get (settings,
2315 "gtk-toolbar-icon-size", &size,
2319 size = DEFAULT_ICON_SIZE;
2321 if (size != toolbar->icon_size)
2322 gtk_toolbar_set_icon_size (toolbar, size);
2324 toolbar->icon_size_set = FALSE;
2329 gtk_toolbar_set_show_arrow (GtkToolbar *toolbar,
2330 gboolean show_arrow)
2332 GtkToolbarPrivate *priv;
2334 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2336 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2337 show_arrow = show_arrow != FALSE;
2339 if (priv->show_arrow != show_arrow)
2341 priv->show_arrow = show_arrow;
2343 if (!priv->show_arrow)
2344 gtk_widget_hide (priv->arrow_button);
2346 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2347 g_object_notify (G_OBJECT (toolbar), "show_arrow");
2352 gtk_toolbar_get_show_arrow (GtkToolbar *toolbar)
2354 GtkToolbarPrivate *priv;
2356 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2358 if (!gtk_toolbar_check_new_api (toolbar))
2361 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2363 return priv->show_arrow;
2367 gtk_toolbar_get_drop_index (GtkToolbar *toolbar,
2371 gint drop_index, drop_pos;
2373 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2375 if (!gtk_toolbar_check_new_api (toolbar))
2378 find_drop_pos (toolbar, x, y, &drop_index, &drop_pos);
2384 gtk_toolbar_append_item (GtkToolbar *toolbar,
2386 const char *tooltip_text,
2387 const char *tooltip_private_text,
2389 GtkSignalFunc callback,
2392 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
2394 tooltip_text, tooltip_private_text,
2395 icon, callback, user_data,
2396 toolbar->num_children);
2400 gtk_toolbar_prepend_item (GtkToolbar *toolbar,
2402 const char *tooltip_text,
2403 const char *tooltip_private_text,
2405 GtkSignalFunc callback,
2408 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
2410 tooltip_text, tooltip_private_text,
2411 icon, callback, user_data,
2416 gtk_toolbar_insert_item (GtkToolbar *toolbar,
2418 const char *tooltip_text,
2419 const char *tooltip_private_text,
2421 GtkSignalFunc callback,
2425 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
2427 tooltip_text, tooltip_private_text,
2428 icon, callback, user_data,
2433 gtk_toolbar_insert_stock (GtkToolbar *toolbar,
2434 const gchar *stock_id,
2435 const char *tooltip_text,
2436 const char *tooltip_private_text,
2437 GtkSignalFunc callback,
2441 return gtk_toolbar_internal_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
2443 tooltip_text, tooltip_private_text,
2444 NULL, callback, user_data,
2449 gtk_toolbar_append_space (GtkToolbar *toolbar)
2451 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
2455 toolbar->num_children);
2459 gtk_toolbar_prepend_space (GtkToolbar *toolbar)
2461 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
2469 gtk_toolbar_insert_space (GtkToolbar *toolbar,
2472 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
2480 gtk_toolbar_remove_space (GtkToolbar *toolbar,
2485 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2487 if (!gtk_toolbar_check_old_api (toolbar))
2490 item = g_list_nth_data (toolbar->children, position);
2494 g_warning ("Toolbar position %d doesn't exist", position);
2498 if (GTK_BIN (item)->child)
2500 g_warning ("Toolbar position %d is not a space", position);
2503 gtk_toolbar_remove_tool_item (toolbar, item);
2507 gtk_toolbar_append_widget (GtkToolbar *toolbar,
2509 const gchar *tooltip_text,
2510 const gchar *tooltip_private_text)
2512 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
2514 tooltip_text, tooltip_private_text,
2516 toolbar->num_children);
2520 gtk_toolbar_prepend_widget (GtkToolbar *toolbar,
2522 const gchar *tooltip_text,
2523 const gchar *tooltip_private_text)
2525 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
2527 tooltip_text, tooltip_private_text,
2533 gtk_toolbar_insert_widget (GtkToolbar *toolbar,
2535 const char *tooltip_text,
2536 const char *tooltip_private_text,
2539 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
2541 tooltip_text, tooltip_private_text,
2547 gtk_toolbar_append_element (GtkToolbar *toolbar,
2548 GtkToolbarChildType type,
2551 const char *tooltip_text,
2552 const char *tooltip_private_text,
2554 GtkSignalFunc callback,
2557 return gtk_toolbar_insert_element (toolbar, type, widget, text,
2558 tooltip_text, tooltip_private_text,
2559 icon, callback, user_data,
2560 toolbar->num_children);
2564 gtk_toolbar_prepend_element (GtkToolbar *toolbar,
2565 GtkToolbarChildType type,
2568 const char *tooltip_text,
2569 const char *tooltip_private_text,
2571 GtkSignalFunc callback,
2574 return gtk_toolbar_insert_element (toolbar, type, widget, text,
2575 tooltip_text, tooltip_private_text,
2576 icon, callback, user_data, 0);
2580 gtk_toolbar_insert_element (GtkToolbar *toolbar,
2581 GtkToolbarChildType type,
2584 const char *tooltip_text,
2585 const char *tooltip_private_text,
2587 GtkSignalFunc callback,
2591 return gtk_toolbar_internal_insert_element (toolbar, type, widget, text,
2592 tooltip_text, tooltip_private_text,
2593 icon, callback, user_data, position, FALSE);
2597 _gtk_toolbar_elide_underscores (const gchar *original)
2601 gboolean last_underscore;
2603 q = result = g_malloc (strlen (original) + 1);
2604 last_underscore = FALSE;
2606 for (p = original; *p; p++)
2608 if (!last_underscore && *p == '_')
2609 last_underscore = TRUE;
2612 last_underscore = FALSE;
2623 gtk_toolbar_internal_insert_element (GtkToolbar *toolbar,
2624 GtkToolbarChildType type,
2627 const char *tooltip_text,
2628 const char *tooltip_private_text,
2630 GtkSignalFunc callback,
2635 GtkToolbarChild *child;
2636 GtkToolItem *item = NULL;
2638 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
2640 if (!gtk_toolbar_check_old_api (toolbar))
2643 if (type == GTK_TOOLBAR_CHILD_WIDGET)
2644 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
2645 else if (type != GTK_TOOLBAR_CHILD_RADIOBUTTON)
2646 g_return_val_if_fail (widget == NULL, NULL);
2648 child = g_new (GtkToolbarChild, 1);
2652 child->label = NULL;
2656 case GTK_TOOLBAR_CHILD_SPACE:
2657 item = gtk_separator_tool_item_new ();
2658 child->widget = NULL;
2661 case GTK_TOOLBAR_CHILD_WIDGET:
2662 item = gtk_tool_item_new ();
2663 child->widget = widget;
2664 gtk_container_add (GTK_CONTAINER (item), child->widget);
2667 case GTK_TOOLBAR_CHILD_BUTTON:
2668 item = gtk_tool_button_new (NULL, NULL);
2669 child->widget = GTK_TOOL_BUTTON (item)->button;
2672 case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
2673 item = gtk_toggle_tool_button_new ();
2674 child->widget = GTK_TOOL_BUTTON (item)->button;
2677 case GTK_TOOLBAR_CHILD_RADIOBUTTON:
2678 item = gtk_radio_tool_button_new (widget
2679 ? gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget))
2681 child->widget = GTK_TOOL_BUTTON (item)->button;
2685 gtk_widget_show (GTK_WIDGET (item));
2687 if (type == GTK_TOOLBAR_CHILD_BUTTON ||
2688 type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
2689 type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
2695 GtkStockItem stock_item;
2698 gtk_tool_button_set_stock_id (GTK_TOOL_BUTTON (item), text);
2700 gtk_stock_lookup (text, &stock_item);
2701 label_text = _gtk_toolbar_elide_underscores (stock_item.label);
2702 child->label = GTK_WIDGET (gtk_label_new (label_text));
2703 g_free (label_text);
2707 child->label = gtk_label_new (text);
2709 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (item), child->label);
2710 gtk_widget_show (child->label);
2716 gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (item), icon);
2718 /* Applications depend on the toolbar showing the widget for them */
2719 gtk_widget_show (GTK_WIDGET (icon));
2723 * We need to connect to the button's clicked callback because some
2724 * programs may rely on that the widget in the callback is a GtkButton
2727 g_signal_connect (child->widget, "clicked",
2728 callback, user_data);
2731 if ((type != GTK_TOOLBAR_CHILD_SPACE) && tooltip_text)
2732 gtk_tool_item_set_tooltip (item, toolbar->tooltips,
2733 tooltip_text, tooltip_private_text);
2735 toolbar->children = g_list_insert (toolbar->children, child, position);
2737 gtk_toolbar_insert_tool_item (toolbar, item, position);
2739 return child->widget;
2743 gtk_toolbar_finalize (GObject *object)
2746 GtkToolbar *toolbar = GTK_TOOLBAR (object);
2748 if (toolbar->tooltips)
2749 g_object_unref (toolbar->tooltips);
2751 for (list = toolbar->children; list != NULL; list = list->next)
2752 g_free (list->data);
2754 g_list_free (toolbar->children);
2756 G_OBJECT_CLASS (parent_class)->finalize (object);