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/.
28 #include "gtkviewport.h"
29 #include "gtkextendedlayout.h"
31 #include "gtkmarshalers.h"
32 #include "gtkprivate.h"
43 static void gtk_viewport_finalize (GObject *object);
44 static void gtk_viewport_destroy (GtkObject *object);
45 static void gtk_viewport_set_property (GObject *object,
49 static void gtk_viewport_get_property (GObject *object,
53 static void gtk_viewport_set_scroll_adjustments (GtkViewport *viewport,
54 GtkAdjustment *hadjustment,
55 GtkAdjustment *vadjustment);
56 static void gtk_viewport_realize (GtkWidget *widget);
57 static void gtk_viewport_unrealize (GtkWidget *widget);
58 static void gtk_viewport_paint (GtkWidget *widget,
60 static gint gtk_viewport_expose (GtkWidget *widget,
61 GdkEventExpose *event);
62 static void gtk_viewport_add (GtkContainer *container,
64 static void gtk_viewport_size_allocate (GtkWidget *widget,
65 GtkAllocation *allocation);
66 static void gtk_viewport_adjustment_value_changed (GtkAdjustment *adjustment,
68 static void gtk_viewport_style_set (GtkWidget *widget,
69 GtkStyle *previous_style);
71 static void gtk_viewport_extended_layout_init (GtkExtendedLayoutIface *iface);
73 G_DEFINE_TYPE_WITH_CODE (GtkViewport, gtk_viewport, GTK_TYPE_BIN,
74 G_IMPLEMENT_INTERFACE (GTK_TYPE_EXTENDED_LAYOUT,
75 gtk_viewport_extended_layout_init))
78 gtk_viewport_class_init (GtkViewportClass *class)
80 GtkObjectClass *object_class;
81 GObjectClass *gobject_class;
82 GtkWidgetClass *widget_class;
83 GtkContainerClass *container_class;
85 object_class = (GtkObjectClass*) class;
86 gobject_class = G_OBJECT_CLASS (class);
87 widget_class = (GtkWidgetClass*) class;
88 container_class = (GtkContainerClass*) class;
90 gobject_class->finalize = gtk_viewport_finalize;
91 gobject_class->set_property = gtk_viewport_set_property;
92 gobject_class->get_property = gtk_viewport_get_property;
93 object_class->destroy = gtk_viewport_destroy;
95 widget_class->realize = gtk_viewport_realize;
96 widget_class->unrealize = gtk_viewport_unrealize;
97 widget_class->expose_event = gtk_viewport_expose;
98 widget_class->size_allocate = gtk_viewport_size_allocate;
99 widget_class->style_set = gtk_viewport_style_set;
101 container_class->add = gtk_viewport_add;
103 class->set_scroll_adjustments = gtk_viewport_set_scroll_adjustments;
105 g_object_class_install_property (gobject_class,
107 g_param_spec_object ("hadjustment",
108 P_("Horizontal adjustment"),
109 P_("The GtkAdjustment that determines the values of the horizontal position for this viewport"),
111 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
113 g_object_class_install_property (gobject_class,
115 g_param_spec_object ("vadjustment",
116 P_("Vertical adjustment"),
117 P_("The GtkAdjustment that determines the values of the vertical position for this viewport"),
119 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
121 g_object_class_install_property (gobject_class,
123 g_param_spec_enum ("shadow-type",
125 P_("Determines how the shadowed box around the viewport is drawn"),
126 GTK_TYPE_SHADOW_TYPE,
128 GTK_PARAM_READWRITE));
131 * GtkViewport::set-scroll-adjustments
132 * @horizontal: the horizontal #GtkAdjustment
133 * @vertical: the vertical #GtkAdjustment
135 * Set the scroll adjustments for the viewport. Usually scrolled containers
136 * like #GtkScrolledWindow will emit this signal to connect two instances
137 * of #GtkScrollbar to the scroll directions of the #GtkViewport.
139 widget_class->set_scroll_adjustments_signal =
140 g_signal_new (I_("set-scroll-adjustments"),
141 G_OBJECT_CLASS_TYPE (gobject_class),
142 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
143 G_STRUCT_OFFSET (GtkViewportClass, set_scroll_adjustments),
145 _gtk_marshal_VOID__OBJECT_OBJECT,
148 GTK_TYPE_ADJUSTMENT);
152 gtk_viewport_set_property (GObject *object,
157 GtkViewport *viewport;
159 viewport = GTK_VIEWPORT (object);
163 case PROP_HADJUSTMENT:
164 gtk_viewport_set_hadjustment (viewport, g_value_get_object (value));
166 case PROP_VADJUSTMENT:
167 gtk_viewport_set_vadjustment (viewport, g_value_get_object (value));
169 case PROP_SHADOW_TYPE:
170 gtk_viewport_set_shadow_type (viewport, g_value_get_enum (value));
173 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
179 gtk_viewport_get_property (GObject *object,
184 GtkViewport *viewport;
186 viewport = GTK_VIEWPORT (object);
190 case PROP_HADJUSTMENT:
191 g_value_set_object (value, viewport->hadjustment);
193 case PROP_VADJUSTMENT:
194 g_value_set_object (value, viewport->vadjustment);
196 case PROP_SHADOW_TYPE:
197 g_value_set_enum (value, viewport->shadow_type);
200 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
206 gtk_viewport_init (GtkViewport *viewport)
208 gtk_widget_set_has_window (GTK_WIDGET (viewport), TRUE);
210 gtk_widget_set_redraw_on_allocate (GTK_WIDGET (viewport), FALSE);
211 gtk_container_set_resize_mode (GTK_CONTAINER (viewport), GTK_RESIZE_QUEUE);
213 viewport->shadow_type = GTK_SHADOW_IN;
214 viewport->view_window = NULL;
215 viewport->bin_window = NULL;
216 viewport->hadjustment = NULL;
217 viewport->vadjustment = NULL;
222 * @hadjustment: horizontal adjustment.
223 * @vadjustment: vertical adjustment.
224 * @returns: a new #GtkViewport.
226 * Creates a new #GtkViewport with the given adjustments.
230 gtk_viewport_new (GtkAdjustment *hadjustment,
231 GtkAdjustment *vadjustment)
235 viewport = g_object_new (GTK_TYPE_VIEWPORT,
236 "hadjustment", hadjustment,
237 "vadjustment", vadjustment,
243 #define ADJUSTMENT_POINTER(viewport, orientation) \
244 (((orientation) == GTK_ORIENTATION_HORIZONTAL) ? \
245 &(viewport)->hadjustment : &(viewport)->vadjustment)
248 viewport_disconnect_adjustment (GtkViewport *viewport,
249 GtkOrientation orientation)
251 GtkAdjustment **adjustmentp = ADJUSTMENT_POINTER (viewport, orientation);
255 g_signal_handlers_disconnect_by_func (*adjustmentp,
256 gtk_viewport_adjustment_value_changed,
258 g_object_unref (*adjustmentp);
264 gtk_viewport_finalize (GObject *object)
266 GtkViewport *viewport = GTK_VIEWPORT (object);
268 viewport_disconnect_adjustment (viewport, GTK_ORIENTATION_HORIZONTAL);
269 viewport_disconnect_adjustment (viewport, GTK_ORIENTATION_VERTICAL);
271 G_OBJECT_CLASS (gtk_viewport_parent_class)->finalize (object);
275 gtk_viewport_destroy (GtkObject *object)
277 GtkViewport *viewport = GTK_VIEWPORT (object);
279 viewport_disconnect_adjustment (viewport, GTK_ORIENTATION_HORIZONTAL);
280 viewport_disconnect_adjustment (viewport, GTK_ORIENTATION_VERTICAL);
282 GTK_OBJECT_CLASS (gtk_viewport_parent_class)->destroy (object);
286 * gtk_viewport_get_hadjustment:
287 * @viewport: a #GtkViewport.
289 * Returns the horizontal adjustment of the viewport.
291 * Return value: the horizontal adjustment of @viewport.
294 gtk_viewport_get_hadjustment (GtkViewport *viewport)
296 g_return_val_if_fail (GTK_IS_VIEWPORT (viewport), NULL);
298 if (!viewport->hadjustment)
299 gtk_viewport_set_hadjustment (viewport, NULL);
301 return viewport->hadjustment;
305 * gtk_viewport_get_vadjustment:
306 * @viewport: a #GtkViewport.
308 * Returns the vertical adjustment of the viewport.
310 * Return value: the vertical adjustment of @viewport.
313 gtk_viewport_get_vadjustment (GtkViewport *viewport)
315 g_return_val_if_fail (GTK_IS_VIEWPORT (viewport), NULL);
317 if (!viewport->vadjustment)
318 gtk_viewport_set_vadjustment (viewport, NULL);
320 return viewport->vadjustment;
324 viewport_get_view_allocation (GtkViewport *viewport,
325 GtkAllocation *view_allocation)
327 GtkWidget *widget = GTK_WIDGET (viewport);
328 GtkAllocation *allocation = &widget->allocation;
329 gint border_width = GTK_CONTAINER (viewport)->border_width;
331 view_allocation->x = 0;
332 view_allocation->y = 0;
334 if (viewport->shadow_type != GTK_SHADOW_NONE)
336 view_allocation->x = widget->style->xthickness;
337 view_allocation->y = widget->style->ythickness;
340 view_allocation->width = MAX (1, allocation->width - view_allocation->x * 2 - border_width * 2);
341 view_allocation->height = MAX (1, allocation->height - view_allocation->y * 2 - border_width * 2);
345 viewport_reclamp_adjustment (GtkAdjustment *adjustment,
346 gboolean *value_changed)
348 gdouble value = adjustment->value;
350 value = CLAMP (value, 0, adjustment->upper - adjustment->page_size);
351 if (value != adjustment->value)
353 adjustment->value = value;
355 *value_changed = TRUE;
357 else if (value_changed)
358 *value_changed = FALSE;
362 viewport_set_hadjustment_values (GtkViewport *viewport,
363 gboolean *value_changed)
365 GtkBin *bin = GTK_BIN (viewport);
366 GtkAllocation view_allocation;
367 GtkAdjustment *hadjustment = gtk_viewport_get_hadjustment (viewport);
368 gdouble old_page_size;
372 viewport_get_view_allocation (viewport, &view_allocation);
374 old_page_size = hadjustment->page_size;
375 old_upper = hadjustment->upper;
376 old_value = hadjustment->value;
377 hadjustment->page_size = view_allocation.width;
378 hadjustment->step_increment = view_allocation.width * 0.1;
379 hadjustment->page_increment = view_allocation.width * 0.9;
381 hadjustment->lower = 0;
383 if (bin->child && gtk_widget_get_visible (bin->child))
385 GtkRequisition child_requisition;
387 gtk_widget_get_child_requisition (bin->child, &child_requisition);
388 hadjustment->upper = MAX (child_requisition.width, view_allocation.width);
391 hadjustment->upper = view_allocation.width;
393 if (gtk_widget_get_direction (GTK_WIDGET (viewport)) == GTK_TEXT_DIR_RTL)
395 gdouble dist = old_upper - (old_value + old_page_size);
396 hadjustment->value = hadjustment->upper - dist - hadjustment->page_size;
397 viewport_reclamp_adjustment (hadjustment, value_changed);
398 *value_changed = (old_value != hadjustment->value);
401 viewport_reclamp_adjustment (hadjustment, value_changed);
405 viewport_set_vadjustment_values (GtkViewport *viewport,
406 gboolean *value_changed)
408 GtkBin *bin = GTK_BIN (viewport);
409 GtkAllocation view_allocation;
410 GtkAdjustment *vadjustment = gtk_viewport_get_vadjustment (viewport);
412 viewport_get_view_allocation (viewport, &view_allocation);
414 vadjustment->page_size = view_allocation.height;
415 vadjustment->step_increment = view_allocation.height * 0.1;
416 vadjustment->page_increment = view_allocation.height * 0.9;
418 vadjustment->lower = 0;
420 if (bin->child && gtk_widget_get_visible (bin->child))
424 gtk_extended_layout_get_height_for_width (GTK_EXTENDED_LAYOUT (bin->child),
425 view_allocation.width,
428 vadjustment->upper = MAX (natural_height, view_allocation.height);
431 vadjustment->upper = view_allocation.height;
433 viewport_reclamp_adjustment (vadjustment, value_changed);
437 viewport_set_adjustment (GtkViewport *viewport,
438 GtkOrientation orientation,
439 GtkAdjustment *adjustment)
441 GtkAdjustment **adjustmentp = ADJUSTMENT_POINTER (viewport, orientation);
442 gboolean value_changed;
444 if (adjustment && adjustment == *adjustmentp)
448 adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0,
450 viewport_disconnect_adjustment (viewport, orientation);
451 *adjustmentp = adjustment;
452 g_object_ref_sink (adjustment);
454 if (orientation == GTK_ORIENTATION_HORIZONTAL)
455 viewport_set_hadjustment_values (viewport, &value_changed);
457 viewport_set_vadjustment_values (viewport, &value_changed);
459 g_signal_connect (adjustment, "value-changed",
460 G_CALLBACK (gtk_viewport_adjustment_value_changed),
463 gtk_adjustment_changed (adjustment);
466 gtk_adjustment_value_changed (adjustment);
468 gtk_viewport_adjustment_value_changed (adjustment, viewport);
472 * gtk_viewport_set_hadjustment:
473 * @viewport: a #GtkViewport.
474 * @adjustment: (allow-none): a #GtkAdjustment.
476 * Sets the horizontal adjustment of the viewport.
479 gtk_viewport_set_hadjustment (GtkViewport *viewport,
480 GtkAdjustment *adjustment)
482 g_return_if_fail (GTK_IS_VIEWPORT (viewport));
484 g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
486 viewport_set_adjustment (viewport, GTK_ORIENTATION_HORIZONTAL, adjustment);
488 g_object_notify (G_OBJECT (viewport), "hadjustment");
492 * gtk_viewport_set_vadjustment:
493 * @viewport: a #GtkViewport.
494 * @adjustment: (allow-none): a #GtkAdjustment.
496 * Sets the vertical adjustment of the viewport.
499 gtk_viewport_set_vadjustment (GtkViewport *viewport,
500 GtkAdjustment *adjustment)
502 g_return_if_fail (GTK_IS_VIEWPORT (viewport));
504 g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
506 viewport_set_adjustment (viewport, GTK_ORIENTATION_VERTICAL, adjustment);
508 g_object_notify (G_OBJECT (viewport), "vadjustment");
512 gtk_viewport_set_scroll_adjustments (GtkViewport *viewport,
513 GtkAdjustment *hadjustment,
514 GtkAdjustment *vadjustment)
516 gtk_viewport_set_hadjustment (viewport, hadjustment);
517 gtk_viewport_set_vadjustment (viewport, vadjustment);
521 * gtk_viewport_set_shadow_type:
522 * @viewport: a #GtkViewport.
523 * @type: the new shadow type.
525 * Sets the shadow type of the viewport.
528 gtk_viewport_set_shadow_type (GtkViewport *viewport,
531 g_return_if_fail (GTK_IS_VIEWPORT (viewport));
533 if ((GtkShadowType) viewport->shadow_type != type)
535 viewport->shadow_type = type;
537 if (gtk_widget_get_visible (GTK_WIDGET (viewport)))
539 gtk_widget_size_allocate (GTK_WIDGET (viewport), &(GTK_WIDGET (viewport)->allocation));
540 gtk_widget_queue_draw (GTK_WIDGET (viewport));
543 g_object_notify (G_OBJECT (viewport), "shadow-type");
548 * gtk_viewport_get_shadow_type:
549 * @viewport: a #GtkViewport
551 * Gets the shadow type of the #GtkViewport. See
552 * gtk_viewport_set_shadow_type().
554 * Return value: the shadow type
557 gtk_viewport_get_shadow_type (GtkViewport *viewport)
559 g_return_val_if_fail (GTK_IS_VIEWPORT (viewport), GTK_SHADOW_NONE);
561 return viewport->shadow_type;
565 * gtk_viewport_get_bin_window:
566 * @viewport: a #GtkViewport
568 * Gets the bin window of the #GtkViewport.
570 * Return value: a #GdkWindow
575 gtk_viewport_get_bin_window (GtkViewport *viewport)
577 g_return_val_if_fail (GTK_IS_VIEWPORT (viewport), NULL);
579 return viewport->bin_window;
583 gtk_viewport_realize (GtkWidget *widget)
585 GtkViewport *viewport = GTK_VIEWPORT (widget);
586 GtkBin *bin = GTK_BIN (widget);
587 GtkAdjustment *hadjustment = gtk_viewport_get_hadjustment (viewport);
588 GtkAdjustment *vadjustment = gtk_viewport_get_vadjustment (viewport);
589 gint border_width = GTK_CONTAINER (widget)->border_width;
591 GtkAllocation view_allocation;
592 GdkWindowAttr attributes;
593 gint attributes_mask;
596 gtk_widget_set_realized (widget, TRUE);
598 attributes.x = widget->allocation.x + border_width;
599 attributes.y = widget->allocation.y + border_width;
600 attributes.width = widget->allocation.width - border_width * 2;
601 attributes.height = widget->allocation.height - border_width * 2;
602 attributes.window_type = GDK_WINDOW_CHILD;
603 attributes.wclass = GDK_INPUT_OUTPUT;
604 attributes.visual = gtk_widget_get_visual (widget);
605 attributes.colormap = gtk_widget_get_colormap (widget);
607 event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
608 /* We select on button_press_mask so that button 4-5 scrolls are trapped.
610 attributes.event_mask = event_mask | GDK_BUTTON_PRESS_MASK;
612 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
614 widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
615 &attributes, attributes_mask);
616 gdk_window_set_user_data (widget->window, viewport);
618 viewport_get_view_allocation (viewport, &view_allocation);
620 attributes.x = view_allocation.x;
621 attributes.y = view_allocation.y;
622 attributes.width = view_allocation.width;
623 attributes.height = view_allocation.height;
624 attributes.event_mask = 0;
626 viewport->view_window = gdk_window_new (widget->window, &attributes, attributes_mask);
627 gdk_window_set_user_data (viewport->view_window, viewport);
629 gdk_window_set_back_pixmap (viewport->view_window, NULL, FALSE);
631 attributes.x = - hadjustment->value;
632 attributes.y = - vadjustment->value;
633 attributes.width = hadjustment->upper;
634 attributes.height = vadjustment->upper;
636 attributes.event_mask = event_mask;
638 viewport->bin_window = gdk_window_new (viewport->view_window, &attributes, attributes_mask);
639 gdk_window_set_user_data (viewport->bin_window, viewport);
642 gtk_widget_set_parent_window (bin->child, viewport->bin_window);
644 widget->style = gtk_style_attach (widget->style, widget->window);
645 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
646 gtk_style_set_background (widget->style, viewport->bin_window, GTK_STATE_NORMAL);
648 /* Call paint here to allow a theme to set the background without flashing
650 gtk_paint_flat_box(widget->style, viewport->bin_window, GTK_STATE_NORMAL,
652 NULL, widget, "viewportbin",
655 gdk_window_show (viewport->bin_window);
656 gdk_window_show (viewport->view_window);
660 gtk_viewport_unrealize (GtkWidget *widget)
662 GtkViewport *viewport = GTK_VIEWPORT (widget);
664 gdk_window_set_user_data (viewport->view_window, NULL);
665 gdk_window_destroy (viewport->view_window);
666 viewport->view_window = NULL;
668 gdk_window_set_user_data (viewport->bin_window, NULL);
669 gdk_window_destroy (viewport->bin_window);
670 viewport->bin_window = NULL;
672 GTK_WIDGET_CLASS (gtk_viewport_parent_class)->unrealize (widget);
676 gtk_viewport_paint (GtkWidget *widget,
679 if (gtk_widget_is_drawable (widget))
681 GtkViewport *viewport = GTK_VIEWPORT (widget);
683 gtk_paint_shadow (widget->style, widget->window,
684 GTK_STATE_NORMAL, viewport->shadow_type,
685 area, widget, "viewport",
691 gtk_viewport_expose (GtkWidget *widget,
692 GdkEventExpose *event)
694 GtkViewport *viewport;
696 if (gtk_widget_is_drawable (widget))
698 viewport = GTK_VIEWPORT (widget);
700 if (event->window == widget->window)
701 gtk_viewport_paint (widget, &event->area);
702 else if (event->window == viewport->bin_window)
704 gtk_paint_flat_box(widget->style, viewport->bin_window,
705 GTK_STATE_NORMAL, GTK_SHADOW_NONE,
706 &event->area, widget, "viewportbin",
709 GTK_WIDGET_CLASS (gtk_viewport_parent_class)->expose_event (widget, event);
717 gtk_viewport_add (GtkContainer *container,
720 GtkBin *bin = GTK_BIN (container);
722 g_return_if_fail (bin->child == NULL);
724 gtk_widget_set_parent_window (child, GTK_VIEWPORT (bin)->bin_window);
726 GTK_CONTAINER_CLASS (gtk_viewport_parent_class)->add (container, child);
730 gtk_viewport_size_allocate (GtkWidget *widget,
731 GtkAllocation *allocation)
733 GtkViewport *viewport = GTK_VIEWPORT (widget);
734 GtkBin *bin = GTK_BIN (widget);
735 gint border_width = GTK_CONTAINER (widget)->border_width;
736 gboolean hadjustment_value_changed, vadjustment_value_changed;
737 GtkAdjustment *hadjustment = gtk_viewport_get_hadjustment (viewport);
738 GtkAdjustment *vadjustment = gtk_viewport_get_vadjustment (viewport);
739 GtkAllocation child_allocation;
741 /* If our size changed, and we have a shadow, queue a redraw on widget->window to
742 * redraw the shadow correctly.
744 if (gtk_widget_get_mapped (widget) &&
745 viewport->shadow_type != GTK_SHADOW_NONE &&
746 (widget->allocation.width != allocation->width ||
747 widget->allocation.height != allocation->height))
748 gdk_window_invalidate_rect (widget->window, NULL, FALSE);
750 widget->allocation = *allocation;
752 viewport_set_hadjustment_values (viewport, &hadjustment_value_changed);
753 viewport_set_vadjustment_values (viewport, &vadjustment_value_changed);
755 child_allocation.x = 0;
756 child_allocation.y = 0;
757 child_allocation.width = hadjustment->upper;
758 child_allocation.height = vadjustment->upper;
759 if (gtk_widget_get_realized (widget))
761 GtkAllocation view_allocation;
762 gdk_window_move_resize (widget->window,
763 allocation->x + border_width,
764 allocation->y + border_width,
765 allocation->width - border_width * 2,
766 allocation->height - border_width * 2);
768 viewport_get_view_allocation (viewport, &view_allocation);
769 gdk_window_move_resize (viewport->view_window,
772 view_allocation.width,
773 view_allocation.height);
774 gdk_window_move_resize (viewport->bin_window,
775 - hadjustment->value,
776 - vadjustment->value,
777 child_allocation.width,
778 child_allocation.height);
780 if (bin->child && gtk_widget_get_visible (bin->child))
781 gtk_widget_size_allocate (bin->child, &child_allocation);
783 gtk_adjustment_changed (hadjustment);
784 gtk_adjustment_changed (vadjustment);
785 if (hadjustment_value_changed)
786 gtk_adjustment_value_changed (hadjustment);
787 if (vadjustment_value_changed)
788 gtk_adjustment_value_changed (vadjustment);
792 gtk_viewport_adjustment_value_changed (GtkAdjustment *adjustment,
795 GtkViewport *viewport = GTK_VIEWPORT (data);
796 GtkBin *bin = GTK_BIN (data);
798 if (bin->child && gtk_widget_get_visible (bin->child) &&
799 gtk_widget_get_realized (GTK_WIDGET (viewport)))
801 GtkAdjustment *hadjustment = gtk_viewport_get_hadjustment (viewport);
802 GtkAdjustment *vadjustment = gtk_viewport_get_vadjustment (viewport);
806 gdk_window_get_position (viewport->bin_window, &old_x, &old_y);
807 new_x = - hadjustment->value;
808 new_y = - vadjustment->value;
810 if (new_x != old_x || new_y != old_y)
812 gdk_window_move (viewport->bin_window, new_x, new_y);
813 gdk_window_process_updates (viewport->bin_window, TRUE);
819 gtk_viewport_style_set (GtkWidget *widget,
820 GtkStyle *previous_style)
822 if (gtk_widget_get_realized (widget) &&
823 gtk_widget_get_has_window (widget))
825 GtkViewport *viewport = GTK_VIEWPORT (widget);
827 gtk_style_set_background (widget->style, viewport->bin_window, GTK_STATE_NORMAL);
828 gtk_style_set_background (widget->style, widget->window, widget->state);
833 gtk_viewport_get_desired_size (GtkExtendedLayout *layout,
834 GtkRequisition *minimum_size,
835 GtkRequisition *natural_size)
838 GtkRequisition child_min, child_nat;
840 child = gtk_bin_get_child (GTK_BIN (layout));
842 minimum_size->width = GTK_CONTAINER (layout)->border_width;
843 minimum_size->height = GTK_CONTAINER (layout)->border_width;
844 natural_size->width = GTK_CONTAINER (layout)->border_width;
845 natural_size->height = GTK_CONTAINER (layout)->border_width;
847 if (GTK_VIEWPORT (layout)->shadow_type != GTK_SHADOW_NONE)
849 minimum_size->width += 2 * GTK_WIDGET (layout)->style->xthickness;
850 minimum_size->height += 2 * GTK_WIDGET (layout)->style->ythickness;
851 natural_size->width += 2 * GTK_WIDGET (layout)->style->xthickness;
852 natural_size->height += 2 * GTK_WIDGET (layout)->style->ythickness;
855 if (child && gtk_widget_get_visible (child))
857 gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (child), &child_min, &child_nat);
859 minimum_size->width += child_min.width;
860 minimum_size->height += child_min.height;
861 natural_size->width += child_nat.width;
862 natural_size->height += child_nat.height;
867 gtk_viewport_extended_layout_init (GtkExtendedLayoutIface *iface)
869 iface->get_desired_size = gtk_viewport_get_desired_size;
872 #define __GTK_VIEWPORT_C__
873 #include "gtkaliasdef.c"