]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk/win_gtk.c
don't include missing.h before windows headers
[wxWidgets.git] / src / gtk / win_gtk.c
... / ...
CommitLineData
1/* ///////////////////////////////////////////////////////////////////////////
2// Name: src/gtk/win_gtk.c
3// Purpose: Native GTK+ widget for wxWidgets, based on GtkLayout and
4// GtkFixed. It makes use of the gravity window property and
5// therefore does not work with GTK 1.0.
6// Author: Robert Roebling
7// Id: $Id$
8// Copyright: (c) 1998 Robert Roebling
9// Licence: wxWidgets licence
10/////////////////////////////////////////////////////////////////////////// */
11
12#ifdef VMS
13#define XCheckIfEvent XCHECKIFEVENT
14#endif
15
16#include "wx/platform.h"
17#include "wx/gtk/win_gtk.h"
18
19#ifdef __cplusplus
20extern "C" {
21#endif /* __cplusplus */
22
23typedef struct _GtkPizzaAdjData GtkPizzaAdjData;
24
25struct _GtkPizzaAdjData
26{
27 gint dx;
28 gint dy;
29};
30
31static void gtk_pizza_class_init (GtkPizzaClass *klass);
32static void gtk_pizza_init (GtkPizza *pizza);
33
34static void gtk_pizza_realize (GtkWidget *widget);
35static void gtk_pizza_unrealize (GtkWidget *widget);
36
37static void gtk_pizza_map (GtkWidget *widget);
38
39static void gtk_pizza_size_request (GtkWidget *widget,
40 GtkRequisition *requisition);
41static void gtk_pizza_size_allocate (GtkWidget *widget,
42 GtkAllocation *allocation);
43static gint gtk_pizza_expose (GtkWidget *widget,
44 GdkEventExpose *event);
45static void gtk_pizza_style_set (GtkWidget *widget,
46 GtkStyle *previous_style);
47static void gtk_pizza_add (GtkContainer *container,
48 GtkWidget *widget);
49static void gtk_pizza_remove (GtkContainer *container,
50 GtkWidget *widget);
51static void gtk_pizza_forall (GtkContainer *container,
52 gboolean include_internals,
53 GtkCallback callback,
54 gpointer callback_data);
55
56static void gtk_pizza_allocate_child (GtkPizza *pizza,
57 GtkPizzaChild *child);
58static void gtk_pizza_adjust_allocations_recurse (GtkWidget *widget,
59 gpointer cb_data);
60
61static GtkType gtk_pizza_child_type (GtkContainer *container);
62
63static void gtk_pizza_scroll_set_adjustments (GtkPizza *pizza,
64 GtkAdjustment *hadj,
65 GtkAdjustment *vadj);
66
67static GtkWidgetClass* pizza_parent_class;
68
69GtkType
70gtk_pizza_get_type ()
71{
72 static GtkType pizza_type = 0;
73
74 if (!pizza_type)
75 {
76 static const GTypeInfo pizza_info =
77 {
78 sizeof (GtkPizzaClass),
79 NULL, /* base_init */
80 NULL, /* base_finalize */
81 (GClassInitFunc) gtk_pizza_class_init,
82 NULL, /* class_finalize */
83 NULL, /* class_data */
84 sizeof (GtkPizza),
85 16, /* n_preallocs */
86 (GInstanceInitFunc) gtk_pizza_init,
87 NULL
88 };
89 pizza_type = g_type_register_static (GTK_TYPE_CONTAINER, "GtkPizza", &pizza_info, (GTypeFlags)0);
90 }
91
92 return pizza_type;
93}
94
95/* Marshaller needed for set_scroll_adjustments signal,
96 generated with GLib-2.4.6 glib-genmarshal */
97#define g_marshal_value_peek_object(v) g_value_get_object (v)
98static void
99g_cclosure_user_marshal_VOID__OBJECT_OBJECT (GClosure *closure,
100 GValue *return_value,
101 guint n_param_values,
102 const GValue *param_values,
103 gpointer invocation_hint,
104 gpointer marshal_data)
105{
106 typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT) (gpointer data1,
107 gpointer arg_1,
108 gpointer arg_2,
109 gpointer data2);
110 register GMarshalFunc_VOID__OBJECT_OBJECT callback;
111 register GCClosure *cc = (GCClosure*) closure;
112 register gpointer data1, data2;
113
114 g_return_if_fail (n_param_values == 3);
115
116 if (G_CCLOSURE_SWAP_DATA (closure))
117 {
118 data1 = closure->data;
119 data2 = g_value_peek_pointer (param_values + 0);
120 }
121 else
122 {
123 data1 = g_value_peek_pointer (param_values + 0);
124 data2 = closure->data;
125 }
126 callback = (GMarshalFunc_VOID__OBJECT_OBJECT) (marshal_data ? marshal_data : cc->callback);
127
128 callback (data1,
129 g_marshal_value_peek_object (param_values + 1),
130 g_marshal_value_peek_object (param_values + 2),
131 data2);
132}
133
134static void
135gtk_pizza_class_init (GtkPizzaClass *klass)
136{
137 GtkObjectClass *object_class;
138 GtkWidgetClass *widget_class;
139 GtkContainerClass *container_class;
140
141 object_class = (GtkObjectClass*) klass;
142 widget_class = (GtkWidgetClass*) klass;
143 container_class = (GtkContainerClass*) klass;
144 pizza_parent_class = gtk_type_class (GTK_TYPE_CONTAINER);
145
146 widget_class->map = gtk_pizza_map;
147 widget_class->realize = gtk_pizza_realize;
148 widget_class->unrealize = gtk_pizza_unrealize;
149 widget_class->size_request = gtk_pizza_size_request;
150 widget_class->size_allocate = gtk_pizza_size_allocate;
151 widget_class->expose_event = gtk_pizza_expose;
152 widget_class->style_set = gtk_pizza_style_set;
153
154 container_class->add = gtk_pizza_add;
155 container_class->remove = gtk_pizza_remove;
156 container_class->forall = gtk_pizza_forall;
157
158 container_class->child_type = gtk_pizza_child_type;
159
160 klass->set_scroll_adjustments = gtk_pizza_scroll_set_adjustments;
161
162 widget_class->set_scroll_adjustments_signal =
163 g_signal_new(
164 "set_scroll_adjustments",
165 G_TYPE_FROM_CLASS(object_class),
166 G_SIGNAL_RUN_LAST,
167 G_STRUCT_OFFSET(GtkPizzaClass, set_scroll_adjustments),
168 NULL,
169 NULL,
170 g_cclosure_user_marshal_VOID__OBJECT_OBJECT,
171 G_TYPE_NONE,
172 2,
173 GTK_TYPE_ADJUSTMENT,
174 GTK_TYPE_ADJUSTMENT);
175}
176
177static GtkType
178gtk_pizza_child_type (GtkContainer *container)
179{
180 return GTK_TYPE_WIDGET;
181}
182
183static void
184gtk_pizza_init (GtkPizza *pizza)
185{
186 GTK_WIDGET_UNSET_FLAGS (pizza, GTK_NO_WINDOW);
187
188 pizza->shadow_type = GTK_MYSHADOW_NONE;
189
190 pizza->children = NULL;
191
192 pizza->bin_window = NULL;
193
194 pizza->m_xoffset = 0;
195 pizza->m_yoffset = 0;
196
197 pizza->m_width = -1;
198}
199
200GtkWidget*
201gtk_pizza_new ()
202{
203 GtkPizza *pizza;
204
205 pizza = g_object_new (gtk_pizza_get_type (), NULL);
206
207 return GTK_WIDGET (pizza);
208}
209
210gint gtk_pizza_get_xoffset (GtkPizza *pizza)
211{
212 g_return_val_if_fail ( (pizza != NULL), -1 );
213 g_return_val_if_fail ( (GTK_IS_PIZZA (pizza)), -1 );
214
215 return pizza->m_xoffset;
216}
217
218gint gtk_pizza_get_yoffset (GtkPizza *pizza)
219{
220 g_return_val_if_fail ( (pizza != NULL), -1 );
221 g_return_val_if_fail ( (GTK_IS_PIZZA (pizza)), -1 );
222
223 return pizza->m_yoffset;
224}
225
226void gtk_pizza_set_xoffset (GtkPizza *pizza, gint xoffset)
227{
228 g_return_if_fail (pizza != NULL);
229 g_return_if_fail (GTK_IS_PIZZA (pizza));
230
231 pizza->m_xoffset = xoffset;
232 // do something
233}
234
235void gtk_pizza_set_yoffset (GtkPizza *pizza, gint yoffset)
236{
237 g_return_if_fail (pizza != NULL);
238 g_return_if_fail (GTK_IS_PIZZA (pizza));
239
240 pizza->m_xoffset = yoffset;
241 // do something
242}
243
244gint gtk_pizza_get_rtl_offset (GtkPizza *pizza)
245{
246 gint width;
247
248 g_return_val_if_fail ( (pizza != NULL), 0 );
249 g_return_val_if_fail ( (GTK_IS_PIZZA (pizza)), 0 );
250
251 if (!pizza->bin_window) return 0;
252
253 gdk_window_get_geometry( pizza->bin_window, NULL, NULL, &width, NULL, NULL );
254
255 return width;
256}
257
258
259static void
260gtk_pizza_scroll_set_adjustments (GtkPizza *pizza,
261 GtkAdjustment *hadj,
262 GtkAdjustment *vadj)
263{
264 /* We handle scrolling in the wxScrolledWindow, not here. */
265}
266
267void
268gtk_pizza_set_shadow_type (GtkPizza *pizza,
269 GtkMyShadowType type)
270{
271 g_return_if_fail (pizza != NULL);
272 g_return_if_fail (GTK_IS_PIZZA (pizza));
273
274 if (pizza->shadow_type != type)
275 {
276 pizza->shadow_type = type;
277
278 if (GTK_WIDGET_VISIBLE (pizza))
279 {
280 gtk_widget_size_allocate (GTK_WIDGET (pizza), &(GTK_WIDGET (pizza)->allocation));
281 gtk_widget_queue_draw (GTK_WIDGET (pizza));
282 }
283 }
284}
285
286void
287gtk_pizza_put (GtkPizza *pizza,
288 GtkWidget *widget,
289 gint x,
290 gint y,
291 gint width,
292 gint height)
293{
294 GtkPizzaChild *child_info;
295
296 g_return_if_fail (pizza != NULL);
297 g_return_if_fail (GTK_IS_PIZZA (pizza));
298 g_return_if_fail (widget != NULL);
299
300 if (gtk_widget_get_direction( GTK_WIDGET(pizza) ) == GTK_TEXT_DIR_RTL)
301 {
302 // reverse horizontal placement
303 x = pizza->m_width - x - width;
304 }
305
306 child_info = g_new (GtkPizzaChild, 1);
307
308 child_info->widget = widget;
309 child_info->x = x;
310 child_info->y = y;
311 child_info->width = width;
312 child_info->height = height;
313
314 if (GTK_IS_PIZZA(widget))
315 GTK_PIZZA(widget)->m_width = width;
316
317 pizza->children = g_list_append (pizza->children, child_info);
318
319 if (GTK_WIDGET_REALIZED (pizza))
320 gtk_widget_set_parent_window (widget, pizza->bin_window);
321
322 gtk_widget_set_parent (widget, GTK_WIDGET (pizza));
323
324 gtk_widget_set_size_request (widget, width, height);
325}
326
327void
328gtk_pizza_set_size (GtkPizza *pizza,
329 GtkWidget *widget,
330 gint x,
331 gint y,
332 gint width,
333 gint height)
334{
335 GtkPizzaChild *child;
336 GList *children;
337
338 g_return_if_fail (pizza != NULL);
339 g_return_if_fail (GTK_IS_PIZZA (pizza));
340 g_return_if_fail (widget != NULL);
341
342#ifndef WX_WARN_ILLEGAL_SETSIZE
343 /* this really shouldn't happen -- but it does, a lot, right now and we
344 can't pass negative values to gtk_widget_set_size_request() without getting
345 a warning printed out, so filter them out here */
346 if ( width < 0 )
347 width = 0;
348 if ( height < 0 )
349 height = 0;
350#endif
351
352 children = pizza->children;
353 while (children)
354 {
355 child = children->data;
356 children = children->next;
357
358 if (child->widget == widget)
359 {
360 gint new_x = x;
361 if (gtk_widget_get_direction( GTK_WIDGET(pizza) ) == GTK_TEXT_DIR_RTL)
362 {
363 // reverse horizontal placement
364 new_x = pizza->m_width - new_x - width;
365 }
366
367 if ((child->x == new_x) &&
368 (child->y == y) &&
369 (child->width == width) &&
370 (child->height == height)) return;
371
372 child->x = new_x;
373 child->y = y;
374 child->width = width;
375 child->height = height;
376
377 if (GTK_IS_PIZZA(widget))
378 GTK_PIZZA(widget)->m_width = width;
379
380 gtk_widget_set_size_request (widget, width, height);
381
382 return;
383 }
384 }
385}
386
387static void
388gtk_pizza_map (GtkWidget *widget)
389{
390 GtkPizza *pizza;
391 GtkPizzaChild *child;
392 GList *children;
393
394 g_return_if_fail (widget != NULL);
395 g_return_if_fail (GTK_IS_PIZZA (widget));
396
397 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
398 pizza = GTK_PIZZA (widget);
399
400 children = pizza->children;
401 while (children)
402 {
403 child = children->data;
404 children = children->next;
405
406 if ( GTK_WIDGET_VISIBLE (child->widget) &&
407 !GTK_WIDGET_MAPPED (child->widget) )
408 {
409 gtk_widget_map (child->widget);
410 }
411 }
412
413 gdk_window_show (widget->window);
414 gdk_window_show (pizza->bin_window);
415}
416
417static void
418gtk_pizza_realize (GtkWidget *widget)
419{
420 GtkPizza *pizza;
421 GdkWindowAttr attributes;
422 gint attributes_mask;
423 GtkPizzaChild *child;
424 GList *children;
425
426 g_return_if_fail (widget != NULL);
427 g_return_if_fail (GTK_IS_PIZZA (widget));
428
429 pizza = GTK_PIZZA (widget);
430 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
431
432 attributes.window_type = GDK_WINDOW_CHILD;
433
434 attributes.x = widget->allocation.x;
435 attributes.y = widget->allocation.y;
436 attributes.width = widget->allocation.width;
437 attributes.height = widget->allocation.height;
438
439#ifndef __WXUNIVERSAL__
440 if (pizza->shadow_type == GTK_MYSHADOW_NONE)
441 {
442 /* no border, no changes to sizes */
443 }
444 else if (pizza->shadow_type == GTK_MYSHADOW_THIN)
445 {
446 /* GTK_MYSHADOW_THIN == wxSIMPLE_BORDER */
447 attributes.x += 1;
448 attributes.y += 1;
449 attributes.width -= 2;
450 attributes.height -= 2;
451 }
452 else
453 {
454 /* GTK_MYSHADOW_IN == wxSUNKEN_BORDER */
455 /* GTK_MYSHADOW_OUT == wxRAISED_BORDER */
456 attributes.x += 2;
457 attributes.y += 2;
458 attributes.width -= 4;
459 attributes.height -= 4;
460 }
461#endif /* __WXUNIVERSAL__ */
462
463 /* minimal size */
464 if (attributes.width < 2) attributes.width = 2;
465 if (attributes.height < 2) attributes.height = 2;
466
467 attributes.wclass = GDK_INPUT_OUTPUT;
468 attributes.visual = gtk_widget_get_visual (widget);
469 attributes.colormap = gtk_widget_get_colormap (widget);
470 attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK;
471 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
472
473 widget->window = gdk_window_new(gtk_widget_get_parent_window (widget),
474 &attributes, attributes_mask);
475 gdk_window_set_user_data (widget->window, widget);
476
477 attributes.x = 0;
478 attributes.y = 0;
479
480 attributes.event_mask = gtk_widget_get_events (widget);
481 attributes.event_mask |= GDK_EXPOSURE_MASK |
482 GDK_SCROLL_MASK |
483 GDK_POINTER_MOTION_MASK |
484 GDK_POINTER_MOTION_HINT_MASK |
485 GDK_BUTTON_MOTION_MASK |
486 GDK_BUTTON1_MOTION_MASK |
487 GDK_BUTTON2_MOTION_MASK |
488 GDK_BUTTON3_MOTION_MASK |
489 GDK_BUTTON_PRESS_MASK |
490 GDK_BUTTON_RELEASE_MASK |
491 GDK_KEY_PRESS_MASK |
492 GDK_KEY_RELEASE_MASK |
493 GDK_ENTER_NOTIFY_MASK |
494 GDK_LEAVE_NOTIFY_MASK |
495 GDK_FOCUS_CHANGE_MASK;
496
497 pizza->bin_window = gdk_window_new(widget->window,
498 &attributes, attributes_mask);
499 gdk_window_set_user_data (pizza->bin_window, widget);
500
501 widget->style = gtk_style_attach (widget->style, widget->window);
502 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
503 gtk_style_set_background (widget->style, pizza->bin_window, GTK_STATE_NORMAL );
504
505/*
506 gdk_window_set_back_pixmap( widget->window, NULL, FALSE );
507 gdk_window_set_back_pixmap( pizza->bin_window, NULL, FALSE );
508*/
509
510 /* cannot be done before realisation */
511 children = pizza->children;
512 while (children)
513 {
514 child = children->data;
515 children = children->next;
516
517 gtk_widget_set_parent_window (child->widget, pizza->bin_window);
518 }
519}
520
521static void
522gtk_pizza_unrealize (GtkWidget *widget)
523{
524 GtkPizza *pizza;
525
526 g_return_if_fail (widget != NULL);
527 g_return_if_fail (GTK_IS_PIZZA (widget));
528
529 pizza = GTK_PIZZA (widget);
530
531 gdk_window_set_user_data (pizza->bin_window, NULL);
532 gdk_window_destroy (pizza->bin_window);
533 pizza->bin_window = NULL;
534
535 if (pizza_parent_class->unrealize)
536 pizza_parent_class->unrealize(widget);
537}
538
539static void
540gtk_pizza_size_request (GtkWidget *widget,
541 GtkRequisition *requisition)
542{
543 GtkPizza *pizza;
544 GtkPizzaChild *child;
545 GList *children;
546 GtkRequisition child_requisition;
547
548 g_return_if_fail (widget != NULL);
549 g_return_if_fail (GTK_IS_PIZZA (widget));
550 g_return_if_fail (requisition != NULL);
551
552 pizza = GTK_PIZZA (widget);
553
554 children = pizza->children;
555 while (children)
556 {
557 child = children->data;
558 children = children->next;
559
560 if (GTK_WIDGET_VISIBLE (child->widget))
561 {
562 gtk_widget_size_request (child->widget, &child_requisition);
563 }
564 }
565
566 /* request very little, I'm not sure if requesting nothing
567 will always have positive effects on stability... */
568 requisition->width = 2;
569 requisition->height = 2;
570}
571
572static void
573gtk_pizza_size_allocate (GtkWidget *widget,
574 GtkAllocation *allocation)
575{
576 GtkPizza *pizza;
577 gint border;
578 gint x,y,w,h;
579 GtkPizzaChild *child;
580 GList *children;
581
582 g_return_if_fail (widget != NULL);
583 g_return_if_fail (GTK_IS_PIZZA(widget));
584 g_return_if_fail (allocation != NULL);
585
586 pizza = GTK_PIZZA (widget);
587
588 widget->allocation = *allocation;
589
590 if (pizza->shadow_type == GTK_MYSHADOW_NONE)
591 border = 0;
592 else
593 if (pizza->shadow_type == GTK_MYSHADOW_THIN)
594 border = 1;
595 else
596 border = 2;
597
598 x = allocation->x + border;
599 y = allocation->y + border;
600 w = allocation->width - border*2;
601 h = allocation->height - border*2;
602 if (w < 0)
603 w = 0;
604 if (h < 0)
605 h = 0;
606
607 if (GTK_WIDGET_REALIZED (widget))
608 {
609 gdk_window_move_resize( widget->window, x, y, w, h );
610 gdk_window_move_resize( pizza->bin_window, 0, 0, w, h );
611 }
612
613 children = pizza->children;
614 while (children)
615 {
616 child = children->data;
617 children = children->next;
618
619 gtk_pizza_allocate_child (pizza, child);
620 }
621}
622
623static gint
624gtk_pizza_expose (GtkWidget *widget,
625 GdkEventExpose *event)
626{
627 GtkPizza *pizza;
628
629 g_return_val_if_fail (widget != NULL, FALSE);
630 g_return_val_if_fail (GTK_IS_PIZZA (widget), FALSE);
631 g_return_val_if_fail (event != NULL, FALSE);
632
633 pizza = (GtkPizza*)widget;
634
635 if (event->window != pizza->bin_window)
636 return FALSE;
637
638 pizza_parent_class->expose_event(widget, event);
639
640 return FALSE;
641}
642
643static void
644gtk_pizza_style_set(GtkWidget *widget, GtkStyle *previous_style)
645{
646 if (GTK_WIDGET_REALIZED(widget))
647 {
648 gtk_style_set_background(widget->style, widget->window, GTK_STATE_NORMAL);
649 gtk_style_set_background(widget->style, GTK_PIZZA(widget)->bin_window, GTK_STATE_NORMAL );
650 }
651
652 pizza_parent_class->style_set(widget, previous_style);
653}
654
655static void
656gtk_pizza_add (GtkContainer *container,
657 GtkWidget *widget)
658{
659 g_return_if_fail (container != NULL);
660 g_return_if_fail (GTK_IS_PIZZA (container));
661 g_return_if_fail (widget != NULL);
662
663 gtk_pizza_put (GTK_PIZZA (container), widget, 0, 0, 20, 20 );
664}
665
666static void
667gtk_pizza_remove (GtkContainer *container,
668 GtkWidget *widget)
669{
670 GtkPizza *pizza;
671 GtkPizzaChild *child;
672 GList *children;
673
674 g_return_if_fail (container != NULL);
675 g_return_if_fail (GTK_IS_PIZZA (container));
676 g_return_if_fail (widget != NULL);
677
678 pizza = GTK_PIZZA (container);
679
680 children = pizza->children;
681 while (children)
682 {
683 child = children->data;
684
685 if (child->widget == widget)
686 {
687 gtk_widget_unparent (widget);
688
689 /* security checks */
690 g_return_if_fail (GTK_IS_WIDGET (widget));
691
692 pizza->children = g_list_remove_link (pizza->children, children);
693 g_list_free (children);
694 g_free (child);
695
696 /* security checks */
697 g_return_if_fail (GTK_IS_WIDGET (widget));
698
699 break;
700 }
701
702 children = children->next;
703 }
704}
705
706static void
707gtk_pizza_forall (GtkContainer *container,
708 gboolean include_internals,
709 GtkCallback callback,
710 gpointer callback_data)
711{
712 GtkPizza *pizza;
713 GtkPizzaChild *child;
714 GList *children;
715
716 g_return_if_fail (container != NULL);
717 g_return_if_fail (GTK_IS_PIZZA (container));
718 g_return_if_fail (callback != (GtkCallback)NULL);
719
720 pizza = GTK_PIZZA (container);
721
722 children = pizza->children;
723 while (children)
724 {
725 child = children->data;
726 children = children->next;
727
728 (* callback) (child->widget, callback_data);
729 }
730}
731
732static void
733gtk_pizza_allocate_child (GtkPizza *pizza,
734 GtkPizzaChild *child)
735{
736 GtkAllocation allocation;
737 GtkRequisition requisition;
738
739 allocation.x = child->x - pizza->m_xoffset;
740 allocation.y = child->y - pizza->m_yoffset;
741 gtk_widget_get_child_requisition (child->widget, &requisition);
742 allocation.width = requisition.width;
743 allocation.height = requisition.height;
744
745 gtk_widget_size_allocate (child->widget, &allocation);
746}
747
748static void
749gtk_pizza_adjust_allocations_recurse (GtkWidget *widget,
750 gpointer cb_data)
751{
752 GtkPizzaAdjData *data = cb_data;
753
754 widget->allocation.x += data->dx;
755 widget->allocation.y += data->dy;
756
757 if (GTK_WIDGET_NO_WINDOW (widget) && GTK_IS_CONTAINER (widget))
758 {
759 gtk_container_forall (GTK_CONTAINER (widget),
760 gtk_pizza_adjust_allocations_recurse,
761 cb_data);
762 }
763}
764
765static void
766gtk_pizza_adjust_allocations (GtkPizza *pizza,
767 gint dx,
768 gint dy)
769{
770 GList *tmp_list;
771 GtkPizzaAdjData data;
772
773 data.dx = dx;
774 data.dy = dy;
775
776 tmp_list = pizza->children;
777 while (tmp_list)
778 {
779 GtkPizzaChild *child = tmp_list->data;
780 tmp_list = tmp_list->next;
781
782 child->widget->allocation.x += dx;
783 child->widget->allocation.y += dy;
784
785 if (GTK_WIDGET_NO_WINDOW (child->widget) &&
786 GTK_IS_CONTAINER (child->widget))
787 {
788 gtk_container_forall (GTK_CONTAINER (child->widget),
789 gtk_pizza_adjust_allocations_recurse,
790 &data);
791 }
792 }
793}
794
795void
796gtk_pizza_scroll (GtkPizza *pizza, gint dx, gint dy)
797{
798 pizza->m_xoffset += dx;
799 pizza->m_yoffset += dy;
800
801 gtk_pizza_adjust_allocations (pizza, -dx, -dy);
802
803 if (pizza->bin_window)
804 gdk_window_scroll( pizza->bin_window, -dx, -dy );
805}
806
807#ifdef __cplusplus
808}
809#endif /* __cplusplus */