actor: Add a custom scriptable "margin" property
authorBastian Winkler <buz@netbuz.org>
Sat, 19 May 2012 12:37:08 +0000 (14:37 +0200)
committerBastian Winkler <buz@netbuz.org>
Mon, 21 May 2012 13:31:34 +0000 (15:31 +0200)
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
tests/conform/script-parser.c
tests/conform/test-conform-main.c
tests/data/Makefile.am
tests/data/test-script-margin.json [new file with mode: 0644]

index 5ded50e..b2dcb1a 100644 (file)
  *   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".</para>
+ *   <para>#ClutterActor also defines a scriptable "margin" property which
+ *   follows the CSS "margin" shorthand.
+ *   <informalexample>
+ *     <programlisting>
+ * // 4 values
+ * "margin" : [ &lt;top&gt;, &lt;right&gt;, &lt;bottom&gt; &lt;left&gt; ]
+ * // 3 values
+ * "margin" : [ &lt;top&gt;, &lt;left/right&gt;, &lt;bottom&gt; ]
+ * // 2 values
+ * "margin" : [ &lt;top/bottom&gt;, &lt;left/right&gt; ]
+ * // 1 value
+ * "margin" : [ &lt;top/right/bottom/left&gt; ]
+ *     </programlisting>
+ *   </informalexample>
+ *   </para>
  *   <para>#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);
 }
index 4b51691..8c2ae7c 100644 (file)
@@ -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);
+}
+
index 04536ae..fd119ab 100644 (file)
@@ -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);
index e461a48..896ed5b 100644 (file)
@@ -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 (file)
index 0000000..1f5289f
--- /dev/null
@@ -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]
+  }
+]