diff --git a/ChangeLog b/ChangeLog index d9b9f044b..c3158e615 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2006-08-14 Matthew Allum + + * clutter/Makefile.am: + * clutter/clutter-behaviour.c: + * clutter/clutter-behaviour.h: + * clutter/clutter-behaviours.c: + * clutter/clutter-behaviours.h: + * clutter/clutter-timeline.c: + * clutter/clutter-timeline.h: + Add very initial new behaviour functionality. + + * clutter/clutter-stage.c: + * clutter/clutter-main.c: + * clutter/clutter-actor.c: + Improve clipping using stencil test rather than scissor check. + ( Should now handle rotated clips etc ). + + * clutter/clutter-group.c: (clutter_group_paint): + Fix typo on position check. + 2006-08-07 Matthew Allum * clutter/clutter-video-texture.c: (lay_pipeline): diff --git a/clutter/Makefile.am b/clutter/Makefile.am index 1fcd58a13..b679ef653 100644 --- a/clutter/Makefile.am +++ b/clutter/Makefile.am @@ -21,6 +21,8 @@ source_h = \ $(srcdir)/clutter-clone-texture.h \ $(srcdir)/clutter-video-texture.h \ $(srcdir)/clutter-label.h \ + $(srcdir)/clutter-behaviour.h \ + $(srcdir)/clutter-behaviours.h \ $(srcdir)/clutter-main.h clutter-marshal.h: clutter-marshal.list @@ -83,6 +85,8 @@ source_c = clutter-main.c \ clutter-video-texture.c \ clutter-label.c \ clutter-actor.c \ + clutter-behaviour.c \ + clutter-behaviours.c \ clutter-enum-types.c source_h_priv = clutter-private.h diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index 4c2810475..fadaac977 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -253,6 +253,7 @@ clutter_actor_paint (ClutterActor *self) klass = CLUTTER_ACTOR_GET_CLASS (self); +#if 0 if (self->priv->has_clip) { ClutterGeometry *clip = &(self->priv->clip); @@ -276,6 +277,7 @@ clutter_actor_paint (ClutterActor *self) clip->width, clip->height); } +#endif glPushMatrix(); @@ -325,13 +327,39 @@ clutter_actor_paint (ClutterActor *self) if (self->priv->z) glTranslatef ( 0.0, 0.0, (float)self->priv->z); + if (self->priv->has_clip) + { + ClutterGeometry *clip = &(self->priv->clip); + + glClearStencil (0.0f); + glEnable (GL_STENCIL_TEST); + + glStencilFunc (GL_NEVER, 0x1, 0x1); + glStencilOp (GL_INCR, GL_INCR, GL_INCR); + glColor3f(1.0f, 1.0f, 1.0f); + + /* render clip geomerty */ + glRecti (self->priv->coords.x1 + clip->x, + self->priv->coords.y1 + clip->y, + self->priv->coords.x1 + clip->x + clip->width, + self->priv->coords.y1 + clip->y + clip->height); + + glStencilFunc (GL_EQUAL, 0x1, 0x1); + glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); + } + if (klass->paint) (klass->paint) (self); - glPopMatrix(); - if (self->priv->has_clip) - glDisable (GL_SCISSOR_TEST); + { + glDisable (GL_STENCIL_TEST); +#if 0 + glDisable (GL_SCISSOR_TEST); +#endif + } + + glPopMatrix(); } /** diff --git a/clutter/clutter-behaviour.c b/clutter/clutter-behaviour.c new file mode 100644 index 000000000..4d1c08abc --- /dev/null +++ b/clutter/clutter-behaviour.c @@ -0,0 +1,239 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION:clutter-behaviour + * @short_description: Class for providing behaviours to actors + * + */ + +#include "config.h" + +#include "clutter-behaviour.h" +#include "clutter-enum-types.h" +#include "clutter-private.h" /* for DBG */ +#include "clutter-timeline.h" + +G_DEFINE_TYPE (ClutterBehaviour, clutter_behaviour, G_TYPE_OBJECT); + +struct ClutterBehaviourPrivate +{ + ClutterTimeline *timeline; + GSList *actors; +}; + +enum +{ + PROP_0, + PROP_TIMELINE +}; + +#define CLUTTER_BEHAVIOUR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \ + CLUTTER_TYPE_BEHAVIOUR, \ + ClutterBehaviourPrivate)) + +static void +clutter_behaviour_dispose (GObject *object) +{ + ClutterBehaviour *self = CLUTTER_BEHAVIOUR(object); + + if (self->priv) + { + /* FIXME: remove all actors */ + } + + G_OBJECT_CLASS (clutter_behaviour_parent_class)->dispose (object); +} + +static void +clutter_behaviour_finalize (GObject *object) +{ + ClutterBehaviour *self = CLUTTER_BEHAVIOUR(object); + + if (self->priv) + { + g_free(self->priv); + self->priv = NULL; + } + + G_OBJECT_CLASS (clutter_behaviour_parent_class)->finalize (object); +} + +static void +clutter_behaviour_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ClutterBehaviour *behaviour; + ClutterBehaviourPrivate *priv; + + 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)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +clutter_behaviour_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ClutterBehaviour *behaviour; + ClutterBehaviourPrivate *priv; + + behaviour = CLUTTER_BEHAVIOUR(object); + priv = CLUTTER_BEHAVIOUR_GET_PRIVATE(behaviour); + + switch (prop_id) + { + case PROP_TIMELINE: + g_value_set_object (value, priv->timeline); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + +static void +clutter_behaviour_class_init (ClutterBehaviourClass *klass) +{ + GObjectClass *object_class; + + 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; + + g_object_class_install_property + (object_class, PROP_TIMELINE, + g_param_spec_object ("timeline", + "Timeline", + "Timeline source for behaviour", + CLUTTER_TYPE_TIMELINE, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE)); + + g_type_class_add_private (object_class, sizeof (ClutterBehaviourPrivate)); +} + +static void +clutter_behaviour_init (ClutterBehaviour *self) +{ + ClutterBehaviourPrivate *priv; + + self->priv = priv = CLUTTER_BEHAVIOUR_GET_PRIVATE (self); + +} + +ClutterBehaviour* +clutter_behaviour_new (ClutterTimeline *timeline) +{ + ClutterBehaviour *behave; + + behave = g_object_new (CLUTTER_TYPE_BEHAVIOUR, + "timeline", timeline, + NULL); + + return behave; +} + +void +clutter_behaviour_apply (ClutterBehaviour *behave, ClutterActor *actor) +{ + g_return_if_fail (actor != NULL); + + if (g_slist_find (behave->priv->actors, (gconstpointer)actor)) + return; + + g_object_ref (actor); + behave->priv->actors = g_slist_append (behave->priv->actors, actor); +} + +void +clutter_behaviour_remove (ClutterBehaviour *behave, ClutterActor *actor) +{ + g_return_if_fail (actor != NULL); + + if (g_slist_find (behave->priv->actors, (gconstpointer)actor)) + { + g_object_unref (actor); + behave->priv->actors = g_slist_remove (behave->priv->actors, actor); + } +} + +void +clutter_behaviour_remove_all (ClutterBehaviour *behave) +{ + /* tofix */ +} + +void +clutter_behaviour_actors_foreach (ClutterBehaviour *behave, + GFunc func, + gpointer userdata) +{ + g_slist_foreach (behave->priv->actors, func, userdata); +} + +ClutterTimeline* +clutter_behaviour_get_timelime (ClutterBehaviour *behave) +{ + return behave->priv->timeline; +} + +void +clutter_behaviour_set_timelime (ClutterBehaviour *behave, + ClutterTimeline *timeline) +{ + ClutterBehaviourPrivate *priv; + + priv = CLUTTER_BEHAVIOUR_GET_PRIVATE(behave); + + if (priv->timeline) + { + g_object_unref(priv->timeline); + priv->timeline = NULL; + } + + if (behave) + { + g_object_ref(timeline); + priv->timeline = timeline; + } +} diff --git a/clutter/clutter-behaviour.h b/clutter/clutter-behaviour.h new file mode 100644 index 000000000..a1bc11f22 --- /dev/null +++ b/clutter/clutter-behaviour.h @@ -0,0 +1,75 @@ +#ifndef _HAVE_CLUTTER_BEHAVIOUR_H +#define _HAVE_CLUTTER_BEHAVIOUR_H + +#include + +#include "clutter.h" + +G_BEGIN_DECLS + +#define CLUTTER_TYPE_BEHAVIOUR clutter_behaviour_get_type() + +#define CLUTTER_BEHAVIOUR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + CLUTTER_TYPE_BEHAVIOUR, ClutterBehaviour)) + +#define CLUTTER_BEHAVIOUR_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + CLUTTER_TYPE_BEHAVIOUR, ClutterBehaviourClass)) + +#define CLUTTER_IS_BEHAVIOUR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + CLUTTER_TYPE_BEHAVIOUR)) + +#define CLUTTER_IS_BEHAVIOUR_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + CLUTTER_TYPE_BEHAVIOUR)) + +#define CLUTTER_BEHAVIOUR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + CLUTTER_TYPE_BEHAVIOUR, ClutterBehaviourClass)) + +typedef struct _ClutterBehaviour ClutterBehaviour; +typedef struct ClutterBehaviourPrivate ClutterBehaviourPrivate; +typedef struct _ClutterBehaviourClass ClutterBehaviourClass; + +struct _ClutterBehaviour +{ + ClutterTimeline parent; + ClutterBehaviourPrivate *priv; +}; + +struct _ClutterBehaviourClass +{ + ClutterTimelineClass parent_class; +}; + +GType clutter_behaviour_get_type (void); + +ClutterBehaviour* +clutter_behaviour_new (ClutterTimeline *timeline); + +void +clutter_behaviour_apply (ClutterBehaviour *behave, ClutterActor *actor); + +void +clutter_behaviour_remove (ClutterBehaviour *behave, ClutterActor *actor); + +void +clutter_behaviour_remove_all (ClutterBehaviour *behave); + +void +clutter_behaviour_actors_foreach (ClutterBehaviour *behave, + GFunc func, + gpointer userdata); + +void +clutter_behaviour_set_timelime (ClutterBehaviour *behave, + ClutterTimeline *timeline); + +ClutterTimeline* +clutter_behaviour_get_timelime (ClutterBehaviour *behave); + +G_END_DECLS + +#endif diff --git a/clutter/clutter-behaviours.c b/clutter/clutter-behaviours.c new file mode 100644 index 000000000..dd7ea7aea --- /dev/null +++ b/clutter/clutter-behaviours.c @@ -0,0 +1,246 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2006 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION:clutter-behaviour + * @short_description: Class for providing behaviours to actors + * + */ + +#include "config.h" + +#include "clutter-behaviours.h" +#include "clutter-enum-types.h" +#include "clutter-private.h" /* for DBG */ +#include "clutter-timeline.h" + +G_DEFINE_TYPE (ClutterBehaviourPath, \ + clutter_behaviour_path, \ + CLUTTER_TYPE_BEHAVIOUR); + +struct ClutterBehaviourPathPrivate +{ + gint x1, y1, x2, y2; +}; + +#define CLUTTER_BEHAVIOUR_PATH_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \ + CLUTTER_TYPE_BEHAVIOUR_PATH, \ + ClutterBehaviourPathPrivate)) + +static void +clutter_behaviour_path_dispose (GObject *object) +{ + ClutterBehaviourPath *self = CLUTTER_BEHAVIOUR_PATH(object); + + if (self->priv) + { + /* FIXME: remove all actors */ + } + + G_OBJECT_CLASS (clutter_behaviour_path_parent_class)->dispose (object); +} + +static void +clutter_behaviour_path_finalize (GObject *object) +{ + ClutterBehaviourPath *self = CLUTTER_BEHAVIOUR_PATH(object); + + if (self->priv) + { + g_free(self->priv); + self->priv = NULL; + } + + G_OBJECT_CLASS (clutter_behaviour_path_parent_class)->finalize (object); +} + + +static void +clutter_behaviour_path_class_init (ClutterBehaviourPathClass *klass) +{ + GObjectClass *object_class; + + object_class = (GObjectClass*) klass; + + object_class->finalize = clutter_behaviour_path_finalize; + object_class->dispose = clutter_behaviour_path_dispose; + + g_type_class_add_private (object_class, sizeof (ClutterBehaviourPathPrivate)); +} + +static void +clutter_behaviour_path_init (ClutterBehaviourPath *self) +{ + ClutterBehaviourPathPrivate *priv; + + self->priv = priv = CLUTTER_BEHAVIOUR_PATH_GET_PRIVATE (self); +} + +ClutterBehaviour* +clutter_behaviour_path_new (ClutterTimeline *timeline, + gint x1, + gint y1, + gint x2, + gint y2) +{ + ClutterBehaviourPath *behave; + + behave = g_object_new (CLUTTER_TYPE_BEHAVIOUR_PATH, + "timeline", timeline, + NULL); + + return CLUTTER_BEHAVIOUR(behave); +} + +/* opacity */ + +G_DEFINE_TYPE (ClutterBehaviourOpacity, \ + clutter_behaviour_opacity, \ + CLUTTER_TYPE_BEHAVIOUR); + +struct ClutterBehaviourOpacityPrivate +{ + guint8 opacity_start; + guint8 opacity_end; + gulong handler_id; /* FIXME: handle in parent class ? */ +}; + +#define CLUTTER_BEHAVIOUR_OPACITY_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \ + CLUTTER_TYPE_BEHAVIOUR_OPACITY, \ + ClutterBehaviourOpacityPrivate)) + +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); + } + + G_OBJECT_CLASS (clutter_behaviour_opacity_parent_class)->dispose (object); +} + +static void +clutter_behaviour_opacity_finalize (GObject *object) +{ + ClutterBehaviourOpacity *self = CLUTTER_BEHAVIOUR_OPACITY(object); + + if (self->priv) + { + g_free(self->priv); + self->priv = NULL; + } + + G_OBJECT_CLASS (clutter_behaviour_opacity_parent_class)->finalize (object); +} + + +static void +clutter_behaviour_opacity_class_init (ClutterBehaviourOpacityClass *klass) +{ + GObjectClass *object_class; + + object_class = (GObjectClass*) klass; + + object_class->finalize = clutter_behaviour_opacity_finalize; + object_class->dispose = clutter_behaviour_opacity_dispose; + + g_type_class_add_private (object_class, sizeof (ClutterBehaviourOpacityPrivate)); +} + +static void +clutter_behaviour_opacity_init (ClutterBehaviourOpacity *self) +{ + ClutterBehaviourOpacityPrivate *priv; + + 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_timeline_get_alpha + (clutter_behaviour_get_timelime (CLUTTER_BEHAVIOUR(behave))); + + opacity = (alpha * (priv->opacity_end - priv->opacity_start)) + / CLUTTER_TIMELINE_MAX_ALPHA; + + opacity += priv->opacity_start; + + clutter_actor_set_opacity (actor, opacity); +} + +static void +clutter_behaviour_opacity_frame (ClutterTimeline *timelime, + gint frame_num, + gpointer data) +{ + ClutterBehaviourOpacity *behave; + + behave = CLUTTER_BEHAVIOUR_OPACITY(data); + + clutter_behaviour_actors_foreach + (CLUTTER_BEHAVIOUR(behave), + (GFunc)clutter_behaviour_opacity_frame_foreach, + GINT_TO_POINTER(frame_num)); +} + +ClutterBehaviour* +clutter_behaviour_opacity_new (ClutterTimeline *timeline, + guint8 opacity_start, + guint8 opacity_end) +{ + ClutterBehaviourOpacity *behave; + + behave = g_object_new (CLUTTER_TYPE_BEHAVIOUR_OPACITY, + "timeline", timeline, + NULL); + + behave->priv->opacity_start = opacity_start; + behave->priv->opacity_end = opacity_end; + + /* FIXME: Should be part of regular behave functionality */ + behave->priv->handler_id + = g_signal_connect (timeline, + "new-frame", + G_CALLBACK (clutter_behaviour_opacity_frame), + behave); + + return CLUTTER_BEHAVIOUR(behave); +} diff --git a/clutter/clutter-behaviours.h b/clutter/clutter-behaviours.h new file mode 100644 index 000000000..ff8184ff7 --- /dev/null +++ b/clutter/clutter-behaviours.h @@ -0,0 +1,103 @@ +#ifndef _HAVE_CLUTTER_BEHAVIOURS_H +#define _HAVE_CLUTTER_BEHAVIOURS_H + +#include +#include "clutter-behaviour.h" + +G_BEGIN_DECLS + +#define CLUTTER_TYPE_BEHAVIOUR_PATH clutter_behaviour_path_get_type() + +#define CLUTTER_BEHAVIOUR_PATH(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + CLUTTER_TYPE_BEHAVIOUR_PATH, ClutterBehaviourPath)) + +#define CLUTTER_BEHAVIOUR_PATH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + CLUTTER_TYPE_BEHAVIOUR_PATH, ClutterBehaviourPathClass)) + +#define CLUTTER_IS_BEHAVIOUR_PATH(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + CLUTTER_TYPE_BEHAVIOUR_PATH)) + +#define CLUTTER_IS_BEHAVIOUR_PATH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + CLUTTER_TYPE_BEHAVIOUR_PATH)) + +#define CLUTTER_BEHAVIOUR_PATH_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + CLUTTER_TYPE_BEHAVIOUR_PATH, ClutterBehaviourPathClass)) + +typedef struct _ClutterBehaviourPath ClutterBehaviourPath; +typedef struct ClutterBehaviourPathPrivate ClutterBehaviourPathPrivate; +typedef struct _ClutterBehaviourPathClass ClutterBehaviourPathClass; + +struct _ClutterBehaviourPath +{ + ClutterBehaviour parent; + ClutterBehaviourPathPrivate *priv; +}; + +struct _ClutterBehaviourPathClass +{ + ClutterBehaviourClass parent_class; +}; + +GType clutter_behaviour_path_get_type (void); + +ClutterBehaviour* +clutter_behaviour_path_new (ClutterTimeline *timeline, + gint x1, + gint y1, + gint x2, + gint y2); + +/* opacity */ + +#define CLUTTER_TYPE_BEHAVIOUR_OPACITY clutter_behaviour_opacity_get_type() + +#define CLUTTER_BEHAVIOUR_OPACITY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + CLUTTER_TYPE_BEHAVIOUR_OPACITY, ClutterBehaviourOpacity)) + +#define CLUTTER_BEHAVIOUR_OPACITY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + CLUTTER_TYPE_BEHAVIOUR_OPACITY, ClutterBehaviourOpacityClass)) + +#define CLUTTER_IS_BEHAVIOUR_OPACITY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + CLUTTER_TYPE_BEHAVIOUR_OPACITY)) + +#define CLUTTER_IS_BEHAVIOUR_OPACITY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + CLUTTER_TYPE_BEHAVIOUR_OPACITY)) + +#define CLUTTER_BEHAVIOUR_OPACITY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + CLUTTER_TYPE_BEHAVIOUR_OPACITY, ClutterBehaviourOpacityClass)) + +typedef struct _ClutterBehaviourOpacity ClutterBehaviourOpacity; +typedef struct ClutterBehaviourOpacityPrivate ClutterBehaviourOpacityPrivate; +typedef struct _ClutterBehaviourOpacityClass ClutterBehaviourOpacityClass; + +struct _ClutterBehaviourOpacity +{ + ClutterBehaviour parent; + ClutterBehaviourOpacityPrivate *priv; +}; + +struct _ClutterBehaviourOpacityClass +{ + ClutterBehaviourClass parent_class; +}; + +GType clutter_behaviour_opacity_get_type (void); + +ClutterBehaviour* +clutter_behaviour_opacity_new (ClutterTimeline *timeline, + guint8 opacity_start, + guint8 opacity_end); + +G_END_DECLS + +#endif diff --git a/clutter/clutter-group.c b/clutter/clutter-group.c index 3a2952455..a230c9b27 100644 --- a/clutter/clutter-group.c +++ b/clutter/clutter-group.c @@ -75,7 +75,7 @@ clutter_group_paint (ClutterActor *actor) clutter_actor_get_geometry (actor, &geom); - if (geom.x != 0 && geom.y != 0) + if (geom.x != 0 || geom.y != 0) glTranslatef(geom.x, geom.y, 0.0); } diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index 3b573cfb1..5e20c0b8f 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -285,7 +285,7 @@ clutter_redraw (void) ((float) stage_color.green / 0xff * 1.0), ((float) stage_color.blue / 0xff * 1.0), 0.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c index ba71e08f7..984a9bfb8 100644 --- a/clutter/clutter-stage.c +++ b/clutter/clutter-stage.c @@ -381,6 +381,7 @@ clutter_stage_realize (ClutterActor *actor) GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, + GLX_STENCIL_SIZE, 1, 0 }; diff --git a/clutter/clutter-timeline.c b/clutter/clutter-timeline.c index 2449263ed..abeb5b7a7 100644 --- a/clutter/clutter-timeline.c +++ b/clutter/clutter-timeline.c @@ -44,14 +44,17 @@ G_DEFINE_TYPE (ClutterTimeline, clutter_timeline, G_TYPE_OBJECT); struct ClutterTimelinePrivate { - guint timeout_id; - guint fps; - guint nframes; - guint current_frame_num; - gulong last_frame_msecs; - gulong start_frame_secs; + guint timeout_id; + guint fps; + guint nframes; + guint current_frame_num; + gulong last_frame_msecs; + gulong start_frame_secs; + + guint32 alpha; + ClutterTimelineAlphaFunc alpha_func; - guint loop : 1; + guint loop : 1; }; enum @@ -59,7 +62,8 @@ enum PROP_0, PROP_FPS, PROP_NFRAMES, - PROP_LOOP + PROP_LOOP, + PROP_ALPHA }; enum @@ -73,6 +77,17 @@ enum static int timeline_signals[LAST_SIGNAL] = { 0 }; +/* Alpha funcs */ + +guint32 +clutter_timeline_alpha_ramp_inc_func (ClutterTimeline *timeline) +{ + return (timeline->priv->current_frame_num * CLUTTER_TIMELINE_MAX_ALPHA) + / timeline->priv->nframes; +} + +/* Object */ + static void clutter_timeline_set_property (GObject *object, guint prop_id, @@ -93,6 +108,9 @@ clutter_timeline_set_property (GObject *object, case PROP_NFRAMES: priv->nframes = g_value_get_int (value); break; + case PROP_ALPHA: + priv->alpha = g_value_get_int (value); + break; case PROP_LOOP: priv->loop = g_value_get_boolean (value); break; @@ -182,6 +200,16 @@ clutter_timeline_class_init (ClutterTimelineClass *klass) 50, G_PARAM_CONSTRUCT | G_PARAM_READWRITE)); + g_object_class_install_property + (object_class, PROP_ALPHA, + g_param_spec_int ("alpha", + "Alpha value for timeline", + "Alpha value for timeline", + 0, + CLUTTER_TIMELINE_MAX_ALPHA, + 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_NFRAMES, g_param_spec_int ("num-frames", @@ -190,7 +218,7 @@ clutter_timeline_class_init (ClutterTimelineClass *klass) 0, G_MAXINT, 0, - G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); + G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_LOOP, @@ -298,6 +326,10 @@ timeline_timeout_func (gpointer data) /* Advance frames */ priv->current_frame_num += nframes;; + /* Update alpha value */ + if (priv->alpha_func) + priv->alpha = priv->alpha_func(timeline); + /* Handle loop or stop */ if (priv->current_frame_num > priv->nframes) { @@ -545,6 +577,21 @@ clutter_timeline_is_playing (ClutterTimeline *timeline) return (timeline->priv->timeout_id != 0); } +/** + * clutter_timeline_get_alpha: + * @timeline: A #ClutterTimeline + * + * Query the timelines current alpha value. + * + * Return Value: The current alpha value for the timeline + */ +gint32 +clutter_timeline_get_alpha (ClutterTimeline *timeline) +{ + g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), FALSE); + + return timeline->priv->alpha; +} /** * clutter_timeline_new: diff --git a/clutter/clutter-timeline.h b/clutter/clutter-timeline.h index 84faadeeb..8d812c6a1 100644 --- a/clutter/clutter-timeline.h +++ b/clutter/clutter-timeline.h @@ -58,6 +58,8 @@ typedef struct _ClutterTimeline ClutterTimeline; typedef struct _ClutterTimelineClass ClutterTimelineClass; typedef struct ClutterTimelinePrivate ClutterTimelinePrivate; +typedef guint32 (*ClutterTimelineAlphaFunc) (ClutterTimeline *timeline); + struct _ClutterTimeline { GObject parent; @@ -82,6 +84,8 @@ struct _ClutterTimelineClass void (*_clutter_timeline_5) (void); }; +#define CLUTTER_TIMELINE_MAX_ALPHA 0xffff + GType clutter_timeline_get_type (void); ClutterTimeline* @@ -123,6 +127,18 @@ clutter_timeline_get_n_frames (ClutterTimeline *timeline); gboolean clutter_timeline_is_playing (ClutterTimeline *timeline); +/* Alpha funcs */ + +gint32 +clutter_timeline_get_alpha (ClutterTimeline *timeline); + +guint32 +clutter_timeline_alpha_ramp_inc_func (ClutterTimeline *timeline); + + + +#define CLUTTER_ALPHA_RAMP_INC clutter_timeline_alpha_ramp_inc_func; + G_END_DECLS #endif