/** * mx_adjustment_set_value: * @adjustment: An #MxAdjustment * @value: A #gdouble * * Set the value of the #MxAdjustment:value property. * */ void mx_adjustment_set_value (MxAdjustment *adjustment, gdouble value) { MxAdjustmentPrivate *priv; g_return_if_fail (MX_IS_ADJUSTMENT (adjustment)); priv = adjustment->priv; /* Defer clamp until after construction. */ if (!priv->is_constructing) { if (!priv->elastic && priv->clamp_value) value = CLAMP (value, priv->lower, MAX (priv->lower, priv->upper - priv->page_size)); } if (priv->value != value) { stop_interpolation (adjustment); priv->value = value; g_object_notify (G_OBJECT (adjustment), "value"); mx_adjustment_emit_changed (adjustment); } }
static void interpolation_completed_cb (ClutterTimeline *timeline, MxAdjustment *adjustment) { MxAdjustmentPrivate *priv = adjustment->priv; if (priv->elastic && priv->clamp_value) { if (clutter_timeline_get_direction (priv->interpolation) == CLUTTER_TIMELINE_FORWARD) { clutter_timeline_set_direction (priv->interpolation, CLUTTER_TIMELINE_BACKWARD); clutter_timeline_set_duration (priv->interpolation, 250); clutter_timeline_rewind (priv->interpolation); if (priv->new_position < priv->lower) { priv->old_position = priv->lower; clutter_timeline_start (priv->interpolation); } else if (priv->new_position > (priv->upper - priv->page_size)) { priv->old_position = priv->upper - priv->page_size; clutter_timeline_start (priv->interpolation); } } else { stop_interpolation (adjustment); mx_adjustment_set_value (adjustment, priv->old_position); } } else { stop_interpolation (adjustment); mx_adjustment_set_value (adjustment, priv->new_position); } g_signal_emit (adjustment, signals[INTERPOLATION_COMPLETED], 0); }
/** * mx_adjustment_interpolate: * @adjustment: A #MxAdjustment * @value: A #gdouble * @duration: duration in milliseconds * @mode: A #ClutterAnimationMode * * Interpolate #MxAdjustment:value to the new value specified by @value, using * the mode and duration given. */ void mx_adjustment_interpolate (MxAdjustment *adjustment, gdouble value, guint duration, gulong mode) { MxAdjustmentPrivate *priv = adjustment->priv; g_return_if_fail (isfinite (value)); if (duration <= 1) { stop_interpolation (adjustment); mx_adjustment_set_value (adjustment, value); return; } priv->old_position = priv->value; priv->new_position = value; if (!priv->interpolation) { priv->interpolation = clutter_timeline_new (duration); g_signal_connect (priv->interpolation, "new-frame", G_CALLBACK (interpolation_new_frame_cb), adjustment); g_signal_connect (priv->interpolation, "completed", G_CALLBACK (interpolation_completed_cb), adjustment); } else { /* Extend the animation if it gets interrupted, otherwise frequent calls * to this function will end up with no advancements until the calls * finish (as the animation never gets a chance to start). */ clutter_timeline_set_direction (priv->interpolation, CLUTTER_TIMELINE_FORWARD); clutter_timeline_rewind (priv->interpolation); clutter_timeline_set_duration (priv->interpolation, duration); } if (priv->interpolate_alpha) g_object_unref (priv->interpolate_alpha); priv->interpolate_alpha = clutter_alpha_new_full (priv->interpolation, mode); clutter_timeline_start (priv->interpolation); }
static void mx_adjustment_dispose (GObject *object) { MxAdjustmentPrivate *priv = MX_ADJUSTMENT (object)->priv; stop_interpolation (MX_ADJUSTMENT (object)); /* Remove idle handlers */ mx_adjustment_remove_idle (&priv->value_source); mx_adjustment_remove_idle (&priv->lower_source); mx_adjustment_remove_idle (&priv->upper_source); mx_adjustment_remove_idle (&priv->page_inc_source); mx_adjustment_remove_idle (&priv->step_inc_source); mx_adjustment_remove_idle (&priv->page_size_source); mx_adjustment_remove_idle (&priv->changed_source); G_OBJECT_CLASS (mx_adjustment_parent_class)->dispose (object); }
static void interpolation_new_frame_cb (ClutterTimeline *timeline, guint msecs, MxAdjustment *adjustment) { gdouble new_value; MxAdjustmentPrivate *priv = adjustment->priv; new_value = priv->old_position + (priv->new_position - priv->old_position) * clutter_timeline_get_progress (priv->interpolation); priv->interpolation = NULL; mx_adjustment_set_value (adjustment, new_value); priv->interpolation = timeline; /* Stop the interpolation if we've reached the end of the adjustment */ if (!priv->elastic && priv->clamp_value && ((new_value < priv->lower) || (new_value > (priv->upper - priv->page_size)))) stop_interpolation (adjustment); }