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