From 6b2cbb990835f366060e59344db9019d271b2a89 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 25 Oct 2010 15:46:04 +0100 Subject: [PATCH] Add ClutterPathConstraint ClutterPathConstraint is a simple Constraint implementation that modifies the allocation of the Actor to which is has been applied using a progress value and a ClutterPath. --- clutter/Makefile.am | 2 + clutter/clutter-path-constraint.c | 287 ++++++++++++++++++++++++++++++ clutter/clutter-path-constraint.h | 65 +++++++ clutter/clutter.h | 1 + 4 files changed, 355 insertions(+) create mode 100644 clutter/clutter-path-constraint.c create mode 100644 clutter/clutter-path-constraint.h diff --git a/clutter/Makefile.am b/clutter/Makefile.am index b26df5222..2fa4bef40 100644 --- a/clutter/Makefile.am +++ b/clutter/Makefile.am @@ -114,6 +114,7 @@ source_h = \ $(srcdir)/clutter-model.h \ $(srcdir)/clutter-offscreen-effect.h \ $(srcdir)/clutter-page-turn-effect.h \ + $(srcdir)/clutter-path-constraint.h \ $(srcdir)/clutter-path.h \ $(srcdir)/clutter-rectangle.h \ $(srcdir)/clutter-score.h \ @@ -193,6 +194,7 @@ source_c = \ $(srcdir)/clutter-model.c \ $(srcdir)/clutter-offscreen-effect.c \ $(srcdir)/clutter-page-turn-effect.c \ + $(srcdir)/clutter-path-constraint.c \ $(srcdir)/clutter-path.c \ $(srcdir)/clutter-rectangle.c \ $(srcdir)/clutter-score.c \ diff --git a/clutter/clutter-path-constraint.c b/clutter/clutter-path-constraint.c new file mode 100644 index 000000000..fa4f8dc15 --- /dev/null +++ b/clutter/clutter-path-constraint.c @@ -0,0 +1,287 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Copyright (C) 2010 Intel Corporation. + * + * 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, see . + * + * Author: + * Emmanuele Bassi + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "clutter-path-constraint.h" + +#include "clutter-debug.h" +#include "clutter-private.h" + +#define CLUTTER_PATH_CONSTRAINT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_PATH_CONSTRAINT, ClutterPathConstraintClass)) +#define CLUTTER_IS_PATH_CONSTRAINT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_PATH_CONSTRAINT)) +#define CLUTTER_PATH_CONSTRAINT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_PATH_CONSTRAINT, ClutterPathConstraintClass)) + +typedef struct _ClutterPathConstraintClass ClutterPathConstraintClass; + +struct _ClutterPathConstraint +{ + ClutterConstraint parent_instance; + + ClutterPath *path; + + gfloat offset; + + ClutterActor *actor; +}; + +struct _ClutterPathConstraintClass +{ + ClutterConstraintClass parent_class; +}; + +enum +{ + PROP_0, + + PROP_PATH, + PROP_OFFSET, + + LAST_PROPERTY +}; + +G_DEFINE_TYPE (ClutterPathConstraint, clutter_path_constraint, CLUTTER_TYPE_CONSTRAINT); + +static GParamSpec *path_properties[LAST_PROPERTY] = { NULL, }; + +static void +clutter_path_constraint_update_allocation (ClutterConstraint *constraint, + ClutterActor *actor, + ClutterActorBox *allocation) +{ + ClutterPathConstraint *self = CLUTTER_PATH_CONSTRAINT (constraint); + gfloat width, height; + ClutterKnot position; + guint knot_id; + + if (self->path == NULL) + return; + + knot_id = clutter_path_get_position (self->path, self->offset, &position); + clutter_actor_box_get_size (allocation, &width, &height); + allocation->x1 = position.x; + allocation->y1 = position.y; + allocation->x2 = allocation->x1 + width; + allocation->y2 = allocation->y1 + height; +} + +static void +clutter_path_constraint_set_actor (ClutterActorMeta *meta, + ClutterActor *new_actor) +{ + ClutterPathConstraint *path = CLUTTER_PATH_CONSTRAINT (meta); + ClutterActorMetaClass *parent; + + /* store the pointer to the actor, for later use */ + path->actor = new_actor; + + parent = CLUTTER_ACTOR_META_CLASS (clutter_path_constraint_parent_class); + parent->set_actor (meta, new_actor); +} + +static void +clutter_path_constraint_dispose (GObject *gobject) +{ + ClutterPathConstraint *self = CLUTTER_PATH_CONSTRAINT (gobject); + + if (self->path != NULL) + { + g_object_unref (self->path); + self->path = NULL; + } + + G_OBJECT_CLASS (clutter_path_constraint_parent_class)->dispose (gobject); +} + +static void +clutter_path_constraint_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ClutterPathConstraint *self = CLUTTER_PATH_CONSTRAINT (gobject); + + switch (prop_id) + { + case PROP_PATH: + clutter_path_constraint_set_path (self, g_value_get_object (value)); + break; + + case PROP_OFFSET: + clutter_path_constraint_set_offset (self, g_value_get_float (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +clutter_path_constraint_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ClutterPathConstraint *self = CLUTTER_PATH_CONSTRAINT (gobject); + + switch (prop_id) + { + case PROP_PATH: + g_value_set_object (value, self->path); + break; + + case PROP_OFFSET: + g_value_set_float (value, self->offset); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +clutter_path_constraint_class_init (ClutterPathConstraintClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); + ClutterConstraintClass *constraint_class = CLUTTER_CONSTRAINT_CLASS (klass); + + /** + * ClutterPathConstraint:path: + * + * The #ClutterPath used to constrain the position of an actor. + * + * Since: 1.6 + */ + path_properties[PROP_PATH] = + g_param_spec_object ("path", + P_("Path"), + P_("The path used to constrain an actor"), + CLUTTER_TYPE_PATH, + CLUTTER_PARAM_READWRITE); + + /** + * ClutterPathConstraint:offset: + * + * The offset along the #ClutterPathConstraint:path, between -1.0 and 2.0. + * + * Since: 1.6 + */ + path_properties[PROP_OFFSET] = + g_param_spec_float ("offset", + P_("Offset"), + P_("The offset along the path, between -1.0 and 2.0"), + -1.0, 2.0, + 0.0, + CLUTTER_PARAM_READWRITE); + + gobject_class->set_property = clutter_path_constraint_set_property; + gobject_class->get_property = clutter_path_constraint_get_property; + gobject_class->dispose = clutter_path_constraint_dispose; + _clutter_object_class_install_properties (gobject_class, + LAST_PROPERTY, + path_properties); + + meta_class->set_actor = clutter_path_constraint_set_actor; + + constraint_class->update_allocation = clutter_path_constraint_update_allocation; +} + +static void +clutter_path_constraint_init (ClutterPathConstraint *self) +{ + self->offset = 0.0f; +} + +ClutterConstraint * +clutter_path_constraint_new (ClutterPath *path, + gfloat offset) +{ + g_return_val_if_fail (path == NULL || CLUTTER_IS_PATH (path), NULL); + + return g_object_new (CLUTTER_TYPE_PATH_CONSTRAINT, + "path", path, + "offset", offset, + NULL); +} + +void +clutter_path_constraint_set_path (ClutterPathConstraint *constraint, + ClutterPath *path) +{ + g_return_if_fail (CLUTTER_IS_PATH_CONSTRAINT (constraint)); + g_return_if_fail (path == NULL || CLUTTER_IS_PATH (path)); + + if (constraint->path == path) + return; + + if (constraint->path != NULL) + { + g_object_unref (constraint->path); + constraint->path = NULL; + } + + if (path != NULL) + constraint->path = g_object_ref_sink (path); + + if (constraint->actor != NULL) + clutter_actor_queue_relayout (constraint->actor); + + _clutter_notify_by_pspec (G_OBJECT (constraint), path_properties[PROP_PATH]); +} + +ClutterPath * +clutter_path_constraint_get_path (ClutterPathConstraint *constraint) +{ + g_return_val_if_fail (CLUTTER_IS_PATH_CONSTRAINT (constraint), NULL); + + return constraint->path; +} + +void +clutter_path_constraint_set_offset (ClutterPathConstraint *constraint, + gfloat offset) +{ + g_return_if_fail (CLUTTER_IS_PATH_CONSTRAINT (constraint)); + + if (constraint->offset == offset) + return; + + constraint->offset = offset; + + if (constraint->actor != NULL) + clutter_actor_queue_relayout (constraint->actor); + + _clutter_notify_by_pspec (G_OBJECT (constraint), path_properties[PROP_OFFSET]); +} + +gfloat +clutter_path_constraint_get_offset (ClutterPathConstraint *constraint) +{ + g_return_val_if_fail (CLUTTER_IS_PATH_CONSTRAINT (constraint), 0.0); + + return constraint->offset; +} diff --git a/clutter/clutter-path-constraint.h b/clutter/clutter-path-constraint.h new file mode 100644 index 000000000..89e93a870 --- /dev/null +++ b/clutter/clutter-path-constraint.h @@ -0,0 +1,65 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Copyright (C) 2010 Intel Corporation. + * + * 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, see . + * + * Author: + * Emmanuele Bassi + */ + +#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __CLUTTER_PATH_CONSTRAINT_H__ +#define __CLUTTER_PATH_CONSTRAINT_H__ + +#include +#include + +G_BEGIN_DECLS + +#define CLUTTER_TYPE_PATH_CONSTRAINT (clutter_path_constraint_get_type ()) +#define CLUTTER_PATH_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_PATH_CONSTRAINT, ClutterPathConstraint)) +#define CLUTTER_IS_PATH_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_PATH_CONSTRAINT)) + +/** + * ClutterPathConstraint: + * + * ClutterPathConstraint is an opaque structure + * whose members cannot be directly accessed + * + * Since: 1.4 + */ +typedef struct _ClutterPathConstraint ClutterPathConstraint; + +GType clutter_path_constraint_get_type (void) G_GNUC_CONST; + +ClutterConstraint *clutter_path_constraint_new (ClutterPath *path, + gfloat offset); + +void clutter_path_constraint_set_path (ClutterPathConstraint *constraint, + ClutterPath *path); +ClutterPath * clutter_path_constraint_get_path (ClutterPathConstraint *constraint); +void clutter_path_constraint_set_offset (ClutterPathConstraint *constraint, + gfloat offset); +gfloat clutter_path_constraint_get_offset (ClutterPathConstraint *constraint); + +G_END_DECLS + +#endif /* __CLUTTER_PATH_CONSTRAINT_H__ */ diff --git a/clutter/clutter.h b/clutter/clutter.h index 18145472f..0c81fdc44 100644 --- a/clutter/clutter.h +++ b/clutter/clutter.h @@ -82,6 +82,7 @@ #include "clutter-model.h" #include "clutter-offscreen-effect.h" #include "clutter-page-turn-effect.h" +#include "clutter-path-constraint.h" #include "clutter-path.h" #include "clutter-rectangle.h" #include "clutter-score.h"