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 4
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
60 #define MAX_HOMOGENEOUS_N_CHARS 13 /* Items that are wider than this do not participate
61 * in the homogeneous game. In units of
62 * pango_font_get_estimated_char_width().
75 CHILD_PROP_HOMOGENEOUS
87 static void gtk_toolbar_init (GtkToolbar *toolbar);
88 static void gtk_toolbar_class_init (GtkToolbarClass *klass);
90 static void gtk_toolbar_set_property (GObject *object,
94 static void gtk_toolbar_get_property (GObject *object,
99 static gint gtk_toolbar_expose (GtkWidget *widget,
100 GdkEventExpose *event);
101 static void gtk_toolbar_realize (GtkWidget *widget);
102 static void gtk_toolbar_unrealize (GtkWidget *widget);
103 static void gtk_toolbar_size_request (GtkWidget *widget,
104 GtkRequisition *requisition);
105 static void gtk_toolbar_size_allocate (GtkWidget *widget,
106 GtkAllocation *allocation);
107 static void gtk_toolbar_style_set (GtkWidget *widget,
108 GtkStyle *prev_style);
109 static void gtk_toolbar_direction_changed (GtkWidget *widget,
110 GtkTextDirection previous_direction);
111 static gboolean gtk_toolbar_focus (GtkWidget *widget,
112 GtkDirectionType dir);
113 static void gtk_toolbar_screen_changed (GtkWidget *widget,
114 GdkScreen *previous_screen);
115 static void gtk_toolbar_map (GtkWidget *widget);
116 static void gtk_toolbar_unmap (GtkWidget *widget);
118 static void gtk_toolbar_set_child_property (GtkContainer *container,
123 static void gtk_toolbar_get_child_property (GtkContainer *container,
128 static void gtk_toolbar_finalize (GObject *object);
131 static void gtk_toolbar_add (GtkContainer *container,
133 static void gtk_toolbar_remove (GtkContainer *container,
135 static void gtk_toolbar_forall (GtkContainer *container,
136 gboolean include_internals,
137 GtkCallback callback,
138 gpointer callback_data);
139 static GType gtk_toolbar_child_type (GtkContainer *container);
141 static void gtk_toolbar_real_orientation_changed (GtkToolbar *toolbar,
142 GtkOrientation orientation);
143 static void gtk_toolbar_real_style_changed (GtkToolbar *toolbar,
144 GtkToolbarStyle style);
146 static gboolean gtk_toolbar_move_focus (GtkToolbar *toolbar,
147 GtkDirectionType dir);
148 static gboolean gtk_toolbar_focus_home_or_end (GtkToolbar *toolbar,
149 gboolean focus_home);
151 static gboolean gtk_toolbar_button_press (GtkWidget *toolbar,
152 GdkEventButton *event);
153 static gboolean gtk_toolbar_arrow_button_press (GtkWidget *button,
154 GdkEventButton *event,
155 GtkToolbar *toolbar);
156 static void gtk_toolbar_arrow_button_clicked (GtkWidget *button,
157 GtkToolbar *toolbar);
158 static void gtk_toolbar_update_button_relief (GtkToolbar *toolbar);
159 static GtkReliefStyle get_button_relief (GtkToolbar *toolbar);
160 static gint get_internal_padding (GtkToolbar *toolbar);
161 static GtkShadowType get_shadow_type (GtkToolbar *toolbar);
162 static void gtk_toolbar_remove_tool_item (GtkToolbar *toolbar,
164 static gboolean gtk_toolbar_popup_menu (GtkWidget *toolbar);
166 static GtkWidget *gtk_toolbar_internal_insert_element (GtkToolbar *toolbar,
167 GtkToolbarChildType type,
170 const char *tooltip_text,
171 const char *tooltip_private_text,
173 GtkSignalFunc callback,
177 static void gtk_toolbar_insert_tool_item (GtkToolbar *toolbar,
180 gboolean is_placeholder);
189 #define GTK_TOOLBAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_TOOLBAR, GtkToolbarPrivate))
190 typedef struct _ToolbarContent ToolbarContent;
191 struct _ToolbarContent
194 guint is_overflow : 1;
195 guint is_placeholder : 1;
202 struct _GtkToolbarPrivate
207 GtkWidget *arrow_button;
213 GdkWindow *event_window;
215 GtkSettings *settings;
219 gboolean leaving_dnd;
221 gint n_overflow_items_when_dnd_started;
222 GtkToolItem *highlight_tool_item;
225 static GtkContainerClass *parent_class = NULL;
226 static guint toolbar_signals [LAST_SIGNAL] = { 0 };
229 gtk_toolbar_get_type (void)
231 static GtkType type = 0;
235 static const GTypeInfo type_info =
237 sizeof (GtkToolbarClass),
238 (GBaseInitFunc) NULL,
239 (GBaseFinalizeFunc) NULL,
240 (GClassInitFunc) gtk_toolbar_class_init,
241 (GClassFinalizeFunc) NULL,
245 (GInstanceInitFunc) gtk_toolbar_init,
248 type = g_type_register_static (GTK_TYPE_CONTAINER,
257 add_arrow_bindings (GtkBindingSet *binding_set,
259 GtkDirectionType dir)
261 guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
263 gtk_binding_entry_add_signal (binding_set, keysym, 0,
265 GTK_TYPE_DIRECTION_TYPE, dir);
266 gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
268 GTK_TYPE_DIRECTION_TYPE, dir);
272 add_ctrl_tab_bindings (GtkBindingSet *binding_set,
273 GdkModifierType modifiers,
274 GtkDirectionType direction)
276 gtk_binding_entry_add_signal (binding_set,
277 GDK_Tab, GDK_CONTROL_MASK | modifiers,
279 GTK_TYPE_DIRECTION_TYPE, direction);
280 gtk_binding_entry_add_signal (binding_set,
281 GDK_KP_Tab, GDK_CONTROL_MASK | modifiers,
283 GTK_TYPE_DIRECTION_TYPE, direction);
287 gtk_toolbar_class_init (GtkToolbarClass *klass)
289 GObjectClass *gobject_class;
290 GtkWidgetClass *widget_class;
291 GtkContainerClass *container_class;
292 GtkBindingSet *binding_set;
294 parent_class = g_type_class_peek_parent (klass);
296 gobject_class = (GObjectClass *)klass;
297 widget_class = (GtkWidgetClass *)klass;
298 container_class = (GtkContainerClass *)klass;
300 gobject_class->set_property = gtk_toolbar_set_property;
301 gobject_class->get_property = gtk_toolbar_get_property;
302 gobject_class->finalize = gtk_toolbar_finalize;
304 widget_class->button_press_event = gtk_toolbar_button_press;
305 widget_class->expose_event = gtk_toolbar_expose;
306 widget_class->size_request = gtk_toolbar_size_request;
307 widget_class->size_allocate = gtk_toolbar_size_allocate;
308 widget_class->style_set = gtk_toolbar_style_set;
309 widget_class->direction_changed = gtk_toolbar_direction_changed;
310 widget_class->focus = gtk_toolbar_focus;
311 widget_class->screen_changed = gtk_toolbar_screen_changed;
312 widget_class->realize = gtk_toolbar_realize;
313 widget_class->unrealize = gtk_toolbar_unrealize;
314 widget_class->map = gtk_toolbar_map;
315 widget_class->unmap = gtk_toolbar_unmap;
316 widget_class->popup_menu = gtk_toolbar_popup_menu;
318 container_class->add = gtk_toolbar_add;
319 container_class->remove = gtk_toolbar_remove;
320 container_class->forall = gtk_toolbar_forall;
321 container_class->child_type = gtk_toolbar_child_type;
322 container_class->get_child_property = gtk_toolbar_get_child_property;
323 container_class->set_child_property = gtk_toolbar_set_child_property;
325 klass->orientation_changed = gtk_toolbar_real_orientation_changed;
326 klass->style_changed = gtk_toolbar_real_style_changed;
329 * GtkToolbar::orientation-changed:
330 * @toolbar: the object which emitted the signal
331 * @orientation: the new #GtkOrientation of the toolbar
333 * Emitted when the orientation of the toolbar changes.
335 toolbar_signals[ORIENTATION_CHANGED] =
336 g_signal_new ("orientation-changed",
337 G_OBJECT_CLASS_TYPE (klass),
339 G_STRUCT_OFFSET (GtkToolbarClass, orientation_changed),
341 g_cclosure_marshal_VOID__ENUM,
343 GTK_TYPE_ORIENTATION);
345 * GtkToolbar::style-changed:
346 * @toolbar: The #GtkToolbar which emitted the signal
347 * @style: the new #GtkToolbarStyle of the toolbar
349 * Emitted when the style of the toolbar changes.
351 toolbar_signals[STYLE_CHANGED] =
352 g_signal_new ("style-changed",
353 G_OBJECT_CLASS_TYPE (klass),
355 G_STRUCT_OFFSET (GtkToolbarClass, style_changed),
357 g_cclosure_marshal_VOID__ENUM,
359 GTK_TYPE_TOOLBAR_STYLE);
361 * GtkToolbar::popup-context-menu:
362 * @toolbar: the #GtkToolbar which emitted the signal
363 * @x: the x coordinate of the point where the menu should appear
364 * @y: the y coordinate of the point where the menu should appear
365 * @button: the mouse button the user pressed, or -1
367 * Emitted when the user right-clicks the toolbar or uses the
368 * keybinding to display a popup menu.
370 * Application developers should handle this signal if they want
371 * to display a context menu on the toolbar. The context-menu should
372 * appear at the coordinates given by @x and @y. The mouse button
373 * number is given by the @button parameter. If the menu was popped
374 * up using the keybaord, @button is -1.
376 * Return value: return %TRUE if the signal was handled, %FALSE if not
378 toolbar_signals[POPUP_CONTEXT_MENU] =
379 g_signal_new ("popup_context_menu",
380 G_OBJECT_CLASS_TYPE (klass),
382 G_STRUCT_OFFSET (GtkToolbarClass, popup_context_menu),
383 _gtk_boolean_handled_accumulator, NULL,
384 _gtk_marshal_BOOLEAN__INT_INT_INT,
386 G_TYPE_INT, G_TYPE_INT,
389 * GtkToolbar::move-focus:
390 * @toolbar: the #GtkToolbar which emitted the signal
391 * @dir: a #GtkDirection
393 * A keybinding signal used internally by GTK+. This signal can't
394 * be used in application code.
396 * Return value: %TRUE if the signal was handled, %FALSE if not
398 toolbar_signals[MOVE_FOCUS] =
399 _gtk_binding_signal_new ("move_focus",
400 G_TYPE_FROM_CLASS (klass),
401 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
402 G_CALLBACK (gtk_toolbar_move_focus),
404 _gtk_marshal_BOOLEAN__ENUM,
406 GTK_TYPE_DIRECTION_TYPE);
408 * GtkToolbar::focus-home-or-end:
409 * @toolbar: the #GtkToolbar which emitted the signal
410 * @focus_home: %TRUE if the first item should be focused
412 * A keybinding signal used internally by GTK+. This signal can't
413 * be used in application code
415 * Return value: %TRUE if the signal was handled, %FALSE if not
417 toolbar_signals[FOCUS_HOME_OR_END] =
418 _gtk_binding_signal_new ("focus_home_or_end",
419 G_OBJECT_CLASS_TYPE (klass),
420 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
421 G_CALLBACK (gtk_toolbar_focus_home_or_end),
423 _gtk_marshal_BOOLEAN__BOOLEAN,
428 g_object_class_install_property (gobject_class,
430 g_param_spec_enum ("orientation",
432 _("The orientation of the toolbar"),
433 GTK_TYPE_ORIENTATION,
434 GTK_ORIENTATION_HORIZONTAL,
437 g_object_class_install_property (gobject_class,
439 g_param_spec_enum ("toolbar_style",
441 _("How to draw the toolbar"),
442 GTK_TYPE_TOOLBAR_STYLE,
445 g_object_class_install_property (gobject_class,
447 g_param_spec_boolean ("show_arrow",
449 _("If an arrow should be shown if the toolbar doesn't fit"),
453 /* child properties */
454 gtk_container_class_install_child_property (container_class,
456 g_param_spec_boolean ("expand",
458 _("Whether the item should receive extra space when the toolbar grows"),
462 gtk_container_class_install_child_property (container_class,
463 CHILD_PROP_HOMOGENEOUS,
464 g_param_spec_boolean ("homogeneous",
466 _("Whether the item should be the same size as other homogeneous items"),
470 /* style properties */
471 gtk_widget_class_install_style_property (widget_class,
472 g_param_spec_int ("space_size",
474 _("Size of spacers"),
480 gtk_widget_class_install_style_property (widget_class,
481 g_param_spec_int ("internal_padding",
482 _("Internal padding"),
483 _("Amount of border space between the toolbar shadow and the buttons"),
489 gtk_widget_class_install_style_property (widget_class,
490 g_param_spec_enum ("space_style",
492 _("Whether spacers are vertical lines or just blank"),
493 GTK_TYPE_TOOLBAR_SPACE_STYLE,
497 gtk_widget_class_install_style_property (widget_class,
498 g_param_spec_enum ("button_relief",
500 _("Type of bevel around toolbar buttons"),
501 GTK_TYPE_RELIEF_STYLE,
504 gtk_widget_class_install_style_property (widget_class,
505 g_param_spec_enum ("shadow_type",
507 _("Style of bevel around the toolbar"),
508 GTK_TYPE_SHADOW_TYPE,
512 gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-style",
514 _("Whether default toolbars have text only, text and icons, icons only, etc."),
515 GTK_TYPE_TOOLBAR_STYLE,
516 DEFAULT_TOOLBAR_STYLE,
519 gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-icon-size",
520 _("Toolbar icon size"),
521 _("Size of icons in default toolbars"),
526 binding_set = gtk_binding_set_by_class (klass);
528 add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
529 add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
530 add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
531 add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
533 gtk_binding_entry_add_signal (binding_set, GDK_KP_Home, 0,
534 "focus_home_or_end", 1,
535 G_TYPE_BOOLEAN, TRUE);
536 gtk_binding_entry_add_signal (binding_set, GDK_Home, 0,
537 "focus_home_or_end", 1,
538 G_TYPE_BOOLEAN, TRUE);
539 gtk_binding_entry_add_signal (binding_set, GDK_KP_End, 0,
540 "focus_home_or_end", 1,
541 G_TYPE_BOOLEAN, FALSE);
542 gtk_binding_entry_add_signal (binding_set, GDK_End, 0,
543 "focus_home_or_end", 1,
544 G_TYPE_BOOLEAN, FALSE);
546 add_ctrl_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
547 add_ctrl_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
549 g_type_class_add_private (gobject_class, sizeof (GtkToolbarPrivate));
553 gtk_toolbar_init (GtkToolbar *toolbar)
555 GtkToolbarPrivate *priv;
557 GTK_WIDGET_UNSET_FLAGS (toolbar, GTK_CAN_FOCUS);
558 GTK_WIDGET_SET_FLAGS (toolbar, GTK_NO_WINDOW);
560 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
562 toolbar->orientation = GTK_ORIENTATION_HORIZONTAL;
563 toolbar->style = DEFAULT_TOOLBAR_STYLE;
564 toolbar->icon_size = DEFAULT_ICON_SIZE;
565 toolbar->tooltips = gtk_tooltips_new ();
566 g_object_ref (toolbar->tooltips);
567 gtk_object_sink (GTK_OBJECT (toolbar->tooltips));
569 priv->arrow_button = gtk_toggle_button_new ();
570 g_signal_connect (priv->arrow_button, "button_press_event",
571 G_CALLBACK (gtk_toolbar_arrow_button_press), toolbar);
572 g_signal_connect (priv->arrow_button, "clicked",
573 G_CALLBACK (gtk_toolbar_arrow_button_clicked), toolbar);
574 gtk_button_set_relief (GTK_BUTTON (priv->arrow_button),
575 get_button_relief (toolbar));
577 priv->api_mode = DONT_KNOW;
579 gtk_button_set_focus_on_click (GTK_BUTTON (priv->arrow_button), FALSE);
581 priv->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
582 gtk_widget_set_name (priv->arrow, "gtk-toolbar-arrow");
583 gtk_widget_show (priv->arrow);
584 gtk_container_add (GTK_CONTAINER (priv->arrow_button), priv->arrow);
586 gtk_widget_set_parent (priv->arrow_button, GTK_WIDGET (toolbar));
588 /* which child position a drop will occur at */
590 priv->show_arrow = TRUE;
591 priv->settings = NULL;
593 priv->timer = g_timer_new ();
597 toolbar_item_visible (GtkToolbar *toolbar,
600 if (GTK_WIDGET_VISIBLE (item) &&
601 ((toolbar->orientation == GTK_ORIENTATION_HORIZONTAL &&
602 gtk_tool_item_get_visible_horizontal (item)) ||
603 (toolbar->orientation == GTK_ORIENTATION_VERTICAL &&
604 gtk_tool_item_get_visible_vertical (item))))
606 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
608 /* With the old toolbar you could hide a button by calling gtk_widget_hide()
609 * on it. This doesn't work with the new API because the GtkToolItem will not be
612 if (priv->api_mode == OLD_API)
614 GtkWidget *bin_child = GTK_BIN (item)->child;
616 if (bin_child && !GTK_WIDGET_VISIBLE (bin_child))
627 toolbar_item_is_homogeneous (GtkToolbar *toolbar,
631 GtkWidget *widget = GTK_WIDGET (item);
632 GtkRequisition requisition;
633 PangoContext *context;
634 PangoFontMetrics *metrics;
636 gint max_homogeneous_pixels;
638 context = gtk_widget_get_pango_context (widget);
639 metrics = pango_context_get_metrics (context,
640 widget->style->font_desc,
641 pango_context_get_language (context));
642 char_width = pango_font_metrics_get_approximate_char_width (metrics);
643 pango_font_metrics_unref (metrics);
645 max_homogeneous_pixels = PANGO_PIXELS (MAX_HOMOGENEOUS_N_CHARS * char_width);
647 result = gtk_tool_item_get_homogeneous (item) && !GTK_IS_SEPARATOR_TOOL_ITEM (item);
649 gtk_widget_size_request (GTK_WIDGET (item), &requisition);
651 if ((gtk_tool_item_get_is_important (item) &&
652 toolbar->style == GTK_TOOLBAR_BOTH_HORIZ &&
653 toolbar->orientation == GTK_ORIENTATION_HORIZONTAL) ||
654 requisition.width > max_homogeneous_pixels)
663 gtk_toolbar_set_property (GObject *object,
668 GtkToolbar *toolbar = GTK_TOOLBAR (object);
672 case PROP_ORIENTATION:
673 gtk_toolbar_set_orientation (toolbar, g_value_get_enum (value));
675 case PROP_TOOLBAR_STYLE:
676 gtk_toolbar_set_style (toolbar, g_value_get_enum (value));
678 case PROP_SHOW_ARROW:
679 gtk_toolbar_set_show_arrow (toolbar, g_value_get_boolean (value));
682 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
688 gtk_toolbar_get_property (GObject *object,
693 GtkToolbar *toolbar = GTK_TOOLBAR (object);
694 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
698 case PROP_ORIENTATION:
699 g_value_set_enum (value, toolbar->orientation);
701 case PROP_TOOLBAR_STYLE:
702 g_value_set_enum (value, toolbar->style);
704 case PROP_SHOW_ARROW:
705 g_value_set_boolean (value, priv->show_arrow);
708 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
714 gtk_toolbar_map (GtkWidget *widget)
716 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
718 GTK_WIDGET_CLASS (parent_class)->map (widget);
720 if (priv->event_window)
721 gdk_window_show_unraised (priv->event_window);
725 gtk_toolbar_unmap (GtkWidget *widget)
727 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
729 if (priv->event_window)
730 gdk_window_hide (priv->event_window);
732 GTK_WIDGET_CLASS (parent_class)->unmap (widget);
736 gtk_toolbar_realize (GtkWidget *widget)
738 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
739 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
741 GdkWindowAttr attributes;
742 gint attributes_mask;
745 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
747 border_width = GTK_CONTAINER (widget)->border_width;
749 attributes.wclass = GDK_INPUT_ONLY;
750 attributes.window_type = GDK_WINDOW_CHILD;
751 attributes.x = widget->allocation.x + border_width;
752 attributes.y = widget->allocation.y + border_width;
753 attributes.width = widget->allocation.width - border_width * 2;
754 attributes.height = widget->allocation.height - border_width * 2;
755 attributes.event_mask = gtk_widget_get_events (widget);
756 attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
757 GDK_BUTTON_RELEASE_MASK |
758 GDK_ENTER_NOTIFY_MASK |
759 GDK_LEAVE_NOTIFY_MASK);
761 attributes_mask = GDK_WA_X | GDK_WA_Y;
763 widget->window = gtk_widget_get_parent_window (widget);
764 g_object_ref (widget->window);
765 widget->style = gtk_style_attach (widget->style, widget->window);
767 priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget),
768 &attributes, attributes_mask);
769 gdk_window_set_user_data (priv->event_window, toolbar);
773 gtk_toolbar_unrealize (GtkWidget *widget)
775 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
777 if (priv->event_window)
779 gdk_window_set_user_data (priv->event_window, NULL);
780 gdk_window_destroy (priv->event_window);
781 priv->event_window = NULL;
784 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
785 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
789 gtk_toolbar_expose (GtkWidget *widget,
790 GdkEventExpose *event)
792 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
793 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
798 border_width = GTK_CONTAINER (widget)->border_width;
800 if (GTK_WIDGET_DRAWABLE (widget))
802 gtk_paint_box (widget->style,
804 GTK_WIDGET_STATE (widget),
805 get_shadow_type (toolbar),
806 &event->area, widget, "toolbar",
807 border_width + widget->allocation.x,
808 border_width + widget->allocation.y,
809 widget->allocation.width - 2 * border_width,
810 widget->allocation.height - 2 * border_width);
813 for (list = priv->content; list != NULL; list = list->next)
815 ToolbarContent *content = list->data;
816 GtkToolItem *item = content->item;
818 if (!content->is_placeholder)
819 gtk_container_propagate_expose (GTK_CONTAINER (widget),
824 gtk_container_propagate_expose (GTK_CONTAINER (widget),
832 gtk_toolbar_size_request (GtkWidget *widget,
833 GtkRequisition *requisition)
835 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
836 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
838 gint max_child_height;
839 gint max_child_width;
840 gint max_homogeneous_child_width;
841 gint max_homogeneous_child_height;
842 gint homogeneous_size;
844 gint pack_front_size;
846 GtkRequisition arrow_requisition;
848 max_homogeneous_child_width = 0;
849 max_homogeneous_child_height = 0;
851 max_child_height = 0;
852 for (list = priv->content; list != NULL; list = list->next)
854 GtkRequisition requisition;
855 ToolbarContent *content = list->data;
856 GtkToolItem *item = content->item;
858 if (!toolbar_item_visible (toolbar, item))
861 gtk_widget_size_request (GTK_WIDGET (item), &requisition);
863 max_child_width = MAX (max_child_width, requisition.width);
864 max_child_height = MAX (max_child_height, requisition.height);
866 if (toolbar_item_is_homogeneous (toolbar, item))
868 max_homogeneous_child_width = MAX (max_homogeneous_child_width, requisition.width);
869 max_homogeneous_child_height = MAX (max_homogeneous_child_height, requisition.height);
873 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
874 homogeneous_size = max_homogeneous_child_width;
876 homogeneous_size = max_homogeneous_child_height;
879 for (list = priv->content; list != NULL; list = list->next)
881 ToolbarContent *content = list->data;
882 GtkToolItem *item = content->item;
885 if (!toolbar_item_visible (toolbar, item))
888 if (toolbar_item_is_homogeneous (toolbar, item))
890 size = homogeneous_size;
894 GtkRequisition requisition;
896 gtk_widget_size_request (GTK_WIDGET (item), &requisition);
898 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
899 size = requisition.width;
901 size = requisition.height;
904 pack_front_size += size;
907 if (priv->show_arrow && priv->api_mode == NEW_API)
909 gtk_widget_size_request (priv->arrow_button, &arrow_requisition);
911 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
912 long_req = arrow_requisition.width;
914 long_req = arrow_requisition.height;
916 /* There is no point requesting space for the arrow if that would take
917 * up more space than all the items combined
919 long_req = MIN (long_req, pack_front_size);
923 arrow_requisition.height = 0;
924 arrow_requisition.width = 0;
926 long_req = pack_front_size;
929 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
931 requisition->width = long_req;
932 requisition->height = MAX (max_child_height, arrow_requisition.height);
936 requisition->height = long_req;
937 requisition->width = MAX (max_child_width, arrow_requisition.width);
941 ipadding = get_internal_padding (toolbar);
943 requisition->width += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width);
944 requisition->height += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width);
946 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
948 requisition->width += 2 * widget->style->xthickness;
949 requisition->height += 2 * widget->style->ythickness;
952 toolbar->button_maxw = max_homogeneous_child_width;
953 toolbar->button_maxh = max_homogeneous_child_height;
957 fixup_allocation_for_rtl (gint total_size,
958 GtkAllocation *allocation)
960 allocation->x += (total_size - (2 * allocation->x + allocation->width));
964 fixup_allocation_for_vertical (GtkAllocation *allocation)
969 allocation->x = allocation->y;
972 tmp = allocation->width;
973 allocation->width = allocation->height;
974 allocation->height = tmp;
978 get_item_size (GtkToolbar *toolbar,
981 GtkRequisition requisition;
982 GtkToolItem *item = GTK_TOOL_ITEM (child);
984 gtk_widget_get_child_requisition (child, &requisition);
986 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
988 if (toolbar_item_is_homogeneous (toolbar, item))
989 return toolbar->button_maxw;
991 return requisition.width;
995 if (toolbar_item_is_homogeneous (toolbar, item))
996 return toolbar->button_maxh;
998 return requisition.height;
1003 gtk_toolbar_size_allocate (GtkWidget *widget,
1004 GtkAllocation *allocation)
1006 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1007 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1008 GtkAllocation *allocations;
1009 GtkAllocation arrow_allocation;
1011 gint size, pos, short_size;
1014 gboolean need_arrow;
1015 gint n_expand_items;
1017 gint available_size;
1020 GtkRequisition arrow_requisition;
1022 gboolean overflowing;
1024 widget->allocation = *allocation;
1026 border_width = GTK_CONTAINER (toolbar)->border_width;
1028 if (GTK_WIDGET_REALIZED (widget))
1030 gdk_window_move_resize (priv->event_window,
1031 allocation->x + border_width,
1032 allocation->y + border_width,
1033 allocation->width - border_width * 2,
1034 allocation->height - border_width * 2);
1037 border_width += get_internal_padding (toolbar);
1039 gtk_widget_get_child_requisition (GTK_WIDGET (priv->arrow_button),
1040 &arrow_requisition);
1042 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1044 available_size = size = allocation->width - 2 * border_width;
1045 short_size = allocation->height - 2 * border_width;
1046 arrow_size = arrow_requisition.width;
1048 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1050 available_size -= 2 * widget->style->xthickness;
1051 short_size -= 2 * widget->style->ythickness;
1056 available_size = size = allocation->height - 2 * border_width;
1057 short_size = allocation->width - 2 * border_width;
1058 arrow_size = arrow_requisition.height;
1060 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1062 available_size -= 2 * widget->style->ythickness;
1063 short_size -= 2 * widget->style->xthickness;
1067 n_items = g_list_length (priv->content);
1068 allocations = g_new0 (GtkAllocation, n_items);
1071 for (list = priv->content; list != NULL; list = list->next)
1073 ToolbarContent *content = list->data;
1074 GtkToolItem *item = content->item;
1076 if (toolbar_item_visible (toolbar, item))
1077 needed_size += get_item_size (toolbar, GTK_WIDGET (item));
1080 need_arrow = (needed_size > available_size) && priv->show_arrow && priv->api_mode == NEW_API;
1083 size = available_size - arrow_size;
1085 size = available_size;
1089 /* calculate widths of pack front items */
1090 overflowing = FALSE;
1091 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1093 ToolbarContent *content = list->data;
1094 GtkToolItem *item = content->item;
1097 if (!toolbar_item_visible (toolbar, item))
1100 item_size = get_item_size (toolbar, GTK_WIDGET (item));
1101 if (item_size <= size && !overflowing)
1104 allocations[i].width = item_size;
1105 content->is_overflow = FALSE;
1110 content->is_overflow = TRUE;
1117 arrow_allocation.width = arrow_size;
1118 arrow_allocation.height = short_size;
1121 /* expand expandable items */
1123 /* We don't expand when dnd causes items to overflow. Doing so would result in
1124 * weird jumps as items are overflowed and expandable items suddenly get lots of
1125 * extra space. On the other hand we can't disable expanding completely, because
1126 * that would cause a weird jump when dnd begins
1128 if (!(priv->in_dnd && n_overflowed > priv->n_overflow_items_when_dnd_started))
1131 for (list = priv->content; list != NULL; list = list->next)
1133 ToolbarContent *content = list->data;
1134 GtkToolItem *item = content->item;
1136 if (toolbar_item_visible (toolbar, item) &&
1137 gtk_tool_item_get_expand (item) &&
1138 !content->is_overflow)
1144 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1146 ToolbarContent *content = list->data;
1147 GtkToolItem *item = content->item;
1149 if (toolbar_item_visible (toolbar, item) &&
1150 gtk_tool_item_get_expand (item) &&
1151 !content->is_overflow)
1153 gint extra = size / n_expand_items;
1154 if (size % n_expand_items != 0)
1157 allocations[i].width += extra;
1163 g_assert (n_expand_items == 0);
1166 /* position regular items */
1168 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1170 ToolbarContent *content = list->data;
1171 GtkToolItem *item = content->item;
1173 if (toolbar_item_visible (toolbar, item) && !content->is_overflow)
1175 allocations[i].x = pos;
1176 allocations[i].y = border_width;
1177 allocations[i].height = short_size;
1179 pos += allocations[i].width;
1183 /* position arrow */
1186 arrow_allocation.x = available_size - border_width - arrow_allocation.width;
1187 arrow_allocation.y = border_width;
1190 /* fix up allocations in the vertical or RTL cases */
1191 if (toolbar->orientation == GTK_ORIENTATION_VERTICAL)
1193 for (i = 0; i < n_items; ++i)
1194 fixup_allocation_for_vertical (&(allocations[i]));
1197 fixup_allocation_for_vertical (&arrow_allocation);
1199 else if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
1201 for (i = 0; i < n_items; ++i)
1202 fixup_allocation_for_rtl (available_size, &(allocations[i]));
1205 fixup_allocation_for_rtl (available_size, &arrow_allocation);
1208 /* translate the items by allocation->(x,y) */
1209 for (i = 0; i < n_items; ++i)
1211 allocations[i].x += allocation->x;
1212 allocations[i].y += allocation->y;
1214 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1216 allocations[i].x += widget->style->xthickness;
1217 allocations[i].y += widget->style->ythickness;
1223 arrow_allocation.x += allocation->x;
1224 arrow_allocation.y += allocation->y;
1226 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1228 arrow_allocation.x += widget->style->xthickness;
1229 arrow_allocation.y += widget->style->ythickness;
1233 /* finally allocate the items */
1234 for (list = priv->content, i = 0; list != NULL; list = list->next, i++)
1236 ToolbarContent *content = list->data;
1237 GtkToolItem *item = content->item;
1239 if (toolbar_item_visible (toolbar, item) && !content->is_overflow)
1241 gtk_widget_size_allocate (GTK_WIDGET (item), &(allocations[i]));
1242 gtk_widget_set_child_visible (GTK_WIDGET (item), TRUE);
1246 gtk_widget_set_child_visible (GTK_WIDGET (item), FALSE);
1252 gtk_widget_size_allocate (GTK_WIDGET (priv->arrow_button),
1254 gtk_widget_show (GTK_WIDGET (priv->arrow_button));
1258 gtk_widget_hide (GTK_WIDGET (priv->arrow_button));
1261 g_free (allocations);
1265 gtk_toolbar_style_set (GtkWidget *widget,
1266 GtkStyle *prev_style)
1268 if (GTK_WIDGET_REALIZED (widget))
1269 gtk_style_set_background (widget->style, widget->window, widget->state);
1272 gtk_toolbar_update_button_relief (GTK_TOOLBAR (widget));
1276 gtk_toolbar_direction_changed (GtkWidget *widget,
1277 GtkTextDirection previous_dir)
1279 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1280 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1282 if (toolbar->orientation == GTK_ORIENTATION_VERTICAL)
1284 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
1285 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
1287 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_LEFT, GTK_SHADOW_NONE);
1290 GTK_WIDGET_CLASS (parent_class)->direction_changed (widget, previous_dir);
1294 gtk_toolbar_list_children_in_focus_order (GtkToolbar *toolbar,
1295 GtkDirectionType dir)
1297 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1298 GList *result = NULL;
1302 /* generate list of children in reverse logical order */
1304 for (list = priv->content; list != NULL; list = list->next)
1306 ToolbarContent *content = list->data;
1307 GtkToolItem *item = content->item;
1309 result = g_list_prepend (result, item);
1312 result = g_list_prepend (result, priv->arrow_button);
1314 rtl = (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL);
1316 /* move in logical order when
1318 * - dir is TAB_FORWARD
1320 * - in RTL mode and moving left or up
1322 * - in LTR mode and moving right or down
1324 if (dir == GTK_DIR_TAB_FORWARD ||
1325 (rtl && (dir == GTK_DIR_UP || dir == GTK_DIR_LEFT)) ||
1326 (!rtl && (dir == GTK_DIR_DOWN || dir == GTK_DIR_RIGHT)))
1328 result = g_list_reverse (result);
1335 gtk_toolbar_focus_home_or_end (GtkToolbar *toolbar,
1336 gboolean focus_home)
1338 GList *children, *list;
1339 GtkDirectionType dir = focus_home? GTK_DIR_RIGHT : GTK_DIR_LEFT;
1341 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1343 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
1345 children = g_list_reverse (children);
1347 dir = (dir == GTK_DIR_RIGHT)? GTK_DIR_LEFT : GTK_DIR_RIGHT;
1350 for (list = children; list != NULL; list = list->next)
1352 GtkWidget *child = list->data;
1354 if (GTK_CONTAINER (toolbar)->focus_child == child)
1357 if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1361 g_list_free (children);
1366 /* Keybinding handler. This function is called when the user presses
1367 * Ctrl TAB or an arrow key.
1370 gtk_toolbar_move_focus (GtkToolbar *toolbar,
1371 GtkDirectionType dir)
1374 gboolean try_focus = FALSE;
1376 GtkContainer *container = GTK_CONTAINER (toolbar);
1378 if (container->focus_child &&
1379 gtk_widget_child_focus (container->focus_child, dir))
1384 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1386 for (list = children; list != NULL; list = list->next)
1388 GtkWidget *child = list->data;
1390 if (try_focus && GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1393 if (child == GTK_CONTAINER (toolbar)->focus_child)
1397 g_list_free (children);
1402 /* The focus handler for the toolbar. It called when the user presses
1403 * TAB or otherwise tries to focus the toolbar.
1406 gtk_toolbar_focus (GtkWidget *widget,
1407 GtkDirectionType dir)
1409 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1410 GList *children, *list;
1412 /* if focus is already somewhere inside the toolbar then return FALSE.
1413 * The only way focus can stay inside the toolbar is when the user presses
1414 * arrow keys or Ctrl TAB (both of which are handled by the
1415 * gtk_toolbar_move_focus() keybinding function.
1417 if (GTK_CONTAINER (widget)->focus_child)
1420 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1422 for (list = children; list != NULL; list = list->next)
1424 GtkWidget *child = list->data;
1426 if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1430 g_list_free (children);
1436 style_change_notify (GtkToolbar *toolbar)
1438 if (!toolbar->style_set)
1440 /* pretend it was set, then unset, thus reverting to new default */
1441 toolbar->style_set = TRUE;
1442 gtk_toolbar_unset_style (toolbar);
1447 icon_size_change_notify (GtkToolbar *toolbar)
1449 if (!toolbar->icon_size_set)
1451 /* pretend it was set, then unset, thus reverting to new default */
1452 toolbar->icon_size_set = TRUE;
1453 gtk_toolbar_unset_icon_size (toolbar);
1457 static GtkSettings *
1458 toolbar_get_settings (GtkToolbar *toolbar)
1460 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1461 return priv->settings;
1465 gtk_toolbar_screen_changed (GtkWidget *widget,
1466 GdkScreen *previous_screen)
1468 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
1469 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1470 GtkSettings *old_settings = toolbar_get_settings (toolbar);
1471 GtkSettings *settings;
1473 if (gtk_widget_has_screen (GTK_WIDGET (toolbar)))
1474 settings = gtk_widget_get_settings (GTK_WIDGET (toolbar));
1478 if (settings == old_settings)
1483 g_signal_handler_disconnect (old_settings, toolbar->style_set_connection);
1484 g_signal_handler_disconnect (old_settings, toolbar->icon_size_connection);
1486 g_object_unref (old_settings);
1491 toolbar->style_set_connection =
1492 g_signal_connect_swapped (settings,
1493 "notify::gtk-toolbar-style",
1494 G_CALLBACK (style_change_notify),
1496 toolbar->icon_size_connection =
1497 g_signal_connect_swapped (settings,
1498 "notify::gtk-toolbar-icon-size",
1499 G_CALLBACK (icon_size_change_notify),
1502 g_object_ref (settings);
1503 priv->settings = settings;
1506 priv->settings = NULL;
1508 style_change_notify (toolbar);
1509 icon_size_change_notify (toolbar);
1513 find_drop_index (GtkToolbar *toolbar,
1517 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1518 GList *interesting_content;
1520 GtkOrientation orientation;
1521 GtkTextDirection direction;
1522 gint best_distance = G_MAXINT;
1526 ToolbarContent *best_content;
1528 /* list items we care about wrt. drag and drop */
1529 interesting_content = NULL;
1530 for (list = priv->content; list != NULL; list = list->next)
1532 ToolbarContent *content = list->data;
1533 GtkToolItem *item = content->item;
1535 if (toolbar_item_visible (toolbar, item) && !content->is_overflow)
1536 interesting_content = g_list_prepend (interesting_content, content);
1538 interesting_content = g_list_reverse (interesting_content);
1540 if (!interesting_content)
1543 orientation = toolbar->orientation;
1544 direction = gtk_widget_get_direction (GTK_WIDGET (toolbar));
1546 /* distance to first interesting item */
1547 best_content = interesting_content->data;
1549 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1553 if (direction == GTK_TEXT_DIR_LTR)
1554 pos = GTK_WIDGET (best_content->item)->allocation.x;
1556 pos = GTK_WIDGET (best_content->item)->allocation.x +
1557 GTK_WIDGET (best_content->item)->allocation.width;
1562 pos = GTK_WIDGET (best_content->item)->allocation.y;
1565 best_content = NULL;
1566 best_distance = ABS (pos - cursor);
1568 /* distance to far end of each item */
1569 for (list = interesting_content; list != NULL; list = list->next)
1571 ToolbarContent *content = list->data;
1572 GtkWidget *widget = GTK_WIDGET (content->item);
1574 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1576 if (direction == GTK_TEXT_DIR_LTR)
1577 pos = widget->allocation.x + widget->allocation.width;
1579 pos = widget->allocation.x;
1583 pos = widget->allocation.y + widget->allocation.height;
1586 distance = ABS (pos - cursor);
1588 if (distance < best_distance)
1590 best_distance = distance;
1591 best_content = content;
1595 g_list_free (interesting_content);
1600 return g_list_index (priv->content, best_content) + 1;
1604 get_size (GtkToolItem *tool_item, gint *width, gint *height)
1606 if (!GTK_WIDGET_VISIBLE (tool_item))
1615 gtk_widget_get_child_requisition (GTK_WIDGET (tool_item), &req);
1617 *height = req.height;
1621 #define UPDATE_TIME (0.10)
1624 update_dnd_animation (gpointer data)
1626 GtkToolbar *toolbar = data;
1627 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1633 GDK_THREADS_ENTER();
1635 if (priv->need_sync)
1638 elapsed = g_timer_elapsed (priv->timer, NULL);
1642 list = priv->content;
1646 ToolbarContent *content = list->data;
1647 GtkWidget *widget = GTK_WIDGET (content->item);
1648 GList *next = list->next;
1649 gdouble exact_value;
1650 gint start_value, goal_value;
1651 gint new_value, prev_value;
1653 if (content->is_placeholder)
1655 gint prev_width, prev_height;
1657 get_size (GTK_TOOL_ITEM (widget), &prev_width, &prev_height);
1658 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1660 start_value = content->start_width;
1661 goal_value = content->goal_width;
1662 prev_value = prev_width;
1666 start_value = content->start_height;
1667 goal_value = content->goal_height;
1668 prev_value = prev_height;
1671 if (elapsed <= UPDATE_TIME)
1673 exact_value = start_value + (elapsed / UPDATE_TIME) * (goal_value - start_value);
1674 new_value = (int) (exact_value + error + 0.5);
1676 error += (exact_value - new_value);
1682 exact_value = (double)goal_value;
1683 new_value = goal_value;
1687 gtk_widget_hide (widget);
1689 gtk_widget_show (widget);
1691 /* We need to check for "elapsed > UPDATE_TIME" so that the widget
1692 * doesn't disappear before time. We need its contribution to
1693 * the error value, even if its pixel width is 0.
1695 if (goal_value == 0 && elapsed > UPDATE_TIME)
1697 gtk_toolbar_remove_tool_item (toolbar, GTK_TOOL_ITEM (widget));
1699 else if (new_value != prev_value)
1701 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1702 gtk_widget_set_size_request (widget, new_value, 0);
1704 gtk_widget_set_size_request (widget, 0, new_value);
1706 priv->need_sync = TRUE;
1714 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (toolbar));
1719 if (priv->leaving_dnd)
1721 priv->in_dnd = FALSE;
1722 priv->leaving_dnd = FALSE;
1723 priv->n_overflow_items_when_dnd_started = 0;
1726 GDK_THREADS_LEAVE();
1731 GDK_THREADS_LEAVE();
1737 ensure_idle_handler (GtkToolbar *toolbar)
1739 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1742 priv->idle_id = g_idle_add (update_dnd_animation, toolbar);
1746 reset_all_placeholders (GtkToolbar *toolbar)
1748 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1751 for (list = priv->content; list != NULL; list = list->next)
1753 ToolbarContent *content = list->data;
1754 if (content->is_placeholder)
1756 get_size (content->item,
1757 &(content->start_width), &(content->start_height));
1758 content->goal_width = 0;
1759 content->goal_height = 0;
1763 g_timer_reset (priv->timer);
1767 physical_to_logical (GtkToolbar *toolbar, gint physical)
1769 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1773 g_assert (physical >= 0);
1776 for (list = priv->content; list && physical > 0; list = list->next)
1778 ToolbarContent *content = list->data;
1780 if (!content->is_placeholder)
1785 g_assert (physical == 0);
1791 logical_to_physical (GtkToolbar *toolbar, gint logical)
1793 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1797 g_assert (logical >= 0);
1800 for (list = priv->content; list; list = list->next)
1802 ToolbarContent *content = list->data;
1804 if (!content->is_placeholder)
1814 g_assert (logical == 0);
1820 get_item_requisition (GtkToolbar *toolbar,
1821 GtkToolItem *tool_item,
1825 GtkRequisition requisition;
1827 g_object_ref (G_OBJECT (tool_item));
1828 gtk_widget_set_parent (GTK_WIDGET (tool_item), GTK_WIDGET (toolbar));
1830 gtk_widget_size_request (GTK_WIDGET (tool_item), &requisition);
1831 *width = requisition.width;
1832 *height = requisition.height;
1834 gtk_widget_unparent (GTK_WIDGET (tool_item));
1835 g_object_unref (G_OBJECT (tool_item));
1839 * gtk_toolbar_set_drop_highlight_item:
1840 * @toolbar: a #GtkToolbar
1841 * @item: a #GtkToolItem, or %NULL to turn of highlighting
1842 * @index: a position on @toolbar
1844 * Highlights @toolbar to give an idea of what it would look like
1845 * if @item was added to @toolbar at position indicated by @index. If @item
1846 * is %NULL, highlighting is turned off. In that case @index is ignored.
1848 * The @tool_item passed to this function must not be part of any widget
1849 * hierarchy. When an item is set as drop highlight item it can not
1850 * added to any widget hierarchy or used as highlight item for another
1856 gtk_toolbar_set_drop_highlight_item (GtkToolbar *toolbar,
1857 GtkToolItem *tool_item,
1860 ToolbarContent *content;
1861 GtkToolbarPrivate *priv;
1862 gint start_width, start_height;
1865 GtkRequisition requisition;
1867 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1868 g_return_if_fail (tool_item == NULL || GTK_IS_TOOL_ITEM (tool_item));
1870 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1876 priv->leaving_dnd = TRUE;
1877 reset_all_placeholders (toolbar);
1878 ensure_idle_handler (toolbar);
1880 if (priv->highlight_tool_item)
1882 gtk_widget_unparent (GTK_WIDGET (priv->highlight_tool_item));
1883 g_object_unref (priv->highlight_tool_item);
1884 priv->highlight_tool_item = NULL;
1891 if (tool_item != priv->highlight_tool_item)
1893 if (priv->highlight_tool_item)
1894 g_object_unref (priv->highlight_tool_item);
1896 g_object_ref (tool_item);
1897 gtk_object_sink (GTK_OBJECT (tool_item));
1899 priv->highlight_tool_item = tool_item;
1901 gtk_widget_set_parent (GTK_WIDGET (priv->highlight_tool_item),
1902 GTK_WIDGET (toolbar));
1907 priv->n_overflow_items_when_dnd_started = 0;
1908 for (list = priv->content; list != NULL; list = list->next)
1910 content = list->data;
1911 if (content->is_overflow &&
1912 toolbar_item_visible (toolbar, content->item))
1914 priv->n_overflow_items_when_dnd_started++;
1919 priv->in_dnd = TRUE;
1920 priv->leaving_dnd = FALSE;
1922 n_items = gtk_toolbar_get_n_items (toolbar);
1923 if (index < 0 || index > n_items)
1926 index = logical_to_physical (toolbar, index);
1928 content = g_list_nth_data (priv->content, index);
1932 ToolbarContent *prev_content;
1934 prev_content = g_list_nth_data (priv->content, index - 1);
1936 if (prev_content && prev_content->is_placeholder)
1937 content = prev_content;
1940 if (!content || !content->is_placeholder)
1942 GtkWidget *placeholder = GTK_WIDGET (gtk_separator_tool_item_new ());
1943 gtk_widget_set_size_request (placeholder, 0, 0);
1944 gtk_toolbar_insert_tool_item (toolbar, GTK_TOOL_ITEM (placeholder),
1946 content = g_list_nth_data (priv->content, index);
1947 g_assert (content->is_placeholder);
1948 start_width = start_height = 0;
1952 get_size (content->item, &start_width, &start_height);
1956 g_assert (content->is_placeholder);
1958 gtk_widget_size_request (GTK_WIDGET (priv->highlight_tool_item),
1961 if (content->start_width != start_width ||
1962 content->start_height != start_height ||
1963 content->goal_width != requisition.width ||
1964 content->goal_height != requisition.height)
1966 reset_all_placeholders (toolbar);
1968 content->start_width = start_width;
1969 content->goal_width = requisition.width;
1970 content->start_height = start_height;
1971 content->goal_height = requisition.height;
1973 ensure_idle_handler (toolbar);
1978 gtk_toolbar_unhighlight_drop_location (GtkToolbar *toolbar)
1983 gtk_toolbar_get_child_property (GtkContainer *container,
1989 GtkToolItem *item = GTK_TOOL_ITEM (child);
1991 switch (property_id)
1993 case CHILD_PROP_HOMOGENEOUS:
1994 g_value_set_boolean (value, gtk_tool_item_get_homogeneous (item));
1997 case CHILD_PROP_EXPAND:
1998 g_value_set_boolean (value, gtk_tool_item_get_expand (item));
2002 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
2008 gtk_toolbar_set_child_property (GtkContainer *container,
2011 const GValue *value,
2014 switch (property_id)
2016 case CHILD_PROP_HOMOGENEOUS:
2017 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
2020 case CHILD_PROP_EXPAND:
2021 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
2025 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
2031 gtk_toolbar_add (GtkContainer *container,
2034 GtkToolbar *toolbar;
2036 g_return_if_fail (GTK_IS_TOOLBAR (container));
2037 g_return_if_fail (widget != NULL);
2039 toolbar = GTK_TOOLBAR (container);
2041 if (GTK_IS_TOOL_ITEM (widget))
2042 gtk_toolbar_insert (toolbar, GTK_TOOL_ITEM (widget), 0);
2044 gtk_toolbar_append_widget (toolbar, widget, NULL, NULL);
2048 gtk_toolbar_remove (GtkContainer *container,
2051 GtkToolbar *toolbar;
2052 GtkToolItem *item = NULL;
2054 g_return_if_fail (GTK_IS_TOOLBAR (container));
2055 g_return_if_fail (GTK_IS_WIDGET (widget));
2057 toolbar = GTK_TOOLBAR (container);
2059 if (GTK_IS_TOOL_ITEM (widget))
2061 item = GTK_TOOL_ITEM (widget);
2065 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2068 for (list = priv->content; list != NULL; list = list->next)
2070 ToolbarContent *content = list->data;
2072 if (GTK_BIN (content->item)->child == widget)
2074 item = content->item;
2080 g_return_if_fail (item != NULL);
2082 gtk_toolbar_remove_tool_item (GTK_TOOLBAR (container), item);
2086 gtk_toolbar_forall (GtkContainer *container,
2087 gboolean include_internals,
2088 GtkCallback callback,
2089 gpointer callback_data)
2091 GtkToolbar *toolbar = GTK_TOOLBAR (container);
2092 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2095 g_return_if_fail (callback != NULL);
2097 list = priv->content;
2100 ToolbarContent *content = list->data;
2101 GList *next = list->next;
2103 if (!content->is_placeholder || include_internals)
2104 (*callback) (GTK_WIDGET (content->item), callback_data);
2109 if (include_internals)
2110 (* callback) (priv->arrow_button, callback_data);
2114 gtk_toolbar_child_type (GtkContainer *container)
2116 return GTK_TYPE_TOOL_ITEM;
2120 gtk_toolbar_reconfigured (GtkToolbar *toolbar)
2122 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2125 list = priv->content;
2128 ToolbarContent *content = list->data;
2129 GList *next = list->next;
2131 _gtk_tool_item_toolbar_reconfigured (content->item);
2138 gtk_toolbar_real_orientation_changed (GtkToolbar *toolbar,
2139 GtkOrientation orientation)
2141 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2142 if (toolbar->orientation != orientation)
2144 toolbar->orientation = orientation;
2146 if (orientation == GTK_ORIENTATION_HORIZONTAL)
2147 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_DOWN, GTK_SHADOW_NONE);
2148 else if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
2149 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
2151 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_LEFT, GTK_SHADOW_NONE);
2153 gtk_toolbar_reconfigured (toolbar);
2155 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2156 g_object_notify (G_OBJECT (toolbar), "orientation");
2161 gtk_toolbar_real_style_changed (GtkToolbar *toolbar,
2162 GtkToolbarStyle style)
2164 if (toolbar->style != style)
2166 toolbar->style = style;
2168 gtk_toolbar_reconfigured (toolbar);
2170 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2171 g_object_notify (G_OBJECT (toolbar), "toolbar_style");
2176 menu_position_func (GtkMenu *menu,
2182 GtkToolbar *toolbar = GTK_TOOLBAR (user_data);
2183 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2185 GtkRequisition menu_req;
2187 gdk_window_get_origin (GTK_BUTTON (priv->arrow_button)->event_window, x, y);
2188 gtk_widget_size_request (priv->arrow_button, &req);
2189 gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
2191 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
2193 *y += priv->arrow_button->allocation.height;
2194 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
2195 *x += priv->arrow_button->allocation.width - req.width;
2197 *x += req.width - menu_req.width;
2201 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
2202 *x += priv->arrow_button->allocation.width;
2204 *x -= menu_req.width;
2205 *y += priv->arrow_button->allocation.height - req.height;
2212 menu_deactivated (GtkWidget *menu,
2213 GtkToolbar *toolbar)
2215 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2217 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->arrow_button), FALSE);
2221 remove_item (GtkWidget *menu_item,
2224 gtk_container_remove (GTK_CONTAINER (menu_item->parent), menu_item);
2228 show_menu (GtkToolbar *toolbar,
2229 GdkEventButton *event)
2231 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2236 gtk_container_foreach (GTK_CONTAINER (priv->menu), remove_item, NULL);
2237 gtk_widget_destroy (GTK_WIDGET (priv->menu));
2240 priv->menu = GTK_MENU (gtk_menu_new ());
2241 g_signal_connect (priv->menu, "deactivate", G_CALLBACK (menu_deactivated), toolbar);
2243 for (list = priv->content; list != NULL; list = list->next)
2245 ToolbarContent *content = list->data;
2246 GtkToolItem *item = content->item;
2248 if (toolbar_item_visible (toolbar, item) && content->is_overflow)
2250 GtkWidget *menu_item = gtk_tool_item_retrieve_proxy_menu_item (item);
2254 g_assert (GTK_IS_MENU_ITEM (menu_item));
2255 gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), menu_item);
2260 gtk_widget_show_all (GTK_WIDGET (priv->menu));
2262 gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL,
2263 menu_position_func, toolbar,
2264 event? event->button : 0, event? event->time : gtk_get_current_event_time());
2268 gtk_toolbar_arrow_button_clicked (GtkWidget *button,
2269 GtkToolbar *toolbar)
2271 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2273 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->arrow_button)) &&
2274 (!priv->menu || !GTK_WIDGET_VISIBLE (GTK_WIDGET (priv->menu))))
2276 /* We only get here when the button is clicked with the keybaord,
2277 * because mouse button presses result in the menu being shown so
2278 * that priv->menu would be non-NULL and visible.
2280 show_menu (toolbar, NULL);
2281 gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->menu), FALSE);
2286 gtk_toolbar_arrow_button_press (GtkWidget *button,
2287 GdkEventButton *event,
2288 GtkToolbar *toolbar)
2290 show_menu (toolbar, event);
2291 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
2297 gtk_toolbar_button_press (GtkWidget *toolbar,
2298 GdkEventButton *event)
2300 if (event->button == 3)
2302 gboolean return_value;
2304 g_signal_emit (toolbar, toolbar_signals[POPUP_CONTEXT_MENU], 0,
2305 (int)event->x_root, (int)event->y_root, event->button,
2308 return return_value;
2315 gtk_toolbar_popup_menu (GtkWidget *toolbar)
2317 gboolean return_value;
2318 /* This function is the handler for the "popup menu" keybinding,
2319 * ie., it is called when the user presses Shift F10
2321 g_signal_emit (toolbar, toolbar_signals[POPUP_CONTEXT_MENU], 0,
2322 -1, -1, -1, &return_value);
2324 return return_value;
2328 gtk_toolbar_update_button_relief (GtkToolbar *toolbar)
2330 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2332 gtk_toolbar_reconfigured (toolbar);
2334 gtk_button_set_relief (GTK_BUTTON (priv->arrow_button), get_button_relief (toolbar));
2337 static GtkReliefStyle
2338 get_button_relief (GtkToolbar *toolbar)
2340 GtkReliefStyle button_relief = GTK_RELIEF_NORMAL;
2342 gtk_widget_ensure_style (GTK_WIDGET (toolbar));
2344 gtk_widget_style_get (GTK_WIDGET (toolbar),
2345 "button_relief", &button_relief,
2348 return button_relief;
2352 get_internal_padding (GtkToolbar *toolbar)
2356 gtk_widget_style_get (GTK_WIDGET (toolbar),
2357 "internal_padding", &ipadding,
2363 static GtkShadowType
2364 get_shadow_type (GtkToolbar *toolbar)
2366 GtkShadowType shadow_type;
2368 gtk_widget_style_get (GTK_WIDGET (toolbar),
2369 "shadow_type", &shadow_type,
2376 gtk_toolbar_check_old_api (GtkToolbar *toolbar)
2378 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2380 if (priv->api_mode == NEW_API)
2382 g_warning ("mixing deprecated and non-deprecated GtkToolbar API is not allowed");
2386 priv->api_mode = OLD_API;
2391 gtk_toolbar_check_new_api (GtkToolbar *toolbar)
2393 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2395 if (priv->api_mode == OLD_API)
2397 g_warning ("mixing deprecated and non-deprecated GtkToolbar API is not allowed");
2401 priv->api_mode = NEW_API;
2406 gtk_toolbar_insert_tool_item (GtkToolbar *toolbar,
2409 gboolean is_placeholder)
2411 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2412 ToolbarContent *content = g_new0 (ToolbarContent, 1);
2414 content->is_overflow = FALSE;
2415 content->is_placeholder = is_placeholder;
2416 content->item = item;
2417 toolbar->num_children++;
2419 priv->content = g_list_insert (priv->content, content, pos);
2421 gtk_widget_set_parent (GTK_WIDGET (item), GTK_WIDGET (toolbar));
2425 gtk_toolbar_remove_tool_item (GtkToolbar *toolbar,
2428 GtkToolbarPrivate *priv;
2431 ToolbarContent *content = NULL;
2433 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2434 g_return_if_fail (GTK_IS_TOOL_ITEM (item));
2436 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2440 for (tmp = priv->content; tmp != NULL; tmp = tmp->next)
2442 content = tmp->data;
2443 if (content->item == item)
2449 g_return_if_fail (content != NULL);
2453 priv->content = g_list_remove (priv->content, content);
2455 gtk_widget_unparent (GTK_WIDGET (item));
2457 if (priv->api_mode == OLD_API)
2459 GtkToolbarChild *toolbar_child;
2461 toolbar_child = g_list_nth_data (toolbar->children, nth_child);
2462 toolbar->children = g_list_remove (toolbar->children, toolbar_child);
2464 g_free (toolbar_child);
2467 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2473 * Creates a new toolbar.
2475 * Return Value: the newly-created toolbar.
2478 gtk_toolbar_new (void)
2480 GtkToolbar *toolbar;
2482 toolbar = g_object_new (GTK_TYPE_TOOLBAR, NULL);
2484 return GTK_WIDGET (toolbar);
2488 * gtk_toolbar_insert:
2489 * @toolbar: a #GtkToolbar
2490 * @item: a #GtkToolItem
2491 * @pos: the position of the new item
2493 * Insert a #GtkToolItem into the toolbar at position @pos. If @pos is
2494 * 0 the item is prepended to the start of the toolbar. If @pos is
2495 * negative, the item is appended to the end of the toolbar.
2500 gtk_toolbar_insert (GtkToolbar *toolbar,
2504 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2505 g_return_if_fail (GTK_IS_TOOL_ITEM (item));
2507 if (!gtk_toolbar_check_new_api (toolbar))
2511 pos = logical_to_physical (toolbar, pos);
2513 gtk_toolbar_insert_tool_item (toolbar, item, pos, FALSE);
2517 * gtk_toolbar_get_item_index:
2518 * @toolbar: a #GtkToolbar
2519 * @item: a #GtkToolItem that is a child of @toolbar
2521 * Returns the position of @item on the toolbar, starting from 0.
2522 * It is an error if @item is not a child of the toolbar.
2524 * Return value: the position of item on the toolbar.
2529 gtk_toolbar_get_item_index (GtkToolbar *toolbar,
2532 GtkToolbarPrivate *priv;
2536 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
2537 g_return_val_if_fail (GTK_IS_TOOL_ITEM (item), -1);
2538 g_return_val_if_fail (GTK_WIDGET (item)->parent == GTK_WIDGET (toolbar), -1);
2540 if (!gtk_toolbar_check_new_api (toolbar))
2543 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2546 for (list = priv->content; list != NULL; list = list->next)
2548 ToolbarContent *content = list->data;
2550 if (content->item == item)
2556 return physical_to_logical (toolbar, n);
2560 * gtk_toolbar_set_orientation:
2561 * @toolbar: a #GtkToolbar.
2562 * @orientation: a new #GtkOrientation.
2564 * Sets whether a toolbar should appear horizontally or vertically.
2567 gtk_toolbar_set_orientation (GtkToolbar *toolbar,
2568 GtkOrientation orientation)
2570 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2572 g_signal_emit (toolbar, toolbar_signals[ORIENTATION_CHANGED], 0, orientation);
2576 * gtk_toolbar_get_orientation:
2577 * @toolbar: a #GtkToolbar
2579 * Retrieves the current orientation of the toolbar. See
2580 * gtk_toolbar_set_orientation().
2582 * Return value: the orientation
2585 gtk_toolbar_get_orientation (GtkToolbar *toolbar)
2587 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_ORIENTATION_HORIZONTAL);
2589 return toolbar->orientation;
2593 * gtk_toolbar_set_style:
2594 * @toolbar: a #GtkToolbar.
2595 * @style: the new style for @toolbar.
2597 * Alters the view of @toolbar to display either icons only, text only, or both.
2600 gtk_toolbar_set_style (GtkToolbar *toolbar,
2601 GtkToolbarStyle style)
2603 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2605 toolbar->style_set = TRUE;
2606 g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
2612 * gtk_toolbar_get_style:
2613 * @toolbar: a #GtkToolbar
2615 * Retrieves whether the toolbar has text, icons, or both . See
2616 * gtk_toolbar_set_style().
2618 * Return value: the current style of @toolbar
2621 gtk_toolbar_get_style (GtkToolbar *toolbar)
2623 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), DEFAULT_TOOLBAR_STYLE);
2625 return toolbar->style;
2629 * gtk_toolbar_unset_style:
2630 * @toolbar: a #GtkToolbar
2632 * Unsets a toolbar style set with gtk_toolbar_set_style(), so that
2633 * user preferences will be used to determine the toolbar style.
2636 gtk_toolbar_unset_style (GtkToolbar *toolbar)
2638 GtkToolbarStyle style;
2640 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2642 if (toolbar->style_set)
2644 GtkSettings *settings = toolbar_get_settings (toolbar);
2647 g_object_get (settings,
2648 "gtk-toolbar-style", &style,
2651 style = DEFAULT_TOOLBAR_STYLE;
2653 if (style != toolbar->style)
2654 g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
2656 toolbar->style_set = FALSE;
2661 * gtk_toolbar_set_tooltips:
2662 * @toolbar: a #GtkToolbar.
2663 * @enable: set to %FALSE to disable the tooltips, or %TRUE to enable them.
2665 * Sets if the tooltips of a toolbar should be active or not.
2668 gtk_toolbar_set_tooltips (GtkToolbar *toolbar,
2671 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2674 gtk_tooltips_enable (toolbar->tooltips);
2676 gtk_tooltips_disable (toolbar->tooltips);
2680 * gtk_toolbar_get_tooltips:
2681 * @toolbar: a #GtkToolbar
2683 * Retrieves whether tooltips are enabled. See
2684 * gtk_toolbar_set_tooltips().
2686 * Return value: %TRUE if tooltips are enabled
2689 gtk_toolbar_get_tooltips (GtkToolbar *toolbar)
2691 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2693 return toolbar->tooltips->enabled;
2697 * gtk_toolbar_get_n_items:
2698 * @toolbar: a #GtkToolbar
2700 * Returns the number of items on the toolbar.
2702 * Return value: the number of items on the toolbar
2707 gtk_toolbar_get_n_items (GtkToolbar *toolbar)
2709 GtkToolbarPrivate *priv;
2711 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
2713 if (!gtk_toolbar_check_new_api (toolbar))
2716 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2718 return physical_to_logical (toolbar, g_list_length (priv->content));
2722 * gtk_toolbar_get_nth_item:
2723 * @toolbar: a #GtkToolbar
2724 * @n: A position on the toolbar
2726 * Returns the @n<!-- -->'s item on @toolbar, or %NULL if the
2727 * toolbar does not contain an @n<!-- -->'th item.
2729 * Return value: The @n<!-- -->'th #GtkToolItem on @toolbar, or %NULL if there
2730 * isn't an @n<!-- -->th item.
2735 gtk_toolbar_get_nth_item (GtkToolbar *toolbar,
2738 GtkToolbarPrivate *priv;
2739 ToolbarContent *content;
2742 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
2744 if (!gtk_toolbar_check_new_api (toolbar))
2747 n_items = gtk_toolbar_get_n_items (toolbar);
2749 if (n < 0 || n >= n_items)
2752 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2754 content = g_list_nth_data (priv->content, logical_to_physical (toolbar, n));
2757 g_assert (!content->is_placeholder);
2759 return content->item;
2763 * gtk_toolbar_set_icon_size:
2764 * @toolbar: A #GtkToolbar
2765 * @icon_size: The #GtkIconSize that stock icons in the toolbar shall have.
2767 * This function sets the size of stock icons in the toolbar. You
2768 * can call it both before you add the icons and after they've been
2769 * added. The size you set will override user preferences for the default
2773 gtk_toolbar_set_icon_size (GtkToolbar *toolbar,
2774 GtkIconSize icon_size)
2776 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2778 toolbar->icon_size_set = TRUE;
2780 if (toolbar->icon_size == icon_size)
2783 toolbar->icon_size = icon_size;
2785 gtk_toolbar_reconfigured (toolbar);
2787 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2791 * gtk_toolbar_get_icon_size:
2792 * @toolbar: a #GtkToolbar
2794 * Retrieves the icon size fo the toolbar. See gtk_toolbar_set_icon_size().
2796 * Return value: the current icon size for the icons on the toolbar.
2799 gtk_toolbar_get_icon_size (GtkToolbar *toolbar)
2801 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), DEFAULT_ICON_SIZE);
2803 return toolbar->icon_size;
2807 * gtk_toolbar_get_relief_style:
2808 * @toolbar: a #GtkToolbar
2810 * Returns the relief style of buttons on @toolbar. See
2811 * gtk_button_set_relief_style().
2813 * Return value: The relief style of buttons on @toolbar.
2818 gtk_toolbar_get_relief_style (GtkToolbar *toolbar)
2820 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_RELIEF_NONE);
2822 return get_button_relief (toolbar);
2826 * gtk_toolbar_unset_icon_size:
2827 * @toolbar: a #GtkToolbar
2829 * Unsets toolbar icon size set with gtk_toolbar_set_icon_size(), so that
2830 * user preferences will be used to determine the icon size.
2833 gtk_toolbar_unset_icon_size (GtkToolbar *toolbar)
2837 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2839 if (toolbar->icon_size_set)
2841 GtkSettings *settings = toolbar_get_settings (toolbar);
2845 g_object_get (settings,
2846 "gtk-toolbar-icon-size", &size,
2850 size = DEFAULT_ICON_SIZE;
2852 if (size != toolbar->icon_size)
2853 gtk_toolbar_set_icon_size (toolbar, size);
2855 toolbar->icon_size_set = FALSE;
2860 * gtk_toolbar_set_show_arrow:
2861 * @toolbar: a #GtkToolbar
2862 * @show_arrow: Whether to show an overflow menu
2864 * Sets whether to show an overflow menu when
2865 * @toolbar doesn't have room for all items on it. If %TRUE,
2866 * items that there are not room are available through an
2872 gtk_toolbar_set_show_arrow (GtkToolbar *toolbar,
2873 gboolean show_arrow)
2875 GtkToolbarPrivate *priv;
2877 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2879 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2880 show_arrow = show_arrow != FALSE;
2882 if (priv->show_arrow != show_arrow)
2884 priv->show_arrow = show_arrow;
2886 if (!priv->show_arrow)
2887 gtk_widget_hide (priv->arrow_button);
2889 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2890 g_object_notify (G_OBJECT (toolbar), "show_arrow");
2895 * gtk_toolbar_get_show_arrow:
2896 * @toolbar: a #GtkToolbar
2898 * Returns whether the toolbar has an overflow menu.
2899 * See gtk_toolbar_set_show_arrow()
2906 gtk_toolbar_get_show_arrow (GtkToolbar *toolbar)
2908 GtkToolbarPrivate *priv;
2910 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2912 if (!gtk_toolbar_check_new_api (toolbar))
2915 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2917 return priv->show_arrow;
2921 * gtk_toolbar_get_drop_index:
2922 * @toolbar: a #GtkToolbar
2923 * @x: x coordinate of a point on the toolbar
2924 * @y: y coordinate of a point on the toolbar
2926 * Returns the position corresponding to the indicated point on
2927 * @toolbar. This is useful when dragging items to the toolbar:
2928 * this function returns the position a new item should be
2931 * @x and @y are in @toolbar coordinates.
2933 * Return value: The position corresponding to the point (@x, @y) on the toolbar.
2938 gtk_toolbar_get_drop_index (GtkToolbar *toolbar,
2942 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2944 if (!gtk_toolbar_check_new_api (toolbar))
2947 return physical_to_logical (toolbar, find_drop_index (toolbar, x, y));
2951 * gtk_toolbar_append_item:
2952 * @toolbar: a #GtkToolbar.
2953 * @text: give your toolbar button a label.
2954 * @tooltip_text: a string that appears when the user holds the mouse over this item.
2955 * @tooltip_private_text: use with #GtkTipsQuery.
2956 * @icon: a #GtkWidget that should be used as the button's icon.
2957 * @callback: the function to be executed when the button is pressed.
2958 * @user_data: a pointer to any data you wish to be passed to the callback.
2960 * Inserts a new item into the toolbar. You must specify the position
2961 * in the toolbar where it will be inserted.
2963 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
2964 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
2966 * Return value: the new toolbar item as a #GtkWidget.
2969 gtk_toolbar_append_item (GtkToolbar *toolbar,
2971 const char *tooltip_text,
2972 const char *tooltip_private_text,
2974 GtkSignalFunc callback,
2977 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
2979 tooltip_text, tooltip_private_text,
2980 icon, callback, user_data,
2981 toolbar->num_children);
2985 * gtk_toolbar_prepend_item:
2986 * @toolbar: a #GtkToolbar.
2987 * @text: give your toolbar button a label.
2988 * @tooltip_text: a string that appears when the user holds the mouse over this item.
2989 * @tooltip_private_text: use with #GtkTipsQuery.
2990 * @icon: a #GtkWidget that should be used as the button's icon.
2991 * @callback: the function to be executed when the button is pressed.
2992 * @user_data: a pointer to any data you wish to be passed to the callback.
2994 * Adds a new button to the beginning (top or left edges) of the given toolbar.
2996 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
2997 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
2999 * Return value: the new toolbar item as a #GtkWidget.
3002 gtk_toolbar_prepend_item (GtkToolbar *toolbar,
3004 const char *tooltip_text,
3005 const char *tooltip_private_text,
3007 GtkSignalFunc callback,
3010 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3012 tooltip_text, tooltip_private_text,
3013 icon, callback, user_data,
3018 * gtk_toolbar_insert_item:
3019 * @toolbar: a #GtkToolbar.
3020 * @text: give your toolbar button a label.
3021 * @tooltip_text: a string that appears when the user holds the mouse over this item.
3022 * @tooltip_private_text: use with #GtkTipsQuery.
3023 * @icon: a #GtkWidget that should be used as the button's icon.
3024 * @callback: the function to be executed when the button is pressed.
3025 * @user_data: a pointer to any data you wish to be passed to the callback.
3026 * @position: the number of widgets to insert this item after.
3028 * Inserts a new item into the toolbar. You must specify the position in the
3029 * toolbar where it will be inserted.
3031 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3032 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3034 * Return value: the new toolbar item as a #GtkWidget.
3037 gtk_toolbar_insert_item (GtkToolbar *toolbar,
3039 const char *tooltip_text,
3040 const char *tooltip_private_text,
3042 GtkSignalFunc callback,
3046 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3048 tooltip_text, tooltip_private_text,
3049 icon, callback, user_data,
3054 * gtk_toolbar_insert_stock:
3055 * @toolbar: A #GtkToolbar
3056 * @stock_id: The id of the stock item you want to insert
3057 * @tooltip_text: The text in the tooltip of the toolbar button
3058 * @tooltip_private_text: The private text of the tooltip
3059 * @callback: The callback called when the toolbar button is clicked.
3060 * @user_data: user data passed to callback
3061 * @position: The position the button shall be inserted at.
3062 * -1 means at the end.
3064 * Inserts a stock item at the specified position of the toolbar. If
3065 * @stock_id is not a known stock item ID, it's inserted verbatim,
3066 * except that underscores used to mark mnemonics are removed.
3068 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3069 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3071 * Returns: the inserted widget
3074 gtk_toolbar_insert_stock (GtkToolbar *toolbar,
3075 const gchar *stock_id,
3076 const char *tooltip_text,
3077 const char *tooltip_private_text,
3078 GtkSignalFunc callback,
3082 return gtk_toolbar_internal_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3084 tooltip_text, tooltip_private_text,
3085 NULL, callback, user_data,
3090 * gtk_toolbar_append_space:
3091 * @toolbar: a #GtkToolbar.
3093 * Adds a new space to the end of the toolbar.
3096 gtk_toolbar_append_space (GtkToolbar *toolbar)
3098 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
3102 toolbar->num_children);
3106 * gtk_toolbar_prepend_space:
3107 * @toolbar: a #GtkToolbar.
3109 * Adds a new space to the beginning of the toolbar.
3112 gtk_toolbar_prepend_space (GtkToolbar *toolbar)
3114 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
3122 * gtk_toolbar_insert_space:
3123 * @toolbar: a #GtkToolbar
3124 * @position: the number of widgets after which a space should be inserted.
3126 * Inserts a new space in the toolbar at the specified position.
3129 gtk_toolbar_insert_space (GtkToolbar *toolbar,
3132 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
3140 * gtk_toolbar_remove_space:
3141 * @toolbar: a #GtkToolbar.
3142 * @position: the index of the space to remove.
3144 * Removes a space from the specified position.
3147 gtk_toolbar_remove_space (GtkToolbar *toolbar,
3152 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
3154 if (!gtk_toolbar_check_old_api (toolbar))
3157 item = g_list_nth_data (toolbar->children, position);
3161 g_warning ("Toolbar position %d doesn't exist", position);
3165 if (!GTK_IS_SEPARATOR_TOOL_ITEM (item))
3167 g_warning ("Toolbar position %d is not a space", position);
3171 gtk_toolbar_remove_tool_item (toolbar, item);
3175 * gtk_toolbar_append_widget:
3176 * @toolbar: a #GtkToolbar.
3177 * @widget: a #GtkWidget to add to the toolbar.
3178 * @tooltip_text: the element's tooltip.
3179 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3181 * Adds a widget to the end of the given toolbar.
3184 gtk_toolbar_append_widget (GtkToolbar *toolbar,
3186 const gchar *tooltip_text,
3187 const gchar *tooltip_private_text)
3189 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
3191 tooltip_text, tooltip_private_text,
3193 toolbar->num_children);
3197 * gtk_toolbar_prepend_widget:
3198 * @toolbar: a #GtkToolbar.
3199 * @widget: a #GtkWidget to add to the toolbar.
3200 * @tooltip_text: the element's tooltip.
3201 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3203 * Adds a widget to the beginning of the given toolbar.
3206 gtk_toolbar_prepend_widget (GtkToolbar *toolbar,
3208 const gchar *tooltip_text,
3209 const gchar *tooltip_private_text)
3211 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
3213 tooltip_text, tooltip_private_text,
3219 * gtk_toolbar_insert_widget:
3220 * @toolbar: a #GtkToolbar.
3221 * @widget: a #GtkWidget to add to the toolbar.
3222 * @tooltip_text: the element's tooltip.
3223 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3224 * @position: the number of widgets to insert this widget after.
3226 * Inserts a widget in the toolbar at the given position.
3229 gtk_toolbar_insert_widget (GtkToolbar *toolbar,
3231 const char *tooltip_text,
3232 const char *tooltip_private_text,
3235 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
3237 tooltip_text, tooltip_private_text,
3243 * gtk_toolbar_append_element:
3244 * @toolbar: a #GtkToolbar.
3245 * @type: a value of type #GtkToolbarChildType that determines what @widget will be.
3246 * @widget: a #GtkWidget, or %NULL.
3247 * @text: the element's label.
3248 * @tooltip_text: the element's tooltip.
3249 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3250 * @icon: a #GtkWidget that provides pictorial representation of the element's function.
3251 * @callback: the function to be executed when the button is pressed.
3252 * @user_data: any data you wish to pass to the callback.
3254 * Adds a new element to the end of a toolbar.
3256 * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element.
3257 * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine
3258 * the radio group for the new element. In all other cases, @widget must
3261 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3262 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3264 * Return value: the new toolbar element as a #GtkWidget.
3267 gtk_toolbar_append_element (GtkToolbar *toolbar,
3268 GtkToolbarChildType type,
3271 const char *tooltip_text,
3272 const char *tooltip_private_text,
3274 GtkSignalFunc callback,
3277 return gtk_toolbar_insert_element (toolbar, type, widget, text,
3278 tooltip_text, tooltip_private_text,
3279 icon, callback, user_data,
3280 toolbar->num_children);
3284 * gtk_toolbar_prepend_element:
3285 * @toolbar: a #GtkToolbar.
3286 * @type: a value of type #GtkToolbarChildType that determines what @widget will be.
3287 * @widget: a #GtkWidget, or %NULL
3288 * @text: the element's label.
3289 * @tooltip_text: the element's tooltip.
3290 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3291 * @icon: a #GtkWidget that provides pictorial representation of the element's function.
3292 * @callback: the function to be executed when the button is pressed.
3293 * @user_data: any data you wish to pass to the callback.
3295 * Adds a new element to the beginning of a toolbar.
3297 * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element.
3298 * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine
3299 * the radio group for the new element. In all other cases, @widget must
3302 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3303 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3305 * Return value: the new toolbar element as a #GtkWidget.
3308 gtk_toolbar_prepend_element (GtkToolbar *toolbar,
3309 GtkToolbarChildType type,
3312 const char *tooltip_text,
3313 const char *tooltip_private_text,
3315 GtkSignalFunc callback,
3318 return gtk_toolbar_insert_element (toolbar, type, widget, text,
3319 tooltip_text, tooltip_private_text,
3320 icon, callback, user_data, 0);
3324 * gtk_toolbar_insert_element:
3325 * @toolbar: a #GtkToolbar.
3326 * @type: a value of type #GtkToolbarChildType that determines what @widget
3328 * @widget: a #GtkWidget, or %NULL.
3329 * @text: the element's label.
3330 * @tooltip_text: the element's tooltip.
3331 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3332 * @icon: a #GtkWidget that provides pictorial representation of the element's function.
3333 * @callback: the function to be executed when the button is pressed.
3334 * @user_data: any data you wish to pass to the callback.
3335 * @position: the number of widgets to insert this element after.
3337 * Inserts a new element in the toolbar at the given position.
3339 * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element.
3340 * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine
3341 * the radio group for the new element. In all other cases, @widget must
3344 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3345 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3347 * Return value: the new toolbar element as a #GtkWidget.
3350 gtk_toolbar_insert_element (GtkToolbar *toolbar,
3351 GtkToolbarChildType type,
3354 const char *tooltip_text,
3355 const char *tooltip_private_text,
3357 GtkSignalFunc callback,
3361 return gtk_toolbar_internal_insert_element (toolbar, type, widget, text,
3362 tooltip_text, tooltip_private_text,
3363 icon, callback, user_data, position, FALSE);
3367 _gtk_toolbar_elide_underscores (const gchar *original)
3371 gboolean last_underscore;
3373 q = result = g_malloc (strlen (original) + 1);
3374 last_underscore = FALSE;
3376 for (p = original; *p; p++)
3378 if (!last_underscore && *p == '_')
3379 last_underscore = TRUE;
3382 last_underscore = FALSE;
3393 gtk_toolbar_internal_insert_element (GtkToolbar *toolbar,
3394 GtkToolbarChildType type,
3397 const char *tooltip_text,
3398 const char *tooltip_private_text,
3400 GtkSignalFunc callback,
3405 GtkToolbarChild *child;
3406 GtkToolItem *item = NULL;
3408 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
3410 if (!gtk_toolbar_check_old_api (toolbar))
3413 if (type == GTK_TOOLBAR_CHILD_WIDGET)
3414 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3415 else if (type != GTK_TOOLBAR_CHILD_RADIOBUTTON)
3416 g_return_val_if_fail (widget == NULL, NULL);
3418 child = g_new (GtkToolbarChild, 1);
3422 child->label = NULL;
3426 case GTK_TOOLBAR_CHILD_SPACE:
3427 item = gtk_separator_tool_item_new ();
3428 child->widget = NULL;
3431 case GTK_TOOLBAR_CHILD_WIDGET:
3432 item = gtk_tool_item_new ();
3433 child->widget = widget;
3434 gtk_container_add (GTK_CONTAINER (item), child->widget);
3437 case GTK_TOOLBAR_CHILD_BUTTON:
3438 item = gtk_tool_button_new (NULL, NULL);
3439 child->widget = _gtk_tool_button_get_button (GTK_TOOL_BUTTON (item));
3442 case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
3443 item = gtk_toggle_tool_button_new ();
3444 child->widget = _gtk_tool_button_get_button (GTK_TOOL_BUTTON (item));
3447 case GTK_TOOLBAR_CHILD_RADIOBUTTON:
3448 item = gtk_radio_tool_button_new (widget
3449 ? gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget))
3451 child->widget = _gtk_tool_button_get_button (GTK_TOOL_BUTTON (item));
3455 gtk_widget_show (GTK_WIDGET (item));
3457 if (type == GTK_TOOLBAR_CHILD_BUTTON ||
3458 type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
3459 type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
3465 GtkStockItem stock_item;
3468 gtk_tool_button_set_stock_id (GTK_TOOL_BUTTON (item), text);
3470 gtk_stock_lookup (text, &stock_item);
3471 label_text = _gtk_toolbar_elide_underscores (stock_item.label);
3472 child->label = GTK_WIDGET (gtk_label_new (label_text));
3473 g_free (label_text);
3477 child->label = gtk_label_new (text);
3479 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (item), child->label);
3480 gtk_widget_show (child->label);
3486 gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (item), icon);
3488 /* Applications depend on the toolbar showing the widget for them */
3489 gtk_widget_show (GTK_WIDGET (icon));
3493 * We need to connect to the button's clicked callback because some
3494 * programs may rely on that the widget in the callback is a GtkButton
3497 g_signal_connect (child->widget, "clicked",
3498 callback, user_data);
3501 if ((type != GTK_TOOLBAR_CHILD_SPACE) && tooltip_text)
3502 gtk_tool_item_set_tooltip (item, toolbar->tooltips,
3503 tooltip_text, tooltip_private_text);
3505 toolbar->children = g_list_insert (toolbar->children, child, position);
3507 gtk_toolbar_insert_tool_item (toolbar, item, position, FALSE);
3509 return child->widget;
3513 gtk_toolbar_finalize (GObject *object)
3516 GtkToolbar *toolbar = GTK_TOOLBAR (object);
3517 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3519 if (toolbar->tooltips)
3520 g_object_unref (toolbar->tooltips);
3522 for (list = toolbar->children; list != NULL; list = list->next)
3523 g_free (list->data);
3525 g_list_free (toolbar->children);
3527 for (list = priv->content; list != NULL; list = list->next)
3528 g_free (list->data);
3530 g_list_free (priv->content);
3532 g_timer_destroy (priv->timer);
3535 g_source_remove (priv->idle_id);
3537 G_OBJECT_CLASS (parent_class)->finalize (object);