]> Pileus Git - ~andy/gtk/blob - gtk/gtktoolbar.c
Patch from Matthias Clasen to remove remove all instances of
[~andy/gtk] / gtk / gtktoolbar.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  * GtkToolbar copyright (C) Federico Mena
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 /*
22  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
23  * file for a list of people on the GTK+ Team.  See the ChangeLog
24  * files for a list of changes.  These files are distributed with
25  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
26  */
27
28 #include "gtkbutton.h"
29 #include "gtktogglebutton.h"
30 #include "gtkradiobutton.h"
31 #include "gtklabel.h"
32 #include "gtkvbox.h"
33 #include "gtkhbox.h"
34 #include "gtktoolbar.h"
35 #include "gtkstock.h"
36 #include "gtkiconfactory.h"
37 #include "gtkimage.h"
38 #include "gtksettings.h"
39 #include "gtkintl.h"
40
41
42 #define DEFAULT_IPADDING 0
43 #define DEFAULT_SPACE_SIZE  5
44 #define DEFAULT_SPACE_STYLE GTK_TOOLBAR_SPACE_LINE
45
46 #define DEFAULT_ICON_SIZE GTK_ICON_SIZE_LARGE_TOOLBAR
47
48 #define SPACE_LINE_DIVISION 10
49 #define SPACE_LINE_START    3
50 #define SPACE_LINE_END      7
51
52 enum {
53   PROP_0,
54   PROP_ORIENTATION,
55   PROP_TOOLBAR_STYLE,
56 };
57
58 enum {
59   ORIENTATION_CHANGED,
60   STYLE_CHANGED,
61   LAST_SIGNAL
62 };
63
64 typedef struct _GtkToolbarChildSpace GtkToolbarChildSpace;
65 struct _GtkToolbarChildSpace
66 {
67   GtkToolbarChild child;
68
69   gint alloc_x, alloc_y;
70 };
71
72 static void gtk_toolbar_class_init               (GtkToolbarClass *class);
73 static void gtk_toolbar_init                     (GtkToolbar      *toolbar);
74 static void gtk_toolbar_finalize                 (GObject         *object);
75 static void gtk_toolbar_set_property             (GObject         *object,
76                                                   guint            prop_id,
77                                                   const GValue    *value,
78                                                   GParamSpec      *pspec);
79 static void gtk_toolbar_get_property             (GObject         *object,
80                                                   guint            prop_id,
81                                                   GValue          *value,
82                                                   GParamSpec      *pspec);
83 static void gtk_toolbar_destroy                  (GtkObject       *object);
84 static void gtk_toolbar_map                      (GtkWidget       *widget);
85 static void gtk_toolbar_unmap                    (GtkWidget       *widget);
86 static gint gtk_toolbar_expose                   (GtkWidget       *widget,
87                                                   GdkEventExpose  *event);
88 static void gtk_toolbar_size_request             (GtkWidget       *widget,
89                                                   GtkRequisition  *requisition);
90 static void gtk_toolbar_size_allocate            (GtkWidget       *widget,
91                                                   GtkAllocation   *allocation);
92 static void gtk_toolbar_style_set                (GtkWidget       *widget,
93                                                   GtkStyle        *prev_style);
94 static gboolean gtk_toolbar_focus                (GtkWidget       *widget,
95                                                   GtkDirectionType dir);
96 static void gtk_toolbar_show_all                 (GtkWidget       *widget);
97 static void gtk_toolbar_add                      (GtkContainer    *container,
98                                                   GtkWidget       *widget);
99 static void gtk_toolbar_remove                   (GtkContainer    *container,
100                                                   GtkWidget       *widget);
101 static void gtk_toolbar_forall                   (GtkContainer    *container,
102                                                   gboolean         include_internals,
103                                                   GtkCallback      callback,
104                                                   gpointer         callback_data);
105
106 static void gtk_real_toolbar_orientation_changed (GtkToolbar      *toolbar,
107                                                   GtkOrientation   orientation);
108 static void gtk_real_toolbar_style_changed       (GtkToolbar      *toolbar,
109                                                   GtkToolbarStyle  style);
110
111 static GtkWidget * gtk_toolbar_internal_insert_element (GtkToolbar          *toolbar,
112                                                         GtkToolbarChildType  type,
113                                                         GtkWidget           *widget,
114                                                         const char          *text,
115                                                         const char          *tooltip_text,
116                                                         const char          *tooltip_private_text,
117                                                         GtkWidget           *icon,
118                                                         GtkSignalFunc        callback,
119                                                         gpointer             user_data,
120                                                         gint                 position,
121                                                         gboolean             has_mnemonic);
122
123 static GtkWidget * gtk_toolbar_internal_insert_item (GtkToolbar    *toolbar,
124                                                      const char    *text,
125                                                      const char    *tooltip_text,
126                                                      const char    *tooltip_private_text,
127                                                      GtkWidget     *icon,
128                                                      GtkSignalFunc  callback,
129                                                      gpointer       user_data,
130                                                      gint           position,
131                                                      gboolean       has_mnemonic);
132
133 static void        gtk_toolbar_update_button_relief (GtkToolbar *toolbar);
134
135 static GtkReliefStyle       get_button_relief (GtkToolbar *toolbar);
136 static gint                 get_space_size    (GtkToolbar *toolbar);
137 static GtkToolbarSpaceStyle get_space_style   (GtkToolbar *toolbar);
138
139
140 static GtkContainerClass *parent_class;
141
142 static guint toolbar_signals[LAST_SIGNAL] = { 0 };
143
144
145 GtkType
146 gtk_toolbar_get_type (void)
147 {
148   static GtkType toolbar_type = 0;
149
150   if (!toolbar_type)
151     {
152       static const GtkTypeInfo toolbar_info =
153       {
154         "GtkToolbar",
155         sizeof (GtkToolbar),
156         sizeof (GtkToolbarClass),
157         (GtkClassInitFunc) gtk_toolbar_class_init,
158         (GtkObjectInitFunc) gtk_toolbar_init,
159         /* reserved_1 */ NULL,
160         /* reserved_2 */ NULL,
161         (GtkClassInitFunc) NULL,
162       };
163
164       toolbar_type = gtk_type_unique (gtk_container_get_type (), &toolbar_info);
165     }
166
167   return toolbar_type;
168 }
169
170 static void
171 gtk_toolbar_class_init (GtkToolbarClass *class)
172 {
173   GObjectClass   *gobject_class;
174   GtkObjectClass *object_class;
175   GtkWidgetClass *widget_class;
176   GtkContainerClass *container_class;
177
178   gobject_class = G_OBJECT_CLASS (class);
179   object_class = (GtkObjectClass *) class;
180   widget_class = (GtkWidgetClass *) class;
181   container_class = (GtkContainerClass *) class;
182
183   parent_class = gtk_type_class (gtk_container_get_type ());
184
185   gobject_class->finalize = gtk_toolbar_finalize;
186   
187   object_class->destroy = gtk_toolbar_destroy;
188   gobject_class->set_property = gtk_toolbar_set_property;
189   gobject_class->get_property = gtk_toolbar_get_property;
190
191   widget_class->map = gtk_toolbar_map;
192   widget_class->unmap = gtk_toolbar_unmap;
193   widget_class->expose_event = gtk_toolbar_expose;
194   widget_class->size_request = gtk_toolbar_size_request;
195   widget_class->size_allocate = gtk_toolbar_size_allocate;
196   widget_class->style_set = gtk_toolbar_style_set;
197   widget_class->show_all = gtk_toolbar_show_all;
198   widget_class->focus = gtk_toolbar_focus;
199   
200   container_class->add = gtk_toolbar_add;
201   container_class->remove = gtk_toolbar_remove;
202   container_class->forall = gtk_toolbar_forall;
203   
204   class->orientation_changed = gtk_real_toolbar_orientation_changed;
205   class->style_changed = gtk_real_toolbar_style_changed;
206
207   toolbar_signals[ORIENTATION_CHANGED] =
208     gtk_signal_new ("orientation_changed",
209                     GTK_RUN_FIRST,
210                     GTK_CLASS_TYPE (object_class),
211                     GTK_SIGNAL_OFFSET (GtkToolbarClass, orientation_changed),
212                     gtk_marshal_VOID__INT,
213                     GTK_TYPE_NONE, 1,
214                     GTK_TYPE_INT);
215   toolbar_signals[STYLE_CHANGED] =
216     gtk_signal_new ("style_changed",
217                     GTK_RUN_FIRST,
218                     GTK_CLASS_TYPE (object_class),
219                     GTK_SIGNAL_OFFSET (GtkToolbarClass, style_changed),
220                     gtk_marshal_VOID__INT,
221                     GTK_TYPE_NONE, 1,
222                     GTK_TYPE_INT);
223   
224   g_object_class_install_property (gobject_class,
225                                    PROP_ORIENTATION,
226                                    g_param_spec_enum ("orientation",
227                                                       _("Orientation"),
228                                                       _("The orientation of the toolbar"),
229                                                       GTK_TYPE_ORIENTATION,
230                                                       GTK_ORIENTATION_HORIZONTAL,
231                                                       G_PARAM_READWRITE));
232  
233    g_object_class_install_property (gobject_class,
234                                     PROP_TOOLBAR_STYLE,
235                                     g_param_spec_enum ("toolbar_style",
236                                                       _("Toolbar Style"),
237                                                       _("How to draw the toolbar"),
238                                                       GTK_TYPE_TOOLBAR_STYLE,
239                                                       GTK_TOOLBAR_ICONS,
240                                                       G_PARAM_READWRITE));
241
242
243   gtk_widget_class_install_style_property (widget_class,
244                                            g_param_spec_int ("space_size",
245                                                              _("Spacer size"),
246                                                              _("Size of spacers"),
247                                                              0,
248                                                              G_MAXINT,
249                                                              DEFAULT_SPACE_SIZE,
250                                                              G_PARAM_READABLE));
251
252   gtk_widget_class_install_style_property (widget_class,
253                                            g_param_spec_int ("internal_padding",
254                                                              _("Internal padding"),
255                                                              _("Amount of border space between the toolbar shadow and the buttons"),
256                                                              0,
257                                                              G_MAXINT,
258                                                              DEFAULT_IPADDING,
259                                                              G_PARAM_READABLE));
260   
261   gtk_widget_class_install_style_property (widget_class,
262                                            g_param_spec_enum ("space_style",
263                                                              _("Space style"),
264                                                              _("Whether spacers are vertical lines or just blank"),
265                                                               GTK_TYPE_TOOLBAR_SPACE_STYLE,
266                                                               DEFAULT_SPACE_STYLE,
267                                                               
268                                                               G_PARAM_READABLE));
269
270   gtk_widget_class_install_style_property (widget_class,
271                                            g_param_spec_enum ("button_relief",
272                                                              _("Button relief"),
273                                                              _("Type of bevel around toolbar buttons"),
274                                                               GTK_TYPE_RELIEF_STYLE,
275                                                               GTK_RELIEF_NONE,
276                                                               G_PARAM_READABLE));
277
278   gtk_widget_class_install_style_property (widget_class,
279                                            g_param_spec_enum ("shadow_type",
280                                                               _("Shadow type"),
281                                                               _("Style of bevel around the toolbar"),
282                                                               GTK_TYPE_SHADOW_TYPE,
283                                                               GTK_SHADOW_OUT,
284                                                               G_PARAM_READABLE));
285
286   gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-style",
287                                                     _("Toolbar style"),
288                                                     _("Whether default toolbars have text only, text and icons, icons only, etc."),
289                                                     GTK_TYPE_TOOLBAR_STYLE,
290                                                     GTK_TOOLBAR_BOTH,
291                                                     G_PARAM_READWRITE));
292
293   gtk_settings_install_property (g_param_spec_enum ("gtk-toolbar-icon-size",
294                                                     _("Toolbar icon size"),
295                                                     _("Size of icons in default toolbars"),
296                                                     GTK_TYPE_ICON_SIZE,
297                                                     GTK_ICON_SIZE_LARGE_TOOLBAR,
298                                                     G_PARAM_READWRITE));  
299 }
300
301 static void
302 style_change_notify (GObject    *object,
303                      GParamSpec *pspec,
304                      gpointer    data)
305 {
306   GtkToolbar *toolbar;
307
308   toolbar = GTK_TOOLBAR (data);
309
310   if (!toolbar->style_set)
311     {
312       /* pretend it was set, then unset, thus reverting to new default */
313       toolbar->style_set = TRUE; 
314       gtk_toolbar_unset_style (toolbar);
315     }
316 }
317
318 static void
319 icon_size_change_notify (GObject    *object,
320                          GParamSpec *pspec,
321                          gpointer    data)
322 {
323   GtkToolbar *toolbar;
324
325   toolbar = GTK_TOOLBAR (data);
326
327   if (!toolbar->icon_size_set)
328     {
329       /* pretend it was set, then unset, thus reverting to new default */
330       toolbar->icon_size_set = TRUE; 
331       gtk_toolbar_unset_icon_size (toolbar);
332     }
333 }
334
335 static void
336 gtk_toolbar_init (GtkToolbar *toolbar)
337 {
338   GTK_WIDGET_SET_FLAGS (toolbar, GTK_NO_WINDOW);
339   GTK_WIDGET_UNSET_FLAGS (toolbar, GTK_CAN_FOCUS);
340
341   toolbar->num_children = 0;
342   toolbar->children     = NULL;
343   toolbar->orientation  = GTK_ORIENTATION_HORIZONTAL;
344   toolbar->icon_size    = DEFAULT_ICON_SIZE;
345   toolbar->tooltips     = gtk_tooltips_new ();
346   toolbar->button_maxw  = 0;
347   toolbar->button_maxh  = 0;
348
349   toolbar->style_set = FALSE;
350   toolbar->icon_size_set = FALSE;
351   g_object_get (gtk_settings_get_default (),
352                 "gtk-toolbar-icon-size",
353                 &toolbar->icon_size,
354                 "gtk-toolbar-style",
355                 &toolbar->style,
356                 NULL);
357   
358   toolbar->style_set_connection =
359     g_signal_connect (G_OBJECT (gtk_settings_get_default ()),
360                       "notify::gtk-toolbar-style",
361                       G_CALLBACK (style_change_notify),
362                       toolbar);
363
364   toolbar->icon_size_connection =
365     g_signal_connect (G_OBJECT (gtk_settings_get_default ()),
366                       "notify::gtk-toolbar-icon-size",
367                       G_CALLBACK (icon_size_change_notify),
368                       toolbar);
369 }
370
371 static void
372 gtk_toolbar_finalize (GObject *object)
373 {
374   GtkToolbar *toolbar;
375
376   toolbar = GTK_TOOLBAR (object);
377
378   g_signal_handler_disconnect (G_OBJECT (gtk_settings_get_default ()),
379                                toolbar->style_set_connection);
380   g_signal_handler_disconnect (G_OBJECT (gtk_settings_get_default ()),
381                                toolbar->icon_size_connection);
382   
383   G_OBJECT_CLASS (parent_class)->finalize (object);
384 }
385
386 static void
387 gtk_toolbar_set_property (GObject      *object,
388                           guint         prop_id,
389                           const GValue *value,
390                           GParamSpec   *pspec)
391 {
392   GtkToolbar *toolbar = GTK_TOOLBAR (object);
393   
394   switch (prop_id)
395     {
396     case PROP_ORIENTATION:
397       gtk_toolbar_set_orientation (toolbar, g_value_get_enum (value));
398       break;
399     case PROP_TOOLBAR_STYLE:
400       gtk_toolbar_set_style (toolbar, g_value_get_enum (value));
401       break;
402     }
403 }
404
405 static void
406 gtk_toolbar_get_property (GObject      *object,
407                           guint         prop_id,
408                           GValue       *value,
409                           GParamSpec   *pspec)
410 {
411   GtkToolbar *toolbar = GTK_TOOLBAR (object);
412
413   switch (prop_id)
414     {
415     case PROP_ORIENTATION:
416       g_value_set_enum (value, toolbar->orientation);
417       break;
418     case PROP_TOOLBAR_STYLE:
419       g_value_set_enum (value, toolbar->style);
420       break;
421     default:
422       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
423       break;
424     }
425 }
426
427 GtkWidget*
428 gtk_toolbar_new (void)
429 {
430   GtkToolbar *toolbar;
431
432   toolbar = gtk_type_new (gtk_toolbar_get_type ());
433
434   return GTK_WIDGET (toolbar);
435 }
436
437 static void
438 gtk_toolbar_destroy (GtkObject *object)
439 {
440   GtkToolbar *toolbar;
441   GList *children;
442
443   g_return_if_fail (GTK_IS_TOOLBAR (object));
444
445   toolbar = GTK_TOOLBAR (object);
446
447   if (toolbar->tooltips)
448     {
449       gtk_object_unref (GTK_OBJECT (toolbar->tooltips));
450       toolbar->tooltips = NULL;
451     }
452
453   for (children = toolbar->children; children; children = children->next)
454     {
455       GtkToolbarChild *child;
456
457       child = children->data;
458
459       if (child->type != GTK_TOOLBAR_CHILD_SPACE)
460         {
461           gtk_widget_ref (child->widget);
462           gtk_widget_unparent (child->widget);
463           gtk_widget_destroy (child->widget);
464           gtk_widget_unref (child->widget);
465         }
466
467       g_free (child);
468     }
469   g_list_free (toolbar->children);
470   toolbar->children = NULL;
471   
472   GTK_OBJECT_CLASS (parent_class)->destroy (object);
473 }
474
475 static void
476 gtk_toolbar_map (GtkWidget *widget)
477 {
478   GtkToolbar *toolbar;
479   GList *children;
480   GtkToolbarChild *child;
481
482   g_return_if_fail (GTK_IS_TOOLBAR (widget));
483
484   toolbar = GTK_TOOLBAR (widget);
485   GTK_WIDGET_SET_FLAGS (toolbar, GTK_MAPPED);
486
487   for (children = toolbar->children; children; children = children->next)
488     {
489       child = children->data;
490
491       if ((child->type != GTK_TOOLBAR_CHILD_SPACE)
492           && GTK_WIDGET_VISIBLE (child->widget) && !GTK_WIDGET_MAPPED (child->widget))
493         gtk_widget_map (child->widget);
494     }
495 }
496
497 static void
498 gtk_toolbar_unmap (GtkWidget *widget)
499 {
500   GtkToolbar *toolbar;
501   GList *children;
502   GtkToolbarChild *child;
503
504   g_return_if_fail (GTK_IS_TOOLBAR (widget));
505
506   toolbar = GTK_TOOLBAR (widget);
507   GTK_WIDGET_UNSET_FLAGS (toolbar, GTK_MAPPED);
508
509   for (children = toolbar->children; children; children = children->next)
510     {
511       child = children->data;
512
513       if ((child->type != GTK_TOOLBAR_CHILD_SPACE)
514           && GTK_WIDGET_VISIBLE (child->widget) && GTK_WIDGET_MAPPED (child->widget))
515         gtk_widget_unmap (child->widget);
516     }
517 }
518
519 static void
520 gtk_toolbar_paint_space_line (GtkWidget       *widget,
521                               GdkRectangle    *area,
522                               GtkToolbarChild *child)
523 {
524   GtkToolbar *toolbar;
525   GtkToolbarChildSpace *child_space;
526   gint space_size;
527   
528   g_return_if_fail (GTK_IS_TOOLBAR (widget));
529   g_return_if_fail (child != NULL);
530   g_return_if_fail (child->type == GTK_TOOLBAR_CHILD_SPACE);
531
532   toolbar = GTK_TOOLBAR (widget);
533
534   child_space = (GtkToolbarChildSpace *) child;
535   space_size = get_space_size (toolbar);
536   
537   if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
538     gtk_paint_vline (widget->style, widget->window,
539                      GTK_WIDGET_STATE (widget), area, widget,
540                      "toolbar",
541                      child_space->alloc_y + toolbar->button_maxh *
542                      SPACE_LINE_START / SPACE_LINE_DIVISION,
543                      child_space->alloc_y + toolbar->button_maxh *
544                      SPACE_LINE_END / SPACE_LINE_DIVISION,
545                      child_space->alloc_x +
546                      (space_size -
547                       widget->style->xthickness) / 2);
548   else
549     gtk_paint_hline (widget->style, widget->window,
550                      GTK_WIDGET_STATE (widget), area, widget,
551                      "toolbar",
552                      child_space->alloc_x + toolbar->button_maxw *
553                      SPACE_LINE_START / SPACE_LINE_DIVISION,
554                      child_space->alloc_x + toolbar->button_maxw *
555                      SPACE_LINE_END / SPACE_LINE_DIVISION,
556                      child_space->alloc_y +
557                      (space_size -
558                       widget->style->ythickness) / 2);
559 }
560
561 static gint
562 gtk_toolbar_expose (GtkWidget      *widget,
563                     GdkEventExpose *event)
564 {
565   GtkToolbar *toolbar;
566   GList *children;
567   GtkToolbarChild *child;
568   gint border_width;
569   
570   g_return_val_if_fail (GTK_IS_TOOLBAR (widget), FALSE);
571   g_return_val_if_fail (event != NULL, FALSE);
572
573   border_width = GTK_CONTAINER (widget)->border_width;
574   
575   if (GTK_WIDGET_DRAWABLE (widget))
576     {
577       GtkShadowType shadow_type;
578
579       toolbar = GTK_TOOLBAR (widget);
580
581       gtk_widget_style_get (widget, "shadow_type", &shadow_type, NULL);
582       
583       gtk_paint_box (widget->style,
584                      widget->window,
585                      GTK_WIDGET_STATE (widget),
586                      shadow_type,
587                      &event->area, widget, "toolbar",
588                      widget->allocation.x + border_width,
589                      widget->allocation.y + border_width,
590                      widget->allocation.width - border_width,
591                      widget->allocation.height - border_width);
592       
593       for (children = toolbar->children; children; children = children->next)
594         {
595           child = children->data;
596
597           if (child->type == GTK_TOOLBAR_CHILD_SPACE)
598             {
599               if (get_space_style (toolbar) == GTK_TOOLBAR_SPACE_LINE)
600                 gtk_toolbar_paint_space_line (widget, &event->area, child);
601             }
602           else
603             gtk_container_propagate_expose (GTK_CONTAINER (widget),
604                                             child->widget,
605                                             event);
606         }
607     }
608
609   return FALSE;
610 }
611
612 static void
613 gtk_toolbar_size_request (GtkWidget      *widget,
614                           GtkRequisition *requisition)
615 {
616   GtkToolbar *toolbar;
617   GList *children;
618   GtkToolbarChild *child;
619   gint nbuttons;
620   gint button_maxw, button_maxh;
621   gint widget_maxw, widget_maxh;
622   GtkRequisition child_requisition;
623   gint space_size;
624   gint ipadding;
625   
626   g_return_if_fail (GTK_IS_TOOLBAR (widget));
627   g_return_if_fail (requisition != NULL);
628
629   toolbar = GTK_TOOLBAR (widget);
630
631   requisition->width = GTK_CONTAINER (toolbar)->border_width * 2;
632   requisition->height = GTK_CONTAINER (toolbar)->border_width * 2;
633   nbuttons = 0;
634   button_maxw = 0;
635   button_maxh = 0;
636   widget_maxw = 0;
637   widget_maxh = 0;
638
639   space_size = get_space_size (toolbar);
640   
641   for (children = toolbar->children; children; children = children->next)
642     {
643       child = children->data;
644
645       switch (child->type)
646         {
647         case GTK_TOOLBAR_CHILD_SPACE:
648           if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
649             requisition->width += space_size;
650           else
651             requisition->height += space_size;
652
653           break;
654
655         case GTK_TOOLBAR_CHILD_BUTTON:
656         case GTK_TOOLBAR_CHILD_RADIOBUTTON:
657         case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
658           if (GTK_WIDGET_VISIBLE (child->widget))
659             {              
660               gtk_widget_size_request (child->widget, &child_requisition);
661
662               nbuttons++;
663               button_maxw = MAX (button_maxw, child_requisition.width);
664               button_maxh = MAX (button_maxh, child_requisition.height);
665             }
666
667           break;
668
669         case GTK_TOOLBAR_CHILD_WIDGET:
670           if (GTK_WIDGET_VISIBLE (child->widget))
671             {
672               gtk_widget_size_request (child->widget, &child_requisition);
673
674               widget_maxw = MAX (widget_maxw, child_requisition.width);
675               widget_maxh = MAX (widget_maxh, child_requisition.height);
676
677               if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
678                 requisition->width += child_requisition.width;
679               else
680                 requisition->height += child_requisition.height;
681             }
682
683           break;
684
685         default:
686           g_assert_not_reached ();
687         }
688     }
689
690   if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
691     {
692       requisition->width += nbuttons * button_maxw;
693       requisition->height += MAX (button_maxh, widget_maxh);
694     }
695   else
696     {
697       requisition->width += MAX (button_maxw, widget_maxw);
698       requisition->height += nbuttons * button_maxh;
699     }
700
701   /* Extra spacing */
702   gtk_widget_style_get (widget, "internal_padding", &ipadding, NULL);
703   
704   requisition->width += 2 * (widget->style->xthickness + ipadding);
705   requisition->height += 2 * (widget->style->ythickness + ipadding);
706   
707   toolbar->button_maxw = button_maxw;
708   toolbar->button_maxh = button_maxh;
709 }
710
711 static void
712 gtk_toolbar_size_allocate (GtkWidget     *widget,
713                            GtkAllocation *allocation)
714 {
715   GtkToolbar *toolbar;
716   GList *children;
717   GtkToolbarChild *child;
718   GtkToolbarChildSpace *child_space;
719   GtkAllocation alloc;
720   GtkRequisition child_requisition;
721   gint x_border_width, y_border_width;
722   gint space_size;
723   gint ipadding;
724   
725   g_return_if_fail (GTK_IS_TOOLBAR (widget));
726   g_return_if_fail (allocation != NULL);
727
728   toolbar = GTK_TOOLBAR (widget);
729   widget->allocation = *allocation;
730   
731   x_border_width = GTK_CONTAINER (toolbar)->border_width;
732   y_border_width = GTK_CONTAINER (toolbar)->border_width;
733
734   gtk_widget_style_get (widget, "internal_padding", &ipadding, NULL);
735   
736   x_border_width += 2 * (widget->style->xthickness + ipadding);
737   y_border_width += 2 * (widget->style->ythickness + ipadding);
738   
739   if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
740     alloc.x = allocation->x + x_border_width;
741   else
742     alloc.y = allocation->y + y_border_width;
743
744   space_size = get_space_size (toolbar);
745   
746   for (children = toolbar->children; children; children = children->next)
747     {
748       child = children->data;
749
750       switch (child->type)
751         {
752         case GTK_TOOLBAR_CHILD_SPACE:
753
754           child_space = (GtkToolbarChildSpace *) child;
755
756           if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
757             {
758               child_space->alloc_x = alloc.x;
759               child_space->alloc_y = allocation->y + (allocation->height - toolbar->button_maxh) / 2;
760               alloc.x += space_size;
761             }
762           else
763             {
764               child_space->alloc_x = allocation->x + (allocation->width - toolbar->button_maxw) / 2;
765               child_space->alloc_y = alloc.y;
766               alloc.y += space_size;
767             }
768
769           break;
770
771         case GTK_TOOLBAR_CHILD_BUTTON:
772         case GTK_TOOLBAR_CHILD_RADIOBUTTON:
773         case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
774           if (!GTK_WIDGET_VISIBLE (child->widget))
775             break;
776
777           alloc.width = toolbar->button_maxw;
778           alloc.height = toolbar->button_maxh;
779
780           if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
781             alloc.y = allocation->y + (allocation->height - toolbar->button_maxh) / 2;
782           else
783             alloc.x = allocation->x + (allocation->width - toolbar->button_maxw) / 2;
784
785           gtk_widget_size_allocate (child->widget, &alloc);
786
787           if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
788             alloc.x += toolbar->button_maxw;
789           else
790             alloc.y += toolbar->button_maxh;
791
792           break;
793
794         case GTK_TOOLBAR_CHILD_WIDGET:
795           if (!GTK_WIDGET_VISIBLE (child->widget))
796             break;
797
798           gtk_widget_get_child_requisition (child->widget, &child_requisition);
799           
800           alloc.width = child_requisition.width;
801           alloc.height = child_requisition.height;
802
803           if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
804             alloc.y = allocation->y + (allocation->height - child_requisition.height) / 2;
805           else
806             alloc.x = allocation->x + (allocation->width - child_requisition.width) / 2;
807
808           gtk_widget_size_allocate (child->widget, &alloc);
809
810           if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
811             alloc.x += child_requisition.width;
812           else
813             alloc.y += child_requisition.height;
814
815           break;
816
817         default:
818           g_assert_not_reached ();
819         }
820     }
821 }
822
823 static void
824 gtk_toolbar_style_set (GtkWidget  *widget,
825                        GtkStyle   *prev_style)
826 {
827   if (prev_style)
828     gtk_toolbar_update_button_relief (GTK_TOOLBAR (widget));
829 }
830
831 static gboolean
832 gtk_toolbar_focus (GtkWidget       *widget,
833                    GtkDirectionType dir)
834 {
835   /* Focus can't go in toolbars */
836   
837   return FALSE;
838 }
839
840 static void
841 child_show_all (GtkWidget *widget)
842 {
843   /* Don't show our own children, since that would
844    * show labels we may intend to hide in icons-only mode
845    */
846   if (!g_object_get_data (G_OBJECT (widget),
847                           "gtk-toolbar-is-child"))
848     gtk_widget_show_all (widget);
849 }
850
851 static void
852 gtk_toolbar_show_all (GtkWidget *widget)
853 {
854   gtk_container_foreach (GTK_CONTAINER (widget),
855                          (GtkCallback) child_show_all,
856                          NULL);
857   gtk_widget_show (widget);
858 }
859
860 static void
861 gtk_toolbar_add (GtkContainer *container,
862                  GtkWidget    *widget)
863 {
864   g_return_if_fail (GTK_IS_TOOLBAR (container));
865   g_return_if_fail (widget != NULL);
866
867   gtk_toolbar_append_widget (GTK_TOOLBAR (container), widget, NULL, NULL);
868 }
869
870 static void
871 gtk_toolbar_remove (GtkContainer *container,
872                     GtkWidget    *widget)
873 {
874   GtkToolbar *toolbar;
875   GList *children;
876   GtkToolbarChild *child;
877
878   g_return_if_fail (GTK_IS_TOOLBAR (container));
879   g_return_if_fail (widget != NULL);
880
881   toolbar = GTK_TOOLBAR (container);
882
883   for (children = toolbar->children; children; children = children->next)
884     {
885       child = children->data;
886
887       if ((child->type != GTK_TOOLBAR_CHILD_SPACE) && (child->widget == widget))
888         {
889           gboolean was_visible;
890
891           was_visible = GTK_WIDGET_VISIBLE (widget);
892           gtk_widget_unparent (widget);
893
894           toolbar->children = g_list_remove_link (toolbar->children, children);
895           g_free (child);
896           g_list_free (children);
897           toolbar->num_children--;
898
899           if (was_visible && GTK_WIDGET_VISIBLE (container))
900             gtk_widget_queue_resize (GTK_WIDGET (container));
901
902           break;
903         }
904     }
905 }
906
907 static void
908 gtk_toolbar_forall (GtkContainer *container,
909                     gboolean      include_internals,
910                     GtkCallback   callback,
911                     gpointer      callback_data)
912 {
913   GtkToolbar *toolbar;
914   GList *children;
915   GtkToolbarChild *child;
916
917   g_return_if_fail (GTK_IS_TOOLBAR (container));
918   g_return_if_fail (callback != NULL);
919
920   toolbar = GTK_TOOLBAR (container);
921
922   for (children = toolbar->children; children; children = children->next)
923     {
924       child = children->data;
925
926       if (child->type != GTK_TOOLBAR_CHILD_SPACE)
927         (*callback) (child->widget, callback_data);
928     }
929 }
930
931 GtkWidget *
932 gtk_toolbar_append_item (GtkToolbar    *toolbar,
933                          const char    *text,
934                          const char    *tooltip_text,
935                          const char    *tooltip_private_text,
936                          GtkWidget     *icon,
937                          GtkSignalFunc  callback,
938                          gpointer       user_data)
939 {
940   return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
941                                      NULL, text,
942                                      tooltip_text, tooltip_private_text,
943                                      icon, callback, user_data,
944                                      toolbar->num_children);
945 }
946
947 GtkWidget *
948 gtk_toolbar_prepend_item (GtkToolbar    *toolbar,
949                           const char    *text,
950                           const char    *tooltip_text,
951                           const char    *tooltip_private_text,
952                           GtkWidget     *icon,
953                           GtkSignalFunc  callback,
954                           gpointer       user_data)
955 {
956   return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
957                                      NULL, text,
958                                      tooltip_text, tooltip_private_text,
959                                      icon, callback, user_data,
960                                      0);
961 }
962
963 static GtkWidget *
964 gtk_toolbar_internal_insert_item (GtkToolbar    *toolbar,
965                                   const char    *text,
966                                   const char    *tooltip_text,
967                                   const char    *tooltip_private_text,
968                                   GtkWidget     *icon,
969                                   GtkSignalFunc  callback,
970                                   gpointer       user_data,
971                                   gint           position,
972                                   gboolean       has_mnemonic)
973 {
974   return gtk_toolbar_internal_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
975                                               NULL, text,
976                                               tooltip_text, tooltip_private_text,
977                                               icon, callback, user_data,
978                                               position, has_mnemonic);
979 }
980      
981 GtkWidget *
982 gtk_toolbar_insert_item (GtkToolbar    *toolbar,
983                          const char    *text,
984                          const char    *tooltip_text,
985                          const char    *tooltip_private_text,
986                          GtkWidget     *icon,
987                          GtkSignalFunc  callback,
988                          gpointer       user_data,
989                          gint           position)
990 {
991   return gtk_toolbar_internal_insert_item (toolbar, 
992                                            text, tooltip_text, tooltip_private_text,
993                                            icon, callback, user_data,
994                                            position, FALSE);
995 }
996
997 /**
998  * gtk_toolbar_set_icon_size:
999  * @toolbar: A #GtkToolbar
1000  * @icon_size: The #GtkIconSize that stock icons in the toolbar shall have.
1001  *
1002  * This function sets the size of stock icons in the toolbar. You
1003  * can call it both before you add the icons and after they've been
1004  * added. The size you set will override user preferences for the default
1005  * icon size.
1006  **/
1007 void
1008 gtk_toolbar_set_icon_size (GtkToolbar  *toolbar,
1009                            GtkIconSize  icon_size)
1010 {
1011   GList *children;
1012   GtkToolbarChild *child;
1013   GtkImage *image;
1014   gchar *stock_id;
1015
1016   g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1017
1018   toolbar->icon_size_set = TRUE;
1019   
1020   if (toolbar->icon_size == icon_size)
1021     return;
1022   
1023   toolbar->icon_size = icon_size;
1024
1025   for (children = toolbar->children; children; children = children->next)
1026     {
1027       child = children->data;
1028       if (child->type == GTK_TOOLBAR_CHILD_BUTTON &&
1029           GTK_IS_IMAGE (child->icon))
1030         {
1031           image = GTK_IMAGE (child->icon);
1032           if (gtk_image_get_storage_type (image) == GTK_IMAGE_STOCK)
1033             {
1034               gtk_image_get_stock (image, &stock_id, NULL);
1035               stock_id = g_strdup (stock_id);
1036               gtk_image_set_from_stock (image,
1037                                         stock_id,
1038                                         icon_size);
1039               g_free (stock_id);
1040             }
1041         }
1042     }
1043   
1044   gtk_widget_queue_resize (GTK_WIDGET (toolbar));
1045 }
1046
1047 /**
1048  * gtk_toolbar_get_icon_size:
1049  * @toolbar: a #GtkToolbar
1050  *
1051  * Retrieves the icon size fo the toolbar. See gtk_toolbar_set_icon_size().
1052  *
1053  * Return value: the current icon size for the icons on the toolbar.
1054  **/
1055 GtkIconSize
1056 gtk_toolbar_get_icon_size (GtkToolbar *toolbar)
1057 {
1058   g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_ICON_SIZE_LARGE_TOOLBAR);
1059
1060   return toolbar->icon_size;
1061 }
1062
1063 /**
1064  * gtk_toolbar_unset_icon_size:
1065  * @toolbar: a #GtkToolbar
1066  * 
1067  * Unsets toolbar icon size set with gtk_toolbar_set_icon_size(), so that
1068  * user preferences will be used to determine the icon size.
1069  **/
1070 void
1071 gtk_toolbar_unset_icon_size (GtkToolbar  *toolbar)
1072 {
1073   GtkIconSize size;
1074
1075   if (toolbar->icon_size_set)
1076     {
1077       g_object_get (gtk_settings_get_default (),
1078                     "gtk-toolbar-icon-size",
1079                     &size, NULL);
1080
1081       if (size != toolbar->icon_size)
1082         gtk_toolbar_set_icon_size (toolbar, size);
1083
1084       toolbar->icon_size_set = FALSE;
1085     }
1086 }
1087
1088 /**
1089  * gtk_toolbar_insert_stock:
1090  * @toolbar: A #GtkToolbar
1091  * @stock_id: The id of the stock item you want to insert
1092  * @tooltip_text: The text in the tooltip of the toolbar button
1093  * @tooltip_private_text: The private text of the tooltip
1094  * @callback: The callback called when the toolbar button is clicked.
1095  * @user_data: user data passed to callback
1096  * @position: The position the button shall be inserted at.
1097  *            -1 means at the end.
1098  *
1099  * Inserts a stock item at the specified position of the toolbar.  If
1100  * @stock_id is not a known stock item ID, it's inserted verbatim,
1101  * except that underscores are used to mark mnemonics (see
1102  * gtk_label_new_with_mnemonic()).
1103  *
1104  * Returns: the inserted widget
1105  */
1106 GtkWidget*
1107 gtk_toolbar_insert_stock (GtkToolbar      *toolbar,
1108                           const gchar     *stock_id,
1109                           const char      *tooltip_text,
1110                           const char      *tooltip_private_text,
1111                           GtkSignalFunc    callback,
1112                           gpointer         user_data,
1113                           gint             position)
1114 {
1115   GtkStockItem item;
1116   GtkWidget *image;
1117
1118   if (gtk_stock_lookup (stock_id, &item))
1119     {
1120       image = gtk_image_new_from_stock (stock_id, toolbar->icon_size);
1121
1122       return gtk_toolbar_internal_insert_item (toolbar,
1123                                                item.label,
1124                                                tooltip_text,
1125                                                tooltip_private_text,
1126                                                image,
1127                                                callback,
1128                                                user_data,
1129                                                position,
1130                                                TRUE);
1131     }
1132   else
1133     return gtk_toolbar_internal_insert_item (toolbar,
1134                                              stock_id,
1135                                              tooltip_text,
1136                                              tooltip_private_text,
1137                                              NULL,
1138                                              callback,
1139                                              user_data,
1140                                              position,
1141                                              TRUE);
1142 }
1143
1144
1145
1146 void
1147 gtk_toolbar_append_space (GtkToolbar *toolbar)
1148 {
1149   gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
1150                               NULL, NULL,
1151                               NULL, NULL,
1152                               NULL, NULL, NULL,
1153                               toolbar->num_children);
1154 }
1155
1156 void
1157 gtk_toolbar_prepend_space (GtkToolbar *toolbar)
1158 {
1159   gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
1160                               NULL, NULL,
1161                               NULL, NULL,
1162                               NULL, NULL, NULL,
1163                               0);
1164 }
1165
1166 void
1167 gtk_toolbar_insert_space (GtkToolbar *toolbar,
1168                           gint        position)
1169 {
1170   gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
1171                               NULL, NULL,
1172                               NULL, NULL,
1173                               NULL, NULL, NULL,
1174                               position);
1175 }
1176
1177 void
1178 gtk_toolbar_remove_space (GtkToolbar *toolbar,
1179                           gint        position)
1180 {
1181   GList *children;
1182   GtkToolbarChild *child;
1183   gint i;
1184   
1185   g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1186   
1187   i = 0;
1188   for (children = toolbar->children; children; children = children->next)
1189     {
1190       child = children->data;
1191
1192       if (i == position)
1193         {
1194           if (child->type == GTK_TOOLBAR_CHILD_SPACE)
1195             {
1196               toolbar->children = g_list_remove_link (toolbar->children, children);
1197               g_free (child);
1198               g_list_free (children);
1199               toolbar->num_children--;
1200               
1201               gtk_widget_queue_resize (GTK_WIDGET (toolbar));
1202             }
1203           else
1204             {
1205               g_warning ("Toolbar position %d is not a space", position);
1206             }
1207
1208           return;
1209         }
1210
1211       ++i;
1212     }
1213
1214   g_warning ("Toolbar position %d doesn't exist", position);
1215 }
1216
1217 void
1218 gtk_toolbar_append_widget (GtkToolbar  *toolbar,
1219                            GtkWidget   *widget,
1220                            const gchar *tooltip_text,
1221                            const gchar *tooltip_private_text)
1222 {
1223   gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
1224                               widget, NULL,
1225                               tooltip_text, tooltip_private_text,
1226                               NULL, NULL, NULL,
1227                               toolbar->num_children);
1228 }
1229
1230 void
1231 gtk_toolbar_prepend_widget (GtkToolbar  *toolbar,
1232                             GtkWidget   *widget,
1233                             const gchar *tooltip_text,
1234                             const gchar *tooltip_private_text)
1235 {
1236   gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
1237                               widget, NULL,
1238                               tooltip_text, tooltip_private_text,
1239                               NULL, NULL, NULL,
1240                               0);
1241 }
1242
1243 void
1244 gtk_toolbar_insert_widget (GtkToolbar *toolbar,
1245                            GtkWidget  *widget,
1246                            const char *tooltip_text,
1247                            const char *tooltip_private_text,
1248                            gint        position)
1249 {
1250   gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
1251                               widget, NULL,
1252                               tooltip_text, tooltip_private_text,
1253                               NULL, NULL, NULL,
1254                               position);
1255 }
1256
1257 GtkWidget*
1258 gtk_toolbar_append_element (GtkToolbar          *toolbar,
1259                             GtkToolbarChildType  type,
1260                             GtkWidget           *widget,
1261                             const char          *text,
1262                             const char          *tooltip_text,
1263                             const char          *tooltip_private_text,
1264                             GtkWidget           *icon,
1265                             GtkSignalFunc        callback,
1266                             gpointer             user_data)
1267 {
1268   return gtk_toolbar_insert_element (toolbar, type, widget, text,
1269                                      tooltip_text, tooltip_private_text,
1270                                      icon, callback, user_data,
1271                                      toolbar->num_children);
1272 }
1273
1274 GtkWidget *
1275 gtk_toolbar_prepend_element (GtkToolbar          *toolbar,
1276                              GtkToolbarChildType  type,
1277                              GtkWidget           *widget,
1278                              const char          *text,
1279                              const char          *tooltip_text,
1280                              const char          *tooltip_private_text,
1281                              GtkWidget           *icon,
1282                              GtkSignalFunc        callback,
1283                              gpointer             user_data)
1284 {
1285   return gtk_toolbar_insert_element (toolbar, type, widget, text,
1286                                      tooltip_text, tooltip_private_text,
1287                                      icon, callback, user_data, 0);
1288 }
1289
1290 GtkWidget *
1291 gtk_toolbar_insert_element (GtkToolbar          *toolbar,
1292                             GtkToolbarChildType  type,
1293                             GtkWidget           *widget,
1294                             const char          *text,
1295                             const char          *tooltip_text,
1296                             const char          *tooltip_private_text,
1297                             GtkWidget           *icon,
1298                             GtkSignalFunc        callback,
1299                             gpointer             user_data,
1300                             gint                 position)
1301 {
1302   g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
1303   if (type == GTK_TOOLBAR_CHILD_WIDGET)
1304     {
1305       g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
1306     }
1307   else if (type != GTK_TOOLBAR_CHILD_RADIOBUTTON)
1308     g_return_val_if_fail (widget == NULL, NULL);
1309   
1310   return gtk_toolbar_internal_insert_element (toolbar, type, widget, text,
1311                                               tooltip_text, tooltip_private_text,
1312                                               icon, callback, user_data,
1313                                               position, FALSE);
1314 }
1315
1316 static GtkWidget *
1317 gtk_toolbar_internal_insert_element (GtkToolbar          *toolbar,
1318                                      GtkToolbarChildType  type,
1319                                      GtkWidget           *widget,
1320                                      const char          *text,
1321                                      const char          *tooltip_text,
1322                                      const char          *tooltip_private_text,
1323                                      GtkWidget           *icon,
1324                                      GtkSignalFunc        callback,
1325                                      gpointer             user_data,
1326                                      gint                 position,
1327                                      gboolean             has_mnemonic)
1328 {
1329   GtkToolbarChild *child;
1330   GtkWidget *box;
1331
1332   g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
1333   if (type == GTK_TOOLBAR_CHILD_WIDGET)
1334     {
1335       g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
1336     }
1337   else if (type != GTK_TOOLBAR_CHILD_RADIOBUTTON)
1338     g_return_val_if_fail (widget == NULL, NULL);
1339
1340   if (type == GTK_TOOLBAR_CHILD_SPACE)
1341     child = (GtkToolbarChild *) g_new (GtkToolbarChildSpace, 1);
1342   else
1343     child = g_new (GtkToolbarChild, 1);
1344
1345   child->type = type;
1346   child->icon = NULL;
1347   child->label = NULL;
1348
1349   switch (type)
1350     {
1351     case GTK_TOOLBAR_CHILD_SPACE:
1352       child->widget = NULL;
1353       ((GtkToolbarChildSpace *) child)->alloc_x =
1354         ((GtkToolbarChildSpace *) child)->alloc_y = 0;
1355       break;
1356
1357     case GTK_TOOLBAR_CHILD_WIDGET:
1358       child->widget = widget;
1359       break;
1360
1361     case GTK_TOOLBAR_CHILD_BUTTON:
1362     case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
1363     case GTK_TOOLBAR_CHILD_RADIOBUTTON:
1364       if (type == GTK_TOOLBAR_CHILD_BUTTON)
1365         {
1366           child->widget = gtk_button_new ();
1367           gtk_button_set_relief (GTK_BUTTON (child->widget), get_button_relief (toolbar));
1368         }
1369       else if (type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
1370         {
1371           child->widget = gtk_toggle_button_new ();
1372           gtk_button_set_relief (GTK_BUTTON (child->widget), get_button_relief (toolbar));
1373           gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (child->widget),
1374                                       FALSE);
1375         }
1376       else
1377         {
1378           child->widget = gtk_radio_button_new (widget
1379                                                 ? gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget))
1380                                                 : NULL);
1381           gtk_button_set_relief (GTK_BUTTON (child->widget), get_button_relief (toolbar));
1382           gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (child->widget), FALSE);
1383         }
1384
1385       GTK_WIDGET_UNSET_FLAGS (child->widget, GTK_CAN_FOCUS);
1386
1387       if (callback)
1388         gtk_signal_connect (GTK_OBJECT (child->widget), "clicked",
1389                             callback, user_data);
1390
1391       if (toolbar->style == GTK_TOOLBAR_BOTH_HORIZ)
1392           box = gtk_hbox_new (FALSE, 0);
1393       else
1394           box = gtk_vbox_new (FALSE, 0);
1395       gtk_container_add (GTK_CONTAINER (child->widget), box);
1396       gtk_widget_show (box);
1397
1398       if (text)
1399         {
1400           if (has_mnemonic)
1401             child->label = gtk_label_new_with_mnemonic (text);
1402           else
1403             child->label = gtk_label_new (text);
1404           gtk_box_pack_end (GTK_BOX (box), child->label, FALSE, FALSE, 0);
1405           if (toolbar->style != GTK_TOOLBAR_ICONS)
1406             gtk_widget_show (child->label);
1407         }
1408
1409       if (icon)
1410         {
1411           child->icon = GTK_WIDGET (icon);
1412           gtk_box_pack_end (GTK_BOX (box), child->icon, FALSE, FALSE, 0);
1413           if (toolbar->style != GTK_TOOLBAR_TEXT)
1414             gtk_widget_show (child->icon);
1415         }
1416
1417       if (type != GTK_TOOLBAR_CHILD_WIDGET)
1418         {
1419           /* Mark child as ours */
1420           g_object_set_data (G_OBJECT (child->widget),
1421                              "gtk-toolbar-is-child",
1422                              GINT_TO_POINTER (TRUE));
1423         }
1424       gtk_widget_show (child->widget);
1425       break;
1426
1427     default:
1428       g_assert_not_reached ();
1429     }
1430
1431   if ((type != GTK_TOOLBAR_CHILD_SPACE) && tooltip_text)
1432     gtk_tooltips_set_tip (toolbar->tooltips, child->widget,
1433                           tooltip_text, tooltip_private_text);
1434
1435   toolbar->children = g_list_insert (toolbar->children, child, position);
1436   toolbar->num_children++;
1437
1438   if (type != GTK_TOOLBAR_CHILD_SPACE)
1439     {
1440       gtk_widget_set_parent (child->widget, GTK_WIDGET (toolbar));
1441
1442       if (GTK_WIDGET_REALIZED (child->widget->parent))
1443         gtk_widget_realize (child->widget);
1444
1445       if (GTK_WIDGET_VISIBLE (child->widget->parent) && GTK_WIDGET_VISIBLE (child->widget))
1446         {
1447           if (GTK_WIDGET_MAPPED (child->widget->parent))
1448             gtk_widget_map (child->widget);
1449
1450           gtk_widget_queue_resize (child->widget);
1451         }
1452     }
1453   else
1454     gtk_widget_queue_resize (GTK_WIDGET (toolbar));
1455
1456   return child->widget;
1457 }
1458
1459 void
1460 gtk_toolbar_set_orientation (GtkToolbar     *toolbar,
1461                              GtkOrientation  orientation)
1462 {
1463   g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1464
1465   gtk_signal_emit (GTK_OBJECT (toolbar), toolbar_signals[ORIENTATION_CHANGED], orientation);
1466 }
1467
1468 /**
1469  * gtk_toolbar_get_orientation:
1470  * @toolbar: a #GtkToolbar
1471  * 
1472  * Retrieves the current orientation of the toolbar. See
1473  * gtk_toolbar_set_orientation().
1474  *
1475  * Return value: the orientation
1476  **/
1477 GtkOrientation
1478 gtk_toolbar_get_orientation (GtkToolbar *toolbar)
1479 {
1480   g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_ORIENTATION_HORIZONTAL);
1481
1482   return toolbar->orientation;
1483 }
1484
1485 void
1486 gtk_toolbar_set_style (GtkToolbar      *toolbar,
1487                        GtkToolbarStyle  style)
1488 {
1489   g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1490
1491   toolbar->style_set = TRUE;
1492   gtk_signal_emit (GTK_OBJECT (toolbar), toolbar_signals[STYLE_CHANGED], style);
1493 }
1494
1495 /**
1496  * gtk_toolbar_get_style:
1497  * @toolbar: a #GtkToolbar
1498  *
1499  * Retrieves whether the toolbar has text, icons, or both . See
1500  * gtk_toolbar_set_style().
1501  
1502  * Return value: the current style of @toolbar
1503  **/
1504 GtkToolbarStyle
1505 gtk_toolbar_get_style (GtkToolbar *toolbar)
1506 {
1507   g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH);
1508
1509   return toolbar->style;
1510 }
1511
1512 /**
1513  * gtk_toolbar_unset_style:
1514  * @toolbar: a #GtkToolbar
1515  * 
1516  * Unsets a toolbar style set with gtk_toolbar_set_style(), so that
1517  * user preferences will be used to determine the toolbar style.
1518  **/
1519 void
1520 gtk_toolbar_unset_style (GtkToolbar *toolbar)
1521 {
1522   GtkToolbarStyle style;
1523   
1524   g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1525
1526   if (toolbar->style_set)
1527     {
1528       g_object_get (gtk_settings_get_default (),
1529                     "gtk-toolbar-style",
1530                     &style,
1531                     NULL);
1532
1533       if (style != toolbar->style)
1534         gtk_signal_emit (GTK_OBJECT (toolbar), toolbar_signals[STYLE_CHANGED], style);
1535       
1536       toolbar->style_set = FALSE;
1537     }
1538 }
1539
1540 void
1541 gtk_toolbar_set_tooltips (GtkToolbar *toolbar,
1542                           gboolean    enable)
1543 {
1544   g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1545
1546   if (enable)
1547     gtk_tooltips_enable (toolbar->tooltips);
1548   else
1549     gtk_tooltips_disable (toolbar->tooltips);
1550 }
1551
1552 /**
1553  * gtk_toolbar_get_tooltips:
1554  * @toolbar: a #GtkToolbar
1555  *
1556  * Retrieves whether tooltips are enabled. See
1557  * gtk_toolbar_set_tooltips().
1558  *
1559  * Return value: %TRUE if tooltips are enabled
1560  **/
1561 gboolean
1562 gtk_toolbar_get_tooltips (GtkToolbar *toolbar)
1563 {
1564   g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
1565
1566   return toolbar->tooltips->enabled;
1567 }
1568
1569 static void
1570 gtk_toolbar_update_button_relief (GtkToolbar *toolbar)
1571 {
1572   GList *children;
1573   GtkToolbarChild *child;
1574   GtkReliefStyle relief;
1575   
1576   g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1577
1578   relief = get_button_relief (toolbar);
1579   
1580   for (children = toolbar->children; children; children = children->next)
1581     {
1582       child = children->data;
1583       if (child->type == GTK_TOOLBAR_CHILD_BUTTON ||
1584           child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
1585           child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
1586         gtk_button_set_relief (GTK_BUTTON (child->widget), relief);
1587     }
1588 }
1589
1590 static void
1591 gtk_real_toolbar_orientation_changed (GtkToolbar     *toolbar,
1592                                       GtkOrientation  orientation)
1593 {
1594   g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1595
1596   if (toolbar->orientation != orientation)
1597     {
1598       toolbar->orientation = orientation;
1599       gtk_widget_queue_resize (GTK_WIDGET (toolbar));
1600       g_object_notify (G_OBJECT (toolbar), "orientation");
1601     }
1602 }
1603
1604 static void
1605 gtk_real_toolbar_style_changed (GtkToolbar      *toolbar,
1606                                 GtkToolbarStyle  style)
1607 {
1608   GList *children;
1609   GtkToolbarChild *child;
1610   GtkWidget* box = NULL;
1611   
1612   g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1613
1614   if (toolbar->style != style)
1615     {
1616       toolbar->style = style;
1617
1618       for (children = toolbar->children; children; children = children->next)
1619         {
1620           child = children->data;
1621
1622           if (child->type == GTK_TOOLBAR_CHILD_BUTTON ||
1623               child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
1624               child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
1625             switch (style)
1626               {
1627               case GTK_TOOLBAR_ICONS:
1628                 if (child->icon && !GTK_WIDGET_VISIBLE (child->icon))
1629                   gtk_widget_show (child->icon);
1630
1631                 if (child->label && GTK_WIDGET_VISIBLE (child->label))
1632                   gtk_widget_hide (child->label);
1633
1634                 break;
1635
1636               case GTK_TOOLBAR_TEXT:
1637                 if (child->icon && GTK_WIDGET_VISIBLE (child->icon))
1638                   gtk_widget_hide (child->icon);
1639                 
1640                 if (child->label && !GTK_WIDGET_VISIBLE (child->label))
1641                   gtk_widget_show (child->label);
1642
1643                 break;
1644
1645               case GTK_TOOLBAR_BOTH:
1646                 if (child->icon && !GTK_WIDGET_VISIBLE (child->icon))
1647                   gtk_widget_show (child->icon);
1648
1649                 if (child->label && !GTK_WIDGET_VISIBLE (child->label))
1650                   gtk_widget_show (child->label);
1651
1652                 box = (GtkWidget*)gtk_container_children (GTK_CONTAINER (child->widget))->data;
1653
1654                 if (GTK_IS_HBOX (box))
1655                 {
1656                     if (child->icon)
1657                     {
1658                         gtk_object_ref (GTK_OBJECT (child->icon));
1659                         gtk_container_remove (GTK_CONTAINER (box),
1660                                               child->icon);
1661                     }
1662                     if (child->label)
1663                     {
1664                         gtk_object_ref (GTK_OBJECT (child->label));
1665                         gtk_container_remove (GTK_CONTAINER (box),
1666                                               child->label);
1667                     }
1668                     gtk_container_remove (GTK_CONTAINER (child->widget),
1669                                           box);
1670                     
1671                     box = gtk_vbox_new (FALSE, 0);
1672                     gtk_widget_show (box);
1673                     
1674                     if (child->label)
1675                     {
1676                         gtk_box_pack_end (GTK_BOX (box), child->label, FALSE, FALSE, 0);
1677                         gtk_object_unref (GTK_OBJECT (child->label));
1678                     }
1679                     if (child->icon)
1680                     {
1681                         gtk_box_pack_end (GTK_BOX (box), child->icon, FALSE, FALSE, 0);
1682                         gtk_object_unref (GTK_OBJECT (child->icon));
1683                     }
1684                     gtk_container_add (GTK_CONTAINER (child->widget),
1685                                        box);
1686                 }
1687                 
1688                 break;
1689                 
1690               case GTK_TOOLBAR_BOTH_HORIZ:
1691                 if (child->icon && !GTK_WIDGET_VISIBLE (child->icon))
1692                   gtk_widget_show (child->icon);
1693                 if (child->label && !GTK_WIDGET_VISIBLE (child->label))
1694                   gtk_widget_show (child->label);
1695
1696                 box = (GtkWidget*)gtk_container_children (GTK_CONTAINER (child->widget))->data;
1697                 
1698                 if (GTK_IS_VBOX (box))
1699                 {
1700                     if (child->icon)
1701                     {
1702                         gtk_object_ref (GTK_OBJECT (child->icon));
1703                         gtk_container_remove (GTK_CONTAINER (box),
1704                                               child->icon);
1705                     }
1706                     if (child->label)
1707                     {
1708                         gtk_object_ref (GTK_OBJECT (child->label));
1709                         gtk_container_remove (GTK_CONTAINER (box),
1710                                               child->label);
1711                     }
1712                     gtk_container_remove (GTK_CONTAINER (child->widget),
1713                                           box);
1714
1715                     box = gtk_hbox_new (FALSE, 0);
1716                     gtk_widget_show (box);
1717                     
1718                     if (child->label)
1719                     {
1720                         gtk_box_pack_end (GTK_BOX (box), child->label, TRUE, TRUE, 0);
1721                         gtk_object_unref (GTK_OBJECT (child->label));
1722                     }
1723                     if (child->icon)
1724                     {
1725                         gtk_box_pack_end (GTK_BOX (box), child->icon, FALSE, FALSE, 0);
1726                         gtk_object_unref (GTK_OBJECT (child->icon));
1727                     }
1728                     gtk_container_add (GTK_CONTAINER (child->widget), box);
1729                     
1730                 }
1731                 
1732                 break;
1733
1734               default:
1735                 g_assert_not_reached ();
1736               }
1737         }
1738
1739       gtk_widget_queue_resize (GTK_WIDGET (toolbar));
1740       g_object_notify (G_OBJECT (toolbar), "toolbar_style");
1741     }
1742 }
1743
1744
1745 static GtkReliefStyle
1746 get_button_relief (GtkToolbar *toolbar)
1747 {
1748   GtkReliefStyle button_relief = GTK_RELIEF_NORMAL;
1749   
1750   gtk_widget_style_get (GTK_WIDGET (toolbar),
1751                         "button_relief", &button_relief,
1752                         NULL);
1753
1754   return button_relief;
1755 }
1756
1757 static gint
1758 get_space_size (GtkToolbar *toolbar)
1759 {
1760   gint space_size = DEFAULT_SPACE_SIZE;
1761
1762   gtk_widget_style_get (GTK_WIDGET (toolbar),
1763                         "space_size", &space_size,
1764                         NULL);
1765
1766   return space_size;
1767 }
1768
1769 static GtkToolbarSpaceStyle
1770 get_space_style (GtkToolbar *toolbar)
1771 {
1772   GtkToolbarSpaceStyle space_style = DEFAULT_SPACE_STYLE;
1773
1774   gtk_widget_style_get (GTK_WIDGET (toolbar),
1775                         "space_style", &space_style,
1776                         NULL);
1777
1778
1779   return space_style;  
1780 }