diff --git a/src/st/st-adjustment.c b/src/st/st-adjustment.c index e2ef9b2f3..e6b33670c 100644 --- a/src/st/st-adjustment.c +++ b/src/st/st-adjustment.c @@ -566,3 +566,31 @@ st_adjustment_get_values (StAdjustment *adjustment, *page_size = priv->page_size; } +/** + * st_adjustment_adjust_for_scroll_event: + * @adjustment: An #StAdjustment + * @delta: A delta, retrieved directly from clutter_event_get_scroll_delta() + * or similar. + * + * Adjusts the adjustment using delta values from a scroll event. + * You should use this instead of using st_adjustment_set_value() + * as this method will tweak the values directly using the same + * math as GTK+, to ensure that scrolling is consistent across + * the environment. + */ +void +st_adjustment_adjust_for_scroll_event (StAdjustment *adjustment, + gdouble delta) +{ + StAdjustmentPrivate *priv; + gdouble new_value, scroll_unit; + + g_return_if_fail (ST_IS_ADJUSTMENT (adjustment)); + + priv = adjustment->priv; + + scroll_unit = pow (priv->page_size, 2.0 / 3.0); + + new_value = priv->value + delta * scroll_unit; + st_adjustment_set_value (adjustment, new_value); +} diff --git a/src/st/st-adjustment.h b/src/st/st-adjustment.h index 7660a08ec..fe041cf8a 100644 --- a/src/st/st-adjustment.h +++ b/src/st/st-adjustment.h @@ -99,6 +99,10 @@ void st_adjustment_get_values (StAdjustment *adjustment, gdouble *step_increment, gdouble *page_increment, gdouble *page_size); + +void st_adjustment_adjust_for_scroll_event (StAdjustment *adjustment, + gdouble delta); + G_END_DECLS #endif /* __ST_ADJUSTMENT_H__ */ diff --git a/src/st/st-scroll-view.c b/src/st/st-scroll-view.c index c8f89ceee..285ba2d60 100644 --- a/src/st/st-scroll-view.c +++ b/src/st/st-scroll-view.c @@ -665,6 +665,30 @@ st_scroll_view_allocate (ClutterActor *actor, } +static void +adjust_with_direction (StAdjustment *adj, + ClutterScrollDirection direction) +{ + gdouble delta; + + switch (direction) + { + case CLUTTER_SCROLL_UP: + case CLUTTER_SCROLL_LEFT: + delta = -1.0; + break; + case CLUTTER_SCROLL_RIGHT: + case CLUTTER_SCROLL_DOWN: + delta = 1.0; + break; + case CLUTTER_SCROLL_SMOOTH: + g_assert_not_reached (); + break; + } + + st_adjustment_adjust_for_scroll_event (adj, delta); +} + static void st_scroll_view_style_changed (StWidget *widget) { @@ -687,57 +711,31 @@ st_scroll_view_scroll_event (ClutterActor *self, ClutterScrollEvent *event) { StScrollViewPrivate *priv = ST_SCROLL_VIEW (self)->priv; - gdouble value, step, hvalue, vvalue, delta_x, delta_y; /* don't handle scroll events if requested not to */ if (!priv->mouse_scroll) return FALSE; - switch (event->direction) - { - case CLUTTER_SCROLL_SMOOTH: - clutter_event_get_scroll_delta ((ClutterEvent *)event, - &delta_x, &delta_y); - g_object_get (priv->hadjustment, - "value", &hvalue, - NULL); - g_object_get (priv->vadjustment, - "value", &vvalue, - NULL); - break; - case CLUTTER_SCROLL_UP: - case CLUTTER_SCROLL_DOWN: - g_object_get (priv->vadjustment, - "step-increment", &step, - "value", &value, - NULL); - break; - case CLUTTER_SCROLL_LEFT: - case CLUTTER_SCROLL_RIGHT: - g_object_get (priv->hadjustment, - "step-increment", &step, - "value", &value, - NULL); - break; - } + if (clutter_event_is_pointer_emulated ((ClutterEvent *) event)) + return TRUE; switch (event->direction) { case CLUTTER_SCROLL_SMOOTH: - st_adjustment_set_value (priv->hadjustment, hvalue + delta_x); - st_adjustment_set_value (priv->vadjustment, vvalue + delta_y); + { + gdouble delta_x, delta_y; + clutter_event_get_scroll_delta ((ClutterEvent *)event, &delta_x, &delta_y); + st_adjustment_adjust_for_scroll_event (priv->hadjustment, delta_x); + st_adjustment_adjust_for_scroll_event (priv->vadjustment, delta_y); + } break; case CLUTTER_SCROLL_UP: - st_adjustment_set_value (priv->vadjustment, value - step); - break; case CLUTTER_SCROLL_DOWN: - st_adjustment_set_value (priv->vadjustment, value + step); + adjust_with_direction (priv->vadjustment, event->direction); break; case CLUTTER_SCROLL_LEFT: - st_adjustment_set_value (priv->hadjustment, value - step); - break; case CLUTTER_SCROLL_RIGHT: - st_adjustment_set_value (priv->hadjustment, value + step); + adjust_with_direction (priv->hadjustment, event->direction); break; }