1 /* ///////////////////////////////////////////////////////////////////////////
3 // Purpose: native GTK+ widget for wxWindows
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////// */
10 #include "wx/gtk/win_gtk.h"
11 #include <gtk/gtkfeatures.h>
13 /*-------------------------------------------------------------------------
14 // conditional compilation
15 //------------------------------------------------------------------------- */
17 #if (GTK_MINOR_VERSION > 0)
18 #define NEW_GTK_CONSTRUCT_CODE
23 #endif /* __cplusplus */
25 static void gtk_myfixed_class_init (GtkMyFixedClass
*klass
);
26 static void gtk_myfixed_init (GtkMyFixed
*myfixed
);
27 static void gtk_myfixed_map (GtkWidget
*widget
);
28 #ifndef NEW_GTK_CONSTRUCT_CODE
29 static void gtk_myfixed_unmap (GtkWidget
*widget
);
31 static void gtk_myfixed_realize (GtkWidget
*widget
);
32 static void gtk_myfixed_size_request (GtkWidget
*widget
,
33 GtkRequisition
*requisition
);
34 static void gtk_myfixed_size_allocate (GtkWidget
*widget
,
35 GtkAllocation
*allocation
);
36 static void gtk_myfixed_paint (GtkWidget
*widget
,
38 static void gtk_myfixed_draw (GtkWidget
*widget
,
40 static gint
gtk_myfixed_expose (GtkWidget
*widget
,
41 GdkEventExpose
*event
);
42 static void gtk_myfixed_add (GtkContainer
*container
,
44 static void gtk_myfixed_remove (GtkContainer
*container
,
46 static void gtk_myfixed_foreach (GtkContainer
*container
,
47 #if (GTK_MINOR_VERSION > 0)
48 gboolean include_internals
,
51 gpointer callback_data
);
52 #ifdef NEW_GTK_CONSTRUCT_CODE
53 static GtkType
gtk_myfixed_child_type (GtkContainer
*container
);
57 static GtkContainerClass
*parent_class
= NULL
;
61 gtk_myfixed_get_type ()
63 static guint myfixed_type
= 0;
67 GtkTypeInfo myfixed_info
=
71 sizeof (GtkMyFixedClass
),
72 (GtkClassInitFunc
) gtk_myfixed_class_init
,
73 (GtkObjectInitFunc
) gtk_myfixed_init
,
74 #ifndef NEW_GTK_CONSTRUCT_CODE
78 /* reserved_1 */ NULL
,
79 /* reserved_2 */ NULL
,
80 (GtkClassInitFunc
) NULL
,
84 myfixed_type
= gtk_type_unique (gtk_container_get_type (), &myfixed_info
);
91 gtk_myfixed_class_init (GtkMyFixedClass
*klass
)
93 GtkObjectClass
*object_class
;
94 GtkWidgetClass
*widget_class
;
95 GtkContainerClass
*container_class
;
97 object_class
= (GtkObjectClass
*) klass
;
98 widget_class
= (GtkWidgetClass
*) klass
;
99 container_class
= (GtkContainerClass
*) klass
;
101 #ifndef NEW_GTK_CONSTRUCT_CODE
102 parent_class
= gtk_type_class (gtk_container_get_type ());
104 parent_class
= gtk_type_class (GTK_TYPE_CONTAINER
);
107 widget_class
->map
= gtk_myfixed_map
;
108 #ifndef NEW_GTK_CONSTRUCT_CODE
109 widget_class
->unmap
= gtk_myfixed_unmap
;
111 widget_class
->realize
= gtk_myfixed_realize
;
112 widget_class
->size_request
= gtk_myfixed_size_request
;
113 widget_class
->size_allocate
= gtk_myfixed_size_allocate
;
114 widget_class
->draw
= gtk_myfixed_draw
;
115 widget_class
->expose_event
= gtk_myfixed_expose
;
117 container_class
->add
= gtk_myfixed_add
;
118 container_class
->remove
= gtk_myfixed_remove
;
119 #if (GTK_MINOR_VERSION > 0)
120 container_class
->forall
= gtk_myfixed_foreach
;
122 container_class
->foreach
= gtk_myfixed_foreach
;
125 #ifdef NEW_GTK_CONSTRUCT_CODE
126 container_class
->child_type
= gtk_myfixed_child_type
;
130 #ifdef NEW_GTK_CONSTRUCT_CODE
132 gtk_myfixed_child_type (GtkContainer
*container
)
134 return GTK_TYPE_WIDGET
;
139 gtk_myfixed_init (GtkMyFixed
*myfixed
)
141 GTK_WIDGET_UNSET_FLAGS (myfixed
, GTK_NO_WINDOW
);
143 #ifndef NEW_GTK_CONSTRUCT_CODE
144 GTK_WIDGET_SET_FLAGS (myfixed
, GTK_BASIC
);
147 myfixed
->children
= NULL
;
155 myfixed
= gtk_type_new (gtk_myfixed_get_type ());
157 return GTK_WIDGET (myfixed
);
161 gtk_myfixed_put (GtkMyFixed
*myfixed
,
166 GtkMyFixedChild
*child_info
;
168 g_return_if_fail (myfixed
!= NULL
);
169 g_return_if_fail (GTK_IS_MYFIXED (myfixed
));
170 g_return_if_fail (widget
!= NULL
);
172 child_info
= g_new (GtkMyFixedChild
, 1);
173 child_info
->widget
= widget
;
177 gtk_widget_set_parent (widget
, GTK_WIDGET (myfixed
));
179 myfixed
->children
= g_list_append (myfixed
->children
, child_info
);
181 if (GTK_WIDGET_REALIZED (myfixed
) && !GTK_WIDGET_REALIZED (widget
))
182 gtk_widget_realize (widget
);
184 if (GTK_WIDGET_MAPPED (myfixed
) && !GTK_WIDGET_MAPPED (widget
))
185 gtk_widget_map (widget
);
187 if (GTK_WIDGET_VISIBLE (widget
) && GTK_WIDGET_VISIBLE (myfixed
))
188 gtk_widget_queue_resize (GTK_WIDGET (myfixed
));
192 gtk_myfixed_move (GtkMyFixed
*myfixed
,
197 GtkMyFixedChild
*child
;
200 g_return_if_fail (myfixed
!= NULL
);
201 g_return_if_fail (GTK_IS_MYFIXED (myfixed
));
202 g_return_if_fail (widget
!= NULL
);
204 children
= myfixed
->children
;
207 child
= children
->data
;
208 children
= children
->next
;
210 if (child
->widget
== widget
)
212 if ((child
->x
== x
) && (child
->y
== y
)) return;
217 if (GTK_WIDGET_VISIBLE (widget
) && GTK_WIDGET_VISIBLE (myfixed
))
218 gtk_widget_queue_resize (GTK_WIDGET (myfixed
));
226 gtk_myfixed_map (GtkWidget
*widget
)
229 GtkMyFixedChild
*child
;
232 g_return_if_fail (widget
!= NULL
);
233 g_return_if_fail (GTK_IS_MYFIXED (widget
));
235 GTK_WIDGET_SET_FLAGS (widget
, GTK_MAPPED
);
236 myfixed
= GTK_MYFIXED (widget
);
238 gdk_window_show (widget
->window
);
240 children
= myfixed
->children
;
243 child
= children
->data
;
244 children
= children
->next
;
246 if (GTK_WIDGET_VISIBLE (child
->widget
) &&
247 !GTK_WIDGET_MAPPED (child
->widget
))
248 gtk_widget_map (child
->widget
);
252 #ifndef NEW_GTK_CONSTRUCT_CODE
254 gtk_myfixed_unmap (GtkWidget
*widget
)
256 g_return_if_fail (widget
!= NULL
);
257 g_return_if_fail (GTK_IS_MYFIXED (widget
));
259 GTK_WIDGET_UNSET_FLAGS (widget
, GTK_MAPPED
);
264 gtk_myfixed_realize (GtkWidget
*widget
)
267 GdkWindowAttr attributes
;
268 gint attributes_mask
;
270 g_return_if_fail (widget
!= NULL
);
271 g_return_if_fail (GTK_IS_MYFIXED (widget
));
273 myfixed
= GTK_MYFIXED (widget
);
275 GTK_WIDGET_SET_FLAGS (widget
, GTK_REALIZED
);
277 attributes
.window_type
= GDK_WINDOW_CHILD
;
278 attributes
.x
= widget
->allocation
.x
;
279 attributes
.y
= widget
->allocation
.y
;
280 attributes
.width
= 32000;
281 attributes
.height
= 32000;
282 attributes
.wclass
= GDK_INPUT_OUTPUT
;
283 attributes
.visual
= gtk_widget_get_visual (widget
);
284 attributes
.colormap
= gtk_widget_get_colormap (widget
);
285 attributes
.event_mask
= gtk_widget_get_events (widget
);
286 attributes
.event_mask
|=
288 GDK_POINTER_MOTION_MASK
|
289 GDK_POINTER_MOTION_HINT_MASK
|
290 GDK_BUTTON_MOTION_MASK
|
291 GDK_BUTTON1_MOTION_MASK
|
292 GDK_BUTTON2_MOTION_MASK
|
293 GDK_BUTTON3_MOTION_MASK
|
294 GDK_BUTTON_PRESS_MASK
|
295 GDK_BUTTON_RELEASE_MASK
|
297 GDK_KEY_RELEASE_MASK
|
298 GDK_ENTER_NOTIFY_MASK
|
299 GDK_LEAVE_NOTIFY_MASK
|
300 GDK_FOCUS_CHANGE_MASK
;
302 attributes_mask
= GDK_WA_X
| GDK_WA_Y
| GDK_WA_VISUAL
| GDK_WA_COLORMAP
;
304 widget
->window
= gdk_window_new (gtk_widget_get_parent_window (widget
), &attributes
,
306 gdk_window_set_user_data (widget
->window
, widget
);
308 widget
->style
= gtk_style_attach (widget
->style
, widget
->window
);
309 gtk_style_set_background (widget
->style
, widget
->window
, GTK_STATE_NORMAL
);
313 gtk_myfixed_size_request (GtkWidget
*widget
,
314 GtkRequisition
*requisition
)
317 GtkMyFixedChild
*child
;
320 g_return_if_fail (widget
!= NULL
);
321 g_return_if_fail (GTK_IS_MYFIXED (widget
));
322 g_return_if_fail (requisition
!= NULL
);
324 myfixed
= GTK_MYFIXED (widget
);
326 requisition
->width
= 0;
327 requisition
->height
= 0;
329 children
= myfixed
->children
;
332 child
= children
->data
;
333 children
= children
->next
;
335 if (GTK_WIDGET_VISIBLE (child
->widget
))
337 gtk_widget_size_request (child
->widget
, &child
->widget
->requisition
);
343 gtk_myfixed_size_allocate (GtkWidget
*widget
,
344 GtkAllocation
*allocation
)
347 GtkMyFixedChild
*child
;
348 GtkAllocation child_allocation
;
350 guint16 border_width
;
352 g_return_if_fail (widget
!= NULL
);
353 g_return_if_fail (GTK_IS_MYFIXED(widget
));
354 g_return_if_fail (allocation
!= NULL
);
356 myfixed
= GTK_MYFIXED (widget
);
358 widget
->allocation
= *allocation
;
359 if (GTK_WIDGET_REALIZED (widget
))
360 gdk_window_move_resize (widget
->window
, allocation
->x
, allocation
->y
, 32000, 32000 );
362 border_width
= GTK_CONTAINER (myfixed
)->border_width
;
364 children
= myfixed
->children
;
367 child
= children
->data
;
368 children
= children
->next
;
370 if (GTK_WIDGET_VISIBLE (child
->widget
))
372 child_allocation
.x
= child
->x
+ border_width
;
373 child_allocation
.y
= child
->y
+ border_width
;
374 child_allocation
.width
= child
->widget
->requisition
.width
;
375 child_allocation
.height
= child
->widget
->requisition
.height
;
376 gtk_widget_size_allocate (child
->widget
, &child_allocation
);
382 gtk_myfixed_paint (GtkWidget
*widget
,
385 g_return_if_fail (widget
!= NULL
);
386 g_return_if_fail (GTK_IS_MYFIXED (widget
));
387 g_return_if_fail (area
!= NULL
);
389 if (GTK_WIDGET_DRAWABLE (widget
))
390 gdk_window_clear_area (widget
->window
,
392 area
->width
, area
->height
);
396 gtk_myfixed_draw (GtkWidget
*widget
,
400 GtkMyFixedChild
*child
;
401 GdkRectangle child_area
;
404 g_return_if_fail (widget
!= NULL
);
405 g_return_if_fail (GTK_IS_MYFIXED (widget
));
407 if (GTK_WIDGET_DRAWABLE (widget
))
409 myfixed
= GTK_MYFIXED (widget
);
410 gtk_myfixed_paint (widget
, area
);
412 children
= myfixed
->children
;
415 child
= children
->data
;
416 children
= children
->next
;
418 if (gtk_widget_intersect (child
->widget
, area
, &child_area
))
419 gtk_widget_draw (child
->widget
, &child_area
);
425 gtk_myfixed_expose (GtkWidget
*widget
,
426 GdkEventExpose
*event
)
429 GtkMyFixedChild
*child
;
430 GdkEventExpose child_event
;
433 g_return_val_if_fail (widget
!= NULL
, FALSE
);
434 g_return_val_if_fail (GTK_IS_MYFIXED (widget
), FALSE
);
435 g_return_val_if_fail (event
!= NULL
, FALSE
);
437 if (GTK_WIDGET_DRAWABLE (widget
))
439 myfixed
= GTK_MYFIXED (widget
);
441 child_event
= *event
;
443 children
= myfixed
->children
;
446 child
= children
->data
;
447 children
= children
->next
;
449 if (GTK_WIDGET_NO_WINDOW (child
->widget
) &&
450 gtk_widget_intersect (child
->widget
, &event
->area
,
452 gtk_widget_event (child
->widget
, (GdkEvent
*) &child_event
);
460 gtk_myfixed_add (GtkContainer
*container
,
463 g_return_if_fail (container
!= NULL
);
464 g_return_if_fail (GTK_IS_MYFIXED (container
));
465 g_return_if_fail (widget
!= NULL
);
467 gtk_myfixed_put (GTK_MYFIXED (container
), widget
, 0, 0);
471 gtk_myfixed_remove (GtkContainer
*container
,
475 GtkMyFixedChild
*child
;
478 g_return_if_fail (container
!= NULL
);
479 g_return_if_fail (GTK_IS_MYFIXED (container
));
480 g_return_if_fail (widget
!= NULL
);
482 myfixed
= GTK_MYFIXED (container
);
484 children
= myfixed
->children
;
487 child
= children
->data
;
489 if (child
->widget
== widget
)
491 gtk_widget_unparent (widget
);
493 myfixed
->children
= g_list_remove_link (myfixed
->children
, children
);
494 g_list_free (children
);
497 if (GTK_WIDGET_VISIBLE (widget
) && GTK_WIDGET_VISIBLE (container
))
498 gtk_widget_queue_resize (GTK_WIDGET (container
));
503 children
= children
->next
;
508 gtk_myfixed_foreach (GtkContainer
*container
,
509 #if (GTK_MINOR_VERSION > 0)
510 gboolean include_internals
,
512 GtkCallback callback
,
513 gpointer callback_data
)
516 GtkMyFixedChild
*child
;
519 g_return_if_fail (container
!= NULL
);
520 g_return_if_fail (GTK_IS_MYFIXED (container
));
521 g_return_if_fail (callback
!= NULL
);
523 myfixed
= GTK_MYFIXED (container
);
525 children
= myfixed
->children
;
528 child
= children
->data
;
529 children
= children
->next
;
531 (* callback
) (child
->widget
, callback_data
);
538 #endif /* __cplusplus */