From 34cc7fe21c837ad5a5b878bac4cf7fdd737ea562 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Tue, 18 Nov 2008 12:42:05 +0000 Subject: [PATCH] 2008-11-18 Emmanuele Bassi * clutter/clutter-alpha.h: * clutter/clutter-alpha.c: (clutter_alpha_set_mode): Use a lookup table to find the alpha function given the animation mode. (clutter_exp_in_func), (clutter_exp_out_func), (clutter_exp_in_out_func): Add new exponential functions. * clutter/clutter-script.c: Update the lookup table with the new animation modes; match "linear" to the ramp-inc alpha function. * clutter/clutter-types.h: Add new AnimationMode values. * tests/interactive/test-easing.c: Update the easing functions test. --- ChangeLog | 20 +++++ clutter/clutter-alpha.c | 139 +++++++++++++++++++++----------- clutter/clutter-alpha.h | 42 ++++------ clutter/clutter-script.c | 10 ++- clutter/clutter-types.h | 11 ++- tests/interactive/test-easing.c | 6 +- 6 files changed, 153 insertions(+), 75 deletions(-) diff --git a/ChangeLog b/ChangeLog index a90840603..0fd137309 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2008-11-18 Emmanuele Bassi + + * clutter/clutter-alpha.h: + * clutter/clutter-alpha.c: + (clutter_alpha_set_mode): Use a lookup table to find the alpha + function given the animation mode. + + (clutter_exp_in_func), + (clutter_exp_out_func), + (clutter_exp_in_out_func): Add new exponential functions. + + * clutter/clutter-script.c: Update the lookup table with the + new animation modes; match "linear" to the ramp-inc alpha + function. + + * clutter/clutter-types.h: Add new AnimationMode values. + + * tests/interactive/test-easing.c: Update the easing functions + test. + 2008-11-18 Neil Roberts * tests/conform/test-pick.c (test_pick): The final result message diff --git a/clutter/clutter-alpha.c b/clutter/clutter-alpha.c index 4c16f06b3..aee22a09c 100644 --- a/clutter/clutter-alpha.c +++ b/clutter/clutter-alpha.c @@ -32,14 +32,23 @@ * of time. * * #ClutterAlpha is a class for calculating an integer value between - * 0 and %CLUTTER_ALPHA_MAX_ALPHA as a function of time. You should - * provide a #ClutterTimeline and bind it to the #ClutterAlpha object; - * you should also provide a function returning the alpha value depending - * on the position inside the timeline; this function will be executed - * each time a new frame in the #ClutterTimeline is reached. Since the - * alpha function is controlled by the timeline instance, you can pause - * or stop the #ClutterAlpha from calling the alpha function by controlling - * the #ClutterTimeline object. + * 0 and %CLUTTER_ALPHA_MAX_ALPHA as a function of time. + * + * A #ClutterAlpha binds a #ClutterTimeline to a progress function which + * translates the time T into an adimensional factor alpha. The factor can + * then be used to drive a #ClutterBehaviour, which will translate the + * alpha value into something meaningful for a #ClutterActor. + * + * You should provide a #ClutterTimeline and bind it to the #ClutterAlpha + * instance using clutter_alpha_set_timeline(); you should also provide a + * function returning the alpha value depending on the progress of the + * timeline, using clutter_alpha_set_func() or clutter_alpha_set_closure(). + * The alpha function will be executed each time a new frame in the + * #ClutterTimeline is reached. + * + * Since the alpha function is controlled by the timeline instance, you can + * pause, stop or resume the #ClutterAlpha from calling the alpha function by + * using the appropriate functions of the #ClutterTimeline object. * * #ClutterAlpha is used to "drive" a #ClutterBehaviour instance. * @@ -341,7 +350,7 @@ clutter_alpha_set_closure (ClutterAlpha *alpha, /** * clutter_alpha_set_func: * @alpha: A #ClutterAlpha - * @func: A #ClutterAlphaAlphaFunc + * @func: A #ClutterAlphaFunc * @data: user data to be passed to the alpha function, or %NULL * @destroy: notify function used when disposing the alpha function * @@ -517,6 +526,25 @@ clutter_alpha_get_mode (ClutterAlpha *alpha) return alpha->priv->mode; } +/* XXX - keep in sync with ClutterAnimationMode */ +static const struct { + ClutterAnimationMode mode; + ClutterAlphaFunc func; +} animation_modes[] = { + { CLUTTER_CUSTOM_MODE, NULL }, + { CLUTTER_LINEAR, clutter_ramp_inc_func }, + { CLUTTER_SINE_IN, clutter_sine_in_func }, + { CLUTTER_SINE_OUT, clutter_sine_out_func }, + { CLUTTER_SINE_IN_OUT, clutter_sine_in_out_func }, + { CLUTTER_EASE_IN, clutter_ease_in_func }, + { CLUTTER_EASE_OUT, clutter_ease_out_func }, + { CLUTTER_EASE_IN_OUT, clutter_ease_in_out_func }, + { CLUTTER_EXPO_IN, clutter_exp_in_func }, + { CLUTTER_EXPO_OUT, clutter_exp_out_func }, + { CLUTTER_EXPO_IN_OUT, clutter_exp_in_out_func }, + { CLUTTER_SMOOTH_IN_OUT, clutter_smoothstep_inc_func } +}; + /** * clutter_alpha_set_mode: * @alpha: a #ClutterAlpha @@ -539,43 +567,10 @@ clutter_alpha_set_mode (ClutterAlpha *alpha, priv->mode = mode; - switch (priv->mode) - { - case CLUTTER_LINEAR: - clutter_alpha_set_func (alpha, clutter_ramp_inc_func, NULL, NULL); - break; - - case CLUTTER_SINE_IN: - clutter_alpha_set_func (alpha, clutter_sine_in_func, NULL, NULL); - break; - - case CLUTTER_SINE_OUT: - clutter_alpha_set_func (alpha, clutter_sine_out_func, NULL, NULL); - break; - - case CLUTTER_SINE_IN_OUT: - clutter_alpha_set_func (alpha, clutter_sine_inc_func, NULL, NULL); - break; - - case CLUTTER_EASE_IN: - clutter_alpha_set_func (alpha, clutter_ease_in_func, NULL, NULL); - break; - - case CLUTTER_EASE_OUT: - clutter_alpha_set_func (alpha, clutter_ease_out_func, NULL, NULL); - break; - - case CLUTTER_EASE_IN_OUT: - clutter_alpha_set_func (alpha, clutter_ease_in_out_func, NULL, NULL); - break; - - case CLUTTER_CUSTOM_MODE: - break; - - default: - g_assert_not_reached (); - break; - } + /* sanity check to avoid getting an out of sync enum/function mapping */ + g_assert (animation_modes[mode].mode == mode); + if (G_LIKELY (animation_modes[mode].func != NULL)) + clutter_alpha_set_func (alpha, animation_modes[mode].func, NULL, NULL); g_object_notify (G_OBJECT (alpha), "mode"); } @@ -1399,3 +1394,55 @@ clutter_ease_in_out_func (ClutterAlpha *alpha, return CLAMP (res * CLUTTER_ALPHA_MAX_ALPHA, 0, CLUTTER_ALPHA_MAX_ALPHA); } + +guint32 +clutter_exp_in_func (ClutterAlpha *alpha, + gpointer dummy) +{ + ClutterTimeline *timeline; + gdouble progress, res; + + timeline = clutter_alpha_get_timeline (alpha); + progress = clutter_timeline_get_progress (timeline); + + res = pow (2, 10 * (progress - 1)); + res = CLAMP (res * CLUTTER_ALPHA_MAX_ALPHA, 0, CLUTTER_ALPHA_MAX_ALPHA); + + return res; +} + +guint32 +clutter_exp_out_func (ClutterAlpha *alpha, + gpointer dummy) +{ + ClutterTimeline *timeline; + gdouble progress, res; + + timeline = clutter_alpha_get_timeline (alpha); + progress = clutter_timeline_get_progress (timeline); + + res = -pow (2, (-10 * progress)) + 1; + res = CLAMP (res * CLUTTER_ALPHA_MAX_ALPHA, 0, CLUTTER_ALPHA_MAX_ALPHA); + + return res; +} + +guint32 +clutter_exp_in_out_func (ClutterAlpha *alpha, + gpointer dummy) +{ + ClutterTimeline *timeline; + gdouble progress, res; + + timeline = clutter_alpha_get_timeline (alpha); + progress = clutter_timeline_get_progress (timeline); + + if (progress < 0.5) + res = 0.5 * pow (2, (10 * (progress - 1))); + else + res = 0.5 * -pow (2, (-10 * progress)) + 1; + + res = CLAMP (res * CLUTTER_ALPHA_MAX_ALPHA, 0, CLUTTER_ALPHA_MAX_ALPHA); + + return res; +} diff --git a/clutter/clutter-alpha.h b/clutter/clutter-alpha.h index 4cd05f999..eba9e3fb8 100644 --- a/clutter/clutter-alpha.h +++ b/clutter/clutter-alpha.h @@ -37,31 +37,16 @@ G_BEGIN_DECLS -#define CLUTTER_TYPE_ALPHA clutter_alpha_get_type() +#define CLUTTER_TYPE_ALPHA (clutter_alpha_get_type ()) +#define CLUTTER_ALPHA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ALPHA, ClutterAlpha)) +#define CLUTTER_ALPHA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ALPHA, ClutterAlphaClass)) +#define CLUTTER_IS_ALPHA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ALPHA)) +#define CLUTTER_IS_ALPHA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ALPHA)) +#define CLUTTER_ALPHA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ALPHA, ClutterAlphaClass)) -#define CLUTTER_ALPHA(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - CLUTTER_TYPE_ALPHA, ClutterAlpha)) - -#define CLUTTER_ALPHA_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - CLUTTER_TYPE_ALPHA, ClutterAlphaClass)) - -#define CLUTTER_IS_ALPHA(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - CLUTTER_TYPE_ALPHA)) - -#define CLUTTER_IS_ALPHA_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), \ - CLUTTER_TYPE_ALPHA)) - -#define CLUTTER_ALPHA_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - CLUTTER_TYPE_ALPHA, ClutterAlphaClass)) - -typedef struct _ClutterAlpha ClutterAlpha; -typedef struct _ClutterAlphaClass ClutterAlphaClass; -typedef struct _ClutterAlphaPrivate ClutterAlphaPrivate; +typedef struct _ClutterAlpha ClutterAlpha; +typedef struct _ClutterAlphaClass ClutterAlphaClass; +typedef struct _ClutterAlphaPrivate ClutterAlphaPrivate; /** * ClutterAlphaFunc: @@ -121,7 +106,7 @@ struct _ClutterAlphaClass * * Since: 0.2 */ -#define CLUTTER_ALPHA_MAX_ALPHA 0xffff +#define CLUTTER_ALPHA_MAX_ALPHA (0xffff) GType clutter_alpha_get_type (void) G_GNUC_CONST; @@ -190,6 +175,13 @@ guint32 clutter_ease_out_func (ClutterAlpha *alpha, guint32 clutter_ease_in_out_func (ClutterAlpha *alpha, gpointer dummy); +guint32 clutter_exp_in_func (ClutterAlpha *alpha, + gpointer dummy); +guint32 clutter_exp_out_func (ClutterAlpha *alpha, + gpointer dummy); +guint32 clutter_exp_in_out_func (ClutterAlpha *alpha, + gpointer dummy); + G_END_DECLS #endif /* __CLUTTER_ALPHA_H__ */ diff --git a/clutter/clutter-script.c b/clutter/clutter-script.c index 7cc00ed15..95c69036e 100644 --- a/clutter/clutter-script.c +++ b/clutter/clutter-script.c @@ -518,7 +518,8 @@ construct_timeline (ClutterScript *script, } /* ugh. if g_module_open() fails (*cough* python *cough*) we need a fallback - * for finding at least our own functions. + * for finding at least our own functions. keep the nick in sync with the + * ClutterAnimationMode enumeration */ static const struct { @@ -542,9 +543,14 @@ static const struct ALPHA_FUNC (clutter_smoothstep_dec_func, "smoothstep-dec"), ALPHA_FUNC (clutter_exp_inc_func, "exp-inc"), ALPHA_FUNC (clutter_exp_dec_func, "exp-dec"), + ALPHA_FUNC (clutter_ramp_inc_func, "linear"), ALPHA_FUNC (clutter_ease_in_func, "ease-in"), ALPHA_FUNC (clutter_ease_out_func, "ease-out"), - ALPHA_FUNC (clutter_ease_in_out_func, "ease-in-out") + ALPHA_FUNC (clutter_ease_in_out_func, "ease-in-out"), + ALPHA_FUNC (clutter_exp_in_func, "exp-in"), + ALPHA_FUNC (clutter_exp_out_func, "exp-out"), + ALPHA_FUNC (clutter_exp_in_out_func, "exp-in-out"), + ALPHA_FUNC (clutter_smoothstep_inc_func, "smooth-in-out") #undef ALPHA_FUNC }; diff --git a/clutter/clutter-types.h b/clutter/clutter-types.h index 82b905012..2e97d52ed 100644 --- a/clutter/clutter-types.h +++ b/clutter/clutter-types.h @@ -196,6 +196,10 @@ typedef enum { * @CLUTTER_EASE_IN: ease-in progress * @CLUTTER_EASE_OUT: ease-out progress * @CLUTTER_EASE_IN_OUT: ease-in-out progress + * @CLUTTER_EXPO_IN: exponential in progress + * @CLUTTER_EXPO_OUT: exponential out progress + * @CLUTTER_EXPO_IN_OUT: exponential in-out progress + * @CLUTTER_SMOOTH_IN_OUT: smoothstep in-out progress * * The animation modes used by #ClutterAlpha and #ClutterAnimation. This * enumeration can be expanded in later versions of Clutter. @@ -204,13 +208,18 @@ typedef enum { */ typedef enum { CLUTTER_CUSTOM_MODE, + CLUTTER_LINEAR, CLUTTER_SINE_IN, CLUTTER_SINE_OUT, CLUTTER_SINE_IN_OUT, CLUTTER_EASE_IN, CLUTTER_EASE_OUT, - CLUTTER_EASE_IN_OUT + CLUTTER_EASE_IN_OUT, + CLUTTER_EXPO_IN, + CLUTTER_EXPO_OUT, + CLUTTER_EXPO_IN_OUT, + CLUTTER_SMOOTH_IN_OUT, } ClutterAnimationMode; G_END_DECLS diff --git a/tests/interactive/test-easing.c b/tests/interactive/test-easing.c index d968239bf..ad3a88ff7 100644 --- a/tests/interactive/test-easing.c +++ b/tests/interactive/test-easing.c @@ -12,7 +12,11 @@ const struct { { "sine-in-out", CLUTTER_SINE_IN_OUT }, { "ease-in", CLUTTER_EASE_IN }, { "ease-out", CLUTTER_EASE_OUT }, - { "ease-in-out", CLUTTER_EASE_IN_OUT } + { "ease-in-out", CLUTTER_EASE_IN_OUT }, + { "expo-in", CLUTTER_EXPO_IN }, + { "expo-out", CLUTTER_EXPO_OUT }, + { "expo-in-out", CLUTTER_EXPO_IN_OUT }, + { "smooth-in-out", CLUTTER_SMOOTH_IN_OUT } }; static const gint n_easing_modes = G_N_ELEMENTS (easing_modes);