]> Pileus Git - ~andy/gtk/blob - gtk/gtktoolbutton.c
don't attempt to add a NULL icon to the box.
[~andy/gtk] / gtk / gtktoolbutton.c
1 /* gtktoolbutton.c
2  *
3  * Copyright (C) 2002 Anders Carlsson <andersca@codefactory.se>
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 "gtktoolbutton.h"
24 #include "gtkbutton.h"
25 #include "gtkhbox.h"
26 #include "gtkiconfactory.h"
27 #include "gtkimage.h"
28 #include "gtkimagemenuitem.h"
29 #include "gtklabel.h"
30 #include "gtkstock.h"
31 #include "gtkvbox.h"
32 #include "gtkintl.h"
33 #include "gtktoolbar.h"
34 #include "gtkiconfactory.h"
35
36 #include <string.h>
37
38 #define MENU_ID "gtk-tool-button-menu-id"
39
40 enum {
41   CLICKED,
42   LAST_SIGNAL
43 };
44
45 enum {
46   PROP_0,
47   PROP_LABEL,
48   PROP_USE_UNDERLINE,
49   PROP_LABEL_WIDGET,
50   PROP_STOCK_ID,
51   PROP_ICON_WIDGET,
52 };
53
54 static void gtk_tool_button_init          (GtkToolButton      *button,
55                                            GtkToolButtonClass *klass);
56 static void gtk_tool_button_class_init    (GtkToolButtonClass *klass);
57 static void gtk_tool_button_set_property  (GObject            *object,
58                                            guint               prop_id,
59                                            const GValue       *value,
60                                            GParamSpec         *pspec);
61 static void gtk_tool_button_get_property  (GObject            *object,
62                                            guint               prop_id,
63                                            GValue             *value,
64                                            GParamSpec         *pspec);
65 static void gtk_tool_button_finalize      (GObject            *object);
66
67 static void gtk_tool_button_toolbar_reconfigured (GtkToolItem *tool_item);
68 static gboolean   gtk_tool_button_create_menu_proxy (GtkToolItem     *item);
69 static void       button_clicked                    (GtkWidget       *widget,
70                                                      GtkToolButton   *button);
71
72 static void gtk_tool_button_construct_contents (GtkToolItem *tool_item);
73       
74 static GObjectClass *parent_class = NULL;
75 static guint         toolbutton_signals[LAST_SIGNAL] = { 0 };
76
77 struct _GtkToolButtonPrivate
78 {
79   GtkWidget *button;
80
81   gchar *stock_id;
82   gchar *label_text;
83   GtkWidget *label_widget;
84   GtkWidget *icon_widget;
85   
86   guint use_underline : 1;
87 };
88
89 GType
90 gtk_tool_button_get_type (void)
91 {
92   static GtkType type = 0;
93
94   if (!type)
95     {
96       static const GTypeInfo type_info =
97         {
98           sizeof (GtkToolButtonClass),
99           (GBaseInitFunc) NULL,
100           (GBaseFinalizeFunc) NULL,
101           (GClassInitFunc) gtk_tool_button_class_init,
102           (GClassFinalizeFunc) NULL,
103           NULL,
104           sizeof (GtkToolButton),
105           0, /* n_preallocs */
106           (GInstanceInitFunc) gtk_tool_button_init,
107         };
108
109       type = g_type_register_static (GTK_TYPE_TOOL_ITEM,
110                                      "GtkToolButton",
111                                      &type_info, 0);
112     }
113   return type;
114 }
115
116 static void
117 gtk_tool_button_class_init (GtkToolButtonClass *klass)
118 {
119   GObjectClass *object_class;
120   GtkWidgetClass *widget_class;
121   GtkToolItemClass *tool_item_class;
122   
123   parent_class = g_type_class_peek_parent (klass);
124   
125   object_class = (GObjectClass *)klass;
126   widget_class = (GtkWidgetClass *)klass;
127   tool_item_class = (GtkToolItemClass *)klass;
128   
129   object_class->set_property = gtk_tool_button_set_property;
130   object_class->get_property = gtk_tool_button_get_property;
131   object_class->finalize = gtk_tool_button_finalize;
132
133   tool_item_class->create_menu_proxy = gtk_tool_button_create_menu_proxy;
134   tool_item_class->toolbar_reconfigured = gtk_tool_button_toolbar_reconfigured;
135   
136   klass->button_type = GTK_TYPE_BUTTON;
137
138   /* Properties are interpreted like this:
139    *
140    *          - if the tool button has an icon_widget, then that widget
141    *            will be used as the icon. Otherwise, if the tool button
142    *            has a stock id, the corresponding stock icon will be
143    *            used. Otherwise, the tool button will not have an icon.
144    *
145    *          - if the tool button has a label_widget then that widget
146    *            will be used as the label. Otherwise, if the tool button
147    *            has a label text, that text will be used as label. Otherwise,
148    *            if the toolbutton has a stock id, the corresponding text
149    *            will be used as label. Otherwise, the toolbutton will
150    *            have an empty label.
151    *
152    *          - The use_underline property only has an effect when the label
153    *            on the toolbutton comes from the label property (ie. not from
154    *            label_widget or from stock_id).
155    *
156    *            In that case, if use_underline is set,
157    *
158    *                    - underscores are removed from the label text before
159    *                      the label is shown on the toolbutton unless the
160    *                      underscore is followed by another underscore
161    *
162    *                    - an underscore indicates that the next character when
163    *                      used in the overflow menu should be used as a mnemonic.
164    *
165    *            In short: use_underline = TRUE means that the label text has
166    *            the form "_Open" and the toolbar should take appropriate action.
167    */
168
169   g_object_class_install_property (object_class,
170                                    PROP_LABEL,
171                                    g_param_spec_string ("label",
172                                                         _("Label"),
173                                                         _("Text to show in the item."),
174                                                         NULL,
175                                                         G_PARAM_READWRITE));
176   g_object_class_install_property (object_class,
177                                    PROP_USE_UNDERLINE,
178                                    g_param_spec_boolean ("use_underline",
179                                                          _("Use underline"),
180                                                          _("If set, an underline in the label property indicates that the next character should be used for the mnemonic accelerator key in the overflow menu"),
181                                                          FALSE,
182                                                          G_PARAM_READWRITE));
183   g_object_class_install_property (object_class,
184                                    PROP_LABEL_WIDGET,
185                                    g_param_spec_object ("label_widget",
186                                                         _("Label widget"),
187                                                         _("Widget to use as the item label"),
188                                                         GTK_TYPE_WIDGET,
189                                                         G_PARAM_READWRITE));
190   g_object_class_install_property (object_class,
191                                    PROP_STOCK_ID,
192                                    g_param_spec_string ("stock_id",
193                                                         _("Stock Id"),
194                                                         _("The stock icon displayed on the item"),
195                                                         NULL,
196                                                         G_PARAM_READWRITE));
197   g_object_class_install_property (object_class,
198                                    PROP_ICON_WIDGET,
199                                    g_param_spec_object ("icon_widget",
200                                                         _("Icon widget"),
201                                                         _("Icon widget to display in the item"),
202                                                         GTK_TYPE_WIDGET,
203                                                         G_PARAM_READWRITE));
204
205   toolbutton_signals[CLICKED] =
206     g_signal_new ("clicked",
207                   G_OBJECT_CLASS_TYPE (klass),
208                   G_SIGNAL_RUN_FIRST,
209                   G_STRUCT_OFFSET (GtkToolButtonClass, clicked),
210                   NULL, NULL,
211                   g_cclosure_marshal_VOID__VOID,
212                   G_TYPE_NONE, 0);
213   
214   g_type_class_add_private (object_class, sizeof (GtkToolButtonPrivate));
215 }
216
217 static void
218 gtk_tool_button_init (GtkToolButton      *button,
219                       GtkToolButtonClass *klass)
220 {
221   GtkToolItem *toolitem = GTK_TOOL_ITEM (button);
222   
223   button->priv = GTK_TOOL_BUTTON_GET_PRIVATE (button);
224
225   gtk_tool_item_set_homogeneous (toolitem, TRUE);
226
227   /* create button */
228   button->priv->button = g_object_new (klass->button_type, NULL);
229   gtk_button_set_focus_on_click (GTK_BUTTON (button->priv->button), FALSE);
230   g_signal_connect_object (button->priv->button, "clicked",
231                            G_CALLBACK (button_clicked), button, 0);
232
233   gtk_container_add (GTK_CONTAINER (button), button->priv->button);
234   gtk_widget_show (button->priv->button);
235 }
236
237 static void
238 gtk_tool_button_construct_contents (GtkToolItem *tool_item)
239 {
240   GtkToolButton *button = GTK_TOOL_BUTTON (tool_item);
241   GtkWidget *label = NULL;
242   GtkWidget *icon = NULL;
243   GtkToolbarStyle style;
244   gboolean need_label = FALSE;
245   gboolean need_icon = FALSE;
246   GtkIconSize icon_size;
247   GtkWidget *box = NULL;
248
249   if (gtk_tool_item_get_proxy_menu_item (tool_item, MENU_ID))
250     {
251       /* Remove item, so it will be recreated on the next
252        * create_proxy_menu_item()
253        */
254       gtk_tool_item_set_proxy_menu_item (tool_item, MENU_ID, NULL);
255     }
256   
257   if (button->priv->icon_widget && button->priv->icon_widget->parent)
258     {
259       gtk_container_remove (GTK_CONTAINER (button->priv->icon_widget->parent),
260                             button->priv->icon_widget);
261     }
262
263   if (button->priv->label_widget && button->priv->label_widget->parent)
264     {
265       gtk_container_remove (GTK_CONTAINER (button->priv->label_widget->parent),
266                             button->priv->label_widget);
267     }
268
269   if (GTK_BIN (button->priv->button)->child)
270     {
271       /* Note: we are not destroying the label_widget or icon_widget
272        * here because they were removed from their containers above
273        */
274       gtk_widget_destroy (GTK_BIN (button->priv->button)->child);
275     }
276
277   style = gtk_tool_item_get_toolbar_style (GTK_TOOL_ITEM (button));
278   
279   if (style != GTK_TOOLBAR_TEXT)
280     need_icon = TRUE;
281
282   if (style != GTK_TOOLBAR_ICONS)
283     need_label = TRUE;
284
285   if (need_label)
286     {
287       if (button->priv->label_widget)
288         {
289           label = button->priv->label_widget;
290         }
291       else
292         {
293           GtkStockItem stock_item;
294           gboolean elide;
295           gchar *label_text;
296
297           if (button->priv->label_text)
298             {
299               label_text = button->priv->label_text;
300               elide = button->priv->use_underline;
301             }
302           else if (button->priv->stock_id && gtk_stock_lookup (button->priv->stock_id, &stock_item))
303             {
304               label_text = stock_item.label;
305               elide = TRUE;
306             }
307           else
308             {
309               label_text = "";
310               elide = FALSE;
311             }
312
313           if (elide)
314             label_text = _gtk_toolbar_elide_underscores (label_text);
315           else
316             label_text = g_strdup (label_text);
317
318           label = gtk_label_new (label_text);
319
320           g_free (label_text);
321           
322           gtk_widget_show (label);
323         }
324     }
325
326   icon_size = gtk_tool_item_get_icon_size (GTK_TOOL_ITEM (button));
327   if (need_icon)
328     {
329       if (button->priv->icon_widget)
330         {
331           icon = button->priv->icon_widget;
332           
333           if (GTK_IS_IMAGE (icon))
334             {
335               g_object_set (G_OBJECT (button->priv->icon_widget),
336                             "icon-size", icon_size,
337                             NULL);
338             }
339         }
340       else if (button->priv->stock_id)
341         {
342           icon = gtk_image_new_from_stock (button->priv->stock_id, icon_size);
343           gtk_widget_show (icon);
344         }
345     }
346
347   switch (style)
348     {
349     case GTK_TOOLBAR_ICONS:
350       if (icon)
351         gtk_container_add (GTK_CONTAINER (button->priv->button), icon);
352       break;
353
354     case GTK_TOOLBAR_BOTH:
355       box = gtk_vbox_new (FALSE, 0);
356       if (icon)
357         gtk_box_pack_start (GTK_BOX (box), icon, TRUE, TRUE, 0);
358       gtk_box_pack_start (GTK_BOX (box), label, FALSE, TRUE, 0);
359       gtk_container_add (GTK_CONTAINER (button->priv->button), box);
360       break;
361
362     case GTK_TOOLBAR_BOTH_HORIZ:
363       box = gtk_hbox_new (FALSE, 0);
364       gtk_box_pack_start (GTK_BOX (box), icon, FALSE, TRUE, 0);
365       gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
366       gtk_container_add (GTK_CONTAINER (button->priv->button), box);
367       break;
368
369     case GTK_TOOLBAR_TEXT:
370       gtk_container_add (GTK_CONTAINER (button->priv->button), label);
371       break;
372     }
373
374   if (box)
375     gtk_widget_show (box);
376
377   gtk_button_set_relief (GTK_BUTTON (button->priv->button),
378                          gtk_tool_item_get_relief_style (GTK_TOOL_ITEM (button)));
379
380   gtk_widget_queue_resize (GTK_WIDGET (button));
381 }
382
383 static void
384 gtk_tool_button_set_property (GObject         *object,
385                               guint            prop_id,
386                               const GValue    *value,
387                               GParamSpec      *pspec)
388 {
389   GtkToolButton *button = GTK_TOOL_BUTTON (object);
390   
391   switch (prop_id)
392     {
393     case PROP_LABEL:
394       gtk_tool_button_set_label (button, g_value_get_string (value));
395       break;
396     case PROP_USE_UNDERLINE:
397       gtk_tool_button_set_use_underline (button, g_value_get_boolean (value));
398       break;
399     case PROP_LABEL_WIDGET:
400       gtk_tool_button_set_label_widget (button, g_value_get_object (value));
401       break;
402     case PROP_STOCK_ID:
403       gtk_tool_button_set_stock_id (button, g_value_get_string (value));
404       break;
405     case PROP_ICON_WIDGET:
406       gtk_tool_button_set_icon_widget (button, g_value_get_object (value));
407       break;
408     default:
409       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
410     }
411 }
412
413 static void
414 gtk_tool_button_get_property (GObject         *object,
415                               guint            prop_id,
416                               GValue          *value,
417                               GParamSpec      *pspec)
418 {
419   GtkToolButton *button = GTK_TOOL_BUTTON (object);
420
421   switch (prop_id)
422     {
423     case PROP_LABEL:
424       g_value_set_string (value, gtk_tool_button_get_label (button));
425       break;
426     case PROP_LABEL_WIDGET:
427       g_value_set_object (value, gtk_tool_button_get_label_widget (button));
428       break;
429     case PROP_USE_UNDERLINE:
430       g_value_set_boolean (value, gtk_tool_button_get_use_underline (button));
431       break;
432     case PROP_STOCK_ID:
433       g_value_set_string (value, button->priv->stock_id);
434       break;
435     case PROP_ICON_WIDGET:
436       g_value_set_object (value, button->priv->icon_widget);
437       break;
438     default:
439       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
440     }
441 }
442
443 static void
444 gtk_tool_button_finalize (GObject *object)
445 {
446   GtkToolButton *button = GTK_TOOL_BUTTON (object);
447
448   if (button->priv->stock_id)
449     g_free (button->priv->stock_id);
450
451   if (button->priv->label_text)
452     g_free (button->priv->label_text);
453
454   if (button->priv->label_widget)
455     g_object_unref (G_OBJECT (button->priv->label_widget));
456
457   if (button->priv->icon_widget)
458     g_object_unref (G_OBJECT (button->priv->icon_widget));
459   
460   parent_class->finalize (object);
461 }
462
463 static GtkWidget *
464 clone_image_menu_size (GtkImage *image, GtkSettings *settings)
465 {
466   GtkImageType storage_type = gtk_image_get_storage_type (image);
467
468   if (storage_type == GTK_IMAGE_STOCK)
469     {
470       gchar *stock_id;
471       gtk_image_get_stock (image, &stock_id, NULL);
472       return gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_MENU);
473     }
474   else if (storage_type == GTK_IMAGE_ICON_SET)
475     {
476       GtkIconSet *icon_set;
477       gtk_image_get_icon_set (image, &icon_set, NULL);
478       return gtk_image_new_from_icon_set (icon_set, GTK_ICON_SIZE_MENU);
479     }
480   else if (storage_type == GTK_IMAGE_PIXBUF)
481     {
482       gint width, height;
483       
484       if (settings &&
485           gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU,
486                                              &width, &height))
487         {
488           GdkPixbuf *src_pixbuf, *dest_pixbuf;
489
490           src_pixbuf = gtk_image_get_pixbuf (image);
491           dest_pixbuf = gdk_pixbuf_scale_simple (src_pixbuf, width, height,
492                                                  GDK_INTERP_BILINEAR);
493
494           return gtk_image_new_from_pixbuf (dest_pixbuf);
495         }
496     }
497
498   return NULL;
499 }
500       
501 static gboolean
502 gtk_tool_button_create_menu_proxy (GtkToolItem *item)
503 {
504   GtkToolButton *button = GTK_TOOL_BUTTON (item);
505   GtkWidget *menu_item;
506   GtkWidget *menu_image = NULL;
507   GtkStockItem stock_item;
508   gboolean use_mnemonic = TRUE;
509   const char *label;
510
511   if (button->priv->label_widget && GTK_IS_LABEL (button->priv->label_widget))
512     {
513       label = gtk_label_get_label (GTK_LABEL (button->priv->label_widget));
514       use_mnemonic = gtk_label_get_use_underline (GTK_LABEL (button->priv->label_widget));
515     }
516   else if (button->priv->label_text)
517     {
518       label = button->priv->label_text;
519       use_mnemonic = button->priv->use_underline;
520     }
521   else if (button->priv->stock_id && gtk_stock_lookup (button->priv->stock_id, &stock_item))
522     {
523       label = stock_item.label;
524       use_mnemonic = FALSE;
525     }
526   else
527     {
528       label = "";
529       use_mnemonic = FALSE;
530     }
531   
532   if (use_mnemonic)
533     menu_item = gtk_image_menu_item_new_with_mnemonic (label);
534   else
535     menu_item = gtk_image_menu_item_new_with_label (label);
536
537   if (button->priv->icon_widget && GTK_IS_IMAGE (button->priv->icon_widget))
538     {
539       menu_image = clone_image_menu_size (GTK_IMAGE (button->priv->icon_widget),
540                                           gtk_widget_get_settings (GTK_WIDGET (button)));
541     }
542   else if (button->priv->stock_id)
543     {
544       menu_image = gtk_image_new_from_stock (button->priv->stock_id, GTK_ICON_SIZE_MENU);
545     }
546
547   if (menu_image)
548     gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), menu_image);
549
550   g_signal_connect_closure_by_id (menu_item,
551                                   g_signal_lookup ("activate", G_OBJECT_TYPE (menu_item)), 0,
552                                   g_cclosure_new_object_swap (G_CALLBACK (gtk_button_clicked),
553                                                               G_OBJECT (GTK_TOOL_BUTTON (button)->priv->button)),
554                                   FALSE);
555
556   gtk_tool_item_set_proxy_menu_item (GTK_TOOL_ITEM (button), MENU_ID, menu_item);
557   
558   return TRUE;
559 }
560
561 static void
562 button_clicked (GtkWidget     *widget,
563                 GtkToolButton *button)
564 {
565   g_signal_emit_by_name (button, "clicked");
566 }
567
568 static void
569 gtk_tool_button_toolbar_reconfigured (GtkToolItem *tool_item)
570 {
571   gtk_tool_button_construct_contents (tool_item);
572 }
573
574 GtkToolItem *
575 gtk_tool_button_new_from_stock (const gchar *stock_id)
576 {
577   GtkToolButton *button;
578
579   g_return_val_if_fail (stock_id != NULL, NULL);
580     
581   button = g_object_new (GTK_TYPE_TOOL_BUTTON,
582                          "stock_id", stock_id,
583                          NULL);
584
585   return GTK_TOOL_ITEM (button);
586 }
587
588 GtkToolItem *
589 gtk_tool_button_new (const gchar *label,
590                      GtkWidget   *icon_widget)
591 {
592   GtkToolButton *button;
593
594   button = g_object_new (GTK_TYPE_TOOL_BUTTON,
595                          NULL);
596   
597   if (label)
598     gtk_tool_button_set_label (button, label);
599
600   if (icon_widget)
601     gtk_tool_button_set_icon_widget (button, icon_widget);
602
603   return GTK_TOOL_ITEM (button);  
604 }
605
606 void
607 gtk_tool_button_set_label (GtkToolButton *button,
608                            const gchar   *label)
609 {
610   gchar *old_label;
611   
612   g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
613
614   old_label = button->priv->label_text;
615
616   button->priv->label_text = g_strdup (label);
617   gtk_tool_button_construct_contents (GTK_TOOL_ITEM (button));
618       
619   g_object_notify (G_OBJECT (button), "label");
620
621   if (old_label)
622     g_free (old_label);
623 }
624
625 G_CONST_RETURN gchar *
626 gtk_tool_button_get_label (GtkToolButton *button)
627 {
628   g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), NULL);
629
630   return button->priv->label_text;
631 }
632
633 void
634 gtk_tool_button_set_use_underline (GtkToolButton *button,
635                                    gboolean       use_underline)
636 {
637   g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
638
639   use_underline = use_underline != FALSE;
640
641   if (use_underline != button->priv->use_underline)
642     {
643       button->priv->use_underline = use_underline;
644
645       gtk_tool_button_construct_contents (GTK_TOOL_ITEM (button));
646
647       g_object_notify (G_OBJECT (button), "use_underline");
648     }
649 }
650
651 gboolean
652 gtk_tool_button_get_use_underline (GtkToolButton *button)
653 {
654   g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), FALSE);
655
656   return button->priv->use_underline;
657 }
658
659 void
660 gtk_tool_button_set_stock_id (GtkToolButton *button,
661                               const gchar   *stock_id)
662 {
663   gchar *old_stock_id;
664   
665   g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
666
667   old_stock_id = button->priv->stock_id;
668
669   button->priv->stock_id = g_strdup (stock_id);
670   gtk_tool_button_construct_contents (GTK_TOOL_ITEM (button));
671   
672   g_object_notify (G_OBJECT (button), "stock_id");
673
674   g_free (old_stock_id);
675 }
676
677 G_CONST_RETURN gchar *
678 gtk_tool_button_get_stock_id (GtkToolButton *button)
679 {
680   g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), NULL);
681
682   return button->priv->stock_id;
683 }
684
685 void
686 gtk_tool_button_set_icon_widget (GtkToolButton *button,
687                                  GtkWidget     *icon)
688 {
689   g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
690   g_return_if_fail (icon == NULL || GTK_IS_WIDGET (icon));
691
692   if (icon != button->priv->icon_widget)
693     {
694       if (button->priv->icon_widget)
695         g_object_unref (G_OBJECT (button->priv->icon_widget));
696
697       if (icon)
698         {
699           g_object_ref (icon);
700           gtk_object_sink (GTK_OBJECT (icon));
701         }
702
703       button->priv->icon_widget = icon;
704
705       gtk_tool_button_construct_contents (GTK_TOOL_ITEM (button));
706       
707       g_object_notify (G_OBJECT (button), "icon_widget");
708     }
709 }
710
711 void
712 gtk_tool_button_set_label_widget (GtkToolButton *button,
713                                   GtkWidget     *label_widget)
714 {
715   g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
716   g_return_if_fail (label_widget == NULL || GTK_IS_WIDGET (label_widget));
717
718   if (label_widget != button->priv->label_widget)
719     {
720       if (button->priv->label_widget)
721         g_object_unref (button->priv->label_widget);
722
723       if (label_widget)
724         {
725           g_object_ref (label_widget);
726           gtk_object_sink (GTK_OBJECT (label_widget));
727         }
728
729       button->priv->label_widget = label_widget;
730
731       gtk_tool_button_construct_contents (GTK_TOOL_ITEM (button));
732       
733       g_object_notify (G_OBJECT (button), "label_widget");
734     }
735 }
736
737 GtkWidget *
738 gtk_tool_button_get_label_widget (GtkToolButton *button)
739 {
740   g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), NULL);
741
742   return button->priv->label_widget;
743 }
744
745 GtkWidget *
746 gtk_tool_button_get_icon_widget (GtkToolButton *button)
747 {
748   g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), NULL);
749
750   return button->priv->icon_widget;
751 }
752
753 GtkWidget *
754 _gtk_tool_button_get_button (GtkToolButton *button)
755 {
756   g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), NULL);
757
758   return button->priv->button;
759 }