]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/win_gtk.c
some fixes after global _T() => T() change
[wxWidgets.git] / src / gtk1 / win_gtk.c
CommitLineData
c67daf87 1/* ///////////////////////////////////////////////////////////////////////////
c67d8618 2// Name: win_gtk.c
01111366 3// Purpose: native GTK+ widget for wxWindows
c801d85f 4// Author: Robert Roebling
c67d8618 5// Id: $Id$
01111366 6// Copyright: (c) 1998 Robert Roebling
c801d85f 7// Licence: wxWindows licence
c67daf87 8/////////////////////////////////////////////////////////////////////////// */
c801d85f
KB
9
10#include "wx/gtk/win_gtk.h"
034be888 11#include "gtk/gtksignal.h"
bbf7db28 12#include "gtk/gtknotebook.h"
98d3fdbe 13#include "gtk/gtkscrolledwindow.h"
38c7b3d3 14
c801d85f
KB
15#ifdef __cplusplus
16extern "C" {
17#endif /* __cplusplus */
18
19static void gtk_myfixed_class_init (GtkMyFixedClass *klass);
20static void gtk_myfixed_init (GtkMyFixed *myfixed);
21static void gtk_myfixed_map (GtkWidget *widget);
034be888 22#if (GTK_MINOR_VERSION == 0)
c801d85f 23static void gtk_myfixed_unmap (GtkWidget *widget);
38c7b3d3 24#endif
c801d85f
KB
25static void gtk_myfixed_realize (GtkWidget *widget);
26static void gtk_myfixed_size_request (GtkWidget *widget,
27 GtkRequisition *requisition);
28static void gtk_myfixed_size_allocate (GtkWidget *widget,
29 GtkAllocation *allocation);
30static void gtk_myfixed_paint (GtkWidget *widget,
31 GdkRectangle *area);
32static void gtk_myfixed_draw (GtkWidget *widget,
33 GdkRectangle *area);
34static gint gtk_myfixed_expose (GtkWidget *widget,
35 GdkEventExpose *event);
36static void gtk_myfixed_add (GtkContainer *container,
37 GtkWidget *widget);
38static void gtk_myfixed_remove (GtkContainer *container,
39 GtkWidget *widget);
40static void gtk_myfixed_foreach (GtkContainer *container,
d345e841 41#if (GTK_MINOR_VERSION > 0)
75ed1d15
GL
42 gboolean include_internals,
43#endif
c801d85f
KB
44 GtkCallback callback,
45 gpointer callback_data);
034be888 46#if (GTK_MINOR_VERSION > 0)
38c7b3d3
RR
47static GtkType gtk_myfixed_child_type (GtkContainer *container);
48#endif
c801d85f 49
034be888
RR
50#if (GTK_MINOR_VERSION > 0)
51static void gtk_myfixed_scroll_set_adjustments (GtkMyFixed *myfixed,
52 GtkAdjustment *hadj,
53 GtkAdjustment *vadj);
54#endif
c801d85f 55
c801d85f
KB
56
57
034be888
RR
58static GtkContainerClass *parent_class = NULL;
59
c801d85f
KB
60guint
61gtk_myfixed_get_type ()
62{
053f9cc1 63 static guint myfixed_type = 0;
c801d85f 64
053f9cc1 65 if (!myfixed_type)
c801d85f 66 {
053f9cc1
RR
67 GtkTypeInfo myfixed_info =
68 {
69 "GtkMyFixed",
70 sizeof (GtkMyFixed),
71 sizeof (GtkMyFixedClass),
72 (GtkClassInitFunc) gtk_myfixed_class_init,
73 (GtkObjectInitFunc) gtk_myfixed_init,
034be888 74#if (GTK_MINOR_VERSION > 0)
053f9cc1
RR
75 /* reserved_1 */ NULL,
76 /* reserved_2 */ NULL,
77 (GtkClassInitFunc) NULL,
034be888 78#else
053f9cc1
RR
79 (GtkArgSetFunc) NULL,
80 (GtkArgGetFunc) NULL,
38c7b3d3 81#endif
053f9cc1
RR
82 };
83 myfixed_type = gtk_type_unique (gtk_container_get_type (), &myfixed_info);
c801d85f 84 }
053f9cc1
RR
85
86 return myfixed_type;
c801d85f
KB
87}
88
89static void
90gtk_myfixed_class_init (GtkMyFixedClass *klass)
91{
053f9cc1
RR
92 GtkObjectClass *object_class;
93 GtkWidgetClass *widget_class;
94 GtkContainerClass *container_class;
c801d85f 95
053f9cc1
RR
96 object_class = (GtkObjectClass*) klass;
97 widget_class = (GtkWidgetClass*) klass;
98 container_class = (GtkContainerClass*) klass;
f5368809 99
034be888 100#if (GTK_MINOR_VERSION > 0)
053f9cc1 101 parent_class = gtk_type_class (GTK_TYPE_CONTAINER);
034be888 102#else
053f9cc1 103 parent_class = gtk_type_class (gtk_container_get_type ());
38c7b3d3 104#endif
c801d85f 105
053f9cc1 106 widget_class->map = gtk_myfixed_map;
034be888 107#if (GTK_MINOR_VERSION == 0)
053f9cc1 108 widget_class->unmap = gtk_myfixed_unmap;
38c7b3d3 109#endif
053f9cc1
RR
110 widget_class->realize = gtk_myfixed_realize;
111 widget_class->size_request = gtk_myfixed_size_request;
112 widget_class->size_allocate = gtk_myfixed_size_allocate;
113 widget_class->draw = gtk_myfixed_draw;
114 widget_class->expose_event = gtk_myfixed_expose;
115
116 container_class->add = gtk_myfixed_add;
117 container_class->remove = gtk_myfixed_remove;
d345e841 118#if (GTK_MINOR_VERSION > 0)
053f9cc1 119 container_class->forall = gtk_myfixed_foreach;
75ed1d15 120#else
053f9cc1 121 container_class->foreach = gtk_myfixed_foreach;
75ed1d15 122#endif
38c7b3d3 123
034be888 124#if (GTK_MINOR_VERSION > 0)
053f9cc1 125 container_class->child_type = gtk_myfixed_child_type;
38c7b3d3 126#endif
034be888
RR
127
128#if (GTK_MINOR_VERSION > 0)
053f9cc1 129 klass->set_scroll_adjustments = gtk_myfixed_scroll_set_adjustments;
034be888 130
053f9cc1 131 widget_class->set_scroll_adjustments_signal =
034be888
RR
132 gtk_signal_new ("set_scroll_adjustments",
133 GTK_RUN_LAST,
134 object_class->type,
135 GTK_SIGNAL_OFFSET (GtkMyFixedClass, set_scroll_adjustments),
136 gtk_marshal_NONE__POINTER_POINTER,
137 GTK_TYPE_NONE, 2, GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT);
138#endif
38c7b3d3
RR
139}
140
034be888 141#if (GTK_MINOR_VERSION > 0)
38c7b3d3
RR
142static GtkType
143gtk_myfixed_child_type (GtkContainer *container)
144{
053f9cc1 145 return GTK_TYPE_WIDGET;
c801d85f 146}
38c7b3d3 147#endif
c801d85f
KB
148
149static void
150gtk_myfixed_init (GtkMyFixed *myfixed)
151{
053f9cc1 152 GTK_WIDGET_UNSET_FLAGS (myfixed, GTK_NO_WINDOW);
38c7b3d3 153
034be888 154#if (GTK_MINOR_VERSION == 0)
053f9cc1 155 GTK_WIDGET_SET_FLAGS (myfixed, GTK_BASIC);
38c7b3d3 156#endif
f5368809 157
034be888 158#if (GTK_MINOR_VERSION > 0)
5e014a0c 159 myfixed->shadow_type = GTK_MYSHADOW_NONE;
034be888
RR
160#endif
161
053f9cc1 162 myfixed->children = NULL;
c801d85f
KB
163}
164
165GtkWidget*
166gtk_myfixed_new ()
167{
053f9cc1 168 GtkMyFixed *myfixed;
c801d85f 169
053f9cc1 170 myfixed = gtk_type_new (gtk_myfixed_get_type ());
c801d85f 171
053f9cc1 172 return GTK_WIDGET (myfixed);
c801d85f
KB
173}
174
034be888 175#if (GTK_MINOR_VERSION > 0)
053f9cc1
RR
176void
177gtk_myfixed_scroll_set_adjustments (GtkMyFixed *myfixed,
178 GtkAdjustment *hadj,
179 GtkAdjustment *vadj)
034be888
RR
180{
181 /* OK, this is embarassing, but this function has to be here */
182}
183
184void
5e014a0c
RR
185gtk_myfixed_set_shadow_type (GtkMyFixed *myfixed,
186 GtkMyShadowType type)
034be888 187{
053f9cc1
RR
188 g_return_if_fail (myfixed != NULL);
189 g_return_if_fail (GTK_IS_MYFIXED (myfixed));
034be888 190
5e014a0c 191 if ((GtkMyShadowType) myfixed->shadow_type != type)
034be888 192 {
053f9cc1 193 myfixed->shadow_type = type;
034be888 194
053f9cc1 195 if (GTK_WIDGET_VISIBLE (myfixed))
034be888 196 {
053f9cc1
RR
197 gtk_widget_size_allocate (GTK_WIDGET (myfixed), &(GTK_WIDGET (myfixed)->allocation));
198 gtk_widget_queue_draw (GTK_WIDGET (myfixed));
034be888
RR
199 }
200 }
201}
202#endif
203
c801d85f 204void
053f9cc1
RR
205gtk_myfixed_put (GtkMyFixed *myfixed,
206 GtkWidget *widget,
fdd3ed7a
RR
207 gint16 x,
208 gint16 y,
209 gint16 width,
210 gint16 height)
c801d85f 211{
053f9cc1
RR
212 GtkMyFixedChild *child_info;
213
214 g_return_if_fail (myfixed != NULL);
215 g_return_if_fail (GTK_IS_MYFIXED (myfixed));
216 g_return_if_fail (widget != NULL);
217
218 child_info = g_new (GtkMyFixedChild, 1);
219 child_info->widget = widget;
220 child_info->x = x;
221 child_info->y = y;
222 child_info->width = width;
223 child_info->height = height;
d4c99d6f 224
053f9cc1 225 gtk_widget_set_parent (widget, GTK_WIDGET (myfixed));
c801d85f 226
053f9cc1 227 myfixed->children = g_list_append (myfixed->children, child_info);
c801d85f 228
053f9cc1
RR
229 if (GTK_WIDGET_REALIZED (myfixed))
230 gtk_widget_realize (widget);
c801d85f 231
053f9cc1 232 if (GTK_WIDGET_VISIBLE (myfixed) && GTK_WIDGET_VISIBLE (widget))
326f9654 233 {
053f9cc1
RR
234 if (GTK_WIDGET_MAPPED (myfixed))
235 gtk_widget_map (widget);
326f9654 236
053f9cc1 237 gtk_widget_queue_resize (GTK_WIDGET (myfixed));
326f9654 238 }
c801d85f
KB
239}
240
241void
053f9cc1
RR
242gtk_myfixed_move (GtkMyFixed *myfixed,
243 GtkWidget *widget,
fdd3ed7a
RR
244 gint16 x,
245 gint16 y)
c801d85f 246{
053f9cc1
RR
247 GtkMyFixedChild *child;
248 GList *children;
c801d85f 249
053f9cc1
RR
250 g_return_if_fail (myfixed != NULL);
251 g_return_if_fail (GTK_IS_MYFIXED (myfixed));
252 g_return_if_fail (widget != NULL);
c801d85f 253
053f9cc1
RR
254 children = myfixed->children;
255 while (children)
fdd3ed7a 256 {
053f9cc1
RR
257 child = children->data;
258 children = children->next;
fdd3ed7a 259
053f9cc1 260 if (child->widget == widget)
fdd3ed7a 261 {
053f9cc1
RR
262 gtk_myfixed_set_size( myfixed, widget, x, y, child->width, child->height );
263 break;
fdd3ed7a
RR
264 }
265 }
266}
267
268void
269gtk_myfixed_resize (GtkMyFixed *myfixed,
270 GtkWidget *widget,
271 gint16 width,
272 gint16 height)
273{
053f9cc1
RR
274 GtkMyFixedChild *child;
275 GList *children;
fdd3ed7a 276
053f9cc1
RR
277 g_return_if_fail (myfixed != NULL);
278 g_return_if_fail (GTK_IS_MYFIXED (myfixed));
279 g_return_if_fail (widget != NULL);
fdd3ed7a 280
053f9cc1
RR
281 children = myfixed->children;
282 while (children)
fdd3ed7a 283 {
053f9cc1
RR
284 child = children->data;
285 children = children->next;
fdd3ed7a 286
053f9cc1 287 if (child->widget == widget)
fdd3ed7a 288 {
053f9cc1
RR
289 gtk_myfixed_set_size( myfixed, widget, child->x, child->y, width, height );
290 break;
fdd3ed7a
RR
291 }
292 }
293}
294
295void
053f9cc1
RR
296gtk_myfixed_set_size (GtkMyFixed *myfixed,
297 GtkWidget *widget,
fdd3ed7a
RR
298 gint16 x,
299 gint16 y,
300 gint16 width,
301 gint16 height)
302{
053f9cc1
RR
303 GtkMyFixedChild *child;
304 GList *children;
305 GtkAllocation child_allocation;
fdd3ed7a 306
053f9cc1
RR
307 g_return_if_fail (myfixed != NULL);
308 g_return_if_fail (GTK_IS_MYFIXED (myfixed));
309 g_return_if_fail (widget != NULL);
fdd3ed7a 310
053f9cc1
RR
311 children = myfixed->children;
312 while (children)
c801d85f 313 {
053f9cc1
RR
314 child = children->data;
315 children = children->next;
c801d85f 316
053f9cc1 317 if (child->widget == widget)
c801d85f 318 {
053f9cc1
RR
319 if ((child->x == x) &&
320 (child->y == y) &&
321 (child->width == width) &&
322 (child->height == height)) return;
fb1585ae 323
053f9cc1
RR
324 child->x = x;
325 child->y = y;
326 child->width = width;
327 child->height = height;
328
329 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (myfixed))
330 {
7d6d2cd4
RR
331 if ( (child->width > 1) &&
332 (child->height > 1) &&
333 !(GTK_WIDGET_REALIZED(widget) && GTK_IS_NOTEBOOK(widget)) )
053f9cc1
RR
334 {
335 child_allocation.x = child->x;
336 child_allocation.y = child->y;
337 child_allocation.width = MAX( child->width, 1 );
338 child_allocation.height = MAX( child->height, 1 );
339
340 /* work around for GTK bug when moving widgets outside
341 the X window -> do NOT move them entirely outside */
342 if (child_allocation.y + child_allocation.height < 0)
343 child_allocation.y = -child_allocation.height;
344 if (child_allocation.x + child_allocation.width < 0)
345 child_allocation.x = -child_allocation.width;
346
347 gtk_widget_size_allocate (widget, &child_allocation);
348 }
349 else
350 {
351 gtk_widget_queue_resize (GTK_WIDGET (myfixed));
352 }
353 }
354 break;
c801d85f
KB
355 }
356 }
357}
358
359static void
360gtk_myfixed_map (GtkWidget *widget)
361{
053f9cc1
RR
362 GtkMyFixed *myfixed;
363 GtkMyFixedChild *child;
364 GList *children;
c801d85f 365
053f9cc1
RR
366 g_return_if_fail (widget != NULL);
367 g_return_if_fail (GTK_IS_MYFIXED (widget));
c801d85f 368
053f9cc1
RR
369 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
370 myfixed = GTK_MYFIXED (widget);
c801d85f 371
053f9cc1
RR
372 children = myfixed->children;
373 while (children)
c801d85f 374 {
053f9cc1
RR
375 child = children->data;
376 children = children->next;
c801d85f 377
053f9cc1
RR
378 if (GTK_WIDGET_VISIBLE (child->widget) && !GTK_WIDGET_MAPPED (child->widget))
379 gtk_widget_map (child->widget);
c801d85f 380 }
d872b8a9 381
053f9cc1 382 gdk_window_show (widget->window);
c801d85f
KB
383}
384
034be888 385#if (GTK_MINOR_VERSION == 0)
c801d85f
KB
386static void
387gtk_myfixed_unmap (GtkWidget *widget)
388{
053f9cc1
RR
389 g_return_if_fail (widget != NULL);
390 g_return_if_fail (GTK_IS_MYFIXED (widget));
c801d85f 391
053f9cc1 392 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
c801d85f 393}
38c7b3d3 394#endif
c801d85f
KB
395
396static void
397gtk_myfixed_realize (GtkWidget *widget)
398{
053f9cc1
RR
399 GtkMyFixed *myfixed;
400 GdkWindowAttr attributes;
401 gint attributes_mask;
c801d85f 402
053f9cc1
RR
403 g_return_if_fail (widget != NULL);
404 g_return_if_fail (GTK_IS_MYFIXED (widget));
c801d85f 405
053f9cc1 406 myfixed = GTK_MYFIXED (widget);
d4c99d6f 407
053f9cc1 408 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
c801d85f 409
053f9cc1 410 attributes.window_type = GDK_WINDOW_CHILD;
034be888
RR
411
412#if (GTK_MINOR_VERSION > 0)
053f9cc1
RR
413 attributes.x = widget->allocation.x;
414 attributes.y = widget->allocation.y;
415 attributes.width = widget->allocation.width;
416 attributes.height = widget->allocation.height;
417
5e014a0c 418 if (myfixed->shadow_type == GTK_MYSHADOW_NONE)
053f9cc1 419 {
5e014a0c
RR
420 /* no border, no changes to sizes */
421 } else
422 if (myfixed->shadow_type == GTK_MYSHADOW_THIN)
423 {
424 /* GTK_MYSHADOW_THIN == wxSIMPLE_BORDER */
425 attributes.x += 1;
426 attributes.y += 1;
427 attributes.width -= 2;
428 attributes.height -= 2;
429 } else
430 {
431 /* GTK_MYSHADOW_IN == wxSUNKEN_BORDER */
432 /* GTK_MYSHADOW_OUT == wxRAISED_BORDER */
053f9cc1
RR
433 attributes.x += 2;
434 attributes.y += 2;
435 attributes.width -= 4;
436 attributes.height -= 4;
437 }
58dea4b0 438
053f9cc1
RR
439 if (attributes.width < 2) attributes.width = 2;
440 if (attributes.height < 2) attributes.height = 2;
034be888 441#else
053f9cc1
RR
442 attributes.x = widget->allocation.x;
443 attributes.y = widget->allocation.y;
444 attributes.width = 32000;
445 attributes.height = 32000;
034be888 446#endif
053f9cc1
RR
447 attributes.wclass = GDK_INPUT_OUTPUT;
448 attributes.visual = gtk_widget_get_visual (widget);
449 attributes.colormap = gtk_widget_get_colormap (widget);
450 attributes.event_mask = gtk_widget_get_events (widget);
451 attributes.event_mask |=
452 GDK_EXPOSURE_MASK |
453 GDK_POINTER_MOTION_MASK |
454 GDK_POINTER_MOTION_HINT_MASK |
455 GDK_BUTTON_MOTION_MASK |
456 GDK_BUTTON1_MOTION_MASK |
457 GDK_BUTTON2_MOTION_MASK |
458 GDK_BUTTON3_MOTION_MASK |
459 GDK_BUTTON_PRESS_MASK |
460 GDK_BUTTON_RELEASE_MASK |
461 GDK_KEY_PRESS_MASK |
462 GDK_KEY_RELEASE_MASK |
463 GDK_ENTER_NOTIFY_MASK |
464 GDK_LEAVE_NOTIFY_MASK |
465 GDK_FOCUS_CHANGE_MASK;
466 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
467
468 widget->window = gdk_window_new( gtk_widget_get_parent_window (widget), &attributes,
469 attributes_mask);
470 gdk_window_set_user_data (widget->window, widget);
c801d85f 471
053f9cc1
RR
472 widget->style = gtk_style_attach (widget->style, widget->window);
473 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
c801d85f
KB
474}
475
476static void
477gtk_myfixed_size_request (GtkWidget *widget,
053f9cc1 478 GtkRequisition *requisition)
c801d85f 479{
053f9cc1
RR
480 GtkMyFixed *myfixed;
481 GtkMyFixedChild *child;
482 GList *children;
483 GtkRequisition child_requisition;
c801d85f 484
053f9cc1
RR
485 g_return_if_fail (widget != NULL);
486 g_return_if_fail (GTK_IS_MYFIXED (widget));
487 g_return_if_fail (requisition != NULL);
c801d85f 488
053f9cc1 489 myfixed = GTK_MYFIXED (widget);
c801d85f 490
053f9cc1
RR
491 children = myfixed->children;
492 while (children)
c801d85f 493 {
053f9cc1
RR
494 child = children->data;
495 children = children->next;
c801d85f 496
053f9cc1 497 if (GTK_WIDGET_VISIBLE (child->widget))
c801d85f 498 {
053f9cc1 499 gtk_widget_size_request (child->widget, &child_requisition);
c801d85f
KB
500 }
501 }
d872b8a9 502
053f9cc1
RR
503 /* request very little, I'm not sure if requesting nothing
504 will always have positive effects on stability... */
505 requisition->width = 2;
506 requisition->height = 2;
c801d85f
KB
507}
508
509static void
510gtk_myfixed_size_allocate (GtkWidget *widget,
fdd3ed7a 511 GtkAllocation *allocation)
c801d85f 512{
053f9cc1
RR
513 GtkMyFixed *myfixed;
514 gint border;
515 GtkMyFixedChild *child;
516 GtkAllocation child_allocation;
517 GList *children;
c801d85f 518
053f9cc1
RR
519 g_return_if_fail (widget != NULL);
520 g_return_if_fail (GTK_IS_MYFIXED(widget));
521 g_return_if_fail (allocation != NULL);
c801d85f 522
053f9cc1 523 myfixed = GTK_MYFIXED (widget);
e208b369 524
227e5e99 525 widget->allocation = *allocation;
a0fdacee 526#if (GTK_MINOR_VERSION > 0)
5e014a0c 527 if (myfixed->shadow_type == GTK_MYSHADOW_NONE)
053f9cc1 528 border = 0;
5e014a0c
RR
529 else
530 if (myfixed->shadow_type == GTK_MYSHADOW_THIN)
531 border = 1;
053f9cc1
RR
532 else
533 border = 2;
ef47f9b3 534#else
053f9cc1 535 border = 0;
ef47f9b3 536#endif
034be888 537
053f9cc1
RR
538 if (GTK_WIDGET_REALIZED (widget))
539 {
540 gdk_window_move_resize( widget->window,
541 allocation->x+border, allocation->y+border,
034be888 542#if (GTK_MINOR_VERSION > 0)
053f9cc1 543 allocation->width-border*2, allocation->height-border*2
034be888 544#else
053f9cc1 545 32000, 32000
034be888 546#endif
053f9cc1
RR
547 );
548 }
c801d85f 549
053f9cc1
RR
550 children = myfixed->children;
551 while (children)
c801d85f 552 {
053f9cc1
RR
553 child = children->data;
554 children = children->next;
69cdfbf7 555
053f9cc1
RR
556 if (GTK_WIDGET_VISIBLE (child->widget))
557 {
98d3fdbe
RR
558/* please look at the text in wxWindow::DoSetSize() on why the
559 test GTK_WIDGET_REALIZED() has to be here */
053f9cc1
RR
560/* if (GTK_IS_NOTEBOOK(child->widget) && !GTK_WIDGET_REALIZED(child->widget))
561 {
562 gtk_widget_queue_resize( child->widget );
563 }
98d3fdbe 564 else */
053f9cc1
RR
565 {
566 child_allocation.x = child->x;
567 child_allocation.y = child->y;
568 child_allocation.width = MAX( child->width, 1 );
569 child_allocation.height = MAX( child->height, 1 );
570
571 /* work around for GTK bug when moving widgets outside
572 the X window -> do NOT move them entirely outside */
573 if (child_allocation.y + child_allocation.height < 0)
574 child_allocation.y = -child_allocation.height;
575 if (child_allocation.x + child_allocation.width < 0)
576 child_allocation.x = -child_allocation.width;
577
578 gtk_widget_size_allocate (child->widget, &child_allocation);
579 }
580 }
581 }
c801d85f
KB
582}
583
584static void
585gtk_myfixed_paint (GtkWidget *widget,
fdd3ed7a 586 GdkRectangle *area)
c801d85f 587{
053f9cc1
RR
588 g_return_if_fail (widget != NULL);
589 g_return_if_fail (GTK_IS_MYFIXED (widget));
590 g_return_if_fail (area != NULL);
591
592 if (GTK_WIDGET_DRAWABLE (widget))
593 gdk_window_clear_area (widget->window,
594 area->x, area->y,
595 area->width, area->height);
c801d85f
KB
596}
597
598static void
599gtk_myfixed_draw (GtkWidget *widget,
fdd3ed7a 600 GdkRectangle *area)
c801d85f
KB
601{
602 GtkMyFixed *myfixed;
603 GtkMyFixedChild *child;
604 GdkRectangle child_area;
605 GList *children;
606
607 g_return_if_fail (widget != NULL);
608 g_return_if_fail (GTK_IS_MYFIXED (widget));
609
610 if (GTK_WIDGET_DRAWABLE (widget))
611 {
612 myfixed = GTK_MYFIXED (widget);
f7a11f8c 613
c801d85f 614 children = myfixed->children;
f7a11f8c
RR
615 if (children) /* mini optimisation */
616 gtk_myfixed_paint (widget, area);
617
c801d85f
KB
618 while (children)
619 {
620 child = children->data;
621 children = children->next;
622
623 if (gtk_widget_intersect (child->widget, area, &child_area))
624 gtk_widget_draw (child->widget, &child_area);
625 }
626 }
627}
628
629static gint
630gtk_myfixed_expose (GtkWidget *widget,
fdd3ed7a 631 GdkEventExpose *event)
c801d85f
KB
632{
633 GtkMyFixed *myfixed;
634 GtkMyFixedChild *child;
635 GdkEventExpose child_event;
636 GList *children;
637
638 g_return_val_if_fail (widget != NULL, FALSE);
639 g_return_val_if_fail (GTK_IS_MYFIXED (widget), FALSE);
640 g_return_val_if_fail (event != NULL, FALSE);
641
642 if (GTK_WIDGET_DRAWABLE (widget))
643 {
644 myfixed = GTK_MYFIXED (widget);
645
646 child_event = *event;
647
648 children = myfixed->children;
649 while (children)
650 {
651 child = children->data;
652 children = children->next;
653
654 if (GTK_WIDGET_NO_WINDOW (child->widget) &&
655 gtk_widget_intersect (child->widget, &event->area,
656 &child_event.area))
657 gtk_widget_event (child->widget, (GdkEvent*) &child_event);
658 }
659 }
660
661 return FALSE;
662}
663
664static void
665gtk_myfixed_add (GtkContainer *container,
666 GtkWidget *widget)
667{
668 g_return_if_fail (container != NULL);
669 g_return_if_fail (GTK_IS_MYFIXED (container));
670 g_return_if_fail (widget != NULL);
671
fdd3ed7a 672 gtk_myfixed_put (GTK_MYFIXED (container), widget, 0, 0, 20, 20 );
c801d85f
KB
673}
674
675static void
676gtk_myfixed_remove (GtkContainer *container,
677 GtkWidget *widget)
678{
679 GtkMyFixed *myfixed;
680 GtkMyFixedChild *child;
681 GList *children;
682
683 g_return_if_fail (container != NULL);
684 g_return_if_fail (GTK_IS_MYFIXED (container));
685 g_return_if_fail (widget != NULL);
686
687 myfixed = GTK_MYFIXED (container);
688
689 children = myfixed->children;
690 while (children)
691 {
692 child = children->data;
693
694 if (child->widget == widget)
695 {
d872b8a9
RR
696 gboolean was_visible = GTK_WIDGET_VISIBLE (widget);
697
c801d85f
KB
698 gtk_widget_unparent (widget);
699
5fd11f09
RR
700 /* security checks */
701 g_return_if_fail (GTK_IS_WIDGET (widget));
702
c801d85f
KB
703 myfixed->children = g_list_remove_link (myfixed->children, children);
704 g_list_free (children);
705 g_free (child);
706
d872b8a9 707 if (was_visible && GTK_WIDGET_VISIBLE (container))
c801d85f
KB
708 gtk_widget_queue_resize (GTK_WIDGET (container));
709
5fd11f09
RR
710 /* security checks */
711 g_return_if_fail (GTK_IS_WIDGET (widget));
712
c801d85f
KB
713 break;
714 }
715
716 children = children->next;
717 }
718}
719
720static void
721gtk_myfixed_foreach (GtkContainer *container,
d345e841 722#if (GTK_MINOR_VERSION > 0)
75ed1d15
GL
723 gboolean include_internals,
724#endif
c801d85f
KB
725 GtkCallback callback,
726 gpointer callback_data)
727{
728 GtkMyFixed *myfixed;
729 GtkMyFixedChild *child;
730 GList *children;
731
732 g_return_if_fail (container != NULL);
733 g_return_if_fail (GTK_IS_MYFIXED (container));
734 g_return_if_fail (callback != NULL);
735
736 myfixed = GTK_MYFIXED (container);
737
738 children = myfixed->children;
739 while (children)
740 {
741 child = children->data;
742 children = children->next;
743
744 (* callback) (child->widget, callback_data);
745 }
746}
747
748
749#ifdef __cplusplus
750}
751#endif /* __cplusplus */
752