Merge branch 'wip/constraints'

* wip/constraints: (24 commits)
  Add the Cogl API reference to the fixxref extra directories
  Document the internal MetaGroup class
  Remove the construct-only flag from ActorMeta:name
  doc: Remove gtk-doc annotations from the json-glib copy
  doc: Fix parameter documentation
  Add named modifiers for Action and Constraint
  Remove a redundant animation
  Set the stage resizable in test-constraints
  Use a 9 grid for the constraints test
  Miscellaneous documentation fixes
  docs: Document animating action and constraint properties
  docs: Document BindConstraint and AlignConstraint
  constraint: Rename BindConstraint:bind-axis
  constraints: Add AlignConstraint
  tests: Add a constraints interactive test
  constraint: Add BindConstraint
  actor: Implement Animatable
  animation: Use the new Animatable API for custom properties
  animatable: Add custom properties to Animatable
  constraint: Add ClutterConstraint base class
  ...

Conflicts:
	configure.ac
This commit is contained in:
Emmanuele Bassi 2010-05-21 10:55:09 +01:00
commit 5e3dc55666
40 changed files with 4287 additions and 178 deletions

2
.gitignore vendored
View File

@ -149,6 +149,8 @@ TAGS
/tests/interactive/stamp-test-interactive /tests/interactive/stamp-test-interactive
/tests/interactive/test-animator /tests/interactive/test-animator
/tests/interactive/test-stage-sizing /tests/interactive/test-stage-sizing
/tests/interactive/test-drag
/tests/interactive/test-constraints
/tests/conform/stamp-test-conformance /tests/conform/stamp-test-conformance
/tests/conform/test-anchors /tests/conform/test-anchors
/tests/conform/test-cogl-backface-culling /tests/conform/test-cogl-backface-culling

View File

@ -65,7 +65,10 @@ AM_CFLAGS = $(CLUTTER_CFLAGS) $(MAINTAINER_CFLAGS) $(GCOV_CFLAGS)
# please, keep this sorted alphabetically # please, keep this sorted alphabetically
source_h = \ source_h = \
$(srcdir)/clutter-action.h \
$(srcdir)/clutter-actor-meta.h \
$(srcdir)/clutter-actor.h \ $(srcdir)/clutter-actor.h \
$(srcdir)/clutter-align-constraint.h \
$(srcdir)/clutter-alpha.h \ $(srcdir)/clutter-alpha.h \
$(srcdir)/clutter-animatable.h \ $(srcdir)/clutter-animatable.h \
$(srcdir)/clutter-animation.h \ $(srcdir)/clutter-animation.h \
@ -78,6 +81,7 @@ source_h = \
$(srcdir)/clutter-behaviour-path.h \ $(srcdir)/clutter-behaviour-path.h \
$(srcdir)/clutter-behaviour-rotate.h \ $(srcdir)/clutter-behaviour-rotate.h \
$(srcdir)/clutter-behaviour-scale.h \ $(srcdir)/clutter-behaviour-scale.h \
$(srcdir)/clutter-bind-constraint.h \
$(srcdir)/clutter-binding-pool.h \ $(srcdir)/clutter-binding-pool.h \
$(srcdir)/clutter-bin-layout.h \ $(srcdir)/clutter-bin-layout.h \
$(srcdir)/clutter-box.h \ $(srcdir)/clutter-box.h \
@ -86,9 +90,11 @@ source_h = \
$(srcdir)/clutter-child-meta.h \ $(srcdir)/clutter-child-meta.h \
$(srcdir)/clutter-clone.h \ $(srcdir)/clutter-clone.h \
$(srcdir)/clutter-color.h \ $(srcdir)/clutter-color.h \
$(srcdir)/clutter-constraint.h \
$(srcdir)/clutter-container.h \ $(srcdir)/clutter-container.h \
$(srcdir)/clutter-deprecated.h \ $(srcdir)/clutter-deprecated.h \
$(srcdir)/clutter-device-manager.h \ $(srcdir)/clutter-device-manager.h \
$(srcdir)/clutter-drag-action.h \
$(srcdir)/clutter-event.h \ $(srcdir)/clutter-event.h \
$(srcdir)/clutter-feature.h \ $(srcdir)/clutter-feature.h \
$(srcdir)/clutter-fixed.h \ $(srcdir)/clutter-fixed.h \
@ -138,7 +144,10 @@ include $(top_srcdir)/build/autotools/Makefile.am.enums
# please, keep this sorted alphabetically # please, keep this sorted alphabetically
source_c = \ source_c = \
$(srcdir)/clutter-action.c \
$(srcdir)/clutter-actor-meta.c \
$(srcdir)/clutter-actor.c \ $(srcdir)/clutter-actor.c \
$(srcdir)/clutter-align-constraint.c \
$(srcdir)/clutter-alpha.c \ $(srcdir)/clutter-alpha.c \
$(srcdir)/clutter-animatable.c \ $(srcdir)/clutter-animatable.c \
$(srcdir)/clutter-animation.c \ $(srcdir)/clutter-animation.c \
@ -152,6 +161,7 @@ source_c = \
$(srcdir)/clutter-behaviour-rotate.c \ $(srcdir)/clutter-behaviour-rotate.c \
$(srcdir)/clutter-behaviour-scale.c \ $(srcdir)/clutter-behaviour-scale.c \
$(srcdir)/clutter-bezier.c \ $(srcdir)/clutter-bezier.c \
$(srcdir)/clutter-bind-constraint.c \
$(srcdir)/clutter-binding-pool.c \ $(srcdir)/clutter-binding-pool.c \
$(srcdir)/clutter-bin-layout.c \ $(srcdir)/clutter-bin-layout.c \
$(srcdir)/clutter-box.c \ $(srcdir)/clutter-box.c \
@ -160,8 +170,10 @@ source_c = \
$(srcdir)/clutter-child-meta.c \ $(srcdir)/clutter-child-meta.c \
$(srcdir)/clutter-clone.c \ $(srcdir)/clutter-clone.c \
$(srcdir)/clutter-color.c \ $(srcdir)/clutter-color.c \
$(srcdir)/clutter-constraint.c \
$(srcdir)/clutter-container.c \ $(srcdir)/clutter-container.c \
$(srcdir)/clutter-device-manager.c \ $(srcdir)/clutter-device-manager.c \
$(srcdir)/clutter-drag-action.c \
clutter-enum-types.c \ clutter-enum-types.c \
$(srcdir)/clutter-event.c \ $(srcdir)/clutter-event.c \
$(srcdir)/clutter-feature.c \ $(srcdir)/clutter-feature.c \
@ -206,6 +218,7 @@ source_c_priv = \
$(NULL) $(NULL)
source_h_priv = \ source_h_priv = \
$(srcdir)/clutter-actor-meta-private.h \
$(srcdir)/clutter-bezier.h \ $(srcdir)/clutter-bezier.h \
$(srcdir)/clutter-debug.h \ $(srcdir)/clutter-debug.h \
$(srcdir)/clutter-keysyms-table.h \ $(srcdir)/clutter-keysyms-table.h \

61
clutter/clutter-action.c Normal file
View File

@ -0,0 +1,61 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
/**
* SECTION:clutter-action
* @Title: ClutterAction
* @Short_Description: Abstract class for actor actions
* @See_Also: #ClutterEffect
*
* #ClutterAction is an abstract base class for action that modify the
* user interaction of a #ClutterActor, just like #ClutterEffect is an
* abstract class for modifiers of the appearance of a #ClutterActor.
*
* Implementations of #ClutterAction are associated to an actor and can
* provide behavioral changes when dealing with user input - for instance
* drag and drop capabilities, or scrolling, or panning.
*
* #ClutterAction is available since Clutter 1.4
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-action.h"
#include "clutter-debug.h"
#include "clutter-private.h"
G_DEFINE_ABSTRACT_TYPE (ClutterAction, clutter_action, CLUTTER_TYPE_ACTOR_META);
static void
clutter_action_class_init (ClutterActionClass *klass)
{
}
static void
clutter_action_init (ClutterAction *self)
{
}

101
clutter/clutter-action.h Normal file
View File

@ -0,0 +1,101 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef __CLUTTER_ACTION_H__
#define __CLUTTER_ACTION_H__
#include <clutter/clutter-actor-meta.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_ACTION (clutter_action_get_type ())
#define CLUTTER_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTION, ClutterAction))
#define CLUTTER_IS_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTION))
#define CLUTTER_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ACTION, ClutterActionClass))
#define CLUTTER_IS_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ACTION))
#define CLUTTER_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ACTION, ClutterActionClass))
typedef struct _ClutterActionClass ClutterActionClass;
/**
* ClutterAction:
*
* The <structname>ClutterAction</structname> structure contains only
* private data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _ClutterAction
{
/*< private >*/
ClutterActorMeta parent_instance;
};
/**
* ClutterActionClass:
*
* The <structname>ClutterActionClass</structname> structure contains
* only private data
*
* Since: 1.4
*/
struct _ClutterActionClass
{
/*< private >*/
ClutterActorMetaClass parent_class;
void (* _clutter_action1) (void);
void (* _clutter_action2) (void);
void (* _clutter_action3) (void);
void (* _clutter_action4) (void);
void (* _clutter_action5) (void);
void (* _clutter_action6) (void);
void (* _clutter_action7) (void);
void (* _clutter_action8) (void);
};
GType clutter_action_get_type (void) G_GNUC_CONST;
/* ClutterActor API */
void clutter_actor_add_action (ClutterActor *self,
ClutterAction *action);
void clutter_actor_add_action_with_name (ClutterActor *self,
const gchar *name,
ClutterAction *action);
void clutter_actor_remove_action (ClutterActor *self,
ClutterAction *action);
void clutter_actor_remove_action_by_name (ClutterActor *self,
const gchar *name);
ClutterAction *clutter_actor_get_action (ClutterActor *self,
const gchar *name);
GList * clutter_actor_get_actions (ClutterActor *self);
void clutter_actor_clear_actions (ClutterActor *self);
G_END_DECLS
#endif /* __CLUTTER_ACTION_H__ */

View File

@ -0,0 +1,42 @@
#ifndef __CLUTTER_ACTOR_META_PRIVATE_H__
#define __CLUTTER_ACTOR_META_PRIVATE_H__
#include <clutter/clutter-actor-meta.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_META_GROUP (_clutter_meta_group_get_type ())
#define CLUTTER_META_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_META_GROUP, ClutterMetaGroup))
#define CLUTTER_IS_META_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_META_GROUP))
typedef struct _ClutterMetaGroup ClutterMetaGroup;
typedef struct _ClutterMetaGroupClass ClutterMetaGroupClass;
struct _ClutterMetaGroup
{
GObject parent_instance;
ClutterActor *actor;
GList *meta;
};
struct _ClutterMetaGroupClass
{
GObjectClass parent_class;
};
GType _clutter_meta_group_get_type (void) G_GNUC_CONST;
void _clutter_meta_group_add_meta (ClutterMetaGroup *group,
ClutterActorMeta *meta);
void _clutter_meta_group_remove_meta (ClutterMetaGroup *group,
ClutterActorMeta *meta);
G_CONST_RETURN GList *_clutter_meta_group_peek_metas (ClutterMetaGroup *group);
void _clutter_meta_group_clear_metas (ClutterMetaGroup *group);
ClutterActorMeta * _clutter_meta_group_get_meta (ClutterMetaGroup *group,
const gchar *name);
G_END_DECLS
#endif /* __CLUTTER_ACTOR_META_PRIVATE_H__ */

View File

@ -0,0 +1,457 @@
/**
* SECTION:clutter-actor-meta
* @Title: ClutterActorMeta
* @Short_Description: Base class of actor modifiers
*
* #ClutterActorMeta is an abstract class providing a common API for
* modifiers of #ClutterActor
*
* A #ClutterActorMeta can only be owned by a single #ClutterActor at
* any time
*
* #ClutterActorMeta is available since Clutter 1.4
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-actor-meta-private.h"
#include "clutter-debug.h"
#include "clutter-private.h"
struct _ClutterActorMetaPrivate
{
ClutterActor *actor;
gchar *name;
guint is_enabled : 1;
};
enum
{
PROP_0,
PROP_ACTOR,
PROP_NAME,
PROP_ENABLED
};
G_DEFINE_ABSTRACT_TYPE (ClutterActorMeta,
clutter_actor_meta,
G_TYPE_INITIALLY_UNOWNED);
static void
clutter_actor_meta_real_set_actor (ClutterActorMeta *meta,
ClutterActor *actor)
{
meta->priv->actor = actor;
}
static void
clutter_actor_meta_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterActorMeta *meta = CLUTTER_ACTOR_META (gobject);
switch (prop_id)
{
case PROP_NAME:
clutter_actor_meta_set_name (meta, g_value_get_string (value));
break;
case PROP_ENABLED:
clutter_actor_meta_set_enabled (meta, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_actor_meta_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ClutterActorMeta *meta = CLUTTER_ACTOR_META (gobject);
switch (prop_id)
{
case PROP_ACTOR:
g_value_set_object (value, meta->priv->actor);
break;
case PROP_NAME:
g_value_set_string (value, meta->priv->name);
break;
case PROP_ENABLED:
g_value_set_boolean (value, meta->priv->is_enabled);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_actor_meta_finalize (GObject *gobject)
{
ClutterActorMetaPrivate *priv = CLUTTER_ACTOR_META (gobject)->priv;
g_free (priv->name);
G_OBJECT_CLASS (clutter_actor_meta_parent_class)->finalize (gobject);
}
void
clutter_actor_meta_class_init (ClutterActorMetaClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
g_type_class_add_private (klass, sizeof (ClutterActorMetaPrivate));
klass->set_actor = clutter_actor_meta_real_set_actor;
gobject_class->set_property = clutter_actor_meta_set_property;
gobject_class->get_property = clutter_actor_meta_get_property;
gobject_class->finalize = clutter_actor_meta_finalize;
/**
* ClutterActorMeta:actor:
*
* The #ClutterActor attached to the #ClutterActorMeta instance
*
* Since: 1.4
*/
pspec = g_param_spec_object ("actor",
"Actor",
"The actor attached to the meta",
CLUTTER_TYPE_ACTOR,
CLUTTER_PARAM_READABLE);
g_object_class_install_property (gobject_class, PROP_ACTOR, pspec);
/**
* ClutterActorMeta:name:
*
* The unique name to access the #ClutterActorMeta
*
* Since: 1.4
*/
pspec = g_param_spec_string ("name",
"Name",
"The name of the meta",
NULL,
CLUTTER_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_NAME, pspec);
/**
* ClutterActorMeta:enabled:
*
* Whether or not the #ClutterActorMeta is enabled
*
* Since: 1.4
*/
pspec = g_param_spec_boolean ("enabled",
"Enabled",
"Whether the meta is enabled",
TRUE,
CLUTTER_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_ENABLED, pspec);
}
void
clutter_actor_meta_init (ClutterActorMeta *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
CLUTTER_TYPE_ACTOR_META,
ClutterActorMetaPrivate);
self->priv->is_enabled = TRUE;
}
/**
* clutter_actor_meta_set_name:
* @meta: a #ClutterActorMeta
* @name: the name of @meta
*
* Sets the name of @meta
*
* The name can be used to identify the #ClutterActorMeta instance
*
* Since: 1.4
*/
void
clutter_actor_meta_set_name (ClutterActorMeta *meta,
const gchar *name)
{
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
if (g_strcmp0 (meta->priv->name, name) == 0)
return;
g_free (meta->priv->name);
meta->priv->name = g_strdup (name);
g_object_notify (G_OBJECT (meta), "name");
}
/**
* clutter_actor_meta_get_name:
* @meta: a #ClutterActorMeta
*
* Retrieves the name set using clutter_actor_meta_set_name()
*
* Return value: (transfer none): the name of the #ClutterActorMeta
* instance, or %NULL if none was set. The returned string is owned
* by the #ClutterActorMeta instance and it should not be modified
* or freed
*
* Since: 1.4
*/
G_CONST_RETURN gchar *
clutter_actor_meta_get_name (ClutterActorMeta *meta)
{
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL);
return meta->priv->name;
}
/**
* clutter_actor_meta_set_enabled:
* @meta: a #ClutterActorMeta
* @is_enabled: whether @meta is enabled
*
* Sets whether @meta should be enabled or not
*
* Since: 1.4
*/
void
clutter_actor_meta_set_enabled (ClutterActorMeta *meta,
gboolean is_enabled)
{
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
is_enabled = !!is_enabled;
if (meta->priv->is_enabled == is_enabled)
return;
meta->priv->is_enabled = is_enabled;
g_object_notify (G_OBJECT (meta), "enabled");
}
/**
* clutter_actor_meta_get_enabled:
* @meta: a #ClutterActorMeta
*
* Retrieves whether @meta is enabled
*
* Return value: %TRUE if the #ClutterActorMeta instance is enabled
*
* Since: 1.4
*/
gboolean
clutter_actor_meta_get_enabled (ClutterActorMeta *meta)
{
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), FALSE);
return meta->priv->is_enabled;
}
/*
* _clutter_actor_meta_set_actor
* @meta: a #ClutterActorMeta
* @actor: a #ClutterActor or %NULL
*
* Sets or unsets a back pointer to the #ClutterActor that owns
* the @meta
*
* Since: 1.4
*/
void
_clutter_actor_meta_set_actor (ClutterActorMeta *meta,
ClutterActor *actor)
{
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
g_return_if_fail (actor == NULL || CLUTTER_IS_ACTOR (actor));
CLUTTER_ACTOR_META_GET_CLASS (meta)->set_actor (meta, actor);
}
/**
* clutter_actor_meta_get_actor:
* @meta: a #ClutterActorMeta
*
* Retrieves a pointer to the #ClutterActor that owns @meta
*
* Return value: (transfer none): a pointer to a #ClutterActor or %NULL
*
* Since: 1.4
*/
ClutterActor *
clutter_actor_meta_get_actor (ClutterActorMeta *meta)
{
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL);
return meta->priv->actor;
}
/*
* ClutterMetaGroup: a collection of ClutterActorMeta instances
*/
G_DEFINE_TYPE (ClutterMetaGroup, _clutter_meta_group, G_TYPE_OBJECT);
static void
_clutter_meta_group_dispose (GObject *gobject)
{
_clutter_meta_group_clear_metas (CLUTTER_META_GROUP (gobject));
G_OBJECT_CLASS (_clutter_meta_group_parent_class)->dispose (gobject);
}
static void
_clutter_meta_group_class_init (ClutterMetaGroupClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->dispose = _clutter_meta_group_dispose;
}
static void
_clutter_meta_group_init (ClutterMetaGroup *self)
{
}
/*
* _clutter_meta_group_add_meta:
* @group: a #ClutterMetaGroup
* @meta: a #ClutterActorMeta to add
*
* Adds @meta to @group
*
* This function will remove the floating reference of @meta or, if the
* floating reference has already been sunk, add a reference to it
*/
void
_clutter_meta_group_add_meta (ClutterMetaGroup *group,
ClutterActorMeta *meta)
{
if (meta->priv->actor != NULL)
{
g_warning ("The meta of type '%s' with name '%s' is "
"already attached to actor '%s'",
G_OBJECT_TYPE_NAME (meta),
meta->priv->name != NULL
? meta->priv->name
: "<unknown>",
clutter_actor_get_name (meta->priv->actor) != NULL
? clutter_actor_get_name (meta->priv->actor)
: G_OBJECT_TYPE_NAME (meta->priv->actor));
return;
}
group->meta = g_list_append (group->meta, meta);
g_object_ref_sink (meta);
_clutter_actor_meta_set_actor (meta, group->actor);
}
/*
* _clutter_meta_group_remove_meta:
* @group: a #ClutterMetaGroup
* @meta: a #ClutterActorMeta to remove
*
* Removes @meta from @group and releases the reference being held on it
*/
void
_clutter_meta_group_remove_meta (ClutterMetaGroup *group,
ClutterActorMeta *meta)
{
if (meta->priv->actor != group->actor)
{
g_warning ("The meta of type '%s' with name '%s' is not "
"attached to the actor '%s'",
G_OBJECT_TYPE_NAME (meta),
meta->priv->name != NULL
? meta->priv->name
: "<unknown>",
clutter_actor_get_name (group->actor) != NULL
? clutter_actor_get_name (group->actor)
: G_OBJECT_TYPE_NAME (group->actor));
return;
}
_clutter_actor_meta_set_actor (meta, NULL);
group->meta = g_list_remove (group->meta, meta);
g_object_unref (meta);
}
/*
* _clutter_meta_group_peek_metas:
* @group: a #ClutterMetaGroup
*
* Returns a pointer to the #ClutterActorMeta list
*
* Return value: a const pointer to the #GList of #ClutterActorMeta
*/
G_CONST_RETURN GList *
_clutter_meta_group_peek_metas (ClutterMetaGroup *group)
{
return group->meta;
}
/*
* _clutter_meta_group_clear_metas:
* @group: a #ClutterMetaGroup
*
* Clears @group of all #ClutterActorMeta instances and releases
* the reference on them
*/
void
_clutter_meta_group_clear_metas (ClutterMetaGroup *group)
{
g_list_foreach (group->meta, (GFunc) _clutter_actor_meta_set_actor, NULL);
g_list_foreach (group->meta, (GFunc) g_object_unref, NULL);
g_list_free (group->meta);
group->meta = NULL;
}
/*
* _clutter_meta_group_get_meta:
* @group: a #ClutterMetaGroup
* @name: the name of the #ClutterActorMeta to retrieve
*
* Retrieves a named #ClutterActorMeta from @group
*
* Return value: a #ClutterActorMeta for the given name, or %NULL
*/
ClutterActorMeta *
_clutter_meta_group_get_meta (ClutterMetaGroup *group,
const gchar *name)
{
GList *l;
for (l = group->meta; l != NULL; l = l->next)
{
ClutterActorMeta *meta = l->data;
if (g_strcmp0 (meta->priv->name, name) == 0)
return meta;
}
return NULL;
}

View File

