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