1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 * GtkToolbar copyright (C) Federico Mena
5 * Copyright (C) 2002 Anders Carlsson <andersca@gnome.org>
6 * Copyright (C) 2002 James Henstridge <james@daa.com.au>
7 * Copyright (C) 2003, 2004 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
37 #include "gtktoolbar.h"
38 #include "gtkradiotoolbutton.h"
39 #include "gtkseparatortoolitem.h"
41 #include "gtkradiobutton.h"
42 #include "gtktoolbar.h"
43 #include "gtkbindings.h"
44 #include <gdk/gdkkeysyms.h>
45 #include "gtkmarshalers.h"
49 #include "gtkprivate.h"
55 #include "gtkseparatormenuitem.h"
57 typedef struct _ToolbarContent ToolbarContent;
59 #define DEFAULT_IPADDING 0
61 #define DEFAULT_SPACE_SIZE 12
62 #define DEFAULT_SPACE_STYLE GTK_TOOLBAR_SPACE_LINE
63 #define SPACE_LINE_DIVISION 10.0
64 #define SPACE_LINE_START 2.0
65 #define SPACE_LINE_END 8.0
67 #define DEFAULT_ICON_SIZE GTK_ICON_SIZE_LARGE_TOOLBAR
68 #define DEFAULT_TOOLBAR_STYLE GTK_TOOLBAR_BOTH
70 #define MAX_HOMOGENEOUS_N_CHARS 13 /* Items that are wider than this do not participate
71 * in the homogeneous game. In units of
72 * pango_font_get_estimated_char_width().
74 #define SLIDE_SPEED 600 /* How fast the items slide, in pixels per second */
76 #define MIXED_API_WARNING \
77 "Mixing deprecated and non-deprecated GtkToolbar API is not allowed"
88 /* Child properties */
92 CHILD_PROP_HOMOGENEOUS
124 struct _GtkToolbarPrivate
129 GtkWidget * arrow_button;
132 GdkWindow * event_window;
134 GtkSettings * settings;
136 GtkToolItem * highlight_tool_item;
137 gint max_homogeneous_pixels;
141 guint show_arrow : 1;
143 guint is_sliding : 1;
144 guint need_rebuild : 1; /* whether the overflow menu should be regenerated */
147 static void gtk_toolbar_init (GtkToolbar *toolbar);
148 static void gtk_toolbar_class_init (GtkToolbarClass *klass);
149 static void gtk_toolbar_set_property (GObject *object,
153 static void gtk_toolbar_get_property (GObject *object,
157 static gint gtk_toolbar_expose (GtkWidget *widget,
158 GdkEventExpose *event);
159 static void gtk_toolbar_realize (GtkWidget *widget);
160 static void gtk_toolbar_unrealize (GtkWidget *widget);
161 static void gtk_toolbar_size_request (GtkWidget *widget,
162 GtkRequisition *requisition);
163 static void gtk_toolbar_size_allocate (GtkWidget *widget,
164 GtkAllocation *allocation);
165 static void gtk_toolbar_style_set (GtkWidget *widget,
166 GtkStyle *prev_style);
167 static gboolean gtk_toolbar_focus (GtkWidget *widget,
168 GtkDirectionType dir);
169 static void gtk_toolbar_screen_changed (GtkWidget *widget,
170 GdkScreen *previous_screen);
171 static void gtk_toolbar_map (GtkWidget *widget);
172 static void gtk_toolbar_unmap (GtkWidget *widget);
173 static void gtk_toolbar_set_child_property (GtkContainer *container,
178 static void gtk_toolbar_get_child_property (GtkContainer *container,
183 static void gtk_toolbar_finalize (GObject *object);
184 static void gtk_toolbar_show_all (GtkWidget *widget);
185 static void gtk_toolbar_hide_all (GtkWidget *widget);
186 static void gtk_toolbar_add (GtkContainer *container,
188 static void gtk_toolbar_remove (GtkContainer *container,
190 static void gtk_toolbar_forall (GtkContainer *container,
191 gboolean include_internals,
192 GtkCallback callback,
193 gpointer callback_data);
194 static GType gtk_toolbar_child_type (GtkContainer *container);
195 static void gtk_toolbar_orientation_changed (GtkToolbar *toolbar,
196 GtkOrientation orientation);
197 static void gtk_toolbar_real_style_changed (GtkToolbar *toolbar,
198 GtkToolbarStyle style);
199 static gboolean gtk_toolbar_move_focus (GtkToolbar *toolbar,
200 GtkDirectionType dir);
201 static gboolean gtk_toolbar_focus_home_or_end (GtkToolbar *toolbar,
202 gboolean focus_home);
203 static gboolean gtk_toolbar_button_press (GtkWidget *toolbar,
204 GdkEventButton *event);
205 static gboolean gtk_toolbar_arrow_button_press (GtkWidget *button,
206 GdkEventButton *event,
207 GtkToolbar *toolbar);
208 static void gtk_toolbar_arrow_button_clicked (GtkWidget *button,
209 GtkToolbar *toolbar);
210 static void gtk_toolbar_update_button_relief (GtkToolbar *toolbar);
211 static gboolean gtk_toolbar_popup_menu (GtkWidget *toolbar);
212 static GtkWidget *internal_insert_element (GtkToolbar *toolbar,
213 GtkToolbarChildType type,
216 const char *tooltip_text,
217 const char *tooltip_private_text,
219 GtkSignalFunc callback,
223 static void gtk_toolbar_reconfigured (GtkToolbar *toolbar);
224 static gboolean gtk_toolbar_check_new_api (GtkToolbar *toolbar);
225 static gboolean gtk_toolbar_check_old_api (GtkToolbar *toolbar);
227 static GtkReliefStyle get_button_relief (GtkToolbar *toolbar);
228 static gint get_internal_padding (GtkToolbar *toolbar);
229 static GtkShadowType get_shadow_type (GtkToolbar *toolbar);
230 static gint get_space_size (GtkToolbar *toolbar);
231 static GtkToolbarSpaceStyle get_space_style (GtkToolbar *toolbar);
233 /* methods on ToolbarContent 'class' */
234 static ToolbarContent *toolbar_content_new_tool_item (GtkToolbar *toolbar,
236 gboolean is_placeholder,
238 static ToolbarContent *toolbar_content_new_compatibility (GtkToolbar *toolbar,
239 GtkToolbarChildType type,
244 static void toolbar_content_remove (ToolbarContent *content,
245 GtkToolbar *toolbar);
246 static void toolbar_content_free (ToolbarContent *content);
247 static void toolbar_content_expose (ToolbarContent *content,
248 GtkContainer *container,
249 GdkEventExpose *expose);
250 static gboolean toolbar_content_visible (ToolbarContent *content,
251 GtkToolbar *toolbar);
252 static void toolbar_content_size_request (ToolbarContent *content,
254 GtkRequisition *requisition);
255 static gboolean toolbar_content_is_homogeneous (ToolbarContent *content,
256 GtkToolbar *toolbar);
257 static gboolean toolbar_content_is_placeholder (ToolbarContent *content);
258 static gboolean toolbar_content_disappearing (ToolbarContent *content);
259 static ItemState toolbar_content_get_state (ToolbarContent *content);
260 static gboolean toolbar_content_child_visible (ToolbarContent *content);
261 static void toolbar_content_get_goal_allocation (ToolbarContent *content,
262 GtkAllocation *allocation);
263 static void toolbar_content_get_allocation (ToolbarContent *content,
264 GtkAllocation *allocation);
265 static void toolbar_content_set_start_allocation (ToolbarContent *content,
266 GtkAllocation *new_start_allocation);
267 static void toolbar_content_get_start_allocation (ToolbarContent *content,
268 GtkAllocation *start_allocation);
269 static gboolean toolbar_content_get_expand (ToolbarContent *content);
270 static void toolbar_content_set_goal_allocation (ToolbarContent *content,
271 GtkAllocation *allocation);
272 static void toolbar_content_set_child_visible (ToolbarContent *content,
275 static void toolbar_content_size_allocate (ToolbarContent *content,
276 GtkAllocation *allocation);
277 static void toolbar_content_set_state (ToolbarContent *content,
278 ItemState new_state);
279 static GtkWidget * toolbar_content_get_widget (ToolbarContent *content);
280 static void toolbar_content_set_disappearing (ToolbarContent *content,
281 gboolean disappearing);
282 static void toolbar_content_set_size_request (ToolbarContent *content,
285 static void toolbar_content_toolbar_reconfigured (ToolbarContent *content,
286 GtkToolbar *toolbar);
287 static GtkWidget * toolbar_content_retrieve_menu_item (ToolbarContent *content);
288 static gboolean toolbar_content_has_proxy_menu_item (ToolbarContent *content);
289 static gboolean toolbar_content_is_separator (ToolbarContent *content);
290 static void toolbar_content_show_all (ToolbarContent *content);
291 static void toolbar_content_hide_all (ToolbarContent *content);
294 #define GTK_TOOLBAR_GET_PRIVATE(o) \
295 (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_TOOLBAR, GtkToolbarPrivate))
297 static GtkContainerClass * parent_class = NULL;
298 static guint toolbar_signals [LAST_SIGNAL] = { 0 };
301 gtk_toolbar_get_type (void)
303 static GtkType type = 0;
307 static const GTypeInfo type_info =
309 sizeof (GtkToolbarClass),
310 (GBaseInitFunc) NULL,
311 (GBaseFinalizeFunc) NULL,
312 (GClassInitFunc) gtk_toolbar_class_init,
313 (GClassFinalizeFunc) NULL,
317 (GInstanceInitFunc) gtk_toolbar_init,
320 type = g_type_register_static (GTK_TYPE_CONTAINER,
329 add_arrow_bindings (GtkBindingSet *binding_set,
331 GtkDirectionType dir)
333 guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
335 gtk_binding_entry_add_signal (binding_set, keysym, 0,
337 GTK_TYPE_DIRECTION_TYPE, dir);
338 gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
340 GTK_TYPE_DIRECTION_TYPE, dir);
344 add_ctrl_tab_bindings (GtkBindingSet *binding_set,
345 GdkModifierType modifiers,
346 GtkDirectionType direction)
348 gtk_binding_entry_add_signal (binding_set,
349 GDK_Tab, GDK_CONTROL_MASK | modifiers,
351 GTK_TYPE_DIRECTION_TYPE, direction);
352 gtk_binding_entry_add_signal (binding_set,
353 GDK_KP_Tab, GDK_CONTROL_MASK | modifiers,
355 GTK_TYPE_DIRECTION_TYPE, direction);
359 gtk_toolbar_class_init (GtkToolbarClass *klass)
361 GObjectClass *gobject_class;
362 GtkWidgetClass *widget_class;
363 GtkContainerClass *container_class;
364 GtkBindingSet *binding_set;
366 parent_class = g_type_class_peek_parent (klass);
368 gobject_class = (GObjectClass *)klass;
369 widget_class = (GtkWidgetClass *)klass;
370 container_class = (GtkContainerClass *)klass;
372 gobject_class->set_property = gtk_toolbar_set_property;
373 gobject_class->get_property = gtk_toolbar_get_property;
374 gobject_class->finalize = gtk_toolbar_finalize;
376 widget_class->button_press_event = gtk_toolbar_button_press;
377 widget_class->expose_event = gtk_toolbar_expose;
378 widget_class->size_request = gtk_toolbar_size_request;
379 widget_class->size_allocate = gtk_toolbar_size_allocate;
380 widget_class->style_set = gtk_toolbar_style_set;
381 widget_class->focus = gtk_toolbar_focus;
382 widget_class->screen_changed = gtk_toolbar_screen_changed;
383 widget_class->realize = gtk_toolbar_realize;
384 widget_class->unrealize = gtk_toolbar_unrealize;
385 widget_class->map = gtk_toolbar_map;
386 widget_class->unmap = gtk_toolbar_unmap;
387 widget_class->popup_menu = gtk_toolbar_popup_menu;
388 widget_class->show_all = gtk_toolbar_show_all;
389 widget_class->hide_all = gtk_toolbar_hide_all;
391 container_class->add = gtk_toolbar_add;
392 container_class->remove = gtk_toolbar_remove;
393 container_class->forall = gtk_toolbar_forall;
394 container_class->child_type = gtk_toolbar_child_type;
395 container_class->get_child_property = gtk_toolbar_get_child_property;
396 container_class->set_child_property = gtk_toolbar_set_child_property;
398 klass->orientation_changed = gtk_toolbar_orientation_changed;
399 klass->style_changed = gtk_toolbar_real_style_changed;
402 * GtkToolbar::orientation-changed:
403 * @toolbar: the object which emitted the signal
404 * @orientation: the new #GtkOrientation of the toolbar
406 * Emitted when the orientation of the toolbar changes.
408 toolbar_signals[ORIENTATION_CHANGED] =
409 g_signal_new ("orientation-changed",
410 G_OBJECT_CLASS_TYPE (klass),
412 G_STRUCT_OFFSET (GtkToolbarClass, orientation_changed),
414 g_cclosure_marshal_VOID__ENUM,
416 GTK_TYPE_ORIENTATION);
418 * GtkToolbar::style-changed:
419 * @toolbar: The #GtkToolbar which emitted the signal
420 * @style: the new #GtkToolbarStyle of the toolbar
422 * Emitted when the style of the toolbar changes.
424 toolbar_signals[STYLE_CHANGED] =
425 g_signal_new ("style-changed",
426 G_OBJECT_CLASS_TYPE (klass),
428 G_STRUCT_OFFSET (GtkToolbarClass, style_changed),
430 g_cclosure_marshal_VOID__ENUM,
432 GTK_TYPE_TOOLBAR_STYLE);
434 * GtkToolbar::popup-context-menu:
435 * @toolbar: the #GtkToolbar which emitted the signal
436 * @x: the x coordinate of the point where the menu should appear
437 * @y: the y coordinate of the point where the menu should appear
438 * @button: the mouse button the user pressed, or -1
440 * Emitted when the user right-clicks the toolbar or uses the
441 * keybinding to display a popup menu.
443 * Application developers should handle this signal if they want
444 * to display a context menu on the toolbar. The context-menu should
445 * appear at the coordinates given by @x and @y. The mouse button
446 * number is given by the @button parameter. If the menu was popped
447 * up using the keybaord, @button is -1.
449 * Return value: return %TRUE if the signal was handled, %FALSE if not
451 toolbar_signals[POPUP_CONTEXT_MENU] =
452 g_signal_new ("popup_context_menu",
453 G_OBJECT_CLASS_TYPE (klass),
455 G_STRUCT_OFFSET (GtkToolbarClass, popup_context_menu),
456 _gtk_boolean_handled_accumulator, NULL,
457 _gtk_marshal_BOOLEAN__INT_INT_INT,
459 G_TYPE_INT, G_TYPE_INT,
462 * GtkToolbar::move-focus:
463 * @toolbar: the #GtkToolbar which emitted the signal
464 * @dir: a #GtkDirection
466 * A keybinding signal used internally by GTK+. This signal can't
467 * be used in application code.
469 * Return value: %TRUE if the signal was handled, %FALSE if not
471 toolbar_signals[MOVE_FOCUS] =
472 _gtk_binding_signal_new ("move_focus",
473 G_TYPE_FROM_CLASS (klass),
474 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
475 G_CALLBACK (gtk_toolbar_move_focus),
477 _gtk_marshal_BOOLEAN__ENUM,
479 GTK_TYPE_DIRECTION_TYPE);
481 * GtkToolbar::focus-home-or-end:
482 * @toolbar: the #GtkToolbar which emitted the signal
483 * @focus_home: %TRUE if the first item should be focused
485 * A keybinding signal used internally by GTK+. This signal can't
486 * be used in application code
488 * Return value: %TRUE if the signal was handled, %FALSE if not
490 toolbar_signals[FOCUS_HOME_OR_END] =
491 _gtk_binding_signal_new ("focus_home_or_end",
492 G_OBJECT_CLASS_TYPE (klass),
493 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
494 G_CALLBACK (gtk_toolbar_focus_home_or_end),
496 _gtk_marshal_BOOLEAN__BOOLEAN,
501 g_object_class_install_property (gobject_class,
503 g_param_spec_enum ("orientation",
505 P_("The orientation of the toolbar"),
506 GTK_TYPE_ORIENTATION,
507 GTK_ORIENTATION_HORIZONTAL,
510 g_object_class_install_property (gobject_class,
512 g_param_spec_enum ("toolbar_style",
514 P_("How to draw the toolbar"),
515 GTK_TYPE_TOOLBAR_STYLE,
518 g_object_class_install_property (gobject_class,
520 g_param_spec_boolean ("show_arrow",
522 P_("If an arrow should be shown if the toolbar doesn't fit"),
526 /* child properties */
527 gtk_container_class_install_child_property (container_class,
529 g_param_spec_boolean ("expand",
531 P_("Whether the item should receive extra space when the toolbar grows"),
535 gtk_container_class_install_child_property (container_class,
536 CHILD_PROP_HOMOGENEOUS,
537 g_param_spec_boolean ("homogeneous",
539 P_("Whether the item should be the same size as other homogeneous items"),
543 /* style properties */
544 gtk_widget_class_install_style_property (widget_class,
545 g_param_spec_int ("space_size",
547 P_("Size of spacers"),
553 gtk_widget_class_install_style_property (widget_class,
554 g_param_spec_int ("internal_padding",
555 P_("Internal padding"),
556 P_("Amount of border space between the toolbar shadow and the buttons"),
562 gtk_widget_class_install_style_property (widget_class,
563 g_param_spec_enum ("space_style",
565 P_("Whether spacers are vertical lines or just blank"),
566 GTK_TYPE_TOOLBAR_SPACE_STYLE,
570 gtk_widget_class_install_style_property (widget_class,
571 g_param_spec_enum ("button_relief",
573 P_("Type of bevel around toolbar buttons"),
574 GTK_TYPE_RELIEF_STYLE,
577 gtk_widget_class_install_style_property (widget_class,
578 g_param_spec_enum ("shadow_type",
580 P_("Style of bevel around the toolbar"),
581 GTK_TYPE_SHADOW_TYPE,
585 gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-style",
587 P_("Whether default toolbars have text only, text and icons, icons only, etc."),
588 GTK_TYPE_TOOLBAR_STYLE,
589 DEFAULT_TOOLBAR_STYLE,
592 gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-icon-size",
593 P_("Toolbar icon size"),
594 P_("Size of icons in default toolbars"),
599 binding_set = gtk_binding_set_by_class (klass);
601 add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
602 add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
603 add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
604 add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
606 gtk_binding_entry_add_signal (binding_set, GDK_KP_Home, 0,
607 "focus_home_or_end", 1,
608 G_TYPE_BOOLEAN, TRUE);
609 gtk_binding_entry_add_signal (binding_set, GDK_Home, 0,
610 "focus_home_or_end", 1,
611 G_TYPE_BOOLEAN, TRUE);
612 gtk_binding_entry_add_signal (binding_set, GDK_KP_End, 0,
613 "focus_home_or_end", 1,
614 G_TYPE_BOOLEAN, FALSE);
615 gtk_binding_entry_add_signal (binding_set, GDK_End, 0,
616 "focus_home_or_end", 1,
617 G_TYPE_BOOLEAN, FALSE);
619 add_ctrl_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
620 add_ctrl_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
622 g_type_class_add_private (gobject_class, sizeof (GtkToolbarPrivate));
626 gtk_toolbar_init (GtkToolbar *toolbar)
628 GtkToolbarPrivate *priv;
630 GTK_WIDGET_UNSET_FLAGS (toolbar, GTK_CAN_FOCUS);
631 GTK_WIDGET_SET_FLAGS (toolbar, GTK_NO_WINDOW);
633 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
635 toolbar->orientation = GTK_ORIENTATION_HORIZONTAL;
636 toolbar->style = DEFAULT_TOOLBAR_STYLE;
637 toolbar->icon_size = DEFAULT_ICON_SIZE;
638 toolbar->tooltips = gtk_tooltips_new ();
639 g_object_ref (toolbar->tooltips);
640 gtk_object_sink (GTK_OBJECT (toolbar->tooltips));
642 priv->arrow_button = gtk_toggle_button_new ();
643 g_signal_connect (priv->arrow_button, "button_press_event",
644 G_CALLBACK (gtk_toolbar_arrow_button_press), toolbar);
645 g_signal_connect (priv->arrow_button, "clicked",
646 G_CALLBACK (gtk_toolbar_arrow_button_clicked), toolbar);
647 gtk_button_set_relief (GTK_BUTTON (priv->arrow_button),
648 get_button_relief (toolbar));
650 priv->api_mode = DONT_KNOW;
652 gtk_button_set_focus_on_click (GTK_BUTTON (priv->arrow_button), FALSE);
654 priv->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
655 gtk_widget_set_name (priv->arrow, "gtk-toolbar-arrow");
656 gtk_widget_show (priv->arrow);
657 gtk_container_add (GTK_CONTAINER (priv->arrow_button), priv->arrow);
659 gtk_widget_set_parent (priv->arrow_button, GTK_WIDGET (toolbar));
661 /* which child position a drop will occur at */
663 priv->show_arrow = TRUE;
664 priv->settings = NULL;
666 priv->max_homogeneous_pixels = -1;
668 priv->timer = g_timer_new ();
672 gtk_toolbar_set_property (GObject *object,
677 GtkToolbar *toolbar = GTK_TOOLBAR (object);
681 case PROP_ORIENTATION:
682 gtk_toolbar_set_orientation (toolbar, g_value_get_enum (value));
684 case PROP_TOOLBAR_STYLE:
685 gtk_toolbar_set_style (toolbar, g_value_get_enum (value));
687 case PROP_SHOW_ARROW:
688 gtk_toolbar_set_show_arrow (toolbar, g_value_get_boolean (value));
691 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
697 gtk_toolbar_get_property (GObject *object,
702 GtkToolbar *toolbar = GTK_TOOLBAR (object);
703 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
707 case PROP_ORIENTATION:
708 g_value_set_enum (value, toolbar->orientation);
710 case PROP_TOOLBAR_STYLE:
711 g_value_set_enum (value, toolbar->style);
713 case PROP_SHOW_ARROW:
714 g_value_set_boolean (value, priv->show_arrow);
717 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
723 gtk_toolbar_map (GtkWidget *widget)
725 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
727 GTK_WIDGET_CLASS (parent_class)->map (widget);
729 if (priv->event_window)
730 gdk_window_show_unraised (priv->event_window);
734 gtk_toolbar_unmap (GtkWidget *widget)
736 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
738 if (priv->event_window)
739 gdk_window_hide (priv->event_window);
741 GTK_WIDGET_CLASS (parent_class)->unmap (widget);
745 gtk_toolbar_realize (GtkWidget *widget)
747 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
748 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
750 GdkWindowAttr attributes;
751 gint attributes_mask;
754 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
756 border_width = GTK_CONTAINER (widget)->border_width;
758 attributes.wclass = GDK_INPUT_ONLY;
759 attributes.window_type = GDK_WINDOW_CHILD;
760 attributes.x = widget->allocation.x + border_width;
761 attributes.y = widget->allocation.y + border_width;
762 attributes.width = widget->allocation.width - border_width * 2;
763 attributes.height = widget->allocation.height - border_width * 2;
764 attributes.event_mask = gtk_widget_get_events (widget);
765 attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
766 GDK_BUTTON_RELEASE_MASK |
767 GDK_ENTER_NOTIFY_MASK |
768 GDK_LEAVE_NOTIFY_MASK);
770 attributes_mask = GDK_WA_X | GDK_WA_Y;
772 widget->window = gtk_widget_get_parent_window (widget);
773 g_object_ref (widget->window);
774 widget->style = gtk_style_attach (widget->style, widget->window);
776 priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget),
777 &attributes, attributes_mask);
778 gdk_window_set_user_data (priv->event_window, toolbar);
782 gtk_toolbar_unrealize (GtkWidget *widget)
784 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
786 if (priv->event_window)
788 gdk_window_set_user_data (priv->event_window, NULL);
789 gdk_window_destroy (priv->event_window);
790 priv->event_window = NULL;
793 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
794 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
798 gtk_toolbar_expose (GtkWidget *widget,
799 GdkEventExpose *event)
801 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
802 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
807 border_width = GTK_CONTAINER (widget)->border_width;
809 if (GTK_WIDGET_DRAWABLE (widget))
811 gtk_paint_box (widget->style,
813 GTK_WIDGET_STATE (widget),
814 get_shadow_type (toolbar),
815 &event->area, widget, "toolbar",
816 border_width + widget->allocation.x,
817 border_width + widget->allocation.y,
818 widget->allocation.width - 2 * border_width,
819 widget->allocation.height - 2 * border_width);
822 for (list = priv->content; list != NULL; list = list->next)
824 ToolbarContent *content = list->data;
826 toolbar_content_expose (content, GTK_CONTAINER (widget), event);
829 gtk_container_propagate_expose (GTK_CONTAINER (widget),
837 gtk_toolbar_size_request (GtkWidget *widget,
838 GtkRequisition *requisition)
840 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
841 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
843 gint max_child_height;
844 gint max_child_width;
845 gint max_homogeneous_child_width;
846 gint max_homogeneous_child_height;
847 gint homogeneous_size;
849 gint pack_front_size;
851 GtkRequisition arrow_requisition;
853 max_homogeneous_child_width = 0;
854 max_homogeneous_child_height = 0;
856 max_child_height = 0;
857 for (list = priv->content; list != NULL; list = list->next)
859 GtkRequisition requisition;
860 ToolbarContent *content = list->data;
862 if (!toolbar_content_visible (content, toolbar))
865 toolbar_content_size_request (content, toolbar, &requisition);
867 max_child_width = MAX (max_child_width, requisition.width);
868 max_child_height = MAX (max_child_height, requisition.height);
870 if (toolbar_content_is_homogeneous (content, toolbar))
872 max_homogeneous_child_width = MAX (max_homogeneous_child_width, requisition.width);
873 max_homogeneous_child_height = MAX (max_homogeneous_child_height, requisition.height);
877 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
878 homogeneous_size = max_homogeneous_child_width;
880 homogeneous_size = max_homogeneous_child_height;
883 for (list = priv->content; list != NULL; list = list->next)
885 ToolbarContent *content = list->data;
888 if (!toolbar_content_visible (content, toolbar))
891 if (toolbar_content_is_homogeneous (content, toolbar))
893 size = homogeneous_size;
897 GtkRequisition requisition;
899 toolbar_content_size_request (content, toolbar, &requisition);
901 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
902 size = requisition.width;
904 size = requisition.height;
907 pack_front_size += size;
910 if (priv->show_arrow && priv->api_mode == NEW_API)
912 gtk_widget_size_request (priv->arrow_button, &arrow_requisition);
914 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
915 long_req = arrow_requisition.width;
917 long_req = arrow_requisition.height;
919 /* There is no point requesting space for the arrow if that would take
920 * up more space than all the items combined
922 long_req = MIN (long_req, pack_front_size);
926 arrow_requisition.height = 0;
927 arrow_requisition.width = 0;
929 long_req = pack_front_size;
932 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
934 requisition->width = long_req;
935 requisition->height = MAX (max_child_height, arrow_requisition.height);
939 requisition->height = long_req;
940 requisition->width = MAX (max_child_width, arrow_requisition.width);
944 ipadding = get_internal_padding (toolbar);
946 requisition->width += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width);
947 requisition->height += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width);
949 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
951 requisition->width += 2 * widget->style->xthickness;
952 requisition->height += 2 * widget->style->ythickness;
955 toolbar->button_maxw = max_homogeneous_child_width;
956 toolbar->button_maxh = max_homogeneous_child_height;
960 position (gint from, gint to, gdouble elapsed)
963 return MIN (from + SLIDE_SPEED * elapsed, to);
965 return MAX (from - SLIDE_SPEED * elapsed, to);
969 compute_intermediate_allocation (GtkToolbar *toolbar,
970 const GtkAllocation *start,
971 const GtkAllocation *goal,
972 GtkAllocation *intermediate)
974 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
975 gdouble elapsed = g_timer_elapsed (priv->timer, NULL);
977 intermediate->x = position (start->x, goal->x, elapsed);
978 intermediate->y = position (start->y, goal->y, elapsed);
979 intermediate->width =
980 position (start->x + start->width, goal->x + goal->width, elapsed) - intermediate->x;
981 intermediate->height =
982 position (start->y + start->height, goal->y + goal->height, elapsed) - intermediate->y;
986 fixup_allocation_for_rtl (gint total_size,
987 GtkAllocation *allocation)
989 allocation->x += (total_size - (2 * allocation->x + allocation->width));
993 fixup_allocation_for_vertical (GtkAllocation *allocation)
998 allocation->x = allocation->y;
1001 tmp = allocation->width;
1002 allocation->width = allocation->height;
1003 allocation->height = tmp;
1007 get_item_size (GtkToolbar *toolbar,
1008 ToolbarContent *content)
1010 GtkRequisition requisition;
1012 toolbar_content_size_request (content, toolbar, &requisition);
1014 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1016 if (toolbar_content_is_homogeneous (content, toolbar))
1017 return toolbar->button_maxw;
1019 return requisition.width;
1023 if (toolbar_content_is_homogeneous (content, toolbar))
1024 return toolbar->button_maxh;
1026 return requisition.height;
1031 slide_idle_handler (gpointer data)
1033 GtkToolbar *toolbar = data;
1034 GtkToolbarPrivate *priv;
1037 GDK_THREADS_ENTER ();
1039 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1041 if (priv->need_sync)
1044 priv->need_sync = FALSE;
1047 for (list = priv->content; list != NULL; list = list->next)
1049 ToolbarContent *content = list->data;
1051 GtkAllocation goal_allocation;
1052 GtkAllocation allocation;
1055 state = toolbar_content_get_state (content);
1056 toolbar_content_get_goal_allocation (content, &goal_allocation);
1057 toolbar_content_get_allocation (content, &allocation);
1061 if (state == NOT_ALLOCATED)
1063 /* an unallocated item means that size allocate has to
1064 * called at least once more
1069 /* An invisible item with a goal allocation of
1070 * 0 is already at its goal.
1072 if ((state == NORMAL || state == OVERFLOWN) &&
1073 ((goal_allocation.width != 0 &&
1074 goal_allocation.height != 0) ||
1075 toolbar_content_child_visible (content)))
1077 if ((goal_allocation.x != allocation.x ||
1078 goal_allocation.y != allocation.y ||
1079 goal_allocation.width != allocation.width ||
1080 goal_allocation.height != allocation.height))
1082 /* An item is not in its right position yet. Note
1083 * that OVERFLOWN items do get an allocation in
1084 * gtk_toolbar_size_allocate(). This way you can see
1085 * them slide back in when you drag an item off the
1092 if (toolbar_content_is_placeholder (content) &&
1093 toolbar_content_disappearing (content) &&
1094 toolbar_content_child_visible (content))
1096 /* A disappearing placeholder is still visible.
1104 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (toolbar));
1106 GDK_THREADS_LEAVE ();
1111 priv->is_sliding = FALSE;
1114 GDK_THREADS_LEAVE();
1119 rect_within (GtkAllocation *a1,
1122 return (a1->x >= a2->x &&
1123 a1->x + a1->width <= a2->x + a2->width &&
1125 a1->y + a1->height <= a2->y + a2->height);
1129 gtk_toolbar_begin_sliding (GtkToolbar *toolbar)
1131 GtkWidget *widget = GTK_WIDGET (toolbar);
1132 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1140 /* Start the sliding. This function copies the allocation of every
1141 * item into content->start_allocation. For items that haven't
1142 * been allocated yet, we calculate their position and save that
1143 * in start_allocatino along with zero width and zero height.
1145 * FIXME: It would be nice if we could share this code with
1146 * the equivalent in gtk_widget_size_allocate().
1148 priv->is_sliding = TRUE;
1151 priv->idle_id = g_idle_add (slide_idle_handler, toolbar);
1153 rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
1154 vertical = (toolbar->orientation == GTK_ORIENTATION_VERTICAL);
1155 border_width = get_internal_padding (toolbar) + GTK_CONTAINER (toolbar)->border_width;
1159 cur_x = widget->allocation.width - border_width - widget->style->xthickness;
1160 cur_y = widget->allocation.height - border_width - widget->style->ythickness;
1164 cur_x = border_width + widget->style->xthickness;
1165 cur_y = border_width + widget->style->ythickness;
1168 cur_x += widget->allocation.x;
1169 cur_y += widget->allocation.y;
1171 for (list = priv->content; list != NULL; list = list->next)
1173 ToolbarContent *content = list->data;
1174 GtkAllocation new_start_allocation;
1175 GtkAllocation item_allocation;
1178 state = toolbar_content_get_state (content);
1179 toolbar_content_get_allocation (content, &item_allocation);
1181 if ((state == NORMAL &&
1182 rect_within (&item_allocation, &(widget->allocation))) ||
1185 new_start_allocation = item_allocation;
1189 new_start_allocation.x = cur_x;
1190 new_start_allocation.y = cur_y;
1194 new_start_allocation.width = widget->allocation.width -
1195 2 * border_width - 2 * widget->style->xthickness;
1196 new_start_allocation.height = 0;
1200 new_start_allocation.width = 0;
1201 new_start_allocation.height = widget->allocation.height -
1202 2 * border_width - 2 * widget->style->ythickness;
1207 cur_y = new_start_allocation.y + new_start_allocation.height;
1209 cur_x = new_start_allocation.x;
1211 cur_x = new_start_allocation.x + new_start_allocation.width;
1213 toolbar_content_set_start_allocation (content, &new_start_allocation);
1216 /* This resize will run before the first idle handler. This
1217 * will make sure that items get the right goal allocatiuon
1218 * so that the idle handler will not immediately return
1221 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (toolbar));
1222 g_timer_reset (priv->timer);
1226 gtk_toolbar_stop_sliding (GtkToolbar *toolbar)
1228 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1230 if (priv->is_sliding)
1234 priv->is_sliding = FALSE;
1238 g_source_remove (priv->idle_id);
1242 list = priv->content;
1245 ToolbarContent *content = list->data;
1248 if (toolbar_content_is_placeholder (content))
1250 toolbar_content_remove (content, toolbar);
1251 toolbar_content_free (content);
1255 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (toolbar));
1260 remove_item (GtkWidget *menu_item,
1263 gtk_container_remove (GTK_CONTAINER (menu_item->parent), menu_item);
1267 menu_deactivated (GtkWidget *menu,
1268 GtkToolbar *toolbar)
1270 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1271 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->arrow_button), FALSE);
1275 menu_detached (GtkWidget *toolbar,
1278 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1283 rebuild_menu (GtkToolbar *toolbar)
1285 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1286 GList *list, *children;
1290 priv->menu = GTK_MENU (gtk_menu_new());
1291 gtk_menu_attach_to_widget (priv->menu,
1292 GTK_WIDGET (toolbar),
1295 g_signal_connect (priv->menu, "deactivate", G_CALLBACK (menu_deactivated), toolbar);
1298 gtk_container_foreach (GTK_CONTAINER (priv->menu), remove_item, NULL);
1300 for (list = priv->content; list != NULL; list = list->next)
1302 ToolbarContent *content = list->data;
1304 if (toolbar_content_get_state (content) == OVERFLOWN &&
1305 !toolbar_content_is_placeholder (content))
1307 GtkWidget *menu_item = toolbar_content_retrieve_menu_item (content);
1311 g_assert (GTK_IS_MENU_ITEM (menu_item));
1312 gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), menu_item);
1317 /* Remove leading and trailing separator items */
1318 children = gtk_container_get_children (GTK_CONTAINER (priv->menu));
1321 while (list && GTK_IS_SEPARATOR_MENU_ITEM (list->data))
1323 GtkWidget *child = list->data;
1325 gtk_container_remove (GTK_CONTAINER (priv->menu), child);
1328 g_list_free (children);
1330 /* Regenerate the list of children so we don't try to remove items twice */
1331 children = gtk_container_get_children (GTK_CONTAINER (priv->menu));
1333 list = g_list_last (children);
1334 while (list && GTK_IS_SEPARATOR_MENU_ITEM (list->data))
1336 GtkWidget *child = list->data;
1338 gtk_container_remove (GTK_CONTAINER (priv->menu), child);
1341 g_list_free (children);
1343 priv->need_rebuild = FALSE;
1347 gtk_toolbar_size_allocate (GtkWidget *widget,
1348 GtkAllocation *allocation)
1350 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1351 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1352 GtkAllocation *allocations;
1353 ItemState *new_states;
1354 GtkAllocation arrow_allocation;
1356 gint size, pos, short_size;
1359 gboolean need_arrow;
1360 gint n_expand_items;
1362 gint available_size;
1365 GtkRequisition arrow_requisition;
1366 gboolean overflowing;
1367 gboolean size_changed;
1369 GtkAllocation item_area;
1371 size_changed = FALSE;
1372 if (widget->allocation.x != allocation->x ||
1373 widget->allocation.y != allocation->y ||
1374 widget->allocation.width != allocation->width ||
1375 widget->allocation.height != allocation->height)
1377 size_changed = TRUE;
1381 gtk_toolbar_stop_sliding (toolbar);
1383 widget->allocation = *allocation;
1385 border_width = GTK_CONTAINER (toolbar)->border_width;
1387 if (GTK_WIDGET_REALIZED (widget))
1389 gdk_window_move_resize (priv->event_window,
1390 allocation->x + border_width,
1391 allocation->y + border_width,
1392 allocation->width - border_width * 2,
1393 allocation->height - border_width * 2);
1396 border_width += get_internal_padding (toolbar);
1398 gtk_widget_get_child_requisition (GTK_WIDGET (priv->arrow_button),
1399 &arrow_requisition);
1401 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1403 available_size = size = allocation->width - 2 * border_width;
1404 short_size = allocation->height - 2 * border_width;
1405 arrow_size = arrow_requisition.width;
1407 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1409 available_size -= 2 * widget->style->xthickness;
1410 short_size -= 2 * widget->style->ythickness;
1415 available_size = size = allocation->height - 2 * border_width;
1416 short_size = allocation->width - 2 * border_width;
1417 arrow_size = arrow_requisition.height;
1419 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1421 available_size -= 2 * widget->style->ythickness;
1422 short_size -= 2 * widget->style->xthickness;
1426 n_items = g_list_length (priv->content);
1427 allocations = g_new0 (GtkAllocation, n_items);
1428 new_states = g_new0 (ItemState, n_items);
1432 for (list = priv->content; list != NULL; list = list->next)
1434 ToolbarContent *content = list->data;
1436 if (toolbar_content_visible (content, toolbar))
1438 needed_size += get_item_size (toolbar, content);
1440 /* Do we need an arrow?
1442 * Assume we don't, and see if any non-separator item with a
1443 * proxy menu item is then going to overflow.
1445 if (needed_size > available_size &&
1448 priv->api_mode == NEW_API &&
1449 toolbar_content_has_proxy_menu_item (content) &&
1450 !toolbar_content_is_separator (content))
1458 size = available_size - arrow_size;
1460 size = available_size;
1462 /* calculate widths of items */
1463 overflowing = FALSE;
1464 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1466 ToolbarContent *content = list->data;
1469 if (!toolbar_content_visible (content, toolbar))
1471 new_states[i] = HIDDEN;
1475 item_size = get_item_size (toolbar, content);
1476 if (item_size <= size && !overflowing)
1479 allocations[i].width = item_size;
1480 new_states[i] = NORMAL;
1485 new_states[i] = OVERFLOWN;
1486 allocations[i].width = item_size;
1490 /* calculate width of arrow */
1493 arrow_allocation.width = arrow_size;
1494 arrow_allocation.height = short_size;
1497 /* expand expandable items */
1499 /* We don't expand when there is an overflow menu, because that leads to
1500 * weird jumps when items get moved to the overflow menu and the expanding
1501 * items suddenly get a lot of extra space
1506 for (i = 0, list = priv->content; list != NULL; list = list->next, ++i)
1508 ToolbarContent *content = list->data;
1510 if (toolbar_content_get_expand (content) && new_states[i] == NORMAL)
1514 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1516 ToolbarContent *content = list->data;
1518 if (toolbar_content_get_expand (content) && new_states[i] == NORMAL)
1520 gint extra = size / n_expand_items;
1521 if (size % n_expand_items != 0)
1524 allocations[i].width += extra;
1530 g_assert (n_expand_items == 0);
1533 /* position items */
1535 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1537 /* both NORMAL and OVERFLOWN items get a position. This ensures
1538 * that sliding will work for OVERFLOWN items too
1540 if (new_states[i] == NORMAL ||
1541 new_states[i] == OVERFLOWN)
1543 allocations[i].x = pos;
1544 allocations[i].y = border_width;
1545 allocations[i].height = short_size;
1547 pos += allocations[i].width;
1551 /* position arrow */
1554 arrow_allocation.x = available_size - border_width - arrow_allocation.width;
1555 arrow_allocation.y = border_width;
1558 item_area.x = border_width;
1559 item_area.y = border_width;
1560 item_area.width = available_size - (need_arrow? arrow_size : 0);
1561 item_area.height = short_size;
1563 /* fix up allocations in the vertical or RTL cases */
1564 if (toolbar->orientation == GTK_ORIENTATION_VERTICAL)
1566 for (i = 0; i < n_items; ++i)
1567 fixup_allocation_for_vertical (&(allocations[i]));
1570 fixup_allocation_for_vertical (&arrow_allocation);
1572 fixup_allocation_for_vertical (&item_area);
1574 else if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
1576 for (i = 0; i < n_items; ++i)
1577 fixup_allocation_for_rtl (available_size, &(allocations[i]));
1580 fixup_allocation_for_rtl (available_size, &arrow_allocation);
1582 fixup_allocation_for_rtl (available_size, &item_area);
1585 /* translate the items by allocation->(x,y) */
1586 for (i = 0; i < n_items; ++i)
1588 allocations[i].x += allocation->x;
1589 allocations[i].y += allocation->y;
1591 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1593 allocations[i].x += widget->style->xthickness;
1594 allocations[i].y += widget->style->ythickness;
1600 arrow_allocation.x += allocation->x;
1601 arrow_allocation.y += allocation->y;
1603 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1605 arrow_allocation.x += widget->style->xthickness;
1606 arrow_allocation.y += widget->style->ythickness;
1610 item_area.x += allocation->x;
1611 item_area.y += allocation->y;
1612 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1614 item_area.x += widget->style->xthickness;
1615 item_area.y += widget->style->ythickness;
1618 /* did anything change? */
1619 for (list = priv->content, i = 0; list != NULL; list = list->next, i++)
1621 ToolbarContent *content = list->data;
1623 if (toolbar_content_get_state (content) == NORMAL &&
1624 new_states[i] != NORMAL)
1626 /* an item disappeared and we didn't change size, so begin sliding */
1627 if (!size_changed && priv->api_mode == NEW_API)
1628 gtk_toolbar_begin_sliding (toolbar);
1632 /* finally allocate the items */
1633 if (priv->is_sliding)
1635 for (list = priv->content, i = 0; list != NULL; list = list->next, i++)
1637 ToolbarContent *content = list->data;
1639 toolbar_content_set_goal_allocation (content, &(allocations[i]));
1643 elapsed = g_timer_elapsed (priv->timer, NULL);
1644 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1646 ToolbarContent *content = list->data;
1648 if (new_states[i] == OVERFLOWN ||
1649 new_states[i] == NORMAL)
1651 GtkAllocation alloc;
1652 GtkAllocation start_allocation;
1653 GtkAllocation goal_allocation;
1655 if (priv->is_sliding)
1657 toolbar_content_get_start_allocation (content, &start_allocation);
1658 toolbar_content_get_goal_allocation (content, &goal_allocation);
1660 compute_intermediate_allocation (toolbar,
1665 priv->need_sync = TRUE;
1669 alloc = allocations[i];
1672 if (alloc.width == 0 || alloc.height == 0)
1674 toolbar_content_set_child_visible (content, toolbar, FALSE);
1678 if (!rect_within (&alloc, &item_area))
1680 toolbar_content_set_child_visible (content, toolbar, FALSE);
1681 toolbar_content_size_allocate (content, &alloc);
1685 toolbar_content_set_child_visible (content, toolbar, TRUE);
1686 toolbar_content_size_allocate (content, &alloc);
1692 toolbar_content_set_child_visible (content, toolbar, FALSE);
1695 toolbar_content_set_state (content, new_states[i]);
1698 if (priv->menu && priv->need_rebuild)
1699 rebuild_menu (toolbar);
1703 gtk_widget_size_allocate (GTK_WIDGET (priv->arrow_button),
1705 gtk_widget_show (GTK_WIDGET (priv->arrow_button));
1709 gtk_widget_hide (GTK_WIDGET (priv->arrow_button));
1711 if (priv->menu && GTK_WIDGET_VISIBLE (priv->menu))
1712 gtk_menu_shell_deactivate (GTK_MENU_SHELL (priv->menu));
1715 g_free (allocations);
1716 g_free (new_states);
1720 gtk_toolbar_update_button_relief (GtkToolbar *toolbar)
1722 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1724 gtk_toolbar_reconfigured (toolbar);
1726 gtk_button_set_relief (GTK_BUTTON (priv->arrow_button), get_button_relief (toolbar));
1730 gtk_toolbar_style_set (GtkWidget *widget,
1731 GtkStyle *prev_style)
1733 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
1735 priv->max_homogeneous_pixels = -1;
1737 if (GTK_WIDGET_REALIZED (widget))
1738 gtk_style_set_background (widget->style, widget->window, widget->state);
1741 gtk_toolbar_update_button_relief (GTK_TOOLBAR (widget));
1745 gtk_toolbar_list_children_in_focus_order (GtkToolbar *toolbar,
1746 GtkDirectionType dir)
1748 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1749 GList *result = NULL;
1753 /* generate list of children in reverse logical order */
1755 for (list = priv->content; list != NULL; list = list->next)
1757 ToolbarContent *content = list->data;
1760 widget = toolbar_content_get_widget (content);
1763 result = g_list_prepend (result, widget);
1766 result = g_list_prepend (result, priv->arrow_button);
1768 rtl = (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL);
1770 /* move in logical order when
1772 * - dir is TAB_FORWARD
1774 * - in RTL mode and moving left or up
1776 * - in LTR mode and moving right or down
1778 if (dir == GTK_DIR_TAB_FORWARD ||
1779 (rtl && (dir == GTK_DIR_UP || dir == GTK_DIR_LEFT)) ||
1780 (!rtl && (dir == GTK_DIR_DOWN || dir == GTK_DIR_RIGHT)))
1782 result = g_list_reverse (result);
1789 gtk_toolbar_focus_home_or_end (GtkToolbar *toolbar,
1790 gboolean focus_home)
1792 GList *children, *list;
1793 GtkDirectionType dir = focus_home? GTK_DIR_RIGHT : GTK_DIR_LEFT;
1795 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1797 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
1799 children = g_list_reverse (children);
1801 dir = (dir == GTK_DIR_RIGHT)? GTK_DIR_LEFT : GTK_DIR_RIGHT;
1804 for (list = children; list != NULL; list = list->next)
1806 GtkWidget *child = list->data;
1808 if (GTK_CONTAINER (toolbar)->focus_child == child)
1811 if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1815 g_list_free (children);
1820 /* Keybinding handler. This function is called when the user presses
1821 * Ctrl TAB or an arrow key.
1824 gtk_toolbar_move_focus (GtkToolbar *toolbar,
1825 GtkDirectionType dir)
1828 gboolean try_focus = FALSE;
1830 GtkContainer *container = GTK_CONTAINER (toolbar);
1832 if (container->focus_child &&
1833 gtk_widget_child_focus (container->focus_child, dir))
1838 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1840 for (list = children; list != NULL; list = list->next)
1842 GtkWidget *child = list->data;
1844 if (try_focus && GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1847 if (child == GTK_CONTAINER (toolbar)->focus_child)
1851 g_list_free (children);
1856 /* The focus handler for the toolbar. It called when the user presses
1857 * TAB or otherwise tries to focus the toolbar.
1860 gtk_toolbar_focus (GtkWidget *widget,
1861 GtkDirectionType dir)
1863 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1864 GList *children, *list;
1865 gboolean result = FALSE;
1867 /* if focus is already somewhere inside the toolbar then return FALSE.
1868 * The only way focus can stay inside the toolbar is when the user presses
1869 * arrow keys or Ctrl TAB (both of which are handled by the
1870 * gtk_toolbar_move_focus() keybinding function.
1872 if (GTK_CONTAINER (widget)->focus_child)
1875 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1877 for (list = children; list != NULL; list = list->next)
1879 GtkWidget *child = list->data;
1881 if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1888 g_list_free (children);
1894 style_change_notify (GtkToolbar *toolbar)
1896 if (!toolbar->style_set)
1898 /* pretend it was set, then unset, thus reverting to new default */
1899 toolbar->style_set = TRUE;
1900 gtk_toolbar_unset_style (toolbar);
1905 icon_size_change_notify (GtkToolbar *toolbar)
1907 if (!toolbar->icon_size_set)
1909 /* pretend it was set, then unset, thus reverting to new default */
1910 toolbar->icon_size_set = TRUE;
1911 gtk_toolbar_unset_icon_size (toolbar);
1915 static GtkSettings *
1916 toolbar_get_settings (GtkToolbar *toolbar)
1918 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1919 return priv->settings;
1923 gtk_toolbar_screen_changed (GtkWidget *widget,
1924 GdkScreen *previous_screen)
1926 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
1927 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1928 GtkSettings *old_settings = toolbar_get_settings (toolbar);
1929 GtkSettings *settings;
1931 if (gtk_widget_has_screen (GTK_WIDGET (toolbar)))
1932 settings = gtk_widget_get_settings (GTK_WIDGET (toolbar));
1936 if (settings == old_settings)
1941 g_signal_handler_disconnect (old_settings, toolbar->style_set_connection);
1942 g_signal_handler_disconnect (old_settings, toolbar->icon_size_connection);
1944 g_object_unref (old_settings);
1949 toolbar->style_set_connection =
1950 g_signal_connect_swapped (settings,
1951 "notify::gtk-toolbar-style",
1952 G_CALLBACK (style_change_notify),
1954 toolbar->icon_size_connection =
1955 g_signal_connect_swapped (settings,
1956 "notify::gtk-toolbar-icon-size",
1957 G_CALLBACK (icon_size_change_notify),
1960 g_object_ref (settings);
1961 priv->settings = settings;
1964 priv->settings = NULL;
1966 style_change_notify (toolbar);
1967 icon_size_change_notify (toolbar);
1971 find_drop_index (GtkToolbar *toolbar,
1975 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1976 GList *interesting_content;
1978 GtkOrientation orientation;
1979 GtkTextDirection direction;
1980 gint best_distance = G_MAXINT;
1984 ToolbarContent *best_content;
1985 GtkAllocation allocation;
1987 /* list items we care about wrt. drag and drop */
1988 interesting_content = NULL;
1989 for (list = priv->content; list != NULL; list = list->next)
1991 ToolbarContent *content = list->data;
1993 if (toolbar_content_get_state (content) == NORMAL)
1994 interesting_content = g_list_prepend (interesting_content, content);
1996 interesting_content = g_list_reverse (interesting_content);
1998 if (!interesting_content)
2001 orientation = toolbar->orientation;
2002 direction = gtk_widget_get_direction (GTK_WIDGET (toolbar));
2004 /* distance to first interesting item */
2005 best_content = interesting_content->data;
2006 toolbar_content_get_allocation (best_content, &allocation);
2008 if (orientation == GTK_ORIENTATION_HORIZONTAL)
2012 if (direction == GTK_TEXT_DIR_LTR)
2015 pos = allocation.x + allocation.width;
2023 best_content = NULL;
2024 best_distance = ABS (pos - cursor);
2026 /* distance to far end of each item */
2027 for (list = interesting_content; list != NULL; list = list->next)
2029 ToolbarContent *content = list->data;
2031 toolbar_content_get_allocation (content, &allocation);
2033 if (orientation == GTK_ORIENTATION_HORIZONTAL)
2035 if (direction == GTK_TEXT_DIR_LTR)
2036 pos = allocation.x + allocation.width;
2042 pos = allocation.y + allocation.height;
2045 distance = ABS (pos - cursor);
2047 if (distance < best_distance)
2049 best_distance = distance;
2050 best_content = content;
2054 g_list_free (interesting_content);
2059 return g_list_index (priv->content, best_content) + 1;
2063 reset_all_placeholders (GtkToolbar *toolbar)
2065 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2068 for (list = priv->content; list != NULL; list = list->next)
2070 ToolbarContent *content = list->data;
2071 if (toolbar_content_is_placeholder (content))
2072 toolbar_content_set_disappearing (content, TRUE);
2077 physical_to_logical (GtkToolbar *toolbar,
2080 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2084 g_assert (physical >= 0);
2087 for (list = priv->content; list && physical > 0; list = list->next)
2089 ToolbarContent *content = list->data;
2091 if (!toolbar_content_is_placeholder (content))
2096 g_assert (physical == 0);
2102 logical_to_physical (GtkToolbar *toolbar,
2105 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2109 g_assert (logical >= 0);
2112 for (list = priv->content; list; list = list->next)
2114 ToolbarContent *content = list->data;
2116 if (!toolbar_content_is_placeholder (content))
2126 g_assert (logical == 0);
2132 * gtk_toolbar_set_drop_highlight_item:
2133 * @toolbar: a #GtkToolbar
2134 * @tool_item: a #GtkToolItem, or %NULL to turn of highlighting
2135 * @index_: a position on @toolbar
2137 * Highlights @toolbar to give an idea of what it would look like
2138 * if @item was added to @toolbar at the position indicated by @index_.
2139 * If @item is %NULL, highlighting is turned off. In that case @index_
2142 * The @tool_item passed to this function must not be part of any widget
2143 * hierarchy. When an item is set as drop highlight item it can not
2144 * added to any widget hierarchy or used as highlight item for another
2150 gtk_toolbar_set_drop_highlight_item (GtkToolbar *toolbar,
2151 GtkToolItem *tool_item,
2154 ToolbarContent *content;
2155 GtkToolbarPrivate *priv;
2157 GtkRequisition requisition;
2158 GtkRequisition old_requisition;
2159 gboolean restart_sliding;
2161 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2162 g_return_if_fail (tool_item == NULL || GTK_IS_TOOL_ITEM (tool_item));
2164 gtk_toolbar_check_new_api (toolbar);
2166 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2170 if (priv->highlight_tool_item)
2172 gtk_widget_unparent (GTK_WIDGET (priv->highlight_tool_item));
2173 g_object_unref (priv->highlight_tool_item);
2174 priv->highlight_tool_item = NULL;
2177 reset_all_placeholders (toolbar);
2178 gtk_toolbar_begin_sliding (toolbar);
2182 n_items = gtk_toolbar_get_n_items (toolbar);
2183 if (index_ < 0 || index_ > n_items)
2186 if (tool_item != priv->highlight_tool_item)
2188 if (priv->highlight_tool_item)
2189 g_object_unref (priv->highlight_tool_item);
2191 g_object_ref (tool_item);
2192 gtk_object_sink (GTK_OBJECT (tool_item));
2194 priv->highlight_tool_item = tool_item;
2196 gtk_widget_set_parent (GTK_WIDGET (priv->highlight_tool_item),
2197 GTK_WIDGET (toolbar));
2200 index_ = logical_to_physical (toolbar, index_);
2202 content = g_list_nth_data (priv->content, index_);
2206 ToolbarContent *prev_content;
2208 prev_content = g_list_nth_data (priv->content, index_ - 1);
2210 if (prev_content && toolbar_content_is_placeholder (prev_content))
2211 content = prev_content;
2214 if (!content || !toolbar_content_is_placeholder (content))
2216 GtkWidget *placeholder;
2218 placeholder = GTK_WIDGET (gtk_separator_tool_item_new ());
2220 content = toolbar_content_new_tool_item (toolbar,
2221 GTK_TOOL_ITEM (placeholder),
2223 gtk_widget_show (placeholder);
2227 g_assert (toolbar_content_is_placeholder (content));
2229 gtk_widget_size_request (GTK_WIDGET (priv->highlight_tool_item),
2233 restart_sliding = FALSE;
2234 toolbar_content_size_request (content, toolbar, &old_requisition);
2235 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
2237 requisition.height = -1;
2238 if (requisition.width != old_requisition.width)
2239 restart_sliding = TRUE;
2243 requisition.width = -1;
2244 if (requisition.height != old_requisition.height)
2245 restart_sliding = TRUE;
2248 if (toolbar_content_disappearing (content))
2249 restart_sliding = TRUE;
2251 reset_all_placeholders (toolbar);
2252 toolbar_content_set_disappearing (content, FALSE);
2254 toolbar_content_set_size_request (content,
2255 requisition.width, requisition.height);
2257 if (restart_sliding)
2258 gtk_toolbar_begin_sliding (toolbar);
2262 gtk_toolbar_get_child_property (GtkContainer *container,
2268 GtkToolItem *item = GTK_TOOL_ITEM (child);
2270 switch (property_id)
2272 case CHILD_PROP_HOMOGENEOUS:
2273 g_value_set_boolean (value, gtk_tool_item_get_homogeneous (item));
2276 case CHILD_PROP_EXPAND:
2277 g_value_set_boolean (value, gtk_tool_item_get_expand (item));
2281 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
2287 gtk_toolbar_set_child_property (GtkContainer *container,
2290 const GValue *value,
2293 switch (property_id)
2295 case CHILD_PROP_HOMOGENEOUS:
2296 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
2299 case CHILD_PROP_EXPAND:
2300 gtk_tool_item_set_expand (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
2304 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
2310 gtk_toolbar_show_all (GtkWidget *widget)
2312 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
2315 for (list = priv->content; list != NULL; list = list->next)
2317 ToolbarContent *content = list->data;
2319 toolbar_content_show_all (content);
2322 gtk_widget_show (widget);
2326 gtk_toolbar_hide_all (GtkWidget *widget)
2328 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
2331 for (list = priv->content; list != NULL; list = list->next)
2333 ToolbarContent *content = list->data;
2335 toolbar_content_hide_all (content);
2338 gtk_widget_hide (widget);
2342 gtk_toolbar_add (GtkContainer *container,
2345 GtkToolbar *toolbar;
2347 g_return_if_fail (GTK_IS_TOOLBAR (container));
2348 g_return_if_fail (widget != NULL);
2350 toolbar = GTK_TOOLBAR (container);
2352 if (GTK_IS_TOOL_ITEM (widget))
2353 gtk_toolbar_insert (toolbar, GTK_TOOL_ITEM (widget), -1);
2355 gtk_toolbar_append_widget (toolbar, widget, NULL, NULL);
2359 gtk_toolbar_remove (GtkContainer *container,
2362 GtkToolbar *toolbar;
2363 GtkToolbarPrivate *priv;
2364 ToolbarContent *content_to_remove;
2367 g_return_if_fail (GTK_IS_TOOLBAR (container));
2368 g_return_if_fail (GTK_IS_WIDGET (widget));
2370 toolbar = GTK_TOOLBAR (container);
2371 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2373 content_to_remove = NULL;
2374 for (list = priv->content; list != NULL; list = list->next)
2376 ToolbarContent *content = list->data;
2379 child = toolbar_content_get_widget (content);
2380 if (child && child == widget)
2382 content_to_remove = content;
2387 g_return_if_fail (content_to_remove != NULL);
2389 toolbar_content_remove (content_to_remove, toolbar);
2390 toolbar_content_free (content_to_remove);
2394 gtk_toolbar_forall (GtkContainer *container,
2395 gboolean include_internals,
2396 GtkCallback callback,
2397 gpointer callback_data)
2399 GtkToolbar *toolbar = GTK_TOOLBAR (container);
2400 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2403 g_return_if_fail (callback != NULL);
2405 list = priv->content;
2408 ToolbarContent *content = list->data;
2409 GList *next = list->next;
2411 if (include_internals || !toolbar_content_is_placeholder (content))
2413 GtkWidget *child = toolbar_content_get_widget (content);
2416 (*callback) (child, callback_data);
2422 if (include_internals)
2423 (* callback) (priv->arrow_button, callback_data);
2427 gtk_toolbar_child_type (GtkContainer *container)
2429 return GTK_TYPE_TOOL_ITEM;
2433 gtk_toolbar_reconfigured (GtkToolbar *toolbar)
2435 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2438 list = priv->content;
2441 ToolbarContent *content = list->data;
2442 GList *next = list->next;
2444 toolbar_content_toolbar_reconfigured (content, toolbar);
2451 gtk_toolbar_orientation_changed (GtkToolbar *toolbar,
2452 GtkOrientation orientation)
2454 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2455 if (toolbar->orientation != orientation)
2457 toolbar->orientation = orientation;
2459 if (orientation == GTK_ORIENTATION_HORIZONTAL)
2460 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_DOWN, GTK_SHADOW_NONE);
2462 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
2464 gtk_toolbar_reconfigured (toolbar);
2466 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2467 g_object_notify (G_OBJECT (toolbar), "orientation");
2472 gtk_toolbar_real_style_changed (GtkToolbar *toolbar,
2473 GtkToolbarStyle style)
2475 if (toolbar->style != style)
2477 toolbar->style = style;
2479 gtk_toolbar_reconfigured (toolbar);
2481 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2482 g_object_notify (G_OBJECT (toolbar), "toolbar_style");
2487 menu_position_func (GtkMenu *menu,
2493 GtkToolbar *toolbar = GTK_TOOLBAR (user_data);
2494 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2496 GtkRequisition menu_req;
2498 gdk_window_get_origin (GTK_BUTTON (priv->arrow_button)->event_window, x, y);
2499 gtk_widget_size_request (priv->arrow_button, &req);
2500 gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
2502 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
2504 *y += priv->arrow_button->allocation.height;
2505 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
2506 *x += priv->arrow_button->allocation.width - req.width;
2508 *x += req.width - menu_req.width;
2512 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
2513 *x += priv->arrow_button->allocation.width;
2515 *x -= menu_req.width;
2516 *y += priv->arrow_button->allocation.height - req.height;
2523 show_menu (GtkToolbar *toolbar,
2524 GdkEventButton *event)
2526 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2528 rebuild_menu (toolbar);
2530 gtk_widget_show_all (GTK_WIDGET (priv->menu));
2532 gtk_menu_popup (priv->menu, NULL, NULL,
2533 menu_position_func, toolbar,
2534 event? event->button : 0,
2535 event? event->time : gtk_get_current_event_time());
2539 gtk_toolbar_arrow_button_clicked (GtkWidget *button,
2540 GtkToolbar *toolbar)
2542 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2544 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->arrow_button)) &&
2545 (!priv->menu || !GTK_WIDGET_VISIBLE (priv->menu)))
2547 /* We only get here when the button is clicked with the keyboard,
2548 * because mouse button presses result in the menu being shown so
2549 * that priv->menu would be non-NULL and visible.
2551 show_menu (toolbar, NULL);
2552 gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->menu), FALSE);
2557 gtk_toolbar_arrow_button_press (GtkWidget *button,
2558 GdkEventButton *event,
2559 GtkToolbar *toolbar)
2561 show_menu (toolbar, event);
2562 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
2568 gtk_toolbar_button_press (GtkWidget *toolbar,
2569 GdkEventButton *event)
2571 if (event->button == 3)
2573 gboolean return_value;
2575 g_signal_emit (toolbar, toolbar_signals[POPUP_CONTEXT_MENU], 0,
2576 (int)event->x_root, (int)event->y_root, event->button,
2579 return return_value;
2586 gtk_toolbar_popup_menu (GtkWidget *toolbar)
2588 gboolean return_value;
2589 /* This function is the handler for the "popup menu" keybinding,
2590 * ie., it is called when the user presses Shift F10
2592 g_signal_emit (toolbar, toolbar_signals[POPUP_CONTEXT_MENU], 0,
2593 -1, -1, -1, &return_value);
2595 return return_value;
2601 * Creates a new toolbar.
2603 * Return Value: the newly-created toolbar.
2606 gtk_toolbar_new (void)
2608 GtkToolbar *toolbar;
2610 toolbar = g_object_new (GTK_TYPE_TOOLBAR, NULL);
2612 return GTK_WIDGET (toolbar);
2616 * gtk_toolbar_insert:
2617 * @toolbar: a #GtkToolbar
2618 * @item: a #GtkToolItem
2619 * @pos: the position of the new item
2621 * Insert a #GtkToolItem into the toolbar at position @pos. If @pos is
2622 * 0 the item is prepended to the start of the toolbar. If @pos is
2623 * negative, the item is appended to the end of the toolbar.
2628 gtk_toolbar_insert (GtkToolbar *toolbar,
2632 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2633 g_return_if_fail (GTK_IS_TOOL_ITEM (item));
2635 if (!gtk_toolbar_check_new_api (toolbar))
2639 pos = logical_to_physical (toolbar, pos);
2641 toolbar_content_new_tool_item (toolbar, item, FALSE, pos);
2645 * gtk_toolbar_get_item_index:
2646 * @toolbar: a #GtkToolbar
2647 * @item: a #GtkToolItem that is a child of @toolbar
2649 * Returns the position of @item on the toolbar, starting from 0.
2650 * It is an error if @item is not a child of the toolbar.
2652 * Return value: the position of item on the toolbar.
2657 gtk_toolbar_get_item_index (GtkToolbar *toolbar,
2660 GtkToolbarPrivate *priv;
2664 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
2665 g_return_val_if_fail (GTK_IS_TOOL_ITEM (item), -1);
2666 g_return_val_if_fail (GTK_WIDGET (item)->parent == GTK_WIDGET (toolbar), -1);
2668 if (!gtk_toolbar_check_new_api (toolbar))
2671 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2674 for (list = priv->content; list != NULL; list = list->next)
2676 ToolbarContent *content = list->data;
2679 widget = toolbar_content_get_widget (content);
2681 if (item == GTK_TOOL_ITEM (widget))
2687 return physical_to_logical (toolbar, n);
2691 * gtk_toolbar_set_orientation:
2692 * @toolbar: a #GtkToolbar.
2693 * @orientation: a new #GtkOrientation.
2695 * Sets whether a toolbar should appear horizontally or vertically.
2698 gtk_toolbar_set_orientation (GtkToolbar *toolbar,
2699 GtkOrientation orientation)
2701 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2703 g_signal_emit (toolbar, toolbar_signals[ORIENTATION_CHANGED], 0, orientation);
2707 * gtk_toolbar_get_orientation:
2708 * @toolbar: a #GtkToolbar
2710 * Retrieves the current orientation of the toolbar. See
2711 * gtk_toolbar_set_orientation().
2713 * Return value: the orientation
2716 gtk_toolbar_get_orientation (GtkToolbar *toolbar)
2718 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_ORIENTATION_HORIZONTAL);
2720 return toolbar->orientation;
2724 * gtk_toolbar_set_style:
2725 * @toolbar: a #GtkToolbar.
2726 * @style: the new style for @toolbar.
2728 * Alters the view of @toolbar to display either icons only, text only, or both.
2731 gtk_toolbar_set_style (GtkToolbar *toolbar,
2732 GtkToolbarStyle style)
2734 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2736 toolbar->style_set = TRUE;
2737 g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
2741 * gtk_toolbar_get_style:
2742 * @toolbar: a #GtkToolbar
2744 * Retrieves whether the toolbar has text, icons, or both . See
2745 * gtk_toolbar_set_style().
2747 * Return value: the current style of @toolbar
2750 gtk_toolbar_get_style (GtkToolbar *toolbar)
2752 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), DEFAULT_TOOLBAR_STYLE);
2754 return toolbar->style;
2758 * gtk_toolbar_unset_style:
2759 * @toolbar: a #GtkToolbar
2761 * Unsets a toolbar style set with gtk_toolbar_set_style(), so that
2762 * user preferences will be used to determine the toolbar style.
2765 gtk_toolbar_unset_style (GtkToolbar *toolbar)
2767 GtkToolbarStyle style;
2769 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2771 if (toolbar->style_set)
2773 GtkSettings *settings = toolbar_get_settings (toolbar);
2776 g_object_get (settings,
2777 "gtk-toolbar-style", &style,
2780 style = DEFAULT_TOOLBAR_STYLE;
2782 if (style != toolbar->style)
2783 g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
2785 toolbar->style_set = FALSE;
2790 * gtk_toolbar_set_tooltips:
2791 * @toolbar: a #GtkToolbar.
2792 * @enable: set to %FALSE to disable the tooltips, or %TRUE to enable them.
2794 * Sets if the tooltips of a toolbar should be active or not.
2797 gtk_toolbar_set_tooltips (GtkToolbar *toolbar,
2800 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2803 gtk_tooltips_enable (toolbar->tooltips);
2805 gtk_tooltips_disable (toolbar->tooltips);
2809 * gtk_toolbar_get_tooltips:
2810 * @toolbar: a #GtkToolbar
2812 * Retrieves whether tooltips are enabled. See
2813 * gtk_toolbar_set_tooltips().
2815 * Return value: %TRUE if tooltips are enabled
2818 gtk_toolbar_get_tooltips (GtkToolbar *toolbar)
2820 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2822 return toolbar->tooltips->enabled;
2826 * gtk_toolbar_get_n_items:
2827 * @toolbar: a #GtkToolbar
2829 * Returns the number of items on the toolbar.
2831 * Return value: the number of items on the toolbar
2836 gtk_toolbar_get_n_items (GtkToolbar *toolbar)
2838 GtkToolbarPrivate *priv;
2840 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
2842 if (!gtk_toolbar_check_new_api (toolbar))
2845 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2847 return physical_to_logical (toolbar, g_list_length (priv->content));
2851 * gtk_toolbar_get_nth_item:
2852 * @toolbar: a #GtkToolbar
2853 * @n: A position on the toolbar
2855 * Returns the @n<!-- -->'s item on @toolbar, or %NULL if the
2856 * toolbar does not contain an @n<!-- -->'th item.
2858 * Return value: The @n<!-- -->'th #GtkToolItem on @toolbar, or %NULL if there
2859 * isn't an @n<!-- -->th item.
2864 gtk_toolbar_get_nth_item (GtkToolbar *toolbar,
2867 GtkToolbarPrivate *priv;
2868 ToolbarContent *content;
2871 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
2873 if (!gtk_toolbar_check_new_api (toolbar))
2876 n_items = gtk_toolbar_get_n_items (toolbar);
2878 if (n < 0 || n >= n_items)
2881 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2883 content = g_list_nth_data (priv->content, logical_to_physical (toolbar, n));
2886 g_assert (!toolbar_content_is_placeholder (content));
2888 return GTK_TOOL_ITEM (toolbar_content_get_widget (content));
2892 * gtk_toolbar_get_icon_size:
2893 * @toolbar: a #GtkToolbar
2895 * Retrieves the icon size fo the toolbar. See gtk_toolbar_set_icon_size().
2897 * Return value: the current icon size for the icons on the toolbar.
2900 gtk_toolbar_get_icon_size (GtkToolbar *toolbar)
2902 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), DEFAULT_ICON_SIZE);
2904 return toolbar->icon_size;
2908 * gtk_toolbar_get_relief_style:
2909 * @toolbar: a #GtkToolbar
2911 * Returns the relief style of buttons on @toolbar. See
2912 * gtk_button_set_relief().
2914 * Return value: The relief style of buttons on @toolbar.
2919 gtk_toolbar_get_relief_style (GtkToolbar *toolbar)
2921 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_RELIEF_NONE);
2923 return get_button_relief (toolbar);
2927 * gtk_toolbar_set_show_arrow:
2928 * @toolbar: a #GtkToolbar
2929 * @show_arrow: Whether to show an overflow menu
2931 * Sets whether to show an overflow menu when
2932 * @toolbar doesn't have room for all items on it. If %TRUE,
2933 * items that there are not room are available through an
2939 gtk_toolbar_set_show_arrow (GtkToolbar *toolbar,
2940 gboolean show_arrow)
2942 GtkToolbarPrivate *priv;
2944 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2946 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2947 show_arrow = show_arrow != FALSE;
2949 if (priv->show_arrow != show_arrow)
2951 priv->show_arrow = show_arrow;
2953 if (!priv->show_arrow)
2954 gtk_widget_hide (priv->arrow_button);
2956 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2957 g_object_notify (G_OBJECT (toolbar), "show_arrow");
2962 * gtk_toolbar_get_show_arrow:
2963 * @toolbar: a #GtkToolbar
2965 * Returns whether the toolbar has an overflow menu.
2966 * See gtk_toolbar_set_show_arrow()
2973 gtk_toolbar_get_show_arrow (GtkToolbar *toolbar)
2975 GtkToolbarPrivate *priv;
2977 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2979 if (!gtk_toolbar_check_new_api (toolbar))
2982 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2984 return priv->show_arrow;
2988 * gtk_toolbar_get_drop_index:
2989 * @toolbar: a #GtkToolbar
2990 * @x: x coordinate of a point on the toolbar
2991 * @y: y coordinate of a point on the toolbar
2993 * Returns the position corresponding to the indicated point on
2994 * @toolbar. This is useful when dragging items to the toolbar:
2995 * this function returns the position a new item should be
2998 * @x and @y are in @toolbar coordinates.
3000 * Return value: The position corresponding to the point (@x, @y) on the toolbar.
3005 gtk_toolbar_get_drop_index (GtkToolbar *toolbar,
3009 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
3011 if (!gtk_toolbar_check_new_api (toolbar))
3014 return physical_to_logical (toolbar, find_drop_index (toolbar, x, y));
3018 gtk_toolbar_finalize (GObject *object)
3021 GtkToolbar *toolbar = GTK_TOOLBAR (object);
3022 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3024 if (toolbar->tooltips)
3025 g_object_unref (toolbar->tooltips);
3027 if (priv->arrow_button)
3028 gtk_widget_unparent (priv->arrow_button);
3030 for (list = priv->content; list != NULL; list = list->next)
3032 ToolbarContent *content = list->data;
3034 toolbar_content_free (content);
3037 g_list_free (priv->content);
3038 g_list_free (toolbar->children);
3040 g_timer_destroy (priv->timer);
3043 gtk_widget_destroy (GTK_WIDGET (priv->menu));
3046 g_source_remove (priv->idle_id);
3048 G_OBJECT_CLASS (parent_class)->finalize (object);
3056 * gtk_toolbar_set_icon_size:
3057 * @toolbar: A #GtkToolbar
3058 * @icon_size: The #GtkIconSize that stock icons in the toolbar shall have.
3060 * This function sets the size of stock icons in the toolbar. You
3061 * can call it both before you add the icons and after they've been
3062 * added. The size you set will override user preferences for the default
3066 gtk_toolbar_set_icon_size (GtkToolbar *toolbar,
3067 GtkIconSize icon_size)
3069 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
3071 toolbar->icon_size_set = TRUE;
3073 if (toolbar->icon_size == icon_size)
3076 toolbar->icon_size = icon_size;
3078 gtk_toolbar_reconfigured (toolbar);
3080 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
3084 * gtk_toolbar_unset_icon_size:
3085 * @toolbar: a #GtkToolbar
3087 * Unsets toolbar icon size set with gtk_toolbar_set_icon_size(), so that
3088 * user preferences will be used to determine the icon size.
3091 gtk_toolbar_unset_icon_size (GtkToolbar *toolbar)
3095 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
3097 if (toolbar->icon_size_set)
3099 GtkSettings *settings = toolbar_get_settings (toolbar);
3103 g_object_get (settings,
3104 "gtk-toolbar-icon-size", &size,
3108 size = DEFAULT_ICON_SIZE;
3110 if (size != toolbar->icon_size)
3111 gtk_toolbar_set_icon_size (toolbar, size);
3113 toolbar->icon_size_set = FALSE;
3118 * gtk_toolbar_append_item:
3119 * @toolbar: a #GtkToolbar.
3120 * @text: give your toolbar button a label.
3121 * @tooltip_text: a string that appears when the user holds the mouse over this item.
3122 * @tooltip_private_text: use with #GtkTipsQuery.
3123 * @icon: a #GtkWidget that should be used as the button's icon.
3124 * @callback: the function to be executed when the button is pressed.
3125 * @user_data: a pointer to any data you wish to be passed to the callback.
3127 * Inserts a new item into the toolbar. You must specify the position
3128 * in the toolbar where it will be inserted.
3130 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3131 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3133 * Return value: the new toolbar item as a #GtkWidget.
3136 gtk_toolbar_append_item (GtkToolbar *toolbar,
3138 const char *tooltip_text,
3139 const char *tooltip_private_text,
3141 GtkSignalFunc callback,
3144 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3146 tooltip_text, tooltip_private_text,
3147 icon, callback, user_data,
3148 toolbar->num_children);
3152 * gtk_toolbar_prepend_item:
3153 * @toolbar: a #GtkToolbar.
3154 * @text: give your toolbar button a label.
3155 * @tooltip_text: a string that appears when the user holds the mouse over this item.
3156 * @tooltip_private_text: use with #GtkTipsQuery.
3157 * @icon: a #GtkWidget that should be used as the button's icon.
3158 * @callback: the function to be executed when the button is pressed.
3159 * @user_data: a pointer to any data you wish to be passed to the callback.
3161 * Adds a new button to the beginning (top or left edges) of the given toolbar.
3163 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3164 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3166 * Return value: the new toolbar item as a #GtkWidget.
3169 gtk_toolbar_prepend_item (GtkToolbar *toolbar,
3171 const char *tooltip_text,
3172 const char *tooltip_private_text,
3174 GtkSignalFunc callback,
3177 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3179 tooltip_text, tooltip_private_text,
3180 icon, callback, user_data,
3185 * gtk_toolbar_insert_item:
3186 * @toolbar: a #GtkToolbar.
3187 * @text: give your toolbar button a label.
3188 * @tooltip_text: a string that appears when the user holds the mouse over this item.
3189 * @tooltip_private_text: use with #GtkTipsQuery.
3190 * @icon: a #GtkWidget that should be used as the button's icon.
3191 * @callback: the function to be executed when the button is pressed.
3192 * @user_data: a pointer to any data you wish to be passed to the callback.
3193 * @position: the number of widgets to insert this item after.
3195 * Inserts a new item into the toolbar. You must specify the position in the
3196 * toolbar where it will be inserted.
3198 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3199 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3201 * Return value: the new toolbar item as a #GtkWidget.
3204 gtk_toolbar_insert_item (GtkToolbar *toolbar,
3206 const char *tooltip_text,
3207 const char *tooltip_private_text,
3209 GtkSignalFunc callback,
3213 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3215 tooltip_text, tooltip_private_text,
3216 icon, callback, user_data,
3221 * gtk_toolbar_insert_stock:
3222 * @toolbar: A #GtkToolbar
3223 * @stock_id: The id of the stock item you want to insert
3224 * @tooltip_text: The text in the tooltip of the toolbar button
3225 * @tooltip_private_text: The private text of the tooltip
3226 * @callback: The callback called when the toolbar button is clicked.
3227 * @user_data: user data passed to callback
3228 * @position: The position the button shall be inserted at.
3229 * -1 means at the end.
3231 * Inserts a stock item at the specified position of the toolbar. If
3232 * @stock_id is not a known stock item ID, it's inserted verbatim,
3233 * except that underscores used to mark mnemonics are removed.
3235 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3236 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3238 * Returns: the inserted widget
3241 gtk_toolbar_insert_stock (GtkToolbar *toolbar,
3242 const gchar *stock_id,
3243 const char *tooltip_text,
3244 const char *tooltip_private_text,
3245 GtkSignalFunc callback,
3249 return internal_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3251 tooltip_text, tooltip_private_text,
3252 NULL, callback, user_data,
3257 * gtk_toolbar_append_space:
3258 * @toolbar: a #GtkToolbar.
3260 * Adds a new space to the end of the toolbar.
3263 gtk_toolbar_append_space (GtkToolbar *toolbar)
3265 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
3269 toolbar->num_children);
3273 * gtk_toolbar_prepend_space:
3274 * @toolbar: a #GtkToolbar.
3276 * Adds a new space to the beginning of the toolbar.
3279 gtk_toolbar_prepend_space (GtkToolbar *toolbar)
3281 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
3289 * gtk_toolbar_insert_space:
3290 * @toolbar: a #GtkToolbar
3291 * @position: the number of widgets after which a space should be inserted.
3293 * Inserts a new space in the toolbar at the specified position.
3296 gtk_toolbar_insert_space (GtkToolbar *toolbar,
3299 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
3307 * gtk_toolbar_remove_space:
3308 * @toolbar: a #GtkToolbar.
3309 * @position: the index of the space to remove.
3311 * Removes a space from the specified position.
3314 gtk_toolbar_remove_space (GtkToolbar *toolbar,
3317 GtkToolbarPrivate *priv;
3318 ToolbarContent *content;
3320 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
3322 if (!gtk_toolbar_check_old_api (toolbar))
3325 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3327 content = g_list_nth_data (priv->content, position);
3331 g_warning ("Toolbar position %d doesn't exist", position);
3335 if (!toolbar_content_is_separator (content))
3337 g_warning ("Toolbar position %d is not a space", position);
3341 toolbar_content_remove (content, toolbar);
3342 toolbar_content_free (content);
3346 * gtk_toolbar_append_widget:
3347 * @toolbar: a #GtkToolbar.
3348 * @widget: a #GtkWidget to add to the toolbar.
3349 * @tooltip_text: the element's tooltip.
3350 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3352 * Adds a widget to the end of the given toolbar.
3355 gtk_toolbar_append_widget (GtkToolbar *toolbar,
3357 const gchar *tooltip_text,
3358 const gchar *tooltip_private_text)
3360 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
3362 tooltip_text, tooltip_private_text,
3364 toolbar->num_children);
3368 * gtk_toolbar_prepend_widget:
3369 * @toolbar: a #GtkToolbar.
3370 * @widget: a #GtkWidget to add to the toolbar.
3371 * @tooltip_text: the element's tooltip.
3372 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3374 * Adds a widget to the beginning of the given toolbar.
3377 gtk_toolbar_prepend_widget (GtkToolbar *toolbar,
3379 const gchar *tooltip_text,
3380 const gchar *tooltip_private_text)
3382 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
3384 tooltip_text, tooltip_private_text,
3390 * gtk_toolbar_insert_widget:
3391 * @toolbar: a #GtkToolbar.
3392 * @widget: a #GtkWidget to add to the toolbar.
3393 * @tooltip_text: the element's tooltip.
3394 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3395 * @position: the number of widgets to insert this widget after.
3397 * Inserts a widget in the toolbar at the given position.
3400 gtk_toolbar_insert_widget (GtkToolbar *toolbar,
3402 const char *tooltip_text,
3403 const char *tooltip_private_text,
3406 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
3408 tooltip_text, tooltip_private_text,
3414 * gtk_toolbar_append_element:
3415 * @toolbar: a #GtkToolbar.
3416 * @type: a value of type #GtkToolbarChildType that determines what @widget will be.
3417 * @widget: a #GtkWidget, or %NULL.
3418 * @text: the element's label.
3419 * @tooltip_text: the element's tooltip.
3420 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3421 * @icon: a #GtkWidget that provides pictorial representation of the element's function.
3422 * @callback: the function to be executed when the button is pressed.
3423 * @user_data: any data you wish to pass to the callback.
3425 * Adds a new element to the end of a toolbar.
3427 * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element.
3428 * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine
3429 * the radio group for the new element. In all other cases, @widget must
3432 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3433 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3435 * Return value: the new toolbar element as a #GtkWidget.
3438 gtk_toolbar_append_element (GtkToolbar *toolbar,
3439 GtkToolbarChildType type,
3442 const char *tooltip_text,
3443 const char *tooltip_private_text,
3445 GtkSignalFunc callback,
3448 return gtk_toolbar_insert_element (toolbar, type, widget, text,
3449 tooltip_text, tooltip_private_text,
3450 icon, callback, user_data,
3451 toolbar->num_children);
3455 * gtk_toolbar_prepend_element:
3456 * @toolbar: a #GtkToolbar.
3457 * @type: a value of type #GtkToolbarChildType that determines what @widget will be.
3458 * @widget: a #GtkWidget, or %NULL
3459 * @text: the element's label.
3460 * @tooltip_text: the element's tooltip.
3461 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3462 * @icon: a #GtkWidget that provides pictorial representation of the element's function.
3463 * @callback: the function to be executed when the button is pressed.
3464 * @user_data: any data you wish to pass to the callback.
3466 * Adds a new element to the beginning of a toolbar.
3468 * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element.
3469 * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine
3470 * the radio group for the new element. In all other cases, @widget must
3473 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3474 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3476 * Return value: the new toolbar element as a #GtkWidget.
3479 gtk_toolbar_prepend_element (GtkToolbar *toolbar,
3480 GtkToolbarChildType type,
3483 const char *tooltip_text,
3484 const char *tooltip_private_text,
3486 GtkSignalFunc callback,
3489 return gtk_toolbar_insert_element (toolbar, type, widget, text,
3490 tooltip_text, tooltip_private_text,
3491 icon, callback, user_data, 0);
3495 * gtk_toolbar_insert_element:
3496 * @toolbar: a #GtkToolbar.
3497 * @type: a value of type #GtkToolbarChildType that determines what @widget
3499 * @widget: a #GtkWidget, or %NULL.
3500 * @text: the element's label.
3501 * @tooltip_text: the element's tooltip.
3502 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3503 * @icon: a #GtkWidget that provides pictorial representation of the element's function.
3504 * @callback: the function to be executed when the button is pressed.
3505 * @user_data: any data you wish to pass to the callback.
3506 * @position: the number of widgets to insert this element after.
3508 * Inserts a new element in the toolbar at the given position.
3510 * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element.
3511 * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine
3512 * the radio group for the new element. In all other cases, @widget must
3515 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3516 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3518 * Return value: the new toolbar element as a #GtkWidget.
3521 gtk_toolbar_insert_element (GtkToolbar *toolbar,
3522 GtkToolbarChildType type,
3525 const char *tooltip_text,
3526 const char *tooltip_private_text,
3528 GtkSignalFunc callback,
3532 return internal_insert_element (toolbar, type, widget, text,
3533 tooltip_text, tooltip_private_text,
3534 icon, callback, user_data, position, FALSE);
3538 set_child_packing_and_visibility(GtkToolbar *toolbar,
3539 GtkToolbarChild *child)
3544 box = gtk_bin_get_child (GTK_BIN (child->widget));
3546 g_return_if_fail (GTK_IS_BOX (box));
3550 expand = (toolbar->style != GTK_TOOLBAR_BOTH);
3552 gtk_box_set_child_packing (GTK_BOX (box), child->label,
3553 expand, expand, 0, GTK_PACK_END);
3555 if (toolbar->style != GTK_TOOLBAR_ICONS)
3556 gtk_widget_show (child->label);
3558 gtk_widget_hide (child->label);
3563 expand = (toolbar->style != GTK_TOOLBAR_BOTH_HORIZ);
3565 gtk_box_set_child_packing (GTK_BOX (box), child->icon,
3566 expand, expand, 0, GTK_PACK_END);
3568 if (toolbar->style != GTK_TOOLBAR_TEXT)
3569 gtk_widget_show (child->icon);
3571 gtk_widget_hide (child->icon);
3576 internal_insert_element (GtkToolbar *toolbar,
3577 GtkToolbarChildType type,
3580 const char *tooltip_text,
3581 const char *tooltip_private_text,
3583 GtkSignalFunc callback,
3589 ToolbarContent *content;
3590 GtkToolbarPrivate *priv;
3591 char *free_me = NULL;
3592 gboolean is_button = FALSE;
3594 GtkWidget *child_widget;
3595 GtkWidget *child_label;
3596 GtkWidget *child_icon;
3598 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
3599 if (type == GTK_TOOLBAR_CHILD_WIDGET)
3600 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3601 else if (type != GTK_TOOLBAR_CHILD_RADIOBUTTON)
3602 g_return_val_if_fail (widget == NULL, NULL);
3603 if (GTK_IS_TOOL_ITEM (widget))
3604 g_warning (MIXED_API_WARNING);
3606 if (!gtk_toolbar_check_old_api (toolbar))
3609 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3611 child_widget = NULL;
3617 case GTK_TOOLBAR_CHILD_SPACE:
3620 case GTK_TOOLBAR_CHILD_WIDGET:
3621 child_widget = widget;
3624 case GTK_TOOLBAR_CHILD_BUTTON:
3625 case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
3626 case GTK_TOOLBAR_CHILD_RADIOBUTTON:
3628 if (type == GTK_TOOLBAR_CHILD_BUTTON)
3630 child_widget = gtk_button_new ();
3632 else if (type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
3634 child_widget = gtk_toggle_button_new ();
3635 gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (child_widget), FALSE);
3637 else /* type == GTK_TOOLBAR_CHILD_RADIOBUTTON */
3639 GSList *group = NULL;
3642 group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
3644 child_widget = gtk_radio_button_new (group);
3645 gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (child_widget), FALSE);
3648 gtk_button_set_relief (GTK_BUTTON (child_widget), get_button_relief (toolbar));
3649 gtk_button_set_focus_on_click (GTK_BUTTON (child_widget), FALSE);
3653 g_signal_connect (child_widget, "clicked",
3654 callback, user_data);
3657 if (toolbar->style == GTK_TOOLBAR_BOTH_HORIZ)
3658 box = gtk_hbox_new (FALSE, 0);
3660 box = gtk_vbox_new (FALSE, 0);
3662 gtk_container_add (GTK_CONTAINER (child_widget), box);
3663 gtk_widget_show (box);
3665 if (text && use_stock)
3667 GtkStockItem stock_item;
3668 if (gtk_stock_lookup (text, &stock_item))
3671 icon = gtk_image_new_from_stock (text, toolbar->icon_size);
3673 text = free_me = _gtk_toolbar_elide_underscores (stock_item.label);
3679 child_label = gtk_label_new (text);
3681 gtk_container_add (GTK_CONTAINER (box), child_label);
3686 child_icon = GTK_WIDGET (icon);
3687 gtk_container_add (GTK_CONTAINER (box), child_icon);
3690 gtk_widget_show (child_widget);
3694 g_assert_not_reached ();
3698 if ((type != GTK_TOOLBAR_CHILD_SPACE) && tooltip_text)
3700 gtk_tooltips_set_tip (toolbar->tooltips, child_widget,
3701 tooltip_text, tooltip_private_text);
3704 content = toolbar_content_new_compatibility (toolbar, type, child_widget,
3705 child_icon, child_label, position);
3710 return child_widget;
3714 * ToolbarContent methods
3716 struct _ToolbarContent
3726 GtkAllocation start_allocation;
3727 GtkAllocation goal_allocation;
3728 guint is_placeholder : 1;
3729 guint disappearing : 1;
3734 GtkToolbarChild child;
3735 GtkAllocation space_allocation;
3736 guint space_visible : 1;
3741 static ToolbarContent *
3742 toolbar_content_new_tool_item (GtkToolbar *toolbar,
3744 gboolean is_placeholder,
3747 ToolbarContent *content;
3748 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3750 content = g_new0 (ToolbarContent, 1);
3752 content->type = TOOL_ITEM;
3753 content->state = NOT_ALLOCATED;
3754 content->u.tool_item.item = item;
3755 content->u.tool_item.is_placeholder = is_placeholder;
3757 gtk_widget_set_parent (GTK_WIDGET (item), GTK_WIDGET (toolbar));
3759 priv->content = g_list_insert (priv->content, content, pos);
3761 if (!is_placeholder)
3763 toolbar->num_children++;
3765 gtk_toolbar_stop_sliding (toolbar);
3768 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
3769 priv->need_rebuild = TRUE;
3774 static ToolbarContent *
3775 toolbar_content_new_compatibility (GtkToolbar *toolbar,
3776 GtkToolbarChildType type,
3782 ToolbarContent *content;
3783 GtkToolbarChild *child;
3784 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3786 content = g_new0 (ToolbarContent, 1);
3788 child = &(content->u.compatibility.child);
3790 content->type = COMPATIBILITY;
3792 child->widget = widget;
3794 child->label = label;
3796 if (type != GTK_TOOLBAR_CHILD_SPACE)
3798 gtk_widget_set_parent (child->widget, GTK_WIDGET (toolbar));
3802 content->u.compatibility.space_visible = TRUE;
3803 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
3806 if (type == GTK_TOOLBAR_CHILD_BUTTON ||
3807 type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON ||
3808 type == GTK_TOOLBAR_CHILD_RADIOBUTTON)
3810 set_child_packing_and_visibility (toolbar, child);
3813 priv->content = g_list_insert (priv->content, content, pos);
3814 toolbar->children = g_list_insert (toolbar->children, child, pos);
3815 priv->need_rebuild = TRUE;
3817 toolbar->num_children++;
3823 toolbar_content_remove (ToolbarContent *content,
3824 GtkToolbar *toolbar)
3826 GtkToolbarChild *child;
3827 GtkToolbarPrivate *priv;
3829 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3831 switch (content->type)
3834 gtk_widget_unparent (GTK_WIDGET (content->u.tool_item.item));
3838 child = &(content->u.compatibility.child);
3840 if (child->type != GTK_TOOLBAR_CHILD_SPACE)
3842 g_object_ref (child->widget);
3843 gtk_widget_unparent (child->widget);
3844 gtk_widget_destroy (child->widget);
3845 g_object_unref (child->widget);
3848 toolbar->children = g_list_remove (toolbar->children, child);
3852 priv->content = g_list_remove (priv->content, content);
3854 if (!toolbar_content_is_placeholder (content))
3855 toolbar->num_children--;
3857 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
3858 priv->need_rebuild = TRUE;
3862 toolbar_content_free (ToolbarContent *content)
3868 calculate_max_homogeneous_pixels (GtkWidget *widget)
3870 PangoContext *context;
3871 PangoFontMetrics *metrics;
3874 context = gtk_widget_get_pango_context (widget);
3875 metrics = pango_context_get_metrics (context,
3876 widget->style->font_desc,
3877 pango_context_get_language (context));
3878 char_width = pango_font_metrics_get_approximate_char_width (metrics);
3879 pango_font_metrics_unref (metrics);
3881 return PANGO_PIXELS (MAX_HOMOGENEOUS_N_CHARS * char_width);
3885 toolbar_content_expose (ToolbarContent *content,
3886 GtkContainer *container,
3887 GdkEventExpose *expose)
3889 GtkToolbar *toolbar = GTK_TOOLBAR (container);
3890 GtkToolbarChild *child;
3891 GtkWidget *widget = NULL; /* quiet gcc */
3893 switch (content->type)
3896 if (!content->u.tool_item.is_placeholder)
3897 widget = GTK_WIDGET (content->u.tool_item.item);
3901 child = &(content->u.compatibility.child);
3903 if (child->type == GTK_TOOLBAR_CHILD_SPACE)
3905 if (get_space_style (toolbar) == GTK_TOOLBAR_SPACE_LINE &&
3906 content->u.compatibility.space_visible)
3908 _gtk_toolbar_paint_space_line (GTK_WIDGET (toolbar), toolbar,
3910 &content->u.compatibility.space_allocation);
3915 widget = child->widget;
3920 gtk_container_propagate_expose (container, widget, expose);
3924 toolbar_content_visible (ToolbarContent *content,
3925 GtkToolbar *toolbar)
3929 switch (content->type)
3932 item = content->u.tool_item.item;
3934 if (!GTK_WIDGET_VISIBLE (item))
3937 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL &&
3938 gtk_tool_item_get_visible_horizontal (item))
3943 if ((toolbar->orientation == GTK_ORIENTATION_VERTICAL &&
3944 gtk_tool_item_get_visible_vertical (item)))
3953 if (content->u.compatibility.child.type != GTK_TOOLBAR_CHILD_SPACE)
3954 return GTK_WIDGET_VISIBLE (content->u.compatibility.child.widget);
3960 g_assert_not_reached ();
3965 toolbar_content_size_request (ToolbarContent *content,
3966 GtkToolbar *toolbar,
3967 GtkRequisition *requisition)
3971 switch (content->type)
3974 gtk_widget_size_request (GTK_WIDGET (content->u.tool_item.item),
3976 if (content->u.tool_item.is_placeholder &&
3977 content->u.tool_item.disappearing)
3979 requisition->width = 0;
3980 requisition->height = 0;
3985 space_size = get_space_size (toolbar);
3987 if (content->u.compatibility.child.type != GTK_TOOLBAR_CHILD_SPACE)
3989 gtk_widget_size_request (content->u.compatibility.child.widget,
3994 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
3996 requisition->width = space_size;
3997 requisition->height = 0;
4001 requisition->height = space_size;
4002 requisition->width = 0;
4011 toolbar_content_is_homogeneous (ToolbarContent *content,
4012 GtkToolbar *toolbar)
4014 gboolean result = FALSE; /* quiet gcc */
4015 GtkRequisition requisition;
4016 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
4018 if (priv->max_homogeneous_pixels < 0)
4020 priv->max_homogeneous_pixels =
4021 calculate_max_homogeneous_pixels (GTK_WIDGET (toolbar));
4024 toolbar_content_size_request (content, toolbar, &requisition);
4026 if (requisition.width > priv->max_homogeneous_pixels)
4029 switch (content->type)
4032 result = gtk_tool_item_get_homogeneous (content->u.tool_item.item) &&
4033 !GTK_IS_SEPARATOR_TOOL_ITEM (content->u.tool_item.item);
4035 if (gtk_tool_item_get_is_important (content->u.tool_item.item) &&
4036 toolbar->style == GTK_TOOLBAR_BOTH_HORIZ &&
4037 toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
4044 if (content->u.compatibility.child.type == GTK_TOOLBAR_CHILD_BUTTON ||
4045 content->u.compatibility.child.type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
4046 content->u.compatibility.child.type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
4061 toolbar_content_is_placeholder (ToolbarContent *content)
4063 if (content->type == TOOL_ITEM && content->u.tool_item.is_placeholder)
4070 toolbar_content_disappearing (ToolbarContent *content)
4072 if (content->type == TOOL_ITEM && content->u.tool_item.disappearing)
4079 toolbar_content_get_state (ToolbarContent *content)
4081 return content->state;
4085 toolbar_content_child_visible (ToolbarContent *content)
4087 switch (content->type)
4090 return GTK_WIDGET_CHILD_VISIBLE (content->u.tool_item.item);
4094 if (content->u.compatibility.child.type != GTK_TOOLBAR_CHILD_SPACE)
4096 return GTK_WIDGET_CHILD_VISIBLE (content->u.compatibility.child.widget);
4100 return content->u.compatibility.space_visible;
4105 return FALSE; /* quiet gcc */
4109 toolbar_content_get_goal_allocation (ToolbarContent *content,
4110 GtkAllocation *allocation)
4112 switch (content->type)
4115 *allocation = content->u.tool_item.goal_allocation;
4119 /* Goal allocations are only relevant when we are
4120 * using the new API, so we should never get here
4122 g_assert_not_reached ();
4128 toolbar_content_get_allocation (ToolbarContent *content,
4129 GtkAllocation *allocation)
4131 GtkToolbarChild *child;
4133 switch (content->type)
4136 *allocation = GTK_WIDGET (content->u.tool_item.item)->allocation;
4140 child = &(content->u.compatibility.child);
4142 if (child->type == GTK_TOOLBAR_CHILD_SPACE)
4143 *allocation = content->u.compatibility.space_allocation;
4145 *allocation = child->widget->allocation;
4151 toolbar_content_set_start_allocation (ToolbarContent *content,
4152 GtkAllocation *allocation)
4154 switch (content->type)
4157 content->u.tool_item.start_allocation = *allocation;
4161 /* start_allocation is only relevant when using the new API */
4162 g_assert_not_reached ();
4168 toolbar_content_get_expand (ToolbarContent *content)
4170 if (content->type == TOOL_ITEM &&
4171 gtk_tool_item_get_expand (content->u.tool_item.item))
4180 toolbar_content_set_goal_allocation (ToolbarContent *content,
4181 GtkAllocation *allocation)
4183 switch (content->type)
4186 content->u.tool_item.goal_allocation = *allocation;
4190 /* Only relevant when using new API */
4191 g_assert_not_reached ();
4197 toolbar_content_set_child_visible (ToolbarContent *content,
4198 GtkToolbar *toolbar,
4201 GtkToolbarChild *child;
4203 switch (content->type)
4206 gtk_widget_set_child_visible (GTK_WIDGET (content->u.tool_item.item),
4211 child = &(content->u.compatibility.child);
4213 if (child->type != GTK_TOOLBAR_CHILD_SPACE)
4215 gtk_widget_set_child_visible (child->widget, visible);
4219 content->u.compatibility.space_visible = visible;
4220 gtk_widget_queue_draw (GTK_WIDGET (toolbar));
4227 toolbar_content_get_start_allocation (ToolbarContent *content,
4228 GtkAllocation *start_allocation)
4230 switch (content->type)
4233 *start_allocation = content->u.tool_item.start_allocation;
4237 /* Only relevant for new API */
4238 g_assert_not_reached ();
4244 toolbar_content_size_allocate (ToolbarContent *content,
4245 GtkAllocation *allocation)
4247 switch (content->type)
4250 gtk_widget_size_allocate (GTK_WIDGET (content->u.tool_item.item),
4255 if (content->u.compatibility.child.type != GTK_TOOLBAR_CHILD_SPACE)
4257 gtk_widget_size_allocate (content->u.compatibility.child.widget,
4262 content->u.compatibility.space_allocation = *allocation;
4269 toolbar_content_set_state (ToolbarContent *content,
4272 content->state = state;
4276 toolbar_content_get_widget (ToolbarContent *content)
4278 GtkToolbarChild *child;
4280 switch (content->type)
4283 return GTK_WIDGET (content->u.tool_item.item);
4287 child = &(content->u.compatibility.child);
4288 if (child->type != GTK_TOOLBAR_CHILD_SPACE)
4289 return child->widget;
4299 toolbar_content_set_disappearing (ToolbarContent *content,
4300 gboolean disappearing)
4302 switch (content->type)
4305 content->u.tool_item.disappearing = disappearing;
4309 /* Only relevant for new API */
4310 g_assert_not_reached ();
4316 toolbar_content_set_size_request (ToolbarContent *content,
4320 switch (content->type)
4323 gtk_widget_set_size_request (GTK_WIDGET (content->u.tool_item.item),
4328 /* Setting size requests only happens with sliding,
4329 * so not relevant here
4331 g_assert_not_reached ();
4337 toolbar_child_reconfigure (GtkToolbar *toolbar,
4338 GtkToolbarChild *child)
4342 GtkToolbarStyle style;
4343 GtkIconSize icon_size;
4344 GtkReliefStyle relief;
4347 style = gtk_toolbar_get_style (toolbar);
4348 icon_size = gtk_toolbar_get_icon_size (toolbar);
4349 relief = gtk_toolbar_get_relief_style (toolbar);
4352 if (child->type == GTK_TOOLBAR_CHILD_BUTTON ||
4353 child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
4354 child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
4356 box = gtk_bin_get_child (GTK_BIN (child->widget));
4358 if (style == GTK_TOOLBAR_BOTH && GTK_IS_HBOX (box))
4362 vbox = gtk_vbox_new (FALSE, 0);
4365 gtk_widget_reparent (child->label, vbox);
4367 gtk_widget_reparent (child->icon, vbox);
4369 gtk_widget_destroy (box);
4370 gtk_container_add (GTK_CONTAINER (child->widget), vbox);
4372 gtk_widget_show (vbox);
4374 else if (style == GTK_TOOLBAR_BOTH_HORIZ && GTK_IS_VBOX (box))
4378 hbox = gtk_hbox_new (FALSE, 0);
4381 gtk_widget_reparent (child->label, hbox);
4383 gtk_widget_reparent (child->icon, hbox);
4385 gtk_widget_destroy (box);
4386 gtk_container_add (GTK_CONTAINER (child->widget), hbox);
4388 gtk_widget_show (hbox);
4391 set_child_packing_and_visibility (toolbar, child);
4396 if ((child->type == GTK_TOOLBAR_CHILD_BUTTON ||
4397 child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON ||
4398 child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON) &&
4399 GTK_IS_IMAGE (child->icon))
4401 image = GTK_IMAGE (child->icon);
4402 if (gtk_image_get_storage_type (image) == GTK_IMAGE_STOCK)
4404 gtk_image_get_stock (image, &stock_id, NULL);
4405 stock_id = g_strdup (stock_id);
4406 gtk_image_set_from_stock (image,
4414 if (child->type == GTK_TOOLBAR_CHILD_BUTTON ||
4415 child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
4416 child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
4418 gtk_button_set_relief (GTK_BUTTON (child->widget), relief);
4423 toolbar_content_toolbar_reconfigured (ToolbarContent *content,
4424 GtkToolbar *toolbar)
4426 switch (content->type)
4429 _gtk_tool_item_toolbar_reconfigured (content->u.tool_item.item);
4433 toolbar_child_reconfigure (toolbar, &(content->u.compatibility.child));
4439 toolbar_content_retrieve_menu_item (ToolbarContent *content)
4441 if (content->type == TOOL_ITEM)
4442 return gtk_tool_item_retrieve_proxy_menu_item (content->u.tool_item.item);
4444 /* FIXME - we might actually be able to do something meaningful here */
4449 toolbar_content_has_proxy_menu_item (ToolbarContent *content)
4451 GtkWidget *menu_item;
4453 menu_item = toolbar_content_retrieve_menu_item (content);
4455 return menu_item != NULL;
4459 toolbar_content_is_separator (ToolbarContent *content)
4461 GtkToolbarChild *child;
4463 switch (content->type)
4466 return GTK_IS_SEPARATOR_TOOL_ITEM (content->u.tool_item.item);
4470 child = &(content->u.compatibility.child);
4471 return (child->type == GTK_TOOLBAR_CHILD_SPACE);
4479 ignore_show_and_hide_all (ToolbarContent *content)
4481 if (content->type == COMPATIBILITY)
4483 GtkToolbarChildType type = content->u.compatibility.child.type;
4485 if (type == GTK_TOOLBAR_CHILD_BUTTON ||
4486 type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON ||
4487 type == GTK_TOOLBAR_CHILD_RADIOBUTTON)
4497 toolbar_content_show_all (ToolbarContent *content)
4501 if (ignore_show_and_hide_all (content))
4504 widget = toolbar_content_get_widget (content);
4506 gtk_widget_show_all (widget);
4510 toolbar_content_hide_all (ToolbarContent *content)
4514 if (ignore_show_and_hide_all (content))
4517 widget = toolbar_content_get_widget (content);
4519 gtk_widget_hide_all (widget);
4526 get_space_size (GtkToolbar *toolbar)
4528 gint space_size = DEFAULT_SPACE_SIZE;
4532 gtk_widget_style_get (GTK_WIDGET (toolbar),
4533 "space_size", &space_size,
4540 static GtkToolbarSpaceStyle
4541 get_space_style (GtkToolbar *toolbar)
4543 GtkToolbarSpaceStyle space_style = DEFAULT_SPACE_STYLE;
4547 gtk_widget_style_get (GTK_WIDGET (toolbar),
4548 "space_style", &space_style,
4555 static GtkReliefStyle
4556 get_button_relief (GtkToolbar *toolbar)
4558 GtkReliefStyle button_relief = GTK_RELIEF_NORMAL;
4560 gtk_widget_ensure_style (GTK_WIDGET (toolbar));
4562 gtk_widget_style_get (GTK_WIDGET (toolbar),
4563 "button_relief", &button_relief,
4566 return button_relief;
4570 get_internal_padding (GtkToolbar *toolbar)
4574 gtk_widget_style_get (GTK_WIDGET (toolbar),
4575 "internal_padding", &ipadding,
4581 static GtkShadowType
4582 get_shadow_type (GtkToolbar *toolbar)
4584 GtkShadowType shadow_type;
4586 gtk_widget_style_get (GTK_WIDGET (toolbar),
4587 "shadow_type", &shadow_type,
4597 gtk_toolbar_check_old_api (GtkToolbar *toolbar)
4599 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
4601 if (priv->api_mode == NEW_API)
4603 g_warning (MIXED_API_WARNING);
4607 priv->api_mode = OLD_API;
4612 gtk_toolbar_check_new_api (GtkToolbar *toolbar)
4614 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
4616 if (priv->api_mode == OLD_API)
4618 g_warning (MIXED_API_WARNING);
4622 priv->api_mode = NEW_API;
4626 /* GTK+ internal methods */
4629 _gtk_toolbar_get_default_space_size (void)
4631 return DEFAULT_SPACE_SIZE;
4635 _gtk_toolbar_paint_space_line (GtkWidget *widget,
4636 GtkToolbar *toolbar,
4638 GtkAllocation *allocation)
4640 const double start_fraction = (SPACE_LINE_START / SPACE_LINE_DIVISION);
4641 const double end_fraction = (SPACE_LINE_END / SPACE_LINE_DIVISION);
4643 GtkToolbarSpaceStyle space_style;
4644 GtkOrientation orientation;
4646 g_return_if_fail (GTK_IS_WIDGET (widget));
4648 space_style = toolbar? get_space_style (toolbar) : DEFAULT_SPACE_STYLE;
4649 orientation = toolbar? toolbar->orientation : GTK_ORIENTATION_HORIZONTAL;
4651 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4653 gtk_paint_vline (widget->style, widget->window,
4654 GTK_WIDGET_STATE (widget), area, widget,
4656 allocation->y + allocation->height * start_fraction,
4657 allocation->y + allocation->height * end_fraction,
4658 allocation->x + (allocation->width - widget->style->xthickness) / 2);
4662 gtk_paint_hline (widget->style, widget->window,
4663 GTK_WIDGET_STATE (widget), area, widget,
4665 allocation->x + allocation->width * start_fraction,
4666 allocation->x + allocation->width * end_fraction,
4667 allocation->y + (allocation->height - widget->style->ythickness) / 2);
4672 _gtk_toolbar_elide_underscores (const gchar *original)
4676 gboolean last_underscore;
4678 q = result = g_malloc (strlen (original) + 1);
4679 last_underscore = FALSE;
4681 for (p = original; *p; p++)
4683 if (!last_underscore && *p == '_')
4684 last_underscore = TRUE;
4687 last_underscore = FALSE;