1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 * GtkToolbar copyright (C) Federico Mena
5 * Copyright (C) 2002 Anders Carlsson <andersca@gnome.org>
6 * Copyright (C) 2002 James Henstridge <james@daa.com.au>
7 * Copyright (C) 2003, 2004 Soeren Sandmann <sandmann@daimi.au.dk>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
26 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
27 * file for a list of people on the GTK+ Team. See the ChangeLog
28 * files for a list of changes. These files are distributed with
29 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
32 #undef GTK_DISABLE_DEPRECATED
36 #include "gtktoolbar.h"
37 #include "gtkradiotoolbutton.h"
38 #include "gtkseparatortoolitem.h"
40 #include "gtkradiobutton.h"
41 #include "gtktoolbar.h"
42 #include "gtkbindings.h"
43 #include <gdk/gdkkeysyms.h>
44 #include "gtkmarshalers.h"
48 #include "gtkprivate.h"
55 typedef struct _ToolbarContent ToolbarContent;
57 #define DEFAULT_IPADDING 0
59 #define DEFAULT_SPACE_SIZE 12
60 #define DEFAULT_SPACE_STYLE GTK_TOOLBAR_SPACE_LINE
61 #define SPACE_LINE_DIVISION 10.0
62 #define SPACE_LINE_START 2.0
63 #define SPACE_LINE_END 8.0
65 #define DEFAULT_ICON_SIZE GTK_ICON_SIZE_LARGE_TOOLBAR
66 #define DEFAULT_TOOLBAR_STYLE GTK_TOOLBAR_BOTH
68 #define MAX_HOMOGENEOUS_N_CHARS 13 /* Items that are wider than this do not participate
69 * in the homogeneous game. In units of
70 * pango_font_get_estimated_char_width().
72 #define SLIDE_SPEED 600 /* How fast the items slide, in pixels per second */
82 /* Child properties */
86 CHILD_PROP_HOMOGENEOUS
118 struct _GtkToolbarPrivate
123 GtkWidget * arrow_button;
127 GdkWindow * event_window;
129 GtkSettings * settings;
131 GtkToolItem * highlight_tool_item;
132 gint max_homogeneous_pixels;
136 guint show_arrow : 1;
138 guint is_sliding : 1;
141 static void gtk_toolbar_init (GtkToolbar *toolbar);
142 static void gtk_toolbar_class_init (GtkToolbarClass *klass);
143 static void gtk_toolbar_set_property (GObject *object,
147 static void gtk_toolbar_get_property (GObject *object,
151 static gint gtk_toolbar_expose (GtkWidget *widget,
152 GdkEventExpose *event);
153 static void gtk_toolbar_realize (GtkWidget *widget);
154 static void gtk_toolbar_unrealize (GtkWidget *widget);
155 static void gtk_toolbar_size_request (GtkWidget *widget,
156 GtkRequisition *requisition);
157 static void gtk_toolbar_size_allocate (GtkWidget *widget,
158 GtkAllocation *allocation);
159 static void gtk_toolbar_style_set (GtkWidget *widget,
160 GtkStyle *prev_style);
161 static gboolean gtk_toolbar_focus (GtkWidget *widget,
162 GtkDirectionType dir);
163 static void gtk_toolbar_screen_changed (GtkWidget *widget,
164 GdkScreen *previous_screen);
165 static void gtk_toolbar_map (GtkWidget *widget);
166 static void gtk_toolbar_unmap (GtkWidget *widget);
167 static void gtk_toolbar_set_child_property (GtkContainer *container,
172 static void gtk_toolbar_get_child_property (GtkContainer *container,
177 static void gtk_toolbar_finalize (GObject *object);
178 static void gtk_toolbar_show_all (GtkWidget *widget);
179 static void gtk_toolbar_hide_all (GtkWidget *widget);
180 static void gtk_toolbar_add (GtkContainer *container,
182 static void gtk_toolbar_remove (GtkContainer *container,
184 static void gtk_toolbar_forall (GtkContainer *container,
185 gboolean include_internals,
186 GtkCallback callback,
187 gpointer callback_data);
188 static GType gtk_toolbar_child_type (GtkContainer *container);
189 static void gtk_toolbar_orientation_changed (GtkToolbar *toolbar,
190 GtkOrientation orientation);
191 static void gtk_toolbar_real_style_changed (GtkToolbar *toolbar,
192 GtkToolbarStyle style);
193 static gboolean gtk_toolbar_move_focus (GtkToolbar *toolbar,
194 GtkDirectionType dir);
195 static gboolean gtk_toolbar_focus_home_or_end (GtkToolbar *toolbar,
196 gboolean focus_home);
197 static gboolean gtk_toolbar_button_press (GtkWidget *toolbar,
198 GdkEventButton *event);
199 static gboolean gtk_toolbar_arrow_button_press (GtkWidget *button,
200 GdkEventButton *event,
201 GtkToolbar *toolbar);
202 static void gtk_toolbar_arrow_button_clicked (GtkWidget *button,
203 GtkToolbar *toolbar);
204 static void gtk_toolbar_update_button_relief (GtkToolbar *toolbar);
205 static gboolean gtk_toolbar_popup_menu (GtkWidget *toolbar);
206 static GtkWidget *internal_insert_element (GtkToolbar *toolbar,
207 GtkToolbarChildType type,
210 const char *tooltip_text,
211 const char *tooltip_private_text,
213 GtkSignalFunc callback,
217 static void gtk_toolbar_reconfigured (GtkToolbar *toolbar);
218 static gboolean gtk_toolbar_check_new_api (GtkToolbar *toolbar);
219 static gboolean gtk_toolbar_check_old_api (GtkToolbar *toolbar);
221 static GtkReliefStyle get_button_relief (GtkToolbar *toolbar);
222 static gint get_internal_padding (GtkToolbar *toolbar);
223 static GtkShadowType get_shadow_type (GtkToolbar *toolbar);
224 static gint get_space_size (GtkToolbar *toolbar);
225 static GtkToolbarSpaceStyle get_space_style (GtkToolbar *toolbar);
227 /* methods on ToolbarContent 'class' */
228 static ToolbarContent *toolbar_content_new_tool_item (GtkToolbar *toolbar,
230 gboolean is_placeholder,
232 static ToolbarContent *toolbar_content_new_compatibility (GtkToolbar *toolbar,
233 GtkToolbarChildType type,
238 static void toolbar_content_remove (ToolbarContent *content,
239 GtkToolbar *toolbar);
240 static void toolbar_content_free (ToolbarContent *content);
241 static void toolbar_content_expose (ToolbarContent *content,
242 GtkContainer *container,
243 GdkEventExpose *expose);
244 static gboolean toolbar_content_visible (ToolbarContent *content,
245 GtkToolbar *toolbar);
246 static void toolbar_content_size_request (ToolbarContent *content,
248 GtkRequisition *requisition);
249 static gboolean toolbar_content_is_homogeneous (ToolbarContent *content,
250 GtkToolbar *toolbar);
251 static gboolean toolbar_content_is_placeholder (ToolbarContent *content);
252 static gboolean toolbar_content_disappearing (ToolbarContent *content);
253 static ItemState toolbar_content_get_state (ToolbarContent *content);
254 static gboolean toolbar_content_child_visible (ToolbarContent *content);
255 static void toolbar_content_get_goal_allocation (ToolbarContent *content,
256 GtkAllocation *allocation);
257 static void toolbar_content_get_allocation (ToolbarContent *content,
258 GtkAllocation *allocation);
259 static void toolbar_content_set_start_allocation (ToolbarContent *content,
260 GtkAllocation *new_start_allocation);
261 static void toolbar_content_get_start_allocation (ToolbarContent *content,
262 GtkAllocation *start_allocation);
263 static gboolean toolbar_content_get_expand (ToolbarContent *content);
264 static void toolbar_content_set_goal_allocation (ToolbarContent *content,
265 GtkAllocation *allocation);
266 static void toolbar_content_set_child_visible (ToolbarContent *content,
269 static void toolbar_content_size_allocate (ToolbarContent *content,
270 GtkAllocation *allocation);
271 static void toolbar_content_set_state (ToolbarContent *content,
272 ItemState new_state);
273 static GtkWidget * toolbar_content_get_widget (ToolbarContent *content);
274 static void toolbar_content_set_disappearing (ToolbarContent *content,
275 gboolean disappearing);
276 static void toolbar_content_set_size_request (ToolbarContent *content,
279 static void toolbar_content_toolbar_reconfigured (ToolbarContent *content,
280 GtkToolbar *toolbar);
281 static GtkWidget * toolbar_content_retrieve_menu_item (ToolbarContent *content);
282 static gboolean toolbar_content_is_separator (ToolbarContent *content);
283 static void toolbar_content_show_all (ToolbarContent *content);
284 static void toolbar_content_hide_all (ToolbarContent *content);
287 #define GTK_TOOLBAR_GET_PRIVATE(o) \
288 (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_TOOLBAR, GtkToolbarPrivate))
290 static GtkContainerClass * parent_class = NULL;
291 static guint toolbar_signals [LAST_SIGNAL] = { 0 };
294 gtk_toolbar_get_type (void)
296 static GtkType type = 0;
300 static const GTypeInfo type_info =
302 sizeof (GtkToolbarClass),
303 (GBaseInitFunc) NULL,
304 (GBaseFinalizeFunc) NULL,
305 (GClassInitFunc) gtk_toolbar_class_init,
306 (GClassFinalizeFunc) NULL,
310 (GInstanceInitFunc) gtk_toolbar_init,
313 type = g_type_register_static (GTK_TYPE_CONTAINER,
322 add_arrow_bindings (GtkBindingSet *binding_set,
324 GtkDirectionType dir)
326 guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
328 gtk_binding_entry_add_signal (binding_set, keysym, 0,
330 GTK_TYPE_DIRECTION_TYPE, dir);
331 gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
333 GTK_TYPE_DIRECTION_TYPE, dir);
337 add_ctrl_tab_bindings (GtkBindingSet *binding_set,
338 GdkModifierType modifiers,
339 GtkDirectionType direction)
341 gtk_binding_entry_add_signal (binding_set,
342 GDK_Tab, GDK_CONTROL_MASK | modifiers,
344 GTK_TYPE_DIRECTION_TYPE, direction);
345 gtk_binding_entry_add_signal (binding_set,
346 GDK_KP_Tab, GDK_CONTROL_MASK | modifiers,
348 GTK_TYPE_DIRECTION_TYPE, direction);
352 gtk_toolbar_class_init (GtkToolbarClass *klass)
354 GObjectClass *gobject_class;
355 GtkWidgetClass *widget_class;
356 GtkContainerClass *container_class;
357 GtkBindingSet *binding_set;
359 parent_class = g_type_class_peek_parent (klass);
361 gobject_class = (GObjectClass *)klass;
362 widget_class = (GtkWidgetClass *)klass;
363 container_class = (GtkContainerClass *)klass;
365 gobject_class->set_property = gtk_toolbar_set_property;
366 gobject_class->get_property = gtk_toolbar_get_property;
367 gobject_class->finalize = gtk_toolbar_finalize;
369 widget_class->button_press_event = gtk_toolbar_button_press;
370 widget_class->expose_event = gtk_toolbar_expose;
371 widget_class->size_request = gtk_toolbar_size_request;
372 widget_class->size_allocate = gtk_toolbar_size_allocate;
373 widget_class->style_set = gtk_toolbar_style_set;
374 widget_class->focus = gtk_toolbar_focus;
375 widget_class->screen_changed = gtk_toolbar_screen_changed;
376 widget_class->realize = gtk_toolbar_realize;
377 widget_class->unrealize = gtk_toolbar_unrealize;
378 widget_class->map = gtk_toolbar_map;
379 widget_class->unmap = gtk_toolbar_unmap;
380 widget_class->popup_menu = gtk_toolbar_popup_menu;
381 widget_class->show_all = gtk_toolbar_show_all;
382 widget_class->hide_all = gtk_toolbar_hide_all;
384 container_class->add = gtk_toolbar_add;
385 container_class->remove = gtk_toolbar_remove;
386 container_class->forall = gtk_toolbar_forall;
387 container_class->child_type = gtk_toolbar_child_type;
388 container_class->get_child_property = gtk_toolbar_get_child_property;
389 container_class->set_child_property = gtk_toolbar_set_child_property;
391 klass->orientation_changed = gtk_toolbar_orientation_changed;
392 klass->style_changed = gtk_toolbar_real_style_changed;
395 * GtkToolbar::orientation-changed:
396 * @toolbar: the object which emitted the signal
397 * @orientation: the new #GtkOrientation of the toolbar
399 * Emitted when the orientation of the toolbar changes.
401 toolbar_signals[ORIENTATION_CHANGED] =
402 g_signal_new ("orientation-changed",
403 G_OBJECT_CLASS_TYPE (klass),
405 G_STRUCT_OFFSET (GtkToolbarClass, orientation_changed),
407 g_cclosure_marshal_VOID__ENUM,
409 GTK_TYPE_ORIENTATION);
411 * GtkToolbar::style-changed:
412 * @toolbar: The #GtkToolbar which emitted the signal
413 * @style: the new #GtkToolbarStyle of the toolbar
415 * Emitted when the style of the toolbar changes.
417 toolbar_signals[STYLE_CHANGED] =
418 g_signal_new ("style-changed",
419 G_OBJECT_CLASS_TYPE (klass),
421 G_STRUCT_OFFSET (GtkToolbarClass, style_changed),
423 g_cclosure_marshal_VOID__ENUM,
425 GTK_TYPE_TOOLBAR_STYLE);
427 * GtkToolbar::popup-context-menu:
428 * @toolbar: the #GtkToolbar which emitted the signal
429 * @x: the x coordinate of the point where the menu should appear
430 * @y: the y coordinate of the point where the menu should appear
431 * @button: the mouse button the user pressed, or -1
433 * Emitted when the user right-clicks the toolbar or uses the
434 * keybinding to display a popup menu.
436 * Application developers should handle this signal if they want
437 * to display a context menu on the toolbar. The context-menu should
438 * appear at the coordinates given by @x and @y. The mouse button
439 * number is given by the @button parameter. If the menu was popped
440 * up using the keybaord, @button is -1.
442 * Return value: return %TRUE if the signal was handled, %FALSE if not
444 toolbar_signals[POPUP_CONTEXT_MENU] =
445 g_signal_new ("popup_context_menu",
446 G_OBJECT_CLASS_TYPE (klass),
448 G_STRUCT_OFFSET (GtkToolbarClass, popup_context_menu),
449 _gtk_boolean_handled_accumulator, NULL,
450 _gtk_marshal_BOOLEAN__INT_INT_INT,
452 G_TYPE_INT, G_TYPE_INT,
455 * GtkToolbar::move-focus:
456 * @toolbar: the #GtkToolbar which emitted the signal
457 * @dir: a #GtkDirection
459 * A keybinding signal used internally by GTK+. This signal can't
460 * be used in application code.
462 * Return value: %TRUE if the signal was handled, %FALSE if not
464 toolbar_signals[MOVE_FOCUS] =
465 _gtk_binding_signal_new ("move_focus",
466 G_TYPE_FROM_CLASS (klass),
467 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
468 G_CALLBACK (gtk_toolbar_move_focus),
470 _gtk_marshal_BOOLEAN__ENUM,
472 GTK_TYPE_DIRECTION_TYPE);
474 * GtkToolbar::focus-home-or-end:
475 * @toolbar: the #GtkToolbar which emitted the signal
476 * @focus_home: %TRUE if the first item should be focused
478 * A keybinding signal used internally by GTK+. This signal can't
479 * be used in application code
481 * Return value: %TRUE if the signal was handled, %FALSE if not
483 toolbar_signals[FOCUS_HOME_OR_END] =
484 _gtk_binding_signal_new ("focus_home_or_end",
485 G_OBJECT_CLASS_TYPE (klass),
486 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
487 G_CALLBACK (gtk_toolbar_focus_home_or_end),
489 _gtk_marshal_BOOLEAN__BOOLEAN,
494 g_object_class_install_property (gobject_class,
496 g_param_spec_enum ("orientation",
498 P_("The orientation of the toolbar"),
499 GTK_TYPE_ORIENTATION,
500 GTK_ORIENTATION_HORIZONTAL,
503 g_object_class_install_property (gobject_class,
505 g_param_spec_enum ("toolbar_style",
507 P_("How to draw the toolbar"),
508 GTK_TYPE_TOOLBAR_STYLE,
511 g_object_class_install_property (gobject_class,
513 g_param_spec_boolean ("show_arrow",
515 P_("If an arrow should be shown if the toolbar doesn't fit"),
519 /* child properties */
520 gtk_container_class_install_child_property (container_class,
522 g_param_spec_boolean ("expand",
524 P_("Whether the item should receive extra space when the toolbar grows"),
528 gtk_container_class_install_child_property (container_class,
529 CHILD_PROP_HOMOGENEOUS,
530 g_param_spec_boolean ("homogeneous",
532 P_("Whether the item should be the same size as other homogeneous items"),
536 /* style properties */
537 gtk_widget_class_install_style_property (widget_class,
538 g_param_spec_int ("space_size",
540 P_("Size of spacers"),
546 gtk_widget_class_install_style_property (widget_class,
547 g_param_spec_int ("internal_padding",
548 P_("Internal padding"),
549 P_("Amount of border space between the toolbar shadow and the buttons"),
555 gtk_widget_class_install_style_property (widget_class,
556 g_param_spec_enum ("space_style",
558 P_("Whether spacers are vertical lines or just blank"),
559 GTK_TYPE_TOOLBAR_SPACE_STYLE,
563 gtk_widget_class_install_style_property (widget_class,
564 g_param_spec_enum ("button_relief",
566 P_("Type of bevel around toolbar buttons"),
567 GTK_TYPE_RELIEF_STYLE,
570 gtk_widget_class_install_style_property (widget_class,
571 g_param_spec_enum ("shadow_type",
573 P_("Style of bevel around the toolbar"),
574 GTK_TYPE_SHADOW_TYPE,
578 gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-style",
580 P_("Whether default toolbars have text only, text and icons, icons only, etc."),
581 GTK_TYPE_TOOLBAR_STYLE,
582 DEFAULT_TOOLBAR_STYLE,
585 gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-icon-size",
586 P_("Toolbar icon size"),
587 P_("Size of icons in default toolbars"),
592 binding_set = gtk_binding_set_by_class (klass);
594 add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
595 add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
596 add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
597 add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
599 gtk_binding_entry_add_signal (binding_set, GDK_KP_Home, 0,
600 "focus_home_or_end", 1,
601 G_TYPE_BOOLEAN, TRUE);
602 gtk_binding_entry_add_signal (binding_set, GDK_Home, 0,
603 "focus_home_or_end", 1,
604 G_TYPE_BOOLEAN, TRUE);
605 gtk_binding_entry_add_signal (binding_set, GDK_KP_End, 0,
606 "focus_home_or_end", 1,
607 G_TYPE_BOOLEAN, FALSE);
608 gtk_binding_entry_add_signal (binding_set, GDK_End, 0,
609 "focus_home_or_end", 1,
610 G_TYPE_BOOLEAN, FALSE);
612 add_ctrl_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
613 add_ctrl_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
615 g_type_class_add_private (gobject_class, sizeof (GtkToolbarPrivate));
619 gtk_toolbar_init (GtkToolbar *toolbar)
621 GtkToolbarPrivate *priv;
623 GTK_WIDGET_UNSET_FLAGS (toolbar, GTK_CAN_FOCUS);
624 GTK_WIDGET_SET_FLAGS (toolbar, GTK_NO_WINDOW);
626 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
628 toolbar->orientation = GTK_ORIENTATION_HORIZONTAL;
629 toolbar->style = DEFAULT_TOOLBAR_STYLE;
630 toolbar->icon_size = DEFAULT_ICON_SIZE;
631 toolbar->tooltips = gtk_tooltips_new ();
632 g_object_ref (toolbar->tooltips);
633 gtk_object_sink (GTK_OBJECT (toolbar->tooltips));
635 priv->arrow_button = gtk_toggle_button_new ();
636 g_signal_connect (priv->arrow_button, "button_press_event",
637 G_CALLBACK (gtk_toolbar_arrow_button_press), toolbar);
638 g_signal_connect (priv->arrow_button, "clicked",
639 G_CALLBACK (gtk_toolbar_arrow_button_clicked), toolbar);
640 gtk_button_set_relief (GTK_BUTTON (priv->arrow_button),
641 get_button_relief (toolbar));
643 priv->api_mode = DONT_KNOW;
645 gtk_button_set_focus_on_click (GTK_BUTTON (priv->arrow_button), FALSE);
647 priv->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
648 gtk_widget_set_name (priv->arrow, "gtk-toolbar-arrow");
649 gtk_widget_show (priv->arrow);
650 gtk_container_add (GTK_CONTAINER (priv->arrow_button), priv->arrow);
652 gtk_widget_set_parent (priv->arrow_button, GTK_WIDGET (toolbar));
654 /* which child position a drop will occur at */
656 priv->show_arrow = TRUE;
657 priv->settings = NULL;
659 priv->max_homogeneous_pixels = -1;
661 priv->timer = g_timer_new ();
665 gtk_toolbar_set_property (GObject *object,
670 GtkToolbar *toolbar = GTK_TOOLBAR (object);
674 case PROP_ORIENTATION:
675 gtk_toolbar_set_orientation (toolbar, g_value_get_enum (value));
677 case PROP_TOOLBAR_STYLE:
678 gtk_toolbar_set_style (toolbar, g_value_get_enum (value));
680 case PROP_SHOW_ARROW:
681 gtk_toolbar_set_show_arrow (toolbar, g_value_get_boolean (value));
684 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
690 gtk_toolbar_get_property (GObject *object,
695 GtkToolbar *toolbar = GTK_TOOLBAR (object);
696 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
700 case PROP_ORIENTATION:
701 g_value_set_enum (value, toolbar->orientation);
703 case PROP_TOOLBAR_STYLE:
704 g_value_set_enum (value, toolbar->style);
706 case PROP_SHOW_ARROW:
707 g_value_set_boolean (value, priv->show_arrow);
710 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
716 gtk_toolbar_map (GtkWidget *widget)
718 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
720 GTK_WIDGET_CLASS (parent_class)->map (widget);
722 if (priv->event_window)
723 gdk_window_show_unraised (priv->event_window);
727 gtk_toolbar_unmap (GtkWidget *widget)
729 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
731 if (priv->event_window)
732 gdk_window_hide (priv->event_window);
734 GTK_WIDGET_CLASS (parent_class)->unmap (widget);
738 gtk_toolbar_realize (GtkWidget *widget)
740 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
741 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
743 GdkWindowAttr attributes;
744 gint attributes_mask;
747 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
749 border_width = GTK_CONTAINER (widget)->border_width;
751 attributes.wclass = GDK_INPUT_ONLY;
752 attributes.window_type = GDK_WINDOW_CHILD;
753 attributes.x = widget->allocation.x + border_width;
754 attributes.y = widget->allocation.y + border_width;
755 attributes.width = widget->allocation.width - border_width * 2;
756 attributes.height = widget->allocation.height - border_width * 2;
757 attributes.event_mask = gtk_widget_get_events (widget);
758 attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
759 GDK_BUTTON_RELEASE_MASK |
760 GDK_ENTER_NOTIFY_MASK |
761 GDK_LEAVE_NOTIFY_MASK);
763 attributes_mask = GDK_WA_X | GDK_WA_Y;
765 widget->window = gtk_widget_get_parent_window (widget);
766 g_object_ref (widget->window);
767 widget->style = gtk_style_attach (widget->style, widget->window);
769 priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget),
770 &attributes, attributes_mask);
771 gdk_window_set_user_data (priv->event_window, toolbar);
775 gtk_toolbar_unrealize (GtkWidget *widget)
777 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
779 if (priv->event_window)
781 gdk_window_set_user_data (priv->event_window, NULL);
782 gdk_window_destroy (priv->event_window);
783 priv->event_window = NULL;
786 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
787 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
791 gtk_toolbar_expose (GtkWidget *widget,
792 GdkEventExpose *event)
794 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
795 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
800 border_width = GTK_CONTAINER (widget)->border_width;
802 if (GTK_WIDGET_DRAWABLE (widget))
804 gtk_paint_box (widget->style,
806 GTK_WIDGET_STATE (widget),
807 get_shadow_type (toolbar),
808 &event->area, widget, "toolbar",
809 border_width + widget->allocation.x,
810 border_width + widget->allocation.y,
811 widget->allocation.width - 2 * border_width,
812 widget->allocation.height - 2 * border_width);
815 for (list = priv->content; list != NULL; list = list->next)
817 ToolbarContent *content = list->data;
819 toolbar_content_expose (content, GTK_CONTAINER (widget), event);
822 gtk_container_propagate_expose (GTK_CONTAINER (widget),
830 gtk_toolbar_size_request (GtkWidget *widget,
831 GtkRequisition *requisition)
833 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
834 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
836 gint max_child_height;
837 gint max_child_width;
838 gint max_homogeneous_child_width;
839 gint max_homogeneous_child_height;
840 gint homogeneous_size;
842 gint pack_front_size;
844 GtkRequisition arrow_requisition;
846 max_homogeneous_child_width = 0;
847 max_homogeneous_child_height = 0;
849 max_child_height = 0;
850 for (list = priv->content; list != NULL; list = list->next)
852 GtkRequisition requisition;
853 ToolbarContent *content = list->data;
855 if (!toolbar_content_visible (content, toolbar))
858 toolbar_content_size_request (content, toolbar, &requisition);
860 max_child_width = MAX (max_child_width, requisition.width);
861 max_child_height = MAX (max_child_height, requisition.height);
863 if (toolbar_content_is_homogeneous (content, toolbar))
865 max_homogeneous_child_width = MAX (max_homogeneous_child_width, requisition.width);
866 max_homogeneous_child_height = MAX (max_homogeneous_child_height, requisition.height);
870 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
871 homogeneous_size = max_homogeneous_child_width;
873 homogeneous_size = max_homogeneous_child_height;
876 for (list = priv->content; list != NULL; list = list->next)
878 ToolbarContent *content = list->data;
881 if (!toolbar_content_visible (content, toolbar))
884 if (toolbar_content_is_homogeneous (content, toolbar))
886 size = homogeneous_size;
890 GtkRequisition requisition;
892 toolbar_content_size_request (content, toolbar, &requisition);
894 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
895 size = requisition.width;
897 size = requisition.height;
900 pack_front_size += size;
903 if (priv->show_arrow && priv->api_mode == NEW_API)
905 gtk_widget_size_request (priv->arrow_button, &arrow_requisition);
907 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
908 long_req = arrow_requisition.width;
910 long_req = arrow_requisition.height;
912 /* There is no point requesting space for the arrow if that would take
913 * up more space than all the items combined
915 long_req = MIN (long_req, pack_front_size);
919 arrow_requisition.height = 0;
920 arrow_requisition.width = 0;
922 long_req = pack_front_size;
925 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
927 requisition->width = long_req;
928 requisition->height = MAX (max_child_height, arrow_requisition.height);
932 requisition->height = long_req;
933 requisition->width = MAX (max_child_width, arrow_requisition.width);
937 ipadding = get_internal_padding (toolbar);
939 requisition->width += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width);
940 requisition->height += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width);
942 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
944 requisition->width += 2 * widget->style->xthickness;
945 requisition->height += 2 * widget->style->ythickness;
948 toolbar->button_maxw = max_homogeneous_child_width;
949 toolbar->button_maxh = max_homogeneous_child_height;
953 position (gint from, gint to, gdouble elapsed)
956 return MIN (from + SLIDE_SPEED * elapsed, to);
958 return MAX (from - SLIDE_SPEED * elapsed, to);
962 compute_intermediate_allocation (GtkToolbar *toolbar,
963 const GtkAllocation *start,
964 const GtkAllocation *goal,
965 GtkAllocation *intermediate)
967 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
968 gdouble elapsed = g_timer_elapsed (priv->timer, NULL);
970 intermediate->x = position (start->x, goal->x, elapsed);
971 intermediate->y = position (start->y, goal->y, elapsed);
972 intermediate->width =
973 position (start->x + start->width, goal->x + goal->width, elapsed) - intermediate->x;
974 intermediate->height =
975 position (start->y + start->height, goal->y + goal->height, elapsed) - intermediate->y;
979 fixup_allocation_for_rtl (gint total_size,
980 GtkAllocation *allocation)
982 allocation->x += (total_size - (2 * allocation->x + allocation->width));
986 fixup_allocation_for_vertical (GtkAllocation *allocation)
991 allocation->x = allocation->y;
994 tmp = allocation->width;
995 allocation->width = allocation->height;
996 allocation->height = tmp;
1000 get_item_size (GtkToolbar *toolbar,
1001 ToolbarContent *content)
1003 GtkRequisition requisition;
1005 toolbar_content_size_request (content, toolbar, &requisition);
1007 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1009 if (toolbar_content_is_homogeneous (content, toolbar))
1010 return toolbar->button_maxw;
1012 return requisition.width;
1016 if (toolbar_content_is_homogeneous (content, toolbar))
1017 return toolbar->button_maxh;
1019 return requisition.height;
1024 slide_idle_handler (gpointer data)
1026 GtkToolbar *toolbar = data;
1027 GtkToolbarPrivate *priv;
1030 GDK_THREADS_ENTER ();
1032 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1034 if (priv->need_sync)
1037 priv->need_sync = FALSE;
1040 for (list = priv->content; list != NULL; list = list->next)
1042 ToolbarContent *content = list->data;
1044 GtkAllocation goal_allocation;
1045 GtkAllocation allocation;
1048 state = toolbar_content_get_state (content);
1049 toolbar_content_get_goal_allocation (content, &goal_allocation);
1050 toolbar_content_get_allocation (content, &allocation);
1054 if (state == NOT_ALLOCATED)
1056 /* an unallocated item means that size allocate has to
1057 * called at least once more
1062 /* An invisible item with a goal allocation of
1063 * 0 is already at its goal.
1065 if ((state == NORMAL || state == OVERFLOWN) &&
1066 ((goal_allocation.width != 0 &&
1067 goal_allocation.height != 0) ||
1068 toolbar_content_child_visible (content)))
1070 if ((goal_allocation.x != allocation.x ||
1071 goal_allocation.y != allocation.y ||
1072 goal_allocation.width != allocation.width ||
1073 goal_allocation.height != allocation.height))
1075 /* An item is not in its right position yet. Note
1076 * that OVERFLOWN items do get an allocation in
1077 * gtk_toolbar_size_allocate(). This way you can see
1078 * them slide back in when you drag an item off the
1085 if (toolbar_content_is_placeholder (content) &&
1086 toolbar_content_disappearing (content) &&
1087 toolbar_content_child_visible (content))
1089 /* A disappearing placeholder is still visible.
1097 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (toolbar));
1099 GDK_THREADS_LEAVE ();
1104 priv->is_sliding = FALSE;
1107 GDK_THREADS_LEAVE();
1112 rect_within (GtkAllocation *a1,
1115 return (a1->x >= a2->x &&
1116 a1->x + a1->width <= a2->x + a2->width &&
1118 a1->y + a1->height <= a2->y + a2->height);
1122 gtk_toolbar_begin_sliding (GtkToolbar *toolbar)
1124 GtkWidget *widget = GTK_WIDGET (toolbar);
1125 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1133 /* Start the sliding. This function copies the allocation of every
1134 * item into content->start_allocation. For items that haven't
1135 * been allocated yet, we calculate their position and save that
1136 * in start_allocatino along with zero width and zero height.
1138 priv->is_sliding = TRUE;
1141 priv->idle_id = g_idle_add (slide_idle_handler, toolbar);
1143 rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
1144 vertical = (toolbar->orientation == GTK_ORIENTATION_VERTICAL);
1145 border_width = get_internal_padding (toolbar) + GTK_CONTAINER (toolbar)->border_width;
1149 cur_x = widget->allocation.width - border_width - widget->style->xthickness;
1150 cur_y = widget->allocation.height - border_width - widget->style->ythickness;
1154 cur_x = border_width + widget->style->xthickness;
1155 cur_y = border_width + widget->style->ythickness;
1158 cur_x += widget->allocation.x;
1159 cur_y += widget->allocation.y;
1161 for (list = priv->content; list != NULL; list = list->next)
1163 ToolbarContent *content = list->data;
1164 GtkAllocation new_start_allocation;
1165 GtkAllocation item_allocation;
1168 state = toolbar_content_get_state (content);
1169 toolbar_content_get_allocation (content, &item_allocation);
1171 if ((state == NORMAL &&
1172 rect_within (&item_allocation, &(widget->allocation))) ||
1175 new_start_allocation = item_allocation;
1179 new_start_allocation.x = cur_x;
1180 new_start_allocation.y = cur_y;
1184 new_start_allocation.width = widget->allocation.width -
1185 2 * border_width - 2 * widget->style->xthickness;
1186 new_start_allocation.height = 0;
1190 new_start_allocation.width = 0;
1191 new_start_allocation.height = widget->allocation.height -
1192 2 * border_width - 2 * widget->style->ythickness;
1197 cur_y = new_start_allocation.y + new_start_allocation.height;
1199 cur_x = new_start_allocation.x;
1201 cur_x = new_start_allocation.x + new_start_allocation.width;
1203 toolbar_content_set_start_allocation (content, &new_start_allocation);
1206 /* This resize will run before the first idle handler. This
1207 * will make sure that items get the right goal allocatiuon
1208 * so that the idle handler will not immediately return
1211 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (toolbar));
1212 g_timer_reset (priv->timer);
1216 gtk_toolbar_stop_sliding (GtkToolbar *toolbar)
1218 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1220 if (priv->is_sliding)
1224 priv->is_sliding = FALSE;
1228 g_source_remove (priv->idle_id);
1232 list = priv->content;
1235 ToolbarContent *content = list->data;
1238 if (toolbar_content_is_placeholder (content))
1240 toolbar_content_remove (content, toolbar);
1241 toolbar_content_free (content);
1245 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (toolbar));
1250 gtk_toolbar_size_allocate (GtkWidget *widget,
1251 GtkAllocation *allocation)
1253 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1254 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1255 GtkAllocation *allocations;
1256 ItemState *new_states;
1257 GtkAllocation arrow_allocation;
1259 gint size, pos, short_size;
1262 gboolean need_arrow;
1263 gint n_expand_items;
1265 gint available_size;
1268 GtkRequisition arrow_requisition;
1269 gboolean overflowing;
1270 gboolean size_changed;
1272 GtkAllocation item_area;
1274 size_changed = FALSE;
1275 if (widget->allocation.x != allocation->x ||
1276 widget->allocation.y != allocation->y ||
1277 widget->allocation.width != allocation->width ||
1278 widget->allocation.height != allocation->height)
1280 size_changed = TRUE;
1284 gtk_toolbar_stop_sliding (toolbar);
1286 widget->allocation = *allocation;
1288 border_width = GTK_CONTAINER (toolbar)->border_width;
1290 if (GTK_WIDGET_REALIZED (widget))
1292 gdk_window_move_resize (priv->event_window,
1293 allocation->x + border_width,
1294 allocation->y + border_width,
1295 allocation->width - border_width * 2,
1296 allocation->height - border_width * 2);
1299 border_width += get_internal_padding (toolbar);
1301 gtk_widget_get_child_requisition (GTK_WIDGET (priv->arrow_button),
1302 &arrow_requisition);
1304 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
1306 available_size = size = allocation->width - 2 * border_width;
1307 short_size = allocation->height - 2 * border_width;
1308 arrow_size = arrow_requisition.width;
1310 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1312 available_size -= 2 * widget->style->xthickness;
1313 short_size -= 2 * widget->style->ythickness;
1318 available_size = size = allocation->height - 2 * border_width;
1319 short_size = allocation->width - 2 * border_width;
1320 arrow_size = arrow_requisition.height;
1322 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1324 available_size -= 2 * widget->style->ythickness;
1325 short_size -= 2 * widget->style->xthickness;
1329 n_items = g_list_length (priv->content);
1330 allocations = g_new0 (GtkAllocation, n_items);
1331 new_states = g_new0 (ItemState, n_items);
1334 for (list = priv->content; list != NULL; list = list->next)
1336 ToolbarContent *content = list->data;
1338 if (toolbar_content_visible (content, toolbar))
1339 needed_size += get_item_size (toolbar, content);
1342 need_arrow = (needed_size > available_size) && priv->show_arrow && priv->api_mode == NEW_API;
1345 size = available_size - arrow_size;
1347 size = available_size;
1349 /* calculate widths of items */
1350 overflowing = FALSE;
1351 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1353 ToolbarContent *content = list->data;
1356 if (!toolbar_content_visible (content, toolbar))
1358 new_states[i] = HIDDEN;
1362 item_size = get_item_size (toolbar, content);
1363 if (item_size <= size && !overflowing)
1366 allocations[i].width = item_size;
1367 new_states[i] = NORMAL;
1372 new_states[i] = OVERFLOWN;
1373 allocations[i].width = item_size;
1377 /* calculate width of arrow */
1380 arrow_allocation.width = arrow_size;
1381 arrow_allocation.height = short_size;
1384 /* expand expandable items */
1386 /* We don't expand when there is an overflow menu, because that leads to
1387 * weird jumps when items get moved to the overflow menu and the expanding
1388 * items suddenly get a lot of extra space
1393 for (i = 0, list = priv->content; list != NULL; list = list->next, ++i)
1395 ToolbarContent *content = list->data;
1397 if (toolbar_content_get_expand (content) && new_states[i] == NORMAL)
1401 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1403 ToolbarContent *content = list->data;
1405 if (toolbar_content_get_expand (content) && new_states[i] == NORMAL)
1407 gint extra = size / n_expand_items;
1408 if (size % n_expand_items != 0)
1411 allocations[i].width += extra;
1417 g_assert (n_expand_items == 0);
1420 /* position items */
1422 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1424 /* both NORMAL and OVERFLOWN items get a position. This ensures
1425 * that sliding will work for OVERFLOWN items too
1427 if (new_states[i] == NORMAL ||
1428 new_states[i] == OVERFLOWN)
1430 allocations[i].x = pos;
1431 allocations[i].y = border_width;
1432 allocations[i].height = short_size;
1434 pos += allocations[i].width;
1438 /* position arrow */
1441 arrow_allocation.x = available_size - border_width - arrow_allocation.width;
1442 arrow_allocation.y = border_width;
1445 item_area.x = border_width;
1446 item_area.y = border_width;
1447 item_area.width = available_size - (need_arrow? arrow_size : 0);
1448 item_area.height = short_size;
1450 /* fix up allocations in the vertical or RTL cases */
1451 if (toolbar->orientation == GTK_ORIENTATION_VERTICAL)
1453 for (i = 0; i < n_items; ++i)
1454 fixup_allocation_for_vertical (&(allocations[i]));
1457 fixup_allocation_for_vertical (&arrow_allocation);
1459 fixup_allocation_for_vertical (&item_area);
1461 else if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
1463 for (i = 0; i < n_items; ++i)
1464 fixup_allocation_for_rtl (available_size, &(allocations[i]));
1467 fixup_allocation_for_rtl (available_size, &arrow_allocation);
1469 fixup_allocation_for_rtl (available_size, &item_area);
1472 /* translate the items by allocation->(x,y) */
1473 for (i = 0; i < n_items; ++i)
1475 allocations[i].x += allocation->x;
1476 allocations[i].y += allocation->y;
1478 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1480 allocations[i].x += widget->style->xthickness;
1481 allocations[i].y += widget->style->ythickness;
1487 arrow_allocation.x += allocation->x;
1488 arrow_allocation.y += allocation->y;
1490 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1492 arrow_allocation.x += widget->style->xthickness;
1493 arrow_allocation.y += widget->style->ythickness;
1497 item_area.x += allocation->x;
1498 item_area.y += allocation->y;
1499 if (get_shadow_type (toolbar) != GTK_SHADOW_NONE)
1501 item_area.x += widget->style->xthickness;
1502 item_area.y += widget->style->ythickness;
1505 /* did anything change? */
1506 for (list = priv->content, i = 0; list != NULL; list = list->next, i++)
1508 ToolbarContent *content = list->data;
1510 if (toolbar_content_get_state (content) == NORMAL &&
1511 new_states[i] != NORMAL)
1513 /* an item disappeared, begin sliding */
1514 if (!size_changed && priv->api_mode == NEW_API)
1515 gtk_toolbar_begin_sliding (toolbar);
1519 /* finally allocate the items */
1520 if (priv->is_sliding)
1522 for (list = priv->content, i = 0; list != NULL; list = list->next, i++)
1524 ToolbarContent *content = list->data;
1526 toolbar_content_set_goal_allocation (content, &(allocations[i]));
1530 elapsed = g_timer_elapsed (priv->timer, NULL);
1531 for (list = priv->content, i = 0; list != NULL; list = list->next, ++i)
1533 ToolbarContent *content = list->data;
1535 if (new_states[i] == OVERFLOWN ||
1536 new_states[i] == NORMAL)
1538 GtkAllocation alloc;
1539 GtkAllocation start_allocation;
1540 GtkAllocation goal_allocation;
1542 if (priv->is_sliding)
1544 toolbar_content_get_start_allocation (content, &start_allocation);
1545 toolbar_content_get_goal_allocation (content, &goal_allocation);
1547 compute_intermediate_allocation (toolbar,
1552 priv->need_sync = TRUE;
1556 alloc = allocations[i];
1559 if (alloc.width == 0 || alloc.height == 0)
1561 toolbar_content_set_child_visible (content, toolbar, FALSE);
1565 if (!rect_within (&alloc, &item_area))
1567 toolbar_content_set_child_visible (content, toolbar, FALSE);
1568 toolbar_content_size_allocate (content, &alloc);
1572 toolbar_content_set_child_visible (content, toolbar, TRUE);
1573 toolbar_content_size_allocate (content, &alloc);
1579 toolbar_content_set_child_visible (content, toolbar, FALSE);
1582 toolbar_content_set_state (content, new_states[i]);
1587 gtk_widget_size_allocate (GTK_WIDGET (priv->arrow_button),
1589 gtk_widget_show (GTK_WIDGET (priv->arrow_button));
1593 gtk_widget_hide (GTK_WIDGET (priv->arrow_button));
1596 g_free (allocations);
1597 g_free (new_states);
1601 gtk_toolbar_update_button_relief (GtkToolbar *toolbar)
1603 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1605 gtk_toolbar_reconfigured (toolbar);
1607 gtk_button_set_relief (GTK_BUTTON (priv->arrow_button), get_button_relief (toolbar));
1611 gtk_toolbar_style_set (GtkWidget *widget,
1612 GtkStyle *prev_style)
1614 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
1616 priv->max_homogeneous_pixels = -1;
1618 if (GTK_WIDGET_REALIZED (widget))
1619 gtk_style_set_background (widget->style, widget->window, widget->state);
1622 gtk_toolbar_update_button_relief (GTK_TOOLBAR (widget));
1626 gtk_toolbar_list_children_in_focus_order (GtkToolbar *toolbar,
1627 GtkDirectionType dir)
1629 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1630 GList *result = NULL;
1634 /* generate list of children in reverse logical order */
1636 for (list = priv->content; list != NULL; list = list->next)
1638 ToolbarContent *content = list->data;
1641 widget = toolbar_content_get_widget (content);
1644 result = g_list_prepend (result, widget);
1647 result = g_list_prepend (result, priv->arrow_button);
1649 rtl = (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL);
1651 /* move in logical order when
1653 * - dir is TAB_FORWARD
1655 * - in RTL mode and moving left or up
1657 * - in LTR mode and moving right or down
1659 if (dir == GTK_DIR_TAB_FORWARD ||
1660 (rtl && (dir == GTK_DIR_UP || dir == GTK_DIR_LEFT)) ||
1661 (!rtl && (dir == GTK_DIR_DOWN || dir == GTK_DIR_RIGHT)))
1663 result = g_list_reverse (result);
1670 gtk_toolbar_focus_home_or_end (GtkToolbar *toolbar,
1671 gboolean focus_home)
1673 GList *children, *list;
1674 GtkDirectionType dir = focus_home? GTK_DIR_RIGHT : GTK_DIR_LEFT;
1676 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1678 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
1680 children = g_list_reverse (children);
1682 dir = (dir == GTK_DIR_RIGHT)? GTK_DIR_LEFT : GTK_DIR_RIGHT;
1685 for (list = children; list != NULL; list = list->next)
1687 GtkWidget *child = list->data;
1689 if (GTK_CONTAINER (toolbar)->focus_child == child)
1692 if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1696 g_list_free (children);
1701 /* Keybinding handler. This function is called when the user presses
1702 * Ctrl TAB or an arrow key.
1705 gtk_toolbar_move_focus (GtkToolbar *toolbar,
1706 GtkDirectionType dir)
1709 gboolean try_focus = FALSE;
1711 GtkContainer *container = GTK_CONTAINER (toolbar);
1713 if (container->focus_child &&
1714 gtk_widget_child_focus (container->focus_child, dir))
1719 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1721 for (list = children; list != NULL; list = list->next)
1723 GtkWidget *child = list->data;
1725 if (try_focus && GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1728 if (child == GTK_CONTAINER (toolbar)->focus_child)
1732 g_list_free (children);
1737 /* The focus handler for the toolbar. It called when the user presses
1738 * TAB or otherwise tries to focus the toolbar.
1741 gtk_toolbar_focus (GtkWidget *widget,
1742 GtkDirectionType dir)
1744 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1745 GList *children, *list;
1746 gboolean result = FALSE;
1748 /* if focus is already somewhere inside the toolbar then return FALSE.
1749 * The only way focus can stay inside the toolbar is when the user presses
1750 * arrow keys or Ctrl TAB (both of which are handled by the
1751 * gtk_toolbar_move_focus() keybinding function.
1753 if (GTK_CONTAINER (widget)->focus_child)
1756 children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
1758 for (list = children; list != NULL; list = list->next)
1760 GtkWidget *child = list->data;
1762 if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
1769 g_list_free (children);
1775 style_change_notify (GtkToolbar *toolbar)
1777 if (!toolbar->style_set)
1779 /* pretend it was set, then unset, thus reverting to new default */
1780 toolbar->style_set = TRUE;
1781 gtk_toolbar_unset_style (toolbar);
1786 icon_size_change_notify (GtkToolbar *toolbar)
1788 if (!toolbar->icon_size_set)
1790 /* pretend it was set, then unset, thus reverting to new default */
1791 toolbar->icon_size_set = TRUE;
1792 gtk_toolbar_unset_icon_size (toolbar);
1796 static GtkSettings *
1797 toolbar_get_settings (GtkToolbar *toolbar)
1799 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1800 return priv->settings;
1804 gtk_toolbar_screen_changed (GtkWidget *widget,
1805 GdkScreen *previous_screen)
1807 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
1808 GtkToolbar *toolbar = GTK_TOOLBAR (widget);
1809 GtkSettings *old_settings = toolbar_get_settings (toolbar);
1810 GtkSettings *settings;
1812 if (gtk_widget_has_screen (GTK_WIDGET (toolbar)))
1813 settings = gtk_widget_get_settings (GTK_WIDGET (toolbar));
1817 if (settings == old_settings)
1822 g_signal_handler_disconnect (old_settings, toolbar->style_set_connection);
1823 g_signal_handler_disconnect (old_settings, toolbar->icon_size_connection);
1825 g_object_unref (old_settings);
1830 toolbar->style_set_connection =
1831 g_signal_connect_swapped (settings,
1832 "notify::gtk-toolbar-style",
1833 G_CALLBACK (style_change_notify),
1835 toolbar->icon_size_connection =
1836 g_signal_connect_swapped (settings,
1837 "notify::gtk-toolbar-icon-size",
1838 G_CALLBACK (icon_size_change_notify),
1841 g_object_ref (settings);
1842 priv->settings = settings;
1845 priv->settings = NULL;
1847 style_change_notify (toolbar);
1848 icon_size_change_notify (toolbar);
1852 find_drop_index (GtkToolbar *toolbar,
1856 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1857 GList *interesting_content;
1859 GtkOrientation orientation;
1860 GtkTextDirection direction;
1861 gint best_distance = G_MAXINT;
1865 ToolbarContent *best_content;
1866 GtkAllocation allocation;
1868 /* list items we care about wrt. drag and drop */
1869 interesting_content = NULL;
1870 for (list = priv->content; list != NULL; list = list->next)
1872 ToolbarContent *content = list->data;
1874 if (toolbar_content_get_state (content) == NORMAL)
1875 interesting_content = g_list_prepend (interesting_content, content);
1877 interesting_content = g_list_reverse (interesting_content);
1879 if (!interesting_content)
1882 orientation = toolbar->orientation;
1883 direction = gtk_widget_get_direction (GTK_WIDGET (toolbar));
1885 /* distance to first interesting item */
1886 best_content = interesting_content->data;
1887 toolbar_content_get_allocation (best_content, &allocation);
1889 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1893 if (direction == GTK_TEXT_DIR_LTR)
1896 pos = allocation.x + allocation.width;
1904 best_content = NULL;
1905 best_distance = ABS (pos - cursor);
1907 /* distance to far end of each item */
1908 for (list = interesting_content; list != NULL; list = list->next)
1910 ToolbarContent *content = list->data;
1912 toolbar_content_get_allocation (content, &allocation);
1914 if (orientation == GTK_ORIENTATION_HORIZONTAL)
1916 if (direction == GTK_TEXT_DIR_LTR)
1917 pos = allocation.x + allocation.width;
1923 pos = allocation.y + allocation.height;
1926 distance = ABS (pos - cursor);
1928 if (distance < best_distance)
1930 best_distance = distance;
1931 best_content = content;
1935 g_list_free (interesting_content);
1940 return g_list_index (priv->content, best_content) + 1;
1944 reset_all_placeholders (GtkToolbar *toolbar)
1946 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1949 for (list = priv->content; list != NULL; list = list->next)
1951 ToolbarContent *content = list->data;
1952 if (toolbar_content_is_placeholder (content))
1953 toolbar_content_set_disappearing (content, TRUE);
1958 physical_to_logical (GtkToolbar *toolbar,
1961 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1965 g_assert (physical >= 0);
1968 for (list = priv->content; list && physical > 0; list = list->next)
1970 ToolbarContent *content = list->data;
1972 if (!toolbar_content_is_placeholder (content))
1977 g_assert (physical == 0);
1983 logical_to_physical (GtkToolbar *toolbar,
1986 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
1990 g_assert (logical >= 0);
1993 for (list = priv->content; list; list = list->next)
1995 ToolbarContent *content = list->data;
1997 if (!toolbar_content_is_placeholder (content))
2007 g_assert (logical == 0);
2013 * gtk_toolbar_set_drop_highlight_item:
2014 * @toolbar: a #GtkToolbar
2015 * @tool_item: a #GtkToolItem, or %NULL to turn of highlighting
2016 * @index: a position on @toolbar
2018 * Highlights @toolbar to give an idea of what it would look like
2019 * if @item was added to @toolbar at position indicated by @index. If @item
2020 * is %NULL, highlighting is turned off. In that case @index is ignored.
2022 * The @tool_item passed to this function must not be part of any widget
2023 * hierarchy. When an item is set as drop highlight item it can not
2024 * added to any widget hierarchy or used as highlight item for another
2030 gtk_toolbar_set_drop_highlight_item (GtkToolbar *toolbar,
2031 GtkToolItem *tool_item,
2034 ToolbarContent *content;
2035 GtkToolbarPrivate *priv;
2037 GtkRequisition requisition;
2038 GtkRequisition old_requisition;
2039 gboolean restart_sliding;
2041 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2042 g_return_if_fail (tool_item == NULL || GTK_IS_TOOL_ITEM (tool_item));
2044 gtk_toolbar_check_new_api (toolbar);
2046 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2050 if (priv->highlight_tool_item)
2052 gtk_widget_unparent (GTK_WIDGET (priv->highlight_tool_item));
2053 g_object_unref (priv->highlight_tool_item);
2054 priv->highlight_tool_item = NULL;
2057 reset_all_placeholders (toolbar);
2058 gtk_toolbar_begin_sliding (toolbar);
2062 n_items = gtk_toolbar_get_n_items (toolbar);
2063 if (index < 0 || index > n_items)
2066 if (tool_item != priv->highlight_tool_item)
2068 if (priv->highlight_tool_item)
2069 g_object_unref (priv->highlight_tool_item);
2071 g_object_ref (tool_item);
2072 gtk_object_sink (GTK_OBJECT (tool_item));
2074 priv->highlight_tool_item = tool_item;
2076 gtk_widget_set_parent (GTK_WIDGET (priv->highlight_tool_item),
2077 GTK_WIDGET (toolbar));
2080 index = logical_to_physical (toolbar, index);
2082 content = g_list_nth_data (priv->content, index);
2086 ToolbarContent *prev_content;
2088 prev_content = g_list_nth_data (priv->content, index - 1);
2090 if (prev_content && toolbar_content_is_placeholder (prev_content))
2091 content = prev_content;
2094 if (!content || !toolbar_content_is_placeholder (content))
2096 GtkWidget *placeholder;
2098 placeholder = GTK_WIDGET (gtk_separator_tool_item_new ());
2100 content = toolbar_content_new_tool_item (toolbar,
2101 GTK_TOOL_ITEM (placeholder),
2103 gtk_widget_show (placeholder);
2107 g_assert (toolbar_content_is_placeholder (content));
2109 gtk_widget_size_request (GTK_WIDGET (priv->highlight_tool_item),
2113 restart_sliding = FALSE;
2114 toolbar_content_size_request (content, toolbar, &old_requisition);
2115 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
2117 requisition.height = -1;
2118 if (requisition.width != old_requisition.width)
2119 restart_sliding = TRUE;
2123 requisition.width = -1;
2124 if (requisition.height != old_requisition.height)
2125 restart_sliding = TRUE;
2128 if (toolbar_content_disappearing (content))
2129 restart_sliding = TRUE;
2131 reset_all_placeholders (toolbar);
2132 toolbar_content_set_disappearing (content, FALSE);
2134 toolbar_content_set_size_request (content,
2135 requisition.width, requisition.height);
2137 if (restart_sliding)
2138 gtk_toolbar_begin_sliding (toolbar);
2142 gtk_toolbar_get_child_property (GtkContainer *container,
2148 GtkToolItem *item = GTK_TOOL_ITEM (child);
2150 switch (property_id)
2152 case CHILD_PROP_HOMOGENEOUS:
2153 g_value_set_boolean (value, gtk_tool_item_get_homogeneous (item));
2156 case CHILD_PROP_EXPAND:
2157 g_value_set_boolean (value, gtk_tool_item_get_expand (item));
2161 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
2167 gtk_toolbar_set_child_property (GtkContainer *container,
2170 const GValue *value,
2173 switch (property_id)
2175 case CHILD_PROP_HOMOGENEOUS:
2176 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
2179 case CHILD_PROP_EXPAND:
2180 gtk_tool_item_set_expand (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
2184 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
2190 gtk_toolbar_show_all (GtkWidget *widget)
2192 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
2195 for (list = priv->content; list != NULL; list = list->next)
2197 ToolbarContent *content = list->data;
2199 toolbar_content_show_all (content);
2202 gtk_widget_show (widget);
2206 gtk_toolbar_hide_all (GtkWidget *widget)
2208 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
2211 for (list = priv->content; list != NULL; list = list->next)
2213 ToolbarContent *content = list->data;
2215 toolbar_content_hide_all (content);
2218 gtk_widget_hide (widget);
2222 gtk_toolbar_add (GtkContainer *container,
2225 GtkToolbar *toolbar;
2227 g_return_if_fail (GTK_IS_TOOLBAR (container));
2228 g_return_if_fail (widget != NULL);
2230 toolbar = GTK_TOOLBAR (container);
2232 if (GTK_IS_TOOL_ITEM (widget))
2233 gtk_toolbar_insert (toolbar, GTK_TOOL_ITEM (widget), -1);
2235 gtk_toolbar_append_widget (toolbar, widget, NULL, NULL);
2239 gtk_toolbar_remove (GtkContainer *container,
2242 GtkToolbar *toolbar;
2243 GtkToolbarPrivate *priv;
2244 ToolbarContent *content_to_remove;
2247 g_return_if_fail (GTK_IS_TOOLBAR (container));
2248 g_return_if_fail (GTK_IS_WIDGET (widget));
2250 toolbar = GTK_TOOLBAR (container);
2251 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2253 content_to_remove = NULL;
2254 for (list = priv->content; list != NULL; list = list->next)
2256 ToolbarContent *content = list->data;
2259 child = toolbar_content_get_widget (content);
2260 if (child && child == widget)
2262 content_to_remove = content;
2267 g_return_if_fail (content_to_remove != NULL);
2269 toolbar_content_remove (content_to_remove, toolbar);
2270 toolbar_content_free (content_to_remove);
2274 gtk_toolbar_forall (GtkContainer *container,
2275 gboolean include_internals,
2276 GtkCallback callback,
2277 gpointer callback_data)
2279 GtkToolbar *toolbar = GTK_TOOLBAR (container);
2280 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2283 g_return_if_fail (callback != NULL);
2285 list = priv->content;
2288 ToolbarContent *content = list->data;
2289 GList *next = list->next;
2291 if (include_internals || !toolbar_content_is_placeholder (content))
2293 GtkWidget *child = toolbar_content_get_widget (content);
2296 (*callback) (child, callback_data);
2302 if (include_internals)
2303 (* callback) (priv->arrow_button, callback_data);
2307 gtk_toolbar_child_type (GtkContainer *container)
2309 return GTK_TYPE_TOOL_ITEM;
2313 gtk_toolbar_reconfigured (GtkToolbar *toolbar)
2315 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2318 list = priv->content;
2321 ToolbarContent *content = list->data;
2322 GList *next = list->next;
2324 toolbar_content_toolbar_reconfigured (content, toolbar);
2331 gtk_toolbar_orientation_changed (GtkToolbar *toolbar,
2332 GtkOrientation orientation)
2334 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2335 if (toolbar->orientation != orientation)
2337 toolbar->orientation = orientation;
2339 if (orientation == GTK_ORIENTATION_HORIZONTAL)
2340 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_DOWN, GTK_SHADOW_NONE);
2342 gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
2344 gtk_toolbar_reconfigured (toolbar);
2346 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2347 g_object_notify (G_OBJECT (toolbar), "orientation");
2352 gtk_toolbar_real_style_changed (GtkToolbar *toolbar,
2353 GtkToolbarStyle style)
2355 if (toolbar->style != style)
2357 toolbar->style = style;
2359 gtk_toolbar_reconfigured (toolbar);
2361 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2362 g_object_notify (G_OBJECT (toolbar), "toolbar_style");
2367 menu_position_func (GtkMenu *menu,
2373 GtkToolbar *toolbar = GTK_TOOLBAR (user_data);
2374 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2376 GtkRequisition menu_req;
2378 gdk_window_get_origin (GTK_BUTTON (priv->arrow_button)->event_window, x, y);
2379 gtk_widget_size_request (priv->arrow_button, &req);
2380 gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
2382 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
2384 *y += priv->arrow_button->allocation.height;
2385 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
2386 *x += priv->arrow_button->allocation.width - req.width;
2388 *x += req.width - menu_req.width;
2392 if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
2393 *x += priv->arrow_button->allocation.width;
2395 *x -= menu_req.width;
2396 *y += priv->arrow_button->allocation.height - req.height;
2403 menu_deactivated (GtkWidget *menu,
2404 GtkToolbar *toolbar)
2406 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2407 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->arrow_button), FALSE);
2411 menu_detached (GtkWidget *toolbar,
2414 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2419 remove_item (GtkWidget *menu_item,
2422 gtk_container_remove (GTK_CONTAINER (menu_item->parent), menu_item);
2426 show_menu (GtkToolbar *toolbar,
2427 GdkEventButton *event)
2429 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2434 gtk_container_foreach (GTK_CONTAINER (priv->menu), remove_item, NULL);
2435 gtk_widget_destroy (GTK_WIDGET (priv->menu));
2438 priv->menu = GTK_MENU (gtk_menu_new ());
2439 gtk_menu_attach_to_widget (priv->menu,
2440 GTK_WIDGET (toolbar),
2442 g_signal_connect (priv->menu, "deactivate", G_CALLBACK (menu_deactivated), toolbar);
2444 for (list = priv->content; list != NULL; list = list->next)
2446 ToolbarContent *content = list->data;
2448 if (toolbar_content_get_state (content) == OVERFLOWN &&
2449 !toolbar_content_is_placeholder (content))
2451 GtkWidget *menu_item = toolbar_content_retrieve_menu_item (content);
2455 g_assert (GTK_IS_MENU_ITEM (menu_item));
2456 gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), menu_item);
2461 gtk_widget_show_all (GTK_WIDGET (priv->menu));
2463 gtk_menu_popup (priv->menu, NULL, NULL,
2464 menu_position_func, toolbar,
2465 event? event->button : 0,
2466 event? event->time : gtk_get_current_event_time());
2470 gtk_toolbar_arrow_button_clicked (GtkWidget *button,
2471 GtkToolbar *toolbar)
2473 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2475 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->arrow_button)) &&
2476 (!priv->menu || !GTK_WIDGET_VISIBLE (GTK_WIDGET (priv->menu))))
2478 /* We only get here when the button is clicked with the keybaord,
2479 * because mouse button presses result in the menu being shown so
2480 * that priv->menu would be non-NULL and visible.
2482 show_menu (toolbar, NULL);
2483 gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->menu), FALSE);
2488 gtk_toolbar_arrow_button_press (GtkWidget *button,
2489 GdkEventButton *event,
2490 GtkToolbar *toolbar)
2492 show_menu (toolbar, event);
2493 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
2499 gtk_toolbar_button_press (GtkWidget *toolbar,
2500 GdkEventButton *event)
2502 if (event->button == 3)
2504 gboolean return_value;
2506 g_signal_emit (toolbar, toolbar_signals[POPUP_CONTEXT_MENU], 0,
2507 (int)event->x_root, (int)event->y_root, event->button,
2510 return return_value;
2517 gtk_toolbar_popup_menu (GtkWidget *toolbar)
2519 gboolean return_value;
2520 /* This function is the handler for the "popup menu" keybinding,
2521 * ie., it is called when the user presses Shift F10
2523 g_signal_emit (toolbar, toolbar_signals[POPUP_CONTEXT_MENU], 0,
2524 -1, -1, -1, &return_value);
2526 return return_value;
2532 * Creates a new toolbar.
2534 * Return Value: the newly-created toolbar.
2537 gtk_toolbar_new (void)
2539 GtkToolbar *toolbar;
2541 toolbar = g_object_new (GTK_TYPE_TOOLBAR, NULL);
2543 return GTK_WIDGET (toolbar);
2547 * gtk_toolbar_insert:
2548 * @toolbar: a #GtkToolbar
2549 * @item: a #GtkToolItem
2550 * @pos: the position of the new item
2552 * Insert a #GtkToolItem into the toolbar at position @pos. If @pos is
2553 * 0 the item is prepended to the start of the toolbar. If @pos is
2554 * negative, the item is appended to the end of the toolbar.
2559 gtk_toolbar_insert (GtkToolbar *toolbar,
2563 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2564 g_return_if_fail (GTK_IS_TOOL_ITEM (item));
2566 if (!gtk_toolbar_check_new_api (toolbar))
2570 pos = logical_to_physical (toolbar, pos);
2572 toolbar_content_new_tool_item (toolbar, item, FALSE, pos);
2576 * gtk_toolbar_get_item_index:
2577 * @toolbar: a #GtkToolbar
2578 * @item: a #GtkToolItem that is a child of @toolbar
2580 * Returns the position of @item on the toolbar, starting from 0.
2581 * It is an error if @item is not a child of the toolbar.
2583 * Return value: the position of item on the toolbar.
2588 gtk_toolbar_get_item_index (GtkToolbar *toolbar,
2591 GtkToolbarPrivate *priv;
2595 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
2596 g_return_val_if_fail (GTK_IS_TOOL_ITEM (item), -1);
2597 g_return_val_if_fail (GTK_WIDGET (item)->parent == GTK_WIDGET (toolbar), -1);
2599 if (!gtk_toolbar_check_new_api (toolbar))
2602 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2605 for (list = priv->content; list != NULL; list = list->next)
2607 ToolbarContent *content = list->data;
2610 widget = toolbar_content_get_widget (content);
2612 if (item == GTK_TOOL_ITEM (widget))
2618 return physical_to_logical (toolbar, n);
2622 * gtk_toolbar_set_orientation:
2623 * @toolbar: a #GtkToolbar.
2624 * @orientation: a new #GtkOrientation.
2626 * Sets whether a toolbar should appear horizontally or vertically.
2629 gtk_toolbar_set_orientation (GtkToolbar *toolbar,
2630 GtkOrientation orientation)
2632 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2634 g_signal_emit (toolbar, toolbar_signals[ORIENTATION_CHANGED], 0, orientation);
2638 * gtk_toolbar_get_orientation:
2639 * @toolbar: a #GtkToolbar
2641 * Retrieves the current orientation of the toolbar. See
2642 * gtk_toolbar_set_orientation().
2644 * Return value: the orientation
2647 gtk_toolbar_get_orientation (GtkToolbar *toolbar)
2649 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_ORIENTATION_HORIZONTAL);
2651 return toolbar->orientation;
2655 * gtk_toolbar_set_style:
2656 * @toolbar: a #GtkToolbar.
2657 * @style: the new style for @toolbar.
2659 * Alters the view of @toolbar to display either icons only, text only, or both.
2662 gtk_toolbar_set_style (GtkToolbar *toolbar,
2663 GtkToolbarStyle style)
2665 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2667 toolbar->style_set = TRUE;
2668 g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
2672 * gtk_toolbar_get_style:
2673 * @toolbar: a #GtkToolbar
2675 * Retrieves whether the toolbar has text, icons, or both . See
2676 * gtk_toolbar_set_style().
2678 * Return value: the current style of @toolbar
2681 gtk_toolbar_get_style (GtkToolbar *toolbar)
2683 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), DEFAULT_TOOLBAR_STYLE);
2685 return toolbar->style;
2689 * gtk_toolbar_unset_style:
2690 * @toolbar: a #GtkToolbar
2692 * Unsets a toolbar style set with gtk_toolbar_set_style(), so that
2693 * user preferences will be used to determine the toolbar style.
2696 gtk_toolbar_unset_style (GtkToolbar *toolbar)
2698 GtkToolbarStyle style;
2700 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2702 if (toolbar->style_set)
2704 GtkSettings *settings = toolbar_get_settings (toolbar);
2707 g_object_get (settings,
2708 "gtk-toolbar-style", &style,
2711 style = DEFAULT_TOOLBAR_STYLE;
2713 if (style != toolbar->style)
2714 g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
2716 toolbar->style_set = FALSE;
2721 * gtk_toolbar_set_tooltips:
2722 * @toolbar: a #GtkToolbar.
2723 * @enable: set to %FALSE to disable the tooltips, or %TRUE to enable them.
2725 * Sets if the tooltips of a toolbar should be active or not.
2728 gtk_toolbar_set_tooltips (GtkToolbar *toolbar,
2731 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2734 gtk_tooltips_enable (toolbar->tooltips);
2736 gtk_tooltips_disable (toolbar->tooltips);
2740 * gtk_toolbar_get_tooltips:
2741 * @toolbar: a #GtkToolbar
2743 * Retrieves whether tooltips are enabled. See
2744 * gtk_toolbar_set_tooltips().
2746 * Return value: %TRUE if tooltips are enabled
2749 gtk_toolbar_get_tooltips (GtkToolbar *toolbar)
2751 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2753 return toolbar->tooltips->enabled;
2757 * gtk_toolbar_get_n_items:
2758 * @toolbar: a #GtkToolbar
2760 * Returns the number of items on the toolbar.
2762 * Return value: the number of items on the toolbar
2767 gtk_toolbar_get_n_items (GtkToolbar *toolbar)
2769 GtkToolbarPrivate *priv;
2771 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
2773 if (!gtk_toolbar_check_new_api (toolbar))
2776 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2778 return physical_to_logical (toolbar, g_list_length (priv->content));
2782 * gtk_toolbar_get_nth_item:
2783 * @toolbar: a #GtkToolbar
2784 * @n: A position on the toolbar
2786 * Returns the @n<!-- -->'s item on @toolbar, or %NULL if the
2787 * toolbar does not contain an @n<!-- -->'th item.
2789 * Return value: The @n<!-- -->'th #GtkToolItem on @toolbar, or %NULL if there
2790 * isn't an @n<!-- -->th item.
2795 gtk_toolbar_get_nth_item (GtkToolbar *toolbar,
2798 GtkToolbarPrivate *priv;
2799 ToolbarContent *content;
2802 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
2804 if (!gtk_toolbar_check_new_api (toolbar))
2807 n_items = gtk_toolbar_get_n_items (toolbar);
2809 if (n < 0 || n >= n_items)
2812 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2814 content = g_list_nth_data (priv->content, logical_to_physical (toolbar, n));
2817 g_assert (!toolbar_content_is_placeholder (content));
2819 return GTK_TOOL_ITEM (toolbar_content_get_widget (content));
2823 * gtk_toolbar_get_icon_size:
2824 * @toolbar: a #GtkToolbar
2826 * Retrieves the icon size fo the toolbar. See gtk_toolbar_set_icon_size().
2828 * Return value: the current icon size for the icons on the toolbar.
2831 gtk_toolbar_get_icon_size (GtkToolbar *toolbar)
2833 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), DEFAULT_ICON_SIZE);
2835 return toolbar->icon_size;
2839 * gtk_toolbar_get_relief_style:
2840 * @toolbar: a #GtkToolbar
2842 * Returns the relief style of buttons on @toolbar. See
2843 * gtk_button_set_relief().
2845 * Return value: The relief style of buttons on @toolbar.
2850 gtk_toolbar_get_relief_style (GtkToolbar *toolbar)
2852 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_RELIEF_NONE);
2854 return get_button_relief (toolbar);
2858 * gtk_toolbar_set_show_arrow:
2859 * @toolbar: a #GtkToolbar
2860 * @show_arrow: Whether to show an overflow menu
2862 * Sets whether to show an overflow menu when
2863 * @toolbar doesn't have room for all items on it. If %TRUE,
2864 * items that there are not room are available through an
2870 gtk_toolbar_set_show_arrow (GtkToolbar *toolbar,
2871 gboolean show_arrow)
2873 GtkToolbarPrivate *priv;
2875 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2877 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2878 show_arrow = show_arrow != FALSE;
2880 if (priv->show_arrow != show_arrow)
2882 priv->show_arrow = show_arrow;
2884 if (!priv->show_arrow)
2885 gtk_widget_hide (priv->arrow_button);
2887 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
2888 g_object_notify (G_OBJECT (toolbar), "show_arrow");
2893 * gtk_toolbar_get_show_arrow:
2894 * @toolbar: a #GtkToolbar
2896 * Returns whether the toolbar has an overflow menu.
2897 * See gtk_toolbar_set_show_arrow()
2904 gtk_toolbar_get_show_arrow (GtkToolbar *toolbar)
2906 GtkToolbarPrivate *priv;
2908 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
2910 if (!gtk_toolbar_check_new_api (toolbar))
2913 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2915 return priv->show_arrow;
2919 * gtk_toolbar_get_drop_index:
2920 * @toolbar: a #GtkToolbar
2921 * @x: x coordinate of a point on the toolbar
2922 * @y: y coordinate of a point on the toolbar
2924 * Returns the position corresponding to the indicated point on
2925 * @toolbar. This is useful when dragging items to the toolbar:
2926 * this function returns the position a new item should be
2929 * @x and @y are in @toolbar coordinates.
2931 * Return value: The position corresponding to the point (@x, @y) on the toolbar.
2936 gtk_toolbar_get_drop_index (GtkToolbar *toolbar,
2940 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
2942 if (!gtk_toolbar_check_new_api (toolbar))
2945 return physical_to_logical (toolbar, find_drop_index (toolbar, x, y));
2949 gtk_toolbar_finalize (GObject *object)
2952 GtkToolbar *toolbar = GTK_TOOLBAR (object);
2953 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
2955 if (toolbar->tooltips)
2956 g_object_unref (toolbar->tooltips);
2958 for (list = priv->content; list != NULL; list = list->next)
2960 ToolbarContent *content = list->data;
2962 toolbar_content_free (content);
2965 g_list_free (priv->content);
2966 g_list_free (toolbar->children);
2968 g_timer_destroy (priv->timer);
2971 gtk_widget_destroy (GTK_WIDGET (priv->menu));
2974 g_source_remove (priv->idle_id);
2976 G_OBJECT_CLASS (parent_class)->finalize (object);
2984 * gtk_toolbar_set_icon_size:
2985 * @toolbar: A #GtkToolbar
2986 * @icon_size: The #GtkIconSize that stock icons in the toolbar shall have.
2988 * This function sets the size of stock icons in the toolbar. You
2989 * can call it both before you add the icons and after they've been
2990 * added. The size you set will override user preferences for the default
2994 gtk_toolbar_set_icon_size (GtkToolbar *toolbar,
2995 GtkIconSize icon_size)
2997 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
2999 toolbar->icon_size_set = TRUE;
3001 if (toolbar->icon_size == icon_size)
3004 toolbar->icon_size = icon_size;
3006 gtk_toolbar_reconfigured (toolbar);
3008 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
3012 * gtk_toolbar_unset_icon_size:
3013 * @toolbar: a #GtkToolbar
3015 * Unsets toolbar icon size set with gtk_toolbar_set_icon_size(), so that
3016 * user preferences will be used to determine the icon size.
3019 gtk_toolbar_unset_icon_size (GtkToolbar *toolbar)
3023 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
3025 if (toolbar->icon_size_set)
3027 GtkSettings *settings = toolbar_get_settings (toolbar);
3031 g_object_get (settings,
3032 "gtk-toolbar-icon-size", &size,
3036 size = DEFAULT_ICON_SIZE;
3038 if (size != toolbar->icon_size)
3039 gtk_toolbar_set_icon_size (toolbar, size);
3041 toolbar->icon_size_set = FALSE;
3046 * gtk_toolbar_append_item:
3047 * @toolbar: a #GtkToolbar.
3048 * @text: give your toolbar button a label.
3049 * @tooltip_text: a string that appears when the user holds the mouse over this item.
3050 * @tooltip_private_text: use with #GtkTipsQuery.
3051 * @icon: a #GtkWidget that should be used as the button's icon.
3052 * @callback: the function to be executed when the button is pressed.
3053 * @user_data: a pointer to any data you wish to be passed to the callback.
3055 * Inserts a new item into the toolbar. You must specify the position
3056 * in the toolbar where it will be inserted.
3058 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3059 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3061 * Return value: the new toolbar item as a #GtkWidget.
3064 gtk_toolbar_append_item (GtkToolbar *toolbar,
3066 const char *tooltip_text,
3067 const char *tooltip_private_text,
3069 GtkSignalFunc callback,
3072 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3074 tooltip_text, tooltip_private_text,
3075 icon, callback, user_data,
3076 toolbar->num_children);
3080 * gtk_toolbar_prepend_item:
3081 * @toolbar: a #GtkToolbar.
3082 * @text: give your toolbar button a label.
3083 * @tooltip_text: a string that appears when the user holds the mouse over this item.
3084 * @tooltip_private_text: use with #GtkTipsQuery.
3085 * @icon: a #GtkWidget that should be used as the button's icon.
3086 * @callback: the function to be executed when the button is pressed.
3087 * @user_data: a pointer to any data you wish to be passed to the callback.
3089 * Adds a new button to the beginning (top or left edges) of the given toolbar.
3091 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3092 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3094 * Return value: the new toolbar item as a #GtkWidget.
3097 gtk_toolbar_prepend_item (GtkToolbar *toolbar,
3099 const char *tooltip_text,
3100 const char *tooltip_private_text,
3102 GtkSignalFunc callback,
3105 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3107 tooltip_text, tooltip_private_text,
3108 icon, callback, user_data,
3113 * gtk_toolbar_insert_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.
3121 * @position: the number of widgets to insert this item after.
3123 * Inserts a new item into the toolbar. You must specify the position in the
3124 * toolbar where it will be inserted.
3126 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3127 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3129 * Return value: the new toolbar item as a #GtkWidget.
3132 gtk_toolbar_insert_item (GtkToolbar *toolbar,
3134 const char *tooltip_text,
3135 const char *tooltip_private_text,
3137 GtkSignalFunc callback,
3141 return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3143 tooltip_text, tooltip_private_text,
3144 icon, callback, user_data,
3149 * gtk_toolbar_insert_stock:
3150 * @toolbar: A #GtkToolbar
3151 * @stock_id: The id of the stock item you want to insert
3152 * @tooltip_text: The text in the tooltip of the toolbar button
3153 * @tooltip_private_text: The private text of the tooltip
3154 * @callback: The callback called when the toolbar button is clicked.
3155 * @user_data: user data passed to callback
3156 * @position: The position the button shall be inserted at.
3157 * -1 means at the end.
3159 * Inserts a stock item at the specified position of the toolbar. If
3160 * @stock_id is not a known stock item ID, it's inserted verbatim,
3161 * except that underscores used to mark mnemonics are removed.
3163 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3164 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3166 * Returns: the inserted widget
3169 gtk_toolbar_insert_stock (GtkToolbar *toolbar,
3170 const gchar *stock_id,
3171 const char *tooltip_text,
3172 const char *tooltip_private_text,
3173 GtkSignalFunc callback,
3177 return internal_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
3179 tooltip_text, tooltip_private_text,
3180 NULL, callback, user_data,
3185 * gtk_toolbar_append_space:
3186 * @toolbar: a #GtkToolbar.
3188 * Adds a new space to the end of the toolbar.
3191 gtk_toolbar_append_space (GtkToolbar *toolbar)
3193 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
3197 toolbar->num_children);
3201 * gtk_toolbar_prepend_space:
3202 * @toolbar: a #GtkToolbar.
3204 * Adds a new space to the beginning of the toolbar.
3207 gtk_toolbar_prepend_space (GtkToolbar *toolbar)
3209 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
3217 * gtk_toolbar_insert_space:
3218 * @toolbar: a #GtkToolbar
3219 * @position: the number of widgets after which a space should be inserted.
3221 * Inserts a new space in the toolbar at the specified position.
3224 gtk_toolbar_insert_space (GtkToolbar *toolbar,
3227 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
3235 * gtk_toolbar_remove_space:
3236 * @toolbar: a #GtkToolbar.
3237 * @position: the index of the space to remove.
3239 * Removes a space from the specified position.
3242 gtk_toolbar_remove_space (GtkToolbar *toolbar,
3245 GtkToolbarPrivate *priv;
3246 ToolbarContent *content;
3248 g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
3250 if (!gtk_toolbar_check_old_api (toolbar))
3253 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3255 content = g_list_nth_data (priv->content, position);
3259 g_warning ("Toolbar position %d doesn't exist", position);
3263 if (!toolbar_content_is_separator (content))
3265 g_warning ("Toolbar position %d is not a space", position);
3269 toolbar_content_remove (content, toolbar);
3270 toolbar_content_free (content);
3274 * gtk_toolbar_append_widget:
3275 * @toolbar: a #GtkToolbar.
3276 * @widget: a #GtkWidget to add to the toolbar.
3277 * @tooltip_text: the element's tooltip.
3278 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3280 * Adds a widget to the end of the given toolbar.
3283 gtk_toolbar_append_widget (GtkToolbar *toolbar,
3285 const gchar *tooltip_text,
3286 const gchar *tooltip_private_text)
3288 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
3290 tooltip_text, tooltip_private_text,
3292 toolbar->num_children);
3296 * gtk_toolbar_prepend_widget:
3297 * @toolbar: a #GtkToolbar.
3298 * @widget: a #GtkWidget to add to the toolbar.
3299 * @tooltip_text: the element's tooltip.
3300 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3302 * Adds a widget to the beginning of the given toolbar.
3305 gtk_toolbar_prepend_widget (GtkToolbar *toolbar,
3307 const gchar *tooltip_text,
3308 const gchar *tooltip_private_text)
3310 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
3312 tooltip_text, tooltip_private_text,
3318 * gtk_toolbar_insert_widget:
3319 * @toolbar: a #GtkToolbar.
3320 * @widget: a #GtkWidget to add to the toolbar.
3321 * @tooltip_text: the element's tooltip.
3322 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3323 * @position: the number of widgets to insert this widget after.
3325 * Inserts a widget in the toolbar at the given position.
3328 gtk_toolbar_insert_widget (GtkToolbar *toolbar,
3330 const char *tooltip_text,
3331 const char *tooltip_private_text,
3334 gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
3336 tooltip_text, tooltip_private_text,
3342 * gtk_toolbar_append_element:
3343 * @toolbar: a #GtkToolbar.
3344 * @type: a value of type #GtkToolbarChildType that determines what @widget will be.
3345 * @widget: a #GtkWidget, or %NULL.
3346 * @text: the element's label.
3347 * @tooltip_text: the element's tooltip.
3348 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3349 * @icon: a #GtkWidget that provides pictorial representation of the element's function.
3350 * @callback: the function to be executed when the button is pressed.
3351 * @user_data: any data you wish to pass to the callback.
3353 * Adds a new element to the end of a toolbar.
3355 * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element.
3356 * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine
3357 * the radio group for the new element. In all other cases, @widget must
3360 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3361 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3363 * Return value: the new toolbar element as a #GtkWidget.
3366 gtk_toolbar_append_element (GtkToolbar *toolbar,
3367 GtkToolbarChildType type,
3370 const char *tooltip_text,
3371 const char *tooltip_private_text,
3373 GtkSignalFunc callback,
3376 return gtk_toolbar_insert_element (toolbar, type, widget, text,
3377 tooltip_text, tooltip_private_text,
3378 icon, callback, user_data,
3379 toolbar->num_children);
3383 * gtk_toolbar_prepend_element:
3384 * @toolbar: a #GtkToolbar.
3385 * @type: a value of type #GtkToolbarChildType that determines what @widget will be.
3386 * @widget: a #GtkWidget, or %NULL
3387 * @text: the element's label.
3388 * @tooltip_text: the element's tooltip.
3389 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3390 * @icon: a #GtkWidget that provides pictorial representation of the element's function.
3391 * @callback: the function to be executed when the button is pressed.
3392 * @user_data: any data you wish to pass to the callback.
3394 * Adds a new element to the beginning of a toolbar.
3396 * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element.
3397 * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine
3398 * the radio group for the new element. In all other cases, @widget must
3401 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3402 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3404 * Return value: the new toolbar element as a #GtkWidget.
3407 gtk_toolbar_prepend_element (GtkToolbar *toolbar,
3408 GtkToolbarChildType type,
3411 const char *tooltip_text,
3412 const char *tooltip_private_text,
3414 GtkSignalFunc callback,
3417 return gtk_toolbar_insert_element (toolbar, type, widget, text,
3418 tooltip_text, tooltip_private_text,
3419 icon, callback, user_data, 0);
3423 * gtk_toolbar_insert_element:
3424 * @toolbar: a #GtkToolbar.
3425 * @type: a value of type #GtkToolbarChildType that determines what @widget
3427 * @widget: a #GtkWidget, or %NULL.
3428 * @text: the element's label.
3429 * @tooltip_text: the element's tooltip.
3430 * @tooltip_private_text: used for context-sensitive help about this toolbar element.
3431 * @icon: a #GtkWidget that provides pictorial representation of the element's function.
3432 * @callback: the function to be executed when the button is pressed.
3433 * @user_data: any data you wish to pass to the callback.
3434 * @position: the number of widgets to insert this element after.
3436 * Inserts a new element in the toolbar at the given position.
3438 * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element.
3439 * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine
3440 * the radio group for the new element. In all other cases, @widget must
3443 * @callback must be a pointer to a function taking a #GtkWidget and a gpointer as
3444 * arguments. Use the GTK_SIGNAL_FUNC() to cast the function to #GtkSignalFunc.
3446 * Return value: the new toolbar element as a #GtkWidget.
3449 gtk_toolbar_insert_element (GtkToolbar *toolbar,
3450 GtkToolbarChildType type,
3453 const char *tooltip_text,
3454 const char *tooltip_private_text,
3456 GtkSignalFunc callback,
3460 return internal_insert_element (toolbar, type, widget, text,
3461 tooltip_text, tooltip_private_text,
3462 icon, callback, user_data, position, FALSE);
3466 set_child_packing_and_visibility(GtkToolbar *toolbar,
3467 GtkToolbarChild *child)
3472 box = gtk_bin_get_child (GTK_BIN (child->widget));
3474 g_return_if_fail (GTK_IS_BOX (box));
3478 expand = (toolbar->style != GTK_TOOLBAR_BOTH);
3480 gtk_box_set_child_packing (GTK_BOX (box), child->label,
3481 expand, expand, 0, GTK_PACK_END);
3483 if (toolbar->style != GTK_TOOLBAR_ICONS)
3484 gtk_widget_show (child->label);
3486 gtk_widget_hide (child->label);
3491 expand = (toolbar->style != GTK_TOOLBAR_BOTH_HORIZ);
3493 gtk_box_set_child_packing (GTK_BOX (box), child->icon,
3494 expand, expand, 0, GTK_PACK_END);
3496 if (toolbar->style != GTK_TOOLBAR_TEXT)
3497 gtk_widget_show (child->icon);
3499 gtk_widget_hide (child->icon);
3504 internal_insert_element (GtkToolbar *toolbar,
3505 GtkToolbarChildType type,
3508 const char *tooltip_text,
3509 const char *tooltip_private_text,
3511 GtkSignalFunc callback,
3517 ToolbarContent *content;
3518 GtkToolbarPrivate *priv;
3519 char *free_me = NULL;
3520 gboolean is_button = FALSE;
3522 GtkWidget *child_widget;
3523 GtkWidget *child_label;
3524 GtkWidget *child_icon;
3526 g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
3527 if (type == GTK_TOOLBAR_CHILD_WIDGET)
3528 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3529 else if (type != GTK_TOOLBAR_CHILD_RADIOBUTTON)
3530 g_return_val_if_fail (widget == NULL, NULL);
3532 if (!gtk_toolbar_check_old_api (toolbar))
3535 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3537 child_widget = NULL;
3543 case GTK_TOOLBAR_CHILD_SPACE:
3546 case GTK_TOOLBAR_CHILD_WIDGET:
3547 child_widget = widget;
3550 case GTK_TOOLBAR_CHILD_BUTTON:
3551 case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
3552 case GTK_TOOLBAR_CHILD_RADIOBUTTON:
3554 if (type == GTK_TOOLBAR_CHILD_BUTTON)
3556 child_widget = gtk_button_new ();
3558 else if (type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
3560 child_widget = gtk_toggle_button_new ();
3561 gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (child_widget), FALSE);
3563 else /* type == GTK_TOOLBAR_CHILD_RADIOBUTTON */
3565 GSList *group = NULL;
3568 group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
3570 child_widget = gtk_radio_button_new (group);
3571 gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (child_widget), FALSE);
3574 gtk_button_set_relief (GTK_BUTTON (child_widget), get_button_relief (toolbar));
3575 gtk_button_set_focus_on_click (GTK_BUTTON (child_widget), FALSE);
3579 g_signal_connect (child_widget, "clicked",
3580 callback, user_data);
3583 if (toolbar->style == GTK_TOOLBAR_BOTH_HORIZ)
3584 box = gtk_hbox_new (FALSE, 0);
3586 box = gtk_vbox_new (FALSE, 0);
3588 gtk_container_add (GTK_CONTAINER (child_widget), box);
3589 gtk_widget_show (box);
3591 if (text && use_stock)
3593 GtkStockItem stock_item;
3594 if (gtk_stock_lookup (text, &stock_item))
3597 icon = gtk_image_new_from_stock (text, toolbar->icon_size);
3599 text = free_me = _gtk_toolbar_elide_underscores (stock_item.label);
3605 child_label = gtk_label_new (text);
3607 gtk_container_add (GTK_CONTAINER (box), child_label);
3612 child_icon = GTK_WIDGET (icon);
3613 gtk_container_add (GTK_CONTAINER (box), child_icon);
3616 gtk_widget_show (child_widget);
3620 g_assert_not_reached ();
3624 if ((type != GTK_TOOLBAR_CHILD_SPACE) && tooltip_text)
3626 gtk_tooltips_set_tip (toolbar->tooltips, child_widget,
3627 tooltip_text, tooltip_private_text);
3630 content = toolbar_content_new_compatibility (toolbar, type, child_widget,
3631 child_icon, child_label, position);
3636 return child_widget;
3640 * ToolbarContent methods
3642 struct _ToolbarContent
3652 GtkAllocation start_allocation;
3653 GtkAllocation goal_allocation;
3654 guint is_placeholder : 1;
3655 guint disappearing : 1;
3660 GtkToolbarChild child;
3661 GtkAllocation space_allocation;
3662 guint space_visible : 1;
3667 static ToolbarContent *
3668 toolbar_content_new_tool_item (GtkToolbar *toolbar,
3670 gboolean is_placeholder,
3673 ToolbarContent *content;
3674 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3676 content = g_new0 (ToolbarContent, 1);
3678 content->type = TOOL_ITEM;
3679 content->state = NOT_ALLOCATED;
3680 content->u.tool_item.item = item;
3681 content->u.tool_item.is_placeholder = is_placeholder;
3683 gtk_widget_set_parent (GTK_WIDGET (item), GTK_WIDGET (toolbar));
3685 priv->content = g_list_insert (priv->content, content, pos);
3687 if (!is_placeholder)
3689 toolbar->num_children++;
3691 gtk_toolbar_stop_sliding (toolbar);
3694 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
3699 static ToolbarContent *
3700 toolbar_content_new_compatibility (GtkToolbar *toolbar,
3701 GtkToolbarChildType type,
3707 ToolbarContent *content;
3708 GtkToolbarChild *child;
3709 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3711 content = g_new0 (ToolbarContent, 1);
3713 child = &(content->u.compatibility.child);
3715 content->type = COMPATIBILITY;
3717 child->widget = widget;
3719 child->label = label;
3721 if (type != GTK_TOOLBAR_CHILD_SPACE)
3723 gtk_widget_set_parent (child->widget, GTK_WIDGET (toolbar));
3727 content->u.compatibility.space_visible = TRUE;
3728 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
3731 if (type == GTK_TOOLBAR_CHILD_BUTTON ||
3732 type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON ||
3733 type == GTK_TOOLBAR_CHILD_RADIOBUTTON)
3735 set_child_packing_and_visibility (toolbar, child);
3738 priv->content = g_list_insert (priv->content, content, pos);
3739 toolbar->children = g_list_insert (toolbar->children, child, pos);
3741 toolbar->num_children++;
3747 toolbar_content_remove (ToolbarContent *content,
3748 GtkToolbar *toolbar)
3750 GtkToolbarChild *child;
3751 GtkToolbarPrivate *priv;
3753 priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3755 switch (content->type)
3758 gtk_widget_unparent (GTK_WIDGET (content->u.tool_item.item));
3762 child = &(content->u.compatibility.child);
3764 if (child->type != GTK_TOOLBAR_CHILD_SPACE)
3766 g_object_ref (child->widget);
3767 gtk_widget_unparent (child->widget);
3768 gtk_widget_destroy (child->widget);
3769 g_object_unref (child->widget);
3772 toolbar->children = g_list_remove (toolbar->children, child);
3776 priv->content = g_list_remove (priv->content, content);
3778 if (!toolbar_content_is_placeholder (content))
3779 toolbar->num_children--;
3781 gtk_widget_queue_resize (GTK_WIDGET (toolbar));
3785 toolbar_content_free (ToolbarContent *content)
3791 calculate_max_homogeneous_pixels (GtkWidget *widget)
3793 PangoContext *context;
3794 PangoFontMetrics *metrics;
3797 context = gtk_widget_get_pango_context (widget);
3798 metrics = pango_context_get_metrics (context,
3799 widget->style->font_desc,
3800 pango_context_get_language (context));
3801 char_width = pango_font_metrics_get_approximate_char_width (metrics);
3802 pango_font_metrics_unref (metrics);
3804 return PANGO_PIXELS (MAX_HOMOGENEOUS_N_CHARS * char_width);
3808 toolbar_content_expose (ToolbarContent *content,
3809 GtkContainer *container,
3810 GdkEventExpose *expose)
3812 GtkToolbar *toolbar = GTK_TOOLBAR (container);
3813 GtkToolbarChild *child;
3814 GtkWidget *widget = NULL; /* quiet gcc */
3816 switch (content->type)
3819 if (!content->u.tool_item.is_placeholder)
3820 widget = GTK_WIDGET (content->u.tool_item.item);
3824 child = &(content->u.compatibility.child);
3826 if (child->type == GTK_TOOLBAR_CHILD_SPACE)
3828 if (get_space_style (toolbar) == GTK_TOOLBAR_SPACE_LINE &&
3829 content->u.compatibility.space_visible)
3831 _gtk_toolbar_paint_space_line (GTK_WIDGET (toolbar), toolbar,
3833 &content->u.compatibility.space_allocation);
3838 widget = child->widget;
3843 gtk_container_propagate_expose (container, widget, expose);
3847 toolbar_content_visible (ToolbarContent *content,
3848 GtkToolbar *toolbar)
3852 switch (content->type)
3855 item = content->u.tool_item.item;
3857 if (!GTK_WIDGET_VISIBLE (item))
3860 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL &&
3861 gtk_tool_item_get_visible_horizontal (item))
3866 if ((toolbar->orientation == GTK_ORIENTATION_VERTICAL &&
3867 gtk_tool_item_get_visible_vertical (item)))
3876 if (content->u.compatibility.child.type != GTK_TOOLBAR_CHILD_SPACE)
3877 return GTK_WIDGET_VISIBLE (content->u.compatibility.child.widget);
3883 g_assert_not_reached ();
3888 toolbar_content_size_request (ToolbarContent *content,
3889 GtkToolbar *toolbar,
3890 GtkRequisition *requisition)
3894 switch (content->type)
3897 gtk_widget_size_request (GTK_WIDGET (content->u.tool_item.item),
3899 if (content->u.tool_item.is_placeholder &&
3900 content->u.tool_item.disappearing)
3902 requisition->width = 0;
3903 requisition->height = 0;
3908 space_size = get_space_size (toolbar);
3910 if (content->u.compatibility.child.type != GTK_TOOLBAR_CHILD_SPACE)
3912 gtk_widget_size_request (content->u.compatibility.child.widget,
3917 if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
3919 requisition->width = space_size;
3920 requisition->height = 0;
3924 requisition->height = space_size;
3925 requisition->width = 0;
3934 toolbar_content_is_homogeneous (ToolbarContent *content,
3935 GtkToolbar *toolbar)
3937 gboolean result = FALSE; /* quiet gcc */
3938 GtkRequisition requisition;
3939 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
3941 if (priv->max_homogeneous_pixels < 0)
3943 priv->max_homogeneous_pixels =
3944 calculate_max_homogeneous_pixels (GTK_WIDGET (toolbar));
3947 toolbar_content_size_request (content, toolbar, &requisition);
3949 if (requisition.width > priv->max_homogeneous_pixels)
3952 switch (content->type)
3955 result = gtk_tool_item_get_homogeneous (content->u.tool_item.item) &&
3956 !GTK_IS_SEPARATOR_TOOL_ITEM (content->u.tool_item.item);
3958 if (gtk_tool_item_get_is_important (content->u.tool_item.item) &&
3959 toolbar->style == GTK_TOOLBAR_BOTH_HORIZ &&
3960 toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
3967 if (content->u.compatibility.child.type == GTK_TOOLBAR_CHILD_BUTTON ||
3968 content->u.compatibility.child.type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
3969 content->u.compatibility.child.type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
3984 toolbar_content_is_placeholder (ToolbarContent *content)
3986 if (content->type == TOOL_ITEM && content->u.tool_item.is_placeholder)
3993 toolbar_content_disappearing (ToolbarContent *content)
3995 if (content->type == TOOL_ITEM && content->u.tool_item.disappearing)
4002 toolbar_content_get_state (ToolbarContent *content)
4004 return content->state;
4008 toolbar_content_child_visible (ToolbarContent *content)
4010 switch (content->type)
4013 return GTK_WIDGET_CHILD_VISIBLE (content->u.tool_item.item);
4017 if (content->u.compatibility.child.type != GTK_TOOLBAR_CHILD_SPACE)
4019 return GTK_WIDGET_CHILD_VISIBLE (content->u.compatibility.child.widget);
4023 return content->u.compatibility.space_visible;
4028 return FALSE; /* quiet gcc */
4032 toolbar_content_get_goal_allocation (ToolbarContent *content,
4033 GtkAllocation *allocation)
4035 switch (content->type)
4038 *allocation = content->u.tool_item.goal_allocation;
4042 /* Goal allocations are only relevant when we are
4043 * using the new API, so we should never get here
4045 g_assert_not_reached ();
4051 toolbar_content_get_allocation (ToolbarContent *content,
4052 GtkAllocation *allocation)
4054 GtkToolbarChild *child;
4056 switch (content->type)
4059 *allocation = GTK_WIDGET (content->u.tool_item.item)->allocation;
4063 child = &(content->u.compatibility.child);
4065 if (child->type == GTK_TOOLBAR_CHILD_SPACE)
4066 *allocation = content->u.compatibility.space_allocation;
4068 *allocation = child->widget->allocation;
4074 toolbar_content_set_start_allocation (ToolbarContent *content,
4075 GtkAllocation *allocation)
4077 switch (content->type)
4080 content->u.tool_item.start_allocation = *allocation;
4084 /* start_allocation is only relevant when using the new API */
4085 g_assert_not_reached ();
4091 toolbar_content_get_expand (ToolbarContent *content)
4093 if (content->type == TOOL_ITEM &&
4094 gtk_tool_item_get_expand (content->u.tool_item.item))
4103 toolbar_content_set_goal_allocation (ToolbarContent *content,
4104 GtkAllocation *allocation)
4106 switch (content->type)
4109 content->u.tool_item.goal_allocation = *allocation;
4113 /* Only relevant when using new API */
4114 g_assert_not_reached ();
4120 toolbar_content_set_child_visible (ToolbarContent *content,
4121 GtkToolbar *toolbar,
4124 GtkToolbarChild *child;
4126 switch (content->type)
4129 gtk_widget_set_child_visible (GTK_WIDGET (content->u.tool_item.item),
4134 child = &(content->u.compatibility.child);
4136 if (child->type != GTK_TOOLBAR_CHILD_SPACE)
4138 gtk_widget_set_child_visible (child->widget, visible);
4142 content->u.compatibility.space_visible = visible;
4143 gtk_widget_queue_draw (GTK_WIDGET (toolbar));
4150 toolbar_content_get_start_allocation (ToolbarContent *content,
4151 GtkAllocation *start_allocation)
4153 switch (content->type)
4156 *start_allocation = content->u.tool_item.start_allocation;
4160 /* Only relevant for new API */
4161 g_assert_not_reached ();
4167 toolbar_content_size_allocate (ToolbarContent *content,
4168 GtkAllocation *allocation)
4170 switch (content->type)
4173 gtk_widget_size_allocate (GTK_WIDGET (content->u.tool_item.item),
4178 if (content->u.compatibility.child.type != GTK_TOOLBAR_CHILD_SPACE)
4180 gtk_widget_size_allocate (content->u.compatibility.child.widget,
4185 content->u.compatibility.space_allocation = *allocation;
4192 toolbar_content_set_state (ToolbarContent *content,
4195 content->state = state;
4199 toolbar_content_get_widget (ToolbarContent *content)
4201 GtkToolbarChild *child;
4203 switch (content->type)
4206 return GTK_WIDGET (content->u.tool_item.item);
4210 child = &(content->u.compatibility.child);
4211 if (child->type != GTK_TOOLBAR_CHILD_SPACE)
4212 return child->widget;
4222 toolbar_content_set_disappearing (ToolbarContent *content,
4223 gboolean disappearing)
4225 switch (content->type)
4228 content->u.tool_item.disappearing = disappearing;
4232 /* Only relevant for new API */
4233 g_assert_not_reached ();
4239 toolbar_content_set_size_request (ToolbarContent *content,
4243 switch (content->type)
4246 gtk_widget_set_size_request (GTK_WIDGET (content->u.tool_item.item),
4251 /* Setting size requests only happens with sliding,
4252 * so not relevant here
4254 g_assert_not_reached ();
4260 toolbar_child_reconfigure (GtkToolbar *toolbar,
4261 GtkToolbarChild *child)
4265 GtkToolbarStyle style;
4266 GtkIconSize icon_size;
4267 GtkReliefStyle relief;
4270 style = gtk_toolbar_get_style (toolbar);
4271 icon_size = gtk_toolbar_get_icon_size (toolbar);
4272 relief = gtk_toolbar_get_relief_style (toolbar);
4275 if (child->type == GTK_TOOLBAR_CHILD_BUTTON ||
4276 child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
4277 child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
4279 box = gtk_bin_get_child (GTK_BIN (child->widget));
4281 if (style == GTK_TOOLBAR_BOTH && GTK_IS_HBOX (box))
4285 vbox = gtk_vbox_new (FALSE, 0);
4288 gtk_widget_reparent (child->label, vbox);
4290 gtk_widget_reparent (child->icon, vbox);
4292 gtk_widget_destroy (box);
4293 gtk_container_add (GTK_CONTAINER (child->widget), vbox);
4295 gtk_widget_show (vbox);
4297 else if (style == GTK_TOOLBAR_BOTH_HORIZ && GTK_IS_VBOX (box))
4301 hbox = gtk_hbox_new (FALSE, 0);
4304 gtk_widget_reparent (child->label, hbox);
4306 gtk_widget_reparent (child->icon, hbox);
4308 gtk_widget_destroy (box);
4309 gtk_container_add (GTK_CONTAINER (child->widget), hbox);
4311 gtk_widget_show (hbox);
4314 set_child_packing_and_visibility (toolbar, child);
4319 if ((child->type == GTK_TOOLBAR_CHILD_BUTTON ||
4320 child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON ||
4321 child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON) &&
4322 GTK_IS_IMAGE (child->icon))
4324 image = GTK_IMAGE (child->icon);
4325 if (gtk_image_get_storage_type (image) == GTK_IMAGE_STOCK)
4327 gtk_image_get_stock (image, &stock_id, NULL);
4328 stock_id = g_strdup (stock_id);
4329 gtk_image_set_from_stock (image,
4337 if (child->type == GTK_TOOLBAR_CHILD_BUTTON ||
4338 child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
4339 child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
4341 gtk_button_set_relief (GTK_BUTTON (child->widget), relief);
4346 toolbar_content_toolbar_reconfigured (ToolbarContent *content,
4347 GtkToolbar *toolbar)
4349 switch (content->type)
4352 _gtk_tool_item_toolbar_reconfigured (content->u.tool_item.item);
4356 toolbar_child_reconfigure (toolbar, &(content->u.compatibility.child));
4362 toolbar_content_retrieve_menu_item (ToolbarContent *content)
4364 if (content->type == TOOL_ITEM)
4365 return gtk_tool_item_retrieve_proxy_menu_item (content->u.tool_item.item);
4367 /* FIXME - we might actually be able to do something meaningful here */
4372 toolbar_content_is_separator (ToolbarContent *content)
4374 GtkToolbarChild *child;
4376 switch (content->type)
4379 return GTK_IS_SEPARATOR_TOOL_ITEM (content->u.tool_item.item);
4383 child = &(content->u.compatibility.child);
4384 return (child->type == GTK_TOOLBAR_CHILD_SPACE);
4392 ignore_show_and_hide_all (ToolbarContent *content)
4394 if (content->type == COMPATIBILITY)
4396 GtkToolbarChildType type = content->u.compatibility.child.type;
4398 if (type == GTK_TOOLBAR_CHILD_BUTTON ||
4399 type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON ||
4400 type == GTK_TOOLBAR_CHILD_RADIOBUTTON)
4410 toolbar_content_show_all (ToolbarContent *content)
4414 if (ignore_show_and_hide_all (content))
4417 widget = toolbar_content_get_widget (content);
4419 gtk_widget_show_all (widget);
4423 toolbar_content_hide_all (ToolbarContent *content)
4427 if (ignore_show_and_hide_all (content))
4430 widget = toolbar_content_get_widget (content);
4432 gtk_widget_hide_all (widget);
4439 get_space_size (GtkToolbar *toolbar)
4441 gint space_size = DEFAULT_SPACE_SIZE;
4445 gtk_widget_style_get (GTK_WIDGET (toolbar),
4446 "space_size", &space_size,
4453 static GtkToolbarSpaceStyle
4454 get_space_style (GtkToolbar *toolbar)
4456 GtkToolbarSpaceStyle space_style = DEFAULT_SPACE_STYLE;
4460 gtk_widget_style_get (GTK_WIDGET (toolbar),
4461 "space_style", &space_style,
4468 static GtkReliefStyle
4469 get_button_relief (GtkToolbar *toolbar)
4471 GtkReliefStyle button_relief = GTK_RELIEF_NORMAL;
4473 gtk_widget_ensure_style (GTK_WIDGET (toolbar));
4475 gtk_widget_style_get (GTK_WIDGET (toolbar),
4476 "button_relief", &button_relief,
4479 return button_relief;
4483 get_internal_padding (GtkToolbar *toolbar)
4487 gtk_widget_style_get (GTK_WIDGET (toolbar),
4488 "internal_padding", &ipadding,
4494 static GtkShadowType
4495 get_shadow_type (GtkToolbar *toolbar)
4497 GtkShadowType shadow_type;
4499 gtk_widget_style_get (GTK_WIDGET (toolbar),
4500 "shadow_type", &shadow_type,
4509 #define mixed_api_warning \
4510 "mixing deprecated and non-deprecated GtkToolbar API is not allowed"
4513 gtk_toolbar_check_old_api (GtkToolbar *toolbar)
4515 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
4517 if (priv->api_mode == NEW_API)
4519 g_warning (mixed_api_warning);
4523 priv->api_mode = OLD_API;
4528 gtk_toolbar_check_new_api (GtkToolbar *toolbar)
4530 GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
4532 if (priv->api_mode == OLD_API)
4534 g_warning (mixed_api_warning);
4538 priv->api_mode = NEW_API;
4542 /* GTK+ internal methods */
4545 _gtk_toolbar_get_default_space_size (void)
4547 return DEFAULT_SPACE_SIZE;
4551 _gtk_toolbar_paint_space_line (GtkWidget *widget,
4552 GtkToolbar *toolbar,
4554 GtkAllocation *allocation)
4556 const double start_fraction = (SPACE_LINE_START / SPACE_LINE_DIVISION);
4557 const double end_fraction = (SPACE_LINE_END / SPACE_LINE_DIVISION);
4560 GtkToolbarSpaceStyle space_style;
4561 GtkOrientation orientation;
4563 g_return_if_fail (GTK_IS_WIDGET (widget));
4565 space_size = get_space_size (toolbar);
4566 space_style = get_space_style (toolbar);
4567 orientation = toolbar? toolbar->orientation : GTK_ORIENTATION_HORIZONTAL;
4569 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4571 gtk_paint_vline (widget->style, widget->window,
4572 GTK_WIDGET_STATE (widget), area, widget,
4574 allocation->y + allocation->height * start_fraction,
4575 allocation->y + allocation->height * end_fraction,
4576 allocation->x + (space_size - widget->style->xthickness) / 2);
4580 gtk_paint_hline (widget->style, widget->window,
4581 GTK_WIDGET_STATE (widget), area, widget,
4583 allocation->x + allocation->width * start_fraction,
4584 allocation->x + allocation->width * end_fraction,
4585 allocation->y + (space_size - widget->style->ythickness) / 2);
4590 _gtk_toolbar_elide_underscores (const gchar *original)
4594 gboolean last_underscore;
4596 q = result = g_malloc (strlen (original) + 1);
4597 last_underscore = FALSE;
4599 for (p = original; *p; p++)
4601 if (!last_underscore && *p == '_')
4602 last_underscore = TRUE;
4605 last_underscore = FALSE;