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
1
.gitignore
vendored
1
.gitignore
vendored
@ -238,6 +238,7 @@ TAGS
|
|||||||
/tests/conform/test-texture-fbo
|
/tests/conform/test-texture-fbo
|
||||||
/tests/conform/test-script-single
|
/tests/conform/test-script-single
|
||||||
/tests/conform/test-script-child
|
/tests/conform/test-script-child
|
||||||
|
/tests/conform/test-list-model-from-script
|
||||||
/tests/conform/test-script-implicit-alpha
|
/tests/conform/test-script-implicit-alpha
|
||||||
/tests/conform/test-script-object-property
|
/tests/conform/test-script-object-property
|
||||||
/tests/conform/test-script-animation
|
/tests/conform/test-script-animation
|
||||||
|
@ -132,8 +132,14 @@
|
|||||||
#include "clutter-marshal.h"
|
#include "clutter-marshal.h"
|
||||||
#include "clutter-private.h"
|
#include "clutter-private.h"
|
||||||
#include "clutter-debug.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
|
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:
|
* 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_populate);
|
||||||
TEST_CONFORM_SIMPLE ("/model", test_list_model_iterate);
|
TEST_CONFORM_SIMPLE ("/model", test_list_model_iterate);
|
||||||
TEST_CONFORM_SIMPLE ("/model", test_list_model_filter);
|
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_from_string);
|
||||||
TEST_CONFORM_SIMPLE ("/color", test_color_to_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);
|
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 New Issue
Block a user