/** * clutter_container_child_get_property: * @container: a #ClutterContainer * @child: a #ClutterActor that is a child of @container. * @property: the name of the property to set. * @value: the value. * * Gets a container specific property of a child of @container, In general, * a copy is made of the property contents and the caller is responsible for * freeing the memory by calling g_value_unset(). * * Note that clutter_container_child_set_property() is really intended for * language bindings, clutter_container_child_set() is much more convenient * for C programming. * * Since: 0.8 */ void clutter_container_child_get_property (ClutterContainer *container, ClutterActor *child, const gchar *property, GValue *value) { GObjectClass *klass; GParamSpec *pspec; g_return_if_fail (CLUTTER_IS_CONTAINER (container)); g_return_if_fail (CLUTTER_IS_ACTOR (child)); g_return_if_fail (property != NULL); g_return_if_fail (value != NULL); klass = G_OBJECT_GET_CLASS (container); pspec = clutter_container_class_find_child_property (klass, property); if (!pspec) { g_warning ("%s: Containers of type '%s' have no child " "property named '%s'", G_STRLOC, G_OBJECT_TYPE_NAME (container), property); return; } if (!(pspec->flags & G_PARAM_READABLE)) { g_warning ("%s: Child property '%s' of the container '%s' " "is not writable", G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (container)); return; } container_get_child_property (container, child, value, pspec); }
/** * clutter_container_child_get: * @container: a #ClutterContainer * @actor: a #ClutterActor that is a child of @container. * @first_prop: name of the first property to be set. * @...: value for the first property, followed optionally by more name/value * pairs terminated with NULL. * * Gets @container specific properties of an actor. * * In general, a copy is made of the property contents and the caller is * responsible for freeing the memory in the appropriate manner for the type, for * instance by calling free() or g_object_unref(). * * Since: 0.8 */ void clutter_container_child_get (ClutterContainer *container, ClutterActor *actor, const gchar *first_prop, ...) { GObjectClass *klass; const gchar *name; va_list var_args; g_return_if_fail (CLUTTER_IS_CONTAINER (container)); g_return_if_fail (CLUTTER_IS_ACTOR (actor)); klass = G_OBJECT_GET_CLASS (container); va_start (var_args, first_prop); name = first_prop; while (name) { GValue value = G_VALUE_INIT; gchar *error = NULL; GParamSpec *pspec; pspec = clutter_container_class_find_child_property (klass, name); if (!pspec) { g_warning ("%s: container '%s' has no child property named '%s'", G_STRLOC, G_OBJECT_TYPE_NAME (container), name); break; } if (!(pspec->flags & G_PARAM_READABLE)) { g_warning ("%s: child property '%s' of container '%s' is not readable", G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (container)); break; } g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); container_get_child_property (container, actor, &value, pspec); G_VALUE_LCOPY (&value, var_args, 0, &error); if (error) { g_warning ("%s: %s", G_STRLOC, error); free (error); g_value_unset (&value); break; } g_value_unset (&value); name = va_arg (var_args, gchar*); } va_end (var_args); }
static VALUE rbclt_container_find_child_property (VALUE self, VALUE rclass, VALUE prop_name) { GObjectClass *klass = rbclt_container_get_container_class (rclass); GParamSpec *param = clutter_container_class_find_child_property (klass, StringValuePtr (prop_name)); g_type_class_unref (klass); return GOBJ2RVAL (param); }
static VALUE rbclt_container_child_get (int argc, VALUE *argv, VALUE self) { ClutterContainer *container = CLUTTER_CONTAINER (RVAL2GOBJ (self)); ClutterActor *actor; VALUE ary = rb_ary_new (); int i; if (argc < 2) rb_raise (rb_eArgError, "wrong number of arguments (%d for %d)", argc, 2); if (!CLUTTER_IS_ACTOR (actor = (ClutterActor *) RVAL2GOBJ (argv[0]))) rb_raise (rb_eArgError, "actor required"); for (i = 1; i < argc; i++) { GValue value; const char *prop = StringValuePtr (argv[i]); GObjectClass *klass = G_OBJECT_CLASS (g_type_class_ref (G_TYPE_FROM_INSTANCE (container))); GParamSpec *pspec = clutter_container_class_find_child_property (klass, prop); g_type_class_unref (klass); if (pspec == NULL) rb_raise (rb_eArgError, "child property not found \"%s\"", prop); memset (&value, 0, sizeof (VALUE)); g_value_init (&value, pspec->value_type); clutter_container_child_get_property (container, actor, prop, &value); rb_ary_push (ary, GVAL2RVAL (&value)); g_value_unset (&value); } if (RARRAY_LEN (ary) == 1) return RARRAY_PTR (ary)[0]; else return ary; }
static VALUE rbclt_container_child_set (int argc, VALUE *argv, VALUE self) { ClutterContainer *container = CLUTTER_CONTAINER (RVAL2GOBJ (self)); ClutterActor *actor; int i; if (argc < 2) rb_raise (rb_eArgError, "wrong number of arguments (%d for %d)", argc, 2); else if ((argc & 1) == 0) rb_raise (rb_eArgError, "wrong number of arguments " "(prop-value pairs needed)"); if (!CLUTTER_IS_ACTOR (actor = (ClutterActor *) RVAL2GOBJ (argv[0]))) rb_raise (rb_eArgError, "actor required"); for (i = 1; i < argc; i += 2) { GValue value; const char *prop = StringValuePtr (argv[i]); GObjectClass *klass = G_OBJECT_CLASS (g_type_class_ref (G_TYPE_FROM_INSTANCE (container))); GParamSpec *pspec = clutter_container_class_find_child_property (klass, prop); g_type_class_unref (klass); if (pspec == NULL) rb_raise (rb_eArgError, "child property not found \"%s\"", prop); memset (&value, 0, sizeof (VALUE)); g_value_init (&value, pspec->value_type); rbgobj_rvalue_to_gvalue (argv[i + 1], &value); clutter_container_child_set_property (container, actor, prop, &value); g_value_unset (&value); } return self; }
/** * clutter_container_child_set: * @container: a #ClutterContainer * @actor: a #ClutterActor that is a child of @container. * @first_prop: name of the first property to be set. * @...: value for the first property, followed optionally by more name/value * pairs terminated with NULL. * * Sets container specific properties on the child of a container. * * Since: 0.8 */ void clutter_container_child_set (ClutterContainer *container, ClutterActor *actor, const gchar *first_prop, ...) { GObjectClass *klass; const gchar *name; va_list var_args; g_return_if_fail (CLUTTER_IS_CONTAINER (container)); g_return_if_fail (CLUTTER_IS_ACTOR (actor)); klass = G_OBJECT_GET_CLASS (container); va_start (var_args, first_prop); name = first_prop; while (name) { GValue value = G_VALUE_INIT; gchar *error = NULL; GParamSpec *pspec; pspec = clutter_container_class_find_child_property (klass, name); if (!pspec) { g_warning ("%s: Containers of type '%s' have no child " "property named '%s'", G_STRLOC, G_OBJECT_TYPE_NAME (container), name); break; } if (!(pspec->flags & G_PARAM_WRITABLE)) { g_warning ("%s: Child property '%s' of the container '%s' " "is not writable", G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (container)); break; } G_VALUE_COLLECT_INIT (&value, G_PARAM_SPEC_VALUE_TYPE (pspec), var_args, 0, &error); if (error) { /* we intentionally leak the GValue because it might * be in an undefined state and calling g_value_unset() * on it might crash */ g_warning ("%s: %s", G_STRLOC, error); free (error); break; } container_set_child_property (container, actor, &value, pspec); g_value_unset (&value); name = va_arg (var_args, gchar*); } va_end (var_args); }