]> Pileus Git - ~andy/gtk/blob - gtk/gtktoolitem.c
Call gtk_tool_item_set_visible_vertical for PROP_VISIBLE_VERTICAL.
[~andy/gtk] / gtk / gtktoolitem.c
1 /* gtktoolitem.c
2  *
3  * Copyright (C) 2002 Anders Carlsson <andersca@gnome.org>
4  * Copyright (C) 2002 James Henstridge <james@daa.com.au>
5  * Copyright (C) 2003 Soeren Sandmann <sandmann@daimi.au.dk>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #include "gtktoolitem.h"
24 #include "gtkmarshalers.h"
25 #include "gtktoolbar.h"
26 #include "gtkseparatormenuitem.h"
27 #include "gtkintl.h"
28 #include "gtkmain.h"
29
30 #include <string.h>
31
32 enum {
33   CREATE_MENU_PROXY,
34   TOOLBAR_RECONFIGURED,
35   SET_TOOLTIP,
36   LAST_SIGNAL
37 };
38
39 enum {
40   PROP_0,
41   PROP_VISIBLE_HORIZONTAL,
42   PROP_VISIBLE_VERTICAL,
43   PROP_IS_IMPORTANT
44 };
45
46 #define GTK_TOOL_ITEM_GET_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_TOOL_ITEM, GtkToolItemPrivate))
47
48 struct _GtkToolItemPrivate
49 {
50   gchar *tip_text;
51   gchar *tip_private;
52
53   guint visible_horizontal : 1;
54   guint visible_vertical : 1;
55   guint homogeneous : 1;
56   guint expand : 1;
57   guint use_drag_window : 1;
58   guint is_important : 1;
59
60   GdkWindow *drag_window;
61   
62   gchar *menu_item_id;
63   GtkWidget *menu_item;
64 };
65   
66 static void gtk_tool_item_init       (GtkToolItem *toolitem);
67 static void gtk_tool_item_class_init (GtkToolItemClass *class);
68 static void gtk_tool_item_finalize    (GObject *object);
69 static void gtk_tool_item_parent_set   (GtkWidget   *toolitem,
70                                         GtkWidget   *parent);
71 static void gtk_tool_item_set_property (GObject         *object,
72                                         guint            prop_id,
73                                         const GValue    *value,
74                                         GParamSpec      *pspec);
75 static void gtk_tool_item_get_property (GObject         *object,
76                                         guint            prop_id,
77                                         GValue          *value,
78                                         GParamSpec      *pspec);
79 static void gtk_tool_item_realize       (GtkWidget      *widget);
80 static void gtk_tool_item_unrealize     (GtkWidget      *widget);
81 static void gtk_tool_item_map           (GtkWidget      *widget);
82 static void gtk_tool_item_unmap         (GtkWidget      *widget);
83 static void gtk_tool_item_size_request  (GtkWidget      *widget,
84                                          GtkRequisition *requisition);
85 static void gtk_tool_item_size_allocate (GtkWidget      *widget,
86                                          GtkAllocation  *allocation);
87 static gboolean gtk_tool_item_real_set_tooltip (GtkToolItem *tool_item,
88                                                 GtkTooltips *tooltips,
89                                                 const gchar *tip_text,
90                                                 const gchar *tip_private);
91
92 static gboolean gtk_tool_item_create_menu_proxy (GtkToolItem *item);
93
94
95 static GObjectClass *parent_class = NULL;
96 static guint         toolitem_signals[LAST_SIGNAL] = { 0 };
97
98 GType
99 gtk_tool_item_get_type (void)
100 {
101   static GtkType type = 0;
102
103   if (!type)
104     {
105       static const GTypeInfo type_info =
106         {
107           sizeof (GtkToolItemClass),
108           (GBaseInitFunc) NULL,
109           (GBaseFinalizeFunc) NULL,
110           (GClassInitFunc) gtk_tool_item_class_init,
111           (GClassFinalizeFunc) NULL,
112           NULL,
113         
114           sizeof (GtkToolItem),
115           0, /* n_preallocs */
116           (GInstanceInitFunc) gtk_tool_item_init,
117         };
118
119       type = g_type_register_static (GTK_TYPE_BIN,
120                                      "GtkToolItem",
121                                      &type_info, 0);
122     }
123   return type;
124 }
125
126 static void
127 gtk_tool_item_class_init (GtkToolItemClass *klass)
128 {
129   GObjectClass *object_class;
130   GtkWidgetClass *widget_class;
131   
132   parent_class = g_type_class_peek_parent (klass);
133   object_class = (GObjectClass *)klass;
134   widget_class = (GtkWidgetClass *)klass;
135   
136   object_class->set_property = gtk_tool_item_set_property;
137   object_class->get_property = gtk_tool_item_get_property;
138   object_class->finalize = gtk_tool_item_finalize;
139
140   widget_class->realize       = gtk_tool_item_realize;
141   widget_class->unrealize     = gtk_tool_item_unrealize;
142   widget_class->map           = gtk_tool_item_map;
143   widget_class->unmap         = gtk_tool_item_unmap;
144   widget_class->size_request  = gtk_tool_item_size_request;
145   widget_class->size_allocate = gtk_tool_item_size_allocate;
146   widget_class->parent_set    = gtk_tool_item_parent_set;
147
148   klass->create_menu_proxy = gtk_tool_item_create_menu_proxy;
149   klass->set_tooltip       = gtk_tool_item_real_set_tooltip;
150   
151   g_object_class_install_property (object_class,
152                                    PROP_VISIBLE_HORIZONTAL,
153                                    g_param_spec_boolean ("visible_horizontal",
154                                                          _("Visible when horizontal"),
155                                                          _("Whether the toolbar item is visible when the toolbar is in a horizontal orientation."),
156                                                          TRUE,
157                                                          G_PARAM_READWRITE));
158   g_object_class_install_property (object_class,
159                                    PROP_VISIBLE_VERTICAL,
160                                    g_param_spec_boolean ("visible_vertical",
161                                                          _("Visible when vertical"),
162                                                          _("Whether the toolbar item is visible when the toolbar is in a vertical orientation."),
163                                                          TRUE,
164                                                          G_PARAM_READWRITE));
165   g_object_class_install_property (object_class,
166                                    PROP_IS_IMPORTANT,
167                                    g_param_spec_boolean ("is_important",
168                                                          _("Is important"),
169                                                          _("Whether the toolbar item is considered important. When TRUE, toolbar buttons show text in GTK_TOOLBAR_BOTH_HORIZ mode"),
170                                                          FALSE,
171                                                          G_PARAM_READWRITE));
172
173 /**
174  * GtkToolItem::create-menu-proxy:
175  * @toolitem: the object the signal was emitted on
176  *
177  * This signal is emitted when the toolbar is displaying an overflow menu.
178  * In response the tool item should either 
179  * <itemizedlist>
180  * <listitem> call gtk_tool_item_set_proxy_menu_item() with a %NULL
181  * pointer and return %TRUE to indicate that the item should not appear
182  * in the overflow menu
183  * </listitem>
184  * <listitem> call gtk_tool_item_set_proxy_menu_item() with a new menu
185  * item and return %TRUE, or 
186  * </listitem>
187  * <listitem> return %FALSE to indicate that the signal was not
188  * handled by the item. This means that
189  * the item will not appear in the overflow menu unless a later handler
190  * installs a menu item.
191  * </listitem>
192  * </itemizedlist>
193  * 
194  * Return value: %TRUE if the signal was handled, %FALSE if not
195  **/
196   toolitem_signals[CREATE_MENU_PROXY] =
197     g_signal_new ("create_menu_proxy",
198                   G_OBJECT_CLASS_TYPE (klass),
199                   G_SIGNAL_RUN_LAST,
200                   G_STRUCT_OFFSET (GtkToolItemClass, create_menu_proxy),
201                   _gtk_boolean_handled_accumulator, NULL,
202                   _gtk_marshal_BOOLEAN__VOID,
203                   G_TYPE_BOOLEAN, 0);
204
205 /**
206  * GtkToolItem::toolbar-reconfigured:
207  * @toolitem: the object the signal was emitted on
208  *
209  * This signal is emitted when some property of the toolbar that the
210  * item is a child of changes. For custom subclasses of #GtkToolItem,
211  * the default handler of this signal use the functions
212  * <itemizedlist>
213  * <listitem>gtk_toolbar_get_orientation()</listitem>
214  * <listitem>gtk_toolbar_get_style()</listitem>
215  * <listitem>gtk_toolbar_get_icon_size()</listitem>
216  * <listitem>gtk_toolbar_get_relief_style()</listitem>
217  * </itemizedlist>
218  * to find out what the toolbar should look like and change
219  * themselves accordingly.
220  **/
221   toolitem_signals[TOOLBAR_RECONFIGURED] =
222     g_signal_new ("toolbar_reconfigured",
223                   G_OBJECT_CLASS_TYPE (klass),
224                   G_SIGNAL_RUN_LAST,
225                   G_STRUCT_OFFSET (GtkToolItemClass, toolbar_reconfigured),
226                   NULL, NULL,
227                   _gtk_marshal_VOID__VOID,
228                   G_TYPE_NONE, 0);
229 /**
230  * GtkToolItem::set-tooltip:
231  * @toolitem: the object the signal was emitted on
232  * @tooltips: the #GtkTooltips
233  * @tip_text: the tooltip text
234  * @tip_private: the tooltip private text
235  *
236  * This signal is emitted when the toolitem's tooltip changes.
237  * Application developers can use gtk_tool_item_set_tooltip() to
238  * set the item's tooltip.
239  *
240  * Return value: %TRUE if the signal was handled, %FALSE if not
241  **/
242   toolitem_signals[SET_TOOLTIP] =
243     g_signal_new ("set_tooltip",
244                   G_OBJECT_CLASS_TYPE (klass),
245                   G_SIGNAL_RUN_LAST,
246                   G_STRUCT_OFFSET (GtkToolItemClass, set_tooltip),
247                   _gtk_boolean_handled_accumulator, NULL,
248                   _gtk_marshal_BOOLEAN__OBJECT_STRING_STRING,
249                   G_TYPE_BOOLEAN, 3,
250                   GTK_TYPE_TOOLTIPS,
251                   G_TYPE_STRING,
252                   G_TYPE_STRING);                 
253
254   g_type_class_add_private (object_class, sizeof (GtkToolItemPrivate));
255 }
256
257 static void
258 gtk_tool_item_init (GtkToolItem *toolitem)
259 {
260   GTK_WIDGET_UNSET_FLAGS (toolitem, GTK_CAN_FOCUS);  
261
262   toolitem->priv = GTK_TOOL_ITEM_GET_PRIVATE (toolitem);
263
264   toolitem->priv->visible_horizontal = TRUE;
265   toolitem->priv->visible_vertical = TRUE;
266   toolitem->priv->homogeneous = FALSE;
267   toolitem->priv->expand = FALSE;
268 }
269
270 static void
271 gtk_tool_item_finalize (GObject *object)
272 {
273   GtkToolItem *item = GTK_TOOL_ITEM (object);
274
275   if (item->priv->menu_item)
276     g_object_unref (item->priv->menu_item);
277   
278   if (G_OBJECT_CLASS (parent_class)->finalize)
279     G_OBJECT_CLASS (parent_class)->finalize (object);
280 }
281
282 static void
283 gtk_tool_item_parent_set   (GtkWidget   *toolitem,
284                             GtkWidget   *prev_parent)
285 {
286   _gtk_tool_item_toolbar_reconfigured (GTK_TOOL_ITEM (toolitem));
287 }
288
289 static void
290 gtk_tool_item_set_property (GObject      *object,
291                             guint         prop_id,
292                             const GValue *value,
293                             GParamSpec   *pspec)
294 {
295   GtkToolItem *toolitem = GTK_TOOL_ITEM (object);
296
297   switch (prop_id)
298     {
299     case PROP_VISIBLE_HORIZONTAL:
300       gtk_tool_item_set_visible_horizontal (toolitem, g_value_get_boolean (value));
301       break;
302     case PROP_VISIBLE_VERTICAL:
303       gtk_tool_item_set_visible_vertical (toolitem, g_value_get_boolean (value));
304       break;
305     case PROP_IS_IMPORTANT:
306       gtk_tool_item_set_is_important (toolitem, g_value_get_boolean (value));
307       break;
308     default:
309       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
310     }
311 }
312
313 static void
314 gtk_tool_item_get_property (GObject    *object,
315                             guint       prop_id,
316                             GValue     *value,
317                             GParamSpec *pspec)
318 {
319   GtkToolItem *toolitem = GTK_TOOL_ITEM (object);
320
321   switch (prop_id)
322     {
323     case PROP_VISIBLE_HORIZONTAL:
324       g_value_set_boolean (value, toolitem->priv->visible_horizontal);
325       break;
326     case PROP_VISIBLE_VERTICAL:
327       g_value_set_boolean (value, toolitem->priv->visible_vertical);
328       break;
329     case PROP_IS_IMPORTANT:
330       g_value_set_boolean (value, toolitem->priv->is_important);
331       break;
332     default:
333       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
334     }
335 }
336
337 static void
338 create_drag_window (GtkToolItem *toolitem)
339 {
340   GtkWidget *widget;
341   GdkWindowAttr attributes;
342   gint attributes_mask, border_width;
343
344   g_return_if_fail (toolitem->priv->use_drag_window == TRUE);
345
346   widget = GTK_WIDGET (toolitem);
347   border_width = GTK_CONTAINER (toolitem)->border_width;
348
349   attributes.window_type = GDK_WINDOW_CHILD;
350   attributes.x = widget->allocation.x + border_width;
351   attributes.y = widget->allocation.y + border_width;
352   attributes.width = widget->allocation.width - border_width * 2;
353   attributes.height = widget->allocation.height - border_width * 2;
354   attributes.wclass = GDK_INPUT_ONLY;
355   attributes.event_mask = gtk_widget_get_events (widget);
356   attributes.event_mask |= (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
357
358   attributes_mask = GDK_WA_X | GDK_WA_Y;
359
360   toolitem->priv->drag_window = gdk_window_new (gtk_widget_get_parent_window (widget),
361                                           &attributes, attributes_mask);
362   gdk_window_set_user_data (toolitem->priv->drag_window, toolitem);
363 }
364
365 static void
366 gtk_tool_item_realize (GtkWidget *widget)
367 {
368   GtkToolItem *toolitem;
369
370   toolitem = GTK_TOOL_ITEM (widget);
371   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
372
373   widget->window = gtk_widget_get_parent_window (widget);
374   g_object_ref (widget->window);
375
376   if (toolitem->priv->use_drag_window)
377     create_drag_window(toolitem);
378
379   widget->style = gtk_style_attach (widget->style, widget->window);
380 }
381
382 static void
383 destroy_drag_window (GtkToolItem *toolitem)
384 {
385   if (toolitem->priv->drag_window)
386     {
387       gdk_window_set_user_data (toolitem->priv->drag_window, NULL);
388       gdk_window_destroy (toolitem->priv->drag_window);
389       toolitem->priv->drag_window = NULL;
390     }
391 }
392
393 static void
394 gtk_tool_item_unrealize (GtkWidget *widget)
395 {
396   GtkToolItem *toolitem;
397
398   toolitem = GTK_TOOL_ITEM (widget);
399
400   destroy_drag_window (toolitem);
401   
402   GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
403 }
404
405 static void
406 gtk_tool_item_map (GtkWidget *widget)
407 {
408   GtkToolItem *toolitem;
409
410   toolitem = GTK_TOOL_ITEM (widget);
411   GTK_WIDGET_CLASS (parent_class)->map (widget);
412   if (toolitem->priv->drag_window)
413     gdk_window_show (toolitem->priv->drag_window);
414 }
415
416 static void
417 gtk_tool_item_unmap (GtkWidget *widget)
418 {
419   GtkToolItem *toolitem;
420
421   toolitem = GTK_TOOL_ITEM (widget);
422   if (toolitem->priv->drag_window)
423     gdk_window_hide (toolitem->priv->drag_window);
424   GTK_WIDGET_CLASS (parent_class)->unmap (widget);
425 }
426
427 static void
428 gtk_tool_item_size_request (GtkWidget      *widget,
429                             GtkRequisition *requisition)
430 {
431   GtkWidget *child = GTK_BIN (widget)->child;
432
433   if (child && GTK_WIDGET_VISIBLE (child))
434     {
435       gtk_widget_size_request (child, requisition);
436     }
437   else
438     {
439       requisition->height = 0;
440       requisition->width = 0;
441     }
442   
443   requisition->width += (GTK_CONTAINER (widget)->border_width) * 2;
444   requisition->height += (GTK_CONTAINER (widget)->border_width) * 2;
445 }
446
447 static void
448 gtk_tool_item_size_allocate (GtkWidget     *widget,
449                              GtkAllocation *allocation)
450 {
451   GtkToolItem *toolitem = GTK_TOOL_ITEM (widget);
452   GtkAllocation child_allocation;
453   gint border_width;
454   GtkWidget *child = GTK_BIN (widget)->child;
455
456   widget->allocation = *allocation;
457   border_width = GTK_CONTAINER (widget)->border_width;
458
459   if (toolitem->priv->drag_window)
460     gdk_window_move_resize (toolitem->priv->drag_window,
461                             widget->allocation.x + border_width,
462                             widget->allocation.y + border_width,
463                             widget->allocation.width - border_width * 2,
464                             widget->allocation.height - border_width * 2);
465   
466   if (child && GTK_WIDGET_VISIBLE (child))
467     {
468       child_allocation.x = allocation->x + border_width;
469       child_allocation.y = allocation->y + border_width;
470       child_allocation.width = allocation->width - 2 * border_width;
471       child_allocation.height = allocation->height - 2 * border_width;
472       
473       gtk_widget_size_allocate (child, &child_allocation);
474     }
475 }
476
477 static gboolean
478 gtk_tool_item_create_menu_proxy (GtkToolItem *item)
479 {
480   return FALSE;
481 }
482
483 /**
484  * gtk_tool_item_new:
485  * 
486  * Creates a new #GtkToolItem
487  * 
488  * Return value: the new #GtkToolItem
489  * 
490  * Since: 2.4
491  **/
492 GtkToolItem *
493 gtk_tool_item_new (void)
494 {
495   GtkToolItem *item;
496
497   item = g_object_new (GTK_TYPE_TOOL_ITEM, NULL);
498
499   return item;
500 }
501
502 /**
503  * gtk_tool_item_get_icon_size:
504  * @tool_item: a #GtkToolItem:
505  * 
506  * Returns the icon size used for @tool_item. Custom subclasses of
507  * #GtkToolItem should call this function to find out what size icons
508  * they should use.
509  * 
510  * Return value: a #GtkIconSize indicating the icon size used for @tool_item
511  * 
512  * Since: 2.4
513  **/
514 GtkIconSize
515 gtk_tool_item_get_icon_size (GtkToolItem *tool_item)
516 {
517   GtkWidget *parent;
518
519   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ICON_SIZE_LARGE_TOOLBAR);
520
521   parent = GTK_WIDGET (tool_item)->parent;
522   if (!parent || !GTK_IS_TOOLBAR (parent))
523     return GTK_ICON_SIZE_LARGE_TOOLBAR;
524
525   return gtk_toolbar_get_icon_size (GTK_TOOLBAR (parent));
526 }
527
528 /**
529  * gtk_tool_item_get_orientation:
530  * @tool_item: a #GtkToolItem: 
531  * 
532  * Returns the orientation used for @tool_item. Custom subclasses of
533  * #GtkToolItem should call this function to find out what size icons
534  * they should use.
535  * 
536  * Return value: a #GtkOrientation indicating the orientation
537  * used for @tool_item
538  * 
539  * Since: 2.4
540  **/
541 GtkOrientation
542 gtk_tool_item_get_orientation (GtkToolItem *tool_item)
543 {
544   GtkWidget *parent;
545   
546   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ORIENTATION_HORIZONTAL);
547
548   parent = GTK_WIDGET (tool_item)->parent;
549   if (!parent || !GTK_IS_TOOLBAR (parent))
550     return GTK_ORIENTATION_HORIZONTAL;
551
552   return gtk_toolbar_get_orientation (GTK_TOOLBAR (parent));
553 }
554
555 /**
556  * gtk_tool_item_get_toolbar_style:
557  * @tool_item: a #GtkToolItem: 
558  * 
559  * Returns the toolbar style used for @tool_item. Custom subclasses of
560  * #GtkToolItem should call this function in the handler of the
561  * GtkToolItem::toolbar_reconfigured signal to find out in what style
562  * the toolbar is displayed and change themselves accordingly 
563  *
564  * Possibilities are:
565  * <itemizedlist>
566  * <listitem> GTK_TOOLBAR_BOTH, meaning the tool item should show
567  * both an icon and a label, stacked vertically </listitem>
568  * <listitem> GTK_TOOLBAR_ICONS, meaning the toolbar shows
569  * only icons </listitem>
570  * <listitem> GTK_TOOLBAR_TEXT, meaning the tool item should only
571  * show text</listitem>
572  * <listitem> GTK_TOOLBAR_BOTH_HORIZ, meaning the tool item should show
573  * both an icon and a label, arranged horizontally (however, note the 
574  * #GtkToolButton::has_text_horizontally that makes tool buttons not
575  * show labels when the toolbar style is GTK_TOOLBAR_BOTH_HORIZ.
576  * </listitem>
577  * </itemizedlist>
578  * 
579  * Return value: A #GtkToolbarStyle indicating the toolbar style used
580  * for @tool_item.
581  * 
582  * Since: 2.4
583  **/
584 GtkToolbarStyle
585 gtk_tool_item_get_toolbar_style (GtkToolItem *tool_item)
586 {
587   GtkWidget *parent;
588   
589   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_TOOLBAR_ICONS);
590
591   parent = GTK_WIDGET (tool_item)->parent;
592   if (!parent || !GTK_IS_TOOLBAR (parent))
593     return GTK_TOOLBAR_ICONS;
594
595   return gtk_toolbar_get_style (GTK_TOOLBAR (parent));
596 }
597
598 /**
599  * gtk_tool_item_get_relief_style:
600  * @tool_item: a #GtkToolItem: 
601  * 
602  * Returns the relief style of @tool_item. See gtk_button_set_relief_style().
603  * Custom subclasses of #GtkToolItem should call this function in the handler
604  * of the #GtkToolItem::toolbar_reconfigured signal to find out the
605  * relief style of buttons.
606  * 
607  * Return value: a #GtkReliefStyle indicating the relief style used
608  * for @tool_item.
609  * 
610  * Since: 2.4
611  **/
612 GtkReliefStyle 
613 gtk_tool_item_get_relief_style (GtkToolItem *tool_item)
614 {
615   GtkWidget *parent;
616   
617   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_RELIEF_NONE);
618
619   parent = GTK_WIDGET (tool_item)->parent;
620   if (!parent || !GTK_IS_TOOLBAR (parent))
621     return GTK_RELIEF_NONE;
622
623   return gtk_toolbar_get_relief_style (GTK_TOOLBAR (parent));
624 }
625
626 /**
627  * gtk_tool_item_set_expand:
628  * @tool_item: a #GtkToolItem: 
629  * @expand: Whether @tool_item is allocated extra space
630  * 
631  * Sets whether @tool_item is allocated extra space when there
632  * is more room on the toolbar then needed for the items. The
633  * effect is that the item gets bigger when the toolbar gets bigger
634  * and smaller when the toolbar gets smaller.
635  * 
636  * Since: 2.4
637  **/
638 void
639 gtk_tool_item_set_expand (GtkToolItem *tool_item,
640                           gboolean     expand)
641 {
642   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
643     
644   expand = expand != FALSE;
645
646   if (tool_item->priv->expand != expand)
647     {
648       tool_item->priv->expand = expand;
649       gtk_widget_child_notify (GTK_WIDGET (tool_item), "expand");
650       gtk_widget_queue_resize (GTK_WIDGET (tool_item));
651     }
652 }
653
654 /**
655  * gtk_tool_item_get_expand:
656  * @tool_item: a #GtkToolItem: 
657  * 
658  * Returns whether @tool_item is allocated extra space.
659  * See gtk_tool_item_set_expand().
660  * 
661  * Return value: %TRUE if @tool_item is allocated extra space.
662  * 
663  * Since: 2.4
664  **/
665 gboolean
666 gtk_tool_item_get_expand (GtkToolItem *tool_item)
667 {
668   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), FALSE);
669
670   return tool_item->priv->expand;
671 }
672
673 /**
674  * gtk_tool_item_set_homogeneous:
675  * @tool_item: a #GtkToolItem: 
676  * @homogeneous: whether @tool_item is the same size as other homogeneous items
677  * 
678  * Sets whether @tool_item is to be allocated the same size as other
679  * homogeneous items. The effect is that all homogeneous items will have
680  * the same width as the widest of the items.
681  * 
682  * Since: 2.4
683  **/
684 void
685 gtk_tool_item_set_homogeneous (GtkToolItem *tool_item,
686                                gboolean     homogeneous)
687 {
688   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
689     
690   homogeneous = homogeneous != FALSE;
691
692   if (tool_item->priv->homogeneous != homogeneous)
693     {
694       tool_item->priv->homogeneous = homogeneous;
695       gtk_widget_child_notify (GTK_WIDGET (tool_item), "homogeneous");
696       gtk_widget_queue_resize (GTK_WIDGET (tool_item));
697     }
698 }
699
700 /**
701  * gtk_tool_item_get_homogeneous:
702  * @tool_item: a #GtkToolItem: 
703  * 
704  * Returns whether @tool_item is the same size as other homogeneous
705  * items. See gtk_tool_item_set_homogeneous().
706  * 
707  * Return value: %TRUE if the item is the same size as other homogeneous
708  * item.s
709  * 
710  * Since: 2.4
711  **/
712 gboolean
713 gtk_tool_item_get_homogeneous (GtkToolItem *tool_item)
714 {
715   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), FALSE);
716
717   return tool_item->priv->homogeneous;
718 }
719
720 /**
721  * gtk_tool_item_get_is_important:
722  * @tool_item: a #GtkToolItem
723  * 
724  * Returns whether @tool_item is considered important. See
725  * gtk_tool_item_set_is_important()
726  * 
727  * Return value: %TRUE if @tool_item is considered important.
728  * 
729  * Since: 2.4
730  **/
731 gboolean
732 gtk_tool_item_get_is_important (GtkToolItem *tool_item)
733 {
734   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), FALSE);
735
736   return tool_item->priv->is_important;
737 }
738
739 /**
740  * gtk_tool_item_set_is_important:
741  * @tool_item: a #GtkToolItem
742  * @is_important: whether the tool item should be considered important
743  * 
744  * Sets whether @tool_item should be considered important. The #GtkToolButton
745  * class uses this property to determine whether to show or hide its label
746  * when the toolbar style is %GTK_TOOLBAR_BOTH_HORIZ. The result is that
747  * only tool buttons with the "is_important" property set have labels, an
748  * effect known as "priority text"
749  * 
750  * Since: 2.4
751  **/
752 void
753 gtk_tool_item_set_is_important (GtkToolItem *tool_item, gboolean is_important)
754 {
755   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
756
757   is_important = is_important != FALSE;
758
759   if (is_important != tool_item->priv->is_important)
760     {
761       tool_item->priv->is_important = is_important;
762
763       gtk_widget_queue_resize (GTK_WIDGET (tool_item));
764
765       g_object_notify (G_OBJECT (tool_item), "is_important");
766     }
767 }
768
769 static gboolean
770 gtk_tool_item_real_set_tooltip (GtkToolItem *tool_item,
771                                 GtkTooltips *tooltips,
772                                 const gchar *tip_text,
773                                 const gchar *tip_private)
774 {
775   GtkWidget *child = GTK_BIN (tool_item)->child;
776
777   if (!child)
778     return FALSE;
779
780   gtk_tooltips_set_tip (tooltips, child, tip_text, tip_private);
781
782   return TRUE;
783 }
784
785 /**
786  * gtk_tool_item_set_tooltip:
787  * @tool_item: a #GtkToolItem: 
788  * @tooltips: The #GtkTooltips object to be used
789  * @tip_text: text to be used as tooltip text for @tool_item
790  * @tip_private: text to be used as private tooltip text
791  *
792  * Sets the #GtkTooltips object to be used for @tool_item, the
793  * text to be displayed as tooltip on the item and the private text
794  * to be used. See gtk_tooltips_set_tip().
795  * 
796  * Since: 2.4
797  **/
798 void
799 gtk_tool_item_set_tooltip (GtkToolItem *tool_item,
800                            GtkTooltips *tooltips,
801                            const gchar *tip_text,
802                            const gchar *tip_private)
803 {
804   gboolean retval;
805   
806   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
807
808   g_signal_emit (tool_item, toolitem_signals[SET_TOOLTIP], 0,
809                  tooltips, tip_text, tip_private, &retval);
810 }
811
812 /**
813  * gtk_tool_item_set_use_drag_window:
814  * @toolitem: a #GtkToolItem 
815  * @use_drag_window: Whether @toolitem has a drag window.
816  * 
817  * Sets whether @toolitem has a drag window. When %TRUE the
818  * toolitem can be used as a drag source through gtk_drag_source_set().
819  * When @toolitem has a drag window it will intercept all events,
820  * even those that would otherwise be sent to a child of @toolitem.
821  * 
822  * Since: 2.4
823  **/
824 void
825 gtk_tool_item_set_use_drag_window (GtkToolItem *toolitem,
826                                    gboolean     use_drag_window)
827 {
828   g_return_if_fail (GTK_IS_TOOL_ITEM (toolitem));
829
830   use_drag_window = use_drag_window != FALSE;
831
832   if (toolitem->priv->use_drag_window != use_drag_window)
833     {
834       toolitem->priv->use_drag_window = use_drag_window;
835       
836       if (use_drag_window)
837         {
838           if (!toolitem->priv->drag_window && GTK_WIDGET_REALIZED (toolitem))
839             {
840               create_drag_window(toolitem);
841               if (GTK_WIDGET_MAPPED (toolitem))
842                 gdk_window_show (toolitem->priv->drag_window);
843             }
844         }
845       else
846         {
847           destroy_drag_window (toolitem);
848         }
849     }
850 }
851
852 /**
853  * gtk_tool_item_get_use_drag_window:
854  * @toolitem: a #GtkToolItem 
855  * 
856  * Returns whether @toolitem has a drag window. See
857  * gtk_tool_item_set_use_drag_window().
858  * 
859  * Return value: %TRUE if @toolitem uses a drag window.
860  * 
861  * Since: 2.4
862  **/
863 gboolean
864 gtk_tool_item_get_use_drag_window (GtkToolItem *toolitem)
865 {
866   g_return_val_if_fail (GTK_IS_TOOL_ITEM (toolitem), FALSE);
867
868   return toolitem->priv->use_drag_window;
869 }
870
871 /**
872  * gtk_tool_item_set_visible_horizontal:
873  * @toolitem: a #GtkToolItem
874  * @visible_horizontal: Whether @toolitem is visible when in horizontal mode
875  * 
876  * Sets whether @toolitem is visible when the toolbar is docked horizontally.
877  * 
878  * Since: 2.4
879  **/
880 void
881 gtk_tool_item_set_visible_horizontal (GtkToolItem *toolitem,
882                                       gboolean     visible_horizontal)
883 {
884   g_return_if_fail (GTK_IS_TOOL_ITEM (toolitem));
885
886   visible_horizontal = visible_horizontal != FALSE;
887
888   if (toolitem->priv->visible_horizontal != visible_horizontal)
889     {
890       toolitem->priv->visible_horizontal = visible_horizontal;
891
892       g_object_notify (G_OBJECT (toolitem), "visible_horizontal");
893
894       gtk_widget_queue_resize (GTK_WIDGET (toolitem));
895     }
896 }
897
898 /**
899  * gtk_tool_item_get_visible_horizontal:
900  * @toolitem: a #GtkToolItem 
901  * 
902  * Returns whether the @toolitem is visible on toolbars that are
903  * docked horizontally.
904  * 
905  * Return value: %TRUE if @toolitem is visible on toolbars that are
906  * docked horizontally.
907  * 
908  * Since: 2.4
909  **/
910 gboolean
911 gtk_tool_item_get_visible_horizontal (GtkToolItem *toolitem)
912 {
913   g_return_val_if_fail (GTK_IS_TOOL_ITEM (toolitem), FALSE);
914
915   return toolitem->priv->visible_horizontal;
916 }
917
918 /**
919  * gtk_tool_item_set_visible_vertical:
920  * @toolitem: a #GtkToolItem 
921  * @visible_vertical: whether @toolitem is visible when the toolbar
922  * is in vertical mode
923  *
924  * Sets whether @toolitem is visible when the toolbar is docked
925  * vertically. Some tool items, such as text entries, are too wide to be
926  * useful on a vertically docked toolbar. If @visible_vertical is %FALSE
927  * @toolitem will not appear on toolbars that are docked vertically.
928  * 
929  * Since: 2.4
930  **/
931 void
932 gtk_tool_item_set_visible_vertical (GtkToolItem *toolitem,
933                                     gboolean     visible_vertical)
934 {
935   g_return_if_fail (GTK_IS_TOOL_ITEM (toolitem));
936
937   visible_vertical = visible_vertical != FALSE;
938
939   if (toolitem->priv->visible_vertical != visible_vertical)
940     {
941       toolitem->priv->visible_vertical = visible_vertical;
942
943       g_object_notify (G_OBJECT (toolitem), "visible_vertical");
944
945       gtk_widget_queue_resize (GTK_WIDGET (toolitem));
946     }
947 }
948
949 /**
950  * gtk_tool_item_get_visible_vertical:
951  * @toolitem: a #GtkToolItem 
952  * 
953  * Returns whether @toolitem is visible when the toolbar is docked vertically.
954  * See gtk_tool_item_set_visible_vertical().
955  * 
956  * Return value: Whether @toolitem is visible when the toolbar is docked vertically
957  * 
958  * Since: 2.4
959  **/
960 gboolean
961 gtk_tool_item_get_visible_vertical (GtkToolItem *toolitem)
962 {
963   g_return_val_if_fail (GTK_IS_TOOL_ITEM (toolitem), FALSE);
964
965   return toolitem->priv->visible_vertical;
966 }
967
968 /**
969  * gtk_tool_item_retrieve_proxy_menu_item:
970  * @tool_item: a #GtkToolItem: 
971  * 
972  * Returns the #GtkMenuItem that was last set by
973  * gtk_tool_item_set_proxy_menu_item(), ie. the #GtkMenuItem
974  * that is going to appear in the overflow menu.
975  * 
976  * Return value: The #GtkMenuItem that is going to appear in the
977  * overflow menu for @tool_item.
978  * 
979  * Since: 2.4
980  **/
981 GtkWidget *
982 gtk_tool_item_retrieve_proxy_menu_item (GtkToolItem *tool_item)
983 {
984   gboolean retval;
985   
986   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
987
988   g_signal_emit (tool_item, toolitem_signals[CREATE_MENU_PROXY], 0, &retval);
989   
990   return tool_item->priv->menu_item;
991 }
992
993 /**
994  * gtk_tool_item_get_proxy_menu_item:
995  * @tool_item: a #GtkToolItem: 
996  * @menu_item_id: a string used to identify the menu item
997  * 
998  * If @menu_item_id matches the string passed to
999  * gtk_tool_item_set_proxy_menu_item() return the corresponding #GtkMenuItem.
1000  *
1001  * Custom subclasses of #GtkToolItem should use this function to update
1002  * their menu item when the #GtkToolItem changes. That the
1003  * @menu_item_id<!-- -->s must match ensures that a #GtkToolItem will not
1004  * inadvertently change a menu item that they did not create.
1005  * 
1006  * Return value: The #GtkMenuItem passed to
1007  * gtk_tool_item_set_proxy_menu_item(), if the @menu_item_id<!-- -->s match.
1008  * 
1009  * Since: 2.4
1010  **/
1011 GtkWidget *
1012 gtk_tool_item_get_proxy_menu_item (GtkToolItem *tool_item,
1013                                    const gchar *menu_item_id)
1014 {
1015   g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
1016   g_return_val_if_fail (menu_item_id != NULL, NULL);
1017
1018   if (tool_item->priv->menu_item_id && strcmp (tool_item->priv->menu_item_id, menu_item_id) == 0)
1019     return tool_item->priv->menu_item;
1020
1021   return NULL;
1022 }
1023
1024 /**
1025  * gtk_tool_item_set_proxy_menu_item:
1026  * @tool_item: a #GtkToolItem:
1027  * @menu_item_id: a string used to identify @menu_item
1028  * @menu_item: a #GtkMenuItem to be used in the overflow menu
1029  * 
1030  * Sets the #GtkMenuItem used in the toolbar overflow menu. The
1031  * @menu_item_id is used to identify the caller of this function and
1032  * should also be used with gtk_tool_item_get_proxy_menu_item().
1033  * 
1034  * Since: 2.4
1035  **/
1036 void
1037 gtk_tool_item_set_proxy_menu_item (GtkToolItem *tool_item,
1038                                    const gchar *menu_item_id,
1039                                    GtkWidget   *menu_item)
1040 {
1041   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1042   g_return_if_fail (menu_item == NULL || GTK_IS_MENU_ITEM (menu_item));
1043   g_return_if_fail (menu_item_id != NULL);
1044
1045   if (tool_item->priv->menu_item_id)
1046     g_free (tool_item->priv->menu_item_id);
1047       
1048   tool_item->priv->menu_item_id = g_strdup (menu_item_id);
1049
1050   if (tool_item->priv->menu_item != menu_item)
1051     {
1052       if (tool_item->priv->menu_item)
1053         g_object_unref (G_OBJECT (tool_item->priv->menu_item));
1054       
1055       if (menu_item)
1056         {
1057           g_object_ref (menu_item);
1058           gtk_object_sink (GTK_OBJECT (menu_item));
1059         }
1060       
1061       tool_item->priv->menu_item = menu_item;
1062     }
1063 }
1064
1065 /**
1066  * _gtk_tool_item_toolbar_reconfigured:
1067  * @tool_item: a #GtkToolItem: 
1068  * 
1069  * Emits the signal #GtkToolItem::toolbar_reconfigured on @tool_item. This
1070  * internal function is called by #GtkToolbar when some aspect of its
1071  * configuration changes.
1072  * 
1073  * Since: 2.4
1074  **/
1075 void
1076 _gtk_tool_item_toolbar_reconfigured (GtkToolItem *tool_item)
1077 {
1078   g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
1079
1080   g_signal_emit (tool_item, toolitem_signals[TOOLBAR_RECONFIGURED], 0);
1081   
1082   gtk_widget_queue_resize (GTK_WIDGET (tool_item));
1083 }
1084