From f04a0a464572fc97f92ca9d656a2784ec03e60cf Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Fri, 30 Nov 2007 09:27:10 +0000 Subject: [PATCH] 2007-11-30 Emmanuele Bassi * clutter/clutter-actor.c (parse_units), (clutter_actor_parse_custom_node), (clutter_scriptable_iface_init): Override the parsing code for the x, y, width and height properties of ClutterActor, to allow strings with modifiers when defining the position and/or the dimensions of an actor. Bare integers are assumed as pixels; floating point values in the [0, 1] interval are assumed as percentages; strings can have these modifiers: - px - pixels - mm - millimeters - pt - points (at the current resolution) - % - percentage of the stage * clutter/clutter-units.h: Fix the conversion macros * tests/test-script.json: Test the new values. --- ChangeLog | 20 +++++ clutter/clutter-actor.c | 160 ++++++++++++++++++++++++++++++++++++++-- clutter/clutter-units.h | 16 ++-- tests/test-script.json | 10 +-- 4 files changed, 185 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5b57416eb..b27f5694f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2007-11-30 Emmanuele Bassi + + * clutter/clutter-actor.c (parse_units), + (clutter_actor_parse_custom_node), + (clutter_scriptable_iface_init): Override the parsing code + for the x, y, width and height properties of ClutterActor, + to allow strings with modifiers when defining the position + and/or the dimensions of an actor. Bare integers are assumed + as pixels; floating point values in the [0, 1] interval are + assumed as percentages; strings can have these modifiers: + + - px - pixels + - mm - millimeters + - pt - points (at the current resolution) + - % - percentage of the stage + + * clutter/clutter-units.h: Fix the conversion macros + + * tests/test-script.json: Test the new values. + 2007-11-29 Emmanuele Bassi * clutter/clutter-model.[ch]: Slight API change in the constructor diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index 926b8c5af..2779eeb17 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -150,10 +150,6 @@ #include "clutter-units.h" #include "cogl.h" -G_DEFINE_ABSTRACT_TYPE (ClutterActor, - clutter_actor, - G_TYPE_INITIALLY_UNOWNED); - static guint32 __id = 0; @@ -220,11 +216,16 @@ enum static guint actor_signals[LAST_SIGNAL] = { 0, }; -static void -_clutter_actor_apply_modelview_transform (ClutterActor * self); +static void clutter_scriptable_iface_init (ClutterScriptableIface *iface); -static void -_clutter_actor_apply_modelview_transform_recursive (ClutterActor * self); +static void _clutter_actor_apply_modelview_transform (ClutterActor *self); +static void _clutter_actor_apply_modelview_transform_recursive (ClutterActor *self); + +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (ClutterActor, + clutter_actor, + G_TYPE_INITIALLY_UNOWNED, + G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_SCRIPTABLE, + clutter_scriptable_iface_init)); static gboolean redraw_update_idle (gpointer data) @@ -3764,6 +3765,149 @@ clutter_actor_set_anchor_point_from_gravity (ClutterActor *self, priv->anchor_y = y; } +typedef enum +{ + PARSE_X, + PARSE_Y, + PARSE_WIDTH, + PARSE_HEIGHT +} ParseDimension; + +static ClutterUnit +parse_units (ParseDimension dimension, + JsonNode *node) +{ + GValue value = { 0, }; + ClutterUnit retval = 0; + + if (JSON_NODE_TYPE (node) != JSON_NODE_VALUE) + return 0; + + json_node_get_value (node, &value); + + if (G_VALUE_HOLDS (&value, G_TYPE_INT)) + { + gint pixels = g_value_get_int (&value); + + retval = CLUTTER_UNITS_FROM_DEVICE (pixels); + } + else if (G_VALUE_HOLDS (&value, G_TYPE_STRING)) + { + gint64 val; + gchar *end; + + val = g_ascii_strtoll (g_value_get_string (&value), &end, 10); + + /* assume pixels */ + if (*end == '\0') + { + retval = CLUTTER_UNITS_FROM_DEVICE (val); + goto out; + } + + if (strcmp (end, "px") == 0) + { + retval = CLUTTER_UNITS_FROM_DEVICE (val); + goto out; + } + + if (strcmp (end, "mm") == 0) + { + retval = CLUTTER_UNITS_FROM_MM (val); + goto out; + } + + if (strcmp (end, "pt") == 0) + { + retval = CLUTTER_UNITS_FROM_POINTS (val); + goto out; + } + + if (end[0] == '%' && end[1] == '\0') + { + if (dimension == PARSE_X || dimension == PARSE_WIDTH) + retval = CLUTTER_UNITS_FROM_STAGE_WIDTH_PERCENTAGE (val); + else + retval = CLUTTER_UNITS_FROM_STAGE_HEIGHT_PERCENTAGE (val); + + goto out; + } + + g_warning ("Invalid value `%s': integers, strings or floating point " + "values can be used for the x, y, width and height " + "properties. Valid modifiers for strings are `px', 'mm' " + "and '%%'.", + g_value_get_string (&value)); + + retval = 0; + } + else if (G_VALUE_HOLDS (&value, G_TYPE_DOUBLE)) + { + gint val = CLAMP (g_value_get_double (&value) * 100, 0, 100); + + if (dimension == PARSE_X || dimension == PARSE_WIDTH) + retval = CLUTTER_UNITS_FROM_STAGE_WIDTH_PERCENTAGE (val); + else + retval = CLUTTER_UNITS_FROM_STAGE_HEIGHT_PERCENTAGE (val); + } + else + { + g_warning ("Invalid value of type `%s': integers, strings of floating " + "point values can be used for the x, y, width and height " + "properties.", + g_type_name (G_VALUE_TYPE (&value))); + } + +out: + g_value_unset (&value); + + return retval; +} + +static gboolean +clutter_actor_parse_custom_node (ClutterScriptable *scriptable, + ClutterScript *script, + GValue *value, + const gchar *name, + JsonNode *node) +{ + gboolean retval = FALSE; + + if ((name[0] == 'x' && name[1] == '\0') || + (name[0] == 'y' && name[1] == '\0') || + (strcmp (name, "width") == 0) || + (strcmp (name, "height") == 0)) + { + ClutterUnit units; + ParseDimension dimension; + + if (name[0] == 'x') + dimension = PARSE_X; + else if (name[0] == 'y') + dimension = PARSE_Y; + else if (name[0] == 'w') + dimension = PARSE_WIDTH; + else + dimension = PARSE_HEIGHT; + + units = parse_units (dimension, node); + + /* convert back to pixels */ + g_value_init (value, G_TYPE_INT); + g_value_set_int (value, CLUTTER_UNITS_TO_DEVICE (units)); + + retval = TRUE; + } + + return retval; +} + +static void +clutter_scriptable_iface_init (ClutterScriptableIface *iface) +{ + iface->parse_custom_node = clutter_actor_parse_custom_node; +} + /* * ClutterGeometry */ diff --git a/clutter/clutter-units.h b/clutter/clutter-units.h index 1b8ca09dc..a9acfac19 100644 --- a/clutter/clutter-units.h +++ b/clutter/clutter-units.h @@ -86,28 +86,28 @@ typedef gint32 ClutterUnit; #define CLUTTER_UNITS_TO_PANGO_UNIT(x) ((x) >> 6) #define CLUTTER_UNITS_FROM_STAGE_WIDTH_PERCENTAGE(x) \ - ((clutter_actor_get_widthu (clutter_stage_get_default ()) * x)/100) + ((clutter_actor_get_widthu (clutter_stage_get_default ()) * x) / 100) #define CLUTTER_UNITS_FROM_STAGE_HEIGHT_PERCENTAGE(x) \ - ((clutter_actor_get_heightu (clutter_stage_get_default ()) * x)/100) + ((clutter_actor_get_heightu (clutter_stage_get_default ()) * x) / 100) #define CLUTTER_UNITS_FROM_PARENT_WIDTH_PERCENTAGE(a, x) \ - ((clutter_actor_get_widthu (clutter_actor_get_parent (a)) * x)/100) + ((clutter_actor_get_widthu (clutter_actor_get_parent (a)) * x) / 100) #define CLUTTER_UNITS_FROM_PARENT_HEIGHT_PERCENTAGE(a, x) \ - ((clutter_actor_get_heightu (clutter_actor_get_parent (a)) * x)/100) + ((clutter_actor_get_heightu (clutter_actor_get_parent (a)) * x) / 100) #define CLUTTER_UNITS_FROM_MM(x) \ - CLUTTER_UNITS_FROM_FLOAT(((x*clutter_stage_get_resolution (clutter_stage_get_default ())) / 25.4)) + (CLUTTER_UNITS_FROM_FLOAT ((((x) * clutter_stage_get_resolution ((ClutterStage *) clutter_stage_get_default ())) / 25.4))) #define CLUTTER_UNITS_FROM_MMX(x) \ - CFX_DIV(CFX_MUL(x,clutter_stage_get_resolutionx(clutter_stage_get_default())),0x196666) + (CFX_DIV (CFX_MUL ((x), clutter_stage_get_resolutionx ((ClutterStage *) clutter_stage_get_default ())), 0x196666)) #define CLUTTER_UNITS_FROM_POINTS(x) \ - CLUTTER_UNITS_FROM_FLOAT(((x*clutter_stage_get_resolution(clutter_stage_get_default()))/72.0)) + CLUTTER_UNITS_FROM_FLOAT ((((x) * clutter_stage_get_resolution ((ClutterStage *) clutter_stage_get_default ())) / 72.0)) #define CLUTTER_UNITS_FROM_POINTSX(x) \ - (CFX_MUL(x,clutter_stage_get_resolutionx(clutter_stage_get_default()))/72) + (CFX_MUL ((x), clutter_stage_get_resolutionx ((ClutterStage *) clutter_stage_get_default ())) / 72) G_END_DECLS diff --git a/tests/test-script.json b/tests/test-script.json index dcc9b0e73..72039f988 100644 --- a/tests/test-script.json +++ b/tests/test-script.json @@ -4,7 +4,7 @@ "type" : "ClutterStage", "color" : "white", "width" : 500, - "height" : 400, + "height" : "400px", "signals" : [ { "name" : "key-press-event", "handler" : "clutter_main_quit" } ], @@ -38,10 +38,10 @@ "id" : "red-hand", "type" : "ClutterTexture", "pixbuf" : "redhand.png", - "x" : 50, - "y" : 150, - "width" : 100, - "height" : 100, + "x" : "50%", + "y" : "50%", + "width" : "20mm", + "height" : "100px", "opacity" : 100, "visible" : true, "behaviours" : [ "rotate-behaviour", "fade-behaviour" ]