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 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.
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.
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.
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/.
27 #include "diacanvas.h"
36 static void dia_canvas_class_init (DiaCanvasClass
*klass
);
37 static void dia_canvas_init (DiaCanvas
*canvas
);
38 static void dia_canvas_realize (GtkWidget
*widget
);
39 static void dia_canvas_size_request (GtkWidget
*widget
,
40 GtkRequisition
*requisition
);
41 static void dia_canvas_size_allocate (GtkWidget
*widget
,
42 GtkAllocation
*allocation
);
43 static void dia_canvas_add (GtkContainer
*container
,
45 static void dia_canvas_remove (GtkContainer
*container
,
47 static void dia_canvas_forall (GtkContainer
*container
,
48 gboolean include_internals
,
50 gpointer callback_data
);
51 static GType
dia_canvas_child_type (GtkContainer
*container
);
53 static void dia_canvas_set_child_property (GtkContainer
*container
,
58 static void dia_canvas_get_child_property (GtkContainer
*container
,
63 static void dia_canvas_send_configure (DiaCanvas
*darea
);
65 static GtkContainerClass
*parent_class
= NULL
;
69 dia_canvas_get_type (void)
71 static GType canvas_type
= 0;
75 static const GTypeInfo canvas_info
=
77 sizeof (DiaCanvasClass
),
79 NULL
, /* base_finalize */
80 (GClassInitFunc
) dia_canvas_class_init
,
81 NULL
, /* class_finalize */
82 NULL
, /* class_data */
85 (GInstanceInitFunc
) dia_canvas_init
,
88 canvas_type
= g_type_register_static (GTK_TYPE_CONTAINER
, "DiaCanvas",
96 dia_canvas_class_init (DiaCanvasClass
*class)
98 GtkWidgetClass
*widget_class
;
99 GtkContainerClass
*container_class
;
101 widget_class
= (GtkWidgetClass
*) class;
102 container_class
= (GtkContainerClass
*) class;
104 parent_class
= g_type_class_peek_parent (class);
106 widget_class
->realize
= dia_canvas_realize
;
107 widget_class
->size_request
= dia_canvas_size_request
;
108 widget_class
->size_allocate
= dia_canvas_size_allocate
;
110 container_class
->add
= dia_canvas_add
;
111 container_class
->remove
= dia_canvas_remove
;
112 container_class
->forall
= dia_canvas_forall
;
113 container_class
->child_type
= dia_canvas_child_type
;
115 container_class
->set_child_property
= dia_canvas_set_child_property
;
116 container_class
->get_child_property
= dia_canvas_get_child_property
;
118 gtk_container_class_install_child_property (container_class
,
120 g_param_spec_int ("x",
122 _("X position of child widget"),
128 gtk_container_class_install_child_property (container_class
,
130 g_param_spec_int ("y",
132 _("Y position of child widget"),
140 dia_canvas_child_type (GtkContainer
*container
)
142 return GTK_TYPE_WIDGET
;
146 dia_canvas_init (DiaCanvas
*canvas
)
148 canvas
->children
= NULL
;
152 dia_canvas_new (void)
154 return g_object_new (DIA_TYPE_CANVAS
, NULL
);
158 dia_canvas_set_size (DiaCanvas
*canvas
,
162 g_return_if_fail (DIA_IS_CANVAS (canvas
));
164 canvas
->wantedsize
.width
= width
;
165 canvas
->wantedsize
.height
= height
;
167 gtk_widget_queue_resize (GTK_WIDGET (canvas
));
171 dia_canvas_send_configure (DiaCanvas
*darea
)
174 GdkEvent
*event
= gdk_event_new (GDK_CONFIGURE
);
176 widget
= GTK_WIDGET (darea
);
178 event
->configure
.window
= g_object_ref (widget
->window
);
179 event
->configure
.send_event
= TRUE
;
180 event
->configure
.x
= widget
->allocation
.x
;
181 event
->configure
.y
= widget
->allocation
.y
;
182 event
->configure
.width
= widget
->allocation
.width
;
183 event
->configure
.height
= widget
->allocation
.height
;
185 gtk_widget_event (widget
, event
);
186 gdk_event_free (event
);
189 static DiaCanvasChild
*
190 get_child (DiaCanvas
*canvas
,
195 children
= canvas
->children
;
198 DiaCanvasChild
*child
;
200 child
= children
->data
;
201 children
= children
->next
;
203 if (child
->widget
== widget
)
211 dia_canvas_put (DiaCanvas
*canvas
,
216 DiaCanvasChild
*child_info
;
218 g_return_if_fail (DIA_IS_CANVAS (canvas
));
219 g_return_if_fail (GTK_IS_WIDGET (canvas
));
221 child_info
= g_new (DiaCanvasChild
, 1);
222 child_info
->widget
= widget
;
226 gtk_widget_set_parent (widget
, GTK_WIDGET (canvas
));
228 canvas
->children
= g_list_append (canvas
->children
, child_info
);
232 dia_canvas_move_internal (DiaCanvas
*canvas
,
239 DiaCanvasChild
*child
;
241 g_return_if_fail (DIA_IS_CANVAS (canvas
));
242 g_return_if_fail (GTK_IS_WIDGET (widget
));
243 g_return_if_fail (widget
->parent
== GTK_WIDGET (canvas
));
245 child
= get_child (canvas
, widget
);
249 gtk_widget_freeze_child_notify (widget
);
254 gtk_widget_child_notify (widget
, "x");
260 gtk_widget_child_notify (widget
, "y");
263 gtk_widget_thaw_child_notify (widget
);
265 if (GTK_WIDGET_VISIBLE (widget
) && GTK_WIDGET_VISIBLE (canvas
))
266 gtk_widget_queue_resize (GTK_WIDGET (canvas
));
270 dia_canvas_move (DiaCanvas
*canvas
,
275 dia_canvas_move_internal (canvas
, widget
, TRUE
, x
, TRUE
, y
);
279 dia_canvas_set_child_property (GtkContainer
*container
,
288 dia_canvas_move_internal (DIA_CANVAS (container
),
290 TRUE
, g_value_get_int (value
),
294 dia_canvas_move_internal (DIA_CANVAS (container
),
297 TRUE
, g_value_get_int (value
));
300 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container
, property_id
, pspec
);
306 dia_canvas_get_child_property (GtkContainer
*container
,
312 DiaCanvasChild
*canvas_child
;
314 canvas_child
= get_child (DIA_CANVAS (container
), child
);
319 g_value_set_int (value
, canvas_child
->x
);
322 g_value_set_int (value
, canvas_child
->y
);
325 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container
, property_id
, pspec
);
331 dia_canvas_realize (GtkWidget
*widget
)
333 GdkWindowAttr attributes
;
334 gint attributes_mask
;
336 GTK_WIDGET_SET_FLAGS (widget
, GTK_REALIZED
);
338 attributes
.window_type
= GDK_WINDOW_CHILD
;
339 attributes
.x
= widget
->allocation
.x
;
340 attributes
.y
= widget
->allocation
.y
;
341 attributes
.width
= widget
->allocation
.width
;
342 attributes
.height
= widget
->allocation
.height
;
343 attributes
.wclass
= GDK_INPUT_OUTPUT
;
344 attributes
.visual
= gtk_widget_get_visual (widget
);
345 attributes
.colormap
= gtk_widget_get_colormap (widget
);
346 attributes
.event_mask
= gtk_widget_get_events (widget
);
347 attributes
.event_mask
|= GDK_EXPOSURE_MASK
| GDK_BUTTON_PRESS_MASK
;
349 attributes_mask
= GDK_WA_X
| GDK_WA_Y
| GDK_WA_VISUAL
| GDK_WA_COLORMAP
;
351 widget
->window
= gdk_window_new (gtk_widget_get_parent_window (widget
), &attributes
,
353 gdk_window_set_user_data (widget
->window
, widget
);
355 widget
->style
= gtk_style_attach (widget
->style
, widget
->window
);
356 gtk_style_set_background (widget
->style
, widget
->window
, GTK_STATE_NORMAL
);
358 dia_canvas_send_configure (DIA_CANVAS (widget
));
362 dia_canvas_size_request (GtkWidget
*widget
,
363 GtkRequisition
*requisition
)
366 DiaCanvasChild
*child
;
368 GtkRequisition child_requisition
;
370 canvas
= DIA_CANVAS (widget
);
372 requisition
->width
= canvas
->wantedsize
.width
;
373 requisition
->height
= canvas
->wantedsize
.height
;
376 children
= canvas
->children
;
379 child
= children
->data
;
380 children
= children
->next
;
382 if (GTK_WIDGET_VISIBLE (child
->widget
))
384 gtk_widget_size_request (child
->widget
, &child_requisition
);
386 requisition
->height
= MAX (requisition
->height
,
388 child_requisition
.height
);
389 requisition
->width
= MAX (requisition
->width
,
391 child_requisition
.width
);
395 requisition->height += GTK_CONTAINER (canvas)->border_width * 2;
396 requisition->width += GTK_CONTAINER (canvas)->border_width * 2;
401 dia_canvas_size_allocate (GtkWidget
*widget
,
402 GtkAllocation
*allocation
)
405 DiaCanvasChild
*child
;
406 GtkAllocation child_allocation
;
407 GtkRequisition child_requisition
;
409 guint16 border_width
;
411 canvas
= DIA_CANVAS (widget
);
413 widget
->allocation
= *allocation
;
415 if (GTK_WIDGET_REALIZED (widget
)) {
416 gdk_window_move_resize (widget
->window
,
421 dia_canvas_send_configure (DIA_CANVAS (widget
));
423 border_width
= GTK_CONTAINER (canvas
)->border_width
;
425 children
= canvas
->children
;
428 child
= children
->data
;
429 children
= children
->next
;
431 if (GTK_WIDGET_VISIBLE (child
->widget
))
433 gtk_widget_get_child_requisition (child
->widget
, &child_requisition
);
434 child_allocation
.x
= child
->x
+ border_width
;
435 child_allocation
.y
= child
->y
+ border_width
;
437 if (GTK_WIDGET_NO_WINDOW (widget
))
439 child_allocation
.x
+= widget
->allocation
.x
;
440 child_allocation
.y
+= widget
->allocation
.y
;
443 child_allocation
.width
= child_requisition
.width
;
444 child_allocation
.height
= child_requisition
.height
;
445 gtk_widget_size_allocate (child
->widget
, &child_allocation
);
451 dia_canvas_add (GtkContainer
*container
,
454 dia_canvas_put (DIA_CANVAS (container
), widget
, 0, 0);
458 dia_canvas_remove (GtkContainer
*container
,
462 DiaCanvasChild
*child
;
465 canvas
= DIA_CANVAS (container
);
467 children
= canvas
->children
;
470 child
= children
->data
;
472 if (child
->widget
== widget
)
474 gboolean was_visible
= GTK_WIDGET_VISIBLE (widget
);
476 gtk_widget_unparent (widget
);
478 canvas
->children
= g_list_remove_link (canvas
->children
, children
);
479 g_list_free (children
);
482 if (was_visible
&& GTK_WIDGET_VISIBLE (container
))
483 gtk_widget_queue_resize (GTK_WIDGET (container
));
488 children
= children
->next
;
493 dia_canvas_forall (GtkContainer
*container
,
494 gboolean include_internals
,
495 GtkCallback callback
,
496 gpointer callback_data
)
499 DiaCanvasChild
*child
;
502 g_return_if_fail (callback
!= NULL
);
504 canvas
= DIA_CANVAS (container
);
506 children
= canvas
->children
;
509 child
= children
->data
;
510 children
= children
->next
;
512 (* callback
) (child
->widget
, callback_data
);