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,
67 fixed_type = gtk_type_unique (gtk_container_get_type (), &fixed_info);
74 gtk_fixed_class_init (GtkFixedClass *class)
76 GtkObjectClass *object_class;
77 GtkWidgetClass *widget_class;
78 GtkContainerClass *container_class;
80 object_class = (GtkObjectClass*) class;
81 widget_class = (GtkWidgetClass*) class;
82 container_class = (GtkContainerClass*) class;
84 parent_class = gtk_type_class (gtk_container_get_type ());
86 object_class->destroy = gtk_fixed_destroy;
88 widget_class->map = gtk_fixed_map;
89 widget_class->unmap = gtk_fixed_unmap;
90 widget_class->realize = gtk_fixed_realize;
91 widget_class->unrealize = gtk_fixed_unrealize;
92 widget_class->size_request = gtk_fixed_size_request;
93 widget_class->size_allocate = gtk_fixed_size_allocate;
94 widget_class->draw = gtk_fixed_draw;
95 widget_class->expose_event = gtk_fixed_expose;
97 container_class->add = gtk_fixed_add;
98 container_class->remove = gtk_fixed_remove;
99 container_class->foreach = gtk_fixed_foreach;
103 gtk_fixed_init (GtkFixed *fixed)
105 GTK_WIDGET_UNSET_FLAGS (fixed, GTK_NO_WINDOW);
106 GTK_WIDGET_SET_FLAGS (fixed, GTK_BASIC);
108 fixed->children = NULL;
116 fixed = gtk_type_new (gtk_fixed_get_type ());
117 return GTK_WIDGET (fixed);
121 gtk_fixed_put (GtkFixed *fixed,
126 GtkFixedChild *child_info;
128 g_return_if_fail (fixed != NULL);
129 g_return_if_fail (GTK_IS_FIXED (fixed));
130 g_return_if_fail (widget != NULL);
132 child_info = g_new (GtkFixedChild, 1);
133 child_info->widget = widget;
137 gtk_widget_set_parent (widget, GTK_WIDGET (fixed));
139 fixed->children = g_list_append (fixed->children, child_info);
141 if (GTK_WIDGET_REALIZED (fixed) && !GTK_WIDGET_REALIZED (widget))
142 gtk_widget_realize (widget);
144 if (GTK_WIDGET_MAPPED (fixed) && !GTK_WIDGET_MAPPED (widget))
145 gtk_widget_map (widget);
147 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (fixed))
148 gtk_widget_queue_resize (GTK_WIDGET (fixed));
152 gtk_fixed_move (GtkFixed *fixed,
157 GtkFixedChild *child;
160 g_return_if_fail (fixed != NULL);
161 g_return_if_fail (GTK_IS_FIXED (fixed));
162 g_return_if_fail (widget != NULL);
164 children = fixed->children;
167 child = children->data;
168 children = children->next;
170 if (child->widget == widget)
175 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (fixed))
176 gtk_widget_queue_resize (GTK_WIDGET (fixed));
184 gtk_fixed_destroy (GtkObject *object)
187 GtkFixedChild *child;
190 g_return_if_fail (object != NULL);
191 g_return_if_fail (GTK_IS_FIXED (object));
193 fixed = GTK_FIXED (object);
195 children = fixed->children;
198 child = children->data;
199 children = children->next;
201 child->widget->parent = NULL;
202 gtk_object_unref (GTK_OBJECT (child->widget));
203 gtk_widget_destroy (child->widget);
207 g_list_free (fixed->children);
209 if (GTK_OBJECT_CLASS (parent_class)->destroy)
210 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
214 gtk_fixed_map (GtkWidget *widget)
217 GtkFixedChild *child;
220 g_return_if_fail (widget != NULL);
221 g_return_if_fail (GTK_IS_FIXED (widget));
223 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
224 fixed = GTK_FIXED (widget);
226 gdk_window_show (widget->window);
228 children = fixed->children;
231 child = children->data;
232 children = children->next;
234 if (GTK_WIDGET_VISIBLE (child->widget) &&
235 !GTK_WIDGET_MAPPED (child->widget))
236 gtk_widget_map (child->widget);
241 gtk_fixed_unmap (GtkWidget *widget)
243 g_return_if_fail (widget != NULL);
244 g_return_if_fail (GTK_IS_FIXED (widget));
246 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
250 gtk_fixed_realize (GtkWidget *widget)
252 GdkWindowAttr attributes;
253 gint attributes_mask;
255 g_return_if_fail (widget != NULL);
256 g_return_if_fail (GTK_IS_FIXED (widget));
258 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
260 attributes.window_type = GDK_WINDOW_CHILD;
261 attributes.x = widget->allocation.x;
262 attributes.y = widget->allocation.y;
263 attributes.width = widget->allocation.width;
264 attributes.height = widget->allocation.height;
265 attributes.wclass = GDK_INPUT_OUTPUT;
266 attributes.visual = gtk_widget_get_visual (widget);
267 attributes.colormap = gtk_widget_get_colormap (widget);
268 attributes.event_mask = gtk_widget_get_events (widget);
269 attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
271 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
273 widget->window = gdk_window_new (widget->parent->window, &attributes,
275 gdk_window_set_user_data (widget->window, widget);
277 widget->style = gtk_style_attach (widget->style, widget->window);
278 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
282 gtk_fixed_unrealize (GtkWidget *widget)
284 g_return_if_fail (widget != NULL);
285 g_return_if_fail (GTK_IS_FIXED (widget));
287 GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED | GTK_MAPPED);
289 gtk_style_detach (widget->style);
290 gdk_window_destroy (widget->window);
291 widget->window = NULL;
295 gtk_fixed_size_request (GtkWidget *widget,
296 GtkRequisition *requisition)
299 GtkFixedChild *child;
302 g_return_if_fail (widget != NULL);
303 g_return_if_fail (GTK_IS_FIXED (widget));
304 g_return_if_fail (requisition != NULL);
306 fixed = GTK_FIXED (widget);
307 requisition->width = 0;
308 requisition->height = 0;
310 children = fixed->children;
313 child = children->data;
314 children = children->next;
316 if (GTK_WIDGET_VISIBLE (child->widget))
318 gtk_widget_size_request (child->widget, &child->widget->requisition);
320 requisition->height = MAX (requisition->height,
322 child->widget->requisition.height);
323 requisition->width = MAX (requisition->width,
325 child->widget->requisition.width);
329 requisition->height += GTK_CONTAINER (fixed)->border_width * 2;
330 requisition->width += GTK_CONTAINER (fixed)->border_width * 2;
334 gtk_fixed_size_allocate (GtkWidget *widget,
335 GtkAllocation *allocation)
338 GtkFixedChild *child;
339 GtkAllocation child_allocation;
341 guint16 border_width;
343 g_return_if_fail (widget != NULL);
344 g_return_if_fail (GTK_IS_FIXED(widget));
345 g_return_if_fail (allocation != NULL);
347 fixed = GTK_FIXED (widget);
349 widget->allocation = *allocation;
350 if (GTK_WIDGET_REALIZED (widget))
351 gdk_window_move_resize (widget->window,
357 border_width = GTK_CONTAINER (fixed)->border_width;
359 children = fixed->children;
362 child = children->data;
363 children = children->next;
365 if (GTK_WIDGET_VISIBLE (child->widget))
367 child_allocation.x = child->x + border_width;
368 child_allocation.y = child->y + border_width;
369 child_allocation.width = child->widget->requisition.width;
370 child_allocation.height = child->widget->requisition.height;
371 gtk_widget_size_allocate (child->widget, &child_allocation);
377 gtk_fixed_paint (GtkWidget *widget,
380 g_return_if_fail (widget != NULL);
381 g_return_if_fail (GTK_IS_FIXED (widget));
382 g_return_if_fail (area != NULL);
384 if (GTK_WIDGET_DRAWABLE (widget))
385 gdk_window_clear_area (widget->window,
387 area->width, area->height);
391 gtk_fixed_draw (GtkWidget *widget,
395 GtkFixedChild *child;
396 GdkRectangle child_area;
399 g_return_if_fail (widget != NULL);
400 g_return_if_fail (GTK_IS_FIXED (widget));
402 if (GTK_WIDGET_DRAWABLE (widget))
404 fixed = GTK_FIXED (widget);
405 gtk_fixed_paint (widget, area);
407 children = fixed->children;
410 child = children->data;
411 children = children->next;
413 if (gtk_widget_intersect (child->widget, area, &child_area))
414 gtk_widget_draw (child->widget, &child_area);
420 gtk_fixed_expose (GtkWidget *widget,
421 GdkEventExpose *event)
424 GtkFixedChild *child;
425 GdkEventExpose child_event;
428 g_return_val_if_fail (widget != NULL, FALSE);
429 g_return_val_if_fail (GTK_IS_FIXED (widget), FALSE);
430 g_return_val_if_fail (event != NULL, FALSE);
432 if (GTK_WIDGET_DRAWABLE (widget))
434 fixed = GTK_FIXED (widget);
436 child_event = *event;
438 children = fixed->children;
441 child = children->data;
442 children = children->next;
444 if (GTK_WIDGET_NO_WINDOW (child->widget) &&
445 gtk_widget_intersect (child->widget, &event->area,
447 gtk_widget_event (child->widget, (GdkEvent*) &child_event);
455 gtk_fixed_add (GtkContainer *container,
458 g_return_if_fail (container != NULL);
459 g_return_if_fail (GTK_IS_FIXED (container));
460 g_return_if_fail (widget != NULL);
462 gtk_fixed_put (GTK_FIXED (container), widget, 0, 0);
466 gtk_fixed_remove (GtkContainer *container,
470 GtkFixedChild *child;
473 g_return_if_fail (container != NULL);
474 g_return_if_fail (GTK_IS_FIXED (container));
475 g_return_if_fail (widget != NULL);
477 fixed = GTK_FIXED (container);
479 children = fixed->children;
482 child = children->data;
484 if (child->widget == widget)
486 gtk_widget_unparent (widget);
488 fixed->children = g_list_remove_link (fixed->children, children);
489 g_list_free (children);
492 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
493 gtk_widget_queue_resize (GTK_WIDGET (container));
498 children = children->next;
503 gtk_fixed_foreach (GtkContainer *container,
504 GtkCallback callback,
505 gpointer callback_data)
508 GtkFixedChild *child;
511 g_return_if_fail (container != NULL);
512 g_return_if_fail (GTK_IS_FIXED (container));
513 g_return_if_fail (callback != NULL);
515 fixed = GTK_FIXED (container);
517 children = fixed->children;
520 child = children->data;
521 children = children->next;
523 (* callback) (child->widget, callback_data);