@ -0,0 +1,84 @@
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef __CLUTTER_ACTOR_META_H__
#define __CLUTTER_ACTOR_META_H__
#include <clutter/clutter-types.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_ACTOR_META (clutter_actor_meta_get_type ())
#define CLUTTER_ACTOR_META(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTOR_META, ClutterActorMeta))
#define CLUTTER_IS_ACTOR_META(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTOR_META))
#define CLUTTER_ACTOR_META_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ACTOR_META, ClutterActorMetaClass))
#define CLUTTER_IS_ACTOR_META_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ACTOR_META))
#define CLUTTER_ACTOR_META_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ACTOR_META, ClutterActorMetaClass))
typedef struct _ClutterActorMetaPrivate ClutterActorMetaPrivate;
typedef struct _ClutterActorMetaClass ClutterActorMetaClass;
/**
* ClutterActorMeta:
*
* The <structname>ClutterActorMeta</structname> structure contains only
* private data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _ClutterActorMeta
{
/*< private >*/
GInitiallyUnowned parent_instance;
ClutterActorMetaPrivate *priv;
};
/**
* ClutterActorMetaClass:
* @set_actor: virtual function, invoked when attaching and detaching
* a #ClutterActorMeta instance to a #ClutterActor
*
* The <structname>ClutterActorMetaClass</structname> structure contains
* only private data
*
* Since: 1.4
*/
struct _ClutterActorMetaClass
{
/*< private >*/
GInitiallyUnownedClass parent_class;
/*< public >*/
void (* set_actor) (ClutterActorMeta *meta,
ClutterActor *actor);
/*< private >*/
void (* _clutter_meta1) (void);
void (* _clutter_meta2) (void);
void (* _clutter_meta3) (void);
void (* _clutter_meta4) (void);
void (* _clutter_meta5) (void);
void (* _clutter_meta6) (void);
void (* _clutter_meta7) (void);
};
GType clutter_actor_meta_get_type (void) G_GNUC_CONST;
void clutter_actor_meta_set_name (ClutterActorMeta *meta,
const gchar *name);
G_CONST_RETURN gchar *clutter_actor_meta_get_name (ClutterActorMeta *meta);
void clutter_actor_meta_set_enabled (ClutterActorMeta *meta,
gboolean is_enabled);
gboolean clutter_actor_meta_get_enabled (ClutterActorMeta *meta);
ClutterActor * clutter_actor_meta_get_actor (ClutterActorMeta *meta);
/* private */
void _clutter_actor_meta_set_actor (ClutterActorMeta *meta,
ClutterActor *actor);
G_END_DECLS
#endif /* __CLUTTER_ACTOR_META_H__ */

View File

@ -155,6 +155,65 @@
* should read the documentation for the #ClutterUnits parser format for * should read the documentation for the #ClutterUnits parser format for
* the valid units and syntax.</para> * the valid units and syntax.</para>
* </refsect2> * </refsect2>
*
* <refsect2 id="ClutterActor-animating">
* <title>Custom animatable properties</title>
* <para>#ClutterActor allows accessing properties of #ClutterAction
* and #ClutterConstraint instances associated to an actor instance
* for animation purposes.</para>
* <para>In order to access a specific #ClutterAction or a #ClutterConstraint
* property it is necessary to set the #ClutterActorMeta:name property on the
* given action or constraint.</para>
* <para>The property can be accessed using the the following syntax:</para>
* <informalexample>
* <programlisting>
* @&lt;section&gt;.&lt;meta-name&gt;.&lt;property-name&gt;
* </programlisting>
* </informalexample>
* <para>The initial <emphasis>@</emphasis> is mandatory.</para>
* <para>The <emphasis>section</emphasis> fragment can be one between
* "actions" or "constraints".</para>
* <para>The <emphasis>meta-name</emphasis> fragment is the name of the
* action or constraint, as specified by the #ClutterActorMeta:name
* property.</para>
* <para>The <emphasis>property-name</emphasis> fragment is the name of the
* action or constraint property to be animated.</para>
* <example id="example-ClutterActor-animating-meta">
* <title>Animating a constraint property</title>
* <para>The example below animates a #ClutterBindConstraint applied to an
* actor using clutter_actor_animate(). The <emphasis>rect</emphasis> has
* a binding constraint for the <emphasis>origin</emphasis> actor, and in
* its initial state is fully transparent and overlapping the actor to
* which is bound to. </para>
* <programlisting>
* constraint = clutter_bind_constraint_new (origin, CLUTTER_BIND_X, 0.0);
* clutter_actor_meta_set_name (CLUTTER_ACTOR_META (constraint), "bind-x");
* clutter_actor_add_constraint (rect, constraint);
*
* constraint = clutter_bind_constraint_new (origin, CLUTTER_BIND_Y, 0.0);
* clutter_actor_meta_set_name (CLUTTER_ACTOR_META (constraint), "bind-y");
* clutter_actor_add_constraint (rect, constraint);
*
* clutter_actor_set_reactive (rect, TRUE);
* clutter_actor_set_opacity (rect, 0);
*
* g_signal_connect (rect, "button-press-event",
* G_CALLBACK (on_button_press),
* NULL);
* </programlisting>
* <para>On button press, the rectangle "slides" from behind the actor to
* which is bound to, using the #ClutterBindConstraint:offset property and
* the #ClutterActor:opacity property.</para>
* <programlisting>
* float new_offset = clutter_actor_get_width (origin) + h_padding;
*
* clutter_actor_animate (rect, CLUTTER_EASE_OUT_CUBIC, 500,
* "opacity", 255,
* "@constraints.bind-x.offset", new_offset,
* NULL);
* </programlisting>
* </example>
* </refsect2>
*/ */
/** /**
@ -226,17 +285,23 @@
#endif #endif
#include "clutter-actor.h" #include "clutter-actor.h"
#include "clutter-action.h"
#include "clutter-actor-meta-private.h"
#include "clutter-animatable.h"
#include "clutter-constraint.h"
#include "clutter-container.h" #include "clutter-container.h"
#include "clutter-main.h" #include "clutter-debug.h"
#include "clutter-enum-types.h" #include "clutter-enum-types.h"
#include "clutter-scriptable.h" #include "clutter-main.h"
#include "clutter-script.h"
#include "clutter-marshal.h" #include "clutter-marshal.h"
#include "clutter-private.h" #include "clutter-private.h"
#include "clutter-debug.h"
#include "clutter-units.h"
#include "clutter-profile.h" #include "clutter-profile.h"
#include "clutter-scriptable.h"
#include "clutter-script.h"
#include "clutter-stage.h" #include "clutter-stage.h"
#include "clutter-units.h"
#include "cogl/cogl.h" #include "cogl/cogl.h"
typedef struct _ShaderData ShaderData; typedef struct _ShaderData ShaderData;
@ -391,6 +456,9 @@ struct _ClutterActorPrivate
* See clutter_actor_queue_clipped_redraw() for details. * See clutter_actor_queue_clipped_redraw() for details.
*/ */
const ClutterActorBox *oob_queue_redraw_clip; const ClutterActorBox *oob_queue_redraw_clip;
ClutterMetaGroup *actions;
ClutterMetaGroup *constraints;
}; };
enum enum
@ -471,7 +539,10 @@ enum
PROP_SHOW_ON_SET_PARENT, PROP_SHOW_ON_SET_PARENT,
PROP_TEXT_DIRECTION, PROP_TEXT_DIRECTION,
PROP_HAS_POINTER PROP_HAS_POINTER,
PROP_ACTIONS,
PROP_CONSTRAINTS
}; };
enum enum
@ -506,6 +577,7 @@ enum
static guint actor_signals[LAST_SIGNAL] = { 0, }; static guint actor_signals[LAST_SIGNAL] = { 0, };
static void clutter_scriptable_iface_init (ClutterScriptableIface *iface); static void clutter_scriptable_iface_init (ClutterScriptableIface *iface);
static void clutter_animatable_iface_init (ClutterAnimatableIface *iface);
static void _clutter_actor_apply_modelview_transform (ClutterActor *self); static void _clutter_actor_apply_modelview_transform (ClutterActor *self);
@ -571,7 +643,9 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (ClutterActor,
clutter_actor, clutter_actor,
G_TYPE_INITIALLY_UNOWNED, G_TYPE_INITIALLY_UNOWNED,
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_SCRIPTABLE, G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_SCRIPTABLE,
clutter_scriptable_iface_init)); clutter_scriptable_iface_init)
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_ANIMATABLE,
clutter_animatable_iface_init));
static const gchar * static const gchar *
get_actor_debug_name (ClutterActor *actor) get_actor_debug_name (ClutterActor *actor)
@ -2892,6 +2966,14 @@ clutter_actor_set_property (GObject *object,
clutter_actor_set_text_direction (actor, g_value_get_enum (value)); clutter_actor_set_text_direction (actor, g_value_get_enum (value));
break; break;
case PROP_ACTIONS:
clutter_actor_add_action (actor, g_value_get_object (value));
break;
case PROP_CONSTRAINTS:
clutter_actor_add_constraint (actor, g_value_get_object (value));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -3199,12 +3281,18 @@ clutter_actor_dispose (GObject *object)
destroy_shader_data (self); destroy_shader_data (self);
if (priv->pango_context) if (priv->pango_context != NULL)
{ {
g_object_unref (priv->pango_context); g_object_unref (priv->pango_context);
priv->pango_context = NULL; priv->pango_context = NULL;
} }
if (priv->actions != NULL)
{
g_object_unref (priv->actions);
priv->actions = NULL;
}
g_signal_emit (self, actor_signals[DESTROY], 0); g_signal_emit (self, actor_signals[DESTROY], 0);
G_OBJECT_CLASS (clutter_actor_parent_class)->dispose (object); G_OBJECT_CLASS (clutter_actor_parent_class)->dispose (object);
@ -3999,6 +4087,34 @@ clutter_actor_class_init (ClutterActorClass *klass)
PROP_HAS_POINTER, PROP_HAS_POINTER,
pspec); pspec);
/**
* ClutterActor:actions:
*
* Adds a #ClutterAction to the actor
*
* Since: 1.4
*/
pspec = g_param_spec_object ("actions",
"Actions",
"Adds an action to the actor",
CLUTTER_TYPE_ACTION,
CLUTTER_PARAM_WRITABLE);
g_object_class_install_property (object_class, PROP_ACTIONS, pspec);
/**
* ClutterActor:constraints:
*
* Adds a #ClutterConstaint to the actor
*
* Since: 1.4
*/
pspec = g_param_spec_object ("constraints",
"Constraints",
"Adds a constraint to the actor",
CLUTTER_TYPE_CONSTRAINT,
CLUTTER_PARAM_WRITABLE);
g_object_class_install_property (object_class, PROP_CONSTRAINTS, pspec);
/** /**
* ClutterActor::destroy: * ClutterActor::destroy:
* @actor: the object which received the signal * @actor: the object which received the signal
@ -8104,6 +8220,158 @@ clutter_scriptable_iface_init (ClutterScriptableIface *iface)
iface->set_custom_property = clutter_actor_set_custom_property; iface->set_custom_property = clutter_actor_set_custom_property;
} }
static ClutterActorMeta *
get_meta_from_animation_property (ClutterActor *actor,
const gchar *name,
gchar **name_p)
{
ClutterActorPrivate *priv = actor->priv;
ClutterActorMeta *meta = NULL;
gchar **tokens;
/* if this is not a special property, fall through */
if (name[0] != '@')
return NULL;
/* detect the properties named using the following spec:
*
* @<section>.<meta-name>.<property-name>
*
* where <section> can be one of the following:
*
* - actions
* - constraints
*
* and <meta-name> is the name set on a specific ActorMeta
*/
tokens = g_strsplit (name + 1, ".", -1);
if (tokens == NULL || g_strv_length (tokens) != 3)
{
CLUTTER_NOTE (ANIMATION, "Invalid property name '%s'",
name + 1);
g_strfreev (tokens);
return NULL;
}
if (strcmp (tokens[0], "actions") == 0)
meta = _clutter_meta_group_get_meta (priv->actions, tokens[1]);
if (strcmp (tokens[0], "constraints") == 0)
meta = _clutter_meta_group_get_meta (priv->constraints, tokens[1]);
if (name_p != NULL)
*name_p = g_strdup (tokens[2]);
CLUTTER_NOTE (ANIMATION,
"Looking for property '%s' of object '%s' in section '%s'",
tokens[2],
tokens[1],
tokens[0]);
g_strfreev (tokens);
return meta;
}
static GParamSpec *
clutter_actor_find_property (ClutterAnimatable *animatable,
ClutterAnimation *animation,
const gchar *property_name)
{
ClutterActorMeta *meta = NULL;
GObjectClass *klass = NULL;
GParamSpec *pspec = NULL;
gchar *p_name = NULL;
meta = get_meta_from_animation_property (CLUTTER_ACTOR (animatable),
property_name,
&p_name);
if (meta != NULL)
{
klass = G_OBJECT_GET_CLASS (meta);
pspec = g_object_class_find_property (klass, p_name);
g_free (p_name);
}
else
{
klass = G_OBJECT_GET_CLASS (animatable);
pspec = g_object_class_find_property (klass, property_name);
}
return pspec;
}
static void
clutter_actor_get_initial_state (ClutterAnimatable *animatable,
ClutterAnimation *animation,
const gchar *property_name,
GValue *initial)
{
ClutterActorMeta *meta = NULL;
gchar *p_name = NULL;
meta = get_meta_from_animation_property (CLUTTER_ACTOR (animatable),
property_name,
&p_name);
if (meta != NULL)
g_object_get_property (G_OBJECT (meta), p_name, initial);
else
g_object_get_property (G_OBJECT (animatable), property_name, initial);
g_free (p_name);
}
static void
clutter_actor_set_final_state (ClutterAnimatable *animatable,
ClutterAnimation *animation,
const gchar *property_name,
const GValue *final)
{
ClutterActorMeta *meta = NULL;
gchar *p_name = NULL;
meta = get_meta_from_animation_property (CLUTTER_ACTOR (animatable),
property_name,
&p_name);
if (meta != NULL)
g_object_set_property (G_OBJECT (meta), p_name, final);
else
g_object_set_property (G_OBJECT (animatable), property_name, final);
g_free (p_name);
}
static gboolean
clutter_actor_animate_property (ClutterAnimatable *animatable,
ClutterAnimation *animation,
const gchar *property_name,
const GValue *initial,
const GValue *final,
gdouble progress,
GValue *new_value)
{
ClutterInterval *interval;
interval = clutter_animation_get_interval (animation, property_name);
return clutter_interval_compute_value (interval, progress, new_value);
}
static void
clutter_animatable_iface_init (ClutterAnimatableIface *iface)
{
iface->animate_property = clutter_actor_animate_property;
iface->find_property = clutter_actor_find_property;
iface->get_initial_state = clutter_actor_get_initial_state;
iface->set_final_state = clutter_actor_set_final_state;
}
/** /**
* clutter_actor_transform_stage_point * clutter_actor_transform_stage_point
* @self: A #ClutterActor * @self: A #ClutterActor
@ -10172,3 +10440,414 @@ clutter_actor_has_allocation (ClutterActor *self)
CLUTTER_ACTOR_IS_VISIBLE (self) && CLUTTER_ACTOR_IS_VISIBLE (self) &&
!priv->needs_allocation; !priv->needs_allocation;
} }
/**
* clutter_actor_add_action:
* @self: a #ClutterActor
* @action: a #ClutterAction
*
* Adds @action to the list of actions applied to @self
*
* A #ClutterAction can only belong to one actor at a time
*
* The #ClutterActor will hold a reference on @action until either
* clutter_actor_remove_action() or clutter_actor_clear_actions()
* is called
*
* Since: 1.4
*/
void
clutter_actor_add_action (ClutterActor *self,
ClutterAction *action)
{
ClutterActorPrivate *priv;
g_return_if_fail (CLUTTER_IS_ACTOR (self));
g_return_if_fail (CLUTTER_IS_ACTION (action));
priv = self->priv;
if (priv->actions == NULL)
{
priv->actions = g_object_new (CLUTTER_TYPE_META_GROUP, NULL);
priv->actions->actor = self;
}
_clutter_meta_group_add_meta (priv->actions, CLUTTER_ACTOR_META (action));
g_object_notify (G_OBJECT (self), "actions");
}
/**
* clutter_actor_add_action_with_name:
* @self: a #ClutterActor
* @name: the name to set on the action
* @action: a #ClutterAction
*
* A convenience function for setting the name of a #ClutterAction
* while adding it to the list of actions applied to @self
*
* This function is the logical equivalent of:
*
* |[
* clutter_actor_meta_set_name (CLUTTER_ACTOR_META (action), name);
* clutter_actor_add_action (self, action);
* ]|
*
* Since: 1.4
*/
void
clutter_actor_add_action_with_name (ClutterActor *self,
const gchar *name,
ClutterAction *action)
{
g_return_if_fail (CLUTTER_IS_ACTOR (self));
g_return_if_fail (name != NULL);
g_return_if_fail (CLUTTER_IS_ACTION (self));
clutter_actor_meta_set_name (CLUTTER_ACTOR_META (action), name);
clutter_actor_add_action (self, action);
}
/**
* clutter_actor_remove_action:
* @self: a #ClutterActor
* @action: a #ClutterAction
*
* Removes @action from the list of actions applied to @self
*
* The reference held by @self on the #ClutterAction will be released
*
* Since: 1.4
*/
void
clutter_actor_remove_action (ClutterActor *self,
ClutterAction *action)
{
ClutterActorPrivate *priv;
g_return_if_fail (CLUTTER_IS_ACTOR (self));
g_return_if_fail (CLUTTER_IS_ACTION (action));
priv = self->priv;
if (priv->actions == NULL)
return;
_clutter_meta_group_remove_meta (priv->actions, CLUTTER_ACTOR_META (action));
g_object_notify (G_OBJECT (self), "actions");
}
/**
* clutter_actor_remove_action_by_name:
* @self: a #ClutterActor
* @name: the name of the action to remove
*
* Removes the #ClutterAction with the given name from the list
* of actions applied to @self
*
* Since: 1.4
*/
void
clutter_actor_remove_action_by_name (ClutterActor *self,
const gchar *name)
{
ClutterActorPrivate *priv;
ClutterActorMeta *meta;
g_return_if_fail (CLUTTER_IS_ACTOR (self));
g_return_if_fail (name != NULL);
priv = self->priv;
if (priv->actions == NULL)
return;
meta = _clutter_meta_group_get_meta (priv->actions, name);
if (meta == NULL)
return;
_clutter_meta_group_remove_meta (priv->actions, meta);
g_object_notify (G_OBJECT (self), "actions");
}
/**
* clutter_actor_get_actions:
* @self: a #ClutterActor
*
* Retrieves the list of actions applied to @self
*
* Return value: (transfer container) (element-type ClutterAction): a copy
* of the list of #ClutterAction<!-- -->s. The contents of the list are
* owned by the #ClutterActor. Use g_list_free() to free the resources
* allocated by the returned #GList
*
* Since: 1.4
*/
GList *
clutter_actor_get_actions (ClutterActor *self)
{
const GList *actions;
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL);
if (self->priv->actions == NULL)
return NULL;
actions = _clutter_meta_group_peek_metas (self->priv->actions);
return g_list_copy ((GList *) actions);
}
/**
* clutter_actor_get_action:
* @self: a #ClutterActor
* @name: the name of the action to retrieve
*
* Retrieves the #ClutterAction with the given name in the list
* of actions applied to @self
*
* Return value: (transfer none): a #ClutterAction for the given
* name, or %NULL. The returned #ClutterAction is owned by the
* actor and it should not be unreferenced directly
*
* Since: 1.4
*/
ClutterAction *
clutter_actor_get_action (ClutterActor *self,
const gchar *name)
{
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL);
g_return_val_if_fail (name != NULL, NULL);
if (self->priv->actions == NULL)
return NULL;
return CLUTTER_ACTION (_clutter_meta_group_get_meta (self->priv->actions, name));
}
/**
* clutter_actor_clear_actions:
* @self: a #ClutterActor
*
* Clears the list of actions applied to @self
*
* Since: 1.4
*/
void
clutter_actor_clear_actions (ClutterActor *self)
{
g_return_if_fail (CLUTTER_IS_ACTOR (self));
if (self->priv->actions == NULL)
return;
_clutter_meta_group_clear_metas (self->priv->actions);
}
/**
* clutter_actor_add_constraint:
* @self: a #ClutterActor
* @constraint: a #ClutterConstraint
*
* Adds @constraint to the list of #ClutterConstraint<!-- -->s applied
* to @self
*
* The #ClutterActor will hold a reference on the @constraint until
* either clutter_actor_remove_constraint() or
* clutter_actor_clear_constraints() is called.
*
* Since: 1.4
*/
void
clutter_actor_add_constraint (ClutterActor *self,
ClutterConstraint *constraint)
{
ClutterActorPrivate *priv;
g_return_if_fail (CLUTTER_IS_ACTOR (self));
g_return_if_fail (CLUTTER_IS_CONSTRAINT (constraint));
priv = self->priv;
if (priv->constraints == NULL)
{
priv->constraints = g_object_new (CLUTTER_TYPE_META_GROUP, NULL);
priv->constraints->actor = self;
}
_clutter_meta_group_add_meta (priv->constraints,
CLUTTER_ACTOR_META (constraint));
g_object_notify (G_OBJECT (self), "constraints");
}
/**
* clutter_actor_add_constraint_with_name:
* @self: a #ClutterActor
* @name: the name to set on the constraint
* @constraint: a #ClutterConstraint
*
* A convenience function for setting the name of a #ClutterConstraint
* while adding it to the list of constraints applied to @self
*
* This function is the logical equivalent of:
*
* |[
* clutter_actor_meta_set_name (CLUTTER_ACTOR_META (constraint), name);
* clutter_actor_add_constraint (self, constraint);
* ]|
*
* Since: 1.4
*/
void
clutter_actor_add_constraint_with_name (ClutterActor *self,
const gchar *name,
ClutterConstraint *constraint)
{
g_return_if_fail (CLUTTER_IS_ACTOR (self));
g_return_if_fail (name != NULL);
g_return_if_fail (CLUTTER_IS_CONSTRAINT (constraint));
clutter_actor_meta_set_name (CLUTTER_ACTOR_META (constraint), name);
clutter_actor_add_constraint (self, constraint);
}
/**
* clutter_actor_remove_constraint:
* @self: a #ClutterActor
* @constraint: a #ClutterConstraint
*
* Removes @constraint from the list of constraints applied to @self
*
* The reference held by @self on the #ClutterConstraint will be released
*
* Since: 1.4
*/
void
clutter_actor_remove_constraint (ClutterActor *self,
ClutterConstraint *constraint)
{
ClutterActorPrivate *priv;
g_return_if_fail (CLUTTER_IS_ACTOR (self));
g_return_if_fail (CLUTTER_IS_CONSTRAINT (constraint));
priv = self->priv;
if (priv->constraints == NULL)
return;
_clutter_meta_group_remove_meta (priv->constraints,
CLUTTER_ACTOR_META (constraint));
g_object_notify (G_OBJECT (self), "constraints");
}
/**
* clutter_actor_remove_constraint_by_name:
* @self: a #ClutterActor
* @name: the name of the constraint to remove
*
* Removes the #ClutterConstraint with the given name from the list
* of constraints applied to @self
*
* Since: 1.4
*/
void
clutter_actor_remove_constraint_by_name (ClutterActor *self,
const gchar *name)
{
ClutterActorPrivate *priv;
ClutterActorMeta *meta;
g_return_if_fail (CLUTTER_IS_ACTOR (self));
g_return_if_fail (name != NULL);
priv = self->priv;
if (priv->constraints == NULL)
return;
meta = _clutter_meta_group_get_meta (priv->constraints, name);
if (meta == NULL)
return;
_clutter_meta_group_remove_meta (priv->constraints, meta);
}
/**
* clutter_actor_get_constraints:
* @self: a #ClutterActor
*
* Retrieves the list of constraints applied to @self
*
* Return value: (transfer container) (element-type ClutterConstraint): a copy
* of the list of #ClutterConstraint<!-- -->s. The contents of the list are
* owned by the #ClutterActor. Use g_list_free() to free the resources
* allocated by the returned #GList
*
* Since: 1.4
*/
GList *
clutter_actor_get_constraints (ClutterActor *self)
{
const GList *constraints;
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL);
if (self->priv->constraints == NULL)
return NULL;
constraints = _clutter_meta_group_peek_metas (self->priv->constraints);
return g_list_copy ((GList *) constraints);
}
/**
* clutter_actor_get_constraint:
* @self: a #ClutterActor
* @name: the name of the constraint to retrieve
*
* Retrieves the #ClutterConstraint with the given name in the list
* of constraints applied to @self
*
* Return value: (transfer none): a #ClutterConstraint for the given
* name, or %NULL. The returned #ClutterConstraint is owned by the
* actor and it should not be unreferenced directly
*
* Since: 1.4
*/
ClutterConstraint *
clutter_actor_get_constraint (ClutterActor *self,
const gchar *name)
{
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL);
g_return_val_if_fail (name != NULL, NULL);
if (self->priv->constraints == NULL)
return NULL;
return CLUTTER_CONSTRAINT (_clutter_meta_group_get_meta (self->priv->constraints, name));
}
/**
* clutter_actor_clear_constraints:
* @self: a #ClutterActor
*
* Clears the list of constraints applied to @self
*
* Since: 1.4
*/
void
clutter_actor_clear_constraints (ClutterActor *self)
{
g_return_if_fail (CLUTTER_IS_ACTOR (self));
if (self->priv->constraints == NULL)
return;
_clutter_meta_group_clear_metas (self->priv->constraints);
}

