]> Pileus Git - ~andy/gtk/blob - gtk/gtktoolbar.c
Added gtk_toolbar_*_element() functions. Rewrote others
[~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 Library 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  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the Free
17  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19
20 #include "gtkbutton.h"
21 #include "gtktogglebutton.h"
22 #include "gtkradiobutton.h"
23 #include "gtklabel.h"
24 #include "gtkvbox.h"
25 #include "gtktoolbar.h"
26
27
28 #define DEFAULT_SPACE_SIZE 5
29
30
31 enum {
32   ORIENTATION_CHANGED,
33   STYLE_CHANGED,
34   LAST_SIGNAL
35 };
36
37 typedef void (*GtkToolbarSignal1) (GtkObject *object,
38                                    gint       arg1,
39                                    gpointer   data);
40
41 static void gtk_toolbar_marshal_signal_1 (GtkObject     *object,
42                                           GtkSignalFunc  func,
43                                           gpointer       func_data,
44                                           GtkArg        *args);
45
46
47 static void gtk_toolbar_class_init               (GtkToolbarClass *class);
48 static void gtk_toolbar_init                     (GtkToolbar      *toolbar);
49 static void gtk_toolbar_destroy                  (GtkObject       *object);
50 static void gtk_toolbar_map                      (GtkWidget       *widget);
51 static void gtk_toolbar_unmap                    (GtkWidget       *widget);
52 static void gtk_toolbar_draw                     (GtkWidget       *widget,
53                                                   GdkRectangle    *area);
54 static gint gtk_toolbar_expose                   (GtkWidget       *widget,
55                                                   GdkEventExpose  *event);
56 static void gtk_toolbar_size_request             (GtkWidget       *widget,
57                                                   GtkRequisition  *requisition);
58 static void gtk_toolbar_size_allocate            (GtkWidget       *widget,
59                                                   GtkAllocation   *allocation);
60 static void gtk_toolbar_add                      (GtkContainer    *container,
61                                                   GtkWidget       *widget);
62 static void gtk_toolbar_remove                   (GtkContainer    *container,
63                                                   GtkWidget       *widget);
64 static void gtk_toolbar_foreach                  (GtkContainer    *container,
65                                                   GtkCallback      callback,
66                                                   gpointer         callback_data);
67 static void gtk_real_toolbar_orientation_changed (GtkToolbar      *toolbar,
68                                                   GtkOrientation   orientation);
69 static void gtk_real_toolbar_style_changed       (GtkToolbar      *toolbar,
70                                                   GtkToolbarStyle  style);
71
72
73 static GtkContainerClass *parent_class;
74
75 static gint toolbar_signals[LAST_SIGNAL] = { 0 };
76
77
78 guint
79 gtk_toolbar_get_type (void)
80 {
81   static guint toolbar_type = 0;
82
83   if (!toolbar_type)
84     {
85       GtkTypeInfo toolbar_info =
86       {
87         "GtkToolbar",
88         sizeof (GtkToolbar),
89         sizeof (GtkToolbarClass),
90         (GtkClassInitFunc) gtk_toolbar_class_init,
91         (GtkObjectInitFunc) gtk_toolbar_init,
92         (GtkArgSetFunc) NULL,
93         (GtkArgGetFunc) NULL,
94       };
95
96       toolbar_type = gtk_type_unique (gtk_container_get_type (), &toolbar_info);
97     }
98
99   return toolbar_type;
100 }
101
102 static void
103 gtk_toolbar_class_init (GtkToolbarClass *class)
104 {
105   GtkObjectClass *object_class;
106   GtkWidgetClass *widget_class;
107   GtkContainerClass *container_class;
108
109   object_class = (GtkObjectClass *) class;
110   widget_class = (GtkWidgetClass *) class;
111   container_class = (GtkContainerClass *) class;
112
113   parent_class = gtk_type_class (gtk_container_get_type ());
114
115   toolbar_signals[ORIENTATION_CHANGED] =
116     gtk_signal_new ("orientation_changed",
117                     GTK_RUN_FIRST,
118                     object_class->type,
119                     GTK_SIGNAL_OFFSET (GtkToolbarClass, orientation_changed),
120                     gtk_toolbar_marshal_signal_1,
121                     GTK_TYPE_NONE, 1,
122                     GTK_TYPE_INT);
123   toolbar_signals[STYLE_CHANGED] =
124     gtk_signal_new ("style_changed",
125                     GTK_RUN_FIRST,
126                     object_class->type,
127                     GTK_SIGNAL_OFFSET (GtkToolbarClass, style_changed),
128                     gtk_toolbar_marshal_signal_1,
129                     GTK_TYPE_NONE, 1,
130                     GTK_TYPE_INT);
131
132   gtk_object_class_add_signals (object_class, toolbar_signals, LAST_SIGNAL);
133
134   object_class->destroy = gtk_toolbar_destroy;
135
136   widget_class->map = gtk_toolbar_map;
137   widget_class->unmap = gtk_toolbar_unmap;
138   widget_class->draw = gtk_toolbar_draw;
139   widget_class->expose_event = gtk_toolbar_expose;
140   widget_class->size_request = gtk_toolbar_size_request;
141   widget_class->size_allocate = gtk_toolbar_size_allocate;
142
143   container_class->add = gtk_toolbar_add;
144   container_class->remove = gtk_toolbar_remove;
145   container_class->foreach = gtk_toolbar_foreach;
146   container_class->focus = NULL;
147
148   class->orientation_changed = gtk_real_toolbar_orientation_changed;
149   class->style_changed = gtk_real_toolbar_style_changed;
150 }
151
152 static void
153 gtk_toolbar_init (GtkToolbar *toolbar)
154 {
155   GTK_WIDGET_SET_FLAGS (toolbar, GTK_NO_WINDOW);
156   GTK_WIDGET_UNSET_FLAGS (toolbar, GTK_CAN_FOCUS);
157
158   toolbar->num_children = 0;
159   toolbar->children     = NULL;
160   toolbar->orientation  = GTK_ORIENTATION_HORIZONTAL;
161   toolbar->style        = GTK_TOOLBAR_ICONS;
162   toolbar->space_size   = DEFAULT_SPACE_SIZE;
163   toolbar->tooltips     = gtk_tooltips_new ();
164   toolbar->button_maxw  = 0;
165   toolbar->button_maxh  = 0;
166 }
167
168 GtkWidget *
169 gtk_toolbar_new (GtkOrientation  orientation,
170                  GtkToolbarStyle style)
171 {
172   GtkToolbar *toolbar;
173
174   toolbar = gtk_type_new (gtk_toolbar_get_type ());
175
176   toolbar->orientation = orientation;
177   toolbar->style = style;
178
179   return GTK_WIDGET (toolbar);
180 }
181
182 static void
183 gtk_toolbar_destroy (GtkObject *object)
184 {
185   GtkToolbar *toolbar;
186   GList      *children;
187
188   g_return_if_fail (object != NULL);
189   g_return_if_fail (GTK_IS_TOOLBAR (object));
190
191   toolbar = GTK_TOOLBAR (object);
192
193   gtk_object_unref (GTK_OBJECT (toolbar->tooltips));
194   toolbar->tooltips = NULL;
195
196   for (children = toolbar->children; children; children = children->next)
197     {
198       GtkToolbarChild      *child;
199
200       child = children->data;
201
202       if (child->type != GTK_TOOLBAR_CHILD_SPACE)
203         {
204           gtk_widget_ref (child->widget);
205           gtk_widget_unparent (child->widget);
206           gtk_widget_destroy (child->widget);
207           gtk_widget_unref (child->widget);
208         }
209
210       g_free (child);
211     }
212
213   g_list_free (toolbar->children);
214   toolbar->children = NULL;
215   
216   if (GTK_OBJECT_CLASS (parent_class)->destroy)
217     (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
218 }
219
220 static void
221 gtk_toolbar_map (GtkWidget *widget)
222 {
223   GtkToolbar *toolbar;
224   GList      *children;
225   GtkToolbarChild      *child;
226
227   g_return_if_fail (widget != NULL);
228   g_return_if_fail (GTK_IS_TOOLBAR (widget));
229
230   toolbar = GTK_TOOLBAR (widget);
231   GTK_WIDGET_SET_FLAGS (toolbar, GTK_MAPPED);
232
233   for (children = toolbar->children; children; children = children->next)
234     {
235       child = children->data;
236
237       if ((child->type != GTK_TOOLBAR_CHILD_SPACE)
238           && GTK_WIDGET_VISIBLE (child->widget) && !GTK_WIDGET_MAPPED (child->widget))
239         gtk_widget_map (child->widget);
240     }
241 }
242
243 static void
244 gtk_toolbar_unmap (GtkWidget *widget)
245 {
246   GtkToolbar *toolbar;
247   GList      *children;
248   GtkToolbarChild      *child;
249
250   g_return_if_fail (widget != NULL);
251   g_return_if_fail (GTK_IS_TOOLBAR (widget));
252
253   toolbar = GTK_TOOLBAR (widget);
254   GTK_WIDGET_UNSET_FLAGS (toolbar, GTK_MAPPED);
255
256   for (children = toolbar->children; children; children = children->next)
257     {
258       child = children->data;
259
260       if ((child->type != GTK_TOOLBAR_CHILD_SPACE)
261           && GTK_WIDGET_VISIBLE (child->widget) && GTK_WIDGET_MAPPED (child->widget))
262         gtk_widget_unmap (child->widget);
263     }
264 }
265
266 static void
267 gtk_toolbar_draw (GtkWidget    *widget,
268                   GdkRectangle *area)
269 {
270   GtkToolbar   *toolbar;
271   GList        *children;
272   GtkToolbarChild        *child;
273   GdkRectangle  child_area;
274
275   g_return_if_fail (widget != NULL);
276   g_return_if_fail (GTK_IS_TOOLBAR (widget));
277
278   if (GTK_WIDGET_DRAWABLE (widget))
279     {
280       toolbar = GTK_TOOLBAR (widget);
281
282       for (children = toolbar->children; children; children = children->next)
283         {
284           child = children->data;
285
286           if ((child->type != GTK_TOOLBAR_CHILD_SPACE)
287               && gtk_widget_intersect (child->widget, area, &child_area))
288             gtk_widget_draw (child->widget, &child_area);
289         }
290     }
291 }
292
293 static gint
294 gtk_toolbar_expose (GtkWidget      *widget,
295                     GdkEventExpose *event)
296 {
297   GtkToolbar     *toolbar;
298   GList          *children;
299   GtkToolbarChild          *child;
300   GdkEventExpose  child_event;
301
302   g_return_val_if_fail (widget != NULL, FALSE);
303   g_return_val_if_fail (GTK_IS_TOOLBAR (widget), FALSE);
304   g_return_val_if_fail (event != NULL, FALSE);
305
306   if (GTK_WIDGET_DRAWABLE (widget))
307     {
308       toolbar = GTK_TOOLBAR (widget);
309
310       child_event = *event;
311
312       for (children = toolbar->children; children; children = children->next)
313         {
314           child = children->data;
315
316           if ((child->type != GTK_TOOLBAR_CHILD_SPACE)
317               && GTK_WIDGET_NO_WINDOW (child->widget)
318               && gtk_widget_intersect (child->widget, &event->area, &child_event.area))
319             gtk_widget_event (child->widget, (GdkEvent *) &child_event);
320         }
321     }
322
323   return FALSE;
324 }
325
326 static void
327 gtk_toolbar_size_request (GtkWidget      *widget,
328                           GtkRequisition *requisition)
329 {
330   GtkToolbar *toolbar;
331   GList      *children;
332   GtkToolbarChild      *child;
333   gint        nbuttons;
334   gint        button_maxw, button_maxh;
335   gint        widget_maxw, widget_maxh;
336
337   g_return_if_fail (widget != NULL);
338   g_return_if_fail (GTK_IS_TOOLBAR (widget));
339   g_return_if_fail (requisition != NULL);
340
341   toolbar = GTK_TOOLBAR (widget);
342
343   requisition->width = GTK_CONTAINER (toolbar)->border_width * 2;
344   requisition->height = GTK_CONTAINER (toolbar)->border_width * 2;
345   nbuttons = 0;
346   button_maxw = 0;
347   button_maxh = 0;
348   widget_maxw = 0;
349   widget_maxh = 0;
350
351   for (children = toolbar->children; children; children = children->next)
352     {
353       child = children->data;
354
355       switch (child->type)
356         {
357         case GTK_TOOLBAR_CHILD_SPACE:
358           if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
359             requisition->width += toolbar->space_size;
360           else
361             requisition->height += toolbar->space_size;
362
363           break;
364
365         case GTK_TOOLBAR_CHILD_BUTTON:
366         case GTK_TOOLBAR_CHILD_RADIOBUTTON:
367         case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
368           if (GTK_WIDGET_VISIBLE (child->widget))
369             {
370               gtk_widget_size_request (child->widget, &child->widget->requisition);
371
372               nbuttons++;
373               button_maxw = MAX (button_maxw, child->widget->requisition.width);
374               button_maxh = MAX (button_maxh, child->widget->requisition.height);
375             }
376
377           break;
378
379         case GTK_TOOLBAR_CHILD_WIDGET:
380           if (GTK_WIDGET_VISIBLE (child->widget))
381             {
382               gtk_widget_size_request (child->widget, &child->widget->requisition);
383
384               widget_maxw = MAX (widget_maxw, child->widget->requisition.width);
385               widget_maxh = MAX (widget_maxh, child->widget->requisition.height);
386
387               if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
388                 requisition->width += child->widget->requisition.width;
389               else
390                 requisition->height += child->widget->requisition.height;
391             }
392
393           break;
394
395         default:
396           g_assert_not_reached ();
397         }
398     }
399
400   if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
401     {
402       requisition->width += nbuttons * button_maxw;
403       requisition->height += MAX (button_maxh, widget_maxh);
404     }
405   else
406     {
407       requisition->width += MAX (button_maxw, widget_maxw);
408       requisition->height += nbuttons * button_maxh;
409     }
410
411   toolbar->button_maxw = button_maxw;
412   toolbar->button_maxh = button_maxh;
413 }
414
415 static void
416 gtk_toolbar_size_allocate (GtkWidget     *widget,
417                            GtkAllocation *allocation)
418 {
419   GtkToolbar     *toolbar;
420   GList          *children;
421   GtkToolbarChild          *child;
422   GtkAllocation   alloc;
423   gint            border_width;
424
425   g_return_if_fail (widget != NULL);
426   g_return_if_fail (GTK_IS_TOOLBAR (widget));
427   g_return_if_fail (allocation != NULL);
428
429   toolbar = GTK_TOOLBAR (widget);
430   widget->allocation = *allocation;
431
432   border_width = GTK_CONTAINER (toolbar)->border_width;
433
434   if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
435     alloc.x = allocation->x + border_width;
436   else
437     alloc.y = allocation->y + border_width;
438
439   for (children = toolbar->children; children; children = children->next)
440     {
441       child = children->data;
442
443       switch (child->type)
444         {
445         case GTK_TOOLBAR_CHILD_SPACE:
446           if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
447             alloc.x += toolbar->space_size;
448           else
449             alloc.y += toolbar->space_size;
450
451           break;
452
453         case GTK_TOOLBAR_CHILD_BUTTON:
454         case GTK_TOOLBAR_CHILD_RADIOBUTTON:
455         case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
456           alloc.width = toolbar->button_maxw;
457           alloc.height = toolbar->button_maxh;
458
459           if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
460             alloc.y = allocation->y + (allocation->height - toolbar->button_maxh) / 2;
461           else
462             alloc.x = allocation->x + (allocation->width - toolbar->button_maxw) / 2;
463
464           gtk_widget_size_allocate (child->widget, &alloc);
465
466           if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
467             alloc.x += toolbar->button_maxw;
468           else
469             alloc.y += toolbar->button_maxh;
470
471           break;
472
473         case GTK_TOOLBAR_CHILD_WIDGET:
474           alloc.width = child->widget->requisition.width;
475           alloc.height = child->widget->requisition.height;
476
477           if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
478             alloc.y = allocation->y + (allocation->height - child->widget->requisition.height) / 2;
479           else
480             alloc.x = allocation->x + (allocation->width - child->widget->requisition.width) / 2;
481
482           gtk_widget_size_allocate (child->widget, &alloc);
483
484           if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
485             alloc.x += child->widget->requisition.width;
486           else
487             alloc.y += child->widget->requisition.height;
488
489           break;
490
491         default:
492           g_assert_not_reached ();
493         }
494     }
495 }
496
497 static void
498 gtk_toolbar_add (GtkContainer *container,
499                  GtkWidget    *widget)
500 {
501   g_return_if_fail (container != NULL);
502   g_return_if_fail (GTK_IS_TOOLBAR (container));
503   g_return_if_fail (widget != NULL);
504
505   gtk_toolbar_append_widget (GTK_TOOLBAR (container), widget, NULL, NULL);
506 }
507
508 static void
509 gtk_toolbar_remove (GtkContainer *container,
510                     GtkWidget    *widget)
511 {
512   GtkToolbar *toolbar;
513   GList      *children;
514   GtkToolbarChild      *child;
515
516   g_return_if_fail (container != NULL);
517   g_return_if_fail (GTK_IS_TOOLBAR (container));
518   g_return_if_fail (widget != NULL);
519
520   toolbar = GTK_TOOLBAR (container);
521
522   for (children = toolbar->children; children; children = children->next)
523     {
524       child = children->data;
525
526       if ((child->type != GTK_TOOLBAR_CHILD_SPACE) && (child->widget == widget))
527         {
528           gboolean was_visible;
529
530           was_visible = GTK_WIDGET_VISIBLE (widget);
531           gtk_widget_unparent (widget);
532
533           toolbar->children = g_list_remove_link (toolbar->children, children);
534           g_free (child);
535           g_list_free (children);
536           toolbar->num_children--;
537
538           if (was_visible && GTK_WIDGET_VISIBLE (container))
539             gtk_widget_queue_resize (GTK_WIDGET (container));
540
541           break;
542         }
543     }
544 }
545
546 static void
547 gtk_toolbar_foreach (GtkContainer *container,
548                      GtkCallback   callback,
549                      gpointer      callback_data)
550 {
551   GtkToolbar *toolbar;
552   GList      *children;
553   GtkToolbarChild      *child;
554
555   g_return_if_fail (container != NULL);
556   g_return_if_fail (GTK_IS_TOOLBAR (container));
557   g_return_if_fail (callback != NULL);
558
559   toolbar = GTK_TOOLBAR (container);
560
561   for (children = toolbar->children; children; children = children->next)
562     {
563       child = children->data;
564
565       if (child->type != GTK_TOOLBAR_CHILD_SPACE)
566         (*callback) (child->widget, callback_data);
567     }
568 }
569
570 GtkWidget *
571 gtk_toolbar_append_item (GtkToolbar    *toolbar,
572                          const char    *text,
573                          const char    *tooltip_text,
574                          const char    *tooltip_private_text,
575                          GtkWidget     *icon,
576                          GtkSignalFunc  callback,
577                          gpointer       user_data)
578 {
579     return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
580                                        NULL, text,
581                                        tooltip_text, tooltip_private_text,
582                                        icon, callback, user_data,
583                                        toolbar->num_children);
584 }
585
586 GtkWidget *
587 gtk_toolbar_prepend_item (GtkToolbar    *toolbar,
588                           const char    *text,
589                           const char    *tooltip_text,
590                           const char    *tooltip_private_text,
591                           GtkWidget     *icon,
592                           GtkSignalFunc  callback,
593                           gpointer       user_data)
594 {
595     return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
596                                        NULL, text,
597                                        tooltip_text, tooltip_private_text,
598                                        icon, callback, user_data,
599                                        0);
600 }
601
602 GtkWidget *
603 gtk_toolbar_insert_item (GtkToolbar    *toolbar,
604                          const char    *text,
605                          const char    *tooltip_text,
606                          const char    *tooltip_private_text,
607                          GtkWidget     *icon,
608                          GtkSignalFunc  callback,
609                          gpointer       user_data,
610                          gint           position)
611 {
612     return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
613                                        NULL, text,
614                                        tooltip_text, tooltip_private_text,
615                                        icon, callback, user_data,
616                                        position);
617 }
618
619 void
620 gtk_toolbar_append_space (GtkToolbar *toolbar)
621 {
622     gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
623                                 NULL, NULL,
624                                 NULL, NULL,
625                                 NULL, NULL, NULL,
626                                 toolbar->num_children);
627 }
628
629 void
630 gtk_toolbar_prepend_space (GtkToolbar *toolbar)
631 {
632     gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
633                                 NULL, NULL,
634                                 NULL, NULL,
635                                 NULL, NULL, NULL,
636                                 0);
637 }
638
639 void
640 gtk_toolbar_insert_space (GtkToolbar *toolbar,
641                           gint        position)
642 {
643     gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
644                                 NULL, NULL,
645                                 NULL, NULL,
646                                 NULL, NULL, NULL,
647                                 position);
648 }
649
650 void
651 gtk_toolbar_append_widget (GtkToolbar  *toolbar,
652                            GtkWidget   *widget,
653                            const gchar *tooltip_text,
654                            const gchar *tooltip_private_text)
655 {
656     gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
657                                 widget, NULL,
658                                 tooltip_text, tooltip_private_text,
659                                 NULL, NULL, NULL,
660                                 toolbar->num_children);
661 }
662
663 void
664 gtk_toolbar_prepend_widget (GtkToolbar  *toolbar,
665                             GtkWidget   *widget,
666                             const gchar *tooltip_text,
667                             const gchar *tooltip_private_text)
668 {
669     gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
670                                 widget, NULL,
671                                 tooltip_text, tooltip_private_text,
672                                 NULL, NULL, NULL,
673                                 toolbar->num_children);
674 }
675
676 void
677 gtk_toolbar_insert_widget (GtkToolbar *toolbar,
678                            GtkWidget  *widget,
679                            const char *tooltip_text,
680                            const char *tooltip_private_text,
681                            gint        position)
682 {
683     gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
684                                 widget, NULL,
685                                 tooltip_text, tooltip_private_text,
686                                 NULL, NULL, NULL,
687                                 position);
688 }
689
690 GtkWidget *gtk_toolbar_append_element  (GtkToolbar      *toolbar,
691                                         GtkToolbarChildType type,
692                                         GtkWidget       *widget,
693                                         const char      *text,
694                                         const char      *tooltip_text,
695                                         const char      *tooltip_private_text,
696                                         GtkWidget       *icon,
697                                         GtkSignalFunc    callback,
698                                         gpointer         user_data)
699 {
700   return gtk_toolbar_insert_element(toolbar, type, widget, text,
701                                     tooltip_text, tooltip_private_text,
702                                     icon, callback, user_data,
703                                     toolbar->num_children);
704 }
705
706 GtkWidget *gtk_toolbar_prepend_element (GtkToolbar      *toolbar,
707                                         GtkToolbarChildType type,
708                                         GtkWidget       *widget,
709                                         const char      *text,
710                                         const char      *tooltip_text,
711                                         const char      *tooltip_private_text,
712                                         GtkWidget       *icon,
713                                         GtkSignalFunc    callback,
714                                         gpointer         user_data)
715 {
716   return gtk_toolbar_insert_element(toolbar, type, widget, text,
717                                     tooltip_text, tooltip_private_text,
718                                     icon, callback, user_data, 0);
719 }
720
721 GtkWidget *gtk_toolbar_insert_element  (GtkToolbar      *toolbar,
722                                         GtkToolbarChildType type,
723                                         GtkWidget       *widget,
724                                         const char      *text,
725                                         const char      *tooltip_text,
726                                         const char      *tooltip_private_text,
727                                         GtkWidget       *icon,
728                                         GtkSignalFunc    callback,
729                                         gpointer         user_data,
730                                         gint             position)
731 {
732     GtkToolbarChild *child;
733     GtkWidget *vbox;
734
735     g_return_val_if_fail (toolbar != NULL, NULL);
736     g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
737
738     child = g_new (GtkToolbarChild, 1);
739     child->type = type;
740     child->icon = NULL;
741     child->label = NULL;
742
743     switch (type) {
744       case GTK_TOOLBAR_CHILD_SPACE:
745         child->widget = NULL;
746         break;
747       case GTK_TOOLBAR_CHILD_WIDGET:
748         child->widget = widget;
749         break;
750       case GTK_TOOLBAR_CHILD_BUTTON:
751       case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
752       case GTK_TOOLBAR_CHILD_RADIOBUTTON:
753         if (type == GTK_TOOLBAR_CHILD_BUTTON) {
754             child->widget = gtk_button_new ();
755         } else if (type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON) {
756             child->widget = gtk_toggle_button_new ();
757             gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON(child->widget),
758                                         FALSE);
759         } else {
760             child->widget =
761                 gtk_radio_button_new(
762                     widget
763                     ? gtk_radio_button_group(GTK_RADIO_BUTTON(widget))
764                     : NULL);
765             gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON(child->widget),
766                                         FALSE);
767         }
768             
769         vbox = gtk_vbox_new (FALSE, 0);
770         gtk_container_add (GTK_CONTAINER (child->widget), vbox);
771         gtk_widget_show (vbox);
772
773         if (icon) {
774             child->icon = GTK_WIDGET (icon);
775             gtk_box_pack_start (GTK_BOX (vbox), child->icon, FALSE, FALSE, 0);
776             if (toolbar->style != GTK_TOOLBAR_TEXT)
777                 gtk_widget_show (child->icon);
778         }
779
780         if (text) {
781             child->label = gtk_label_new (text);
782             gtk_box_pack_start (GTK_BOX (vbox), child->label, FALSE, FALSE, 0);
783             if (toolbar->style != GTK_TOOLBAR_ICONS)
784                 gtk_widget_show (child->label);
785         }
786
787         gtk_widget_show (child->widget);
788         break;
789       default:
790         g_assert_not_reached ();
791     }
792
793     if (callback)
794         gtk_signal_connect (GTK_OBJECT (child->widget), "clicked",
795                             callback, user_data);
796
797     if (tooltip_text)
798         gtk_tooltips_set_tip (toolbar->tooltips, child->widget,
799                               tooltip_text, tooltip_private_text);
800
801     toolbar->children = g_list_insert (toolbar->children, child, position);
802     toolbar->num_children++;
803
804     if (type != GTK_TOOLBAR_CHILD_SPACE)
805         gtk_widget_set_parent (child->widget, GTK_WIDGET (toolbar));
806
807     if (type != GTK_TOOLBAR_CHILD_SPACE && GTK_WIDGET_VISIBLE (toolbar))
808     {
809         if (GTK_WIDGET_REALIZED (toolbar)
810             && !GTK_WIDGET_REALIZED (child->widget))
811             gtk_widget_realize (child->widget);
812         
813         if (GTK_WIDGET_MAPPED (toolbar)
814             && !GTK_WIDGET_MAPPED (child->widget))
815             gtk_widget_map (child->widget);
816     }
817
818     if (GTK_WIDGET_VISIBLE (toolbar) &&
819         (type == GTK_TOOLBAR_CHILD_SPACE ||
820          GTK_WIDGET_VISIBLE (child->widget)))
821         gtk_widget_queue_resize (GTK_WIDGET (toolbar));
822
823     return child->widget;
824 }
825
826 void
827 gtk_toolbar_set_orientation (GtkToolbar     *toolbar,
828                              GtkOrientation  orientation)
829 {
830   gtk_signal_emit (GTK_OBJECT (toolbar), toolbar_signals[ORIENTATION_CHANGED], orientation);
831 }
832
833 void
834 gtk_toolbar_set_style (GtkToolbar      *toolbar,
835                        GtkToolbarStyle  style)
836 {
837   gtk_signal_emit (GTK_OBJECT (toolbar), toolbar_signals[STYLE_CHANGED], style);
838 }
839
840 void
841 gtk_toolbar_set_space_size (GtkToolbar *toolbar,
842                             gint        space_size)
843 {
844   g_return_if_fail (toolbar != NULL);
845   g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
846
847   if (toolbar->space_size != space_size)
848     {
849       toolbar->space_size = space_size;
850       gtk_widget_queue_resize (GTK_WIDGET (toolbar));
851     }
852 }
853
854 void
855 gtk_toolbar_set_tooltips (GtkToolbar *toolbar,
856                           gint        enable)
857 {
858   g_return_if_fail (toolbar != NULL);
859   g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
860
861   if (enable)
862     gtk_tooltips_enable (toolbar->tooltips);
863   else
864     gtk_tooltips_disable (toolbar->tooltips);
865 }
866
867 static void
868 gtk_toolbar_marshal_signal_1 (GtkObject     *object,
869                               GtkSignalFunc  func,
870                               gpointer       func_data,
871                               GtkArg        *args)
872 {
873   GtkToolbarSignal1 rfunc;
874
875   rfunc = (GtkToolbarSignal1) func;
876
877   (*rfunc) (object, GTK_VALUE_ENUM (args[0]), func_data);
878 }
879
880 static void
881 gtk_real_toolbar_orientation_changed (GtkToolbar     *toolbar,
882                                       GtkOrientation  orientation)
883 {
884   g_return_if_fail (toolbar != NULL);
885   g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
886
887   if (toolbar->orientation != orientation)
888     {
889       toolbar->orientation = orientation;
890       gtk_widget_queue_resize (GTK_WIDGET (toolbar));
891     }
892 }
893
894 static void
895 gtk_real_toolbar_style_changed (GtkToolbar      *toolbar,
896                                 GtkToolbarStyle  style)
897 {
898   GList *children;
899   GtkToolbarChild *child;
900
901   g_return_if_fail (toolbar != NULL);
902   g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
903
904   if (toolbar->style != style)
905     {
906       toolbar->style = style;
907
908       for (children = toolbar->children; children; children = children->next)
909         {
910           child = children->data;
911
912           if (child->type == GTK_TOOLBAR_CHILD_BUTTON ||
913               child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
914               child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
915             switch (style)
916               {
917               case GTK_TOOLBAR_ICONS:
918                 if (child->icon && !GTK_WIDGET_VISIBLE (child->icon))
919                   gtk_widget_show (child->icon);
920
921                 if (child->label && GTK_WIDGET_VISIBLE (child->label))
922                   gtk_widget_hide (child->label);
923
924                 break;
925
926               case GTK_TOOLBAR_TEXT:
927                 if (child->icon && GTK_WIDGET_VISIBLE (child->icon))
928                   gtk_widget_hide (child->icon);
929
930                 if (child->label && !GTK_WIDGET_VISIBLE (child->label))
931                   gtk_widget_show (child->label);
932
933                 break;
934
935               case GTK_TOOLBAR_BOTH:
936                 if (child->icon && !GTK_WIDGET_VISIBLE (child->icon))
937                   gtk_widget_show (child->icon);
938
939                 if (child->label && !GTK_WIDGET_VISIBLE (child->label))
940                   gtk_widget_show (child->label);
941
942                 break;
943
944               default:
945                 g_assert_not_reached ();
946               }
947         }
948                 
949       gtk_widget_queue_resize (GTK_WIDGET (toolbar));
950     }
951 }