diff options
author | Michael Natterer <mitch@lanedo.com> | 2012-01-24 12:12:34 +0100 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2012-03-01 16:28:58 -0500 |
commit | 2a72e7b7b86d1bdb3a6a818b94cb21bc8f611127 (patch) | |
tree | 660f9692e56372b55d36c12cf282df8bf765de9a /gtk/gtkscrolledwindow.c | |
parent | 147cdd846502d261e2efa02a96ef39d238f8ec4f (diff) | |
download | gtk+-2a72e7b7b86d1bdb3a6a818b94cb21bc8f611127.tar.gz |
gtk: Implement smooth scrolling in scrolledwindow/range
If delta_x/y information is provided in scroll events, use it
to modify the underlying adjustment in steps proportional to
the deltas provided.
If the child widget of a scrolledwindow doesn't set
GDK_SMOOTH_SCROLL_MASK, regular scroll events will be dispatched,
and still handled by these 2 widgets.
Diffstat (limited to 'gtk/gtkscrolledwindow.c')
-rw-r--r-- | gtk/gtkscrolledwindow.c | 75 |
1 files changed, 63 insertions, 12 deletions
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c index 7c7399497a..05bad81533 100644 --- a/gtk/gtkscrolledwindow.c +++ b/gtk/gtkscrolledwindow.c @@ -2248,7 +2248,9 @@ gtk_scrolled_window_scroll_event (GtkWidget *widget, { GtkScrolledWindowPrivate *priv; GtkScrolledWindow *scrolled_window; - GtkWidget *range; + gboolean handled = FALSE; + gdouble delta_x; + gdouble delta_y; g_return_val_if_fail (GTK_IS_SCROLLED_WINDOW (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); @@ -2256,23 +2258,72 @@ gtk_scrolled_window_scroll_event (GtkWidget *widget, scrolled_window = GTK_SCROLLED_WINDOW (widget); priv = scrolled_window->priv; - if (event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_DOWN) - range = priv->vscrollbar; - else - range = priv->hscrollbar; + if (gdk_event_get_scroll_deltas ((GdkEvent *) event, &delta_x, &delta_y)) + { + if (delta_x != 0.0 && priv->hscrollbar && + gtk_widget_get_visible (priv->hscrollbar)) + { + GtkAdjustment *adj; + gdouble new_value; + + adj = gtk_range_get_adjustment (GTK_RANGE (priv->hscrollbar)); + + new_value = CLAMP (gtk_adjustment_get_value (adj) + delta_x, + gtk_adjustment_get_lower (adj), + gtk_adjustment_get_upper (adj) - + gtk_adjustment_get_page_size (adj)); + + gtk_adjustment_set_value (adj, new_value); + + handled = TRUE; + } + + if (delta_y != 0.0 && priv->vscrollbar && + gtk_widget_get_visible (priv->vscrollbar)) + { + GtkAdjustment *adj; + gdouble new_value; + + adj = gtk_range_get_adjustment (GTK_RANGE (priv->vscrollbar)); + + new_value = CLAMP (gtk_adjustment_get_value (adj) + delta_y, + gtk_adjustment_get_lower (adj), + gtk_adjustment_get_upper (adj) - + gtk_adjustment_get_page_size (adj)); + + gtk_adjustment_set_value (adj, new_value); - if (range && gtk_widget_get_visible (range)) + handled = TRUE; + } + } + else { - GtkAdjustment *adjustment = gtk_range_get_adjustment (GTK_RANGE (range)); - gdouble delta; + GtkWidget *range; - delta = _gtk_range_get_wheel_delta (GTK_RANGE (range), event->direction); - gtk_adjustment_set_value (adjustment, gtk_adjustment_get_value (adjustment) + delta); + if (event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_DOWN) + range = priv->vscrollbar; + else + range = priv->hscrollbar; - return TRUE; + if (range && gtk_widget_get_visible (range)) + { + GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (range)); + gdouble delta, new_value; + + delta = _gtk_range_get_wheel_delta (GTK_RANGE (range), event); + + new_value = CLAMP (gtk_adjustment_get_value (adj) + delta, + gtk_adjustment_get_lower (adj), + gtk_adjustment_get_upper (adj) - + gtk_adjustment_get_page_size (adj)); + + gtk_adjustment_set_value (adj, new_value); + + handled = TRUE; + } } - return FALSE; + return handled; } static gboolean |