diff --git a/gobject/tests/binding.c b/gobject/tests/binding.c index 1d3ead481..be6d751c1 100644 --- a/gobject/tests/binding.c +++ b/gobject/tests/binding.c @@ -2,6 +2,47 @@ #include #include +typedef struct { + GTypeInterface g_iface; +} FooInterface; + +GType foo_get_type (void); + +G_DEFINE_INTERFACE (Foo, foo, G_TYPE_OBJECT) + +static void +foo_default_init (FooInterface *iface) +{ +} + +typedef struct { + GObject parent; +} Baa; + +typedef struct { + GObjectClass parent_class; +} BaaClass; + +static void +baa_init_foo (FooInterface *iface) +{ +} + +GType baa_get_type (void); + +G_DEFINE_TYPE_WITH_CODE (Baa, baa, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (foo_get_type (), baa_init_foo)) + +static void +baa_init (Baa *baa) +{ +} + +static void +baa_class_init (BaaClass *class) +{ +} + typedef struct _BindingSource { GObject parent_instance; @@ -10,6 +51,7 @@ typedef struct _BindingSource gint bar; gdouble double_value; gboolean toggle; + gpointer item; } BindingSource; typedef struct _BindingSourceClass @@ -24,7 +66,8 @@ enum PROP_SOURCE_FOO, PROP_SOURCE_BAR, PROP_SOURCE_DOUBLE_VALUE, - PROP_SOURCE_TOGGLE + PROP_SOURCE_TOGGLE, + PROP_SOURCE_OBJECT }; static GType binding_source_get_type (void); @@ -56,6 +99,10 @@ binding_source_set_property (GObject *gobject, source->toggle = g_value_get_boolean (value); break; + case PROP_SOURCE_OBJECT: + source->item = g_value_get_object (value); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); } @@ -87,6 +134,10 @@ binding_source_get_property (GObject *gobject, g_value_set_boolean (value, source->toggle); break; + case PROP_SOURCE_OBJECT: + g_value_set_object (value, source->item); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); } @@ -119,6 +170,10 @@ binding_source_class_init (BindingSourceClass *klass) g_param_spec_boolean ("toggle", "Toggle", "Toggle", FALSE, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_SOURCE_OBJECT, + g_param_spec_object ("object", "Object", "Object", + G_TYPE_OBJECT, + G_PARAM_READWRITE)); } static void @@ -133,6 +188,7 @@ typedef struct _BindingTarget gint bar; gdouble double_value; gboolean toggle; + gpointer foo; } BindingTarget; typedef struct _BindingTargetClass @@ -146,7 +202,8 @@ enum PROP_TARGET_BAR, PROP_TARGET_DOUBLE_VALUE, - PROP_TARGET_TOGGLE + PROP_TARGET_TOGGLE, + PROP_TARGET_FOO }; static GType binding_target_get_type (void); @@ -174,6 +231,10 @@ binding_target_set_property (GObject *gobject, target->toggle = g_value_get_boolean (value); break; + case PROP_TARGET_FOO: + target->foo = g_value_get_object (value); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); } @@ -201,6 +262,10 @@ binding_target_get_property (GObject *gobject, g_value_set_boolean (value, target->toggle); break; + case PROP_TARGET_FOO: + g_value_set_object (value, target->foo); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); } @@ -228,6 +293,10 @@ binding_target_class_init (BindingTargetClass *klass) g_param_spec_boolean ("toggle", "Toggle", "Toggle", FALSE, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_TARGET_FOO, + g_param_spec_object ("foo", "Foo", "Foo", + foo_get_type (), + G_PARAM_READWRITE)); } static void @@ -757,6 +826,66 @@ binding_fail (void) g_assert_null (binding); } +static gboolean +transform_to_func (GBinding *binding, + const GValue *value_a, + GValue *value_b, + gpointer user_data) +{ + if (g_value_type_compatible (G_VALUE_TYPE (value_a), G_VALUE_TYPE (value_b))) + { + g_value_copy (value_a, value_b); + return TRUE; + } + + if (g_value_type_transformable (G_VALUE_TYPE (value_a), G_VALUE_TYPE (value_b))) + { + if (g_value_transform (value_a, value_b)) + return TRUE; + } + + return FALSE; +} + +static void +binding_interface (void) +{ + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + GObject *baa; + GBinding *binding; + GClosure *transform_to; + + /* binding a generic object property to an interface-valued one */ + binding = g_object_bind_property (source, "object", + target, "foo", + G_BINDING_DEFAULT); + + baa = g_object_new (baa_get_type (), NULL); + g_object_set (source, "object", baa, NULL); + g_object_unref (baa); + + g_binding_unbind (binding); + + /* the same, with a generic marshaller */ + transform_to = g_cclosure_new (G_CALLBACK (transform_to_func), NULL, NULL); + g_closure_set_marshal (transform_to, g_cclosure_marshal_generic); + binding = g_object_bind_property_with_closures (source, "object", + target, "foo", + G_BINDING_DEFAULT, + transform_to, + NULL); + + baa = g_object_new (baa_get_type (), NULL); + g_object_set (source, "object", baa, NULL); + g_object_unref (baa); + + g_binding_unbind (binding); + + g_object_unref (source); + g_object_unref (target); +} + int main (int argc, char *argv[]) { @@ -778,6 +907,7 @@ main (int argc, char *argv[]) g_test_add_func ("/binding/unbind-weak", binding_unbind_weak); g_test_add_func ("/binding/unbind-multiple", binding_unbind_multiple); g_test_add_func ("/binding/fail", binding_fail); + g_test_add_func ("/binding/interface", binding_interface); return g_test_run (); }