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