]> Pileus Git - ~andy/gtk/blob - gtk/gtkfixed.c
Patch from Matthias Clasen to remove remove all instances of
[~andy/gtk] / gtk / gtkfixed.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 Lesser 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  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser 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
20 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include "gtkfixed.h"
28
29
30 static void gtk_fixed_class_init    (GtkFixedClass    *klass);
31 static void gtk_fixed_init          (GtkFixed         *fixed);
32 static void gtk_fixed_map           (GtkWidget        *widget);
33 static void gtk_fixed_realize       (GtkWidget        *widget);
34 static void gtk_fixed_size_request  (GtkWidget        *widget,
35                                      GtkRequisition   *requisition);
36 static void gtk_fixed_size_allocate (GtkWidget        *widget,
37                                      GtkAllocation    *allocation);
38 static void gtk_fixed_add           (GtkContainer     *container,
39                                      GtkWidget        *widget);
40 static void gtk_fixed_remove        (GtkContainer     *container,
41                                      GtkWidget        *widget);
42 static void gtk_fixed_forall        (GtkContainer     *container,
43                                      gboolean          include_internals,
44                                      GtkCallback       callback,
45                                      gpointer          callback_data);
46 static GtkType gtk_fixed_child_type (GtkContainer     *container);
47
48
49 static GtkContainerClass *parent_class = NULL;
50
51
52 GtkType
53 gtk_fixed_get_type (void)
54 {
55   static GtkType fixed_type = 0;
56
57   if (!fixed_type)
58     {
59       static const GtkTypeInfo fixed_info =
60       {
61         "GtkFixed",
62         sizeof (GtkFixed),
63         sizeof (GtkFixedClass),
64         (GtkClassInitFunc) gtk_fixed_class_init,
65         (GtkObjectInitFunc) gtk_fixed_init,
66         /* reserved_1 */ NULL,
67         /* reserved_2 */ NULL,
68         (GtkClassInitFunc) NULL,
69       };
70
71       fixed_type = gtk_type_unique (GTK_TYPE_CONTAINER, &fixed_info);
72     }
73
74   return fixed_type;
75 }
76
77 static void
78 gtk_fixed_class_init (GtkFixedClass *class)
79 {
80   GtkObjectClass *object_class;
81   GtkWidgetClass *widget_class;
82   GtkContainerClass *container_class;
83
84   object_class = (GtkObjectClass*) class;
85   widget_class = (GtkWidgetClass*) class;
86   container_class = (GtkContainerClass*) class;
87
88   parent_class = gtk_type_class (GTK_TYPE_CONTAINER);
89
90   widget_class->map = gtk_fixed_map;
91   widget_class->realize = gtk_fixed_realize;
92   widget_class->size_request = gtk_fixed_size_request;
93   widget_class->size_allocate = gtk_fixed_size_allocate;
94
95   container_class->add = gtk_fixed_add;
96   container_class->remove = gtk_fixed_remove;
97   container_class->forall = gtk_fixed_forall;
98   container_class->child_type = gtk_fixed_child_type;
99 }
100
101 static GtkType
102 gtk_fixed_child_type (GtkContainer     *container)
103 {
104   return GTK_TYPE_WIDGET;
105 }
106
107 static void
108 gtk_fixed_init (GtkFixed *fixed)
109 {
110   GTK_WIDGET_UNSET_FLAGS (fixed, GTK_NO_WINDOW);
111  
112   fixed->children = NULL;
113 }
114
115 GtkWidget*
116 gtk_fixed_new (void)
117 {
118   GtkFixed *fixed;
119
120   fixed = gtk_type_new (GTK_TYPE_FIXED);
121   return GTK_WIDGET (fixed);
122 }
123
124 void
125 gtk_fixed_put (GtkFixed       *fixed,
126                GtkWidget      *widget,
127                gint16         x,
128                gint16         y)
129 {
130   GtkFixedChild *child_info;
131
132   g_return_if_fail (GTK_IS_FIXED (fixed));
133   g_return_if_fail (widget != NULL);
134
135   child_info = g_new (GtkFixedChild, 1);
136   child_info->widget = widget;
137   child_info->x = x;
138   child_info->y = y;
139
140   gtk_widget_set_parent (widget, GTK_WIDGET (fixed));
141
142   fixed->children = g_list_append (fixed->children, child_info); 
143
144   if (GTK_WIDGET_REALIZED (fixed))
145     gtk_widget_realize (widget);
146
147   if (GTK_WIDGET_VISIBLE (fixed) && GTK_WIDGET_VISIBLE (widget))
148     {
149       if (GTK_WIDGET_MAPPED (fixed))
150         gtk_widget_map (widget);
151       
152       gtk_widget_queue_resize (GTK_WIDGET (fixed));
153     }
154 }
155
156 void
157 gtk_fixed_move (GtkFixed       *fixed,
158                 GtkWidget      *widget,
159                 gint16         x,
160                 gint16         y)
161 {
162   GtkFixedChild *child;
163   GList *children;
164
165   g_return_if_fail (GTK_IS_FIXED (fixed));
166   g_return_if_fail (widget != NULL);
167
168   children = fixed->children;
169   while (children)
170     {
171       child = children->data;
172       children = children->next;
173
174       if (child->widget == widget)
175         {
176           child->x = x;
177           child->y = y;
178
179           if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (fixed))
180             gtk_widget_queue_resize (GTK_WIDGET (fixed));
181
182           break;
183         }
184     }
185 }
186
187 static void
188 gtk_fixed_map (GtkWidget *widget)
189 {
190   GtkFixed *fixed;
191   GtkFixedChild *child;
192   GList *children;
193
194   g_return_if_fail (GTK_IS_FIXED (widget));
195
196   GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
197   fixed = GTK_FIXED (widget);
198
199   children = fixed->children;
200   while (children)
201     {
202       child = children->data;
203       children = children->next;
204
205       if (GTK_WIDGET_VISIBLE (child->widget) &&
206           !GTK_WIDGET_MAPPED (child->widget))
207         gtk_widget_map (child->widget);
208     }
209
210   gdk_window_show (widget->window);
211 }
212
213 static void
214 gtk_fixed_realize (GtkWidget *widget)
215 {
216   GdkWindowAttr attributes;
217   gint attributes_mask;
218
219   g_return_if_fail (GTK_IS_FIXED (widget));
220
221   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
222
223   attributes.window_type = GDK_WINDOW_CHILD;
224   attributes.x = widget->allocation.x;
225   attributes.y = widget->allocation.y;
226   attributes.width = widget->allocation.width;
227   attributes.height = widget->allocation.height;
228   attributes.wclass = GDK_INPUT_OUTPUT;
229   attributes.visual = gtk_widget_get_visual (widget);
230   attributes.colormap = gtk_widget_get_colormap (widget);
231   attributes.event_mask = gtk_widget_get_events (widget);
232   attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
233
234   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
235
236   widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, 
237                                    attributes_mask);
238   gdk_window_set_user_data (widget->window, widget);
239
240   widget->style = gtk_style_attach (widget->style, widget->window);
241   gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
242 }
243
244 static void
245 gtk_fixed_size_request (GtkWidget      *widget,
246                         GtkRequisition *requisition)
247 {
248   GtkFixed *fixed;  
249   GtkFixedChild *child;
250   GList *children;
251   GtkRequisition child_requisition;
252
253   g_return_if_fail (GTK_IS_FIXED (widget));
254   g_return_if_fail (requisition != NULL);
255
256   fixed = GTK_FIXED (widget);
257   requisition->width = 0;
258   requisition->height = 0;
259
260   children = fixed->children;
261   while (children)
262     {
263       child = children->data;
264       children = children->next;
265
266       if (GTK_WIDGET_VISIBLE (child->widget))
267         {
268           gtk_widget_size_request (child->widget, &child_requisition);
269
270           requisition->height = MAX (requisition->height,
271                                      child->y +
272                                      child_requisition.height);
273           requisition->width = MAX (requisition->width,
274                                     child->x +
275                                     child_requisition.width);
276         }
277     }
278
279   requisition->height += GTK_CONTAINER (fixed)->border_width * 2;
280   requisition->width += GTK_CONTAINER (fixed)->border_width * 2;
281 }
282
283 static void
284 gtk_fixed_size_allocate (GtkWidget     *widget,
285                          GtkAllocation *allocation)
286 {
287   GtkFixed *fixed;
288   GtkFixedChild *child;
289   GtkAllocation child_allocation;
290   GtkRequisition child_requisition;
291   GList *children;
292   guint16 border_width;
293
294   g_return_if_fail (GTK_IS_FIXED(widget));
295   g_return_if_fail (allocation != NULL);
296
297   fixed = GTK_FIXED (widget);
298
299   widget->allocation = *allocation;
300   if (GTK_WIDGET_REALIZED (widget))
301     gdk_window_move_resize (widget->window,
302                             allocation->x, 
303                             allocation->y,
304                             allocation->width, 
305                             allocation->height);
306
307   border_width = GTK_CONTAINER (fixed)->border_width;
308   
309   children = fixed->children;
310   while (children)
311     {
312       child = children->data;
313       children = children->next;
314       
315       if (GTK_WIDGET_VISIBLE (child->widget))
316         {
317           gtk_widget_get_child_requisition (child->widget, &child_requisition);
318           child_allocation.x = child->x + border_width;
319           child_allocation.y = child->y + border_width;
320           child_allocation.width = child_requisition.width;
321           child_allocation.height = child_requisition.height;
322           gtk_widget_size_allocate (child->widget, &child_allocation);
323         }
324     }
325 }
326
327 static void
328 gtk_fixed_add (GtkContainer *container,
329                GtkWidget    *widget)
330 {
331   g_return_if_fail (GTK_IS_FIXED (container));
332   g_return_if_fail (widget != NULL);
333
334   gtk_fixed_put (GTK_FIXED (container), widget, 0, 0);
335 }
336
337 static void
338 gtk_fixed_remove (GtkContainer *container,
339                   GtkWidget    *widget)
340 {
341   GtkFixed *fixed;
342   GtkFixedChild *child;
343   GList *children;
344
345   g_return_if_fail (GTK_IS_FIXED (container));
346   g_return_if_fail (widget != NULL);
347
348   fixed = GTK_FIXED (container);
349
350   children = fixed->children;
351   while (children)
352     {
353       child = children->data;
354
355       if (child->widget == widget)
356         {
357           gboolean was_visible = GTK_WIDGET_VISIBLE (widget);
358           
359           gtk_widget_unparent (widget);
360
361           fixed->children = g_list_remove_link (fixed->children, children);
362           g_list_free (children);
363           g_free (child);
364
365           if (was_visible && GTK_WIDGET_VISIBLE (container))
366             gtk_widget_queue_resize (GTK_WIDGET (container));
367
368           break;
369         }
370
371       children = children->next;
372     }
373 }
374
375 static void
376 gtk_fixed_forall (GtkContainer *container,
377                   gboolean      include_internals,
378                   GtkCallback   callback,
379                   gpointer      callback_data)
380 {
381   GtkFixed *fixed;
382   GtkFixedChild *child;
383   GList *children;
384
385   g_return_if_fail (GTK_IS_FIXED (container));
386   g_return_if_fail (callback != NULL);
387
388   fixed = GTK_FIXED (container);
389
390   children = fixed->children;
391   while (children)
392     {
393       child = children->data;
394       children = children->next;
395
396       (* callback) (child->widget, callback_data);
397     }
398 }