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