1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
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.
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.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 static void gtk_fixed_class_init (GtkFixedClass *klass);
22 static void gtk_fixed_init (GtkFixed *fixed);
23 static void gtk_fixed_destroy (GtkObject *object);
24 static void gtk_fixed_map (GtkWidget *widget);
25 static void gtk_fixed_unmap (GtkWidget *widget);
26 static void gtk_fixed_realize (GtkWidget *widget);
27 static void gtk_fixed_unrealize (GtkWidget *widget);
28 static void gtk_fixed_size_request (GtkWidget *widget,
29 GtkRequisition *requisition);
30 static void gtk_fixed_size_allocate (GtkWidget *widget,
31 GtkAllocation *allocation);
32 static void gtk_fixed_paint (GtkWidget *widget,
34 static void gtk_fixed_draw (GtkWidget *widget,
36 static gint gtk_fixed_expose (GtkWidget *widget,
37 GdkEventExpose *event);
38 static void gtk_fixed_add (GtkContainer *container,
40 static void gtk_fixed_remove (GtkContainer *container,
42 static void gtk_fixed_foreach (GtkContainer *container,
44 gpointer callback_data);
47 static GtkContainerClass *parent_class = NULL;
53 static guint fixed_type = 0;
57 GtkTypeInfo fixed_info =
61 sizeof (GtkFixedClass),
62 (GtkClassInitFunc) gtk_fixed_class_init,
63 (GtkObjectInitFunc) gtk_fixed_init,
68 fixed_type = gtk_type_unique (gtk_container_get_type (), &fixed_info);
75 gtk_fixed_class_init (GtkFixedClass *class)
77 GtkObjectClass *object_class;
78 GtkWidgetClass *widget_class;
79 GtkContainerClass *container_class;
81 object_class = (GtkObjectClass*) class;
82 widget_class = (GtkWidgetClass*) class;
83 container_class = (GtkContainerClass*) class;
85 parent_class = gtk_type_class (gtk_container_get_type ());
87 object_class->destroy = gtk_fixed_destroy;
89 widget_class->map = gtk_fixed_map;
90 widget_class->unmap = gtk_fixed_unmap;
91 widget_class->realize = gtk_fixed_realize;
92 widget_class->unrealize = gtk_fixed_unrealize;
93 widget_class->size_request = gtk_fixed_size_request;
94 widget_class->size_allocate = gtk_fixed_size_allocate;
95 widget_class->draw = gtk_fixed_draw;
96 widget_class->expose_event = gtk_fixed_expose;
98 container_class->add = gtk_fixed_add;
99 container_class->remove = gtk_fixed_remove;
100 container_class->foreach = gtk_fixed_foreach;
104 gtk_fixed_init (GtkFixed *fixed)
106 GTK_WIDGET_UNSET_FLAGS (fixed, GTK_NO_WINDOW);
107 GTK_WIDGET_SET_FLAGS (fixed, GTK_BASIC);
109 fixed->children = NULL;
117 fixed = gtk_type_new (gtk_fixed_get_type ());
118 return GTK_WIDGET (fixed);
122 gtk_fixed_put (GtkFixed *fixed,
127 GtkFixedChild *child_info;
129 g_return_if_fail (fixed != NULL);
130 g_return_if_fail (GTK_IS_FIXED (fixed));
131 g_return_if_fail (widget != NULL);
133 child_info = g_new (GtkFixedChild, 1);
134 child_info->widget = widget;
138 gtk_widget_set_parent (widget, GTK_WIDGET (fixed));
140 fixed->children = g_list_append (fixed->children, child_info);
142 if (GTK_WIDGET_REALIZED (fixed) && !GTK_WIDGET_REALIZED (widget))
143 gtk_widget_realize (widget);
145 if (GTK_WIDGET_MAPPED (fixed) && !GTK_WIDGET_MAPPED (widget))
146 gtk_widget_map (widget);
148 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (fixed))
149 gtk_widget_queue_resize (GTK_WIDGET (fixed));
153 gtk_fixed_move (GtkFixed *fixed,
158 GtkFixedChild *child;
161 g_return_if_fail (fixed != NULL);
162 g_return_if_fail (GTK_IS_FIXED (fixed));
163 g_return_if_fail (widget != NULL);
165 children = fixed->children;
168 child = children->data;
169 children = children->next;
171 if (child->widget == widget)
176 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (fixed))
177 gtk_widget_queue_resize (GTK_WIDGET (fixed));
185 gtk_fixed_destroy (GtkObject *object)
188 GtkFixedChild *child;
191 g_return_if_fail (object != NULL);
192 g_return_if_fail (GTK_IS_FIXED (object));
194 fixed = GTK_FIXED (object);
196 children = fixed->children;
199 child = children->data;
200 children = children->next;
202 child->widget->parent = NULL;
203 gtk_object_unref (GTK_OBJECT (child->widget));
204 gtk_widget_destroy (child->widget);
208 g_list_free (fixed->children);
210 if (GTK_OBJECT_CLASS (parent_class)->destroy)
211 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
215 gtk_fixed_map (GtkWidget *widget)
218 GtkFixedChild *child;
221 g_return_if_fail (widget != NULL);
222 g_return_if_fail (GTK_IS_FIXED (widget));
224 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
225 fixed = GTK_FIXED (widget);
227 gdk_window_show (widget->window);
229 children = fixed->children;
232 child = children->data;
233 children = children->next;
235 if (GTK_WIDGET_VISIBLE (child->widget) &&
236 !GTK_WIDGET_MAPPED (child->widget))
237 gtk_widget_map (child->widget);
242 gtk_fixed_unmap (GtkWidget *widget)
244 g_return_if_fail (widget != NULL);
245 g_return_if_fail (GTK_IS_FIXED (widget));
247 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
251 gtk_fixed_realize (GtkWidget *widget)
253 GdkWindowAttr attributes;
254 gint attributes_mask;
256 g_return_if_fail (widget != NULL);
257 g_return_if_fail (GTK_IS_FIXED (widget));
259 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
261 attributes.window_type = GDK_WINDOW_CHILD;
262 attributes.x = widget->allocation.x;
263 attributes.y = widget->allocation.y;
264 attributes.width = widget->allocation.width;
265 attributes.height = widget->allocation.height;
266 attributes.wclass = GDK_INPUT_OUTPUT;
267 attributes.visual = gtk_widget_get_visual (widget);
268 attributes.colormap = gtk_widget_get_colormap (widget);
269 attributes.event_mask = gtk_widget_get_events (widget);
270 attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
272 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
274 widget->window = gdk_window_new (widget->parent->window, &attributes,
276 gdk_window_set_user_data (widget->window, widget);
278 widget->style = gtk_style_attach (widget->style, widget->window);
279 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
283 gtk_fixed_unrealize (GtkWidget *widget)
285 g_return_if_fail (widget != NULL);
286 g_return_if_fail (GTK_IS_FIXED (widget));
288 GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED | GTK_MAPPED);
290 gtk_style_detach (widget->style);
291 gdk_window_destroy (widget->window);
292 widget->window = NULL;
296 gtk_fixed_size_request (GtkWidget *widget,
297 GtkRequisition *requisition)
300 GtkFixedChild *child;
303 g_return_if_fail (widget != NULL);
304 g_return_if_fail (GTK_IS_FIXED (widget));
305 g_return_if_fail (requisition != NULL);
307 fixed = GTK_FIXED (widget);
308 requisition->width = 0;
309 requisition->height = 0;
311 children = fixed->children;
314 child = children->data;
315 children = children->next;
317 if (GTK_WIDGET_VISIBLE (child->widget))
319 gtk_widget_size_request (child->widget, &child->widget->requisition);
321 requisition->height = MAX (requisition->height,
323 child->widget->requisition.height);
324 requisition->width = MAX (requisition->width,
326 child->widget->requisition.width);
330 requisition->height += GTK_CONTAINER (fixed)->border_width * 2;
331 requisition->width += GTK_CONTAINER (fixed)->border_width * 2;
335 gtk_fixed_size_allocate (GtkWidget *widget,
336 GtkAllocation *allocation)
339 GtkFixedChild *child;
340 GtkAllocation child_allocation;
342 guint16 border_width;
344 g_return_if_fail (widget != NULL);
345 g_return_if_fail (GTK_IS_FIXED(widget));
346 g_return_if_fail (allocation != NULL);
348 fixed = GTK_FIXED (widget);
350 widget->allocation = *allocation;
351 if (GTK_WIDGET_REALIZED (widget))
352 gdk_window_move_resize (widget->window,
358 border_width = GTK_CONTAINER (fixed)->border_width;
360 children = fixed->children;
363 child = children->data;
364 children = children->next;
366 if (GTK_WIDGET_VISIBLE (child->widget))
368 child_allocation.x = child->x + border_width;
369 child_allocation.y = child->y + border_width;
370 child_allocation.width = child->widget->requisition.width;
371 child_allocation.height = child->widget->requisition.height;
372 gtk_widget_size_allocate (child->widget, &child_allocation);
378 gtk_fixed_paint (GtkWidget *widget,
381 g_return_if_fail (widget != NULL);
382 g_return_if_fail (GTK_IS_FIXED (widget));
383 g_return_if_fail (area != NULL);
385 if (GTK_WIDGET_DRAWABLE (widget))
386 gdk_window_clear_area (widget->window,
388 area->width, area->height);
392 gtk_fixed_draw (GtkWidget *widget,
396 GtkFixedChild *child;
397 GdkRectangle child_area;
400 g_return_if_fail (widget != NULL);
401 g_return_if_fail (GTK_IS_FIXED (widget));
403 if (GTK_WIDGET_DRAWABLE (widget))
405 fixed = GTK_FIXED (widget);
406 gtk_fixed_paint (widget, area);
408 children = fixed->children;
411 child = children->data;
412 children = children->next;
414 if (gtk_widget_intersect (child->widget, area, &child_area))
415 gtk_widget_draw (child->widget, &child_area);
421 gtk_fixed_expose (GtkWidget *widget,
422 GdkEventExpose *event)
425 GtkFixedChild *child;
426 GdkEventExpose child_event;
429 g_return_val_if_fail (widget != NULL, FALSE);
430 g_return_val_if_fail (GTK_IS_FIXED (widget), FALSE);
431 g_return_val_if_fail (event != NULL, FALSE);
433 if (GTK_WIDGET_DRAWABLE (widget))
435 fixed = GTK_FIXED (widget);
437 child_event = *event;
439 children = fixed->children;
442 child = children->data;
443 children = children->next;
445 if (GTK_WIDGET_NO_WINDOW (child->widget) &&
446 gtk_widget_intersect (child->widget, &event->area,
448 gtk_widget_event (child->widget, (GdkEvent*) &child_event);
456 gtk_fixed_add (GtkContainer *container,
459 g_return_if_fail (container != NULL);
460 g_return_if_fail (GTK_IS_FIXED (container));
461 g_return_if_fail (widget != NULL);
463 gtk_fixed_put (GTK_FIXED (container), widget, 0, 0);
467 gtk_fixed_remove (GtkContainer *container,
471 GtkFixedChild *child;
474 g_return_if_fail (container != NULL);
475 g_return_if_fail (GTK_IS_FIXED (container));
476 g_return_if_fail (widget != NULL);
478 fixed = GTK_FIXED (container);
480 children = fixed->children;
483 child = children->data;
485 if (child->widget == widget)
487 gtk_widget_unparent (widget);
489 fixed->children = g_list_remove_link (fixed->children, children);
490 g_list_free (children);
493 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
494 gtk_widget_queue_resize (GTK_WIDGET (container));
499 children = children->next;
504 gtk_fixed_foreach (GtkContainer *container,
505 GtkCallback callback,
506 gpointer callback_data)
509 GtkFixedChild *child;
512 g_return_if_fail (container != NULL);
513 g_return_if_fail (GTK_IS_FIXED (container));
514 g_return_if_fail (callback != NULL);
516 fixed = GTK_FIXED (container);
518 children = fixed->children;
521 child = children->data;
522 children = children->next;
524 (* callback) (child->widget, callback_data);