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