/tests/conform/test-cogl-viewport
/tests/conform/test-texture-fbo
/tests/conform/test-script-single
+/tests/conform/test-script-child
/tests/micro-bench/test-text-perf
/tests/micro-bench/test-text
/tests/micro-bench/test-picking
pinfo->name = g_strdup (name);
pinfo->node = json_node_copy (node);
pinfo->pspec = NULL;
+ pinfo->is_child = g_str_has_prefix (name, "child::") ? TRUE : FALSE;
oinfo->properties = g_list_prepend (oinfo->properties, pinfo);
}
GParameter param = { NULL };
gboolean res = FALSE;
+ if (pinfo->is_child)
+ {
+ CLUTTER_NOTE (SCRIPT, "Child property '%s' ignored", pinfo->name);
+ unparsed = g_list_prepend (unparsed, pinfo);
+ continue;
+ }
+
CLUTTER_NOTE (SCRIPT, "Parsing %s property (id:%s)",
pinfo->pspec ? "regular" : "custom",
pinfo->name);
}
static void
+apply_child_properties (ClutterScript *script,
+ ClutterContainer *container,
+ ClutterActor *actor,
+ ObjectInfo *oinfo)
+{
+ ClutterScriptable *scriptable = NULL;
+ ClutterScriptableIface *iface = NULL;
+ gboolean set_custom_property = FALSE;
+ gboolean parse_custom_node = FALSE;
+ GList *l, *unresolved, *properties;
+ GObjectClass *klass;
+ GType meta_type;
+
+ meta_type = CLUTTER_CONTAINER_GET_IFACE (container)->child_meta_type;
+ if (meta_type == G_TYPE_INVALID)
+ return;
+
+ klass = G_OBJECT_GET_CLASS (container);
+
+ /* shortcut, to avoid typechecking every time */
+ if (CLUTTER_IS_SCRIPTABLE (container))
+ {
+ scriptable = CLUTTER_SCRIPTABLE (container);
+ iface = CLUTTER_SCRIPTABLE_GET_IFACE (scriptable);
+
+ parse_custom_node = iface->parse_custom_node != NULL ? TRUE : FALSE;
+ set_custom_property = iface->set_custom_property != NULL ? TRUE : FALSE;
+ }
+
+ properties = oinfo->properties;
+ oinfo->properties = NULL;
+
+ unresolved = NULL;
+ for (l = properties; l != NULL; l = l->next)
+ {
+ PropertyInfo *pinfo = l->data;
+ GValue value = { 0, };
+ const gchar *name;
+ gboolean res;
+
+ if (!pinfo->is_child)
+ {
+ unresolved = g_list_prepend (unresolved, pinfo);
+ continue;
+ }
+
+ name = pinfo->name + strlen ("child::");
+
+ pinfo->pspec =
+ clutter_container_class_find_child_property (klass, name);
+
+ if (pinfo->pspec != NULL)
+ g_param_spec_ref (pinfo->pspec);
+
+ CLUTTER_NOTE (SCRIPT, "Parsing %s child property (id:%s)",
+ pinfo->pspec != NULL ? "regular" : "custom",
+ name);
+
+ if (parse_custom_node)
+ res = iface->parse_custom_node (scriptable, script, &value,
+ name,
+ pinfo->node);
+
+ if (!res)
+ res = clutter_script_parse_node (script, &value,
+ name,
+ pinfo->node,
+ pinfo->pspec);
+
+ if (!res)
+ {
+ CLUTTER_NOTE (SCRIPT, "Child property '%s' ignored", name);
+ unresolved = g_list_prepend (unresolved, pinfo);
+ continue;
+ }
+
+
+ CLUTTER_NOTE (SCRIPT,
+ "Setting %s child property '%s' (type:%s) to "
+ "object '%s' (id:%s)",
+ set_custom_property ? "custom" : "regular",
+ name,
+ g_type_name (G_VALUE_TYPE (&value)),
+ g_type_name (oinfo->gtype),
+ oinfo->id);
+
+ clutter_container_child_set_property (container, actor,
+ name,
+ &value);
+
+ g_value_unset (&value);
+
+ property_info_free (pinfo);
+ }
+
+ g_list_free (properties);
+
+ oinfo->properties = unresolved;
+}
+
+static void
apply_behaviours (ClutterScript *script,
ObjectInfo *oinfo)
{
- ClutterActor *actor = CLUTTER_ACTOR (oinfo->object);
+ ClutterActor *actor = CLUTTER_ACTOR (oinfo->object);
GList *l, *unresolved;
unresolved = NULL;
g_type_name (G_OBJECT_TYPE (container)));
clutter_container_add_actor (container, CLUTTER_ACTOR (object));
+
+ apply_child_properties (script,
+ container, CLUTTER_ACTOR (object),
+ child_info);
}
g_list_foreach (oinfo->children, (GFunc) g_free, NULL);
gchar *name;
JsonNode *node;
GParamSpec *pspec;
+
+ guint is_child : 1;
} PropertyInfo;
typedef struct {
test_conformance_LDADD = $(top_builddir)/clutter/libclutter-@CLUTTER_WINSYS@-@CLUTTER_API_VERSION@.la $(CLUTTER_LIBS)
+test_conformance_LDFLAGS = -rdynamic
+
.PHONY: test
.PHONY: test-report test-report-normal test-report-disable-npots
.PHONY: full-report full-report-normal full-report-disable-npots
TEST_CONFORM_SIMPLE ("/cogl", test_cogl_readpixels);
TEST_CONFORM_SIMPLE ("/script", test_script_single);
+ TEST_CONFORM_SIMPLE ("/script", test_script_child);
return g_test_run ();
}
#include "test-conform-common.h"
+#define TEST_TYPE_GROUP (test_group_get_type ())
+#define TEST_TYPE_GROUP_META (test_group_meta_get_type ())
+
+#define TEST_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_GROUP, TestGroup))
+#define TEST_IS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_GROUP))
+
+#define TEST_GROUP_META(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_GROUP_META, TestGroupMeta))
+#define TEST_IS_GROUP_META(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_GROUP_META))
+
+typedef struct _ClutterGroup TestGroup;
+
+typedef struct _TestGroupMeta {
+ ClutterChildMeta parent_instance;
+
+ guint is_focus : 1;
+} TestGroupMeta;
+
+typedef struct _ClutterGroupClass TestGroupClass;
+typedef struct _ClutterChildMetaClass TestGroupMetaClass;
+
+G_DEFINE_TYPE (TestGroupMeta, test_group_meta, CLUTTER_TYPE_CHILD_META);
+
+enum
+{
+ PROP_META_0,
+
+ PROP_META_FOCUS
+};
+
+static void
+test_group_meta_set_property (GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TestGroupMeta *self = TEST_GROUP_META (gobject);
+
+ switch (prop_id)
+ {
+ case PROP_META_FOCUS:
+ self->is_focus = g_value_get_boolean (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+test_group_meta_get_property (GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TestGroupMeta *self = TEST_GROUP_META (gobject);
+
+ switch (prop_id)
+ {
+ case PROP_META_FOCUS:
+ g_value_set_boolean (value, self->is_focus);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+test_group_meta_class_init (TestGroupMetaClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GParamSpec *pspec;
+
+ gobject_class->set_property = test_group_meta_set_property;
+ gobject_class->get_property = test_group_meta_get_property;
+
+ pspec = g_param_spec_boolean ("focus", "Focus", "Focus",
+ FALSE,
+ G_PARAM_READWRITE);
+ g_object_class_install_property (gobject_class, PROP_META_FOCUS, pspec);
+}
+
+static void
+test_group_meta_init (TestGroupMeta *meta)
+{
+ meta->is_focus = FALSE;
+}
+
+static void
+clutter_container_iface_init (ClutterContainerIface *iface)
+{
+ iface->child_meta_type = TEST_TYPE_GROUP_META;
+}
+
+G_DEFINE_TYPE_WITH_CODE (TestGroup, test_group, CLUTTER_TYPE_GROUP,
+ G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER,
+ clutter_container_iface_init));
+
+static void
+test_group_class_init (TestGroupClass *klass)
+{
+}
+
+static void
+test_group_init (TestGroup *self)
+{
+}
+
+void
+test_script_child (TestConformSimpleFixture *fixture,
+ gconstpointer dummy)
+{
+ ClutterScript *script = clutter_script_new ();
+ GObject *container, *actor;
+ GError *error = NULL;
+ gboolean focus_ret;
+ gchar *test_file;
+
+ test_file = clutter_test_get_data_file ("test-script-child.json");
+ clutter_script_load_from_file (script, test_file, &error);
+ if (g_test_verbose () && (error != NULL))
+ g_warning ("Unable to load '%s': %s", test_file, error->message);
+ g_assert (error == NULL);
+
+ container = actor = NULL;
+ clutter_script_get_objects (script,
+ "test-group", &container,
+ "test-rect-1", &actor,
+ NULL);
+ g_assert (TEST_IS_GROUP (container));
+ g_assert (CLUTTER_IS_RECTANGLE (actor));
+
+ focus_ret = FALSE;
+ clutter_container_child_get (CLUTTER_CONTAINER (container),
+ CLUTTER_ACTOR (actor),
+ "focus", &focus_ret,
+ NULL);
+ g_assert (focus_ret);
+
+ actor = clutter_script_get_object (script, "test-rect-2");
+ g_assert (CLUTTER_IS_RECTANGLE (actor));
+
+ focus_ret = FALSE;
+ clutter_container_child_get (CLUTTER_CONTAINER (container),
+ CLUTTER_ACTOR (actor),
+ "focus", &focus_ret,
+ NULL);
+ g_assert (!focus_ret);
+
+ g_object_unref (script);
+ clutter_actor_destroy (CLUTTER_ACTOR (container));
+ g_free (test_file);
+}
+
void
test_script_single (TestConformSimpleFixture *fixture,
gconstpointer dummy)
--- /dev/null
+{
+ "type" : "TestGroup",
+ "id" : "test-group",
+ "children" : [
+ {
+ "type" : "ClutterRectangle",
+ "id" : "test-rect-1",
+ "width" : 100.0,
+ "height" : 100.0,
+ "color" : [ 255, 0, 0, 255 ],
+ "child::focus" : true
+ },
+ {
+ "type" : "ClutterRectangle",
+ "id" : "test-rect-2",
+ "width" : 100.0,
+ "height" : 100.0,
+ "color" : [ 0, 255, 0, 255 ]
+ }
+ ]
+}