View File

@ -0,0 +1,335 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
/**
* SECTION:clutter-align-constraint
* @Title: ClutterAlignConstraint
* @Short_Description: A constraint aligning the position of an actor
*
* #ClutterAlignConstraint is a #ClutterConstraint that aligns the position
* of the #ClutterActor to which it is applied to the size of another
* #ClutterActor using an alignment factor
*
* #ClutterAlignConstraint is available since Clutter 1.4
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-align-constraint.h"
#include "clutter-constraint.h"
#include "clutter-debug.h"
#include "clutter-enum-types.h"
#include "clutter-private.h"
#define CLUTTER_ALIGN_CONSTRAINT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ALIGN_CONSTRAINT, ClutterAlignConstraintClass))
#define CLUTTER_IS_ALIGN_CONSTRAINT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ALIGN_CONSTRAINT))
#define CLUTTER_ALIGN_CONSTRAINT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ALIGN_CONSTRAINT, ClutterAlignConstraintClass))
typedef struct _ClutterAlignConstraintClass ClutterAlignConstraintClass;
struct _ClutterAlignConstraint
{
ClutterConstraint parent_instance;
ClutterActor *source;
ClutterAlignAxis align_axis;
gfloat factor;
};
struct _ClutterAlignConstraintClass
{
ClutterConstraintClass parent_class;
};
enum
{
PROP_0,
PROP_SOURCE,
PROP_ALIGN_AXIS,
PROP_FACTOR
};
G_DEFINE_TYPE (ClutterAlignConstraint,
clutter_align_constraint,
CLUTTER_TYPE_CONSTRAINT);
static void
update_actor_position (ClutterAlignConstraint *align)
{
gfloat source_width, source_height;
gfloat actor_width, actor_height;
ClutterActor *actor;
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (align)))
return;
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (align));
if (actor == NULL)
return;
clutter_actor_get_size (align->source, &source_width, &source_height);
clutter_actor_get_size (actor, &actor_width, &actor_height);
switch (align->align_axis)
{
case CLUTTER_ALIGN_X_AXIS:
clutter_actor_set_x (actor, (source_width - actor_width) * align->factor);
break;
case CLUTTER_ALIGN_Y_AXIS:
clutter_actor_set_y (actor, (source_height - actor_height) * align->factor);
break;
}
}
static void
source_position_changed (GObject *gobject,
GParamSpec *pspec,
ClutterAlignConstraint *align)
{
if (strcmp (pspec->name, "width") == 0 ||
strcmp (pspec->name, "height") == 0)
{
update_actor_position (align);
}
}
static void
source_destroyed (ClutterActor *actor,
ClutterAlignConstraint *align)
{
align->source = NULL;
}
static void
_clutter_align_constraint_set_source (ClutterAlignConstraint *align,
ClutterActor *source)
{
ClutterActor *old_source = align->source;
if (old_source != NULL)
{
g_signal_handlers_disconnect_by_func (old_source,
G_CALLBACK (source_destroyed),
align);
g_signal_handlers_disconnect_by_func (old_source,
G_CALLBACK (source_position_changed),
align);
}
align->source = source;
g_signal_connect (align->source, "notify",
G_CALLBACK (source_position_changed),
align);
g_signal_connect (align->source, "destroy",
G_CALLBACK (source_destroyed),
align);
update_actor_position (align);
g_object_notify (G_OBJECT (align), "source");
}
static void
_clutter_align_constraint_set_align_axis (ClutterAlignConstraint *align,
ClutterAlignAxis axis)
{
if (align->align_axis == axis)
return;
align->align_axis = axis;
update_actor_position (align);
g_object_notify (G_OBJECT (align), "align-axis");
}
static void
_clutter_align_constraint_set_factor (ClutterAlignConstraint *align,
gfloat factor)
{
align->factor = CLAMP (factor, 0.0, 1.0);
update_actor_position (align);
g_object_notify (G_OBJECT (align), "factor");
}
static void
clutter_align_constraint_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (gobject);
switch (prop_id)
{
case PROP_SOURCE:
_clutter_align_constraint_set_source (align, g_value_get_object (value));
break;
case PROP_ALIGN_AXIS:
_clutter_align_constraint_set_align_axis (align, g_value_get_enum (value));
break;
case PROP_FACTOR:
_clutter_align_constraint_set_factor (align, g_value_get_float (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_align_constraint_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (gobject);
switch (prop_id)
{
case PROP_SOURCE:
g_value_set_object (value, align->source);
break;
case PROP_ALIGN_AXIS:
g_value_set_enum (value, align->align_axis);
break;
case PROP_FACTOR:
g_value_set_float (value, align->factor);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_align_constraint_class_init (ClutterAlignConstraintClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
gobject_class->set_property = clutter_align_constraint_set_property;
gobject_class->get_property = clutter_align_constraint_get_property;
/**
* ClutterAlignConstraint:source:
*
* The #ClutterActor used as the source for the alignment
*
* Since: 1.4
*/
pspec = g_param_spec_object ("source",
"Source",
"The source of the alignment",
CLUTTER_TYPE_ACTOR,
CLUTTER_PARAM_READWRITE |
G_PARAM_CONSTRUCT);
g_object_class_install_property (gobject_class, PROP_SOURCE, pspec);
/**
* ClutterAlignConstraint:align-axis:
*
* The axis to be used to compute the alignment
*
* Since: 1.4
*/
pspec = g_param_spec_enum ("align-axis",
"Align Axis",
"The axis to align the position to",
CLUTTER_TYPE_ALIGN_AXIS,
CLUTTER_ALIGN_X_AXIS,
CLUTTER_PARAM_READWRITE |
G_PARAM_CONSTRUCT);
g_object_class_install_property (gobject_class, PROP_ALIGN_AXIS, pspec);
/**
* ClutterAlignConstraint:factor:
*
* The alignment factor, as a normalized value between 0.0 and 1.0
*
* The #ClutterAlignConstraint:factor depends on the
* #ClutterAlignConstraint:align-axis value: with %CLUTTER_ALIGN_X_AXIS,
* 0.0 means left and 1.0 means right; with %CLUTTER_ALIGN_Y_AXIS, 0.0
* means top and 1.0 means bottom
*
* Since: 1.4
*/
pspec = g_param_spec_float ("factor",
"Factor",
"The alignment factor, between 0.0 and 1.0",
0.0, 1.0,
0.0,
CLUTTER_PARAM_READWRITE |
G_PARAM_CONSTRUCT);
g_object_class_install_property (gobject_class, PROP_FACTOR, pspec);
}
static void
clutter_align_constraint_init (ClutterAlignConstraint *self)
{
self->source = NULL;
self->align_axis = CLUTTER_ALIGN_X_AXIS;
self->factor = 0.0f;
}
/**
* clutter_align_constraint_new:
* @source: the #ClutterActor to use as the source of the alignment
* @axis: the axis to be used to compute the alignment
* @factor: the alignment factor, between 0.0 and 1.0
*
* Creates a new constraint, aligning a #ClutterActor's position with
* regards of the size of the actor to @source, with the given alignment
* @factor
*
* Return value: the newly created #ClutterAlignConstraint
*
* Since: 1.4
*/
ClutterConstraint *
clutter_align_constraint_new (ClutterActor *source,
ClutterAlignAxis axis,
gfloat factor)
{
g_return_val_if_fail (CLUTTER_IS_ACTOR (source), NULL);
return g_object_new (CLUTTER_TYPE_ALIGN_CONSTRAINT,
"source", source,
"align-axis", axis,
"factor", factor,
NULL);
}

View File

@ -0,0 +1,73 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef __CLUTTER_ALIGN_CONSTRAINT_H__
#define __CLUTTER_ALIGN_CONSTRAINT_H__
#include <clutter/clutter-constraint.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_ALIGN_CONSTRAINT (clutter_align_constraint_get_type ())
#define CLUTTER_ALIGN_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ALIGN_CONSTRAINT, ClutterAlignConstraint))
#define CLUTTER_IS_ALIGN_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ALIGN_CONSTRAINT))
/**
* ClutterAlignConstraint:
*
* <structname>ClutterAlignConstraint</structname> is an opaque structure
* whose members cannot be directly accesses
*
* Since: 1.4
*/
typedef struct _ClutterAlignConstraint ClutterAlignConstraint;
/**
* ClutterAlignAxis:
* @CLUTTER_ALIGN_X_AXIS: Maintain the alignment on the X axis
* @CLUTTER_ALIGN_Y_AXIS: Maintain the alignment on the Y axis
*
* Specifies the axis on which #ClutterAlignConstraint should maintain
* the alignment
*
* Since: 1.4
*/
typedef enum { /*< prefix=CLUTTER_ALIGN >*/
CLUTTER_ALIGN_X_AXIS,
CLUTTER_ALIGN_Y_AXIS,
} ClutterAlignAxis;
GType clutter_align_constraint_get_type (void) G_GNUC_CONST;
ClutterConstraint *clutter_align_constraint_new (ClutterActor *source,
ClutterAlignAxis axis,
gfloat factor);
G_END_DECLS
#endif /* __CLUTTER_ALIGN_CONSTRAINT_H__ */

View File

@ -124,3 +124,101 @@ clutter_animatable_animate_property (ClutterAnimatable *animatable,
return res; return res;
} }
/**
* clutter_animatable_find_property:
* @animatable: a #ClutterAnimatable
* @animation: a #ClutterAnimation
* @property_name: the name of the animatable property to find
*
* Finds the #GParamSpec for @property_name
*
* Return value: (transfer none): The #GParamSpec for the given property
* or %NULL
*
* Since: 1.4
*/
GParamSpec *
clutter_animatable_find_property (ClutterAnimatable *animatable,
ClutterAnimation *animation,
const gchar *property_name)
{
ClutterAnimatableIface *iface;
g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), NULL);
g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), NULL);
g_return_val_if_fail (property_name != NULL, NULL);
CLUTTER_NOTE (ANIMATION, "Looking for property '%s'", property_name);
iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable);
if (iface->find_property != NULL)
return iface->find_property (animatable, animation, property_name);
return g_object_class_find_property (G_OBJECT_GET_CLASS (animatable),
property_name);
}
/**
* clutter_animatable_get_initial_state:
* @animatable: a #ClutterAnimatable
* @animation: a #ClutterAnimation
* @property_name: the name of the animatable property to retrieve
* @value: a #GValue initialized to the type of the property to retrieve
*
* Retrieves the current state of @property_name and sets @value with it
*
* Since: 1.4
*/
void
clutter_animatable_get_initial_state (ClutterAnimatable *animatable,
ClutterAnimation *animation,
const gchar *property_name,
GValue *value)
{
ClutterAnimatableIface *iface;
g_return_if_fail (CLUTTER_IS_ANIMATABLE (animatable));
g_return_if_fail (CLUTTER_IS_ANIMATION (animation));
g_return_if_fail (property_name != NULL);
CLUTTER_NOTE (ANIMATION, "Getting initial state of '%s'", property_name);
iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable);
if (iface->get_initial_state != NULL)
iface->get_initial_state (animatable, animation, property_name, value);
else
g_object_get_property (G_OBJECT (animatable), property_name, value);
}
/**
* clutter_animatable_set_final_state:
* @animatable: a #ClutterAnimatable
* @animation: a #ClutterAnimation
* @property_name: the name of the animatable property to set
* @value: the value of the animatable property to set
*
* Sets the current state of @property_name to @value
*
* Since: 1.4
*/
void
clutter_animatable_set_final_state (ClutterAnimatable *animatable,
ClutterAnimation *animation,
const gchar *property_name,
const GValue *value)
{
ClutterAnimatableIface *iface;
g_return_if_fail (CLUTTER_IS_ANIMATABLE (animatable));
g_return_if_fail (CLUTTER_IS_ANIMATION (animation));
g_return_if_fail (property_name != NULL);
CLUTTER_NOTE (ANIMATION, "Setting state of property '%s'", property_name);
iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable);
if (iface->set_final_state != NULL)
iface->set_final_state (animatable, animation, property_name, value);
else
g_object_set_property (G_OBJECT (animatable), property_name, value);
}

View File

@ -52,7 +52,14 @@ typedef struct _ClutterAnimatableIface ClutterAnimatableIface;
/** /**
* ClutterAnimatableIface: * ClutterAnimatableIface:
* @animate_property: virtual function for animating a property * @animate_property: virtual function for custom interpolation of a
* property
* @find_property: virtual function for retrieving the #GParamSpec of
* an animatable property
* @get_initial_state: virtual function for retrieving the initial
* state of an animatable property
* @set_final_state: virtual function for setting the state of an
* animatable property
* *
* Base interface for #GObject<!-- -->s that can be animated by a * Base interface for #GObject<!-- -->s that can be animated by a
* a #ClutterAnimation. * a #ClutterAnimation.
@ -72,6 +79,17 @@ struct _ClutterAnimatableIface
const GValue *final_value, const GValue *final_value,
gdouble progress, gdouble progress,
GValue *value); GValue *value);
GParamSpec *(* find_property) (ClutterAnimatable *animatable,
ClutterAnimation *animation,
const gchar *property_name);
void (* get_initial_state) (ClutterAnimatable *animatable,
ClutterAnimation *animation,
const gchar *property_name,
GValue *value);
void (* set_final_state) (ClutterAnimatable *animatable,
ClutterAnimation *animation,
const gchar *property_name,
const GValue *value);
}; };
GType clutter_animatable_get_type (void) G_GNUC_CONST; GType clutter_animatable_get_type (void) G_GNUC_CONST;
@ -84,6 +102,18 @@ gboolean clutter_animatable_animate_property (ClutterAnimatable *animatable,
gdouble progress, gdouble progress,
GValue *value); GValue *value);
GParamSpec *clutter_animatable_find_property (ClutterAnimatable *animatable,
ClutterAnimation *animation,
const gchar *property_name);
void clutter_animatable_get_initial_state (ClutterAnimatable *animatable,
ClutterAnimation *animation,
const gchar *property_name,
GValue *value);
void clutter_animatable_set_final_state (ClutterAnimatable *animatable,
ClutterAnimation *animation,
const gchar *property_name,
const GValue *value);
G_END_DECLS G_END_DECLS
#endif /* __CLUTTER_ANIMATABLE_H__ */ #endif /* __CLUTTER_ANIMATABLE_H__ */

View File

