From aeea9ee7785df7c07ef1af4f32f47dcd2e4cb22c Mon Sep 17 00:00:00 2001 From: Bastian Winkler Date: Sat, 19 May 2012 14:37:08 +0200 Subject: [PATCH] actor: Add a custom scriptable "margin" property The property uses an array with the following CSS style syntax [ top, right, bottom, left ] or [ top, left/right, bottom ] or [ top/bottom, left/right ] or [ top/right/bottom/left ] https://bugzilla.gnome.org/show_bug.cgi?id=676367 --- clutter/clutter-actor.c | 88 ++++++++++++++++++++++++++++++ tests/conform/script-parser.c | 44 +++++++++++++++ tests/conform/test-conform-main.c | 1 + tests/data/Makefile.am | 1 + tests/data/test-script-margin.json | 22 ++++++++ 5 files changed, 156 insertions(+) create mode 100644 tests/data/test-script-margin.json diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index 5ded50e6f..b2dcb1ade 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -383,6 +383,21 @@ * it must contain the center of rotation as described by two coordinates: * Y and Z for "x-axis"; X and Z for "y-axis"; and X and Y for * "z-axis". + * #ClutterActor also defines a scriptable "margin" property which + * follows the CSS "margin" shorthand. + * + * + * // 4 values + * "margin" : [ <top>, <right>, <bottom> <left> ] + * // 3 values + * "margin" : [ <top>, <left/right>, <bottom> ] + * // 2 values + * "margin" : [ <top/bottom>, <left/right> ] + * // 1 value + * "margin" : [ <top/right/bottom/left> ] + * + * + * * #ClutterActor will also parse every positional and dimensional * property defined as a string through clutter_units_from_string(); you * should read the documentation for the #ClutterUnits parser format for @@ -13017,6 +13032,63 @@ parse_behaviours (ClutterScript *script, return g_slist_reverse (retval); } +static ClutterMargin * +parse_margin (ClutterActor *self, + JsonNode *node) +{ + ClutterMargin *margin; + JsonArray *array; + + if (!JSON_NODE_HOLDS_ARRAY (node)) + { + g_warning ("The margin property must be an array of 1 to 4 elements"); + return NULL; + } + + margin = clutter_margin_new (); + array = json_node_get_array (node); + switch (json_array_get_length (array)) + { + case 1: + margin->top = margin->right = margin->bottom = margin->left = + parse_units (self, 0, json_array_get_element (array, 0)); + break; + + case 2: + margin->top = margin->bottom = + parse_units (self, 0, json_array_get_element (array, 0)); + margin->right = margin->left = + parse_units (self, 0, json_array_get_element (array, 1)); + break; + + case 3: + margin->top = + parse_units (self, 0, json_array_get_element (array, 0)); + margin->right = margin->left = + parse_units (self, 0, json_array_get_element (array, 1)); + margin->bottom = + parse_units (self, 0, json_array_get_element (array, 2)); + break; + + case 4: + margin->top = + parse_units (self, 0, json_array_get_element (array, 0)); + margin->right = + parse_units (self, 0, json_array_get_element (array, 1)); + margin->bottom = + parse_units (self, 0, json_array_get_element (array, 2)); + margin->left = + parse_units (self, 0, json_array_get_element (array, 3)); + break; + + default: + g_warning ("The margin property must be an array of 1 to 4 elements"); + clutter_margin_free (margin); + return NULL; + } + return margin; +} + static gboolean clutter_actor_parse_custom_node (ClutterScriptable *scriptable, ClutterScript *script, @@ -13106,6 +13178,17 @@ clutter_actor_parse_custom_node (ClutterScriptable *scriptable, retval = TRUE; } + else if (strcmp (name, "margin") == 0) + { + ClutterMargin *margin = parse_margin (actor, node); + + if (margin) + { + g_value_init (value, CLUTTER_TYPE_MARGIN); + g_value_set_boxed (value, margin); + retval = TRUE; + } + } return retval; } @@ -13198,6 +13281,11 @@ clutter_actor_set_custom_property (ClutterScriptable *scriptable, return; } + if (strcmp (name, "margin") == 0) + { + clutter_actor_set_margin (actor, g_value_get_boxed (value)); + return; + } g_object_set_property (G_OBJECT (scriptable), name, value); } diff --git a/tests/conform/script-parser.c b/tests/conform/script-parser.c index 4b5169163..8c2ae7cd0 100644 --- a/tests/conform/script-parser.c +++ b/tests/conform/script-parser.c @@ -398,3 +398,47 @@ script_layout_property (TestConformSimpleFixture *fixture, g_object_unref (script); } + +script_margin (TestConformSimpleFixture *fixture, + gpointer dummy) +{ + ClutterScript *script = clutter_script_new (); + ClutterActor *actor; + gchar *test_file; + GError *error = NULL; + + test_file = clutter_test_get_data_file ("test-script-margin.json"); + clutter_script_load_from_file (script, test_file, &error); + if (g_test_verbose () && error) + g_print ("Error: %s", error->message); + + g_assert_no_error (error); + + actor = CLUTTER_ACTOR (clutter_script_get_object (script, "actor-1")); + g_assert_cmpfloat (clutter_actor_get_margin_top (actor), ==, 10.0f); + g_assert_cmpfloat (clutter_actor_get_margin_right (actor), ==, 10.0f); + g_assert_cmpfloat (clutter_actor_get_margin_bottom (actor), ==, 10.0f); + g_assert_cmpfloat (clutter_actor_get_margin_left (actor), ==, 10.0f); + + actor = CLUTTER_ACTOR (clutter_script_get_object (script, "actor-2")); + g_assert_cmpfloat (clutter_actor_get_margin_top (actor), ==, 10.0f); + g_assert_cmpfloat (clutter_actor_get_margin_right (actor), ==, 20.0f); + g_assert_cmpfloat (clutter_actor_get_margin_bottom (actor), ==, 10.0f); + g_assert_cmpfloat (clutter_actor_get_margin_left (actor), ==, 20.0f); + + actor = CLUTTER_ACTOR (clutter_script_get_object (script, "actor-3")); + g_assert_cmpfloat (clutter_actor_get_margin_top (actor), ==, 10.0f); + g_assert_cmpfloat (clutter_actor_get_margin_right (actor), ==, 20.0f); + g_assert_cmpfloat (clutter_actor_get_margin_bottom (actor), ==, 30.0f); + g_assert_cmpfloat (clutter_actor_get_margin_left (actor), ==, 20.0f); + + actor = CLUTTER_ACTOR (clutter_script_get_object (script, "actor-4")); + g_assert_cmpfloat (clutter_actor_get_margin_top (actor), ==, 10.0f); + g_assert_cmpfloat (clutter_actor_get_margin_right (actor), ==, 20.0f); + g_assert_cmpfloat (clutter_actor_get_margin_bottom (actor), ==, 30.0f); + g_assert_cmpfloat (clutter_actor_get_margin_left (actor), ==, 40.0f); + + g_object_unref (script); + g_free (test_file); +} + diff --git a/tests/conform/test-conform-main.c b/tests/conform/test-conform-main.c index 04536ae97..fd119ab22 100644 --- a/tests/conform/test-conform-main.c +++ b/tests/conform/test-conform-main.c @@ -221,6 +221,7 @@ main (int argc, char **argv) TEST_CONFORM_SIMPLE ("/script", animator_properties); TEST_CONFORM_SIMPLE ("/script", animator_multi_properties); TEST_CONFORM_SIMPLE ("/script", state_base); + TEST_CONFORM_SIMPLE ("/script", script_margin); TEST_CONFORM_SIMPLE ("/timeline", timeline_base); TEST_CONFORM_SIMPLE ("/timeline", timeline_markers_from_script); diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index e461a48ab..896ed5b27 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -16,6 +16,7 @@ json_files = \ test-animator-3.json \ test-state-1.json \ test-script-timeline-markers.json \ + test-script-margin.json \ $(NULL) png_files = \ diff --git a/tests/data/test-script-margin.json b/tests/data/test-script-margin.json new file mode 100644 index 000000000..1f5289fa6 --- /dev/null +++ b/tests/data/test-script-margin.json @@ -0,0 +1,22 @@ +[ + { + "id" : "actor-1", + "type" : "ClutterActor", + "margin" : [ 10 ] + }, + { + "id" : "actor-2", + "type" : "ClutterActor", + "margin" : [ 10, 20 ] + }, + { + "id" : "actor-3", + "type" : "ClutterActor", + "margin" : [ 10, 20, 30 ] + }, + { + "id" : "actor-4", + "type" : "ClutterActor", + "margin" : [ 10, 20, 30, 40] + } +]