X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkviewport.c;h=48fac8329ae86c2c137ae4924644bed097b9c605;hb=f35439bfacf90900e2c24f7ae3da173183c79d34;hp=e72945109dc850d613381cb81f33bdef90554d0e;hpb=ef33adff83617e2c937052316b9fb925d4972252;p=~andy%2Fgtk diff --git a/gtk/gtkviewport.c b/gtk/gtkviewport.c index e72945109..48fac8329 100644 --- a/gtk/gtkviewport.c +++ b/gtk/gtkviewport.c @@ -24,10 +24,12 @@ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ -#include "gtksignal.h" +#include #include "gtkviewport.h" #include "gtkintl.h" #include "gtkmarshalers.h" +#include "gtkprivate.h" +#include "gtkalias.h" enum { PROP_0, @@ -37,8 +39,7 @@ enum { }; -static void gtk_viewport_class_init (GtkViewportClass *klass); -static void gtk_viewport_init (GtkViewport *viewport); +static void gtk_viewport_finalize (GObject *object); static void gtk_viewport_destroy (GtkObject *object); static void gtk_viewport_set_property (GObject *object, guint prop_id, @@ -63,39 +64,12 @@ static void gtk_viewport_size_request (GtkWidget *widget, GtkRequisition *requisition); static void gtk_viewport_size_allocate (GtkWidget *widget, GtkAllocation *allocation); -static void gtk_viewport_adjustment_changed (GtkAdjustment *adjustment, - gpointer data); static void gtk_viewport_adjustment_value_changed (GtkAdjustment *adjustment, gpointer data); static void gtk_viewport_style_set (GtkWidget *widget, GtkStyle *previous_style); -static GtkBinClass *parent_class; - -GtkType -gtk_viewport_get_type (void) -{ - static GtkType viewport_type = 0; - - if (!viewport_type) - { - static const GtkTypeInfo viewport_info = - { - "GtkViewport", - sizeof (GtkViewport), - sizeof (GtkViewportClass), - (GtkClassInitFunc) gtk_viewport_class_init, - (GtkObjectInitFunc) gtk_viewport_init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - viewport_type = gtk_type_unique (GTK_TYPE_BIN, &viewport_info); - } - - return viewport_type; -} +G_DEFINE_TYPE (GtkViewport, gtk_viewport, GTK_TYPE_BIN) static void gtk_viewport_class_init (GtkViewportClass *class) @@ -109,8 +83,8 @@ gtk_viewport_class_init (GtkViewportClass *class) gobject_class = G_OBJECT_CLASS (class); widget_class = (GtkWidgetClass*) class; container_class = (GtkContainerClass*) class; - parent_class = (GtkBinClass*) gtk_type_class (GTK_TYPE_BIN); + gobject_class->finalize = gtk_viewport_finalize; gobject_class->set_property = gtk_viewport_set_property; gobject_class->get_property = gtk_viewport_get_property; object_class->destroy = gtk_viewport_destroy; @@ -129,35 +103,38 @@ gtk_viewport_class_init (GtkViewportClass *class) g_object_class_install_property (gobject_class, PROP_HADJUSTMENT, g_param_spec_object ("hadjustment", - _("Horizontal adjustment"), - _("The GtkAdjustment that determines the values of the horizontal position for this viewport"), + P_("Horizontal adjustment"), + P_("The GtkAdjustment that determines the values of the horizontal position for this viewport"), GTK_TYPE_ADJUSTMENT, - G_PARAM_READWRITE)); + GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT)); g_object_class_install_property (gobject_class, PROP_VADJUSTMENT, g_param_spec_object ("vadjustment", - _("Vertical adjustment"), - _("The GtkAdjustment that determines the values of the vertical position for this viewport"), + P_("Vertical adjustment"), + P_("The GtkAdjustment that determines the values of the vertical position for this viewport"), GTK_TYPE_ADJUSTMENT, - G_PARAM_READWRITE)); + GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT)); g_object_class_install_property (gobject_class, PROP_SHADOW_TYPE, - g_param_spec_enum ("shadow_type", - _("Shadow type"), - _("Determines how the shadowed box around the viewport is drawn"), + g_param_spec_enum ("shadow-type", + P_("Shadow type"), + P_("Determines how the shadowed box around the viewport is drawn"), GTK_TYPE_SHADOW_TYPE, GTK_SHADOW_IN, - G_PARAM_READWRITE)); + GTK_PARAM_READWRITE)); widget_class->set_scroll_adjustments_signal = - gtk_signal_new ("set_scroll_adjustments", - GTK_RUN_LAST, - GTK_CLASS_TYPE (object_class), - GTK_SIGNAL_OFFSET (GtkViewportClass, set_scroll_adjustments), - _gtk_marshal_VOID__OBJECT_OBJECT, - GTK_TYPE_NONE, 2, GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT); + g_signal_new (I_("set_scroll_adjustments"), + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (GtkViewportClass, set_scroll_adjustments), + NULL, NULL, + _gtk_marshal_VOID__OBJECT_OBJECT, + G_TYPE_NONE, 2, + GTK_TYPE_ADJUSTMENT, + GTK_TYPE_ADJUSTMENT); } static void @@ -252,25 +229,46 @@ gtk_viewport_new (GtkAdjustment *hadjustment, return viewport; } +#define ADJUSTMENT_POINTER(viewport, orientation) \ + (((orientation) == GTK_ORIENTATION_HORIZONTAL) ? \ + &(viewport)->hadjustment : &(viewport)->vadjustment) + static void -gtk_viewport_destroy (GtkObject *object) +viewport_disconnect_adjustment (GtkViewport *viewport, + GtkOrientation orientation) { - GtkViewport *viewport = GTK_VIEWPORT (object); + GtkAdjustment **adjustmentp = ADJUSTMENT_POINTER (viewport, orientation); - if (viewport->hadjustment) - { - gtk_signal_disconnect_by_data (GTK_OBJECT (viewport->hadjustment), viewport); - gtk_object_unref (GTK_OBJECT (viewport->hadjustment)); - viewport->hadjustment = NULL; - } - if (viewport->vadjustment) + if (*adjustmentp) { - gtk_signal_disconnect_by_data (GTK_OBJECT (viewport->vadjustment), viewport); - gtk_object_unref (GTK_OBJECT (viewport->vadjustment)); - viewport->vadjustment = NULL; + g_signal_handlers_disconnect_by_func (*adjustmentp, + gtk_viewport_adjustment_value_changed, + viewport); + g_object_unref (*adjustmentp); + *adjustmentp = NULL; } +} + +static void +gtk_viewport_finalize (GObject *object) +{ + GtkViewport *viewport = GTK_VIEWPORT (object); + + viewport_disconnect_adjustment (viewport, GTK_ORIENTATION_HORIZONTAL); + viewport_disconnect_adjustment (viewport, GTK_ORIENTATION_VERTICAL); + + G_OBJECT_CLASS (gtk_viewport_parent_class)->finalize (object); +} + +static void +gtk_viewport_destroy (GtkObject *object) +{ + GtkViewport *viewport = GTK_VIEWPORT (object); + + viewport_disconnect_adjustment (viewport, GTK_ORIENTATION_HORIZONTAL); + viewport_disconnect_adjustment (viewport, GTK_ORIENTATION_VERTICAL); - GTK_OBJECT_CLASS (parent_class)->destroy (object); + GTK_OBJECT_CLASS (gtk_viewport_parent_class)->destroy (object); } /** @@ -311,6 +309,151 @@ gtk_viewport_get_vadjustment (GtkViewport *viewport) return viewport->vadjustment; } +static void +viewport_get_view_allocation (GtkViewport *viewport, + GtkAllocation *view_allocation) +{ + GtkWidget *widget = GTK_WIDGET (viewport); + GtkAllocation *allocation = &widget->allocation; + gint border_width = GTK_CONTAINER (viewport)->border_width; + + view_allocation->x = 0; + view_allocation->y = 0; + + if (viewport->shadow_type != GTK_SHADOW_NONE) + { + view_allocation->x = widget->style->xthickness; + view_allocation->y = widget->style->ythickness; + } + + view_allocation->width = MAX (1, allocation->width - view_allocation->x * 2 - border_width * 2); + view_allocation->height = MAX (1, allocation->height - view_allocation->y * 2 - border_width * 2); +} + +static void +viewport_reclamp_adjustment (GtkAdjustment *adjustment, + gboolean *value_changed) +{ + gdouble value = adjustment->value; + + value = CLAMP (value, 0, adjustment->upper - adjustment->page_size); + if (value != adjustment->value) + { + adjustment->value = value; + if (value_changed) + *value_changed = TRUE; + } + else if (value_changed) + *value_changed = FALSE; +} + +static void +viewport_set_hadjustment_values (GtkViewport *viewport, + gboolean *value_changed) +{ + GtkBin *bin = GTK_BIN (viewport); + GtkAllocation view_allocation; + GtkAdjustment *hadjustment = gtk_viewport_get_hadjustment (viewport); + gdouble old_page_size; + gdouble old_upper; + gdouble old_value; + + viewport_get_view_allocation (viewport, &view_allocation); + + old_page_size = hadjustment->page_size; + old_upper = hadjustment->upper; + old_value = hadjustment->value; + hadjustment->page_size = view_allocation.width; + hadjustment->step_increment = view_allocation.width * 0.1; + hadjustment->page_increment = view_allocation.width * 0.9; + + hadjustment->lower = 0; + + if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) + { + GtkRequisition child_requisition; + + gtk_widget_get_child_requisition (bin->child, &child_requisition); + hadjustment->upper = MAX (child_requisition.width, view_allocation.width); + } + else + hadjustment->upper = view_allocation.width; + + if (gtk_widget_get_direction (GTK_WIDGET (viewport)) == GTK_TEXT_DIR_RTL) + { + gdouble dist = old_upper - (old_value + old_page_size); + hadjustment->value = hadjustment->upper - dist - hadjustment->page_size; + viewport_reclamp_adjustment (hadjustment, value_changed); + *value_changed = (old_value != hadjustment->value); + } + else + viewport_reclamp_adjustment (hadjustment, value_changed); +} + +static void +viewport_set_vadjustment_values (GtkViewport *viewport, + gboolean *value_changed) +{ + GtkBin *bin = GTK_BIN (viewport); + GtkAllocation view_allocation; + GtkAdjustment *vadjustment = gtk_viewport_get_vadjustment (viewport); + + viewport_get_view_allocation (viewport, &view_allocation); + + vadjustment->page_size = view_allocation.height; + vadjustment->step_increment = view_allocation.height * 0.1; + vadjustment->page_increment = view_allocation.height * 0.9; + + vadjustment->lower = 0; + + if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) + { + GtkRequisition child_requisition; + + gtk_widget_get_child_requisition (bin->child, &child_requisition); + vadjustment->upper = MAX (child_requisition.height, view_allocation.height); + } + else + vadjustment->upper = view_allocation.height; + + viewport_reclamp_adjustment (vadjustment, value_changed); +} + +static void +viewport_set_adjustment (GtkViewport *viewport, + GtkOrientation orientation, + GtkAdjustment *adjustment) +{ + GtkAdjustment **adjustmentp = ADJUSTMENT_POINTER (viewport, orientation); + gboolean value_changed; + + if (adjustment && adjustment == *adjustmentp) + return; + + if (!adjustment) + adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, + 0.0, 0.0, 0.0)); + viewport_disconnect_adjustment (viewport, orientation); + *adjustmentp = adjustment; + g_object_ref_sink (adjustment); + + if (orientation == GTK_ORIENTATION_HORIZONTAL) + viewport_set_hadjustment_values (viewport, &value_changed); + else + viewport_set_vadjustment_values (viewport, &value_changed); + + g_signal_connect (adjustment, "value_changed", + G_CALLBACK (gtk_viewport_adjustment_value_changed), + viewport); + + gtk_adjustment_changed (adjustment); + + if (value_changed) + gtk_adjustment_value_changed (adjustment); + else + gtk_viewport_adjustment_value_changed (adjustment, viewport); +} + /** * gtk_viewport_set_hadjustment: * @viewport: a #GtkViewport. @@ -326,32 +469,7 @@ gtk_viewport_set_hadjustment (GtkViewport *viewport, if (adjustment) g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); - if (viewport->hadjustment && viewport->hadjustment != adjustment) - { - gtk_signal_disconnect_by_data (GTK_OBJECT (viewport->hadjustment), viewport); - gtk_object_unref (GTK_OBJECT (viewport->hadjustment)); - viewport->hadjustment = NULL; - } - - if (!adjustment) - adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, - 0.0, 0.0, 0.0)); - - if (viewport->hadjustment != adjustment) - { - viewport->hadjustment = adjustment; - gtk_object_ref (GTK_OBJECT (viewport->hadjustment)); - gtk_object_sink (GTK_OBJECT (viewport->hadjustment)); - - gtk_signal_connect (GTK_OBJECT (adjustment), "changed", - (GtkSignalFunc) gtk_viewport_adjustment_changed, - (gpointer) viewport); - gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed", - (GtkSignalFunc) gtk_viewport_adjustment_value_changed, - (gpointer) viewport); - - gtk_viewport_adjustment_changed (adjustment, viewport); - } + viewport_set_adjustment (viewport, GTK_ORIENTATION_HORIZONTAL, adjustment); g_object_notify (G_OBJECT (viewport), "hadjustment"); } @@ -371,34 +489,9 @@ gtk_viewport_set_vadjustment (GtkViewport *viewport, if (adjustment) g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); - if (viewport->vadjustment && viewport->vadjustment != adjustment) - { - gtk_signal_disconnect_by_data (GTK_OBJECT (viewport->vadjustment), viewport); - gtk_object_unref (GTK_OBJECT (viewport->vadjustment)); - viewport->vadjustment = NULL; - } - - if (!adjustment) - adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, - 0.0, 0.0, 0.0)); - - if (viewport->vadjustment != adjustment) - { - viewport->vadjustment = adjustment; - gtk_object_ref (GTK_OBJECT (viewport->vadjustment)); - gtk_object_sink (GTK_OBJECT (viewport->vadjustment)); - - gtk_signal_connect (GTK_OBJECT (adjustment), "changed", - (GtkSignalFunc) gtk_viewport_adjustment_changed, - (gpointer) viewport); - gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed", - (GtkSignalFunc) gtk_viewport_adjustment_value_changed, - (gpointer) viewport); - - gtk_viewport_adjustment_changed (adjustment, viewport); - } + viewport_set_adjustment (viewport, GTK_ORIENTATION_VERTICAL, adjustment); - g_object_notify (G_OBJECT (viewport), "vadjustment"); + g_object_notify (G_OBJECT (viewport), "vadjustment"); } static void @@ -406,10 +499,8 @@ gtk_viewport_set_scroll_adjustments (GtkViewport *viewport, GtkAdjustment *hadjustment, GtkAdjustment *vadjustment) { - if (viewport->hadjustment != hadjustment) - gtk_viewport_set_hadjustment (viewport, hadjustment); - if (viewport->vadjustment != vadjustment) - gtk_viewport_set_vadjustment (viewport, vadjustment); + gtk_viewport_set_hadjustment (viewport, hadjustment); + gtk_viewport_set_vadjustment (viewport, vadjustment); } /** @@ -435,7 +526,7 @@ gtk_viewport_set_shadow_type (GtkViewport *viewport, gtk_widget_queue_draw (GTK_WIDGET (viewport)); } - g_object_notify (G_OBJECT (viewport), "shadow_type"); + g_object_notify (G_OBJECT (viewport), "shadow-type"); } } @@ -459,17 +550,17 @@ gtk_viewport_get_shadow_type (GtkViewport *viewport) static void gtk_viewport_realize (GtkWidget *widget) { - GtkBin *bin; - GtkViewport *viewport; + GtkViewport *viewport = GTK_VIEWPORT (widget); + GtkBin *bin = GTK_BIN (widget); + GtkAdjustment *hadjustment = gtk_viewport_get_hadjustment (viewport); + GtkAdjustment *vadjustment = gtk_viewport_get_vadjustment (viewport); + gint border_width = GTK_CONTAINER (widget)->border_width; + + GtkAllocation view_allocation; GdkWindowAttr attributes; gint attributes_mask; gint event_mask; - gint border_width; - border_width = GTK_CONTAINER (widget)->border_width; - - bin = GTK_BIN (widget); - viewport = GTK_VIEWPORT (widget); GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); attributes.x = widget->allocation.x + border_width; @@ -492,32 +583,23 @@ gtk_viewport_realize (GtkWidget *widget) &attributes, attributes_mask); gdk_window_set_user_data (widget->window, viewport); - if (viewport->shadow_type != GTK_SHADOW_NONE) - { - attributes.x = widget->style->xthickness; - attributes.y = widget->style->ythickness; - } - else - { - attributes.x = 0; - attributes.y = 0; - } - - attributes.width = MAX (1, (gint)widget->allocation.width - attributes.x * 2 - border_width * 2); - attributes.height = MAX (1, (gint)widget->allocation.height - attributes.y * 2 - border_width * 2); + viewport_get_view_allocation (viewport, &view_allocation); + + attributes.x = view_allocation.x; + attributes.y = view_allocation.y; + attributes.width = view_allocation.width; + attributes.height = view_allocation.height; attributes.event_mask = 0; viewport->view_window = gdk_window_new (widget->window, &attributes, attributes_mask); gdk_window_set_user_data (viewport->view_window, viewport); - attributes.x = 0; - attributes.y = 0; - - if (bin->child) - { - attributes.width = viewport->hadjustment->upper; - attributes.height = viewport->vadjustment->upper; - } + gdk_window_set_back_pixmap (viewport->view_window, NULL, FALSE); + + attributes.x = - hadjustment->value; + attributes.y = - vadjustment->value; + attributes.width = hadjustment->upper; + attributes.height = vadjustment->upper; attributes.event_mask = event_mask; @@ -531,10 +613,12 @@ gtk_viewport_realize (GtkWidget *widget) gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); gtk_style_set_background (widget->style, viewport->bin_window, GTK_STATE_NORMAL); - gtk_paint_flat_box(widget->style, viewport->bin_window, GTK_STATE_NORMAL, - GTK_SHADOW_NONE, - NULL, widget, "viewportbin", - 0, 0, -1, -1); + /* Call paint here to allow a theme to set the background without flashing + */ + gtk_paint_flat_box(widget->style, viewport->bin_window, GTK_STATE_NORMAL, + GTK_SHADOW_NONE, + NULL, widget, "viewportbin", + 0, 0, -1, -1); gdk_window_show (viewport->bin_window); gdk_window_show (viewport->view_window); @@ -553,8 +637,8 @@ gtk_viewport_unrealize (GtkWidget *widget) gdk_window_destroy (viewport->bin_window); viewport->bin_window = NULL; - if (GTK_WIDGET_CLASS (parent_class)->unrealize) - (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); + if (GTK_WIDGET_CLASS (gtk_viewport_parent_class)->unrealize) + (* GTK_WIDGET_CLASS (gtk_viewport_parent_class)->unrealize) (widget); } static void @@ -570,9 +654,10 @@ gtk_viewport_paint (GtkWidget *widget, { viewport = GTK_VIEWPORT (widget); - gtk_draw_shadow (widget->style, widget->window, - GTK_STATE_NORMAL, viewport->shadow_type, - 0, 0, -1, -1); + gtk_paint_shadow (widget->style, widget->window, + GTK_STATE_NORMAL, viewport->shadow_type, + area, widget, "viewport", + 0, 0, -1, -1); } } @@ -581,12 +666,10 @@ gtk_viewport_expose (GtkWidget *widget, GdkEventExpose *event) { GtkViewport *viewport; - GtkBin *bin; if (GTK_WIDGET_DRAWABLE (widget)) { viewport = GTK_VIEWPORT (widget); - bin = GTK_BIN (widget); if (event->window == widget->window) gtk_viewport_paint (widget, &event->area); @@ -597,10 +680,8 @@ gtk_viewport_expose (GtkWidget *widget, &event->area, widget, "viewportbin", 0, 0, -1, -1); - (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event); + (* GTK_WIDGET_CLASS (gtk_viewport_parent_class)->expose_event) (widget, event); } - - } return FALSE; @@ -619,25 +700,27 @@ gtk_viewport_add (GtkContainer *container, gtk_widget_set_parent_window (child, GTK_VIEWPORT (bin)->bin_window); - GTK_CONTAINER_CLASS (parent_class)->add (container, child); + GTK_CONTAINER_CLASS (gtk_viewport_parent_class)->add (container, child); } static void gtk_viewport_size_request (GtkWidget *widget, GtkRequisition *requisition) { - GtkViewport *viewport; GtkBin *bin; GtkRequisition child_requisition; - viewport = GTK_VIEWPORT (widget); bin = GTK_BIN (widget); - requisition->width = (GTK_CONTAINER (widget)->border_width + - GTK_WIDGET (widget)->style->xthickness) * 2; + requisition->width = GTK_CONTAINER (widget)->border_width; + + requisition->height = GTK_CONTAINER (widget)->border_width; - requisition->height = (GTK_CONTAINER (widget)->border_width * 2 + - GTK_WIDGET (widget)->style->ythickness) * 2; + if (GTK_VIEWPORT (widget)->shadow_type != GTK_SHADOW_NONE) + { + requisition->width += 2 * widget->style->xthickness; + requisition->height += 2 * widget->style->ythickness; + } if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) { @@ -653,15 +736,11 @@ gtk_viewport_size_allocate (GtkWidget *widget, { GtkViewport *viewport = GTK_VIEWPORT (widget); GtkBin *bin = GTK_BIN (widget); - GtkAllocation child_allocation; - gint hval, vval; gint border_width = GTK_CONTAINER (widget)->border_width; - - /* demand creation */ - if (!viewport->hadjustment) - gtk_viewport_set_hadjustment (viewport, NULL); - if (!viewport->vadjustment) - gtk_viewport_set_vadjustment (viewport, NULL); + gboolean hadjustment_value_changed, vadjustment_value_changed; + GtkAdjustment *hadjustment = gtk_viewport_get_hadjustment (viewport); + GtkAdjustment *vadjustment = gtk_viewport_get_vadjustment (viewport); + GtkAllocation child_allocation; /* If our size changed, and we have a shadow, queue a redraw on widget->window to * redraw the shadow correctly. @@ -673,109 +752,44 @@ gtk_viewport_size_allocate (GtkWidget *widget, gdk_window_invalidate_rect (widget->window, NULL, FALSE); widget->allocation = *allocation; - + + viewport_set_hadjustment_values (viewport, &hadjustment_value_changed); + viewport_set_vadjustment_values (viewport, &vadjustment_value_changed); + child_allocation.x = 0; child_allocation.y = 0; - - if (viewport->shadow_type != GTK_SHADOW_NONE) - { - child_allocation.x = widget->style->xthickness; - child_allocation.y = widget->style->ythickness; - } - - child_allocation.width = MAX (1, allocation->width - child_allocation.x * 2 - border_width * 2); - child_allocation.height = MAX (1, allocation->height - child_allocation.y * 2 - border_width * 2); - + child_allocation.width = hadjustment->upper; + child_allocation.height = vadjustment->upper; if (GTK_WIDGET_REALIZED (widget)) { + GtkAllocation view_allocation; gdk_window_move_resize (widget->window, allocation->x + border_width, allocation->y + border_width, allocation->width - border_width * 2, allocation->height - border_width * 2); - - gdk_window_move_resize (viewport->view_window, - child_allocation.x, - child_allocation.y, - child_allocation.width, - child_allocation.height); - } - - viewport->hadjustment->page_size = child_allocation.width; - viewport->hadjustment->step_increment = child_allocation.width * 0.1; - viewport->hadjustment->page_increment = child_allocation.width * 0.9; - - viewport->vadjustment->page_size = child_allocation.height; - viewport->vadjustment->step_increment = child_allocation.height * 0.1; - viewport->vadjustment->page_increment = child_allocation.height * 0.9; - - hval = viewport->hadjustment->value; - vval = viewport->vadjustment->value; - - if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) - { - GtkRequisition child_requisition; - gtk_widget_get_child_requisition (bin->child, &child_requisition); - viewport->hadjustment->lower = 0; - viewport->hadjustment->upper = MAX (child_requisition.width, - child_allocation.width); - - hval = CLAMP (hval, 0, - viewport->hadjustment->upper - - viewport->hadjustment->page_size); - - viewport->vadjustment->lower = 0; - viewport->vadjustment->upper = MAX (child_requisition.height, - child_allocation.height); - - vval = CLAMP (vval, 0, - viewport->vadjustment->upper - - viewport->vadjustment->page_size); + viewport_get_view_allocation (viewport, &view_allocation); + gdk_window_move_resize (viewport->view_window, + view_allocation.x, + view_allocation.y, + view_allocation.width, + view_allocation.height); + gdk_window_move_resize (viewport->bin_window, + - hadjustment->value, + - vadjustment->value, + child_allocation.width, + child_allocation.height); } - if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) - { - child_allocation.x = 0; - child_allocation.y = 0; - - child_allocation.width = viewport->hadjustment->upper; - child_allocation.height = viewport->vadjustment->upper; - - if (GTK_WIDGET_REALIZED (widget)) - gdk_window_resize (viewport->bin_window, - child_allocation.width, - child_allocation.height); - - child_allocation.x = 0; - child_allocation.y = 0; - gtk_widget_size_allocate (bin->child, &child_allocation); - } - - gtk_signal_emit_by_name (GTK_OBJECT (viewport->hadjustment), "changed"); - gtk_signal_emit_by_name (GTK_OBJECT (viewport->vadjustment), "changed"); - if (viewport->hadjustment->value != hval) - { - viewport->hadjustment->value = hval; - gtk_signal_emit_by_name (GTK_OBJECT (viewport->hadjustment), "value_changed"); - } - if (viewport->vadjustment->value != vval) - { - viewport->vadjustment->value = vval; - gtk_signal_emit_by_name (GTK_OBJECT (viewport->vadjustment), "value_changed"); - } -} - -static void -gtk_viewport_adjustment_changed (GtkAdjustment *adjustment, - gpointer data) -{ - GtkViewport *viewport; - - g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); - g_return_if_fail (GTK_IS_VIEWPORT (data)); - - viewport = GTK_VIEWPORT (data); + gtk_widget_size_allocate (bin->child, &child_allocation); + + gtk_adjustment_changed (hadjustment); + gtk_adjustment_changed (vadjustment); + if (hadjustment_value_changed) + gtk_adjustment_value_changed (hadjustment); + if (vadjustment_value_changed) + gtk_adjustment_value_changed (vadjustment); } static void @@ -784,7 +798,6 @@ gtk_viewport_adjustment_value_changed (GtkAdjustment *adjustment, { GtkViewport *viewport; GtkBin *bin; - GtkAllocation child_allocation; g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); g_return_if_fail (GTK_IS_VIEWPORT (data)); @@ -792,25 +805,21 @@ gtk_viewport_adjustment_value_changed (GtkAdjustment *adjustment, viewport = GTK_VIEWPORT (data); bin = GTK_BIN (data); - if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) + if (bin->child && GTK_WIDGET_VISIBLE (bin->child) && + GTK_WIDGET_REALIZED (viewport)) { - child_allocation.x = 0; - child_allocation.y = 0; + GtkAdjustment *hadjustment = gtk_viewport_get_hadjustment (viewport); + GtkAdjustment *vadjustment = gtk_viewport_get_vadjustment (viewport); + gint old_x, old_y; + gint new_x, new_y; - if (viewport->hadjustment->lower != (viewport->hadjustment->upper - - viewport->hadjustment->page_size)) - child_allocation.x = viewport->hadjustment->lower - viewport->hadjustment->value; + gdk_window_get_position (viewport->bin_window, &old_x, &old_y); + new_x = - hadjustment->value; + new_y = - vadjustment->value; - if (viewport->vadjustment->lower != (viewport->vadjustment->upper - - viewport->vadjustment->page_size)) - child_allocation.y = viewport->vadjustment->lower - viewport->vadjustment->value; - - if (GTK_WIDGET_REALIZED (viewport)) + if (new_x != old_x || new_y != old_y) { - gdk_window_move (viewport->bin_window, - child_allocation.x, - child_allocation.y); - + gdk_window_move (viewport->bin_window, new_x, new_y); gdk_window_process_updates (viewport->bin_window, TRUE); } } @@ -831,3 +840,6 @@ gtk_viewport_style_set (GtkWidget *widget, gtk_style_set_background (widget->style, widget->window, widget->state); } } + +#define __GTK_VIEWPORT_C__ +#include "gtkaliasdef.c"