source: trunk/third/gtk/gtk/gtktoolbar.c @ 15781

Revision 15781, 32.1 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r15780, which included commits to RCS files with non-trunk default branches.
Line 
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/*
22 * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
23 * file for a list of people on the GTK+ Team.  See the ChangeLog
24 * files for a list of changes.  These files are distributed with
25 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
26 */
27
28#include "gtkbutton.h"
29#include "gtktogglebutton.h"
30#include "gtkradiobutton.h"
31#include "gtklabel.h"
32#include "gtkvbox.h"
33#include "gtktoolbar.h"
34
35
36#define DEFAULT_SPACE_SIZE  5
37#define DEFAULT_SPACE_STYLE GTK_TOOLBAR_SPACE_EMPTY
38
39#define SPACE_LINE_DIVISION 10
40#define SPACE_LINE_START    3
41#define SPACE_LINE_END      7
42
43enum {
44  ARG_0,
45  ARG_ORIENTATION,
46  ARG_TOOLBAR_STYLE,
47  ARG_SPACE_SIZE,
48  ARG_SPACE_STYLE,
49  ARG_RELIEF
50};
51
52enum {
53  ORIENTATION_CHANGED,
54  STYLE_CHANGED,
55  LAST_SIGNAL
56};
57
58typedef struct _GtkToolbarChildSpace GtkToolbarChildSpace;
59struct _GtkToolbarChildSpace
60{
61  GtkToolbarChild child;
62
63  gint alloc_x, alloc_y;
64};
65
66static void gtk_toolbar_class_init               (GtkToolbarClass *class);
67static void gtk_toolbar_init                     (GtkToolbar      *toolbar);
68static void gtk_toolbar_set_arg                  (GtkObject       *object,
69                                                  GtkArg          *arg,
70                                                  guint            arg_id);
71static void gtk_toolbar_get_arg                  (GtkObject       *object,
72                                                  GtkArg          *arg,
73                                                  guint            arg_id);
74static void gtk_toolbar_destroy                  (GtkObject       *object);
75static void gtk_toolbar_map                      (GtkWidget       *widget);
76static void gtk_toolbar_unmap                    (GtkWidget       *widget);
77static void gtk_toolbar_draw                     (GtkWidget       *widget,
78                                                  GdkRectangle    *area);
79static gint gtk_toolbar_expose                   (GtkWidget       *widget,
80                                                  GdkEventExpose  *event);
81static void gtk_toolbar_size_request             (GtkWidget       *widget,
82                                                  GtkRequisition  *requisition);
83static void gtk_toolbar_size_allocate            (GtkWidget       *widget,
84                                                  GtkAllocation   *allocation);
85static void gtk_toolbar_add                      (GtkContainer    *container,
86                                                  GtkWidget       *widget);
87static void gtk_toolbar_remove                   (GtkContainer    *container,
88                                                  GtkWidget       *widget);
89static void gtk_toolbar_forall                   (GtkContainer    *container,
90                                                  gboolean         include_internals,
91                                                  GtkCallback      callback,
92                                                  gpointer         callback_data);
93static void gtk_real_toolbar_orientation_changed (GtkToolbar      *toolbar,
94                                                  GtkOrientation   orientation);
95static void gtk_real_toolbar_style_changed       (GtkToolbar      *toolbar,
96                                                  GtkToolbarStyle  style);
97
98
99static GtkContainerClass *parent_class;
100
101static guint toolbar_signals[LAST_SIGNAL] = { 0 };
102
103
104guint
105gtk_toolbar_get_type (void)
106{
107  static guint toolbar_type = 0;
108
109  if (!toolbar_type)
110    {
111      static const GtkTypeInfo toolbar_info =
112      {
113        "GtkToolbar",
114        sizeof (GtkToolbar),
115        sizeof (GtkToolbarClass),
116        (GtkClassInitFunc) gtk_toolbar_class_init,
117        (GtkObjectInitFunc) gtk_toolbar_init,
118        /* reserved_1 */ NULL,
119        /* reserved_2 */ NULL,
120        (GtkClassInitFunc) NULL,
121      };
122
123      toolbar_type = gtk_type_unique (gtk_container_get_type (), &toolbar_info);
124    }
125
126  return toolbar_type;
127}
128
129static void
130gtk_toolbar_class_init (GtkToolbarClass *class)
131{
132  GtkObjectClass *object_class;
133  GtkWidgetClass *widget_class;
134  GtkContainerClass *container_class;
135
136  object_class = (GtkObjectClass *) class;
137  widget_class = (GtkWidgetClass *) class;
138  container_class = (GtkContainerClass *) class;
139
140  parent_class = gtk_type_class (gtk_container_get_type ());
141 
142  toolbar_signals[ORIENTATION_CHANGED] =
143    gtk_signal_new ("orientation_changed",
144                    GTK_RUN_FIRST,
145                    object_class->type,
146                    GTK_SIGNAL_OFFSET (GtkToolbarClass, orientation_changed),
147                    gtk_marshal_NONE__INT,
148                    GTK_TYPE_NONE, 1,
149                    GTK_TYPE_INT);
150  toolbar_signals[STYLE_CHANGED] =
151    gtk_signal_new ("style_changed",
152                    GTK_RUN_FIRST,
153                    object_class->type,
154                    GTK_SIGNAL_OFFSET (GtkToolbarClass, style_changed),
155                    gtk_marshal_NONE__INT,
156                    GTK_TYPE_NONE, 1,
157                    GTK_TYPE_INT);
158
159  gtk_object_class_add_signals (object_class, toolbar_signals, LAST_SIGNAL);
160
161  object_class->destroy = gtk_toolbar_destroy;
162  object_class->set_arg = gtk_toolbar_set_arg;
163  object_class->get_arg = gtk_toolbar_get_arg;
164
165  widget_class->map = gtk_toolbar_map;
166  widget_class->unmap = gtk_toolbar_unmap;
167  widget_class->draw = gtk_toolbar_draw;
168  widget_class->expose_event = gtk_toolbar_expose;
169  widget_class->size_request = gtk_toolbar_size_request;
170  widget_class->size_allocate = gtk_toolbar_size_allocate;
171
172  container_class->add = gtk_toolbar_add;
173  container_class->remove = gtk_toolbar_remove;
174  container_class->forall = gtk_toolbar_forall;
175  container_class->focus = NULL;
176 
177  class->orientation_changed = gtk_real_toolbar_orientation_changed;
178  class->style_changed = gtk_real_toolbar_style_changed;
179 
180  gtk_object_add_arg_type ("GtkToolbar::orientation", GTK_TYPE_ORIENTATION,
181                           GTK_ARG_READWRITE, ARG_ORIENTATION);
182  gtk_object_add_arg_type ("GtkToolbar::toolbar_style", GTK_TYPE_TOOLBAR_STYLE,
183                           GTK_ARG_READWRITE, ARG_TOOLBAR_STYLE);
184  gtk_object_add_arg_type ("GtkToolbar::space_size", GTK_TYPE_UINT,
185                           GTK_ARG_READWRITE, ARG_SPACE_SIZE);
186  gtk_object_add_arg_type ("GtkToolbar::space_style", GTK_TYPE_TOOLBAR_SPACE_STYLE,
187                           GTK_ARG_READWRITE, ARG_SPACE_STYLE);
188  gtk_object_add_arg_type ("GtkToolbar::relief", GTK_TYPE_RELIEF_STYLE,
189                           GTK_ARG_READWRITE, ARG_RELIEF);
190}
191
192static void
193gtk_toolbar_init (GtkToolbar *toolbar)
194{
195  GTK_WIDGET_SET_FLAGS (toolbar, GTK_NO_WINDOW);
196  GTK_WIDGET_UNSET_FLAGS (toolbar, GTK_CAN_FOCUS);
197
198  toolbar->num_children = 0;
199  toolbar->children     = NULL;
200  toolbar->orientation  = GTK_ORIENTATION_HORIZONTAL;
201  toolbar->style        = GTK_TOOLBAR_ICONS;
202  toolbar->relief       = GTK_RELIEF_NORMAL;
203  toolbar->space_size   = DEFAULT_SPACE_SIZE;
204  toolbar->space_style  = DEFAULT_SPACE_STYLE;
205  toolbar->tooltips     = gtk_tooltips_new ();
206  toolbar->button_maxw  = 0;
207  toolbar->button_maxh  = 0;
208}
209
210static void
211gtk_toolbar_set_arg (GtkObject *object,
212                     GtkArg    *arg,
213                     guint      arg_id)
214{
215  GtkToolbar *toolbar = GTK_TOOLBAR (object);
216 
217  switch (arg_id)
218    {
219    case ARG_ORIENTATION:
220      gtk_toolbar_set_orientation (toolbar, GTK_VALUE_ENUM (*arg));
221      break;
222    case ARG_TOOLBAR_STYLE:
223      gtk_toolbar_set_style (toolbar, GTK_VALUE_ENUM (*arg));
224      break;
225    case ARG_SPACE_SIZE:
226      gtk_toolbar_set_space_size (toolbar, GTK_VALUE_UINT (*arg));
227      break;
228    case ARG_SPACE_STYLE:
229      gtk_toolbar_set_space_style (toolbar, GTK_VALUE_ENUM (*arg));
230      break;     
231    case ARG_RELIEF:
232      gtk_toolbar_set_button_relief (toolbar, GTK_VALUE_ENUM (*arg));
233      break;
234    }
235}
236
237static void
238gtk_toolbar_get_arg (GtkObject *object,
239                     GtkArg    *arg,
240                     guint      arg_id)
241{
242  GtkToolbar *toolbar = GTK_TOOLBAR (object);
243
244  switch (arg_id)
245    {
246    case ARG_ORIENTATION:
247      GTK_VALUE_ENUM (*arg) = toolbar->orientation;
248      break;
249    case ARG_TOOLBAR_STYLE:
250      GTK_VALUE_ENUM (*arg) = toolbar->style;
251      break;
252    case ARG_SPACE_SIZE:
253      GTK_VALUE_UINT (*arg) = toolbar->space_size;
254      break;           
255    case ARG_SPACE_STYLE:
256      GTK_VALUE_ENUM (*arg) = toolbar->space_style;
257      break;
258    case ARG_RELIEF:
259      GTK_VALUE_ENUM (*arg) = toolbar->relief;
260      break;   
261    default:
262      arg->type = GTK_TYPE_INVALID;
263      break;
264    }
265}
266
267GtkWidget*
268gtk_toolbar_new (GtkOrientation  orientation,
269                 GtkToolbarStyle style)
270{
271  GtkToolbar *toolbar;
272
273  toolbar = gtk_type_new (gtk_toolbar_get_type ());
274
275  toolbar->orientation = orientation;
276  toolbar->style = style;
277
278  return GTK_WIDGET (toolbar);
279}
280
281static void
282gtk_toolbar_destroy (GtkObject *object)
283{
284  GtkToolbar *toolbar;
285  GList *children;
286
287  g_return_if_fail (object != NULL);
288  g_return_if_fail (GTK_IS_TOOLBAR (object));
289
290  toolbar = GTK_TOOLBAR (object);
291
292  gtk_object_unref (GTK_OBJECT (toolbar->tooltips));
293  toolbar->tooltips = NULL;
294
295  for (children = toolbar->children; children; children = children->next)
296    {
297      GtkToolbarChild *child;
298
299      child = children->data;
300
301      if (child->type != GTK_TOOLBAR_CHILD_SPACE)
302        {
303          gtk_widget_ref (child->widget);
304          gtk_widget_unparent (child->widget);
305          gtk_widget_destroy (child->widget);
306          gtk_widget_unref (child->widget);
307        }
308
309      g_free (child);
310    }
311
312  g_list_free (toolbar->children);
313  toolbar->children = NULL;
314 
315  if (GTK_OBJECT_CLASS (parent_class)->destroy)
316    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
317}
318
319static void
320gtk_toolbar_map (GtkWidget *widget)
321{
322  GtkToolbar *toolbar;
323  GList *children;
324  GtkToolbarChild *child;
325
326  g_return_if_fail (widget != NULL);
327  g_return_if_fail (GTK_IS_TOOLBAR (widget));
328
329  toolbar = GTK_TOOLBAR (widget);
330  GTK_WIDGET_SET_FLAGS (toolbar, GTK_MAPPED);
331
332  for (children = toolbar->children; children; children = children->next)
333    {
334      child = children->data;
335
336      if ((child->type != GTK_TOOLBAR_CHILD_SPACE)
337          && GTK_WIDGET_VISIBLE (child->widget) && !GTK_WIDGET_MAPPED (child->widget))
338        gtk_widget_map (child->widget);
339    }
340}
341
342static void
343gtk_toolbar_unmap (GtkWidget *widget)
344{
345  GtkToolbar *toolbar;
346  GList *children;
347  GtkToolbarChild *child;
348
349  g_return_if_fail (widget != NULL);
350  g_return_if_fail (GTK_IS_TOOLBAR (widget));
351
352  toolbar = GTK_TOOLBAR (widget);
353  GTK_WIDGET_UNSET_FLAGS (toolbar, GTK_MAPPED);
354
355  for (children = toolbar->children; children; children = children->next)
356    {
357      child = children->data;
358
359      if ((child->type != GTK_TOOLBAR_CHILD_SPACE)
360          && GTK_WIDGET_VISIBLE (child->widget) && GTK_WIDGET_MAPPED (child->widget))
361        gtk_widget_unmap (child->widget);
362    }
363}
364
365static void
366gtk_toolbar_paint_space_line (GtkWidget       *widget,
367                              GdkRectangle    *area,
368                              GtkToolbarChild *child)
369{
370  GtkToolbar *toolbar;
371  GtkToolbarChildSpace *child_space;
372
373  g_return_if_fail (widget != NULL);
374  g_return_if_fail (GTK_IS_TOOLBAR (widget));
375  g_return_if_fail (child != NULL);
376  g_return_if_fail (child->type == GTK_TOOLBAR_CHILD_SPACE);
377
378  toolbar = GTK_TOOLBAR (widget);
379
380  child_space = (GtkToolbarChildSpace *) child;
381
382  if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
383    gtk_paint_vline (widget->style, widget->window,
384                     GTK_WIDGET_STATE (widget), area, widget,
385                     "toolbar",
386                     child_space->alloc_y + toolbar->button_maxh *
387                     SPACE_LINE_START / SPACE_LINE_DIVISION,
388                     child_space->alloc_y + toolbar->button_maxh *
389                     SPACE_LINE_END / SPACE_LINE_DIVISION,
390                     child_space->alloc_x +
391                     (toolbar->space_size -
392                      widget->style->klass->xthickness) / 2);
393  else
394    gtk_paint_hline (widget->style, widget->window,
395                     GTK_WIDGET_STATE (widget), area, widget,
396                     "toolbar",
397                     child_space->alloc_x + toolbar->button_maxw *
398                     SPACE_LINE_START / SPACE_LINE_DIVISION,
399                     child_space->alloc_x + toolbar->button_maxw *
400                     SPACE_LINE_END / SPACE_LINE_DIVISION,
401                     child_space->alloc_y +
402                     (toolbar->space_size -
403                      widget->style->klass->ythickness) / 2);
404}
405
406static void
407gtk_toolbar_draw (GtkWidget    *widget,
408                  GdkRectangle *area)
409{
410  GtkToolbar *toolbar;
411  GList *children;
412  GtkToolbarChild *child;
413  GdkRectangle child_area;
414
415  g_return_if_fail (widget != NULL);
416  g_return_if_fail (GTK_IS_TOOLBAR (widget));
417
418  if (GTK_WIDGET_DRAWABLE (widget))
419    {
420      toolbar = GTK_TOOLBAR (widget);
421
422      for (children = toolbar->children; children; children = children->next)
423        {
424          child = children->data;
425
426          if (child->type == GTK_TOOLBAR_CHILD_SPACE)
427            {
428              if (toolbar->space_style == GTK_TOOLBAR_SPACE_LINE)
429                gtk_toolbar_paint_space_line (widget, area, child);
430            }
431          else if (gtk_widget_intersect (child->widget, area, &child_area))
432            gtk_widget_draw (child->widget, &child_area);
433        }
434    }
435}
436
437static gint
438gtk_toolbar_expose (GtkWidget      *widget,
439                    GdkEventExpose *event)
440{
441  GtkToolbar *toolbar;
442  GList *children;
443  GtkToolbarChild *child;
444  GdkEventExpose child_event;
445
446  g_return_val_if_fail (widget != NULL, FALSE);
447  g_return_val_if_fail (GTK_IS_TOOLBAR (widget), FALSE);
448  g_return_val_if_fail (event != NULL, FALSE);
449
450  if (GTK_WIDGET_DRAWABLE (widget))
451    {
452      toolbar = GTK_TOOLBAR (widget);
453
454      child_event = *event;
455
456      for (children = toolbar->children; children; children = children->next)
457        {
458          child = children->data;
459
460          if (child->type == GTK_TOOLBAR_CHILD_SPACE)
461            {
462              if (toolbar->space_style == GTK_TOOLBAR_SPACE_LINE)
463                gtk_toolbar_paint_space_line (widget, &event->area, child);
464            }
465          else if (GTK_WIDGET_NO_WINDOW (child->widget)
466                   && gtk_widget_intersect (child->widget, &event->area, &child_event.area))
467            gtk_widget_event (child->widget, (GdkEvent *) &child_event);
468        }
469    }
470
471  return FALSE;
472}
473
474static void
475gtk_toolbar_size_request (GtkWidget      *widget,
476                          GtkRequisition *requisition)
477{
478  GtkToolbar *toolbar;
479  GList *children;
480  GtkToolbarChild *child;
481  gint nbuttons;
482  gint button_maxw, button_maxh;
483  gint widget_maxw, widget_maxh;
484  GtkRequisition child_requisition;
485
486  g_return_if_fail (widget != NULL);
487  g_return_if_fail (GTK_IS_TOOLBAR (widget));
488  g_return_if_fail (requisition != NULL);
489
490  toolbar = GTK_TOOLBAR (widget);
491
492  requisition->width = GTK_CONTAINER (toolbar)->border_width * 2;
493  requisition->height = GTK_CONTAINER (toolbar)->border_width * 2;
494  nbuttons = 0;
495  button_maxw = 0;
496  button_maxh = 0;
497  widget_maxw = 0;
498  widget_maxh = 0;
499
500  for (children = toolbar->children; children; children = children->next)
501    {
502      child = children->data;
503
504      switch (child->type)
505        {
506        case GTK_TOOLBAR_CHILD_SPACE:
507          if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
508            requisition->width += toolbar->space_size;
509          else
510            requisition->height += toolbar->space_size;
511
512          break;
513
514        case GTK_TOOLBAR_CHILD_BUTTON:
515        case GTK_TOOLBAR_CHILD_RADIOBUTTON:
516        case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
517          if (GTK_WIDGET_VISIBLE (child->widget))
518            {
519              gtk_widget_size_request (child->widget, &child_requisition);
520
521              nbuttons++;
522              button_maxw = MAX (button_maxw, child_requisition.width);
523              button_maxh = MAX (button_maxh, child_requisition.height);
524            }
525
526          break;
527
528        case GTK_TOOLBAR_CHILD_WIDGET:
529          if (GTK_WIDGET_VISIBLE (child->widget))
530            {
531              gtk_widget_size_request (child->widget, &child_requisition);
532
533              widget_maxw = MAX (widget_maxw, child_requisition.width);
534              widget_maxh = MAX (widget_maxh, child_requisition.height);
535
536              if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
537                requisition->width += child_requisition.width;
538              else
539                requisition->height += child_requisition.height;
540            }
541
542          break;
543
544        default:
545          g_assert_not_reached ();
546        }
547    }
548
549  if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
550    {
551      requisition->width += nbuttons * button_maxw;
552      requisition->height += MAX (button_maxh, widget_maxh);
553    }
554  else
555    {
556      requisition->width += MAX (button_maxw, widget_maxw);
557      requisition->height += nbuttons * button_maxh;
558    }
559
560  toolbar->button_maxw = button_maxw;
561  toolbar->button_maxh = button_maxh;
562}
563
564static void
565gtk_toolbar_size_allocate (GtkWidget     *widget,
566                           GtkAllocation *allocation)
567{
568  GtkToolbar *toolbar;
569  GList *children;
570  GtkToolbarChild *child;
571  GtkToolbarChildSpace *child_space;
572  GtkAllocation alloc;
573  GtkRequisition child_requisition;
574  gint border_width;
575
576  g_return_if_fail (widget != NULL);
577  g_return_if_fail (GTK_IS_TOOLBAR (widget));
578  g_return_if_fail (allocation != NULL);
579
580  toolbar = GTK_TOOLBAR (widget);
581  widget->allocation = *allocation;
582
583  border_width = GTK_CONTAINER (toolbar)->border_width;
584
585  if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
586    alloc.x = allocation->x + border_width;
587  else
588    alloc.y = allocation->y + border_width;
589
590  for (children = toolbar->children; children; children = children->next)
591    {
592      child = children->data;
593
594      switch (child->type)
595        {
596        case GTK_TOOLBAR_CHILD_SPACE:
597
598          child_space = (GtkToolbarChildSpace *) child;
599
600          if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
601            {
602              child_space->alloc_x = alloc.x;
603              child_space->alloc_y = allocation->y + (allocation->height - toolbar->button_maxh) / 2;
604              alloc.x += toolbar->space_size;
605            }
606          else
607            {
608              child_space->alloc_x = allocation->x + (allocation->width - toolbar->button_maxw) / 2;
609              child_space->alloc_y = alloc.y;
610              alloc.y += toolbar->space_size;
611            }
612
613          break;
614
615        case GTK_TOOLBAR_CHILD_BUTTON:
616        case GTK_TOOLBAR_CHILD_RADIOBUTTON:
617        case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
618          if (!GTK_WIDGET_VISIBLE (child->widget))
619            break;
620
621          alloc.width = toolbar->button_maxw;
622          alloc.height = toolbar->button_maxh;
623
624          if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
625            alloc.y = allocation->y + (allocation->height - toolbar->button_maxh) / 2;
626          else
627            alloc.x = allocation->x + (allocation->width - toolbar->button_maxw) / 2;
628
629          gtk_widget_size_allocate (child->widget, &alloc);
630
631          if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
632            alloc.x += toolbar->button_maxw;
633          else
634            alloc.y += toolbar->button_maxh;
635
636          break;
637
638        case GTK_TOOLBAR_CHILD_WIDGET:
639          if (!GTK_WIDGET_VISIBLE (child->widget))
640            break;
641
642          gtk_widget_get_child_requisition (child->widget, &child_requisition);
643         
644          alloc.width = child_requisition.width;
645          alloc.height = child_requisition.height;
646
647          if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
648            alloc.y = allocation->y + (allocation->height - child_requisition.height) / 2;
649          else
650            alloc.x = allocation->x + (allocation->width - child_requisition.width) / 2;
651
652          gtk_widget_size_allocate (child->widget, &alloc);
653
654          if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
655            alloc.x += child_requisition.width;
656          else
657            alloc.y += child_requisition.height;
658
659          break;
660
661        default:
662          g_assert_not_reached ();
663        }
664    }
665}
666
667static void
668gtk_toolbar_add (GtkContainer *container,
669                 GtkWidget    *widget)
670{
671  g_return_if_fail (container != NULL);
672  g_return_if_fail (GTK_IS_TOOLBAR (container));
673  g_return_if_fail (widget != NULL);
674
675  gtk_toolbar_append_widget (GTK_TOOLBAR (container), widget, NULL, NULL);
676}
677
678static void
679gtk_toolbar_remove (GtkContainer *container,
680                    GtkWidget    *widget)
681{
682  GtkToolbar *toolbar;
683  GList *children;
684  GtkToolbarChild *child;
685
686  g_return_if_fail (container != NULL);
687  g_return_if_fail (GTK_IS_TOOLBAR (container));
688  g_return_if_fail (widget != NULL);
689
690  toolbar = GTK_TOOLBAR (container);
691
692  for (children = toolbar->children; children; children = children->next)
693    {
694      child = children->data;
695
696      if ((child->type != GTK_TOOLBAR_CHILD_SPACE) && (child->widget == widget))
697        {
698          gboolean was_visible;
699
700          was_visible = GTK_WIDGET_VISIBLE (widget);
701          gtk_widget_unparent (widget);
702
703          toolbar->children = g_list_remove_link (toolbar->children, children);
704          g_free (child);
705          g_list_free (children);
706          toolbar->num_children--;
707
708          if (was_visible && GTK_WIDGET_VISIBLE (container))
709            gtk_widget_queue_resize (GTK_WIDGET (container));
710
711          break;
712        }
713    }
714}
715
716static void
717gtk_toolbar_forall (GtkContainer *container,
718                    gboolean      include_internals,
719                    GtkCallback   callback,
720                    gpointer      callback_data)
721{
722  GtkToolbar *toolbar;
723  GList *children;
724  GtkToolbarChild *child;
725
726  g_return_if_fail (container != NULL);
727  g_return_if_fail (GTK_IS_TOOLBAR (container));
728  g_return_if_fail (callback != NULL);
729
730  toolbar = GTK_TOOLBAR (container);
731
732  for (children = toolbar->children; children; children = children->next)
733    {
734      child = children->data;
735
736      if (child->type != GTK_TOOLBAR_CHILD_SPACE)
737        (*callback) (child->widget, callback_data);
738    }
739}
740
741GtkWidget *
742gtk_toolbar_append_item (GtkToolbar    *toolbar,
743                         const char    *text,
744                         const char    *tooltip_text,
745                         const char    *tooltip_private_text,
746                         GtkWidget     *icon,
747                         GtkSignalFunc  callback,
748                         gpointer       user_data)
749{
750  return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
751                                     NULL, text,
752                                     tooltip_text, tooltip_private_text,
753                                     icon, callback, user_data,
754                                     toolbar->num_children);
755}
756
757GtkWidget *
758gtk_toolbar_prepend_item (GtkToolbar    *toolbar,
759                          const char    *text,
760                          const char    *tooltip_text,
761                          const char    *tooltip_private_text,
762                          GtkWidget     *icon,
763                          GtkSignalFunc  callback,
764                          gpointer       user_data)
765{
766  return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
767                                     NULL, text,
768                                     tooltip_text, tooltip_private_text,
769                                     icon, callback, user_data,
770                                     0);
771}
772
773GtkWidget *
774gtk_toolbar_insert_item (GtkToolbar    *toolbar,
775                         const char    *text,
776                         const char    *tooltip_text,
777                         const char    *tooltip_private_text,
778                         GtkWidget     *icon,
779                         GtkSignalFunc  callback,
780                         gpointer       user_data,
781                         gint           position)
782{
783  return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
784                                     NULL, text,
785                                     tooltip_text, tooltip_private_text,
786                                     icon, callback, user_data,
787                                     position);
788}
789
790void
791gtk_toolbar_append_space (GtkToolbar *toolbar)
792{
793  gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
794                              NULL, NULL,
795                              NULL, NULL,
796                              NULL, NULL, NULL,
797                              toolbar->num_children);
798}
799
800void
801gtk_toolbar_prepend_space (GtkToolbar *toolbar)
802{
803  gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
804                              NULL, NULL,
805                              NULL, NULL,
806                              NULL, NULL, NULL,
807                              0);
808}
809
810void
811gtk_toolbar_insert_space (GtkToolbar *toolbar,
812                          gint        position)
813{
814  gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_SPACE,
815                              NULL, NULL,
816                              NULL, NULL,
817                              NULL, NULL, NULL,
818                              position);
819}
820
821void
822gtk_toolbar_append_widget (GtkToolbar  *toolbar,
823                           GtkWidget   *widget,
824                           const gchar *tooltip_text,
825                           const gchar *tooltip_private_text)
826{
827  gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
828                              widget, NULL,
829                              tooltip_text, tooltip_private_text,
830                              NULL, NULL, NULL,
831                              toolbar->num_children);
832}
833
834void
835gtk_toolbar_prepend_widget (GtkToolbar  *toolbar,
836                            GtkWidget   *widget,
837                            const gchar *tooltip_text,
838                            const gchar *tooltip_private_text)
839{
840  gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
841                              widget, NULL,
842                              tooltip_text, tooltip_private_text,
843                              NULL, NULL, NULL,
844                              0);
845}
846
847void
848gtk_toolbar_insert_widget (GtkToolbar *toolbar,
849                           GtkWidget  *widget,
850                           const char *tooltip_text,
851                           const char *tooltip_private_text,
852                           gint        position)
853{
854  gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_WIDGET,
855                              widget, NULL,
856                              tooltip_text, tooltip_private_text,
857                              NULL, NULL, NULL,
858                              position);
859}
860
861GtkWidget*
862gtk_toolbar_append_element (GtkToolbar          *toolbar,
863                            GtkToolbarChildType  type,
864                            GtkWidget           *widget,
865                            const char          *text,
866                            const char          *tooltip_text,
867                            const char          *tooltip_private_text,
868                            GtkWidget           *icon,
869                            GtkSignalFunc        callback,
870                            gpointer             user_data)
871{
872  return gtk_toolbar_insert_element (toolbar, type, widget, text,
873                                     tooltip_text, tooltip_private_text,
874                                     icon, callback, user_data,
875                                     toolbar->num_children);
876}
877
878GtkWidget *
879gtk_toolbar_prepend_element (GtkToolbar          *toolbar,
880                             GtkToolbarChildType  type,
881                             GtkWidget           *widget,
882                             const char          *text,
883                             const char          *tooltip_text,
884                             const char          *tooltip_private_text,
885                             GtkWidget           *icon,
886                             GtkSignalFunc        callback,
887                             gpointer             user_data)
888{
889  return gtk_toolbar_insert_element (toolbar, type, widget, text,
890                                     tooltip_text, tooltip_private_text,
891                                     icon, callback, user_data, 0);
892}
893
894GtkWidget *
895gtk_toolbar_insert_element (GtkToolbar          *toolbar,
896                            GtkToolbarChildType  type,
897                            GtkWidget           *widget,
898                            const char          *text,
899                            const char          *tooltip_text,
900                            const char          *tooltip_private_text,
901                            GtkWidget           *icon,
902                            GtkSignalFunc        callback,
903                            gpointer             user_data,
904                            gint                 position)
905{
906  GtkToolbarChild *child;
907  GtkWidget *vbox;
908
909  g_return_val_if_fail (toolbar != NULL, NULL);
910  g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
911  if (type == GTK_TOOLBAR_CHILD_WIDGET)
912    {
913      g_return_val_if_fail (widget != NULL, NULL);
914      g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
915    }
916  else if (type != GTK_TOOLBAR_CHILD_RADIOBUTTON)
917    g_return_val_if_fail (widget == NULL, NULL);
918
919  if (type == GTK_TOOLBAR_CHILD_SPACE)
920    child = (GtkToolbarChild *) g_new (GtkToolbarChildSpace, 1);
921  else
922    child = g_new (GtkToolbarChild, 1);
923
924  child->type = type;
925  child->icon = NULL;
926  child->label = NULL;
927
928  switch (type)
929    {
930    case GTK_TOOLBAR_CHILD_SPACE:
931      child->widget = NULL;
932      ((GtkToolbarChildSpace *) child)->alloc_x =
933        ((GtkToolbarChildSpace *) child)->alloc_y = 0;
934      break;
935
936    case GTK_TOOLBAR_CHILD_WIDGET:
937      child->widget = widget;
938      break;
939
940    case GTK_TOOLBAR_CHILD_BUTTON:
941    case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
942    case GTK_TOOLBAR_CHILD_RADIOBUTTON:
943      if (type == GTK_TOOLBAR_CHILD_BUTTON)
944        {
945          child->widget = gtk_button_new ();
946          gtk_button_set_relief (GTK_BUTTON (child->widget), toolbar->relief);
947        }
948      else if (type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
949        {
950          child->widget = gtk_toggle_button_new ();
951          gtk_button_set_relief (GTK_BUTTON (child->widget), toolbar->relief);
952          gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (child->widget),
953                                      FALSE);
954        }
955      else
956        {
957          child->widget = gtk_radio_button_new (widget
958                                                ? gtk_radio_button_group (GTK_RADIO_BUTTON (widget))
959                                                : NULL);
960          gtk_button_set_relief (GTK_BUTTON (child->widget), toolbar->relief);
961          gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (child->widget), FALSE);
962        }
963
964      GTK_WIDGET_UNSET_FLAGS (child->widget, GTK_CAN_FOCUS);
965
966      if (callback)
967        gtk_signal_connect (GTK_OBJECT (child->widget), "clicked",
968                            callback, user_data);
969
970      vbox = gtk_vbox_new (FALSE, 0);
971      gtk_container_add (GTK_CONTAINER (child->widget), vbox);
972      gtk_widget_show (vbox);
973
974      if (text)
975        {
976          child->label = gtk_label_new (text);
977          gtk_box_pack_end (GTK_BOX (vbox), child->label, FALSE, FALSE, 0);
978          if (toolbar->style != GTK_TOOLBAR_ICONS)
979            gtk_widget_show (child->label);
980        }
981
982      if (icon)
983        {
984          child->icon = GTK_WIDGET (icon);
985          gtk_box_pack_end (GTK_BOX (vbox), child->icon, FALSE, FALSE, 0);
986          if (toolbar->style != GTK_TOOLBAR_TEXT)
987            gtk_widget_show (child->icon);
988        }
989
990      gtk_widget_show (child->widget);
991      break;
992
993    default:
994      g_assert_not_reached ();
995    }
996
997  if ((type != GTK_TOOLBAR_CHILD_SPACE) && tooltip_text)
998    gtk_tooltips_set_tip (toolbar->tooltips, child->widget,
999                          tooltip_text, tooltip_private_text);
1000
1001  toolbar->children = g_list_insert (toolbar->children, child, position);
1002  toolbar->num_children++;
1003
1004  if (type != GTK_TOOLBAR_CHILD_SPACE)
1005    {
1006      gtk_widget_set_parent (child->widget, GTK_WIDGET (toolbar));
1007
1008      if (GTK_WIDGET_REALIZED (child->widget->parent))
1009        gtk_widget_realize (child->widget);
1010
1011      if (GTK_WIDGET_VISIBLE (child->widget->parent) && GTK_WIDGET_VISIBLE (child->widget))
1012        {
1013          if (GTK_WIDGET_MAPPED (child->widget->parent))
1014            gtk_widget_map (child->widget);
1015
1016          gtk_widget_queue_resize (child->widget);
1017        }
1018    }
1019  else
1020    gtk_widget_queue_resize (GTK_WIDGET (toolbar));
1021
1022  return child->widget;
1023}
1024
1025void
1026gtk_toolbar_set_orientation (GtkToolbar     *toolbar,
1027                             GtkOrientation  orientation)
1028{
1029  g_return_if_fail (toolbar != NULL);
1030  g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1031
1032  gtk_signal_emit (GTK_OBJECT (toolbar), toolbar_signals[ORIENTATION_CHANGED], orientation);
1033}
1034
1035void
1036gtk_toolbar_set_style (GtkToolbar      *toolbar,
1037                       GtkToolbarStyle  style)
1038{
1039  g_return_if_fail (toolbar != NULL);
1040  g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1041
1042  gtk_signal_emit (GTK_OBJECT (toolbar), toolbar_signals[STYLE_CHANGED], style);
1043}
1044
1045void
1046gtk_toolbar_set_space_size (GtkToolbar *toolbar,
1047                            gint        space_size)
1048{
1049  g_return_if_fail (toolbar != NULL);
1050  g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1051
1052  if (toolbar->space_size != space_size)
1053    {
1054      toolbar->space_size = space_size;
1055      gtk_widget_queue_resize (GTK_WIDGET (toolbar));
1056    }
1057}
1058
1059void
1060gtk_toolbar_set_space_style (GtkToolbar           *toolbar,
1061                             GtkToolbarSpaceStyle  space_style)
1062{
1063  g_return_if_fail (toolbar != NULL);
1064  g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1065
1066  if (toolbar->space_style != space_style)
1067    {
1068      toolbar->space_style = space_style;
1069      gtk_widget_queue_resize (GTK_WIDGET (toolbar));
1070    }
1071}
1072
1073void
1074gtk_toolbar_set_tooltips (GtkToolbar *toolbar,
1075                          gint        enable)
1076{
1077  g_return_if_fail (toolbar != NULL);
1078  g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1079
1080  if (enable)
1081    gtk_tooltips_enable (toolbar->tooltips);
1082  else
1083    gtk_tooltips_disable (toolbar->tooltips);
1084}
1085
1086void
1087gtk_toolbar_set_button_relief (GtkToolbar *toolbar,
1088                               GtkReliefStyle relief)
1089{
1090  GList *children;
1091  GtkToolbarChild *child;
1092 
1093  g_return_if_fail (toolbar != NULL);
1094  g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1095
1096  if (toolbar->relief != relief)
1097    {
1098      toolbar->relief = relief;
1099     
1100      for (children = toolbar->children; children; children = children->next)
1101        {
1102          child = children->data;
1103          if (child->type == GTK_TOOLBAR_CHILD_BUTTON ||
1104              child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
1105              child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
1106            gtk_button_set_relief (GTK_BUTTON (child->widget), relief);
1107        }
1108     
1109      gtk_widget_queue_resize (GTK_WIDGET (toolbar));
1110    }
1111}
1112
1113GtkReliefStyle
1114gtk_toolbar_get_button_relief (GtkToolbar *toolbar)
1115{
1116  g_return_val_if_fail (toolbar != NULL, GTK_RELIEF_NORMAL);
1117  g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_RELIEF_NORMAL);
1118
1119  return toolbar->relief;
1120}
1121
1122static void
1123gtk_real_toolbar_orientation_changed (GtkToolbar     *toolbar,
1124                                      GtkOrientation  orientation)
1125{
1126  g_return_if_fail (toolbar != NULL);
1127  g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1128
1129  if (toolbar->orientation != orientation)
1130    {
1131      toolbar->orientation = orientation;
1132      gtk_widget_queue_resize (GTK_WIDGET (toolbar));
1133    }
1134}
1135
1136static void
1137gtk_real_toolbar_style_changed (GtkToolbar      *toolbar,
1138                                GtkToolbarStyle  style)
1139{
1140  GList *children;
1141  GtkToolbarChild *child;
1142
1143  g_return_if_fail (toolbar != NULL);
1144  g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
1145
1146  if (toolbar->style != style)
1147    {
1148      toolbar->style = style;
1149
1150      for (children = toolbar->children; children; children = children->next)
1151        {
1152          child = children->data;
1153
1154          if (child->type == GTK_TOOLBAR_CHILD_BUTTON ||
1155              child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
1156              child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
1157            switch (style)
1158              {
1159              case GTK_TOOLBAR_ICONS:
1160                if (child->icon && !GTK_WIDGET_VISIBLE (child->icon))
1161                  gtk_widget_show (child->icon);
1162
1163                if (child->label && GTK_WIDGET_VISIBLE (child->label))
1164                  gtk_widget_hide (child->label);
1165
1166                break;
1167
1168              case GTK_TOOLBAR_TEXT:
1169                if (child->icon && GTK_WIDGET_VISIBLE (child->icon))
1170                  gtk_widget_hide (child->icon);
1171
1172                if (child->label && !GTK_WIDGET_VISIBLE (child->label))
1173                  gtk_widget_show (child->label);
1174
1175                break;
1176
1177              case GTK_TOOLBAR_BOTH:
1178                if (child->icon && !GTK_WIDGET_VISIBLE (child->icon))
1179                  gtk_widget_show (child->icon);
1180
1181                if (child->label && !GTK_WIDGET_VISIBLE (child->label))
1182                  gtk_widget_show (child->label);
1183
1184                break;
1185
1186              default:
1187                g_assert_not_reached ();
1188              }
1189        }
1190               
1191      gtk_widget_queue_resize (GTK_WIDGET (toolbar));
1192    }
1193}
Note: See TracBrowser for help on using the repository browser.