2008-11-18 Emmanuele Bassi <ebassi@linux.intel.com>

* 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.
This commit is contained in:
Emmanuele Bassi 2008-11-18 12:42:05 +00:00
parent 33a67bc299
commit 34cc7fe21c
6 changed files with 153 additions and 75 deletions

View File

@ -1,3 +1,23 @@
2008-11-18 Emmanuele Bassi <ebassi@linux.intel.com>
* 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 <neil@linux.intel.com>
* tests/conform/test-pick.c (test_pick): The final result message

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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
};

View File

@ -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

View File

@ -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);