static void clamp_adjustments (ChamplainKineticScrollView *scroll) { ChamplainKineticScrollViewPrivate *priv = scroll->priv; if (priv->viewport) { ChamplainAdjustment *hadj, *vadj; gdouble d, value, lower, step_increment; champlain_viewport_get_adjustments (CHAMPLAIN_VIEWPORT (priv->viewport), &hadj, &vadj); /* Snap to the nearest step increment on hadjustment */ champlain_adjustment_get_values (hadj, &value, &lower, NULL, &step_increment); d = (rint ((value - lower) / step_increment) * step_increment) + lower; champlain_adjustment_set_value (hadj, d); /* Snap to the nearest step increment on vadjustment */ champlain_adjustment_get_values (vadj, &value, &lower, NULL, &step_increment); d = (rint ((value - lower) / step_increment) * step_increment) + lower; champlain_adjustment_set_value (vadj, d); } }
static void deceleration_new_frame_cb (ClutterTimeline *timeline, gint frame_num, ChamplainKineticScrollView *scroll) { ChamplainKineticScrollViewPrivate *priv = scroll->priv; if (priv->viewport) { gdouble value, lower, upper; ChamplainAdjustment *hadjust, *vadjust; gint i; gboolean stop = TRUE; champlain_viewport_get_adjustments (CHAMPLAIN_VIEWPORT (priv->viewport), &hadjust, &vadjust); for (i = 0; i < clutter_timeline_get_delta (timeline) / 15; i++) { champlain_adjustment_set_value (hadjust, priv->dx + champlain_adjustment_get_value (hadjust)); champlain_adjustment_set_value (vadjust, priv->dy + champlain_adjustment_get_value (vadjust)); priv->dx = (priv->dx / priv->decel_rate); priv->dy = (priv->dy / priv->decel_rate); } /* Check if we've hit the upper or lower bounds and stop the timeline */ champlain_adjustment_get_values (hadjust, &value, &lower, &upper, NULL); if (((priv->dx > 0) && (value < upper)) || ((priv->dx < 0) && (value > lower))) stop = FALSE; if (stop) { champlain_adjustment_get_values (vadjust, &value, &lower, &upper, NULL); if (((priv->dy > 0) && (value < upper)) || ((priv->dy < 0) && (value > lower))) stop = FALSE; } if (stop) { clutter_timeline_stop (timeline); deceleration_completed_cb (timeline, scroll); } } }
static void allocate (ClutterActor *self, const ClutterActorBox *box, ClutterAllocationFlags flags) { ClutterActorBox child_box; CoglFixed prev_value; ChamplainViewportPrivate *priv = CHAMPLAIN_VIEWPORT (self)->priv; /* Chain up */ CLUTTER_ACTOR_CLASS (champlain_viewport_parent_class)-> allocate (self, box, flags); /* Refresh adjustments */ if (priv->sync_adjustments) { if (priv->hadjustment) { g_object_set (G_OBJECT (priv->hadjustment), "lower", 0.0, "upper", (box->x2 - box->x1), NULL); /* Make sure value is clamped */ prev_value = champlain_adjustment_get_value (priv->hadjustment); champlain_adjustment_set_value (priv->hadjustment, prev_value); } if (priv->vadjustment) { g_object_set (G_OBJECT (priv->vadjustment), "lower", 0.0, "upper", (box->y2 - box->y1), NULL); prev_value = champlain_adjustment_get_value (priv->vadjustment); champlain_adjustment_set_value (priv->vadjustment, prev_value); } } child_box.x1 = 0; child_box.x2 = box->x2 - box->x1; child_box.y1 = 0; child_box.y2 = box->y2 - box->y1; clutter_actor_allocate (CLUTTER_ACTOR (priv->content_group), &child_box, flags); }
void champlain_viewport_set_origin (ChamplainViewport *viewport, float x, float y) { ChamplainViewportPrivate *priv; g_return_if_fail (CHAMPLAIN_IS_VIEWPORT (viewport)); priv = viewport->priv; g_object_freeze_notify (G_OBJECT (viewport)); if (x != priv->x) { priv->x = x; g_object_notify (G_OBJECT (viewport), "x-origin"); if (priv->hadjustment) champlain_adjustment_set_value (priv->hadjustment, x); } if (y != priv->y) { priv->y = y; g_object_notify (G_OBJECT (viewport), "y-origin"); if (priv->vadjustment) champlain_adjustment_set_value (priv->vadjustment, y); } g_object_thaw_notify (G_OBJECT (viewport)); if (priv->child) clutter_actor_set_position (priv->child, -x, -y); clutter_actor_queue_redraw (CLUTTER_ACTOR (viewport)); }
static gboolean motion_event_cb (ClutterActor *stage, ClutterMotionEvent *event, ChamplainKineticScrollView *scroll) { ChamplainKineticScrollViewPrivate *priv = scroll->priv; ClutterActor *actor = CLUTTER_ACTOR (scroll); gfloat x, y; if ((event->type != CLUTTER_MOTION || !(event->modifier_state & CLUTTER_BUTTON1_MASK)) && (event->type != CLUTTER_TOUCH_UPDATE || priv->sequence != clutter_event_get_event_sequence ((ClutterEvent *) event))) return FALSE; if (clutter_actor_transform_stage_point (actor, event->x, event->y, &x, &y)) { ChamplainKineticScrollViewMotion *motion; if (priv->viewport) { gdouble dx, dy; ChamplainAdjustment *hadjust, *vadjust; champlain_viewport_get_adjustments (CHAMPLAIN_VIEWPORT (priv->viewport), &hadjust, &vadjust); motion = &g_array_index (priv->motion_buffer, ChamplainKineticScrollViewMotion, priv->last_motion); if (hadjust) { dx = (motion->x - x) + champlain_adjustment_get_value (hadjust); champlain_adjustment_set_value (hadjust, dx); } if (vadjust) { dy = (motion->y - y) + champlain_adjustment_get_value (vadjust); champlain_adjustment_set_value (vadjust, dy); } } priv->last_motion++; if (priv->last_motion == priv->motion_buffer->len) { priv->motion_buffer = g_array_remove_index (priv->motion_buffer, 0); g_array_set_size (priv->motion_buffer, priv->last_motion); priv->last_motion--; } motion = &g_array_index (priv->motion_buffer, ChamplainKineticScrollViewMotion, priv->last_motion); motion->x = x; motion->y = y; g_get_current_time (&motion->time); } /* Due to the way gestures in progress connect to the stage in order to * receive events, we must let these events go through, as they could be * essential for the management of the ClutterZoomGesture in the * ChamplainView. */ return FALSE; }
static gboolean motion_event_cb (ClutterActor *stage, ClutterMotionEvent *event, ChamplainKineticScrollView *scroll) { ChamplainKineticScrollViewPrivate *priv = scroll->priv; ClutterActor *actor = CLUTTER_ACTOR (scroll); gfloat x, y; if (event->type != CLUTTER_MOTION || !(event->modifier_state & CLUTTER_BUTTON1_MASK)) return FALSE; if (clutter_actor_transform_stage_point (actor, event->x, event->y, &x, &y)) { ChamplainKineticScrollViewMotion *motion; if (priv->viewport) { gdouble dx, dy; ChamplainAdjustment *hadjust, *vadjust; champlain_viewport_get_adjustments (CHAMPLAIN_VIEWPORT (priv->viewport), &hadjust, &vadjust); motion = &g_array_index (priv->motion_buffer, ChamplainKineticScrollViewMotion, priv->last_motion); if (hadjust) { dx = (motion->x - x) + champlain_adjustment_get_value (hadjust); champlain_adjustment_set_value (hadjust, dx); } if (vadjust) { dy = (motion->y - y) + champlain_adjustment_get_value (vadjust); champlain_adjustment_set_value (vadjust, dy); } } priv->last_motion++; if (priv->last_motion == priv->motion_buffer->len) { priv->motion_buffer = g_array_remove_index (priv->motion_buffer, 0); g_array_set_size (priv->motion_buffer, priv->last_motion); priv->last_motion--; } motion = &g_array_index (priv->motion_buffer, ChamplainKineticScrollViewMotion, priv->last_motion); motion->x = x; motion->y = y; g_get_current_time (&motion->time); } return TRUE; }