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
52 #define DEFAULT_SPACE_SIZE 5
53 #define DEFAULT_SPACE_STYLE GTK_TOOLBAR_SPACE_LINE
55 #define DEFAULT_ICON_SIZE GTK_ICON_SIZE_LARGE_TOOLBAR
56 #define DEFAULT_TOOLBAR_STYLE GTK_TOOLBAR_BOTH
58 #define SPACE_LINE_DIVISION 10
59 #define SPACE_LINE_START 3
60 #define SPACE_LINE_END 7
72 CHILD_PROP_HOMOGENEOUS,
85 static void gtk_toolbar_init (GtkToolbar *toolbar);
86 static void gtk_toolbar_class_init (GtkToolbarClass *klass);
88 static void gtk_toolbar_set_property (GObject *object,
92 static void gtk_toolbar_get_property (GObject *object,
97 static gint gtk_toolbar_expose (GtkWidget *widget,
98 GdkEventExpose *event);
99 static void gtk_toolbar_realize (GtkWidget *widget);
100 static void gtk_toolbar_unrealize (GtkWidget *widget);
101 static void gtk_toolbar_size_request (GtkWidget *widget,
102 GtkRequisition *requisition);
103 static void gtk_toolbar_size_allocate (GtkWidget *widget,
104 GtkAllocation *allocation);
105 static void gtk_toolbar_style_set (GtkWidget *widget,
106 GtkStyle *prev_style);
107 static void gtk_toolbar_direction_changed (GtkWidget *widget,
108 GtkTextDirection previous_direction);
109 static gboolean gtk_toolbar_focus (GtkWidget *widget,
110 GtkDirectionType dir);
111 static void gtk_toolbar_screen_changed (GtkWidget *widget,
112 GdkScreen *previous_screen);
113 static void gtk_toolbar_map (GtkWidget *widget);
114 static void gtk_toolbar_unmap (GtkWidget *widget);
116 static void gtk_toolbar_drag_leave (GtkWidget *widget,
117 GdkDragContext *context,
119 static gboolean gtk_toolbar_drag_motion (GtkWidget *widget,
120 GdkDragContext *context,
124 static void gtk_toolbar_set_child_property (GtkContainer *container,
129 static void gtk_toolbar_get_child_property (GtkContainer *container,
134 static void gtk_toolbar_finalize (GObject *object);
137 static void gtk_toolbar_add (GtkContainer *container,
139 static void gtk_toolbar_remove (GtkContainer *container,
141 static void gtk_toolbar_forall (GtkContainer *container,
142 gboolean include_internals,
143 GtkCallback callback,
144 gpointer callback_data);
145 static GType gtk_toolbar_child_type (GtkContainer *container);
147 static void gtk_toolbar_real_orientation_changed (GtkToolbar *toolbar,
148 GtkOrientation orientation);
149 static void gtk_toolbar_real_style_changed (GtkToolbar *toolbar,
150 GtkToolbarStyle style);
152 static gboolean gtk_toolbar_move_focus (GtkToolbar *toolbar,
153 GtkDirectionType dir);
154 static gboolean gtk_toolbar_focus_home_or_end (GtkToolbar *toolbar,
155 gboolean focus_home);
157 static gboolean gtk_toolbar_button_press (GtkWidget *toolbar,
158 GdkEventButton *event);
159 static gboolean gtk_toolbar_arrow_button_press (GtkWidget *button,
160 GdkEventButton *event,
161 GtkToolbar *toolbar);
162 static void gtk_toolbar_arrow_button_clicked (GtkWidget *button,
163 GtkToolbar *toolbar);
164 static void gtk_toolbar_update_button_relief (GtkToolbar *toolbar);
165 static GtkReliefStyle get_button_relief (GtkToolbar *toolbar);
166 static gint get_space_size (GtkToolbar *toolbar);
167 static GtkToolbarSpaceStyle get_space_style (GtkToolbar *toolbar);
168 static gint get_internal_padding (GtkToolbar *toolbar);
169 static void gtk_toolbar_remove_tool_item (GtkToolbar *toolbar,
172 static GtkWidget *gtk_toolbar_internal_insert_element (GtkToolbar *toolbar,
173 GtkToolbarChildType type,
176 const char *tooltip_text,
177 const char *tooltip_private_text,
179 GtkSignalFunc callback,
191 struct _GtkToolbarPrivate
196 GtkWidget *arrow_button;
201 GdkWindow *drag_highlight;
204 GdkWindow *event_window;
206 GtkSettings *settings;
209 static GtkContainerClass *parent_class = NULL;
210 static guint toolbar_signals [LAST_SIGNAL] = { 0 };
213 gtk_toolbar_get_type (void)
215 static GtkType type = 0;
219 static const GTypeInfo type_info =
221 sizeof (GtkToolbarClass),
222 (GBaseInitFunc) NULL,
223 (GBaseFinalizeFunc) NULL,
224 (GClassInitFunc) gtk_toolbar_class_init,
225 (GClassFinalizeFunc) NULL,
229 (GInstanceInitFunc) gtk_toolbar_init,
232 type = g_type_register_static (GTK_TYPE_CONTAINER,
241 add_arrow_bindings (GtkBindingSet *binding_set,
243 GtkDirectionType dir)
245 guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
247 gtk_binding_entry_add_signal (binding_set, keysym, 0,
249 GTK_TYPE_DIRECTION_TYPE, dir);
250 gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
252 GTK_TYPE_DIRECTION_TYPE, dir);
256 add_ctrl_tab_bindings (GtkBindingSet *binding_set,
257 GdkModifierType modifiers,
258 GtkDirectionType direction)
260 gtk_binding_entry_add_signal (binding_set,
261 GDK_Tab, GDK_CONTROL_MASK | modifiers,
263 GTK_TYPE_DIRECTION_TYPE, direction);
264 gtk_binding_entry_add_signal (binding_set,
265 GDK_KP_Tab, GDK_CONTROL_MASK | modifiers,
267 GTK_TYPE_DIRECTION_TYPE, direction);
271 gtk_toolbar_class_init (GtkToolbarClass *klass)
273 GObjectClass *gobject_class;
274 GtkWidgetClass *widget_class;
275 GtkContainerClass *container_class;
276 GtkBindingSet *binding_set;
278 parent_class = g_type_class_peek_parent (klass);
280 gobject_class = (GObjectClass *)klass;
281 widget_class = (GtkWidgetClass *)klass;
282 container_class = (GtkContainerClass *)klass;
284 gobject_class->set_property = gtk_toolbar_set_property;
285 gobject_class->get_property = gtk_toolbar_get_property;
286 gobject_class->finalize = gtk_toolbar_finalize;
288 widget_class->button_press_event = gtk_toolbar_button_press;
289 widget_class->expose_event = gtk_toolbar_expose;
290 widget_class->size_request = gtk_toolbar_size_request;
291 widget_class->size_allocate = gtk_toolbar_size_allocate;
292 widget_class->style_set = gtk_toolbar_style_set;
293 widget_class->direction_changed = gtk_toolbar_direction_changed;
294 widget_class->focus = gtk_toolbar_focus;
295 widget_class->screen_changed = gtk_toolbar_screen_changed;
296 widget_class->realize = gtk_toolbar_realize;
297 widget_class->unrealize = gtk_toolbar_unrealize;
298 widget_class->map = gtk_toolbar_map;
299 widget_class->unmap = gtk_toolbar_unmap;
301 widget_class->drag_leave = gtk_toolbar_drag_leave;
302 widget_class->drag_motion = gtk_toolbar_drag_motion;
304 container_class->add = gtk_toolbar_add;
305 container_class->remove = gtk_toolbar_remove;
306 container_class->forall = gtk_toolbar_forall;
307 container_class->child_type = gtk_toolbar_child_type;
308 container_class->get_child_property = gtk_toolbar_get_child_property;
309 container_class->set_child_property = gtk_toolbar_set_child_property;
311 klass->orientation_changed = gtk_toolbar_real_orientation_changed;
312 klass->style_changed = gtk_toolbar_real_style_changed;
314 toolbar_signals[ORIENTATION_CHANGED] =
315 g_signal_new ("orientation_changed",
316 G_OBJECT_CLASS_TYPE (klass),
318 G_STRUCT_OFFSET (GtkToolbarClass, orientation_changed),
320 g_cclosure_marshal_VOID__ENUM,
322 GTK_TYPE_ORIENTATION);
323 toolbar_signals[STYLE_CHANGED] =
324 g_signal_new ("style_changed",
325 G_OBJECT_CLASS_TYPE (klass),
327 G_STRUCT_OFFSET (GtkToolbarClass, style_changed),
329 g_cclosure_marshal_VOID__ENUM,
331 GTK_TYPE_TOOLBAR_STYLE);
332 toolbar_signals[POPUP_CONTEXT_MENU] =
333 g_signal_new ("popup_context_menu",
334 G_OBJECT_CLASS_TYPE (klass),
336 G_STRUCT_OFFSET (GtkToolbarClass, popup_context_menu),
338 _gtk_marshal_VOID__INT_INT_INT,
340 toolbar_signals[MOVE_FOCUS] =
341 _gtk_binding_signal_new ("move_focus",
342 G_TYPE_FROM_CLASS (klass),
343 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
344 G_CALLBACK (gtk_toolbar_move_focus),
346 _gtk_marshal_BOOLEAN__ENUM,
348 GTK_TYPE_DIRECTION_TYPE);
349 toolbar_signals[FOCUS_HOME_OR_END] =
350 _gtk_binding_signal_new ("focus_home_or_end",
351 G_OBJECT_CLASS_TYPE (klass),
352 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
353 G_CALLBACK (gtk_toolbar_focus_home_or_end),
355 _gtk_marshal_BOOLEAN__BOOLEAN,
360 g_object_class_install_property (gobject_class,
362 g_param_spec_enum ("orientation",
364 _("The orientation of the toolbar"),
365 GTK_TYPE_ORIENTATION,
366 GTK_ORIENTATION_HORIZONTAL,
369 g_object_class_install_property (gobject_class,
371 g_param_spec_enum ("toolbar_style",
373 _("How to draw the toolbar"),
374 GTK_TYPE_TOOLBAR_STYLE,
377 g_object_class_install_property (gobject_class,
379 g_param_spec_boolean ("show_arrow",
381 _("If an arrow should be shown if the toolbar doesn't fit"),
385 /* child properties */
386 gtk_container_class_install_child_property (container_class,
388 g_param_spec_boolean ("expand",
390 _("Whether the item should receive extra space when the toolbar grows"),
394 gtk_container_class_install_child_property (container_class,
395 CHILD_PROP_HOMOGENEOUS,
396 g_param_spec_boolean ("homogeneous",
398 _("Whether the item should be the same size as other homogeneous items"),
402 gtk_container_class_install_child_property (container_class,
404 g_param_spec_uint ("pack_end",
406 _("Whether the item is positioned at the end of the toolbar"),
410 /* style properties */
411 gtk_widget_class_install_style_property (widget_class,
412 g_param_spec_int ("space_size",
414 _("Size of spacers"),
420 gtk_widget_class_install_style_property (widget_class,
421 g_param_spec_int ("internal_padding",
422 _("Internal padding"),
423 _("Amount of border space between the toolbar shadow and the buttons"),
429 gtk_widget_class_install_style_property (widget_class,
430 g_param_spec_enum ("space_style",
432 _("Whether spacers are vertical lines or just blank"),
433 GTK_TYPE_TOOLBAR_SPACE_STYLE,
437 gtk_widget_class_install_style_property (widget_class,
438 g_param_spec_enum ("button_relief",
440 _("Type of bevel around toolbar buttons"),
441 GTK_TYPE_RELIEF_STYLE,
444 gtk_widget_class_install_style_property (widget_class,
445 g_param_spec_enum ("shadow_type",
447 _("Style of bevel around the toolbar"),
448 GTK_TYPE_SHADOW_TYPE,
452 gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-style",
454 _("Whether default toolbars have text only, text and icons, icons only, etc."),
455 GTK_TYPE_TOOLBAR_STYLE,
456 DEFAULT_TOOLBAR_STYLE,
459 gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-icon-size",
460 _("Toolbar icon size"),
461 _("Size of icons in default toolbars"),
466 binding_set = gtk_binding_set_by_class (klass);
468 add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
469 add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
470 add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
471 add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
473 gtk_binding_entry_add_signal (binding_set, GDK_KP_Home, 0,
474 "focus_home_or_end", 1,
475 G_TYPE_BOOLEAN, TRUE);
476 gtk_binding_entry_add_signal (binding_set, GDK_Home, 0,
477 "focus_home_or_end", 1,
478 G_TYPE_BOOLEAN, TRUE);
479 gtk_binding_entry_add_signal (binding_set, GDK_KP_End, 0,
480 "focus_home_or_end", 1,
481 G_TYPE_BOOLEAN, FALSE);
482 gtk_binding_entry_add_signal (binding_set, GDK_End, 0,
483 "focus_home_or_end", 1,
484 G_TYPE_BOOLEAN, FALSE);
486 add_ctrl_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
487 add_ctrl_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
489 g_type_class_add_private (gobject_class, sizeof (GtkToolbarPrivate));
493 gtk_toolbar_init (GtkToolbar *toolbar)
495 GtkToolbarPrivate *priv;
497 GTK_WIDGET_UNSET_FLAGS (toolbar, GTK_CAN_FOCUS);
498 GTK_WIDGET_SET_FLAGS (toolbar, GTK_NO_WINDOW);
500 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
502 toolbar->orientation = GTK_ORIENTATION_HORIZONTAL;
503 toolbar->style = DEFAULT_TOOLBAR_STYLE;
504 toolbar->icon_size = DEFAULT_ICON_SIZE;
505 toolbar->tooltips = gtk_tooltips_new ();
506 g_object_ref (toolbar->tooltips);
507 gtk_object_sink (GTK_OBJECT (toolbar->tooltips));
509 priv->arrow_button = gtk_toggle_button_new ();
510 g_signal_connect (priv->arrow_button, "button_press_event",
511 G_CALLBACK (gtk_toolbar_arrow_button_press), toolbar);
512 g_signal_connect (priv->arrow_button, "clicked",
513 G_CALLBACK (gtk_toolbar_arrow_button_clicked), toolbar);
514 gtk_button_set_relief (GTK_BUTTON (priv->arrow_button),
515 get_button_relief (toolbar));
517 priv->api_mode = DONT_KNOW;
519 gtk_button_set_focus_on_click (GTK_BUTTON (priv->arrow_button), FALSE);
521 priv->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
522 gtk_widget_show (priv->arrow);
523 gtk_container_add (GTK_CONTAINER (priv->arrow_button), priv->arrow);
525 gtk_widget_set_parent (priv->arrow_button, GTK_WIDGET (toolbar));
527 /* which child position a drop will occur at */
528 priv->drop_index = -1;
529 priv->drag_highlight = NULL;
533 priv->settings = NULL;
537 toolbar_item_visible (GtkToolbar *toolbar,
540 if (GTK_WIDGET_VISIBLE (item) &&
541 ((toolbar->orientation == GTK_ORIENTATION_HORIZONTAL && item->visible_horizontal) ||
542 (toolbar->orientation == GTK_ORIENTATION_VERTICAL && item->visible_vertical)))
544 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
546 /* With the old toolbar you could hide a button by calling gtk_widget_hide()
547 * on it. This doesn't work with the new API because the GtkToolItem will not be
550 if (priv->api_mode == OLD_API)
552 GtkWidget *bin_child = GTK_BIN (item)->child;
554 if (bin_child && !GTK_WIDGET_VISIBLE (bin_child))
565 gtk_toolbar_set_property (GObject *object,
570 GtkToolbar *toolbar = GTK_TOOLBAR (object);
574 case PROP_ORIENTATION:
575 gtk_toolbar_set_orientation (toolbar, g_value_get_enum (value));
577 case PROP_TOOLBAR_STYLE:
578 gtk_toolbar_set_style (toolbar, g_value_get_enum (value));
580 case PROP_SHOW_ARROW:
581 gtk_toolbar_set_show_arrow (toolbar, g_value_get_boolean (value));
584 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
590 gtk_toolbar_get_property (GObject *object,
595 GtkToolbar *toolbar = GTK_TOOLBAR (object);
596 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
600 case PROP_ORIENTATION:
601 g_value_set_enum (value, toolbar->orientation);
603 case PROP_TOOLBAR_STYLE:
604 g_value_set_enum (value, toolbar->style);
606 case PROP_SHOW_ARROW:
607 g_value_set_boolean (value, priv->show_arrow);
610 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
616 gtk_toolbar_map (GtkWidget *widget)
618 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
620 GTK_WIDGET_CLASS (parent_class)->map (widget);
622 if (priv->event_window)
623 gdk_window_show_unraised (priv->event_window);
627 gtk_toolbar_unmap (GtkWidget *widget)
629 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
631 if (priv->event_window)
632 gdk_window_hide (priv->event_window);
634 GTK_WIDGET_CLASS (parent_class)->unmap (widget);
638 gtk_toolbar_paint_space_line (GtkWidget *widget,
643 GtkAllocation *allocation;
646 g_return_if_fail (GTK_BIN (item)->child == NULL);
648 toolbar = GTK_TOOLBAR (widget);
650 allocation = >K_WIDGET (item)->allocation;
651 space_size = get_space_size (toolbar);
653 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
654 gtk_paint_vline (widget->style, widget->window,
655 GTK_WIDGET_STATE (widget), area, widget,
657 allocation->y + allocation->height *
658 SPACE_LINE_START / SPACE_LINE_DIVISION,
659 allocation->y + allocation->height *
660 SPACE_LINE_END / SPACE_LINE_DIVISION,
661 allocation->x + (space_size-widget->style->xthickness)/2);
662 else if (toolbar->orientation == GTK_ORIENTATION_VERTICAL)
663 gtk_paint_hline (widget->style, widget->window,
664 GTK_WIDGET_STATE (widget), area, widget,
666 allocation->x + allocation->width *
667 SPACE_LINE_START / SPACE_LINE_DIVISION,
668 allocation->x + allocation->width *
669 SPACE_LINE_END / SPACE_LINE_DIVISION,
670 allocation->y + (space_size-widget->style->ythickness)/2);
674 gtk_toolbar_realize (GtkWidget *widget)
676 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
677 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
679 GdkWindowAttr attributes;
680 gint attributes_mask;
683 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
685 border_width = GTK_CONTAINER (widget)->border_width;
687 attributes.wclass = GDK_INPUT_ONLY;
688 attributes.window_type = GDK_WINDOW_CHILD;
689 attributes.x = widget->allocation.x + border_width;
690 attributes.y = widget->allocation.y + border_width;
691 attributes.width = widget->allocation.width - border_width * 2;
692 attributes.height = widget->allocation.height - border_width * 2;
693 attributes.event_mask = gtk_widget_get_events (widget);
694 /* FIXME: does GDK_EXPOSURE_MASK make sense for an input-only window?
695 * If it doesn't, then it should be removed here and in gtkbutton.c,
696 * gtkmenuitem.c, and maybe other places
698 attributes.event_mask |= (GDK_EXPOSURE_MASK |
699 GDK_BUTTON_PRESS_MASK |
700 GDK_BUTTON_RELEASE_MASK |
701 GDK_ENTER_NOTIFY_MASK |
702 GDK_LEAVE_NOTIFY_MASK);
704 attributes_mask = GDK_WA_X | GDK_WA_Y;
706 widget->window = gtk_widget_get_parent_window (widget);
707 g_object_ref (widget->window);
708 widget->style = gtk_style_attach (widget->style, widget->window);
710 priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget),
711 &attributes, attributes_mask);
712 gdk_window_set_user_data (priv->event_window, toolbar);
716 gtk_toolbar_unrealize (GtkWidget *widget)
718 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
720 if (priv->drag_highlight)
722 gdk_window_set_user_data (priv->drag_highlight, NULL);
723 gdk_window_destroy (priv->drag_highlight);
724 priv->drag_highlight = NULL;
727 if (priv->event_window)
729 gdk_window_set_user_data (priv->event_window, NULL);
730 gdk_window_destroy (priv->event_window);
731 priv->event_window = NULL;
734 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
735 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
739 gtk_toolbar_expose (GtkWidget *widget,
740 GdkEventExpose *event)
742 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
743 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
748 border_width = GTK_CONTAINER (widget)->border_width;
750 if (GTK_WIDGET_DRAWABLE (widget))
752 GtkShadowType shadow_type;
754 gtk_widget_style_get (widget, "shadow_type", &shadow_type, NULL);
756 gtk_paint_box (widget->style,
758 GTK_WIDGET_STATE (widget),
760 &event->area, widget, "toolbar",
761 border_width + widget->allocation.x,
762 border_width + widget->allocation.y,
763 widget->allocation.width - 2 * border_width,
764 widget->allocation.height - 2 * border_width);
770 GtkToolItem *item = GTK_TOOL_ITEM (items->data);
772 if (GTK_BIN (item)->child)
773 gtk_container_propagate_expose (GTK_CONTAINER (widget),
776 else if (GTK_WIDGET_MAPPED (item) && get_space_style (toolbar) == GTK_TOOLBAR_SPACE_LINE)
777 gtk_toolbar_paint_space_line (widget, &event->area, item);
782 gtk_container_propagate_expose (GTK_CONTAINER (widget),
790 gtk_toolbar_size_request (GtkWidget *widget,
791 GtkRequisition *requisition)
793 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
794 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
795 gint space_size = get_space_size (toolbar);
797 gint max_child_height;
798 gint max_child_width;
799 gint max_homogeneous_child_width;
800 gint max_homogeneous_child_height;
801 gint homogeneous_size;
804 gint pack_front_size;
806 GtkRequisition arrow_requisition;
808 max_homogeneous_child_width = 0;
809 max_homogeneous_child_height = 0;
811 max_child_height = 0;
812 for (list = priv->items; list != NULL; list = list->next)
814 GtkRequisition requisition;
815 GtkToolItem *item = list->data;
817 if (!toolbar_item_visible (toolbar, item))
820 gtk_widget_size_request (GTK_WIDGET (item), &requisition);
822 max_child_width = MAX (max_child_width, requisition.width);
823 max_child_height = MAX (max_child_height, requisition.height);
825 if (GTK_TOOL_ITEM (item)->homogeneous && GTK_BIN (item)->child)
827 max_homogeneous_child_width = MAX (max_homogeneous_child_width, requisition.width);
828 max_homogeneous_child_height = MAX (max_homogeneous_child_height, requisition.height);
832 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
833 homogeneous_size = max_homogeneous_child_width;
835 homogeneous_size = max_homogeneous_child_height;
839 for (list = priv->items; list != NULL; list = list->next)
841 GtkToolItem *item = list->data;
844 if (!toolbar_item_visible (toolbar, item))
847 if (!GTK_BIN (item)->child)
851 else if (item->homogeneous)
853 size = homogeneous_size;
857 GtkRequisition requisition;
859 gtk_widget_size_request (GTK_WIDGET (item), &requisition);
861 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
862 size = requisition.width;
864 size = requisition.height;
868 pack_end_size += size;
870 pack_front_size += size;
873 if (priv->show_arrow)
875 gtk_widget_size_request (priv->arrow_button, &arrow_requisition);
877 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
878 long_req = arrow_requisition.width;
880 long_req = arrow_requisition.height;
882 /* There is no point requesting space for the arrow if that would take
883 * up more space than all the items combined
885 long_req = MIN (long_req, pack_front_size + pack_end_size);
889 arrow_requisition.height = 0;
890 arrow_requisition.width = 0;
892 long_req = pack_end_size + pack_front_size;
895 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
897 requisition->width = long_req;
898 requisition->height = MAX (max_child_height, arrow_requisition.height);
902 requisition->height = long_req;
903 requisition->width = MAX (max_child_width, arrow_requisition.width);
907 ipadding = get_internal_padding (toolbar);
909 requisition->width += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width);
910 requisition->height += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width);
912 toolbar->button_maxw = max_homogeneous_child_width;
913 toolbar->button_maxh = max_homogeneous_child_height;
917 fixup_allocation_for_rtl (gint total_size,
918 GtkAllocation *allocation)
920 allocation->x += (total_size - (2 * allocation->x + allocation->width));
924 fixup_allocation_for_vertical (GtkAllocation *allocation)
929 allocation->x = allocation->y;
932 tmp = allocation->width;
933 allocation->width = allocation->height;
934 allocation->height = tmp;
938 get_item_size (GtkToolbar *toolbar,
941 GtkRequisition requisition;
942 GtkToolItem *item = GTK_TOOL_ITEM (child);
944 if (!GTK_BIN (item)->child)
945 return get_space_size (toolbar);
947 gtk_widget_get_child_requisition (child, &requisition);
949 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
951 if (item->homogeneous)
952 return toolbar->button_maxw;
954 return requisition.width;
958 if (item->homogeneous)
959 return toolbar->button_maxh;
961 return requisition.height;
966 gtk_toolbar_size_allocate (GtkWidget *widget,
967 GtkAllocation *allocation)
969 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
970 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
972 GtkAllocation *allocations;
973 GtkAllocation arrow_allocation;
975 gint size, pos, short_size;
985 GtkRequisition arrow_requisition;
987 widget->allocation = *allocation;
989 space_size = get_space_size (toolbar);
991 border_width = GTK_CONTAINER (toolbar)->border_width;
993 if (GTK_WIDGET_REALIZED (widget))
995 gdk_window_move_resize (priv->event_window,
996 allocation->x + border_width,
997 allocation->y + border_width,
998 allocation->width - border_width * 2,
999 allocation->height - border_width * 2);
1002 border_width += get_internal_padding (toolbar);
1004 gtk_widget_get_child_requisition (GTK_WIDGET (priv->arrow_button),
1005 &arrow_requisition);
1007 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1009 available_size = size = allocation->width - 2 * border_width;
1010 short_size = allocation->height - 2 * border_width;
1011 arrow_size = arrow_requisition.width;
1015 available_size = size = allocation->height - 2 * border_width;
1016 short_size = allocation->width - 2 * border_width;
1017 arrow_size = arrow_requisition.height;
1020 n_items = g_list_length (priv->items);
1021 allocations = g_new0 (GtkAllocation, n_items);
1024 for (list = priv->items; list != NULL; list = list->next)
1026 GtkToolItem *item = list->data;
1028 if (toolbar_item_visible (toolbar, item))
1029 needed_size += get_item_size (toolbar, GTK_WIDGET (item));
1032 need_arrow = (needed_size > available_size) && priv->show_arrow;
1035 size = available_size - arrow_size;
1037 size = available_size;
1039 items = g_list_copy (priv->items);
1041 /* calculate widths of pack end items */
1042 for (list = g_list_last (items), i = 0; list != NULL; list = list->prev, ++i)
1044 GtkToolItem *item = list->data;
1045 GtkAllocation *allocation = &(allocations[n_items - i - 1]);
1048 if (!item->pack_end || !toolbar_item_visible (toolbar, item))
1051 item_size = get_item_size (toolbar, GTK_WIDGET (item));
1052 if (item_size <= size)
1055 allocation->width = item_size;
1056 item->overflow_item = FALSE;
1064 item->overflow_item = TRUE;
1072 /* calculate widths of pack front items */
1073 for (list = items, i = 0; list != NULL; list = list->next, ++i)
1075 GtkToolItem *item = list->data;
1078 if (item->pack_end || !toolbar_item_visible (toolbar, item))
1081 item_size = get_item_size (toolbar, GTK_WIDGET (item));
1082 if (item_size <= size)
1085 allocations[i].width = item_size;
1086 item->overflow_item = FALSE;
1093 if (!item->pack_end)
1094 item->overflow_item = TRUE;
1103 arrow_allocation.width = arrow_size;
1104 arrow_allocation.height = short_size;
1107 /* expand expandable items */
1109 for (list = priv->items; list != NULL; list = list->next)
1111 GtkToolItem *item = list->data;
1113 if (toolbar_item_visible (toolbar, item) && item->expand &&
1114 !item->overflow_item && GTK_BIN (item)->child)
1120 for (list = items, i = 0; list != NULL; list = list->next, ++i)
1122 GtkToolItem *item = list->data;
1124 if (toolbar_item_visible (toolbar, item) && item->expand &&
1125 !item->overflow_item && GTK_BIN (item)->child)
1127 gint extra = size / n_expand_items;
1128 if (size % n_expand_items != 0)
1131 allocations[i].width += extra;
1137 g_assert (n_expand_items == 0);
1139 /* position pack front items */
1141 for (list = items, i = 0; list != NULL; list = list->next, ++i)
1143 GtkToolItem *item = list->data;
1145 if (toolbar_item_visible (toolbar, item) && !item->overflow_item && !item->pack_end)
1147 allocations[i].x = pos;
1148 allocations[i].y = border_width;
1149 allocations[i].height = short_size;
1151 pos += allocations[i].width;
1155 /* position pack end items */
1156 pos = available_size + border_width;
1157 for (list = g_list_last (items), i = 0; list != NULL; list = list->prev, ++i)
1159 GtkToolItem *item = list->data;
1161 if (toolbar_item_visible (toolbar, item) && !item->overflow_item && item->pack_end)
1163 GtkAllocation *allocation = &(allocations[n_items - i - 1]);
1165 allocation->x = pos - allocation->width;
1166 allocation->y = border_width;
1167 allocation->height = short_size;
1169 pos -= allocation->width;
1173 /* position arrow */
1176 arrow_allocation.x = pos - arrow_allocation.width;
1177 arrow_allocation.y = border_width;
1180 /* fix up allocations in the vertical or RTL cases */
1181 if (toolbar->orientation == GTK_ORIENTATION_VERTICAL)
1183 for (i = 0; i < n_items; ++i)
1184 fixup_allocation_for_vertical (&(allocations[i]));
1187 fixup_allocation_for_vertical (&arrow_allocation);
1189 else if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
1191 for (i = 0; i < n_items; ++i)
1192 fixup_allocation_for_rtl (available_size, &(allocations[i]));
1195 fixup_allocation_for_rtl (available_size, &arrow_allocation);
1198 /* translate the items by allocation->(x,y) */
1199 for (i = 0; i < n_items; ++i)
1201 allocations[i].x += allocation->x;
1202 allocations[i].y += allocation->y;
1207 arrow_allocation.x += allocation->x;
1208 arrow_allocation.y += allocation->y;
1211 /* finally allocate the items */
1212 for (list = items, i = 0; list != NULL; list = list->next, i++)
1214 GtkToolItem *item = list->data;
1216 if (toolbar_item_visible (toolbar, item) && !item->overflow_item)
1218 gtk_widget_size_allocate (GTK_WIDGET (item), &(allocations[i]));
1219 gtk_widget_set_child_visible (GTK_WIDGET (item), TRUE);
1223 gtk_widget_set_child_visible (GTK_WIDGET (item), FALSE);
1229 gtk_widget_size_allocate (GTK_WIDGET (priv->arrow_button),
1231 gtk_widget_show (GTK_WIDGET (priv->arrow_button));
1235 gtk_widget_hide (GTK_WIDGET (priv->arrow_button));
1238 g_free (allocations);
1239 g_list_free (items);
1243 gtk_toolbar_style_set (GtkWidget *widget,
1244 GtkStyle *prev_style)
1246 if (GTK_WIDGET_REALIZED (widget))
1247 gtk_style_set_background (widget->style, widget->window, widget->state);
1250 gtk_toolbar_update_button_relief (GTK_TOOLBAR (widget));
1254 gtk_toolbar_direction_changed (GtkWidget *widget,
1255 GtkTextDirection previous_dir)
1257 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1258 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1260 if (toolbar->orientation == GTK_ORIENTATION_VERTICAL)
1262 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
1263 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
1265 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_LEFT, GTK_SHADOW_NONE);
1268 GTK_WIDGET_CLASS (parent_class)->direction_changed (widget, previous_dir);
1272 gtk_toolbar_list_children_in_focus_order (GtkToolbar *toolbar,
1273 GtkDirectionType dir)
1275 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1276 GList *result = NULL;
1280 /* generate list of children in reverse logical order */
1282 for (list = priv->items; list != NULL; list = list->next)
1284 GtkToolItem *item = list->data;
1285 if (!item->pack_end)
1286 result = g_list_prepend (result, item);
1289 for (list = priv->items; list != NULL; list = list->next)
1291 GtkToolItem *item = list->data;
1294 result = g_list_prepend (result, item);
1297 result = g_list_prepend (result, priv->arrow_button);
1299 rtl = (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL);
1301 /* move in logical order when
1303 * - dir is TAB_FORWARD
1305 * - in RTL mode and moving left or up
1307 * - in LTR mode and moving right or down
1309 if (dir == GTK_DIR_TAB_FORWARD ||
1310 (rtl && (dir == GTK_DIR_UP || dir == GTK_DIR_LEFT)) ||
1311 (!rtl && (dir == GTK_DIR_DOWN || dir == GTK_DIR_RIGHT)))
1313 result = g_list_reverse (result);
1320 gtk_toolbar_focus_home_or_end (GtkToolbar *toolbar,
1321 gboolean focus_home)
1323 GList *children, *list;
1324 GtkDirectionType dir = focus_home? GTK_DIR_RIGHT : GTK_DIR_LEFT;
1326 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1328 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
1330 children = g_list_reverse (children);
1332 dir = (dir == GTK_DIR_RIGHT)? GTK_DIR_LEFT : GTK_DIR_RIGHT;
1335 for (list = children; list != NULL; list = list->next)
1337 GtkWidget *child = list->data;
1339 if (GTK_CONTAINER (toolbar)->focus_child == child)
1342 if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1346 g_list_free (children);
1351 /* Keybinding handler. This function is called when the user presses
1352 * Ctrl TAB or an arrow key.
1355 gtk_toolbar_move_focus (GtkToolbar *toolbar,
1356 GtkDirectionType dir)
1359 gboolean try_focus = FALSE;
1361 GtkContainer *container = GTK_CONTAINER (toolbar);
1363 if (container->focus_child &&
1364 gtk_widget_child_focus (container->focus_child, dir))
1369 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1371 for (list = children; list != NULL; list = list->next)
1373 GtkWidget *child = list->data;
1375 if (try_focus && GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1378 if (child == GTK_CONTAINER (toolbar)->focus_child)
1382 g_list_free (children);
1387 /* The focus handler for the toolbar. It called when the user presses
1388 * TAB or otherwise tries to focus the toolbar.
1391 gtk_toolbar_focus (GtkWidget *widget,
1392 GtkDirectionType dir)
1394 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1395 GList *children, *list;
1397 /* if focus is already somewhere inside the toolbar then return FALSE.
1398 * The only way focus can stay inside the toolbar is when the user presses
1399 * arrow keys or Ctrl TAB (both of which are handled by the
1400 * gtk_toolbar_move_focus() keybinding function.
1402 if (GTK_CONTAINER (widget)->focus_child)
1405 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1407 for (list = children; list != NULL; list = list->next)
1409 GtkWidget *child = list->data;
1411 if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1415 g_list_free (children);
1421 style_change_notify (GtkToolbar *toolbar)
1423 if (!toolbar->style_set)
1425 /* pretend it was set, then unset, thus reverting to new default */
1426 toolbar->style_set = TRUE;
1427 gtk_toolbar_unset_style (toolbar);
1432 icon_size_change_notify (GtkToolbar *toolbar)
1434 if (!toolbar->icon_size_set)
1436 /* pretend it was set, then unset, thus reverting to new default */
1437 toolbar->icon_size_set = TRUE;
1438 gtk_toolbar_unset_icon_size (toolbar);
1442 static GtkSettings *
1443 toolbar_get_settings (GtkToolbar *toolbar)
1445 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1446 return priv->settings;
1450 gtk_toolbar_screen_changed (GtkWidget *widget,
1451 GdkScreen *previous_screen)
1453 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
1454 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1455 GtkSettings *old_settings = toolbar_get_settings (toolbar);
1456 GtkSettings *settings;
1458 if (gtk_widget_has_screen (GTK_WIDGET (toolbar)))
1459 settings = gtk_widget_get_settings (GTK_WIDGET (toolbar));
1463 if (settings == old_settings)
1468 g_signal_handler_disconnect (old_settings, toolbar->style_set_connection);
1469 g_signal_handler_disconnect (old_settings, toolbar->icon_size_connection);
1471 g_object_unref (old_settings);
1476 toolbar->style_set_connection =
1477 g_signal_connect_swapped (settings,
1478 "notify::gtk-toolbar-style",
1479 G_CALLBACK (style_change_notify),
1481 toolbar->icon_size_connection =
1482 g_signal_connect_swapped (settings,
1483 "notify::gtk-toolbar-icon-size",
1484 G_CALLBACK (icon_size_change_notify),
1487 g_object_ref (settings);
1488 priv->settings = settings;
1491 priv->settings = NULL;
1493 style_change_notify (toolbar);
1494 icon_size_change_notify (toolbar);
1498 find_drop_pos (GtkToolbar *toolbar,
1504 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1505 GtkOrientation orientation;
1506 GtkTextDirection direction;
1510 gint best_distance, best_pos, best_index, index;
1512 orientation = toolbar->orientation;
1513 direction = gtk_widget_get_direction (GTK_WIDGET (toolbar));
1514 border_width = GTK_CONTAINER (toolbar)->border_width + get_internal_padding (toolbar);
1516 items = priv->items;
1520 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1522 if (direction == GTK_TEXT_DIR_LTR)
1523 *drop_pos = border_width;
1525 *drop_pos = GTK_WIDGET (toolbar)->allocation.width - border_width;
1529 *drop_pos = border_width;
1534 /* initial conditions */
1535 item = GTK_TOOL_ITEM (items->data);
1537 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1539 if (direction == GTK_TEXT_DIR_LTR)
1540 best_pos = GTK_WIDGET (item)->allocation.x;
1542 best_pos = GTK_WIDGET (item)->allocation.x +
1543 GTK_WIDGET (item)->allocation.width;
1544 best_distance = ABS (best_pos - x);
1548 best_pos = GTK_WIDGET (item)->allocation.y;
1549 best_distance = ABS (best_pos - y);
1555 item = GTK_TOOL_ITEM (items->data);
1557 if (GTK_WIDGET_DRAWABLE (item) && !item->pack_end)
1561 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1563 if (direction == GTK_TEXT_DIR_LTR)
1564 pos = GTK_WIDGET (item)->allocation.x +
1565 GTK_WIDGET (item)->allocation.width;
1567 pos = GTK_WIDGET (item)->allocation.x;
1568 distance = ABS (pos - x);
1572 pos = GTK_WIDGET (item)->allocation.y +
1573 GTK_WIDGET (item)->allocation.height;
1574 distance = ABS (pos - y);
1576 if (distance < best_distance)
1580 best_distance = distance;
1583 items = items->next;
1585 *drop_index = best_index;
1586 *drop_pos = best_pos;
1590 gtk_toolbar_drag_leave (GtkWidget *widget,
1591 GdkDragContext *context,
1594 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1595 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1597 if (priv->drag_highlight)
1599 gdk_window_set_user_data (priv->drag_highlight, NULL);
1600 gdk_window_destroy (priv->drag_highlight);
1601 priv->drag_highlight = NULL;
1604 priv->drop_index = -1;
1608 gtk_toolbar_drag_motion (GtkWidget *widget,
1609 GdkDragContext *context,
1614 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1615 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1616 gint new_index, new_pos;
1618 find_drop_pos(toolbar, x, y, &new_index, &new_pos);
1620 if (!priv->drag_highlight)
1622 GdkWindowAttr attributes;
1623 guint attributes_mask;
1625 attributes.window_type = GDK_WINDOW_CHILD;
1626 attributes.wclass = GDK_INPUT_OUTPUT;
1627 attributes.visual = gtk_widget_get_visual (widget);
1628 attributes.colormap = gtk_widget_get_colormap (widget);
1629 attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK;
1630 attributes.width = 1;
1631 attributes.height = 1;
1632 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
1633 priv->drag_highlight = gdk_window_new (widget->window,
1634 &attributes, attributes_mask);
1635 gdk_window_set_user_data (priv->drag_highlight, widget);
1636 gdk_window_set_background (priv->drag_highlight,
1637 &widget->style->fg[widget->state]);
1640 if (priv->drop_index < 0 ||
1641 priv->drop_index != new_index)
1643 gint border_width = GTK_CONTAINER (toolbar)->border_width;
1644 priv->drop_index = new_index;
1645 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1647 gdk_window_move_resize (priv->drag_highlight,
1648 widget->allocation.x + new_pos - 1,
1649 widget->allocation.y + border_width,
1650 2, widget->allocation.height-border_width*2);
1654 gdk_window_move_resize (priv->drag_highlight,
1655 widget->allocation.x + border_width,
1656 widget->allocation.y + new_pos - 1,
1657 widget->allocation.width-border_width*2, 2);
1661 gdk_window_show (priv->drag_highlight);
1663 gdk_drag_status (context, context->suggested_action, time_);
1669 gtk_toolbar_get_child_property (GtkContainer *container,
1675 GtkToolItem *item = GTK_TOOL_ITEM (child);
1677 switch (property_id)
1679 case CHILD_PROP_PACK_END:
1680 g_value_set_boolean (value, item->pack_end);
1683 case CHILD_PROP_HOMOGENEOUS:
1684 g_value_set_boolean (value, item->homogeneous);
1687 case CHILD_PROP_EXPAND:
1688 g_value_set_boolean (value, item->expand);
1692 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
1698 gtk_toolbar_set_child_property (GtkContainer *container,
1701 const GValue *value,
1704 switch (property_id)
1706 case CHILD_PROP_PACK_END:
1707 gtk_tool_item_set_pack_end (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
1710 case CHILD_PROP_HOMOGENEOUS:
1711 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
1714 case CHILD_PROP_EXPAND:
1715 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
1719 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
1725 gtk_toolbar_add (GtkContainer *container,
1728 GtkToolbar *toolbar;
1730 g_return_if_fail (GTK_IS_TOOLBAR (container));
1731 g_return_if_fail (widget != NULL);
1733 toolbar = GTK_TOOLBAR (container);
1735 if (GTK_IS_TOOL_ITEM (widget))
1736 gtk_toolbar_insert (toolbar, GTK_TOOL_ITEM (widget), 0);
1738 gtk_toolbar_append_widget (toolbar, widget, NULL, NULL);
1742 gtk_toolbar_remove (GtkContainer *container,
1745 GtkToolbar *toolbar;
1746 GtkToolItem *item = NULL;
1748 g_return_if_fail (GTK_IS_TOOLBAR (container));
1750 toolbar = GTK_TOOLBAR (container);
1752 if (GTK_IS_TOOL_ITEM (widget))
1754 item = GTK_TOOL_ITEM (widget);
1758 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1761 for (list = priv->items; list != NULL; list = list->next)
1763 if (GTK_BIN (list->data)->child == widget)
1771 g_return_if_fail (item != NULL);
1773 gtk_toolbar_remove_tool_item (GTK_TOOLBAR (container), item);
1777 gtk_toolbar_forall (GtkContainer *container,
1778 gboolean include_internals,
1779 GtkCallback callback,
1780 gpointer callback_data)
1782 GtkToolbar *toolbar = GTK_TOOLBAR (container);
1783 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1786 g_return_if_fail (callback != NULL);
1788 items = priv->items;
1792 GtkToolItem *item = GTK_TOOL_ITEM (items->data);
1794 items = items->next;
1796 (*callback) (GTK_WIDGET (item), callback_data);
1799 if (include_internals)
1800 (* callback) (priv->arrow_button, callback_data);
1804 gtk_toolbar_child_type (GtkContainer *container)
1806 return GTK_TYPE_TOOL_ITEM;
1810 gtk_toolbar_reconfigured (GtkToolbar *toolbar)
1812 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1815 items = priv->items;
1818 GtkToolItem *item = GTK_TOOL_ITEM (items->data);
1820 gtk_tool_item_toolbar_reconfigured (item);
1822 items = items->next;
1827 gtk_toolbar_real_orientation_changed (GtkToolbar *toolbar,
1828 GtkOrientation orientation)
1830 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1831 if (toolbar->orientation != orientation)
1833 toolbar->orientation = orientation;
1835 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1836 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_DOWN, GTK_SHADOW_NONE);
1837 else if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
1838 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
1840 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_LEFT, GTK_SHADOW_NONE);
1842 gtk_toolbar_reconfigured (toolbar);
1844 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
1845 g_object_notify (G_OBJECT (toolbar), "orientation");
1850 gtk_toolbar_real_style_changed (GtkToolbar *toolbar,
1851 GtkToolbarStyle style)
1853 if (toolbar->style != style)
1855 toolbar->style = style;
1857 gtk_toolbar_reconfigured (toolbar);
1859 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
1860 g_object_notify (G_OBJECT (toolbar), "toolbar_style");
1865 menu_position_func (GtkMenu *menu,
1871 GtkToolbar *toolbar = GTK_TOOLBAR (user_data);
1872 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1874 GtkRequisition menu_req;
1876 gdk_window_get_origin (GTK_BUTTON (priv->arrow_button)->event_window, x, y);
1877 gtk_widget_size_request (priv->arrow_button, &req);
1878 gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
1880 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1882 *y += priv->arrow_button->allocation.height;
1883 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
1884 *x += priv->arrow_button->allocation.width - req.width;
1886 *x += req.width - menu_req.width;
1890 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
1891 *x += priv->arrow_button->allocation.width;
1893 *x -= menu_req.width;
1894 *y += priv->arrow_button->allocation.height - req.height;
1901 menu_deactivated (GtkWidget *menu,
1902 GtkToolbar *toolbar)
1904 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1906 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->arrow_button), FALSE);
1910 remove_item (GtkWidget *menu_item,
1913 gtk_container_remove (GTK_CONTAINER (menu_item->parent), menu_item);
1917 show_menu (GtkToolbar *toolbar,
1918 GdkEventButton *event)
1920 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1925 gtk_container_foreach (GTK_CONTAINER (priv->menu), remove_item, NULL);
1926 gtk_widget_destroy (GTK_WIDGET (priv->menu));
1929 priv->menu = GTK_MENU (gtk_menu_new ());
1930 g_signal_connect (priv->menu, "deactivate", G_CALLBACK (menu_deactivated), toolbar);
1932 for (list = priv->items; list != NULL; list = list->next)
1934 GtkToolItem *item = list->data;
1936 if (toolbar_item_visible (toolbar, item) && item->overflow_item)
1938 GtkWidget *menu_item = gtk_tool_item_retrieve_proxy_menu_item (item);
1942 g_assert (GTK_IS_MENU_ITEM (menu_item));
1943 gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), menu_item);
1948 gtk_widget_show_all (GTK_WIDGET (priv->menu));
1950 gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL,
1951 menu_position_func, toolbar,
1952 event? event->button : 0, event? event->time : gtk_get_current_event_time());
1956 gtk_toolbar_arrow_button_clicked (GtkWidget *button,
1957 GtkToolbar *toolbar)
1959 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1961 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->arrow_button)) &&
1962 (!priv->menu || !GTK_WIDGET_VISIBLE (GTK_WIDGET (priv->menu))))
1964 /* We only get here when the button is clicked with the keybaord,
1965 * because mouse button presses result in the menu being shown so
1966 * that priv->menu would be non-NULL and visible.
1968 show_menu (toolbar, NULL);
1969 gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->menu), FALSE);
1974 gtk_toolbar_arrow_button_press (GtkWidget *button,
1975 GdkEventButton *event,
1976 GtkToolbar *toolbar)
1978 show_menu (toolbar, event);
1979 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
1985 gtk_toolbar_button_press (GtkWidget *toolbar,
1986 GdkEventButton *event)
1988 if (event->button == 3)
1990 g_signal_emit (toolbar, toolbar_signals[POPUP_CONTEXT_MENU], 0,
1991 (int)event->x_root, (int)event->y_root, event->button, NULL);
1998 gtk_toolbar_update_button_relief (GtkToolbar *toolbar)
2000 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2002 gtk_toolbar_reconfigured (toolbar);
2004 gtk_button_set_relief (GTK_BUTTON (priv->arrow_button), get_button_relief (toolbar));
2007 static GtkReliefStyle
2008 get_button_relief (GtkToolbar *toolbar)
2010 GtkReliefStyle button_relief = GTK_RELIEF_NORMAL;
2012 gtk_widget_ensure_style (GTK_WIDGET (toolbar));
2014 gtk_widget_style_get (GTK_WIDGET (toolbar),
2015 "button_relief", &button_relief,
2018 return button_relief;
2022 get_space_size (GtkToolbar *toolbar)
2024 gint space_size = DEFAULT_SPACE_SIZE;
2026 gtk_widget_style_get (GTK_WIDGET (toolbar),
2027 "space_size", &space_size,
2033 static GtkToolbarSpaceStyle
2034 get_space_style (GtkToolbar *toolbar)
2036 GtkToolbarSpaceStyle space_style = DEFAULT_SPACE_STYLE;
2038 gtk_widget_style_get (GTK_WIDGET (toolbar),
2039 "space_style", &space_style,
2047 get_internal_padding (GtkToolbar *toolbar)
2051 gtk_widget_style_get (GTK_WIDGET (toolbar),
2052 "internal_padding", &ipadding,
2059 gtk_toolbar_check_old_api (GtkToolbar *toolbar)
2061 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2063 if (priv->api_mode == NEW_API)
2065 g_warning ("mixing deprecated and non-deprecated GtkToolbar API is not allowed");
2069 priv->api_mode = OLD_API;
2074 gtk_toolbar_check_new_api (GtkToolbar *toolbar)
2076 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2078 if (priv->api_mode == OLD_API)
2080 g_warning ("mixing deprecated and non-deprecated GtkToolbar API is not allowed");
2084 priv->api_mode = NEW_API;
2089 gtk_toolbar_insert_tool_item (GtkToolbar *toolbar,
2093 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2095 priv->items = g_list_insert (priv->items, item, pos);
2096 toolbar->num_children++;
2098 gtk_widget_set_parent (GTK_WIDGET (item), GTK_WIDGET (toolbar));
2102 gtk_toolbar_remove_tool_item (GtkToolbar *toolbar,
2105 GtkToolbarPrivate *priv;
2108 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2109 g_return_if_fail (GTK_IS_TOOL_ITEM (item));
2111 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2116 GList *next = tmp->next;
2117 GtkWidget *child = tmp->data;
2119 if (child == GTK_WIDGET (item))
2121 gboolean was_visible;
2123 was_visible = GTK_WIDGET_VISIBLE (item);
2124 gtk_widget_unparent (GTK_WIDGET (item));
2126 priv->items = g_list_remove_link (priv->items, tmp);
2127 toolbar->num_children--;
2129 if (was_visible && GTK_WIDGET_VISIBLE (toolbar))
2130 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2140 gtk_toolbar_new (void)
2142 GtkToolbar *toolbar;
2144 toolbar = g_object_new (GTK_TYPE_TOOLBAR, NULL);
2146 return GTK_WIDGET (toolbar);
2150 gtk_toolbar_insert (GtkToolbar *toolbar,
2154 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2155 g_return_if_fail (GTK_IS_TOOL_ITEM (item));
2157 if (!gtk_toolbar_check_new_api (toolbar))
2160 gtk_toolbar_insert_tool_item (toolbar, item, pos);
2164 gtk_toolbar_get_item_index (GtkToolbar *toolbar,
2167 GtkToolbarPrivate *priv;
2169 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
2170 g_return_val_if_fail (GTK_IS_TOOL_ITEM (item), -1);
2172 if (!gtk_toolbar_check_new_api (toolbar))
2175 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2176 g_return_val_if_fail (g_list_find (priv->items, item) != NULL, -1);
2178 return g_list_index (priv->items, item);
2182 gtk_toolbar_set_orientation (GtkToolbar *toolbar,
2183 GtkOrientation orientation)
2185 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2187 g_signal_emit (toolbar, toolbar_signals[ORIENTATION_CHANGED], 0, orientation);
2191 gtk_toolbar_get_orientation (GtkToolbar *toolbar)
2193 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_ORIENTATION_HORIZONTAL);
2195 return toolbar->orientation;
2199 gtk_toolbar_set_style (GtkToolbar *toolbar,
2200 GtkToolbarStyle style)
2202 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2204 toolbar->style_set = TRUE;
2205 g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
2211 gtk_toolbar_get_style (GtkToolbar *toolbar)
2213 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), DEFAULT_TOOLBAR_STYLE);
2215 return toolbar->style;
2219 gtk_toolbar_unset_style (GtkToolbar *toolbar)
2221 GtkToolbarStyle style;
2223 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2225 if (toolbar->style_set)
2227 GtkSettings *settings = toolbar_get_settings (toolbar);
2230 g_object_get (settings,
2231 "gtk-toolbar-style", &style,
2234 style = DEFAULT_TOOLBAR_STYLE;
2236 if (style != toolbar->style)
2237 g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
2239 toolbar->style_set = FALSE;
2244 gtk_toolbar_set_tooltips (GtkToolbar *toolbar,
2247 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2250 gtk_tooltips_enable (toolbar->tooltips);
2252 gtk_tooltips_disable (toolbar->tooltips);
2256 gtk_toolbar_get_tooltips (GtkToolbar *toolbar)
2258 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2260 return toolbar->tooltips->enabled;
2264 gtk_toolbar_get_n_items (GtkToolbar *toolbar)
2266 GtkToolbarPrivate *priv;
2268 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
2270 if (!gtk_toolbar_check_new_api (toolbar))
2273 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2275 return g_list_length (priv->items);
2279 * returns NULL if n is out of range
2282 gtk_toolbar_get_nth_item (GtkToolbar *toolbar,
2285 GtkToolbarPrivate *priv;
2287 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
2289 if (!gtk_toolbar_check_new_api (toolbar))
2292 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2294 return g_list_nth_data (priv->items, n);
2298 gtk_toolbar_set_icon_size (GtkToolbar *toolbar,
2299 GtkIconSize icon_size)
2301 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2303 toolbar->icon_size_set = TRUE;
2305 if (toolbar->icon_size == icon_size)
2308 toolbar->icon_size = icon_size;
2310 gtk_toolbar_reconfigured (toolbar);
2312 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2316 gtk_toolbar_get_icon_size (GtkToolbar *toolbar)
2318 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), DEFAULT_ICON_SIZE);
2320 return toolbar->icon_size;
2324 gtk_toolbar_get_relief_style (GtkToolbar *toolbar)
2326 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_RELIEF_NONE);
2328 return get_button_relief (toolbar);
2332 gtk_toolbar_unset_icon_size (GtkToolbar *toolbar)
2336 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2338 if (toolbar->icon_size_set)
2340 GtkSettings *settings = toolbar_get_settings (toolbar);
2344 g_object_get (settings,
2345 "gtk-toolbar-icon-size", &size,
2349 size = DEFAULT_ICON_SIZE;
2351 if (size != toolbar->icon_size)
2352 gtk_toolbar_set_icon_size (toolbar, size);
2354 toolbar->icon_size_set = FALSE;
2359 gtk_toolbar_set_show_arrow (GtkToolbar *toolbar,
2360 gboolean show_arrow)
2362 GtkToolbarPrivate *priv;
2364 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2366 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2367 show_arrow = show_arrow != FALSE;
2369 if (priv->show_arrow != show_arrow)
2371 priv->show_arrow = show_arrow;
2373 if (!priv->show_arrow)
2374 gtk_widget_hide (priv->arrow_button);
2376 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2377 g_object_notify (G_OBJECT (toolbar), "show_arrow");
2382 gtk_toolbar_get_show_arrow (GtkToolbar *toolbar)
2384 GtkToolbarPrivate *priv;
2386 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2388 if (!gtk_toolbar_check_new_api (toolbar))
2391 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2393 return priv->show_arrow;
2397 gtk_toolbar_get_drop_index (GtkToolbar *toolbar,
2401 gint drop_index, drop_pos;
2403 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2405 if (!gtk_toolbar_check_new_api (toolbar))
2408 find_drop_pos (toolbar, x, y, &drop_index, &drop_pos);
2414 gtk_toolbar_append_item (GtkToolbar *toolbar,
2416 const char *tooltip_text,
2417 const char *tooltip_private_text,
2419 GtkSignalFunc callback,
2422 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
2424 tooltip_text, tooltip_private_text,
2425 icon, callback, user_data,
2426 toolbar->num_children);
2430 gtk_toolbar_prepend_item (GtkToolbar *toolbar,
2432 const char *tooltip_text,
2433 const char *tooltip_private_text,
2435 GtkSignalFunc callback,
2438 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
2440 tooltip_text, tooltip_private_text,
2441 icon, callback, user_data,
2446 gtk_toolbar_insert_item (GtkToolbar *toolbar,
2448 const char *tooltip_text,
2449 const char *tooltip_private_text,
2451 GtkSignalFunc callback,
2455 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
2457 tooltip_text, tooltip_private_text,
2458 icon, callback, user_data,
2463 gtk_toolbar_insert_stock (GtkToolbar *toolbar,
2464 const gchar *stock_id,
2465 const char *tooltip_text,
2466 const char *tooltip_private_text,
2467 GtkSignalFunc callback,
2471 return gtk_toolbar_internal_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
2473 tooltip_text, tooltip_private_text,
2474 NULL, callback, user_data,
2479 gtk_toolbar_append_space (GtkToolbar *toolbar)
2481 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
2485 toolbar->num_children);
2489 gtk_toolbar_prepend_space (GtkToolbar *toolbar)
2491 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
2499 gtk_toolbar_insert_space (GtkToolbar *toolbar,
2502 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
2510 gtk_toolbar_remove_space (GtkToolbar *toolbar,
2515 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2517 if (!gtk_toolbar_check_old_api (toolbar))
2520 item = g_list_nth_data (toolbar->children, position);
2524 g_warning ("Toolbar position %d doesn't exist", position);
2528 if (GTK_BIN (item)->child)
2530 g_warning ("Toolbar position %d is not a space", position);
2533 gtk_toolbar_remove_tool_item (toolbar, item);
2537 gtk_toolbar_append_widget (GtkToolbar *toolbar,
2539 const gchar *tooltip_text,
2540 const gchar *tooltip_private_text)
2542 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
2544 tooltip_text, tooltip_private_text,
2546 toolbar->num_children);
2550 gtk_toolbar_prepend_widget (GtkToolbar *toolbar,
2552 const gchar *tooltip_text,
2553 const gchar *tooltip_private_text)
2555 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
2557 tooltip_text, tooltip_private_text,
2563 gtk_toolbar_insert_widget (GtkToolbar *toolbar,
2565 const char *tooltip_text,
2566 const char *tooltip_private_text,
2569 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
2571 tooltip_text, tooltip_private_text,
2577 gtk_toolbar_append_element (GtkToolbar *toolbar,
2578 GtkToolbarChildType type,
2581 const char *tooltip_text,
2582 const char *tooltip_private_text,
2584 GtkSignalFunc callback,
2587 return gtk_toolbar_insert_element (toolbar, type, widget, text,
2588 tooltip_text, tooltip_private_text,
2589 icon, callback, user_data,
2590 toolbar->num_children);
2594 gtk_toolbar_prepend_element (GtkToolbar *toolbar,
2595 GtkToolbarChildType type,
2598 const char *tooltip_text,
2599 const char *tooltip_private_text,
2601 GtkSignalFunc callback,
2604 return gtk_toolbar_insert_element (toolbar, type, widget, text,
2605 tooltip_text, tooltip_private_text,
2606 icon, callback, user_data, 0);
2610 gtk_toolbar_insert_element (GtkToolbar *toolbar,
2611 GtkToolbarChildType type,
2614 const char *tooltip_text,
2615 const char *tooltip_private_text,
2617 GtkSignalFunc callback,
2621 return gtk_toolbar_internal_insert_element (toolbar, type, widget, text,
2622 tooltip_text, tooltip_private_text,
2623 icon, callback, user_data, position, FALSE);
2627 _gtk_toolbar_elide_underscores (const gchar *original)
2631 gboolean last_underscore;
2633 q = result = g_malloc (strlen (original) + 1);
2634 last_underscore = FALSE;
2636 for (p = original; *p; p++)
2638 if (!last_underscore && *p == '_')
2639 last_underscore = TRUE;
2642 last_underscore = FALSE;
2653 gtk_toolbar_internal_insert_element (GtkToolbar *toolbar,
2654 GtkToolbarChildType type,
2657 const char *tooltip_text,
2658 const char *tooltip_private_text,
2660 GtkSignalFunc callback,
2665 GtkToolbarChild *child;
2666 GtkToolItem *item = NULL;
2668 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
2670 if (!gtk_toolbar_check_old_api (toolbar))
2673 if (type == GTK_TOOLBAR_CHILD_WIDGET)
2674 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
2675 else if (type != GTK_TOOLBAR_CHILD_RADIOBUTTON)
2676 g_return_val_if_fail (widget == NULL, NULL);
2678 child = g_new (GtkToolbarChild, 1);
2682 child->label = NULL;
2686 case GTK_TOOLBAR_CHILD_SPACE:
2687 item = gtk_separator_tool_item_new ();
2688 child->widget = NULL;
2691 case GTK_TOOLBAR_CHILD_WIDGET:
2692 item = gtk_tool_item_new ();
2693 child->widget = widget;
2694 gtk_container_add (GTK_CONTAINER (item), child->widget);
2697 case GTK_TOOLBAR_CHILD_BUTTON:
2698 item = gtk_tool_button_new (NULL, NULL);
2699 child->widget = GTK_TOOL_BUTTON (item)->button;
2702 case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
2703 item = gtk_toggle_tool_button_new ();
2704 child->widget = GTK_TOOL_BUTTON (item)->button;
2707 case GTK_TOOLBAR_CHILD_RADIOBUTTON:
2708 item = gtk_radio_tool_button_new (widget
2709 ? gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget))
2711 child->widget = GTK_TOOL_BUTTON (item)->button;
2715 gtk_widget_show (GTK_WIDGET (item));
2717 if (type == GTK_TOOLBAR_CHILD_BUTTON ||
2718 type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
2719 type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
2725 GtkStockItem stock_item;
2728 gtk_tool_button_set_stock_id (GTK_TOOL_BUTTON (item), text);
2730 gtk_stock_lookup (text, &stock_item);
2731 label_text = _gtk_toolbar_elide_underscores (stock_item.label);
2732 child->label = GTK_WIDGET (gtk_label_new (label_text));
2733 g_free (label_text);
2737 child->label = gtk_label_new (text);
2739 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (item), child->label);
2740 gtk_widget_show (child->label);
2746 gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (item), icon);
2748 /* Applications depend on the toolbar showing the widget for them */
2749 gtk_widget_show (GTK_WIDGET (icon));
2753 * We need to connect to the button's clicked callback because some
2754 * programs may rely on that the widget in the callback is a GtkButton
2757 g_signal_connect (child->widget, "clicked",
2758 callback, user_data);
2761 if ((type != GTK_TOOLBAR_CHILD_SPACE) && tooltip_text)
2762 gtk_tool_item_set_tooltip (item, toolbar->tooltips,
2763 tooltip_text, tooltip_private_text);
2765 toolbar->children = g_list_insert (toolbar->children, child, position);
2767 gtk_toolbar_insert_tool_item (toolbar, item, position);
2769 return child->widget;
2773 gtk_toolbar_finalize (GObject *object)
2775 GtkToolbar *toolbar = GTK_TOOLBAR (object);
2777 if (toolbar->tooltips)
2778 g_object_unref (toolbar->tooltips);
2780 G_OBJECT_CLASS (parent_class)->finalize (object);