]> Pileus Git - ~andy/gtk/blob - gtk/gtkbin.c
Changed LGPL address for FSF in all .h and .c files
[~andy/gtk] / gtk / gtkbin.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 #include "gtkbin.h"
20
21
22 static void gtk_bin_class_init (GtkBinClass    *klass);
23 static void gtk_bin_init       (GtkBin         *bin);
24 static void gtk_bin_map        (GtkWidget      *widget);
25 static void gtk_bin_unmap      (GtkWidget      *widget);
26 static void gtk_bin_draw       (GtkWidget      *widget,
27                                 GdkRectangle   *area);
28 static gint gtk_bin_expose     (GtkWidget      *widget,
29                                 GdkEventExpose *event);
30 static void gtk_bin_add        (GtkContainer   *container,
31                                 GtkWidget      *widget);
32 static void gtk_bin_remove     (GtkContainer   *container,
33                                 GtkWidget      *widget);
34 static void gtk_bin_foreach    (GtkContainer   *container,
35                                 GtkCallback     callback,
36                                 gpointer        callback_data);
37
38
39 static GtkContainerClass *parent_class = NULL;
40
41
42 guint
43 gtk_bin_get_type ()
44 {
45   static guint bin_type = 0;
46
47   if (!bin_type)
48     {
49       GtkTypeInfo bin_info =
50       {
51         "GtkBin",
52         sizeof (GtkBin),
53         sizeof (GtkBinClass),
54         (GtkClassInitFunc) gtk_bin_class_init,
55         (GtkObjectInitFunc) gtk_bin_init,
56         (GtkArgSetFunc) NULL,
57         (GtkArgGetFunc) NULL,
58       };
59
60       bin_type = gtk_type_unique (gtk_container_get_type (), &bin_info);
61     }
62
63   return bin_type;
64 }
65
66 static void
67 gtk_bin_class_init (GtkBinClass *class)
68 {
69   GtkObjectClass *object_class;
70   GtkWidgetClass *widget_class;
71   GtkContainerClass *container_class;
72
73   object_class = (GtkObjectClass*) class;
74   widget_class = (GtkWidgetClass*) class;
75   container_class = (GtkContainerClass*) class;
76
77   parent_class = gtk_type_class (gtk_container_get_type ());
78
79   widget_class->map = gtk_bin_map;
80   widget_class->unmap = gtk_bin_unmap;
81   widget_class->draw = gtk_bin_draw;
82   widget_class->expose_event = gtk_bin_expose;
83
84   container_class->add = gtk_bin_add;
85   container_class->remove = gtk_bin_remove;
86   container_class->foreach = gtk_bin_foreach;
87 }
88
89 static void
90 gtk_bin_init (GtkBin *bin)
91 {
92   GTK_WIDGET_SET_FLAGS (bin, GTK_NO_WINDOW);
93
94   bin->child = NULL;
95 }
96
97
98 static void
99 gtk_bin_map (GtkWidget *widget)
100 {
101   GtkBin *bin;
102
103   g_return_if_fail (widget != NULL);
104   g_return_if_fail (GTK_IS_BIN (widget));
105
106   GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
107   bin = GTK_BIN (widget);
108
109   if (!GTK_WIDGET_NO_WINDOW (widget))
110     gdk_window_show (widget->window);
111   else
112     gtk_widget_queue_draw (widget);
113
114   if (bin->child &&
115       GTK_WIDGET_VISIBLE (bin->child) &&
116       !GTK_WIDGET_MAPPED (bin->child))
117     gtk_widget_map (bin->child);
118 }
119
120 static void
121 gtk_bin_unmap (GtkWidget *widget)
122 {
123   GtkBin *bin;
124
125   g_return_if_fail (widget != NULL);
126   g_return_if_fail (GTK_IS_BIN (widget));
127
128   GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
129   bin = GTK_BIN (widget);
130
131   if (GTK_WIDGET_NO_WINDOW (widget))
132     gdk_window_clear_area (widget->window,
133                            widget->allocation.x,
134                            widget->allocation.y,
135                            widget->allocation.width,
136                            widget->allocation.height);
137   else
138     gdk_window_hide (widget->window);
139
140   if (bin->child &&
141       GTK_WIDGET_VISIBLE (bin->child) &&
142       GTK_WIDGET_MAPPED (bin->child))
143     gtk_widget_unmap (bin->child);
144 }
145
146 static void
147 gtk_bin_draw (GtkWidget    *widget,
148               GdkRectangle *area)
149 {
150   GtkBin *bin;
151   GdkRectangle child_area;
152
153   g_return_if_fail (widget != NULL);
154   g_return_if_fail (GTK_IS_BIN (widget));
155
156   if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget))
157     {
158       bin = GTK_BIN (widget);
159
160       if (bin->child &&
161           gtk_widget_intersect (bin->child, area, &child_area))
162         gtk_widget_draw (bin->child, &child_area);
163     }
164 }
165
166 static gint
167 gtk_bin_expose (GtkWidget      *widget,
168                 GdkEventExpose *event)
169 {
170   GtkBin *bin;
171   GdkEventExpose child_event;
172
173   g_return_val_if_fail (widget != NULL, FALSE);
174   g_return_val_if_fail (GTK_IS_BIN (widget), FALSE);
175   g_return_val_if_fail (event != NULL, FALSE);
176
177   if (GTK_WIDGET_DRAWABLE (widget))
178     {
179       bin = GTK_BIN (widget);
180
181       child_event = *event;
182       if (bin->child &&
183           GTK_WIDGET_NO_WINDOW (bin->child) &&
184           gtk_widget_intersect (bin->child, &event->area, &child_event.area))
185         gtk_widget_event (bin->child, (GdkEvent*) &child_event);
186     }
187
188   return FALSE;
189 }
190
191
192 static void
193 gtk_bin_add (GtkContainer *container,
194              GtkWidget    *widget)
195 {
196   GtkBin *bin;
197
198   g_return_if_fail (container != NULL);
199   g_return_if_fail (GTK_IS_BIN (container));
200   g_return_if_fail (widget != NULL);
201
202   bin = GTK_BIN (container);
203
204   if (!bin->child)
205     {
206       gtk_widget_set_parent (widget, GTK_WIDGET (container));
207
208       if (GTK_WIDGET_VISIBLE (widget->parent))
209         {
210           if (GTK_WIDGET_REALIZED (widget->parent) &&
211               !GTK_WIDGET_REALIZED (widget))
212             gtk_widget_realize (widget);
213           
214           if (GTK_WIDGET_MAPPED (widget->parent) &&
215               !GTK_WIDGET_MAPPED (widget))
216             gtk_widget_map (widget);
217         }
218
219       bin->child = widget;
220
221       if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
222         gtk_widget_queue_resize (widget);
223     }
224 }
225
226 static void
227 gtk_bin_remove (GtkContainer *container,
228                 GtkWidget    *widget)
229 {
230   GtkBin *bin;
231
232   g_return_if_fail (container != NULL);
233   g_return_if_fail (GTK_IS_BIN (container));
234   g_return_if_fail (widget != NULL);
235
236   bin = GTK_BIN (container);
237
238   if (bin->child == widget)
239     {
240       gtk_widget_unparent (widget);
241       bin->child = NULL;
242
243       if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
244         gtk_widget_queue_resize (GTK_WIDGET (container));
245     }
246 }
247
248 static void
249 gtk_bin_foreach (GtkContainer *container,
250                  GtkCallback   callback,
251                  gpointer      callback_data)
252 {
253   GtkBin *bin;
254
255   g_return_if_fail (container != NULL);
256   g_return_if_fail (GTK_IS_BIN (container));
257   g_return_if_fail (callback != NULL);
258
259   bin = GTK_BIN (container);
260
261   if (bin->child)
262     (* callback) (bin->child, callback_data);
263 }