diff --git a/ChangeLog b/ChangeLog index 95cac42d5..510c18b03 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2006-08-29 Jorn Baayen + + * clutter/clutter-behaviour.c: (_clutter_behaviour_finalize), + (_clutter_behaviour_set_property), + (_clutter_behaviour_get_property), (clutter_behaviour_class_init), + (clutter_behaviour_init), (clutter_behaviour_apply), + (clutter_behaviour_remove), (clutter_behaviour_remove_all), + (clutter_behaviour_actors_foreach): + * clutter/clutter-behaviour.h: + * clutter/clutter-behaviours.c: + (clutter_behaviour_property_change), + (clutter_behaviour_opacity_dispose), + (clutter_behaviour_opacity_finalize), + (clutter_behaviour_opacity_class_init), + (clutter_behaviour_opacity_init): + * clutter/clutter-behaviours.h: + * clutter/clutter-marshal.list: + * examples/behave.c: (main): + + Behaviours track generic GObject properties. + + * clutter/clutter-video-texture.h: + + Remove signal prototypes - they are already specified in + clutter-media.h. + 2006-08-28 Jorn Baayen * clutter/Makefile.am: diff --git a/clutter/clutter-alpha.c b/clutter/clutter-alpha.c index dad63eef1..df628d8aa 100644 --- a/clutter/clutter-alpha.c +++ b/clutter/clutter-alpha.c @@ -171,7 +171,7 @@ clutter_alpha_get_property (GObject *object, g_value_set_pointer (value, priv->func); break; case PROP_ALPHA: - g_value_set_int (value, priv->alpha); + g_value_set_uint (value, priv->alpha); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -227,13 +227,13 @@ clutter_alpha_class_init (ClutterAlphaClass *klass) g_object_class_install_property (object_class, PROP_ALPHA, - g_param_spec_int ("alpha", - "Alpha value", - "Alpha value", - 0, - CLUTTER_ALPHA_MAX_ALPHA, - 0, - G_PARAM_READABLE)); + g_param_spec_uint ("alpha", + "Alpha value", + "Alpha value", + 0, + CLUTTER_ALPHA_MAX_ALPHA, + 0, + G_PARAM_READABLE)); } static void diff --git a/clutter/clutter-behaviour.c b/clutter/clutter-behaviour.c index 7832923d4..3e100d2b7 100644 --- a/clutter/clutter-behaviour.c +++ b/clutter/clutter-behaviour.c @@ -31,44 +31,56 @@ #include "config.h" -#include "clutter-timeline.h" #include "clutter-actor.h" #include "clutter-behaviour.h" +#include "clutter-marshal.h" G_DEFINE_TYPE (ClutterBehaviour, clutter_behaviour, G_TYPE_OBJECT); struct ClutterBehaviourPrivate { - ClutterTimeline *timeline; - GSList *actors; + GObject *object; + GParamSpec *param_spec; + guint notify_id; + GSList *actors; }; enum { PROP_0, - PROP_TIMELINE + PROP_OBJECT, + PROP_PROPERTY }; +enum { + SIGNAL_PROPERTY_CHANGE, + SIGNAL_LAST +}; + +static guint signals[SIGNAL_LAST]; + #define CLUTTER_BEHAVIOUR_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \ CLUTTER_TYPE_BEHAVIOUR, \ ClutterBehaviourPrivate)) static void -clutter_behaviour_dispose (GObject *object) +_clutter_behaviour_dispose (GObject *object) { ClutterBehaviour *self = CLUTTER_BEHAVIOUR(object); if (self->priv) { /* FIXME: remove all actors */ + + clutter_behaviour_set_object (self, NULL); } G_OBJECT_CLASS (clutter_behaviour_parent_class)->dispose (object); } static void -clutter_behaviour_finalize (GObject *object) +_clutter_behaviour_finalize (GObject *object) { ClutterBehaviour *self = CLUTTER_BEHAVIOUR(object); @@ -82,21 +94,22 @@ clutter_behaviour_finalize (GObject *object) } static void -clutter_behaviour_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +_clutter_behaviour_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - ClutterBehaviour *behaviour; - ClutterBehaviourPrivate *priv; + ClutterBehaviour *behaviour; behaviour = CLUTTER_BEHAVIOUR(object); - priv = CLUTTER_BEHAVIOUR_GET_PRIVATE(behaviour); switch (prop_id) { - case PROP_TIMELINE: - clutter_behaviour_set_timelime (behaviour, g_value_get_object (value)); + case PROP_OBJECT: + clutter_behaviour_set_object (behaviour, g_value_get_object (value)); + break; + case PROP_PROPERTY: + clutter_behaviour_set_property (behaviour, g_value_get_string (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -105,10 +118,10 @@ clutter_behaviour_set_property (GObject *object, } static void -clutter_behaviour_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +_clutter_behaviour_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) { ClutterBehaviour *behaviour; ClutterBehaviourPrivate *priv; @@ -118,8 +131,11 @@ clutter_behaviour_get_property (GObject *object, switch (prop_id) { - case PROP_TIMELINE: - g_value_set_object (value, priv->timeline); + case PROP_OBJECT: + g_value_set_object (value, priv->object); + break; + case PROP_PROPERTY: + g_value_set_string (value, priv->param_spec->name); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -135,19 +151,37 @@ clutter_behaviour_class_init (ClutterBehaviourClass *klass) object_class = (GObjectClass*) klass; - object_class->finalize = clutter_behaviour_finalize; - object_class->dispose = clutter_behaviour_dispose; - object_class->set_property = clutter_behaviour_set_property; - object_class->get_property = clutter_behaviour_get_property; + object_class->finalize = _clutter_behaviour_finalize; + object_class->dispose = _clutter_behaviour_dispose; + object_class->set_property = _clutter_behaviour_set_property; + object_class->get_property = _clutter_behaviour_get_property; g_object_class_install_property - (object_class, PROP_TIMELINE, - g_param_spec_object ("timeline", - "Timeline", - "Timeline source for behaviour", - CLUTTER_TYPE_TIMELINE, + (object_class, PROP_OBJECT, + g_param_spec_object ("object", + "Object", + "Object whose property to monitor", + G_TYPE_OBJECT, G_PARAM_CONSTRUCT | G_PARAM_READWRITE)); + g_object_class_install_property + (object_class, PROP_PROPERTY, + g_param_spec_string ("property", + "Property", + "Property to monitor", + NULL, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE)); + + signals[SIGNAL_PROPERTY_CHANGE] = + g_signal_new ("property-change", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ClutterBehaviourClass, property_change), + NULL, NULL, + clutter_marshal_VOID__OBJECT_POINTER, + G_TYPE_NONE, + 2, G_TYPE_OBJECT, G_TYPE_POINTER); + g_type_class_add_private (object_class, sizeof (ClutterBehaviourPrivate)); } @@ -161,12 +195,14 @@ clutter_behaviour_init (ClutterBehaviour *self) } ClutterBehaviour* -clutter_behaviour_new (ClutterTimeline *timeline) +clutter_behaviour_new (GObject *object, + const char *property) { ClutterBehaviour *behave; behave = g_object_new (CLUTTER_TYPE_BEHAVIOUR, - "timeline", timeline, + "object", object, + "property", property, NULL); return behave; @@ -210,29 +246,102 @@ clutter_behaviour_actors_foreach (ClutterBehaviour *behave, g_slist_foreach (behave->priv->actors, func, userdata); } -ClutterTimeline* -clutter_behaviour_get_timelime (ClutterBehaviour *behave) +GObject* +clutter_behaviour_get_object (ClutterBehaviour *behave) { - return behave->priv->timeline; + return behave->priv->object; } void -clutter_behaviour_set_timelime (ClutterBehaviour *behave, - ClutterTimeline *timeline) +clutter_behaviour_set_object (ClutterBehaviour *behave, + GObject *object) { ClutterBehaviourPrivate *priv; + const char *property; priv = CLUTTER_BEHAVIOUR_GET_PRIVATE(behave); - if (priv->timeline) + if (priv->object) { - g_object_unref(priv->timeline); - priv->timeline = NULL; - } + property = clutter_behaviour_get_property (behave); + clutter_behaviour_set_property (behave, NULL); - if (timeline) + g_object_unref(priv->object); + priv->object = NULL; + } + else + property = NULL; + + if (object) { - g_object_ref(timeline); - priv->timeline = timeline; + priv->object = g_object_ref(object); + + if (property) + clutter_behaviour_set_property (behave, property); + } +} + +const char * +clutter_behaviour_get_property (ClutterBehaviour *behave) +{ + if (behave->priv->param_spec) + return behave->priv->param_spec->name; + else + return NULL; +} + +GParamSpec * +clutter_behaviour_get_param_spec (ClutterBehaviour *behave) +{ + return behave->priv->param_spec; +} + +static void +notify_cb (GObject *object, + GParamSpec *param_spec, + ClutterBehaviour *behave) +{ + g_signal_emit (behave, + signals[SIGNAL_PROPERTY_CHANGE], + 0, + object, + param_spec); +} + +void +clutter_behaviour_set_property (ClutterBehaviour *behave, + const char *property) +{ + g_return_if_fail (behave->priv->object); + + if (behave->priv->notify_id) + { + g_signal_handler_disconnect (behave->priv->object, + behave->priv->notify_id); + behave->priv->notify_id = 0; + } + + behave->priv->param_spec = NULL; + + if (property) + { + guint signal_id; + GClosure *closure; + + behave->priv->param_spec = + g_object_class_find_property (G_OBJECT_GET_CLASS (behave->priv->object), + property); + g_return_if_fail (behave->priv->param_spec); + + signal_id = g_signal_lookup ("notify", + G_OBJECT_TYPE (behave->priv->object)); + closure = g_cclosure_new ((GCallback) notify_cb, behave, NULL); + + behave->priv->notify_id = + g_signal_connect_closure_by_id (behave->priv->object, + signal_id, + g_quark_from_string (property), + closure, + FALSE); } } diff --git a/clutter/clutter-behaviour.h b/clutter/clutter-behaviour.h index 8472275ec..f426d53cc 100644 --- a/clutter/clutter-behaviour.h +++ b/clutter/clutter-behaviour.h @@ -40,12 +40,17 @@ struct _ClutterBehaviour struct _ClutterBehaviourClass { GObjectClass parent_class; + + void (* property_change) (ClutterBehaviour *behave, + GObject *object, + GParamSpec *param_spec); }; GType clutter_behaviour_get_type (void); ClutterBehaviour* -clutter_behaviour_new (ClutterTimeline *timeline); +clutter_behaviour_new (GObject *object, + const char *property); void clutter_behaviour_apply (ClutterBehaviour *behave, ClutterActor *actor); @@ -62,11 +67,21 @@ clutter_behaviour_actors_foreach (ClutterBehaviour *behave, gpointer userdata); void -clutter_behaviour_set_timelime (ClutterBehaviour *behave, - ClutterTimeline *timeline); +clutter_behaviour_set_object (ClutterBehaviour *behave, + GObject *object); -ClutterTimeline* -clutter_behaviour_get_timelime (ClutterBehaviour *behave); +GObject* +clutter_behaviour_get_object (ClutterBehaviour *behave); + +void +clutter_behaviour_set_property (ClutterBehaviour *behave, + const char *property); + +const char* +clutter_behaviour_get_property (ClutterBehaviour *behave); + +GParamSpec* +clutter_behaviour_get_param_spec (ClutterBehaviour *behave); G_END_DECLS diff --git a/clutter/clutter-behaviours.c b/clutter/clutter-behaviours.c index 3f0b87f40..35e225689 100644 --- a/clutter/clutter-behaviours.c +++ b/clutter/clutter-behaviours.c @@ -31,7 +31,6 @@ #include "config.h" -#include "clutter-timeline.h" #include "clutter-actor.h" #include "clutter-behaviour.h" #include "clutter-behaviours.h" @@ -125,16 +124,18 @@ function line(x0, x1, y0, y1) */ ClutterBehaviour* -clutter_behaviour_path_new (ClutterTimeline *timeline, - gint x1, - gint y1, - gint x2, - gint y2) +clutter_behaviour_path_new (GObject *object, + const char *property, + gint x1, + gint y1, + gint x2, + gint y2) { ClutterBehaviourPath *behave; behave = g_object_new (CLUTTER_TYPE_BEHAVIOUR_PATH, - "timeline", timeline, + "object", object, + "property", property, NULL); return CLUTTER_BEHAVIOUR(behave); @@ -148,10 +149,8 @@ G_DEFINE_TYPE (ClutterBehaviourOpacity, \ struct ClutterBehaviourOpacityPrivate { - ClutterAlpha *alpha; - guint8 opacity_start; - guint8 opacity_end; - gulong handler_id; /* FIXME: handle in parent class ? */ + guint8 opacity_start; + guint8 opacity_end; }; #define CLUTTER_BEHAVIOUR_OPACITY_GET_PRIVATE(obj) \ @@ -159,28 +158,52 @@ struct ClutterBehaviourOpacityPrivate CLUTTER_TYPE_BEHAVIOUR_OPACITY, \ ClutterBehaviourOpacityPrivate)) +static void +clutter_behaviour_opacity_frame_foreach (ClutterActor *actor, + ClutterBehaviourOpacity *behave) +{ + guint32 alpha; + guint8 opacity; + ClutterBehaviourOpacityPrivate *priv; + ClutterBehaviour *_behave; + GParamSpec *pspec; + + priv = CLUTTER_BEHAVIOUR_OPACITY_GET_PRIVATE (behave); + _behave = CLUTTER_BEHAVIOUR (behave); + + pspec = clutter_behaviour_get_param_spec (_behave); + + g_object_get (clutter_behaviour_get_object (_behave), + pspec->name, + &alpha, + NULL); + + opacity = (alpha * (priv->opacity_end - priv->opacity_start)) + / ((GParamSpecUInt *) pspec)->maximum; + + opacity += priv->opacity_start; + + CLUTTER_DBG("alpha %i opacity %i\n", alpha, opacity); + + clutter_actor_set_opacity (actor, opacity); +} + +static void +clutter_behaviour_property_change (ClutterBehaviour *behave, + GObject *object, + GParamSpec *param_spec) +{ + g_return_if_fail (param_spec->value_type == G_TYPE_UINT); + + clutter_behaviour_actors_foreach + (behave, + (GFunc)clutter_behaviour_opacity_frame_foreach, + CLUTTER_BEHAVIOUR_OPACITY(behave)); +} + static void clutter_behaviour_opacity_dispose (GObject *object) { - ClutterBehaviourOpacity *self = CLUTTER_BEHAVIOUR_OPACITY(object); - - if (self->priv) - { - if (self->priv->handler_id) - { - g_signal_handler_disconnect - (clutter_behaviour_get_timelime (CLUTTER_BEHAVIOUR(self)), - self->priv->handler_id); - self->priv->handler_id = 0; - } - - if (self->priv->alpha) - { - g_object_unref (self->priv->alpha); - self->priv->alpha = NULL; - } - } - G_OBJECT_CLASS (clutter_behaviour_opacity_parent_class)->dispose (object); } @@ -202,13 +225,18 @@ clutter_behaviour_opacity_finalize (GObject *object) static void clutter_behaviour_opacity_class_init (ClutterBehaviourOpacityClass *klass) { - GObjectClass *object_class; + GObjectClass *object_class; + ClutterBehaviourClass *behave_class; object_class = (GObjectClass*) klass; object_class->finalize = clutter_behaviour_opacity_finalize; object_class->dispose = clutter_behaviour_opacity_dispose; + behave_class = (ClutterBehaviourClass*) klass; + + behave_class->property_change = clutter_behaviour_property_change; + g_type_class_add_private (object_class, sizeof (ClutterBehaviourOpacityPrivate)); } @@ -220,67 +248,32 @@ clutter_behaviour_opacity_init (ClutterBehaviourOpacity *self) self->priv = priv = CLUTTER_BEHAVIOUR_OPACITY_GET_PRIVATE (self); } -static void -clutter_behaviour_opacity_frame_foreach (ClutterActor *actor, - ClutterBehaviourOpacity *behave) -{ - gint32 alpha; - guint8 opacity; - ClutterBehaviourOpacityPrivate *priv; - - priv = CLUTTER_BEHAVIOUR_OPACITY_GET_PRIVATE (behave); - - alpha = clutter_alpha_get_alpha (priv->alpha); - - opacity = (alpha * (priv->opacity_end - priv->opacity_start)) - / CLUTTER_ALPHA_MAX_ALPHA; - - opacity += priv->opacity_start; - - CLUTTER_DBG("alpha %i opacity %i\n", alpha, opacity); - - clutter_actor_set_opacity (actor, opacity); -} - -static void -clutter_behaviour_opacity_frame (GObject *object, - GParamSpec *pspec, - gpointer data) -{ - ClutterBehaviourOpacity *behave; - - behave = CLUTTER_BEHAVIOUR_OPACITY(data); - - clutter_behaviour_actors_foreach - (CLUTTER_BEHAVIOUR(behave), - (GFunc)clutter_behaviour_opacity_frame_foreach, - behave); -} - ClutterBehaviour* -clutter_behaviour_opacity_new (ClutterAlpha *alpha, - guint8 opacity_start, - guint8 opacity_end) +clutter_behaviour_opacity_new (GObject *object, + const char *property, + guint8 opacity_start, + guint8 opacity_end) { ClutterBehaviourOpacity *behave; - ClutterTimeline *timeline; - - timeline = clutter_alpha_get_timeline (alpha); behave = g_object_new (CLUTTER_TYPE_BEHAVIOUR_OPACITY, - "timeline", timeline, + "object", object, + "property", property, NULL); - behave->priv->alpha = g_object_ref (alpha); - behave->priv->opacity_start = opacity_start; behave->priv->opacity_end = opacity_end; - behave->priv->handler_id - = g_signal_connect (alpha, - "notify::alpha", - G_CALLBACK (clutter_behaviour_opacity_frame), - behave); - return CLUTTER_BEHAVIOUR(behave); } + +ClutterBehaviour* +clutter_behaviour_opacity_new_from_alpha (ClutterAlpha *alpha, + guint8 opacity_start, + guint8 opacity_end) +{ + return clutter_behaviour_opacity_new (G_OBJECT (alpha), + "alpha", + opacity_start, + opacity_end); +} diff --git a/clutter/clutter-behaviours.h b/clutter/clutter-behaviours.h index 02a2d0945..8e5743efd 100644 --- a/clutter/clutter-behaviours.h +++ b/clutter/clutter-behaviours.h @@ -2,8 +2,8 @@ #define _HAVE_CLUTTER_BEHAVIOURS_H #include -#include "clutter-behaviour.h" #include "clutter-alpha.h" +#include "clutter-behaviour.h" G_BEGIN_DECLS @@ -47,11 +47,12 @@ struct _ClutterBehaviourPathClass GType clutter_behaviour_path_get_type (void); ClutterBehaviour* -clutter_behaviour_path_new (ClutterTimeline *timeline, - gint x1, - gint y1, - gint x2, - gint y2); +clutter_behaviour_path_new (GObject *object, + const char *property, + gint x1, + gint y1, + gint x2, + gint y2); /* opacity */ @@ -95,9 +96,15 @@ struct _ClutterBehaviourOpacityClass GType clutter_behaviour_opacity_get_type (void); ClutterBehaviour* -clutter_behaviour_opacity_new (ClutterAlpha *alpha, - guint8 opacity_start, - guint8 opacity_end); +clutter_behaviour_opacity_new (GObject *object, + const char *property, + guint8 opacity_start, + guint8 opacity_end); + +ClutterBehaviour* +clutter_behaviour_opacity_new_from_alpha (ClutterAlpha *alpha, + guint8 opacity_start, + guint8 opacity_end); G_END_DECLS diff --git a/clutter/clutter-marshal.list b/clutter/clutter-marshal.list index fdbbf5afd..6fb2b54e1 100644 --- a/clutter/clutter-marshal.list +++ b/clutter/clutter-marshal.list @@ -5,3 +5,4 @@ VOID:INT,INT VOID:BOXED VOID:OBJECT VOID:VOID +VOID:OBJECT,POINTER diff --git a/clutter/clutter-video-texture.h b/clutter/clutter-video-texture.h index 51f7fceac..f258a02e5 100644 --- a/clutter/clutter-video-texture.h +++ b/clutter/clutter-video-texture.h @@ -72,13 +72,6 @@ struct _ClutterVideoTextureClass { ClutterTextureClass parent_class; - /* Signals */ - void (* tag_list_available) (ClutterVideoTexture *video_texture, - GstTagList *tag_list); - void (* eos) (ClutterVideoTexture *video_texture); - void (* error) (ClutterVideoTexture *video_texture, - GError *error); - /* Future padding */ void (* _clutter_reserved1) (void); void (* _clutter_reserved2) (void); diff --git a/examples/behave.c b/examples/behave.c index 3a8f5c653..666cd8629 100644 --- a/examples/behave.c +++ b/examples/behave.c @@ -36,7 +36,7 @@ main (int argc, char *argv[]) alpha = clutter_alpha_new (timeline, CLUTTER_ALPHA_RAMP); /* Create a behaviour for that time line */ - behave = clutter_behaviour_opacity_new (alpha, 0X33 ,0xff); + behave = clutter_behaviour_opacity_new_from_alpha (alpha, 0X33, 0xff); /* Apply it to our actor */ clutter_behaviour_apply (behave, hand);