@ -212,6 +212,7 @@ static void
clutter_animation_real_completed (ClutterAnimation *self) clutter_animation_real_completed (ClutterAnimation *self)
{ {
ClutterAnimationPrivate *priv = self->priv; ClutterAnimationPrivate *priv = self->priv;
ClutterAnimatable *animatable = NULL;
ClutterAnimation *animation; ClutterAnimation *animation;
ClutterTimeline *timeline; ClutterTimeline *timeline;
ClutterTimelineDirection direction; ClutterTimelineDirection direction;
@ -221,6 +222,9 @@ clutter_animation_real_completed (ClutterAnimation *self)
timeline = clutter_animation_get_timeline (self); timeline = clutter_animation_get_timeline (self);
direction = clutter_timeline_get_direction (timeline); direction = clutter_timeline_get_direction (timeline);
if (CLUTTER_IS_ANIMATABLE (priv->object))
animatable = CLUTTER_ANIMATABLE (priv->object);
/* explicitly set the final state of the animation */ /* explicitly set the final state of the animation */
CLUTTER_NOTE (ANIMATION, "Set final state on object [%p]", priv->object); CLUTTER_NOTE (ANIMATION, "Set final state on object [%p]", priv->object);
g_hash_table_iter_init (&iter, priv->properties); g_hash_table_iter_init (&iter, priv->properties);
@ -235,6 +239,11 @@ clutter_animation_real_completed (ClutterAnimation *self)
else else
p_value = clutter_interval_peek_initial_value (interval); p_value = clutter_interval_peek_initial_value (interval);
if (animatable != NULL)
clutter_animatable_set_final_state (animatable, self,
p_name,
p_value);
else
g_object_set_property (priv->object, p_name, p_value); g_object_set_property (priv->object, p_name, p_value);
} }
@ -580,6 +589,7 @@ clutter_animation_init (ClutterAnimation *self)
static inline void static inline void
clutter_animation_bind_property_internal (ClutterAnimation *animation, clutter_animation_bind_property_internal (ClutterAnimation *animation,
const gchar *property_name,
GParamSpec *pspec, GParamSpec *pspec,
ClutterInterval *interval) ClutterInterval *interval)
{ {
@ -589,17 +599,18 @@ clutter_animation_bind_property_internal (ClutterAnimation *animation,
{ {
g_warning ("Cannot bind property '%s': the interval is out " g_warning ("Cannot bind property '%s': the interval is out "
"of bounds", "of bounds",
pspec->name); property_name);
return; return;
} }
g_hash_table_insert (priv->properties, g_hash_table_insert (priv->properties,
g_strdup (pspec->name), g_strdup (property_name),
g_object_ref_sink (interval)); g_object_ref_sink (interval));
} }
static inline void static inline void
clutter_animation_update_property_internal (ClutterAnimation *animation, clutter_animation_update_property_internal (ClutterAnimation *animation,
const gchar *property_name,
GParamSpec *pspec, GParamSpec *pspec,
ClutterInterval *interval) ClutterInterval *interval)
{ {
@ -609,12 +620,12 @@ clutter_animation_update_property_internal (ClutterAnimation *animation,
{ {
g_warning ("Cannot bind property '%s': the interval is out " g_warning ("Cannot bind property '%s': the interval is out "
"of bounds", "of bounds",
pspec->name); property_name);
return; return;
} }
g_hash_table_replace (priv->properties, g_hash_table_replace (priv->properties,
g_strdup (pspec->name), g_strdup (property_name),
g_object_ref_sink (interval)); g_object_ref_sink (interval));
} }
@ -624,7 +635,6 @@ clutter_animation_validate_bind (ClutterAnimation *animation,
GType argtype) GType argtype)
{ {
ClutterAnimationPrivate *priv; ClutterAnimationPrivate *priv;
GObjectClass *klass;
GParamSpec *pspec; GParamSpec *pspec;
GType pspec_type; GType pspec_type;
@ -647,9 +657,22 @@ clutter_animation_validate_bind (ClutterAnimation *animation,
return NULL; return NULL;
} }
klass = G_OBJECT_GET_CLASS (priv->object); if (CLUTTER_IS_ANIMATABLE (priv->object))
{
ClutterAnimatable *animatable = CLUTTER_ANIMATABLE (priv->object);
pspec = clutter_animatable_find_property (animatable,
animation,
property_name);
}
else
{
GObjectClass *klass = G_OBJECT_GET_CLASS (priv->object);
pspec = g_object_class_find_property (klass, property_name); pspec = g_object_class_find_property (klass, property_name);
if (!pspec) }
if (pspec == NULL)
{ {
g_warning ("Cannot bind property '%s': objects of type '%s' have " g_warning ("Cannot bind property '%s': objects of type '%s' have "
"no such property", "no such property",
@ -715,7 +738,9 @@ clutter_animation_bind_interval (ClutterAnimation *animation,
if (pspec == NULL) if (pspec == NULL)
return NULL; return NULL;
clutter_animation_bind_property_internal (animation, pspec, interval); clutter_animation_bind_property_internal (animation, property_name,
pspec,
interval);
return animation; return animation;
} }
@ -760,12 +785,21 @@ clutter_animation_bind (ClutterAnimation *animation,
return NULL; return NULL;
g_value_init (&initial, G_PARAM_SPEC_VALUE_TYPE (pspec)); g_value_init (&initial, G_PARAM_SPEC_VALUE_TYPE (pspec));
if (CLUTTER_IS_ANIMATABLE (priv->object))
clutter_animatable_get_initial_state (CLUTTER_ANIMATABLE (priv->object),
animation,
property_name,
&initial);
else
g_object_get_property (priv->object, property_name, &initial); g_object_get_property (priv->object, property_name, &initial);
interval = clutter_interval_new_with_values (type, &initial, final); interval = clutter_interval_new_with_values (type, &initial, final);
g_value_unset (&initial); g_value_unset (&initial);
clutter_animation_bind_property_internal (animation, pspec, interval); clutter_animation_bind_property_internal (animation, property_name,
pspec,
interval);
return animation; return animation;
} }
@ -845,7 +879,6 @@ clutter_animation_update_interval (ClutterAnimation *animation,
ClutterInterval *interval) ClutterInterval *interval)
{ {
ClutterAnimationPrivate *priv; ClutterAnimationPrivate *priv;
GObjectClass *klass;
GParamSpec *pspec; GParamSpec *pspec;
GType pspec_type, int_type; GType pspec_type, int_type;
@ -863,9 +896,22 @@ clutter_animation_update_interval (ClutterAnimation *animation,
return; return;
} }
klass = G_OBJECT_GET_CLASS (priv->object); if (CLUTTER_IS_ANIMATABLE (priv->object))
{
ClutterAnimatable *animatable = CLUTTER_ANIMATABLE (priv->object);
pspec = clutter_animatable_find_property (animatable,
animation,
property_name);
}
else
{
GObjectClass *klass = G_OBJECT_GET_CLASS (priv->object);
pspec = g_object_class_find_property (klass, property_name); pspec = g_object_class_find_property (klass, property_name);
if (!pspec) }
if (pspec == NULL)
{ {
g_warning ("Cannot update property '%s': objects of type '%s' have " g_warning ("Cannot update property '%s': objects of type '%s' have "
"no such property", "no such property",
@ -889,7 +935,9 @@ clutter_animation_update_interval (ClutterAnimation *animation,
return; return;
} }
clutter_animation_update_property_internal (animation, pspec, interval); clutter_animation_update_property_internal (animation, property_name,
pspec,
interval);
} }
/** /**
@ -1050,7 +1098,14 @@ on_alpha_notify (GObject *gobject,
} }
if (apply) if (apply)
{
if (is_animatable)
clutter_animatable_set_final_state (animatable, animation,
p_name,
&value);
else
g_object_set_property (priv->object, p_name, &value); g_object_set_property (priv->object, p_name, &value);
}
g_value_unset (&value); g_value_unset (&value);
} }
@ -1688,6 +1743,13 @@ done:
GValue cur_value = { 0, }; GValue cur_value = { 0, };
g_value_init (&cur_value, G_PARAM_SPEC_VALUE_TYPE (pspec)); g_value_init (&cur_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
if (CLUTTER_IS_ANIMATABLE (priv->object))
clutter_animatable_get_initial_state (CLUTTER_ANIMATABLE (priv->object),
animation,
property_name,
&cur_value);
else
g_object_get_property (priv->object, property_name, &cur_value); g_object_get_property (priv->object, property_name, &cur_value);
interval = interval =
@ -1695,19 +1757,27 @@ done:
&cur_value, &cur_value,
&real_value); &real_value);
if (!clutter_animation_has_property (animation, pspec->name)) if (!clutter_animation_has_property (animation, property_name))
clutter_animation_bind_property_internal (animation, clutter_animation_bind_property_internal (animation, property_name,
pspec, pspec,
interval); interval);
else else
clutter_animation_update_property_internal (animation, clutter_animation_update_property_internal (animation, property_name,
pspec, pspec,
interval); interval);
g_value_unset (&cur_value); g_value_unset (&cur_value);
} }
else
{
if (CLUTTER_IS_ANIMATABLE (priv->object))
clutter_animatable_set_final_state (CLUTTER_ANIMATABLE (priv->object),
animation,
property_name,
&real_value);
else else
g_object_set_property (priv->object, property_name, &real_value); g_object_set_property (priv->object, property_name, &real_value);
}
g_value_unset (&real_value); g_value_unset (&real_value);
} }
@ -1719,10 +1789,14 @@ clutter_animation_setupv (ClutterAnimation *animation,
const GValue *values) const GValue *values)
{ {
ClutterAnimationPrivate *priv = animation->priv; ClutterAnimationPrivate *priv = animation->priv;
GObjectClass *klass; ClutterAnimatable *animatable = NULL;
gint i; GObjectClass *klass = NULL;
gboolean is_fixed = FALSE; gboolean is_fixed = FALSE;
gint i;
if (CLUTTER_IS_ANIMATABLE (priv->object))
animatable = CLUTTER_ANIMATABLE (priv->object);
else
klass = G_OBJECT_GET_CLASS (priv->object); klass = G_OBJECT_GET_CLASS (priv->object);
for (i = 0; i < n_properties; i++) for (i = 0; i < n_properties; i++)
@ -1736,8 +1810,14 @@ clutter_animation_setupv (ClutterAnimation *animation,
is_fixed = TRUE; is_fixed = TRUE;
} }
if (animatable != NULL)
pspec = clutter_animatable_find_property (animatable,
animation,
property_name);
else
pspec = g_object_class_find_property (klass, property_name); pspec = g_object_class_find_property (klass, property_name);
if (!pspec)
if (pspec == NULL)
{ {
g_warning ("Cannot bind property '%s': objects of type '%s' do " g_warning ("Cannot bind property '%s': objects of type '%s' do "
"not have this property", "not have this property",
@ -1792,9 +1872,13 @@ clutter_animation_setup_valist (ClutterAnimation *animation,
va_list var_args) va_list var_args)
{ {
ClutterAnimationPrivate *priv = animation->priv; ClutterAnimationPrivate *priv = animation->priv;
GObjectClass *klass; ClutterAnimatable *animatable = NULL;
GObjectClass *klass = NULL;
const gchar *property_name; const gchar *property_name;
if (CLUTTER_IS_ANIMATABLE (priv->object))
animatable = CLUTTER_ANIMATABLE (priv->object);
else
klass = G_OBJECT_GET_CLASS (priv->object); klass = G_OBJECT_GET_CLASS (priv->object);
property_name = first_property_name; property_name = first_property_name;
@ -1827,8 +1911,14 @@ clutter_animation_setup_valist (ClutterAnimation *animation,
is_fixed = TRUE; is_fixed = TRUE;
} }
if (animatable != NULL)
pspec = clutter_animatable_find_property (animatable,
animation,
property_name);
else
pspec = g_object_class_find_property (klass, property_name); pspec = g_object_class_find_property (klass, property_name);
if (!pspec)
if (pspec == NULL)
{ {
g_warning ("Cannot bind property '%s': objects of type '%s' do " g_warning ("Cannot bind property '%s': objects of type '%s' do "
"not have this property", "not have this property",
@ -1899,7 +1989,7 @@ animation_create_for_actor (ClutterActor *actor)
* @actor: a #ClutterActor * @actor: a #ClutterActor
* @alpha: a #ClutterAlpha * @alpha: a #ClutterAlpha
* @first_property_name: the name of a property * @first_property_name: the name of a property
* @VarArgs: a %NULL terminated list of property names and * @Varargs: a %NULL terminated list of property names and
* property values * property values
* *
* Animates the given list of properties of @actor between the current * Animates the given list of properties of @actor between the current
@ -1956,7 +2046,7 @@ clutter_actor_animate_with_alpha (ClutterActor *actor,
* @mode: an animation mode logical id * @mode: an animation mode logical id
* @timeline: a #ClutterTimeline * @timeline: a #ClutterTimeline
* @first_property_name: the name of a property * @first_property_name: the name of a property
* @VarArgs: a %NULL terminated list of property names and * @Varargs: a %NULL terminated list of property names and
* property values * property values
* *
* Animates the given list of properties of @actor between the current * Animates the given list of properties of @actor between the current
@ -2007,7 +2097,7 @@ clutter_actor_animate_with_timeline (ClutterActor *actor,
* @mode: an animation mode logical id * @mode: an animation mode logical id
* @duration: duration of the animation, in milliseconds * @duration: duration of the animation, in milliseconds
* @first_property_name: the name of a property * @first_property_name: the name of a property
* @VarArgs: a %NULL terminated list of property names and * @Varargs: a %NULL terminated list of property names and
* property values * property values
* *
* Animates the given list of properties of @actor between the current * Animates the given list of properties of @actor between the current

View File

@ -1150,7 +1150,7 @@ clutter_animator_get_duration (ClutterAnimator *animator)
* @first_mode: the id of the alpha function to use * @first_mode: the id of the alpha function to use
* @first_progress: at which stage of the animation this value applies; the * @first_progress: at which stage of the animation this value applies; the
* range is a normalized floating point value between 0 and 1 * range is a normalized floating point value between 0 and 1
* @VarArgs: the value first_property_name should have for first_object * @Varargs: the value first_property_name should have for first_object
* at first_progress, followed by more (object, property_name, mode, * at first_progress, followed by more (object, property_name, mode,
* progress, value) tuples, followed by %NULL * progress, value) tuples, followed by %NULL
* *

View File

@ -0,0 +1,337 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
/**
* SECTION:clutter-bind-constraint
* @Title: ClutterBindConstraint
* @Short_Description: A constraint binding the position of an actor
*
* #ClutterBindConstraint is a #ClutterConstraint that binds the position of
* the #ClutterActor to which it is applied to the the position of another
* #ClutterActor.
*
* #ClutterBindConstraint is available since Clutter 1.4
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-bind-constraint.h"
#include "clutter-constraint.h"
#include "clutter-debug.h"
#include "clutter-enum-types.h"
#include "clutter-private.h"
#define CLUTTER_BIND_CONSTRAINT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BIND_CONSTRAINT, ClutterBindConstraintClass))
#define CLUTTER_IS_BIND_CONSTRAINT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BIND_CONSTRAINT))
#define CLUTTER_BIND_CONSTRAINT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BIND_CONSTRAINT, ClutterBindConstraintClass))
typedef struct _ClutterBindConstraintClass ClutterBindConstraintClass;
struct _ClutterBindConstraint
{
ClutterConstraint parent_instance;
ClutterActor *source;
ClutterBindCoordinate coordinate;
gfloat offset;
};
struct _ClutterBindConstraintClass
{
ClutterConstraintClass parent_class;
};
enum
{
PROP_0,
PROP_SOURCE,
PROP_COORDINATE,
PROP_OFFSET
};
G_DEFINE_TYPE (ClutterBindConstraint,
clutter_bind_constraint,
CLUTTER_TYPE_CONSTRAINT);
static void
update_actor_position (ClutterBindConstraint *bind)
{
ClutterVertex source_position;
ClutterActor *actor;
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (bind)))
return;
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (bind));
if (actor == NULL)
return;
source_position.x = clutter_actor_get_x (bind->source);
source_position.y = clutter_actor_get_y (bind->source);
source_position.z = clutter_actor_get_depth (bind->source);
switch (bind->coordinate)
{
case CLUTTER_BIND_X:
clutter_actor_set_x (actor, source_position.x + bind->offset);
break;
case CLUTTER_BIND_Y:
clutter_actor_set_y (actor, source_position.y + bind->offset);
break;
case CLUTTER_BIND_Z:
clutter_actor_set_depth (actor, source_position.z + bind->offset);
break;
}
}
static void
source_position_changed (GObject *gobject,
GParamSpec *pspec,
ClutterBindConstraint *bind)
{
if (strcmp (pspec->name, "x") == 0 ||
strcmp (pspec->name, "y") == 0 ||
strcmp (pspec->name, "depth") == 0)
{
update_actor_position (bind);
}
}
static void
source_destroyed (ClutterActor *actor,
ClutterBindConstraint *bind)
{
bind->source = NULL;
}
static void
_clutter_bind_constraint_set_source (ClutterBindConstraint *bind,
ClutterActor *source)
{
ClutterActor *old_source = bind->source;
if (old_source != NULL)
{
g_signal_handlers_disconnect_by_func (old_source,
G_CALLBACK (source_destroyed),
bind);
g_signal_handlers_disconnect_by_func (old_source,
G_CALLBACK (source_position_changed),
bind);
}
bind->source = source;
g_signal_connect (bind->source, "notify",
G_CALLBACK (source_position_changed),
bind);
g_signal_connect (bind->source, "destroy",
G_CALLBACK (source_destroyed),
bind);
update_actor_position (bind);
g_object_notify (G_OBJECT (bind), "source");
}
static void
_clutter_bind_constraint_set_coordinate (ClutterBindConstraint *bind,
ClutterBindCoordinate coord)
{
if (bind->coordinate == coord)
return;
bind->coordinate = coord;
update_actor_position (bind);
g_object_notify (G_OBJECT (bind), "coordinate");
}
static void
_clutter_bind_constraint_set_offset (ClutterBindConstraint *bind,
gfloat offset)
{
if (fabs (bind->offset - offset) < 0.00001f)
return;
bind->offset = offset;
update_actor_position (bind);
g_object_notify (G_OBJECT (bind), "offset");
}
static void
clutter_bind_constraint_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (gobject);
switch (prop_id)
{
case PROP_SOURCE:
_clutter_bind_constraint_set_source (bind, g_value_get_object (value));
break;
case PROP_COORDINATE:
_clutter_bind_constraint_set_coordinate (bind, g_value_get_enum (value));
break;
case PROP_OFFSET:
_clutter_bind_constraint_set_offset (bind, g_value_get_float (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_bind_constraint_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (gobject);
switch (prop_id)
{
case PROP_SOURCE:
g_value_set_object (value, bind->source);
break;
case PROP_COORDINATE:
g_value_set_enum (value, bind->coordinate);
break;
case PROP_OFFSET:
g_value_set_float (value, bind->offset);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_bind_constraint_class_init (ClutterBindConstraintClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
gobject_class->set_property = clutter_bind_constraint_set_property;
gobject_class->get_property = clutter_bind_constraint_get_property;
/**
* ClutterBindConstraint:source:
*
* The #ClutterActor used as the source for the binding
*
* Since: 1.4
*/
pspec = g_param_spec_object ("source",
"Source",
"The source of the binding",
CLUTTER_TYPE_ACTOR,
CLUTTER_PARAM_READWRITE |
G_PARAM_CONSTRUCT);
g_object_class_install_property (gobject_class, PROP_SOURCE, pspec);
/**
* ClutterBindConstraint:coordinate:
*
* The coordinate to be bound
*
* Since: 1.4
*/
pspec = g_param_spec_enum ("coordinate",
"Coordinate",
"The coordinate to bind",
CLUTTER_TYPE_BIND_COORDINATE,
CLUTTER_BIND_X,
CLUTTER_PARAM_READWRITE |
G_PARAM_CONSTRUCT);
g_object_class_install_property (gobject_class, PROP_COORDINATE, pspec);
/**
* ClutterBindConstraint:offset:
*
* The offset, in pixels, to be applied to the binding
*
* Since: 1.4
*/
pspec = g_param_spec_float ("offset",
"Offset",
"The offset in pixels to apply to the binding",
-G_MAXFLOAT, G_MAXFLOAT,
0.0f,
CLUTTER_PARAM_READWRITE |
G_PARAM_CONSTRUCT);
g_object_class_install_property (gobject_class, PROP_OFFSET, pspec);
}
static void
clutter_bind_constraint_init (ClutterBindConstraint *self)
{
self->source = NULL;
self->coordinate = CLUTTER_BIND_X;
self->offset = 0.0f;
}
/**
* clutter_bind_constraint_new:
* @source: the #ClutterActor to use as the source of the binding
* @coordinate: the coordinate to bind
* @offset: the offset to apply to the binding, in pixels
*
* Creates a new constraint, binding a #ClutterActor's position to
* the given @coordinate of the position of @source
*
* Return value: the newly created #ClutterBindConstraint
*
* Since: 1.4
*/
ClutterConstraint *
clutter_bind_constraint_new (ClutterActor *source,
ClutterBindCoordinate coordinate,
gfloat offset)
{
g_return_val_if_fail (CLUTTER_IS_ACTOR (source), NULL);
return g_object_new (CLUTTER_TYPE_BIND_CONSTRAINT,
"source", source,
"coordinate", coordinate,
"offset", offset,
NULL);
}

View File

@ -0,0 +1,74 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef __CLUTTER_BIND_CONSTRAINT_H__
#define __CLUTTER_BIND_CONSTRAINT_H__
#include <clutter/clutter-constraint.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_BIND_CONSTRAINT (clutter_bind_constraint_get_type ())
#define CLUTTER_BIND_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BIND_CONSTRAINT, ClutterBindConstraint))
#define CLUTTER_IS_BIND_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BIND_CONSTRAINT))
/**
* ClutterBindConstraint:
*
* <structname>ClutterBindConstraint</structname> is an opaque structure
* whose members cannot be directly accessed
*
* Since: 1.4
*/
typedef struct _ClutterBindConstraint ClutterBindConstraint;
/**
* ClutterBindCoordinate:
* @CLUTTER_BIND_X: Bind the X coordinate
* @CLUTTER_BIND_Y: Bind the Y coordinate
* @CLUTTER_BIND_Z: Bind the Z coordinate
*
* Specifies which coordinate should be used in a binding
*
* Since: 1.4
*/
typedef enum { /*< prefix=CLUTTER_BIND >*/
CLUTTER_BIND_X,
CLUTTER_BIND_Y,
CLUTTER_BIND_Z
} ClutterBindCoordinate;
GType clutter_bind_constraint_get_type (void) G_GNUC_CONST;
ClutterConstraint *clutter_bind_constraint_new (ClutterActor *source,
ClutterBindCoordinate coordinate,
gfloat offset);
G_END_DECLS
#endif /* __CLUTTER_BIND_CONSTRAINT_H__ */

View File

@ -1419,7 +1419,7 @@ clutter_box_layout_get_vertical (ClutterBoxLayout *layout)
/** /**
* clutter_box_layout_set_homogeneous: * clutter_box_layout_set_homogeneous:
* @layout: a #ClutterBoxLayout * @layout: a #ClutterBoxLayout
* @vertical: %TRUE if the layout should be homogeneous * @homogeneous: %TRUE if the layout should be homogeneous
* *
* Sets whether the size of @layout children should be * Sets whether the size of @layout children should be
* homogeneous * homogeneous

View File

@ -0,0 +1,33 @@
/**
* SECTION:clutter-constraint
* @Title: ClutterConstraint
* @Short_Description: A constraint on an actor's position or size
* @See_Also: #ClutterAction
*
* #ClutterConstraint is a base abstract class for modifiers of a #ClutterActor
* position or size.
*
* #ClutterConstraint is available since Clutter 1.4
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-constraint.h"
#include "clutter-actor-meta-private.h"
G_DEFINE_ABSTRACT_TYPE (ClutterConstraint,
clutter_constraint,
CLUTTER_TYPE_ACTOR_META);
static void
clutter_constraint_class_init (ClutterConstraintClass *klass)
{
}
static void
clutter_constraint_init (ClutterConstraint *self)
{
}

View File

@ -0,0 +1,102 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef __CLUTTER_CONSTRAINT_H__
#define __CLUTTER_CONSTRAINT_H__
#include <clutter/clutter-actor-meta.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_CONSTRAINT (clutter_constraint_get_type ())
#define CLUTTER_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CONSTRAINT, ClutterConstraint))
#define CLUTTER_IS_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CONSTRAINT))
#define CLUTTER_CONSTRAINT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_CONSTRAINT, ClutterConstraintClass))
#define CLUTTER_IS_CONSTRAINT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_CONSTRAINT))
#define CLUTTER_CONSTRAINT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_CONSTRAINT, ClutterConstraintClass))
typedef struct _ClutterConstraintClass ClutterConstraintClass;
/**
* ClutterConstraint:
*
* The <structname>ClutterConstraint</structname> structure contains only
* private data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _ClutterConstraint
{
/*< private >*/
ClutterActorMeta parent_instance;
};
/**
* ClutterConstraintClass:
*
* The <structname>ClutterConstraintClass</structname> structure contains
* only private data
*
* Since: 1.4
*/
struct _ClutterConstraintClass
{
/*< private >*/
ClutterActorMetaClass parent_class;
/*< private >*/
void (* _clutter_constraint1) (void);
void (* _clutter_constraint2) (void);
void (* _clutter_constraint3) (void);
void (* _clutter_constraint4) (void);
void (* _clutter_constraint5) (void);
void (* _clutter_constraint6) (void);
void (* _clutter_constraint7) (void);
void (* _clutter_constraint8) (void);
};
GType clutter_constraint_get_type (void) G_GNUC_CONST;
/* ClutterActor API */
void clutter_actor_add_constraint (ClutterActor *self,
ClutterConstraint *constraint);
void clutter_actor_add_constraint_with_name (ClutterActor *self,
const gchar *name,
ClutterConstraint *constraint);
void clutter_actor_remove_constraint (ClutterActor *self,
ClutterConstraint *constraint);
void clutter_actor_remove_constraint_by_name (ClutterActor *self,
const gchar *name);
GList * clutter_actor_get_constraints (ClutterActor *self);
ClutterConstraint *clutter_actor_get_constraint (ClutterActor *self,
const gchar *name);
void clutter_actor_clear_constraints (ClutterActor *self);
G_END_DECLS
#endif /* __CLUTTER_CONSTRAINT_H__ */

View File

@ -0,0 +1,813 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
/**
* SECTION:clutter-drag-action
* @Title: ClutterDragAction
* @Short_Description: Action enabling dragging on actors
*
* #ClutterDragAction is a sub-class of #ClutterAction that implements
* all the necessary logic for dragging actors.
*
* The simplest usage of #ClutterDragAction consists in adding it to
* a #ClutterActor and connecting to the #ClutterDragAction::drag-motion
* signal handler to move the actor; for instance:
*
* |[
* ClutterAction *action = clutter_drag_action_new ();
*
* g_signal_connect (action, "drag-motion",
* G_CALLBACK (on_drag_motion),
* NULL);
*
* clutter_actor_add_action (actor, action);
* ]|
*
* Where the on_drag_motion() signal handler calls clutter_actor_move_by()
* using the delta between motion events passed to the handler:
*
* |[
* static void
* on_drag_motion (ClutterDragAction *action,
* ClutterActor *actor,
* gfloat delta_x,
* gfloat delta_y,
* ClutterModifierType modifiers)
* {
* clutter_actor_move_by (actor, delta_x, delta_y);
* }
* ]|
*
* It is also possible to set another #ClutterActor as the dragged actor
* by calling clutter_drag_action_set_drag_handle() from within a handle
* of the #ClutterDragAction::drag-begin signal. The drag handle must be
* parented and exist between the emission of #ClutterDragAction::drag-begin
* and #ClutterDragAction::drag-end.
*
* #ClutterDragAction is available since Clutter 1.4
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-drag-action.h"
#include "clutter-debug.h"
#include "clutter-enum-types.h"
#include "clutter-marshal.h"
#include "clutter-private.h"
struct _ClutterDragActionPrivate
{
ClutterActor *stage;
gfloat drag_threshold;
ClutterActor *drag_handle;
ClutterDragAxis drag_axis;
gulong button_press_id;
gulong capture_id;
gfloat press_x;
gfloat press_y;
ClutterModifierType press_state;
gint press_button;
gfloat last_motion_x;
gfloat last_motion_y;
gfloat transformed_press_x;
gfloat transformed_press_y;
guint emit_delayed_press : 1;
guint in_drag : 1;
};
enum
{
PROP_0,
PROP_DRAG_THRESHOLD,
PROP_DRAG_HANDLE,
PROP_DRAG_AXIS
};
enum
{
DRAG_BEGIN,
DRAG_MOTION,
DRAG_END,
LAST_SIGNAL
};
static guint drag_signals[LAST_SIGNAL] = { 0, };
/* forward declaration */
static gboolean on_captured_event (ClutterActor *stage,
ClutterEvent *event,
ClutterDragAction *action);
G_DEFINE_TYPE (ClutterDragAction, clutter_drag_action, CLUTTER_TYPE_ACTION);
static void
emit_drag_begin (ClutterDragAction *action,
ClutterActor *actor,
ClutterEvent *event)
{
ClutterDragActionPrivate *priv = action->priv;
g_signal_emit (action, drag_signals[DRAG_BEGIN], 0,
actor,
priv->press_x, priv->press_y,
priv->press_button,
priv->press_state);
}
static void
emit_drag_motion (ClutterDragAction *action,
ClutterActor *actor,
ClutterEvent *event)
{
ClutterDragActionPrivate *priv = action->priv;
ClutterActor *drag_handle = NULL;
gfloat delta_x, delta_y;
gfloat motion_x, motion_y;
clutter_event_get_coords (event, &priv->last_motion_x, &priv->last_motion_y);
if (priv->drag_handle != NULL && !priv->emit_delayed_press)
drag_handle = priv->drag_handle;
else
drag_handle = actor;
motion_x = motion_y = 0.0f;
clutter_actor_transform_stage_point (drag_handle,
priv->last_motion_x,
priv->last_motion_y,
&motion_x, &motion_y);
delta_x = delta_y = 0.0f;
switch (priv->drag_axis)
{
case CLUTTER_DRAG_AXIS_NONE:
delta_x = motion_x - priv->transformed_press_x;
delta_y = motion_y - priv->transformed_press_y;
break;
case CLUTTER_DRAG_X_AXIS:
delta_x = motion_x - priv->transformed_press_x;
break;
case CLUTTER_DRAG_Y_AXIS:
delta_y = motion_y - priv->transformed_press_y;
break;
default:
g_assert_not_reached ();
return;
}
if (priv->emit_delayed_press)
{
if (ABS (delta_x) >= priv->drag_threshold ||
ABS (delta_y) >= priv->drag_threshold)
{
priv->emit_delayed_press = FALSE;
emit_drag_begin (action, actor, NULL);
}
else
return;
}
g_signal_emit (action, drag_signals[DRAG_MOTION], 0,
actor,
delta_x, delta_y);
}
static void
emit_drag_end (ClutterDragAction *action,
ClutterActor *actor,
ClutterEvent *event)
{
ClutterDragActionPrivate *priv = action->priv;
clutter_event_get_coords (event, &priv->last_motion_x, &priv->last_motion_y);
/* we might not have emitted ::drag-begin yet */
if (!priv->emit_delayed_press)
g_signal_emit (action, drag_signals[DRAG_END], 0,
actor,
priv->last_motion_x, priv->last_motion_y,
clutter_event_get_button (event),
clutter_event_get_state (event));
/* disconnect the capture */
if (priv->capture_id != 0)
{
g_signal_handler_disconnect (priv->stage, priv->capture_id);
priv->capture_id = 0;
}
priv->in_drag = FALSE;
}
static gboolean
on_captured_event (ClutterActor *stage,
ClutterEvent *event,
ClutterDragAction *action)
{
ClutterDragActionPrivate *priv = action->priv;
ClutterActor *actor;
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
if (!priv->in_drag)
return FALSE;
switch (clutter_event_type (event))
{
case CLUTTER_MOTION:
{
ClutterModifierType mods = clutter_event_get_state (event);
/* we might miss a button-release event in case of grabs,
* so we need to check whether the button is still down
* during a motion event
*/
if (mods & CLUTTER_BUTTON1_MASK)
emit_drag_motion (action, actor, event);
else
emit_drag_end (action, actor, event);
}
break;
case CLUTTER_BUTTON_RELEASE:
if (priv->in_drag)
emit_drag_end (action, actor, event);
break;
default:
break;
}
return FALSE;
}
static gboolean
on_button_press (ClutterActor *actor,
ClutterEvent *event,
ClutterDragAction *action)
{
ClutterDragActionPrivate *priv = action->priv;
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action)))
return FALSE;
if (priv->stage == NULL)
priv->stage = clutter_actor_get_stage (actor);
clutter_event_get_coords (event, &priv->press_x, &priv->press_y);
priv->press_button = clutter_event_get_button (event);
priv->press_state = clutter_event_get_state (event);
priv->last_motion_x = priv->press_x;
priv->last_motion_y = priv->press_y;
priv->transformed_press_x = priv->press_x;
priv->transformed_press_y = priv->press_y;
clutter_actor_transform_stage_point (actor, priv->press_x, priv->press_y,
&priv->transformed_press_x,
&priv->transformed_press_y);
if (priv->drag_threshold == 0)
emit_drag_begin (action, actor, event);
else
priv->emit_delayed_press = TRUE;
priv->in_drag = TRUE;
priv->capture_id = g_signal_connect_after (priv->stage, "captured-event",
G_CALLBACK (on_captured_event),
action);
return FALSE;
}
static void
clutter_drag_action_set_actor (ClutterActorMeta *meta,
ClutterActor *actor)
{
ClutterDragActionPrivate *priv = CLUTTER_DRAG_ACTION (meta)->priv;
if (priv->button_press_id != 0)
{
ClutterActor *old_actor;
old_actor = clutter_actor_meta_get_actor (meta);
g_signal_handler_disconnect (old_actor, priv->button_press_id);
if (priv->capture_id != 0)
g_signal_handler_disconnect (old_actor, priv->capture_id);
priv->button_press_id = 0;
priv->capture_id = 0;
priv->stage = NULL;
}
if (actor != NULL)
priv->button_press_id = g_signal_connect (actor, "button-press-event",
G_CALLBACK (on_button_press),
meta);
CLUTTER_ACTOR_META_CLASS (clutter_drag_action_parent_class)->set_actor (meta, actor);
}
static void
clutter_drag_action_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterDragAction *action = CLUTTER_DRAG_ACTION (gobject);
switch (prop_id)
{
case PROP_DRAG_THRESHOLD:
clutter_drag_action_set_drag_threshold (action, g_value_get_uint (value));
break;
case PROP_DRAG_HANDLE:
clutter_drag_action_set_drag_handle (action, g_value_get_object (value));
break;
case PROP_DRAG_AXIS:
clutter_drag_action_set_drag_axis (action, g_value_get_enum (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
}
}
static void
clutter_drag_action_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ClutterDragActionPrivate *priv = CLUTTER_DRAG_ACTION (gobject)->priv;
switch (prop_id)
{
case PROP_DRAG_THRESHOLD:
g_value_set_uint (value, priv->drag_threshold);
break;
case PROP_DRAG_HANDLE:
g_value_set_object (value, priv->drag_handle);
break;
case PROP_DRAG_AXIS:
g_value_set_enum (value, priv->drag_axis);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
}
}
static void
clutter_drag_action_dispose (GObject *gobject)
{
ClutterDragActionPrivate *priv = CLUTTER_DRAG_ACTION (gobject)->priv;
if (priv->capture_id != 0)
{
if (priv->stage != NULL)
g_signal_handler_disconnect (priv->stage, priv->capture_id);
priv->capture_id = 0;
priv->stage = NULL;
}
if (priv->button_press_id != 0)
{
ClutterActor *actor;
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (gobject));
g_signal_handler_disconnect (actor, priv->button_press_id);
priv->button_press_id = 0;
}
G_OBJECT_CLASS (clutter_drag_action_parent_class)->dispose (gobject);
}
static void
clutter_drag_action_class_init (ClutterDragActionClass *klass)
{
ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
g_type_class_add_private (klass, sizeof (ClutterDragActionPrivate));
gobject_class->set_property = clutter_drag_action_set_property;
gobject_class->get_property = clutter_drag_action_get_property;
gobject_class->dispose = clutter_drag_action_dispose;
meta_class->set_actor = clutter_drag_action_set_actor;
/**
* ClutterDragAction:drag-threshold:
*
* The threshold, in pixels, that begins a drag action
*
* When set to a non-zero value, #ClutterDragAction will only emit
* #ClutterDragAction::drag-begin if the pointer has moved at least
* of the given amount of pixels since the button press event
*
* Since: 1.4
*/
pspec = g_param_spec_uint ("drag-threshold",
"Drag Threshold",
"The amount of pixels required to start "
"dragging",
0, G_MAXUINT,
0,
CLUTTER_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_DRAG_THRESHOLD, pspec);
/**
* ClutterDragAction:drag-handle:
*
* The #ClutterActor that is effectively being dragged
*
* A #ClutterDragActor will, be default, use the #ClutterActor that
* has been attached to the action; it is possible to create a
* separate #ClutterActor and use it instead.
*
* Setting this property has no effect on the #ClutterActor argument
* passed to the #ClutterDragAction signals
*
* Since: 1.4
*/
pspec = g_param_spec_object ("drag-handle",
"Drag Handle",
"The actor that is being dragged",
CLUTTER_TYPE_ACTOR,
CLUTTER_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_DRAG_HANDLE, pspec);
/**
* ClutterDragAction:drag-axis:
*
* Constraints the dragging action to the specified axis
*
* Since: 1.4
*/
pspec = g_param_spec_enum ("drag-axis",
"Drag Axis",
"Constraints the dragging to an axis",
CLUTTER_TYPE_DRAG_AXIS,
CLUTTER_DRAG_AXIS_NONE,
CLUTTER_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_DRAG_AXIS, pspec);
/**
* ClutterDragAction::drag-begin:
* @action: the #ClutterDragAction that emitted the signal
* @actor: the #ClutterActor attached to the action
* @event_x: the X coordinate (in stage space) of the press event
* @event_y: the Y coordinate (in stage space) of the press event
* @button: the button of the press event
* @modifiers: the modifiers of the press event
*
* The ::drag-begin signal is emitted when the #ClutterDragAction
* starts the dragging
*
* The emission of this signal can be delayed by using the
* #ClutterDragAction:drag-threshold property
*
* Since: 1.4
*/
drag_signals[DRAG_BEGIN] =
g_signal_new (I_("drag-begin"),
CLUTTER_TYPE_DRAG_ACTION,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterDragActionClass, drag_begin),
NULL, NULL,
clutter_marshal_VOID__OBJECT_FLOAT_FLOAT_INT_FLAGS,
G_TYPE_NONE, 5,
CLUTTER_TYPE_ACTOR,
G_TYPE_FLOAT,
G_TYPE_FLOAT,
G_TYPE_INT,
CLUTTER_TYPE_MODIFIER_TYPE);
/**
* ClutterDragAction::drag-motion
* @action: the #ClutterDragAction that emitted the signal
* @actor: the #ClutterActor attached to the action
* @delta_x: the X component of the distance between the press event
* that began the dragging and the current position of the pointer,
* as of the latest motion event
* @delta_y: the Y component of the distance between the press event
* that began the dragging and the current position of the pointer,
* as of the latest motion event
* @modifiers: the modifiers of the latest motion event
*
* The ::drag-motion signal is emitted for each motion event after
* the #ClutterDragAction::drag-begin signal has been emitted.
*
* The components of the distance between the press event and the
* latest motion event are computed in the actor's coordinate space,
* to take into account eventual transformations. If you want the
* stage coordinates of the latest motion event you can use
* clutter_drag_action_get_motion_coords().
*
* Since: 1.4
*/
drag_signals[DRAG_MOTION] =
g_signal_new (I_("drag-motion"),
CLUTTER_TYPE_DRAG_ACTION,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterDragActionClass, drag_motion),
NULL, NULL,
clutter_marshal_VOID__OBJECT_FLOAT_FLOAT,
G_TYPE_NONE, 3,
CLUTTER_TYPE_ACTOR,
G_TYPE_FLOAT,
G_TYPE_FLOAT);
/**
* ClutterDragAction::drag-end:
* @action: the #ClutterDragAction that emitted the signal
* @actor: the #ClutterActor attached to the action
* @event_x: the X coordinate (in stage space) of the release event
* @event_y: the Y coordinate (in stage space) of the release event
* @button: the button of the release event
* @modifiers: the modifiers of the release event
*
* The ::drag-end signal is emitted at the end of the dragging,
* when the pointer button's is released
*
* This signal is emitted if and only if the #ClutterDragAction::drag-begin
* signal has been emitted first
*
* Since: 1.4
*/
drag_signals[DRAG_END] =
g_signal_new (I_("drag-end"),
CLUTTER_TYPE_DRAG_ACTION,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterDragActionClass, drag_end),
NULL, NULL,
clutter_marshal_VOID__OBJECT_FLOAT_FLOAT_INT_FLAGS,
G_TYPE_NONE, 5,
CLUTTER_TYPE_ACTOR,
G_TYPE_FLOAT,
G_TYPE_FLOAT,
G_TYPE_INT,
CLUTTER_TYPE_MODIFIER_TYPE);
}
static void
clutter_drag_action_init (ClutterDragAction *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, CLUTTER_TYPE_DRAG_ACTION,
ClutterDragActionPrivate);
}
/**
* clutter_drag_action_new:
*
* Creates a new #ClutterDragAction instance
*
* Return value: the newly created #ClutterDragAction
*
* Since: 1.4
*/
ClutterAction *
clutter_drag_action_new (void)
{
return g_object_new (CLUTTER_TYPE_DRAG_ACTION, NULL);
}
/**
* clutter_drag_action_set_drag_threshold:
* @action: a #ClutterDragAction
* @threshold: a distance, in pixels
*
* Sets the drag threshold that must be cleared by the pointer
* before @action can begin the dragging
*
* Since: 1.4
*/
void
clutter_drag_action_set_drag_threshold (ClutterDragAction *action,
guint threshold)
{
ClutterDragActionPrivate *priv;
g_return_if_fail (CLUTTER_IS_DRAG_ACTION (action));
priv = action->priv;
if (priv->drag_threshold == threshold)
return;
priv->drag_threshold = threshold;
g_object_notify (G_OBJECT (action), "drag-threshold");
}
/**
* clutter_drag_action_get_drag_threshold:
* @action: a #ClutterDragAction
*
* Retrieves the value set by clutter_drag_action_set_drag_threshold()
*
* Return value: the drag threshold value, in pixels
*
* Since: 1.4
*/
guint
clutter_drag_action_get_drag_threshold (ClutterDragAction *action)
{
g_return_val_if_fail (CLUTTER_IS_DRAG_ACTION (action), 0);
return action->priv->drag_threshold;
}
/**
* clutter_drag_action_set_drag_handle:
* @action: a #ClutterDragHandle
* @handle: a #ClutterActor
*
* Sets the actor to be used as the drag handle
*
* Since: 1.4
*/
void
clutter_drag_action_set_drag_handle (ClutterDragAction *action,
ClutterActor *handle)
{
ClutterDragActionPrivate *priv;
g_return_if_fail (CLUTTER_IS_DRAG_ACTION (action));
g_return_if_fail (CLUTTER_IS_ACTOR (handle));
priv = action->priv;
if (priv->drag_handle == handle)
return;
priv->drag_handle = handle;
g_object_notify (G_OBJECT (action), "drag-handle");
}
/**
* clutter_drag_action_get_drag_handle:
* @action: a #ClutterDragAction
*
* Retrieves the drag handle set by clutter_drag_action_set_drag_handle()
*
* Return value: (transfer none): a #ClutterActor, used as the drag
* handle, or %NULL if none was set
*
* Since: 1.4
*/
ClutterActor *
clutter_drag_action_get_drag_handle (ClutterDragAction *action)
{
g_return_val_if_fail (CLUTTER_IS_DRAG_ACTION (action), NULL);
return action->priv->drag_handle;
}
/**
* clutter_drag_action_set_drag_axis:
* @action: a #ClutterDragAction
* @axis: the axis to constraint the dragging to
*
* Restricts the dragging action to a specific axis
*
* Since: 1.4
*/
void
clutter_drag_action_set_drag_axis (ClutterDragAction *action,
ClutterDragAxis axis)
{
ClutterDragActionPrivate *priv;
g_return_if_fail (CLUTTER_IS_DRAG_ACTION (action));
g_return_if_fail (axis >= CLUTTER_DRAG_AXIS_NONE &&
axis <= CLUTTER_DRAG_Y_AXIS);
priv = action->priv;
if (priv->drag_axis == axis)
return;
priv->drag_axis = axis;
g_object_notify (G_OBJECT (action), "drag-axis");
}
/**
* clutter_drag_action_get_drag_axis:
* @action: a #ClutterDragAction
*
* Retrieves the axis constraint set by clutter_drag_action_set_drag_axis()
*
* Return value: the axis constraint
*
* Since: 1.4
*/
ClutterDragAxis
clutter_drag_action_get_drag_axis (ClutterDragAction *action)
{
g_return_val_if_fail (CLUTTER_IS_DRAG_ACTION (action),
CLUTTER_DRAG_AXIS_NONE);
return action->priv->drag_axis;
}
/**
* clutter_drag_action_get_press_coords:
* @action: a #ClutterDragAction
* @press_x: (out): return location for the press event's X coordinate
* @press_y: (out): return location for the press event's Y coordinate
*
* Retrieves the coordinates, in stage space, of the press event
* that started the dragging
*
* Since: 1.4
*/
void
clutter_drag_action_get_press_coords (ClutterDragAction *action,
gfloat *press_x,
gfloat *press_y)
{
g_return_if_fail (CLUTTER_IS_DRAG_ACTION (action));
if (press_x)
*press_x = action->priv->press_x;
if (press_y)
*press_y = action->priv->press_y;
}
/**
* clutter_drag_action_get_motion_coords:
* @action: a #ClutterDragAction
* @motion_x: (out): return location for the latest motion
* event's X coordinate
* @motion_y: (out): return location for the latest motion
* event's Y coordinate
*
* Retrieves the coordinates, in stage space, of the latest motion
* event during the dragging
*
* Since: 1.4
*/
void
clutter_drag_action_get_motion_coords (ClutterDragAction *action,
gfloat *motion_x,
gfloat *motion_y)
{
g_return_if_fail (CLUTTER_IS_DRAG_ACTION (action));
if (motion_x)
*motion_x = action->priv->last_motion_x;
if (motion_y)
*motion_y = action->priv->last_motion_y;
}

