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"
54 #include "gtkseparatormenuitem.h"
56 typedef struct _ToolbarContent ToolbarContent;
58 #define DEFAULT_IPADDING 0
60 #define DEFAULT_SPACE_SIZE 12
61 #define DEFAULT_SPACE_STYLE GTK_TOOLBAR_SPACE_LINE
62 #define SPACE_LINE_DIVISION 10.0
63 #define SPACE_LINE_START 2.0
64 #define SPACE_LINE_END 8.0
66 #define DEFAULT_ICON_SIZE GTK_ICON_SIZE_LARGE_TOOLBAR
67 #define DEFAULT_TOOLBAR_STYLE GTK_TOOLBAR_BOTH
69 #define MAX_HOMOGENEOUS_N_CHARS 13 /* Items that are wider than this do not participate
70 * in the homogeneous game. In units of
71 * pango_font_get_estimated_char_width().
73 #define SLIDE_SPEED 600 /* How fast the items slide, in pixels per second */
83 /* Child properties */
87 CHILD_PROP_HOMOGENEOUS
119 struct _GtkToolbarPrivate
124 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;
139 guint need_rebuild : 1; /* whether the overflow menu should be regenerated */
142 static void gtk_toolbar_init (GtkToolbar *toolbar);
143 static void gtk_toolbar_class_init (GtkToolbarClass *klass);
144 static void gtk_toolbar_set_property (GObject *object,
148 static void gtk_toolbar_get_property (GObject *object,
152 static gint gtk_toolbar_expose (GtkWidget *widget,
153 GdkEventExpose *event);
154 static void gtk_toolbar_realize (GtkWidget *widget);
155 static void gtk_toolbar_unrealize (GtkWidget *widget);
156 static void gtk_toolbar_size_request (GtkWidget *widget,
157 GtkRequisition *requisition);
158 static void gtk_toolbar_size_allocate (GtkWidget *widget,
159 GtkAllocation *allocation);
160 static void gtk_toolbar_style_set (GtkWidget *widget,
161 GtkStyle *prev_style);
162 static gboolean gtk_toolbar_focus (GtkWidget *widget,
163 GtkDirectionType dir);
164 static void gtk_toolbar_screen_changed (GtkWidget *widget,
165 GdkScreen *previous_screen);
166 static void gtk_toolbar_map (GtkWidget *widget);
167 static void gtk_toolbar_unmap (GtkWidget *widget);
168 static void gtk_toolbar_set_child_property (GtkContainer *container,
173 static void gtk_toolbar_get_child_property (GtkContainer *container,
178 static void gtk_toolbar_finalize (GObject *object);
179 static void gtk_toolbar_show_all (GtkWidget *widget);
180 static void gtk_toolbar_hide_all (GtkWidget *widget);
181 static void gtk_toolbar_add (GtkContainer *container,
183 static void gtk_toolbar_remove (GtkContainer *container,
185 static void gtk_toolbar_forall (GtkContainer *container,
186 gboolean include_internals,
187 GtkCallback callback,
188 gpointer callback_data);
189 static GType gtk_toolbar_child_type (GtkContainer *container);
190 static void gtk_toolbar_orientation_changed (GtkToolbar *toolbar,
191 GtkOrientation orientation);
192 static void gtk_toolbar_real_style_changed (GtkToolbar *toolbar,
193 GtkToolbarStyle style);
194 static gboolean gtk_toolbar_move_focus (GtkToolbar *toolbar,
195 GtkDirectionType dir);
196 static gboolean gtk_toolbar_focus_home_or_end (GtkToolbar *toolbar,
197 gboolean focus_home);
198 static gboolean gtk_toolbar_button_press (GtkWidget *toolbar,
199 GdkEventButton *event);
200 static gboolean gtk_toolbar_arrow_button_press (GtkWidget *button,
201 GdkEventButton *event,
202 GtkToolbar *toolbar);
203 static void gtk_toolbar_arrow_button_clicked (GtkWidget *button,
204 GtkToolbar *toolbar);
205 static void gtk_toolbar_update_button_relief (GtkToolbar *toolbar);
206 static gboolean gtk_toolbar_popup_menu (GtkWidget *toolbar);
207 static GtkWidget *internal_insert_element (GtkToolbar *toolbar,
208 GtkToolbarChildType type,
211 const char *tooltip_text,
212 const char *tooltip_private_text,
214 GtkSignalFunc callback,
218 static void gtk_toolbar_reconfigured (GtkToolbar *toolbar);
219 static gboolean gtk_toolbar_check_new_api (GtkToolbar *toolbar);
220 static gboolean gtk_toolbar_check_old_api (GtkToolbar *toolbar);
222 static GtkReliefStyle get_button_relief (GtkToolbar *toolbar);
223 static gint get_internal_padding (GtkToolbar *toolbar);
224 static GtkShadowType get_shadow_type (GtkToolbar *toolbar);
225 static gint get_space_size (GtkToolbar *toolbar);
226 static GtkToolbarSpaceStyle get_space_style (GtkToolbar *toolbar);
228 /* methods on ToolbarContent 'class' */
229 static ToolbarContent *toolbar_content_new_tool_item (GtkToolbar *toolbar,
231 gboolean is_placeholder,
233 static ToolbarContent *toolbar_content_new_compatibility (GtkToolbar *toolbar,
234 GtkToolbarChildType type,
239 static void toolbar_content_remove (ToolbarContent *content,
240 GtkToolbar *toolbar);
241 static void toolbar_content_free (ToolbarContent *content);
242 static void toolbar_content_expose (ToolbarContent *content,
243 GtkContainer *container,
244 GdkEventExpose *expose);
245 static gboolean toolbar_content_visible (ToolbarContent *content,
246 GtkToolbar *toolbar);
247 static void toolbar_content_size_request (ToolbarContent *content,
249 GtkRequisition *requisition);
250 static gboolean toolbar_content_is_homogeneous (ToolbarContent *content,
251 GtkToolbar *toolbar);
252 static gboolean toolbar_content_is_placeholder (ToolbarContent *content);
253 static gboolean toolbar_content_disappearing (ToolbarContent *content);
254 static ItemState toolbar_content_get_state (ToolbarContent *content);
255 static gboolean toolbar_content_child_visible (ToolbarContent *content);
256 static void toolbar_content_get_goal_allocation (ToolbarContent *content,
257 GtkAllocation *allocation);
258 static void toolbar_content_get_allocation (ToolbarContent *content,
259 GtkAllocation *allocation);
260 static void toolbar_content_set_start_allocation (ToolbarContent *content,
261 GtkAllocation *new_start_allocation);
262 static void toolbar_content_get_start_allocation (ToolbarContent *content,
263 GtkAllocation *start_allocation);
264 static gboolean toolbar_content_get_expand (ToolbarContent *content);
265 static void toolbar_content_set_goal_allocation (ToolbarContent *content,
266 GtkAllocation *allocation);
267 static void toolbar_content_set_child_visible (ToolbarContent *content,
270 static void toolbar_content_size_allocate (ToolbarContent *content,
271 GtkAllocation *allocation);
272 static void toolbar_content_set_state (ToolbarContent *content,
273 ItemState new_state);
274 static GtkWidget * toolbar_content_get_widget (ToolbarContent *content);
275 static void toolbar_content_set_disappearing (ToolbarContent *content,
276 gboolean disappearing);
277 static void toolbar_content_set_size_request (ToolbarContent *content,
280 static void toolbar_content_toolbar_reconfigured (ToolbarContent *content,
281 GtkToolbar *toolbar);
282 static GtkWidget * toolbar_content_retrieve_menu_item (ToolbarContent *content);
283 static gboolean toolbar_content_has_proxy_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->focus = gtk_toolbar_focus;
377 widget_class->screen_changed = gtk_toolbar_screen_changed;
378 widget_class->realize = gtk_toolbar_realize;
379 widget_class->unrealize = gtk_toolbar_unrealize;
380 widget_class->map = gtk_toolbar_map;
381 widget_class->unmap = gtk_toolbar_unmap;
382 widget_class->popup_menu = gtk_toolbar_popup_menu;
383 widget_class->show_all = gtk_toolbar_show_all;
384 widget_class->hide_all = gtk_toolbar_hide_all;
386 container_class->add = gtk_toolbar_add;
387 container_class->remove = gtk_toolbar_remove;
388 container_class->forall = gtk_toolbar_forall;
389 container_class->child_type = gtk_toolbar_child_type;
390 container_class->get_child_property = gtk_toolbar_get_child_property;
391 container_class->set_child_property = gtk_toolbar_set_child_property;
393 klass->orientation_changed = gtk_toolbar_orientation_changed;
394 klass->style_changed = gtk_toolbar_real_style_changed;
397 * GtkToolbar::orientation-changed:
398 * @toolbar: the object which emitted the signal
399 * @orientation: the new #GtkOrientation of the toolbar
401 * Emitted when the orientation of the toolbar changes.
403 toolbar_signals[ORIENTATION_CHANGED] =
404 g_signal_new ("orientation-changed",
405 G_OBJECT_CLASS_TYPE (klass),
407 G_STRUCT_OFFSET (GtkToolbarClass, orientation_changed),
409 g_cclosure_marshal_VOID__ENUM,
411 GTK_TYPE_ORIENTATION);
413 * GtkToolbar::style-changed:
414 * @toolbar: The #GtkToolbar which emitted the signal
415 * @style: the new #GtkToolbarStyle of the toolbar
417 * Emitted when the style of the toolbar changes.
419 toolbar_signals[STYLE_CHANGED] =
420 g_signal_new ("style-changed",
421 G_OBJECT_CLASS_TYPE (klass),
423 G_STRUCT_OFFSET (GtkToolbarClass, style_changed),
425 g_cclosure_marshal_VOID__ENUM,
427 GTK_TYPE_TOOLBAR_STYLE);
429 * GtkToolbar::popup-context-menu:
430 * @toolbar: the #GtkToolbar which emitted the signal
431 * @x: the x coordinate of the point where the menu should appear
432 * @y: the y coordinate of the point where the menu should appear
433 * @button: the mouse button the user pressed, or -1
435 * Emitted when the user right-clicks the toolbar or uses the
436 * keybinding to display a popup menu.
438 * Application developers should handle this signal if they want
439 * to display a context menu on the toolbar. The context-menu should
440 * appear at the coordinates given by @x and @y. The mouse button
441 * number is given by the @button parameter. If the menu was popped
442 * up using the keybaord, @button is -1.
444 * Return value: return %TRUE if the signal was handled, %FALSE if not
446 toolbar_signals[POPUP_CONTEXT_MENU] =
447 g_signal_new ("popup_context_menu",
448 G_OBJECT_CLASS_TYPE (klass),
450 G_STRUCT_OFFSET (GtkToolbarClass, popup_context_menu),
451 _gtk_boolean_handled_accumulator, NULL,
452 _gtk_marshal_BOOLEAN__INT_INT_INT,
454 G_TYPE_INT, G_TYPE_INT,
457 * GtkToolbar::move-focus:
458 * @toolbar: the #GtkToolbar which emitted the signal
459 * @dir: a #GtkDirection
461 * A keybinding signal used internally by GTK+. This signal can't
462 * be used in application code.
464 * Return value: %TRUE if the signal was handled, %FALSE if not
466 toolbar_signals[MOVE_FOCUS] =
467 _gtk_binding_signal_new ("move_focus",
468 G_TYPE_FROM_CLASS (klass),
469 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
470 G_CALLBACK (gtk_toolbar_move_focus),
472 _gtk_marshal_BOOLEAN__ENUM,
474 GTK_TYPE_DIRECTION_TYPE);
476 * GtkToolbar::focus-home-or-end:
477 * @toolbar: the #GtkToolbar which emitted the signal
478 * @focus_home: %TRUE if the first item should be focused
480 * A keybinding signal used internally by GTK+. This signal can't
481 * be used in application code
483 * Return value: %TRUE if the signal was handled, %FALSE if not
485 toolbar_signals[FOCUS_HOME_OR_END] =
486 _gtk_binding_signal_new ("focus_home_or_end",
487 G_OBJECT_CLASS_TYPE (klass),
488 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
489 G_CALLBACK (gtk_toolbar_focus_home_or_end),
491 _gtk_marshal_BOOLEAN__BOOLEAN,
496 g_object_class_install_property (gobject_class,
498 g_param_spec_enum ("orientation",
500 P_("The orientation of the toolbar"),
501 GTK_TYPE_ORIENTATION,
502 GTK_ORIENTATION_HORIZONTAL,
505 g_object_class_install_property (gobject_class,
507 g_param_spec_enum ("toolbar_style",
509 P_("How to draw the toolbar"),
510 GTK_TYPE_TOOLBAR_STYLE,
513 g_object_class_install_property (gobject_class,
515 g_param_spec_boolean ("show_arrow",
517 P_("If an arrow should be shown if the toolbar doesn't fit"),
521 /* child properties */
522 gtk_container_class_install_child_property (container_class,
524 g_param_spec_boolean ("expand",
526 P_("Whether the item should receive extra space when the toolbar grows"),
530 gtk_container_class_install_child_property (container_class,
531 CHILD_PROP_HOMOGENEOUS,
532 g_param_spec_boolean ("homogeneous",
534 P_("Whether the item should be the same size as other homogeneous items"),
538 /* style properties */
539 gtk_widget_class_install_style_property (widget_class,
540 g_param_spec_int ("space_size",
542 P_("Size of spacers"),
548 gtk_widget_class_install_style_property (widget_class,
549 g_param_spec_int ("internal_padding",
550 P_("Internal padding"),
551 P_("Amount of border space between the toolbar shadow and the buttons"),
557 gtk_widget_class_install_style_property (widget_class,
558 g_param_spec_enum ("space_style",
560 P_("Whether spacers are vertical lines or just blank"),
561 GTK_TYPE_TOOLBAR_SPACE_STYLE,
565 gtk_widget_class_install_style_property (widget_class,
566 g_param_spec_enum ("button_relief",
568 P_("Type of bevel around toolbar buttons"),
569 GTK_TYPE_RELIEF_STYLE,
572 gtk_widget_class_install_style_property (widget_class,
573 g_param_spec_enum ("shadow_type",
575 P_("Style of bevel around the toolbar"),
576 GTK_TYPE_SHADOW_TYPE,
580 gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-style",
582 P_("Whether default toolbars have text only, text and icons, icons only, etc."),
583 GTK_TYPE_TOOLBAR_STYLE,
584 DEFAULT_TOOLBAR_STYLE,
587 gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-icon-size",
588 P_("Toolbar icon size"),
589 P_("Size of icons in default toolbars"),
594 binding_set = gtk_binding_set_by_class (klass);
596 add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
597 add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
598 add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
599 add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
601 gtk_binding_entry_add_signal (binding_set, GDK_KP_Home, 0,
602 "focus_home_or_end", 1,
603 G_TYPE_BOOLEAN, TRUE);
604 gtk_binding_entry_add_signal (binding_set, GDK_Home, 0,
605 "focus_home_or_end", 1,
606 G_TYPE_BOOLEAN, TRUE);
607 gtk_binding_entry_add_signal (binding_set, GDK_KP_End, 0,
608 "focus_home_or_end", 1,
609 G_TYPE_BOOLEAN, FALSE);
610 gtk_binding_entry_add_signal (binding_set, GDK_End, 0,
611 "focus_home_or_end", 1,
612 G_TYPE_BOOLEAN, FALSE);
614 add_ctrl_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
615 add_ctrl_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
617 g_type_class_add_private (gobject_class, sizeof (GtkToolbarPrivate));
621 gtk_toolbar_init (GtkToolbar *toolbar)
623 GtkToolbarPrivate *priv;
625 GTK_WIDGET_UNSET_FLAGS (toolbar, GTK_CAN_FOCUS);
626 GTK_WIDGET_SET_FLAGS (toolbar, GTK_NO_WINDOW);
628 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
630 toolbar->orientation = GTK_ORIENTATION_HORIZONTAL;
631 toolbar->style = DEFAULT_TOOLBAR_STYLE;
632 toolbar->icon_size = DEFAULT_ICON_SIZE;
633 toolbar->tooltips = gtk_tooltips_new ();
634 g_object_ref (toolbar->tooltips);
635 gtk_object_sink (GTK_OBJECT (toolbar->tooltips));
637 priv->arrow_button = gtk_toggle_button_new ();
638 g_signal_connect (priv->arrow_button, "button_press_event",
639 G_CALLBACK (gtk_toolbar_arrow_button_press), toolbar);
640 g_signal_connect (priv->arrow_button, "clicked",
641 G_CALLBACK (gtk_toolbar_arrow_button_clicked), toolbar);
642 gtk_button_set_relief (GTK_BUTTON (priv->arrow_button),
643 get_button_relief (toolbar));
645 priv->api_mode = DONT_KNOW;
647 gtk_button_set_focus_on_click (GTK_BUTTON (priv->arrow_button), FALSE);
649 priv->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
650 gtk_widget_set_name (priv->arrow, "gtk-toolbar-arrow");
651 gtk_widget_show (priv->arrow);
652 gtk_container_add (GTK_CONTAINER (priv->arrow_button), priv->arrow);
654 gtk_widget_set_parent (priv->arrow_button, GTK_WIDGET (toolbar));
656 /* which child position a drop will occur at */
658 priv->show_arrow = TRUE;
659 priv->settings = NULL;
661 priv->max_homogeneous_pixels = -1;
663 priv->timer = g_timer_new ();
667 gtk_toolbar_set_property (GObject *object,
672 GtkToolbar *toolbar = GTK_TOOLBAR (object);
676 case PROP_ORIENTATION:
677 gtk_toolbar_set_orientation (toolbar, g_value_get_enum (value));
679 case PROP_TOOLBAR_STYLE:
680 gtk_toolbar_set_style (toolbar, g_value_get_enum (value));
682 case PROP_SHOW_ARROW:
683 gtk_toolbar_set_show_arrow (toolbar, g_value_get_boolean (value));
686 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
692 gtk_toolbar_get_property (GObject *object,
697 GtkToolbar *toolbar = GTK_TOOLBAR (object);
698 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
702 case PROP_ORIENTATION:
703 g_value_set_enum (value, toolbar->orientation);
705 case PROP_TOOLBAR_STYLE:
706 g_value_set_enum (value, toolbar->style);
708 case PROP_SHOW_ARROW:
709 g_value_set_boolean (value, priv->show_arrow);
712 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
718 gtk_toolbar_map (GtkWidget *widget)
720 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
722 GTK_WIDGET_CLASS (parent_class)->map (widget);
724 if (priv->event_window)
725 gdk_window_show_unraised (priv->event_window);
729 gtk_toolbar_unmap (GtkWidget *widget)
731 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
733 if (priv->event_window)
734 gdk_window_hide (priv->event_window);
736 GTK_WIDGET_CLASS (parent_class)->unmap (widget);
740 gtk_toolbar_realize (GtkWidget *widget)
742 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
743 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
745 GdkWindowAttr attributes;
746 gint attributes_mask;
749 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
751 border_width = GTK_CONTAINER (widget)->border_width;
753 attributes.wclass = GDK_INPUT_ONLY;
754 attributes.window_type = GDK_WINDOW_CHILD;
755 attributes.x = widget->allocation.x + border_width;
756 attributes.y = widget->allocation.y + border_width;
757 attributes.width = widget->allocation.width - border_width * 2;
758 attributes.height = widget->allocation.height - border_width * 2;
759 attributes.event_mask = gtk_widget_get_events (widget);
760 attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
761 GDK_BUTTON_RELEASE_MASK |
762 GDK_ENTER_NOTIFY_MASK |
763 GDK_LEAVE_NOTIFY_MASK);
765 attributes_mask = GDK_WA_X | GDK_WA_Y;
767 widget->window = gtk_widget_get_parent_window (widget);
768 g_object_ref (widget->window);
769 widget->style = gtk_style_attach (widget->style, widget->window);
771 priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget),
772 &attributes, attributes_mask);
773 gdk_window_set_user_data (priv->event_window, toolbar);
777 gtk_toolbar_unrealize (GtkWidget *widget)
779 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
781 if (priv->event_window)
783 gdk_window_set_user_data (priv->event_window, NULL);
784 gdk_window_destroy (priv->event_window);
785 priv->event_window = NULL;
788 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
789 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
793 gtk_toolbar_expose (GtkWidget *widget,
794 GdkEventExpose *event)
796 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
797 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
802 border_width = GTK_CONTAINER (widget)->border_width;
804 if (GTK_WIDGET_DRAWABLE (widget))
806 gtk_paint_box (widget->style,
808 GTK_WIDGET_STATE (widget),
809 get_shadow_type (toolbar),
810 &event->area, widget, "toolbar",
811 border_width + widget->allocation.x,
812 border_width + widget->allocation.y,
813 widget->allocation.width - 2 * border_width,
814 widget->allocation.height - 2 * border_width);
817 for (list = priv->content; list != NULL; list = list->next)
819 ToolbarContent *content = list->data;
821 toolbar_content_expose (content, GTK_CONTAINER (widget), event);
824 gtk_container_propagate_expose (GTK_CONTAINER (widget),
832 gtk_toolbar_size_request (GtkWidget *widget,
833 GtkRequisition *requisition)
835 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
836 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
838 gint max_child_height;
839 gint max_child_width;
840 gint max_homogeneous_child_width;
841 gint max_homogeneous_child_height;
842 gint homogeneous_size;
844 gint pack_front_size;
846 GtkRequisition arrow_requisition;
848 max_homogeneous_child_width = 0;
849 max_homogeneous_child_height = 0;
851 max_child_height = 0;
852 for (list = priv->content; list != NULL; list = list->next)
854 GtkRequisition requisition;
855 ToolbarContent *content = list->data;
857 if (!toolbar_content_visible (content, toolbar))
860 toolbar_content_size_request (content, toolbar, &requisition);
862 max_child_width = MAX (max_child_width, requisition.width);
863 max_child_height = MAX (max_child_height, requisition.height);
865 if (toolbar_content_is_homogeneous (content, toolbar))
867 max_homogeneous_child_width = MAX (max_homogeneous_child_width, requisition.width);
868 max_homogeneous_child_height = MAX (max_homogeneous_child_height, requisition.height);
872 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
873 homogeneous_size = max_homogeneous_child_width;
875 homogeneous_size = max_homogeneous_child_height;
878 for (list = priv->content; list != NULL; list = list->next)
880 ToolbarContent *content = list->data;
883 if (!toolbar_content_visible (content, toolbar))
886 if (toolbar_content_is_homogeneous (content, toolbar))
888 size = homogeneous_size;
892 GtkRequisition requisition;
894 toolbar_content_size_request (content, toolbar, &requisition);
896 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
897 size = requisition.width;
899 size = requisition.height;
902 pack_front_size += size;
905 if (priv->show_arrow && priv->api_mode == NEW_API)
907 gtk_widget_size_request (priv->arrow_button, &arrow_requisition);
909 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
910 long_req = arrow_requisition.width;
912 long_req = arrow_requisition.height;
914 /* There is no point requesting space for the arrow if that would take
915 * up more space than all the items combined
917 long_req = MIN (long_req, pack_front_size);
921 arrow_requisition.height = 0;
922 arrow_requisition.width = 0;
924 long_req = pack_front_size;
927 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
929 requisition->width = long_req;
930 requisition->height = MAX (max_child_height, arrow_requisition.height);
934 requisition->height = long_req;
935 requisition->width = MAX (max_child_width, arrow_requisition.width);
939 ipadding = get_internal_padding (toolbar);
941 requisition->width += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width);
942 requisition->height += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width);
944 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
946 requisition->width += 2 * widget->style->xthickness;
947 requisition->height += 2 * widget->style->ythickness;
950 toolbar->button_maxw = max_homogeneous_child_width;
951 toolbar->button_maxh = max_homogeneous_child_height;
955 position (gint from, gint to, gdouble elapsed)
958 return MIN (from + SLIDE_SPEED * elapsed, to);
960 return MAX (from - SLIDE_SPEED * elapsed, to);
964 compute_intermediate_allocation (GtkToolbar *toolbar,
965 const GtkAllocation *start,
966 const GtkAllocation *goal,
967 GtkAllocation *intermediate)
969 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
970 gdouble elapsed = g_timer_elapsed (priv->timer, NULL);
972 intermediate->x = position (start->x, goal->x, elapsed);
973 intermediate->y = position (start->y, goal->y, elapsed);
974 intermediate->width =
975 position (start->x + start->width, goal->x + goal->width, elapsed) - intermediate->x;
976 intermediate->height =
977 position (start->y + start->height, goal->y + goal->height, elapsed) - intermediate->y;
981 fixup_allocation_for_rtl (gint total_size,
982 GtkAllocation *allocation)
984 allocation->x += (total_size - (2 * allocation->x + allocation->width));
988 fixup_allocation_for_vertical (GtkAllocation *allocation)
993 allocation->x = allocation->y;
996 tmp = allocation->width;
997 allocation->width = allocation->height;
998 allocation->height = tmp;
1002 get_item_size (GtkToolbar *toolbar,
1003 ToolbarContent *content)
1005 GtkRequisition requisition;
1007 toolbar_content_size_request (content, toolbar, &requisition);
1009 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1011 if (toolbar_content_is_homogeneous (content, toolbar))
1012 return toolbar->button_maxw;
1014 return requisition.width;
1018 if (toolbar_content_is_homogeneous (content, toolbar))
1019 return toolbar->button_maxh;
1021 return requisition.height;
1026 slide_idle_handler (gpointer data)
1028 GtkToolbar *toolbar = data;
1029 GtkToolbarPrivate *priv;
1032 GDK_THREADS_ENTER ();
1034 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1036 if (priv->need_sync)
1039 priv->need_sync = FALSE;
1042 for (list = priv->content; list != NULL; list = list->next)
1044 ToolbarContent *content = list->data;
1046 GtkAllocation goal_allocation;
1047 GtkAllocation allocation;
1050 state = toolbar_content_get_state (content);
1051 toolbar_content_get_goal_allocation (content, &goal_allocation);
1052 toolbar_content_get_allocation (content, &allocation);
1056 if (state == NOT_ALLOCATED)
1058 /* an unallocated item means that size allocate has to
1059 * called at least once more
1064 /* An invisible item with a goal allocation of
1065 * 0 is already at its goal.
1067 if ((state == NORMAL || state == OVERFLOWN) &&
1068 ((goal_allocation.width != 0 &&
1069 goal_allocation.height != 0) ||
1070 toolbar_content_child_visible (content)))
1072 if ((goal_allocation.x != allocation.x ||
1073 goal_allocation.y != allocation.y ||
1074 goal_allocation.width != allocation.width ||
1075 goal_allocation.height != allocation.height))
1077 /* An item is not in its right position yet. Note
1078 * that OVERFLOWN items do get an allocation in
1079 * gtk_toolbar_size_allocate(). This way you can see
1080 * them slide back in when you drag an item off the
1087 if (toolbar_content_is_placeholder (content) &&
1088 toolbar_content_disappearing (content) &&
1089 toolbar_content_child_visible (content))
1091 /* A disappearing placeholder is still visible.
1099 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (toolbar));
1101 GDK_THREADS_LEAVE ();
1106 priv->is_sliding = FALSE;
1109 GDK_THREADS_LEAVE();
1114 rect_within (GtkAllocation *a1,
1117 return (a1->x >= a2->x &&
1118 a1->x + a1->width <= a2->x + a2->width &&
1120 a1->y + a1->height <= a2->y + a2->height);
1124 gtk_toolbar_begin_sliding (GtkToolbar *toolbar)
1126 GtkWidget *widget = GTK_WIDGET (toolbar);
1127 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1135 /* Start the sliding. This function copies the allocation of every
1136 * item into content->start_allocation. For items that haven't
1137 * been allocated yet, we calculate their position and save that
1138 * in start_allocatino along with zero width and zero height.
1140 * FIXME: It would be nice if we could share this code with
1141 * the equivalent in gtk_widget_size_allocate().
1143 priv->is_sliding = TRUE;
1146 priv->idle_id = g_idle_add (slide_idle_handler, toolbar);
1148 rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
1149 vertical = (toolbar->orientation == GTK_ORIENTATION_VERTICAL);
1150 border_width = get_internal_padding (toolbar) + GTK_CONTAINER (toolbar)->border_width;
1154 cur_x = widget->allocation.width - border_width - widget->style->xthickness;
1155 cur_y = widget->allocation.height - border_width - widget->style->ythickness;
1159 cur_x = border_width + widget->style->xthickness;
1160 cur_y = border_width + widget->style->ythickness;
1163 cur_x += widget->allocation.x;
1164 cur_y += widget->allocation.y;
1166 for (list = priv->content; list != NULL; list = list->next)
1168 ToolbarContent *content = list->data;
1169 GtkAllocation new_start_allocation;
1170 GtkAllocation item_allocation;
1173 state = toolbar_content_get_state (content);
1174 toolbar_content_get_allocation (content, &item_allocation);
1176 if ((state == NORMAL &&
1177 rect_within (&item_allocation, &(widget->allocation))) ||
1180 new_start_allocation = item_allocation;
1184 new_start_allocation.x = cur_x;
1185 new_start_allocation.y = cur_y;
1189 new_start_allocation.width = widget->allocation.width -
1190 2 * border_width - 2 * widget->style->xthickness;
1191 new_start_allocation.height = 0;
1195 new_start_allocation.width = 0;
1196 new_start_allocation.height = widget->allocation.height -
1197 2 * border_width - 2 * widget->style->ythickness;
1202 cur_y = new_start_allocation.y + new_start_allocation.height;
1204 cur_x = new_start_allocation.x;
1206 cur_x = new_start_allocation.x + new_start_allocation.width;
1208 toolbar_content_set_start_allocation (content, &new_start_allocation);
1211 /* This resize will run before the first idle handler. This
1212 * will make sure that items get the right goal allocatiuon
1213 * so that the idle handler will not immediately return
1216 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (toolbar));
1217 g_timer_reset (priv->timer);
1221 gtk_toolbar_stop_sliding (GtkToolbar *toolbar)
1223 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1225 if (priv->is_sliding)
1229 priv->is_sliding = FALSE;
1233 g_source_remove (priv->idle_id);
1237 list = priv->content;
1240 ToolbarContent *content = list->data;
1243 if (toolbar_content_is_placeholder (content))
1245 toolbar_content_remove (content, toolbar);
1246 toolbar_content_free (content);
1250 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (toolbar));
1255 remove_item (GtkWidget *menu_item,
1258 gtk_container_remove (GTK_CONTAINER (menu_item->parent), menu_item);
1262 menu_deactivated (GtkWidget *menu,
1263 GtkToolbar *toolbar)
1265 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1266 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->arrow_button), FALSE);
1270 menu_detached (GtkWidget *toolbar,
1273 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1278 rebuild_menu (GtkToolbar *toolbar)
1280 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1281 GList *list, *children;
1285 priv->menu = GTK_MENU (gtk_menu_new());
1286 gtk_menu_attach_to_widget (priv->menu,
1287 GTK_WIDGET (toolbar),
1290 g_signal_connect (priv->menu, "deactivate", G_CALLBACK (menu_deactivated), toolbar);
1293 gtk_container_foreach (GTK_CONTAINER (priv->menu), remove_item, NULL);
1295 for (list = priv->content; list != NULL; list = list->next)
1297 ToolbarContent *content = list->data;
1299 if (toolbar_content_get_state (content) == OVERFLOWN &&
1300 !toolbar_content_is_placeholder (content))
1302 GtkWidget *menu_item = toolbar_content_retrieve_menu_item (content);
1306 g_assert (GTK_IS_MENU_ITEM (menu_item));
1307 gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), menu_item);
1312 /* Remove leading and trailing separator items */
1313 children = gtk_container_get_children (GTK_CONTAINER (priv->menu));
1316 while (list && GTK_IS_SEPARATOR_MENU_ITEM (list->data))
1318 GtkWidget *child = list->data;
1320 gtk_container_remove (GTK_CONTAINER (priv->menu), child);
1323 g_list_free (children);
1325 /* Regenerate the list of children so we don't try to remove items twice */
1326 children = gtk_container_get_children (GTK_CONTAINER (priv->menu));
1328 list = g_list_last (children);
1329 while (list && GTK_IS_SEPARATOR_MENU_ITEM (list->data))
1331 GtkWidget *child = list->data;
1333 gtk_container_remove (GTK_CONTAINER (priv->menu), child);
1336 g_list_free (children);
1338 priv->need_rebuild = FALSE;
1342 gtk_toolbar_size_allocate (GtkWidget *widget,
1343 GtkAllocation *allocation)
1345 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1346 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1347 GtkAllocation *allocations;
1348 ItemState *new_states;
1349 GtkAllocation arrow_allocation;
1351 gint size, pos, short_size;
1354 gboolean need_arrow;
1355 gint n_expand_items;
1357 gint available_size;
1360 GtkRequisition arrow_requisition;
1361 gboolean overflowing;
1362 gboolean size_changed;
1364 GtkAllocation item_area;
1366 size_changed = FALSE;
1367 if (widget->allocation.x != allocation->x ||
1368 widget->allocation.y != allocation->y ||
1369 widget->allocation.width != allocation->width ||
1370 widget->allocation.height != allocation->height)
1372 size_changed = TRUE;
1376 gtk_toolbar_stop_sliding (toolbar);
1378 widget->allocation = *allocation;
1380 border_width = GTK_CONTAINER (toolbar)->border_width;
1382 if (GTK_WIDGET_REALIZED (widget))
1384 gdk_window_move_resize (priv->event_window,
1385 allocation->x + border_width,
1386 allocation->y + border_width,
1387 allocation->width - border_width * 2,
1388 allocation->height - border_width * 2);
1391 border_width += get_internal_padding (toolbar);
1393 gtk_widget_get_child_requisition (GTK_WIDGET (priv->arrow_button),
1394 &arrow_requisition);
1396 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1398 available_size = size = allocation->width - 2 * border_width;
1399 short_size = allocation->height - 2 * border_width;
1400 arrow_size = arrow_requisition.width;
1402 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1404 available_size -= 2 * widget->style->xthickness;
1405 short_size -= 2 * widget->style->ythickness;
1410 available_size = size = allocation->height - 2 * border_width;
1411 short_size = allocation->width - 2 * border_width;
1412 arrow_size = arrow_requisition.height;
1414 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1416 available_size -= 2 * widget->style->ythickness;
1417 short_size -= 2 * widget->style->xthickness;
1421 n_items = g_list_length (priv->content);
1422 allocations = g_new0 (GtkAllocation, n_items);
1423 new_states = g_new0 (ItemState, n_items);
1427 for (list = priv->content; list != NULL; list = list->next)
1429 ToolbarContent *content = list->data;
1431 if (toolbar_content_visible (content, toolbar))
1433 needed_size += get_item_size (toolbar, content);
1435 /* Do we need an arrow?
1437 * Assume we don't, and see if any non-separator item with a
1438 * proxy menu item is then going to overflow.
1440 if (needed_size > available_size &&
1443 priv->api_mode == NEW_API &&
1444 toolbar_content_has_proxy_menu_item (content) &&
1445 !toolbar_content_is_separator (content))
1453 size = available_size - arrow_size;
1455 size = available_size;
1457 /* calculate widths of items */
1458 overflowing = FALSE;
1459 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1461 ToolbarContent *content = list->data;
1464 if (!toolbar_content_visible (content, toolbar))
1466 new_states[i] = HIDDEN;
1470 item_size = get_item_size (toolbar, content);
1471 if (item_size <= size && !overflowing)
1474 allocations[i].width = item_size;
1475 new_states[i] = NORMAL;
1480 new_states[i] = OVERFLOWN;
1481 allocations[i].width = item_size;
1485 /* calculate width of arrow */
1488 arrow_allocation.width = arrow_size;
1489 arrow_allocation.height = short_size;
1492 /* expand expandable items */
1494 /* We don't expand when there is an overflow menu, because that leads to
1495 * weird jumps when items get moved to the overflow menu and the expanding
1496 * items suddenly get a lot of extra space
1501 for (i = 0, list = priv->content; list != NULL; list = list->next, ++i)
1503 ToolbarContent *content = list->data;
1505 if (toolbar_content_get_expand (content) && new_states[i] == NORMAL)
1509 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1511 ToolbarContent *content = list->data;
1513 if (toolbar_content_get_expand (content) && new_states[i] == NORMAL)
1515 gint extra = size / n_expand_items;
1516 if (size % n_expand_items != 0)
1519 allocations[i].width += extra;
1525 g_assert (n_expand_items == 0);
1528 /* position items */
1530 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1532 /* both NORMAL and OVERFLOWN items get a position. This ensures
1533 * that sliding will work for OVERFLOWN items too
1535 if (new_states[i] == NORMAL ||
1536 new_states[i] == OVERFLOWN)
1538 allocations[i].x = pos;
1539 allocations[i].y = border_width;
1540 allocations[i].height = short_size;
1542 pos += allocations[i].width;
1546 /* position arrow */
1549 arrow_allocation.x = available_size - border_width - arrow_allocation.width;
1550 arrow_allocation.y = border_width;
1553 item_area.x = border_width;
1554 item_area.y = border_width;
1555 item_area.width = available_size - (need_arrow? arrow_size : 0);
1556 item_area.height = short_size;
1558 /* fix up allocations in the vertical or RTL cases */
1559 if (toolbar->orientation == GTK_ORIENTATION_VERTICAL)
1561 for (i = 0; i < n_items; ++i)
1562 fixup_allocation_for_vertical (&(allocations[i]));
1565 fixup_allocation_for_vertical (&arrow_allocation);
1567 fixup_allocation_for_vertical (&item_area);
1569 else if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
1571 for (i = 0; i < n_items; ++i)
1572 fixup_allocation_for_rtl (available_size, &(allocations[i]));
1575 fixup_allocation_for_rtl (available_size, &arrow_allocation);
1577 fixup_allocation_for_rtl (available_size, &item_area);
1580 /* translate the items by allocation->(x,y) */
1581 for (i = 0; i < n_items; ++i)
1583 allocations[i].x += allocation->x;
1584 allocations[i].y += allocation->y;
1586 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1588 allocations[i].x += widget->style->xthickness;
1589 allocations[i].y += widget->style->ythickness;
1595 arrow_allocation.x += allocation->x;
1596 arrow_allocation.y += allocation->y;
1598 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1600 arrow_allocation.x += widget->style->xthickness;
1601 arrow_allocation.y += widget->style->ythickness;
1605 item_area.x += allocation->x;
1606 item_area.y += allocation->y;
1607 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1609 item_area.x += widget->style->xthickness;
1610 item_area.y += widget->style->ythickness;
1613 /* did anything change? */
1614 for (list = priv->content, i = 0; list != NULL; list = list->next, i++)
1616 ToolbarContent *content = list->data;
1618 if (toolbar_content_get_state (content) == NORMAL &&
1619 new_states[i] != NORMAL)
1621 /* an item disappeared and we didn't change size, so begin sliding */
1622 if (!size_changed && priv->api_mode == NEW_API)
1623 gtk_toolbar_begin_sliding (toolbar);
1627 /* finally allocate the items */
1628 if (priv->is_sliding)
1630 for (list = priv->content, i = 0; list != NULL; list = list->next, i++)
1632 ToolbarContent *content = list->data;
1634 toolbar_content_set_goal_allocation (content, &(allocations[i]));
1638 elapsed = g_timer_elapsed (priv->timer, NULL);
1639 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1641 ToolbarContent *content = list->data;
1643 if (new_states[i] == OVERFLOWN ||
1644 new_states[i] == NORMAL)
1646 GtkAllocation alloc;
1647 GtkAllocation start_allocation;
1648 GtkAllocation goal_allocation;
1650 if (priv->is_sliding)
1652 toolbar_content_get_start_allocation (content, &start_allocation);
1653 toolbar_content_get_goal_allocation (content, &goal_allocation);
1655 compute_intermediate_allocation (toolbar,
1660 priv->need_sync = TRUE;
1664 alloc = allocations[i];
1667 if (alloc.width == 0 || alloc.height == 0)
1669 toolbar_content_set_child_visible (content, toolbar, FALSE);
1673 if (!rect_within (&alloc, &item_area))
1675 toolbar_content_set_child_visible (content, toolbar, FALSE);
1676 toolbar_content_size_allocate (content, &alloc);
1680 toolbar_content_set_child_visible (content, toolbar, TRUE);
1681 toolbar_content_size_allocate (content, &alloc);
1687 toolbar_content_set_child_visible (content, toolbar, FALSE);
1690 toolbar_content_set_state (content, new_states[i]);
1693 if (priv->menu && priv->need_rebuild)
1694 rebuild_menu (toolbar);
1698 gtk_widget_size_allocate (GTK_WIDGET (priv->arrow_button),
1700 gtk_widget_show (GTK_WIDGET (priv->arrow_button));
1704 gtk_widget_hide (GTK_WIDGET (priv->arrow_button));
1706 if (priv->menu && GTK_WIDGET_VISIBLE (priv->menu))
1707 gtk_menu_shell_deactivate (GTK_MENU_SHELL (priv->menu));
1710 g_free (allocations);
1711 g_free (new_states);
1715 gtk_toolbar_update_button_relief (GtkToolbar *toolbar)
1717 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1719 gtk_toolbar_reconfigured (toolbar);
1721 gtk_button_set_relief (GTK_BUTTON (priv->arrow_button), get_button_relief (toolbar));
1725 gtk_toolbar_style_set (GtkWidget *widget,
1726 GtkStyle *prev_style)
1728 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
1730 priv->max_homogeneous_pixels = -1;
1732 if (GTK_WIDGET_REALIZED (widget))
1733 gtk_style_set_background (widget->style, widget->window, widget->state);
1736 gtk_toolbar_update_button_relief (GTK_TOOLBAR (widget));
1740 gtk_toolbar_list_children_in_focus_order (GtkToolbar *toolbar,
1741 GtkDirectionType dir)
1743 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1744 GList *result = NULL;
1748 /* generate list of children in reverse logical order */
1750 for (list = priv->content; list != NULL; list = list->next)
1752 ToolbarContent *content = list->data;
1755 widget = toolbar_content_get_widget (content);
1758 result = g_list_prepend (result, widget);
1761 result = g_list_prepend (result, priv->arrow_button);
1763 rtl = (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL);
1765 /* move in logical order when
1767 * - dir is TAB_FORWARD
1769 * - in RTL mode and moving left or up
1771 * - in LTR mode and moving right or down
1773 if (dir == GTK_DIR_TAB_FORWARD ||
1774 (rtl && (dir == GTK_DIR_UP || dir == GTK_DIR_LEFT)) ||
1775 (!rtl && (dir == GTK_DIR_DOWN || dir == GTK_DIR_RIGHT)))
1777 result = g_list_reverse (result);
1784 gtk_toolbar_focus_home_or_end (GtkToolbar *toolbar,
1785 gboolean focus_home)
1787 GList *children, *list;
1788 GtkDirectionType dir = focus_home? GTK_DIR_RIGHT : GTK_DIR_LEFT;
1790 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1792 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
1794 children = g_list_reverse (children);
1796 dir = (dir == GTK_DIR_RIGHT)? GTK_DIR_LEFT : GTK_DIR_RIGHT;
1799 for (list = children; list != NULL; list = list->next)
1801 GtkWidget *child = list->data;
1803 if (GTK_CONTAINER (toolbar)->focus_child == child)
1806 if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1810 g_list_free (children);
1815 /* Keybinding handler. This function is called when the user presses
1816 * Ctrl TAB or an arrow key.
1819 gtk_toolbar_move_focus (GtkToolbar *toolbar,
1820 GtkDirectionType dir)
1823 gboolean try_focus = FALSE;
1825 GtkContainer *container = GTK_CONTAINER (toolbar);
1827 if (container->focus_child &&
1828 gtk_widget_child_focus (container->focus_child, dir))
1833 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1835 for (list = children; list != NULL; list = list->next)
1837 GtkWidget *child = list->data;
1839 if (try_focus && GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1842 if (child == GTK_CONTAINER (toolbar)->focus_child)
1846 g_list_free (children);
1851 /* The focus handler for the toolbar. It called when the user presses
1852 * TAB or otherwise tries to focus the toolbar.
1855 gtk_toolbar_focus (GtkWidget *widget,
1856 GtkDirectionType dir)
1858 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1859 GList *children, *list;
1860 gboolean result = FALSE;
1862 /* if focus is already somewhere inside the toolbar then return FALSE.
1863 * The only way focus can stay inside the toolbar is when the user presses
1864 * arrow keys or Ctrl TAB (both of which are handled by the
1865 * gtk_toolbar_move_focus() keybinding function.
1867 if (GTK_CONTAINER (widget)->focus_child)
1870 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1872 for (list = children; list != NULL; list = list->next)
1874 GtkWidget *child = list->data;
1876 if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1883 g_list_free (children);
1889 style_change_notify (GtkToolbar *toolbar)
1891 if (!toolbar->style_set)
1893 /* pretend it was set, then unset, thus reverting to new default */
1894 toolbar->style_set = TRUE;
1895 gtk_toolbar_unset_style (toolbar);
1900 icon_size_change_notify (GtkToolbar *toolbar)
1902 if (!toolbar->icon_size_set)
1904 /* pretend it was set, then unset, thus reverting to new default */
1905 toolbar->icon_size_set = TRUE;
1906 gtk_toolbar_unset_icon_size (toolbar);
1910 static GtkSettings *
1911 toolbar_get_settings (GtkToolbar *toolbar)
1913 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1914 return priv->settings;
1918 gtk_toolbar_screen_changed (GtkWidget *widget,
1919 GdkScreen *previous_screen)
1921 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
1922 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1923 GtkSettings *old_settings = toolbar_get_settings (toolbar);
1924 GtkSettings *settings;
1926 if (gtk_widget_has_screen (GTK_WIDGET (toolbar)))
1927 settings = gtk_widget_get_settings (GTK_WIDGET (toolbar));
1931 if (settings == old_settings)
1936 g_signal_handler_disconnect (old_settings, toolbar->style_set_connection);
1937 g_signal_handler_disconnect (old_settings, toolbar->icon_size_connection);
1939 g_object_unref (old_settings);
1944 toolbar->style_set_connection =
1945 g_signal_connect_swapped (settings,
1946 "notify::gtk-toolbar-style",
1947 G_CALLBACK (style_change_notify),
1949 toolbar->icon_size_connection =
1950 g_signal_connect_swapped (settings,
1951 "notify::gtk-toolbar-icon-size",
1952 G_CALLBACK (icon_size_change_notify),
1955 g_object_ref (settings);
1956 priv->settings = settings;
1959 priv->settings = NULL;
1961 style_change_notify (toolbar);
1962 icon_size_change_notify (toolbar);
1966 find_drop_index (GtkToolbar *toolbar,
1970 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1971 GList *interesting_content;
1973 GtkOrientation orientation;
1974 GtkTextDirection direction;
1975 gint best_distance = G_MAXINT;
1979 ToolbarContent *best_content;
1980 GtkAllocation allocation;
1982 /* list items we care about wrt. drag and drop */
1983 interesting_content = NULL;
1984 for (list = priv->content; list != NULL; list = list->next)
1986 ToolbarContent *content = list->data;
1988 if (toolbar_content_get_state (content) == NORMAL)
1989 interesting_content = g_list_prepend (interesting_content, content);
1991 interesting_content = g_list_reverse (interesting_content);
1993 if (!interesting_content)
1996 orientation = toolbar->orientation;
1997 direction = gtk_widget_get_direction (GTK_WIDGET (toolbar));
1999 /* distance to first interesting item */
2000 best_content = interesting_content->data;
2001 toolbar_content_get_allocation (best_content, &allocation);
2003 if (orientation == GTK_ORIENTATION_HORIZONTAL)
2007 if (direction == GTK_TEXT_DIR_LTR)
2010 pos = allocation.x + allocation.width;
2018 best_content = NULL;
2019 best_distance = ABS (pos - cursor);
2021 /* distance to far end of each item */
2022 for (list = interesting_content; list != NULL; list = list->next)
2024 ToolbarContent *content = list->data;
2026 toolbar_content_get_allocation (content, &allocation);
2028 if (orientation == GTK_ORIENTATION_HORIZONTAL)
2030 if (direction == GTK_TEXT_DIR_LTR)
2031 pos = allocation.x + allocation.width;
2037 pos = allocation.y + allocation.height;
2040 distance = ABS (pos - cursor);
2042 if (distance < best_distance)
2044 best_distance = distance;
2045 best_content = content;
2049 g_list_free (interesting_content);
2054 return g_list_index (priv->content, best_content) + 1;
2058 reset_all_placeholders (GtkToolbar *toolbar)
2060 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2063 for (list = priv->content; list != NULL; list = list->next)
2065 ToolbarContent *content = list->data;
2066 if (toolbar_content_is_placeholder (content))
2067 toolbar_content_set_disappearing (content, TRUE);
2072 physical_to_logical (GtkToolbar *toolbar,
2075 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2079 g_assert (physical >= 0);
2082 for (list = priv->content; list && physical > 0; list = list->next)
2084 ToolbarContent *content = list->data;
2086 if (!toolbar_content_is_placeholder (content))
2091 g_assert (physical == 0);
2097 logical_to_physical (GtkToolbar *toolbar,
2100 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2104 g_assert (logical >= 0);
2107 for (list = priv->content; list; list = list->next)
2109 ToolbarContent *content = list->data;
2111 if (!toolbar_content_is_placeholder (content))
2121 g_assert (logical == 0);
2127 * gtk_toolbar_set_drop_highlight_item:
2128 * @toolbar: a #GtkToolbar
2129 * @tool_item: a #GtkToolItem, or %NULL to turn of highlighting
2130 * @index_: a position on @toolbar
2132 * Highlights @toolbar to give an idea of what it would look like
2133 * if @item was added to @toolbar at the position indicated by @index_.
2134 * If @item is %NULL, highlighting is turned off. In that case @index_
2137 * The @tool_item passed to this function must not be part of any widget
2138 * hierarchy. When an item is set as drop highlight item it can not
2139 * added to any widget hierarchy or used as highlight item for another
2145 gtk_toolbar_set_drop_highlight_item (GtkToolbar *toolbar,
2146 GtkToolItem *tool_item,
2149 ToolbarContent *content;
2150 GtkToolbarPrivate *priv;
2152 GtkRequisition requisition;
2153 GtkRequisition old_requisition;
2154 gboolean restart_sliding;
2156 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2157 g_return_if_fail (tool_item == NULL || GTK_IS_TOOL_ITEM (tool_item));
2159 gtk_toolbar_check_new_api (toolbar);
2161 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2165 if (priv->highlight_tool_item)
2167 gtk_widget_unparent (GTK_WIDGET (priv->highlight_tool_item));
2168 g_object_unref (priv->highlight_tool_item);
2169 priv->highlight_tool_item = NULL;
2172 reset_all_placeholders (toolbar);
2173 gtk_toolbar_begin_sliding (toolbar);
2177 n_items = gtk_toolbar_get_n_items (toolbar);
2178 if (index_ < 0 || index_ > n_items)
2181 if (tool_item != priv->highlight_tool_item)
2183 if (priv->highlight_tool_item)
2184 g_object_unref (priv->highlight_tool_item);
2186 g_object_ref (tool_item);
2187 gtk_object_sink (GTK_OBJECT (tool_item));
2189 priv->highlight_tool_item = tool_item;
2191 gtk_widget_set_parent (GTK_WIDGET (priv->highlight_tool_item),
2192 GTK_WIDGET (toolbar));
2195 index_ = logical_to_physical (toolbar, index_);
2197 content = g_list_nth_data (priv->content, index_);
2201 ToolbarContent *prev_content;
2203 prev_content = g_list_nth_data (priv->content, index_ - 1);
2205 if (prev_content && toolbar_content_is_placeholder (prev_content))
2206 content = prev_content;
2209 if (!content || !toolbar_content_is_placeholder (content))
2211 GtkWidget *placeholder;
2213 placeholder = GTK_WIDGET (gtk_separator_tool_item_new ());
2215 content = toolbar_content_new_tool_item (toolbar,
2216 GTK_TOOL_ITEM (placeholder),
2218 gtk_widget_show (placeholder);
2222 g_assert (toolbar_content_is_placeholder (content));
2224 gtk_widget_size_request (GTK_WIDGET (priv->highlight_tool_item),
2228 restart_sliding = FALSE;
2229 toolbar_content_size_request (content, toolbar, &old_requisition);
2230 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
2232 requisition.height = -1;
2233 if (requisition.width != old_requisition.width)
2234 restart_sliding = TRUE;
2238 requisition.width = -1;
2239 if (requisition.height != old_requisition.height)
2240 restart_sliding = TRUE;
2243 if (toolbar_content_disappearing (content))
2244 restart_sliding = TRUE;
2246 reset_all_placeholders (toolbar);
2247 toolbar_content_set_disappearing (content, FALSE);
2249 toolbar_content_set_size_request (content,
2250 requisition.width, requisition.height);
2252 if (restart_sliding)
2253 gtk_toolbar_begin_sliding (toolbar);
2257 gtk_toolbar_get_child_property (GtkContainer *container,
2263 GtkToolItem *item = GTK_TOOL_ITEM (child);
2265 switch (property_id)
2267 case CHILD_PROP_HOMOGENEOUS:
2268 g_value_set_boolean (value, gtk_tool_item_get_homogeneous (item));
2271 case CHILD_PROP_EXPAND:
2272 g_value_set_boolean (value, gtk_tool_item_get_expand (item));
2276 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
2282 gtk_toolbar_set_child_property (GtkContainer *container,
2285 const GValue *value,
2288 switch (property_id)
2290 case CHILD_PROP_HOMOGENEOUS:
2291 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
2294 case CHILD_PROP_EXPAND:
2295 gtk_tool_item_set_expand (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
2299 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
2305 gtk_toolbar_show_all (GtkWidget *widget)
2307 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
2310 for (list = priv->content; list != NULL; list = list->next)
2312 ToolbarContent *content = list->data;
2314 toolbar_content_show_all (content);
2317 gtk_widget_show (widget);
2321 gtk_toolbar_hide_all (GtkWidget *widget)
2323 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
2326 for (list = priv->content; list != NULL; list = list->next)
2328 ToolbarContent *content = list->data;
2330 toolbar_content_hide_all (content);
2333 gtk_widget_hide (widget);
2337 gtk_toolbar_add (GtkContainer *container,
2340 GtkToolbar *toolbar;
2342 g_return_if_fail (GTK_IS_TOOLBAR (container));
2343 g_return_if_fail (widget != NULL);
2345 toolbar = GTK_TOOLBAR (container);
2347 if (GTK_IS_TOOL_ITEM (widget))
2348 gtk_toolbar_insert (toolbar, GTK_TOOL_ITEM (widget), -1);
2350 gtk_toolbar_append_widget (toolbar, widget, NULL, NULL);
2354 gtk_toolbar_remove (GtkContainer *container,
2357 GtkToolbar *toolbar;
2358 GtkToolbarPrivate *priv;
2359 ToolbarContent *content_to_remove;
2362 g_return_if_fail (GTK_IS_TOOLBAR (container));
2363 g_return_if_fail (GTK_IS_WIDGET (widget));
2365 toolbar = GTK_TOOLBAR (container);
2366 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2368 content_to_remove = NULL;
2369 for (list = priv->content; list != NULL; list = list->next)
2371 ToolbarContent *content = list->data;
2374 child = toolbar_content_get_widget (content);
2375 if (child && child == widget)
2377 content_to_remove = content;
2382 g_return_if_fail (content_to_remove != NULL);
2384 toolbar_content_remove (content_to_remove, toolbar);
2385 toolbar_content_free (content_to_remove);
2389 gtk_toolbar_forall (GtkContainer *container,
2390 gboolean include_internals,
2391 GtkCallback callback,
2392 gpointer callback_data)
2394 GtkToolbar *toolbar = GTK_TOOLBAR (container);
2395 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2398 g_return_if_fail (callback != NULL);
2400 list = priv->content;
2403 ToolbarContent *content = list->data;
2404 GList *next = list->next;
2406 if (include_internals || !toolbar_content_is_placeholder (content))
2408 GtkWidget *child = toolbar_content_get_widget (content);
2411 (*callback) (child, callback_data);
2417 if (include_internals)
2418 (* callback) (priv->arrow_button, callback_data);
2422 gtk_toolbar_child_type (GtkContainer *container)
2424 return GTK_TYPE_TOOL_ITEM;
2428 gtk_toolbar_reconfigured (GtkToolbar *toolbar)
2430 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2433 list = priv->content;
2436 ToolbarContent *content = list->data;
2437 GList *next = list->next;
2439 toolbar_content_toolbar_reconfigured (content, toolbar);
2446 gtk_toolbar_orientation_changed (GtkToolbar *toolbar,
2447 GtkOrientation orientation)
2449 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2450 if (toolbar->orientation != orientation)
2452 toolbar->orientation = orientation;
2454 if (orientation == GTK_ORIENTATION_HORIZONTAL)
2455 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_DOWN, GTK_SHADOW_NONE);
2457 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
2459 gtk_toolbar_reconfigured (toolbar);
2461 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2462 g_object_notify (G_OBJECT (toolbar), "orientation");
2467 gtk_toolbar_real_style_changed (GtkToolbar *toolbar,
2468 GtkToolbarStyle style)
2470 if (toolbar->style != style)
2472 toolbar->style = style;
2474 gtk_toolbar_reconfigured (toolbar);
2476 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2477 g_object_notify (G_OBJECT (toolbar), "toolbar_style");
2482 menu_position_func (GtkMenu *menu,
2488 GtkToolbar *toolbar = GTK_TOOLBAR (user_data);
2489 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2491 GtkRequisition menu_req;
2493 gdk_window_get_origin (GTK_BUTTON (priv->arrow_button)->event_window, x, y);
2494 gtk_widget_size_request (priv->arrow_button, &req);
2495 gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
2497 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
2499 *y += priv->arrow_button->allocation.height;
2500 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
2501 *x += priv->arrow_button->allocation.width - req.width;
2503 *x += req.width - menu_req.width;
2507 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
2508 *x += priv->arrow_button->allocation.width;
2510 *x -= menu_req.width;
2511 *y += priv->arrow_button->allocation.height - req.height;
2518 show_menu (GtkToolbar *toolbar,
2519 GdkEventButton *event)
2521 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2523 rebuild_menu (toolbar);
2525 gtk_widget_show_all (GTK_WIDGET (priv->menu));
2527 gtk_menu_popup (priv->menu, NULL, NULL,
2528 menu_position_func, toolbar,
2529 event? event->button : 0,
2530 event? event->time : gtk_get_current_event_time());
2534 gtk_toolbar_arrow_button_clicked (GtkWidget *button,
2535 GtkToolbar *toolbar)
2537 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2539 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->arrow_button)) &&
2540 (!priv->menu || !GTK_WIDGET_VISIBLE (priv->menu)))
2542 /* We only get here when the button is clicked with the keyboard,
2543 * because mouse button presses result in the menu being shown so
2544 * that priv->menu would be non-NULL and visible.
2546 show_menu (toolbar, NULL);
2547 gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->menu), FALSE);
2552 gtk_toolbar_arrow_button_press (GtkWidget *button,
2553 GdkEventButton *event,
2554 GtkToolbar *toolbar)
2556 show_menu (toolbar, event);
2557 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
2563 gtk_toolbar_button_press (GtkWidget *toolbar,
2564 GdkEventButton *event)
2566 if (event->button == 3)
2568 gboolean return_value;
2570 g_signal_emit (toolbar, toolbar_signals[POPUP_CONTEXT_MENU], 0,
2571 (int)event->x_root, (int)event->y_root, event->button,
2574 return return_value;
2581 gtk_toolbar_popup_menu (GtkWidget *toolbar)
2583 gboolean return_value;
2584 /* This function is the handler for the "popup menu" keybinding,
2585 * ie., it is called when the user presses Shift F10
2587 g_signal_emit (toolbar, toolbar_signals[POPUP_CONTEXT_MENU], 0,
2588 -1, -1, -1, &return_value);
2590 return return_value;
2596 * Creates a new toolbar.
2598 * Return Value: the newly-created toolbar.
2601 gtk_toolbar_new (void)
2603 GtkToolbar *toolbar;
2605 toolbar = g_object_new (GTK_TYPE_TOOLBAR, NULL);
2607 return GTK_WIDGET (toolbar);
2611 * gtk_toolbar_insert:
2612 * @toolbar: a #GtkToolbar
2613 * @item: a #GtkToolItem
2614 * @pos: the position of the new item
2616 * Insert a #GtkToolItem into the toolbar at position @pos. If @pos is
2617 * 0 the item is prepended to the start of the toolbar. If @pos is
2618 * negative, the item is appended to the end of the toolbar.
2623 gtk_toolbar_insert (GtkToolbar *toolbar,
2627 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2628 g_return_if_fail (GTK_IS_TOOL_ITEM (item));
2630 if (!gtk_toolbar_check_new_api (toolbar))
2634 pos = logical_to_physical (toolbar, pos);
2636 toolbar_content_new_tool_item (toolbar, item, FALSE, pos);
2640 * gtk_toolbar_get_item_index:
2641 * @toolbar: a #GtkToolbar
2642 * @item: a #GtkToolItem that is a child of @toolbar
2644 * Returns the position of @item on the toolbar, starting from 0.
2645 * It is an error if @item is not a child of the toolbar.
2647 * Return value: the position of item on the toolbar.
2652 gtk_toolbar_get_item_index (GtkToolbar *toolbar,
2655 GtkToolbarPrivate *priv;
2659 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
2660 g_return_val_if_fail (GTK_IS_TOOL_ITEM (item), -1);
2661 g_return_val_if_fail (GTK_WIDGET (item)->parent == GTK_WIDGET (toolbar), -1);
2663 if (!gtk_toolbar_check_new_api (toolbar))
2666 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2669 for (list = priv->content; list != NULL; list = list->next)
2671 ToolbarContent *content = list->data;
2674 widget = toolbar_content_get_widget (content);
2676 if (item == GTK_TOOL_ITEM (widget))
2682 return physical_to_logical (toolbar, n);
2686 * gtk_toolbar_set_orientation:
2687 * @toolbar: a #GtkToolbar.
2688 * @orientation: a new #GtkOrientation.
2690 * Sets whether a toolbar should appear horizontally or vertically.
2693 gtk_toolbar_set_orientation (GtkToolbar *toolbar,
2694 GtkOrientation orientation)
2696 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2698 g_signal_emit (toolbar, toolbar_signals[ORIENTATION_CHANGED], 0, orientation);
2702 * gtk_toolbar_get_orientation:
2703 * @toolbar: a #GtkToolbar
2705 * Retrieves the current orientation of the toolbar. See
2706 * gtk_toolbar_set_orientation().
2708 * Return value: the orientation
2711 gtk_toolbar_get_orientation (GtkToolbar *toolbar)
2713 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_ORIENTATION_HORIZONTAL);
2715 return toolbar->orientation;
2719 * gtk_toolbar_set_style:
2720 * @toolbar: a #GtkToolbar.
2721 * @style: the new style for @toolbar.
2723 * Alters the view of @toolbar to display either icons only, text only, or both.
2726 gtk_toolbar_set_style (GtkToolbar *toolbar,
2727 GtkToolbarStyle style)
2729 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2731 toolbar->style_set = TRUE;
2732 g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
2736 * gtk_toolbar_get_style:
2737 * @toolbar: a #GtkToolbar
2739 * Retrieves whether the toolbar has text, icons, or both . See
2740 * gtk_toolbar_set_style().
2742 * Return value: the current style of @toolbar
2745 gtk_toolbar_get_style (GtkToolbar *toolbar)
2747 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), DEFAULT_TOOLBAR_STYLE);
2749 return toolbar->style;
2753 * gtk_toolbar_unset_style:
2754 * @toolbar: a #GtkToolbar
2756 * Unsets a toolbar style set with gtk_toolbar_set_style(), so that
2757 * user preferences will be used to determine the toolbar style.
2760 gtk_toolbar_unset_style (GtkToolbar *toolbar)
2762 GtkToolbarStyle style;
2764 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2766 if (toolbar->style_set)
2768 GtkSettings *settings = toolbar_get_settings (toolbar);
2771 g_object_get (settings,
2772 "gtk-toolbar-style", &style,
2775 style = DEFAULT_TOOLBAR_STYLE;
2777 if (style != toolbar->style)
2778 g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
2780 toolbar->style_set = FALSE;
2785 * gtk_toolbar_set_tooltips:
2786 * @toolbar: a #GtkToolbar.
2787 * @enable: set to %FALSE to disable the tooltips, or %TRUE to enable them.
2789 * Sets if the tooltips of a toolbar should be active or not.
2792 gtk_toolbar_set_tooltips (GtkToolbar *toolbar,
2795 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2798 gtk_tooltips_enable (toolbar->tooltips);
2800 gtk_tooltips_disable (toolbar->tooltips);
2804 * gtk_toolbar_get_tooltips:
2805 * @toolbar: a #GtkToolbar
2807 * Retrieves whether tooltips are enabled. See
2808 * gtk_toolbar_set_tooltips().
2810 * Return value: %TRUE if tooltips are enabled
2813 gtk_toolbar_get_tooltips (GtkToolbar *toolbar)
2815 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2817 return toolbar->tooltips->enabled;
2821 * gtk_toolbar_get_n_items:
2822 * @toolbar: a #GtkToolbar
2824 * Returns the number of items on the toolbar.
2826 * Return value: the number of items on the toolbar
2831 gtk_toolbar_get_n_items (GtkToolbar *toolbar)
2833 GtkToolbarPrivate *priv;
2835 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
2837 if (!gtk_toolbar_check_new_api (toolbar))
2840 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2842 return physical_to_logical (toolbar, g_list_length (priv->content));
2846 * gtk_toolbar_get_nth_item:
2847 * @toolbar: a #GtkToolbar
2848 * @n: A position on the toolbar
2850 * Returns the @n<!-- -->'s item on @toolbar, or %NULL if the
2851 * toolbar does not contain an @n<!-- -->'th item.
2853 * Return value: The @n<!-- -->'th #GtkToolItem on @toolbar, or %NULL if there
2854 * isn't an @n<!-- -->th item.
2859 gtk_toolbar_get_nth_item (GtkToolbar *toolbar,
2862 GtkToolbarPrivate *priv;
2863 ToolbarContent *content;
2866 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
2868 if (!gtk_toolbar_check_new_api (toolbar))
2871 n_items = gtk_toolbar_get_n_items (toolbar);
2873 if (n < 0 || n >= n_items)
2876 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2878 content = g_list_nth_data (priv->content, logical_to_physical (toolbar, n));
2881 g_assert (!toolbar_content_is_placeholder (content));
2883 return GTK_TOOL_ITEM (toolbar_content_get_widget (content));
2887 * gtk_toolbar_get_icon_size:
2888 * @toolbar: a #GtkToolbar
2890 * Retrieves the icon size fo the toolbar. See gtk_toolbar_set_icon_size().
2892 * Return value: the current icon size for the icons on the toolbar.
2895 gtk_toolbar_get_icon_size (GtkToolbar *toolbar)
2897 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), DEFAULT_ICON_SIZE);
2899 return toolbar->icon_size;
2903 * gtk_toolbar_get_relief_style:
2904 * @toolbar: a #GtkToolbar
2906 * Returns the relief style of buttons on @toolbar. See
2907 * gtk_button_set_relief().
2909 * Return value: The relief style of buttons on @toolbar.
2914 gtk_toolbar_get_relief_style (GtkToolbar *toolbar)
2916 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_RELIEF_NONE);
2918 return get_button_relief (toolbar);
2922 * gtk_toolbar_set_show_arrow:
2923 * @toolbar: a #GtkToolbar
2924 * @show_arrow: Whether to show an overflow menu
2926 * Sets whether to show an overflow menu when
2927 * @toolbar doesn't have room for all items on it. If %TRUE,
2928 * items that there are not room are available through an
2934 gtk_toolbar_set_show_arrow (GtkToolbar *toolbar,
2935 gboolean show_arrow)
2937 GtkToolbarPrivate *priv;
2939 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2941 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2942 show_arrow = show_arrow != FALSE;
2944 if (priv->show_arrow != show_arrow)
2946 priv->show_arrow = show_arrow;
2948 if (!priv->show_arrow)
2949 gtk_widget_hide (priv->arrow_button);
2951 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2952 g_object_notify (G_OBJECT (toolbar), "show_arrow");
2957 * gtk_toolbar_get_show_arrow:
2958 * @toolbar: a #GtkToolbar
2960 * Returns whether the toolbar has an overflow menu.
2961 * See gtk_toolbar_set_show_arrow()
2968 gtk_toolbar_get_show_arrow (GtkToolbar *toolbar)
2970 GtkToolbarPrivate *priv;
2972 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2974 if (!gtk_toolbar_check_new_api (toolbar))
2977 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2979 return priv->show_arrow;
2983 * gtk_toolbar_get_drop_index:
2984 * @toolbar: a #GtkToolbar
2985 * @x: x coordinate of a point on the toolbar
2986 * @y: y coordinate of a point on the toolbar
2988 * Returns the position corresponding to the indicated point on
2989 * @toolbar. This is useful when dragging items to the toolbar:
2990 * this function returns the position a new item should be
2993 * @x and @y are in @toolbar coordinates.
2995 * Return value: The position corresponding to the point (@x, @y) on the toolbar.
3000 gtk_toolbar_get_drop_index (GtkToolbar *toolbar,
3004 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
3006 if (!gtk_toolbar_check_new_api (toolbar))
3009 return physical_to_logical (toolbar, find_drop_index (toolbar, x, y));
3013 gtk_toolbar_finalize (GObject *object)
3016 GtkToolbar *toolbar = GTK_TOOLBAR (object);
3017 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3019 if (toolbar->tooltips)
3020 g_object_unref (toolbar->tooltips);
3022 if (priv->arrow_button)
3023 gtk_widget_unparent (priv->arrow_button);
3025 for (list = priv->content; list != NULL; list = list->next)
3027 ToolbarContent *content = list->data;
3029 toolbar_content_free (content);
3032 g_list_free (priv->content);
3033 g_list_free (toolbar->children);
3035 g_timer_destroy (priv->timer);
3038 gtk_widget_destroy (GTK_WIDGET (priv->menu));
3041 g_source_remove (priv->idle_id);
3043 G_OBJECT_CLASS (parent_class)->finalize (object);
3051 * gtk_toolbar_set_icon_size:
3052 * @toolbar: A #GtkToolbar
3053 * @icon_size: The #GtkIconSize that stock icons in the toolbar shall have.
3055 * This function sets the size of stock icons in the toolbar. You
3056 * can call it both before you add the icons and after they've been
3057 * added. The size you set will override user preferences for the default
3061 gtk_toolbar_set_icon_size (GtkToolbar *toolbar,
3062 GtkIconSize icon_size)
3064 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
3066 toolbar->icon_size_set = TRUE;
3068 if (toolbar->icon_size == icon_size)
3071 toolbar->icon_size = icon_size;
3073 gtk_toolbar_reconfigured (toolbar);
3075 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
3079 * gtk_toolbar_unset_icon_size:
3080 * @toolbar: a #GtkToolbar
3082 * Unsets toolbar icon size set with gtk_toolbar_set_icon_size(), so that
3083 * user preferences will be used to determine the icon size.
3086 gtk_toolbar_unset_icon_size (GtkToolbar *toolbar)
3090 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
3092 if (toolbar->icon_size_set)
3094 GtkSettings *settings = toolbar_get_settings (toolbar);
3098 g_object_get (settings,
3099 "gtk-toolbar-icon-size", &size,
3103 size = DEFAULT_ICON_SIZE;
3105 if (size != toolbar->icon_size)
3106 gtk_toolbar_set_icon_size (toolbar, size);
3108 toolbar->icon_size_set = FALSE;
3113 * gtk_toolbar_append_item:
3114 * @toolbar: a #GtkToolbar.
3115 * @text: give your toolbar button a label.
3116 * @tooltip_text: a string that appears when the user holds the mouse over this item.
3117 * @tooltip_private_text: use with #GtkTipsQuery.
3118 * @icon: a #GtkWidget that should be used as the button's icon.
3119 * @callback: the function to be executed when the button is pressed.
3120 * @user_data: a pointer to any data you wish to be passed to the callback.
3122 * Inserts a new item into the toolbar. You must specify the position
3123 * in the toolbar where it will be inserted.
3125 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3126 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3128 * Return value: the new toolbar item as a #GtkWidget.
3131 gtk_toolbar_append_item (GtkToolbar *toolbar,
3133 const char *tooltip_text,
3134 const char *tooltip_private_text,
3136 GtkSignalFunc callback,
3139 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3141 tooltip_text, tooltip_private_text,
3142 icon, callback, user_data,
3143 toolbar->num_children);
3147 * gtk_toolbar_prepend_item:
3148 * @toolbar: a #GtkToolbar.
3149 * @text: give your toolbar button a label.
3150 * @tooltip_text: a string that appears when the user holds the mouse over this item.
3151 * @tooltip_private_text: use with #GtkTipsQuery.
3152 * @icon: a #GtkWidget that should be used as the button's icon.
3153 * @callback: the function to be executed when the button is pressed.
3154 * @user_data: a pointer to any data you wish to be passed to the callback.
3156 * Adds a new button to the beginning (top or left edges) of the given toolbar.
3158 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3159 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3161 * Return value: the new toolbar item as a #GtkWidget.
3164 gtk_toolbar_prepend_item (GtkToolbar *toolbar,
3166 const char *tooltip_text,
3167 const char *tooltip_private_text,
3169 GtkSignalFunc callback,
3172 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3174 tooltip_text, tooltip_private_text,
3175 icon, callback, user_data,
3180 * gtk_toolbar_insert_item:
3181 * @toolbar: a #GtkToolbar.
3182 * @text: give your toolbar button a label.
3183 * @tooltip_text: a string that appears when the user holds the mouse over this item.
3184 * @tooltip_private_text: use with #GtkTipsQuery.
3185 * @icon: a #GtkWidget that should be used as the button's icon.
3186 * @callback: the function to be executed when the button is pressed.
3187 * @user_data: a pointer to any data you wish to be passed to the callback.
3188 * @position: the number of widgets to insert this item after.
3190 * Inserts a new item into the toolbar. You must specify the position in the
3191 * toolbar where it will be inserted.
3193 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3194 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3196 * Return value: the new toolbar item as a #GtkWidget.
3199 gtk_toolbar_insert_item (GtkToolbar *toolbar,
3201 const char *tooltip_text,
3202 const char *tooltip_private_text,
3204 GtkSignalFunc callback,
3208 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3210 tooltip_text, tooltip_private_text,
3211 icon, callback, user_data,
3216 * gtk_toolbar_insert_stock:
3217 * @toolbar: A #GtkToolbar
3218 * @stock_id: The id of the stock item you want to insert
3219 * @tooltip_text: The text in the tooltip of the toolbar button
3220 * @tooltip_private_text: The private text of the tooltip
3221 * @callback: The callback called when the toolbar button is clicked.
3222 * @user_data: user data passed to callback
3223 * @position: The position the button shall be inserted at.
3224 * -1 means at the end.
3226 * Inserts a stock item at the specified position of the toolbar. If
3227 * @stock_id is not a known stock item ID, it's inserted verbatim,
3228 * except that underscores used to mark mnemonics are removed.
3230 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3231 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3233 * Returns: the inserted widget
3236 gtk_toolbar_insert_stock (GtkToolbar *toolbar,
3237 const gchar *stock_id,
3238 const char *tooltip_text,
3239 const char *tooltip_private_text,
3240 GtkSignalFunc callback,
3244 return internal_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3246 tooltip_text, tooltip_private_text,
3247 NULL, callback, user_data,
3252 * gtk_toolbar_append_space:
3253 * @toolbar: a #GtkToolbar.
3255 * Adds a new space to the end of the toolbar.
3258 gtk_toolbar_append_space (GtkToolbar *toolbar)
3260 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
3264 toolbar->num_children);
3268 * gtk_toolbar_prepend_space:
3269 * @toolbar: a #GtkToolbar.
3271 * Adds a new space to the beginning of the toolbar.
3274 gtk_toolbar_prepend_space (GtkToolbar *toolbar)
3276 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
3284 * gtk_toolbar_insert_space:
3285 * @toolbar: a #GtkToolbar
3286 * @position: the number of widgets after which a space should be inserted.
3288 * Inserts a new space in the toolbar at the specified position.
3291 gtk_toolbar_insert_space (GtkToolbar *toolbar,
3294 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
3302 * gtk_toolbar_remove_space:
3303 * @toolbar: a #GtkToolbar.
3304 * @position: the index of the space to remove.
3306 * Removes a space from the specified position.
3309 gtk_toolbar_remove_space (GtkToolbar *toolbar,
3312 GtkToolbarPrivate *priv;
3313 ToolbarContent *content;
3315 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
3317 if (!gtk_toolbar_check_old_api (toolbar))
3320 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3322 content = g_list_nth_data (priv->content, position);
3326 g_warning ("Toolbar position %d doesn't exist", position);
3330 if (!toolbar_content_is_separator (content))
3332 g_warning ("Toolbar position %d is not a space", position);
3336 toolbar_content_remove (content, toolbar);
3337 toolbar_content_free (content);
3341 * gtk_toolbar_append_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 end of the given toolbar.
3350 gtk_toolbar_append_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,
3359 toolbar->num_children);
3363 * gtk_toolbar_prepend_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.
3369 * Adds a widget to the beginning of the given toolbar.
3372 gtk_toolbar_prepend_widget (GtkToolbar *toolbar,
3374 const gchar *tooltip_text,
3375 const gchar *tooltip_private_text)
3377 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
3379 tooltip_text, tooltip_private_text,
3385 * gtk_toolbar_insert_widget:
3386 * @toolbar: a #GtkToolbar.
3387 * @widget: a #GtkWidget to add to the toolbar.
3388 * @tooltip_text: the element's tooltip.
3389 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3390 * @position: the number of widgets to insert this widget after.
3392 * Inserts a widget in the toolbar at the given position.
3395 gtk_toolbar_insert_widget (GtkToolbar *toolbar,
3397 const char *tooltip_text,
3398 const char *tooltip_private_text,
3401 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
3403 tooltip_text, tooltip_private_text,
3409 * gtk_toolbar_append_element:
3410 * @toolbar: a #GtkToolbar.
3411 * @type: a value of type #GtkToolbarChildType that determines what @widget will be.
3412 * @widget: a #GtkWidget, or %NULL.
3413 * @text: the element's label.
3414 * @tooltip_text: the element's tooltip.
3415 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3416 * @icon: a #GtkWidget that provides pictorial representation of the element's function.
3417 * @callback: the function to be executed when the button is pressed.
3418 * @user_data: any data you wish to pass to the callback.
3420 * Adds a new element to the end of a toolbar.
3422 * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element.
3423 * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine
3424 * the radio group for the new element. In all other cases, @widget must
3427 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3428 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3430 * Return value: the new toolbar element as a #GtkWidget.
3433 gtk_toolbar_append_element (GtkToolbar *toolbar,
3434 GtkToolbarChildType type,
3437 const char *tooltip_text,
3438 const char *tooltip_private_text,
3440 GtkSignalFunc callback,
3443 return gtk_toolbar_insert_element (toolbar, type, widget, text,
3444 tooltip_text, tooltip_private_text,
3445 icon, callback, user_data,
3446 toolbar->num_children);
3450 * gtk_toolbar_prepend_element:
3451 * @toolbar: a #GtkToolbar.
3452 * @type: a value of type #GtkToolbarChildType that determines what @widget will be.
3453 * @widget: a #GtkWidget, or %NULL
3454 * @text: the element's label.
3455 * @tooltip_text: the element's tooltip.
3456 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3457 * @icon: a #GtkWidget that provides pictorial representation of the element's function.
3458 * @callback: the function to be executed when the button is pressed.
3459 * @user_data: any data you wish to pass to the callback.
3461 * Adds a new element to the beginning of a toolbar.
3463 * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element.
3464 * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine
3465 * the radio group for the new element. In all other cases, @widget must
3468 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3469 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3471 * Return value: the new toolbar element as a #GtkWidget.
3474 gtk_toolbar_prepend_element (GtkToolbar *toolbar,
3475 GtkToolbarChildType type,
3478 const char *tooltip_text,
3479 const char *tooltip_private_text,
3481 GtkSignalFunc callback,
3484 return gtk_toolbar_insert_element (toolbar, type, widget, text,
3485 tooltip_text, tooltip_private_text,
3486 icon, callback, user_data, 0);
3490 * gtk_toolbar_insert_element:
3491 * @toolbar: a #GtkToolbar.
3492 * @type: a value of type #GtkToolbarChildType that determines what @widget
3494 * @widget: a #GtkWidget, or %NULL.
3495 * @text: the element's label.
3496 * @tooltip_text: the element's tooltip.
3497 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3498 * @icon: a #GtkWidget that provides pictorial representation of the element's function.
3499 * @callback: the function to be executed when the button is pressed.
3500 * @user_data: any data you wish to pass to the callback.
3501 * @position: the number of widgets to insert this element after.
3503 * Inserts a new element in the toolbar at the given position.
3505 * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element.
3506 * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine
3507 * the radio group for the new element. In all other cases, @widget must
3510 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3511 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3513 * Return value: the new toolbar element as a #GtkWidget.
3516 gtk_toolbar_insert_element (GtkToolbar *toolbar,
3517 GtkToolbarChildType type,
3520 const char *tooltip_text,
3521 const char *tooltip_private_text,
3523 GtkSignalFunc callback,
3527 return internal_insert_element (toolbar, type, widget, text,
3528 tooltip_text, tooltip_private_text,
3529 icon, callback, user_data, position, FALSE);
3533 set_child_packing_and_visibility(GtkToolbar *toolbar,
3534 GtkToolbarChild *child)
3539 box = gtk_bin_get_child (GTK_BIN (child->widget));
3541 g_return_if_fail (GTK_IS_BOX (box));
3545 expand = (toolbar->style != GTK_TOOLBAR_BOTH);
3547 gtk_box_set_child_packing (GTK_BOX (box), child->label,
3548 expand, expand, 0, GTK_PACK_END);
3550 if (toolbar->style != GTK_TOOLBAR_ICONS)
3551 gtk_widget_show (child->label);
3553 gtk_widget_hide (child->label);
3558 expand = (toolbar->style != GTK_TOOLBAR_BOTH_HORIZ);
3560 gtk_box_set_child_packing (GTK_BOX (box), child->icon,
3561 expand, expand, 0, GTK_PACK_END);
3563 if (toolbar->style != GTK_TOOLBAR_TEXT)
3564 gtk_widget_show (child->icon);
3566 gtk_widget_hide (child->icon);
3571 internal_insert_element (GtkToolbar *toolbar,
3572 GtkToolbarChildType type,
3575 const char *tooltip_text,
3576 const char *tooltip_private_text,
3578 GtkSignalFunc callback,
3584 ToolbarContent *content;
3585 GtkToolbarPrivate *priv;
3586 char *free_me = NULL;
3587 gboolean is_button = FALSE;
3589 GtkWidget *child_widget;
3590 GtkWidget *child_label;
3591 GtkWidget *child_icon;
3593 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
3594 if (type == GTK_TOOLBAR_CHILD_WIDGET)
3595 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3596 else if (type != GTK_TOOLBAR_CHILD_RADIOBUTTON)
3597 g_return_val_if_fail (widget == NULL, NULL);
3599 if (!gtk_toolbar_check_old_api (toolbar))
3602 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3604 child_widget = NULL;
3610 case GTK_TOOLBAR_CHILD_SPACE:
3613 case GTK_TOOLBAR_CHILD_WIDGET:
3614 child_widget = widget;
3617 case GTK_TOOLBAR_CHILD_BUTTON:
3618 case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
3619 case GTK_TOOLBAR_CHILD_RADIOBUTTON:
3621 if (type == GTK_TOOLBAR_CHILD_BUTTON)
3623 child_widget = gtk_button_new ();
3625 else if (type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
3627 child_widget = gtk_toggle_button_new ();
3628 gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (child_widget), FALSE);
3630 else /* type == GTK_TOOLBAR_CHILD_RADIOBUTTON */
3632 GSList *group = NULL;
3635 group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
3637 child_widget = gtk_radio_button_new (group);
3638 gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (child_widget), FALSE);
3641 gtk_button_set_relief (GTK_BUTTON (child_widget), get_button_relief (toolbar));
3642 gtk_button_set_focus_on_click (GTK_BUTTON (child_widget), FALSE);
3646 g_signal_connect (child_widget, "clicked",
3647 callback, user_data);
3650 if (toolbar->style == GTK_TOOLBAR_BOTH_HORIZ)
3651 box = gtk_hbox_new (FALSE, 0);
3653 box = gtk_vbox_new (FALSE, 0);
3655 gtk_container_add (GTK_CONTAINER (child_widget), box);
3656 gtk_widget_show (box);
3658 if (text && use_stock)
3660 GtkStockItem stock_item;
3661 if (gtk_stock_lookup (text, &stock_item))
3664 icon = gtk_image_new_from_stock (text, toolbar->icon_size);
3666 text = free_me = _gtk_toolbar_elide_underscores (stock_item.label);
3672 child_label = gtk_label_new (text);
3674 gtk_container_add (GTK_CONTAINER (box), child_label);
3679 child_icon = GTK_WIDGET (icon);
3680 gtk_container_add (GTK_CONTAINER (box), child_icon);
3683 gtk_widget_show (child_widget);
3687 g_assert_not_reached ();
3691 if ((type != GTK_TOOLBAR_CHILD_SPACE) && tooltip_text)
3693 gtk_tooltips_set_tip (toolbar->tooltips, child_widget,
3694 tooltip_text, tooltip_private_text);
3697 content = toolbar_content_new_compatibility (toolbar, type, child_widget,
3698 child_icon, child_label, position);
3703 return child_widget;
3707 * ToolbarContent methods
3709 struct _ToolbarContent
3719 GtkAllocation start_allocation;
3720 GtkAllocation goal_allocation;
3721 guint is_placeholder : 1;
3722 guint disappearing : 1;
3727 GtkToolbarChild child;
3728 GtkAllocation space_allocation;
3729 guint space_visible : 1;
3734 static ToolbarContent *
3735 toolbar_content_new_tool_item (GtkToolbar *toolbar,
3737 gboolean is_placeholder,
3740 ToolbarContent *content;
3741 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3743 content = g_new0 (ToolbarContent, 1);
3745 content->type = TOOL_ITEM;
3746 content->state = NOT_ALLOCATED;
3747 content->u.tool_item.item = item;
3748 content->u.tool_item.is_placeholder = is_placeholder;
3750 gtk_widget_set_parent (GTK_WIDGET (item), GTK_WIDGET (toolbar));
3752 priv->content = g_list_insert (priv->content, content, pos);
3754 if (!is_placeholder)
3756 toolbar->num_children++;
3758 gtk_toolbar_stop_sliding (toolbar);
3761 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
3762 priv->need_rebuild = TRUE;
3767 static ToolbarContent *
3768 toolbar_content_new_compatibility (GtkToolbar *toolbar,
3769 GtkToolbarChildType type,
3775 ToolbarContent *content;
3776 GtkToolbarChild *child;
3777 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3779 content = g_new0 (ToolbarContent, 1);
3781 child = &(content->u.compatibility.child);
3783 content->type = COMPATIBILITY;
3785 child->widget = widget;
3787 child->label = label;
3789 if (type != GTK_TOOLBAR_CHILD_SPACE)
3791 gtk_widget_set_parent (child->widget, GTK_WIDGET (toolbar));
3795 content->u.compatibility.space_visible = TRUE;
3796 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
3799 if (type == GTK_TOOLBAR_CHILD_BUTTON ||
3800 type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON ||
3801 type == GTK_TOOLBAR_CHILD_RADIOBUTTON)
3803 set_child_packing_and_visibility (toolbar, child);
3806 priv->content = g_list_insert (priv->content, content, pos);
3807 toolbar->children = g_list_insert (toolbar->children, child, pos);
3808 priv->need_rebuild = TRUE;
3810 toolbar->num_children++;
3816 toolbar_content_remove (ToolbarContent *content,
3817 GtkToolbar *toolbar)
3819 GtkToolbarChild *child;
3820 GtkToolbarPrivate *priv;
3822 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3824 switch (content->type)
3827 gtk_widget_unparent (GTK_WIDGET (content->u.tool_item.item));
3831 child = &(content->u.compatibility.child);
3833 if (child->type != GTK_TOOLBAR_CHILD_SPACE)
3835 g_object_ref (child->widget);
3836 gtk_widget_unparent (child->widget);
3837 gtk_widget_destroy (child->widget);
3838 g_object_unref (child->widget);
3841 toolbar->children = g_list_remove (toolbar->children, child);
3845 priv->content = g_list_remove (priv->content, content);
3847 if (!toolbar_content_is_placeholder (content))
3848 toolbar->num_children--;
3850 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
3851 priv->need_rebuild = TRUE;
3855 toolbar_content_free (ToolbarContent *content)
3861 calculate_max_homogeneous_pixels (GtkWidget *widget)
3863 PangoContext *context;
3864 PangoFontMetrics *metrics;
3867 context = gtk_widget_get_pango_context (widget);
3868 metrics = pango_context_get_metrics (context,
3869 widget->style->font_desc,
3870 pango_context_get_language (context));
3871 char_width = pango_font_metrics_get_approximate_char_width (metrics);
3872 pango_font_metrics_unref (metrics);
3874 return PANGO_PIXELS (MAX_HOMOGENEOUS_N_CHARS * char_width);
3878 toolbar_content_expose (ToolbarContent *content,
3879 GtkContainer *container,
3880 GdkEventExpose *expose)
3882 GtkToolbar *toolbar = GTK_TOOLBAR (container);
3883 GtkToolbarChild *child;
3884 GtkWidget *widget = NULL; /* quiet gcc */
3886 switch (content->type)
3889 if (!content->u.tool_item.is_placeholder)
3890 widget = GTK_WIDGET (content->u.tool_item.item);
3894 child = &(content->u.compatibility.child);
3896 if (child->type == GTK_TOOLBAR_CHILD_SPACE)
3898 if (get_space_style (toolbar) == GTK_TOOLBAR_SPACE_LINE &&
3899 content->u.compatibility.space_visible)
3901 _gtk_toolbar_paint_space_line (GTK_WIDGET (toolbar), toolbar,
3903 &content->u.compatibility.space_allocation);
3908 widget = child->widget;
3913 gtk_container_propagate_expose (container, widget, expose);
3917 toolbar_content_visible (ToolbarContent *content,
3918 GtkToolbar *toolbar)
3922 switch (content->type)
3925 item = content->u.tool_item.item;
3927 if (!GTK_WIDGET_VISIBLE (item))
3930 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL &&
3931 gtk_tool_item_get_visible_horizontal (item))
3936 if ((toolbar->orientation == GTK_ORIENTATION_VERTICAL &&
3937 gtk_tool_item_get_visible_vertical (item)))
3946 if (content->u.compatibility.child.type != GTK_TOOLBAR_CHILD_SPACE)
3947 return GTK_WIDGET_VISIBLE (content->u.compatibility.child.widget);
3953 g_assert_not_reached ();
3958 toolbar_content_size_request (ToolbarContent *content,
3959 GtkToolbar *toolbar,
3960 GtkRequisition *requisition)
3964 switch (content->type)
3967 gtk_widget_size_request (GTK_WIDGET (content->u.tool_item.item),
3969 if (content->u.tool_item.is_placeholder &&
3970 content->u.tool_item.disappearing)
3972 requisition->width = 0;
3973 requisition->height = 0;
3978 space_size = get_space_size (toolbar);
3980 if (content->u.compatibility.child.type != GTK_TOOLBAR_CHILD_SPACE)
3982 gtk_widget_size_request (content->u.compatibility.child.widget,
3987 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
3989 requisition->width = space_size;
3990 requisition->height = 0;
3994 requisition->height = space_size;
3995 requisition->width = 0;
4004 toolbar_content_is_homogeneous (ToolbarContent *content,
4005 GtkToolbar *toolbar)
4007 gboolean result = FALSE; /* quiet gcc */
4008 GtkRequisition requisition;
4009 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
4011 if (priv->max_homogeneous_pixels < 0)
4013 priv->max_homogeneous_pixels =
4014 calculate_max_homogeneous_pixels (GTK_WIDGET (toolbar));
4017 toolbar_content_size_request (content, toolbar, &requisition);
4019 if (requisition.width > priv->max_homogeneous_pixels)
4022 switch (content->type)
4025 result = gtk_tool_item_get_homogeneous (content->u.tool_item.item) &&
4026 !GTK_IS_SEPARATOR_TOOL_ITEM (content->u.tool_item.item);
4028 if (gtk_tool_item_get_is_important (content->u.tool_item.item) &&
4029 toolbar->style == GTK_TOOLBAR_BOTH_HORIZ &&
4030 toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
4037 if (content->u.compatibility.child.type == GTK_TOOLBAR_CHILD_BUTTON ||
4038 content->u.compatibility.child.type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
4039 content->u.compatibility.child.type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
4054 toolbar_content_is_placeholder (ToolbarContent *content)
4056 if (content->type == TOOL_ITEM && content->u.tool_item.is_placeholder)
4063 toolbar_content_disappearing (ToolbarContent *content)
4065 if (content->type == TOOL_ITEM && content->u.tool_item.disappearing)
4072 toolbar_content_get_state (ToolbarContent *content)
4074 return content->state;
4078 toolbar_content_child_visible (ToolbarContent *content)
4080 switch (content->type)
4083 return GTK_WIDGET_CHILD_VISIBLE (content->u.tool_item.item);
4087 if (content->u.compatibility.child.type != GTK_TOOLBAR_CHILD_SPACE)
4089 return GTK_WIDGET_CHILD_VISIBLE (content->u.compatibility.child.widget);
4093 return content->u.compatibility.space_visible;
4098 return FALSE; /* quiet gcc */
4102 toolbar_content_get_goal_allocation (ToolbarContent *content,
4103 GtkAllocation *allocation)
4105 switch (content->type)
4108 *allocation = content->u.tool_item.goal_allocation;
4112 /* Goal allocations are only relevant when we are
4113 * using the new API, so we should never get here
4115 g_assert_not_reached ();
4121 toolbar_content_get_allocation (ToolbarContent *content,
4122 GtkAllocation *allocation)
4124 GtkToolbarChild *child;
4126 switch (content->type)
4129 *allocation = GTK_WIDGET (content->u.tool_item.item)->allocation;
4133 child = &(content->u.compatibility.child);
4135 if (child->type == GTK_TOOLBAR_CHILD_SPACE)
4136 *allocation = content->u.compatibility.space_allocation;
4138 *allocation = child->widget->allocation;
4144 toolbar_content_set_start_allocation (ToolbarContent *content,
4145 GtkAllocation *allocation)
4147 switch (content->type)
4150 content->u.tool_item.start_allocation = *allocation;
4154 /* start_allocation is only relevant when using the new API */
4155 g_assert_not_reached ();
4161 toolbar_content_get_expand (ToolbarContent *content)
4163 if (content->type == TOOL_ITEM &&
4164 gtk_tool_item_get_expand (content->u.tool_item.item))
4173 toolbar_content_set_goal_allocation (ToolbarContent *content,
4174 GtkAllocation *allocation)
4176 switch (content->type)
4179 content->u.tool_item.goal_allocation = *allocation;
4183 /* Only relevant when using new API */
4184 g_assert_not_reached ();
4190 toolbar_content_set_child_visible (ToolbarContent *content,
4191 GtkToolbar *toolbar,
4194 GtkToolbarChild *child;
4196 switch (content->type)
4199 gtk_widget_set_child_visible (GTK_WIDGET (content->u.tool_item.item),
4204 child = &(content->u.compatibility.child);
4206 if (child->type != GTK_TOOLBAR_CHILD_SPACE)
4208 gtk_widget_set_child_visible (child->widget, visible);
4212 content->u.compatibility.space_visible = visible;
4213 gtk_widget_queue_draw (GTK_WIDGET (toolbar));
4220 toolbar_content_get_start_allocation (ToolbarContent *content,
4221 GtkAllocation *start_allocation)
4223 switch (content->type)
4226 *start_allocation = content->u.tool_item.start_allocation;
4230 /* Only relevant for new API */
4231 g_assert_not_reached ();
4237 toolbar_content_size_allocate (ToolbarContent *content,
4238 GtkAllocation *allocation)
4240 switch (content->type)
4243 gtk_widget_size_allocate (GTK_WIDGET (content->u.tool_item.item),
4248 if (content->u.compatibility.child.type != GTK_TOOLBAR_CHILD_SPACE)
4250 gtk_widget_size_allocate (content->u.compatibility.child.widget,
4255 content->u.compatibility.space_allocation = *allocation;
4262 toolbar_content_set_state (ToolbarContent *content,
4265 content->state = state;
4269 toolbar_content_get_widget (ToolbarContent *content)
4271 GtkToolbarChild *child;
4273 switch (content->type)
4276 return GTK_WIDGET (content->u.tool_item.item);
4280 child = &(content->u.compatibility.child);
4281 if (child->type != GTK_TOOLBAR_CHILD_SPACE)
4282 return child->widget;
4292 toolbar_content_set_disappearing (ToolbarContent *content,
4293 gboolean disappearing)
4295 switch (content->type)
4298 content->u.tool_item.disappearing = disappearing;
4302 /* Only relevant for new API */
4303 g_assert_not_reached ();
4309 toolbar_content_set_size_request (ToolbarContent *content,
4313 switch (content->type)
4316 gtk_widget_set_size_request (GTK_WIDGET (content->u.tool_item.item),
4321 /* Setting size requests only happens with sliding,
4322 * so not relevant here
4324 g_assert_not_reached ();
4330 toolbar_child_reconfigure (GtkToolbar *toolbar,
4331 GtkToolbarChild *child)
4335 GtkToolbarStyle style;
4336 GtkIconSize icon_size;
4337 GtkReliefStyle relief;
4340 style = gtk_toolbar_get_style (toolbar);
4341 icon_size = gtk_toolbar_get_icon_size (toolbar);
4342 relief = gtk_toolbar_get_relief_style (toolbar);
4345 if (child->type == GTK_TOOLBAR_CHILD_BUTTON ||
4346 child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
4347 child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
4349 box = gtk_bin_get_child (GTK_BIN (child->widget));
4351 if (style == GTK_TOOLBAR_BOTH && GTK_IS_HBOX (box))
4355 vbox = gtk_vbox_new (FALSE, 0);
4358 gtk_widget_reparent (child->label, vbox);
4360 gtk_widget_reparent (child->icon, vbox);
4362 gtk_widget_destroy (box);
4363 gtk_container_add (GTK_CONTAINER (child->widget), vbox);
4365 gtk_widget_show (vbox);
4367 else if (style == GTK_TOOLBAR_BOTH_HORIZ && GTK_IS_VBOX (box))
4371 hbox = gtk_hbox_new (FALSE, 0);
4374 gtk_widget_reparent (child->label, hbox);
4376 gtk_widget_reparent (child->icon, hbox);
4378 gtk_widget_destroy (box);
4379 gtk_container_add (GTK_CONTAINER (child->widget), hbox);
4381 gtk_widget_show (hbox);
4384 set_child_packing_and_visibility (toolbar, child);
4389 if ((child->type == GTK_TOOLBAR_CHILD_BUTTON ||
4390 child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON ||
4391 child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON) &&
4392 GTK_IS_IMAGE (child->icon))
4394 image = GTK_IMAGE (child->icon);
4395 if (gtk_image_get_storage_type (image) == GTK_IMAGE_STOCK)
4397 gtk_image_get_stock (image, &stock_id, NULL);
4398 stock_id = g_strdup (stock_id);
4399 gtk_image_set_from_stock (image,
4407 if (child->type == GTK_TOOLBAR_CHILD_BUTTON ||
4408 child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
4409 child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
4411 gtk_button_set_relief (GTK_BUTTON (child->widget), relief);
4416 toolbar_content_toolbar_reconfigured (ToolbarContent *content,
4417 GtkToolbar *toolbar)
4419 switch (content->type)
4422 _gtk_tool_item_toolbar_reconfigured (content->u.tool_item.item);
4426 toolbar_child_reconfigure (toolbar, &(content->u.compatibility.child));
4432 toolbar_content_retrieve_menu_item (ToolbarContent *content)
4434 if (content->type == TOOL_ITEM)
4435 return gtk_tool_item_retrieve_proxy_menu_item (content->u.tool_item.item);
4437 /* FIXME - we might actually be able to do something meaningful here */
4442 toolbar_content_has_proxy_menu_item (ToolbarContent *content)
4444 GtkWidget *menu_item;
4446 menu_item = toolbar_content_retrieve_menu_item (content);
4448 return menu_item != NULL;
4452 toolbar_content_is_separator (ToolbarContent *content)
4454 GtkToolbarChild *child;
4456 switch (content->type)
4459 return GTK_IS_SEPARATOR_TOOL_ITEM (content->u.tool_item.item);
4463 child = &(content->u.compatibility.child);
4464 return (child->type == GTK_TOOLBAR_CHILD_SPACE);
4472 ignore_show_and_hide_all (ToolbarContent *content)
4474 if (content->type == COMPATIBILITY)
4476 GtkToolbarChildType type = content->u.compatibility.child.type;
4478 if (type == GTK_TOOLBAR_CHILD_BUTTON ||
4479 type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON ||
4480 type == GTK_TOOLBAR_CHILD_RADIOBUTTON)
4490 toolbar_content_show_all (ToolbarContent *content)
4494 if (ignore_show_and_hide_all (content))
4497 widget = toolbar_content_get_widget (content);
4499 gtk_widget_show_all (widget);
4503 toolbar_content_hide_all (ToolbarContent *content)
4507 if (ignore_show_and_hide_all (content))
4510 widget = toolbar_content_get_widget (content);
4512 gtk_widget_hide_all (widget);
4519 get_space_size (GtkToolbar *toolbar)
4521 gint space_size = DEFAULT_SPACE_SIZE;
4525 gtk_widget_style_get (GTK_WIDGET (toolbar),
4526 "space_size", &space_size,
4533 static GtkToolbarSpaceStyle
4534 get_space_style (GtkToolbar *toolbar)
4536 GtkToolbarSpaceStyle space_style = DEFAULT_SPACE_STYLE;
4540 gtk_widget_style_get (GTK_WIDGET (toolbar),
4541 "space_style", &space_style,
4548 static GtkReliefStyle
4549 get_button_relief (GtkToolbar *toolbar)
4551 GtkReliefStyle button_relief = GTK_RELIEF_NORMAL;
4553 gtk_widget_ensure_style (GTK_WIDGET (toolbar));
4555 gtk_widget_style_get (GTK_WIDGET (toolbar),
4556 "button_relief", &button_relief,
4559 return button_relief;
4563 get_internal_padding (GtkToolbar *toolbar)
4567 gtk_widget_style_get (GTK_WIDGET (toolbar),
4568 "internal_padding", &ipadding,
4574 static GtkShadowType
4575 get_shadow_type (GtkToolbar *toolbar)
4577 GtkShadowType shadow_type;
4579 gtk_widget_style_get (GTK_WIDGET (toolbar),
4580 "shadow_type", &shadow_type,
4589 #define mixed_api_warning \
4590 "mixing deprecated and non-deprecated GtkToolbar API is not allowed"
4593 gtk_toolbar_check_old_api (GtkToolbar *toolbar)
4595 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
4597 if (priv->api_mode == NEW_API)
4599 g_warning (mixed_api_warning);
4603 priv->api_mode = OLD_API;
4608 gtk_toolbar_check_new_api (GtkToolbar *toolbar)
4610 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
4612 if (priv->api_mode == OLD_API)
4614 g_warning (mixed_api_warning);
4618 priv->api_mode = NEW_API;
4622 /* GTK+ internal methods */
4625 _gtk_toolbar_get_default_space_size (void)
4627 return DEFAULT_SPACE_SIZE;
4631 _gtk_toolbar_paint_space_line (GtkWidget *widget,
4632 GtkToolbar *toolbar,
4634 GtkAllocation *allocation)
4636 const double start_fraction = (SPACE_LINE_START / SPACE_LINE_DIVISION);
4637 const double end_fraction = (SPACE_LINE_END / SPACE_LINE_DIVISION);
4639 GtkToolbarSpaceStyle space_style;
4640 GtkOrientation orientation;
4642 g_return_if_fail (GTK_IS_WIDGET (widget));
4644 space_style = toolbar? get_space_style (toolbar) : DEFAULT_SPACE_STYLE;
4645 orientation = toolbar? toolbar->orientation : GTK_ORIENTATION_HORIZONTAL;
4647 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4649 gtk_paint_vline (widget->style, widget->window,
4650 GTK_WIDGET_STATE (widget), area, widget,
4652 allocation->y + allocation->height * start_fraction,
4653 allocation->y + allocation->height * end_fraction,
4654 allocation->x + (allocation->width - widget->style->xthickness) / 2);
4658 gtk_paint_hline (widget->style, widget->window,
4659 GTK_WIDGET_STATE (widget), area, widget,
4661 allocation->x + allocation->width * start_fraction,
4662 allocation->x + allocation->width * end_fraction,
4663 allocation->y + (allocation->height - widget->style->ythickness) / 2);
4668 _gtk_toolbar_elide_underscores (const gchar *original)
4672 gboolean last_underscore;
4674 q = result = g_malloc (strlen (original) + 1);
4675 last_underscore = FALSE;
4677 for (p = original; *p; p++)
4679 if (!last_underscore && *p == '_')
4680 last_underscore = TRUE;
4683 last_underscore = FALSE;