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,
178 typedef struct _ToolbarContent ToolbarContent;
180 static ToolbarContent *gtk_toolbar_insert_tool_item (GtkToolbar *toolbar,
183 gboolean is_placeholder);
192 #define GTK_TOOLBAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_TOOLBAR, GtkToolbarPrivate))
201 struct _ToolbarContent
204 guint is_placeholder : 1;
209 GtkAllocation start_allocation;
213 struct _GtkToolbarPrivate
218 GtkWidget *arrow_button;
224 GdkWindow *event_window;
226 GtkSettings *settings;
229 gboolean leaving_dnd;
231 gint n_overflow_items_when_dnd_started;
232 GtkToolItem *highlight_tool_item;
233 gint max_homogeneous_pixels;
239 static GtkContainerClass *parent_class = NULL;
240 static guint toolbar_signals [LAST_SIGNAL] = { 0 };
243 gtk_toolbar_get_type (void)
245 static GtkType type = 0;
249 static const GTypeInfo type_info =
251 sizeof (GtkToolbarClass),
252 (GBaseInitFunc) NULL,
253 (GBaseFinalizeFunc) NULL,
254 (GClassInitFunc) gtk_toolbar_class_init,
255 (GClassFinalizeFunc) NULL,
259 (GInstanceInitFunc) gtk_toolbar_init,
262 type = g_type_register_static (GTK_TYPE_CONTAINER,
271 add_arrow_bindings (GtkBindingSet *binding_set,
273 GtkDirectionType dir)
275 guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
277 gtk_binding_entry_add_signal (binding_set, keysym, 0,
279 GTK_TYPE_DIRECTION_TYPE, dir);
280 gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
282 GTK_TYPE_DIRECTION_TYPE, dir);
286 add_ctrl_tab_bindings (GtkBindingSet *binding_set,
287 GdkModifierType modifiers,
288 GtkDirectionType direction)
290 gtk_binding_entry_add_signal (binding_set,
291 GDK_Tab, GDK_CONTROL_MASK | modifiers,
293 GTK_TYPE_DIRECTION_TYPE, direction);
294 gtk_binding_entry_add_signal (binding_set,
295 GDK_KP_Tab, GDK_CONTROL_MASK | modifiers,
297 GTK_TYPE_DIRECTION_TYPE, direction);
301 gtk_toolbar_class_init (GtkToolbarClass *klass)
303 GObjectClass *gobject_class;
304 GtkWidgetClass *widget_class;
305 GtkContainerClass *container_class;
306 GtkBindingSet *binding_set;
308 parent_class = g_type_class_peek_parent (klass);
310 gobject_class = (GObjectClass *)klass;
311 widget_class = (GtkWidgetClass *)klass;
312 container_class = (GtkContainerClass *)klass;
314 gobject_class->set_property = gtk_toolbar_set_property;
315 gobject_class->get_property = gtk_toolbar_get_property;
316 gobject_class->finalize = gtk_toolbar_finalize;
318 widget_class->button_press_event = gtk_toolbar_button_press;
319 widget_class->expose_event = gtk_toolbar_expose;
320 widget_class->size_request = gtk_toolbar_size_request;
321 widget_class->size_allocate = gtk_toolbar_size_allocate;
322 widget_class->style_set = gtk_toolbar_style_set;
323 widget_class->direction_changed = gtk_toolbar_direction_changed;
324 widget_class->focus = gtk_toolbar_focus;
325 widget_class->screen_changed = gtk_toolbar_screen_changed;
326 widget_class->realize = gtk_toolbar_realize;
327 widget_class->unrealize = gtk_toolbar_unrealize;
328 widget_class->map = gtk_toolbar_map;
329 widget_class->unmap = gtk_toolbar_unmap;
330 widget_class->popup_menu = gtk_toolbar_popup_menu;
332 container_class->add = gtk_toolbar_add;
333 container_class->remove = gtk_toolbar_remove;
334 container_class->forall = gtk_toolbar_forall;
335 container_class->child_type = gtk_toolbar_child_type;
336 container_class->get_child_property = gtk_toolbar_get_child_property;
337 container_class->set_child_property = gtk_toolbar_set_child_property;
339 klass->orientation_changed = gtk_toolbar_real_orientation_changed;
340 klass->style_changed = gtk_toolbar_real_style_changed;
343 * GtkToolbar::orientation-changed:
344 * @toolbar: the object which emitted the signal
345 * @orientation: the new #GtkOrientation of the toolbar
347 * Emitted when the orientation of the toolbar changes.
349 toolbar_signals[ORIENTATION_CHANGED] =
350 g_signal_new ("orientation-changed",
351 G_OBJECT_CLASS_TYPE (klass),
353 G_STRUCT_OFFSET (GtkToolbarClass, orientation_changed),
355 g_cclosure_marshal_VOID__ENUM,
357 GTK_TYPE_ORIENTATION);
359 * GtkToolbar::style-changed:
360 * @toolbar: The #GtkToolbar which emitted the signal
361 * @style: the new #GtkToolbarStyle of the toolbar
363 * Emitted when the style of the toolbar changes.
365 toolbar_signals[STYLE_CHANGED] =
366 g_signal_new ("style-changed",
367 G_OBJECT_CLASS_TYPE (klass),
369 G_STRUCT_OFFSET (GtkToolbarClass, style_changed),
371 g_cclosure_marshal_VOID__ENUM,
373 GTK_TYPE_TOOLBAR_STYLE);
375 * GtkToolbar::popup-context-menu:
376 * @toolbar: the #GtkToolbar which emitted the signal
377 * @x: the x coordinate of the point where the menu should appear
378 * @y: the y coordinate of the point where the menu should appear
379 * @button: the mouse button the user pressed, or -1
381 * Emitted when the user right-clicks the toolbar or uses the
382 * keybinding to display a popup menu.
384 * Application developers should handle this signal if they want
385 * to display a context menu on the toolbar. The context-menu should
386 * appear at the coordinates given by @x and @y. The mouse button
387 * number is given by the @button parameter. If the menu was popped
388 * up using the keybaord, @button is -1.
390 * Return value: return %TRUE if the signal was handled, %FALSE if not
392 toolbar_signals[POPUP_CONTEXT_MENU] =
393 g_signal_new ("popup_context_menu",
394 G_OBJECT_CLASS_TYPE (klass),
396 G_STRUCT_OFFSET (GtkToolbarClass, popup_context_menu),
397 _gtk_boolean_handled_accumulator, NULL,
398 _gtk_marshal_BOOLEAN__INT_INT_INT,
400 G_TYPE_INT, G_TYPE_INT,
403 * GtkToolbar::move-focus:
404 * @toolbar: the #GtkToolbar which emitted the signal
405 * @dir: a #GtkDirection
407 * A keybinding signal used internally by GTK+. This signal can't
408 * be used in application code.
410 * Return value: %TRUE if the signal was handled, %FALSE if not
412 toolbar_signals[MOVE_FOCUS] =
413 _gtk_binding_signal_new ("move_focus",
414 G_TYPE_FROM_CLASS (klass),
415 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
416 G_CALLBACK (gtk_toolbar_move_focus),
418 _gtk_marshal_BOOLEAN__ENUM,
420 GTK_TYPE_DIRECTION_TYPE);
422 * GtkToolbar::focus-home-or-end:
423 * @toolbar: the #GtkToolbar which emitted the signal
424 * @focus_home: %TRUE if the first item should be focused
426 * A keybinding signal used internally by GTK+. This signal can't
427 * be used in application code
429 * Return value: %TRUE if the signal was handled, %FALSE if not
431 toolbar_signals[FOCUS_HOME_OR_END] =
432 _gtk_binding_signal_new ("focus_home_or_end",
433 G_OBJECT_CLASS_TYPE (klass),
434 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
435 G_CALLBACK (gtk_toolbar_focus_home_or_end),
437 _gtk_marshal_BOOLEAN__BOOLEAN,
442 g_object_class_install_property (gobject_class,
444 g_param_spec_enum ("orientation",
446 _("The orientation of the toolbar"),
447 GTK_TYPE_ORIENTATION,
448 GTK_ORIENTATION_HORIZONTAL,
451 g_object_class_install_property (gobject_class,
453 g_param_spec_enum ("toolbar_style",
455 _("How to draw the toolbar"),
456 GTK_TYPE_TOOLBAR_STYLE,
459 g_object_class_install_property (gobject_class,
461 g_param_spec_boolean ("show_arrow",
463 _("If an arrow should be shown if the toolbar doesn't fit"),
467 /* child properties */
468 gtk_container_class_install_child_property (container_class,
470 g_param_spec_boolean ("expand",
472 _("Whether the item should receive extra space when the toolbar grows"),
476 gtk_container_class_install_child_property (container_class,
477 CHILD_PROP_HOMOGENEOUS,
478 g_param_spec_boolean ("homogeneous",
480 _("Whether the item should be the same size as other homogeneous items"),
484 /* style properties */
485 gtk_widget_class_install_style_property (widget_class,
486 g_param_spec_int ("space_size",
488 _("Size of spacers"),
494 gtk_widget_class_install_style_property (widget_class,
495 g_param_spec_int ("internal_padding",
496 _("Internal padding"),
497 _("Amount of border space between the toolbar shadow and the buttons"),
503 gtk_widget_class_install_style_property (widget_class,
504 g_param_spec_enum ("space_style",
506 _("Whether spacers are vertical lines or just blank"),
507 GTK_TYPE_TOOLBAR_SPACE_STYLE,
511 gtk_widget_class_install_style_property (widget_class,
512 g_param_spec_enum ("button_relief",
514 _("Type of bevel around toolbar buttons"),
515 GTK_TYPE_RELIEF_STYLE,
518 gtk_widget_class_install_style_property (widget_class,
519 g_param_spec_enum ("shadow_type",
521 _("Style of bevel around the toolbar"),
522 GTK_TYPE_SHADOW_TYPE,
526 gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-style",
528 _("Whether default toolbars have text only, text and icons, icons only, etc."),
529 GTK_TYPE_TOOLBAR_STYLE,
530 DEFAULT_TOOLBAR_STYLE,
533 gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-icon-size",
534 _("Toolbar icon size"),
535 _("Size of icons in default toolbars"),
540 binding_set = gtk_binding_set_by_class (klass);
542 add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
543 add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
544 add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
545 add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
547 gtk_binding_entry_add_signal (binding_set, GDK_KP_Home, 0,
548 "focus_home_or_end", 1,
549 G_TYPE_BOOLEAN, TRUE);
550 gtk_binding_entry_add_signal (binding_set, GDK_Home, 0,
551 "focus_home_or_end", 1,
552 G_TYPE_BOOLEAN, TRUE);
553 gtk_binding_entry_add_signal (binding_set, GDK_KP_End, 0,
554 "focus_home_or_end", 1,
555 G_TYPE_BOOLEAN, FALSE);
556 gtk_binding_entry_add_signal (binding_set, GDK_End, 0,
557 "focus_home_or_end", 1,
558 G_TYPE_BOOLEAN, FALSE);
560 add_ctrl_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
561 add_ctrl_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
563 g_type_class_add_private (gobject_class, sizeof (GtkToolbarPrivate));
567 gtk_toolbar_init (GtkToolbar *toolbar)
569 GtkToolbarPrivate *priv;
571 GTK_WIDGET_UNSET_FLAGS (toolbar, GTK_CAN_FOCUS);
572 GTK_WIDGET_SET_FLAGS (toolbar, GTK_NO_WINDOW);
574 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
576 toolbar->orientation = GTK_ORIENTATION_HORIZONTAL;
577 toolbar->style = DEFAULT_TOOLBAR_STYLE;
578 toolbar->icon_size = DEFAULT_ICON_SIZE;
579 toolbar->tooltips = gtk_tooltips_new ();
580 g_object_ref (toolbar->tooltips);
581 gtk_object_sink (GTK_OBJECT (toolbar->tooltips));
583 priv->arrow_button = gtk_toggle_button_new ();
584 g_signal_connect (priv->arrow_button, "button_press_event",
585 G_CALLBACK (gtk_toolbar_arrow_button_press), toolbar);
586 g_signal_connect (priv->arrow_button, "clicked",
587 G_CALLBACK (gtk_toolbar_arrow_button_clicked), toolbar);
588 gtk_button_set_relief (GTK_BUTTON (priv->arrow_button),
589 get_button_relief (toolbar));
591 priv->api_mode = DONT_KNOW;
593 gtk_button_set_focus_on_click (GTK_BUTTON (priv->arrow_button), FALSE);
595 priv->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
596 gtk_widget_set_name (priv->arrow, "gtk-toolbar-arrow");
597 gtk_widget_show (priv->arrow);
598 gtk_container_add (GTK_CONTAINER (priv->arrow_button), priv->arrow);
600 gtk_widget_set_parent (priv->arrow_button, GTK_WIDGET (toolbar));
602 /* which child position a drop will occur at */
604 priv->show_arrow = TRUE;
605 priv->settings = NULL;
607 priv->max_homogeneous_pixels = -1;
609 priv->timer = g_timer_new ();
613 toolbar_item_visible (GtkToolbar *toolbar,
616 if (GTK_WIDGET_VISIBLE (item) &&
617 ((toolbar->orientation == GTK_ORIENTATION_HORIZONTAL &&
618 gtk_tool_item_get_visible_horizontal (item)) ||
619 (toolbar->orientation == GTK_ORIENTATION_VERTICAL &&
620 gtk_tool_item_get_visible_vertical (item))))
622 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
624 /* With the old toolbar you could hide a button by calling gtk_widget_hide()
625 * on it. This doesn't work with the new API because the GtkToolItem will not be
628 if (priv->api_mode == OLD_API)
630 GtkWidget *bin_child = GTK_BIN (item)->child;
632 if (bin_child && !GTK_WIDGET_VISIBLE (bin_child))
643 calculate_max_homogeneous_pixels (GtkWidget *widget)
645 PangoContext *context;
646 PangoFontMetrics *metrics;
649 context = gtk_widget_get_pango_context (widget);
650 metrics = pango_context_get_metrics (context,
651 widget->style->font_desc,
652 pango_context_get_language (context));
653 char_width = pango_font_metrics_get_approximate_char_width (metrics);
654 pango_font_metrics_unref (metrics);
656 return PANGO_PIXELS (MAX_HOMOGENEOUS_N_CHARS * char_width);
660 toolbar_item_is_homogeneous (GtkToolbar *toolbar,
664 GtkRequisition requisition;
665 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
667 if (priv->max_homogeneous_pixels < 0)
669 priv->max_homogeneous_pixels =
670 calculate_max_homogeneous_pixels (GTK_WIDGET (toolbar));
673 result = gtk_tool_item_get_homogeneous (item) &&
674 !GTK_IS_SEPARATOR_TOOL_ITEM (item);
676 gtk_widget_size_request (GTK_WIDGET (item), &requisition);
678 if ((gtk_tool_item_get_is_important (item) &&
679 toolbar->style == GTK_TOOLBAR_BOTH_HORIZ &&
680 toolbar->orientation == GTK_ORIENTATION_HORIZONTAL) ||
681 requisition.width > priv->max_homogeneous_pixels)
690 gtk_toolbar_set_property (GObject *object,
695 GtkToolbar *toolbar = GTK_TOOLBAR (object);
699 case PROP_ORIENTATION:
700 gtk_toolbar_set_orientation (toolbar, g_value_get_enum (value));
702 case PROP_TOOLBAR_STYLE:
703 gtk_toolbar_set_style (toolbar, g_value_get_enum (value));
705 case PROP_SHOW_ARROW:
706 gtk_toolbar_set_show_arrow (toolbar, g_value_get_boolean (value));
709 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
715 gtk_toolbar_get_property (GObject *object,
720 GtkToolbar *toolbar = GTK_TOOLBAR (object);
721 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
725 case PROP_ORIENTATION:
726 g_value_set_enum (value, toolbar->orientation);
728 case PROP_TOOLBAR_STYLE:
729 g_value_set_enum (value, toolbar->style);
731 case PROP_SHOW_ARROW:
732 g_value_set_boolean (value, priv->show_arrow);
735 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
741 gtk_toolbar_map (GtkWidget *widget)
743 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
745 GTK_WIDGET_CLASS (parent_class)->map (widget);
747 if (priv->event_window)
748 gdk_window_show_unraised (priv->event_window);
752 gtk_toolbar_unmap (GtkWidget *widget)
754 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
756 if (priv->event_window)
757 gdk_window_hide (priv->event_window);
759 GTK_WIDGET_CLASS (parent_class)->unmap (widget);
763 gtk_toolbar_realize (GtkWidget *widget)
765 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
766 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
768 GdkWindowAttr attributes;
769 gint attributes_mask;
772 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
774 border_width = GTK_CONTAINER (widget)->border_width;
776 attributes.wclass = GDK_INPUT_ONLY;
777 attributes.window_type = GDK_WINDOW_CHILD;
778 attributes.x = widget->allocation.x + border_width;
779 attributes.y = widget->allocation.y + border_width;
780 attributes.width = widget->allocation.width - border_width * 2;
781 attributes.height = widget->allocation.height - border_width * 2;
782 attributes.event_mask = gtk_widget_get_events (widget);
783 attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
784 GDK_BUTTON_RELEASE_MASK |
785 GDK_ENTER_NOTIFY_MASK |
786 GDK_LEAVE_NOTIFY_MASK);
788 attributes_mask = GDK_WA_X | GDK_WA_Y;
790 widget->window = gtk_widget_get_parent_window (widget);
791 g_object_ref (widget->window);
792 widget->style = gtk_style_attach (widget->style, widget->window);
794 priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget),
795 &attributes, attributes_mask);
796 gdk_window_set_user_data (priv->event_window, toolbar);
800 gtk_toolbar_unrealize (GtkWidget *widget)
802 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
804 if (priv->event_window)
806 gdk_window_set_user_data (priv->event_window, NULL);
807 gdk_window_destroy (priv->event_window);
808 priv->event_window = NULL;
811 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
812 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
816 gtk_toolbar_expose (GtkWidget *widget,
817 GdkEventExpose *event)
819 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
820 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
825 border_width = GTK_CONTAINER (widget)->border_width;
827 if (GTK_WIDGET_DRAWABLE (widget))
829 gtk_paint_box (widget->style,
831 GTK_WIDGET_STATE (widget),
832 get_shadow_type (toolbar),
833 &event->area, widget, "toolbar",
834 border_width + widget->allocation.x,
835 border_width + widget->allocation.y,
836 widget->allocation.width - 2 * border_width,
837 widget->allocation.height - 2 * border_width);
840 for (list = priv->content; list != NULL; list = list->next)
842 ToolbarContent *content = list->data;
843 GtkToolItem *item = content->item;
845 if (!content->is_placeholder)
846 gtk_container_propagate_expose (GTK_CONTAINER (widget),
851 gtk_container_propagate_expose (GTK_CONTAINER (widget),
859 gtk_toolbar_size_request (GtkWidget *widget,
860 GtkRequisition *requisition)
862 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
863 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
865 gint max_child_height;
866 gint max_child_width;
867 gint max_homogeneous_child_width;
868 gint max_homogeneous_child_height;
869 gint homogeneous_size;
871 gint pack_front_size;
873 GtkRequisition arrow_requisition;
875 max_homogeneous_child_width = 0;
876 max_homogeneous_child_height = 0;
878 max_child_height = 0;
879 for (list = priv->content; list != NULL; list = list->next)
881 GtkRequisition requisition;
882 ToolbarContent *content = list->data;
883 GtkToolItem *item = content->item;
885 if (!toolbar_item_visible (toolbar, item))
888 gtk_widget_size_request (GTK_WIDGET (item), &requisition);
890 max_child_width = MAX (max_child_width, requisition.width);
891 max_child_height = MAX (max_child_height, requisition.height);
893 if (toolbar_item_is_homogeneous (toolbar, item))
895 max_homogeneous_child_width = MAX (max_homogeneous_child_width, requisition.width);
896 max_homogeneous_child_height = MAX (max_homogeneous_child_height, requisition.height);
900 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
901 homogeneous_size = max_homogeneous_child_width;
903 homogeneous_size = max_homogeneous_child_height;
906 for (list = priv->content; list != NULL; list = list->next)
908 ToolbarContent *content = list->data;
909 GtkToolItem *item = content->item;
912 if (!toolbar_item_visible (toolbar, item))
915 if (toolbar_item_is_homogeneous (toolbar, item))
917 size = homogeneous_size;
921 GtkRequisition requisition;
923 gtk_widget_size_request (GTK_WIDGET (item), &requisition);
925 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
926 size = requisition.width;
928 size = requisition.height;
931 pack_front_size += size;
934 if (priv->show_arrow && priv->api_mode == NEW_API)
936 gtk_widget_size_request (priv->arrow_button, &arrow_requisition);
938 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
939 long_req = arrow_requisition.width;
941 long_req = arrow_requisition.height;
943 /* There is no point requesting space for the arrow if that would take
944 * up more space than all the items combined
946 long_req = MIN (long_req, pack_front_size);
950 arrow_requisition.height = 0;
951 arrow_requisition.width = 0;
953 long_req = pack_front_size;
956 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
958 requisition->width = long_req;
959 requisition->height = MAX (max_child_height, arrow_requisition.height);
963 requisition->height = long_req;
964 requisition->width = MAX (max_child_width, arrow_requisition.width);
968 ipadding = get_internal_padding (toolbar);
970 requisition->width += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width);
971 requisition->height += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width);
973 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
975 requisition->width += 2 * widget->style->xthickness;
976 requisition->height += 2 * widget->style->ythickness;
979 toolbar->button_maxw = max_homogeneous_child_width;
980 toolbar->button_maxh = max_homogeneous_child_height;
984 fixup_allocation_for_rtl (gint total_size,
985 GtkAllocation *allocation)
987 allocation->x += (total_size - (2 * allocation->x + allocation->width));
991 fixup_allocation_for_vertical (GtkAllocation *allocation)
996 allocation->x = allocation->y;
999 tmp = allocation->width;
1000 allocation->width = allocation->height;
1001 allocation->height = tmp;
1005 get_item_size (GtkToolbar *toolbar,
1008 GtkRequisition requisition;
1009 GtkToolItem *item = GTK_TOOL_ITEM (child);
1011 gtk_widget_get_child_requisition (child, &requisition);
1013 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1015 if (toolbar_item_is_homogeneous (toolbar, item))
1016 return toolbar->button_maxw;
1018 return requisition.width;
1022 if (toolbar_item_is_homogeneous (toolbar, item))
1023 return toolbar->button_maxh;
1025 return requisition.height;
1030 gtk_toolbar_size_allocate (GtkWidget *widget,
1031 GtkAllocation *allocation)
1033 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1034 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1035 GtkAllocation *allocations;
1036 ItemState *new_states;
1037 GtkAllocation arrow_allocation;
1039 gint size, pos, short_size;
1042 gboolean need_arrow;
1043 gint n_expand_items;
1045 gint available_size;
1048 GtkRequisition arrow_requisition;
1050 gboolean overflowing;
1052 widget->allocation = *allocation;
1054 border_width = GTK_CONTAINER (toolbar)->border_width;
1056 if (GTK_WIDGET_REALIZED (widget))
1058 gdk_window_move_resize (priv->event_window,
1059 allocation->x + border_width,
1060 allocation->y + border_width,
1061 allocation->width - border_width * 2,
1062 allocation->height - border_width * 2);
1065 border_width += get_internal_padding (toolbar);
1067 gtk_widget_get_child_requisition (GTK_WIDGET (priv->arrow_button),
1068 &arrow_requisition);
1070 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1072 available_size = size = allocation->width - 2 * border_width;
1073 short_size = allocation->height - 2 * border_width;
1074 arrow_size = arrow_requisition.width;
1076 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1078 available_size -= 2 * widget->style->xthickness;
1079 short_size -= 2 * widget->style->ythickness;
1084 available_size = size = allocation->height - 2 * border_width;
1085 short_size = allocation->width - 2 * border_width;
1086 arrow_size = arrow_requisition.height;
1088 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1090 available_size -= 2 * widget->style->ythickness;
1091 short_size -= 2 * widget->style->xthickness;
1095 n_items = g_list_length (priv->content);
1096 allocations = g_new0 (GtkAllocation, n_items);
1097 new_states = g_new0 (ItemState, n_items);
1100 for (list = priv->content; list != NULL; list = list->next)
1102 ToolbarContent *content = list->data;
1103 GtkToolItem *item = content->item;
1105 if (toolbar_item_visible (toolbar, item))
1106 needed_size += get_item_size (toolbar, GTK_WIDGET (item));
1109 need_arrow = (needed_size > available_size) && priv->show_arrow && priv->api_mode == NEW_API;
1112 size = available_size - arrow_size;
1114 size = available_size;
1118 /* calculate widths of items */
1119 overflowing = FALSE;
1120 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1122 ToolbarContent *content = list->data;
1123 GtkToolItem *item = content->item;
1126 if (!toolbar_item_visible (toolbar, item))
1128 new_states[i] = HIDDEN;
1132 item_size = get_item_size (toolbar, GTK_WIDGET (item));
1133 if (item_size <= size && !overflowing)
1136 allocations[i].width = item_size;
1137 new_states[i] = NORMAL;
1143 new_states[i] = OVERFLOWN;
1147 /* calculate width of arrow */
1150 arrow_allocation.width = arrow_size;
1151 arrow_allocation.height = short_size;
1154 /* expand expandable items */
1156 /* We don't expand when dnd causes items to overflow. Doing so would result in
1157 * weird jumps as items are overflowed and expandable items suddenly get lots of
1158 * extra space. On the other hand we can't disable expanding completely, because
1159 * that would cause a weird jump when dnd begins
1161 if (!(priv->in_dnd && n_overflowed > priv->n_overflow_items_when_dnd_started))
1164 for (i = 0, list = priv->content; list != NULL; list = list->next, ++i)
1166 ToolbarContent *content = list->data;
1167 GtkToolItem *item = content->item;
1169 if (gtk_tool_item_get_expand (item) && new_states[i] == NORMAL)
1173 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1175 ToolbarContent *content = list->data;
1176 GtkToolItem *item = content->item;
1178 if (gtk_tool_item_get_expand (item) && new_states[i] == NORMAL)
1180 gint extra = size / n_expand_items;
1181 if (size % n_expand_items != 0)
1184 allocations[i].width += extra;
1190 g_assert (n_expand_items == 0);
1193 /* position items */
1195 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1197 if (new_states[i] == NORMAL)
1199 allocations[i].x = pos;
1200 allocations[i].y = border_width;
1201 allocations[i].height = short_size;
1203 pos += allocations[i].width;
1207 /* position arrow */
1210 arrow_allocation.x = available_size - border_width - arrow_allocation.width;
1211 arrow_allocation.y = border_width;
1214 /* fix up allocations in the vertical or RTL cases */
1215 if (toolbar->orientation == GTK_ORIENTATION_VERTICAL)
1217 for (i = 0; i < n_items; ++i)
1218 fixup_allocation_for_vertical (&(allocations[i]));
1221 fixup_allocation_for_vertical (&arrow_allocation);
1223 else if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
1225 for (i = 0; i < n_items; ++i)
1226 fixup_allocation_for_rtl (available_size, &(allocations[i]));
1229 fixup_allocation_for_rtl (available_size, &arrow_allocation);
1232 /* translate the items by allocation->(x,y) */
1233 for (i = 0; i < n_items; ++i)
1235 allocations[i].x += allocation->x;
1236 allocations[i].y += allocation->y;
1238 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1240 allocations[i].x += widget->style->xthickness;
1241 allocations[i].y += widget->style->ythickness;
1247 arrow_allocation.x += allocation->x;
1248 arrow_allocation.y += allocation->y;
1250 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1252 arrow_allocation.x += widget->style->xthickness;
1253 arrow_allocation.y += widget->style->ythickness;
1257 /* finally allocate the items */
1258 for (list = priv->content, i = 0; list != NULL; list = list->next, i++)
1260 ToolbarContent *content = list->data;
1261 GtkToolItem *item = content->item;
1263 if (new_states[i] == NORMAL)
1265 gtk_widget_size_allocate (GTK_WIDGET (item), &(allocations[i]));
1266 gtk_widget_set_child_visible (GTK_WIDGET (item), TRUE);
1270 gtk_widget_set_child_visible (GTK_WIDGET (item), FALSE);
1273 content->state = new_states[i];
1278 gtk_widget_size_allocate (GTK_WIDGET (priv->arrow_button),
1280 gtk_widget_show (GTK_WIDGET (priv->arrow_button));
1284 gtk_widget_hide (GTK_WIDGET (priv->arrow_button));
1287 g_free (allocations);
1288 g_free (new_states);
1292 gtk_toolbar_style_set (GtkWidget *widget,
1293 GtkStyle *prev_style)
1295 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
1297 priv->max_homogeneous_pixels = -1;
1299 if (GTK_WIDGET_REALIZED (widget))
1300 gtk_style_set_background (widget->style, widget->window, widget->state);
1303 gtk_toolbar_update_button_relief (GTK_TOOLBAR (widget));
1307 gtk_toolbar_direction_changed (GtkWidget *widget,
1308 GtkTextDirection previous_dir)
1310 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1311 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1313 if (toolbar->orientation == GTK_ORIENTATION_VERTICAL)
1315 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
1316 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
1318 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_LEFT, GTK_SHADOW_NONE);
1321 GTK_WIDGET_CLASS (parent_class)->direction_changed (widget, previous_dir);
1325 gtk_toolbar_list_children_in_focus_order (GtkToolbar *toolbar,
1326 GtkDirectionType dir)
1328 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1329 GList *result = NULL;
1333 /* generate list of children in reverse logical order */
1335 for (list = priv->content; list != NULL; list = list->next)
1337 ToolbarContent *content = list->data;
1338 GtkToolItem *item = content->item;
1340 result = g_list_prepend (result, item);
1343 result = g_list_prepend (result, priv->arrow_button);
1345 rtl = (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL);
1347 /* move in logical order when
1349 * - dir is TAB_FORWARD
1351 * - in RTL mode and moving left or up
1353 * - in LTR mode and moving right or down
1355 if (dir == GTK_DIR_TAB_FORWARD ||
1356 (rtl && (dir == GTK_DIR_UP || dir == GTK_DIR_LEFT)) ||
1357 (!rtl && (dir == GTK_DIR_DOWN || dir == GTK_DIR_RIGHT)))
1359 result = g_list_reverse (result);
1366 gtk_toolbar_focus_home_or_end (GtkToolbar *toolbar,
1367 gboolean focus_home)
1369 GList *children, *list;
1370 GtkDirectionType dir = focus_home? GTK_DIR_RIGHT : GTK_DIR_LEFT;
1372 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1374 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
1376 children = g_list_reverse (children);
1378 dir = (dir == GTK_DIR_RIGHT)? GTK_DIR_LEFT : GTK_DIR_RIGHT;
1381 for (list = children; list != NULL; list = list->next)
1383 GtkWidget *child = list->data;
1385 if (GTK_CONTAINER (toolbar)->focus_child == child)
1388 if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1392 g_list_free (children);
1397 /* Keybinding handler. This function is called when the user presses
1398 * Ctrl TAB or an arrow key.
1401 gtk_toolbar_move_focus (GtkToolbar *toolbar,
1402 GtkDirectionType dir)
1405 gboolean try_focus = FALSE;
1407 GtkContainer *container = GTK_CONTAINER (toolbar);
1409 if (container->focus_child &&
1410 gtk_widget_child_focus (container->focus_child, dir))
1415 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1417 for (list = children; list != NULL; list = list->next)
1419 GtkWidget *child = list->data;
1421 if (try_focus && GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1424 if (child == GTK_CONTAINER (toolbar)->focus_child)
1428 g_list_free (children);
1433 /* The focus handler for the toolbar. It called when the user presses
1434 * TAB or otherwise tries to focus the toolbar.
1437 gtk_toolbar_focus (GtkWidget *widget,
1438 GtkDirectionType dir)
1440 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1441 GList *children, *list;
1443 /* if focus is already somewhere inside the toolbar then return FALSE.
1444 * The only way focus can stay inside the toolbar is when the user presses
1445 * arrow keys or Ctrl TAB (both of which are handled by the
1446 * gtk_toolbar_move_focus() keybinding function.
1448 if (GTK_CONTAINER (widget)->focus_child)
1451 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1453 for (list = children; list != NULL; list = list->next)
1455 GtkWidget *child = list->data;
1457 if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1461 g_list_free (children);
1467 style_change_notify (GtkToolbar *toolbar)
1469 if (!toolbar->style_set)
1471 /* pretend it was set, then unset, thus reverting to new default */
1472 toolbar->style_set = TRUE;
1473 gtk_toolbar_unset_style (toolbar);
1478 icon_size_change_notify (GtkToolbar *toolbar)
1480 if (!toolbar->icon_size_set)
1482 /* pretend it was set, then unset, thus reverting to new default */
1483 toolbar->icon_size_set = TRUE;
1484 gtk_toolbar_unset_icon_size (toolbar);
1488 static GtkSettings *
1489 toolbar_get_settings (GtkToolbar *toolbar)
1491 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1492 return priv->settings;
1496 gtk_toolbar_screen_changed (GtkWidget *widget,
1497 GdkScreen *previous_screen)
1499 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
1500 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1501 GtkSettings *old_settings = toolbar_get_settings (toolbar);
1502 GtkSettings *settings;
1504 if (gtk_widget_has_screen (GTK_WIDGET (toolbar)))
1505 settings = gtk_widget_get_settings (GTK_WIDGET (toolbar));
1509 if (settings == old_settings)
1514 g_signal_handler_disconnect (old_settings, toolbar->style_set_connection);
1515 g_signal_handler_disconnect (old_settings, toolbar->icon_size_connection);
1517 g_object_unref (old_settings);
1522 toolbar->style_set_connection =
1523 g_signal_connect_swapped (settings,
1524 "notify::gtk-toolbar-style",
1525 G_CALLBACK (style_change_notify),
1527 toolbar->icon_size_connection =
1528 g_signal_connect_swapped (settings,
1529 "notify::gtk-toolbar-icon-size",
1530 G_CALLBACK (icon_size_change_notify),
1533 g_object_ref (settings);
1534 priv->settings = settings;
1537 priv->settings = NULL;
1539 style_change_notify (toolbar);
1540 icon_size_change_notify (toolbar);
1544 find_drop_index (GtkToolbar *toolbar,
1548 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1549 GList *interesting_content;
1551 GtkOrientation orientation;
1552 GtkTextDirection direction;
1553 gint best_distance = G_MAXINT;
1557 ToolbarContent *best_content;
1559 /* list items we care about wrt. drag and drop */
1560 interesting_content = NULL;
1561 for (list = priv->content; list != NULL; list = list->next)
1563 ToolbarContent *content = list->data;
1565 if (content->state == NORMAL)
1566 interesting_content = g_list_prepend (interesting_content, content);
1568 interesting_content = g_list_reverse (interesting_content);
1570 if (!interesting_content)
1573 orientation = toolbar->orientation;
1574 direction = gtk_widget_get_direction (GTK_WIDGET (toolbar));
1576 /* distance to first interesting item */
1577 best_content = interesting_content->data;
1579 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1583 if (direction == GTK_TEXT_DIR_LTR)
1584 pos = GTK_WIDGET (best_content->item)->allocation.x;
1586 pos = GTK_WIDGET (best_content->item)->allocation.x +
1587 GTK_WIDGET (best_content->item)->allocation.width;
1592 pos = GTK_WIDGET (best_content->item)->allocation.y;
1595 best_content = NULL;
1596 best_distance = ABS (pos - cursor);
1598 /* distance to far end of each item */
1599 for (list = interesting_content; list != NULL; list = list->next)
1601 ToolbarContent *content = list->data;
1602 GtkWidget *widget = GTK_WIDGET (content->item);
1604 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1606 if (direction == GTK_TEXT_DIR_LTR)
1607 pos = widget->allocation.x + widget->allocation.width;
1609 pos = widget->allocation.x;
1613 pos = widget->allocation.y + widget->allocation.height;
1616 distance = ABS (pos - cursor);
1618 if (distance < best_distance)
1620 best_distance = distance;
1621 best_content = content;
1625 g_list_free (interesting_content);
1630 return g_list_index (priv->content, best_content) + 1;
1634 get_size (GtkToolItem *tool_item, gint *width, gint *height)
1636 if (!GTK_WIDGET_VISIBLE (tool_item))
1645 gtk_widget_get_child_requisition (GTK_WIDGET (tool_item), &req);
1647 *height = req.height;
1651 #define UPDATE_TIME (0.10)
1654 update_dnd_animation (gpointer data)
1656 GtkToolbar *toolbar = data;
1657 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1663 GDK_THREADS_ENTER();
1665 if (priv->need_sync)
1668 elapsed = g_timer_elapsed (priv->timer, NULL);
1672 list = priv->content;
1676 ToolbarContent *content = list->data;
1677 GtkWidget *widget = GTK_WIDGET (content->item);
1678 GList *next = list->next;
1679 gdouble exact_value;
1680 gint start_value, goal_value;
1681 gint new_value, prev_value;
1683 if (content->is_placeholder)
1685 gint prev_width, prev_height;
1687 get_size (GTK_TOOL_ITEM (widget), &prev_width, &prev_height);
1688 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1690 start_value = content->start_width;
1691 goal_value = content->goal_width;
1692 prev_value = prev_width;
1696 start_value = content->start_height;
1697 goal_value = content->goal_height;
1698 prev_value = prev_height;
1701 if (elapsed <= UPDATE_TIME)
1703 exact_value = start_value + (elapsed / UPDATE_TIME) * (goal_value - start_value);
1704 new_value = (int) (exact_value + error + 0.5);
1706 error += (exact_value - new_value);
1712 exact_value = (double)goal_value;
1713 new_value = goal_value;
1717 gtk_widget_hide (widget);
1719 gtk_widget_show (widget);
1721 /* We need to check for "elapsed > UPDATE_TIME" so that the widget
1722 * doesn't disappear before time. We need its contribution to
1723 * the error value, even if its pixel width is 0.
1725 if (goal_value == 0 && elapsed > UPDATE_TIME)
1727 gtk_toolbar_remove_tool_item (toolbar, GTK_TOOL_ITEM (widget));
1729 else if (new_value != prev_value)
1731 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1732 gtk_widget_set_size_request (widget, new_value, 0);
1734 gtk_widget_set_size_request (widget, 0, new_value);
1736 priv->need_sync = TRUE;
1744 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (toolbar));
1749 if (priv->leaving_dnd)
1751 priv->in_dnd = FALSE;
1752 priv->leaving_dnd = FALSE;
1753 priv->n_overflow_items_when_dnd_started = 0;
1756 GDK_THREADS_LEAVE();
1761 GDK_THREADS_LEAVE();
1767 ensure_idle_handler (GtkToolbar *toolbar)
1769 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1772 priv->idle_id = g_idle_add (update_dnd_animation, toolbar);
1776 reset_all_placeholders (GtkToolbar *toolbar)
1778 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1781 for (list = priv->content; list != NULL; list = list->next)
1783 ToolbarContent *content = list->data;
1784 if (content->is_placeholder)
1786 get_size (content->item,
1787 &(content->start_width), &(content->start_height));
1788 content->goal_width = 0;
1789 content->goal_height = 0;
1793 g_timer_reset (priv->timer);
1797 physical_to_logical (GtkToolbar *toolbar, gint physical)
1799 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1803 g_assert (physical >= 0);
1806 for (list = priv->content; list && physical > 0; list = list->next)
1808 ToolbarContent *content = list->data;
1810 if (!content->is_placeholder)
1815 g_assert (physical == 0);
1821 logical_to_physical (GtkToolbar *toolbar, gint logical)
1823 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1827 g_assert (logical >= 0);
1830 for (list = priv->content; list; list = list->next)
1832 ToolbarContent *content = list->data;
1834 if (!content->is_placeholder)
1844 g_assert (logical == 0);
1850 * gtk_toolbar_set_drop_highlight_item:
1851 * @toolbar: a #GtkToolbar
1852 * @item: a #GtkToolItem, or %NULL to turn of highlighting
1853 * @index: a position on @toolbar
1855 * Highlights @toolbar to give an idea of what it would look like
1856 * if @item was added to @toolbar at position indicated by @index. If @item
1857 * is %NULL, highlighting is turned off. In that case @index is ignored.
1859 * The @tool_item passed to this function must not be part of any widget
1860 * hierarchy. When an item is set as drop highlight item it can not
1861 * added to any widget hierarchy or used as highlight item for another
1867 gtk_toolbar_set_drop_highlight_item (GtkToolbar *toolbar,
1868 GtkToolItem *tool_item,
1871 ToolbarContent *content;
1872 GtkToolbarPrivate *priv;
1873 gint start_width, start_height;
1876 GtkRequisition requisition;
1878 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1879 g_return_if_fail (tool_item == NULL || GTK_IS_TOOL_ITEM (tool_item));
1881 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1887 priv->leaving_dnd = TRUE;
1888 reset_all_placeholders (toolbar);
1889 ensure_idle_handler (toolbar);
1891 if (priv->highlight_tool_item)
1893 gtk_widget_unparent (GTK_WIDGET (priv->highlight_tool_item));
1894 g_object_unref (priv->highlight_tool_item);
1895 priv->highlight_tool_item = NULL;
1902 if (tool_item != priv->highlight_tool_item)
1904 if (priv->highlight_tool_item)
1905 g_object_unref (priv->highlight_tool_item);
1907 g_object_ref (tool_item);
1908 gtk_object_sink (GTK_OBJECT (tool_item));
1910 priv->highlight_tool_item = tool_item;
1912 gtk_widget_set_parent (GTK_WIDGET (priv->highlight_tool_item),
1913 GTK_WIDGET (toolbar));
1918 priv->n_overflow_items_when_dnd_started = 0;
1919 for (list = priv->content; list != NULL; list = list->next)
1921 content = list->data;
1922 if (content->state == OVERFLOWN)
1923 priv->n_overflow_items_when_dnd_started++;
1927 priv->in_dnd = TRUE;
1928 priv->leaving_dnd = FALSE;
1930 n_items = gtk_toolbar_get_n_items (toolbar);
1931 if (index < 0 || index > n_items)
1934 index = logical_to_physical (toolbar, index);
1936 content = g_list_nth_data (priv->content, index);
1940 ToolbarContent *prev_content;
1942 prev_content = g_list_nth_data (priv->content, index - 1);
1944 if (prev_content && prev_content->is_placeholder)
1945 content = prev_content;
1948 if (!content || !content->is_placeholder)
1950 GtkWidget *placeholder;
1952 placeholder = GTK_WIDGET (gtk_separator_tool_item_new ());
1953 gtk_widget_set_size_request (placeholder, 0, 0);
1954 content = gtk_toolbar_insert_tool_item (toolbar,
1955 GTK_TOOL_ITEM (placeholder),
1957 start_width = start_height = 0;
1961 get_size (content->item, &start_width, &start_height);
1965 g_assert (content->is_placeholder);
1967 gtk_widget_size_request (GTK_WIDGET (priv->highlight_tool_item),
1970 if (content->start_width != start_width ||
1971 content->start_height != start_height ||
1972 content->goal_width != requisition.width ||
1973 content->goal_height != requisition.height)
1975 reset_all_placeholders (toolbar);
1977 content->start_width = start_width;
1978 content->goal_width = requisition.width;
1979 content->start_height = start_height;
1980 content->goal_height = requisition.height;
1982 ensure_idle_handler (toolbar);
1987 gtk_toolbar_unhighlight_drop_location (GtkToolbar *toolbar)
1992 gtk_toolbar_get_child_property (GtkContainer *container,
1998 GtkToolItem *item = GTK_TOOL_ITEM (child);
2000 switch (property_id)
2002 case CHILD_PROP_HOMOGENEOUS:
2003 g_value_set_boolean (value, gtk_tool_item_get_homogeneous (item));
2006 case CHILD_PROP_EXPAND:
2007 g_value_set_boolean (value, gtk_tool_item_get_expand (item));
2011 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
2017 gtk_toolbar_set_child_property (GtkContainer *container,
2020 const GValue *value,
2023 switch (property_id)
2025 case CHILD_PROP_HOMOGENEOUS:
2026 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
2029 case CHILD_PROP_EXPAND:
2030 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
2034 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
2040 gtk_toolbar_add (GtkContainer *container,
2043 GtkToolbar *toolbar;
2045 g_return_if_fail (GTK_IS_TOOLBAR (container));
2046 g_return_if_fail (widget != NULL);
2048 toolbar = GTK_TOOLBAR (container);
2050 if (GTK_IS_TOOL_ITEM (widget))
2051 gtk_toolbar_insert (toolbar, GTK_TOOL_ITEM (widget), 0);
2053 gtk_toolbar_append_widget (toolbar, widget, NULL, NULL);
2057 gtk_toolbar_remove (GtkContainer *container,
2060 GtkToolbar *toolbar;
2061 GtkToolItem *item = NULL;
2063 g_return_if_fail (GTK_IS_TOOLBAR (container));
2064 g_return_if_fail (GTK_IS_WIDGET (widget));
2066 toolbar = GTK_TOOLBAR (container);
2068 if (GTK_IS_TOOL_ITEM (widget))
2070 item = GTK_TOOL_ITEM (widget);
2074 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2077 for (list = priv->content; list != NULL; list = list->next)
2079 ToolbarContent *content = list->data;
2081 if (GTK_BIN (content->item)->child == widget)
2083 item = content->item;
2089 g_return_if_fail (item != NULL);
2091 gtk_toolbar_remove_tool_item (GTK_TOOLBAR (container), item);
2095 gtk_toolbar_forall (GtkContainer *container,
2096 gboolean include_internals,
2097 GtkCallback callback,
2098 gpointer callback_data)
2100 GtkToolbar *toolbar = GTK_TOOLBAR (container);
2101 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2104 g_return_if_fail (callback != NULL);
2106 list = priv->content;
2109 ToolbarContent *content = list->data;
2110 GList *next = list->next;
2112 if (!content->is_placeholder || include_internals)
2113 (*callback) (GTK_WIDGET (content->item), callback_data);
2118 if (include_internals)
2119 (* callback) (priv->arrow_button, callback_data);
2123 gtk_toolbar_child_type (GtkContainer *container)
2125 return GTK_TYPE_TOOL_ITEM;
2129 gtk_toolbar_reconfigured (GtkToolbar *toolbar)
2131 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2134 list = priv->content;
2137 ToolbarContent *content = list->data;
2138 GList *next = list->next;
2140 _gtk_tool_item_toolbar_reconfigured (content->item);
2147 gtk_toolbar_real_orientation_changed (GtkToolbar *toolbar,
2148 GtkOrientation orientation)
2150 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2151 if (toolbar->orientation != orientation)
2153 toolbar->orientation = orientation;
2155 if (orientation == GTK_ORIENTATION_HORIZONTAL)
2156 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_DOWN, GTK_SHADOW_NONE);
2157 else if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
2158 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
2160 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_LEFT, GTK_SHADOW_NONE);
2162 gtk_toolbar_reconfigured (toolbar);
2164 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2165 g_object_notify (G_OBJECT (toolbar), "orientation");
2170 gtk_toolbar_real_style_changed (GtkToolbar *toolbar,
2171 GtkToolbarStyle style)
2173 if (toolbar->style != style)
2175 toolbar->style = style;
2177 gtk_toolbar_reconfigured (toolbar);
2179 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2180 g_object_notify (G_OBJECT (toolbar), "toolbar_style");
2185 menu_position_func (GtkMenu *menu,
2191 GtkToolbar *toolbar = GTK_TOOLBAR (user_data);
2192 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2194 GtkRequisition menu_req;
2196 gdk_window_get_origin (GTK_BUTTON (priv->arrow_button)->event_window, x, y);
2197 gtk_widget_size_request (priv->arrow_button, &req);
2198 gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
2200 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
2202 *y += priv->arrow_button->allocation.height;
2203 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
2204 *x += priv->arrow_button->allocation.width - req.width;
2206 *x += req.width - menu_req.width;
2210 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
2211 *x += priv->arrow_button->allocation.width;
2213 *x -= menu_req.width;
2214 *y += priv->arrow_button->allocation.height - req.height;
2221 menu_deactivated (GtkWidget *menu,
2222 GtkToolbar *toolbar)
2224 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2226 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->arrow_button), FALSE);
2230 remove_item (GtkWidget *menu_item,
2233 gtk_container_remove (GTK_CONTAINER (menu_item->parent), menu_item);
2237 show_menu (GtkToolbar *toolbar,
2238 GdkEventButton *event)
2240 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2245 gtk_container_foreach (GTK_CONTAINER (priv->menu), remove_item, NULL);
2246 gtk_widget_destroy (GTK_WIDGET (priv->menu));
2249 priv->menu = GTK_MENU (gtk_menu_new ());
2250 g_signal_connect (priv->menu, "deactivate", G_CALLBACK (menu_deactivated), toolbar);
2252 for (list = priv->content; list != NULL; list = list->next)
2254 ToolbarContent *content = list->data;
2255 GtkToolItem *item = content->item;
2257 if (content->state == OVERFLOWN)
2259 GtkWidget *menu_item = gtk_tool_item_retrieve_proxy_menu_item (item);
2263 g_assert (GTK_IS_MENU_ITEM (menu_item));
2264 gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), menu_item);
2269 gtk_widget_show_all (GTK_WIDGET (priv->menu));
2271 gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL,
2272 menu_position_func, toolbar,
2273 event? event->button : 0, event? event->time : gtk_get_current_event_time());
2277 gtk_toolbar_arrow_button_clicked (GtkWidget *button,
2278 GtkToolbar *toolbar)
2280 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2282 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->arrow_button)) &&
2283 (!priv->menu || !GTK_WIDGET_VISIBLE (GTK_WIDGET (priv->menu))))
2285 /* We only get here when the button is clicked with the keybaord,
2286 * because mouse button presses result in the menu being shown so
2287 * that priv->menu would be non-NULL and visible.
2289 show_menu (toolbar, NULL);
2290 gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->menu), FALSE);
2295 gtk_toolbar_arrow_button_press (GtkWidget *button,
2296 GdkEventButton *event,
2297 GtkToolbar *toolbar)
2299 show_menu (toolbar, event);
2300 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
2306 gtk_toolbar_button_press (GtkWidget *toolbar,
2307 GdkEventButton *event)
2309 if (event->button == 3)
2311 gboolean return_value;
2313 g_signal_emit (toolbar, toolbar_signals[POPUP_CONTEXT_MENU], 0,
2314 (int)event->x_root, (int)event->y_root, event->button,
2317 return return_value;
2324 gtk_toolbar_popup_menu (GtkWidget *toolbar)
2326 gboolean return_value;
2327 /* This function is the handler for the "popup menu" keybinding,
2328 * ie., it is called when the user presses Shift F10
2330 g_signal_emit (toolbar, toolbar_signals[POPUP_CONTEXT_MENU], 0,
2331 -1, -1, -1, &return_value);
2333 return return_value;
2337 gtk_toolbar_update_button_relief (GtkToolbar *toolbar)
2339 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2341 gtk_toolbar_reconfigured (toolbar);
2343 gtk_button_set_relief (GTK_BUTTON (priv->arrow_button), get_button_relief (toolbar));
2346 static GtkReliefStyle
2347 get_button_relief (GtkToolbar *toolbar)
2349 GtkReliefStyle button_relief = GTK_RELIEF_NORMAL;
2351 gtk_widget_ensure_style (GTK_WIDGET (toolbar));
2353 gtk_widget_style_get (GTK_WIDGET (toolbar),
2354 "button_relief", &button_relief,
2357 return button_relief;
2361 get_internal_padding (GtkToolbar *toolbar)
2365 gtk_widget_style_get (GTK_WIDGET (toolbar),
2366 "internal_padding", &ipadding,
2372 static GtkShadowType
2373 get_shadow_type (GtkToolbar *toolbar)
2375 GtkShadowType shadow_type;
2377 gtk_widget_style_get (GTK_WIDGET (toolbar),
2378 "shadow_type", &shadow_type,
2385 gtk_toolbar_check_old_api (GtkToolbar *toolbar)
2387 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2389 if (priv->api_mode == NEW_API)
2391 g_warning ("mixing deprecated and non-deprecated GtkToolbar API is not allowed");
2395 priv->api_mode = OLD_API;
2400 gtk_toolbar_check_new_api (GtkToolbar *toolbar)
2402 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2404 if (priv->api_mode == OLD_API)
2406 g_warning ("mixing deprecated and non-deprecated GtkToolbar API is not allowed");
2410 priv->api_mode = NEW_API;
2414 static ToolbarContent *
2415 gtk_toolbar_insert_tool_item (GtkToolbar *toolbar,
2418 gboolean is_placeholder)
2420 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2421 ToolbarContent *content = g_new0 (ToolbarContent, 1);
2423 content->is_placeholder = is_placeholder;
2424 content->item = item;
2425 content->state = NOT_ALLOCATED;
2426 toolbar->num_children++;
2428 priv->content = g_list_insert (priv->content, content, pos);
2430 gtk_widget_set_parent (GTK_WIDGET (item), GTK_WIDGET (toolbar));
2435 gtk_toolbar_remove_tool_item (GtkToolbar *toolbar,
2438 GtkToolbarPrivate *priv;
2441 ToolbarContent *content = NULL;
2443 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2444 g_return_if_fail (GTK_IS_TOOL_ITEM (item));
2446 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2450 for (tmp = priv->content; tmp != NULL; tmp = tmp->next)
2452 content = tmp->data;
2453 if (content->item == item)
2459 g_return_if_fail (content != NULL);
2463 priv->content = g_list_remove (priv->content, content);
2465 gtk_widget_unparent (GTK_WIDGET (item));
2467 if (priv->api_mode == OLD_API)
2469 GtkToolbarChild *toolbar_child;
2471 toolbar_child = g_list_nth_data (toolbar->children, nth_child);
2472 toolbar->children = g_list_remove (toolbar->children, toolbar_child);
2474 g_free (toolbar_child);
2477 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2483 * Creates a new toolbar.
2485 * Return Value: the newly-created toolbar.
2488 gtk_toolbar_new (void)
2490 GtkToolbar *toolbar;
2492 toolbar = g_object_new (GTK_TYPE_TOOLBAR, NULL);
2494 return GTK_WIDGET (toolbar);
2498 * gtk_toolbar_insert:
2499 * @toolbar: a #GtkToolbar
2500 * @item: a #GtkToolItem
2501 * @pos: the position of the new item
2503 * Insert a #GtkToolItem into the toolbar at position @pos. If @pos is
2504 * 0 the item is prepended to the start of the toolbar. If @pos is
2505 * negative, the item is appended to the end of the toolbar.
2510 gtk_toolbar_insert (GtkToolbar *toolbar,
2514 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2515 g_return_if_fail (GTK_IS_TOOL_ITEM (item));
2517 if (!gtk_toolbar_check_new_api (toolbar))
2521 pos = logical_to_physical (toolbar, pos);
2523 gtk_toolbar_insert_tool_item (toolbar, item, pos, FALSE);
2527 * gtk_toolbar_get_item_index:
2528 * @toolbar: a #GtkToolbar
2529 * @item: a #GtkToolItem that is a child of @toolbar
2531 * Returns the position of @item on the toolbar, starting from 0.
2532 * It is an error if @item is not a child of the toolbar.
2534 * Return value: the position of item on the toolbar.
2539 gtk_toolbar_get_item_index (GtkToolbar *toolbar,
2542 GtkToolbarPrivate *priv;
2546 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
2547 g_return_val_if_fail (GTK_IS_TOOL_ITEM (item), -1);
2548 g_return_val_if_fail (GTK_WIDGET (item)->parent == GTK_WIDGET (toolbar), -1);
2550 if (!gtk_toolbar_check_new_api (toolbar))
2553 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2556 for (list = priv->content; list != NULL; list = list->next)
2558 ToolbarContent *content = list->data;
2560 if (content->item == item)
2566 return physical_to_logical (toolbar, n);
2570 * gtk_toolbar_set_orientation:
2571 * @toolbar: a #GtkToolbar.
2572 * @orientation: a new #GtkOrientation.
2574 * Sets whether a toolbar should appear horizontally or vertically.
2577 gtk_toolbar_set_orientation (GtkToolbar *toolbar,
2578 GtkOrientation orientation)
2580 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2582 g_signal_emit (toolbar, toolbar_signals[ORIENTATION_CHANGED], 0, orientation);
2586 * gtk_toolbar_get_orientation:
2587 * @toolbar: a #GtkToolbar
2589 * Retrieves the current orientation of the toolbar. See
2590 * gtk_toolbar_set_orientation().
2592 * Return value: the orientation
2595 gtk_toolbar_get_orientation (GtkToolbar *toolbar)
2597 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_ORIENTATION_HORIZONTAL);
2599 return toolbar->orientation;
2603 * gtk_toolbar_set_style:
2604 * @toolbar: a #GtkToolbar.
2605 * @style: the new style for @toolbar.
2607 * Alters the view of @toolbar to display either icons only, text only, or both.
2610 gtk_toolbar_set_style (GtkToolbar *toolbar,
2611 GtkToolbarStyle style)
2613 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2615 toolbar->style_set = TRUE;
2616 g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
2622 * gtk_toolbar_get_style:
2623 * @toolbar: a #GtkToolbar
2625 * Retrieves whether the toolbar has text, icons, or both . See
2626 * gtk_toolbar_set_style().
2628 * Return value: the current style of @toolbar
2631 gtk_toolbar_get_style (GtkToolbar *toolbar)
2633 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), DEFAULT_TOOLBAR_STYLE);
2635 return toolbar->style;
2639 * gtk_toolbar_unset_style:
2640 * @toolbar: a #GtkToolbar
2642 * Unsets a toolbar style set with gtk_toolbar_set_style(), so that
2643 * user preferences will be used to determine the toolbar style.
2646 gtk_toolbar_unset_style (GtkToolbar *toolbar)
2648 GtkToolbarStyle style;
2650 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2652 if (toolbar->style_set)
2654 GtkSettings *settings = toolbar_get_settings (toolbar);
2657 g_object_get (settings,
2658 "gtk-toolbar-style", &style,
2661 style = DEFAULT_TOOLBAR_STYLE;
2663 if (style != toolbar->style)
2664 g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
2666 toolbar->style_set = FALSE;
2671 * gtk_toolbar_set_tooltips:
2672 * @toolbar: a #GtkToolbar.
2673 * @enable: set to %FALSE to disable the tooltips, or %TRUE to enable them.
2675 * Sets if the tooltips of a toolbar should be active or not.
2678 gtk_toolbar_set_tooltips (GtkToolbar *toolbar,
2681 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2684 gtk_tooltips_enable (toolbar->tooltips);
2686 gtk_tooltips_disable (toolbar->tooltips);
2690 * gtk_toolbar_get_tooltips:
2691 * @toolbar: a #GtkToolbar
2693 * Retrieves whether tooltips are enabled. See
2694 * gtk_toolbar_set_tooltips().
2696 * Return value: %TRUE if tooltips are enabled
2699 gtk_toolbar_get_tooltips (GtkToolbar *toolbar)
2701 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2703 return toolbar->tooltips->enabled;
2707 * gtk_toolbar_get_n_items:
2708 * @toolbar: a #GtkToolbar
2710 * Returns the number of items on the toolbar.
2712 * Return value: the number of items on the toolbar
2717 gtk_toolbar_get_n_items (GtkToolbar *toolbar)
2719 GtkToolbarPrivate *priv;
2721 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
2723 if (!gtk_toolbar_check_new_api (toolbar))
2726 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2728 return physical_to_logical (toolbar, g_list_length (priv->content));
2732 * gtk_toolbar_get_nth_item:
2733 * @toolbar: a #GtkToolbar
2734 * @n: A position on the toolbar
2736 * Returns the @n<!-- -->'s item on @toolbar, or %NULL if the
2737 * toolbar does not contain an @n<!-- -->'th item.
2739 * Return value: The @n<!-- -->'th #GtkToolItem on @toolbar, or %NULL if there
2740 * isn't an @n<!-- -->th item.
2745 gtk_toolbar_get_nth_item (GtkToolbar *toolbar,
2748 GtkToolbarPrivate *priv;
2749 ToolbarContent *content;
2752 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
2754 if (!gtk_toolbar_check_new_api (toolbar))
2757 n_items = gtk_toolbar_get_n_items (toolbar);
2759 if (n < 0 || n >= n_items)
2762 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2764 content = g_list_nth_data (priv->content, logical_to_physical (toolbar, n));
2767 g_assert (!content->is_placeholder);
2769 return content->item;
2773 * gtk_toolbar_set_icon_size:
2774 * @toolbar: A #GtkToolbar
2775 * @icon_size: The #GtkIconSize that stock icons in the toolbar shall have.
2777 * This function sets the size of stock icons in the toolbar. You
2778 * can call it both before you add the icons and after they've been
2779 * added. The size you set will override user preferences for the default
2783 gtk_toolbar_set_icon_size (GtkToolbar *toolbar,
2784 GtkIconSize icon_size)
2786 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2788 toolbar->icon_size_set = TRUE;
2790 if (toolbar->icon_size == icon_size)
2793 toolbar->icon_size = icon_size;
2795 gtk_toolbar_reconfigured (toolbar);
2797 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2801 * gtk_toolbar_get_icon_size:
2802 * @toolbar: a #GtkToolbar
2804 * Retrieves the icon size fo the toolbar. See gtk_toolbar_set_icon_size().
2806 * Return value: the current icon size for the icons on the toolbar.
2809 gtk_toolbar_get_icon_size (GtkToolbar *toolbar)
2811 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), DEFAULT_ICON_SIZE);
2813 return toolbar->icon_size;
2817 * gtk_toolbar_get_relief_style:
2818 * @toolbar: a #GtkToolbar
2820 * Returns the relief style of buttons on @toolbar. See
2821 * gtk_button_set_relief_style().
2823 * Return value: The relief style of buttons on @toolbar.
2828 gtk_toolbar_get_relief_style (GtkToolbar *toolbar)
2830 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_RELIEF_NONE);
2832 return get_button_relief (toolbar);
2836 * gtk_toolbar_unset_icon_size:
2837 * @toolbar: a #GtkToolbar
2839 * Unsets toolbar icon size set with gtk_toolbar_set_icon_size(), so that
2840 * user preferences will be used to determine the icon size.
2843 gtk_toolbar_unset_icon_size (GtkToolbar *toolbar)
2847 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2849 if (toolbar->icon_size_set)
2851 GtkSettings *settings = toolbar_get_settings (toolbar);
2855 g_object_get (settings,
2856 "gtk-toolbar-icon-size", &size,
2860 size = DEFAULT_ICON_SIZE;
2862 if (size != toolbar->icon_size)
2863 gtk_toolbar_set_icon_size (toolbar, size);
2865 toolbar->icon_size_set = FALSE;
2870 * gtk_toolbar_set_show_arrow:
2871 * @toolbar: a #GtkToolbar
2872 * @show_arrow: Whether to show an overflow menu
2874 * Sets whether to show an overflow menu when
2875 * @toolbar doesn't have room for all items on it. If %TRUE,
2876 * items that there are not room are available through an
2882 gtk_toolbar_set_show_arrow (GtkToolbar *toolbar,
2883 gboolean show_arrow)
2885 GtkToolbarPrivate *priv;
2887 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2889 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2890 show_arrow = show_arrow != FALSE;
2892 if (priv->show_arrow != show_arrow)
2894 priv->show_arrow = show_arrow;
2896 if (!priv->show_arrow)
2897 gtk_widget_hide (priv->arrow_button);
2899 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2900 g_object_notify (G_OBJECT (toolbar), "show_arrow");
2905 * gtk_toolbar_get_show_arrow:
2906 * @toolbar: a #GtkToolbar
2908 * Returns whether the toolbar has an overflow menu.
2909 * See gtk_toolbar_set_show_arrow()
2916 gtk_toolbar_get_show_arrow (GtkToolbar *toolbar)
2918 GtkToolbarPrivate *priv;
2920 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2922 if (!gtk_toolbar_check_new_api (toolbar))
2925 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2927 return priv->show_arrow;
2931 * gtk_toolbar_get_drop_index:
2932 * @toolbar: a #GtkToolbar
2933 * @x: x coordinate of a point on the toolbar
2934 * @y: y coordinate of a point on the toolbar
2936 * Returns the position corresponding to the indicated point on
2937 * @toolbar. This is useful when dragging items to the toolbar:
2938 * this function returns the position a new item should be
2941 * @x and @y are in @toolbar coordinates.
2943 * Return value: The position corresponding to the point (@x, @y) on the toolbar.
2948 gtk_toolbar_get_drop_index (GtkToolbar *toolbar,
2952 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2954 if (!gtk_toolbar_check_new_api (toolbar))
2957 return physical_to_logical (toolbar, find_drop_index (toolbar, x, y));
2961 * gtk_toolbar_append_item:
2962 * @toolbar: a #GtkToolbar.
2963 * @text: give your toolbar button a label.
2964 * @tooltip_text: a string that appears when the user holds the mouse over this item.
2965 * @tooltip_private_text: use with #GtkTipsQuery.
2966 * @icon: a #GtkWidget that should be used as the button's icon.
2967 * @callback: the function to be executed when the button is pressed.
2968 * @user_data: a pointer to any data you wish to be passed to the callback.
2970 * Inserts a new item into the toolbar. You must specify the position
2971 * in the toolbar where it will be inserted.
2973 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
2974 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
2976 * Return value: the new toolbar item as a #GtkWidget.
2979 gtk_toolbar_append_item (GtkToolbar *toolbar,
2981 const char *tooltip_text,
2982 const char *tooltip_private_text,
2984 GtkSignalFunc callback,
2987 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
2989 tooltip_text, tooltip_private_text,
2990 icon, callback, user_data,
2991 toolbar->num_children);
2995 * gtk_toolbar_prepend_item:
2996 * @toolbar: a #GtkToolbar.
2997 * @text: give your toolbar button a label.
2998 * @tooltip_text: a string that appears when the user holds the mouse over this item.
2999 * @tooltip_private_text: use with #GtkTipsQuery.
3000 * @icon: a #GtkWidget that should be used as the button's icon.
3001 * @callback: the function to be executed when the button is pressed.
3002 * @user_data: a pointer to any data you wish to be passed to the callback.
3004 * Adds a new button to the beginning (top or left edges) of the given toolbar.
3006 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3007 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3009 * Return value: the new toolbar item as a #GtkWidget.
3012 gtk_toolbar_prepend_item (GtkToolbar *toolbar,
3014 const char *tooltip_text,
3015 const char *tooltip_private_text,
3017 GtkSignalFunc callback,
3020 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3022 tooltip_text, tooltip_private_text,
3023 icon, callback, user_data,
3028 * gtk_toolbar_insert_item:
3029 * @toolbar: a #GtkToolbar.
3030 * @text: give your toolbar button a label.
3031 * @tooltip_text: a string that appears when the user holds the mouse over this item.
3032 * @tooltip_private_text: use with #GtkTipsQuery.
3033 * @icon: a #GtkWidget that should be used as the button's icon.
3034 * @callback: the function to be executed when the button is pressed.
3035 * @user_data: a pointer to any data you wish to be passed to the callback.
3036 * @position: the number of widgets to insert this item after.
3038 * Inserts a new item into the toolbar. You must specify the position in the
3039 * toolbar where it will be inserted.
3041 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3042 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3044 * Return value: the new toolbar item as a #GtkWidget.
3047 gtk_toolbar_insert_item (GtkToolbar *toolbar,
3049 const char *tooltip_text,
3050 const char *tooltip_private_text,
3052 GtkSignalFunc callback,
3056 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3058 tooltip_text, tooltip_private_text,
3059 icon, callback, user_data,
3064 * gtk_toolbar_insert_stock:
3065 * @toolbar: A #GtkToolbar
3066 * @stock_id: The id of the stock item you want to insert
3067 * @tooltip_text: The text in the tooltip of the toolbar button
3068 * @tooltip_private_text: The private text of the tooltip
3069 * @callback: The callback called when the toolbar button is clicked.
3070 * @user_data: user data passed to callback
3071 * @position: The position the button shall be inserted at.
3072 * -1 means at the end.
3074 * Inserts a stock item at the specified position of the toolbar. If
3075 * @stock_id is not a known stock item ID, it's inserted verbatim,
3076 * except that underscores used to mark mnemonics are removed.
3078 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3079 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3081 * Returns: the inserted widget
3084 gtk_toolbar_insert_stock (GtkToolbar *toolbar,
3085 const gchar *stock_id,
3086 const char *tooltip_text,
3087 const char *tooltip_private_text,
3088 GtkSignalFunc callback,
3092 return gtk_toolbar_internal_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3094 tooltip_text, tooltip_private_text,
3095 NULL, callback, user_data,
3100 * gtk_toolbar_append_space:
3101 * @toolbar: a #GtkToolbar.
3103 * Adds a new space to the end of the toolbar.
3106 gtk_toolbar_append_space (GtkToolbar *toolbar)
3108 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
3112 toolbar->num_children);
3116 * gtk_toolbar_prepend_space:
3117 * @toolbar: a #GtkToolbar.
3119 * Adds a new space to the beginning of the toolbar.
3122 gtk_toolbar_prepend_space (GtkToolbar *toolbar)
3124 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
3132 * gtk_toolbar_insert_space:
3133 * @toolbar: a #GtkToolbar
3134 * @position: the number of widgets after which a space should be inserted.
3136 * Inserts a new space in the toolbar at the specified position.
3139 gtk_toolbar_insert_space (GtkToolbar *toolbar,
3142 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
3150 * gtk_toolbar_remove_space:
3151 * @toolbar: a #GtkToolbar.
3152 * @position: the index of the space to remove.
3154 * Removes a space from the specified position.
3157 gtk_toolbar_remove_space (GtkToolbar *toolbar,
3162 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
3164 if (!gtk_toolbar_check_old_api (toolbar))
3167 item = g_list_nth_data (toolbar->children, position);
3171 g_warning ("Toolbar position %d doesn't exist", position);
3175 if (!GTK_IS_SEPARATOR_TOOL_ITEM (item))
3177 g_warning ("Toolbar position %d is not a space", position);
3181 gtk_toolbar_remove_tool_item (toolbar, item);
3185 * gtk_toolbar_append_widget:
3186 * @toolbar: a #GtkToolbar.
3187 * @widget: a #GtkWidget to add to the toolbar.
3188 * @tooltip_text: the element's tooltip.
3189 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3191 * Adds a widget to the end of the given toolbar.
3194 gtk_toolbar_append_widget (GtkToolbar *toolbar,
3196 const gchar *tooltip_text,
3197 const gchar *tooltip_private_text)
3199 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
3201 tooltip_text, tooltip_private_text,
3203 toolbar->num_children);
3207 * gtk_toolbar_prepend_widget:
3208 * @toolbar: a #GtkToolbar.
3209 * @widget: a #GtkWidget to add to the toolbar.
3210 * @tooltip_text: the element's tooltip.
3211 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3213 * Adds a widget to the beginning of the given toolbar.
3216 gtk_toolbar_prepend_widget (GtkToolbar *toolbar,
3218 const gchar *tooltip_text,
3219 const gchar *tooltip_private_text)
3221 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
3223 tooltip_text, tooltip_private_text,
3229 * gtk_toolbar_insert_widget:
3230 * @toolbar: a #GtkToolbar.
3231 * @widget: a #GtkWidget to add to the toolbar.
3232 * @tooltip_text: the element's tooltip.
3233 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3234 * @position: the number of widgets to insert this widget after.
3236 * Inserts a widget in the toolbar at the given position.
3239 gtk_toolbar_insert_widget (GtkToolbar *toolbar,
3241 const char *tooltip_text,
3242 const char *tooltip_private_text,
3245 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
3247 tooltip_text, tooltip_private_text,
3253 * gtk_toolbar_append_element:
3254 * @toolbar: a #GtkToolbar.
3255 * @type: a value of type #GtkToolbarChildType that determines what @widget will be.
3256 * @widget: a #GtkWidget, or %NULL.
3257 * @text: the element's label.
3258 * @tooltip_text: the element's tooltip.
3259 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3260 * @icon: a #GtkWidget that provides pictorial representation of the element's function.
3261 * @callback: the function to be executed when the button is pressed.
3262 * @user_data: any data you wish to pass to the callback.
3264 * Adds a new element to the end of a toolbar.
3266 * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element.
3267 * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine
3268 * the radio group for the new element. In all other cases, @widget must
3271 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3272 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3274 * Return value: the new toolbar element as a #GtkWidget.
3277 gtk_toolbar_append_element (GtkToolbar *toolbar,
3278 GtkToolbarChildType type,
3281 const char *tooltip_text,
3282 const char *tooltip_private_text,
3284 GtkSignalFunc callback,
3287 return gtk_toolbar_insert_element (toolbar, type, widget, text,
3288 tooltip_text, tooltip_private_text,
3289 icon, callback, user_data,
3290 toolbar->num_children);
3294 * gtk_toolbar_prepend_element:
3295 * @toolbar: a #GtkToolbar.
3296 * @type: a value of type #GtkToolbarChildType that determines what @widget will be.
3297 * @widget: a #GtkWidget, or %NULL
3298 * @text: the element's label.
3299 * @tooltip_text: the element's tooltip.
3300 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3301 * @icon: a #GtkWidget that provides pictorial representation of the element's function.
3302 * @callback: the function to be executed when the button is pressed.
3303 * @user_data: any data you wish to pass to the callback.
3305 * Adds a new element to the beginning of a toolbar.
3307 * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element.
3308 * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine
3309 * the radio group for the new element. In all other cases, @widget must
3312 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3313 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3315 * Return value: the new toolbar element as a #GtkWidget.
3318 gtk_toolbar_prepend_element (GtkToolbar *toolbar,
3319 GtkToolbarChildType type,
3322 const char *tooltip_text,
3323 const char *tooltip_private_text,
3325 GtkSignalFunc callback,
3328 return gtk_toolbar_insert_element (toolbar, type, widget, text,
3329 tooltip_text, tooltip_private_text,
3330 icon, callback, user_data, 0);
3334 * gtk_toolbar_insert_element:
3335 * @toolbar: a #GtkToolbar.
3336 * @type: a value of type #GtkToolbarChildType that determines what @widget
3338 * @widget: a #GtkWidget, or %NULL.
3339 * @text: the element's label.
3340 * @tooltip_text: the element's tooltip.
3341 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3342 * @icon: a #GtkWidget that provides pictorial representation of the element's function.
3343 * @callback: the function to be executed when the button is pressed.
3344 * @user_data: any data you wish to pass to the callback.
3345 * @position: the number of widgets to insert this element after.
3347 * Inserts a new element in the toolbar at the given position.
3349 * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element.
3350 * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine
3351 * the radio group for the new element. In all other cases, @widget must
3354 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3355 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3357 * Return value: the new toolbar element as a #GtkWidget.
3360 gtk_toolbar_insert_element (GtkToolbar *toolbar,
3361 GtkToolbarChildType type,
3364 const char *tooltip_text,
3365 const char *tooltip_private_text,
3367 GtkSignalFunc callback,
3371 return gtk_toolbar_internal_insert_element (toolbar, type, widget, text,
3372 tooltip_text, tooltip_private_text,
3373 icon, callback, user_data, position, FALSE);
3377 _gtk_toolbar_elide_underscores (const gchar *original)
3381 gboolean last_underscore;
3383 q = result = g_malloc (strlen (original) + 1);
3384 last_underscore = FALSE;
3386 for (p = original; *p; p++)
3388 if (!last_underscore && *p == '_')
3389 last_underscore = TRUE;
3392 last_underscore = FALSE;
3403 gtk_toolbar_internal_insert_element (GtkToolbar *toolbar,
3404 GtkToolbarChildType type,
3407 const char *tooltip_text,
3408 const char *tooltip_private_text,
3410 GtkSignalFunc callback,
3415 GtkToolbarChild *child;
3416 GtkToolItem *item = NULL;
3418 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
3420 if (!gtk_toolbar_check_old_api (toolbar))
3423 if (type == GTK_TOOLBAR_CHILD_WIDGET)
3424 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3425 else if (type != GTK_TOOLBAR_CHILD_RADIOBUTTON)
3426 g_return_val_if_fail (widget == NULL, NULL);
3428 child = g_new (GtkToolbarChild, 1);
3432 child->label = NULL;
3436 case GTK_TOOLBAR_CHILD_SPACE:
3437 item = gtk_separator_tool_item_new ();
3438 child->widget = NULL;
3441 case GTK_TOOLBAR_CHILD_WIDGET:
3442 item = gtk_tool_item_new ();
3443 child->widget = widget;
3444 gtk_container_add (GTK_CONTAINER (item), child->widget);
3447 case GTK_TOOLBAR_CHILD_BUTTON:
3448 item = gtk_tool_button_new (NULL, NULL);
3449 child->widget = _gtk_tool_button_get_button (GTK_TOOL_BUTTON (item));
3452 case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
3453 item = gtk_toggle_tool_button_new ();
3454 child->widget = _gtk_tool_button_get_button (GTK_TOOL_BUTTON (item));
3457 case GTK_TOOLBAR_CHILD_RADIOBUTTON:
3458 item = gtk_radio_tool_button_new (widget
3459 ? gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget))
3461 child->widget = _gtk_tool_button_get_button (GTK_TOOL_BUTTON (item));
3466 * When we are using the old API, consider all items "is_important". That
3467 * way BOTH_HORIZ will continue to show both icon and label in old API mode
3469 gtk_tool_item_set_is_important (item, TRUE);
3471 gtk_widget_show (GTK_WIDGET (item));
3473 if (type == GTK_TOOLBAR_CHILD_BUTTON ||
3474 type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
3475 type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
3481 GtkStockItem stock_item;
3484 gtk_tool_button_set_stock_id (GTK_TOOL_BUTTON (item), text);
3486 gtk_stock_lookup (text, &stock_item);
3487 label_text = _gtk_toolbar_elide_underscores (stock_item.label);
3488 child->label = GTK_WIDGET (gtk_label_new (label_text));
3489 g_free (label_text);
3493 child->label = gtk_label_new (text);
3495 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (item), child->label);
3496 gtk_widget_show (child->label);
3502 gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (item), icon);
3504 /* Applications depend on the toolbar showing the widget for them */
3505 gtk_widget_show (GTK_WIDGET (icon));
3509 * We need to connect to the button's clicked callback because some
3510 * programs may rely on that the widget in the callback is a GtkButton
3513 g_signal_connect (child->widget, "clicked",
3514 callback, user_data);
3517 if ((type != GTK_TOOLBAR_CHILD_SPACE) && tooltip_text)
3518 gtk_tool_item_set_tooltip (item, toolbar->tooltips,
3519 tooltip_text, tooltip_private_text);
3521 toolbar->children = g_list_insert (toolbar->children, child, position);
3523 gtk_toolbar_insert_tool_item (toolbar, item, position, FALSE);
3525 return child->widget;
3529 gtk_toolbar_finalize (GObject *object)
3532 GtkToolbar *toolbar = GTK_TOOLBAR (object);
3533 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3535 if (toolbar->tooltips)
3536 g_object_unref (toolbar->tooltips);
3538 for (list = toolbar->children; list != NULL; list = list->next)
3539 g_free (list->data);
3541 g_list_free (toolbar->children);
3543 for (list = priv->content; list != NULL; list = list->next)
3544 g_free (list->data);
3546 g_list_free (priv->content);
3548 g_timer_destroy (priv->timer);
3551 g_source_remove (priv->idle_id);
3553 G_OBJECT_CLASS (parent_class)->finalize (object);