View File

@ -0,0 +1,148 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef __CLUTTER_DRAG_ACTION_H__
#define __CLUTTER_DRAG_ACTION_H__
#include <clutter/clutter-action.h>
#include <clutter/clutter-event.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_DRAG_ACTION (clutter_drag_action_get_type ())
#define CLUTTER_DRAG_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_DRAG_ACTION, ClutterDragAction))
#define CLUTTER_IS_DRAG_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_DRAG_ACTION))
#define CLUTTER_DRAG_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_DRAG_ACTION, ClutterDragActionClass))
#define CLUTTER_IS_DRAG_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_DRAG_ACTION))
#define CLUTTER_DRAG_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_DRAG_ACTION, ClutterDragActionClass))
typedef struct _ClutterDragAction ClutterDragAction;
typedef struct _ClutterDragActionPrivate ClutterDragActionPrivate;
typedef struct _ClutterDragActionClass ClutterDragActionClass;
/**
* ClutterDragAxis:
* @CLUTTER_DRAG_AXIS_NONE: No constraint
* @CLUTTER_DRAG_X_AXIS: Set a constraint on the X axis
* @CLUTTER_DRAG_Y_AXIS: Set a constraint on the Y axis
*
* The axis of the constraint that should be applied on the
* dragging action
*
* Since: 1.4
*/
typedef enum { /*< prefix=CLUTTER_DRAG >*/
CLUTTER_DRAG_AXIS_NONE = 0,
CLUTTER_DRAG_X_AXIS,
CLUTTER_DRAG_Y_AXIS
} ClutterDragAxis;
/**
* ClutterDragAction:
*
* The <structname>ClutterDragAction</structname> structure contains only
* private data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _ClutterDragAction
{
/*< private >*/
ClutterAction parent_instance;
ClutterDragActionPrivate *priv;
};
/**
* ClutterDragActionClass:
* @drag_begin: class handler of the #ClutterDragAction::drag-begin signal
* @drag_motion: class handler of the #ClutterDragAction::drag-motion signal
* @drag_end: class handler of the #ClutterDragAction::drag-end signal
*
* The <structname>ClutterDragActionClass</structname> structure contains
* only private data
*
* Since: 1.4
*/
struct _ClutterDragActionClass
{
/*< private >*/
ClutterActionClass parent_class;
/*< public >*/
void (* drag_begin) (ClutterDragAction *action,
ClutterActor *actor,
gfloat event_x,
gfloat event_y,
gint button,
ClutterModifierType modifiers);
void (* drag_motion) (ClutterDragAction *action,
ClutterActor *actor,
gfloat delta_x,
gfloat delta_y,
ClutterModifierType modifiers);
void (* drag_end) (ClutterDragAction *action,
ClutterActor *actor,
gfloat event_x,
gfloat event_y,
gint button,
ClutterModifierType modifiers);
/*< private >*/
void (* _clutter_drag_action1) (void);
void (* _clutter_drag_action2) (void);
void (* _clutter_drag_action3) (void);
void (* _clutter_drag_action4) (void);
void (* _clutter_drag_action5) (void);
};
GType clutter_drag_action_get_type (void) G_GNUC_CONST;
ClutterAction * clutter_drag_action_new (void);
void clutter_drag_action_set_drag_threshold (ClutterDragAction *action,
guint threshold);
guint clutter_drag_action_get_drag_threshold (ClutterDragAction *action);
void clutter_drag_action_set_drag_handle (ClutterDragAction *action,
ClutterActor *handle);
ClutterActor * clutter_drag_action_get_drag_handle (ClutterDragAction *action);
void clutter_drag_action_set_drag_axis (ClutterDragAction *action,
ClutterDragAxis axis);
ClutterDragAxis clutter_drag_action_get_drag_axis (ClutterDragAction *action);
void clutter_drag_action_get_press_coords (ClutterDragAction *action,
gfloat *press_x,
gfloat *press_y);
void clutter_drag_action_get_motion_coords (ClutterDragAction *action,
gfloat *motion_x,
gfloat *motion_y);
G_END_DECLS
#endif /* __CLUTTER_DRAG_ACTION_H__ */

