1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 * GtkToolbar copyright (C) Federico Mena
5 * Copyright (C) 2002 Anders Carlsson <andersca@codefactory.se>
6 * Copyright (C) 2002 James Henstridge <james@daa.com.au>
7 * Copyright (C) 2003 Soeren Sandmann <sandmann@daimi.au.dk>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
26 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
27 * file for a list of people on the GTK+ Team. See the ChangeLog
28 * files for a list of changes. These files are distributed with
29 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
32 #undef GTK_DISABLE_DEPRECATED
35 #include "gtktoolbar.h"
36 #include "gtkradiotoolbutton.h"
37 #include "gtkseparatortoolitem.h"
39 #include "gtkradiobutton.h"
40 #include "gtktoolbar.h"
41 #include "gtkbindings.h"
42 #include <gdk/gdkkeysyms.h>
43 #include "gtkmarshalers.h"
47 #include "gtkprivate.h"
51 #define DEFAULT_IPADDING 0
53 /* note: keep in sync with DEFAULT_SPACE_SIZE and DEFAULT_SPACE_STYLE in gtkseparatortoolitem.c */
54 #define DEFAULT_SPACE_SIZE 5
55 #define DEFAULT_SPACE_STYLE GTK_TOOLBAR_SPACE_LINE
57 #define DEFAULT_ICON_SIZE GTK_ICON_SIZE_LARGE_TOOLBAR
58 #define DEFAULT_TOOLBAR_STYLE GTK_TOOLBAR_BOTH
70 CHILD_PROP_HOMOGENEOUS,
83 static void gtk_toolbar_init (GtkToolbar *toolbar);
84 static void gtk_toolbar_class_init (GtkToolbarClass *klass);
86 static void gtk_toolbar_set_property (GObject *object,
90 static void gtk_toolbar_get_property (GObject *object,
95 static gint gtk_toolbar_expose (GtkWidget *widget,
96 GdkEventExpose *event);
97 static void gtk_toolbar_realize (GtkWidget *widget);
98 static void gtk_toolbar_unrealize (GtkWidget *widget);
99 static void gtk_toolbar_size_request (GtkWidget *widget,
100 GtkRequisition *requisition);
101 static void gtk_toolbar_size_allocate (GtkWidget *widget,
102 GtkAllocation *allocation);
103 static void gtk_toolbar_style_set (GtkWidget *widget,
104 GtkStyle *prev_style);
105 static void gtk_toolbar_direction_changed (GtkWidget *widget,
106 GtkTextDirection previous_direction);
107 static gboolean gtk_toolbar_focus (GtkWidget *widget,
108 GtkDirectionType dir);
109 static void gtk_toolbar_screen_changed (GtkWidget *widget,
110 GdkScreen *previous_screen);
111 static void gtk_toolbar_map (GtkWidget *widget);
112 static void gtk_toolbar_unmap (GtkWidget *widget);
114 static void gtk_toolbar_drag_leave (GtkWidget *widget,
115 GdkDragContext *context,
117 static gboolean gtk_toolbar_drag_motion (GtkWidget *widget,
118 GdkDragContext *context,
122 static void gtk_toolbar_set_child_property (GtkContainer *container,
127 static void gtk_toolbar_get_child_property (GtkContainer *container,
132 static void gtk_toolbar_finalize (GObject *object);
135 static void gtk_toolbar_add (GtkContainer *container,
137 static void gtk_toolbar_remove (GtkContainer *container,
139 static void gtk_toolbar_forall (GtkContainer *container,
140 gboolean include_internals,
141 GtkCallback callback,
142 gpointer callback_data);
143 static GType gtk_toolbar_child_type (GtkContainer *container);
145 static void gtk_toolbar_real_orientation_changed (GtkToolbar *toolbar,
146 GtkOrientation orientation);
147 static void gtk_toolbar_real_style_changed (GtkToolbar *toolbar,
148 GtkToolbarStyle style);
150 static gboolean gtk_toolbar_move_focus (GtkToolbar *toolbar,
151 GtkDirectionType dir);
152 static gboolean gtk_toolbar_focus_home_or_end (GtkToolbar *toolbar,
153 gboolean focus_home);
155 static gboolean gtk_toolbar_button_press (GtkWidget *toolbar,
156 GdkEventButton *event);
157 static gboolean gtk_toolbar_arrow_button_press (GtkWidget *button,
158 GdkEventButton *event,
159 GtkToolbar *toolbar);
160 static void gtk_toolbar_arrow_button_clicked (GtkWidget *button,
161 GtkToolbar *toolbar);
162 static void gtk_toolbar_update_button_relief (GtkToolbar *toolbar);
163 static GtkReliefStyle get_button_relief (GtkToolbar *toolbar);
164 static gint get_space_size (GtkToolbar *toolbar);
165 static gint get_internal_padding (GtkToolbar *toolbar);
166 static void gtk_toolbar_remove_tool_item (GtkToolbar *toolbar,
168 static gboolean gtk_toolbar_popup_menu (GtkWidget *toolbar);
170 static GtkWidget *gtk_toolbar_internal_insert_element (GtkToolbar *toolbar,
171 GtkToolbarChildType type,
174 const char *tooltip_text,
175 const char *tooltip_private_text,
177 GtkSignalFunc callback,
189 struct _GtkToolbarPrivate
194 GtkWidget *arrow_button;
199 GdkWindow *drag_highlight;
202 GdkWindow *event_window;
204 GtkSettings *settings;
207 static GtkContainerClass *parent_class = NULL;
208 static guint toolbar_signals [LAST_SIGNAL] = { 0 };
211 gtk_toolbar_get_type (void)
213 static GtkType type = 0;
217 static const GTypeInfo type_info =
219 sizeof (GtkToolbarClass),
220 (GBaseInitFunc) NULL,
221 (GBaseFinalizeFunc) NULL,
222 (GClassInitFunc) gtk_toolbar_class_init,
223 (GClassFinalizeFunc) NULL,
227 (GInstanceInitFunc) gtk_toolbar_init,
230 type = g_type_register_static (GTK_TYPE_CONTAINER,
239 add_arrow_bindings (GtkBindingSet *binding_set,
241 GtkDirectionType dir)
243 guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
245 gtk_binding_entry_add_signal (binding_set, keysym, 0,
247 GTK_TYPE_DIRECTION_TYPE, dir);
248 gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
250 GTK_TYPE_DIRECTION_TYPE, dir);
254 add_ctrl_tab_bindings (GtkBindingSet *binding_set,
255 GdkModifierType modifiers,
256 GtkDirectionType direction)
258 gtk_binding_entry_add_signal (binding_set,
259 GDK_Tab, GDK_CONTROL_MASK | modifiers,
261 GTK_TYPE_DIRECTION_TYPE, direction);
262 gtk_binding_entry_add_signal (binding_set,
263 GDK_KP_Tab, GDK_CONTROL_MASK | modifiers,
265 GTK_TYPE_DIRECTION_TYPE, direction);
269 gtk_toolbar_class_init (GtkToolbarClass *klass)
271 GObjectClass *gobject_class;
272 GtkWidgetClass *widget_class;
273 GtkContainerClass *container_class;
274 GtkBindingSet *binding_set;
276 parent_class = g_type_class_peek_parent (klass);
278 gobject_class = (GObjectClass *)klass;
279 widget_class = (GtkWidgetClass *)klass;
280 container_class = (GtkContainerClass *)klass;
282 gobject_class->set_property = gtk_toolbar_set_property;
283 gobject_class->get_property = gtk_toolbar_get_property;
284 gobject_class->finalize = gtk_toolbar_finalize;
286 widget_class->button_press_event = gtk_toolbar_button_press;
287 widget_class->expose_event = gtk_toolbar_expose;
288 widget_class->size_request = gtk_toolbar_size_request;
289 widget_class->size_allocate = gtk_toolbar_size_allocate;
290 widget_class->style_set = gtk_toolbar_style_set;
291 widget_class->direction_changed = gtk_toolbar_direction_changed;
292 widget_class->focus = gtk_toolbar_focus;
293 widget_class->screen_changed = gtk_toolbar_screen_changed;
294 widget_class->realize = gtk_toolbar_realize;
295 widget_class->unrealize = gtk_toolbar_unrealize;
296 widget_class->map = gtk_toolbar_map;
297 widget_class->unmap = gtk_toolbar_unmap;
298 widget_class->popup_menu = gtk_toolbar_popup_menu;
300 widget_class->drag_leave = gtk_toolbar_drag_leave;
301 widget_class->drag_motion = gtk_toolbar_drag_motion;
303 container_class->add = gtk_toolbar_add;
304 container_class->remove = gtk_toolbar_remove;
305 container_class->forall = gtk_toolbar_forall;
306 container_class->child_type = gtk_toolbar_child_type;
307 container_class->get_child_property = gtk_toolbar_get_child_property;
308 container_class->set_child_property = gtk_toolbar_set_child_property;
310 klass->orientation_changed = gtk_toolbar_real_orientation_changed;
311 klass->style_changed = gtk_toolbar_real_style_changed;
313 toolbar_signals[ORIENTATION_CHANGED] =
314 g_signal_new ("orientation_changed",
315 G_OBJECT_CLASS_TYPE (klass),
317 G_STRUCT_OFFSET (GtkToolbarClass, orientation_changed),
319 g_cclosure_marshal_VOID__ENUM,
321 GTK_TYPE_ORIENTATION);
322 toolbar_signals[STYLE_CHANGED] =
323 g_signal_new ("style_changed",
324 G_OBJECT_CLASS_TYPE (klass),
326 G_STRUCT_OFFSET (GtkToolbarClass, style_changed),
328 g_cclosure_marshal_VOID__ENUM,
330 GTK_TYPE_TOOLBAR_STYLE);
331 toolbar_signals[POPUP_CONTEXT_MENU] =
332 g_signal_new ("popup_context_menu",
333 G_OBJECT_CLASS_TYPE (klass),
335 G_STRUCT_OFFSET (GtkToolbarClass, popup_context_menu),
336 _gtk_boolean_handled_accumulator, NULL,
337 _gtk_marshal_BOOLEAN__INT_INT_INT,
339 G_TYPE_INT, G_TYPE_INT,
341 toolbar_signals[MOVE_FOCUS] =
342 _gtk_binding_signal_new ("move_focus",
343 G_TYPE_FROM_CLASS (klass),
344 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
345 G_CALLBACK (gtk_toolbar_move_focus),
347 _gtk_marshal_BOOLEAN__ENUM,
349 GTK_TYPE_DIRECTION_TYPE);
350 toolbar_signals[FOCUS_HOME_OR_END] =
351 _gtk_binding_signal_new ("focus_home_or_end",
352 G_OBJECT_CLASS_TYPE (klass),
353 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
354 G_CALLBACK (gtk_toolbar_focus_home_or_end),
356 _gtk_marshal_BOOLEAN__BOOLEAN,
361 g_object_class_install_property (gobject_class,
363 g_param_spec_enum ("orientation",
365 _("The orientation of the toolbar"),
366 GTK_TYPE_ORIENTATION,
367 GTK_ORIENTATION_HORIZONTAL,
370 g_object_class_install_property (gobject_class,
372 g_param_spec_enum ("toolbar_style",
374 _("How to draw the toolbar"),
375 GTK_TYPE_TOOLBAR_STYLE,
378 g_object_class_install_property (gobject_class,
380 g_param_spec_boolean ("show_arrow",
382 _("If an arrow should be shown if the toolbar doesn't fit"),
386 /* child properties */
387 gtk_container_class_install_child_property (container_class,
389 g_param_spec_boolean ("expand",
391 _("Whether the item should receive extra space when the toolbar grows"),
395 gtk_container_class_install_child_property (container_class,
396 CHILD_PROP_HOMOGENEOUS,
397 g_param_spec_boolean ("homogeneous",
399 _("Whether the item should be the same size as other homogeneous items"),
403 gtk_container_class_install_child_property (container_class,
405 g_param_spec_uint ("pack_end",
407 _("Whether the item is positioned at the end of the toolbar"),
411 /* style properties */
412 gtk_widget_class_install_style_property (widget_class,
413 g_param_spec_int ("space_size",
415 _("Size of spacers"),
421 gtk_widget_class_install_style_property (widget_class,
422 g_param_spec_int ("internal_padding",
423 _("Internal padding"),
424 _("Amount of border space between the toolbar shadow and the buttons"),
430 gtk_widget_class_install_style_property (widget_class,
431 g_param_spec_enum ("space_style",
433 _("Whether spacers are vertical lines or just blank"),
434 GTK_TYPE_TOOLBAR_SPACE_STYLE,
438 gtk_widget_class_install_style_property (widget_class,
439 g_param_spec_enum ("button_relief",
441 _("Type of bevel around toolbar buttons"),
442 GTK_TYPE_RELIEF_STYLE,
445 gtk_widget_class_install_style_property (widget_class,
446 g_param_spec_enum ("shadow_type",
448 _("Style of bevel around the toolbar"),
449 GTK_TYPE_SHADOW_TYPE,
453 gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-style",
455 _("Whether default toolbars have text only, text and icons, icons only, etc."),
456 GTK_TYPE_TOOLBAR_STYLE,
457 DEFAULT_TOOLBAR_STYLE,
460 gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-icon-size",
461 _("Toolbar icon size"),
462 _("Size of icons in default toolbars"),
467 binding_set = gtk_binding_set_by_class (klass);
469 add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
470 add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
471 add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
472 add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
474 gtk_binding_entry_add_signal (binding_set, GDK_KP_Home, 0,
475 "focus_home_or_end", 1,
476 G_TYPE_BOOLEAN, TRUE);
477 gtk_binding_entry_add_signal (binding_set, GDK_Home, 0,
478 "focus_home_or_end", 1,
479 G_TYPE_BOOLEAN, TRUE);
480 gtk_binding_entry_add_signal (binding_set, GDK_KP_End, 0,
481 "focus_home_or_end", 1,
482 G_TYPE_BOOLEAN, FALSE);
483 gtk_binding_entry_add_signal (binding_set, GDK_End, 0,
484 "focus_home_or_end", 1,
485 G_TYPE_BOOLEAN, FALSE);
487 add_ctrl_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
488 add_ctrl_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
490 g_type_class_add_private (gobject_class, sizeof (GtkToolbarPrivate));
494 gtk_toolbar_init (GtkToolbar *toolbar)
496 GtkToolbarPrivate *priv;
498 GTK_WIDGET_UNSET_FLAGS (toolbar, GTK_CAN_FOCUS);
499 GTK_WIDGET_SET_FLAGS (toolbar, GTK_NO_WINDOW);
501 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
503 toolbar->orientation = GTK_ORIENTATION_HORIZONTAL;
504 toolbar->style = DEFAULT_TOOLBAR_STYLE;
505 toolbar->icon_size = DEFAULT_ICON_SIZE;
506 toolbar->tooltips = gtk_tooltips_new ();
507 g_object_ref (toolbar->tooltips);
508 gtk_object_sink (GTK_OBJECT (toolbar->tooltips));
510 priv->arrow_button = gtk_toggle_button_new ();
511 g_signal_connect (priv->arrow_button, "button_press_event",
512 G_CALLBACK (gtk_toolbar_arrow_button_press), toolbar);
513 g_signal_connect (priv->arrow_button, "clicked",
514 G_CALLBACK (gtk_toolbar_arrow_button_clicked), toolbar);
515 gtk_button_set_relief (GTK_BUTTON (priv->arrow_button),
516 get_button_relief (toolbar));
518 priv->api_mode = DONT_KNOW;
520 gtk_button_set_focus_on_click (GTK_BUTTON (priv->arrow_button), FALSE);
522 priv->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
523 gtk_widget_show (priv->arrow);
524 gtk_container_add (GTK_CONTAINER (priv->arrow_button), priv->arrow);
526 gtk_widget_set_parent (priv->arrow_button, GTK_WIDGET (toolbar));
528 /* which child position a drop will occur at */
529 priv->drop_index = -1;
530 priv->drag_highlight = NULL;
534 priv->settings = NULL;
538 toolbar_item_visible (GtkToolbar *toolbar,
541 if (GTK_WIDGET_VISIBLE (item) &&
542 ((toolbar->orientation == GTK_ORIENTATION_HORIZONTAL &&
543 gtk_tool_item_get_visible_horizontal (item)) ||
544 (toolbar->orientation == GTK_ORIENTATION_VERTICAL &&
545 gtk_tool_item_get_visible_vertical (item))))
547 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
549 /* With the old toolbar you could hide a button by calling gtk_widget_hide()
550 * on it. This doesn't work with the new API because the GtkToolItem will not be
553 if (priv->api_mode == OLD_API)
555 GtkWidget *bin_child = GTK_BIN (item)->child;
557 if (bin_child && !GTK_WIDGET_VISIBLE (bin_child))
568 toolbar_item_set_is_overflow (GtkToolItem *item,
569 gboolean is_overflow)
571 g_object_set_data (G_OBJECT (item), "gtk-toolbar-item-is-overflow", GINT_TO_POINTER (is_overflow));
575 toolbar_item_get_is_overflow (GtkToolItem *item)
579 result = g_object_get_data (G_OBJECT (item), "gtk-toolbar-item-is-overflow");
581 return GPOINTER_TO_INT (result);
585 gtk_toolbar_set_property (GObject *object,
590 GtkToolbar *toolbar = GTK_TOOLBAR (object);
594 case PROP_ORIENTATION:
595 gtk_toolbar_set_orientation (toolbar, g_value_get_enum (value));
597 case PROP_TOOLBAR_STYLE:
598 gtk_toolbar_set_style (toolbar, g_value_get_enum (value));
600 case PROP_SHOW_ARROW:
601 gtk_toolbar_set_show_arrow (toolbar, g_value_get_boolean (value));
604 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
610 gtk_toolbar_get_property (GObject *object,
615 GtkToolbar *toolbar = GTK_TOOLBAR (object);
616 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
620 case PROP_ORIENTATION:
621 g_value_set_enum (value, toolbar->orientation);
623 case PROP_TOOLBAR_STYLE:
624 g_value_set_enum (value, toolbar->style);
626 case PROP_SHOW_ARROW:
627 g_value_set_boolean (value, priv->show_arrow);
630 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
636 gtk_toolbar_map (GtkWidget *widget)
638 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
640 GTK_WIDGET_CLASS (parent_class)->map (widget);
642 if (priv->event_window)
643 gdk_window_show_unraised (priv->event_window);
647 gtk_toolbar_unmap (GtkWidget *widget)
649 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
651 if (priv->event_window)
652 gdk_window_hide (priv->event_window);
654 GTK_WIDGET_CLASS (parent_class)->unmap (widget);
658 gtk_toolbar_realize (GtkWidget *widget)
660 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
661 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
663 GdkWindowAttr attributes;
664 gint attributes_mask;
667 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
669 border_width = GTK_CONTAINER (widget)->border_width;
671 attributes.wclass = GDK_INPUT_ONLY;
672 attributes.window_type = GDK_WINDOW_CHILD;
673 attributes.x = widget->allocation.x + border_width;
674 attributes.y = widget->allocation.y + border_width;
675 attributes.width = widget->allocation.width - border_width * 2;
676 attributes.height = widget->allocation.height - border_width * 2;
677 attributes.event_mask = gtk_widget_get_events (widget);
678 /* FIXME: does GDK_EXPOSURE_MASK make sense for an input-only window?
679 * If it doesn't, then it should be removed here and in gtkbutton.c,
680 * gtkmenuitem.c, and maybe other places
682 attributes.event_mask |= (GDK_EXPOSURE_MASK |
683 GDK_BUTTON_PRESS_MASK |
684 GDK_BUTTON_RELEASE_MASK |
685 GDK_ENTER_NOTIFY_MASK |
686 GDK_LEAVE_NOTIFY_MASK);
688 attributes_mask = GDK_WA_X | GDK_WA_Y;
690 widget->window = gtk_widget_get_parent_window (widget);
691 g_object_ref (widget->window);
692 widget->style = gtk_style_attach (widget->style, widget->window);
694 priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget),
695 &attributes, attributes_mask);
696 gdk_window_set_user_data (priv->event_window, toolbar);
700 gtk_toolbar_unrealize (GtkWidget *widget)
702 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
704 if (priv->drag_highlight)
706 gdk_window_set_user_data (priv->drag_highlight, NULL);
707 gdk_window_destroy (priv->drag_highlight);
708 priv->drag_highlight = NULL;
711 if (priv->event_window)
713 gdk_window_set_user_data (priv->event_window, NULL);
714 gdk_window_destroy (priv->event_window);
715 priv->event_window = NULL;
718 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
719 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
723 gtk_toolbar_expose (GtkWidget *widget,
724 GdkEventExpose *event)
726 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
727 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
732 border_width = GTK_CONTAINER (widget)->border_width;
734 if (GTK_WIDGET_DRAWABLE (widget))
736 GtkShadowType shadow_type;
738 gtk_widget_style_get (widget, "shadow_type", &shadow_type, NULL);
740 gtk_paint_box (widget->style,
742 GTK_WIDGET_STATE (widget),
744 &event->area, widget, "toolbar",
745 border_width + widget->allocation.x,
746 border_width + widget->allocation.y,
747 widget->allocation.width - 2 * border_width,
748 widget->allocation.height - 2 * border_width);
754 GtkToolItem *item = GTK_TOOL_ITEM (items->data);
756 gtk_container_propagate_expose (GTK_CONTAINER (widget),
763 gtk_container_propagate_expose (GTK_CONTAINER (widget),
771 gtk_toolbar_size_request (GtkWidget *widget,
772 GtkRequisition *requisition)
774 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
775 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
776 gint space_size = get_space_size (toolbar);
778 gint max_child_height;
779 gint max_child_width;
780 gint max_homogeneous_child_width;
781 gint max_homogeneous_child_height;
782 gint homogeneous_size;
785 gint pack_front_size;
787 GtkRequisition arrow_requisition;
789 max_homogeneous_child_width = 0;
790 max_homogeneous_child_height = 0;
792 max_child_height = 0;
793 for (list = priv->items; list != NULL; list = list->next)
795 GtkRequisition requisition;
796 GtkToolItem *item = list->data;
798 if (!toolbar_item_visible (toolbar, item))
801 gtk_widget_size_request (GTK_WIDGET (item), &requisition);
803 max_child_width = MAX (max_child_width, requisition.width);
804 max_child_height = MAX (max_child_height, requisition.height);
806 if (gtk_tool_item_get_homogeneous (item) && GTK_BIN (item)->child)
808 max_homogeneous_child_width = MAX (max_homogeneous_child_width, requisition.width);
809 max_homogeneous_child_height = MAX (max_homogeneous_child_height, requisition.height);
813 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
814 homogeneous_size = max_homogeneous_child_width;
816 homogeneous_size = max_homogeneous_child_height;
820 for (list = priv->items; list != NULL; list = list->next)
822 GtkToolItem *item = list->data;
825 if (!toolbar_item_visible (toolbar, item))
828 if (!GTK_BIN (item)->child)
832 else if (gtk_tool_item_get_homogeneous (item))
834 size = homogeneous_size;
838 GtkRequisition requisition;
840 gtk_widget_size_request (GTK_WIDGET (item), &requisition);
842 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
843 size = requisition.width;
845 size = requisition.height;
848 if (gtk_tool_item_get_pack_end (item))
849 pack_end_size += size;
851 pack_front_size += size;
854 if (priv->show_arrow)
856 gtk_widget_size_request (priv->arrow_button, &arrow_requisition);
858 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
859 long_req = arrow_requisition.width;
861 long_req = arrow_requisition.height;
863 /* There is no point requesting space for the arrow if that would take
864 * up more space than all the items combined
866 long_req = MIN (long_req, pack_front_size + pack_end_size);
870 arrow_requisition.height = 0;
871 arrow_requisition.width = 0;
873 long_req = pack_end_size + pack_front_size;
876 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
878 requisition->width = long_req;
879 requisition->height = MAX (max_child_height, arrow_requisition.height);
883 requisition->height = long_req;
884 requisition->width = MAX (max_child_width, arrow_requisition.width);
888 ipadding = get_internal_padding (toolbar);
890 requisition->width += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width);
891 requisition->height += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width);
893 toolbar->button_maxw = max_homogeneous_child_width;
894 toolbar->button_maxh = max_homogeneous_child_height;
898 fixup_allocation_for_rtl (gint total_size,
899 GtkAllocation *allocation)
901 allocation->x += (total_size - (2 * allocation->x + allocation->width));
905 fixup_allocation_for_vertical (GtkAllocation *allocation)
910 allocation->x = allocation->y;
913 tmp = allocation->width;
914 allocation->width = allocation->height;
915 allocation->height = tmp;
919 get_item_size (GtkToolbar *toolbar,
922 GtkRequisition requisition;
923 GtkToolItem *item = GTK_TOOL_ITEM (child);
925 if (!GTK_BIN (item)->child)
926 return get_space_size (toolbar);
928 gtk_widget_get_child_requisition (child, &requisition);
930 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
932 if (gtk_tool_item_get_homogeneous (item))
933 return toolbar->button_maxw;
935 return requisition.width;
939 if (gtk_tool_item_get_homogeneous (item))
940 return toolbar->button_maxh;
942 return requisition.height;
947 gtk_toolbar_size_allocate (GtkWidget *widget,
948 GtkAllocation *allocation)
950 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
951 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
953 GtkAllocation *allocations;
954 GtkAllocation arrow_allocation;
956 gint size, pos, short_size;
966 GtkRequisition arrow_requisition;
968 widget->allocation = *allocation;
970 space_size = get_space_size (toolbar);
972 border_width = GTK_CONTAINER (toolbar)->border_width;
974 if (GTK_WIDGET_REALIZED (widget))
976 gdk_window_move_resize (priv->event_window,
977 allocation->x + border_width,
978 allocation->y + border_width,
979 allocation->width - border_width * 2,
980 allocation->height - border_width * 2);
983 border_width += get_internal_padding (toolbar);
985 gtk_widget_get_child_requisition (GTK_WIDGET (priv->arrow_button),
988 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
990 available_size = size = allocation->width - 2 * border_width;
991 short_size = allocation->height - 2 * border_width;
992 arrow_size = arrow_requisition.width;
996 available_size = size = allocation->height - 2 * border_width;
997 short_size = allocation->width - 2 * border_width;
998 arrow_size = arrow_requisition.height;
1001 n_items = g_list_length (priv->items);
1002 allocations = g_new0 (GtkAllocation, n_items);
1005 for (list = priv->items; list != NULL; list = list->next)
1007 GtkToolItem *item = list->data;
1009 if (toolbar_item_visible (toolbar, item))
1010 needed_size += get_item_size (toolbar, GTK_WIDGET (item));
1013 need_arrow = (needed_size > available_size) && priv->show_arrow;
1016 size = available_size - arrow_size;
1018 size = available_size;
1020 items = g_list_copy (priv->items);
1022 /* calculate widths of pack end items */
1023 for (list = g_list_last (items), i = 0; list != NULL; list = list->prev, ++i)
1025 GtkToolItem *item = list->data;
1026 GtkAllocation *allocation = &(allocations[n_items - i - 1]);
1029 if (!gtk_tool_item_get_pack_end (item) || !toolbar_item_visible (toolbar, item))
1032 item_size = get_item_size (toolbar, GTK_WIDGET (item));
1033 if (item_size <= size)
1036 allocation->width = item_size;
1037 toolbar_item_set_is_overflow (item, FALSE);
1044 if (gtk_tool_item_get_pack_end (item))
1045 toolbar_item_set_is_overflow (item, TRUE);
1053 /* calculate widths of pack front items */
1054 for (list = items, i = 0; list != NULL; list = list->next, ++i)
1056 GtkToolItem *item = list->data;
1059 if (gtk_tool_item_get_pack_end (item) || !toolbar_item_visible (toolbar, item))
1062 item_size = get_item_size (toolbar, GTK_WIDGET (item));
1063 if (item_size <= size)
1066 allocations[i].width = item_size;
1067 toolbar_item_set_is_overflow (item, FALSE);
1074 if (!gtk_tool_item_get_pack_end (item))
1075 toolbar_item_set_is_overflow (item, TRUE);
1084 arrow_allocation.width = arrow_size;
1085 arrow_allocation.height = short_size;
1088 /* expand expandable items */
1090 for (list = priv->items; list != NULL; list = list->next)
1092 GtkToolItem *item = list->data;
1094 if (toolbar_item_visible (toolbar, item) &&
1095 gtk_tool_item_get_expand (item) &&
1096 !toolbar_item_get_is_overflow (item) && GTK_BIN (item)->child)
1102 for (list = items, i = 0; list != NULL; list = list->next, ++i)
1104 GtkToolItem *item = list->data;
1106 if (toolbar_item_visible (toolbar, item) && gtk_tool_item_get_expand (item) &&
1107 !toolbar_item_get_is_overflow (item) && GTK_BIN (item)->child)
1109 gint extra = size / n_expand_items;
1110 if (size % n_expand_items != 0)
1113 allocations[i].width += extra;
1119 g_assert (n_expand_items == 0);
1121 /* position pack front items */
1123 for (list = items, i = 0; list != NULL; list = list->next, ++i)
1125 GtkToolItem *item = list->data;
1127 if (toolbar_item_visible (toolbar, item) && !toolbar_item_get_is_overflow (item) && !gtk_tool_item_get_pack_end (item))
1129 allocations[i].x = pos;
1130 allocations[i].y = border_width;
1131 allocations[i].height = short_size;
1133 pos += allocations[i].width;
1137 /* position pack end items */
1138 pos = available_size + border_width;
1139 for (list = g_list_last (items), i = 0; list != NULL; list = list->prev, ++i)
1141 GtkToolItem *item = list->data;
1143 if (toolbar_item_visible (toolbar, item) && !toolbar_item_get_is_overflow (item) && gtk_tool_item_get_pack_end (item))
1145 GtkAllocation *allocation = &(allocations[n_items - i - 1]);
1147 allocation->x = pos - allocation->width;
1148 allocation->y = border_width;
1149 allocation->height = short_size;
1151 pos -= allocation->width;
1155 /* position arrow */
1158 arrow_allocation.x = pos - arrow_allocation.width;
1159 arrow_allocation.y = border_width;
1162 /* fix up allocations in the vertical or RTL cases */
1163 if (toolbar->orientation == GTK_ORIENTATION_VERTICAL)
1165 for (i = 0; i < n_items; ++i)
1166 fixup_allocation_for_vertical (&(allocations[i]));
1169 fixup_allocation_for_vertical (&arrow_allocation);
1171 else if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
1173 for (i = 0; i < n_items; ++i)
1174 fixup_allocation_for_rtl (available_size, &(allocations[i]));
1177 fixup_allocation_for_rtl (available_size, &arrow_allocation);
1180 /* translate the items by allocation->(x,y) */
1181 for (i = 0; i < n_items; ++i)
1183 allocations[i].x += allocation->x;
1184 allocations[i].y += allocation->y;
1189 arrow_allocation.x += allocation->x;
1190 arrow_allocation.y += allocation->y;
1193 /* finally allocate the items */
1194 for (list = items, i = 0; list != NULL; list = list->next, i++)
1196 GtkToolItem *item = list->data;
1198 if (toolbar_item_visible (toolbar, item) && !toolbar_item_get_is_overflow (item))
1200 gtk_widget_size_allocate (GTK_WIDGET (item), &(allocations[i]));
1201 gtk_widget_set_child_visible (GTK_WIDGET (item), TRUE);
1205 gtk_widget_set_child_visible (GTK_WIDGET (item), FALSE);
1211 gtk_widget_size_allocate (GTK_WIDGET (priv->arrow_button),
1213 gtk_widget_show (GTK_WIDGET (priv->arrow_button));
1217 gtk_widget_hide (GTK_WIDGET (priv->arrow_button));
1220 g_free (allocations);
1221 g_list_free (items);
1225 gtk_toolbar_style_set (GtkWidget *widget,
1226 GtkStyle *prev_style)
1228 if (GTK_WIDGET_REALIZED (widget))
1229 gtk_style_set_background (widget->style, widget->window, widget->state);
1232 gtk_toolbar_update_button_relief (GTK_TOOLBAR (widget));
1236 gtk_toolbar_direction_changed (GtkWidget *widget,
1237 GtkTextDirection previous_dir)
1239 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1240 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1242 if (toolbar->orientation == GTK_ORIENTATION_VERTICAL)
1244 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
1245 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
1247 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_LEFT, GTK_SHADOW_NONE);
1250 GTK_WIDGET_CLASS (parent_class)->direction_changed (widget, previous_dir);
1254 gtk_toolbar_list_children_in_focus_order (GtkToolbar *toolbar,
1255 GtkDirectionType dir)
1257 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1258 GList *result = NULL;
1262 /* generate list of children in reverse logical order */
1264 for (list = priv->items; list != NULL; list = list->next)
1266 GtkToolItem *item = list->data;
1267 if (!gtk_tool_item_get_pack_end (item))
1268 result = g_list_prepend (result, item);
1271 for (list = priv->items; list != NULL; list = list->next)
1273 GtkToolItem *item = list->data;
1275 if (gtk_tool_item_get_pack_end (item))
1276 result = g_list_prepend (result, item);
1279 result = g_list_prepend (result, priv->arrow_button);
1281 rtl = (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL);
1283 /* move in logical order when
1285 * - dir is TAB_FORWARD
1287 * - in RTL mode and moving left or up
1289 * - in LTR mode and moving right or down
1291 if (dir == GTK_DIR_TAB_FORWARD ||
1292 (rtl && (dir == GTK_DIR_UP || dir == GTK_DIR_LEFT)) ||
1293 (!rtl && (dir == GTK_DIR_DOWN || dir == GTK_DIR_RIGHT)))
1295 result = g_list_reverse (result);
1302 gtk_toolbar_focus_home_or_end (GtkToolbar *toolbar,
1303 gboolean focus_home)
1305 GList *children, *list;
1306 GtkDirectionType dir = focus_home? GTK_DIR_RIGHT : GTK_DIR_LEFT;
1308 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1310 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
1312 children = g_list_reverse (children);
1314 dir = (dir == GTK_DIR_RIGHT)? GTK_DIR_LEFT : GTK_DIR_RIGHT;
1317 for (list = children; list != NULL; list = list->next)
1319 GtkWidget *child = list->data;
1321 if (GTK_CONTAINER (toolbar)->focus_child == child)
1324 if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1328 g_list_free (children);
1333 /* Keybinding handler. This function is called when the user presses
1334 * Ctrl TAB or an arrow key.
1337 gtk_toolbar_move_focus (GtkToolbar *toolbar,
1338 GtkDirectionType dir)
1341 gboolean try_focus = FALSE;
1343 GtkContainer *container = GTK_CONTAINER (toolbar);
1345 if (container->focus_child &&
1346 gtk_widget_child_focus (container->focus_child, dir))
1351 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1353 for (list = children; list != NULL; list = list->next)
1355 GtkWidget *child = list->data;
1357 if (try_focus && GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1360 if (child == GTK_CONTAINER (toolbar)->focus_child)
1364 g_list_free (children);
1369 /* The focus handler for the toolbar. It called when the user presses
1370 * TAB or otherwise tries to focus the toolbar.
1373 gtk_toolbar_focus (GtkWidget *widget,
1374 GtkDirectionType dir)
1376 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1377 GList *children, *list;
1379 /* if focus is already somewhere inside the toolbar then return FALSE.
1380 * The only way focus can stay inside the toolbar is when the user presses
1381 * arrow keys or Ctrl TAB (both of which are handled by the
1382 * gtk_toolbar_move_focus() keybinding function.
1384 if (GTK_CONTAINER (widget)->focus_child)
1387 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1389 for (list = children; list != NULL; list = list->next)
1391 GtkWidget *child = list->data;
1393 if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1397 g_list_free (children);
1403 style_change_notify (GtkToolbar *toolbar)
1405 if (!toolbar->style_set)
1407 /* pretend it was set, then unset, thus reverting to new default */
1408 toolbar->style_set = TRUE;
1409 gtk_toolbar_unset_style (toolbar);
1414 icon_size_change_notify (GtkToolbar *toolbar)
1416 if (!toolbar->icon_size_set)
1418 /* pretend it was set, then unset, thus reverting to new default */
1419 toolbar->icon_size_set = TRUE;
1420 gtk_toolbar_unset_icon_size (toolbar);
1424 static GtkSettings *
1425 toolbar_get_settings (GtkToolbar *toolbar)
1427 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1428 return priv->settings;
1432 gtk_toolbar_screen_changed (GtkWidget *widget,
1433 GdkScreen *previous_screen)
1435 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
1436 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1437 GtkSettings *old_settings = toolbar_get_settings (toolbar);
1438 GtkSettings *settings;
1440 if (gtk_widget_has_screen (GTK_WIDGET (toolbar)))
1441 settings = gtk_widget_get_settings (GTK_WIDGET (toolbar));
1445 if (settings == old_settings)
1450 g_signal_handler_disconnect (old_settings, toolbar->style_set_connection);
1451 g_signal_handler_disconnect (old_settings, toolbar->icon_size_connection);
1453 g_object_unref (old_settings);
1458 toolbar->style_set_connection =
1459 g_signal_connect_swapped (settings,
1460 "notify::gtk-toolbar-style",
1461 G_CALLBACK (style_change_notify),
1463 toolbar->icon_size_connection =
1464 g_signal_connect_swapped (settings,
1465 "notify::gtk-toolbar-icon-size",
1466 G_CALLBACK (icon_size_change_notify),
1469 g_object_ref (settings);
1470 priv->settings = settings;
1473 priv->settings = NULL;
1475 style_change_notify (toolbar);
1476 icon_size_change_notify (toolbar);
1480 find_drop_pos (GtkToolbar *toolbar,
1486 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1487 GtkOrientation orientation;
1488 GtkTextDirection direction;
1492 gint best_distance, best_pos, best_index, index;
1494 orientation = toolbar->orientation;
1495 direction = gtk_widget_get_direction (GTK_WIDGET (toolbar));
1496 border_width = GTK_CONTAINER (toolbar)->border_width + get_internal_padding (toolbar);
1498 items = priv->items;
1502 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1504 if (direction == GTK_TEXT_DIR_LTR)
1505 *drop_pos = border_width;
1507 *drop_pos = GTK_WIDGET (toolbar)->allocation.width - border_width;
1511 *drop_pos = border_width;
1516 /* initial conditions */
1517 item = GTK_TOOL_ITEM (items->data);
1519 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1521 if (direction == GTK_TEXT_DIR_LTR)
1522 best_pos = GTK_WIDGET (item)->allocation.x;
1524 best_pos = GTK_WIDGET (item)->allocation.x +
1525 GTK_WIDGET (item)->allocation.width;
1526 best_distance = ABS (best_pos - x);
1530 best_pos = GTK_WIDGET (item)->allocation.y;
1531 best_distance = ABS (best_pos - y);
1537 item = GTK_TOOL_ITEM (items->data);
1539 if (GTK_WIDGET_DRAWABLE (item) && !gtk_tool_item_get_pack_end (item))
1543 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1545 if (direction == GTK_TEXT_DIR_LTR)
1546 pos = GTK_WIDGET (item)->allocation.x +
1547 GTK_WIDGET (item)->allocation.width;
1549 pos = GTK_WIDGET (item)->allocation.x;
1550 distance = ABS (pos - x);
1554 pos = GTK_WIDGET (item)->allocation.y +
1555 GTK_WIDGET (item)->allocation.height;
1556 distance = ABS (pos - y);
1558 if (distance < best_distance)
1562 best_distance = distance;
1565 items = items->next;
1567 *drop_index = best_index;
1568 *drop_pos = best_pos;
1572 gtk_toolbar_drag_leave (GtkWidget *widget,
1573 GdkDragContext *context,
1576 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1577 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1579 if (priv->drag_highlight)
1581 gdk_window_set_user_data (priv->drag_highlight, NULL);
1582 gdk_window_destroy (priv->drag_highlight);
1583 priv->drag_highlight = NULL;
1586 priv->drop_index = -1;
1590 gtk_toolbar_drag_motion (GtkWidget *widget,
1591 GdkDragContext *context,
1596 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1597 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1598 gint new_index, new_pos;
1600 find_drop_pos(toolbar, x, y, &new_index, &new_pos);
1602 if (!priv->drag_highlight)
1604 GdkWindowAttr attributes;
1605 guint attributes_mask;
1607 attributes.window_type = GDK_WINDOW_CHILD;
1608 attributes.wclass = GDK_INPUT_OUTPUT;
1609 attributes.visual = gtk_widget_get_visual (widget);
1610 attributes.colormap = gtk_widget_get_colormap (widget);
1611 attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK;
1612 attributes.width = 1;
1613 attributes.height = 1;
1614 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
1615 priv->drag_highlight = gdk_window_new (widget->window,
1616 &attributes, attributes_mask);
1617 gdk_window_set_user_data (priv->drag_highlight, widget);
1618 gdk_window_set_background (priv->drag_highlight,
1619 &widget->style->fg[widget->state]);
1622 if (priv->drop_index < 0 ||
1623 priv->drop_index != new_index)
1625 gint border_width = GTK_CONTAINER (toolbar)->border_width;
1626 priv->drop_index = new_index;
1627 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1629 gdk_window_move_resize (priv->drag_highlight,
1630 widget->allocation.x + new_pos - 1,
1631 widget->allocation.y + border_width,
1632 2, widget->allocation.height-border_width*2);
1636 gdk_window_move_resize (priv->drag_highlight,
1637 widget->allocation.x + border_width,
1638 widget->allocation.y + new_pos - 1,
1639 widget->allocation.width-border_width*2, 2);
1643 gdk_window_show (priv->drag_highlight);
1645 gdk_drag_status (context, context->suggested_action, time_);
1651 gtk_toolbar_get_child_property (GtkContainer *container,
1657 GtkToolItem *item = GTK_TOOL_ITEM (child);
1659 switch (property_id)
1661 case CHILD_PROP_PACK_END:
1662 g_value_set_boolean (value, gtk_tool_item_get_pack_end (item));
1665 case CHILD_PROP_HOMOGENEOUS:
1666 g_value_set_boolean (value, gtk_tool_item_get_homogeneous (item));
1669 case CHILD_PROP_EXPAND:
1670 g_value_set_boolean (value, gtk_tool_item_get_expand (item));
1674 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
1680 gtk_toolbar_set_child_property (GtkContainer *container,
1683 const GValue *value,
1686 switch (property_id)
1688 case CHILD_PROP_PACK_END:
1689 gtk_tool_item_set_pack_end (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
1692 case CHILD_PROP_HOMOGENEOUS:
1693 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
1696 case CHILD_PROP_EXPAND:
1697 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
1701 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
1707 gtk_toolbar_add (GtkContainer *container,
1710 GtkToolbar *toolbar;
1712 g_return_if_fail (GTK_IS_TOOLBAR (container));
1713 g_return_if_fail (widget != NULL);
1715 toolbar = GTK_TOOLBAR (container);
1717 if (GTK_IS_TOOL_ITEM (widget))
1718 gtk_toolbar_insert (toolbar, GTK_TOOL_ITEM (widget), 0);
1720 gtk_toolbar_append_widget (toolbar, widget, NULL, NULL);
1724 gtk_toolbar_remove (GtkContainer *container,
1727 GtkToolbar *toolbar;
1728 GtkToolItem *item = NULL;
1730 g_return_if_fail (GTK_IS_TOOLBAR (container));
1731 g_return_if_fail (GTK_IS_WIDGET (widget));
1733 toolbar = GTK_TOOLBAR (container);
1735 if (GTK_IS_TOOL_ITEM (widget))
1737 item = GTK_TOOL_ITEM (widget);
1741 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1744 for (list = priv->items; list != NULL; list = list->next)
1746 if (GTK_BIN (list->data)->child == widget)
1754 g_return_if_fail (item != NULL);
1756 gtk_toolbar_remove_tool_item (GTK_TOOLBAR (container), item);
1760 gtk_toolbar_forall (GtkContainer *container,
1761 gboolean include_internals,
1762 GtkCallback callback,
1763 gpointer callback_data)
1765 GtkToolbar *toolbar = GTK_TOOLBAR (container);
1766 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1769 g_return_if_fail (callback != NULL);
1771 items = priv->items;
1775 GtkToolItem *item = GTK_TOOL_ITEM (items->data);
1777 items = items->next;
1779 (*callback) (GTK_WIDGET (item), callback_data);
1782 if (include_internals)
1783 (* callback) (priv->arrow_button, callback_data);
1787 gtk_toolbar_child_type (GtkContainer *container)
1789 return GTK_TYPE_TOOL_ITEM;
1793 gtk_toolbar_reconfigured (GtkToolbar *toolbar)
1795 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1798 items = priv->items;
1801 GtkToolItem *item = GTK_TOOL_ITEM (items->data);
1803 gtk_tool_item_toolbar_reconfigured (item);
1805 items = items->next;
1810 gtk_toolbar_real_orientation_changed (GtkToolbar *toolbar,
1811 GtkOrientation orientation)
1813 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1814 if (toolbar->orientation != orientation)
1816 toolbar->orientation = orientation;
1818 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1819 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_DOWN, GTK_SHADOW_NONE);
1820 else if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
1821 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
1823 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_LEFT, GTK_SHADOW_NONE);
1825 gtk_toolbar_reconfigured (toolbar);
1827 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
1828 g_object_notify (G_OBJECT (toolbar), "orientation");
1833 gtk_toolbar_real_style_changed (GtkToolbar *toolbar,
1834 GtkToolbarStyle style)
1836 if (toolbar->style != style)
1838 toolbar->style = style;
1840 gtk_toolbar_reconfigured (toolbar);
1842 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
1843 g_object_notify (G_OBJECT (toolbar), "toolbar_style");
1848 menu_position_func (GtkMenu *menu,
1854 GtkToolbar *toolbar = GTK_TOOLBAR (user_data);
1855 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1857 GtkRequisition menu_req;
1859 gdk_window_get_origin (GTK_BUTTON (priv->arrow_button)->event_window, x, y);
1860 gtk_widget_size_request (priv->arrow_button, &req);
1861 gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
1863 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1865 *y += priv->arrow_button->allocation.height;
1866 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
1867 *x += priv->arrow_button->allocation.width - req.width;
1869 *x += req.width - menu_req.width;
1873 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
1874 *x += priv->arrow_button->allocation.width;
1876 *x -= menu_req.width;
1877 *y += priv->arrow_button->allocation.height - req.height;
1884 menu_deactivated (GtkWidget *menu,
1885 GtkToolbar *toolbar)
1887 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1889 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->arrow_button), FALSE);
1893 remove_item (GtkWidget *menu_item,
1896 gtk_container_remove (GTK_CONTAINER (menu_item->parent), menu_item);
1900 show_menu (GtkToolbar *toolbar,
1901 GdkEventButton *event)
1903 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1908 gtk_container_foreach (GTK_CONTAINER (priv->menu), remove_item, NULL);
1909 gtk_widget_destroy (GTK_WIDGET (priv->menu));
1912 priv->menu = GTK_MENU (gtk_menu_new ());
1913 g_signal_connect (priv->menu, "deactivate", G_CALLBACK (menu_deactivated), toolbar);
1915 for (list = priv->items; list != NULL; list = list->next)
1917 GtkToolItem *item = list->data;
1919 if (toolbar_item_visible (toolbar, item) && toolbar_item_get_is_overflow (item))
1921 GtkWidget *menu_item = gtk_tool_item_retrieve_proxy_menu_item (item);
1925 g_assert (GTK_IS_MENU_ITEM (menu_item));
1926 gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), menu_item);
1931 gtk_widget_show_all (GTK_WIDGET (priv->menu));
1933 gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL,
1934 menu_position_func, toolbar,
1935 event? event->button : 0, event? event->time : gtk_get_current_event_time());
1939 gtk_toolbar_arrow_button_clicked (GtkWidget *button,
1940 GtkToolbar *toolbar)
1942 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1944 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->arrow_button)) &&
1945 (!priv->menu || !GTK_WIDGET_VISIBLE (GTK_WIDGET (priv->menu))))
1947 /* We only get here when the button is clicked with the keybaord,
1948 * because mouse button presses result in the menu being shown so
1949 * that priv->menu would be non-NULL and visible.
1951 show_menu (toolbar, NULL);
1952 gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->menu), FALSE);
1957 gtk_toolbar_arrow_button_press (GtkWidget *button,
1958 GdkEventButton *event,
1959 GtkToolbar *toolbar)
1961 show_menu (toolbar, event);
1962 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
1968 gtk_toolbar_button_press (GtkWidget *toolbar,
1969 GdkEventButton *event)
1971 if (event->button == 3)
1973 gboolean return_value;
1975 g_signal_emit (toolbar, toolbar_signals[POPUP_CONTEXT_MENU], 0,
1976 (int)event->x_root, (int)event->y_root, event->button,
1979 return return_value;
1986 gtk_toolbar_popup_menu (GtkWidget *toolbar)
1988 gboolean return_value;
1989 /* This function is the handler for the "popup menu" keybinding,
1990 * ie., it is called when the user presses Shift F10
1992 g_signal_emit (toolbar, toolbar_signals[POPUP_CONTEXT_MENU], 0,
1993 -1, -1, -1, &return_value);
1995 return return_value;
1999 gtk_toolbar_update_button_relief (GtkToolbar *toolbar)
2001 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2003 gtk_toolbar_reconfigured (toolbar);
2005 gtk_button_set_relief (GTK_BUTTON (priv->arrow_button), get_button_relief (toolbar));
2008 static GtkReliefStyle
2009 get_button_relief (GtkToolbar *toolbar)
2011 GtkReliefStyle button_relief = GTK_RELIEF_NORMAL;
2013 gtk_widget_ensure_style (GTK_WIDGET (toolbar));
2015 gtk_widget_style_get (GTK_WIDGET (toolbar),
2016 "button_relief", &button_relief,
2019 return button_relief;
2023 get_space_size (GtkToolbar *toolbar)
2025 gint space_size = DEFAULT_SPACE_SIZE;
2027 gtk_widget_style_get (GTK_WIDGET (toolbar),
2028 "space_size", &space_size,
2035 get_internal_padding (GtkToolbar *toolbar)
2039 gtk_widget_style_get (GTK_WIDGET (toolbar),
2040 "internal_padding", &ipadding,
2047 gtk_toolbar_check_old_api (GtkToolbar *toolbar)
2049 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2051 if (priv->api_mode == NEW_API)
2053 g_warning ("mixing deprecated and non-deprecated GtkToolbar API is not allowed");
2057 priv->api_mode = OLD_API;
2062 gtk_toolbar_check_new_api (GtkToolbar *toolbar)
2064 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2066 if (priv->api_mode == OLD_API)
2068 g_warning ("mixing deprecated and non-deprecated GtkToolbar API is not allowed");
2072 priv->api_mode = NEW_API;
2077 gtk_toolbar_insert_tool_item (GtkToolbar *toolbar,
2081 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2083 priv->items = g_list_insert (priv->items, item, pos);
2084 toolbar->num_children++;
2086 gtk_widget_set_parent (GTK_WIDGET (item), GTK_WIDGET (toolbar));
2090 gtk_toolbar_remove_tool_item (GtkToolbar *toolbar,
2093 GtkToolbarPrivate *priv;
2097 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2098 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2099 g_return_if_fail (GTK_IS_TOOL_ITEM (item));
2100 g_return_if_fail (g_list_find (priv->items, item));
2104 for (tmp = priv->items; tmp != NULL; tmp = tmp->next)
2106 if (tmp->data == item)
2112 priv->items = g_list_remove (priv->items, item);
2114 gtk_widget_unparent (GTK_WIDGET (item));
2116 if (priv->api_mode == OLD_API)
2118 GtkToolbarChild *toolbar_child;
2120 toolbar_child = g_list_nth_data (toolbar->children, nth_child);
2121 toolbar->children = g_list_remove (toolbar->children, toolbar_child);
2123 g_free (toolbar_child);
2126 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2130 gtk_toolbar_new (void)
2132 GtkToolbar *toolbar;
2134 toolbar = g_object_new (GTK_TYPE_TOOLBAR, NULL);
2136 return GTK_WIDGET (toolbar);
2140 gtk_toolbar_insert (GtkToolbar *toolbar,
2144 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2145 g_return_if_fail (GTK_IS_TOOL_ITEM (item));
2147 if (!gtk_toolbar_check_new_api (toolbar))
2150 gtk_toolbar_insert_tool_item (toolbar, item, pos);
2154 gtk_toolbar_get_item_index (GtkToolbar *toolbar,
2157 GtkToolbarPrivate *priv;
2159 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
2160 g_return_val_if_fail (GTK_IS_TOOL_ITEM (item), -1);
2162 if (!gtk_toolbar_check_new_api (toolbar))
2165 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2166 g_return_val_if_fail (g_list_find (priv->items, item) != NULL, -1);
2168 return g_list_index (priv->items, item);
2172 gtk_toolbar_set_orientation (GtkToolbar *toolbar,
2173 GtkOrientation orientation)
2175 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2177 g_signal_emit (toolbar, toolbar_signals[ORIENTATION_CHANGED], 0, orientation);
2181 gtk_toolbar_get_orientation (GtkToolbar *toolbar)
2183 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_ORIENTATION_HORIZONTAL);
2185 return toolbar->orientation;
2189 gtk_toolbar_set_style (GtkToolbar *toolbar,
2190 GtkToolbarStyle style)
2192 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2194 toolbar->style_set = TRUE;
2195 g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
2201 gtk_toolbar_get_style (GtkToolbar *toolbar)
2203 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), DEFAULT_TOOLBAR_STYLE);
2205 return toolbar->style;
2209 gtk_toolbar_unset_style (GtkToolbar *toolbar)
2211 GtkToolbarStyle style;
2213 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2215 if (toolbar->style_set)
2217 GtkSettings *settings = toolbar_get_settings (toolbar);
2220 g_object_get (settings,
2221 "gtk-toolbar-style", &style,
2224 style = DEFAULT_TOOLBAR_STYLE;
2226 if (style != toolbar->style)
2227 g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
2229 toolbar->style_set = FALSE;
2234 gtk_toolbar_set_tooltips (GtkToolbar *toolbar,
2237 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2240 gtk_tooltips_enable (toolbar->tooltips);
2242 gtk_tooltips_disable (toolbar->tooltips);
2246 gtk_toolbar_get_tooltips (GtkToolbar *toolbar)
2248 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2250 return toolbar->tooltips->enabled;
2254 gtk_toolbar_get_n_items (GtkToolbar *toolbar)
2256 GtkToolbarPrivate *priv;
2258 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
2260 if (!gtk_toolbar_check_new_api (toolbar))
2263 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2265 return g_list_length (priv->items);
2269 * returns NULL if n is out of range
2272 gtk_toolbar_get_nth_item (GtkToolbar *toolbar,
2275 GtkToolbarPrivate *priv;
2277 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
2279 if (!gtk_toolbar_check_new_api (toolbar))
2282 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2284 return g_list_nth_data (priv->items, n);
2288 gtk_toolbar_set_icon_size (GtkToolbar *toolbar,
2289 GtkIconSize icon_size)
2291 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2293 toolbar->icon_size_set = TRUE;
2295 if (toolbar->icon_size == icon_size)
2298 toolbar->icon_size = icon_size;
2300 gtk_toolbar_reconfigured (toolbar);
2302 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2306 gtk_toolbar_get_icon_size (GtkToolbar *toolbar)
2308 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), DEFAULT_ICON_SIZE);
2310 return toolbar->icon_size;
2314 gtk_toolbar_get_relief_style (GtkToolbar *toolbar)
2316 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_RELIEF_NONE);
2318 return get_button_relief (toolbar);
2322 gtk_toolbar_unset_icon_size (GtkToolbar *toolbar)
2326 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2328 if (toolbar->icon_size_set)
2330 GtkSettings *settings = toolbar_get_settings (toolbar);
2334 g_object_get (settings,
2335 "gtk-toolbar-icon-size", &size,
2339 size = DEFAULT_ICON_SIZE;
2341 if (size != toolbar->icon_size)
2342 gtk_toolbar_set_icon_size (toolbar, size);
2344 toolbar->icon_size_set = FALSE;
2349 gtk_toolbar_set_show_arrow (GtkToolbar *toolbar,
2350 gboolean show_arrow)
2352 GtkToolbarPrivate *priv;
2354 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2356 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2357 show_arrow = show_arrow != FALSE;
2359 if (priv->show_arrow != show_arrow)
2361 priv->show_arrow = show_arrow;
2363 if (!priv->show_arrow)
2364 gtk_widget_hide (priv->arrow_button);
2366 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2367 g_object_notify (G_OBJECT (toolbar), "show_arrow");
2372 gtk_toolbar_get_show_arrow (GtkToolbar *toolbar)
2374 GtkToolbarPrivate *priv;
2376 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2378 if (!gtk_toolbar_check_new_api (toolbar))
2381 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2383 return priv->show_arrow;
2387 gtk_toolbar_get_drop_index (GtkToolbar *toolbar,
2391 gint drop_index, drop_pos;
2393 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2395 if (!gtk_toolbar_check_new_api (toolbar))
2398 find_drop_pos (toolbar, x, y, &drop_index, &drop_pos);
2404 gtk_toolbar_append_item (GtkToolbar *toolbar,
2406 const char *tooltip_text,
2407 const char *tooltip_private_text,
2409 GtkSignalFunc callback,
2412 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
2414 tooltip_text, tooltip_private_text,
2415 icon, callback, user_data,
2416 toolbar->num_children);
2420 gtk_toolbar_prepend_item (GtkToolbar *toolbar,
2422 const char *tooltip_text,
2423 const char *tooltip_private_text,
2425 GtkSignalFunc callback,
2428 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
2430 tooltip_text, tooltip_private_text,
2431 icon, callback, user_data,
2436 gtk_toolbar_insert_item (GtkToolbar *toolbar,
2438 const char *tooltip_text,
2439 const char *tooltip_private_text,
2441 GtkSignalFunc callback,
2445 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
2447 tooltip_text, tooltip_private_text,
2448 icon, callback, user_data,
2453 gtk_toolbar_insert_stock (GtkToolbar *toolbar,
2454 const gchar *stock_id,
2455 const char *tooltip_text,
2456 const char *tooltip_private_text,
2457 GtkSignalFunc callback,
2461 return gtk_toolbar_internal_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
2463 tooltip_text, tooltip_private_text,
2464 NULL, callback, user_data,
2469 gtk_toolbar_append_space (GtkToolbar *toolbar)
2471 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
2475 toolbar->num_children);
2479 gtk_toolbar_prepend_space (GtkToolbar *toolbar)
2481 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
2489 gtk_toolbar_insert_space (GtkToolbar *toolbar,
2492 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
2500 gtk_toolbar_remove_space (GtkToolbar *toolbar,
2505 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2507 if (!gtk_toolbar_check_old_api (toolbar))
2510 item = g_list_nth_data (toolbar->children, position);
2514 g_warning ("Toolbar position %d doesn't exist", position);
2518 if (GTK_BIN (item)->child)
2520 g_warning ("Toolbar position %d is not a space", position);
2523 gtk_toolbar_remove_tool_item (toolbar, item);
2527 gtk_toolbar_append_widget (GtkToolbar *toolbar,
2529 const gchar *tooltip_text,
2530 const gchar *tooltip_private_text)
2532 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
2534 tooltip_text, tooltip_private_text,
2536 toolbar->num_children);
2540 gtk_toolbar_prepend_widget (GtkToolbar *toolbar,
2542 const gchar *tooltip_text,
2543 const gchar *tooltip_private_text)
2545 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
2547 tooltip_text, tooltip_private_text,
2553 gtk_toolbar_insert_widget (GtkToolbar *toolbar,
2555 const char *tooltip_text,
2556 const char *tooltip_private_text,
2559 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
2561 tooltip_text, tooltip_private_text,
2567 gtk_toolbar_append_element (GtkToolbar *toolbar,
2568 GtkToolbarChildType type,
2571 const char *tooltip_text,
2572 const char *tooltip_private_text,
2574 GtkSignalFunc callback,
2577 return gtk_toolbar_insert_element (toolbar, type, widget, text,
2578 tooltip_text, tooltip_private_text,
2579 icon, callback, user_data,
2580 toolbar->num_children);
2584 gtk_toolbar_prepend_element (GtkToolbar *toolbar,
2585 GtkToolbarChildType type,
2588 const char *tooltip_text,
2589 const char *tooltip_private_text,
2591 GtkSignalFunc callback,
2594 return gtk_toolbar_insert_element (toolbar, type, widget, text,
2595 tooltip_text, tooltip_private_text,
2596 icon, callback, user_data, 0);
2600 gtk_toolbar_insert_element (GtkToolbar *toolbar,
2601 GtkToolbarChildType type,
2604 const char *tooltip_text,
2605 const char *tooltip_private_text,
2607 GtkSignalFunc callback,
2611 return gtk_toolbar_internal_insert_element (toolbar, type, widget, text,
2612 tooltip_text, tooltip_private_text,
2613 icon, callback, user_data, position, FALSE);
2617 _gtk_toolbar_elide_underscores (const gchar *original)
2621 gboolean last_underscore;
2623 q = result = g_malloc (strlen (original) + 1);
2624 last_underscore = FALSE;
2626 for (p = original; *p; p++)
2628 if (!last_underscore && *p == '_')
2629 last_underscore = TRUE;
2632 last_underscore = FALSE;
2643 gtk_toolbar_internal_insert_element (GtkToolbar *toolbar,
2644 GtkToolbarChildType type,
2647 const char *tooltip_text,
2648 const char *tooltip_private_text,
2650 GtkSignalFunc callback,
2655 GtkToolbarChild *child;
2656 GtkToolItem *item = NULL;
2658 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
2660 if (!gtk_toolbar_check_old_api (toolbar))
2663 if (type == GTK_TOOLBAR_CHILD_WIDGET)
2664 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
2665 else if (type != GTK_TOOLBAR_CHILD_RADIOBUTTON)
2666 g_return_val_if_fail (widget == NULL, NULL);
2668 child = g_new (GtkToolbarChild, 1);
2672 child->label = NULL;
2676 case GTK_TOOLBAR_CHILD_SPACE:
2677 item = gtk_separator_tool_item_new ();
2678 child->widget = NULL;
2681 case GTK_TOOLBAR_CHILD_WIDGET:
2682 item = gtk_tool_item_new ();
2683 child->widget = widget;
2684 gtk_container_add (GTK_CONTAINER (item), child->widget);
2687 case GTK_TOOLBAR_CHILD_BUTTON:
2688 item = gtk_tool_button_new (NULL, NULL);
2689 child->widget = GTK_TOOL_BUTTON (item)->button;
2692 case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
2693 item = gtk_toggle_tool_button_new ();
2694 child->widget = GTK_TOOL_BUTTON (item)->button;
2697 case GTK_TOOLBAR_CHILD_RADIOBUTTON:
2698 item = gtk_radio_tool_button_new (widget
2699 ? gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget))
2701 child->widget = GTK_TOOL_BUTTON (item)->button;
2705 gtk_widget_show (GTK_WIDGET (item));
2707 if (type == GTK_TOOLBAR_CHILD_BUTTON ||
2708 type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
2709 type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
2715 GtkStockItem stock_item;
2718 gtk_tool_button_set_stock_id (GTK_TOOL_BUTTON (item), text);
2720 gtk_stock_lookup (text, &stock_item);
2721 label_text = _gtk_toolbar_elide_underscores (stock_item.label);
2722 child->label = GTK_WIDGET (gtk_label_new (label_text));
2723 g_free (label_text);
2727 child->label = gtk_label_new (text);
2729 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (item), child->label);
2730 gtk_widget_show (child->label);
2736 gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (item), icon);
2738 /* Applications depend on the toolbar showing the widget for them */
2739 gtk_widget_show (GTK_WIDGET (icon));
2743 * We need to connect to the button's clicked callback because some
2744 * programs may rely on that the widget in the callback is a GtkButton
2747 g_signal_connect (child->widget, "clicked",
2748 callback, user_data);
2751 if ((type != GTK_TOOLBAR_CHILD_SPACE) && tooltip_text)
2752 gtk_tool_item_set_tooltip (item, toolbar->tooltips,
2753 tooltip_text, tooltip_private_text);
2755 toolbar->children = g_list_insert (toolbar->children, child, position);
2757 gtk_toolbar_insert_tool_item (toolbar, item, position);
2759 return child->widget;
2763 gtk_toolbar_finalize (GObject *object)
2766 GtkToolbar *toolbar = GTK_TOOLBAR (object);
2768 if (toolbar->tooltips)
2769 g_object_unref (toolbar->tooltips);
2771 for (list = toolbar->children; list != NULL; list = list->next)
2772 g_free (list->data);
2774 g_list_free (toolbar->children);
2776 G_OBJECT_CLASS (parent_class)->finalize (object);