]> Pileus Git - ~andy/gtk/blob - gtk/gtkbin.c
boy! did i really modify that many 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 static GtkType gtk_bin_child_type (GtkContainer*container);
38
39
40 static GtkContainerClass *parent_class = NULL;
41
42
43 guint
44 gtk_bin_get_type (void)
45 {
46   static guint bin_type = 0;
47
48   if (!bin_type)
49     {
50       GtkTypeInfo bin_info =
51       {
52         "GtkBin",
53         sizeof (GtkBin),
54         sizeof (GtkBinClass),
55         (GtkClassInitFunc) gtk_bin_class_init,
56         (GtkObjectInitFunc) gtk_bin_init,
57         (GtkArgSetFunc) NULL,
58         (GtkArgGetFunc) NULL,
59       };
60
61       bin_type = gtk_type_unique (gtk_container_get_type (), &bin_info);
62     }
63
64   return bin_type;
65 }
66
67 static void
68 gtk_bin_class_init (GtkBinClass *class)
69 {
70   GtkObjectClass *object_class;
71   GtkWidgetClass *widget_class;
72   GtkContainerClass *container_class;
73
74   object_class = (GtkObjectClass*) class;
75   widget_class = (GtkWidgetClass*) class;
76   container_class = (GtkContainerClass*) class;
77
78   parent_class = gtk_type_class (gtk_container_get_type ());
79
80   widget_class->map = gtk_bin_map;
81   widget_class->unmap = gtk_bin_unmap;
82   widget_class->draw = gtk_bin_draw;
83   widget_class->expose_event = gtk_bin_expose;
84
85   container_class->add = gtk_bin_add;
86   container_class->remove = gtk_bin_remove;
87   container_class->foreach = gtk_bin_foreach;
88   container_class->child_type = gtk_bin_child_type;
89 }
90
91 static void
92 gtk_bin_init (GtkBin *bin)
93 {
94   GTK_WIDGET_SET_FLAGS (bin, GTK_NO_WINDOW);
95
96   bin->child = NULL;
97 }
98
99
100 static GtkType
101 gtk_bin_child_type (GtkContainer *container)
102 {
103   if (!GTK_BIN (container)->child)
104     return GTK_TYPE_WIDGET;
105   else
106     return GTK_TYPE_NONE;
107 }
108
109 static void
110 gtk_bin_map (GtkWidget *widget)
111 {
112   GtkBin *bin;
113
114   g_return_if_fail (widget != NULL);
115   g_return_if_fail (GTK_IS_BIN (widget));
116
117   GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
118   bin = GTK_BIN (widget);
119
120   if (!GTK_WIDGET_NO_WINDOW (widget))
121     gdk_window_show (widget->window);
122   else
123     gtk_widget_queue_draw (widget);
124
125   if (bin->child &&
126       GTK_WIDGET_VISIBLE (bin->child) &&
127       !GTK_WIDGET_MAPPED (bin->child))
128     gtk_widget_map (bin->child);
129 }
130
131 static void
132 gtk_bin_unmap (GtkWidget *widget)
133 {
134   GtkBin *bin;
135
136   g_return_if_fail (widget != NULL);
137   g_return_if_fail (GTK_IS_BIN (widget));
138
139   GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
140   bin = GTK_BIN (widget);
141
142   if (GTK_WIDGET_NO_WINDOW (widget))
143     gdk_window_clear_area (widget->window,
144                            widget->allocation.x,
145                            widget->allocation.y,
146                            widget->allocation.width,
147                            widget->allocation.height);
148   else
149     gdk_window_hide (widget->window);
150
151   if (bin->child &&
152       GTK_WIDGET_VISIBLE (bin->child) &&
153       GTK_WIDGET_MAPPED (bin->child))
154     gtk_widget_unmap (bin->child);
155 }
156
157 static void
158 gtk_bin_draw (GtkWidget    *widget,
159               GdkRectangle *area)
160 {
161   GtkBin *bin;
162   GdkRectangle child_area;
163
164   g_return_if_fail (widget != NULL);
165   g_return_if_fail (GTK_IS_BIN (widget));
166
167   if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget))
168     {
169       bin = GTK_BIN (widget);
170
171       if (bin->child &&
172           gtk_widget_intersect (bin->child, area, &child_area))
173         gtk_widget_draw (bin->child, &child_area);
174     }
175 }
176
177 static gint
178 gtk_bin_expose (GtkWidget      *widget,
179                 GdkEventExpose *event)
180 {
181   GtkBin *bin;
182   GdkEventExpose child_event;
183
184   g_return_val_if_fail (widget != NULL, FALSE);
185   g_return_val_if_fail (GTK_IS_BIN (widget), FALSE);
186   g_return_val_if_fail (event != NULL, FALSE);
187
188   if (GTK_WIDGET_DRAWABLE (widget))
189     {
190       bin = GTK_BIN (widget);
191
192       child_event = *event;
193       if (bin->child &&
194           GTK_WIDGET_NO_WINDOW (bin->child) &&
195           gtk_widget_intersect (bin->child, &event->area, &child_event.area))
196         gtk_widget_event (bin->child, (GdkEvent*) &child_event);
197     }
198
199   return FALSE;
200 }
201
202
203 static void
204 gtk_bin_add (GtkContainer *container,
205              GtkWidget    *widget)
206 {
207   GtkBin *bin;
208
209   g_return_if_fail (container != NULL);
210   g_return_if_fail (GTK_IS_BIN (container));
211   g_return_if_fail (widget != NULL);
212
213   bin = GTK_BIN (container);
214   g_return_if_fail (bin->child == NULL);
215
216   gtk_widget_set_parent (widget, GTK_WIDGET (container));
217   
218   if (GTK_WIDGET_VISIBLE (widget->parent))
219     {
220       if (GTK_WIDGET_REALIZED (widget->parent) &&
221           !GTK_WIDGET_REALIZED (widget))
222         gtk_widget_realize (widget);
223       
224       if (GTK_WIDGET_MAPPED (widget->parent) &&
225           !GTK_WIDGET_MAPPED (widget))
226         gtk_widget_map (widget);
227     }
228   
229   bin->child = widget;
230   
231   if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
232     gtk_widget_queue_resize (widget);
233 }
234
235 static void
236 gtk_bin_remove (GtkContainer *container,
237                 GtkWidget    *widget)
238 {
239   GtkBin *bin;
240
241   g_return_if_fail (container != NULL);
242   g_return_if_fail (GTK_IS_BIN (container));
243   g_return_if_fail (widget != NULL);
244
245   bin = GTK_BIN (container);
246
247   if (bin->child == widget)
248     {
249       gboolean widget_was_visible = GTK_WIDGET_VISIBLE (widget);
250
251       gtk_widget_unparent (widget);
252       bin->child = NULL;
253
254       if (widget_was_visible && GTK_WIDGET_VISIBLE (container))
255         gtk_widget_queue_resize (GTK_WIDGET (container));
256     }
257 }
258
259 static void
260 gtk_bin_foreach (GtkContainer *container,
261                  GtkCallback   callback,
262                  gpointer      callback_data)
263 {
264   GtkBin *bin;
265
266   g_return_if_fail (container != NULL);
267   g_return_if_fail (GTK_IS_BIN (container));
268   g_return_if_fail (callback != NULL);
269
270   bin = GTK_BIN (container);
271
272   if (bin->child)
273     (* callback) (bin->child, callback_data);
274 }