View File

@ -417,7 +417,6 @@ struct _ClutterStageStateEvent
/** /**
* ClutterEvent: * ClutterEvent:
* @type: event type
* *
* Generic event wrapper. * Generic event wrapper.
* *
@ -425,6 +424,7 @@ struct _ClutterStageStateEvent
*/ */
union _ClutterEvent union _ClutterEvent
{ {
/*< private >*/
ClutterEventType type; ClutterEventType type;
ClutterAnyEvent any; ClutterAnyEvent any;

View File

@ -10,6 +10,8 @@ VOID:INT,INT
VOID:FLOAT,FLOAT VOID:FLOAT,FLOAT
VOID:INT,INT,INT,INT VOID:INT,INT,INT,INT
VOID:OBJECT VOID:OBJECT
VOID:OBJECT,FLOAT,FLOAT
VOID:OBJECT,FLOAT,FLOAT,INT,FLAGS
VOID:OBJECT,OBJECT,PARAM VOID:OBJECT,OBJECT,PARAM
VOID:OBJECT,POINTER VOID:OBJECT,POINTER
VOID:POINTER VOID:POINTER

View File

@ -65,6 +65,7 @@ struct _ClutterMediaIface
/*< private >*/ /*< private >*/
GTypeInterface base_iface; GTypeInterface base_iface;
/*< public >*/
/* signals */ /* signals */
void (* eos) (ClutterMedia *media); void (* eos) (ClutterMedia *media);
void (* error) (ClutterMedia *media, void (* error) (ClutterMedia *media,

View File

@ -53,10 +53,6 @@ typedef struct _ClutterStageManagerClass ClutterStageManagerClass;
/** /**
* ClutterStageManagerClass: * ClutterStageManagerClass:
* @stage_added: class handler for the #ClutterStageManager::stage-added
* signal
* @stage_removed: class handler for the #ClutterStageManager::stage-removed
* signal
* *
* The #ClutterStageManagerClass structure contains only private data * The #ClutterStageManagerClass structure contains only private data
* and should be accessed using the provided API * and should be accessed using the provided API

View File

@ -40,12 +40,18 @@ G_BEGIN_DECLS
/* Forward delarations to avoid header catch 22's */ /* Forward delarations to avoid header catch 22's */
typedef struct _ClutterActor ClutterActor; typedef struct _ClutterActor ClutterActor;
typedef struct _ClutterStage ClutterStage; typedef struct _ClutterStage ClutterStage;
typedef struct _ClutterContainer ClutterContainer; /* dummy */ typedef struct _ClutterContainer ClutterContainer; /* dummy */
typedef struct _ClutterChildMeta ClutterChildMeta; typedef struct _ClutterChildMeta ClutterChildMeta;
typedef struct _ClutterLayoutMeta ClutterLayoutMeta; typedef struct _ClutterLayoutMeta ClutterLayoutMeta;
typedef struct _ClutterActorMeta ClutterActorMeta;
typedef struct _ClutterAnimator ClutterAnimator; typedef struct _ClutterAnimator ClutterAnimator;
typedef struct _ClutterAction ClutterAction;
typedef struct _ClutterConstraint ClutterConstraint;
typedef union _ClutterEvent ClutterEvent; typedef union _ClutterEvent ClutterEvent;
/** /**

View File

@ -30,7 +30,10 @@
#include "clutter-deprecated.h" #include "clutter-deprecated.h"
#include "clutter-action.h"
#include "clutter-actor.h" #include "clutter-actor.h"
#include "clutter-actor-meta.h"
#include "clutter-align-constraint.h"
#include "clutter-alpha.h" #include "clutter-alpha.h"
#include "clutter-animatable.h" #include "clutter-animatable.h"
#include "clutter-animation.h" #include "clutter-animation.h"
@ -43,6 +46,7 @@
#include "clutter-behaviour-path.h" #include "clutter-behaviour-path.h"
#include "clutter-behaviour-rotate.h" #include "clutter-behaviour-rotate.h"
#include "clutter-behaviour-scale.h" #include "clutter-behaviour-scale.h"
#include "clutter-bind-constraint.h"
#include "clutter-binding-pool.h" #include "clutter-binding-pool.h"
#include "clutter-bin-layout.h" #include "clutter-bin-layout.h"
#include "clutter-box.h" #include "clutter-box.h"
@ -51,8 +55,10 @@
#include "clutter-child-meta.h" #include "clutter-child-meta.h"
#include "clutter-clone.h" #include "clutter-clone.h"
#include "clutter-color.h" #include "clutter-color.h"
#include "clutter-constraint.h"
#include "clutter-container.h" #include "clutter-container.h"
#include "clutter-device-manager.h" #include "clutter-device-manager.h"
#include "clutter-drag-action.h"
#include "clutter-event.h" #include "clutter-event.h"
#include "clutter-feature.h" #include "clutter-feature.h"
#include "clutter-fixed-layout.h" #include "clutter-fixed-layout.h"

View File

@ -27,7 +27,7 @@
#include "json-types-private.h" #include "json-types-private.h"
/** /*
* SECTION:json-array * SECTION:json-array
* @short_description: a JSON array representation * @short_description: a JSON array representation
* *
@ -57,7 +57,7 @@ json_array_get_type (void)
return array_type; return array_type;
} }
/** /*
* json_array_new: * json_array_new:
* *
* Creates a new #JsonArray. * Creates a new #JsonArray.
@ -77,7 +77,7 @@ json_array_new (void)
return array; return array;
} }
/** /*
* json_array_sized_new: * json_array_sized_new:
* @n_elements: number of slots to pre-allocate * @n_elements: number of slots to pre-allocate
* *
@ -98,7 +98,7 @@ json_array_sized_new (guint n_elements)
return array; return array;
} }
/** /*
* json_array_ref: * json_array_ref:
* @array: a #JsonArray * @array: a #JsonArray
* *
@ -118,7 +118,7 @@ json_array_ref (JsonArray *array)
return array; return array;
} }
/** /*
* json_array_unref: * json_array_unref:
* @array: a #JsonArray * @array: a #JsonArray
* *
@ -151,7 +151,7 @@ json_array_unref (JsonArray *array)
} }
} }
/** /*
* json_array_get_elements: * json_array_get_elements:
* @array: a #JsonArray * @array: a #JsonArray
* *
@ -178,7 +178,7 @@ json_array_get_elements (JsonArray *array)
return g_list_reverse (retval); return g_list_reverse (retval);
} }
/** /*
* json_array_dup_element: * json_array_dup_element:
* @array: a #JsonArray * @array: a #JsonArray
* @index_: the index of the element to retrieve * @index_: the index of the element to retrieve
@ -207,7 +207,7 @@ json_array_dup_element (JsonArray *array,
return json_node_copy (retval); return json_node_copy (retval);
} }
/** /*
* json_array_get_element: * json_array_get_element:
* @array: a #JsonArray * @array: a #JsonArray
* @index_: the index of the element to retrieve * @index_: the index of the element to retrieve
@ -227,7 +227,7 @@ json_array_get_element (JsonArray *array,
return g_ptr_array_index (array->elements, index_); return g_ptr_array_index (array->elements, index_);
} }
/** /*
* json_array_get_int_element: * json_array_get_int_element:
* @array: a #JsonArray * @array: a #JsonArray
* @index_: the index of the element to retrieve * @index_: the index of the element to retrieve
@ -257,7 +257,7 @@ json_array_get_int_element (JsonArray *array,
return json_node_get_int (node); return json_node_get_int (node);
} }
/** /*
* json_array_get_double_element: * json_array_get_double_element:
* @array: a #JsonArray * @array: a #JsonArray
* @index_: the index of the element to retrieve * @index_: the index of the element to retrieve
@ -287,7 +287,7 @@ json_array_get_double_element (JsonArray *array,
return json_node_get_double (node); return json_node_get_double (node);
} }
/** /*
* json_array_get_boolean_element: * json_array_get_boolean_element:
* @array: a #JsonArray * @array: a #JsonArray
* @index_: the index of the element to retrieve * @index_: the index of the element to retrieve
@ -317,7 +317,7 @@ json_array_get_boolean_element (JsonArray *array,
return json_node_get_boolean (node); return json_node_get_boolean (node);
} }
/** /*
* json_array_get_string_element: * json_array_get_string_element:
* @array: a #JsonArray * @array: a #JsonArray
* @index_: the index of the element to retrieve * @index_: the index of the element to retrieve
@ -348,7 +348,7 @@ json_array_get_string_element (JsonArray *array,
return json_node_get_string (node); return json_node_get_string (node);
} }
/** /*
* json_array_get_null_element: * json_array_get_null_element:
* @array: a #JsonArray * @array: a #JsonArray
* @index_: the index of the element to retrieve * @index_: the index of the element to retrieve
@ -376,7 +376,7 @@ json_array_get_null_element (JsonArray *array,
return JSON_NODE_TYPE (node) == JSON_NODE_NULL; return JSON_NODE_TYPE (node) == JSON_NODE_NULL;
} }
/** /*
* json_array_get_array_element: * json_array_get_array_element:
* @array: a #JsonArray * @array: a #JsonArray
* @index_: the index of the element to retrieve * @index_: the index of the element to retrieve
@ -406,7 +406,7 @@ json_array_get_array_element (JsonArray *array,
return json_node_get_array (node); return json_node_get_array (node);
} }
/** /*
* json_array_get_object_element: * json_array_get_object_element:
* @array: a #JsonArray * @array: a #JsonArray
* @index_: the index of the element to retrieve * @index_: the index of the element to retrieve
@ -436,7 +436,7 @@ json_array_get_object_element (JsonArray *array,
return json_node_get_object (node); return json_node_get_object (node);
} }
/** /*
* json_array_get_length: * json_array_get_length:
* @array: a #JsonArray * @array: a #JsonArray
* *
@ -452,7 +452,7 @@ json_array_get_length (JsonArray *array)
return array->elements->len; return array->elements->len;
} }
/** /*
* json_array_add_element: * json_array_add_element:
* @array: a #JsonArray * @array: a #JsonArray
* @node: a #JsonNode * @node: a #JsonNode
@ -470,7 +470,7 @@ json_array_add_element (JsonArray *array,
g_ptr_array_add (array->elements, node); g_ptr_array_add (array->elements, node);
} }
/** /*
* json_array_add_int_element: * json_array_add_int_element:
* @array: a #JsonArray * @array: a #JsonArray
* @value: an integer value * @value: an integer value
@ -495,7 +495,7 @@ json_array_add_int_element (JsonArray *array,
g_ptr_array_add (array->elements, node); g_ptr_array_add (array->elements, node);
} }
/** /*
* json_array_add_double_element: * json_array_add_double_element:
* @array: a #JsonArray * @array: a #JsonArray
* @value: a floating point value * @value: a floating point value
@ -520,7 +520,7 @@ json_array_add_double_element (JsonArray *array,
g_ptr_array_add (array->elements, node); g_ptr_array_add (array->elements, node);
} }
/** /*
* json_array_add_boolean_element: * json_array_add_boolean_element:
* @array: a #JsonArray * @array: a #JsonArray
* @value: a boolean value * @value: a boolean value
@ -545,7 +545,7 @@ json_array_add_boolean_element (JsonArray *array,
g_ptr_array_add (array->elements, node); g_ptr_array_add (array->elements, node);
} }
/** /*
* json_array_add_string_element: * json_array_add_string_element:
* @array: a #JsonArray * @array: a #JsonArray
* @value: a string value * @value: a string value
@ -571,7 +571,7 @@ json_array_add_string_element (JsonArray *array,
g_ptr_array_add (array->elements, node); g_ptr_array_add (array->elements, node);
} }
/** /*
* json_array_add_null_element: * json_array_add_null_element:
* @array: a #JsonArray * @array: a #JsonArray
* *
@ -593,7 +593,7 @@ json_array_add_null_element (JsonArray *array)
g_ptr_array_add (array->elements, node); g_ptr_array_add (array->elements, node);
} }
/** /*
* json_array_add_array_element: * json_array_add_array_element:
* @array: a #JsonArray * @array: a #JsonArray
* @value: a #JsonArray * @value: a #JsonArray
@ -620,7 +620,7 @@ json_array_add_array_element (JsonArray *array,
g_ptr_array_add (array->elements, node); g_ptr_array_add (array->elements, node);
} }
/** /*
* json_array_add_object_element: * json_array_add_object_element:
* @array: a #JsonArray * @array: a #JsonArray
* @value: a #JsonObject * @value: a #JsonObject
@ -647,7 +647,7 @@ json_array_add_object_element (JsonArray *array,
g_ptr_array_add (array->elements, node); g_ptr_array_add (array->elements, node);
} }
/** /*
* json_array_remove_element: * json_array_remove_element:
* @array: a #JsonArray * @array: a #JsonArray
* @index_: the position of the element to be removed * @index_: the position of the element to be removed
@ -665,7 +665,7 @@ json_array_remove_element (JsonArray *array,
json_node_free (g_ptr_array_remove_index (array->elements, index_)); json_node_free (g_ptr_array_remove_index (array->elements, index_));
} }
/** /*
* json_array_foreach_element: * json_array_foreach_element:
* @array: a #JsonArray * @array: a #JsonArray
* @func: the function to be called on each element * @func: the function to be called on each element

View File

@ -21,7 +21,7 @@
* Emmanuele Bassi <ebassi@linux.intel.com> * Emmanuele Bassi <ebassi@linux.intel.com>
*/ */
/** /*
* SECTION:json-generator * SECTION:json-generator
* @short_description: Generates JSON data streams * @short_description: Generates JSON data streams
* *
@ -191,7 +191,7 @@ json_generator_class_init (JsonGeneratorClass *klass)
gobject_class->get_property = json_generator_get_property; gobject_class->get_property = json_generator_get_property;
gobject_class->finalize = json_generator_finalize; gobject_class->finalize = json_generator_finalize;
/** /*
* JsonGenerator:pretty: * JsonGenerator:pretty:
* *
* Whether the output should be "pretty-printed", with indentation and * Whether the output should be "pretty-printed", with indentation and
@ -205,7 +205,7 @@ json_generator_class_init (JsonGeneratorClass *klass)
"Pretty-print the output", "Pretty-print the output",
FALSE, FALSE,
G_PARAM_READWRITE)); G_PARAM_READWRITE));
/** /*
* JsonGenerator:indent: * JsonGenerator:indent:
* *
* Number of spaces to be used to indent when pretty printing. * Number of spaces to be used to indent when pretty printing.
@ -218,7 +218,7 @@ json_generator_class_init (JsonGeneratorClass *klass)
0, G_MAXUINT, 0, G_MAXUINT,
2, 2,
G_PARAM_READWRITE)); G_PARAM_READWRITE));
/** /*
* JsonGenerator:root: * JsonGenerator:root:
* *
* The root #JsonNode to be used when constructing a JSON data * The root #JsonNode to be used when constructing a JSON data
@ -233,7 +233,7 @@ json_generator_class_init (JsonGeneratorClass *klass)
"Root of the JSON data tree", "Root of the JSON data tree",
JSON_TYPE_NODE, JSON_TYPE_NODE,
G_PARAM_READWRITE)); G_PARAM_READWRITE));
/** /*
* JsonGenerator:indent-char: * JsonGenerator:indent-char:
* *
* The character that should be used when indenting in pretty print. * The character that should be used when indenting in pretty print.
@ -519,7 +519,7 @@ dump_object (JsonGenerator *generator,
return g_string_free (buffer, FALSE); return g_string_free (buffer, FALSE);
} }
/** /*
* json_generator_new: * json_generator_new:
* *
* Creates a new #JsonGenerator. You can use this object to generate a * Creates a new #JsonGenerator. You can use this object to generate a
@ -534,7 +534,7 @@ json_generator_new (void)
return g_object_new (JSON_TYPE_GENERATOR, NULL); return g_object_new (JSON_TYPE_GENERATOR, NULL);
} }
/** /*
* json_generator_to_data: * json_generator_to_data:
* @generator: a #JsonGenerator * @generator: a #JsonGenerator
* @length: (out): return location for the length of the returned * @length: (out): return location for the length of the returned
@ -588,7 +588,7 @@ json_generator_to_data (JsonGenerator *generator,
return retval; return retval;
} }
/** /*
* json_generator_to_file: * json_generator_to_file:
* @generator: a #JsonGenerator * @generator: a #JsonGenerator
* @filename: path to the target file * @filename: path to the target file
@ -618,7 +618,7 @@ json_generator_to_file (JsonGenerator *generator,
return retval; return retval;
} }
/** /*
* json_generator_set_root: * json_generator_set_root:
* @generator: a #JsonGenerator * @generator: a #JsonGenerator
* @node: a #JsonNode * @node: a #JsonNode

View File

@ -29,7 +29,7 @@
#include "json-types-private.h" #include "json-types-private.h"
/** /*
* SECTION:json-node * SECTION:json-node
* @short_description: Node in a JSON object model * @short_description: Node in a JSON object model
* *
@ -61,7 +61,7 @@ json_node_get_type (void)
return node_type; return node_type;
} }
/** /*
* json_node_get_value_type: * json_node_get_value_type:
* @node: a #JsonNode * @node: a #JsonNode
* *
@ -96,7 +96,7 @@ json_node_get_value_type (JsonNode *node)
} }
} }
/** /*
* json_node_new: * json_node_new:
* @type: a #JsonNodeType * @type: a #JsonNodeType
* *
@ -118,7 +118,7 @@ json_node_new (JsonNodeType type)
return data; return data;
} }
/** /*
* json_node_copy: * json_node_copy:
* @node: a #JsonNode * @node: a #JsonNode
* *
@ -167,7 +167,7 @@ json_node_copy (JsonNode *node)
return copy; return copy;
} }
/** /*
* json_node_set_object: * json_node_set_object:
* @node: a #JsonNode * @node: a #JsonNode
* @object: a #JsonObject * @object: a #JsonObject
@ -190,7 +190,7 @@ json_node_set_object (JsonNode *node,
node->data.object = NULL; node->data.object = NULL;
} }
/** /*
* json_node_take_object: * json_node_take_object:
* @node: a #JsonNode * @node: a #JsonNode
* @object: a #JsonObject * @object: a #JsonObject
@ -214,7 +214,7 @@ json_node_take_object (JsonNode *node,
node->data.object = object; node->data.object = object;
} }
/** /*
* json_node_get_object: * json_node_get_object:
* @node: a #JsonNode * @node: a #JsonNode
* *
@ -231,7 +231,7 @@ json_node_get_object (JsonNode *node)
return node->data.object; return node->data.object;
} }
/** /*
* json_node_dup_object: * json_node_dup_object:
* @node: a #JsonNode * @node: a #JsonNode
* *
@ -252,7 +252,7 @@ json_node_dup_object (JsonNode *node)
return NULL; return NULL;
} }
/** /*
* json_node_set_array: * json_node_set_array:
* @node: a #JsonNode * @node: a #JsonNode
* @array: a #JsonArray * @array: a #JsonArray
@ -275,7 +275,7 @@ json_node_set_array (JsonNode *node,
node->data.array = NULL; node->data.array = NULL;
} }
/** /*
* json_node_take_array: * json_node_take_array:
* @node: a #JsonNode * @node: a #JsonNode
* @array: a #JsonArray * @array: a #JsonArray
@ -299,7 +299,7 @@ json_node_take_array (JsonNode *node,
node->data.array = array; node->data.array = array;
} }
/** /*
* json_node_get_array: * json_node_get_array:
* @node: a #JsonNode * @node: a #JsonNode
* *
@ -316,7 +316,7 @@ json_node_get_array (JsonNode *node)
return node->data.array; return node->data.array;
} }
/** /*
* json_node_dup_array * json_node_dup_array
* @node: a #JsonNode * @node: a #JsonNode
* *
@ -337,7 +337,7 @@ json_node_dup_array (JsonNode *node)
return NULL; return NULL;
} }
/** /*
* json_node_get_value: * json_node_get_value:
* @node: a #JsonNode * @node: a #JsonNode
* @value: return location for an uninitialized value * @value: return location for an uninitialized value
@ -366,7 +366,7 @@ node_value_unset (JsonNode *node)
g_value_unset (&(node->data.value)); g_value_unset (&(node->data.value));
} }
/** /*
* json_node_set_value: * json_node_set_value:
* @node: a #JsonNode * @node: a #JsonNode
* @value: the #GValue to set * @value: the #GValue to set
@ -417,7 +417,7 @@ json_node_set_value (JsonNode *node,
} }
/** /*
* json_node_free: * json_node_free:
* @node: a #JsonNode * @node: a #JsonNode
* *
@ -452,7 +452,7 @@ json_node_free (JsonNode *node)
} }
} }
/** /*
* json_node_type_name: * json_node_type_name:
* @node: a #JsonNode * @node: a #JsonNode
* *
@ -484,7 +484,7 @@ json_node_type_name (JsonNode *node)
return "unknown"; return "unknown";
} }
/** /*
* json_node_get_parent: * json_node_get_parent:
* @node: a #JsonNode * @node: a #JsonNode
* *
@ -500,7 +500,7 @@ json_node_get_parent (JsonNode *node)
return node->parent; return node->parent;
} }
/** /*
* json_node_set_string: * json_node_set_string:
* @node: a #JsonNode of type %JSON_NODE_VALUE * @node: a #JsonNode of type %JSON_NODE_VALUE
* @value: a string value * @value: a string value
@ -530,7 +530,7 @@ json_node_set_string (JsonNode *node,
} }
} }
/** /*
* json_node_get_string: * json_node_get_string:
* @node: a #JsonNode of type %JSON_NODE_VALUE * @node: a #JsonNode of type %JSON_NODE_VALUE
* *
@ -552,7 +552,7 @@ json_node_get_string (JsonNode *node)
return NULL; return NULL;
} }
/** /*
* json_node_dup_string: * json_node_dup_string:
* @node: a #JsonNode of type %JSON_NODE_VALUE * @node: a #JsonNode of type %JSON_NODE_VALUE
* *
@ -575,7 +575,7 @@ json_node_dup_string (JsonNode *node)
return NULL; return NULL;
} }
/** /*
* json_node_set_int: * json_node_set_int:
* @node: a #JsonNode of type %JSON_NODE_VALUE * @node: a #JsonNode of type %JSON_NODE_VALUE
* @value: an integer value * @value: an integer value
@ -605,7 +605,7 @@ json_node_set_int (JsonNode *node,
} }
} }
/** /*
* json_node_get_int: * json_node_get_int:
* @node: a #JsonNode of type %JSON_NODE_VALUE * @node: a #JsonNode of type %JSON_NODE_VALUE
* *
@ -627,7 +627,7 @@ json_node_get_int (JsonNode *node)
return 0; return 0;
} }
/** /*
* json_node_set_double: * json_node_set_double:
* @node: a #JsonNode of type %JSON_NODE_VALUE * @node: a #JsonNode of type %JSON_NODE_VALUE
* @value: a double value * @value: a double value
@ -657,7 +657,7 @@ json_node_set_double (JsonNode *node,
} }
} }
/** /*
* json_node_get_double: * json_node_get_double:
* @node: a #JsonNode of type %JSON_NODE_VALUE * @node: a #JsonNode of type %JSON_NODE_VALUE
* *
@ -679,7 +679,7 @@ json_node_get_double (JsonNode *node)
return 0.0; return 0.0;
} }
/** /*
* json_node_set_boolean: * json_node_set_boolean:
* @node: a #JsonNode of type %JSON_NODE_VALUE * @node: a #JsonNode of type %JSON_NODE_VALUE
* @value: a boolean value * @value: a boolean value
@ -709,7 +709,7 @@ json_node_set_boolean (JsonNode *node,
} }
} }
/** /*
* json_node_get_boolean: * json_node_get_boolean:
* @node: a #JsonNode of type %JSON_NODE_VALUE * @node: a #JsonNode of type %JSON_NODE_VALUE
* *
@ -731,7 +731,7 @@ json_node_get_boolean (JsonNode *node)
return FALSE; return FALSE;
} }
/** /*
* json_node_get_node_type: * json_node_get_node_type:
* @node: a #JsonNode * @node: a #JsonNode
* *
@ -749,7 +749,7 @@ json_node_get_node_type (JsonNode *node)
return node->type; return node->type;
} }
/** /*
* json_node_is_null: * json_node_is_null:
* @node: a #JsonNode * @node: a #JsonNode
* *

View File

@ -29,7 +29,7 @@
#include "json-types-private.h" #include "json-types-private.h"
/** /*
* SECTION:json-object * SECTION:json-object
* @short_description: a JSON object representation * @short_description: a JSON object representation
* *
@ -64,7 +64,7 @@ json_object_get_type (void)
return object_type; return object_type;
} }
/** /*
* json_object_new: * json_object_new:
* *
* Creates a new #JsonObject, an JSON object type representation. * Creates a new #JsonObject, an JSON object type representation.
@ -86,7 +86,7 @@ json_object_new (void)
return object; return object;
} }
/** /*
* json_object_ref: * json_object_ref:
* @object: a #JsonObject * @object: a #JsonObject
* *
@ -106,7 +106,7 @@ json_object_ref (JsonObject *object)
return object; return object;
} }
/** /*
* json_object_unref: * json_object_unref:
* @object: a #JsonObject * @object: a #JsonObject
* *
@ -144,7 +144,7 @@ object_set_member_internal (JsonObject *object,
node); node);
} }
/** /*
* json_object_add_member: * json_object_add_member:
* @object: a #JsonObject * @object: a #JsonObject
* @member_name: the name of the member * @member_name: the name of the member
@ -178,7 +178,7 @@ json_object_add_member (JsonObject *object,
object_set_member_internal (object, member_name, node); object_set_member_internal (object, member_name, node);
} }
/** /*
* json_object_set_member: * json_object_set_member:
* @object: a #JsonObject * @object: a #JsonObject
* @member_name: the name of the member * @member_name: the name of the member
@ -204,7 +204,7 @@ json_object_set_member (JsonObject *object,
object_set_member_internal (object, member_name, node); object_set_member_internal (object, member_name, node);
} }
/** /*
* json_object_set_int_member: * json_object_set_int_member:
* @object: a #JsonObject * @object: a #JsonObject
* @member_name: the name of the member * @member_name: the name of the member
@ -232,7 +232,7 @@ json_object_set_int_member (JsonObject *object,
object_set_member_internal (object, member_name, node); object_set_member_internal (object, member_name, node);
} }
/** /*
* json_object_set_double_member: * json_object_set_double_member:
* @object: a #JsonObject * @object: a #JsonObject
* @member_name: the name of the member * @member_name: the name of the member
@ -260,7 +260,7 @@ json_object_set_double_member (JsonObject *object,
object_set_member_internal (object, member_name, node); object_set_member_internal (object, member_name, node);
} }
/** /*
* json_object_set_boolean_member: * json_object_set_boolean_member:
* @object: a #JsonObject * @object: a #JsonObject
* @member_name: the name of the member * @member_name: the name of the member
@ -288,7 +288,7 @@ json_object_set_boolean_member (JsonObject *object,
object_set_member_internal (object, member_name, node); object_set_member_internal (object, member_name, node);
} }
/** /*
* json_object_set_string_member: * json_object_set_string_member:
* @object: a #JsonObject * @object: a #JsonObject
* @member_name: the name of the member * @member_name: the name of the member
@ -316,7 +316,7 @@ json_object_set_string_member (JsonObject *object,
object_set_member_internal (object, member_name, node); object_set_member_internal (object, member_name, node);
} }
/** /*
* json_object_set_null_member: * json_object_set_null_member:
* @object: a #JsonObject * @object: a #JsonObject
* @member_name: the name of the member * @member_name: the name of the member
@ -341,7 +341,7 @@ json_object_set_null_member (JsonObject *object,
object_set_member_internal (object, member_name, node); object_set_member_internal (object, member_name, node);
} }
/** /*
* json_object_set_array_member: * json_object_set_array_member:
* @object: a #JsonObject * @object: a #JsonObject
* @member_name: the name of the member * @member_name: the name of the member
@ -371,7 +371,7 @@ json_object_set_array_member (JsonObject *object,
object_set_member_internal (object, member_name, node); object_set_member_internal (object, member_name, node);
} }
/** /*
* json_object_set_object_member: * json_object_set_object_member:
* @object: a #JsonObject * @object: a #JsonObject
* @member_name: the name of the member * @member_name: the name of the member
@ -448,7 +448,7 @@ g_hash_table_get_values (GHashTable *hash_table)
} }
#endif /* GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 14 */ #endif /* GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 14 */
/** /*
* json_object_get_members: * json_object_get_members:
* @object: a #JsonObject * @object: a #JsonObject
* *
@ -468,7 +468,7 @@ json_object_get_members (JsonObject *object)
return g_hash_table_get_keys (object->members); return g_hash_table_get_keys (object->members);
} }
/** /*
* json_object_get_values: * json_object_get_values:
* @object: a #JsonObject * @object: a #JsonObject
* *
@ -487,7 +487,7 @@ json_object_get_values (JsonObject *object)
return g_hash_table_get_values (object->members); return g_hash_table_get_values (object->members);
} }
/** /*
* json_object_dup_member: * json_object_dup_member:
* @object: a #JsonObject * @object: a #JsonObject
* @member_name: the name of the JSON object member to access * @member_name: the name of the JSON object member to access
@ -523,7 +523,7 @@ object_get_member_internal (JsonObject *object,
return g_hash_table_lookup (object->members, member_name); return g_hash_table_lookup (object->members, member_name);
} }
/** /*
* json_object_get_member: * json_object_get_member:
* @object: a #JsonObject * @object: a #JsonObject
* @member_name: the name of the JSON object member to access * @member_name: the name of the JSON object member to access
@ -544,7 +544,7 @@ json_object_get_member (JsonObject *object,
return object_get_member_internal (object, member_name); return object_get_member_internal (object, member_name);
} }
/** /*
* json_object_get_int_member: * json_object_get_int_member:
* @object: a #JsonObject * @object: a #JsonObject
* @member_name: the name of the member * @member_name: the name of the member
@ -574,7 +574,7 @@ json_object_get_int_member (JsonObject *object,
return json_node_get_int (node); return json_node_get_int (node);
} }
/** /*
* json_object_get_double_member: * json_object_get_double_member:
* @object: a #JsonObject * @object: a #JsonObject
* @member_name: the name of the member * @member_name: the name of the member
@ -604,7 +604,7 @@ json_object_get_double_member (JsonObject *object,
return json_node_get_double (node); return json_node_get_double (node);
} }
/** /*
* json_object_get_boolean_member: * json_object_get_boolean_member:
* @object: a #JsonObject * @object: a #JsonObject
* @member_name: the name of the member * @member_name: the name of the member
@ -634,7 +634,7 @@ json_object_get_boolean_member (JsonObject *object,
return json_node_get_boolean (node); return json_node_get_boolean (node);
} }
/** /*
* json_object_get_null_member: * json_object_get_null_member:
* @object: a #JsonObject * @object: a #JsonObject
* @member_name: the name of the member * @member_name: the name of the member
@ -663,7 +663,7 @@ json_object_get_null_member (JsonObject *object,
return JSON_NODE_TYPE (node) == JSON_NODE_NULL; return JSON_NODE_TYPE (node) == JSON_NODE_NULL;
} }
/** /*
* json_object_get_string_member: * json_object_get_string_member:
* @object: a #JsonObject * @object: a #JsonObject
* @member_name: the name of the member * @member_name: the name of the member
@ -693,7 +693,7 @@ json_object_get_string_member (JsonObject *object,
return json_node_get_string (node); return json_node_get_string (node);
} }
/** /*
* json_object_get_array_member: * json_object_get_array_member:
* @object: a #JsonObject * @object: a #JsonObject
* @member_name: the name of the member * @member_name: the name of the member
@ -723,7 +723,7 @@ json_object_get_array_member (JsonObject *object,
return json_node_get_array (node); return json_node_get_array (node);
} }
/** /*
* json_object_get_object_member: * json_object_get_object_member:
* @object: a #JsonObject * @object: a #JsonObject
* @member_name: the name of the member * @member_name: the name of the member
@ -753,7 +753,7 @@ json_object_get_object_member (JsonObject *object,
return json_node_get_object (node); return json_node_get_object (node);
} }
/** /*
* json_object_has_member: * json_object_has_member:
* @object: a #JsonObject * @object: a #JsonObject
* @member_name: the name of a JSON object member * @member_name: the name of a JSON object member
@ -772,7 +772,7 @@ json_object_has_member (JsonObject *object,
return (g_hash_table_lookup (object->members, member_name) != NULL); return (g_hash_table_lookup (object->members, member_name) != NULL);
} }
/** /*
* json_object_get_size: * json_object_get_size:
* @object: a #JsonObject * @object: a #JsonObject
* *
@ -788,7 +788,7 @@ json_object_get_size (JsonObject *object)
return g_hash_table_size (object->members); return g_hash_table_size (object->members);
} }
/** /*
* json_object_remove_member: * json_object_remove_member:
* @object: a #JsonObject * @object: a #JsonObject
* @member_name: the name of the member to remove * @member_name: the name of the member to remove
@ -827,7 +827,7 @@ json_object_foreach_internal (gpointer key,
clos->func (clos->object, member_name, member_node, clos->data); clos->func (clos->object, member_name, member_node, clos->data);
} }
/** /*
* json_object_foreach_member: * json_object_foreach_member:
* @object: a #JsonObject * @object: a #JsonObject
* @func: the function to be called on each member * @func: the function to be called on each member

View File

@ -17,7 +17,7 @@
* Emmanuele Bassi <ebassi@openedhand.com> * Emmanuele Bassi <ebassi@openedhand.com>
*/ */
/** /*
* SECTION:json-parser * SECTION:json-parser
* @short_description: Parse JSON data streams * @short_description: Parse JSON data streams
* *
@ -167,7 +167,7 @@ json_parser_class_init (JsonParserClass *klass)
gobject_class->dispose = json_parser_dispose; gobject_class->dispose = json_parser_dispose;
/** /*
* JsonParser::parse-start: * JsonParser::parse-start:
* @parser: the #JsonParser that received the signal * @parser: the #JsonParser that received the signal
* *
@ -182,7 +182,7 @@ json_parser_class_init (JsonParserClass *klass)
NULL, NULL, NULL, NULL,
_json_marshal_VOID__VOID, _json_marshal_VOID__VOID,
G_TYPE_NONE, 0); G_TYPE_NONE, 0);
/** /*
* JsonParser::parse-end: * JsonParser::parse-end:
* @parser: the #JsonParser that received the signal * @parser: the #JsonParser that received the signal
* *
@ -197,7 +197,7 @@ json_parser_class_init (JsonParserClass *klass)
NULL, NULL, NULL, NULL,
_json_marshal_VOID__VOID, _json_marshal_VOID__VOID,
G_TYPE_NONE, 0); G_TYPE_NONE, 0);
/** /*
* JsonParser::object-start: * JsonParser::object-start:
* @parser: the #JsonParser that received the signal * @parser: the #JsonParser that received the signal
* *
@ -212,7 +212,7 @@ json_parser_class_init (JsonParserClass *klass)
NULL, NULL, NULL, NULL,
_json_marshal_VOID__VOID, _json_marshal_VOID__VOID,
G_TYPE_NONE, 0); G_TYPE_NONE, 0);
/** /*
* JsonParser::object-member: * JsonParser::object-member:
* @parser: the #JsonParser that received the signal * @parser: the #JsonParser that received the signal
* @object: a #JsonObject * @object: a #JsonObject
@ -232,7 +232,7 @@ json_parser_class_init (JsonParserClass *klass)
G_TYPE_NONE, 2, G_TYPE_NONE, 2,
JSON_TYPE_OBJECT, JSON_TYPE_OBJECT,
G_TYPE_STRING); G_TYPE_STRING);
/** /*
* JsonParser::object-end: * JsonParser::object-end:
* @parser: the #JsonParser that received the signal * @parser: the #JsonParser that received the signal
* @object: the parsed #JsonObject * @object: the parsed #JsonObject
@ -249,7 +249,7 @@ json_parser_class_init (JsonParserClass *klass)
_json_marshal_VOID__BOXED, _json_marshal_VOID__BOXED,
G_TYPE_NONE, 1, G_TYPE_NONE, 1,
JSON_TYPE_OBJECT); JSON_TYPE_OBJECT);
/** /*
* JsonParser::array-start: * JsonParser::array-start:
* @parser: the #JsonParser that received the signal * @parser: the #JsonParser that received the signal
* *
@ -264,7 +264,7 @@ json_parser_class_init (JsonParserClass *klass)
NULL, NULL, NULL, NULL,
_json_marshal_VOID__VOID, _json_marshal_VOID__VOID,
G_TYPE_NONE, 0); G_TYPE_NONE, 0);
/** /*
* JsonParser::array-element: * JsonParser::array-element:
* @parser: the #JsonParser that received the signal * @parser: the #JsonParser that received the signal
* @array: a #JsonArray * @array: a #JsonArray
@ -284,7 +284,7 @@ json_parser_class_init (JsonParserClass *klass)
G_TYPE_NONE, 2, G_TYPE_NONE, 2,
JSON_TYPE_ARRAY, JSON_TYPE_ARRAY,
G_TYPE_INT); G_TYPE_INT);
/** /*
* JsonParser::array-end: * JsonParser::array-end:
* @parser: the #JsonParser that received the signal * @parser: the #JsonParser that received the signal
* @array: the parsed #JsonArrary * @array: the parsed #JsonArrary
@ -301,7 +301,7 @@ json_parser_class_init (JsonParserClass *klass)
_json_marshal_VOID__BOXED, _json_marshal_VOID__BOXED,
G_TYPE_NONE, 1, G_TYPE_NONE, 1,
JSON_TYPE_ARRAY); JSON_TYPE_ARRAY);
/** /*
* JsonParser::error: * JsonParser::error:
* @parser: the parser instance that received the signal * @parser: the parser instance that received the signal
* @error: a pointer to the #GError * @error: a pointer to the #GError
@ -885,7 +885,7 @@ json_scanner_new (JsonParser *parser)
return scanner; return scanner;
} }
/** /*
* json_parser_new: * json_parser_new:
* *
* Creates a new #JsonParser instance. You can use the #JsonParser to * Creates a new #JsonParser instance. You can use the #JsonParser to
@ -901,7 +901,7 @@ json_parser_new (void)
return g_object_new (JSON_TYPE_PARSER, NULL); return g_object_new (JSON_TYPE_PARSER, NULL);
} }
/** /*
* json_parser_load_from_file: * json_parser_load_from_file:
* @parser: a #JsonParser * @parser: a #JsonParser
* @filename: the path for the file to parse * @filename: the path for the file to parse
@ -944,7 +944,7 @@ json_parser_load_from_file (JsonParser *parser,
return retval; return retval;
} }
/** /*
* json_parser_load_from_data: * json_parser_load_from_data:
* @parser: a #JsonParser * @parser: a #JsonParser
* @data: the buffer to parse * @data: the buffer to parse
@ -1067,7 +1067,7 @@ json_parser_load_from_data (JsonParser *parser,
return retval; return retval;
} }
/** /*
* json_parser_get_root: * json_parser_get_root:
* @parser: a #JsonParser * @parser: a #JsonParser
* *
@ -1084,7 +1084,7 @@ json_parser_get_root (JsonParser *parser)
return parser->priv->root; return parser->priv->root;
} }
/** /*
* json_parser_get_current_line: * json_parser_get_current_line:
* @parser: a #JsonParser * @parser: a #JsonParser
* *
@ -1103,7 +1103,7 @@ json_parser_get_current_line (JsonParser *parser)
return 0; return 0;
} }
/** /*
* json_parser_get_current_pos: * json_parser_get_current_pos:
* @parser: a #JsonParser * @parser: a #JsonParser
* *

View File

@ -799,8 +799,8 @@ PKG_CHECK_MODULES(CLUTTER_DEPS, [$CLUTTER_REQUIRES])
AC_SUBST(CLUTTER_REQUIRES) AC_SUBST(CLUTTER_REQUIRES)
CLUTTER_CFLAGS="$SDL_CFLAGS $EGL_CFLAGS $GLX_CFLAGS $OSX_CFLAGS $WIN32_CFLAGS $CLUTTER_DEPS_CFLAGS $CLUTTER_PROFILE_CFLAGS $GLIB_CFLAGS" CLUTTER_CFLAGS="$EGL_CFLAGS $GLX_CFLAGS $OSX_CFLAGS $WIN32_CFLAGS $CLUTTER_DEPS_CFLAGS $CLUTTER_PROFILE_CFLAGS $GLIB_CFLAGS"
CLUTTER_LIBS="$SDL_LIBS $EGL_LIBS $X11_LIBS $GLX_LIBS $OSX_LIBS $WIN32_LIBS $CLUTTER_DEPS_LIBS $CLUTTER_PROFILE_LDFLAGS $GLIB_LIBS" CLUTTER_LIBS="$EGL_LIBS $X11_LIBS $GLX_LIBS $OSX_LIBS $WIN32_LIBS $CLUTTER_DEPS_LIBS $CLUTTER_PROFILE_LDFLAGS $GLIB_LIBS"
AC_SUBST(CLUTTER_CFLAGS) AC_SUBST(CLUTTER_CFLAGS)
AC_SUBST(CLUTTER_LIBS) AC_SUBST(CLUTTER_LIBS)
@ -811,7 +811,7 @@ GOBJECT_INTROSPECTION_CHECK([0.6.7])
dnl === GTK Doc check ========================================================= dnl === GTK Doc check =========================================================
GTK_DOC_CHECK([1.13]) GTK_DOC_CHECK([1.13], [--flavour no-tmpl])
# we don't want to build the documentation from a Git clone unless we # we don't want to build the documentation from a Git clone unless we
# explicitly tell configure to do so; this allows avoiding to recurse into # explicitly tell configure to do so; this allows avoiding to recurse into

View File

@ -38,6 +38,7 @@ MKTMPL_OPTIONS=
# Extra options to supply to gtkdoc-fixref. Not normally needed. # Extra options to supply to gtkdoc-fixref. Not normally needed.
# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html # e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
FIXXREF_OPTIONS=\ FIXXREF_OPTIONS=\
--extra-dir=../cogl/html \
--extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html/glib \ --extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html/glib \
--extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html/gobject \ --extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html/gobject \
--extra-dir=$(CAIRO_PREFIX)/share/gtk-doc/html/cairo \ --extra-dir=$(CAIRO_PREFIX)/share/gtk-doc/html/cairo \
@ -64,6 +65,7 @@ CFILE_GLOB=$(top_srcdir)/clutter/*.c \
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
IGNORE_HFILES=\ IGNORE_HFILES=\
clutter.h \ clutter.h \
clutter-actor-meta-private.h \
clutter-bezier.h \ clutter-bezier.h \
clutter-debug.h \ clutter-debug.h \
clutter-deprecated.h \ clutter-deprecated.h \

View File

@ -60,6 +60,7 @@
<xi:include href="xml/clutter-media.xml"/> <xi:include href="xml/clutter-media.xml"/>
<xi:include href="xml/clutter-layout-manager.xml"/> <xi:include href="xml/clutter-layout-manager.xml"/>
<xi:include href="xml/clutter-layout-meta.xml"/> <xi:include href="xml/clutter-layout-meta.xml"/>
<xi:include href="xml/clutter-actor-meta.xml"/>
</chapter> </chapter>
<chapter> <chapter>
@ -88,6 +89,16 @@
<xi:include href="xml/clutter-box-layout.xml"/> <xi:include href="xml/clutter-box-layout.xml"/>
</chapter> </chapter>
<chapter>
<title>Actor Modifiers</title>
<xi:include href="xml/clutter-action.xml"/>
<xi:include href="xml/clutter-constraint.xml"/>
<xi:include href="xml/clutter-drag-action.xml"/>
<xi:include href="xml/clutter-bind-constraint.xml"/>
<xi:include href="xml/clutter-align-constraint.xml"/>
</chapter>
</part> </part>
<part id="clutteranimation"> <part id="clutteranimation">

View File

@ -274,7 +274,6 @@ CLUTTER_ACTOR_IS_REACTIVE
<SUBSECTION> <SUBSECTION>
ClutterActorFlags ClutterActorFlags
ClutterRequestMode ClutterRequestMode
ClutterGeometry
CLUTTER_CALLBACK CLUTTER_CALLBACK
ClutterCallback ClutterCallback
ClutterActor ClutterActor
@ -409,6 +408,22 @@ clutter_actor_set_text_direction
clutter_actor_get_text_direction clutter_actor_get_text_direction
clutter_actor_has_pointer clutter_actor_has_pointer
<SUBSECTION>
clutter_actor_add_action
clutter_actor_add_action_with_name
clutter_actor_remove_action
clutter_actor_remove_action_by_name
clutter_actor_get_actions
clutter_actor_get_action
clutter_actor_clear_actions
clutter_actor_add_constraint
clutter_actor_add_constraint_with_name
clutter_actor_remove_constraint
clutter_actor_remove_constraint_by_name
clutter_actor_get_constraints
clutter_actor_get_constraint
clutter_actor_clear_constraints
<SUBSECTION> <SUBSECTION>
ClutterActorBox ClutterActorBox
clutter_actor_box_new clutter_actor_box_new
@ -434,6 +449,10 @@ clutter_vertex_copy
clutter_vertex_free clutter_vertex_free
clutter_vertex_equal clutter_vertex_equal
<SUBSECTION>
ClutterGeometry
clutter_geometry_union
<SUBSECTION Standard> <SUBSECTION Standard>
CLUTTER_TYPE_GEOMETRY CLUTTER_TYPE_GEOMETRY
CLUTTER_TYPE_ACTOR_BOX CLUTTER_TYPE_ACTOR_BOX
@ -444,7 +463,9 @@ CLUTTER_TYPE_ACTOR
CLUTTER_ACTOR_CLASS CLUTTER_ACTOR_CLASS
CLUTTER_IS_ACTOR_CLASS CLUTTER_IS_ACTOR_CLASS
CLUTTER_ACTOR_GET_CLASS CLUTTER_ACTOR_GET_CLASS
<SUBSECTION Private> <SUBSECTION Private>
ClutterRedrawFlags
ClutterActorPrivate ClutterActorPrivate
clutter_actor_get_type clutter_actor_get_type
clutter_actor_box_get_type clutter_actor_box_get_type
@ -1712,6 +1733,9 @@ clutter_text_get_type
ClutterAnimatable ClutterAnimatable
ClutterAnimatableIface ClutterAnimatableIface
clutter_animatable_animate_property clutter_animatable_animate_property
clutter_animatable_find_property
clutter_animatable_get_initial_state
clutter_animatable_set_final_state
<SUBSECTION Standard> <SUBSECTION Standard>
CLUTTER_TYPE_ANIMATABLE CLUTTER_TYPE_ANIMATABLE
@ -1993,6 +2017,8 @@ clutter_box_layout_set_spacing
clutter_box_layout_get_spacing clutter_box_layout_get_spacing
clutter_box_layout_set_vertical clutter_box_layout_set_vertical
clutter_box_layout_get_vertical clutter_box_layout_get_vertical
clutter_box_layout_set_homogeneous
clutter_box_layout_get_homogeneous
<SUBSECTION> <SUBSECTION>
clutter_box_layout_pack clutter_box_layout_pack
@ -2075,3 +2101,120 @@ clutter_animator_get_type
clutter_animator_key_get_type clutter_animator_key_get_type
ClutterAnimatorPrivate ClutterAnimatorPrivate
</SECTION> </SECTION>
<SECTION>
<FILE>clutter-actor-meta</FILE>
<TITLE>ClutterActorMeta</TITLE>
ClutterActorMeta
ClutterActorMetaClass
clutter_actor_meta_set_name
clutter_actor_meta_get_name
clutter_actor_meta_set_enabled
clutter_actor_meta_get_enabled
<SUBSECTION>
clutter_actor_meta_get_actor
<SUBSECTION Standard>
CLUTTER_TYPE_ACTOR_META
CLUTTER_ACTOR_META
CLUTTER_ACTOR_META_CLASS
CLUTTER_IS_ACTOR_META
CLUTTER_IS_ACTOR_META_CLASS
CLUTTER_ACTOR_META_GET_CLASS
clutter_actor_meta_get_type
<SUBSECTION Private>
ClutterActorMetaPrivate
</SECTION>
<SECTION>
<FILE>clutter-action</FILE>
<TITLE>ClutterAction</TITLE>
ClutterAction
ClutterActionClass
<SUBSECTION Standard>
CLUTTER_TYPE_ACTION
CLUTTER_ACTION
CLUTTER_ACTION_CLASS
CLUTTER_IS_ACTION
CLUTTER_IS_ACTION_CLASS
CLUTTER_ACTION_GET_CLASS
clutter_action_get_type
</SECTION>
<SECTION>
<FILE>clutter-constraint</FILE>
<TITLE>ClutterConstraint</TITLE>
ClutterConstraint
ClutterConstraintClass
<SUBSECTION Standard>
CLUTTER_TYPE_CONSTRAINT
CLUTTER_CONSTRAINT
CLUTTER_CONSTRAINT_CLASS
CLUTTER_IS_CONSTRAINT
CLUTTER_IS_CONSTRAINT_CLASS
CLUTTER_CONSTRAINT_GET_CLASS
clutter_constraint_get_type
</SECTION>
<SECTION>
<FILE>clutter-drag-action</FILE>
<TITLE>ClutterDragAction</TITLE>
ClutterDragAction
ClutterDragActionClass
clutter_drag_action_new
clutter_drag_action_set_drag_threshold
clutter_drag_action_get_drag_threshold
clutter_drag_action_set_drag_handle
clutter_drag_action_get_drag_handle
ClutterDragAxis
clutter_drag_action_set_drag_axis
clutter_drag_action_get_drag_axis
<SUBSECTION>
clutter_drag_action_get_press_coords
clutter_drag_action_get_motion_coords
<SUBSECTION Standard>
CLUTTER_TYPE_DRAG_ACTION
CLUTTER_DRAG_ACTION
CLUTTER_DRAG_ACTION_CLASS
CLUTTER_IS_DRAG_ACTION
CLUTTER_IS_DRAG_ACTION_CLASS
CLUTTER_DRAG_ACTION_GET_CLASS
clutter_drag_action_get_type
<SUBSECTION Private>
ClutterDragActionPrivate
</SECTION>
<SECTION>
<FILE>clutter-bind-constraint</FILE>
<TITLE>ClutterBindConstraint</TITLE>
ClutterBindConstraint
ClutterBindCoordinate
clutter_bind_constraint_new
<SUBSECTION Standard>
CLUTTER_TYPE_BIND_CONSTRAINT
CLUTTER_BIND_CONSTRAINT
CLUTTER_IS_BIND_CONSTRAINT
clutter_bind_constraint_get_type
</SECTION>
<SECTION>
<FILE>clutter-align-constraint</FILE>
<TITLE>ClutterAlignConstraint</TITLE>
ClutterAlignConstraint
ClutterAlignAxis
clutter_align_constraint_new
<SUBSECTION Standard>
CLUTTER_TYPE_ALIGN_CONSTRAINT
CLUTTER_ALIGN_CONSTRAINT
CLUTTER_IS_ALIGN_CONSTRAINT
clutter_align_constraint_get_type
</SECTION>

View File

@ -43,3 +43,9 @@ clutter_box_layout_get_type
clutter_input_device_get_type clutter_input_device_get_type
clutter_device_manager_get_type clutter_device_manager_get_type
clutter_animator_get_type clutter_animator_get_type
clutter_actor_meta_get_type
clutter_action_get_type
clutter_drag_action_get_type
clutter_constraint_get_type
clutter_bind_constraint_get_type
clutter_align_constraint_get_type

View File

@ -48,7 +48,9 @@ UNIT_TESTS = \
test-bin-layout.c \ test-bin-layout.c \
test-flow-layout.c \ test-flow-layout.c \
test-box-layout.c \ test-box-layout.c \
test-stage-sizing.c test-stage-sizing.c \
test-drag.c \
test-constraints.c
if X11_TESTS if X11_TESTS
UNIT_TESTS += test-pixmap.c UNIT_TESTS += test-pixmap.c

View File

@ -0,0 +1,173 @@
#include <stdlib.h>
#include <gmodule.h>
#include <clutter/clutter.h>
#define H_PADDING 32
#define V_PADDING 32
enum
{
NorthWest, North, NorthEast,
West, Center, East,
SouthWest, South, SouthEast,
N_RECTS
};
static ClutterActor *rects[N_RECTS] = { NULL, };
static const gchar *colors[N_RECTS] = {
"#8ae234", "#73d216", "#4e9a06",
"#729fcf", "#3465a4", "#204a87",
"#ef2929", "#cc0000", "#a40000"
};
static gboolean is_expanded = FALSE;
static gboolean
on_button_release (ClutterActor *actor,
ClutterEvent *event,
gpointer data G_GNUC_UNUSED)
{
if (!is_expanded)
{
gfloat north_offset, south_offset;
gfloat west_offset, east_offset;
north_offset = (clutter_actor_get_height (rects[Center]) + V_PADDING)
* -1.0f;
south_offset = (clutter_actor_get_height (rects[Center]) + V_PADDING);
west_offset = (clutter_actor_get_width (rects[Center]) + H_PADDING)
* -1.0f;
east_offset = (clutter_actor_get_width (rects[Center]) + H_PADDING);
clutter_actor_animate (rects[NorthWest], CLUTTER_EASE_OUT_CUBIC, 500,
"opacity", 255,
"@constraints.x-bind.offset", west_offset,
"@constraints.y-bind.offset", north_offset,
NULL);
clutter_actor_animate (rects[North], CLUTTER_EASE_OUT_CUBIC, 500,
"opacity", 255,
"@constraints.y-bind.offset", north_offset,
NULL);
clutter_actor_animate (rects[NorthEast], CLUTTER_EASE_OUT_CUBIC, 500,
"opacity", 255,
"@constraints.x-bind.offset", east_offset,
"@constraints.y-bind.offset", north_offset,
NULL);
clutter_actor_animate (rects[West], CLUTTER_EASE_OUT_CUBIC, 500,
"opacity", 255,
"@constraints.x-bind.offset", west_offset,
NULL);
clutter_actor_animate (rects[Center], CLUTTER_LINEAR, 500,
"opacity", 128,
NULL);
clutter_actor_animate (rects[East], CLUTTER_EASE_OUT_CUBIC, 500,
"opacity", 255,
"@constraints.x-bind.offset", east_offset,
NULL);
clutter_actor_animate (rects[SouthWest], CLUTTER_EASE_OUT_CUBIC, 500,
"opacity", 255,
"@constraints.x-bind.offset", west_offset,
"@constraints.y-bind.offset", south_offset,
NULL);
clutter_actor_animate (rects[South], CLUTTER_EASE_OUT_CUBIC, 500,
"opacity", 255,
"@constraints.y-bind.offset", south_offset,
NULL);
clutter_actor_animate (rects[SouthEast], CLUTTER_EASE_OUT_CUBIC, 500,
"opacity", 255,
"@constraints.x-bind.offset", east_offset,
"@constraints.y-bind.offset", south_offset,
NULL);
}
else
{
gint i;
clutter_actor_animate (rects[Center], CLUTTER_LINEAR, 500,
"opacity", 255,
NULL);
for (i = NorthWest; i < N_RECTS; i++)
{
if (i == Center)
continue;
clutter_actor_animate (rects[i], CLUTTER_EASE_OUT_CUBIC, 500,
"opacity", 0,
"@constraints.x-bind.offset", 0.0f,
"@constraints.y-bind.offset", 0.0f,
NULL);
}
}
is_expanded = !is_expanded;
return TRUE;
}
G_MODULE_EXPORT int
test_constraints_main (int argc, char *argv[])
{
ClutterActor *stage, *rect;
ClutterConstraint *constraint;
ClutterColor rect_color;
gint i;
clutter_init (&argc, &argv);
stage = clutter_stage_new ();
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
clutter_stage_set_title (CLUTTER_STAGE (stage), "Constraints");
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
clutter_actor_set_size (stage, 800, 600);
/* main rect */
clutter_color_from_string (&rect_color, "#3465a4");
rect = clutter_rectangle_new ();
g_signal_connect (rect, "button-release-event",
G_CALLBACK (on_button_release),
NULL);
clutter_rectangle_set_color (CLUTTER_RECTANGLE (rect), &rect_color);
clutter_actor_set_size (rect, 128, 128);
clutter_actor_set_reactive (rect, TRUE);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
constraint = clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5);
clutter_actor_add_constraint_with_name (rect, "x-align", constraint);
constraint = clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5);
clutter_actor_add_constraint_with_name (rect, "y-align", constraint);
rects[Center] = rect;
for (i = 0; i < N_RECTS; i++)
{
if (i == Center)
continue;
clutter_color_from_string (&rect_color, colors[i]);
rect = clutter_rectangle_new ();
clutter_rectangle_set_color (CLUTTER_RECTANGLE (rect), &rect_color);
clutter_actor_set_size (rect, 128, 128);
clutter_actor_set_opacity (rect, 0);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
constraint = clutter_bind_constraint_new (rects[Center], CLUTTER_BIND_X, 0.0);
clutter_actor_add_constraint_with_name (rect, "x-bind", constraint);
constraint = clutter_bind_constraint_new (rects[Center], CLUTTER_BIND_Y, 0.0);
clutter_actor_add_constraint_with_name (rect, "y-bind", constraint);
rects[i] = rect;
}
clutter_actor_show (stage);
clutter_main ();
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,189 @@
#include <stdlib.h>
#include <gmodule.h>
#include <clutter/clutter.h>
static void
on_drag_begin (ClutterDragAction *action,
ClutterActor *actor,
gfloat event_x,
gfloat event_y,
gint button,
ClutterModifierType modifiers)
{
gboolean is_copy = (modifiers & CLUTTER_SHIFT_MASK) ? TRUE : FALSE;
ClutterActor *drag_handle = NULL;
if (is_copy)
{
ClutterActor *stage = clutter_actor_get_stage (actor);
ClutterColor handle_color;
drag_handle = clutter_rectangle_new ();
clutter_actor_set_size (drag_handle, 48, 48);
clutter_color_from_string (&handle_color, "#204a87aa");
clutter_rectangle_set_color (CLUTTER_RECTANGLE (drag_handle), &handle_color);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), drag_handle);
clutter_actor_set_position (drag_handle, event_x, event_y);
}
else
drag_handle = actor;
clutter_drag_action_set_drag_handle (action, drag_handle);
clutter_actor_set_opacity (actor, 128);
}
static void
on_drag_motion (ClutterDragAction *action,
ClutterActor *actor,
gfloat delta_x,
gfloat delta_y,
ClutterModifierType modifiers)
{
ClutterActor *drag_handle;
drag_handle = clutter_drag_action_get_drag_handle (action);
g_assert (drag_handle != NULL);
clutter_actor_move_by (drag_handle, delta_x, delta_y);
}
static void
on_drag_end (ClutterDragAction *action,
ClutterActor *actor,
gfloat event_x,
gfloat event_y,
gint button,
ClutterModifierType modifiers)
{
ClutterActor *drag_handle;
drag_handle = clutter_drag_action_get_drag_handle (action);
if (actor != drag_handle)
{
gfloat real_x, real_y;
ClutterActor *parent;
/* if we are dragging a copy we can destroy the copy now
* and animate the real actor to the drop coordinates,
* transformed in the parent's coordinate space
*/
clutter_actor_animate (drag_handle, CLUTTER_LINEAR, 150,
"opacity", 0,
"signal-swapped-after::completed",
G_CALLBACK (clutter_actor_destroy),
drag_handle,
NULL);
parent = clutter_actor_get_parent (actor);
clutter_actor_transform_stage_point (parent, event_x, event_y,
&real_x,
&real_y);
clutter_actor_animate (actor, CLUTTER_EASE_OUT_CUBIC, 150,
"opacity", 255,
"x", real_x,
"y", real_y,
NULL);
}
else
clutter_actor_animate (actor, CLUTTER_LINEAR, 150,
"opacity", 255,
NULL);
}
static ClutterDragAxis
get_drag_axis (const gchar *str)
{
if (str == NULL || *str == '\0')
return CLUTTER_DRAG_AXIS_NONE;
if (*str == 'x' || *str == 'X')
return CLUTTER_DRAG_X_AXIS;
if (*str == 'y' || *str == 'Y')
return CLUTTER_DRAG_Y_AXIS;
g_warn_if_reached ();
return CLUTTER_DRAG_AXIS_NONE;
}
static gchar *drag_axis = NULL;
static gint drag_threshold = 0;
static GOptionEntry entries[] = {
{
"threshold", 't',
0,
G_OPTION_ARG_INT,
&drag_threshold,
"Set the drag threshold", "PIXELS"
},
{
"axis", 'a',
0,
G_OPTION_ARG_STRING,
&drag_axis,
"Set the drag axis", "AXIS"
},
{ NULL }
};
G_MODULE_EXPORT int
test_drag_main (int argc, char *argv[])
{
ClutterActor *stage, *handle;
ClutterAction *action;
ClutterColor handle_color;
GError *error;
error = NULL;
clutter_init_with_args (&argc, &argv,
"test-drag",
entries,
NULL,
&error);
if (error != NULL)
{
g_print ("Unable to run test-drag: %s\n", error->message);
g_error_free (error);
return EXIT_FAILURE;
}
stage = clutter_stage_new ();
clutter_stage_set_title (CLUTTER_STAGE (stage), "Drag Test");
clutter_actor_set_size (stage, 800, 600);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
clutter_color_from_string (&handle_color, "#729fcfff");
handle = clutter_rectangle_new ();
clutter_rectangle_set_color (CLUTTER_RECTANGLE (handle), &handle_color);
clutter_actor_set_size (handle, 128, 128);
clutter_actor_set_position (handle, (800 - 128) / 2, (600 - 128) / 2);
clutter_actor_set_reactive (handle, TRUE);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), handle);
action = clutter_drag_action_new ();
clutter_drag_action_set_drag_threshold (CLUTTER_DRAG_ACTION (action),
drag_threshold);
clutter_drag_action_set_drag_axis (CLUTTER_DRAG_ACTION (action),
get_drag_axis (drag_axis));
g_signal_connect (action, "drag-begin", G_CALLBACK (on_drag_begin), NULL);
g_signal_connect (action, "drag-motion", G_CALLBACK (on_drag_motion), NULL);
g_signal_connect (action, "drag-end", G_CALLBACK (on_drag_end), NULL);
clutter_actor_add_action (handle, action);
clutter_actor_show (stage);
clutter_main ();
return EXIT_SUCCESS;
}