]> Pileus Git - ~andy/gtk/blob - gtk/gtktoolbar.c
Moved the gtk_signal_connect of the specified callback into the big
[~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 guint 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           if (!GTK_WIDGET_VISIBLE (child->widget))
457             break;
458
459           alloc.width = toolbar->button_maxw;
460           alloc.height = toolbar->button_maxh;
461
462           if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
463             alloc.y = allocation->y + (allocation->height - toolbar->button_maxh) / 2;
464           else
465             alloc.x = allocation->x + (allocation->width - toolbar->button_maxw) / 2;
466
467           gtk_widget_size_allocate (child->widget, &alloc);
468
469           if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
470             alloc.x += toolbar->button_maxw;
471           else
472             alloc.y += toolbar->button_maxh;
473
474           break;
475
476         case GTK_TOOLBAR_CHILD_WIDGET:
477           if (!GTK_WIDGET_VISIBLE (child->widget))
478             break;
479
480           alloc.width = child->widget->requisition.width;
481           alloc.height = child->widget->requisition.height;
482
483           if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
484             alloc.y = allocation->y + (allocation->height - child->widget->requisition.height) / 2;
485           else
486             alloc.x = allocation->x + (allocation->width - child->widget->requisition.width) / 2;
487
488           gtk_widget_size_allocate (child->widget, &alloc);
489
490           if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
491             alloc.x += child->widget->requisition.width;
492           else
493             alloc.y += child->widget->requisition.height;
494
495           break;
496
497         default:
498           g_assert_not_reached ();
499         }
500     }
501 }
502
503 static void
504 gtk_toolbar_add (GtkContainer *container,
505                  GtkWidget    *widget)
506 {
507   g_return_if_fail (container != NULL);
508   g_return_if_fail (GTK_IS_TOOLBAR (container));
509   g_return_if_fail (widget != NULL);
510
511   gtk_toolbar_append_widget (GTK_TOOLBAR (container), widget, NULL, NULL);
512 }
513
514 static void
515 gtk_toolbar_remove (GtkContainer *container,
516                     GtkWidget    *widget)
517 {
518   GtkToolbar *toolbar;
519   GList *children;
520   GtkToolbarChild *child;
521
522   g_return_if_fail (container != NULL);
523   g_return_if_fail (GTK_IS_TOOLBAR (container));
524   g_return_if_fail (widget != NULL);
525
526   toolbar = GTK_TOOLBAR (container);
527
528   for (children = toolbar->children; children; children = children->next)
529     {
530       child = children->data;
531
532       if ((child->type != GTK_TOOLBAR_CHILD_SPACE) && (child->widget == widget))
533         {
534           gboolean was_visible;
535
536           was_visible = GTK_WIDGET_VISIBLE (widget);
537           gtk_widget_unparent (widget);
538
539           toolbar->children = g_list_remove_link (toolbar->children, children);
540           g_free (child);
541           g_list_free (children);
542           toolbar->num_children--;
543
544           if (was_visible && GTK_WIDGET_VISIBLE (container))
545             gtk_widget_queue_resize (GTK_WIDGET (container));
546
547           break;
548         }
549     }
550 }
551
552 static void
553 gtk_toolbar_foreach (GtkContainer *container,
554                      GtkCallback   callback,
555                      gpointer      callback_data)
556 {
557   GtkToolbar *toolbar;
558   GList *children;
559   GtkToolbarChild *child;
560
561   g_return_if_fail (container != NULL);
562   g_return_if_fail (GTK_IS_TOOLBAR (container));
563   g_return_if_fail (callback != NULL);
564
565   toolbar = GTK_TOOLBAR (container);
566
567   for (children = toolbar->children; children; children = children->next)
568     {
569       child = children->data;
570
571       if (child->type != GTK_TOOLBAR_CHILD_SPACE)
572         (*callback) (child->widget, callback_data);
573     }
574 }
575
576 GtkWidget *
577 gtk_toolbar_append_item (GtkToolbar    *toolbar,
578                          const char    *text,
579                          const char    *tooltip_text,
580                          const char    *tooltip_private_text,
581                          GtkWidget     *icon,
582                          GtkSignalFunc  callback,
583                          gpointer       user_data)
584 {
585   return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
586                                      NULL, text,
587                                      tooltip_text, tooltip_private_text,
588                                      icon, callback, user_data,
589                                      toolbar->num_children);
590 }
591
592 GtkWidget *
593 gtk_toolbar_prepend_item (GtkToolbar    *toolbar,
594                           const char    *text,
595                           const char    *tooltip_text,
596                           const char    *tooltip_private_text,
597                           GtkWidget     *icon,
598                           GtkSignalFunc  callback,
599                           gpointer       user_data)
600 {
601   return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
602                                      NULL, text,
603                                      tooltip_text, tooltip_private_text,
604                                      icon, callback, user_data,
605                                      0);
606 }
607
608 GtkWidget *
609 gtk_toolbar_insert_item (GtkToolbar    *toolbar,
610                          const char    *text,
611                          const char    *tooltip_text,
612                          const char    *tooltip_private_text,
613                          GtkWidget     *icon,
614                          GtkSignalFunc  callback,
615                          gpointer       user_data,
616                          gint           position)
617 {
618   return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
619                                      NULL, text,
620                                      tooltip_text, tooltip_private_text,
621                                      icon, callback, user_data,
622                                      position);
623 }
624
625 void
626 gtk_toolbar_append_space (GtkToolbar *toolbar)
627 {
628   gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
629                               NULL, NULL,
630                               NULL, NULL,
631                               NULL, NULL, NULL,
632                               toolbar->num_children);
633 }
634
635 void
636 gtk_toolbar_prepend_space (GtkToolbar *toolbar)
637 {
638   gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
639                               NULL, NULL,
640                               NULL, NULL,
641                               NULL, NULL, NULL,
642                               0);
643 }
644
645 void
646 gtk_toolbar_insert_space (GtkToolbar *toolbar,
647                           gint        position)
648 {
649   gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
650                               NULL, NULL,
651                               NULL, NULL,
652                               NULL, NULL, NULL,
653                               position);
654 }
655
656 void
657 gtk_toolbar_append_widget (GtkToolbar  *toolbar,
658                            GtkWidget   *widget,
659                            const gchar *tooltip_text,
660                            const gchar *tooltip_private_text)
661 {
662   gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
663                               widget, NULL,
664                               tooltip_text, tooltip_private_text,
665                               NULL, NULL, NULL,
666                               toolbar->num_children);
667 }
668
669 void
670 gtk_toolbar_prepend_widget (GtkToolbar  *toolbar,
671                             GtkWidget   *widget,
672                             const gchar *tooltip_text,
673                             const gchar *tooltip_private_text)
674 {
675   gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
676                               widget, NULL,
677                               tooltip_text, tooltip_private_text,
678                               NULL, NULL, NULL,
679                               toolbar->num_children);
680 }
681
682 void
683 gtk_toolbar_insert_widget (GtkToolbar *toolbar,
684                            GtkWidget  *widget,
685                            const char *tooltip_text,
686                            const char *tooltip_private_text,
687                            gint        position)
688 {
689   gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
690                               widget, NULL,
691                               tooltip_text, tooltip_private_text,
692                               NULL, NULL, NULL,
693                               position);
694 }
695
696 GtkWidget *
697 gtk_toolbar_append_element (GtkToolbar          *toolbar,
698                             GtkToolbarChildType  type,
699                             GtkWidget           *widget,
700                             const char          *text,
701                             const char          *tooltip_text,
702                             const char          *tooltip_private_text,
703                             GtkWidget           *icon,
704                             GtkSignalFunc        callback,
705                             gpointer             user_data)
706 {
707   return gtk_toolbar_insert_element (toolbar, type, widget, text,
708                                      tooltip_text, tooltip_private_text,
709                                      icon, callback, user_data,
710                                      toolbar->num_children);
711 }
712
713 GtkWidget *
714 gtk_toolbar_prepend_element (GtkToolbar          *toolbar,
715                              GtkToolbarChildType  type,
716                              GtkWidget           *widget,
717                              const char          *text,
718                              const char          *tooltip_text,
719                              const char          *tooltip_private_text,
720                              GtkWidget           *icon,
721                              GtkSignalFunc        callback,
722                              gpointer             user_data)
723 {
724   return gtk_toolbar_insert_element (toolbar, type, widget, text,
725                                      tooltip_text, tooltip_private_text,
726                                      icon, callback, user_data, 0);
727 }
728
729 GtkWidget *
730 gtk_toolbar_insert_element (GtkToolbar          *toolbar,
731                             GtkToolbarChildType  type,
732                             GtkWidget           *widget,
733                             const char          *text,
734                             const char          *tooltip_text,
735                             const char          *tooltip_private_text,
736                             GtkWidget           *icon,
737                             GtkSignalFunc        callback,
738                             gpointer             user_data,
739                             gint                 position)
740 {
741   GtkToolbarChild *child;
742   GtkWidget *vbox;
743
744   g_return_val_if_fail (toolbar != NULL, NULL);
745   g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
746   g_return_val_if_fail ((type != GTK_TOOLBAR_CHILD_WIDGET) || (widget != NULL), NULL);
747
748   child = g_new (GtkToolbarChild, 1);
749   child->type = type;
750   child->icon = NULL;
751   child->label = NULL;
752
753   switch (type)
754     {
755     case GTK_TOOLBAR_CHILD_SPACE:
756       child->widget = NULL;
757       break;
758
759     case GTK_TOOLBAR_CHILD_WIDGET:
760       child->widget = widget;
761       break;
762
763     case GTK_TOOLBAR_CHILD_BUTTON:
764     case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
765     case GTK_TOOLBAR_CHILD_RADIOBUTTON:
766       if (type == GTK_TOOLBAR_CHILD_BUTTON)
767         child->widget = gtk_button_new ();
768       else if (type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
769         {
770           child->widget = gtk_toggle_button_new ();
771           gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (child->widget),
772                                       FALSE);
773         }
774       else
775         {
776           child->widget = gtk_radio_button_new (widget
777                                                 ? gtk_radio_button_group (GTK_RADIO_BUTTON (widget))
778                                                 : NULL);
779           gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (child->widget), FALSE);
780         }
781
782       if (callback)
783         gtk_signal_connect (GTK_OBJECT (child->widget), "clicked",
784                             callback, user_data);
785
786       vbox = gtk_vbox_new (FALSE, 0);
787       gtk_container_add (GTK_CONTAINER (child->widget), vbox);
788       gtk_widget_show (vbox);
789
790       if (icon)
791         {
792           child->icon = GTK_WIDGET (icon);
793           gtk_box_pack_start (GTK_BOX (vbox), child->icon, FALSE, FALSE, 0);
794           if (toolbar->style != GTK_TOOLBAR_TEXT)
795             gtk_widget_show (child->icon);
796         }
797
798       if (text)
799         {
800           child->label = gtk_label_new (text);
801           gtk_box_pack_start (GTK_BOX (vbox), child->label, FALSE, FALSE, 0);
802           if (toolbar->style != GTK_TOOLBAR_ICONS)
803             gtk_widget_show (child->label);
804         }
805
806       gtk_widget_show (child->widget);
807       break;
808
809     default:
810       g_assert_not_reached ();
811     }
812
813   if ((type != GTK_TOOLBAR_CHILD_SPACE) && tooltip_text)
814     gtk_tooltips_set_tip (toolbar->tooltips, child->widget,
815                           tooltip_text, tooltip_private_text);
816
817   toolbar->children = g_list_insert (toolbar->children, child, position);
818   toolbar->num_children++;
819
820   if (type != GTK_TOOLBAR_CHILD_SPACE)
821     gtk_widget_set_parent (child->widget, GTK_WIDGET (toolbar));
822
823   if ((type != GTK_TOOLBAR_CHILD_SPACE) && GTK_WIDGET_VISIBLE (toolbar))
824     {
825       if (GTK_WIDGET_REALIZED (toolbar)
826           && !GTK_WIDGET_REALIZED (child->widget))
827         gtk_widget_realize (child->widget);
828         
829       if (GTK_WIDGET_MAPPED (toolbar)
830           && !GTK_WIDGET_MAPPED (child->widget))
831         gtk_widget_map (child->widget);
832     }
833
834   if (GTK_WIDGET_VISIBLE (toolbar) &&
835       ((type == GTK_TOOLBAR_CHILD_SPACE) ||
836        GTK_WIDGET_VISIBLE (child->widget)))
837     gtk_widget_queue_resize (GTK_WIDGET (toolbar));
838
839   return child->widget;
840 }
841
842 void
843 gtk_toolbar_set_orientation (GtkToolbar     *toolbar,
844                              GtkOrientation  orientation)
845 {
846   gtk_signal_emit (GTK_OBJECT (toolbar), toolbar_signals[ORIENTATION_CHANGED], orientation);
847 }
848
849 void
850 gtk_toolbar_set_style (GtkToolbar      *toolbar,
851                        GtkToolbarStyle  style)
852 {
853   gtk_signal_emit (GTK_OBJECT (toolbar), toolbar_signals[STYLE_CHANGED], style);
854 }
855
856 void
857 gtk_toolbar_set_space_size (GtkToolbar *toolbar,
858                             gint        space_size)
859 {
860   g_return_if_fail (toolbar != NULL);
861   g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
862
863   if (toolbar->space_size != space_size)
864     {
865       toolbar->space_size = space_size;
866       gtk_widget_queue_resize (GTK_WIDGET (toolbar));
867     }
868 }
869
870 void
871 gtk_toolbar_set_tooltips (GtkToolbar *toolbar,
872                           gint        enable)
873 {
874   g_return_if_fail (toolbar != NULL);
875   g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
876
877   if (enable)
878     gtk_tooltips_enable (toolbar->tooltips);
879   else
880     gtk_tooltips_disable (toolbar->tooltips);
881 }
882
883 static void
884 gtk_toolbar_marshal_signal_1 (GtkObject     *object,
885                               GtkSignalFunc  func,
886                               gpointer       func_data,
887                               GtkArg        *args)
888 {
889   GtkToolbarSignal1 rfunc;
890
891   rfunc = (GtkToolbarSignal1) func;
892
893   (*rfunc) (object, GTK_VALUE_ENUM (args[0]), func_data);
894 }
895
896 static void
897 gtk_real_toolbar_orientation_changed (GtkToolbar     *toolbar,
898                                       GtkOrientation  orientation)
899 {
900   g_return_if_fail (toolbar != NULL);
901   g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
902
903   if (toolbar->orientation != orientation)
904     {
905       toolbar->orientation = orientation;
906       gtk_widget_queue_resize (GTK_WIDGET (toolbar));
907     }
908 }
909
910 static void
911 gtk_real_toolbar_style_changed (GtkToolbar      *toolbar,
912                                 GtkToolbarStyle  style)
913 {
914   GList *children;
915   GtkToolbarChild *child;
916
917   g_return_if_fail (toolbar != NULL);
918   g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
919
920   if (toolbar->style != style)
921     {
922       toolbar->style = style;
923
924       for (children = toolbar->children; children; children = children->next)
925         {
926           child = children->data;
927
928           if (child->type == GTK_TOOLBAR_CHILD_BUTTON ||
929               child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
930               child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
931             switch (style)
932               {
933               case GTK_TOOLBAR_ICONS:
934                 if (child->icon && !GTK_WIDGET_VISIBLE (child->icon))
935                   gtk_widget_show (child->icon);
936
937                 if (child->label && GTK_WIDGET_VISIBLE (child->label))
938                   gtk_widget_hide (child->label);
939
940                 break;
941
942               case GTK_TOOLBAR_TEXT:
943                 if (child->icon && GTK_WIDGET_VISIBLE (child->icon))
944                   gtk_widget_hide (child->icon);
945
946                 if (child->label && !GTK_WIDGET_VISIBLE (child->label))
947                   gtk_widget_show (child->label);
948
949                 break;
950
951               case GTK_TOOLBAR_BOTH:
952                 if (child->icon && !GTK_WIDGET_VISIBLE (child->icon))
953                   gtk_widget_show (child->icon);
954
955                 if (child->label && !GTK_WIDGET_VISIBLE (child->label))
956                   gtk_widget_show (child->label);
957
958                 break;
959
960               default:
961                 g_assert_not_reached ();
962               }
963         }
964                 
965       gtk_widget_queue_resize (GTK_WIDGET (toolbar));
966     }
967 }