|
Packit |
31ecd5 |
/*
|
|
Packit |
31ecd5 |
* Clutter.
|
|
Packit |
31ecd5 |
*
|
|
Packit |
31ecd5 |
* An OpenGL based 'interactive canvas' library.
|
|
Packit |
31ecd5 |
*
|
|
Packit |
31ecd5 |
* Copyright (C) 2006, 2007, 2008 OpenedHand Ltd
|
|
Packit |
31ecd5 |
* Copyright (C) 2009 Intel Corportation
|
|
Packit |
31ecd5 |
*
|
|
Packit |
31ecd5 |
* This library is free software; you can redistribute it and/or
|
|
Packit |
31ecd5 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
31ecd5 |
* License as published by the Free Software Foundation; either
|
|
Packit |
31ecd5 |
* version 2 of the License, or (at your option) any later version.
|
|
Packit |
31ecd5 |
*
|
|
Packit |
31ecd5 |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
31ecd5 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
31ecd5 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
31ecd5 |
* Lesser General Public License for more details.
|
|
Packit |
31ecd5 |
*
|
|
Packit |
31ecd5 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
31ecd5 |
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
31ecd5 |
*
|
|
Packit |
31ecd5 |
* Original author:
|
|
Packit |
31ecd5 |
*
|
|
Packit |
31ecd5 |
* Emmanuele Bassi <ebassi@linux.intel.com>
|
|
Packit |
31ecd5 |
*/
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
31ecd5 |
#include "config.h"
|
|
Packit |
31ecd5 |
#endif
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
#include <string.h>
|
|
Packit |
31ecd5 |
#include <stdlib.h>
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
#include <glib.h>
|
|
Packit |
31ecd5 |
#include <gmodule.h>
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
|
|
Packit |
31ecd5 |
#include "deprecated/clutter-container.h"
|
|
Packit |
31ecd5 |
#include "deprecated/clutter-alpha.h"
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
#include "clutter-actor.h"
|
|
Packit |
31ecd5 |
#include "clutter-debug.h"
|
|
Packit |
31ecd5 |
#include "clutter-enum-types.h"
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
#include "clutter-script.h"
|
|
Packit |
31ecd5 |
#include "clutter-script-private.h"
|
|
Packit |
31ecd5 |
#include "clutter-scriptable.h"
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
#include "clutter-stage-manager.h"
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
#include "clutter-private.h"
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static void clutter_script_parser_object_end (JsonParser *parser,
|
|
Packit |
31ecd5 |
JsonObject *object);
|
|
Packit |
31ecd5 |
static void clutter_script_parser_parse_end (JsonParser *parser);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
#define clutter_script_parser_get_type _clutter_script_parser_get_type
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
G_DEFINE_TYPE (ClutterScriptParser, clutter_script_parser, JSON_TYPE_PARSER);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static void
|
|
Packit |
31ecd5 |
clutter_script_parser_class_init (ClutterScriptParserClass *klass)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
JsonParserClass *parser_class = JSON_PARSER_CLASS (klass);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
parser_class->object_end = clutter_script_parser_object_end;
|
|
Packit |
31ecd5 |
parser_class->parse_end = clutter_script_parser_parse_end;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static void
|
|
Packit |
31ecd5 |
clutter_script_parser_init (ClutterScriptParser *parser)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
GType
|
|
Packit |
31ecd5 |
_clutter_script_get_type_from_symbol (const gchar *symbol)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
static GModule *module = NULL;
|
|
Packit |
31ecd5 |
GTypeGetFunc func;
|
|
Packit |
31ecd5 |
GType gtype = G_TYPE_INVALID;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (!module)
|
|
Packit |
31ecd5 |
module = g_module_open (NULL, 0);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (g_module_symbol (module, symbol, (gpointer)&func))
|
|
Packit |
31ecd5 |
gtype = func ();
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return gtype;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
GType
|
|
Packit |
31ecd5 |
_clutter_script_get_type_from_class (const gchar *name)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
static GModule *module = NULL;
|
|
Packit |
31ecd5 |
GString *symbol_name = g_string_sized_new (64);
|
|
Packit |
31ecd5 |
GType gtype = G_TYPE_INVALID;
|
|
Packit |
31ecd5 |
GTypeGetFunc func;
|
|
Packit |
31ecd5 |
gchar *symbol;
|
|
Packit |
31ecd5 |
gint i;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (G_UNLIKELY (!module))
|
|
Packit |
31ecd5 |
module = g_module_open (NULL, 0);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
for (i = 0; name[i] != '\0'; i++)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
gchar c = name[i];
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* the standard naming policy for GObject-based libraries
|
|
Packit |
31ecd5 |
* is:
|
|
Packit |
31ecd5 |
*
|
|
Packit |
31ecd5 |
* NAME := INITIAL_WORD WORD+
|
|
Packit |
31ecd5 |
* INITIAL_WORD := [A-Z][a-z0-9]*
|
|
Packit |
31ecd5 |
* WORD := [A-Z]{1,2}[a-z0-9]+ | [A-Z]{2,}
|
|
Packit |
31ecd5 |
*
|
|
Packit |
31ecd5 |
* for instance:
|
|
Packit |
31ecd5 |
*
|
|
Packit |
31ecd5 |
* GString -> g_string
|
|
Packit |
31ecd5 |
* GtkCTree -> gtk_ctree
|
|
Packit |
31ecd5 |
* ClutterX11TexturePixmap -> clutter_x11_texture_pixmap
|
|
Packit |
31ecd5 |
*
|
|
Packit |
31ecd5 |
* see:
|
|
Packit |
31ecd5 |
*
|
|
Packit |
31ecd5 |
* http://mail.gnome.org/archives/gtk-devel-list/2007-June/msg00022.html
|
|
Packit |
31ecd5 |
*
|
|
Packit |
31ecd5 |
* and:
|
|
Packit |
31ecd5 |
*
|
|
Packit |
31ecd5 |
* http://git.gnome.org/cgit/gtk+/plain/gtk/gtkbuilderparser.c
|
|
Packit |
31ecd5 |
*/
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if ((c == g_ascii_toupper (c) &&
|
|
Packit |
31ecd5 |
i > 0 && name[i - 1] != g_ascii_toupper (name[i - 1])) ||
|
|
Packit |
31ecd5 |
(i > 2 && name[i] == g_ascii_toupper (name[i]) &&
|
|
Packit |
31ecd5 |
name[i - 1] == g_ascii_toupper (name[i - 1]) &&
|
|
Packit |
31ecd5 |
name[i - 2] == g_ascii_toupper (name[i - 2])))
|
|
Packit |
31ecd5 |
g_string_append_c (symbol_name, '_');
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_string_append_c (symbol_name, g_ascii_tolower (c));
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_string_append (symbol_name, "_get_type");
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
symbol = g_string_free (symbol_name, FALSE);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (g_module_symbol (module, symbol, (gpointer)&func))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT, "Type function: %s", symbol);
|
|
Packit |
31ecd5 |
gtype = func ();
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_free (symbol);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return gtype;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/*
|
|
Packit |
31ecd5 |
* clutter_script_enum_from_string:
|
|
Packit |
31ecd5 |
* @type: a #GType for an enumeration type
|
|
Packit |
31ecd5 |
* @string: the enumeration value as a string
|
|
Packit |
31ecd5 |
* @enum_value: (out): return location for the enumeration value as an integer
|
|
Packit |
31ecd5 |
*
|
|
Packit |
31ecd5 |
* Converts an enumeration value inside @string into a numeric
|
|
Packit |
31ecd5 |
* value and places it into @enum_value.
|
|
Packit |
31ecd5 |
*
|
|
Packit |
31ecd5 |
* The enumeration value can be an integer, the enumeration nick
|
|
Packit |
31ecd5 |
* or the enumeration name, as part of the #GEnumValue structure.
|
|
Packit |
31ecd5 |
*
|
|
Packit |
31ecd5 |
* Return value: %TRUE if the conversion was successfull.
|
|
Packit |
31ecd5 |
*/
|
|
Packit |
31ecd5 |
gboolean
|
|
Packit |
31ecd5 |
_clutter_script_enum_from_string (GType type,
|
|
Packit |
31ecd5 |
const gchar *string,
|
|
Packit |
31ecd5 |
gint *enum_value)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
GEnumClass *eclass;
|
|
Packit |
31ecd5 |
GEnumValue *ev;
|
|
Packit |
31ecd5 |
gchar *endptr;
|
|
Packit |
31ecd5 |
gint value;
|
|
Packit |
31ecd5 |
gboolean retval = TRUE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_return_val_if_fail (G_TYPE_IS_ENUM (type), 0);
|
|
Packit |
31ecd5 |
g_return_val_if_fail (string != NULL, 0);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
value = strtoul (string, &endptr, 0);
|
|
Packit |
31ecd5 |
if (endptr != string) /* parsed a number */
|
|
Packit |
31ecd5 |
*enum_value = value;
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
eclass = g_type_class_ref (type);
|
|
Packit |
31ecd5 |
ev = g_enum_get_value_by_name (eclass, string);
|
|
Packit |
31ecd5 |
if (!ev)
|
|
Packit |
31ecd5 |
ev = g_enum_get_value_by_nick (eclass, string);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (ev)
|
|
Packit |
31ecd5 |
*enum_value = ev->value;
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
retval = FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_type_class_unref (eclass);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return retval;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
gboolean
|
|
Packit |
31ecd5 |
_clutter_script_flags_from_string (GType type,
|
|
Packit |
31ecd5 |
const gchar *string,
|
|
Packit |
31ecd5 |
gint *flags_value)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
gchar *endptr, *prevptr;
|
|
Packit |
31ecd5 |
guint i, j, ret, value;
|
|
Packit |
31ecd5 |
gchar *flagstr;
|
|
Packit |
31ecd5 |
GFlagsValue *fv;
|
|
Packit |
31ecd5 |
const gchar *flag;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_return_val_if_fail (G_TYPE_IS_FLAGS (type), 0);
|
|
Packit |
31ecd5 |
g_return_val_if_fail (string != NULL, 0);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
ret = TRUE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
value = strtoul (string, &endptr, 0);
|
|
Packit |
31ecd5 |
if (endptr != string) /* parsed a number */
|
|
Packit |
31ecd5 |
*flags_value = value;
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
GFlagsClass *fclass;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
fclass = g_type_class_ref (type);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
flagstr = g_strdup (string);
|
|
Packit |
31ecd5 |
for (value = i = j = 0; ; i++)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
gboolean eos = (flagstr[i] == '\0') ? TRUE : FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (!eos && flagstr[i] != '|')
|
|
Packit |
31ecd5 |
continue;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
flag = &flagstr[j];
|
|
Packit |
31ecd5 |
endptr = &flagstr[i];
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (!eos)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
flagstr[i++] = '\0';
|
|
Packit |
31ecd5 |
j = i;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* trim spaces */
|
|
Packit |
31ecd5 |
for (;;)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
gunichar ch = g_utf8_get_char (flag);
|
|
Packit |
31ecd5 |
if (!g_unichar_isspace (ch))
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
flag = g_utf8_next_char (flag);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
while (endptr > flag)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
gunichar ch;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
prevptr = g_utf8_prev_char (endptr);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
ch = g_utf8_get_char (prevptr);
|
|
Packit |
31ecd5 |
if (!g_unichar_isspace (ch))
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
endptr = prevptr;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (endptr > flag)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
*endptr = '\0';
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
fv = g_flags_get_value_by_name (fclass, flag);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (!fv)
|
|
Packit |
31ecd5 |
fv = g_flags_get_value_by_nick (fclass, flag);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (fv)
|
|
Packit |
31ecd5 |
value |= fv->value;
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ret = FALSE;
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (eos)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
*flags_value = value;
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_free (flagstr);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_type_class_unref (fclass);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return ret;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static gboolean
|
|
Packit |
31ecd5 |
parse_knot_from_array (JsonArray *array,
|
|
Packit |
31ecd5 |
ClutterKnot *knot)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
if (json_array_get_length (array) != 2)
|
|
Packit |
31ecd5 |
return FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
knot->x = json_array_get_int_element (array, 0);
|
|
Packit |
31ecd5 |
knot->y = json_array_get_int_element (array, 1);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static gboolean
|
|
Packit |
31ecd5 |
parse_knot_from_object (JsonObject *object,
|
|
Packit |
31ecd5 |
ClutterKnot *knot)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "x"))
|
|
Packit |
31ecd5 |
knot->x = json_object_get_int_member (object, "x");
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
knot->x = 0;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "y"))
|
|
Packit |
31ecd5 |
knot->y = json_object_get_int_member (object, "y");
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
knot->y = 0;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
gboolean
|
|
Packit |
31ecd5 |
_clutter_script_parse_knot (ClutterScript *script,
|
|
Packit |
31ecd5 |
JsonNode *node,
|
|
Packit |
31ecd5 |
ClutterKnot *knot)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
g_return_val_if_fail (CLUTTER_IS_SCRIPT (script), FALSE);
|
|
Packit |
31ecd5 |
g_return_val_if_fail (node != NULL, FALSE);
|
|
Packit |
31ecd5 |
g_return_val_if_fail (knot != NULL, FALSE);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
switch (JSON_NODE_TYPE (node))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
case JSON_NODE_ARRAY:
|
|
Packit |
31ecd5 |
return parse_knot_from_array (json_node_get_array (node), knot);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
case JSON_NODE_OBJECT:
|
|
Packit |
31ecd5 |
return parse_knot_from_object (json_node_get_object (node), knot);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
default:
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return FALSE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static gboolean
|
|
Packit |
31ecd5 |
parse_geometry_from_array (JsonArray *array,
|
|
Packit |
31ecd5 |
ClutterGeometry *geometry)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
if (json_array_get_length (array) != 4)
|
|
Packit |
31ecd5 |
return FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
geometry->x = json_array_get_int_element (array, 0);
|
|
Packit |
31ecd5 |
geometry->y = json_array_get_int_element (array, 1);
|
|
Packit |
31ecd5 |
geometry->width = json_array_get_int_element (array, 2);
|
|
Packit |
31ecd5 |
geometry->height = json_array_get_int_element (array, 3);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static gboolean
|
|
Packit |
31ecd5 |
parse_geometry_from_object (JsonObject *object,
|
|
Packit |
31ecd5 |
ClutterGeometry *geometry)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "x"))
|
|
Packit |
31ecd5 |
geometry->x = json_object_get_int_member (object, "x");
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
geometry->x = 0;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "y"))
|
|
Packit |
31ecd5 |
geometry->y = json_object_get_int_member (object, "y");
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
geometry->y = 0;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "width"))
|
|
Packit |
31ecd5 |
geometry->width = json_object_get_int_member (object, "width");
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
geometry->width = 0;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "height"))
|
|
Packit |
31ecd5 |
geometry->height = json_object_get_int_member (object, "height");
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
geometry->height = 0;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
gboolean
|
|
Packit |
31ecd5 |
_clutter_script_parse_geometry (ClutterScript *script,
|
|
Packit |
31ecd5 |
JsonNode *node,
|
|
Packit |
31ecd5 |
ClutterGeometry *geometry)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
g_return_val_if_fail (CLUTTER_IS_SCRIPT (script), FALSE);
|
|
Packit |
31ecd5 |
g_return_val_if_fail (node != NULL, FALSE);
|
|
Packit |
31ecd5 |
g_return_val_if_fail (geometry != NULL, FALSE);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
switch (JSON_NODE_TYPE (node))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
case JSON_NODE_ARRAY:
|
|
Packit |
31ecd5 |
return parse_geometry_from_array (json_node_get_array (node), geometry);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
case JSON_NODE_OBJECT:
|
|
Packit |
31ecd5 |
return parse_geometry_from_object (json_node_get_object (node), geometry);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
default:
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return FALSE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static gboolean
|
|
Packit |
31ecd5 |
parse_color_from_array (JsonArray *array,
|
|
Packit |
31ecd5 |
ClutterColor *color)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
if (json_array_get_length (array) != 3 ||
|
|
Packit |
31ecd5 |
json_array_get_length (array) != 4)
|
|
Packit |
31ecd5 |
return FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
color->red = CLAMP (json_array_get_int_element (array, 0), 0, 255);
|
|
Packit |
31ecd5 |
color->green = CLAMP (json_array_get_int_element (array, 1), 0, 255);
|
|
Packit |
31ecd5 |
color->blue = CLAMP (json_array_get_int_element (array, 2), 0, 255);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (json_array_get_length (array) == 4)
|
|
Packit |
31ecd5 |
color->alpha = CLAMP (json_array_get_int_element (array, 3), 0, 255);
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
color->alpha = 255;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static gboolean
|
|
Packit |
31ecd5 |
parse_color_from_object (JsonObject *object,
|
|
Packit |
31ecd5 |
ClutterColor *color)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "red"))
|
|
Packit |
31ecd5 |
color->red = CLAMP (json_object_get_int_member (object, "red"), 0, 255);
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
color->red = 0;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "green"))
|
|
Packit |
31ecd5 |
color->green = CLAMP (json_object_get_int_member (object, "green"), 0, 255);
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
color->green = 0;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "blue"))
|
|
Packit |
31ecd5 |
color->blue = CLAMP (json_object_get_int_member (object, "blue"), 0, 255);
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
color->blue = 0;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "alpha"))
|
|
Packit |
31ecd5 |
color->alpha = CLAMP (json_object_get_int_member (object, "alpha"), 0, 255);
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
color->alpha = 255;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
gboolean
|
|
Packit |
31ecd5 |
_clutter_script_parse_color (ClutterScript *script,
|
|
Packit |
31ecd5 |
JsonNode *node,
|
|
Packit |
31ecd5 |
ClutterColor *color)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
g_return_val_if_fail (CLUTTER_IS_SCRIPT (script), FALSE);
|
|
Packit |
31ecd5 |
g_return_val_if_fail (node != NULL, FALSE);
|
|
Packit |
31ecd5 |
g_return_val_if_fail (color != NULL, FALSE);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
switch (JSON_NODE_TYPE (node))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
case JSON_NODE_ARRAY:
|
|
Packit |
31ecd5 |
return parse_color_from_array (json_node_get_array (node), color);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
case JSON_NODE_OBJECT:
|
|
Packit |
31ecd5 |
return parse_color_from_object (json_node_get_object (node), color);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
case JSON_NODE_VALUE:
|
|
Packit |
31ecd5 |
return clutter_color_from_string (color, json_node_get_string (node));
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
default:
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return FALSE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static gboolean
|
|
Packit |
31ecd5 |
parse_point_from_array (JsonArray *array,
|
|
Packit |
31ecd5 |
ClutterPoint *point)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
if (json_array_get_length (array) != 2)
|
|
Packit |
31ecd5 |
return FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
point->x = json_array_get_double_element (array, 0);
|
|
Packit |
31ecd5 |
point->y = json_array_get_double_element (array, 1);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static gboolean
|
|
Packit |
31ecd5 |
parse_point_from_object (JsonObject *object,
|
|
Packit |
31ecd5 |
ClutterPoint *point)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "x"))
|
|
Packit |
31ecd5 |
point->x = json_object_get_double_member (object, "x");
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
point->x = 0.f;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "y"))
|
|
Packit |
31ecd5 |
point->y = json_object_get_double_member (object, "y");
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
point->y = 0.f;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
gboolean
|
|
Packit |
31ecd5 |
_clutter_script_parse_point (ClutterScript *script,
|
|
Packit |
31ecd5 |
JsonNode *node,
|
|
Packit |
31ecd5 |
ClutterPoint *point)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
g_return_val_if_fail (CLUTTER_IS_SCRIPT (script), FALSE);
|
|
Packit |
31ecd5 |
g_return_val_if_fail (node != NULL, FALSE);
|
|
Packit |
31ecd5 |
g_return_val_if_fail (point != NULL, FALSE);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
switch (JSON_NODE_TYPE (node))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
case JSON_NODE_ARRAY:
|
|
Packit |
31ecd5 |
return parse_point_from_array (json_node_get_array (node), point);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
case JSON_NODE_OBJECT:
|
|
Packit |
31ecd5 |
return parse_point_from_object (json_node_get_object (node), point);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
default:
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return FALSE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static gboolean
|
|
Packit |
31ecd5 |
parse_size_from_array (JsonArray *array,
|
|
Packit |
31ecd5 |
ClutterSize *size)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
if (json_array_get_length (array) != 2)
|
|
Packit |
31ecd5 |
return FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
size->width = json_array_get_double_element (array, 0);
|
|
Packit |
31ecd5 |
size->height = json_array_get_double_element (array, 1);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static gboolean
|
|
Packit |
31ecd5 |
parse_size_from_object (JsonObject *object,
|
|
Packit |
31ecd5 |
ClutterSize *size)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "width"))
|
|
Packit |
31ecd5 |
size->width = json_object_get_double_member (object, "width");
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
size->width = 0.f;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "height"))
|
|
Packit |
31ecd5 |
size->height = json_object_get_double_member (object, "height");
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
size->height = 0.f;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
gboolean
|
|
Packit |
31ecd5 |
_clutter_script_parse_size (ClutterScript *script,
|
|
Packit |
31ecd5 |
JsonNode *node,
|
|
Packit |
31ecd5 |
ClutterSize *size)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
g_return_val_if_fail (CLUTTER_IS_SCRIPT (script), FALSE);
|
|
Packit |
31ecd5 |
g_return_val_if_fail (node != NULL, FALSE);
|
|
Packit |
31ecd5 |
g_return_val_if_fail (size != NULL, FALSE);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
switch (JSON_NODE_TYPE (node))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
case JSON_NODE_ARRAY:
|
|
Packit |
31ecd5 |
return parse_size_from_array (json_node_get_array (node), size);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
case JSON_NODE_OBJECT:
|
|
Packit |
31ecd5 |
return parse_size_from_object (json_node_get_object (node), size);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
default:
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return FALSE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
const gchar *
|
|
Packit |
31ecd5 |
_clutter_script_get_id_from_node (JsonNode *node)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
JsonObject *object;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
switch (JSON_NODE_TYPE (node))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
case JSON_NODE_OBJECT:
|
|
Packit |
31ecd5 |
object = json_node_get_object (node);
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "id"))
|
|
Packit |
31ecd5 |
return json_object_get_string_member (object, "id");
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
case JSON_NODE_VALUE:
|
|
Packit |
31ecd5 |
return json_node_get_string (node);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
default:
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return NULL;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static GList *
|
|
Packit |
31ecd5 |
parse_children (ObjectInfo *oinfo,
|
|
Packit |
31ecd5 |
JsonNode *node)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
JsonArray *array;
|
|
Packit |
31ecd5 |
GList *retval;
|
|
Packit |
31ecd5 |
guint array_len, i;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (JSON_NODE_TYPE (node) != JSON_NODE_ARRAY)
|
|
Packit |
31ecd5 |
return NULL;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
retval = oinfo->children;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
array = json_node_get_array (node);
|
|
Packit |
31ecd5 |
array_len = json_array_get_length (array);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
for (i = 0; i < array_len; i++)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
JsonNode *child = json_array_get_element (array, i);
|
|
Packit |
31ecd5 |
const gchar *id_;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
id_ = _clutter_script_get_id_from_node (child);
|
|
Packit |
31ecd5 |
if (id_ != NULL)
|
|
Packit |
31ecd5 |
retval = g_list_prepend (retval, g_strdup (id_));
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return g_list_reverse (retval);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static GList *
|
|
Packit |
31ecd5 |
parse_signals (ClutterScript *script,
|
|
Packit |
31ecd5 |
ObjectInfo *oinfo,
|
|
Packit |
31ecd5 |
JsonNode *node)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
JsonArray *array;
|
|
Packit |
31ecd5 |
GList *retval;
|
|
Packit |
31ecd5 |
guint array_len, i;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (JSON_NODE_TYPE (node) != JSON_NODE_ARRAY)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
_clutter_script_warn_invalid_value (script, "signals", "Array", node);
|
|
Packit |
31ecd5 |
return NULL;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
retval = oinfo->signals;
|
|
Packit |
31ecd5 |
array = json_node_get_array (node);
|
|
Packit |
31ecd5 |
array_len = json_array_get_length (array);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
for (i = 0; i < array_len; i++)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
JsonNode *val = json_array_get_element (array, i);
|
|
Packit |
31ecd5 |
SignalInfo *sinfo = NULL;
|
|
Packit |
31ecd5 |
JsonObject *object;
|
|
Packit |
31ecd5 |
const gchar *name;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (JSON_NODE_TYPE (val) != JSON_NODE_OBJECT)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
_clutter_script_warn_invalid_value (script,
|
|
Packit |
31ecd5 |
"signals array", "Object",
|
|
Packit |
31ecd5 |
node);
|
|
Packit |
31ecd5 |
continue;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
object = json_node_get_object (val);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* mandatory: "name" */
|
|
Packit |
31ecd5 |
if (!json_object_has_member (object, "name"))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
_clutter_script_warn_missing_attribute (script, NULL, "name");
|
|
Packit |
31ecd5 |
continue;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
name = json_object_get_string_member (object, "name");
|
|
Packit |
31ecd5 |
if (!name)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
_clutter_script_warn_invalid_value (script,
|
|
Packit |
31ecd5 |
"name", "string",
|
|
Packit |
31ecd5 |
val);
|
|
Packit |
31ecd5 |
continue;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* mandatory: "target-state" or "handler" */
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "target-state"))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
const gchar *state = NULL;
|
|
Packit |
31ecd5 |
const gchar *target = NULL;
|
|
Packit |
31ecd5 |
gboolean warp_to = FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
target = json_object_get_string_member (object, "target-state");
|
|
Packit |
31ecd5 |
if (target == NULL)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
_clutter_script_warn_invalid_value (script,
|
|
Packit |
31ecd5 |
"target-state", "string",
|
|
Packit |
31ecd5 |
val);
|
|
Packit |
31ecd5 |
continue;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "states"))
|
|
Packit |
31ecd5 |
state = json_object_get_string_member (object, "states");
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "warp"))
|
|
Packit |
31ecd5 |
warp_to = json_object_get_boolean_member (object, "warp");
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT,
|
|
Packit |
31ecd5 |
"Added signal '%s' (states:%s, target-state:%s, warp:%s)",
|
|
Packit |
31ecd5 |
name,
|
|
Packit |
31ecd5 |
state != NULL ? state : "<default>", target,
|
|
Packit |
31ecd5 |
warp_to ? "true" : "false");
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
sinfo = g_slice_new0 (SignalInfo);
|
|
Packit |
31ecd5 |
sinfo->is_handler = FALSE;
|
|
Packit |
31ecd5 |
sinfo->name = g_strdup (name);
|
|
Packit |
31ecd5 |
sinfo->state = g_strdup (state);
|
|
Packit |
31ecd5 |
sinfo->target = g_strdup (target);
|
|
Packit |
31ecd5 |
sinfo->warp_to = warp_to;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
else if (json_object_has_member (object, "handler"))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
const gchar *handler;
|
|
Packit |
31ecd5 |
const gchar *connect;
|
|
Packit |
31ecd5 |
GConnectFlags flags = 0;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
handler = json_object_get_string_member (object, "handler");
|
|
Packit |
31ecd5 |
if (handler == NULL)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
_clutter_script_warn_invalid_value (script,
|
|
Packit |
31ecd5 |
"handler", "string",
|
|
Packit |
31ecd5 |
val);
|
|
Packit |
31ecd5 |
continue;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* optional: "object" */
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "object"))
|
|
Packit |
31ecd5 |
connect = json_object_get_string_member (object, "object");
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
connect = NULL;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* optional: "after" */
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "after"))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
if (json_object_get_boolean_member (object, "after"))
|
|
Packit |
31ecd5 |
flags |= G_CONNECT_AFTER;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* optional: "swapped" */
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "swapped"))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
if (json_object_get_boolean_member (object, "swapped"))
|
|
Packit |
31ecd5 |
flags |= G_CONNECT_SWAPPED;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT,
|
|
Packit |
31ecd5 |
"Added signal '%s' (handler:%s, object:%s, flags:%d)",
|
|
Packit |
31ecd5 |
name,
|
|
Packit |
31ecd5 |
handler, connect, flags);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
sinfo = g_slice_new0 (SignalInfo);
|
|
Packit |
31ecd5 |
sinfo->is_handler = TRUE;
|
|
Packit |
31ecd5 |
sinfo->name = g_strdup (name);
|
|
Packit |
31ecd5 |
sinfo->handler = g_strdup (handler);
|
|
Packit |
31ecd5 |
sinfo->object = g_strdup (connect);
|
|
Packit |
31ecd5 |
sinfo->flags = flags;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
_clutter_script_warn_missing_attribute (script,
|
|
Packit |
31ecd5 |
NULL,
|
|
Packit |
31ecd5 |
"handler or state");
|
|
Packit |
31ecd5 |
if (sinfo != NULL)
|
|
Packit |
31ecd5 |
retval = g_list_prepend (retval, sinfo);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return retval;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static ClutterTimeline *
|
|
Packit |
31ecd5 |
construct_timeline (ClutterScript *script,
|
|
Packit |
31ecd5 |
JsonObject *object)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterTimeline *retval = NULL;
|
|
Packit |
31ecd5 |
ObjectInfo *oinfo;
|
|
Packit |
31ecd5 |
GList *members, *l;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* we fake an ObjectInfo so we can reuse clutter_script_construct_object()
|
|
Packit |
31ecd5 |
* here; we do not save it inside the hash table, because if this had
|
|
Packit |
31ecd5 |
* been a named object then we wouldn't have ended up here in the first
|
|
Packit |
31ecd5 |
* place
|
|
Packit |
31ecd5 |
*/
|
|
Packit |
31ecd5 |
oinfo = g_slice_new0 (ObjectInfo);
|
|
Packit |
31ecd5 |
oinfo->gtype = CLUTTER_TYPE_TIMELINE;
|
|
Packit |
31ecd5 |
oinfo->id = g_strdup ("dummy");
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
members = json_object_get_members (object);
|
|
Packit |
31ecd5 |
for (l = members; l != NULL; l = l->next)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
const gchar *name = l->data;
|
|
Packit |
31ecd5 |
JsonNode *node = json_object_get_member (object, name);
|
|
Packit |
31ecd5 |
PropertyInfo *pinfo = g_slice_new0 (PropertyInfo);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
pinfo->name = g_strdelimit (g_strdup (name), G_STR_DELIMITERS, '-');
|
|
Packit |
31ecd5 |
pinfo->node = json_node_copy (node);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
oinfo->properties = g_list_prepend (oinfo->properties, pinfo);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_list_free (members);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
_clutter_script_construct_object (script, oinfo);
|
|
Packit |
31ecd5 |
_clutter_script_apply_properties (script, oinfo);
|
|
Packit |
31ecd5 |
retval = CLUTTER_TIMELINE (oinfo->object);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* we transfer ownership to the alpha function, so we ref before
|
|
Packit |
31ecd5 |
* destroying the ObjectInfo to avoid the timeline going away
|
|
Packit |
31ecd5 |
*/
|
|
Packit |
31ecd5 |
g_object_ref (retval);
|
|
Packit |
31ecd5 |
object_info_free (oinfo);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return retval;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* define the names of the animation modes to match the ones
|
|
Packit |
31ecd5 |
* that developers might be more accustomed to
|
|
Packit |
31ecd5 |
*/
|
|
Packit |
31ecd5 |
static const struct
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
const gchar *name;
|
|
Packit |
31ecd5 |
ClutterAnimationMode mode;
|
|
Packit |
31ecd5 |
} animation_modes[] = {
|
|
Packit |
31ecd5 |
{ "linear", CLUTTER_LINEAR },
|
|
Packit |
31ecd5 |
{ "easeInQuad", CLUTTER_EASE_IN_QUAD },
|
|
Packit |
31ecd5 |
{ "easeOutQuad", CLUTTER_EASE_OUT_QUAD },
|
|
Packit |
31ecd5 |
{ "easeInOutQuad", CLUTTER_EASE_IN_OUT_QUAD },
|
|
Packit |
31ecd5 |
{ "easeInCubic", CLUTTER_EASE_IN_CUBIC },
|
|
Packit |
31ecd5 |
{ "easeOutCubic", CLUTTER_EASE_OUT_CUBIC },
|
|
Packit |
31ecd5 |
{ "easeInOutCubic", CLUTTER_EASE_IN_OUT_CUBIC },
|
|
Packit |
31ecd5 |
{ "easeInQuart", CLUTTER_EASE_IN_QUART },
|
|
Packit |
31ecd5 |
{ "easeOutQuart", CLUTTER_EASE_OUT_QUART },
|
|
Packit |
31ecd5 |
{ "easeInOutQuart", CLUTTER_EASE_IN_OUT_QUART },
|
|
Packit |
31ecd5 |
{ "easeInQuint", CLUTTER_EASE_IN_QUINT },
|
|
Packit |
31ecd5 |
{ "easeOutQuint", CLUTTER_EASE_OUT_QUINT },
|
|
Packit |
31ecd5 |
{ "easeInOutQuint", CLUTTER_EASE_IN_OUT_QUINT },
|
|
Packit |
31ecd5 |
{ "easeInSine", CLUTTER_EASE_IN_SINE },
|
|
Packit |
31ecd5 |
{ "easeOutSine", CLUTTER_EASE_OUT_SINE },
|
|
Packit |
31ecd5 |
{ "easeInOutSine", CLUTTER_EASE_IN_OUT_SINE },
|
|
Packit |
31ecd5 |
{ "easeInExpo", CLUTTER_EASE_IN_EXPO },
|
|
Packit |
31ecd5 |
{ "easeOutExpo", CLUTTER_EASE_OUT_EXPO },
|
|
Packit |
31ecd5 |
{ "easeInOutExpo", CLUTTER_EASE_IN_OUT_EXPO },
|
|
Packit |
31ecd5 |
{ "easeInCirc", CLUTTER_EASE_IN_CIRC },
|
|
Packit |
31ecd5 |
{ "easeOutCirc", CLUTTER_EASE_OUT_CIRC },
|
|
Packit |
31ecd5 |
{ "easeInOutCirc", CLUTTER_EASE_IN_OUT_CIRC },
|
|
Packit |
31ecd5 |
{ "easeInElastic", CLUTTER_EASE_IN_ELASTIC },
|
|
Packit |
31ecd5 |
{ "easeOutElastic", CLUTTER_EASE_OUT_ELASTIC },
|
|
Packit |
31ecd5 |
{ "easeInOutElastic", CLUTTER_EASE_IN_OUT_ELASTIC },
|
|
Packit |
31ecd5 |
{ "easeInBack", CLUTTER_EASE_IN_BACK },
|
|
Packit |
31ecd5 |
{ "easeOutBack", CLUTTER_EASE_OUT_BACK },
|
|
Packit |
31ecd5 |
{ "easeInOutBack", CLUTTER_EASE_IN_OUT_BACK },
|
|
Packit |
31ecd5 |
{ "easeInBounce", CLUTTER_EASE_IN_BOUNCE },
|
|
Packit |
31ecd5 |
{ "easeOutBounce", CLUTTER_EASE_OUT_BOUNCE },
|
|
Packit |
31ecd5 |
{ "easeInOutBounce", CLUTTER_EASE_IN_OUT_BOUNCE },
|
|
Packit |
31ecd5 |
};
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static const gint n_animation_modes = G_N_ELEMENTS (animation_modes);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
gulong
|
|
Packit |
31ecd5 |
_clutter_script_resolve_animation_mode (JsonNode *node)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
gint i, res = CLUTTER_CUSTOM_MODE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (JSON_NODE_TYPE (node) != JSON_NODE_VALUE)
|
|
Packit |
31ecd5 |
return CLUTTER_CUSTOM_MODE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (json_node_get_value_type (node) == G_TYPE_INT64)
|
|
Packit |
31ecd5 |
return json_node_get_int (node);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (json_node_get_value_type (node) == G_TYPE_STRING)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
const gchar *name = json_node_get_string (node);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* XXX - we might be able to optimize by changing the ordering
|
|
Packit |
31ecd5 |
* of the animation_modes array, e.g.
|
|
Packit |
31ecd5 |
* - special casing linear
|
|
Packit |
31ecd5 |
* - tokenizing ('ease', 'In', 'Sine') and matching on token
|
|
Packit |
31ecd5 |
* - binary searching?
|
|
Packit |
31ecd5 |
*/
|
|
Packit |
31ecd5 |
for (i = 0; i < n_animation_modes; i++)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
if (strcmp (animation_modes[i].name, name) == 0)
|
|
Packit |
31ecd5 |
return animation_modes[i].mode;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (_clutter_script_enum_from_string (CLUTTER_TYPE_ANIMATION_MODE,
|
|
Packit |
31ecd5 |
name,
|
|
Packit |
31ecd5 |
&res))
|
|
Packit |
31ecd5 |
return res;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_warning ("Unable to find the animation mode '%s'", name);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return CLUTTER_CUSTOM_MODE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static ClutterAlphaFunc
|
|
Packit |
31ecd5 |
resolve_alpha_func (const gchar *name)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
static GModule *module = NULL;
|
|
Packit |
31ecd5 |
ClutterAlphaFunc func;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT, "Looking up '%s' alpha function", name);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (G_UNLIKELY (!module))
|
|
Packit |
31ecd5 |
module = g_module_open (NULL, 0);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (g_module_symbol (module, name, (gpointer) &func))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT, "Found '%s' alpha function in the symbols table",
|
|
Packit |
31ecd5 |
name);
|
|
Packit |
31ecd5 |
return func;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return NULL;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
GObject *
|
|
Packit |
31ecd5 |
_clutter_script_parse_alpha (ClutterScript *script,
|
|
Packit |
31ecd5 |
JsonNode *node)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
GObject *retval = NULL;
|
|
Packit |
31ecd5 |
JsonObject *object;
|
|
Packit |
31ecd5 |
ClutterTimeline *timeline = NULL;
|
|
Packit |
31ecd5 |
ClutterAlphaFunc alpha_func = NULL;
|
|
Packit |
31ecd5 |
ClutterAnimationMode mode = CLUTTER_CUSTOM_MODE;
|
|
Packit |
31ecd5 |
JsonNode *val;
|
|
Packit |
31ecd5 |
gboolean unref_timeline = FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (JSON_NODE_TYPE (node) != JSON_NODE_OBJECT)
|
|
Packit |
31ecd5 |
return NULL;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
object = json_node_get_object (node);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
val = json_object_get_member (object, "timeline");
|
|
Packit |
31ecd5 |
if (val)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
if (JSON_NODE_TYPE (val) == JSON_NODE_VALUE &&
|
|
Packit |
31ecd5 |
json_node_get_string (val) != NULL)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
const gchar *id_ = json_node_get_string (val);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
timeline =
|
|
Packit |
31ecd5 |
CLUTTER_TIMELINE (clutter_script_get_object (script, id_));
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
else if (JSON_NODE_TYPE (val) == JSON_NODE_OBJECT)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
timeline = construct_timeline (script, json_node_get_object (val));
|
|
Packit |
31ecd5 |
unref_timeline = TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
val = json_object_get_member (object, "mode");
|
|
Packit |
31ecd5 |
if (val != NULL)
|
|
Packit |
31ecd5 |
mode = _clutter_script_resolve_animation_mode (val);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (mode == CLUTTER_CUSTOM_MODE)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
val = json_object_get_member (object, "function");
|
|
Packit |
31ecd5 |
if (val && json_node_get_string (val) != NULL)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
alpha_func = resolve_alpha_func (json_node_get_string (val));
|
|
Packit |
31ecd5 |
if (!alpha_func)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
g_warning ("Unable to find the function '%s' in the "
|
|
Packit |
31ecd5 |
"Clutter alpha functions or the symbols table",
|
|
Packit |
31ecd5 |
json_node_get_string (val));
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT, "Parsed alpha: %s timeline (%p) (mode:%d, func:%p)",
|
|
Packit |
31ecd5 |
unref_timeline ? "implicit" : "explicit",
|
|
Packit |
31ecd5 |
timeline ? timeline : 0x0,
|
|
Packit |
31ecd5 |
mode != CLUTTER_CUSTOM_MODE ? mode : 0,
|
|
Packit |
31ecd5 |
alpha_func ? alpha_func : 0x0);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
retval = g_object_new (CLUTTER_TYPE_ALPHA, NULL);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (mode != CLUTTER_CUSTOM_MODE)
|
|
Packit |
31ecd5 |
clutter_alpha_set_mode (CLUTTER_ALPHA (retval), mode);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (alpha_func != NULL)
|
|
Packit |
31ecd5 |
clutter_alpha_set_func (CLUTTER_ALPHA (retval), alpha_func, NULL, NULL);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
clutter_alpha_set_timeline (CLUTTER_ALPHA (retval), timeline);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* if we created an implicit timeline, the Alpha has full ownership
|
|
Packit |
31ecd5 |
* of it now, since it won't be accessible from ClutterScript
|
|
Packit |
31ecd5 |
*/
|
|
Packit |
31ecd5 |
if (unref_timeline)
|
|
Packit |
31ecd5 |
g_object_unref (timeline);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return retval;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static void
|
|
Packit |
31ecd5 |
clutter_script_parser_object_end (JsonParser *json_parser,
|
|
Packit |
31ecd5 |
JsonObject *object)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterScriptParser *parser = CLUTTER_SCRIPT_PARSER (json_parser);
|
|
Packit |
31ecd5 |
ClutterScript *script = parser->script;
|
|
Packit |
31ecd5 |
ObjectInfo *oinfo;
|
|
Packit |
31ecd5 |
JsonNode *val;
|
|
Packit |
31ecd5 |
const gchar *id_;
|
|
Packit |
31ecd5 |
GList *members, *l;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* if the object definition does not have an 'id' field we'll
|
|
Packit |
31ecd5 |
* fake one for it...
|
|
Packit |
31ecd5 |
*/
|
|
Packit |
31ecd5 |
if (!json_object_has_member (object, "id"))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
gchar *fake;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* ... unless it doesn't even have a type - in which case
|
|
Packit |
31ecd5 |
* it is an internal object definition and we're not
|
|
Packit |
31ecd5 |
* supposed to touch it
|
|
Packit |
31ecd5 |
*/
|
|
Packit |
31ecd5 |
if (!json_object_has_member (object, "type"))
|
|
Packit |
31ecd5 |
return;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
fake = _clutter_script_generate_fake_id (script);
|
|
Packit |
31ecd5 |
json_object_set_string_member (object, "id", fake);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT,
|
|
Packit |
31ecd5 |
"Adding fake id '%s' to object of type '%s'",
|
|
Packit |
31ecd5 |
json_object_get_string_member (object, "id"),
|
|
Packit |
31ecd5 |
json_object_get_string_member (object, "type"));
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_free (fake);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (!json_object_has_member (object, "type"))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
val = json_object_get_member (object, "id");
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
_clutter_script_warn_missing_attribute (script,
|
|
Packit |
31ecd5 |
json_node_get_string (val),
|
|
Packit |
31ecd5 |
"type");
|
|
Packit |
31ecd5 |
return;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
id_ = json_object_get_string_member (object, "id");
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT, "Getting object info for object '%s'", id_);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
oinfo = _clutter_script_get_object_info (script, id_);
|
|
Packit |
31ecd5 |
if (oinfo == NULL)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
const gchar *class_name;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
oinfo = g_slice_new0 (ObjectInfo);
|
|
Packit |
31ecd5 |
oinfo->merge_id = _clutter_script_get_last_merge_id (script);
|
|
Packit |
31ecd5 |
oinfo->id = g_strdup (id_);
|
|
Packit |
31ecd5 |
oinfo->has_unresolved = TRUE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
class_name = json_object_get_string_member (object, "type");
|
|
Packit |
31ecd5 |
oinfo->class_name = g_strdup (class_name);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "type_func"))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
const gchar *type_func;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
type_func = json_object_get_string_member (object, "type_func");
|
|
Packit |
31ecd5 |
oinfo->type_func = g_strdup (type_func);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* remove the type_func member; we don't want it to
|
|
Packit |
31ecd5 |
* pollute the object members
|
|
Packit |
31ecd5 |
*/
|
|
Packit |
31ecd5 |
json_object_remove_member (object, "type_func");
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "children"))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
val = json_object_get_member (object, "children");
|
|
Packit |
31ecd5 |
oinfo->children = parse_children (oinfo, val);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
json_object_remove_member (object, "children");
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
oinfo->has_unresolved = TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (json_object_has_member (object, "signals"))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
val = json_object_get_member (object, "signals");
|
|
Packit |
31ecd5 |
oinfo->signals = parse_signals (script, oinfo, val);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
json_object_remove_member (object, "signals");
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
oinfo->has_unresolved = TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (strcmp (oinfo->class_name, "ClutterStage") == 0 &&
|
|
Packit |
31ecd5 |
json_object_has_member (object, "is-default"))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
oinfo->is_actor = TRUE;
|
|
Packit |
31ecd5 |
oinfo->is_stage = TRUE;
|
|
Packit |
31ecd5 |
oinfo->is_stage_default =
|
|
Packit |
31ecd5 |
json_object_get_boolean_member (object, "is-default");
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
json_object_remove_member (object, "is-default");
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
oinfo->is_stage_default = FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
members = json_object_get_members (object);
|
|
Packit |
31ecd5 |
for (l = members; l; l = l->next)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
const gchar *name = l->data;
|
|
Packit |
31ecd5 |
PropertyInfo *pinfo;
|
|
Packit |
31ecd5 |
JsonNode *node;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT, "Object '%s' member '%s'",
|
|
Packit |
31ecd5 |
oinfo->id,
|
|
Packit |
31ecd5 |
name);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* we have already parsed these */
|
|
Packit |
31ecd5 |
if (strcmp (name, "id") == 0 || strcmp (name, "type") == 0)
|
|
Packit |
31ecd5 |
continue;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
node = json_object_get_member (object, name);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* this should not really happen; we're getting a list of
|
|
Packit |
31ecd5 |
* member names, and if one does not map a real member
|
|
Packit |
31ecd5 |
* value then it's likely that something has gone wrong
|
|
Packit |
31ecd5 |
*/
|
|
Packit |
31ecd5 |
if (G_UNLIKELY (node == NULL))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT,
|
|
Packit |
31ecd5 |
"Empty node for member '%s' of object '%s' (type: %s)",
|
|
Packit |
31ecd5 |
name,
|
|
Packit |
31ecd5 |
oinfo->id,
|
|
Packit |
31ecd5 |
oinfo->class_name);
|
|
Packit |
31ecd5 |
continue;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
pinfo = g_slice_new (PropertyInfo);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
pinfo->name = g_strdup (name);
|
|
Packit |
31ecd5 |
pinfo->node = json_node_copy (node);
|
|
Packit |
31ecd5 |
pinfo->pspec = NULL;
|
|
Packit |
31ecd5 |
pinfo->is_child = g_str_has_prefix (name, "child::") ? TRUE : FALSE;
|
|
Packit |
31ecd5 |
pinfo->is_layout = g_str_has_prefix (name, "layout::") ? TRUE : FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
oinfo->properties = g_list_prepend (oinfo->properties, pinfo);
|
|
Packit |
31ecd5 |
oinfo->has_unresolved = TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_list_free (members);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT,
|
|
Packit |
31ecd5 |
"Added object '%s' (type:%s, id:%d, props:%d, signals:%d)",
|
|
Packit |
31ecd5 |
oinfo->id,
|
|
Packit |
31ecd5 |
oinfo->class_name,
|
|
Packit |
31ecd5 |
oinfo->merge_id,
|
|
Packit |
31ecd5 |
g_list_length (oinfo->properties),
|
|
Packit |
31ecd5 |
g_list_length (oinfo->signals));
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
_clutter_script_add_object_info (script, oinfo);
|
|
Packit |
31ecd5 |
_clutter_script_construct_object (script, oinfo);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static void
|
|
Packit |
31ecd5 |
clutter_script_parser_parse_end (JsonParser *parser)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
clutter_script_ensure_objects (CLUTTER_SCRIPT_PARSER (parser)->script);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
gboolean
|
|
Packit |
31ecd5 |
_clutter_script_parse_translatable_string (ClutterScript *script,
|
|
Packit |
31ecd5 |
JsonNode *node,
|
|
Packit |
31ecd5 |
char **str)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
JsonObject *obj;
|
|
Packit |
31ecd5 |
const char *string, *domain, *context;
|
|
Packit |
31ecd5 |
const char *res;
|
|
Packit |
31ecd5 |
gboolean translatable;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (!JSON_NODE_HOLDS_OBJECT (node))
|
|
Packit |
31ecd5 |
return FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
obj = json_node_get_object (node);
|
|
Packit |
31ecd5 |
if (!(json_object_has_member (obj, "translatable") &&
|
|
Packit |
31ecd5 |
json_object_has_member (obj, "string")))
|
|
Packit |
31ecd5 |
return FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
translatable = json_object_get_boolean_member (obj, "translatable");
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
string = json_object_get_string_member (obj, "string");
|
|
Packit |
31ecd5 |
if (string == NULL || *string == '\0')
|
|
Packit |
31ecd5 |
return FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (json_object_has_member (obj, "context"))
|
|
Packit |
31ecd5 |
context = json_object_get_string_member (obj, "context");
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
context = NULL;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (json_object_has_member (obj, "domain"))
|
|
Packit |
31ecd5 |
domain = json_object_get_string_member (obj, "domain");
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
domain = NULL;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (domain == NULL || *domain == '\0')
|
|
Packit |
31ecd5 |
domain = clutter_script_get_translation_domain (script);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (translatable)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
if (context != NULL && *context != '\0')
|
|
Packit |
31ecd5 |
res = g_dpgettext2 (domain, context, string);
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
res = g_dgettext (domain, string);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
res = string;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (str != NULL)
|
|
Packit |
31ecd5 |
*str = g_strdup (res);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
gboolean
|
|
Packit |
31ecd5 |
_clutter_script_parse_node (ClutterScript *script,
|
|
Packit |
31ecd5 |
GValue *value,
|
|
Packit |
31ecd5 |
const gchar *name,
|
|
Packit |
31ecd5 |
JsonNode *node,
|
|
Packit |
31ecd5 |
GParamSpec *pspec)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
GValue node_value = G_VALUE_INIT;
|
|
Packit |
31ecd5 |
gboolean retval = FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_return_val_if_fail (CLUTTER_IS_SCRIPT (script), FALSE);
|
|
Packit |
31ecd5 |
g_return_val_if_fail (name != NULL, FALSE);
|
|
Packit |
31ecd5 |
g_return_val_if_fail (node != NULL, FALSE);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
switch (JSON_NODE_TYPE (node))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
case JSON_NODE_OBJECT:
|
|
Packit |
31ecd5 |
/* if we don't have a GParamSpec we can't infer the type
|
|
Packit |
31ecd5 |
* of the property; this usually means that this property
|
|
Packit |
31ecd5 |
* is a custom member that will be parsed by the Scriptable
|
|
Packit |
31ecd5 |
* interface implementantion
|
|
Packit |
31ecd5 |
*/
|
|
Packit |
31ecd5 |
if (pspec == NULL && !G_IS_VALUE (value))
|
|
Packit |
31ecd5 |
return FALSE;
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
GType p_type;
|
|
Packit |
31ecd5 |
ObjectInfo *oinfo;
|
|
Packit |
31ecd5 |
const gchar *id_;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (G_IS_VALUE (value))
|
|
Packit |
31ecd5 |
p_type = G_VALUE_TYPE (value);
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
p_type = G_PARAM_SPEC_VALUE_TYPE (pspec);
|
|
Packit |
31ecd5 |
g_value_init (value, p_type);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (g_type_is_a (p_type, G_TYPE_OBJECT))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
/* default GObject handling: we get the id and
|
|
Packit |
31ecd5 |
* retrieve the ObjectInfo for it; since the object
|
|
Packit |
31ecd5 |
* definitions are parsed leaf-first we are guaranteed
|
|
Packit |
31ecd5 |
* to have a defined object at this point
|
|
Packit |
31ecd5 |
*/
|
|
Packit |
31ecd5 |
id_ = _clutter_script_get_id_from_node (node);
|
|
Packit |
31ecd5 |
if (id_ == NULL || *id_ == '\0')
|
|
Packit |
31ecd5 |
return FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
oinfo = _clutter_script_get_object_info (script, id_);
|
|
Packit |
31ecd5 |
if (oinfo == NULL || oinfo->gtype == G_TYPE_INVALID )
|
|
Packit |
31ecd5 |
return FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (g_type_is_a (oinfo->gtype, p_type))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
/* force construction, even though it should
|
|
Packit |
31ecd5 |
* not be necessary; we don't need the properties
|
|
Packit |
31ecd5 |
* to be applied as well: they will when the
|
|
Packit |
31ecd5 |
* ScriptParser finishes
|
|
Packit |
31ecd5 |
*/
|
|
Packit |
31ecd5 |
_clutter_script_construct_object (script, oinfo);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_value_set_object (value, oinfo->object);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
else if (p_type == CLUTTER_TYPE_KNOT)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterKnot knot = { 0, };
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* knot := { "x" : (int), "y" : (int) } */
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (_clutter_script_parse_knot (script, node, &knot))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
g_value_set_boxed (value, &knot);
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
else if (p_type == CLUTTER_TYPE_GEOMETRY)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterGeometry geom = { 0, };
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* geometry := {
|
|
Packit |
31ecd5 |
* "x" : (int),
|
|
Packit |
31ecd5 |
* "y" : (int),
|
|
Packit |
31ecd5 |
* "width" : (int),
|
|
Packit |
31ecd5 |
* "height" : (int)
|
|
Packit |
31ecd5 |
* }
|
|
Packit |
31ecd5 |
*/
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (_clutter_script_parse_geometry (script, node, &geom))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
g_value_set_boxed (value, &geom);
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
else if (p_type == CLUTTER_TYPE_COLOR)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterColor color = { 0, };
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* color := {
|
|
Packit |
31ecd5 |
* "red" : (int),
|
|
Packit |
31ecd5 |
* "green" : (int),
|
|
Packit |
31ecd5 |
* "blue" : (int),
|
|
Packit |
31ecd5 |
* "alpha" : (int)
|
|
Packit |
31ecd5 |
* }
|
|
Packit |
31ecd5 |
*/
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (_clutter_script_parse_color (script, node, &color))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
g_value_set_boxed (value, &color;;
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
else if (p_type == CLUTTER_TYPE_POINT)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterPoint point = CLUTTER_POINT_INIT_ZERO;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (_clutter_script_parse_point (script, node, &point))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
g_value_set_boxed (value, &point);
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
else if (p_type == CLUTTER_TYPE_SIZE)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterSize size = CLUTTER_SIZE_INIT_ZERO;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (_clutter_script_parse_size (script, node, &size))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
g_value_set_boxed (value, &size);
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
else if (p_type == G_TYPE_STRING)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
char *str = NULL;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (_clutter_script_parse_translatable_string (script, node, &str))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
g_value_take_string (value, str);
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
return FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
case JSON_NODE_ARRAY:
|
|
Packit |
31ecd5 |
if (!pspec && !G_IS_VALUE (value))
|
|
Packit |
31ecd5 |
return FALSE;
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
if (!G_IS_VALUE (value))
|
|
Packit |
31ecd5 |
g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (G_VALUE_HOLDS (value, CLUTTER_TYPE_KNOT))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterKnot knot = { 0, };
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* knot := [ (int), (int) ] */
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (_clutter_script_parse_knot (script, node, &knot))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
g_value_set_boxed (value, &knot);
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
else if (G_VALUE_HOLDS (value, CLUTTER_TYPE_GEOMETRY))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterGeometry geom = { 0, };
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* geometry := [ (int), (int), (int), (int) ] */
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (_clutter_script_parse_geometry (script, node, &geom))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
g_value_set_boxed (value, &geom);
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
else if (CLUTTER_VALUE_HOLDS_COLOR (value))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterColor color = { 0, };
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* color := [ (int), (int), (int), (int) ] */
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (_clutter_script_parse_color (script, node, &color))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
g_value_set_boxed (value, &color;;
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
else if (G_VALUE_HOLDS (value, CLUTTER_TYPE_POINT))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterPoint point = CLUTTER_POINT_INIT_ZERO;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (_clutter_script_parse_point (script, node, &point))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
g_value_set_boxed (value, &point);
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
else if (G_VALUE_HOLDS (value, CLUTTER_TYPE_SIZE))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterSize size = CLUTTER_SIZE_INIT_ZERO;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (_clutter_script_parse_size (script, node, &size))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
g_value_set_boxed (value, &size);
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
else if (G_VALUE_HOLDS (value, G_TYPE_STRV))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
JsonArray *array = json_node_get_array (node);
|
|
Packit |
31ecd5 |
guint i, array_len = json_array_get_length (array);
|
|
Packit |
31ecd5 |
GPtrArray *str_array = g_ptr_array_sized_new (array_len);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* strv := [ (str), (str), ... ] */
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
for (i = 0; i < array_len; i++)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
JsonNode *val = json_array_get_element (array, i);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (JSON_NODE_TYPE (val) != JSON_NODE_VALUE &&
|
|
Packit |
31ecd5 |
json_node_get_string (val) == NULL)
|
|
Packit |
31ecd5 |
continue;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_ptr_array_add (str_array,
|
|
Packit |
31ecd5 |
(gpointer) json_node_get_string (val));
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_value_set_boxed (value, str_array->pdata);
|
|
Packit |
31ecd5 |
g_ptr_array_free (str_array, TRUE);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
return FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
case JSON_NODE_NULL:
|
|
Packit |
31ecd5 |
return FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
case JSON_NODE_VALUE:
|
|
Packit |
31ecd5 |
json_node_get_value (node, &node_value);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (!pspec && !G_IS_VALUE (value))
|
|
Packit |
31ecd5 |
g_value_init (value, G_VALUE_TYPE (&node_value));
|
|
Packit |
31ecd5 |
else if (pspec)
|
|
Packit |
31ecd5 |
g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
/* fundamental JSON types */
|
|
Packit |
31ecd5 |
case G_TYPE_INT64:
|
|
Packit |
31ecd5 |
case G_TYPE_DOUBLE:
|
|
Packit |
31ecd5 |
case G_TYPE_STRING:
|
|
Packit |
31ecd5 |
case G_TYPE_BOOLEAN:
|
|
Packit |
31ecd5 |
g_value_copy (&node_value, value);
|
|
Packit |
31ecd5 |
retval = TRUE;
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
case G_TYPE_INT:
|
|
Packit |
31ecd5 |
g_value_set_int (value, g_value_get_int64 (&node_value));
|
|
Packit |
31ecd5 |
retval = TRUE;
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
case G_TYPE_UINT:
|
|
Packit |
31ecd5 |
g_value_set_uint (value, (guint) g_value_get_int64 (&node_value));
|
|
Packit |
31ecd5 |
retval = TRUE;
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
case G_TYPE_ULONG:
|
|
Packit |
31ecd5 |
g_value_set_ulong (value, (gulong) g_value_get_int64 (&node_value));
|
|
Packit |
31ecd5 |
retval = TRUE;
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
case G_TYPE_UCHAR:
|
|
Packit |
31ecd5 |
g_value_set_uchar (value, (guchar) g_value_get_int64 (&node_value));
|
|
Packit |
31ecd5 |
retval = TRUE;
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
case G_TYPE_FLOAT:
|
|
Packit |
31ecd5 |
if (G_VALUE_HOLDS (&node_value, G_TYPE_DOUBLE))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
g_value_set_float (value, g_value_get_double (&node_value));
|
|
Packit |
31ecd5 |
retval = TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
else if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
g_value_set_float (value, g_value_get_int64 (&node_value));
|
|
Packit |
31ecd5 |
retval = TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
case G_TYPE_ENUM:
|
|
Packit |
31ecd5 |
if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
g_value_set_enum (value, g_value_get_int64 (&node_value));
|
|
Packit |
31ecd5 |
retval = TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
else if (G_VALUE_HOLDS (&node_value, G_TYPE_STRING))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
gint enum_value;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
retval = _clutter_script_enum_from_string (G_VALUE_TYPE (value),
|
|
Packit |
31ecd5 |
g_value_get_string (&node_value),
|
|
Packit |
31ecd5 |
&enum_value);
|
|
Packit |
31ecd5 |
if (retval)
|
|
Packit |
31ecd5 |
g_value_set_enum (value, enum_value);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
case G_TYPE_FLAGS:
|
|
Packit |
31ecd5 |
if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
g_value_set_flags (value, g_value_get_int64 (&node_value));
|
|
Packit |
31ecd5 |
retval = TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
else if (G_VALUE_HOLDS (&node_value, G_TYPE_STRING))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
gint flags_value;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
retval = _clutter_script_flags_from_string (G_VALUE_TYPE (value),
|
|
Packit |
31ecd5 |
g_value_get_string (&node_value),
|
|
Packit |
31ecd5 |
&flags_value);
|
|
Packit |
31ecd5 |
if (retval)
|
|
Packit |
31ecd5 |
g_value_set_flags (value, flags_value);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
case G_TYPE_BOXED:
|
|
Packit |
31ecd5 |
if (G_VALUE_HOLDS (value, CLUTTER_TYPE_COLOR))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterColor color = { 0, };
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
retval = _clutter_script_parse_color (script, node, &color;;
|
|
Packit |
31ecd5 |
if (retval)
|
|
Packit |
31ecd5 |
clutter_value_set_color (value, &color;;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
case G_TYPE_OBJECT:
|
|
Packit |
31ecd5 |
if (G_VALUE_HOLDS (&node_value, G_TYPE_STRING))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
const gchar *str = g_value_get_string (&node_value);
|
|
Packit |
31ecd5 |
GObject *object = clutter_script_get_object (script, str);
|
|
Packit |
31ecd5 |
if (object)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT,
|
|
Packit |
31ecd5 |
"Assigning '%s' (%s) to property '%s'",
|
|
Packit |
31ecd5 |
str,
|
|
Packit |
31ecd5 |
G_OBJECT_TYPE_NAME (object),
|
|
Packit |
31ecd5 |
name);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_value_set_object (value, object);
|
|
Packit |
31ecd5 |
retval = TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
default:
|
|
Packit |
31ecd5 |
retval = FALSE;
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (G_VALUE_TYPE (value) == G_TYPE_GTYPE &&
|
|
Packit |
31ecd5 |
G_VALUE_HOLDS (&node_value, G_TYPE_STRING))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
const gchar *str = g_value_get_string (&node_value);
|
|
Packit |
31ecd5 |
GType type = clutter_script_get_type_from_name (script, str);
|
|
Packit |
31ecd5 |
g_value_set_gtype (value, type);
|
|
Packit |
31ecd5 |
retval = TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_value_unset (&node_value);
|
|
Packit |
31ecd5 |
break;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return retval;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static GList *
|
|
Packit |
31ecd5 |
clutter_script_translate_parameters (ClutterScript *script,
|
|
Packit |
31ecd5 |
GObject *object,
|
|
Packit |
31ecd5 |
const gchar *name,
|
|
Packit |
31ecd5 |
GList *properties,
|
|
Packit |
31ecd5 |
GArray **params)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterScriptable *scriptable = NULL;
|
|
Packit |
31ecd5 |
ClutterScriptableIface *iface = NULL;
|
|
Packit |
31ecd5 |
GList *l, *unparsed;
|
|
Packit |
31ecd5 |
gboolean parse_custom = FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
*params = g_array_new (FALSE, FALSE, sizeof (GParameter));
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (CLUTTER_IS_SCRIPTABLE (object))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
scriptable = CLUTTER_SCRIPTABLE (object);
|
|
Packit |
31ecd5 |
iface = CLUTTER_SCRIPTABLE_GET_IFACE (scriptable);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (iface->parse_custom_node)
|
|
Packit |
31ecd5 |
parse_custom = TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
unparsed = NULL;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
for (l = properties; l != NULL; l = l->next)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
PropertyInfo *pinfo = l->data;
|
|
Packit |
31ecd5 |
GParameter param = { NULL };
|
|
Packit |
31ecd5 |
gboolean res = FALSE;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (pinfo->is_child || pinfo->is_layout)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT, "Skipping %s property '%s'",
|
|
Packit |
31ecd5 |
pinfo->is_child ? "child" : "layout",
|
|
Packit |
31ecd5 |
pinfo->name);
|
|
Packit |
31ecd5 |
unparsed = g_list_prepend (unparsed, pinfo);
|
|
Packit |
31ecd5 |
continue;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT, "Parsing %s property (id:%s)",
|
|
Packit |
31ecd5 |
pinfo->pspec ? "regular" : "custom",
|
|
Packit |
31ecd5 |
pinfo->name);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (parse_custom)
|
|
Packit |
31ecd5 |
res = iface->parse_custom_node (scriptable, script, ¶m.value,
|
|
Packit |
31ecd5 |
pinfo->name,
|
|
Packit |
31ecd5 |
pinfo->node);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (!res)
|
|
Packit |
31ecd5 |
res = _clutter_script_parse_node (script, ¶m.value,
|
|
Packit |
31ecd5 |
pinfo->name,
|
|
Packit |
31ecd5 |
pinfo->node,
|
|
Packit |
31ecd5 |
pinfo->pspec);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (!res)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT, "Property '%s' ignored", pinfo->name);
|
|
Packit |
31ecd5 |
unparsed = g_list_prepend (unparsed, pinfo);
|
|
Packit |
31ecd5 |
continue;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
param.name = g_strdup (pinfo->name);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_array_append_val (*params, param);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
property_info_free (pinfo);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_list_free (properties);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return unparsed;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static GList *
|
|
Packit |
31ecd5 |
clutter_script_construct_parameters (ClutterScript *script,
|
|
Packit |
31ecd5 |
GType gtype,
|
|
Packit |
31ecd5 |
const gchar *name,
|
|
Packit |
31ecd5 |
GList *properties,
|
|
Packit |
31ecd5 |
GArray **construct_params)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
GObjectClass *klass;
|
|
Packit |
31ecd5 |
GList *l, *unparsed;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
klass = g_type_class_ref (gtype);
|
|
Packit |
31ecd5 |
g_assert (klass != NULL);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
*construct_params = g_array_new (FALSE, FALSE, sizeof (GParameter));
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
unparsed = NULL;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
for (l = properties; l != NULL; l = l->next)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
PropertyInfo *pinfo = l->data;
|
|
Packit |
31ecd5 |
GParameter param = { NULL };
|
|
Packit |
31ecd5 |
GParamSpec *pspec = NULL;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* we allow custom property names for classes, so if we
|
|
Packit |
31ecd5 |
* don't find a corresponding GObject property for this
|
|
Packit |
31ecd5 |
* class we just skip it and let the class itself deal
|
|
Packit |
31ecd5 |
* with it later on
|
|
Packit |
31ecd5 |
*/
|
|
Packit |
31ecd5 |
pspec = g_object_class_find_property (klass, pinfo->name);
|
|
Packit |
31ecd5 |
if (pspec)
|
|
Packit |
31ecd5 |
pinfo->pspec = g_param_spec_ref (pspec);
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
pinfo->pspec = NULL;
|
|
Packit |
31ecd5 |
unparsed = g_list_prepend (unparsed, pinfo);
|
|
Packit |
31ecd5 |
continue;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (!(pspec->flags & G_PARAM_CONSTRUCT_ONLY))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
unparsed = g_list_prepend (unparsed, pinfo);
|
|
Packit |
31ecd5 |
continue;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
param.name = g_strdup (pinfo->name);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (!_clutter_script_parse_node (script, ¶m.value,
|
|
Packit |
31ecd5 |
pinfo->name,
|
|
Packit |
31ecd5 |
pinfo->node,
|
|
Packit |
31ecd5 |
pinfo->pspec))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
unparsed = g_list_prepend (unparsed, pinfo);
|
|
Packit |
31ecd5 |
continue;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_array_append_val (*construct_params, param);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
property_info_free (pinfo);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_list_free (properties);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_type_class_unref (klass);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return unparsed;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static void
|
|
Packit |
31ecd5 |
apply_layout_properties (ClutterScript *script,
|
|
Packit |
31ecd5 |
ClutterContainer *container,
|
|
Packit |
31ecd5 |
ClutterActor *actor,
|
|
Packit |
31ecd5 |
ObjectInfo *oinfo)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterScriptable *scriptable = NULL;
|
|
Packit |
31ecd5 |
ClutterScriptableIface *iface = NULL;
|
|
Packit |
31ecd5 |
gboolean parse_custom_node = FALSE;
|
|
Packit |
31ecd5 |
GList *l, *unresolved, *properties;
|
|
Packit |
31ecd5 |
ClutterLayoutManager *manager;
|
|
Packit |
31ecd5 |
GType meta_type;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
manager = g_object_get_data (G_OBJECT (container), "clutter-layout-manager");
|
|
Packit |
31ecd5 |
if (manager == NULL)
|
|
Packit |
31ecd5 |
return;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
meta_type = _clutter_layout_manager_get_child_meta_type (manager);
|
|
Packit |
31ecd5 |
if (meta_type == G_TYPE_INVALID)
|
|
Packit |
31ecd5 |
return;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT, "Layout manager of type '%s' with meta type '%s'",
|
|
Packit |
31ecd5 |
G_OBJECT_TYPE_NAME (manager),
|
|
Packit |
31ecd5 |
g_type_name (meta_type));
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* shortcut, to avoid typechecking every time */
|
|
Packit |
31ecd5 |
if (CLUTTER_IS_SCRIPTABLE (manager))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
scriptable = CLUTTER_SCRIPTABLE (manager);
|
|
Packit |
31ecd5 |
iface = CLUTTER_SCRIPTABLE_GET_IFACE (scriptable);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
parse_custom_node = iface->parse_custom_node != NULL ? TRUE : FALSE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
properties = oinfo->properties;
|
|
Packit |
31ecd5 |
oinfo->properties = NULL;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
unresolved = NULL;
|
|
Packit |
31ecd5 |
for (l = properties; l != NULL; l = l->next)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
PropertyInfo *pinfo = l->data;
|
|
Packit |
31ecd5 |
GValue value = G_VALUE_INIT;
|
|
Packit |
31ecd5 |
gboolean res = FALSE;
|
|
Packit |
31ecd5 |
const gchar *name;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (!pinfo->is_layout)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
unresolved = g_list_prepend (unresolved, pinfo);
|
|
Packit |
31ecd5 |
continue;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
name = pinfo->name + strlen ("layout::");
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
pinfo->pspec =
|
|
Packit |
31ecd5 |
clutter_layout_manager_find_child_property (manager, name);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (pinfo->pspec != NULL)
|
|
Packit |
31ecd5 |
g_param_spec_ref (pinfo->pspec);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT, "Parsing %s layout property (id:%s)",
|
|
Packit |
31ecd5 |
pinfo->pspec != NULL ? "regular" : "custom",
|
|
Packit |
31ecd5 |
name);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (parse_custom_node)
|
|
Packit |
31ecd5 |
res = iface->parse_custom_node (scriptable, script, &value,
|
|
Packit |
31ecd5 |
name,
|
|
Packit |
31ecd5 |
pinfo->node);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (!res)
|
|
Packit |
31ecd5 |
res = _clutter_script_parse_node (script, &value,
|
|
Packit |
31ecd5 |
name,
|
|
Packit |
31ecd5 |
pinfo->node,
|
|
Packit |
31ecd5 |
pinfo->pspec);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (!res)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT, "Layout property '%s' ignored", name);
|
|
Packit |
31ecd5 |
unresolved = g_list_prepend (unresolved, pinfo);
|
|
Packit |
31ecd5 |
continue;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT,
|
|
Packit |
31ecd5 |
"Setting %s layout property '%s' (type:%s) to "
|
|
Packit |
31ecd5 |
"object '%s' (id:%s)",
|
|
Packit |
31ecd5 |
iface->set_custom_property != NULL ? "custom" : "regular",
|
|
Packit |
31ecd5 |
name,
|
|
Packit |
31ecd5 |
g_type_name (G_VALUE_TYPE (&value)),
|
|
Packit |
31ecd5 |
g_type_name (oinfo->gtype),
|
|
Packit |
31ecd5 |
oinfo->id);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
clutter_layout_manager_child_set_property (manager, container, actor,
|
|
Packit |
31ecd5 |
name,
|
|
Packit |
31ecd5 |
&value);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_value_unset (&value);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
property_info_free (pinfo);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_list_free (properties);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
oinfo->properties = unresolved;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static void
|
|
Packit |
31ecd5 |
apply_child_properties (ClutterScript *script,
|
|
Packit |
31ecd5 |
ClutterContainer *container,
|
|
Packit |
31ecd5 |
ClutterActor *actor,
|
|
Packit |
31ecd5 |
ObjectInfo *oinfo)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterScriptable *scriptable = NULL;
|
|
Packit |
31ecd5 |
ClutterScriptableIface *iface = NULL;
|
|
Packit |
31ecd5 |
gboolean parse_custom_node = FALSE;
|
|
Packit |
31ecd5 |
GList *l, *unresolved, *properties;
|
|
Packit |
31ecd5 |
GObjectClass *klass;
|
|
Packit |
31ecd5 |
GType meta_type;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
meta_type = CLUTTER_CONTAINER_GET_IFACE (container)->child_meta_type;
|
|
Packit |
31ecd5 |
if (meta_type == G_TYPE_INVALID)
|
|
Packit |
31ecd5 |
return;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
klass = G_OBJECT_GET_CLASS (container);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* shortcut, to avoid typechecking every time */
|
|
Packit |
31ecd5 |
if (CLUTTER_IS_SCRIPTABLE (container))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
scriptable = CLUTTER_SCRIPTABLE (container);
|
|
Packit |
31ecd5 |
iface = CLUTTER_SCRIPTABLE_GET_IFACE (scriptable);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
parse_custom_node = iface->parse_custom_node != NULL ? TRUE : FALSE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
properties = oinfo->properties;
|
|
Packit |
31ecd5 |
oinfo->properties = NULL;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
unresolved = NULL;
|
|
Packit |
31ecd5 |
for (l = properties; l != NULL; l = l->next)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
PropertyInfo *pinfo = l->data;
|
|
Packit |
31ecd5 |
GValue value = G_VALUE_INIT;
|
|
Packit |
31ecd5 |
gboolean res = FALSE;
|
|
Packit |
31ecd5 |
const gchar *name;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (!pinfo->is_child)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
unresolved = g_list_prepend (unresolved, pinfo);
|
|
Packit |
31ecd5 |
continue;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
name = pinfo->name + strlen ("child::");
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
pinfo->pspec =
|
|
Packit |
31ecd5 |
clutter_container_class_find_child_property (klass, name);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (pinfo->pspec != NULL)
|
|
Packit |
31ecd5 |
g_param_spec_ref (pinfo->pspec);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT, "Parsing %s child property (id:%s)",
|
|
Packit |
31ecd5 |
pinfo->pspec != NULL ? "regular" : "custom",
|
|
Packit |
31ecd5 |
name);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (parse_custom_node)
|
|
Packit |
31ecd5 |
res = iface->parse_custom_node (scriptable, script, &value,
|
|
Packit |
31ecd5 |
name,
|
|
Packit |
31ecd5 |
pinfo->node);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (!res)
|
|
Packit |
31ecd5 |
res = _clutter_script_parse_node (script, &value,
|
|
Packit |
31ecd5 |
name,
|
|
Packit |
31ecd5 |
pinfo->node,
|
|
Packit |
31ecd5 |
pinfo->pspec);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (!res)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT, "Child property '%s' ignored", name);
|
|
Packit |
31ecd5 |
unresolved = g_list_prepend (unresolved, pinfo);
|
|
Packit |
31ecd5 |
continue;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT,
|
|
Packit |
31ecd5 |
"Setting %s child property '%s' (type:%s) to "
|
|
Packit |
31ecd5 |
"object '%s' (id:%s)",
|
|
Packit |
31ecd5 |
iface->set_custom_property != NULL ? "custom" : "regular",
|
|
Packit |
31ecd5 |
name,
|
|
Packit |
31ecd5 |
g_type_name (G_VALUE_TYPE (&value)),
|
|
Packit |
31ecd5 |
g_type_name (oinfo->gtype),
|
|
Packit |
31ecd5 |
oinfo->id);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
clutter_container_child_set_property (container, actor,
|
|
Packit |
31ecd5 |
name,
|
|
Packit |
31ecd5 |
&value);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_value_unset (&value);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
property_info_free (pinfo);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_list_free (properties);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
oinfo->properties = unresolved;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static void
|
|
Packit |
31ecd5 |
add_children (ClutterScript *script,
|
|
Packit |
31ecd5 |
ObjectInfo *oinfo)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterContainer *container = CLUTTER_CONTAINER (oinfo->object);
|
|
Packit |
31ecd5 |
GList *l, *unresolved;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
unresolved = NULL;
|
|
Packit |
31ecd5 |
for (l = oinfo->children; l != NULL; l = l->next)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
const gchar *name = l->data;
|
|
Packit |
31ecd5 |
GObject *object = NULL;
|
|
Packit |
31ecd5 |
ObjectInfo *child_info;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
child_info = _clutter_script_get_object_info (script, name);
|
|
Packit |
31ecd5 |
if (child_info != NULL)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
_clutter_script_construct_object (script, child_info);
|
|
Packit |
31ecd5 |
object = child_info->object;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (object == NULL)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
unresolved = g_list_prepend (unresolved, g_strdup (name));
|
|
Packit |
31ecd5 |
continue;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (!CLUTTER_IS_ACTOR (object))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
g_warning ("The object definition '%s' (type: %s) is not "
|
|
Packit |
31ecd5 |
"an actor, but it is referenced in the 'children' "
|
|
Packit |
31ecd5 |
"member of the container '%s' (type: %s); skipping.",
|
|
Packit |
31ecd5 |
child_info->id,
|
|
Packit |
31ecd5 |
g_type_name (child_info->gtype),
|
|
Packit |
31ecd5 |
oinfo->id,
|
|
Packit |
31ecd5 |
g_type_name (oinfo->gtype));
|
|
Packit |
31ecd5 |
continue;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT, "Adding children '%s' to actor of type '%s'",
|
|
Packit |
31ecd5 |
name,
|
|
Packit |
31ecd5 |
g_type_name (G_OBJECT_TYPE (container)));
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
clutter_container_add_actor (container, CLUTTER_ACTOR (object));
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_list_foreach (oinfo->children, (GFunc) g_free, NULL);
|
|
Packit |
31ecd5 |
g_list_free (oinfo->children);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
oinfo->children = unresolved;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
static inline void
|
|
Packit |
31ecd5 |
_clutter_script_check_unresolved (ClutterScript *script,
|
|
Packit |
31ecd5 |
ObjectInfo *oinfo)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
if (oinfo->children != NULL && CLUTTER_IS_CONTAINER (oinfo->object))
|
|
Packit |
31ecd5 |
add_children (script, oinfo);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* this is a bit *eugh*, but it allows us to effectively make sure
|
|
Packit |
31ecd5 |
* that child and layout properties are parsed and applied to the
|
|
Packit |
31ecd5 |
* right child
|
|
Packit |
31ecd5 |
*/
|
|
Packit |
31ecd5 |
if (oinfo->properties != NULL && CLUTTER_IS_ACTOR (oinfo->object))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterActor *parent;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
parent = clutter_actor_get_parent (CLUTTER_ACTOR (oinfo->object));
|
|
Packit |
31ecd5 |
if (parent != NULL)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterContainer *container = CLUTTER_CONTAINER (parent);
|
|
Packit |
31ecd5 |
ClutterActor *child;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
for (child = clutter_actor_get_first_child (parent);
|
|
Packit |
31ecd5 |
child != NULL;
|
|
Packit |
31ecd5 |
child = clutter_actor_get_next_sibling (child))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ObjectInfo *child_info;
|
|
Packit |
31ecd5 |
const gchar *id_;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
id_ = clutter_get_script_id (G_OBJECT (child));
|
|
Packit |
31ecd5 |
if (id_ == NULL || *id_ == '\0')
|
|
Packit |
31ecd5 |
continue;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
child_info = _clutter_script_get_object_info (script, id_);
|
|
Packit |
31ecd5 |
if (child_info == NULL)
|
|
Packit |
31ecd5 |
continue;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
apply_child_properties (script, container,
|
|
Packit |
31ecd5 |
child,
|
|
Packit |
31ecd5 |
child_info);
|
|
Packit |
31ecd5 |
apply_layout_properties (script, container,
|
|
Packit |
31ecd5 |
child,
|
|
Packit |
31ecd5 |
child_info);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (oinfo->properties || oinfo->children)
|
|
Packit |
31ecd5 |
oinfo->has_unresolved = TRUE;
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
oinfo->has_unresolved = FALSE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
void
|
|
Packit |
31ecd5 |
_clutter_script_apply_properties (ClutterScript *script,
|
|
Packit |
31ecd5 |
ObjectInfo *oinfo)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterScriptable *scriptable = NULL;
|
|
Packit |
31ecd5 |
ClutterScriptableIface *iface = NULL;
|
|
Packit |
31ecd5 |
gboolean set_custom_property = FALSE;
|
|
Packit |
31ecd5 |
GObject *object = oinfo->object;
|
|
Packit |
31ecd5 |
GList *properties;
|
|
Packit |
31ecd5 |
GArray *params;
|
|
Packit |
31ecd5 |
guint i;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (!oinfo->has_unresolved)
|
|
Packit |
31ecd5 |
return;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* shortcut, to avoid typechecking every time */
|
|
Packit |
31ecd5 |
if (CLUTTER_IS_SCRIPTABLE (object))
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
scriptable = CLUTTER_SCRIPTABLE (object);
|
|
Packit |
31ecd5 |
iface = CLUTTER_SCRIPTABLE_GET_IFACE (scriptable);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (iface->set_custom_property)
|
|
Packit |
31ecd5 |
set_custom_property = TRUE;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* then we get the rest of the parameters, asking the object itself
|
|
Packit |
31ecd5 |
* to translate them for us, if we cannot do that
|
|
Packit |
31ecd5 |
*/
|
|
Packit |
31ecd5 |
properties = oinfo->properties;
|
|
Packit |
31ecd5 |
oinfo->properties = clutter_script_translate_parameters (script,
|
|
Packit |
31ecd5 |
object,
|
|
Packit |
31ecd5 |
oinfo->id,
|
|
Packit |
31ecd5 |
properties,
|
|
Packit |
31ecd5 |
¶ms);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* consume all the properties we could translate in this pass */
|
|
Packit |
31ecd5 |
for (i = 0; i < params->len; i++)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
GParameter *param = &g_array_index (params, GParameter, i);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
CLUTTER_NOTE (SCRIPT,
|
|
Packit |
31ecd5 |
"Setting %s property '%s' (type:%s) to object '%s' (id:%s)",
|
|
Packit |
31ecd5 |
set_custom_property ? "custom" : "regular",
|
|
Packit |
31ecd5 |
param->name,
|
|
Packit |
31ecd5 |
g_type_name (G_VALUE_TYPE (¶m->value)),
|
|
Packit |
31ecd5 |
g_type_name (oinfo->gtype),
|
|
Packit |
31ecd5 |
oinfo->id);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (set_custom_property)
|
|
Packit |
31ecd5 |
iface->set_custom_property (scriptable, script,
|
|
Packit |
31ecd5 |
param->name,
|
|
Packit |
31ecd5 |
¶m->value);
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
g_object_set_property (object, param->name, ¶m->value);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_free ((gchar *) param->name);
|
|
Packit |
31ecd5 |
g_value_unset (¶m->value);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_array_free (params, TRUE);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
_clutter_script_check_unresolved (script, oinfo);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
void
|
|
Packit |
31ecd5 |
_clutter_script_construct_object (ClutterScript *script,
|
|
Packit |
31ecd5 |
ObjectInfo *oinfo)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
GArray *params = NULL;
|
|
Packit |
31ecd5 |
guint i;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* we have completely updated the object */
|
|
Packit |
31ecd5 |
if (oinfo->object != NULL)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
if (oinfo->has_unresolved)
|
|
Packit |
31ecd5 |
_clutter_script_check_unresolved (script, oinfo);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
return;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (oinfo->gtype == G_TYPE_INVALID)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
if (G_UNLIKELY (oinfo->type_func))
|
|
Packit |
31ecd5 |
oinfo->gtype = _clutter_script_get_type_from_symbol (oinfo->type_func);
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
oinfo->gtype = clutter_script_get_type_from_name (script, oinfo->class_name);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (G_UNLIKELY (oinfo->gtype == G_TYPE_INVALID))
|
|
Packit |
31ecd5 |
return;
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
oinfo->is_actor = g_type_is_a (oinfo->gtype, CLUTTER_TYPE_ACTOR);
|
|
Packit |
31ecd5 |
if (oinfo->is_actor)
|
|
Packit |
31ecd5 |
oinfo->is_stage = g_type_is_a (oinfo->gtype, CLUTTER_TYPE_STAGE);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (oinfo->is_stage && oinfo->is_stage_default)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
ClutterStageManager *manager = clutter_stage_manager_get_default ();
|
|
Packit |
31ecd5 |
GList *properties = oinfo->properties;
|
|
Packit |
31ecd5 |
ClutterStage *default_stage;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* the default stage is a complex beast: we cannot create it using
|
|
Packit |
31ecd5 |
* g_object_newv() but we need clutter_script_construct_parameters()
|
|
Packit |
31ecd5 |
* to add the GParamSpec to the PropertyInfo pspec member, so
|
|
Packit |
31ecd5 |
* that we don't have to implement every complex property (like
|
|
Packit |
31ecd5 |
* the "color" one) directly inside the ClutterStage class.
|
|
Packit |
31ecd5 |
*/
|
|
Packit |
31ecd5 |
oinfo->properties =
|
|
Packit |
31ecd5 |
clutter_script_construct_parameters (script,
|
|
Packit |
31ecd5 |
oinfo->gtype,
|
|
Packit |
31ecd5 |
oinfo->id,
|
|
Packit |
31ecd5 |
properties,
|
|
Packit |
31ecd5 |
¶ms);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
default_stage = clutter_stage_manager_get_default_stage (manager);
|
|
Packit |
31ecd5 |
oinfo->object = G_OBJECT (default_stage);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
for (i = 0; i < params->len; i++)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
GParameter *param = &g_array_index (params, GParameter, i);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_free ((gchar *) param->name);
|
|
Packit |
31ecd5 |
g_value_unset (¶m->value);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_array_free (params, TRUE);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
GList *properties = oinfo->properties;
|
|
Packit |
31ecd5 |
GParameter *parameters;
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* every other object: first, we get the construction parameters */
|
|
Packit |
31ecd5 |
oinfo->properties =
|
|
Packit |
31ecd5 |
clutter_script_construct_parameters (script,
|
|
Packit |
31ecd5 |
oinfo->gtype,
|
|
Packit |
31ecd5 |
oinfo->id,
|
|
Packit |
31ecd5 |
properties,
|
|
Packit |
31ecd5 |
¶ms);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
parameters = (GParameter *) (void *) params->data;
|
|
Packit |
31ecd5 |
oinfo->object = g_object_newv (oinfo->gtype,
|
|
Packit |
31ecd5 |
params->len,
|
|
Packit |
31ecd5 |
parameters);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
/* by sinking the floating reference, we make sure that the reference
|
|
Packit |
31ecd5 |
* count is correct whether the object is referenced from somewhere
|
|
Packit |
31ecd5 |
* else too or only by this ClutterScript object.
|
|
Packit |
31ecd5 |
*/
|
|
Packit |
31ecd5 |
g_object_ref_sink (oinfo->object);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
for (i = 0; i < params->len; i++)
|
|
Packit |
31ecd5 |
{
|
|
Packit |
31ecd5 |
GParameter *param = &g_array_index (params, GParameter, i);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_free ((gchar *) param->name);
|
|
Packit |
31ecd5 |
g_value_unset (¶m->value);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_array_free (params, TRUE);
|
|
Packit |
31ecd5 |
}
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
g_assert (oinfo->object != NULL);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
if (CLUTTER_IS_SCRIPTABLE (oinfo->object))
|
|
Packit |
31ecd5 |
clutter_scriptable_set_id (CLUTTER_SCRIPTABLE (oinfo->object), oinfo->id);
|
|
Packit |
31ecd5 |
else
|
|
Packit |
31ecd5 |
g_object_set_data_full (oinfo->object, "clutter-script-id",
|
|
Packit |
31ecd5 |
g_strdup (oinfo->id),
|
|
Packit |
31ecd5 |
g_free);
|
|
Packit |
31ecd5 |
|
|
Packit |
31ecd5 |
_clutter_script_check_unresolved (script, oinfo);
|
|
Packit |
31ecd5 |
}
|