[script] Parse easing modes by name

The easing modes for a ClutterAlpha can either be parsed by using
the enumeration "nickname" (the shorthand form of the enumeration
value) or by using the common naming policy used in other
animation frameworks, like:

        easeInCubic
        easeOutElastic
        easeInOutBounce
This commit is contained in:
Emmanuele Bassi 2009-01-20 18:24:58 +00:00
parent 268abcd786
commit ac1a0d568e
2 changed files with 83 additions and 31 deletions

View File

@ -184,6 +184,7 @@
#include "clutter-script-private.h"
#include "clutter-scriptable.h"
#include "clutter-enum-types.h"
#include "clutter-private.h"
#include "clutter-debug.h"
@ -517,41 +518,77 @@ construct_timeline (ClutterScript *script,
return retval;
}
/* ugh. if g_module_open() fails (*cough* python *cough*) we need a fallback
* for finding at least our own functions. keep the nick in sync with the
* ClutterAnimationMode enumeration
/* define the names of the animation modes to match the ones
* that developers might be more accustomed to
*/
static const struct
{
const gchar *name;
const gchar *short_name;
ClutterAlphaFunc symbol;
} clutter_alphas[] = {
#define ALPHA_FUNC(func,nick) { #func, nick, func }
#undef ALPHA_FUNC
{ NULL, NULL, NULL }
ClutterAnimationMode mode;
} animation_modes[] = {
{ "linear", CLUTTER_LINEAR },
{ "easeInQuad", CLUTTER_EASE_IN_QUAD },
{ "easeOutQuad", CLUTTER_EASE_OUT_QUAD },
{ "easeInOutQuad", CLUTTER_EASE_IN_OUT_QUAD },
{ "easeInCubic", CLUTTER_EASE_IN_CUBIC },
{ "easeOutCubic", CLUTTER_EASE_OUT_CUBIC },
{ "easeInOutCubic", CLUTTER_EASE_IN_OUT_CUBIC },
{ "easeInQuart", CLUTTER_EASE_IN_QUART },
{ "easeOutQuart", CLUTTER_EASE_OUT_QUART },
{ "easeInOutQuart", CLUTTER_EASE_IN_OUT_QUART },
{ "easeInQuint", CLUTTER_EASE_IN_QUINT },
{ "easeOutQuint", CLUTTER_EASE_OUT_QUINT },
{ "easeInOutQuint", CLUTTER_EASE_IN_OUT_QUINT },
{ "easeInSine", CLUTTER_EASE_IN_SINE },
{ "easeOutSine", CLUTTER_EASE_OUT_SINE },
{ "easeInOutSine", CLUTTER_EASE_IN_OUT_SINE },
{ "easeInExpo", CLUTTER_EASE_IN_EXPO },
{ "easeOutExpo", CLUTTER_EASE_OUT_EXPO },
{ "easeInOutExpo", CLUTTER_EASE_IN_OUT_EXPO },
{ "easeInCirc", CLUTTER_EASE_IN_CIRC },
{ "easeOutCirc", CLUTTER_EASE_OUT_CIRC },
{ "easeInOutCirc", CLUTTER_EASE_IN_OUT_CIRC },
{ "easeInElastic", CLUTTER_EASE_IN_ELASTIC },
{ "easeOutElastic", CLUTTER_EASE_OUT_ELASTIC },
{ "easeInOutElastic", CLUTTER_EASE_IN_OUT_ELASTIC },
{ "easeInBack", CLUTTER_EASE_IN_BACK },
{ "easeOutBack", CLUTTER_EASE_OUT_BACK },
{ "easeInOutBack", CLUTTER_EASE_IN_OUT_BACK },
{ "easeInBounce", CLUTTER_EASE_IN_BOUNCE },
{ "easeOutBounce", CLUTTER_EASE_OUT_BOUNCE },
{ "easeInOutBounce", CLUTTER_EASE_IN_OUT_BOUNCE },
};
static const gint n_clutter_alphas = G_N_ELEMENTS (clutter_alphas);
static const gint n_animation_modes = G_N_ELEMENTS (animation_modes);
static ClutterAnimationMode
resolve_animation_mode (const gchar *name)
{
gint i, res = 0;
for (i = 0; i < n_animation_modes; i++)
{
if (strcmp (animation_modes[i].name, name) == 0)
return animation_modes[i].mode;
}
if (clutter_script_enum_from_string (CLUTTER_TYPE_ANIMATION_MODE,
name, &res))
return res;
g_warning ("Unable to find the animation mode '%s'", name);
return CLUTTER_CUSTOM_MODE;
}
static ClutterAlphaFunc
resolve_alpha_func (const gchar *name)
{
static GModule *module = NULL;
ClutterAlphaFunc func;
gint i;
CLUTTER_NOTE (SCRIPT, "Looking up `%s' alpha function", name);
for (i = 0; i < n_clutter_alphas; i++)
if (strcmp (name, clutter_alphas[i].name) == 0 ||
strcmp (name, clutter_alphas[i].short_name) == 0)
{
CLUTTER_NOTE (SCRIPT, "Found `%s' alpha function in the whitelist",
name);
return clutter_alphas[i].symbol;
}
if (G_UNLIKELY (!module))
module = g_module_open (NULL, G_MODULE_BIND_LAZY);
@ -573,6 +610,7 @@ clutter_script_parse_alpha (ClutterScript *script,
JsonObject *object;
ClutterTimeline *timeline = NULL;
ClutterAlphaFunc alpha_func = NULL;
ClutterAnimationMode mode = CLUTTER_CUSTOM_MODE;
JsonNode *val;
gboolean unref_timeline = FALSE;
@ -599,6 +637,12 @@ clutter_script_parse_alpha (ClutterScript *script,
}
}
val = json_object_get_member (object, "mode");
if (val && json_node_get_string (val) != NULL)
mode = resolve_animation_mode (json_node_get_string (val));
if (mode == CLUTTER_CUSTOM_MODE)
{
val = json_object_get_member (object, "function");
if (val && json_node_get_string (val) != NULL)
{
@ -610,14 +654,22 @@ clutter_script_parse_alpha (ClutterScript *script,
json_node_get_string (val));
}
}
}
CLUTTER_NOTE (SCRIPT, "Parsed alpha: %s timeline (%p) and func:%p",
CLUTTER_NOTE (SCRIPT, "Parsed alpha: %s timeline (%p) (mode:%d, func:%p)",
unref_timeline ? "implicit" : "explicit",
timeline ? timeline : 0x0,
mode != CLUTTER_CUSTOM_MODE ? mode : 0,
alpha_func ? alpha_func : 0x0);
retval = g_object_new (CLUTTER_TYPE_ALPHA, NULL);
if (mode != CLUTTER_CUSTOM_MODE)
clutter_alpha_set_mode (CLUTTER_ALPHA (retval), mode);
if (alpha_func != NULL)
clutter_alpha_set_func (CLUTTER_ALPHA (retval), alpha_func, NULL, NULL);
clutter_alpha_set_timeline (CLUTTER_ALPHA (retval), timeline);
if (unref_timeline)
g_object_unref (timeline);

View File

@ -43,7 +43,7 @@ static const gchar *test_behaviour =
" \"path\" : \"M 50 50 L 100 100\","
" \"alpha\" : {"
" \"timeline\" : \"main-timeline\","
" \"function\" : \"ramp\""
" \"mode\" : \"linear\""
" }"
" },"
" {"
@ -54,7 +54,7 @@ static const gchar *test_behaviour =
" \"axis\" : \"y-axis\","
" \"alpha\" : {"
" \"timeline\" : \"main-timeline\","
" \"function\" : \"sine\""
" \"mode\" : \"ease-in-sine\""
" }"
" },"
" {"
@ -64,7 +64,7 @@ static const gchar *test_behaviour =
" \"opacity-end\" : 0,"
" \"alpha\" : {"
" \"timeline\" : \"main-timeline\","
" \"function\" : \"ramp-inc\""
" \"mode\" : \"easeOutCubic\""
" }"
" }"
"]";