4 * An OpenGL based 'interactive canvas' library.
6 * Copyright (C) 2008 Intel Corporation.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
22 * Emmanuele Bassi <ebassi@linux.intel.com>
26 * SECTION:clutter-interval
27 * @short_description: An object holding an interval of two values
29 * #ClutterInterval is a simple object that can hold two values
30 * defining an interval. #ClutterInterval can hold any value that
31 * can be enclosed inside a #GValue.
33 * Once a #ClutterInterval for a specific #GType has been instantiated
34 * the #ClutterInterval:value-type property cannot be changed anymore.
36 * #ClutterInterval starts with a floating reference; this means that
37 * any object taking a reference on a #ClutterInterval instance should
38 * also take ownership of the interval by using g_object_ref_sink().
40 * #ClutterInterval is used by #ClutterAnimation to define the
41 * interval of values that an implicit animation should tween over.
43 * #ClutterInterval can be subclassed to override the validation
44 * and value computation.
46 * #ClutterInterval is available since Clutter 1.0
57 #include <glib-object.h>
58 #include <gobject/gvaluecollector.h>
60 #include "clutter-color.h"
61 #include "clutter-fixed.h"
62 #include "clutter-interval.h"
63 #include "clutter-private.h"
64 #include "clutter-units.h"
77 static GParamSpec *obj_props[PROP_LAST];
88 #define CLUTTER_INTERVAL_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_INTERVAL, ClutterIntervalPrivate))
90 struct _ClutterIntervalPrivate
97 G_DEFINE_TYPE (ClutterInterval, clutter_interval, G_TYPE_INITIALLY_UNOWNED);
100 clutter_interval_real_validate (ClutterInterval *interval,
103 GType pspec_gtype = G_PARAM_SPEC_VALUE_TYPE (pspec);
105 /* check the GTypes we provide first */
106 if (pspec_gtype == COGL_TYPE_FIXED)
108 ClutterParamSpecFixed *pspec_fixed = CLUTTER_PARAM_SPEC_FIXED (pspec);
112 clutter_interval_get_interval (interval, &a, &b);
113 if ((a >= pspec_fixed->minimum && a <= pspec_fixed->maximum) &&
114 (b >= pspec_fixed->minimum && b <= pspec_fixed->maximum))
120 /* then check the fundamental types */
121 switch (G_TYPE_FUNDAMENTAL (pspec_gtype))
125 GParamSpecInt *pspec_int = G_PARAM_SPEC_INT (pspec);
129 clutter_interval_get_interval (interval, &a, &b);
130 if ((a >= pspec_int->minimum && a <= pspec_int->maximum) &&
131 (b >= pspec_int->minimum && b <= pspec_int->maximum))
140 GParamSpecInt64 *pspec_int = G_PARAM_SPEC_INT64 (pspec);
144 clutter_interval_get_interval (interval, &a, &b);
145 if ((a >= pspec_int->minimum && a <= pspec_int->maximum) &&
146 (b >= pspec_int->minimum && b <= pspec_int->maximum))
155 GParamSpecUInt *pspec_uint = G_PARAM_SPEC_UINT (pspec);
159 clutter_interval_get_interval (interval, &a, &b);
160 if ((a >= pspec_uint->minimum && a <= pspec_uint->maximum) &&
161 (b >= pspec_uint->minimum && b <= pspec_uint->maximum))
170 GParamSpecUInt64 *pspec_int = G_PARAM_SPEC_UINT64 (pspec);
174 clutter_interval_get_interval (interval, &a, &b);
175 if ((a >= pspec_int->minimum && a <= pspec_int->maximum) &&
176 (b >= pspec_int->minimum && b <= pspec_int->maximum))
185 GParamSpecChar *pspec_char = G_PARAM_SPEC_CHAR (pspec);
189 clutter_interval_get_interval (interval, &a, &b);
190 if ((a >= pspec_char->minimum && a <= pspec_char->maximum) &&
191 (b >= pspec_char->minimum && b <= pspec_char->maximum))
200 GParamSpecUChar *pspec_uchar = G_PARAM_SPEC_UCHAR (pspec);
204 clutter_interval_get_interval (interval, &a, &b);
205 if ((a >= pspec_uchar->minimum && a <= pspec_uchar->maximum) &&
206 (b >= pspec_uchar->minimum && b <= pspec_uchar->maximum))
215 GParamSpecFloat *pspec_flt = G_PARAM_SPEC_FLOAT (pspec);
219 clutter_interval_get_interval (interval, &a, &b);
220 if ((a >= pspec_flt->minimum && a <= pspec_flt->maximum) &&
221 (b >= pspec_flt->minimum && b <= pspec_flt->maximum))
230 GParamSpecDouble *pspec_flt = G_PARAM_SPEC_DOUBLE (pspec);
234 clutter_interval_get_interval (interval, &a, &b);
235 if ((a >= pspec_flt->minimum && a <= pspec_flt->maximum) &&
236 (b >= pspec_flt->minimum && b <= pspec_flt->maximum))
254 clutter_interval_real_compute_value (ClutterInterval *interval,
258 GValue *initial, *final;
260 gboolean retval = FALSE;
262 initial = clutter_interval_peek_initial_value (interval);
263 final = clutter_interval_peek_final_value (interval);
265 value_type = clutter_interval_get_value_type (interval);
267 if (_clutter_has_progress_function (value_type))
269 retval = _clutter_run_progress_function (value_type,
278 switch (G_TYPE_FUNDAMENTAL (value_type))
284 ia = g_value_get_int (initial);
285 ib = g_value_get_int (final);
287 res = (factor * (ib - ia)) + ia;
289 g_value_set_int (value, res);
299 ia = g_value_get_schar (initial);
300 ib = g_value_get_schar (final);
302 res = (factor * (ib - (gdouble) ia)) + ia;
304 g_value_set_schar (value, res);
314 ia = g_value_get_uint (initial);
315 ib = g_value_get_uint (final);
317 res = (factor * (ib - (gdouble) ia)) + ia;
319 g_value_set_uint (value, res);
329 ia = g_value_get_uchar (initial);
330 ib = g_value_get_uchar (final);
332 res = (factor * (ib - (gdouble) ia)) + ia;
334 g_value_set_uchar (value, res);
345 if (value_type == G_TYPE_DOUBLE)
347 ia = g_value_get_double (initial);
348 ib = g_value_get_double (final);
352 ia = g_value_get_float (initial);
353 ib = g_value_get_float (final);
356 res = (factor * (ib - ia)) + ia;
358 if (value_type == G_TYPE_DOUBLE)
359 g_value_set_double (value, res);
361 g_value_set_float (value, res);
369 g_value_set_boolean (value, TRUE);
371 g_value_set_boolean (value, FALSE);
383 /* We're trying to animate a property without knowing how to do that. Issue
384 * a warning with a hint to what could be done to fix that */
385 if (G_UNLIKELY (retval == FALSE))
387 g_warning ("%s: Could not compute progress between two %s. You can "
388 "register a progress function to instruct ClutterInterval "
389 "how to deal with this GType",
391 g_type_name (value_type));
398 clutter_interval_finalize (GObject *gobject)
400 ClutterIntervalPrivate *priv = CLUTTER_INTERVAL (gobject)->priv;
402 g_value_unset (&priv->values[0]);
403 g_value_unset (&priv->values[1]);
405 g_free (priv->values);
407 G_OBJECT_CLASS (clutter_interval_parent_class)->finalize (gobject);
411 clutter_interval_set_property (GObject *gobject,
416 ClutterIntervalPrivate *priv = CLUTTER_INTERVAL_GET_PRIVATE (gobject);
420 case PROP_VALUE_TYPE:
421 priv->value_type = g_value_get_gtype (value);
425 if (g_value_get_boxed (value) != NULL)
426 clutter_interval_set_initial_value (CLUTTER_INTERVAL (gobject),
427 g_value_get_boxed (value));
428 else if (G_IS_VALUE (&priv->values[INITIAL]))
429 g_value_unset (&priv->values[INITIAL]);
433 if (g_value_get_boxed (value) != NULL)
434 clutter_interval_set_final_value (CLUTTER_INTERVAL (gobject),
435 g_value_get_boxed (value));
436 else if (G_IS_VALUE (&priv->values[FINAL]))
437 g_value_unset (&priv->values[FINAL]);
441 G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
447 clutter_interval_get_property (GObject *gobject,
452 ClutterIntervalPrivate *priv = CLUTTER_INTERVAL_GET_PRIVATE (gobject);
456 case PROP_VALUE_TYPE:
457 g_value_set_gtype (value, priv->value_type);
461 if (G_IS_VALUE (&priv->values[INITIAL]))
462 g_value_set_boxed (value, &priv->values[INITIAL]);
466 if (G_IS_VALUE (&priv->values[FINAL]))
467 g_value_set_boxed (value, &priv->values[FINAL]);
471 G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
477 clutter_interval_class_init (ClutterIntervalClass *klass)
479 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
481 g_type_class_add_private (klass, sizeof (ClutterIntervalPrivate));
483 klass->validate = clutter_interval_real_validate;
484 klass->compute_value = clutter_interval_real_compute_value;
486 gobject_class->set_property = clutter_interval_set_property,
487 gobject_class->get_property = clutter_interval_get_property;
488 gobject_class->finalize = clutter_interval_finalize;
491 * ClutterInterval:value-type:
493 * The type of the values in the interval.
497 obj_props[PROP_VALUE_TYPE] =
498 g_param_spec_gtype ("value-type",
500 P_("The type of the values in the interval"),
503 G_PARAM_CONSTRUCT_ONLY |
504 G_PARAM_STATIC_STRINGS);
507 * ClutterInterval:initial:
509 * The initial value of the interval.
513 obj_props[PROP_INITIAL] =
514 g_param_spec_boxed ("initial",
516 P_("Initial value of the interval"),
519 G_PARAM_STATIC_STRINGS);
522 * ClutterInterval:final:
524 * The final value of the interval.
528 obj_props[PROP_FINAL] =
529 g_param_spec_boxed ("final",
531 P_("Final value of the interval"),
534 G_PARAM_STATIC_STRINGS);
536 g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);
540 clutter_interval_init (ClutterInterval *self)
542 ClutterIntervalPrivate *priv;
544 self->priv = priv = CLUTTER_INTERVAL_GET_PRIVATE (self);
546 priv->value_type = G_TYPE_INVALID;
547 priv->values = g_malloc0 (sizeof (GValue) * N_VALUES);
551 clutter_interval_set_value_internal (ClutterInterval *interval,
555 ClutterIntervalPrivate *priv = interval->priv;
558 g_assert (index_ >= INITIAL && index_ <= RESULT);
560 if (G_IS_VALUE (&priv->values[index_]))
561 g_value_unset (&priv->values[index_]);
563 g_value_init (&priv->values[index_], priv->value_type);
565 value_type = G_VALUE_TYPE (value);
566 if (value_type != priv->value_type ||
567 !g_type_is_a (value_type, priv->value_type))
569 if (g_value_type_compatible (value_type, priv->value_type))
571 g_value_copy (value, &priv->values[index_]);
575 if (g_value_type_transformable (value_type, priv->value_type))
577 GValue transform = G_VALUE_INIT;
579 g_value_init (&transform, priv->value_type);
581 if (g_value_transform (value, &transform))
582 g_value_copy (&transform, &priv->values[index_]);
585 g_warning ("%s: Unable to convert a value of type '%s' into "
586 "the value type '%s' of the interval.",
588 g_type_name (value_type),
589 g_type_name (priv->value_type));
592 g_value_unset (&transform);
596 g_value_copy (value, &priv->values[index_]);
600 clutter_interval_get_value_internal (ClutterInterval *interval,
604 ClutterIntervalPrivate *priv = interval->priv;
606 g_assert (index_ >= INITIAL && index_ <= RESULT);
608 g_value_copy (&priv->values[index_], value);
612 clutter_interval_set_initial_internal (ClutterInterval *interval,
615 GType gtype = interval->priv->value_type;
616 GValue value = G_VALUE_INIT;
620 G_VALUE_COLLECT_INIT (&value, gtype, *args, 0, &error);
624 g_warning ("%s: %s", G_STRLOC, error);
626 /* we leak the value here as it might not be in a valid state
627 * given the error and calling g_value_unset() might lead to
628 * undefined behaviour
634 clutter_interval_set_value_internal (interval, INITIAL, &value);
635 g_value_unset (&value);
641 clutter_interval_set_final_internal (ClutterInterval *interval,
644 GType gtype = interval->priv->value_type;
645 GValue value = G_VALUE_INIT;
649 G_VALUE_COLLECT_INIT (&value, gtype, *args, 0, &error);
653 g_warning ("%s: %s", G_STRLOC, error);
655 /* we leak the value here as it might not be in a valid state
656 * given the error and calling g_value_unset() might lead to
657 * undefined behaviour
663 clutter_interval_set_value_internal (interval, FINAL, &value);
664 g_value_unset (&value);
670 clutter_interval_get_interval_valist (ClutterInterval *interval,
673 GType gtype = interval->priv->value_type;
674 GValue value = G_VALUE_INIT;
678 g_value_init (&value, gtype);
679 clutter_interval_get_initial_value (interval, &value);
680 G_VALUE_LCOPY (&value, var_args, 0, &error);
683 g_warning ("%s: %s", G_STRLOC, error);
685 g_value_unset (&value);
689 g_value_unset (&value);
692 g_value_init (&value, gtype);
693 clutter_interval_get_final_value (interval, &value);
694 G_VALUE_LCOPY (&value, var_args, 0, &error);
697 g_warning ("%s: %s", G_STRLOC, error);
699 g_value_unset (&value);
703 g_value_unset (&value);
707 * clutter_interval_new:
708 * @gtype: the type of the values in the interval
709 * @...: the initial value and the final value of the interval
711 * Creates a new #ClutterInterval holding values of type @gtype.
713 * This function avoids using a #GValue for the initial and final values
717 * interval = clutter_interval_new (G_TYPE_FLOAT, 0.0, 1.0);
718 * interval = clutter_interval_new (G_TYPE_BOOLEAN, FALSE, TRUE);
719 * interval = clutter_interval_new (G_TYPE_INT, 0, 360);
722 * Return value: the newly created #ClutterInterval
727 clutter_interval_new (GType gtype,
730 ClutterInterval *retval;
733 g_return_val_if_fail (gtype != G_TYPE_INVALID, NULL);
735 retval = g_object_new (CLUTTER_TYPE_INTERVAL, "value-type", gtype, NULL);
737 va_start (args, gtype);
739 if (!clutter_interval_set_initial_internal (retval, &args))
742 clutter_interval_set_final_internal (retval, &args);
751 * clutter_interval_new_with_values:
752 * @gtype: the type of the values in the interval
753 * @initial: (allow-none): a #GValue holding the initial value of the interval
754 * @final: (allow-none): a #GValue holding the final value of the interval
756 * Creates a new #ClutterInterval of type @gtype, between @initial
759 * This function is useful for language bindings.
761 * Return value: the newly created #ClutterInterval
766 clutter_interval_new_with_values (GType gtype,
767 const GValue *initial,
770 g_return_val_if_fail (gtype != G_TYPE_INVALID, NULL);
771 g_return_val_if_fail (initial == NULL || G_VALUE_TYPE (initial) == gtype, NULL);
772 g_return_val_if_fail (final == NULL || G_VALUE_TYPE (final) == gtype, NULL);
774 return g_object_new (CLUTTER_TYPE_INTERVAL,
782 * clutter_interval_clone:
783 * @interval: a #ClutterInterval
785 * Creates a copy of @interval.
787 * Return value: (transfer full): the newly created #ClutterInterval
792 clutter_interval_clone (ClutterInterval *interval)
794 ClutterInterval *retval;
798 g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), NULL);
799 g_return_val_if_fail (interval->priv->value_type != G_TYPE_INVALID, NULL);
801 gtype = interval->priv->value_type;
802 retval = g_object_new (CLUTTER_TYPE_INTERVAL, "value-type", gtype, NULL);
804 tmp = clutter_interval_peek_initial_value (interval);
805 clutter_interval_set_initial_value (retval, tmp);
807 tmp = clutter_interval_peek_final_value (interval);
808 clutter_interval_set_final_value (retval, tmp);
814 * clutter_interval_get_value_type:
815 * @interval: a #ClutterInterval
817 * Retrieves the #GType of the values inside @interval.
819 * Return value: the type of the value, or G_TYPE_INVALID
824 clutter_interval_get_value_type (ClutterInterval *interval)
826 g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), G_TYPE_INVALID);
828 return interval->priv->value_type;
832 * clutter_interval_set_initial_value:
833 * @interval: a #ClutterInterval
836 * Sets the initial value of @interval to @value. The value is copied
837 * inside the #ClutterInterval.
839 * Rename to: clutter_interval_set_initial
844 clutter_interval_set_initial_value (ClutterInterval *interval,
847 g_return_if_fail (CLUTTER_IS_INTERVAL (interval));
848 g_return_if_fail (value != NULL);
850 clutter_interval_set_value_internal (interval, INITIAL, value);
854 * clutter_interval_set_initial: (skip)
855 * @interval: a #ClutterInterval
856 * @...: the initial value of the interval.
858 * Variadic arguments version of clutter_interval_set_initial_value().
860 * This function is meant as a convenience for the C API.
862 * Language bindings should use clutter_interval_set_initial_value()
868 clutter_interval_set_initial (ClutterInterval *interval,
873 g_return_if_fail (CLUTTER_IS_INTERVAL (interval));
875 va_start (args, interval);
876 clutter_interval_set_initial_internal (interval, &args);
881 * clutter_interval_get_initial_value:
882 * @interval: a #ClutterInterval
883 * @value: (out caller-allocates): a #GValue
885 * Retrieves the initial value of @interval and copies
888 * The passed #GValue must be initialized to the value held by
889 * the #ClutterInterval.
894 clutter_interval_get_initial_value (ClutterInterval *interval,
897 g_return_if_fail (CLUTTER_IS_INTERVAL (interval));
898 g_return_if_fail (value != NULL);
900 clutter_interval_get_value_internal (interval, INITIAL, value);
904 * clutter_interval_peek_initial_value:
905 * @interval: a #ClutterInterval
907 * Gets the pointer to the initial value of @interval
909 * Return value: (transfer none): the initial value of the interval.
910 * The value is owned by the #ClutterInterval and it should not be
916 clutter_interval_peek_initial_value (ClutterInterval *interval)
918 g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), NULL);
920 return interval->priv->values + INITIAL;
924 * clutter_interval_set_final_value:
925 * @interval: a #ClutterInterval
928 * Sets the final value of @interval to @value. The value is
929 * copied inside the #ClutterInterval.
931 * Rename to: clutter_interval_set_final
936 clutter_interval_set_final_value (ClutterInterval *interval,
939 g_return_if_fail (CLUTTER_IS_INTERVAL (interval));
940 g_return_if_fail (value != NULL);
942 clutter_interval_set_value_internal (interval, FINAL, value);
946 * clutter_interval_get_final_value:
947 * @interval: a #ClutterInterval
948 * @value: (out caller-allocates): a #GValue
950 * Retrieves the final value of @interval and copies
953 * The passed #GValue must be initialized to the value held by
954 * the #ClutterInterval.
959 clutter_interval_get_final_value (ClutterInterval *interval,
962 g_return_if_fail (CLUTTER_IS_INTERVAL (interval));
963 g_return_if_fail (value != NULL);
965 clutter_interval_get_value_internal (interval, FINAL, value);
969 * clutter_interval_set_final: (skip)
970 * @interval: a #ClutterInterval
971 * @...: the final value of the interval
973 * Variadic arguments version of clutter_interval_set_final_value().
975 * This function is meant as a convenience for the C API.
977 * Language bindings should use clutter_interval_set_final_value() instead.
982 clutter_interval_set_final (ClutterInterval *interval,
987 g_return_if_fail (CLUTTER_IS_INTERVAL (interval));
989 va_start (args, interval);
990 clutter_interval_set_final_internal (interval, &args);
995 * clutter_interval_peek_final_value:
996 * @interval: a #ClutterInterval
998 * Gets the pointer to the final value of @interval
1000 * Return value: (transfer none): the final value of the interval.
1001 * The value is owned by the #ClutterInterval and it should not be
1007 clutter_interval_peek_final_value (ClutterInterval *interval)
1009 g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), NULL);
1011 return interval->priv->values + FINAL;
1015 * clutter_interval_set_interval:
1016 * @interval: a #ClutterInterval
1017 * @...: the initial and final values of the interval
1019 * Variable arguments wrapper for clutter_interval_set_initial_value()
1020 * and clutter_interval_set_final_value() that avoids using the
1021 * #GValue arguments:
1024 * clutter_interval_set_interval (interval, 0, 50);
1025 * clutter_interval_set_interval (interval, 1.0, 0.0);
1026 * clutter_interval_set_interval (interval, FALSE, TRUE);
1029 * This function is meant for the convenience of the C API; bindings
1030 * should reimplement this function using the #GValue-based API.
1035 clutter_interval_set_interval (ClutterInterval *interval,
1040 g_return_if_fail (CLUTTER_IS_INTERVAL (interval));
1041 g_return_if_fail (interval->priv->value_type != G_TYPE_INVALID);
1043 va_start (args, interval);
1045 if (!clutter_interval_set_initial_internal (interval, &args))
1048 clutter_interval_set_final_internal (interval, &args);
1055 * clutter_interval_get_interval:
1056 * @interval: a #ClutterInterval
1057 * @...: return locations for the initial and final values of
1060 * Variable arguments wrapper for clutter_interval_get_initial_value()
1061 * and clutter_interval_get_final_value() that avoids using the
1062 * #GValue arguments:
1065 * gint a = 0, b = 0;
1066 * clutter_interval_get_interval (interval, &a, &b);
1069 * This function is meant for the convenience of the C API; bindings
1070 * should reimplement this function using the #GValue-based API.
1075 clutter_interval_get_interval (ClutterInterval *interval,
1080 g_return_if_fail (CLUTTER_IS_INTERVAL (interval));
1081 g_return_if_fail (interval->priv->value_type != G_TYPE_INVALID);
1083 va_start (args, interval);
1084 clutter_interval_get_interval_valist (interval, args);
1089 * clutter_interval_validate:
1090 * @interval: a #ClutterInterval
1091 * @pspec: a #GParamSpec
1093 * Validates the initial and final values of @interval against
1096 * Return value: %TRUE if the #ClutterInterval is valid, %FALSE otherwise
1101 clutter_interval_validate (ClutterInterval *interval,
1104 g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), FALSE);
1105 g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE);
1107 return CLUTTER_INTERVAL_GET_CLASS (interval)->validate (interval, pspec);
1111 * clutter_interval_compute_value:
1112 * @interval: a #ClutterInterval
1113 * @factor: the progress factor, between 0 and 1
1114 * @value: (out caller-allocates): return location for an initialized #GValue
1116 * Computes the value between the @interval boundaries given the
1117 * progress @factor and copies it into @value.
1119 * Return value: %TRUE if the operation was successful
1124 clutter_interval_compute_value (ClutterInterval *interval,
1128 g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), FALSE);
1129 g_return_val_if_fail (value != NULL, FALSE);
1131 return CLUTTER_INTERVAL_GET_CLASS (interval)->compute_value (interval,
1137 * clutter_interval_compute:
1138 * @interval: a #ClutterInterval
1139 * @factor: the progress factor, between 0 and 1
1141 * Computes the value between the @interval boundaries given the
1144 * Unlike clutter_interval_compute_value(), this function will
1145 * return a const pointer to the computed value
1147 * You should use this function if you immediately pass the computed
1148 * value to another function that makes a copy of it, like
1149 * g_object_set_property()
1151 * Return value: (transfer none): a pointer to the computed value,
1152 * or %NULL if the computation was not successfull
1157 clutter_interval_compute (ClutterInterval *interval,
1163 g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), NULL);
1165 value = &(interval->priv->values[RESULT]);
1167 if (G_VALUE_TYPE (value) == G_TYPE_INVALID)
1168 g_value_init (value, interval->priv->value_type);
1170 res = CLUTTER_INTERVAL_GET_CLASS (interval)->compute_value (interval,
1175 return interval->priv->values + RESULT;
1181 * clutter_interval_is_valid:
1182 * @interval: a #ClutterInterval
1184 * Checks if the @interval has a valid initial and final values.
1186 * Return value: %TRUE if the #ClutterInterval has an initial and
1187 * final values, and %FALSE otherwise
1192 clutter_interval_is_valid (ClutterInterval *interval)
1194 ClutterIntervalPrivate *priv;
1196 g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), FALSE);
1198 priv = interval->priv;
1200 return G_IS_VALUE (&priv->values[INITIAL]) &&
1201 G_IS_VALUE (&priv->values[FINAL]);