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
36 #include "gtktoolbar.h"
37 #include "gtkradiotoolbutton.h"
38 #include "gtkseparatortoolitem.h"
40 #include "gtkradiobutton.h"
41 #include "gtktoolbar.h"
42 #include "gtkbindings.h"
43 #include <gdk/gdkkeysyms.h>
44 #include "gtkmarshalers.h"
48 #include "gtkprivate.h"
55 typedef struct _ToolbarContent ToolbarContent;
57 #define DEFAULT_IPADDING 0
59 #define DEFAULT_SPACE_SIZE 12
60 #define DEFAULT_SPACE_STYLE GTK_TOOLBAR_SPACE_LINE
61 #define SPACE_LINE_DIVISION 10.0
62 #define SPACE_LINE_START 2.0
63 #define SPACE_LINE_END 8.0
65 #define DEFAULT_ICON_SIZE GTK_ICON_SIZE_LARGE_TOOLBAR
66 #define DEFAULT_TOOLBAR_STYLE GTK_TOOLBAR_BOTH
68 #define MAX_HOMOGENEOUS_N_CHARS 13 /* Items that are wider than this do not participate
69 * in the homogeneous game. In units of
70 * pango_font_get_estimated_char_width().
72 #define SLIDE_SPEED 600 /* How fast the items slide, in pixels per second */
82 /* Child properties */
86 CHILD_PROP_HOMOGENEOUS
118 struct _GtkToolbarPrivate
123 GtkWidget * arrow_button;
127 GdkWindow * event_window;
129 GtkSettings * settings;
131 GtkToolItem * highlight_tool_item;
132 gint max_homogeneous_pixels;
136 guint show_arrow : 1;
138 guint is_sliding : 1;
141 static void gtk_toolbar_init (GtkToolbar *toolbar);
142 static void gtk_toolbar_class_init (GtkToolbarClass *klass);
143 static void gtk_toolbar_set_property (GObject *object,
147 static void gtk_toolbar_get_property (GObject *object,
151 static gint gtk_toolbar_expose (GtkWidget *widget,
152 GdkEventExpose *event);
153 static void gtk_toolbar_realize (GtkWidget *widget);
154 static void gtk_toolbar_unrealize (GtkWidget *widget);
155 static void gtk_toolbar_size_request (GtkWidget *widget,
156 GtkRequisition *requisition);
157 static void gtk_toolbar_size_allocate (GtkWidget *widget,
158 GtkAllocation *allocation);
159 static void gtk_toolbar_style_set (GtkWidget *widget,
160 GtkStyle *prev_style);
161 static void gtk_toolbar_direction_changed (GtkWidget *widget,
162 GtkTextDirection previous_direction);
163 static gboolean gtk_toolbar_focus (GtkWidget *widget,
164 GtkDirectionType dir);
165 static void gtk_toolbar_screen_changed (GtkWidget *widget,
166 GdkScreen *previous_screen);
167 static void gtk_toolbar_map (GtkWidget *widget);
168 static void gtk_toolbar_unmap (GtkWidget *widget);
169 static void gtk_toolbar_set_child_property (GtkContainer *container,
174 static void gtk_toolbar_get_child_property (GtkContainer *container,
179 static void gtk_toolbar_finalize (GObject *object);
180 static void gtk_toolbar_show_all (GtkWidget *widget);
181 static void gtk_toolbar_hide_all (GtkWidget *widget);
182 static void gtk_toolbar_add (GtkContainer *container,
184 static void gtk_toolbar_remove (GtkContainer *container,
186 static void gtk_toolbar_forall (GtkContainer *container,
187 gboolean include_internals,
188 GtkCallback callback,
189 gpointer callback_data);
190 static GType gtk_toolbar_child_type (GtkContainer *container);
191 static void gtk_toolbar_orientation_changed (GtkToolbar *toolbar,
192 GtkOrientation orientation);
193 static void gtk_toolbar_real_style_changed (GtkToolbar *toolbar,
194 GtkToolbarStyle style);
195 static gboolean gtk_toolbar_move_focus (GtkToolbar *toolbar,
196 GtkDirectionType dir);
197 static gboolean gtk_toolbar_focus_home_or_end (GtkToolbar *toolbar,
198 gboolean focus_home);
199 static gboolean gtk_toolbar_button_press (GtkWidget *toolbar,
200 GdkEventButton *event);
201 static gboolean gtk_toolbar_arrow_button_press (GtkWidget *button,
202 GdkEventButton *event,
203 GtkToolbar *toolbar);
204 static void gtk_toolbar_arrow_button_clicked (GtkWidget *button,
205 GtkToolbar *toolbar);
206 static void gtk_toolbar_update_button_relief (GtkToolbar *toolbar);
207 static gboolean gtk_toolbar_popup_menu (GtkWidget *toolbar);
208 static GtkWidget * internal_insert_element (GtkToolbar *toolbar,
209 GtkToolbarChildType type,
212 const char *tooltip_text,
213 const char *tooltip_private_text,
215 GtkSignalFunc callback,
219 static void gtk_toolbar_reconfigured (GtkToolbar *toolbar);
220 static gboolean gtk_toolbar_check_new_api (GtkToolbar *toolbar);
221 static gboolean gtk_toolbar_check_old_api (GtkToolbar *toolbar);
223 static GtkReliefStyle get_button_relief (GtkToolbar *toolbar);
224 static gint get_internal_padding (GtkToolbar *toolbar);
225 static GtkShadowType get_shadow_type (GtkToolbar *toolbar);
226 static gint get_space_size (GtkToolbar *toolbar);
227 static GtkToolbarSpaceStyle get_space_style (GtkToolbar *toolbar);
229 /* methods on ToolbarContent 'class' */
230 static ToolbarContent *toolbar_content_new_tool_item (GtkToolbar *toolbar,
232 gboolean is_placeholder,
234 static ToolbarContent *toolbar_content_new_compatibility (GtkToolbar *toolbar,
235 GtkToolbarChildType type,
240 static void toolbar_content_remove (ToolbarContent *content,
241 GtkToolbar *toolbar);
242 static void toolbar_content_free (ToolbarContent *content);
243 static void toolbar_content_expose (ToolbarContent *content,
244 GtkContainer *container,
245 GdkEventExpose *expose);
246 static gboolean toolbar_content_visible (ToolbarContent *content,
247 GtkToolbar *toolbar);
248 static void toolbar_content_size_request (ToolbarContent *content,
250 GtkRequisition *requisition);
251 static gboolean toolbar_content_is_homogeneous (ToolbarContent *content,
252 GtkToolbar *toolbar);
253 static gboolean toolbar_content_is_placeholder (ToolbarContent *content);
254 static gboolean toolbar_content_disappearing (ToolbarContent *content);
255 static ItemState toolbar_content_get_state (ToolbarContent *content);
256 static gboolean toolbar_content_child_visible (ToolbarContent *content);
257 static void toolbar_content_get_goal_allocation (ToolbarContent *content,
258 GtkAllocation *allocation);
259 static void toolbar_content_get_allocation (ToolbarContent *content,
260 GtkAllocation *allocation);
261 static void toolbar_content_set_start_allocation (ToolbarContent *content,
262 GtkAllocation *new_start_allocation);
263 static void toolbar_content_get_start_allocation (ToolbarContent *content,
264 GtkAllocation *start_allocation);
265 static gboolean toolbar_content_get_expand (ToolbarContent *content);
266 static void toolbar_content_set_goal_allocation (ToolbarContent *content,
267 GtkAllocation *allocation);
268 static void toolbar_content_set_child_visible (ToolbarContent *content,
271 static void toolbar_content_size_allocate (ToolbarContent *content,
272 GtkAllocation *allocation);
273 static void toolbar_content_set_state (ToolbarContent *content,
274 ItemState new_state);
275 static GtkWidget * toolbar_content_get_widget (ToolbarContent *content);
276 static void toolbar_content_set_disappearing (ToolbarContent *content,
277 gboolean disappearing);
278 static void toolbar_content_set_size_request (ToolbarContent *content,
281 static void toolbar_content_toolbar_reconfigured (ToolbarContent *content,
282 GtkToolbar *toolbar);
283 static GtkWidget * toolbar_content_retrieve_menu_item (ToolbarContent *content);
284 static gboolean toolbar_content_is_separator (ToolbarContent *content);
285 static void toolbar_content_show_all (ToolbarContent *content);
286 static void toolbar_content_hide_all (ToolbarContent *content);
289 #define GTK_TOOLBAR_GET_PRIVATE(o) \
290 (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_TOOLBAR, GtkToolbarPrivate))
292 static GtkContainerClass * parent_class = NULL;
293 static guint toolbar_signals [LAST_SIGNAL] = { 0 };
296 gtk_toolbar_get_type (void)
298 static GtkType type = 0;
302 static const GTypeInfo type_info =
304 sizeof (GtkToolbarClass),
305 (GBaseInitFunc) NULL,
306 (GBaseFinalizeFunc) NULL,
307 (GClassInitFunc) gtk_toolbar_class_init,
308 (GClassFinalizeFunc) NULL,
312 (GInstanceInitFunc) gtk_toolbar_init,
315 type = g_type_register_static (GTK_TYPE_CONTAINER,
324 add_arrow_bindings (GtkBindingSet *binding_set,
326 GtkDirectionType dir)
328 guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
330 gtk_binding_entry_add_signal (binding_set, keysym, 0,
332 GTK_TYPE_DIRECTION_TYPE, dir);
333 gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
335 GTK_TYPE_DIRECTION_TYPE, dir);
339 add_ctrl_tab_bindings (GtkBindingSet *binding_set,
340 GdkModifierType modifiers,
341 GtkDirectionType direction)
343 gtk_binding_entry_add_signal (binding_set,
344 GDK_Tab, GDK_CONTROL_MASK | modifiers,
346 GTK_TYPE_DIRECTION_TYPE, direction);
347 gtk_binding_entry_add_signal (binding_set,
348 GDK_KP_Tab, GDK_CONTROL_MASK | modifiers,
350 GTK_TYPE_DIRECTION_TYPE, direction);
354 gtk_toolbar_class_init (GtkToolbarClass *klass)
356 GObjectClass *gobject_class;
357 GtkWidgetClass *widget_class;
358 GtkContainerClass *container_class;
359 GtkBindingSet *binding_set;
361 parent_class = g_type_class_peek_parent (klass);
363 gobject_class = (GObjectClass *)klass;
364 widget_class = (GtkWidgetClass *)klass;
365 container_class = (GtkContainerClass *)klass;
367 gobject_class->set_property = gtk_toolbar_set_property;
368 gobject_class->get_property = gtk_toolbar_get_property;
369 gobject_class->finalize = gtk_toolbar_finalize;
371 widget_class->button_press_event = gtk_toolbar_button_press;
372 widget_class->expose_event = gtk_toolbar_expose;
373 widget_class->size_request = gtk_toolbar_size_request;
374 widget_class->size_allocate = gtk_toolbar_size_allocate;
375 widget_class->style_set = gtk_toolbar_style_set;
376 widget_class->direction_changed = gtk_toolbar_direction_changed;
377 widget_class->focus = gtk_toolbar_focus;
378 widget_class->screen_changed = gtk_toolbar_screen_changed;
379 widget_class->realize = gtk_toolbar_realize;
380 widget_class->unrealize = gtk_toolbar_unrealize;
381 widget_class->map = gtk_toolbar_map;
382 widget_class->unmap = gtk_toolbar_unmap;
383 widget_class->popup_menu = gtk_toolbar_popup_menu;
384 widget_class->show_all = gtk_toolbar_show_all;
385 widget_class->hide_all = gtk_toolbar_hide_all;
387 container_class->add = gtk_toolbar_add;
388 container_class->remove = gtk_toolbar_remove;
389 container_class->forall = gtk_toolbar_forall;
390 container_class->child_type = gtk_toolbar_child_type;
391 container_class->get_child_property = gtk_toolbar_get_child_property;
392 container_class->set_child_property = gtk_toolbar_set_child_property;
394 klass->orientation_changed = gtk_toolbar_orientation_changed;
395 klass->style_changed = gtk_toolbar_real_style_changed;
398 * GtkToolbar::orientation-changed:
399 * @toolbar: the object which emitted the signal
400 * @orientation: the new #GtkOrientation of the toolbar
402 * Emitted when the orientation of the toolbar changes.
404 toolbar_signals[ORIENTATION_CHANGED] =
405 g_signal_new ("orientation-changed",
406 G_OBJECT_CLASS_TYPE (klass),
408 G_STRUCT_OFFSET (GtkToolbarClass, orientation_changed),
410 g_cclosure_marshal_VOID__ENUM,
412 GTK_TYPE_ORIENTATION);
414 * GtkToolbar::style-changed:
415 * @toolbar: The #GtkToolbar which emitted the signal
416 * @style: the new #GtkToolbarStyle of the toolbar
418 * Emitted when the style of the toolbar changes.
420 toolbar_signals[STYLE_CHANGED] =
421 g_signal_new ("style-changed",
422 G_OBJECT_CLASS_TYPE (klass),
424 G_STRUCT_OFFSET (GtkToolbarClass, style_changed),
426 g_cclosure_marshal_VOID__ENUM,
428 GTK_TYPE_TOOLBAR_STYLE);
430 * GtkToolbar::popup-context-menu:
431 * @toolbar: the #GtkToolbar which emitted the signal
432 * @x: the x coordinate of the point where the menu should appear
433 * @y: the y coordinate of the point where the menu should appear
434 * @button: the mouse button the user pressed, or -1
436 * Emitted when the user right-clicks the toolbar or uses the
437 * keybinding to display a popup menu.
439 * Application developers should handle this signal if they want
440 * to display a context menu on the toolbar. The context-menu should
441 * appear at the coordinates given by @x and @y. The mouse button
442 * number is given by the @button parameter. If the menu was popped
443 * up using the keybaord, @button is -1.
445 * Return value: return %TRUE if the signal was handled, %FALSE if not
447 toolbar_signals[POPUP_CONTEXT_MENU] =
448 g_signal_new ("popup_context_menu",
449 G_OBJECT_CLASS_TYPE (klass),
451 G_STRUCT_OFFSET (GtkToolbarClass, popup_context_menu),
452 _gtk_boolean_handled_accumulator, NULL,
453 _gtk_marshal_BOOLEAN__INT_INT_INT,
455 G_TYPE_INT, G_TYPE_INT,
458 * GtkToolbar::move-focus:
459 * @toolbar: the #GtkToolbar which emitted the signal
460 * @dir: a #GtkDirection
462 * A keybinding signal used internally by GTK+. This signal can't
463 * be used in application code.
465 * Return value: %TRUE if the signal was handled, %FALSE if not
467 toolbar_signals[MOVE_FOCUS] =
468 _gtk_binding_signal_new ("move_focus",
469 G_TYPE_FROM_CLASS (klass),
470 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
471 G_CALLBACK (gtk_toolbar_move_focus),
473 _gtk_marshal_BOOLEAN__ENUM,
475 GTK_TYPE_DIRECTION_TYPE);
477 * GtkToolbar::focus-home-or-end:
478 * @toolbar: the #GtkToolbar which emitted the signal
479 * @focus_home: %TRUE if the first item should be focused
481 * A keybinding signal used internally by GTK+. This signal can't
482 * be used in application code
484 * Return value: %TRUE if the signal was handled, %FALSE if not
486 toolbar_signals[FOCUS_HOME_OR_END] =
487 _gtk_binding_signal_new ("focus_home_or_end",
488 G_OBJECT_CLASS_TYPE (klass),
489 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
490 G_CALLBACK (gtk_toolbar_focus_home_or_end),
492 _gtk_marshal_BOOLEAN__BOOLEAN,
497 g_object_class_install_property (gobject_class,
499 g_param_spec_enum ("orientation",
501 P_("The orientation of the toolbar"),
502 GTK_TYPE_ORIENTATION,
503 GTK_ORIENTATION_HORIZONTAL,
506 g_object_class_install_property (gobject_class,
508 g_param_spec_enum ("toolbar_style",
510 P_("How to draw the toolbar"),
511 GTK_TYPE_TOOLBAR_STYLE,
514 g_object_class_install_property (gobject_class,
516 g_param_spec_boolean ("show_arrow",
518 P_("If an arrow should be shown if the toolbar doesn't fit"),
522 /* child properties */
523 gtk_container_class_install_child_property (container_class,
525 g_param_spec_boolean ("expand",
527 P_("Whether the item should receive extra space when the toolbar grows"),
531 gtk_container_class_install_child_property (container_class,
532 CHILD_PROP_HOMOGENEOUS,
533 g_param_spec_boolean ("homogeneous",
535 P_("Whether the item should be the same size as other homogeneous items"),
539 /* style properties */
540 gtk_widget_class_install_style_property (widget_class,
541 g_param_spec_int ("space_size",
543 P_("Size of spacers"),
549 gtk_widget_class_install_style_property (widget_class,
550 g_param_spec_int ("internal_padding",
551 P_("Internal padding"),
552 P_("Amount of border space between the toolbar shadow and the buttons"),
558 gtk_widget_class_install_style_property (widget_class,
559 g_param_spec_enum ("space_style",
561 P_("Whether spacers are vertical lines or just blank"),
562 GTK_TYPE_TOOLBAR_SPACE_STYLE,
566 gtk_widget_class_install_style_property (widget_class,
567 g_param_spec_enum ("button_relief",
569 P_("Type of bevel around toolbar buttons"),
570 GTK_TYPE_RELIEF_STYLE,
573 gtk_widget_class_install_style_property (widget_class,
574 g_param_spec_enum ("shadow_type",
576 P_("Style of bevel around the toolbar"),
577 GTK_TYPE_SHADOW_TYPE,
581 gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-style",
583 P_("Whether default toolbars have text only, text and icons, icons only, etc."),
584 GTK_TYPE_TOOLBAR_STYLE,
585 DEFAULT_TOOLBAR_STYLE,
588 gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-icon-size",
589 P_("Toolbar icon size"),
590 P_("Size of icons in default toolbars"),
595 binding_set = gtk_binding_set_by_class (klass);
597 add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
598 add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
599 add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
600 add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
602 gtk_binding_entry_add_signal (binding_set, GDK_KP_Home, 0,
603 "focus_home_or_end", 1,
604 G_TYPE_BOOLEAN, TRUE);
605 gtk_binding_entry_add_signal (binding_set, GDK_Home, 0,
606 "focus_home_or_end", 1,
607 G_TYPE_BOOLEAN, TRUE);
608 gtk_binding_entry_add_signal (binding_set, GDK_KP_End, 0,
609 "focus_home_or_end", 1,
610 G_TYPE_BOOLEAN, FALSE);
611 gtk_binding_entry_add_signal (binding_set, GDK_End, 0,
612 "focus_home_or_end", 1,
613 G_TYPE_BOOLEAN, FALSE);
615 add_ctrl_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
616 add_ctrl_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
618 g_type_class_add_private (gobject_class, sizeof (GtkToolbarPrivate));
622 gtk_toolbar_init (GtkToolbar *toolbar)
624 GtkToolbarPrivate *priv;
626 GTK_WIDGET_UNSET_FLAGS (toolbar, GTK_CAN_FOCUS);
627 GTK_WIDGET_SET_FLAGS (toolbar, GTK_NO_WINDOW);
629 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
631 toolbar->orientation = GTK_ORIENTATION_HORIZONTAL;
632 toolbar->style = DEFAULT_TOOLBAR_STYLE;
633 toolbar->icon_size = DEFAULT_ICON_SIZE;
634 toolbar->tooltips = gtk_tooltips_new ();
635 g_object_ref (toolbar->tooltips);
636 gtk_object_sink (GTK_OBJECT (toolbar->tooltips));
638 priv->arrow_button = gtk_toggle_button_new ();
639 g_signal_connect (priv->arrow_button, "button_press_event",
640 G_CALLBACK (gtk_toolbar_arrow_button_press), toolbar);
641 g_signal_connect (priv->arrow_button, "clicked",
642 G_CALLBACK (gtk_toolbar_arrow_button_clicked), toolbar);
643 gtk_button_set_relief (GTK_BUTTON (priv->arrow_button),
644 get_button_relief (toolbar));
646 priv->api_mode = DONT_KNOW;
648 gtk_button_set_focus_on_click (GTK_BUTTON (priv->arrow_button), FALSE);
650 priv->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
651 gtk_widget_set_name (priv->arrow, "gtk-toolbar-arrow");
652 gtk_widget_show (priv->arrow);
653 gtk_container_add (GTK_CONTAINER (priv->arrow_button), priv->arrow);
655 gtk_widget_set_parent (priv->arrow_button, GTK_WIDGET (toolbar));
657 /* which child position a drop will occur at */
659 priv->show_arrow = TRUE;
660 priv->settings = NULL;
662 priv->max_homogeneous_pixels = -1;
664 priv->timer = g_timer_new ();
668 gtk_toolbar_set_property (GObject *object,
673 GtkToolbar *toolbar = GTK_TOOLBAR (object);
677 case PROP_ORIENTATION:
678 gtk_toolbar_set_orientation (toolbar, g_value_get_enum (value));
680 case PROP_TOOLBAR_STYLE:
681 gtk_toolbar_set_style (toolbar, g_value_get_enum (value));
683 case PROP_SHOW_ARROW:
684 gtk_toolbar_set_show_arrow (toolbar, g_value_get_boolean (value));
687 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
693 gtk_toolbar_get_property (GObject *object,
698 GtkToolbar *toolbar = GTK_TOOLBAR (object);
699 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
703 case PROP_ORIENTATION:
704 g_value_set_enum (value, toolbar->orientation);
706 case PROP_TOOLBAR_STYLE:
707 g_value_set_enum (value, toolbar->style);
709 case PROP_SHOW_ARROW:
710 g_value_set_boolean (value, priv->show_arrow);
713 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
719 gtk_toolbar_map (GtkWidget *widget)
721 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
723 GTK_WIDGET_CLASS (parent_class)->map (widget);
725 if (priv->event_window)
726 gdk_window_show_unraised (priv->event_window);
730 gtk_toolbar_unmap (GtkWidget *widget)
732 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
734 if (priv->event_window)
735 gdk_window_hide (priv->event_window);
737 GTK_WIDGET_CLASS (parent_class)->unmap (widget);
741 gtk_toolbar_realize (GtkWidget *widget)
743 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
744 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
746 GdkWindowAttr attributes;
747 gint attributes_mask;
750 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
752 border_width = GTK_CONTAINER (widget)->border_width;
754 attributes.wclass = GDK_INPUT_ONLY;
755 attributes.window_type = GDK_WINDOW_CHILD;
756 attributes.x = widget->allocation.x + border_width;
757 attributes.y = widget->allocation.y + border_width;
758 attributes.width = widget->allocation.width - border_width * 2;
759 attributes.height = widget->allocation.height - border_width * 2;
760 attributes.event_mask = gtk_widget_get_events (widget);
761 attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
762 GDK_BUTTON_RELEASE_MASK |
763 GDK_ENTER_NOTIFY_MASK |
764 GDK_LEAVE_NOTIFY_MASK);
766 attributes_mask = GDK_WA_X | GDK_WA_Y;
768 widget->window = gtk_widget_get_parent_window (widget);
769 g_object_ref (widget->window);
770 widget->style = gtk_style_attach (widget->style, widget->window);
772 priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget),
773 &attributes, attributes_mask);
774 gdk_window_set_user_data (priv->event_window, toolbar);
778 gtk_toolbar_unrealize (GtkWidget *widget)
780 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
782 if (priv->event_window)
784 gdk_window_set_user_data (priv->event_window, NULL);
785 gdk_window_destroy (priv->event_window);
786 priv->event_window = NULL;
789 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
790 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
794 gtk_toolbar_expose (GtkWidget *widget,
795 GdkEventExpose *event)
797 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
798 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
803 border_width = GTK_CONTAINER (widget)->border_width;
805 if (GTK_WIDGET_DRAWABLE (widget))
807 gtk_paint_box (widget->style,
809 GTK_WIDGET_STATE (widget),
810 get_shadow_type (toolbar),
811 &event->area, widget, "toolbar",
812 border_width + widget->allocation.x,
813 border_width + widget->allocation.y,
814 widget->allocation.width - 2 * border_width,
815 widget->allocation.height - 2 * border_width);
818 for (list = priv->content; list != NULL; list = list->next)
820 ToolbarContent *content = list->data;
822 toolbar_content_expose (content, GTK_CONTAINER (widget), event);
825 gtk_container_propagate_expose (GTK_CONTAINER (widget),
833 gtk_toolbar_size_request (GtkWidget *widget,
834 GtkRequisition *requisition)
836 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
837 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
839 gint max_child_height;
840 gint max_child_width;
841 gint max_homogeneous_child_width;
842 gint max_homogeneous_child_height;
843 gint homogeneous_size;
845 gint pack_front_size;
847 GtkRequisition arrow_requisition;
849 max_homogeneous_child_width = 0;
850 max_homogeneous_child_height = 0;
852 max_child_height = 0;
853 for (list = priv->content; list != NULL; list = list->next)
855 GtkRequisition requisition;
856 ToolbarContent *content = list->data;
858 if (!toolbar_content_visible (content, toolbar))
861 toolbar_content_size_request (content, toolbar, &requisition);
863 max_child_width = MAX (max_child_width, requisition.width);
864 max_child_height = MAX (max_child_height, requisition.height);
866 if (toolbar_content_is_homogeneous (content, toolbar))
868 max_homogeneous_child_width = MAX (max_homogeneous_child_width, requisition.width);
869 max_homogeneous_child_height = MAX (max_homogeneous_child_height, requisition.height);
873 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
874 homogeneous_size = max_homogeneous_child_width;
876 homogeneous_size = max_homogeneous_child_height;
879 for (list = priv->content; list != NULL; list = list->next)
881 ToolbarContent *content = list->data;
884 if (!toolbar_content_visible (content, toolbar))
887 if (toolbar_content_is_homogeneous (content, toolbar))
889 size = homogeneous_size;
893 GtkRequisition requisition;
895 toolbar_content_size_request (content, toolbar, &requisition);
897 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
898 size = requisition.width;
900 size = requisition.height;
903 pack_front_size += size;
906 if (priv->show_arrow && priv->api_mode == NEW_API)
908 gtk_widget_size_request (priv->arrow_button, &arrow_requisition);
910 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
911 long_req = arrow_requisition.width;
913 long_req = arrow_requisition.height;
915 /* There is no point requesting space for the arrow if that would take
916 * up more space than all the items combined
918 long_req = MIN (long_req, pack_front_size);
922 arrow_requisition.height = 0;
923 arrow_requisition.width = 0;
925 long_req = pack_front_size;
928 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
930 requisition->width = long_req;
931 requisition->height = MAX (max_child_height, arrow_requisition.height);
935 requisition->height = long_req;
936 requisition->width = MAX (max_child_width, arrow_requisition.width);
940 ipadding = get_internal_padding (toolbar);
942 requisition->width += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width);
943 requisition->height += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width);
945 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
947 requisition->width += 2 * widget->style->xthickness;
948 requisition->height += 2 * widget->style->ythickness;
951 toolbar->button_maxw = max_homogeneous_child_width;
952 toolbar->button_maxh = max_homogeneous_child_height;
956 position (gint from, gint to, gdouble elapsed)
959 return MIN (from + SLIDE_SPEED * elapsed, to);
961 return MAX (from - SLIDE_SPEED * elapsed, to);
965 compute_intermediate_allocation (GtkToolbar *toolbar,
966 const GtkAllocation *start,
967 const GtkAllocation *goal,
968 GtkAllocation *intermediate)
970 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
971 gdouble elapsed = g_timer_elapsed (priv->timer, NULL);
973 intermediate->x = position (start->x, goal->x, elapsed);
974 intermediate->y = position (start->y, goal->y, elapsed);
975 intermediate->width =
976 position (start->x + start->width, goal->x + goal->width, elapsed) - intermediate->x;
977 intermediate->height =
978 position (start->y + start->height, goal->y + goal->height, elapsed) - intermediate->y;
982 fixup_allocation_for_rtl (gint total_size,
983 GtkAllocation *allocation)
985 allocation->x += (total_size - (2 * allocation->x + allocation->width));
989 fixup_allocation_for_vertical (GtkAllocation *allocation)
994 allocation->x = allocation->y;
997 tmp = allocation->width;
998 allocation->width = allocation->height;
999 allocation->height = tmp;
1003 get_item_size (GtkToolbar *toolbar,
1004 ToolbarContent *content)
1006 GtkRequisition requisition;
1008 toolbar_content_size_request (content, toolbar, &requisition);
1010 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1012 if (toolbar_content_is_homogeneous (content, toolbar))
1013 return toolbar->button_maxw;
1015 return requisition.width;
1019 if (toolbar_content_is_homogeneous (content, toolbar))
1020 return toolbar->button_maxh;
1022 return requisition.height;
1027 slide_idle_handler (gpointer data)
1029 GtkToolbar *toolbar = data;
1030 GtkToolbarPrivate *priv;
1033 GDK_THREADS_ENTER ();
1035 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1037 if (priv->need_sync)
1040 priv->need_sync = FALSE;
1043 for (list = priv->content; list != NULL; list = list->next)
1045 ToolbarContent *content = list->data;
1047 GtkAllocation goal_allocation;
1048 GtkAllocation allocation;
1051 state = toolbar_content_get_state (content);
1052 toolbar_content_get_goal_allocation (content, &goal_allocation);
1053 toolbar_content_get_allocation (content, &allocation);
1057 if (state == NOT_ALLOCATED)
1059 /* an unallocated item means that size allocate has to
1060 * called at least once more
1065 /* An invisible item with a goal allocation of
1066 * 0 is already at its goal.
1068 if ((state == NORMAL || state == OVERFLOWN) &&
1069 ((goal_allocation.width != 0 &&
1070 goal_allocation.height != 0) ||
1071 toolbar_content_child_visible (content)))
1073 if ((goal_allocation.x != allocation.x ||
1074 goal_allocation.y != allocation.y ||
1075 goal_allocation.width != allocation.width ||
1076 goal_allocation.height != allocation.height))
1078 /* An item is not in its right position yet. Note
1079 * that OVERFLOWN items do get an allocation in
1080 * gtk_toolbar_size_allocate(). This way you can see
1081 * them slide back in when you drag an item off the
1088 if (toolbar_content_is_placeholder (content) &&
1089 toolbar_content_disappearing (content) &&
1090 toolbar_content_child_visible (content))
1092 /* A disappearing placeholder is still visible.
1100 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (toolbar));
1102 GDK_THREADS_LEAVE ();
1107 priv->is_sliding = FALSE;
1110 GDK_THREADS_LEAVE();
1115 rect_within (GtkAllocation *a1,
1118 return (a1->x >= a2->x &&
1119 a1->x + a1->width <= a2->x + a2->width &&
1121 a1->y + a1->height <= a2->y + a2->height);
1125 gtk_toolbar_begin_sliding (GtkToolbar *toolbar)
1127 GtkWidget *widget = GTK_WIDGET (toolbar);
1128 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1136 /* Start the sliding. This function copies the allocation of every
1137 * item into content->start_allocation. For items that haven't
1138 * been allocated yet, we calculate their position and save that
1139 * in start_allocatino along with zero width and zero height.
1141 priv->is_sliding = TRUE;
1144 priv->idle_id = g_idle_add (slide_idle_handler, toolbar);
1146 rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
1147 vertical = (toolbar->orientation == GTK_ORIENTATION_VERTICAL);
1148 border_width = get_internal_padding (toolbar) + GTK_CONTAINER (toolbar)->border_width;
1152 cur_x = widget->allocation.width - border_width - widget->style->xthickness;
1153 cur_y = widget->allocation.height - border_width - widget->style->ythickness;
1157 cur_x = border_width + widget->style->xthickness;
1158 cur_y = border_width + widget->style->ythickness;
1161 cur_x += widget->allocation.x;
1162 cur_y += widget->allocation.y;
1164 for (list = priv->content; list != NULL; list = list->next)
1166 ToolbarContent *content = list->data;
1167 GtkAllocation new_start_allocation;
1168 GtkAllocation item_allocation;
1171 state = toolbar_content_get_state (content);
1172 toolbar_content_get_allocation (content, &item_allocation);
1174 if ((state == NORMAL &&
1175 rect_within (&item_allocation, &(widget->allocation))) ||
1178 new_start_allocation = item_allocation;
1182 new_start_allocation.x = cur_x;
1183 new_start_allocation.y = cur_y;
1187 new_start_allocation.width = widget->allocation.width -
1188 2 * border_width - 2 * widget->style->xthickness;
1189 new_start_allocation.height = 0;
1193 new_start_allocation.width = 0;
1194 new_start_allocation.height = widget->allocation.height -
1195 2 * border_width - 2 * widget->style->ythickness;
1200 cur_y = new_start_allocation.y + new_start_allocation.height;
1202 cur_x = new_start_allocation.x;
1204 cur_x = new_start_allocation.x + new_start_allocation.width;
1206 toolbar_content_set_start_allocation (content, &new_start_allocation);
1209 /* This resize will run before the first idle handler. This
1210 * will make sure that items get the right goal allocatiuon
1211 * so that the idle handler will not immediately return
1214 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (toolbar));
1215 g_timer_reset (priv->timer);
1219 gtk_toolbar_stop_sliding (GtkToolbar *toolbar)
1221 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1223 if (priv->is_sliding)
1227 priv->is_sliding = FALSE;
1231 g_source_remove (priv->idle_id);
1235 list = priv->content;
1238 ToolbarContent *content = list->data;
1241 if (toolbar_content_is_placeholder (content))
1243 toolbar_content_remove (content, toolbar);
1244 toolbar_content_free (content);
1248 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (toolbar));
1253 gtk_toolbar_size_allocate (GtkWidget *widget,
1254 GtkAllocation *allocation)
1256 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1257 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1258 GtkAllocation *allocations;
1259 ItemState *new_states;
1260 GtkAllocation arrow_allocation;
1262 gint size, pos, short_size;
1265 gboolean need_arrow;
1266 gint n_expand_items;
1268 gint available_size;
1271 GtkRequisition arrow_requisition;
1272 gboolean overflowing;
1273 gboolean size_changed;
1275 GtkAllocation item_area;
1277 size_changed = FALSE;
1278 if (widget->allocation.x != allocation->x ||
1279 widget->allocation.y != allocation->y ||
1280 widget->allocation.width != allocation->width ||
1281 widget->allocation.height != allocation->height)
1283 size_changed = TRUE;
1287 gtk_toolbar_stop_sliding (toolbar);
1289 widget->allocation = *allocation;
1291 border_width = GTK_CONTAINER (toolbar)->border_width;
1293 if (GTK_WIDGET_REALIZED (widget))
1295 gdk_window_move_resize (priv->event_window,
1296 allocation->x + border_width,
1297 allocation->y + border_width,
1298 allocation->width - border_width * 2,
1299 allocation->height - border_width * 2);
1302 border_width += get_internal_padding (toolbar);
1304 gtk_widget_get_child_requisition (GTK_WIDGET (priv->arrow_button),
1305 &arrow_requisition);
1307 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1309 available_size = size = allocation->width - 2 * border_width;
1310 short_size = allocation->height - 2 * border_width;
1311 arrow_size = arrow_requisition.width;
1313 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1315 available_size -= 2 * widget->style->xthickness;
1316 short_size -= 2 * widget->style->ythickness;
1321 available_size = size = allocation->height - 2 * border_width;
1322 short_size = allocation->width - 2 * border_width;
1323 arrow_size = arrow_requisition.height;
1325 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1327 available_size -= 2 * widget->style->ythickness;
1328 short_size -= 2 * widget->style->xthickness;
1332 n_items = g_list_length (priv->content);
1333 allocations = g_new0 (GtkAllocation, n_items);
1334 new_states = g_new0 (ItemState, n_items);
1337 for (list = priv->content; list != NULL; list = list->next)
1339 ToolbarContent *content = list->data;
1341 if (toolbar_content_visible (content, toolbar))
1342 needed_size += get_item_size (toolbar, content);
1345 need_arrow = (needed_size > available_size) && priv->show_arrow && priv->api_mode == NEW_API;
1348 size = available_size - arrow_size;
1350 size = available_size;
1352 /* calculate widths of items */
1353 overflowing = FALSE;
1354 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1356 ToolbarContent *content = list->data;
1359 if (!toolbar_content_visible (content, toolbar))
1361 new_states[i] = HIDDEN;
1365 item_size = get_item_size (toolbar, content);
1366 if (item_size <= size && !overflowing)
1369 allocations[i].width = item_size;
1370 new_states[i] = NORMAL;
1375 new_states[i] = OVERFLOWN;
1376 allocations[i].width = item_size;
1380 /* calculate width of arrow */
1383 arrow_allocation.width = arrow_size;
1384 arrow_allocation.height = short_size;
1387 /* expand expandable items */
1389 /* We don't expand when there is an overflow menu, because that leads to
1390 * weird jumps when items get moved to the overflow menu and the expanding
1391 * items suddenly get a lot of extra space
1396 for (i = 0, list = priv->content; list != NULL; list = list->next, ++i)
1398 ToolbarContent *content = list->data;
1400 if (toolbar_content_get_expand (content) && new_states[i] == NORMAL)
1404 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1406 ToolbarContent *content = list->data;
1408 if (toolbar_content_get_expand (content) && new_states[i] == NORMAL)
1410 gint extra = size / n_expand_items;
1411 if (size % n_expand_items != 0)
1414 allocations[i].width += extra;
1420 g_assert (n_expand_items == 0);
1423 /* position items */
1425 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1427 /* both NORMAL and OVERFLOWN items get a position. This ensures
1428 * that sliding will work for OVERFLOWN items too
1430 if (new_states[i] == NORMAL ||
1431 new_states[i] == OVERFLOWN)
1433 allocations[i].x = pos;
1434 allocations[i].y = border_width;
1435 allocations[i].height = short_size;
1437 pos += allocations[i].width;
1441 /* position arrow */
1444 arrow_allocation.x = available_size - border_width - arrow_allocation.width;
1445 arrow_allocation.y = border_width;
1448 item_area.x = border_width;
1449 item_area.y = border_width;
1450 item_area.width = available_size - (need_arrow? arrow_size : 0);
1451 item_area.height = short_size;
1453 /* fix up allocations in the vertical or RTL cases */
1454 if (toolbar->orientation == GTK_ORIENTATION_VERTICAL)
1456 for (i = 0; i < n_items; ++i)
1457 fixup_allocation_for_vertical (&(allocations[i]));
1460 fixup_allocation_for_vertical (&arrow_allocation);
1462 fixup_allocation_for_vertical (&item_area);
1464 else if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
1466 for (i = 0; i < n_items; ++i)
1467 fixup_allocation_for_rtl (available_size, &(allocations[i]));
1470 fixup_allocation_for_rtl (available_size, &arrow_allocation);
1472 fixup_allocation_for_rtl (available_size, &item_area);
1475 /* translate the items by allocation->(x,y) */
1476 for (i = 0; i < n_items; ++i)
1478 allocations[i].x += allocation->x;
1479 allocations[i].y += allocation->y;
1481 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1483 allocations[i].x += widget->style->xthickness;
1484 allocations[i].y += widget->style->ythickness;
1490 arrow_allocation.x += allocation->x;
1491 arrow_allocation.y += allocation->y;
1493 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1495 arrow_allocation.x += widget->style->xthickness;
1496 arrow_allocation.y += widget->style->ythickness;
1500 item_area.x += allocation->x;
1501 item_area.y += allocation->y;
1502 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1504 item_area.x += widget->style->xthickness;
1505 item_area.y += widget->style->ythickness;
1508 /* did anything change? */
1509 for (list = priv->content, i = 0; list != NULL; list = list->next, i++)
1511 ToolbarContent *content = list->data;
1513 if (toolbar_content_get_state (content) == NORMAL &&
1514 new_states[i] != NORMAL)
1516 /* an item disappeared, begin sliding */
1517 if (!size_changed && priv->api_mode == NEW_API)
1518 gtk_toolbar_begin_sliding (toolbar);
1522 /* finally allocate the items */
1523 if (priv->is_sliding)
1525 for (list = priv->content, i = 0; list != NULL; list = list->next, i++)
1527 ToolbarContent *content = list->data;
1529 toolbar_content_set_goal_allocation (content, &(allocations[i]));
1533 elapsed = g_timer_elapsed (priv->timer, NULL);
1534 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1536 ToolbarContent *content = list->data;
1538 if (new_states[i] == OVERFLOWN ||
1539 new_states[i] == NORMAL)
1541 GtkAllocation alloc;
1542 GtkAllocation start_allocation;
1543 GtkAllocation goal_allocation;
1545 if (priv->is_sliding)
1547 toolbar_content_get_start_allocation (content, &start_allocation);
1548 toolbar_content_get_goal_allocation (content, &goal_allocation);
1550 compute_intermediate_allocation (toolbar,
1555 priv->need_sync = TRUE;
1559 alloc = allocations[i];
1562 if (alloc.width == 0 || alloc.height == 0)
1564 toolbar_content_set_child_visible (content, toolbar, FALSE);
1568 if (!rect_within (&alloc, &item_area))
1570 toolbar_content_set_child_visible (content, toolbar, FALSE);
1571 toolbar_content_size_allocate (content, &alloc);
1575 toolbar_content_set_child_visible (content, toolbar, TRUE);
1576 toolbar_content_size_allocate (content, &alloc);
1582 toolbar_content_set_child_visible (content, toolbar, FALSE);
1585 toolbar_content_set_state (content, new_states[i]);
1590 gtk_widget_size_allocate (GTK_WIDGET (priv->arrow_button),
1592 gtk_widget_show (GTK_WIDGET (priv->arrow_button));
1596 gtk_widget_hide (GTK_WIDGET (priv->arrow_button));
1599 g_free (allocations);
1600 g_free (new_states);
1604 gtk_toolbar_update_button_relief (GtkToolbar *toolbar)
1606 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1608 gtk_toolbar_reconfigured (toolbar);
1610 gtk_button_set_relief (GTK_BUTTON (priv->arrow_button), get_button_relief (toolbar));
1614 gtk_toolbar_style_set (GtkWidget *widget,
1615 GtkStyle *prev_style)
1617 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
1619 priv->max_homogeneous_pixels = -1;
1621 if (GTK_WIDGET_REALIZED (widget))
1622 gtk_style_set_background (widget->style, widget->window, widget->state);
1625 gtk_toolbar_update_button_relief (GTK_TOOLBAR (widget));
1629 gtk_toolbar_direction_changed (GtkWidget *widget,
1630 GtkTextDirection previous_dir)
1632 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1633 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1635 if (toolbar->orientation == GTK_ORIENTATION_VERTICAL)
1637 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
1638 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
1640 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_LEFT, GTK_SHADOW_NONE);
1643 GTK_WIDGET_CLASS (parent_class)->direction_changed (widget, previous_dir);
1647 gtk_toolbar_list_children_in_focus_order (GtkToolbar *toolbar,
1648 GtkDirectionType dir)
1650 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1651 GList *result = NULL;
1655 /* generate list of children in reverse logical order */
1657 for (list = priv->content; list != NULL; list = list->next)
1659 ToolbarContent *content = list->data;
1662 widget = toolbar_content_get_widget (content);
1665 result = g_list_prepend (result, widget);
1668 result = g_list_prepend (result, priv->arrow_button);
1670 rtl = (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL);
1672 /* move in logical order when
1674 * - dir is TAB_FORWARD
1676 * - in RTL mode and moving left or up
1678 * - in LTR mode and moving right or down
1680 if (dir == GTK_DIR_TAB_FORWARD ||
1681 (rtl && (dir == GTK_DIR_UP || dir == GTK_DIR_LEFT)) ||
1682 (!rtl && (dir == GTK_DIR_DOWN || dir == GTK_DIR_RIGHT)))
1684 result = g_list_reverse (result);
1691 gtk_toolbar_focus_home_or_end (GtkToolbar *toolbar,
1692 gboolean focus_home)
1694 GList *children, *list;
1695 GtkDirectionType dir = focus_home? GTK_DIR_RIGHT : GTK_DIR_LEFT;
1697 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1699 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
1701 children = g_list_reverse (children);
1703 dir = (dir == GTK_DIR_RIGHT)? GTK_DIR_LEFT : GTK_DIR_RIGHT;
1706 for (list = children; list != NULL; list = list->next)
1708 GtkWidget *child = list->data;
1710 if (GTK_CONTAINER (toolbar)->focus_child == child)
1713 if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1717 g_list_free (children);
1722 /* Keybinding handler. This function is called when the user presses
1723 * Ctrl TAB or an arrow key.
1726 gtk_toolbar_move_focus (GtkToolbar *toolbar,
1727 GtkDirectionType dir)
1730 gboolean try_focus = FALSE;
1732 GtkContainer *container = GTK_CONTAINER (toolbar);
1734 if (container->focus_child &&
1735 gtk_widget_child_focus (container->focus_child, dir))
1740 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1742 for (list = children; list != NULL; list = list->next)
1744 GtkWidget *child = list->data;
1746 if (try_focus && GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1749 if (child == GTK_CONTAINER (toolbar)->focus_child)
1753 g_list_free (children);
1758 /* The focus handler for the toolbar. It called when the user presses
1759 * TAB or otherwise tries to focus the toolbar.
1762 gtk_toolbar_focus (GtkWidget *widget,
1763 GtkDirectionType dir)
1765 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1766 GList *children, *list;
1768 /* if focus is already somewhere inside the toolbar then return FALSE.
1769 * The only way focus can stay inside the toolbar is when the user presses
1770 * arrow keys or Ctrl TAB (both of which are handled by the
1771 * gtk_toolbar_move_focus() keybinding function.
1773 if (GTK_CONTAINER (widget)->focus_child)
1776 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1778 for (list = children; list != NULL; list = list->next)
1780 GtkWidget *child = list->data;
1782 if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1786 g_list_free (children);
1792 style_change_notify (GtkToolbar *toolbar)
1794 if (!toolbar->style_set)
1796 /* pretend it was set, then unset, thus reverting to new default */
1797 toolbar->style_set = TRUE;
1798 gtk_toolbar_unset_style (toolbar);
1803 icon_size_change_notify (GtkToolbar *toolbar)
1805 if (!toolbar->icon_size_set)
1807 /* pretend it was set, then unset, thus reverting to new default */
1808 toolbar->icon_size_set = TRUE;
1809 gtk_toolbar_unset_icon_size (toolbar);
1813 static GtkSettings *
1814 toolbar_get_settings (GtkToolbar *toolbar)
1816 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1817 return priv->settings;
1821 gtk_toolbar_screen_changed (GtkWidget *widget,
1822 GdkScreen *previous_screen)
1824 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
1825 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1826 GtkSettings *old_settings = toolbar_get_settings (toolbar);
1827 GtkSettings *settings;
1829 if (gtk_widget_has_screen (GTK_WIDGET (toolbar)))
1830 settings = gtk_widget_get_settings (GTK_WIDGET (toolbar));
1834 if (settings == old_settings)
1839 g_signal_handler_disconnect (old_settings, toolbar->style_set_connection);
1840 g_signal_handler_disconnect (old_settings, toolbar->icon_size_connection);
1842 g_object_unref (old_settings);
1847 toolbar->style_set_connection =
1848 g_signal_connect_swapped (settings,
1849 "notify::gtk-toolbar-style",
1850 G_CALLBACK (style_change_notify),
1852 toolbar->icon_size_connection =
1853 g_signal_connect_swapped (settings,
1854 "notify::gtk-toolbar-icon-size",
1855 G_CALLBACK (icon_size_change_notify),
1858 g_object_ref (settings);
1859 priv->settings = settings;
1862 priv->settings = NULL;
1864 style_change_notify (toolbar);
1865 icon_size_change_notify (toolbar);
1869 find_drop_index (GtkToolbar *toolbar,
1873 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1874 GList *interesting_content;
1876 GtkOrientation orientation;
1877 GtkTextDirection direction;
1878 gint best_distance = G_MAXINT;
1882 ToolbarContent *best_content;
1883 GtkAllocation allocation;
1885 /* list items we care about wrt. drag and drop */
1886 interesting_content = NULL;
1887 for (list = priv->content; list != NULL; list = list->next)
1889 ToolbarContent *content = list->data;
1891 if (toolbar_content_get_state (content) == NORMAL)
1892 interesting_content = g_list_prepend (interesting_content, content);
1894 interesting_content = g_list_reverse (interesting_content);
1896 if (!interesting_content)
1899 orientation = toolbar->orientation;
1900 direction = gtk_widget_get_direction (GTK_WIDGET (toolbar));
1902 /* distance to first interesting item */
1903 best_content = interesting_content->data;
1904 toolbar_content_get_allocation (best_content, &allocation);
1906 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1910 if (direction == GTK_TEXT_DIR_LTR)
1913 pos = allocation.x + allocation.width;
1921 best_content = NULL;
1922 best_distance = ABS (pos - cursor);
1924 /* distance to far end of each item */
1925 for (list = interesting_content; list != NULL; list = list->next)
1927 ToolbarContent *content = list->data;
1929 toolbar_content_get_allocation (content, &allocation);
1931 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1933 if (direction == GTK_TEXT_DIR_LTR)
1934 pos = allocation.x + allocation.width;
1940 pos = allocation.y + allocation.height;
1943 distance = ABS (pos - cursor);
1945 if (distance < best_distance)
1947 best_distance = distance;
1948 best_content = content;
1952 g_list_free (interesting_content);
1957 return g_list_index (priv->content, best_content) + 1;
1961 reset_all_placeholders (GtkToolbar *toolbar)
1963 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1966 for (list = priv->content; list != NULL; list = list->next)
1968 ToolbarContent *content = list->data;
1969 if (toolbar_content_is_placeholder (content))
1970 toolbar_content_set_disappearing (content, TRUE);
1975 physical_to_logical (GtkToolbar *toolbar,
1978 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1982 g_assert (physical >= 0);
1985 for (list = priv->content; list && physical > 0; list = list->next)
1987 ToolbarContent *content = list->data;
1989 if (!toolbar_content_is_placeholder (content))
1994 g_assert (physical == 0);
2000 logical_to_physical (GtkToolbar *toolbar,
2003 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2007 g_assert (logical >= 0);
2010 for (list = priv->content; list; list = list->next)
2012 ToolbarContent *content = list->data;
2014 if (!toolbar_content_is_placeholder (content))
2024 g_assert (logical == 0);
2030 * gtk_toolbar_set_drop_highlight_item:
2031 * @toolbar: a #GtkToolbar
2032 * @tool_item: a #GtkToolItem, or %NULL to turn of highlighting
2033 * @index: a position on @toolbar
2035 * Highlights @toolbar to give an idea of what it would look like
2036 * if @item was added to @toolbar at position indicated by @index. If @item
2037 * is %NULL, highlighting is turned off. In that case @index is ignored.
2039 * The @tool_item passed to this function must not be part of any widget
2040 * hierarchy. When an item is set as drop highlight item it can not
2041 * added to any widget hierarchy or used as highlight item for another
2047 gtk_toolbar_set_drop_highlight_item (GtkToolbar *toolbar,
2048 GtkToolItem *tool_item,
2051 ToolbarContent *content;
2052 GtkToolbarPrivate *priv;
2054 GtkRequisition requisition;
2055 GtkRequisition old_requisition;
2056 gboolean restart_sliding;
2058 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2059 g_return_if_fail (tool_item == NULL || GTK_IS_TOOL_ITEM (tool_item));
2061 gtk_toolbar_check_new_api (toolbar);
2063 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2067 if (priv->highlight_tool_item)
2069 gtk_widget_unparent (GTK_WIDGET (priv->highlight_tool_item));
2070 g_object_unref (priv->highlight_tool_item);
2071 priv->highlight_tool_item = NULL;
2074 reset_all_placeholders (toolbar);
2075 gtk_toolbar_begin_sliding (toolbar);
2079 n_items = gtk_toolbar_get_n_items (toolbar);
2080 if (index < 0 || index > n_items)
2083 if (tool_item != priv->highlight_tool_item)
2085 if (priv->highlight_tool_item)
2086 g_object_unref (priv->highlight_tool_item);
2088 g_object_ref (tool_item);
2089 gtk_object_sink (GTK_OBJECT (tool_item));
2091 priv->highlight_tool_item = tool_item;
2093 gtk_widget_set_parent (GTK_WIDGET (priv->highlight_tool_item),
2094 GTK_WIDGET (toolbar));
2097 index = logical_to_physical (toolbar, index);
2099 content = g_list_nth_data (priv->content, index);
2103 ToolbarContent *prev_content;
2105 prev_content = g_list_nth_data (priv->content, index - 1);
2107 if (prev_content && toolbar_content_is_placeholder (prev_content))
2108 content = prev_content;
2111 if (!content || !toolbar_content_is_placeholder (content))
2113 GtkWidget *placeholder;
2115 placeholder = GTK_WIDGET (gtk_separator_tool_item_new ());
2117 content = toolbar_content_new_tool_item (toolbar,
2118 GTK_TOOL_ITEM (placeholder),
2120 gtk_widget_show (placeholder);
2124 g_assert (toolbar_content_is_placeholder (content));
2126 gtk_widget_size_request (GTK_WIDGET (priv->highlight_tool_item),
2130 restart_sliding = FALSE;
2131 toolbar_content_size_request (content, toolbar, &old_requisition);
2132 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
2134 requisition.height = -1;
2135 if (requisition.width != old_requisition.width)
2136 restart_sliding = TRUE;
2140 requisition.width = -1;
2141 if (requisition.height != old_requisition.height)
2142 restart_sliding = TRUE;
2145 if (toolbar_content_disappearing (content))
2146 restart_sliding = TRUE;
2148 reset_all_placeholders (toolbar);
2149 toolbar_content_set_disappearing (content, FALSE);
2151 toolbar_content_set_size_request (content,
2152 requisition.width, requisition.height);
2154 if (restart_sliding)
2155 gtk_toolbar_begin_sliding (toolbar);
2159 gtk_toolbar_get_child_property (GtkContainer *container,
2165 GtkToolItem *item = GTK_TOOL_ITEM (child);
2167 switch (property_id)
2169 case CHILD_PROP_HOMOGENEOUS:
2170 g_value_set_boolean (value, gtk_tool_item_get_homogeneous (item));
2173 case CHILD_PROP_EXPAND:
2174 g_value_set_boolean (value, gtk_tool_item_get_expand (item));
2178 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
2184 gtk_toolbar_set_child_property (GtkContainer *container,
2187 const GValue *value,
2190 switch (property_id)
2192 case CHILD_PROP_HOMOGENEOUS:
2193 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
2196 case CHILD_PROP_EXPAND:
2197 gtk_tool_item_set_expand (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
2201 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
2207 gtk_toolbar_show_all (GtkWidget *widget)
2209 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
2212 for (list = priv->content; list != NULL; list = list->next)
2214 ToolbarContent *content = list->data;
2216 toolbar_content_show_all (content);
2219 gtk_widget_show (widget);
2223 gtk_toolbar_hide_all (GtkWidget *widget)
2225 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
2228 for (list = priv->content; list != NULL; list = list->next)
2230 ToolbarContent *content = list->data;
2232 toolbar_content_hide_all (content);
2235 gtk_widget_hide (widget);
2239 gtk_toolbar_add (GtkContainer *container,
2242 GtkToolbar *toolbar;
2244 g_return_if_fail (GTK_IS_TOOLBAR (container));
2245 g_return_if_fail (widget != NULL);
2247 toolbar = GTK_TOOLBAR (container);
2249 if (GTK_IS_TOOL_ITEM (widget))
2250 gtk_toolbar_insert (toolbar, GTK_TOOL_ITEM (widget), -1);
2252 gtk_toolbar_append_widget (toolbar, widget, NULL, NULL);
2256 gtk_toolbar_remove (GtkContainer *container,
2259 GtkToolbar *toolbar;
2260 GtkToolbarPrivate *priv;
2261 ToolbarContent *content_to_remove;
2264 g_return_if_fail (GTK_IS_TOOLBAR (container));
2265 g_return_if_fail (GTK_IS_WIDGET (widget));
2267 toolbar = GTK_TOOLBAR (container);
2268 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2270 content_to_remove = NULL;
2271 for (list = priv->content; list != NULL; list = list->next)
2273 ToolbarContent *content = list->data;
2276 child = toolbar_content_get_widget (content);
2277 if (child && child == widget)
2279 content_to_remove = content;
2284 g_return_if_fail (content_to_remove != NULL);
2286 toolbar_content_remove (content_to_remove, toolbar);
2287 toolbar_content_free (content_to_remove);
2291 gtk_toolbar_forall (GtkContainer *container,
2292 gboolean include_internals,
2293 GtkCallback callback,
2294 gpointer callback_data)
2296 GtkToolbar *toolbar = GTK_TOOLBAR (container);
2297 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2300 g_return_if_fail (callback != NULL);
2302 list = priv->content;
2305 ToolbarContent *content = list->data;
2306 GList *next = list->next;
2308 if (include_internals || !toolbar_content_is_placeholder (content))
2310 GtkWidget *child = toolbar_content_get_widget (content);
2313 (*callback) (child, callback_data);
2319 if (include_internals)
2320 (* callback) (priv->arrow_button, callback_data);
2324 gtk_toolbar_child_type (GtkContainer *container)
2326 return GTK_TYPE_TOOL_ITEM;
2330 gtk_toolbar_reconfigured (GtkToolbar *toolbar)
2332 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2335 list = priv->content;
2338 ToolbarContent *content = list->data;
2339 GList *next = list->next;
2341 toolbar_content_toolbar_reconfigured (content, toolbar);
2348 gtk_toolbar_orientation_changed (GtkToolbar *toolbar,
2349 GtkOrientation orientation)
2351 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2352 if (toolbar->orientation != orientation)
2354 toolbar->orientation = orientation;
2356 if (orientation == GTK_ORIENTATION_HORIZONTAL)
2357 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_DOWN, GTK_SHADOW_NONE);
2358 else if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
2359 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
2361 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_LEFT, GTK_SHADOW_NONE);
2363 gtk_toolbar_reconfigured (toolbar);
2365 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2366 g_object_notify (G_OBJECT (toolbar), "orientation");
2371 gtk_toolbar_real_style_changed (GtkToolbar *toolbar,
2372 GtkToolbarStyle style)
2374 if (toolbar->style != style)
2376 toolbar->style = style;
2378 gtk_toolbar_reconfigured (toolbar);
2380 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2381 g_object_notify (G_OBJECT (toolbar), "toolbar_style");
2386 menu_position_func (GtkMenu *menu,
2392 GtkToolbar *toolbar = GTK_TOOLBAR (user_data);
2393 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2395 GtkRequisition menu_req;
2397 gdk_window_get_origin (GTK_BUTTON (priv->arrow_button)->event_window, x, y);
2398 gtk_widget_size_request (priv->arrow_button, &req);
2399 gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
2401 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
2403 *y += priv->arrow_button->allocation.height;
2404 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
2405 *x += priv->arrow_button->allocation.width - req.width;
2407 *x += req.width - menu_req.width;
2411 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
2412 *x += priv->arrow_button->allocation.width;
2414 *x -= menu_req.width;
2415 *y += priv->arrow_button->allocation.height - req.height;
2422 menu_deactivated (GtkWidget *menu,
2423 GtkToolbar *toolbar)
2425 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2426 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->arrow_button), FALSE);
2430 menu_detached (GtkWidget *toolbar,
2433 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2438 remove_item (GtkWidget *menu_item,
2441 gtk_container_remove (GTK_CONTAINER (menu_item->parent), menu_item);
2445 show_menu (GtkToolbar *toolbar,
2446 GdkEventButton *event)
2448 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2453 gtk_container_foreach (GTK_CONTAINER (priv->menu), remove_item, NULL);
2454 gtk_widget_destroy (GTK_WIDGET (priv->menu));
2457 priv->menu = GTK_MENU (gtk_menu_new ());
2458 gtk_menu_attach_to_widget (priv->menu,
2459 GTK_WIDGET (toolbar),
2461 g_signal_connect (priv->menu, "deactivate", G_CALLBACK (menu_deactivated), toolbar);
2463 for (list = priv->content; list != NULL; list = list->next)
2465 ToolbarContent *content = list->data;
2467 if (toolbar_content_get_state (content) == OVERFLOWN &&
2468 !toolbar_content_is_placeholder (content))
2470 GtkWidget *menu_item = toolbar_content_retrieve_menu_item (content);
2474 g_assert (GTK_IS_MENU_ITEM (menu_item));
2475 gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), menu_item);
2480 gtk_widget_show_all (GTK_WIDGET (priv->menu));
2482 gtk_menu_popup (priv->menu, NULL, NULL,
2483 menu_position_func, toolbar,
2484 event? event->button : 0,
2485 event? event->time : gtk_get_current_event_time());
2489 gtk_toolbar_arrow_button_clicked (GtkWidget *button,
2490 GtkToolbar *toolbar)
2492 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2494 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->arrow_button)) &&
2495 (!priv->menu || !GTK_WIDGET_VISIBLE (GTK_WIDGET (priv->menu))))
2497 /* We only get here when the button is clicked with the keybaord,
2498 * because mouse button presses result in the menu being shown so
2499 * that priv->menu would be non-NULL and visible.
2501 show_menu (toolbar, NULL);
2502 gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->menu), FALSE);
2507 gtk_toolbar_arrow_button_press (GtkWidget *button,
2508 GdkEventButton *event,
2509 GtkToolbar *toolbar)
2511 show_menu (toolbar, event);
2512 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
2518 gtk_toolbar_button_press (GtkWidget *toolbar,
2519 GdkEventButton *event)
2521 if (event->button == 3)
2523 gboolean return_value;
2525 g_signal_emit (toolbar, toolbar_signals[POPUP_CONTEXT_MENU], 0,
2526 (int)event->x_root, (int)event->y_root, event->button,
2529 return return_value;
2536 gtk_toolbar_popup_menu (GtkWidget *toolbar)
2538 gboolean return_value;
2539 /* This function is the handler for the "popup menu" keybinding,
2540 * ie., it is called when the user presses Shift F10
2542 g_signal_emit (toolbar, toolbar_signals[POPUP_CONTEXT_MENU], 0,
2543 -1, -1, -1, &return_value);
2545 return return_value;
2551 * Creates a new toolbar.
2553 * Return Value: the newly-created toolbar.
2556 gtk_toolbar_new (void)
2558 GtkToolbar *toolbar;
2560 toolbar = g_object_new (GTK_TYPE_TOOLBAR, NULL);
2562 return GTK_WIDGET (toolbar);
2566 * gtk_toolbar_insert:
2567 * @toolbar: a #GtkToolbar
2568 * @item: a #GtkToolItem
2569 * @pos: the position of the new item
2571 * Insert a #GtkToolItem into the toolbar at position @pos. If @pos is
2572 * 0 the item is prepended to the start of the toolbar. If @pos is
2573 * negative, the item is appended to the end of the toolbar.
2578 gtk_toolbar_insert (GtkToolbar *toolbar,
2582 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2583 g_return_if_fail (GTK_IS_TOOL_ITEM (item));
2585 if (!gtk_toolbar_check_new_api (toolbar))
2589 pos = logical_to_physical (toolbar, pos);
2591 toolbar_content_new_tool_item (toolbar, item, FALSE, pos);
2595 * gtk_toolbar_get_item_index:
2596 * @toolbar: a #GtkToolbar
2597 * @item: a #GtkToolItem that is a child of @toolbar
2599 * Returns the position of @item on the toolbar, starting from 0.
2600 * It is an error if @item is not a child of the toolbar.
2602 * Return value: the position of item on the toolbar.
2607 gtk_toolbar_get_item_index (GtkToolbar *toolbar,
2610 GtkToolbarPrivate *priv;
2614 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
2615 g_return_val_if_fail (GTK_IS_TOOL_ITEM (item), -1);
2616 g_return_val_if_fail (GTK_WIDGET (item)->parent == GTK_WIDGET (toolbar), -1);
2618 if (!gtk_toolbar_check_new_api (toolbar))
2621 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2624 for (list = priv->content; list != NULL; list = list->next)
2626 ToolbarContent *content = list->data;
2629 widget = toolbar_content_get_widget (content);
2631 if (item == GTK_TOOL_ITEM (widget))
2637 return physical_to_logical (toolbar, n);
2641 * gtk_toolbar_set_orientation:
2642 * @toolbar: a #GtkToolbar.
2643 * @orientation: a new #GtkOrientation.
2645 * Sets whether a toolbar should appear horizontally or vertically.
2648 gtk_toolbar_set_orientation (GtkToolbar *toolbar,
2649 GtkOrientation orientation)
2651 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2653 g_signal_emit (toolbar, toolbar_signals[ORIENTATION_CHANGED], 0, orientation);
2657 * gtk_toolbar_get_orientation:
2658 * @toolbar: a #GtkToolbar
2660 * Retrieves the current orientation of the toolbar. See
2661 * gtk_toolbar_set_orientation().
2663 * Return value: the orientation
2666 gtk_toolbar_get_orientation (GtkToolbar *toolbar)
2668 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_ORIENTATION_HORIZONTAL);
2670 return toolbar->orientation;
2674 * gtk_toolbar_set_style:
2675 * @toolbar: a #GtkToolbar.
2676 * @style: the new style for @toolbar.
2678 * Alters the view of @toolbar to display either icons only, text only, or both.
2681 gtk_toolbar_set_style (GtkToolbar *toolbar,
2682 GtkToolbarStyle style)
2684 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2686 toolbar->style_set = TRUE;
2687 g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
2691 * gtk_toolbar_get_style:
2692 * @toolbar: a #GtkToolbar
2694 * Retrieves whether the toolbar has text, icons, or both . See
2695 * gtk_toolbar_set_style().
2697 * Return value: the current style of @toolbar
2700 gtk_toolbar_get_style (GtkToolbar *toolbar)
2702 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), DEFAULT_TOOLBAR_STYLE);
2704 return toolbar->style;
2708 * gtk_toolbar_unset_style:
2709 * @toolbar: a #GtkToolbar
2711 * Unsets a toolbar style set with gtk_toolbar_set_style(), so that
2712 * user preferences will be used to determine the toolbar style.
2715 gtk_toolbar_unset_style (GtkToolbar *toolbar)
2717 GtkToolbarStyle style;
2719 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2721 if (toolbar->style_set)
2723 GtkSettings *settings = toolbar_get_settings (toolbar);
2726 g_object_get (settings,
2727 "gtk-toolbar-style", &style,
2730 style = DEFAULT_TOOLBAR_STYLE;
2732 if (style != toolbar->style)
2733 g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
2735 toolbar->style_set = FALSE;
2740 * gtk_toolbar_set_tooltips:
2741 * @toolbar: a #GtkToolbar.
2742 * @enable: set to %FALSE to disable the tooltips, or %TRUE to enable them.
2744 * Sets if the tooltips of a toolbar should be active or not.
2747 gtk_toolbar_set_tooltips (GtkToolbar *toolbar,
2750 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2753 gtk_tooltips_enable (toolbar->tooltips);
2755 gtk_tooltips_disable (toolbar->tooltips);
2759 * gtk_toolbar_get_tooltips:
2760 * @toolbar: a #GtkToolbar
2762 * Retrieves whether tooltips are enabled. See
2763 * gtk_toolbar_set_tooltips().
2765 * Return value: %TRUE if tooltips are enabled
2768 gtk_toolbar_get_tooltips (GtkToolbar *toolbar)
2770 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2772 return toolbar->tooltips->enabled;
2776 * gtk_toolbar_get_n_items:
2777 * @toolbar: a #GtkToolbar
2779 * Returns the number of items on the toolbar.
2781 * Return value: the number of items on the toolbar
2786 gtk_toolbar_get_n_items (GtkToolbar *toolbar)
2788 GtkToolbarPrivate *priv;
2790 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
2792 if (!gtk_toolbar_check_new_api (toolbar))
2795 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2797 return physical_to_logical (toolbar, g_list_length (priv->content));
2801 * gtk_toolbar_get_nth_item:
2802 * @toolbar: a #GtkToolbar
2803 * @n: A position on the toolbar
2805 * Returns the @n<!-- -->'s item on @toolbar, or %NULL if the
2806 * toolbar does not contain an @n<!-- -->'th item.
2808 * Return value: The @n<!-- -->'th #GtkToolItem on @toolbar, or %NULL if there
2809 * isn't an @n<!-- -->th item.
2814 gtk_toolbar_get_nth_item (GtkToolbar *toolbar,
2817 GtkToolbarPrivate *priv;
2818 ToolbarContent *content;
2821 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
2823 if (!gtk_toolbar_check_new_api (toolbar))
2826 n_items = gtk_toolbar_get_n_items (toolbar);
2828 if (n < 0 || n >= n_items)
2831 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2833 content = g_list_nth_data (priv->content, logical_to_physical (toolbar, n));
2836 g_assert (!toolbar_content_is_placeholder (content));
2838 return GTK_TOOL_ITEM (toolbar_content_get_widget (content));
2842 * gtk_toolbar_get_icon_size:
2843 * @toolbar: a #GtkToolbar
2845 * Retrieves the icon size fo the toolbar. See gtk_toolbar_set_icon_size().
2847 * Return value: the current icon size for the icons on the toolbar.
2850 gtk_toolbar_get_icon_size (GtkToolbar *toolbar)
2852 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), DEFAULT_ICON_SIZE);
2854 return toolbar->icon_size;
2858 * gtk_toolbar_get_relief_style:
2859 * @toolbar: a #GtkToolbar
2861 * Returns the relief style of buttons on @toolbar. See
2862 * gtk_button_set_relief().
2864 * Return value: The relief style of buttons on @toolbar.
2869 gtk_toolbar_get_relief_style (GtkToolbar *toolbar)
2871 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_RELIEF_NONE);
2873 return get_button_relief (toolbar);
2877 * gtk_toolbar_set_show_arrow:
2878 * @toolbar: a #GtkToolbar
2879 * @show_arrow: Whether to show an overflow menu
2881 * Sets whether to show an overflow menu when
2882 * @toolbar doesn't have room for all items on it. If %TRUE,
2883 * items that there are not room are available through an
2889 gtk_toolbar_set_show_arrow (GtkToolbar *toolbar,
2890 gboolean show_arrow)
2892 GtkToolbarPrivate *priv;
2894 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2896 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2897 show_arrow = show_arrow != FALSE;
2899 if (priv->show_arrow != show_arrow)
2901 priv->show_arrow = show_arrow;
2903 if (!priv->show_arrow)
2904 gtk_widget_hide (priv->arrow_button);
2906 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2907 g_object_notify (G_OBJECT (toolbar), "show_arrow");
2912 * gtk_toolbar_get_show_arrow:
2913 * @toolbar: a #GtkToolbar
2915 * Returns whether the toolbar has an overflow menu.
2916 * See gtk_toolbar_set_show_arrow()
2923 gtk_toolbar_get_show_arrow (GtkToolbar *toolbar)
2925 GtkToolbarPrivate *priv;
2927 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2929 if (!gtk_toolbar_check_new_api (toolbar))
2932 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2934 return priv->show_arrow;
2938 * gtk_toolbar_get_drop_index:
2939 * @toolbar: a #GtkToolbar
2940 * @x: x coordinate of a point on the toolbar
2941 * @y: y coordinate of a point on the toolbar
2943 * Returns the position corresponding to the indicated point on
2944 * @toolbar. This is useful when dragging items to the toolbar:
2945 * this function returns the position a new item should be
2948 * @x and @y are in @toolbar coordinates.
2950 * Return value: The position corresponding to the point (@x, @y) on the toolbar.
2955 gtk_toolbar_get_drop_index (GtkToolbar *toolbar,
2959 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
2961 if (!gtk_toolbar_check_new_api (toolbar))
2964 return physical_to_logical (toolbar, find_drop_index (toolbar, x, y));
2968 gtk_toolbar_finalize (GObject *object)
2971 GtkToolbar *toolbar = GTK_TOOLBAR (object);
2972 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2974 if (toolbar->tooltips)
2975 g_object_unref (toolbar->tooltips);
2977 for (list = priv->content; list != NULL; list = list->next)
2979 ToolbarContent *content = list->data;
2981 toolbar_content_free (content);
2984 g_list_free (priv->content);
2985 g_list_free (toolbar->children);
2987 g_timer_destroy (priv->timer);
2990 gtk_widget_destroy (GTK_WIDGET (priv->menu));
2993 g_source_remove (priv->idle_id);
2995 G_OBJECT_CLASS (parent_class)->finalize (object);
2999 _gtk_toolbar_elide_underscores (const gchar *original)
3003 gboolean last_underscore;
3005 q = result = g_malloc (strlen (original) + 1);
3006 last_underscore = FALSE;
3008 for (p = original; *p; p++)
3010 if (!last_underscore && *p == '_')
3011 last_underscore = TRUE;
3014 last_underscore = FALSE;
3029 * gtk_toolbar_set_icon_size:
3030 * @toolbar: A #GtkToolbar
3031 * @icon_size: The #GtkIconSize that stock icons in the toolbar shall have.
3033 * This function sets the size of stock icons in the toolbar. You
3034 * can call it both before you add the icons and after they've been
3035 * added. The size you set will override user preferences for the default
3039 gtk_toolbar_set_icon_size (GtkToolbar *toolbar,
3040 GtkIconSize icon_size)
3042 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
3044 toolbar->icon_size_set = TRUE;
3046 if (toolbar->icon_size == icon_size)
3049 toolbar->icon_size = icon_size;
3051 gtk_toolbar_reconfigured (toolbar);
3053 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
3057 * gtk_toolbar_unset_icon_size:
3058 * @toolbar: a #GtkToolbar
3060 * Unsets toolbar icon size set with gtk_toolbar_set_icon_size(), so that
3061 * user preferences will be used to determine the icon size.
3064 gtk_toolbar_unset_icon_size (GtkToolbar *toolbar)
3068 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
3070 if (toolbar->icon_size_set)
3072 GtkSettings *settings = toolbar_get_settings (toolbar);
3076 g_object_get (settings,
3077 "gtk-toolbar-icon-size", &size,
3081 size = DEFAULT_ICON_SIZE;
3083 if (size != toolbar->icon_size)
3084 gtk_toolbar_set_icon_size (toolbar, size);
3086 toolbar->icon_size_set = FALSE;
3091 * gtk_toolbar_append_item:
3092 * @toolbar: a #GtkToolbar.
3093 * @text: give your toolbar button a label.
3094 * @tooltip_text: a string that appears when the user holds the mouse over this item.
3095 * @tooltip_private_text: use with #GtkTipsQuery.
3096 * @icon: a #GtkWidget that should be used as the button's icon.
3097 * @callback: the function to be executed when the button is pressed.
3098 * @user_data: a pointer to any data you wish to be passed to the callback.
3100 * Inserts a new item into the toolbar. You must specify the position
3101 * in the toolbar where it will be inserted.
3103 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3104 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3106 * Return value: the new toolbar item as a #GtkWidget.
3109 gtk_toolbar_append_item (GtkToolbar *toolbar,
3111 const char *tooltip_text,
3112 const char *tooltip_private_text,
3114 GtkSignalFunc callback,
3117 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3119 tooltip_text, tooltip_private_text,
3120 icon, callback, user_data,
3121 toolbar->num_children);
3125 * gtk_toolbar_prepend_item:
3126 * @toolbar: a #GtkToolbar.
3127 * @text: give your toolbar button a label.
3128 * @tooltip_text: a string that appears when the user holds the mouse over this item.
3129 * @tooltip_private_text: use with #GtkTipsQuery.
3130 * @icon: a #GtkWidget that should be used as the button's icon.
3131 * @callback: the function to be executed when the button is pressed.
3132 * @user_data: a pointer to any data you wish to be passed to the callback.
3134 * Adds a new button to the beginning (top or left edges) of the given toolbar.
3136 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3137 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3139 * Return value: the new toolbar item as a #GtkWidget.
3142 gtk_toolbar_prepend_item (GtkToolbar *toolbar,
3144 const char *tooltip_text,
3145 const char *tooltip_private_text,
3147 GtkSignalFunc callback,
3150 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3152 tooltip_text, tooltip_private_text,
3153 icon, callback, user_data,
3158 * gtk_toolbar_insert_item:
3159 * @toolbar: a #GtkToolbar.
3160 * @text: give your toolbar button a label.
3161 * @tooltip_text: a string that appears when the user holds the mouse over this item.
3162 * @tooltip_private_text: use with #GtkTipsQuery.
3163 * @icon: a #GtkWidget that should be used as the button's icon.
3164 * @callback: the function to be executed when the button is pressed.
3165 * @user_data: a pointer to any data you wish to be passed to the callback.
3166 * @position: the number of widgets to insert this item after.
3168 * Inserts a new item into the toolbar. You must specify the position in the
3169 * toolbar where it will be inserted.
3171 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3172 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3174 * Return value: the new toolbar item as a #GtkWidget.
3177 gtk_toolbar_insert_item (GtkToolbar *toolbar,
3179 const char *tooltip_text,
3180 const char *tooltip_private_text,
3182 GtkSignalFunc callback,
3186 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3188 tooltip_text, tooltip_private_text,
3189 icon, callback, user_data,
3194 * gtk_toolbar_insert_stock:
3195 * @toolbar: A #GtkToolbar
3196 * @stock_id: The id of the stock item you want to insert
3197 * @tooltip_text: The text in the tooltip of the toolbar button
3198 * @tooltip_private_text: The private text of the tooltip
3199 * @callback: The callback called when the toolbar button is clicked.
3200 * @user_data: user data passed to callback
3201 * @position: The position the button shall be inserted at.
3202 * -1 means at the end.
3204 * Inserts a stock item at the specified position of the toolbar. If
3205 * @stock_id is not a known stock item ID, it's inserted verbatim,
3206 * except that underscores used to mark mnemonics are removed.
3208 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3209 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3211 * Returns: the inserted widget
3214 gtk_toolbar_insert_stock (GtkToolbar *toolbar,
3215 const gchar *stock_id,
3216 const char *tooltip_text,
3217 const char *tooltip_private_text,
3218 GtkSignalFunc callback,
3222 return internal_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3224 tooltip_text, tooltip_private_text,
3225 NULL, callback, user_data,
3230 * gtk_toolbar_append_space:
3231 * @toolbar: a #GtkToolbar.
3233 * Adds a new space to the end of the toolbar.
3236 gtk_toolbar_append_space (GtkToolbar *toolbar)
3238 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
3242 toolbar->num_children);
3246 * gtk_toolbar_prepend_space:
3247 * @toolbar: a #GtkToolbar.
3249 * Adds a new space to the beginning of the toolbar.
3252 gtk_toolbar_prepend_space (GtkToolbar *toolbar)
3254 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
3262 * gtk_toolbar_insert_space:
3263 * @toolbar: a #GtkToolbar
3264 * @position: the number of widgets after which a space should be inserted.
3266 * Inserts a new space in the toolbar at the specified position.
3269 gtk_toolbar_insert_space (GtkToolbar *toolbar,
3272 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
3280 * gtk_toolbar_remove_space:
3281 * @toolbar: a #GtkToolbar.
3282 * @position: the index of the space to remove.
3284 * Removes a space from the specified position.
3287 gtk_toolbar_remove_space (GtkToolbar *toolbar,
3290 GtkToolbarPrivate *priv;
3291 ToolbarContent *content;
3293 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
3295 if (!gtk_toolbar_check_old_api (toolbar))
3298 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3300 content = g_list_nth_data (priv->content, position);
3304 g_warning ("Toolbar position %d doesn't exist", position);
3308 if (!toolbar_content_is_separator (content))
3310 g_warning ("Toolbar position %d is not a space", position);
3314 toolbar_content_remove (content, toolbar);
3315 toolbar_content_free (content);
3319 * gtk_toolbar_append_widget:
3320 * @toolbar: a #GtkToolbar.
3321 * @widget: a #GtkWidget to add to the toolbar.
3322 * @tooltip_text: the element's tooltip.
3323 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3325 * Adds a widget to the end of the given toolbar.
3328 gtk_toolbar_append_widget (GtkToolbar *toolbar,
3330 const gchar *tooltip_text,
3331 const gchar *tooltip_private_text)
3333 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
3335 tooltip_text, tooltip_private_text,
3337 toolbar->num_children);
3341 * gtk_toolbar_prepend_widget:
3342 * @toolbar: a #GtkToolbar.
3343 * @widget: a #GtkWidget to add to the toolbar.
3344 * @tooltip_text: the element's tooltip.
3345 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3347 * Adds a widget to the beginning of the given toolbar.
3350 gtk_toolbar_prepend_widget (GtkToolbar *toolbar,
3352 const gchar *tooltip_text,
3353 const gchar *tooltip_private_text)
3355 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
3357 tooltip_text, tooltip_private_text,
3363 * gtk_toolbar_insert_widget:
3364 * @toolbar: a #GtkToolbar.
3365 * @widget: a #GtkWidget to add to the toolbar.
3366 * @tooltip_text: the element's tooltip.
3367 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3368 * @position: the number of widgets to insert this widget after.
3370 * Inserts a widget in the toolbar at the given position.
3373 gtk_toolbar_insert_widget (GtkToolbar *toolbar,
3375 const char *tooltip_text,
3376 const char *tooltip_private_text,
3379 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
3381 tooltip_text, tooltip_private_text,
3387 * gtk_toolbar_append_element:
3388 * @toolbar: a #GtkToolbar.
3389 * @type: a value of type #GtkToolbarChildType that determines what @widget will be.
3390 * @widget: a #GtkWidget, or %NULL.
3391 * @text: the element's label.
3392 * @tooltip_text: the element's tooltip.
3393 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3394 * @icon: a #GtkWidget that provides pictorial representation of the element's function.
3395 * @callback: the function to be executed when the button is pressed.
3396 * @user_data: any data you wish to pass to the callback.
3398 * Adds a new element to the end of a toolbar.
3400 * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element.
3401 * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine
3402 * the radio group for the new element. In all other cases, @widget must
3405 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3406 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3408 * Return value: the new toolbar element as a #GtkWidget.
3411 gtk_toolbar_append_element (GtkToolbar *toolbar,
3412 GtkToolbarChildType type,
3415 const char *tooltip_text,
3416 const char *tooltip_private_text,
3418 GtkSignalFunc callback,
3421 return gtk_toolbar_insert_element (toolbar, type, widget, text,
3422 tooltip_text, tooltip_private_text,
3423 icon, callback, user_data,
3424 toolbar->num_children);
3428 * gtk_toolbar_prepend_element:
3429 * @toolbar: a #GtkToolbar.
3430 * @type: a value of type #GtkToolbarChildType that determines what @widget will be.
3431 * @widget: a #GtkWidget, or %NULL
3432 * @text: the element's label.
3433 * @tooltip_text: the element's tooltip.
3434 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3435 * @icon: a #GtkWidget that provides pictorial representation of the element's function.
3436 * @callback: the function to be executed when the button is pressed.
3437 * @user_data: any data you wish to pass to the callback.
3439 * Adds a new element to the beginning of a toolbar.
3441 * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element.
3442 * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine
3443 * the radio group for the new element. In all other cases, @widget must
3446 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3447 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3449 * Return value: the new toolbar element as a #GtkWidget.
3452 gtk_toolbar_prepend_element (GtkToolbar *toolbar,
3453 GtkToolbarChildType type,
3456 const char *tooltip_text,
3457 const char *tooltip_private_text,
3459 GtkSignalFunc callback,
3462 return gtk_toolbar_insert_element (toolbar, type, widget, text,
3463 tooltip_text, tooltip_private_text,
3464 icon, callback, user_data, 0);
3468 * gtk_toolbar_insert_element:
3469 * @toolbar: a #GtkToolbar.
3470 * @type: a value of type #GtkToolbarChildType that determines what @widget
3472 * @widget: a #GtkWidget, or %NULL.
3473 * @text: the element's label.
3474 * @tooltip_text: the element's tooltip.
3475 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3476 * @icon: a #GtkWidget that provides pictorial representation of the element's function.
3477 * @callback: the function to be executed when the button is pressed.
3478 * @user_data: any data you wish to pass to the callback.
3479 * @position: the number of widgets to insert this element after.
3481 * Inserts a new element in the toolbar at the given position.
3483 * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element.
3484 * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine
3485 * the radio group for the new element. In all other cases, @widget must
3488 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3489 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3491 * Return value: the new toolbar element as a #GtkWidget.
3494 gtk_toolbar_insert_element (GtkToolbar *toolbar,
3495 GtkToolbarChildType type,
3498 const char *tooltip_text,
3499 const char *tooltip_private_text,
3501 GtkSignalFunc callback,
3505 return internal_insert_element (toolbar, type, widget, text,
3506 tooltip_text, tooltip_private_text,
3507 icon, callback, user_data, position, FALSE);
3511 set_child_packing_and_visibility(GtkToolbar *toolbar,
3512 GtkToolbarChild *child)
3517 box = gtk_bin_get_child (GTK_BIN (child->widget));
3519 g_return_if_fail (GTK_IS_BOX (box));
3523 expand = (toolbar->style != GTK_TOOLBAR_BOTH);
3525 gtk_box_set_child_packing (GTK_BOX (box), child->label,
3526 expand, expand, 0, GTK_PACK_END);
3528 if (toolbar->style != GTK_TOOLBAR_ICONS)
3529 gtk_widget_show (child->label);
3531 gtk_widget_hide (child->label);
3536 expand = (toolbar->style != GTK_TOOLBAR_BOTH_HORIZ);
3538 gtk_box_set_child_packing (GTK_BOX (box), child->icon,
3539 expand, expand, 0, GTK_PACK_END);
3541 if (toolbar->style != GTK_TOOLBAR_TEXT)
3542 gtk_widget_show (child->icon);
3544 gtk_widget_hide (child->icon);
3549 internal_insert_element (GtkToolbar *toolbar,
3550 GtkToolbarChildType type,
3553 const char *tooltip_text,
3554 const char *tooltip_private_text,
3556 GtkSignalFunc callback,
3562 ToolbarContent *content;
3563 GtkToolbarPrivate *priv;
3564 char *free_me = NULL;
3565 gboolean is_button = FALSE;
3567 GtkWidget *child_widget;
3568 GtkWidget *child_label;
3569 GtkWidget *child_icon;
3571 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
3572 if (type == GTK_TOOLBAR_CHILD_WIDGET)
3573 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3574 else if (type != GTK_TOOLBAR_CHILD_RADIOBUTTON)
3575 g_return_val_if_fail (widget == NULL, NULL);
3577 if (!gtk_toolbar_check_old_api (toolbar))
3580 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3582 child_widget = NULL;
3588 case GTK_TOOLBAR_CHILD_SPACE:
3591 case GTK_TOOLBAR_CHILD_WIDGET:
3592 child_widget = widget;
3595 case GTK_TOOLBAR_CHILD_BUTTON:
3596 case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
3597 case GTK_TOOLBAR_CHILD_RADIOBUTTON:
3599 if (type == GTK_TOOLBAR_CHILD_BUTTON)
3601 child_widget = gtk_button_new ();
3603 else if (type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
3605 child_widget = gtk_toggle_button_new ();
3606 gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (child_widget), FALSE);
3608 else /* type == GTK_TOOLBAR_CHILD_RADIOBUTTON */
3610 GSList *group = NULL;
3613 group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
3615 child_widget = gtk_radio_button_new (group);
3616 gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (child_widget), FALSE);
3619 gtk_button_set_relief (GTK_BUTTON (child_widget), get_button_relief (toolbar));
3620 gtk_button_set_focus_on_click (GTK_BUTTON (child_widget), FALSE);
3624 g_signal_connect (child_widget, "clicked",
3625 callback, user_data);
3628 if (toolbar->style == GTK_TOOLBAR_BOTH_HORIZ)
3629 box = gtk_hbox_new (FALSE, 0);
3631 box = gtk_vbox_new (FALSE, 0);
3633 gtk_container_add (GTK_CONTAINER (child_widget), box);
3634 gtk_widget_show (box);
3636 if (text && use_stock)
3638 GtkStockItem stock_item;
3639 if (gtk_stock_lookup (text, &stock_item))
3642 icon = gtk_image_new_from_stock (text, toolbar->icon_size);
3644 text = free_me = _gtk_toolbar_elide_underscores (stock_item.label);
3650 child_label = gtk_label_new (text);
3652 gtk_container_add (GTK_CONTAINER (box), child_label);
3657 child_icon = GTK_WIDGET (icon);
3658 gtk_container_add (GTK_CONTAINER (box), child_icon);
3661 gtk_widget_show (child_widget);
3665 g_assert_not_reached ();
3669 if ((type != GTK_TOOLBAR_CHILD_SPACE) && tooltip_text)
3671 gtk_tooltips_set_tip (toolbar->tooltips, child_widget,
3672 tooltip_text, tooltip_private_text);
3675 content = toolbar_content_new_compatibility (toolbar, type, child_widget,
3676 child_icon, child_label, position);
3681 return child_widget;
3685 * ToolbarContent methods
3687 struct _ToolbarContent
3697 GtkAllocation start_allocation;
3698 GtkAllocation goal_allocation;
3699 guint is_placeholder : 1;
3700 guint disappearing : 1;
3705 GtkToolbarChild child;
3706 GtkAllocation space_allocation;
3707 guint space_visible : 1;
3712 static ToolbarContent *
3713 toolbar_content_new_tool_item (GtkToolbar *toolbar,
3715 gboolean is_placeholder,
3718 ToolbarContent *content;
3719 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3721 content = g_new0 (ToolbarContent, 1);
3723 content->type = TOOL_ITEM;
3724 content->state = NOT_ALLOCATED;
3725 content->u.tool_item.item = item;
3726 content->u.tool_item.is_placeholder = is_placeholder;
3728 gtk_widget_set_parent (GTK_WIDGET (item), GTK_WIDGET (toolbar));
3730 priv->content = g_list_insert (priv->content, content, pos);
3732 if (!is_placeholder)
3734 toolbar->num_children++;
3736 gtk_toolbar_stop_sliding (toolbar);
3739 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
3744 static ToolbarContent *
3745 toolbar_content_new_compatibility (GtkToolbar *toolbar,
3746 GtkToolbarChildType type,
3752 ToolbarContent *content;
3753 GtkToolbarChild *child;
3754 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3756 content = g_new0 (ToolbarContent, 1);
3758 child = &(content->u.compatibility.child);
3760 content->type = COMPATIBILITY;
3762 child->widget = widget;
3764 child->label = label;
3766 if (type != GTK_TOOLBAR_CHILD_SPACE)
3768 gtk_widget_set_parent (child->widget, GTK_WIDGET (toolbar));
3772 content->u.compatibility.space_visible = TRUE;
3773 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
3776 if (type == GTK_TOOLBAR_CHILD_BUTTON ||
3777 type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON ||
3778 type == GTK_TOOLBAR_CHILD_RADIOBUTTON)
3780 set_child_packing_and_visibility (toolbar, child);
3783 priv->content = g_list_insert (priv->content, content, pos);
3784 toolbar->children = g_list_insert (toolbar->children, child, pos);
3786 toolbar->num_children++;
3792 toolbar_content_remove (ToolbarContent *content,
3793 GtkToolbar *toolbar)
3795 GtkToolbarChild *child;
3796 GtkToolbarPrivate *priv;
3798 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3800 switch (content->type)
3803 gtk_widget_unparent (GTK_WIDGET (content->u.tool_item.item));
3807 child = &(content->u.compatibility.child);
3809 if (child->type != GTK_TOOLBAR_CHILD_SPACE)
3811 g_object_ref (child->widget);
3812 gtk_widget_unparent (child->widget);
3813 gtk_widget_destroy (child->widget);
3814 g_object_unref (child->widget);
3817 toolbar->children = g_list_remove (toolbar->children, child);
3821 priv->content = g_list_remove (priv->content, content);
3823 if (!toolbar_content_is_placeholder (content))
3824 toolbar->num_children--;
3826 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
3830 toolbar_content_free (ToolbarContent *content)
3836 calculate_max_homogeneous_pixels (GtkWidget *widget)
3838 PangoContext *context;
3839 PangoFontMetrics *metrics;
3842 context = gtk_widget_get_pango_context (widget);
3843 metrics = pango_context_get_metrics (context,
3844 widget->style->font_desc,
3845 pango_context_get_language (context));
3846 char_width = pango_font_metrics_get_approximate_char_width (metrics);
3847 pango_font_metrics_unref (metrics);
3849 return PANGO_PIXELS (MAX_HOMOGENEOUS_N_CHARS * char_width);
3853 _gtk_toolbar_get_default_space_size (void)
3855 return DEFAULT_SPACE_SIZE;
3859 _gtk_toolbar_paint_space_line (GtkWidget *widget,
3860 GtkToolbar *toolbar,
3862 GtkAllocation *allocation)
3864 const double start_fraction = (SPACE_LINE_START / SPACE_LINE_DIVISION);
3865 const double end_fraction = (SPACE_LINE_END / SPACE_LINE_DIVISION);
3868 GtkToolbarSpaceStyle space_style;
3869 GtkOrientation orientation;
3871 g_return_if_fail (GTK_IS_WIDGET (widget));
3873 space_size = get_space_size (toolbar);
3874 space_style = get_space_style (toolbar);
3875 orientation = toolbar? toolbar->orientation : GTK_ORIENTATION_HORIZONTAL;
3877 if (orientation == GTK_ORIENTATION_HORIZONTAL)
3879 gtk_paint_vline (widget->style, widget->window,
3880 GTK_WIDGET_STATE (widget), area, widget,
3882 allocation->y + allocation->height * start_fraction,
3883 allocation->y + allocation->height * end_fraction,
3884 allocation->x + (space_size - widget->style->xthickness) / 2);
3888 gtk_paint_hline (widget->style, widget->window,
3889 GTK_WIDGET_STATE (widget), area, widget,
3891 allocation->x + allocation->width * start_fraction,
3892 allocation->x + allocation->width * end_fraction,
3893 allocation->y + (space_size - widget->style->ythickness) / 2);
3898 toolbar_content_expose (ToolbarContent *content,
3899 GtkContainer *container,
3900 GdkEventExpose *expose)
3902 GtkToolbar *toolbar = GTK_TOOLBAR (container);
3903 GtkToolbarChild *child;
3904 GtkWidget *widget = NULL; /* quiet gcc */
3906 switch (content->type)
3909 if (!content->u.tool_item.is_placeholder)
3910 widget = GTK_WIDGET (content->u.tool_item.item);
3914 child = &(content->u.compatibility.child);
3916 if (child->type == GTK_TOOLBAR_CHILD_SPACE)
3918 if (get_space_style (toolbar) == GTK_TOOLBAR_SPACE_LINE &&
3919 content->u.compatibility.space_visible)
3921 _gtk_toolbar_paint_space_line (GTK_WIDGET (toolbar), toolbar,
3923 &content->u.compatibility.space_allocation);
3928 widget = child->widget;
3933 gtk_container_propagate_expose (container, widget, expose);
3937 toolbar_content_visible (ToolbarContent *content,
3938 GtkToolbar *toolbar)
3942 switch (content->type)
3945 item = content->u.tool_item.item;
3947 if (!GTK_WIDGET_VISIBLE (item))
3950 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL &&
3951 gtk_tool_item_get_visible_horizontal (item))
3956 if ((toolbar->orientation == GTK_ORIENTATION_VERTICAL &&
3957 gtk_tool_item_get_visible_vertical (item)))
3966 if (content->u.compatibility.child.type != GTK_TOOLBAR_CHILD_SPACE)
3967 return GTK_WIDGET_VISIBLE (content->u.compatibility.child.widget);
3973 g_assert_not_reached ();
3978 toolbar_content_size_request (ToolbarContent *content,
3979 GtkToolbar *toolbar,
3980 GtkRequisition *requisition)
3984 switch (content->type)
3987 gtk_widget_size_request (GTK_WIDGET (content->u.tool_item.item),
3989 if (content->u.tool_item.is_placeholder &&
3990 content->u.tool_item.disappearing)
3992 requisition->width = 0;
3993 requisition->height = 0;
3998 space_size = get_space_size (toolbar);
4000 if (content->u.compatibility.child.type != GTK_TOOLBAR_CHILD_SPACE)
4002 gtk_widget_size_request (content->u.compatibility.child.widget,
4007 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
4009 requisition->width = space_size;
4010 requisition->height = 0;
4014 requisition->height = space_size;
4015 requisition->width = 0;
4024 toolbar_content_is_homogeneous (ToolbarContent *content,
4025 GtkToolbar *toolbar)
4027 gboolean result = FALSE; /* quiet gcc */
4028 GtkRequisition requisition;
4029 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
4031 if (priv->max_homogeneous_pixels < 0)
4033 priv->max_homogeneous_pixels =
4034 calculate_max_homogeneous_pixels (GTK_WIDGET (toolbar));
4037 toolbar_content_size_request (content, toolbar, &requisition);
4039 if (requisition.width > priv->max_homogeneous_pixels)
4042 switch (content->type)
4045 result = gtk_tool_item_get_homogeneous (content->u.tool_item.item) &&
4046 !GTK_IS_SEPARATOR_TOOL_ITEM (content->u.tool_item.item);
4048 if (gtk_tool_item_get_is_important (content->u.tool_item.item) &&
4049 toolbar->style == GTK_TOOLBAR_BOTH_HORIZ &&
4050 toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
4057 if (content->u.compatibility.child.type == GTK_TOOLBAR_CHILD_BUTTON ||
4058 content->u.compatibility.child.type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
4059 content->u.compatibility.child.type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
4074 toolbar_content_is_placeholder (ToolbarContent *content)
4076 if (content->type == TOOL_ITEM && content->u.tool_item.is_placeholder)
4083 toolbar_content_disappearing (ToolbarContent *content)
4085 if (content->type == TOOL_ITEM && content->u.tool_item.disappearing)
4092 toolbar_content_get_state (ToolbarContent *content)
4094 return content->state;
4098 toolbar_content_child_visible (ToolbarContent *content)
4100 switch (content->type)
4103 return GTK_WIDGET_CHILD_VISIBLE (content->u.tool_item.item);
4107 if (content->u.compatibility.child.type != GTK_TOOLBAR_CHILD_SPACE)
4109 return GTK_WIDGET_CHILD_VISIBLE (content->u.compatibility.child.widget);
4113 return content->u.compatibility.space_visible;
4118 return FALSE; /* quiet gcc */
4122 toolbar_content_get_goal_allocation (ToolbarContent *content,
4123 GtkAllocation *allocation)
4125 switch (content->type)
4128 *allocation = content->u.tool_item.goal_allocation;
4132 /* Goal allocations are only relevant when we are
4133 * using the new API, so we should never get here
4135 g_assert_not_reached ();
4141 toolbar_content_get_allocation (ToolbarContent *content,
4142 GtkAllocation *allocation)
4144 GtkToolbarChild *child;
4146 switch (content->type)
4149 *allocation = GTK_WIDGET (content->u.tool_item.item)->allocation;
4153 child = &(content->u.compatibility.child);
4155 if (child->type == GTK_TOOLBAR_CHILD_SPACE)
4156 *allocation = content->u.compatibility.space_allocation;
4158 *allocation = child->widget->allocation;
4164 toolbar_content_set_start_allocation (ToolbarContent *content,
4165 GtkAllocation *allocation)
4167 switch (content->type)
4170 content->u.tool_item.start_allocation = *allocation;
4174 /* start_allocation is only relevant when using the new API */
4175 g_assert_not_reached ();
4181 toolbar_content_get_expand (ToolbarContent *content)
4183 if (content->type == TOOL_ITEM &&
4184 gtk_tool_item_get_expand (content->u.tool_item.item))
4193 toolbar_content_set_goal_allocation (ToolbarContent *content,
4194 GtkAllocation *allocation)
4196 switch (content->type)
4199 content->u.tool_item.goal_allocation = *allocation;
4203 /* Only relevant when using new API */
4204 g_assert_not_reached ();
4210 toolbar_content_set_child_visible (ToolbarContent *content,
4211 GtkToolbar *toolbar,
4214 GtkToolbarChild *child;
4216 switch (content->type)
4219 gtk_widget_set_child_visible (GTK_WIDGET (content->u.tool_item.item),
4224 child = &(content->u.compatibility.child);
4226 if (child->type != GTK_TOOLBAR_CHILD_SPACE)
4228 gtk_widget_set_child_visible (child->widget, visible);
4232 content->u.compatibility.space_visible = visible;
4233 gtk_widget_queue_draw (GTK_WIDGET (toolbar));
4240 toolbar_content_get_start_allocation (ToolbarContent *content,
4241 GtkAllocation *start_allocation)
4243 switch (content->type)
4246 *start_allocation = content->u.tool_item.start_allocation;
4250 /* Only relevant for new API */
4251 g_assert_not_reached ();
4257 toolbar_content_size_allocate (ToolbarContent *content,
4258 GtkAllocation *allocation)
4260 switch (content->type)
4263 gtk_widget_size_allocate (GTK_WIDGET (content->u.tool_item.item),
4268 if (content->u.compatibility.child.type != GTK_TOOLBAR_CHILD_SPACE)
4270 gtk_widget_size_allocate (content->u.compatibility.child.widget,
4275 content->u.compatibility.space_allocation = *allocation;
4282 toolbar_content_set_state (ToolbarContent *content,
4285 content->state = state;
4289 toolbar_content_get_widget (ToolbarContent *content)
4291 GtkToolbarChild *child;
4293 switch (content->type)
4296 return GTK_WIDGET (content->u.tool_item.item);
4300 child = &(content->u.compatibility.child);
4301 if (child->type != GTK_TOOLBAR_CHILD_SPACE)
4302 return child->widget;
4312 toolbar_content_set_disappearing (ToolbarContent *content,
4313 gboolean disappearing)
4315 switch (content->type)
4318 content->u.tool_item.disappearing = disappearing;
4322 /* Only relevant for new API */
4323 g_assert_not_reached ();
4329 toolbar_content_set_size_request (ToolbarContent *content,
4333 switch (content->type)
4336 gtk_widget_set_size_request (GTK_WIDGET (content->u.tool_item.item),
4341 /* Setting size requests only happens with sliding,
4342 * so not relevant here
4344 g_assert_not_reached ();
4350 toolbar_child_reconfigure (GtkToolbar *toolbar,
4351 GtkToolbarChild *child)
4355 GtkToolbarStyle style;
4356 GtkIconSize icon_size;
4357 GtkReliefStyle relief;
4360 style = gtk_toolbar_get_style (toolbar);
4361 icon_size = gtk_toolbar_get_icon_size (toolbar);
4362 relief = gtk_toolbar_get_relief_style (toolbar);
4365 if (child->type == GTK_TOOLBAR_CHILD_BUTTON ||
4366 child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
4367 child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
4369 box = gtk_bin_get_child (GTK_BIN (child->widget));
4371 if (style == GTK_TOOLBAR_BOTH && GTK_IS_HBOX (box))
4375 vbox = gtk_vbox_new (FALSE, 0);
4378 gtk_widget_reparent (child->label, vbox);
4380 gtk_widget_reparent (child->icon, vbox);
4382 gtk_widget_destroy (box);
4383 gtk_container_add (GTK_CONTAINER (child->widget), vbox);
4385 gtk_widget_show (vbox);
4387 else if (style == GTK_TOOLBAR_BOTH_HORIZ && GTK_IS_VBOX (box))
4391 hbox = gtk_hbox_new (FALSE, 0);
4394 gtk_widget_reparent (child->label, hbox);
4396 gtk_widget_reparent (child->icon, hbox);
4398 gtk_widget_destroy (box);
4399 gtk_container_add (GTK_CONTAINER (child->widget), hbox);
4401 gtk_widget_show (hbox);
4404 set_child_packing_and_visibility (toolbar, child);
4409 if ((child->type == GTK_TOOLBAR_CHILD_BUTTON ||
4410 child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON ||
4411 child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON) &&
4412 GTK_IS_IMAGE (child->icon))
4414 image = GTK_IMAGE (child->icon);
4415 if (gtk_image_get_storage_type (image) == GTK_IMAGE_STOCK)
4417 gtk_image_get_stock (image, &stock_id, NULL);
4418 stock_id = g_strdup (stock_id);
4419 gtk_image_set_from_stock (image,
4427 if (child->type == GTK_TOOLBAR_CHILD_BUTTON ||
4428 child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
4429 child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
4431 gtk_button_set_relief (GTK_BUTTON (child->widget), relief);
4436 toolbar_content_toolbar_reconfigured (ToolbarContent *content,
4437 GtkToolbar *toolbar)
4439 switch (content->type)
4442 _gtk_tool_item_toolbar_reconfigured (content->u.tool_item.item);
4446 toolbar_child_reconfigure (toolbar, &(content->u.compatibility.child));
4452 toolbar_content_retrieve_menu_item (ToolbarContent *content)
4454 if (content->type == TOOL_ITEM)
4455 return gtk_tool_item_retrieve_proxy_menu_item (content->u.tool_item.item);
4457 /* FIXME - we might actually be able to do something meaningful here */
4462 toolbar_content_is_separator (ToolbarContent *content)
4464 GtkToolbarChild *child;
4466 switch (content->type)
4469 return GTK_IS_SEPARATOR_TOOL_ITEM (content->u.tool_item.item);
4473 child = &(content->u.compatibility.child);
4474 return (child->type == GTK_TOOLBAR_CHILD_SPACE);
4482 ignore_show_and_hide_all (ToolbarContent *content)
4484 if (content->type == COMPATIBILITY)
4486 GtkToolbarChildType type = content->u.compatibility.child.type;
4488 if (type == GTK_TOOLBAR_CHILD_BUTTON ||
4489 type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON ||
4490 type == GTK_TOOLBAR_CHILD_RADIOBUTTON)
4500 toolbar_content_show_all (ToolbarContent *content)
4504 if (ignore_show_and_hide_all (content))
4507 widget = toolbar_content_get_widget (content);
4509 gtk_widget_show_all (widget);
4513 toolbar_content_hide_all (ToolbarContent *content)
4517 if (ignore_show_and_hide_all (content))
4520 widget = toolbar_content_get_widget (content);
4522 gtk_widget_hide_all (widget);
4529 get_space_size (GtkToolbar *toolbar)
4531 gint space_size = DEFAULT_SPACE_SIZE;
4535 gtk_widget_style_get (GTK_WIDGET (toolbar),
4536 "space_size", &space_size,
4543 static GtkToolbarSpaceStyle
4544 get_space_style (GtkToolbar *toolbar)
4546 GtkToolbarSpaceStyle space_style = DEFAULT_SPACE_STYLE;
4550 gtk_widget_style_get (GTK_WIDGET (toolbar),
4551 "space_style", &space_style,
4558 static GtkReliefStyle
4559 get_button_relief (GtkToolbar *toolbar)
4561 GtkReliefStyle button_relief = GTK_RELIEF_NORMAL;
4563 gtk_widget_ensure_style (GTK_WIDGET (toolbar));
4565 gtk_widget_style_get (GTK_WIDGET (toolbar),
4566 "button_relief", &button_relief,
4569 return button_relief;
4573 get_internal_padding (GtkToolbar *toolbar)
4577 gtk_widget_style_get (GTK_WIDGET (toolbar),
4578 "internal_padding", &ipadding,
4584 static GtkShadowType
4585 get_shadow_type (GtkToolbar *toolbar)
4587 GtkShadowType shadow_type;
4589 gtk_widget_style_get (GTK_WIDGET (toolbar),
4590 "shadow_type", &shadow_type,
4600 gtk_toolbar_check_old_api (GtkToolbar *toolbar)
4602 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
4604 if (priv->api_mode == NEW_API)
4606 g_warning ("mixing deprecated and non-deprecated GtkToolbar API is not allowed");
4610 priv->api_mode = OLD_API;
4615 gtk_toolbar_check_new_api (GtkToolbar *toolbar)
4617 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
4619 if (priv->api_mode == OLD_API)
4621 g_warning ("mixing deprecated and non-deprecated GtkToolbar API is not allowed");
4625 priv->api_mode = NEW_API;