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