summaryrefslogtreecommitdiff
path: root/gtk/gtkscrolledwindow.c
diff options
context:
space:
mode:
authorMichael Natterer <mitch@lanedo.com>2012-01-24 12:12:34 +0100
committerMatthias Clasen <mclasen@redhat.com>2012-03-01 16:28:58 -0500
commit2a72e7b7b86d1bdb3a6a818b94cb21bc8f611127 (patch)
tree660f9692e56372b55d36c12cf282df8bf765de9a /gtk/gtkscrolledwindow.c
parent147cdd846502d261e2efa02a96ef39d238f8ec4f (diff)
downloadgtk+-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.c75
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