model: Implement ClutterScriptable interface
Allow a ClutterModel to be constructed through the ClutterScript API. Currently this allows a model to be generated like like this: { "id" : "test-model", "type" : "ClutterListModel", "columns" : [ [ "text-column", "gchararray" ], [ "int-column", "gint" ], [ "actor-column", "ClutterRectangle" ] ] } where 'columns' is an array containing arrays of column-name, column-type pairs. http://bugzilla.openedhand.com/show_bug.cgi?id=2007
This commit is contained in:
parent
63279f827e
commit
96c31bbf0e
5 changed files with 149 additions and 1 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -238,6 +238,7 @@ TAGS
|
|||
/tests/conform/test-texture-fbo
|
||||
/tests/conform/test-script-single
|
||||
/tests/conform/test-script-child
|
||||
/tests/conform/test-list-model-from-script
|
||||
/tests/conform/test-script-implicit-alpha
|
||||
/tests/conform/test-script-object-property
|
||||
/tests/conform/test-script-animation
|
||||
|
|
|
@ -132,8 +132,14 @@
|
|||
#include "clutter-marshal.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-scriptable.h"
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (ClutterModel, clutter_model, G_TYPE_OBJECT);
|
||||
static void clutter_scriptable_iface_init (ClutterScriptableIface *iface);
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_CODE
|
||||
(ClutterModel, clutter_model, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_SCRIPTABLE,
|
||||
clutter_scriptable_iface_init));
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -445,6 +451,103 @@ clutter_model_check_type (GType gtype)
|
|||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
gchar *name;
|
||||
GType type;
|
||||
} ColumnInfo;
|
||||
|
||||
static gboolean
|
||||
clutter_model_parse_custom_node (ClutterScriptable *scriptable,
|
||||
ClutterScript *script,
|
||||
GValue *value,
|
||||
const gchar *name,
|
||||
JsonNode *node)
|
||||
{
|
||||
GSList *columns = NULL;
|
||||
GList *elements, *l;
|
||||
|
||||
if (strcmp (name, "columns") != 0)
|
||||
return FALSE;
|
||||
|
||||
if (JSON_NODE_TYPE (node) != JSON_NODE_ARRAY)
|
||||
return FALSE;
|
||||
|
||||
elements = json_array_get_elements (json_node_get_array (node));
|
||||
|
||||
for (l = elements; l != NULL; l = l->next)
|
||||
{
|
||||
JsonNode *child_node = l->data;
|
||||
JsonArray *array = json_node_get_array (child_node);
|
||||
ColumnInfo *cinfo;
|
||||
const gchar *column_name;
|
||||
const gchar *type_name;
|
||||
|
||||
if (JSON_NODE_TYPE (node) != JSON_NODE_ARRAY ||
|
||||
json_array_get_length (array) != 2)
|
||||
{
|
||||
g_warning ("A column must be an array of "
|
||||
"[\"column-name\", \"GType-name\"] pairs");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
column_name = json_array_get_string_element (array, 0);
|
||||
type_name = json_array_get_string_element (array, 1);
|
||||
|
||||
cinfo = g_slice_new0 (ColumnInfo);
|
||||
cinfo->name = g_strdup (column_name);
|
||||
cinfo->type = clutter_script_get_type_from_name (script, type_name);
|
||||
|
||||
columns = g_slist_prepend (columns, cinfo);
|
||||
}
|
||||
|
||||
g_list_free (elements);
|
||||
|
||||
g_value_init (value, G_TYPE_POINTER);
|
||||
g_value_set_pointer (value, g_slist_reverse (columns));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_model_set_custom_property (ClutterScriptable *scriptable,
|
||||
ClutterScript *script,
|
||||
const gchar *name,
|
||||
const GValue *value)
|
||||
{
|
||||
if (strcmp (name, "columns") == 0)
|
||||
{
|
||||
ClutterModel *model = CLUTTER_MODEL (scriptable);
|
||||
GSList *columns, *l;
|
||||
guint n_columns;
|
||||
gint i;
|
||||
|
||||
columns = g_value_get_pointer (value);
|
||||
n_columns = g_slist_length (columns);
|
||||
|
||||
clutter_model_set_n_columns (model, n_columns, TRUE, TRUE);
|
||||
|
||||
for (i = 0, l = columns; l != NULL; l = l->next, i++)
|
||||
{
|
||||
ColumnInfo *cinfo = l->data;
|
||||
|
||||
clutter_model_set_column_name (model, i, cinfo->name);
|
||||
clutter_model_set_column_type (model, i, cinfo->type);
|
||||
|
||||
g_free (cinfo->name);
|
||||
g_slice_free (ColumnInfo, cinfo);
|
||||
}
|
||||
|
||||
g_slist_free (columns);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
clutter_scriptable_iface_init (ClutterScriptableIface *iface)
|
||||
{
|
||||
iface->parse_custom_node = clutter_model_parse_custom_node;
|
||||
iface->set_custom_property = clutter_model_set_custom_property;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_model_resort:
|
||||
|
|
|
@ -158,6 +158,7 @@ main (int argc, char **argv)
|
|||
TEST_CONFORM_SIMPLE ("/model", test_list_model_populate);
|
||||
TEST_CONFORM_SIMPLE ("/model", test_list_model_iterate);
|
||||
TEST_CONFORM_SIMPLE ("/model", test_list_model_filter);
|
||||
TEST_CONFORM_SIMPLE ("/model", test_list_model_from_script);
|
||||
|
||||
TEST_CONFORM_SIMPLE ("/color", test_color_from_string);
|
||||
TEST_CONFORM_SIMPLE ("/color", test_color_to_string);
|
||||
|
|
|
@ -335,3 +335,37 @@ test_list_model_populate (TestConformSimpleFixture *fixture,
|
|||
|
||||
g_object_unref (test_data.model);
|
||||
}
|
||||
|
||||
void
|
||||
test_list_model_from_script (TestConformSimpleFixture *fixture,
|
||||
gconstpointer dummy)
|
||||
{
|
||||
ClutterScript *script = clutter_script_new ();
|
||||
GObject *model;
|
||||
GError *error = NULL;
|
||||
gchar *test_file;
|
||||
const gchar *name;
|
||||
GType type;
|
||||
|
||||
test_file = clutter_test_get_data_file ("test-script-model.json");
|
||||
clutter_script_load_from_file (script, test_file, &error);
|
||||
if (g_test_verbose () && error)
|
||||
g_print ("Error: %s", error->message);
|
||||
g_assert (error == NULL);
|
||||
|
||||
model = clutter_script_get_object (script, "test-model");
|
||||
|
||||
g_assert (CLUTTER_IS_MODEL (model));
|
||||
g_assert (clutter_model_get_n_columns (CLUTTER_MODEL (model)) == 3);
|
||||
|
||||
name = clutter_model_get_column_name (CLUTTER_MODEL (model), 0);
|
||||
type = clutter_model_get_column_type (CLUTTER_MODEL (model), 0);
|
||||
g_assert (strcmp (name, "text-column") == 0);
|
||||
g_assert (type == G_TYPE_STRING);
|
||||
|
||||
name = clutter_model_get_column_name (CLUTTER_MODEL (model), 2);
|
||||
type = clutter_model_get_column_type (CLUTTER_MODEL (model), 2);
|
||||
g_print ("type: %s\n", g_type_name (type));
|
||||
g_assert (strcmp (name, "actor-column") == 0);
|
||||
g_assert (type == CLUTTER_TYPE_RECTANGLE);
|
||||
}
|
||||
|
|
9
tests/data/test-script-model.json
Normal file
9
tests/data/test-script-model.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"id" : "test-model",
|
||||
"type" : "ClutterListModel",
|
||||
"columns" : [
|
||||
[ "text-column", "gchararray" ],
|
||||
[ "int-column", "gint" ],
|
||||
[ "actor-column", "ClutterRectangle" ]
|
||||
]
|
||||
}
|
Loading…
Reference in a new issue