diff options
author | Emmanuele Bassi <ebassi@linux.intel.com> | 2010-06-04 16:17:15 +0100 |
---|---|---|
committer | Emmanuele Bassi <ebassi@linux.intel.com> | 2010-06-15 16:06:18 +0100 |
commit | 6d1d9cf1b551845a159a6b822500bb40e33fda74 (patch) | |
tree | 44893244f94fe021fd5d35a2e72ac7009e4ac0bd /gobject/tests | |
parent | f3879a4bdca2ff1cf6c6b016d67a7e5d40c0e86b (diff) | |
download | glib-6d1d9cf1b551845a159a6b822500bb40e33fda74.tar.gz |
gobject: Add GBinding
GBinding is a simple, opaque object that represents a binding between a
property on a GObject instance (source) and property on another GObject
instance (target).
https://bugzilla.gnome.org/show_bug.cgi?id=348080
Diffstat (limited to 'gobject/tests')
-rw-r--r-- | gobject/tests/.gitignore | 1 | ||||
-rw-r--r-- | gobject/tests/Makefile.am | 4 | ||||
-rw-r--r-- | gobject/tests/binding.c | 326 |
3 files changed, 330 insertions, 1 deletions
diff --git a/gobject/tests/.gitignore b/gobject/tests/.gitignore index bb48529e6..ca0d62868 100644 --- a/gobject/tests/.gitignore +++ b/gobject/tests/.gitignore @@ -1,2 +1,3 @@ +binding dynamictests threadtests diff --git a/gobject/tests/Makefile.am b/gobject/tests/Makefile.am index 33b3e0b01..d1735a2be 100644 --- a/gobject/tests/Makefile.am +++ b/gobject/tests/Makefile.am @@ -5,8 +5,10 @@ INCLUDES = -g -I$(top_srcdir) -I$(top_srcdir)/glib $(GLIB_DEBUG_FLAGS) noinst_PROGRAMS = $(TEST_PROGS) libgobject_LDADD = ../libgobject-2.0.la $(top_builddir)/gthread/libgthread-2.0.la $(top_builddir)/glib/libglib-2.0.la -TEST_PROGS += threadtests dynamictests +TEST_PROGS += threadtests dynamictests binding threadtests_SOURCES = threadtests.c threadtests_LDADD = $(libgobject_LDADD) dynamictests_SOURCES = dynamictests.c dynamictests_LDADD = $(libgobject_LDADD) +binding_SOURCES = binding.c +binding_LDADD = $(libgobject_LDADD) diff --git a/gobject/tests/binding.c b/gobject/tests/binding.c new file mode 100644 index 000000000..15036fae0 --- /dev/null +++ b/gobject/tests/binding.c @@ -0,0 +1,326 @@ +#include <stdlib.h> +#include <gstdio.h> +#include <glib-object.h> + +typedef struct _BindingSource +{ + GObject parent_instance; + + gint foo; + gdouble value; +} BindingSource; + +typedef struct _BindingSourceClass +{ + GObjectClass parent_class; +} BindingSourceClass; + +enum +{ + PROP_SOURCE_0, + + PROP_SOURCE_FOO, + + PROP_SOURCE_VALUE +}; + +G_DEFINE_TYPE (BindingSource, binding_source, G_TYPE_OBJECT); + +static void +binding_source_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + BindingSource *source = (BindingSource *) gobject; + + switch (prop_id) + { + case PROP_SOURCE_FOO: + source->foo = g_value_get_int (value); + break; + + case PROP_SOURCE_VALUE: + source->value = g_value_get_double (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +binding_source_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + BindingSource *source = (BindingSource *) gobject; + + switch (prop_id) + { + case PROP_SOURCE_FOO: + g_value_set_int (value, source->foo); + break; + + case PROP_SOURCE_VALUE: + g_value_set_double (value, source->value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +binding_source_class_init (BindingSourceClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = binding_source_set_property; + gobject_class->get_property = binding_source_get_property; + + g_object_class_install_property (gobject_class, PROP_SOURCE_FOO, + g_param_spec_int ("foo", "Foo", "Foo", + -1, 100, + 0, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_SOURCE_VALUE, + g_param_spec_double ("value", "Value", "Value", + -100.0, 200.0, + 0.0, + G_PARAM_READWRITE)); +} + +static void +binding_source_init (BindingSource *self) +{ +} + +typedef struct _BindingTarget +{ + GObject parent_instance; + + gint bar; + gdouble value; +} BindingTarget; + +typedef struct _BindingTargetClass +{ + GObjectClass parent_class; +} BindingTargetClass; + +enum +{ + PROP_TARGET_0, + + PROP_TARGET_BAR, + + PROP_TARGET_VALUE +}; + +G_DEFINE_TYPE (BindingTarget, binding_target, G_TYPE_OBJECT); + +static void +binding_target_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + BindingTarget *target = (BindingTarget *) gobject; + + switch (prop_id) + { + case PROP_TARGET_BAR: + target->bar = g_value_get_int (value); + break; + + case PROP_TARGET_VALUE: + target->value = g_value_get_double (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +binding_target_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + BindingTarget *target = (BindingTarget *) gobject; + + switch (prop_id) + { + case PROP_TARGET_BAR: + g_value_set_int (value, target->bar); + break; + + case PROP_TARGET_VALUE: + g_value_set_double (value, target->value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +binding_target_class_init (BindingTargetClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = binding_target_set_property; + gobject_class->get_property = binding_target_get_property; + + g_object_class_install_property (gobject_class, PROP_TARGET_BAR, + g_param_spec_int ("bar", "Bar", "Bar", + -1, 100, + 0, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_SOURCE_VALUE, + g_param_spec_double ("value", "Value", "Value", + -100.0, 200.0, + 0.0, + G_PARAM_READWRITE)); +} + +static void +binding_target_init (BindingTarget *self) +{ +} + +static gboolean +celsius_to_fahrenheit (GBinding *binding, + const GValue *source_value, + GValue *target_value, + gpointer user_data G_GNUC_UNUSED) +{ + gdouble celsius, fahrenheit; + + g_assert (G_VALUE_HOLDS (source_value, G_TYPE_DOUBLE)); + g_assert (G_VALUE_HOLDS (target_value, G_TYPE_DOUBLE)); + + celsius = g_value_get_double (source_value); + fahrenheit = (9 * celsius / 5) + 32.0; + + if (g_test_verbose ()) + g_print ("Converting %.2fC to %.2fF\n", celsius, fahrenheit); + + g_value_set_double (target_value, fahrenheit); + + return TRUE; +} + +static gboolean +fahrenheit_to_celsius (GBinding *binding, + const GValue *source_value, + GValue *target_value, + gpointer user_data G_GNUC_UNUSED) +{ + gdouble celsius, fahrenheit; + + g_assert (G_VALUE_HOLDS (source_value, G_TYPE_DOUBLE)); + g_assert (G_VALUE_HOLDS (target_value, G_TYPE_DOUBLE)); + + fahrenheit = g_value_get_double (source_value); + celsius = 5 * (fahrenheit - 32.0) / 9; + + if (g_test_verbose ()) + g_print ("Converting %.2fF to %.2fC\n", fahrenheit, celsius); + + g_value_set_double (target_value, celsius); + + return TRUE; +} + +static void +binding_default (void) +{ + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + GBinding *binding; + + binding = g_object_bind_property (source, "foo", + target, "bar", + G_BINDING_DEFAULT); + + g_object_set (source, "foo", 42, NULL); + g_assert_cmpint (source->foo, ==, target->bar); + + g_object_set (target, "bar", 47, NULL); + g_assert_cmpint (source->foo, !=, target->bar); + + g_object_unref (binding); + + g_object_set (source, "foo", 0, NULL); + g_assert_cmpint (source->foo, !=, target->bar); + + g_object_unref (source); + g_object_unref (target); +} + +static void +binding_bidirectional (void) +{ + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + GBinding *binding; + + binding = g_object_bind_property (source, "foo", + target, "bar", + G_BINDING_BIDIRECTIONAL); + + g_object_set (source, "foo", 42, NULL); + g_assert_cmpint (source->foo, ==, target->bar); + + g_object_set (target, "bar", 47, NULL); + g_assert_cmpint (source->foo, ==, target->bar); + + g_object_unref (binding); + + g_object_set (source, "foo", 0, NULL); + g_assert_cmpint (source->foo, !=, target->bar); + + g_object_unref (source); + g_object_unref (target); +} + +static void +binding_transform (void) +{ + BindingSource *source = g_object_new (binding_source_get_type (), NULL); + BindingTarget *target = g_object_new (binding_target_get_type (), NULL); + GBinding *binding; + + binding = g_object_bind_property_full (source, "value", + target, "value", + G_BINDING_BIDIRECTIONAL, + celsius_to_fahrenheit, + fahrenheit_to_celsius, + NULL, NULL); + + g_object_set (source, "value", 24.0, NULL); + g_assert_cmpfloat (target->value, ==, ((9 * 24.0 / 5) + 32.0)); + + g_object_set (target, "value", 69.0, NULL); + g_assert_cmpfloat (source->value, ==, (5 * (69.0 - 32.0) / 9)); + + g_object_unref (source); + g_object_unref (target); +} + +int +main (int argc, char *argv[]) +{ + g_type_init (); + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/binding/default", binding_default); + g_test_add_func ("/binding/bidirectional", binding_bidirectional); + g_test_add_func ("/binding/transform", binding_transform); + + return g_test_run (); +} |