GtkAdjustment *hadjust;
GtkAdjustment *vadjust;
+ gint x_offset;
+ gint y_offset;
GtkPolicyType vscrollbar_policy;
GtkPolicyType hscrollbar_policy;
static gboolean hildon_pannable_area_motion_event_scroll_timeout (HildonPannableArea *area);
static void hildon_pannable_area_motion_event_scroll (HildonPannableArea *area,
gdouble x, gdouble y);
+static void hildon_pannable_area_check_move (HildonPannableArea *area,
+ GdkEventMotion * event,
+ gdouble *x,
+ gdouble *y);
+static void hildon_pannable_area_handle_move (HildonPannableArea *area,
+ GdkEventMotion * event,
+ gdouble *x,
+ gdouble *y);
static gboolean hildon_pannable_area_motion_notify_cb (GtkWidget * widget,
GdkEventMotion * event);
static gboolean hildon_pannable_leave_notify_event (GtkWidget *widget,
priv->child_width = 0;
priv->child_height = 0;
priv->last_in = TRUE;
+ priv->x_offset = 0;
+ priv->y_offset = 0;
gtk_widget_add_events (GTK_WIDGET (area), GDK_POINTER_MOTION_HINT_MASK);
HildonPannableAreaPrivate *priv;
GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
gint border_width;
+ gdouble hv, vv;
border_width = GTK_CONTAINER (widget)->border_width;
gtk_widget_size_allocate (child, &child_allocation);
}
+ hv = priv->hadjust->value;
+ vv = priv->vadjust->value;
+
/* we have to do this after child size_allocate because page_size is
* changed when we allocate the size of the children */
if (priv->overshot_dist_y < 0) {
- gtk_adjustment_set_value (priv->vadjust, priv->vadjust->upper -
- priv->vadjust->page_size);
+ priv->vadjust->value = priv->vadjust->upper - priv->vadjust->page_size;
}
if (priv->overshot_dist_x < 0) {
- gtk_adjustment_set_value (priv->hadjust, priv->hadjust->upper -
- priv->hadjust->page_size);
+ priv->hadjust->value = priv->hadjust->upper - priv->hadjust->page_size;
}
+ if (hv != priv->hadjust->value)
+ gtk_adjustment_value_changed (priv->hadjust);
+
+ if (vv != priv->vadjust->value)
+ gtk_adjustment_value_changed (priv->vadjust);
+
} else {
hildon_pannable_area_check_scrollbars (HILDON_PANNABLE_AREA (widget));
}
hildon_pannable_area_adjust_value_changed (HildonPannableArea * area,
gpointer data)
{
- if (GTK_WIDGET_REALIZED (area)) {
- HildonPannableAreaPrivate *priv = HILDON_PANNABLE_AREA (area)->priv;
+ HildonPannableAreaPrivate *priv = HILDON_PANNABLE_AREA (area)->priv;
+ gint xdiff, ydiff;
+ gint x = priv->x_offset;
+ gint y = priv->y_offset;
+ priv->x_offset = priv->hadjust->value;
+ xdiff = x - priv->x_offset;
+ priv->y_offset = priv->vadjust->value;
+ ydiff = y - priv->y_offset;
+
+ if ((xdiff || ydiff) && GTK_WIDGET_DRAWABLE (area)) {
hildon_pannable_area_redraw (area);
if ((priv->vscroll_visible) || (priv->hscroll_visible)) {
}
}
- gtk_adjustment_set_value (adjust, dist);
+ adjust->value = dist;
} else {
if (!priv->button_pressed) {
*overshot_dist = CLAMP ((*overshot_dist) + inc, -1 * overshoot_max, 0);
} else {
*overshooting = 0;
- gtk_adjustment_set_value (adjust, dist);
+ adjust->value = CLAMP (dist,
+ adjust->lower,
+ adjust->upper -
+ adjust->page_size);
}
if (*overshot_dist != overshot_dist_old)
gboolean sx, sy;
HildonPannableAreaPrivate *priv = area->priv;
gboolean hscroll_visible, vscroll_visible;
+ gdouble hv, vv;
if (gtk_bin_get_child (GTK_BIN (area)) == NULL)
return;
sx = TRUE;
sy = TRUE;
+ hv = priv->hadjust->value;
+ vv = priv->vadjust->value;
+
if (vscroll_visible) {
hildon_pannable_axis_scroll (area, priv->vadjust, &priv->vel_y, y,
&priv->overshooting_y, &priv->overshot_dist_y,
priv->vel_x = 0;
}
+ if (hv != priv->hadjust->value)
+ gtk_adjustment_value_changed (priv->hadjust);
+
+ if (vv != priv->vadjust->value)
+ gtk_adjustment_value_changed (priv->vadjust);
+
/* If the scroll on a particular axis wasn't succesful, reset the
* initial scroll position to the new mouse co-ordinate. This means
* when you get to the top of the page, dragging down works immediately.
}
}
-static gboolean
-hildon_pannable_area_motion_notify_cb (GtkWidget * widget,
- GdkEventMotion * event)
+static void
+hildon_pannable_area_check_move (HildonPannableArea *area,
+ GdkEventMotion * event,
+ gdouble *x,
+ gdouble *y)
{
- HildonPannableArea *area = HILDON_PANNABLE_AREA (widget);
HildonPannableAreaPrivate *priv = area->priv;
- gdouble x, y;
- gdouble delta;
-
- if (gtk_bin_get_child (GTK_BIN (widget)) == NULL)
- return TRUE;
-
- if ((!priv->enabled) || (!priv->button_pressed) ||
- ((event->time == priv->last_time) && (priv->last_type == 2))) {
- gdk_window_get_pointer (widget->window, NULL, NULL, 0);
- return TRUE;
- }
-
- if (priv->last_type == 1) {
- priv->first_drag = TRUE;
- }
-
- x = event->x - priv->x;
- y = event->y - priv->y;
if (priv->first_drag && (!priv->moved) &&
- ((ABS (x) > (priv->panning_threshold))
- || (ABS (y) > (priv->panning_threshold)))) {
+ ((ABS (*x) > (priv->panning_threshold))
+ || (ABS (*y) > (priv->panning_threshold)))) {
priv->moved = TRUE;
- x = 0;
- y = 0;
+ *x = 0;
+ *y = 0;
if (priv->first_drag) {
gboolean vscroll_visible;
hildon_pannable_area_timeout, area);
}
}
+}
- if (priv->moved) {
- switch (priv->mode) {
- case HILDON_PANNABLE_AREA_MODE_PUSH:
- /* Scroll by the amount of pixels the cursor has moved
- * since the last motion event.
- */
- hildon_pannable_area_motion_event_scroll (area, x, y);
+static void
+hildon_pannable_area_handle_move (HildonPannableArea *area,
+ GdkEventMotion * event,
+ gdouble *x,
+ gdouble *y)
+{
+ HildonPannableAreaPrivate *priv = area->priv;
+ gdouble delta;
+
+ switch (priv->mode) {
+ case HILDON_PANNABLE_AREA_MODE_PUSH:
+ /* Scroll by the amount of pixels the cursor has moved
+ * since the last motion event.
+ */
+ hildon_pannable_area_motion_event_scroll (area, *x, *y);
+ priv->x = event->x;
+ priv->y = event->y;
+ break;
+ case HILDON_PANNABLE_AREA_MODE_ACCEL:
+ /* Set acceleration relative to the initial click */
+ priv->ex = event->x;
+ priv->ey = event->y;
+ priv->vel_x = ((*x > 0) ? 1 : -1) *
+ (((ABS (*x) /
+ (gdouble) GTK_WIDGET (area)->allocation.width) *
+ (priv->vmax - priv->vmin)) + priv->vmin);
+ priv->vel_y = ((*y > 0) ? 1 : -1) *
+ (((ABS (*y) /
+ (gdouble) GTK_WIDGET (area)->allocation.height) *
+ (priv->vmax - priv->vmin)) + priv->vmin);
+ break;
+ case HILDON_PANNABLE_AREA_MODE_AUTO:
+
+ delta = event->time - priv->last_time;
+
+ if (priv->mov_mode&HILDON_MOVEMENT_MODE_VERT) {
+ gdouble dist = event->y - priv->y;
+
+ hildon_pannable_area_calculate_velocity (&priv->vel_y,
+ delta,
+ dist,
+ priv->vmax,
+ priv->drag_inertia,
+ priv->force,
+ priv->sps);
+ } else {
+ *y = 0;
+ priv->vel_y = 0;
+ }
+
+ if (priv->mov_mode&HILDON_MOVEMENT_MODE_HORIZ) {
+ gdouble dist = event->x - priv->x;
+
+ hildon_pannable_area_calculate_velocity (&priv->vel_x,
+ delta,
+ dist,
+ priv->vmax,
+ priv->drag_inertia,
+ priv->force,
+ priv->sps);
+ } else {
+ *x = 0;
+ priv->vel_x = 0;
+ }
+
+ hildon_pannable_area_motion_event_scroll (area, *x, *y);
+
+ if (priv->mov_mode&HILDON_MOVEMENT_MODE_HORIZ)
priv->x = event->x;
+ if (priv->mov_mode&HILDON_MOVEMENT_MODE_VERT)
priv->y = event->y;
- break;
- case HILDON_PANNABLE_AREA_MODE_ACCEL:
- /* Set acceleration relative to the initial click */
- priv->ex = event->x;
- priv->ey = event->y;
- priv->vel_x = ((x > 0) ? 1 : -1) *
- (((ABS (x) /
- (gdouble) widget->allocation.width) *
- (priv->vmax - priv->vmin)) + priv->vmin);
- priv->vel_y = ((y > 0) ? 1 : -1) *
- (((ABS (y) /
- (gdouble) widget->allocation.height) *
- (priv->vmax - priv->vmin)) + priv->vmin);
- break;
- case HILDON_PANNABLE_AREA_MODE_AUTO:
-
- delta = event->time - priv->last_time;
- if (priv->mov_mode&HILDON_MOVEMENT_MODE_VERT) {
- gdouble dist = event->y - priv->y;
+ break;
+ default:
+ break;
+ }
+}
- hildon_pannable_area_calculate_velocity (&priv->vel_y,
- delta,
- dist,
- priv->vmax,
- priv->drag_inertia,
- priv->force,
- priv->sps);
- } else {
- y = 0;
- priv->vel_y = 0;
- }
+static gboolean
+hildon_pannable_area_motion_notify_cb (GtkWidget * widget,
+ GdkEventMotion * event)
+{
+ HildonPannableArea *area = HILDON_PANNABLE_AREA (widget);
+ HildonPannableAreaPrivate *priv = area->priv;
+ gdouble x, y;
- if (priv->mov_mode&HILDON_MOVEMENT_MODE_HORIZ) {
- gdouble dist = event->x - priv->x;
+ if (gtk_bin_get_child (GTK_BIN (widget)) == NULL)
+ return TRUE;
- hildon_pannable_area_calculate_velocity (&priv->vel_x,
- delta,
- dist,
- priv->vmax,
- priv->drag_inertia,
- priv->force,
- priv->sps);
- } else {
- x = 0;
- priv->vel_x = 0;
- }
+ if ((!priv->enabled) || (!priv->button_pressed) ||
+ ((event->time == priv->last_time) && (priv->last_type == 2))) {
+ gdk_window_get_pointer (widget->window, NULL, NULL, 0);
+ return TRUE;
+ }
- hildon_pannable_area_motion_event_scroll (area, x, y);
+ if (priv->last_type == 1) {
+ priv->first_drag = TRUE;
+ }
- if (priv->mov_mode&HILDON_MOVEMENT_MODE_HORIZ)
- priv->x = event->x;
- if (priv->mov_mode&HILDON_MOVEMENT_MODE_VERT)
- priv->y = event->y;
+ x = event->x - priv->x;
+ y = event->y - priv->y;
- break;
+ if (!priv->moved) {
+ hildon_pannable_area_check_move (area, event, &x, &y);
+ }
- default:
- break;
- }
+ if (priv->moved) {
+ hildon_pannable_area_handle_move (area, event, &x, &y);
} else if (priv->child) {
gboolean in;
gint pos_x, pos_y;
{
HildonPannableAreaPrivate *priv;
gint width, height;
+ gdouble hv, vv;
g_return_if_fail (HILDON_IS_PANNABLE_AREA (area));
g_return_if_fail (GTK_WIDGET_REALIZED (area));
g_return_if_fail (x < width || y < height);
+ hv = priv->hadjust->value;
+ vv = priv->vadjust->value;
+
if (x != -1) {
gdouble jump_to = x - priv->hadjust->page_size/2;
- if (jump_to > priv->hadjust->upper - priv->hadjust->page_size) {
- jump_to = priv->hadjust->upper - priv->hadjust->page_size;
- }
-
- gtk_adjustment_set_value (priv->hadjust, jump_to);
+ priv->hadjust->value = CLAMP (jump_to,
+ priv->hadjust->lower,
+ priv->hadjust->upper -
+ priv->hadjust->page_size);
}
if (y != -1) {
gdouble jump_to = y - priv->vadjust->page_size/2;
- if (jump_to > priv->vadjust->upper - priv->vadjust->page_size) {
- jump_to = priv->vadjust->upper - priv->vadjust->page_size;
- }
-
- gtk_adjustment_set_value (priv->vadjust, jump_to);
+ priv->vadjust->value = CLAMP (jump_to,
+ priv->vadjust->lower,
+ priv->vadjust->upper -
+ priv->vadjust->page_size);
}
+ if (hv != priv->hadjust->value)
+ gtk_adjustment_value_changed (priv->hadjust);
+
+ if (vv != priv->vadjust->value)
+ gtk_adjustment_value_changed (priv->vadjust);
+
priv->scroll_indicator_alpha = 1.0;
if (priv->scroll_indicator_timeout) {