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@gnome.org>
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);
185 static gboolean gtk_toolbar_check_new_api (GtkToolbar *toolbar);
193 #define GTK_TOOLBAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_TOOLBAR, GtkToolbarPrivate))
202 struct _ToolbarContent
205 guint is_placeholder : 1;
206 guint disappearing : 1;
207 GtkAllocation start_allocation;
208 GtkAllocation goal_allocation;
212 struct _GtkToolbarPrivate
217 GtkWidget * arrow_button;
223 GdkWindow * event_window;
225 GtkSettings * settings;
228 GtkToolItem * highlight_tool_item;
229 gint max_homogeneous_pixels;
235 static GtkContainerClass *parent_class = NULL;
236 static guint toolbar_signals [LAST_SIGNAL] = { 0 };
239 gtk_toolbar_get_type (void)
241 static GtkType type = 0;
245 static const GTypeInfo type_info =
247 sizeof (GtkToolbarClass),
248 (GBaseInitFunc) NULL,
249 (GBaseFinalizeFunc) NULL,
250 (GClassInitFunc) gtk_toolbar_class_init,
251 (GClassFinalizeFunc) NULL,
255 (GInstanceInitFunc) gtk_toolbar_init,
258 type = g_type_register_static (GTK_TYPE_CONTAINER,
267 add_arrow_bindings (GtkBindingSet *binding_set,
269 GtkDirectionType dir)
271 guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
273 gtk_binding_entry_add_signal (binding_set, keysym, 0,
275 GTK_TYPE_DIRECTION_TYPE, dir);
276 gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
278 GTK_TYPE_DIRECTION_TYPE, dir);
282 add_ctrl_tab_bindings (GtkBindingSet *binding_set,
283 GdkModifierType modifiers,
284 GtkDirectionType direction)
286 gtk_binding_entry_add_signal (binding_set,
287 GDK_Tab, GDK_CONTROL_MASK | modifiers,
289 GTK_TYPE_DIRECTION_TYPE, direction);
290 gtk_binding_entry_add_signal (binding_set,
291 GDK_KP_Tab, GDK_CONTROL_MASK | modifiers,
293 GTK_TYPE_DIRECTION_TYPE, direction);
297 gtk_toolbar_class_init (GtkToolbarClass *klass)
299 GObjectClass *gobject_class;
300 GtkWidgetClass *widget_class;
301 GtkContainerClass *container_class;
302 GtkBindingSet *binding_set;
304 parent_class = g_type_class_peek_parent (klass);
306 gobject_class = (GObjectClass *)klass;
307 widget_class = (GtkWidgetClass *)klass;
308 container_class = (GtkContainerClass *)klass;
310 gobject_class->set_property = gtk_toolbar_set_property;
311 gobject_class->get_property = gtk_toolbar_get_property;
312 gobject_class->finalize = gtk_toolbar_finalize;
314 widget_class->button_press_event = gtk_toolbar_button_press;
315 widget_class->expose_event = gtk_toolbar_expose;
316 widget_class->size_request = gtk_toolbar_size_request;
317 widget_class->size_allocate = gtk_toolbar_size_allocate;
318 widget_class->style_set = gtk_toolbar_style_set;
319 widget_class->direction_changed = gtk_toolbar_direction_changed;
320 widget_class->focus = gtk_toolbar_focus;
321 widget_class->screen_changed = gtk_toolbar_screen_changed;
322 widget_class->realize = gtk_toolbar_realize;
323 widget_class->unrealize = gtk_toolbar_unrealize;
324 widget_class->map = gtk_toolbar_map;
325 widget_class->unmap = gtk_toolbar_unmap;
326 widget_class->popup_menu = gtk_toolbar_popup_menu;
328 container_class->add = gtk_toolbar_add;
329 container_class->remove = gtk_toolbar_remove;
330 container_class->forall = gtk_toolbar_forall;
331 container_class->child_type = gtk_toolbar_child_type;
332 container_class->get_child_property = gtk_toolbar_get_child_property;
333 container_class->set_child_property = gtk_toolbar_set_child_property;
335 klass->orientation_changed = gtk_toolbar_real_orientation_changed;
336 klass->style_changed = gtk_toolbar_real_style_changed;
339 * GtkToolbar::orientation-changed:
340 * @toolbar: the object which emitted the signal
341 * @orientation: the new #GtkOrientation of the toolbar
343 * Emitted when the orientation of the toolbar changes.
345 toolbar_signals[ORIENTATION_CHANGED] =
346 g_signal_new ("orientation-changed",
347 G_OBJECT_CLASS_TYPE (klass),
349 G_STRUCT_OFFSET (GtkToolbarClass, orientation_changed),
351 g_cclosure_marshal_VOID__ENUM,
353 GTK_TYPE_ORIENTATION);
355 * GtkToolbar::style-changed:
356 * @toolbar: The #GtkToolbar which emitted the signal
357 * @style: the new #GtkToolbarStyle of the toolbar
359 * Emitted when the style of the toolbar changes.
361 toolbar_signals[STYLE_CHANGED] =
362 g_signal_new ("style-changed",
363 G_OBJECT_CLASS_TYPE (klass),
365 G_STRUCT_OFFSET (GtkToolbarClass, style_changed),
367 g_cclosure_marshal_VOID__ENUM,
369 GTK_TYPE_TOOLBAR_STYLE);
371 * GtkToolbar::popup-context-menu:
372 * @toolbar: the #GtkToolbar which emitted the signal
373 * @x: the x coordinate of the point where the menu should appear
374 * @y: the y coordinate of the point where the menu should appear
375 * @button: the mouse button the user pressed, or -1
377 * Emitted when the user right-clicks the toolbar or uses the
378 * keybinding to display a popup menu.
380 * Application developers should handle this signal if they want
381 * to display a context menu on the toolbar. The context-menu should
382 * appear at the coordinates given by @x and @y. The mouse button
383 * number is given by the @button parameter. If the menu was popped
384 * up using the keybaord, @button is -1.
386 * Return value: return %TRUE if the signal was handled, %FALSE if not
388 toolbar_signals[POPUP_CONTEXT_MENU] =
389 g_signal_new ("popup_context_menu",
390 G_OBJECT_CLASS_TYPE (klass),
392 G_STRUCT_OFFSET (GtkToolbarClass, popup_context_menu),
393 _gtk_boolean_handled_accumulator, NULL,
394 _gtk_marshal_BOOLEAN__INT_INT_INT,
396 G_TYPE_INT, G_TYPE_INT,
399 * GtkToolbar::move-focus:
400 * @toolbar: the #GtkToolbar which emitted the signal
401 * @dir: a #GtkDirection
403 * A keybinding signal used internally by GTK+. This signal can't
404 * be used in application code.
406 * Return value: %TRUE if the signal was handled, %FALSE if not
408 toolbar_signals[MOVE_FOCUS] =
409 _gtk_binding_signal_new ("move_focus",
410 G_TYPE_FROM_CLASS (klass),
411 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
412 G_CALLBACK (gtk_toolbar_move_focus),
414 _gtk_marshal_BOOLEAN__ENUM,
416 GTK_TYPE_DIRECTION_TYPE);
418 * GtkToolbar::focus-home-or-end:
419 * @toolbar: the #GtkToolbar which emitted the signal
420 * @focus_home: %TRUE if the first item should be focused
422 * A keybinding signal used internally by GTK+. This signal can't
423 * be used in application code
425 * Return value: %TRUE if the signal was handled, %FALSE if not
427 toolbar_signals[FOCUS_HOME_OR_END] =
428 _gtk_binding_signal_new ("focus_home_or_end",
429 G_OBJECT_CLASS_TYPE (klass),
430 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
431 G_CALLBACK (gtk_toolbar_focus_home_or_end),
433 _gtk_marshal_BOOLEAN__BOOLEAN,
438 g_object_class_install_property (gobject_class,
440 g_param_spec_enum ("orientation",
442 P_("The orientation of the toolbar"),
443 GTK_TYPE_ORIENTATION,
444 GTK_ORIENTATION_HORIZONTAL,
447 g_object_class_install_property (gobject_class,
449 g_param_spec_enum ("toolbar_style",
451 P_("How to draw the toolbar"),
452 GTK_TYPE_TOOLBAR_STYLE,
455 g_object_class_install_property (gobject_class,
457 g_param_spec_boolean ("show_arrow",
459 P_("If an arrow should be shown if the toolbar doesn't fit"),
463 /* child properties */
464 gtk_container_class_install_child_property (container_class,
466 g_param_spec_boolean ("expand",
468 P_("Whether the item should receive extra space when the toolbar grows"),
472 gtk_container_class_install_child_property (container_class,
473 CHILD_PROP_HOMOGENEOUS,
474 g_param_spec_boolean ("homogeneous",
476 P_("Whether the item should be the same size as other homogeneous items"),
480 /* style properties */
481 gtk_widget_class_install_style_property (widget_class,
482 g_param_spec_int ("space_size",
484 P_("Size of spacers"),
490 gtk_widget_class_install_style_property (widget_class,
491 g_param_spec_int ("internal_padding",
492 P_("Internal padding"),
493 P_("Amount of border space between the toolbar shadow and the buttons"),
499 gtk_widget_class_install_style_property (widget_class,
500 g_param_spec_enum ("space_style",
502 P_("Whether spacers are vertical lines or just blank"),
503 GTK_TYPE_TOOLBAR_SPACE_STYLE,
507 gtk_widget_class_install_style_property (widget_class,
508 g_param_spec_enum ("button_relief",
510 P_("Type of bevel around toolbar buttons"),
511 GTK_TYPE_RELIEF_STYLE,
514 gtk_widget_class_install_style_property (widget_class,
515 g_param_spec_enum ("shadow_type",
517 P_("Style of bevel around the toolbar"),
518 GTK_TYPE_SHADOW_TYPE,
522 gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-style",
524 P_("Whether default toolbars have text only, text and icons, icons only, etc."),
525 GTK_TYPE_TOOLBAR_STYLE,
526 DEFAULT_TOOLBAR_STYLE,
529 gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-icon-size",
530 P_("Toolbar icon size"),
531 P_("Size of icons in default toolbars"),
536 binding_set = gtk_binding_set_by_class (klass);
538 add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
539 add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
540 add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
541 add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
543 gtk_binding_entry_add_signal (binding_set, GDK_KP_Home, 0,
544 "focus_home_or_end", 1,
545 G_TYPE_BOOLEAN, TRUE);
546 gtk_binding_entry_add_signal (binding_set, GDK_Home, 0,
547 "focus_home_or_end", 1,
548 G_TYPE_BOOLEAN, TRUE);
549 gtk_binding_entry_add_signal (binding_set, GDK_KP_End, 0,
550 "focus_home_or_end", 1,
551 G_TYPE_BOOLEAN, FALSE);
552 gtk_binding_entry_add_signal (binding_set, GDK_End, 0,
553 "focus_home_or_end", 1,
554 G_TYPE_BOOLEAN, FALSE);
556 add_ctrl_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
557 add_ctrl_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
559 g_type_class_add_private (gobject_class, sizeof (GtkToolbarPrivate));
563 gtk_toolbar_init (GtkToolbar *toolbar)
565 GtkToolbarPrivate *priv;
567 GTK_WIDGET_UNSET_FLAGS (toolbar, GTK_CAN_FOCUS);
568 GTK_WIDGET_SET_FLAGS (toolbar, GTK_NO_WINDOW);
570 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
572 toolbar->orientation = GTK_ORIENTATION_HORIZONTAL;
573 toolbar->style = DEFAULT_TOOLBAR_STYLE;
574 toolbar->icon_size = DEFAULT_ICON_SIZE;
575 toolbar->tooltips = gtk_tooltips_new ();
576 g_object_ref (toolbar->tooltips);
577 gtk_object_sink (GTK_OBJECT (toolbar->tooltips));
579 priv->arrow_button = gtk_toggle_button_new ();
580 g_signal_connect (priv->arrow_button, "button_press_event",
581 G_CALLBACK (gtk_toolbar_arrow_button_press), toolbar);
582 g_signal_connect (priv->arrow_button, "clicked",
583 G_CALLBACK (gtk_toolbar_arrow_button_clicked), toolbar);
584 gtk_button_set_relief (GTK_BUTTON (priv->arrow_button),
585 get_button_relief (toolbar));
587 priv->api_mode = DONT_KNOW;
589 gtk_button_set_focus_on_click (GTK_BUTTON (priv->arrow_button), FALSE);
591 priv->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
592 gtk_widget_set_name (priv->arrow, "gtk-toolbar-arrow");
593 gtk_widget_show (priv->arrow);
594 gtk_container_add (GTK_CONTAINER (priv->arrow_button), priv->arrow);
596 gtk_widget_set_parent (priv->arrow_button, GTK_WIDGET (toolbar));
598 /* which child position a drop will occur at */
600 priv->show_arrow = TRUE;
601 priv->settings = NULL;
603 priv->max_homogeneous_pixels = -1;
605 priv->timer = g_timer_new ();
609 toolbar_item_visible (GtkToolbar *toolbar,
612 if (GTK_WIDGET_VISIBLE (item) &&
613 ((toolbar->orientation == GTK_ORIENTATION_HORIZONTAL &&
614 gtk_tool_item_get_visible_horizontal (item)) ||
615 (toolbar->orientation == GTK_ORIENTATION_VERTICAL &&
616 gtk_tool_item_get_visible_vertical (item))))
618 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
620 /* With the old toolbar you could hide a button by calling gtk_widget_hide()
621 * on it. This doesn't work with the new API because the GtkToolItem will not be
624 if (priv->api_mode == OLD_API)
626 GtkWidget *bin_child = GTK_BIN (item)->child;
628 if (bin_child && !GTK_WIDGET_VISIBLE (bin_child))
639 calculate_max_homogeneous_pixels (GtkWidget *widget)
641 PangoContext *context;
642 PangoFontMetrics *metrics;
645 context = gtk_widget_get_pango_context (widget);
646 metrics = pango_context_get_metrics (context,
647 widget->style->font_desc,
648 pango_context_get_language (context));
649 char_width = pango_font_metrics_get_approximate_char_width (metrics);
650 pango_font_metrics_unref (metrics);
652 return PANGO_PIXELS (MAX_HOMOGENEOUS_N_CHARS * char_width);
656 toolbar_item_is_homogeneous (GtkToolbar *toolbar,
660 GtkRequisition requisition;
661 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
663 if (priv->max_homogeneous_pixels < 0)
665 priv->max_homogeneous_pixels =
666 calculate_max_homogeneous_pixels (GTK_WIDGET (toolbar));
669 result = gtk_tool_item_get_homogeneous (item) &&
670 !GTK_IS_SEPARATOR_TOOL_ITEM (item);
672 gtk_widget_size_request (GTK_WIDGET (item), &requisition);
674 if ((gtk_tool_item_get_is_important (item) &&
675 toolbar->style == GTK_TOOLBAR_BOTH_HORIZ &&
676 toolbar->orientation == GTK_ORIENTATION_HORIZONTAL) ||
677 requisition.width > priv->max_homogeneous_pixels)
686 gtk_toolbar_set_property (GObject *object,
691 GtkToolbar *toolbar = GTK_TOOLBAR (object);
695 case PROP_ORIENTATION:
696 gtk_toolbar_set_orientation (toolbar, g_value_get_enum (value));
698 case PROP_TOOLBAR_STYLE:
699 gtk_toolbar_set_style (toolbar, g_value_get_enum (value));
701 case PROP_SHOW_ARROW:
702 gtk_toolbar_set_show_arrow (toolbar, g_value_get_boolean (value));
705 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
711 gtk_toolbar_get_property (GObject *object,
716 GtkToolbar *toolbar = GTK_TOOLBAR (object);
717 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
721 case PROP_ORIENTATION:
722 g_value_set_enum (value, toolbar->orientation);
724 case PROP_TOOLBAR_STYLE:
725 g_value_set_enum (value, toolbar->style);
727 case PROP_SHOW_ARROW:
728 g_value_set_boolean (value, priv->show_arrow);
731 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
737 gtk_toolbar_map (GtkWidget *widget)
739 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
741 GTK_WIDGET_CLASS (parent_class)->map (widget);
743 if (priv->event_window)
744 gdk_window_show_unraised (priv->event_window);
748 gtk_toolbar_unmap (GtkWidget *widget)
750 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
752 if (priv->event_window)
753 gdk_window_hide (priv->event_window);
755 GTK_WIDGET_CLASS (parent_class)->unmap (widget);
759 gtk_toolbar_realize (GtkWidget *widget)
761 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
762 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
764 GdkWindowAttr attributes;
765 gint attributes_mask;
768 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
770 border_width = GTK_CONTAINER (widget)->border_width;
772 attributes.wclass = GDK_INPUT_ONLY;
773 attributes.window_type = GDK_WINDOW_CHILD;
774 attributes.x = widget->allocation.x + border_width;
775 attributes.y = widget->allocation.y + border_width;
776 attributes.width = widget->allocation.width - border_width * 2;
777 attributes.height = widget->allocation.height - border_width * 2;
778 attributes.event_mask = gtk_widget_get_events (widget);
779 attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
780 GDK_BUTTON_RELEASE_MASK |
781 GDK_ENTER_NOTIFY_MASK |
782 GDK_LEAVE_NOTIFY_MASK);
784 attributes_mask = GDK_WA_X | GDK_WA_Y;
786 widget->window = gtk_widget_get_parent_window (widget);
787 g_object_ref (widget->window);
788 widget->style = gtk_style_attach (widget->style, widget->window);
790 priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget),
791 &attributes, attributes_mask);
792 gdk_window_set_user_data (priv->event_window, toolbar);
796 gtk_toolbar_unrealize (GtkWidget *widget)
798 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
800 if (priv->event_window)
802 gdk_window_set_user_data (priv->event_window, NULL);
803 gdk_window_destroy (priv->event_window);
804 priv->event_window = NULL;
807 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
808 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
812 gtk_toolbar_expose (GtkWidget *widget,
813 GdkEventExpose *event)
815 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
816 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
821 border_width = GTK_CONTAINER (widget)->border_width;
823 if (GTK_WIDGET_DRAWABLE (widget))
825 gtk_paint_box (widget->style,
827 GTK_WIDGET_STATE (widget),
828 get_shadow_type (toolbar),
829 &event->area, widget, "toolbar",
830 border_width + widget->allocation.x,
831 border_width + widget->allocation.y,
832 widget->allocation.width - 2 * border_width,
833 widget->allocation.height - 2 * border_width);
836 for (list = priv->content; list != NULL; list = list->next)
838 ToolbarContent *content = list->data;
839 GtkToolItem *item = content->item;
841 if (!content->is_placeholder)
842 gtk_container_propagate_expose (GTK_CONTAINER (widget),
847 gtk_container_propagate_expose (GTK_CONTAINER (widget),
855 gtk_toolbar_size_request (GtkWidget *widget,
856 GtkRequisition *requisition)
858 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
859 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
861 gint max_child_height;
862 gint max_child_width;
863 gint max_homogeneous_child_width;
864 gint max_homogeneous_child_height;
865 gint homogeneous_size;
867 gint pack_front_size;
869 GtkRequisition arrow_requisition;
871 max_homogeneous_child_width = 0;
872 max_homogeneous_child_height = 0;
874 max_child_height = 0;
875 for (list = priv->content; list != NULL; list = list->next)
877 GtkRequisition requisition;
878 ToolbarContent *content = list->data;
879 GtkToolItem *item = content->item;
881 if (!toolbar_item_visible (toolbar, item))
884 gtk_widget_size_request (GTK_WIDGET (item), &requisition);
886 max_child_width = MAX (max_child_width, requisition.width);
887 max_child_height = MAX (max_child_height, requisition.height);
889 if (toolbar_item_is_homogeneous (toolbar, item))
891 max_homogeneous_child_width = MAX (max_homogeneous_child_width, requisition.width);
892 max_homogeneous_child_height = MAX (max_homogeneous_child_height, requisition.height);
896 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
897 homogeneous_size = max_homogeneous_child_width;
899 homogeneous_size = max_homogeneous_child_height;
902 for (list = priv->content; list != NULL; list = list->next)
904 ToolbarContent *content = list->data;
905 GtkToolItem *item = content->item;
908 if (!toolbar_item_visible (toolbar, item))
911 if (toolbar_item_is_homogeneous (toolbar, item))
913 size = homogeneous_size;
917 GtkRequisition requisition;
919 gtk_widget_size_request (GTK_WIDGET (item), &requisition);
921 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
922 size = requisition.width;
924 size = requisition.height;
927 pack_front_size += size;
930 if (priv->show_arrow && priv->api_mode == NEW_API)
932 gtk_widget_size_request (priv->arrow_button, &arrow_requisition);
934 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
935 long_req = arrow_requisition.width;
937 long_req = arrow_requisition.height;
939 /* There is no point requesting space for the arrow if that would take
940 * up more space than all the items combined
942 long_req = MIN (long_req, pack_front_size);
946 arrow_requisition.height = 0;
947 arrow_requisition.width = 0;
949 long_req = pack_front_size;
952 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
954 requisition->width = long_req;
955 requisition->height = MAX (max_child_height, arrow_requisition.height);
959 requisition->height = long_req;
960 requisition->width = MAX (max_child_width, arrow_requisition.width);
964 ipadding = get_internal_padding (toolbar);
966 requisition->width += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width);
967 requisition->height += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width);
969 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
971 requisition->width += 2 * widget->style->xthickness;
972 requisition->height += 2 * widget->style->ythickness;
975 toolbar->button_maxw = max_homogeneous_child_width;
976 toolbar->button_maxh = max_homogeneous_child_height;
979 #define SLIDE_SPEED 600 /* pixels per second */
982 position (gint from, gint to, gdouble elapsed)
985 return MIN (from + SLIDE_SPEED * elapsed, to);
987 return MAX (from - SLIDE_SPEED * elapsed, to);
991 compute_intermediate_allocation (GtkToolbar *toolbar,
992 const GtkAllocation *start,
993 const GtkAllocation *goal,
994 GtkAllocation *intermediate)
996 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
997 gdouble elapsed = g_timer_elapsed (priv->timer, NULL);
999 intermediate->x = position (start->x, goal->x, elapsed);
1000 intermediate->y = position (start->y, goal->y, elapsed);
1001 intermediate->width =
1002 position (start->x + start->width, goal->x + goal->width, elapsed) - intermediate->x;
1003 intermediate->height =
1004 position (start->y + start->height, goal->y + goal->height, elapsed) - intermediate->y;
1008 fixup_allocation_for_rtl (gint total_size,
1009 GtkAllocation *allocation)
1011 allocation->x += (total_size - (2 * allocation->x + allocation->width));
1015 fixup_allocation_for_vertical (GtkAllocation *allocation)
1019 tmp = allocation->x;
1020 allocation->x = allocation->y;
1021 allocation->y = tmp;
1023 tmp = allocation->width;
1024 allocation->width = allocation->height;
1025 allocation->height = tmp;
1029 get_item_size (GtkToolbar *toolbar,
1030 ToolbarContent *content)
1032 GtkRequisition requisition;
1033 GtkToolItem *item = content->item;
1035 gtk_widget_get_child_requisition (GTK_WIDGET (item), &requisition);
1037 if (content->is_placeholder && content->disappearing)
1041 else if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1043 if (toolbar_item_is_homogeneous (toolbar, item))
1044 return toolbar->button_maxw;
1046 return requisition.width;
1050 if (toolbar_item_is_homogeneous (toolbar, item))
1051 return toolbar->button_maxh;
1053 return requisition.height;
1058 slide_idle_handler (gpointer data)
1060 GtkToolbar *toolbar = data;
1061 GtkToolbarPrivate *priv;
1064 GDK_THREADS_ENTER ();
1066 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1068 if (priv->need_sync)
1071 priv->need_sync = FALSE;
1074 for (list = priv->content; list != NULL; list = list->next)
1076 ToolbarContent *content = list->data;
1077 GtkWidget *widget = GTK_WIDGET (content->item);
1079 if ((content->state == NOT_ALLOCATED) ||
1080 (content->state == NORMAL &&
1081 GTK_WIDGET_CHILD_VISIBLE (content->item) &&
1082 ((content->goal_allocation.x != widget->allocation.x ||
1083 content->goal_allocation.y != widget->allocation.y ||
1084 content->goal_allocation.width != widget->allocation.width ||
1085 content->goal_allocation.height != widget->allocation.height))) ||
1086 (content->is_placeholder && content->disappearing &&
1087 GTK_WIDGET_CHILD_VISIBLE (content->item)))
1089 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (toolbar));
1091 GDK_THREADS_LEAVE ();
1096 priv->is_sliding = FALSE;
1099 GDK_THREADS_LEAVE();
1104 rect_within (GtkAllocation *a1, GtkAllocation *a2)
1106 return (a1->x >= a2->x &&
1107 a1->x + a1->width <= a2->x + a2->width &&
1109 a1->y + a1->height <= a2->y + a2->height);
1113 gtk_toolbar_begin_sliding (GtkToolbar *toolbar)
1115 GtkWidget *widget = GTK_WIDGET (toolbar);
1116 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1124 /* Start the sliding. This function copies the allocation of every
1125 * item into content->start_allocation. For items that haven't
1126 * been allocated yet, we calculate their position and save that
1127 * in start_allocatino along with zero width and zero height.
1129 priv->is_sliding = TRUE;
1132 priv->idle_id = g_idle_add (slide_idle_handler, toolbar);
1134 rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
1135 vertical = (toolbar->orientation == GTK_ORIENTATION_VERTICAL);
1136 border_width = get_internal_padding (toolbar) + GTK_CONTAINER (toolbar)->border_width;
1140 cur_x = widget->allocation.width - border_width - widget->style->xthickness;
1141 cur_y = widget->allocation.height - border_width - widget->style->ythickness;
1145 cur_x = border_width + widget->style->xthickness;
1146 cur_y = border_width + widget->style->ythickness;
1149 cur_x += widget->allocation.x;
1150 cur_y += widget->allocation.y;
1152 for (list = priv->content; list != NULL; list = list->next)
1154 ToolbarContent *content = list->data;
1155 GtkWidget *item = GTK_WIDGET (content->item);
1156 GtkAllocation *alloc = &(content->start_allocation);
1158 if (content->state == NORMAL && rect_within (&(item->allocation), &(widget->allocation)))
1160 *alloc = item->allocation;
1169 alloc->width = widget->allocation.width -
1170 2 * border_width - 2 * widget->style->xthickness;
1176 alloc->height = widget->allocation.height -
1177 2 * border_width - 2 * widget->style->ythickness;
1182 cur_y = alloc->y + alloc->height;
1186 cur_x = alloc->x + alloc->width;
1189 g_timer_reset (priv->timer);
1193 gtk_toolbar_stop_sliding (GtkToolbar *toolbar)
1195 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1197 if (priv->is_sliding)
1201 priv->is_sliding = FALSE;
1205 g_source_remove (priv->idle_id);
1209 list = priv->content;
1212 ToolbarContent *content = list->data;
1215 if (content->is_placeholder)
1216 gtk_toolbar_remove_tool_item (toolbar, content->item);
1219 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (toolbar));
1224 gtk_toolbar_size_allocate (GtkWidget *widget,
1225 GtkAllocation *allocation)
1227 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1228 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1229 GtkAllocation *allocations;
1230 ItemState *new_states;
1231 GtkAllocation arrow_allocation;
1233 gint size, pos, short_size;
1236 gboolean need_arrow;
1237 gint n_expand_items;
1239 gint available_size;
1242 GtkRequisition arrow_requisition;
1243 gboolean overflowing;
1244 gboolean size_changed;
1247 size_changed = FALSE;
1248 if (widget->allocation.x != allocation->x ||
1249 widget->allocation.y != allocation->y ||
1250 widget->allocation.width != allocation->width ||
1251 widget->allocation.height != allocation->height)
1253 size_changed = TRUE;
1257 gtk_toolbar_stop_sliding (toolbar);
1259 widget->allocation = *allocation;
1261 border_width = GTK_CONTAINER (toolbar)->border_width;
1263 if (GTK_WIDGET_REALIZED (widget))
1265 gdk_window_move_resize (priv->event_window,
1266 allocation->x + border_width,
1267 allocation->y + border_width,
1268 allocation->width - border_width * 2,
1269 allocation->height - border_width * 2);
1272 border_width += get_internal_padding (toolbar);
1274 gtk_widget_get_child_requisition (GTK_WIDGET (priv->arrow_button),
1275 &arrow_requisition);
1277 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1279 available_size = size = allocation->width - 2 * border_width;
1280 short_size = allocation->height - 2 * border_width;
1281 arrow_size = arrow_requisition.width;
1283 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1285 available_size -= 2 * widget->style->xthickness;
1286 short_size -= 2 * widget->style->ythickness;
1291 available_size = size = allocation->height - 2 * border_width;
1292 short_size = allocation->width - 2 * border_width;
1293 arrow_size = arrow_requisition.height;
1295 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1297 available_size -= 2 * widget->style->ythickness;
1298 short_size -= 2 * widget->style->xthickness;
1302 n_items = g_list_length (priv->content);
1303 allocations = g_new0 (GtkAllocation, n_items);
1304 new_states = g_new0 (ItemState, n_items);
1307 for (list = priv->content; list != NULL; list = list->next)
1309 ToolbarContent *content = list->data;
1311 if (toolbar_item_visible (toolbar, content->item))
1312 needed_size += get_item_size (toolbar, content);
1315 need_arrow = (needed_size > available_size) && priv->show_arrow && priv->api_mode == NEW_API;
1318 size = available_size - arrow_size;
1320 size = available_size;
1322 /* calculate widths of items */
1323 overflowing = FALSE;
1324 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1326 ToolbarContent *content = list->data;
1327 GtkToolItem *item = content->item;
1330 if (!toolbar_item_visible (toolbar, item))
1332 new_states[i] = HIDDEN;
1336 item_size = get_item_size (toolbar, content);
1337 if (item_size <= size && !overflowing)
1340 allocations[i].width = item_size;
1341 new_states[i] = NORMAL;
1346 new_states[i] = OVERFLOWN;
1350 /* calculate width of arrow */
1353 arrow_allocation.width = arrow_size;
1354 arrow_allocation.height = short_size;
1357 /* expand expandable items */
1359 /* We don't expand when there is an overflow menu, because that leads to
1360 * weird jumps when items get moved to the overflow menu and the expanding
1361 * items suddenly get a lot of extra space
1366 for (i = 0, list = priv->content; list != NULL; list = list->next, ++i)
1368 ToolbarContent *content = list->data;
1369 GtkToolItem *item = content->item;
1371 if (gtk_tool_item_get_expand (item) && new_states[i] == NORMAL)
1375 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1377 ToolbarContent *content = list->data;
1378 GtkToolItem *item = content->item;
1380 if (gtk_tool_item_get_expand (item) && new_states[i] == NORMAL)
1382 gint extra = size / n_expand_items;
1383 if (size % n_expand_items != 0)
1386 allocations[i].width += extra;
1392 g_assert (n_expand_items == 0);
1395 /* position items */
1397 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1399 if (new_states[i] == NORMAL)
1401 allocations[i].x = pos;
1402 allocations[i].y = border_width;
1403 allocations[i].height = short_size;
1405 pos += allocations[i].width;
1409 /* position arrow */
1412 arrow_allocation.x = available_size - border_width - arrow_allocation.width;
1413 arrow_allocation.y = border_width;
1416 /* fix up allocations in the vertical or RTL cases */
1417 if (toolbar->orientation == GTK_ORIENTATION_VERTICAL)
1419 for (i = 0; i < n_items; ++i)
1420 fixup_allocation_for_vertical (&(allocations[i]));
1423 fixup_allocation_for_vertical (&arrow_allocation);
1425 else if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
1427 for (i = 0; i < n_items; ++i)
1428 fixup_allocation_for_rtl (available_size, &(allocations[i]));
1431 fixup_allocation_for_rtl (available_size, &arrow_allocation);
1434 /* translate the items by allocation->(x,y) */
1435 for (i = 0; i < n_items; ++i)
1437 allocations[i].x += allocation->x;
1438 allocations[i].y += allocation->y;
1440 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1442 allocations[i].x += widget->style->xthickness;
1443 allocations[i].y += widget->style->ythickness;
1449 arrow_allocation.x += allocation->x;
1450 arrow_allocation.y += allocation->y;
1452 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1454 arrow_allocation.x += widget->style->xthickness;
1455 arrow_allocation.y += widget->style->ythickness;
1459 /* did anything change? */
1460 for (list = priv->content, i = 0; list != NULL; list = list->next, i++)
1462 ToolbarContent *content = list->data;
1464 if (content->state == NORMAL && new_states[i] != NORMAL)
1466 /* an item disappeared, begin sliding */
1468 gtk_toolbar_begin_sliding (toolbar);
1472 /* finally allocate the items */
1473 for (list = priv->content, i = 0; list != NULL; list = list->next, i++)
1475 ToolbarContent *content = list->data;
1477 content->goal_allocation = allocations[i];
1480 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1482 ToolbarContent *content = list->data;
1483 GtkToolItem *item = content->item;
1485 if (new_states[i] != NORMAL)
1487 gtk_widget_set_child_visible (GTK_WIDGET (item), FALSE);
1491 GtkAllocation alloc;
1492 elapsed = g_timer_elapsed (priv->timer, NULL);
1494 if (priv->is_sliding)
1496 /* FIXME: we should use the same "elapsed" for all items */
1497 compute_intermediate_allocation (toolbar,
1498 &(content->start_allocation),
1499 &(content->goal_allocation),
1502 priv->need_sync = TRUE;
1506 alloc = allocations[i];
1509 if (alloc.width == 0 || alloc.height == 0)
1511 gtk_widget_set_child_visible (GTK_WIDGET (item), FALSE);
1515 gtk_widget_set_child_visible (GTK_WIDGET (item), TRUE);
1516 gtk_widget_size_allocate (GTK_WIDGET (item), &alloc);
1520 content->state = new_states[i];
1525 gtk_widget_size_allocate (GTK_WIDGET (priv->arrow_button),
1527 gtk_widget_show (GTK_WIDGET (priv->arrow_button));
1531 gtk_widget_hide (GTK_WIDGET (priv->arrow_button));
1534 g_free (allocations);
1535 g_free (new_states);
1539 gtk_toolbar_style_set (GtkWidget *widget,
1540 GtkStyle *prev_style)
1542 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
1544 priv->max_homogeneous_pixels = -1;
1546 if (GTK_WIDGET_REALIZED (widget))
1547 gtk_style_set_background (widget->style, widget->window, widget->state);
1550 gtk_toolbar_update_button_relief (GTK_TOOLBAR (widget));
1554 gtk_toolbar_direction_changed (GtkWidget *widget,
1555 GtkTextDirection previous_dir)
1557 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1558 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1560 if (toolbar->orientation == GTK_ORIENTATION_VERTICAL)
1562 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
1563 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
1565 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_LEFT, GTK_SHADOW_NONE);
1568 GTK_WIDGET_CLASS (parent_class)->direction_changed (widget, previous_dir);
1572 gtk_toolbar_list_children_in_focus_order (GtkToolbar *toolbar,
1573 GtkDirectionType dir)
1575 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1576 GList *result = NULL;
1580 /* generate list of children in reverse logical order */
1582 for (list = priv->content; list != NULL; list = list->next)
1584 ToolbarContent *content = list->data;
1585 GtkToolItem *item = content->item;
1587 result = g_list_prepend (result, item);
1590 result = g_list_prepend (result, priv->arrow_button);
1592 rtl = (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL);
1594 /* move in logical order when
1596 * - dir is TAB_FORWARD
1598 * - in RTL mode and moving left or up
1600 * - in LTR mode and moving right or down
1602 if (dir == GTK_DIR_TAB_FORWARD ||
1603 (rtl && (dir == GTK_DIR_UP || dir == GTK_DIR_LEFT)) ||
1604 (!rtl && (dir == GTK_DIR_DOWN || dir == GTK_DIR_RIGHT)))
1606 result = g_list_reverse (result);
1613 gtk_toolbar_focus_home_or_end (GtkToolbar *toolbar,
1614 gboolean focus_home)
1616 GList *children, *list;
1617 GtkDirectionType dir = focus_home? GTK_DIR_RIGHT : GTK_DIR_LEFT;
1619 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1621 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
1623 children = g_list_reverse (children);
1625 dir = (dir == GTK_DIR_RIGHT)? GTK_DIR_LEFT : GTK_DIR_RIGHT;
1628 for (list = children; list != NULL; list = list->next)
1630 GtkWidget *child = list->data;
1632 if (GTK_CONTAINER (toolbar)->focus_child == child)
1635 if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1639 g_list_free (children);
1644 /* Keybinding handler. This function is called when the user presses
1645 * Ctrl TAB or an arrow key.
1648 gtk_toolbar_move_focus (GtkToolbar *toolbar,
1649 GtkDirectionType dir)
1652 gboolean try_focus = FALSE;
1654 GtkContainer *container = GTK_CONTAINER (toolbar);
1656 if (container->focus_child &&
1657 gtk_widget_child_focus (container->focus_child, dir))
1662 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1664 for (list = children; list != NULL; list = list->next)
1666 GtkWidget *child = list->data;
1668 if (try_focus && GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1671 if (child == GTK_CONTAINER (toolbar)->focus_child)
1675 g_list_free (children);
1680 /* The focus handler for the toolbar. It called when the user presses
1681 * TAB or otherwise tries to focus the toolbar.
1684 gtk_toolbar_focus (GtkWidget *widget,
1685 GtkDirectionType dir)
1687 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1688 GList *children, *list;
1690 /* if focus is already somewhere inside the toolbar then return FALSE.
1691 * The only way focus can stay inside the toolbar is when the user presses
1692 * arrow keys or Ctrl TAB (both of which are handled by the
1693 * gtk_toolbar_move_focus() keybinding function.
1695 if (GTK_CONTAINER (widget)->focus_child)
1698 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1700 for (list = children; list != NULL; list = list->next)
1702 GtkWidget *child = list->data;
1704 if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1708 g_list_free (children);
1714 style_change_notify (GtkToolbar *toolbar)
1716 if (!toolbar->style_set)
1718 /* pretend it was set, then unset, thus reverting to new default */
1719 toolbar->style_set = TRUE;
1720 gtk_toolbar_unset_style (toolbar);
1725 icon_size_change_notify (GtkToolbar *toolbar)
1727 if (!toolbar->icon_size_set)
1729 /* pretend it was set, then unset, thus reverting to new default */
1730 toolbar->icon_size_set = TRUE;
1731 gtk_toolbar_unset_icon_size (toolbar);
1735 static GtkSettings *
1736 toolbar_get_settings (GtkToolbar *toolbar)
1738 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1739 return priv->settings;
1743 gtk_toolbar_screen_changed (GtkWidget *widget,
1744 GdkScreen *previous_screen)
1746 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
1747 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1748 GtkSettings *old_settings = toolbar_get_settings (toolbar);
1749 GtkSettings *settings;
1751 if (gtk_widget_has_screen (GTK_WIDGET (toolbar)))
1752 settings = gtk_widget_get_settings (GTK_WIDGET (toolbar));
1756 if (settings == old_settings)
1761 g_signal_handler_disconnect (old_settings, toolbar->style_set_connection);
1762 g_signal_handler_disconnect (old_settings, toolbar->icon_size_connection);
1764 g_object_unref (old_settings);
1769 toolbar->style_set_connection =
1770 g_signal_connect_swapped (settings,
1771 "notify::gtk-toolbar-style",
1772 G_CALLBACK (style_change_notify),
1774 toolbar->icon_size_connection =
1775 g_signal_connect_swapped (settings,
1776 "notify::gtk-toolbar-icon-size",
1777 G_CALLBACK (icon_size_change_notify),
1780 g_object_ref (settings);
1781 priv->settings = settings;
1784 priv->settings = NULL;
1786 style_change_notify (toolbar);
1787 icon_size_change_notify (toolbar);
1791 find_drop_index (GtkToolbar *toolbar,
1795 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1796 GList *interesting_content;
1798 GtkOrientation orientation;
1799 GtkTextDirection direction;
1800 gint best_distance = G_MAXINT;
1804 ToolbarContent *best_content;
1806 /* list items we care about wrt. drag and drop */
1807 interesting_content = NULL;
1808 for (list = priv->content; list != NULL; list = list->next)
1810 ToolbarContent *content = list->data;
1812 if (content->state == NORMAL)
1813 interesting_content = g_list_prepend (interesting_content, content);
1815 interesting_content = g_list_reverse (interesting_content);
1817 if (!interesting_content)
1820 orientation = toolbar->orientation;
1821 direction = gtk_widget_get_direction (GTK_WIDGET (toolbar));
1823 /* distance to first interesting item */
1824 best_content = interesting_content->data;
1826 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1830 if (direction == GTK_TEXT_DIR_LTR)
1831 pos = GTK_WIDGET (best_content->item)->allocation.x;
1833 pos = GTK_WIDGET (best_content->item)->allocation.x +
1834 GTK_WIDGET (best_content->item)->allocation.width;
1839 pos = GTK_WIDGET (best_content->item)->allocation.y;
1842 best_content = NULL;
1843 best_distance = ABS (pos - cursor);
1845 /* distance to far end of each item */
1846 for (list = interesting_content; list != NULL; list = list->next)
1848 ToolbarContent *content = list->data;
1849 GtkWidget *widget = GTK_WIDGET (content->item);
1851 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1853 if (direction == GTK_TEXT_DIR_LTR)
1854 pos = widget->allocation.x + widget->allocation.width;
1856 pos = widget->allocation.x;
1860 pos = widget->allocation.y + widget->allocation.height;
1863 distance = ABS (pos - cursor);
1865 if (distance < best_distance)
1867 best_distance = distance;
1868 best_content = content;
1872 g_list_free (interesting_content);
1877 return g_list_index (priv->content, best_content) + 1;
1881 reset_all_placeholders (GtkToolbar *toolbar)
1883 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1886 for (list = priv->content; list != NULL; list = list->next)
1888 ToolbarContent *content = list->data;
1889 if (content->is_placeholder)
1890 content->disappearing = TRUE;
1895 physical_to_logical (GtkToolbar *toolbar, gint physical)
1897 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1901 g_assert (physical >= 0);
1904 for (list = priv->content; list && physical > 0; list = list->next)
1906 ToolbarContent *content = list->data;
1908 if (!content->is_placeholder)
1913 g_assert (physical == 0);
1919 logical_to_physical (GtkToolbar *toolbar, gint logical)
1921 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1925 g_assert (logical >= 0);
1928 for (list = priv->content; list; list = list->next)
1930 ToolbarContent *content = list->data;
1932 if (!content->is_placeholder)
1942 g_assert (logical == 0);
1948 * gtk_toolbar_set_drop_highlight_item:
1949 * @toolbar: a #GtkToolbar
1950 * @item: a #GtkToolItem, or %NULL to turn of highlighting
1951 * @index: a position on @toolbar
1953 * Highlights @toolbar to give an idea of what it would look like
1954 * if @item was added to @toolbar at position indicated by @index. If @item
1955 * is %NULL, highlighting is turned off. In that case @index is ignored.
1957 * The @tool_item passed to this function must not be part of any widget
1958 * hierarchy. When an item is set as drop highlight item it can not
1959 * added to any widget hierarchy or used as highlight item for another
1965 gtk_toolbar_set_drop_highlight_item (GtkToolbar *toolbar,
1966 GtkToolItem *tool_item,
1969 ToolbarContent *content;
1970 GtkToolbarPrivate *priv;
1972 GtkRequisition requisition;
1974 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1975 g_return_if_fail (tool_item == NULL || GTK_IS_TOOL_ITEM (tool_item));
1977 gtk_toolbar_check_new_api (toolbar);
1979 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1983 if (priv->highlight_tool_item)
1985 gtk_widget_unparent (GTK_WIDGET (priv->highlight_tool_item));
1986 g_object_unref (priv->highlight_tool_item);
1987 priv->highlight_tool_item = NULL;
1990 reset_all_placeholders (toolbar);
1991 gtk_toolbar_begin_sliding (toolbar);
1995 if (tool_item != priv->highlight_tool_item)
1997 if (priv->highlight_tool_item)
1998 g_object_unref (priv->highlight_tool_item);
2000 g_object_ref (tool_item);
2001 gtk_object_sink (GTK_OBJECT (tool_item));
2003 priv->highlight_tool_item = tool_item;
2005 gtk_widget_set_parent (GTK_WIDGET (priv->highlight_tool_item),
2006 GTK_WIDGET (toolbar));
2009 n_items = gtk_toolbar_get_n_items (toolbar);
2010 if (index < 0 || index > n_items)
2013 index = logical_to_physical (toolbar, index);
2015 content = g_list_nth_data (priv->content, index);
2019 ToolbarContent *prev_content;
2021 prev_content = g_list_nth_data (priv->content, index - 1);
2023 if (prev_content && prev_content->is_placeholder)
2024 content = prev_content;
2027 if (!content || !content->is_placeholder)
2029 GtkWidget *placeholder;
2031 placeholder = GTK_WIDGET (gtk_separator_tool_item_new ());
2032 content = gtk_toolbar_insert_tool_item (toolbar,
2033 GTK_TOOL_ITEM (placeholder),
2035 gtk_widget_show (placeholder);
2039 g_assert (content->is_placeholder);
2041 reset_all_placeholders (toolbar);
2043 content->disappearing = FALSE;
2045 gtk_widget_size_request (GTK_WIDGET (priv->highlight_tool_item),
2048 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
2049 requisition.height = -1;
2051 requisition.width = -1;
2053 gtk_widget_set_size_request (GTK_WIDGET (content->item),
2055 requisition.height);
2057 gtk_toolbar_begin_sliding (toolbar);
2061 gtk_toolbar_get_child_property (GtkContainer *container,
2067 GtkToolItem *item = GTK_TOOL_ITEM (child);
2069 switch (property_id)
2071 case CHILD_PROP_HOMOGENEOUS:
2072 g_value_set_boolean (value, gtk_tool_item_get_homogeneous (item));
2075 case CHILD_PROP_EXPAND:
2076 g_value_set_boolean (value, gtk_tool_item_get_expand (item));
2080 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
2086 gtk_toolbar_set_child_property (GtkContainer *container,
2089 const GValue *value,
2092 switch (property_id)
2094 case CHILD_PROP_HOMOGENEOUS:
2095 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
2098 case CHILD_PROP_EXPAND:
2099 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
2103 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
2109 gtk_toolbar_add (GtkContainer *container,
2112 GtkToolbar *toolbar;
2114 g_return_if_fail (GTK_IS_TOOLBAR (container));
2115 g_return_if_fail (widget != NULL);
2117 toolbar = GTK_TOOLBAR (container);
2119 if (GTK_IS_TOOL_ITEM (widget))
2120 gtk_toolbar_insert (toolbar, GTK_TOOL_ITEM (widget), 0);
2122 gtk_toolbar_append_widget (toolbar, widget, NULL, NULL);
2126 gtk_toolbar_remove (GtkContainer *container,
2129 GtkToolbar *toolbar;
2130 GtkToolItem *item = NULL;
2132 g_return_if_fail (GTK_IS_TOOLBAR (container));
2133 g_return_if_fail (GTK_IS_WIDGET (widget));
2135 toolbar = GTK_TOOLBAR (container);
2137 if (GTK_IS_TOOL_ITEM (widget))
2139 item = GTK_TOOL_ITEM (widget);
2143 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2146 for (list = priv->content; list != NULL; list = list->next)
2148 ToolbarContent *content = list->data;
2150 if (GTK_BIN (content->item)->child == widget)
2152 item = content->item;
2158 g_return_if_fail (item != NULL);
2160 gtk_toolbar_remove_tool_item (GTK_TOOLBAR (container), item);
2164 gtk_toolbar_forall (GtkContainer *container,
2165 gboolean include_internals,
2166 GtkCallback callback,
2167 gpointer callback_data)
2169 GtkToolbar *toolbar = GTK_TOOLBAR (container);
2170 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2173 g_return_if_fail (callback != NULL);
2175 list = priv->content;
2178 ToolbarContent *content = list->data;
2179 GList *next = list->next;
2181 if (!content->is_placeholder || include_internals)
2182 (*callback) (GTK_WIDGET (content->item), callback_data);
2187 if (include_internals)
2188 (* callback) (priv->arrow_button, callback_data);
2192 gtk_toolbar_child_type (GtkContainer *container)
2194 return GTK_TYPE_TOOL_ITEM;
2198 gtk_toolbar_reconfigured (GtkToolbar *toolbar)
2200 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2203 list = priv->content;
2206 ToolbarContent *content = list->data;
2207 GList *next = list->next;
2209 _gtk_tool_item_toolbar_reconfigured (content->item);
2216 gtk_toolbar_real_orientation_changed (GtkToolbar *toolbar,
2217 GtkOrientation orientation)
2219 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2220 if (toolbar->orientation != orientation)
2222 toolbar->orientation = orientation;
2224 if (orientation == GTK_ORIENTATION_HORIZONTAL)
2225 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_DOWN, GTK_SHADOW_NONE);
2226 else if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
2227 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
2229 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_LEFT, GTK_SHADOW_NONE);
2231 gtk_toolbar_reconfigured (toolbar);
2233 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2234 g_object_notify (G_OBJECT (toolbar), "orientation");
2239 gtk_toolbar_real_style_changed (GtkToolbar *toolbar,
2240 GtkToolbarStyle style)
2242 if (toolbar->style != style)
2244 toolbar->style = style;
2246 gtk_toolbar_reconfigured (toolbar);
2248 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2249 g_object_notify (G_OBJECT (toolbar), "toolbar_style");
2254 menu_position_func (GtkMenu *menu,
2260 GtkToolbar *toolbar = GTK_TOOLBAR (user_data);
2261 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2263 GtkRequisition menu_req;
2265 gdk_window_get_origin (GTK_BUTTON (priv->arrow_button)->event_window, x, y);
2266 gtk_widget_size_request (priv->arrow_button, &req);
2267 gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
2269 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
2271 *y += priv->arrow_button->allocation.height;
2272 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
2273 *x += priv->arrow_button->allocation.width - req.width;
2275 *x += req.width - menu_req.width;
2279 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
2280 *x += priv->arrow_button->allocation.width;
2282 *x -= menu_req.width;
2283 *y += priv->arrow_button->allocation.height - req.height;
2290 menu_deactivated (GtkWidget *menu,
2291 GtkToolbar *toolbar)
2293 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2295 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->arrow_button), FALSE);
2299 remove_item (GtkWidget *menu_item,
2302 gtk_container_remove (GTK_CONTAINER (menu_item->parent), menu_item);
2306 show_menu (GtkToolbar *toolbar,
2307 GdkEventButton *event)
2309 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2314 gtk_container_foreach (GTK_CONTAINER (priv->menu), remove_item, NULL);
2315 gtk_widget_destroy (GTK_WIDGET (priv->menu));
2318 priv->menu = GTK_MENU (gtk_menu_new ());
2319 g_signal_connect (priv->menu, "deactivate", G_CALLBACK (menu_deactivated), toolbar);
2321 for (list = priv->content; list != NULL; list = list->next)
2323 ToolbarContent *content = list->data;
2324 GtkToolItem *item = content->item;
2326 if (content->state == OVERFLOWN)
2328 GtkWidget *menu_item = gtk_tool_item_retrieve_proxy_menu_item (item);
2332 g_assert (GTK_IS_MENU_ITEM (menu_item));
2333 gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), menu_item);
2338 gtk_widget_show_all (GTK_WIDGET (priv->menu));
2340 gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL,
2341 menu_position_func, toolbar,
2342 event? event->button : 0, event? event->time : gtk_get_current_event_time());
2346 gtk_toolbar_arrow_button_clicked (GtkWidget *button,
2347 GtkToolbar *toolbar)
2349 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2351 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->arrow_button)) &&
2352 (!priv->menu || !GTK_WIDGET_VISIBLE (GTK_WIDGET (priv->menu))))
2354 /* We only get here when the button is clicked with the keybaord,
2355 * because mouse button presses result in the menu being shown so
2356 * that priv->menu would be non-NULL and visible.
2358 show_menu (toolbar, NULL);
2359 gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->menu), FALSE);
2364 gtk_toolbar_arrow_button_press (GtkWidget *button,
2365 GdkEventButton *event,
2366 GtkToolbar *toolbar)
2368 show_menu (toolbar, event);
2369 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
2375 gtk_toolbar_button_press (GtkWidget *toolbar,
2376 GdkEventButton *event)
2378 if (event->button == 3)
2380 gboolean return_value;
2382 g_signal_emit (toolbar, toolbar_signals[POPUP_CONTEXT_MENU], 0,
2383 (int)event->x_root, (int)event->y_root, event->button,
2386 return return_value;
2393 gtk_toolbar_popup_menu (GtkWidget *toolbar)
2395 gboolean return_value;
2396 /* This function is the handler for the "popup menu" keybinding,
2397 * ie., it is called when the user presses Shift F10
2399 g_signal_emit (toolbar, toolbar_signals[POPUP_CONTEXT_MENU], 0,
2400 -1, -1, -1, &return_value);
2402 return return_value;
2406 gtk_toolbar_update_button_relief (GtkToolbar *toolbar)
2408 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2410 gtk_toolbar_reconfigured (toolbar);
2412 gtk_button_set_relief (GTK_BUTTON (priv->arrow_button), get_button_relief (toolbar));
2415 static GtkReliefStyle
2416 get_button_relief (GtkToolbar *toolbar)
2418 GtkReliefStyle button_relief = GTK_RELIEF_NORMAL;
2420 gtk_widget_ensure_style (GTK_WIDGET (toolbar));
2422 gtk_widget_style_get (GTK_WIDGET (toolbar),
2423 "button_relief", &button_relief,
2426 return button_relief;
2430 get_internal_padding (GtkToolbar *toolbar)
2434 gtk_widget_style_get (GTK_WIDGET (toolbar),
2435 "internal_padding", &ipadding,
2441 static GtkShadowType
2442 get_shadow_type (GtkToolbar *toolbar)
2444 GtkShadowType shadow_type;
2446 gtk_widget_style_get (GTK_WIDGET (toolbar),
2447 "shadow_type", &shadow_type,
2454 gtk_toolbar_check_old_api (GtkToolbar *toolbar)
2456 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2458 if (priv->api_mode == NEW_API)
2460 g_warning ("mixing deprecated and non-deprecated GtkToolbar API is not allowed");
2464 priv->api_mode = OLD_API;
2469 gtk_toolbar_check_new_api (GtkToolbar *toolbar)
2471 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2473 if (priv->api_mode == OLD_API)
2475 g_warning ("mixing deprecated and non-deprecated GtkToolbar API is not allowed");
2479 priv->api_mode = NEW_API;
2483 static ToolbarContent *
2484 gtk_toolbar_insert_tool_item (GtkToolbar *toolbar,
2487 gboolean is_placeholder)
2489 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2490 ToolbarContent *content = g_new0 (ToolbarContent, 1);
2492 content->is_placeholder = is_placeholder;
2493 content->item = item;
2494 content->state = NOT_ALLOCATED;
2495 toolbar->num_children++;
2497 priv->content = g_list_insert (priv->content, content, pos);
2499 gtk_widget_set_parent (GTK_WIDGET (item), GTK_WIDGET (toolbar));
2501 if (!content->is_placeholder)
2502 gtk_toolbar_stop_sliding (toolbar);
2508 gtk_toolbar_remove_tool_item (GtkToolbar *toolbar,
2511 GtkToolbarPrivate *priv;
2514 ToolbarContent *content = NULL;
2516 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2517 g_return_if_fail (GTK_IS_TOOL_ITEM (item));
2519 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2523 for (tmp = priv->content; tmp != NULL; tmp = tmp->next)
2525 content = tmp->data;
2526 if (content->item == item)
2532 g_return_if_fail (content != NULL);
2536 priv->content = g_list_remove (priv->content, content);
2538 gtk_widget_unparent (GTK_WIDGET (item));
2540 if (priv->api_mode == OLD_API)
2542 GtkToolbarChild *toolbar_child;
2544 toolbar_child = g_list_nth_data (toolbar->children, nth_child);
2545 toolbar->children = g_list_remove (toolbar->children, toolbar_child);
2547 g_free (toolbar_child);
2550 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2556 * Creates a new toolbar.
2558 * Return Value: the newly-created toolbar.
2561 gtk_toolbar_new (void)
2563 GtkToolbar *toolbar;
2565 toolbar = g_object_new (GTK_TYPE_TOOLBAR, NULL);
2567 return GTK_WIDGET (toolbar);
2571 * gtk_toolbar_insert:
2572 * @toolbar: a #GtkToolbar
2573 * @item: a #GtkToolItem
2574 * @pos: the position of the new item
2576 * Insert a #GtkToolItem into the toolbar at position @pos. If @pos is
2577 * 0 the item is prepended to the start of the toolbar. If @pos is
2578 * negative, the item is appended to the end of the toolbar.
2583 gtk_toolbar_insert (GtkToolbar *toolbar,
2587 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2588 g_return_if_fail (GTK_IS_TOOL_ITEM (item));
2590 if (!gtk_toolbar_check_new_api (toolbar))
2594 pos = logical_to_physical (toolbar, pos);
2596 gtk_toolbar_insert_tool_item (toolbar, item, pos, FALSE);
2600 * gtk_toolbar_get_item_index:
2601 * @toolbar: a #GtkToolbar
2602 * @item: a #GtkToolItem that is a child of @toolbar
2604 * Returns the position of @item on the toolbar, starting from 0.
2605 * It is an error if @item is not a child of the toolbar.
2607 * Return value: the position of item on the toolbar.
2612 gtk_toolbar_get_item_index (GtkToolbar *toolbar,
2615 GtkToolbarPrivate *priv;
2619 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
2620 g_return_val_if_fail (GTK_IS_TOOL_ITEM (item), -1);
2621 g_return_val_if_fail (GTK_WIDGET (item)->parent == GTK_WIDGET (toolbar), -1);
2623 if (!gtk_toolbar_check_new_api (toolbar))
2626 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2629 for (list = priv->content; list != NULL; list = list->next)
2631 ToolbarContent *content = list->data;
2633 if (content->item == item)
2639 return physical_to_logical (toolbar, n);
2643 * gtk_toolbar_set_orientation:
2644 * @toolbar: a #GtkToolbar.
2645 * @orientation: a new #GtkOrientation.
2647 * Sets whether a toolbar should appear horizontally or vertically.
2650 gtk_toolbar_set_orientation (GtkToolbar *toolbar,
2651 GtkOrientation orientation)
2653 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2655 g_signal_emit (toolbar, toolbar_signals[ORIENTATION_CHANGED], 0, orientation);
2659 * gtk_toolbar_get_orientation:
2660 * @toolbar: a #GtkToolbar
2662 * Retrieves the current orientation of the toolbar. See
2663 * gtk_toolbar_set_orientation().
2665 * Return value: the orientation
2668 gtk_toolbar_get_orientation (GtkToolbar *toolbar)
2670 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_ORIENTATION_HORIZONTAL);
2672 return toolbar->orientation;
2676 * gtk_toolbar_set_style:
2677 * @toolbar: a #GtkToolbar.
2678 * @style: the new style for @toolbar.
2680 * Alters the view of @toolbar to display either icons only, text only, or both.
2683 gtk_toolbar_set_style (GtkToolbar *toolbar,
2684 GtkToolbarStyle style)
2686 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2688 toolbar->style_set = TRUE;
2689 g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
2693 * gtk_toolbar_get_style:
2694 * @toolbar: a #GtkToolbar
2696 * Retrieves whether the toolbar has text, icons, or both . See
2697 * gtk_toolbar_set_style().
2699 * Return value: the current style of @toolbar
2702 gtk_toolbar_get_style (GtkToolbar *toolbar)
2704 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), DEFAULT_TOOLBAR_STYLE);
2706 return toolbar->style;
2710 * gtk_toolbar_unset_style:
2711 * @toolbar: a #GtkToolbar
2713 * Unsets a toolbar style set with gtk_toolbar_set_style(), so that
2714 * user preferences will be used to determine the toolbar style.
2717 gtk_toolbar_unset_style (GtkToolbar *toolbar)
2719 GtkToolbarStyle style;
2721 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2723 if (toolbar->style_set)
2725 GtkSettings *settings = toolbar_get_settings (toolbar);
2728 g_object_get (settings,
2729 "gtk-toolbar-style", &style,
2732 style = DEFAULT_TOOLBAR_STYLE;
2734 if (style != toolbar->style)
2735 g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
2737 toolbar->style_set = FALSE;
2742 * gtk_toolbar_set_tooltips:
2743 * @toolbar: a #GtkToolbar.
2744 * @enable: set to %FALSE to disable the tooltips, or %TRUE to enable them.
2746 * Sets if the tooltips of a toolbar should be active or not.
2749 gtk_toolbar_set_tooltips (GtkToolbar *toolbar,
2752 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2755 gtk_tooltips_enable (toolbar->tooltips);
2757 gtk_tooltips_disable (toolbar->tooltips);
2761 * gtk_toolbar_get_tooltips:
2762 * @toolbar: a #GtkToolbar
2764 * Retrieves whether tooltips are enabled. See
2765 * gtk_toolbar_set_tooltips().
2767 * Return value: %TRUE if tooltips are enabled
2770 gtk_toolbar_get_tooltips (GtkToolbar *toolbar)
2772 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2774 return toolbar->tooltips->enabled;
2778 * gtk_toolbar_get_n_items:
2779 * @toolbar: a #GtkToolbar
2781 * Returns the number of items on the toolbar.
2783 * Return value: the number of items on the toolbar
2788 gtk_toolbar_get_n_items (GtkToolbar *toolbar)
2790 GtkToolbarPrivate *priv;
2792 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
2794 if (!gtk_toolbar_check_new_api (toolbar))
2797 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2799 return physical_to_logical (toolbar, g_list_length (priv->content));
2803 * gtk_toolbar_get_nth_item:
2804 * @toolbar: a #GtkToolbar
2805 * @n: A position on the toolbar
2807 * Returns the @n<!-- -->'s item on @toolbar, or %NULL if the
2808 * toolbar does not contain an @n<!-- -->'th item.
2810 * Return value: The @n<!-- -->'th #GtkToolItem on @toolbar, or %NULL if there
2811 * isn't an @n<!-- -->th item.
2816 gtk_toolbar_get_nth_item (GtkToolbar *toolbar,
2819 GtkToolbarPrivate *priv;
2820 ToolbarContent *content;
2823 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
2825 if (!gtk_toolbar_check_new_api (toolbar))
2828 n_items = gtk_toolbar_get_n_items (toolbar);
2830 if (n < 0 || n >= n_items)
2833 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2835 content = g_list_nth_data (priv->content, logical_to_physical (toolbar, n));
2838 g_assert (!content->is_placeholder);
2840 return content->item;
2844 * gtk_toolbar_set_icon_size:
2845 * @toolbar: A #GtkToolbar
2846 * @icon_size: The #GtkIconSize that stock icons in the toolbar shall have.
2848 * This function sets the size of stock icons in the toolbar. You
2849 * can call it both before you add the icons and after they've been
2850 * added. The size you set will override user preferences for the default
2854 gtk_toolbar_set_icon_size (GtkToolbar *toolbar,
2855 GtkIconSize icon_size)
2857 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2859 toolbar->icon_size_set = TRUE;
2861 if (toolbar->icon_size == icon_size)
2864 toolbar->icon_size = icon_size;
2866 gtk_toolbar_reconfigured (toolbar);
2868 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2872 * gtk_toolbar_get_icon_size:
2873 * @toolbar: a #GtkToolbar
2875 * Retrieves the icon size fo the toolbar. See gtk_toolbar_set_icon_size().
2877 * Return value: the current icon size for the icons on the toolbar.
2880 gtk_toolbar_get_icon_size (GtkToolbar *toolbar)
2882 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), DEFAULT_ICON_SIZE);
2884 return toolbar->icon_size;
2888 * gtk_toolbar_get_relief_style:
2889 * @toolbar: a #GtkToolbar
2891 * Returns the relief style of buttons on @toolbar. See
2892 * gtk_button_set_relief_style().
2894 * Return value: The relief style of buttons on @toolbar.
2899 gtk_toolbar_get_relief_style (GtkToolbar *toolbar)
2901 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_RELIEF_NONE);
2903 return get_button_relief (toolbar);
2907 * gtk_toolbar_unset_icon_size:
2908 * @toolbar: a #GtkToolbar
2910 * Unsets toolbar icon size set with gtk_toolbar_set_icon_size(), so that
2911 * user preferences will be used to determine the icon size.
2914 gtk_toolbar_unset_icon_size (GtkToolbar *toolbar)
2918 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2920 if (toolbar->icon_size_set)
2922 GtkSettings *settings = toolbar_get_settings (toolbar);
2926 g_object_get (settings,
2927 "gtk-toolbar-icon-size", &size,
2931 size = DEFAULT_ICON_SIZE;
2933 if (size != toolbar->icon_size)
2934 gtk_toolbar_set_icon_size (toolbar, size);
2936 toolbar->icon_size_set = FALSE;
2941 * gtk_toolbar_set_show_arrow:
2942 * @toolbar: a #GtkToolbar
2943 * @show_arrow: Whether to show an overflow menu
2945 * Sets whether to show an overflow menu when
2946 * @toolbar doesn't have room for all items on it. If %TRUE,
2947 * items that there are not room are available through an
2953 gtk_toolbar_set_show_arrow (GtkToolbar *toolbar,
2954 gboolean show_arrow)
2956 GtkToolbarPrivate *priv;
2958 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2960 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2961 show_arrow = show_arrow != FALSE;
2963 if (priv->show_arrow != show_arrow)
2965 priv->show_arrow = show_arrow;
2967 if (!priv->show_arrow)
2968 gtk_widget_hide (priv->arrow_button);
2970 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2971 g_object_notify (G_OBJECT (toolbar), "show_arrow");
2976 * gtk_toolbar_get_show_arrow:
2977 * @toolbar: a #GtkToolbar
2979 * Returns whether the toolbar has an overflow menu.
2980 * See gtk_toolbar_set_show_arrow()
2987 gtk_toolbar_get_show_arrow (GtkToolbar *toolbar)
2989 GtkToolbarPrivate *priv;
2991 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2993 if (!gtk_toolbar_check_new_api (toolbar))
2996 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2998 return priv->show_arrow;
3002 * gtk_toolbar_get_drop_index:
3003 * @toolbar: a #GtkToolbar
3004 * @x: x coordinate of a point on the toolbar
3005 * @y: y coordinate of a point on the toolbar
3007 * Returns the position corresponding to the indicated point on
3008 * @toolbar. This is useful when dragging items to the toolbar:
3009 * this function returns the position a new item should be
3012 * @x and @y are in @toolbar coordinates.
3014 * Return value: The position corresponding to the point (@x, @y) on the toolbar.
3019 gtk_toolbar_get_drop_index (GtkToolbar *toolbar,
3023 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
3025 if (!gtk_toolbar_check_new_api (toolbar))
3028 return physical_to_logical (toolbar, find_drop_index (toolbar, x, y));
3032 * gtk_toolbar_append_item:
3033 * @toolbar: a #GtkToolbar.
3034 * @text: give your toolbar button a label.
3035 * @tooltip_text: a string that appears when the user holds the mouse over this item.
3036 * @tooltip_private_text: use with #GtkTipsQuery.
3037 * @icon: a #GtkWidget that should be used as the button's icon.
3038 * @callback: the function to be executed when the button is pressed.
3039 * @user_data: a pointer to any data you wish to be passed to the callback.
3041 * Inserts a new item into the toolbar. You must specify the position
3042 * in the toolbar where it will be inserted.
3044 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3045 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3047 * Return value: the new toolbar item as a #GtkWidget.
3050 gtk_toolbar_append_item (GtkToolbar *toolbar,
3052 const char *tooltip_text,
3053 const char *tooltip_private_text,
3055 GtkSignalFunc callback,
3058 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3060 tooltip_text, tooltip_private_text,
3061 icon, callback, user_data,
3062 toolbar->num_children);
3066 * gtk_toolbar_prepend_item:
3067 * @toolbar: a #GtkToolbar.
3068 * @text: give your toolbar button a label.
3069 * @tooltip_text: a string that appears when the user holds the mouse over this item.
3070 * @tooltip_private_text: use with #GtkTipsQuery.
3071 * @icon: a #GtkWidget that should be used as the button's icon.
3072 * @callback: the function to be executed when the button is pressed.
3073 * @user_data: a pointer to any data you wish to be passed to the callback.
3075 * Adds a new button to the beginning (top or left edges) of the given toolbar.
3077 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3078 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3080 * Return value: the new toolbar item as a #GtkWidget.
3083 gtk_toolbar_prepend_item (GtkToolbar *toolbar,
3085 const char *tooltip_text,
3086 const char *tooltip_private_text,
3088 GtkSignalFunc callback,
3091 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3093 tooltip_text, tooltip_private_text,
3094 icon, callback, user_data,
3099 * gtk_toolbar_insert_item:
3100 * @toolbar: a #GtkToolbar.
3101 * @text: give your toolbar button a label.
3102 * @tooltip_text: a string that appears when the user holds the mouse over this item.
3103 * @tooltip_private_text: use with #GtkTipsQuery.
3104 * @icon: a #GtkWidget that should be used as the button's icon.
3105 * @callback: the function to be executed when the button is pressed.
3106 * @user_data: a pointer to any data you wish to be passed to the callback.
3107 * @position: the number of widgets to insert this item after.
3109 * Inserts a new item into the toolbar. You must specify the position in the
3110 * toolbar where it will be inserted.
3112 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3113 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3115 * Return value: the new toolbar item as a #GtkWidget.
3118 gtk_toolbar_insert_item (GtkToolbar *toolbar,
3120 const char *tooltip_text,
3121 const char *tooltip_private_text,
3123 GtkSignalFunc callback,
3127 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3129 tooltip_text, tooltip_private_text,
3130 icon, callback, user_data,
3135 * gtk_toolbar_insert_stock:
3136 * @toolbar: A #GtkToolbar
3137 * @stock_id: The id of the stock item you want to insert
3138 * @tooltip_text: The text in the tooltip of the toolbar button
3139 * @tooltip_private_text: The private text of the tooltip
3140 * @callback: The callback called when the toolbar button is clicked.
3141 * @user_data: user data passed to callback
3142 * @position: The position the button shall be inserted at.
3143 * -1 means at the end.
3145 * Inserts a stock item at the specified position of the toolbar. If
3146 * @stock_id is not a known stock item ID, it's inserted verbatim,
3147 * except that underscores used to mark mnemonics are removed.
3149 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3150 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3152 * Returns: the inserted widget
3155 gtk_toolbar_insert_stock (GtkToolbar *toolbar,
3156 const gchar *stock_id,
3157 const char *tooltip_text,
3158 const char *tooltip_private_text,
3159 GtkSignalFunc callback,
3163 return gtk_toolbar_internal_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3165 tooltip_text, tooltip_private_text,
3166 NULL, callback, user_data,
3171 * gtk_toolbar_append_space:
3172 * @toolbar: a #GtkToolbar.
3174 * Adds a new space to the end of the toolbar.
3177 gtk_toolbar_append_space (GtkToolbar *toolbar)
3179 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
3183 toolbar->num_children);
3187 * gtk_toolbar_prepend_space:
3188 * @toolbar: a #GtkToolbar.
3190 * Adds a new space to the beginning of the toolbar.
3193 gtk_toolbar_prepend_space (GtkToolbar *toolbar)
3195 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
3203 * gtk_toolbar_insert_space:
3204 * @toolbar: a #GtkToolbar
3205 * @position: the number of widgets after which a space should be inserted.
3207 * Inserts a new space in the toolbar at the specified position.
3210 gtk_toolbar_insert_space (GtkToolbar *toolbar,
3213 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
3221 * gtk_toolbar_remove_space:
3222 * @toolbar: a #GtkToolbar.
3223 * @position: the index of the space to remove.
3225 * Removes a space from the specified position.
3228 gtk_toolbar_remove_space (GtkToolbar *toolbar,
3233 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
3235 if (!gtk_toolbar_check_old_api (toolbar))
3238 item = g_list_nth_data (toolbar->children, position);
3242 g_warning ("Toolbar position %d doesn't exist", position);
3246 if (!GTK_IS_SEPARATOR_TOOL_ITEM (item))
3248 g_warning ("Toolbar position %d is not a space", position);
3252 gtk_toolbar_remove_tool_item (toolbar, item);
3256 * gtk_toolbar_append_widget:
3257 * @toolbar: a #GtkToolbar.
3258 * @widget: a #GtkWidget to add to the toolbar.
3259 * @tooltip_text: the element's tooltip.
3260 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3262 * Adds a widget to the end of the given toolbar.
3265 gtk_toolbar_append_widget (GtkToolbar *toolbar,
3267 const gchar *tooltip_text,
3268 const gchar *tooltip_private_text)
3270 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
3272 tooltip_text, tooltip_private_text,
3274 toolbar->num_children);
3278 * gtk_toolbar_prepend_widget:
3279 * @toolbar: a #GtkToolbar.
3280 * @widget: a #GtkWidget to add to the toolbar.
3281 * @tooltip_text: the element's tooltip.
3282 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3284 * Adds a widget to the beginning of the given toolbar.
3287 gtk_toolbar_prepend_widget (GtkToolbar *toolbar,
3289 const gchar *tooltip_text,
3290 const gchar *tooltip_private_text)
3292 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
3294 tooltip_text, tooltip_private_text,
3300 * gtk_toolbar_insert_widget:
3301 * @toolbar: a #GtkToolbar.
3302 * @widget: a #GtkWidget to add to the toolbar.
3303 * @tooltip_text: the element's tooltip.
3304 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3305 * @position: the number of widgets to insert this widget after.
3307 * Inserts a widget in the toolbar at the given position.
3310 gtk_toolbar_insert_widget (GtkToolbar *toolbar,
3312 const char *tooltip_text,
3313 const char *tooltip_private_text,
3316 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
3318 tooltip_text, tooltip_private_text,
3324 * gtk_toolbar_append_element:
3325 * @toolbar: a #GtkToolbar.
3326 * @type: a value of type #GtkToolbarChildType that determines what @widget will be.
3327 * @widget: a #GtkWidget, or %NULL.
3328 * @text: the element's label.
3329 * @tooltip_text: the element's tooltip.
3330 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3331 * @icon: a #GtkWidget that provides pictorial representation of the element's function.
3332 * @callback: the function to be executed when the button is pressed.
3333 * @user_data: any data you wish to pass to the callback.
3335 * Adds a new element to the end of a toolbar.
3337 * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element.
3338 * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine
3339 * the radio group for the new element. In all other cases, @widget must
3342 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3343 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3345 * Return value: the new toolbar element as a #GtkWidget.
3348 gtk_toolbar_append_element (GtkToolbar *toolbar,
3349 GtkToolbarChildType type,
3352 const char *tooltip_text,
3353 const char *tooltip_private_text,
3355 GtkSignalFunc callback,
3358 return gtk_toolbar_insert_element (toolbar, type, widget, text,
3359 tooltip_text, tooltip_private_text,
3360 icon, callback, user_data,
3361 toolbar->num_children);
3365 * gtk_toolbar_prepend_element:
3366 * @toolbar: a #GtkToolbar.
3367 * @type: a value of type #GtkToolbarChildType that determines what @widget will be.
3368 * @widget: a #GtkWidget, or %NULL
3369 * @text: the element's label.
3370 * @tooltip_text: the element's tooltip.
3371 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3372 * @icon: a #GtkWidget that provides pictorial representation of the element's function.
3373 * @callback: the function to be executed when the button is pressed.
3374 * @user_data: any data you wish to pass to the callback.
3376 * Adds a new element to the beginning of a toolbar.
3378 * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element.
3379 * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine
3380 * the radio group for the new element. In all other cases, @widget must
3383 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3384 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3386 * Return value: the new toolbar element as a #GtkWidget.
3389 gtk_toolbar_prepend_element (GtkToolbar *toolbar,
3390 GtkToolbarChildType type,
3393 const char *tooltip_text,
3394 const char *tooltip_private_text,
3396 GtkSignalFunc callback,
3399 return gtk_toolbar_insert_element (toolbar, type, widget, text,
3400 tooltip_text, tooltip_private_text,
3401 icon, callback, user_data, 0);
3405 * gtk_toolbar_insert_element:
3406 * @toolbar: a #GtkToolbar.
3407 * @type: a value of type #GtkToolbarChildType that determines what @widget
3409 * @widget: a #GtkWidget, or %NULL.
3410 * @text: the element's label.
3411 * @tooltip_text: the element's tooltip.
3412 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3413 * @icon: a #GtkWidget that provides pictorial representation of the element's function.
3414 * @callback: the function to be executed when the button is pressed.
3415 * @user_data: any data you wish to pass to the callback.
3416 * @position: the number of widgets to insert this element after.
3418 * Inserts a new element in the toolbar at the given position.
3420 * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element.
3421 * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine
3422 * the radio group for the new element. In all other cases, @widget must
3425 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3426 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3428 * Return value: the new toolbar element as a #GtkWidget.
3431 gtk_toolbar_insert_element (GtkToolbar *toolbar,
3432 GtkToolbarChildType type,
3435 const char *tooltip_text,
3436 const char *tooltip_private_text,
3438 GtkSignalFunc callback,
3442 return gtk_toolbar_internal_insert_element (toolbar, type, widget, text,
3443 tooltip_text, tooltip_private_text,
3444 icon, callback, user_data, position, FALSE);
3448 _gtk_toolbar_elide_underscores (const gchar *original)
3452 gboolean last_underscore;
3454 q = result = g_malloc (strlen (original) + 1);
3455 last_underscore = FALSE;
3457 for (p = original; *p; p++)
3459 if (!last_underscore && *p == '_')
3460 last_underscore = TRUE;
3463 last_underscore = FALSE;
3474 gtk_toolbar_internal_insert_element (GtkToolbar *toolbar,
3475 GtkToolbarChildType type,
3478 const char *tooltip_text,
3479 const char *tooltip_private_text,
3481 GtkSignalFunc callback,
3486 GtkToolbarChild *child;
3487 GtkToolItem *item = NULL;
3489 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
3491 if (!gtk_toolbar_check_old_api (toolbar))
3494 if (type == GTK_TOOLBAR_CHILD_WIDGET)
3495 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3496 else if (type != GTK_TOOLBAR_CHILD_RADIOBUTTON)
3497 g_return_val_if_fail (widget == NULL, NULL);
3499 child = g_new (GtkToolbarChild, 1);
3503 child->label = NULL;
3507 case GTK_TOOLBAR_CHILD_SPACE:
3508 item = gtk_separator_tool_item_new ();
3509 child->widget = NULL;
3512 case GTK_TOOLBAR_CHILD_WIDGET:
3513 item = gtk_tool_item_new ();
3514 child->widget = widget;
3515 gtk_container_add (GTK_CONTAINER (item), child->widget);
3518 case GTK_TOOLBAR_CHILD_BUTTON:
3519 item = gtk_tool_button_new (NULL, NULL);
3520 child->widget = _gtk_tool_button_get_button (GTK_TOOL_BUTTON (item));
3523 case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
3524 item = gtk_toggle_tool_button_new ();
3525 child->widget = _gtk_tool_button_get_button (GTK_TOOL_BUTTON (item));
3528 case GTK_TOOLBAR_CHILD_RADIOBUTTON:
3529 item = gtk_radio_tool_button_new (widget
3530 ? gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget))
3532 child->widget = _gtk_tool_button_get_button (GTK_TOOL_BUTTON (item));
3537 * When we are using the old API, consider all items "is_important". That
3538 * way BOTH_HORIZ will continue to show both icon and label in old API mode
3540 gtk_tool_item_set_is_important (item, TRUE);
3542 gtk_widget_show (GTK_WIDGET (item));
3544 if (type == GTK_TOOLBAR_CHILD_BUTTON ||
3545 type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
3546 type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
3552 GtkStockItem stock_item;
3555 gtk_tool_button_set_stock_id (GTK_TOOL_BUTTON (item), text);
3557 gtk_stock_lookup (text, &stock_item);
3558 label_text = _gtk_toolbar_elide_underscores (stock_item.label);
3559 child->label = GTK_WIDGET (gtk_label_new (label_text));
3560 g_free (label_text);
3564 child->label = gtk_label_new (text);
3566 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (item), child->label);
3567 gtk_widget_show (child->label);
3573 gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (item), icon);
3575 /* Applications depend on the toolbar showing the widget for them */
3576 gtk_widget_show (GTK_WIDGET (icon));
3580 * We need to connect to the button's clicked callback because some
3581 * programs may rely on that the widget in the callback is a GtkButton
3584 g_signal_connect (child->widget, "clicked",
3585 callback, user_data);
3588 if ((type != GTK_TOOLBAR_CHILD_SPACE) && tooltip_text)
3589 gtk_tool_item_set_tooltip (item, toolbar->tooltips,
3590 tooltip_text, tooltip_private_text);
3592 toolbar->children = g_list_insert (toolbar->children, child, position);
3594 gtk_toolbar_insert_tool_item (toolbar, item, position, FALSE);
3596 return child->widget;
3600 gtk_toolbar_finalize (GObject *object)
3603 GtkToolbar *toolbar = GTK_TOOLBAR (object);
3604 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3606 if (toolbar->tooltips)
3607 g_object_unref (toolbar->tooltips);
3609 for (list = toolbar->children; list != NULL; list = list->next)
3610 g_free (list->data);
3612 g_list_free (toolbar->children);
3614 for (list = priv->content; list != NULL; list = list->next)
3615 g_free (list->data);
3617 g_list_free (priv->content);
3619 g_timer_destroy (priv->timer);
3622 g_source_remove (priv->idle_id);
3624 G_OBJECT_CLASS (parent_class)->finalize (object);