From 90ec410aef224f1ad207f70b061288cea799b48a Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 16 Apr 2007 10:25:30 +0000 Subject: [PATCH] Add ClutterBehaviourRotate Add initial implementation of a rotate behaviour; this behaviour rotates actors along a chosen axis, with a chosen direction, between two angles. Missing: API documentation and the implementation for the angle boundaries setters (double and fixed API). --- clutter/Makefile.am | 6 +- clutter/clutter-behaviour-rotate.c | 403 ++++++++++++++++++++++++++ clutter/clutter-behaviour-rotate.h | 103 +++++++ clutter/clutter.h | 3 +- doc/reference/tmpl/clutter-stage.sgml | 8 - 5 files changed, 512 insertions(+), 11 deletions(-) create mode 100644 clutter/clutter-behaviour-rotate.c create mode 100644 clutter/clutter-behaviour-rotate.h diff --git a/clutter/Makefile.am b/clutter/Makefile.am index e30e2c0ee..e21d17938 100644 --- a/clutter/Makefile.am +++ b/clutter/Makefile.am @@ -38,9 +38,10 @@ source_h = \ $(srcdir)/clutter-actor.h \ $(srcdir)/clutter-alpha.h \ $(srcdir)/clutter-behaviour.h \ + $(srcdir)/clutter-behaviour-bspline.h \ $(srcdir)/clutter-behaviour-opacity.h \ $(srcdir)/clutter-behaviour-path.h \ - $(srcdir)/clutter-behaviour-bspline.h \ + $(srcdir)/clutter-behaviour-rotate.h \ $(srcdir)/clutter-behaviour-scale.h \ $(srcdir)/clutter-clone-texture.h \ $(srcdir)/clutter-color.h \ @@ -122,9 +123,10 @@ source_c = \ clutter-alpha.c \ clutter-backend.c \ clutter-behaviour.c \ + clutter-behaviour-bspline.c \ clutter-behaviour-opacity.c \ clutter-behaviour-path.c \ - clutter-behaviour-bspline.c \ + clutter-behaviour-rotate.c \ clutter-behaviour-scale.c \ clutter-color.c \ clutter-clone-texture.c \ diff --git a/clutter/clutter-behaviour-rotate.c b/clutter/clutter-behaviour-rotate.c new file mode 100644 index 000000000..eafefdd81 --- /dev/null +++ b/clutter/clutter-behaviour-rotate.c @@ -0,0 +1,403 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2007 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-rotate + * @short_description: A behaviour class to rotate actors + * + * A #ClutterBehaviourRotate rotate actors between a starting and ending + * angle on the Z axis. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "clutter-actor.h" +#include "clutter-behaviour.h" +#include "clutter-main.h" +#include "clutter-fixed.h" +#include "clutter-behaviour-rotate.h" +#include "clutter-enum-types.h" +#include "clutter-private.h" +#include "clutter-debug.h" + +#include + +G_DEFINE_TYPE (ClutterBehaviourRotate, + clutter_behaviour_rotate, + CLUTTER_TYPE_BEHAVIOUR); + +struct _ClutterBehaviourRotatePrivate +{ + ClutterFixed angle_begin; + ClutterFixed angle_end; + + ClutterRotateAxis axis; + ClutterRotateDirection direction; +}; + +#define CLUTTER_BEHAVIOUR_ROTATE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \ + CLUTTER_TYPE_BEHAVIOUR_ROTATE, \ + ClutterBehaviourRotatePrivate)) + +enum +{ + PROP_0, + + PROP_ANGLE_BEGIN, + PROP_ANGLE_END, + PROP_AXIS, + PROP_DIRECTION +}; + +static void +rotate_actors (ClutterBehaviour *behaviour, + ClutterActor *actor, + gpointer data) +{ + ClutterBehaviourRotate *rotate_behaviour; + ClutterBehaviourRotatePrivate *priv; + + rotate_behaviour = CLUTTER_BEHAVIOUR_ROTATE (behaviour); + priv = rotate_behaviour->priv; +} + +static void +clutter_behaviour_rotate_alpha_notify (ClutterBehaviour *behaviour, + guint32 alpha_value) +{ + ClutterFixed factor, angle; + ClutterBehaviourRotate *rotate_behaviour; + ClutterBehaviourRotatePrivate *priv; + GSList *actors, *l; + + rotate_behaviour = CLUTTER_BEHAVIOUR_ROTATE (behaviour); + priv = rotate_behaviour->priv; + + factor = CLUTTER_INT_TO_FIXED (alpha_value) / CLUTTER_ALPHA_MAX_ALPHA; + angle = 0; + + switch (priv->direction) + { + case CLUTTER_ROTATE_CW: + angle = CLUTTER_FIXED_MUL (factor, (priv->angle_end - priv->angle_begin)); + angle += priv->angle_begin; + break; + case CLUTTER_ROTATE_CCW: + angle = CLUTTER_FIXED_MUL (factor, (priv->angle_begin - priv->angle_end)); + angle += priv->angle_end; + break; + } + + actors = clutter_behaviour_get_actors (behaviour); + for (l = actors; l; l = l->next) + { + ClutterActor *actor = l->data; + + switch (priv->axis) + { + case CLUTTER_X_AXIS: + clutter_actor_rotate_x (actor, + CLUTTER_FIXED_TO_FLOAT (angle), + 0, 0); + break; + case CLUTTER_Y_AXIS: + clutter_actor_rotate_y (actor, + CLUTTER_FIXED_TO_FLOAT (angle), + 0, 0); + break; + case CLUTTER_Z_AXIS: + clutter_actor_rotate_z (actor, + CLUTTER_FIXED_TO_FLOAT (angle), + 0, 0); + break; + } + } + g_slist_free (actors); +} + +static void +clutter_behaviour_rotate_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ClutterBehaviourRotatePrivate *priv; + + priv = CLUTTER_BEHAVIOUR_ROTATE (gobject)->priv; + + switch (prop_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; + } +} + +static void +clutter_behaviour_rotate_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ClutterBehaviourRotatePrivate *priv; + + priv = CLUTTER_BEHAVIOUR_ROTATE (gobject)->priv; + + switch (prop_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; + } +} + +static void +clutter_behaviour_rotate_class_init (ClutterBehaviourRotateClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + ClutterBehaviourClass *behaviour_class = CLUTTER_BEHAVIOUR_CLASS (klass); + + gobject_class->set_property = clutter_behaviour_rotate_set_property; + gobject_class->get_property = clutter_behaviour_rotate_get_property; + + behaviour_class->alpha_notify = clutter_behaviour_rotate_alpha_notify; + + g_object_class_install_property (gobject_class, + PROP_ANGLE_BEGIN, + g_param_spec_double ("angle-begin", + "Angle Begin", + "Initial angle", + 0.0, 359.0, 0.0, + CLUTTER_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_ANGLE_END, + g_param_spec_double ("angle-end", + "Angle End", + "Final angle", + 0.0, 359.0, 359.0, + CLUTTER_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_AXIS, + g_param_spec_enum ("axis", + "Axis", + "Axis of rotation", + CLUTTER_TYPE_ROTATE_AXIS, + CLUTTER_Z_AXIS, + CLUTTER_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_DIRECTION, + g_param_spec_enum ("direction", + "Direction", + "Direction of rotation", + CLUTTER_TYPE_ROTATE_DIRECTION, + CLUTTER_ROTATE_CW, + CLUTTER_PARAM_READWRITE)); +} + +static void +clutter_behaviour_rotate_init (ClutterBehaviourRotate *rotate) +{ + ClutterBehaviourRotatePrivate *priv; + + rotate->priv = priv = CLUTTER_BEHAVIOUR_ROTATE_GET_PRIVATE (rotate); + + priv->angle_begin = CLUTTER_FLOAT_TO_FIXED (0.0); + priv->angle_end = CLUTTER_FLOAT_TO_FIXED (359.0); + priv->axis = CLUTTER_Z_AXIS; + priv->direction = CLUTTER_ROTATE_CW; +} + +ClutterBehaviour * +clutter_behaviour_rotate_new (ClutterAlpha *alpha, + ClutterRotateAxis axis, + ClutterRotateDirection direction, + gdouble angle_begin, + gdouble angle_end) +{ + return clutter_behaviour_rotate_newx (alpha, axis, direction, + CLUTTER_FLOAT_TO_FIXED (angle_begin), + CLUTTER_FLOAT_TO_FIXED (angle_end)); +} + +ClutterBehaviour * +clutter_behaviour_rotate_newx (ClutterAlpha *alpha, + ClutterRotateAxis axis, + ClutterRotateDirection direction, + ClutterFixed angle_begin, + ClutterFixed angle_end) +{ + ClutterBehaviour *retval; + ClutterBehaviourRotatePrivate *priv; + + retval = g_object_new (CLUTTER_TYPE_BEHAVIOUR_ROTATE, + "alpha", alpha, + "axis", axis, + "direction", direction, + NULL); + + priv = CLUTTER_BEHAVIOUR_ROTATE_GET_PRIVATE (retval); + priv->angle_begin = angle_begin; + priv->angle_end = angle_end; + + return retval; +} + +ClutterRotateAxis +clutter_behaviour_rotate_get_axis (ClutterBehaviourRotate *rotate) +{ + g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR_ROTATE (rotate), CLUTTER_Z_AXIS); + + return rotate->priv->axis; +} + +void +clutter_behaviour_rotate_set_axis (ClutterBehaviourRotate *rotate, + ClutterRotateAxis axis) +{ + ClutterBehaviourRotatePrivate *priv; + + g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ROTATE (rotate)); + + priv = rotate->priv; + + if (priv->axis != axis) + { + g_object_ref (rotate); + + priv->axis = axis; + + g_object_notify (G_OBJECT (rotate), "axis"); + g_object_unref (rotate); + } +} + +ClutterRotateDirection +clutter_behaviour_rotate_get_direction (ClutterBehaviourRotate *rotate) +{ + g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR_ROTATE (rotate), + CLUTTER_ROTATE_CW); + + return rotate->priv->direction; +} + +void +clutter_behaviour_rotate_set_direction (ClutterBehaviourRotate *rotate, + ClutterRotateDirection direction) +{ + ClutterBehaviourRotatePrivate *priv; + + g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ROTATE (rotate)); + + priv = rotate->priv; + + if (priv->direction != direction) + { + g_object_ref (rotate); + + priv->direction = direction; + + g_object_notify (G_OBJECT (rotate), "direction"); + g_object_unref (rotate); + } +} + +void +clutter_behaviour_rotate_get_bounds (ClutterBehaviourRotate *rotate, + gdouble *angle_begin, + gdouble *angle_end) +{ + ClutterBehaviourRotatePrivate *priv; + + g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ROTATE (rotate)); + + priv = rotate->priv; + + if (angle_begin) + *angle_begin = CLUTTER_FIXED_TO_DOUBLE (priv->angle_begin); + + if (angle_end) + *angle_end = CLUTTER_FIXED_TO_DOUBLE (priv->angle_end); +} + +void +clutter_behaviour_rotate_set_bounds (ClutterBehaviourRotate *rotate, + gdouble angle_begin, + gdouble angle_end) +{ +#if 0 + ClutterBehaviourRotatePrivate *priv; + + g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ROTATE (rotate)); + + priv = rotate->priv; + + g_object_ref (rotate); + g_object_freeze_notify (G_OBJECT (rotate)); + + g_object_thaw_notify (G_OBJECT (rotate)); + g_object_unref (rotate); +#endif +} + +void +clutter_behaviour_rotate_get_boundsx (ClutterBehaviourRotate *rotate, + ClutterFixed *angle_begin, + ClutterFixed *angle_end) +{ + ClutterBehaviourRotatePrivate *priv; + + g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ROTATE (rotate)); + + priv = rotate->priv; + + if (angle_begin); + *angle_begin = priv->angle_begin; + + if (angle_end) + *angle_end = priv->angle_end; +} + +void +clutter_behaviour_rotate_set_boundsx (ClutterBehaviourRotate *rotate, + ClutterFixed angle_begin, + ClutterFixed angle_end) +{ +#if 0 + ClutterBehaviourRotatePrivate *priv; + + g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ROTATE (rotate)); + + priv = rotate->priv; + + g_object_ref (rotate); + g_object_freeze_notify (G_OBJECT (rotate)); + + g_object_thaw_notify (G_OBJECT (rotate)); + g_object_unref (rotate); +#endif +} diff --git a/clutter/clutter-behaviour-rotate.h b/clutter/clutter-behaviour-rotate.h new file mode 100644 index 000000000..ecfe40d4e --- /dev/null +++ b/clutter/clutter-behaviour-rotate.h @@ -0,0 +1,103 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Matthew Allum + * + * Copyright (C) 2007 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. + */ + +#ifndef __CLUTTER_BEHAVIOUR_ROTATE_H__ +#define __CLUTTER_BEHAVIOUR_ROTATE_H__ + +#include +#include + +G_BEGIN_DECLS + +#define CLUTTER_TYPE_BEHAVIOUR_ROTATE (clutter_behaviour_rotate_get_type ()) +#define CLUTTER_BEHAVIOUR_ROTATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BEHAVIOUR_ROTATE, ClutterBehaviourRotate)) +#define CLUTTER_IS_BEHAVIOUR_ROTATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BEHAVIOUR_ROTATE)) +#define CLUTTER_BEHAVIOUR_ROTATE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BEHAVIOUR_ROTATE, ClutterBehaviourRotateClass)) +#define CLUTTER_IS_BEHAVIOUR_ROTATE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BEHAVIOUR_ROTATE)) +#define CLUTTER_BEHAVIOUR_ROTATE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((klass), CLUTTER_TYPE_BEHAVIOUR_ROTATE, ClutterBehaviourRotateClass)) + +typedef enum { /*< prefix=CLUTTER >*/ + CLUTTER_X_AXIS, + CLUTTER_Y_AXIS, + CLUTTER_Z_AXIS +} ClutterRotateAxis; + +typedef enum { /*< prefix=CLUTTER_ROTATE >*/ + CLUTTER_ROTATE_CW, + CLUTTER_ROTATE_CCW +} ClutterRotateDirection; + +typedef struct _ClutterBehaviourRotate ClutterBehaviourRotate; +typedef struct _ClutterBehaviourRotatePrivate ClutterBehaviourRotatePrivate; +typedef struct _ClutterBehaviourRotateClass ClutterBehaviourRotateClass; + +struct _ClutterBehaviourRotate +{ + ClutterBehaviour parent_instance; + + /*< private >*/ + ClutterBehaviourRotatePrivate *priv; +}; + +struct _ClutterBehaviourRotateClass +{ + ClutterBehaviourClass parent_class; +}; + +GType clutter_behaviour_rotate_get_type (void) G_GNUC_CONST; + +ClutterBehaviour *clutter_behaviour_rotate_new (ClutterAlpha *alpha, + ClutterRotateAxis axis, + ClutterRotateDirection direction, + gdouble angle_begin, + gdouble angle_end); +ClutterBehaviour *clutter_behaviour_rotate_newx (ClutterAlpha *alpha, + ClutterRotateAxis axis, + ClutterRotateDirection direction, + ClutterFixed angle_begin, + ClutterFixed angle_end); + +ClutterRotateAxis clutter_behaviour_rotate_get_axis (ClutterBehaviourRotate *rotate); +void clutter_behaviour_rotate_set_axis (ClutterBehaviourRotate *rotate, + ClutterRotateAxis axis); +ClutterRotateDirection clutter_behaviour_rotate_get_direction (ClutterBehaviourRotate *rotate); +void clutter_behaviour_rotate_set_direction (ClutterBehaviourRotate *rotate, + ClutterRotateDirection direction); +void clutter_behaviour_rotate_get_bounds (ClutterBehaviourRotate *rotate, + gdouble *angle_begin, + gdouble *angle_end); +void clutter_behaviour_rotate_set_bounds (ClutterBehaviourRotate *rotate, + gdouble angle_begin, + gdouble angle_end); +void clutter_behaviour_rotate_get_boundsx (ClutterBehaviourRotate *rotate, + ClutterFixed *angle_begin, + ClutterFixed *angle_end); +void clutter_behaviour_rotate_set_boundsx (ClutterBehaviourRotate *rotate, + ClutterFixed angle_begin, + ClutterFixed angle_end); + +G_END_DECLS + +#endif /* __CLUTTER_BEHAVIOUR_ROTATE_H__ */ diff --git a/clutter/clutter.h b/clutter/clutter.h index 170ab823d..91de7ad72 100644 --- a/clutter/clutter.h +++ b/clutter/clutter.h @@ -33,9 +33,10 @@ #include "clutter-event.h" #include "clutter-timeline.h" #include "clutter-behaviour.h" +#include "clutter-behaviour-bspline.h" #include "clutter-behaviour-opacity.h" #include "clutter-behaviour-path.h" -#include "clutter-behaviour-bspline.h" +#include "clutter-behaviour-rotate.h" #include "clutter-behaviour-scale.h" #include "clutter-stage.h" #include "clutter-actor.h" diff --git a/doc/reference/tmpl/clutter-stage.sgml b/doc/reference/tmpl/clutter-stage.sgml index d4898fc30..788b4f6c2 100644 --- a/doc/reference/tmpl/clutter-stage.sgml +++ b/doc/reference/tmpl/clutter-stage.sgml @@ -257,11 +257,3 @@ Macro evaluating to the height of the #ClutterStage @Returns: - - - - - -@stage: - -