mirror of
https://github.com/brl/mutter.git
synced 2024-12-22 19:12:04 +00:00
creating a branch for experimenting with the behaviour API
This commit is contained in:
parent
2a4865b2b0
commit
ba32170d94
@ -1,3 +1,5 @@
|
|||||||
|
NULL =
|
||||||
|
|
||||||
MARSHALFILES = clutter-marshal.c clutter-marshal.h
|
MARSHALFILES = clutter-marshal.c clutter-marshal.h
|
||||||
ENUMFILES = clutter-enum-types.c clutter-enum-types.h
|
ENUMFILES = clutter-enum-types.c clutter-enum-types.h
|
||||||
GLIB_GENMARSHAL=`pkg-config --variable=glib_genmarshal glib-2.0`
|
GLIB_GENMARSHAL=`pkg-config --variable=glib_genmarshal glib-2.0`
|
||||||
@ -21,10 +23,12 @@ source_h = \
|
|||||||
$(srcdir)/clutter-clone-texture.h \
|
$(srcdir)/clutter-clone-texture.h \
|
||||||
$(srcdir)/clutter-label.h \
|
$(srcdir)/clutter-label.h \
|
||||||
$(srcdir)/clutter-behaviour.h \
|
$(srcdir)/clutter-behaviour.h \
|
||||||
$(srcdir)/clutter-behaviours.h \
|
$(srcdir)/clutter-opacity-behaviour.h \
|
||||||
|
$(srcdir)/clutter-blink-behaviour.h \
|
||||||
$(srcdir)/clutter-alpha.h \
|
$(srcdir)/clutter-alpha.h \
|
||||||
$(srcdir)/clutter-media.h \
|
$(srcdir)/clutter-media.h \
|
||||||
$(srcdir)/clutter-main.h
|
$(srcdir)/clutter-main.h \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
clutter-marshal.h: clutter-marshal.list
|
clutter-marshal.h: clutter-marshal.list
|
||||||
( $(GLIB_GENMARSHAL) --prefix=clutter_marshal \
|
( $(GLIB_GENMARSHAL) --prefix=clutter_marshal \
|
||||||
@ -85,10 +89,12 @@ source_c = clutter-main.c \
|
|||||||
clutter-label.c \
|
clutter-label.c \
|
||||||
clutter-actor.c \
|
clutter-actor.c \
|
||||||
clutter-behaviour.c \
|
clutter-behaviour.c \
|
||||||
clutter-behaviours.c \
|
clutter-opacity-behaviour.c \
|
||||||
|
clutter-blink-behaviour.c \
|
||||||
clutter-alpha.c \
|
clutter-alpha.c \
|
||||||
clutter-media.c \
|
clutter-media.c \
|
||||||
clutter-enum-types.c
|
clutter-enum-types.c \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
source_h_priv = clutter-private.h
|
source_h_priv = clutter-private.h
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
*
|
*
|
||||||
* Authored By Matthew Allum <mallum@openedhand.com>
|
* Authored By Matthew Allum <mallum@openedhand.com>
|
||||||
* Jorn Baayen <jorn@openedhand.com>
|
* Jorn Baayen <jorn@openedhand.com>
|
||||||
|
* Emmanuele Bassi <ebassi@openedhand.com>
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 OpenedHand
|
* Copyright (C) 2006 OpenedHand
|
||||||
*
|
*
|
||||||
@ -31,78 +32,137 @@
|
|||||||
*
|
*
|
||||||
* #ClutterAlpha is a class for calculating an alpha value as a function
|
* #ClutterAlpha is a class for calculating an alpha value as a function
|
||||||
* of time.
|
* of time.
|
||||||
|
*
|
||||||
|
* When you create a #ClutterAlpha object you should attach a #ClutterTimeline
|
||||||
|
* to it, to be used as a time source. You need to supply the alpha
|
||||||
|
* function to be invoked at each timeline "tick"; some common alpha functions
|
||||||
|
* are available.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include "clutter-alpha.h"
|
#include "clutter-alpha.h"
|
||||||
#include "clutter-main.h"
|
#include "clutter-main.h"
|
||||||
#include "clutter-marshal.h"
|
#include "clutter-marshal.h"
|
||||||
|
|
||||||
G_DEFINE_TYPE (ClutterAlpha, clutter_alpha, G_TYPE_OBJECT);
|
G_DEFINE_TYPE (ClutterAlpha,
|
||||||
|
clutter_alpha,
|
||||||
|
G_TYPE_INITIALLY_UNOWNED);
|
||||||
|
|
||||||
struct ClutterAlphaPrivate
|
struct _ClutterAlphaPrivate
|
||||||
{
|
{
|
||||||
ClutterTimeline *timeline;
|
ClutterTimeline *timeline;
|
||||||
guint timeline_new_frame_id;
|
|
||||||
guint32 alpha;
|
guint32 alpha;
|
||||||
|
|
||||||
ClutterAlphaFunc func;
|
ClutterAlphaFunc func;
|
||||||
|
gpointer data;
|
||||||
|
GDestroyNotify destroy;
|
||||||
|
|
||||||
|
gint delay;
|
||||||
|
guint is_paused : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
|
|
||||||
PROP_TIMELINE,
|
PROP_TIMELINE,
|
||||||
PROP_FUNC,
|
PROP_DELAY,
|
||||||
|
PROP_IS_PAUSED,
|
||||||
PROP_ALPHA
|
PROP_ALPHA
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Alpha funcs */
|
/* Alpha funcs */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_alpha_ramp_inc_func:
|
||||||
|
* @alpha: a #ClutterAlpha
|
||||||
|
* @data: user data (ignored)
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
*
|
||||||
|
* Since: 0.2
|
||||||
|
*/
|
||||||
guint32
|
guint32
|
||||||
clutter_alpha_ramp_inc_func (ClutterAlpha *alpha)
|
clutter_alpha_ramp_inc_func (ClutterAlpha *alpha,
|
||||||
|
gpointer data)
|
||||||
{
|
{
|
||||||
int current_frame_num, nframes;
|
ClutterTimeline *timeline;
|
||||||
|
gint current_frame_num, nframes;
|
||||||
|
|
||||||
current_frame_num =
|
g_return_val_if_fail (CLUTTER_IS_ALPHA (alpha), 0);
|
||||||
clutter_timeline_get_current_frame (alpha->priv->timeline);
|
|
||||||
nframes =
|
|
||||||
clutter_timeline_get_n_frames (alpha->priv->timeline);
|
|
||||||
|
|
||||||
return (current_frame_num * CLUTTER_ALPHA_MAX_ALPHA) / nframes;
|
timeline = clutter_alpha_get_timeline (alpha);
|
||||||
|
|
||||||
|
current_frame_num = clutter_timeline_get_current_frame (timeline);
|
||||||
|
nframes = clutter_timeline_get_n_frames (timeline);
|
||||||
|
|
||||||
|
return (current_frame_num * CLUTTER_ALPHA_MAX) / nframes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_alpha_ramp_dec_func:
|
||||||
|
* @alpha: a #ClutterAlpha
|
||||||
|
* @data: user data (ignored)
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
*
|
||||||
|
* Since: 0.2
|
||||||
|
*/
|
||||||
guint32
|
guint32
|
||||||
clutter_alpha_ramp_dec_func (ClutterAlpha *alpha)
|
clutter_alpha_ramp_dec_func (ClutterAlpha *alpha,
|
||||||
|
gpointer data)
|
||||||
{
|
{
|
||||||
int current_frame_num, nframes;
|
ClutterTimeline *timeline;
|
||||||
|
gint current_frame_num, nframes;
|
||||||
|
|
||||||
current_frame_num =
|
g_return_val_if_fail (CLUTTER_IS_ALPHA (alpha), 0);
|
||||||
clutter_timeline_get_current_frame (alpha->priv->timeline);
|
|
||||||
nframes =
|
|
||||||
clutter_timeline_get_n_frames (alpha->priv->timeline);
|
|
||||||
|
|
||||||
return ((nframes - current_frame_num) * CLUTTER_ALPHA_MAX_ALPHA) / nframes;
|
timeline = clutter_alpha_get_timeline (alpha);
|
||||||
|
|
||||||
|
current_frame_num = clutter_timeline_get_current_frame (timeline);
|
||||||
|
nframes = clutter_timeline_get_n_frames (timeline);
|
||||||
|
|
||||||
|
return ((nframes - current_frame_num) * CLUTTER_ALPHA_MAX) / nframes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_alpha_ramp_func:
|
||||||
|
* @alpha: a #ClutterAlpha
|
||||||
|
* @data: user data (ignored)
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
*
|
||||||
|
* Since: 0.2
|
||||||
|
*/
|
||||||
guint32
|
guint32
|
||||||
clutter_alpha_ramp_func (ClutterAlpha *alpha)
|
clutter_alpha_ramp_func (ClutterAlpha *alpha,
|
||||||
|
gpointer data)
|
||||||
{
|
{
|
||||||
int current_frame_num, nframes;
|
ClutterTimeline *timeline;
|
||||||
|
gint current_frame_num, nframes;
|
||||||
|
guint32 retval;
|
||||||
|
|
||||||
current_frame_num =
|
g_return_val_if_fail (CLUTTER_IS_ALPHA (alpha), 0);
|
||||||
clutter_timeline_get_current_frame (alpha->priv->timeline);
|
|
||||||
nframes =
|
|
||||||
clutter_timeline_get_n_frames (alpha->priv->timeline);
|
|
||||||
|
|
||||||
if (current_frame_num > (nframes/2))
|
timeline = clutter_alpha_get_timeline (alpha);
|
||||||
|
|
||||||
|
current_frame_num = clutter_timeline_get_current_frame (timeline);
|
||||||
|
nframes = clutter_timeline_get_n_frames (timeline);
|
||||||
|
|
||||||
|
if (current_frame_num > (nframes / 2))
|
||||||
{
|
{
|
||||||
return ((nframes - current_frame_num)
|
retval = (nframes - current_frame_num) * CLUTTER_ALPHA_MAX;
|
||||||
* CLUTTER_ALPHA_MAX_ALPHA) / (nframes/2);
|
retval = retval / (nframes / 2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return (current_frame_num * CLUTTER_ALPHA_MAX_ALPHA) / (nframes/2);
|
retval = current_frame_num * CLUTTER_ALPHA_MAX;
|
||||||
|
retval = retval / (nframes / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Object */
|
/* Object */
|
||||||
@ -112,15 +172,23 @@ timeline_new_frame_cb (ClutterTimeline *timeline,
|
|||||||
guint current_frame_num,
|
guint current_frame_num,
|
||||||
ClutterAlpha *alpha)
|
ClutterAlpha *alpha)
|
||||||
{
|
{
|
||||||
ClutterAlphaPrivate *priv;
|
ClutterAlphaPrivate *priv = alpha->priv;
|
||||||
|
|
||||||
priv = alpha->priv;
|
if (priv->is_paused)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((priv->delay != -1) && (current_frame_num < priv->delay))
|
||||||
|
return;
|
||||||
|
|
||||||
/* Update alpha value */
|
/* Update alpha value */
|
||||||
if (priv->func) {
|
if (priv->func)
|
||||||
priv->alpha = priv->func(alpha);
|
{
|
||||||
|
g_object_ref (alpha);
|
||||||
|
|
||||||
|
priv->alpha = priv->func (alpha, priv->data);
|
||||||
g_object_notify (G_OBJECT (alpha), "alpha");
|
g_object_notify (G_OBJECT (alpha), "alpha");
|
||||||
|
|
||||||
|
g_object_unref (alpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,19 +198,18 @@ clutter_alpha_set_property (GObject *object,
|
|||||||
const GValue *value,
|
const GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
ClutterAlpha *alpha;
|
ClutterAlpha *alpha = CLUTTER_ALPHA (object);
|
||||||
ClutterAlphaPrivate *priv;
|
|
||||||
|
|
||||||
alpha = CLUTTER_ALPHA(object);
|
|
||||||
priv = alpha->priv;
|
|
||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_TIMELINE:
|
case PROP_TIMELINE:
|
||||||
clutter_alpha_set_timeline (alpha, g_value_get_object (value));
|
clutter_alpha_set_timeline (alpha, g_value_get_object (value));
|
||||||
break;
|
break;
|
||||||
case PROP_FUNC:
|
case PROP_DELAY:
|
||||||
priv->func = g_value_get_pointer (value);
|
alpha->priv->delay = g_value_get_int (value);
|
||||||
|
break;
|
||||||
|
case PROP_IS_PAUSED:
|
||||||
|
alpha->priv->is_paused = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
@ -156,23 +223,24 @@ clutter_alpha_get_property (GObject *object,
|
|||||||
GValue *value,
|
GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
ClutterAlpha *alpha;
|
|
||||||
ClutterAlphaPrivate *priv;
|
ClutterAlphaPrivate *priv;
|
||||||
|
|
||||||
alpha = CLUTTER_ALPHA(object);
|
priv = CLUTTER_ALPHA (object)->priv;
|
||||||
priv = alpha->priv;
|
|
||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_TIMELINE:
|
case PROP_TIMELINE:
|
||||||
g_value_set_object (value, priv->timeline);
|
g_value_set_object (value, priv->timeline);
|
||||||
break;
|
break;
|
||||||
case PROP_FUNC:
|
|
||||||
g_value_set_pointer (value, priv->func);
|
|
||||||
break;
|
|
||||||
case PROP_ALPHA:
|
case PROP_ALPHA:
|
||||||
g_value_set_uint (value, priv->alpha);
|
g_value_set_uint (value, priv->alpha);
|
||||||
break;
|
break;
|
||||||
|
case PROP_DELAY:
|
||||||
|
g_value_set_int (value, priv->delay);
|
||||||
|
break;
|
||||||
|
case PROP_IS_PAUSED:
|
||||||
|
g_value_set_boolean (value, priv->is_paused);
|
||||||
|
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;
|
||||||
@ -182,13 +250,24 @@ clutter_alpha_get_property (GObject *object,
|
|||||||
static void
|
static void
|
||||||
clutter_alpha_finalize (GObject *object)
|
clutter_alpha_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
|
ClutterAlphaPrivate *priv = CLUTTER_ALPHA (object)->priv;
|
||||||
|
|
||||||
|
if (priv->destroy)
|
||||||
|
{
|
||||||
|
priv->destroy (priv->data);
|
||||||
|
|
||||||
|
priv->data = NULL;
|
||||||
|
priv->destroy = NULL;
|
||||||
|
priv->func = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
G_OBJECT_CLASS (clutter_alpha_parent_class)->finalize (object);
|
G_OBJECT_CLASS (clutter_alpha_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_alpha_dispose (GObject *object)
|
clutter_alpha_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
ClutterAlpha *self = CLUTTER_ALPHA(object);
|
ClutterAlpha *self = CLUTTER_ALPHA (object);
|
||||||
|
|
||||||
clutter_alpha_set_timeline (self, NULL);
|
clutter_alpha_set_timeline (self, NULL);
|
||||||
|
|
||||||
@ -201,7 +280,7 @@ clutter_alpha_class_init (ClutterAlphaClass *klass)
|
|||||||
{
|
{
|
||||||
GObjectClass *object_class;
|
GObjectClass *object_class;
|
||||||
|
|
||||||
object_class = (GObjectClass*) klass;
|
object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
object_class->set_property = clutter_alpha_set_property;
|
object_class->set_property = clutter_alpha_set_property;
|
||||||
object_class->get_property = clutter_alpha_get_property;
|
object_class->get_property = clutter_alpha_get_property;
|
||||||
@ -210,52 +289,98 @@ clutter_alpha_class_init (ClutterAlphaClass *klass)
|
|||||||
|
|
||||||
g_type_class_add_private (klass, sizeof (ClutterAlphaPrivate));
|
g_type_class_add_private (klass, sizeof (ClutterAlphaPrivate));
|
||||||
|
|
||||||
g_object_class_install_property
|
/**
|
||||||
(object_class, PROP_TIMELINE,
|
* ClutterAlpha:timeline
|
||||||
|
*
|
||||||
|
* The #ClutterTimeline object to be used when calculating
|
||||||
|
* the alpha value.
|
||||||
|
*
|
||||||
|
* Since: 0.2
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_TIMELINE,
|
||||||
g_param_spec_object ("timeline",
|
g_param_spec_object ("timeline",
|
||||||
"Timeline",
|
"Timeline",
|
||||||
"Timeline",
|
"Timeline",
|
||||||
CLUTTER_TYPE_TIMELINE,
|
CLUTTER_TYPE_TIMELINE,
|
||||||
G_PARAM_READWRITE));
|
G_PARAM_READWRITE));
|
||||||
|
/**
|
||||||
g_object_class_install_property
|
* ClutterAlpha:alpha
|
||||||
(object_class, PROP_FUNC,
|
*
|
||||||
g_param_spec_pointer ("func",
|
* The last computed value of the alpha function.
|
||||||
"Alpha function",
|
*
|
||||||
"Alpha function",
|
* Since: 0.2
|
||||||
G_PARAM_READWRITE));
|
*/
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
g_object_class_install_property
|
PROP_ALPHA,
|
||||||
(object_class, PROP_ALPHA,
|
|
||||||
g_param_spec_uint ("alpha",
|
g_param_spec_uint ("alpha",
|
||||||
|
"Alpha",
|
||||||
"Alpha value",
|
"Alpha value",
|
||||||
"Alpha value",
|
CLUTTER_ALPHA_MIN,
|
||||||
0,
|
CLUTTER_ALPHA_MAX,
|
||||||
CLUTTER_ALPHA_MAX_ALPHA,
|
CLUTTER_ALPHA_MIN,
|
||||||
0,
|
|
||||||
G_PARAM_READABLE));
|
G_PARAM_READABLE));
|
||||||
|
/**
|
||||||
|
* ClutterAlpha:delay
|
||||||
|
*
|
||||||
|
* The number of frames that should be skipped before
|
||||||
|
* starting the calculation of the alpha function.
|
||||||
|
*
|
||||||
|
* Since: 0.2
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_DELAY,
|
||||||
|
g_param_spec_int ("delay",
|
||||||
|
"Delay",
|
||||||
|
"The number of frames that should be skipped "
|
||||||
|
"before computing the alpha function",
|
||||||
|
0,
|
||||||
|
G_MAXINT,
|
||||||
|
0,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
/**
|
||||||
|
* ClutterAlpha:is-paused
|
||||||
|
*
|
||||||
|
* Whether the #ClutterAlpha should be paused or not;
|
||||||
|
* the timeline bound to the #ClutterAlpha object will
|
||||||
|
* continue to run.
|
||||||
|
*
|
||||||
|
* Since: 0.2
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_IS_PAUSED,
|
||||||
|
g_param_spec_boolean ("is-paused",
|
||||||
|
"Is Paused",
|
||||||
|
"Whether the alpha should be paused or not",
|
||||||
|
FALSE,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_alpha_init (ClutterAlpha *self)
|
clutter_alpha_init (ClutterAlpha *self)
|
||||||
{
|
{
|
||||||
self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self,
|
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
|
||||||
CLUTTER_TYPE_ALPHA,
|
CLUTTER_TYPE_ALPHA,
|
||||||
ClutterAlphaPrivate);
|
ClutterAlphaPrivate);
|
||||||
|
|
||||||
self->priv->func = CLUTTER_ALPHA_RAMP_INC;
|
self->priv->func = CLUTTER_ALPHA_RAMP_INC;
|
||||||
|
|
||||||
|
self->priv->delay = -1;
|
||||||
|
self->priv->is_paused = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_alpha_get_alpha:
|
* clutter_alpha_get_value:
|
||||||
* @alpha: A #ClutterAlpha
|
* @alpha: A #ClutterAlpha
|
||||||
*
|
*
|
||||||
* Query the current alpha value.
|
* Query the current alpha value.
|
||||||
*
|
*
|
||||||
* Return Value: The current alpha value for the alpha
|
* Return value: The current alpha value for the alpha
|
||||||
|
*
|
||||||
|
* Since: 0.2
|
||||||
*/
|
*/
|
||||||
gint32
|
guint32
|
||||||
clutter_alpha_get_alpha (ClutterAlpha *alpha)
|
clutter_alpha_get_value (ClutterAlpha *alpha)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (CLUTTER_IS_ALPHA (alpha), FALSE);
|
g_return_val_if_fail (CLUTTER_IS_ALPHA (alpha), FALSE);
|
||||||
|
|
||||||
@ -266,74 +391,248 @@ clutter_alpha_get_alpha (ClutterAlpha *alpha)
|
|||||||
* clutter_alpha_set_func:
|
* clutter_alpha_set_func:
|
||||||
* @alpha: A #ClutterAlpha
|
* @alpha: A #ClutterAlpha
|
||||||
* @func: A #ClutterAlphaAlphaFunc
|
* @func: A #ClutterAlphaAlphaFunc
|
||||||
|
* @data: the data to be passed to func or %NULL
|
||||||
|
* @destroy: the function to be called when removing the previous
|
||||||
|
* alpha function or %NULL
|
||||||
*
|
*
|
||||||
|
* Since: 0.2
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
clutter_alpha_set_func (ClutterAlpha *alpha,
|
clutter_alpha_set_func (ClutterAlpha *alpha,
|
||||||
ClutterAlphaFunc func)
|
ClutterAlphaFunc func,
|
||||||
|
gpointer data,
|
||||||
|
GDestroyNotify destroy)
|
||||||
{
|
{
|
||||||
alpha->priv->func = func;
|
ClutterAlphaPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_ALPHA (alpha));
|
||||||
|
g_return_if_fail (func != NULL);
|
||||||
|
|
||||||
|
priv = alpha->priv;
|
||||||
|
|
||||||
|
if (priv->destroy)
|
||||||
|
{
|
||||||
|
priv->destroy (priv->data);
|
||||||
|
priv->destroy = NULL;
|
||||||
|
priv->data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->func = func;
|
||||||
|
priv->data = data;
|
||||||
|
priv->destroy = destroy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_alpha_set_timeline:
|
* clutter_alpha_set_timeline:
|
||||||
* @alpha: A #ClutterAlpha
|
* @alpha: A #ClutterAlpha
|
||||||
* @timeline: A #ClutterTimeline
|
* @timeline: A #ClutterTimeline or %NULL to unset the timeline
|
||||||
*
|
*
|
||||||
* Binds @alpha to @timeline.
|
* Binds @timeline to @alpha. Since an alpha is a function of time,
|
||||||
|
* @timeline will be used to compute the alpha each time the "new-frame"
|
||||||
|
* signal of @timeline is emitted.
|
||||||
|
*
|
||||||
|
* Since: 0.2
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
clutter_alpha_set_timeline (ClutterAlpha *alpha,
|
clutter_alpha_set_timeline (ClutterAlpha *alpha,
|
||||||
ClutterTimeline *timeline)
|
ClutterTimeline *timeline)
|
||||||
{
|
{
|
||||||
if (alpha->priv->timeline)
|
ClutterAlphaPrivate *priv;
|
||||||
{
|
|
||||||
g_signal_handler_disconnect (alpha->priv->timeline,
|
|
||||||
alpha->priv->timeline_new_frame_id);
|
|
||||||
|
|
||||||
g_object_unref (alpha->priv->timeline);
|
g_return_if_fail (CLUTTER_IS_ALPHA (alpha));
|
||||||
alpha->priv->timeline = NULL;
|
g_return_if_fail (timeline == NULL || CLUTTER_IS_TIMELINE (timeline));
|
||||||
|
|
||||||
|
priv = alpha->priv;
|
||||||
|
|
||||||
|
g_object_ref (alpha);
|
||||||
|
|
||||||
|
if (priv->timeline)
|
||||||
|
{
|
||||||
|
g_signal_handlers_disconnect_by_func (priv->timeline,
|
||||||
|
timeline_new_frame_cb,
|
||||||
|
alpha);
|
||||||
|
|
||||||
|
g_object_unref (priv->timeline);
|
||||||
|
priv->timeline = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeline)
|
if (timeline)
|
||||||
{
|
{
|
||||||
alpha->priv->timeline = g_object_ref (timeline);
|
priv->timeline = g_object_ref (timeline);
|
||||||
|
|
||||||
alpha->priv->timeline_new_frame_id =
|
g_signal_connect (priv->timeline, "new-frame",
|
||||||
g_signal_connect (alpha->priv->timeline,
|
|
||||||
"new-frame",
|
|
||||||
G_CALLBACK (timeline_new_frame_cb),
|
G_CALLBACK (timeline_new_frame_cb),
|
||||||
alpha);
|
alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (alpha), "timeline");
|
||||||
|
|
||||||
|
g_object_unref (alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_alpha_get_timeline:
|
* clutter_alpha_get_timeline:
|
||||||
* @alpha: A #ClutterAlpha
|
* @alpha: A #ClutterAlpha
|
||||||
*
|
*
|
||||||
* Return value: The #ClutterTimeline
|
* Gets the #ClutterTimeline object bound to @alpha.
|
||||||
|
*
|
||||||
|
* Return value: The #ClutterTimeline bount to @alpa or %NULL.
|
||||||
|
*
|
||||||
|
* Since: 0.2
|
||||||
*/
|
*/
|
||||||
ClutterTimeline *
|
ClutterTimeline *
|
||||||
clutter_alpha_get_timeline (ClutterAlpha *alpha)
|
clutter_alpha_get_timeline (ClutterAlpha *alpha)
|
||||||
{
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_ALPHA (alpha), NULL);
|
||||||
|
|
||||||
return alpha->priv->timeline;
|
return alpha->priv->timeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_alpha_new:
|
* clutter_alpha_get_delay:
|
||||||
* @timeline: #ClutterTimeline timeline
|
* @alpha: a #ClutterAlpha
|
||||||
* @func: #ClutterAlphaFunc alpha function
|
|
||||||
*
|
*
|
||||||
* Create a new #ClutterAlpha instance.
|
* Gets the delay used by @alpha. See clutter_alpha_set_delay().
|
||||||
*
|
*
|
||||||
* Return Value: a new #ClutterAlpha
|
* Return value: the number of frames to wait, or -1
|
||||||
|
*
|
||||||
|
* Since: 0.2
|
||||||
*/
|
*/
|
||||||
ClutterAlpha*
|
gint
|
||||||
clutter_alpha_new (ClutterTimeline *timeline,
|
clutter_alpha_get_delay (ClutterAlpha *alpha)
|
||||||
ClutterAlphaFunc func)
|
|
||||||
{
|
{
|
||||||
return g_object_new (CLUTTER_TYPE_ALPHA,
|
g_return_val_if_fail (CLUTTER_IS_ALPHA (alpha), -1);
|
||||||
"timeline", timeline,
|
|
||||||
"func", func,
|
return alpha->priv->delay;
|
||||||
NULL);
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_alpha_set_delay:
|
||||||
|
* @alpha: a #ClutterAlpha
|
||||||
|
* @delay: the number of frames to wait or -1 for no delay
|
||||||
|
*
|
||||||
|
* Sets the number of timeline frames to wait before starting to
|
||||||
|
* compute the alpha value.
|
||||||
|
*
|
||||||
|
* Since: 0.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_alpha_set_delay (ClutterAlpha *alpha,
|
||||||
|
gint delay)
|
||||||
|
{
|
||||||
|
g_return_if_fail (CLUTTER_IS_ALPHA (alpha));
|
||||||
|
|
||||||
|
if (alpha->priv->delay != delay)
|
||||||
|
{
|
||||||
|
g_object_ref (alpha);
|
||||||
|
|
||||||
|
alpha->priv->delay = delay;
|
||||||
|
g_object_notify (G_OBJECT (alpha), "delay");
|
||||||
|
|
||||||
|
g_object_unref (alpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_alpha_get_is_paused:
|
||||||
|
* @alpha: a #ClutterAlpha
|
||||||
|
*
|
||||||
|
* Gets whether @alpha is in paused state or not.
|
||||||
|
* See clutter_alpha_set_is_paused().
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if @alpha is paused
|
||||||
|
*
|
||||||
|
* Since: 0.2
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
clutter_alpha_get_is_paused (ClutterAlpha *alpha)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_ALPHA (alpha), FALSE);
|
||||||
|
|
||||||
|
return alpha->priv->is_paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_alpha_set_is_paused:
|
||||||
|
* @alpha: a #ClutterAlpha
|
||||||
|
* @is_paused: %TRUE to pause the alpha
|
||||||
|
*
|
||||||
|
* Pauses the calculation of the alpha value of @alpha. This is
|
||||||
|
* independent of the running state of the #ClutterTimeline bount
|
||||||
|
* to @alpha.
|
||||||
|
*
|
||||||
|
* Since: 0.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_alpha_set_is_paused (ClutterAlpha *alpha,
|
||||||
|
gboolean is_paused)
|
||||||
|
{
|
||||||
|
g_return_if_fail (CLUTTER_IS_ALPHA (alpha));
|
||||||
|
|
||||||
|
if (alpha->priv->is_paused != is_paused)
|
||||||
|
{
|
||||||
|
g_object_ref (alpha);
|
||||||
|
|
||||||
|
alpha->priv->is_paused = is_paused;
|
||||||
|
g_object_notify (G_OBJECT (alpha), "is-paused");
|
||||||
|
|
||||||
|
g_object_unref (alpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* clutter_alpha_new:
|
||||||
|
* @timeline: a #ClutterTimeline or %NULL
|
||||||
|
* @func: a #ClutterAlphaFunc alpha function
|
||||||
|
* @data: data to be passed to func, or %NULL
|
||||||
|
*
|
||||||
|
* Creates a new #ClutterAlpha instance, using @timeline as the time
|
||||||
|
* source and @func as the function to compute the alpha(t) value.
|
||||||
|
*
|
||||||
|
* Return value: a new #ClutterAlpha
|
||||||
|
*
|
||||||
|
* Since: 0.2
|
||||||
|
*/
|
||||||
|
ClutterAlpha *
|
||||||
|
clutter_alpha_new (ClutterTimeline *timeline,
|
||||||
|
ClutterAlphaFunc func,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
return clutter_alpha_new_full (timeline, func, data, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_alpha_new_full:
|
||||||
|
* @timeline: #ClutterTimeline or %NULL
|
||||||
|
* @func: a #ClutterAlphaFunc
|
||||||
|
* @data: data to be passed to func
|
||||||
|
* @destroy: function to be called when removing the alpha function
|
||||||
|
*
|
||||||
|
* Creates a new #ClutterAlpha instance, using @timeline as the
|
||||||
|
* time source and @func as the function to compute the alpha(t)
|
||||||
|
* value.
|
||||||
|
*
|
||||||
|
* You should use this constructor in bindings or if you want to
|
||||||
|
* let the #ClutterAlpha object control the lifetime of @data.
|
||||||
|
*
|
||||||
|
* Return value: the newly created #ClutterAlpha instance
|
||||||
|
*
|
||||||
|
* Since: 0.2
|
||||||
|
*/
|
||||||
|
ClutterAlpha *
|
||||||
|
clutter_alpha_new_full (ClutterTimeline *timeline,
|
||||||
|
ClutterAlphaFunc func,
|
||||||
|
gpointer data,
|
||||||
|
GDestroyNotify destroy)
|
||||||
|
{
|
||||||
|
ClutterAlpha *retval;
|
||||||
|
|
||||||
|
g_return_val_if_fail (timeline == NULL || CLUTTER_IS_TIMELINE (timeline), NULL);
|
||||||
|
g_return_val_if_fail (func != NULL, NULL);
|
||||||
|
|
||||||
|
retval = g_object_new (CLUTTER_TYPE_ALPHA,
|
||||||
|
"timeline", timeline,
|
||||||
|
NULL);
|
||||||
|
clutter_alpha_set_func (retval, func, data, destroy);
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
*
|
*
|
||||||
* Authored By Matthew Allum <mallum@openedhand.com>
|
* Authored By Matthew Allum <mallum@openedhand.com>
|
||||||
* Jorn Baayen <jorn@openedhand.com>
|
* Jorn Baayen <jorn@openedhand.com>
|
||||||
|
* Emmanuele Bassi <ebassi@openedhand.com>
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 OpenedHand
|
* Copyright (C) 2006 OpenedHand
|
||||||
*
|
*
|
||||||
@ -24,54 +25,41 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _HAVE_CLUTTER_ALPHA_H
|
#ifndef __CLUTTER_ALPHA_H__
|
||||||
#define _HAVE_CLUTTER_ALPHA_H
|
#define __CLUTTER_ALPHA_H__
|
||||||
|
|
||||||
/* clutter-alpha.h */
|
/* clutter-alpha.h */
|
||||||
|
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
#include <clutter/clutter-timeline.h>
|
||||||
#include "clutter-timeline.h"
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define CLUTTER_TYPE_ALPHA clutter_alpha_get_type()
|
#define CLUTTER_TYPE_ALPHA (clutter_alpha_get_type ())
|
||||||
|
#define CLUTTER_ALPHA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ALPHA, ClutterAlpha))
|
||||||
#define CLUTTER_ALPHA(obj) \
|
#define CLUTTER_ALPHA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ALPHA, ClutterAlphaClass))
|
||||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
#define CLUTTER_IS_ALPHA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ALPHA))
|
||||||
CLUTTER_TYPE_ALPHA, ClutterAlpha))
|
#define CLUTTER_IS_ALPHA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ALPHA))
|
||||||
|
#define CLUTTER_ALPHA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ALPHA, ClutterAlphaClass))
|
||||||
#define CLUTTER_ALPHA_CLASS(klass) \
|
|
||||||
(G_TYPE_CHECK_CLASS_CAST ((klass), \
|
|
||||||
CLUTTER_TYPE_ALPHA, ClutterAlphaClass))
|
|
||||||
|
|
||||||
#define CLUTTER_IS_ALPHA(obj) \
|
|
||||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
|
||||||
CLUTTER_TYPE_ALPHA))
|
|
||||||
|
|
||||||
#define CLUTTER_IS_ALPHA_CLASS(klass) \
|
|
||||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
|
||||||
CLUTTER_TYPE_ALPHA))
|
|
||||||
|
|
||||||
#define CLUTTER_ALPHA_GET_CLASS(obj) \
|
|
||||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
|
||||||
CLUTTER_TYPE_ALPHA, ClutterAlphaClass))
|
|
||||||
|
|
||||||
typedef struct _ClutterAlpha ClutterAlpha;
|
typedef struct _ClutterAlpha ClutterAlpha;
|
||||||
typedef struct _ClutterAlphaClass ClutterAlphaClass;
|
typedef struct _ClutterAlphaClass ClutterAlphaClass;
|
||||||
typedef struct ClutterAlphaPrivate ClutterAlphaPrivate;
|
typedef struct _ClutterAlphaPrivate ClutterAlphaPrivate;
|
||||||
|
|
||||||
typedef guint32 (*ClutterAlphaFunc) (ClutterAlpha *alpha);
|
typedef guint32 (*ClutterAlphaFunc) (ClutterAlpha *alpha,
|
||||||
|
gpointer data);
|
||||||
|
|
||||||
struct _ClutterAlpha
|
struct _ClutterAlpha
|
||||||
{
|
{
|
||||||
GObject parent;
|
GInitiallyUnowned parent;
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
ClutterAlphaPrivate *priv;
|
ClutterAlphaPrivate *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _ClutterAlphaClass
|
struct _ClutterAlphaClass
|
||||||
{
|
{
|
||||||
GObjectClass parent_class;
|
GInitiallyUnowned parent_class;
|
||||||
|
|
||||||
void (*_clutter_alpha_1) (void);
|
void (*_clutter_alpha_1) (void);
|
||||||
void (*_clutter_alpha_2) (void);
|
void (*_clutter_alpha_2) (void);
|
||||||
@ -80,34 +68,37 @@ struct _ClutterAlphaClass
|
|||||||
void (*_clutter_alpha_5) (void);
|
void (*_clutter_alpha_5) (void);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CLUTTER_ALPHA_MAX_ALPHA 0xffff
|
#define CLUTTER_ALPHA_MIN 0x0000
|
||||||
|
#define CLUTTER_ALPHA_MAX 0xffff
|
||||||
|
|
||||||
ClutterAlpha *
|
GType clutter_alpha_get_type (void) G_GNUC_CONST;
|
||||||
clutter_alpha_new (ClutterTimeline *timeline,
|
ClutterAlpha * clutter_alpha_new (ClutterTimeline *timeline,
|
||||||
ClutterAlphaFunc func);
|
ClutterAlphaFunc func,
|
||||||
|
gpointer data);
|
||||||
gint32
|
ClutterAlpha * clutter_alpha_new_full (ClutterTimeline *timeline,
|
||||||
clutter_alpha_get_alpha (ClutterAlpha *alpha);
|
ClutterAlphaFunc func,
|
||||||
|
gpointer data,
|
||||||
void
|
GDestroyNotify destroy);
|
||||||
clutter_alpha_set_func (ClutterAlpha *alpha,
|
guint32 clutter_alpha_get_value (ClutterAlpha *alpha);
|
||||||
ClutterAlphaFunc func);
|
void clutter_alpha_set_func (ClutterAlpha *alpha,
|
||||||
|
ClutterAlphaFunc func,
|
||||||
void
|
gpointer data,
|
||||||
clutter_alpha_set_timeline (ClutterAlpha *alpha,
|
GDestroyNotify destroy);
|
||||||
|
gint clutter_alpha_get_delay (ClutterAlpha *alpha);
|
||||||
|
void clutter_alpha_set_delay (ClutterAlpha *alpha,
|
||||||
|
gint delay);
|
||||||
|
gboolean clutter_alpha_get_is_paused (ClutterAlpha *alpha);
|
||||||
|
void clutter_alpha_set_is_paused (ClutterAlpha *alpha,
|
||||||
|
gboolean is_paused);
|
||||||
|
ClutterTimeline *clutter_alpha_get_timeline (ClutterAlpha *alpha);
|
||||||
|
void clutter_alpha_set_timeline (ClutterAlpha *alpha,
|
||||||
ClutterTimeline *timeline);
|
ClutterTimeline *timeline);
|
||||||
|
|
||||||
ClutterTimeline *
|
|
||||||
clutter_alpha_get_timeline (ClutterAlpha *alpha);
|
|
||||||
|
|
||||||
guint32
|
/* predefined alpha functions */
|
||||||
clutter_alpha_ramp_inc_func (ClutterAlpha *alpha);
|
guint32 clutter_alpha_ramp_inc_func (ClutterAlpha *alpha, gpointer data);
|
||||||
|
guint32 clutter_alpha_ramp_dec_func (ClutterAlpha *alpha, gpointer data);
|
||||||
guint32
|
guint32 clutter_alpha_ramp_func (ClutterAlpha *alpha, gpointer data);
|
||||||
clutter_alpha_ramp_dec_func (ClutterAlpha *alpha);
|
|
||||||
|
|
||||||
guint32
|
|
||||||
clutter_alpha_ramp_func (ClutterAlpha *alpha);
|
|
||||||
|
|
||||||
#define CLUTTER_ALPHA_RAMP_INC clutter_alpha_ramp_inc_func
|
#define CLUTTER_ALPHA_RAMP_INC clutter_alpha_ramp_inc_func
|
||||||
#define CLUTTER_ALPHA_RAMP_DEC clutter_alpha_ramp_dec_func
|
#define CLUTTER_ALPHA_RAMP_DEC clutter_alpha_ramp_dec_func
|
||||||
|
@ -31,33 +31,39 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <gobject/gobjectnotifyqueue.c>
|
||||||
|
|
||||||
#include "clutter-actor.h"
|
#include "clutter-actor.h"
|
||||||
#include "clutter-behaviour.h"
|
#include "clutter-behaviour.h"
|
||||||
#include "clutter-marshal.h"
|
#include "clutter-marshal.h"
|
||||||
|
|
||||||
G_DEFINE_TYPE (ClutterBehaviour, clutter_behaviour, G_TYPE_OBJECT);
|
struct _ClutterBehaviourPrivate
|
||||||
|
|
||||||
struct ClutterBehaviourPrivate
|
|
||||||
{
|
{
|
||||||
GObject *object;
|
ClutterAlpha *alpha;
|
||||||
GParamSpec *param_spec;
|
|
||||||
guint notify_id;
|
|
||||||
GSList *actors;
|
GSList *actors;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_OBJECT,
|
|
||||||
PROP_PROPERTY
|
PROP_ALPHA
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum
|
||||||
SIGNAL_PROPERTY_CHANGE,
|
{
|
||||||
|
NOTIFY_BEHAVIOUR,
|
||||||
|
|
||||||
SIGNAL_LAST
|
SIGNAL_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
static guint signals[SIGNAL_LAST];
|
static GObjectClass *clutter_behaviour_parent_class = NULL;
|
||||||
|
static GParamSpecPool *pspec_pool = NULL;
|
||||||
|
static GObjectNotifyContext property_notify_context = { 0, };
|
||||||
|
static guint behaviour_signals[SIGNAL_LAST] = { 0, };
|
||||||
|
static GQuark quark_property_bridge = 0;
|
||||||
|
|
||||||
#define CLUTTER_BEHAVIOUR_GET_PRIVATE(obj) \
|
#define CLUTTER_BEHAVIOUR_GET_PRIVATE(obj) \
|
||||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
|
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
|
||||||
@ -65,52 +71,66 @@ static guint signals[SIGNAL_LAST];
|
|||||||
ClutterBehaviourPrivate))
|
ClutterBehaviourPrivate))
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_clutter_behaviour_dispose (GObject *object)
|
clutter_behaviour_dispatch_property_changed (ClutterBehaviour *behaviour,
|
||||||
|
guint n_pspecs,
|
||||||
|
GParamSpec **pspecs)
|
||||||
{
|
{
|
||||||
ClutterBehaviour *self = CLUTTER_BEHAVIOUR(object);
|
guint i;
|
||||||
|
|
||||||
if (self->priv)
|
for (i = 0; i < n_pspecs; i++)
|
||||||
{
|
{
|
||||||
/* FIXME: remove all actors */
|
g_signal_emit (behaviour,
|
||||||
|
behaviour_signals[NOTIFY_BEHAVIOUR],
|
||||||
clutter_behaviour_set_object (self, NULL);
|
g_quark_from_string (pspecs[i]->name),
|
||||||
|
pspecs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
G_OBJECT_CLASS (clutter_behaviour_parent_class)->dispose (object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_clutter_behaviour_finalize (GObject *object)
|
clutter_behaviour_base_finalize (ClutterBehaviourClass *klass)
|
||||||
{
|
{
|
||||||
ClutterBehaviour *self = CLUTTER_BEHAVIOUR(object);
|
GList *list, *node;
|
||||||
|
|
||||||
if (self->priv)
|
list = g_param_spec_pool_list_owned (pspec_pool,
|
||||||
|
G_OBJECT_CLASS_TYPE (klass));
|
||||||
|
for (node = list; node != NULL; node = node->next)
|
||||||
{
|
{
|
||||||
g_free(self->priv);
|
GParamSpec *pspec = node->data;
|
||||||
self->priv = NULL;
|
|
||||||
|
g_param_spec_pool_remove (pspec_pool, pspec);
|
||||||
|
g_param_spec_unref (pspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_free (list);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_behaviour_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
ClutterBehaviour *self = CLUTTER_BEHAVIOUR (object);
|
||||||
|
|
||||||
|
if (self->priv->alpha)
|
||||||
|
g_object_unref (self->priv->alpha);
|
||||||
|
|
||||||
|
if (self->priv->actors)
|
||||||
|
{
|
||||||
|
g_slist_foreach (self->priv->actors,
|
||||||
|
(GFunc) g_object_unref,
|
||||||
|
NULL);
|
||||||
|
g_slist_free (self->priv->actors);
|
||||||
}
|
}
|
||||||
|
|
||||||
G_OBJECT_CLASS (clutter_behaviour_parent_class)->finalize (object);
|
G_OBJECT_CLASS (clutter_behaviour_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_clutter_behaviour_set_property (GObject *object,
|
clutter_behaviour_set_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
const GValue *value,
|
const GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
ClutterBehaviour *behaviour;
|
|
||||||
|
|
||||||
behaviour = CLUTTER_BEHAVIOUR(object);
|
|
||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_OBJECT:
|
|
||||||
clutter_behaviour_set_object (behaviour, g_value_get_object (value));
|
|
||||||
break;
|
|
||||||
case PROP_PROPERTY:
|
|
||||||
clutter_behaviour_set_property (behaviour, g_value_get_string (value));
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -118,69 +138,47 @@ _clutter_behaviour_set_property (GObject *object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_clutter_behaviour_get_property (GObject *object,
|
clutter_behaviour_get_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
GValue *value,
|
GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
ClutterBehaviour *behaviour;
|
|
||||||
ClutterBehaviourPrivate *priv;
|
|
||||||
|
|
||||||
behaviour = CLUTTER_BEHAVIOUR(object);
|
|
||||||
priv = CLUTTER_BEHAVIOUR_GET_PRIVATE(behaviour);
|
|
||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_OBJECT:
|
|
||||||
g_value_set_object (value, priv->object);
|
|
||||||
break;
|
|
||||||
case PROP_PROPERTY:
|
|
||||||
g_value_set_string (value, priv->param_spec->name);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
property_notify_dispatcher (GObject *object,
|
||||||
|
guint n_pspecs,
|
||||||
|
GParamSpec **pspecs)
|
||||||
|
{
|
||||||
|
CLUTTER_BEHAVIOUR_GET_CLASS (object)->dispatch_property_changed (CLUTTER_BEHAVIOUR (object), n_pspecs, pspecs);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_behaviour_class_init (ClutterBehaviourClass *klass)
|
clutter_behaviour_class_init (ClutterBehaviourClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class;
|
GObjectClass *object_class;
|
||||||
|
|
||||||
object_class = (GObjectClass*) klass;
|
object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
object_class->finalize = _clutter_behaviour_finalize;
|
clutter_behaviour_parent_class = g_type_class_peek_parent (klass);
|
||||||
object_class->dispose = _clutter_behaviour_dispose;
|
pspec_pool = g_param_spec_pool_new (FALSE);
|
||||||
object_class->set_property = _clutter_behaviour_set_property;
|
property_notify_context.quark_notify_queue =
|
||||||
object_class->get_property = _clutter_behaviour_get_property;
|
g_quark_from_static_string ("ClutterBehaviour-notify-queue");
|
||||||
|
property_notify_context.dispatcher =
|
||||||
|
property_notify_dispatcher;
|
||||||
|
quark_property_bridge = g_quark_from_static_string ("clutter-property-bridge");
|
||||||
|
|
||||||
g_object_class_install_property
|
object_class->finalize = clutter_behaviour_finalize;
|
||||||
(object_class, PROP_OBJECT,
|
object_class->set_property = clutter_behaviour_set_property;
|
||||||
g_param_spec_object ("object",
|
object_class->get_property = clutter_behaviour_get_property;
|
||||||
"Object",
|
|
||||||
"Object whose property to monitor",
|
|
||||||
G_TYPE_OBJECT,
|
|
||||||
G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
|
|
||||||
|
|
||||||
g_object_class_install_property
|
klass->dispatch_property_changed = clutter_behaviour_dispatch_property_changed;
|
||||||
(object_class, PROP_PROPERTY,
|
|
||||||
g_param_spec_string ("property",
|
|
||||||
"Property",
|
|
||||||
"Property to monitor",
|
|
||||||
NULL,
|
|
||||||
G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
|
|
||||||
|
|
||||||
signals[SIGNAL_PROPERTY_CHANGE] =
|
|
||||||
g_signal_new ("property-change",
|
|
||||||
G_TYPE_FROM_CLASS (object_class),
|
|
||||||
G_SIGNAL_RUN_LAST,
|
|
||||||
G_STRUCT_OFFSET (ClutterBehaviourClass, property_change),
|
|
||||||
NULL, NULL,
|
|
||||||
clutter_marshal_VOID__OBJECT_POINTER,
|
|
||||||
G_TYPE_NONE,
|
|
||||||
2, G_TYPE_OBJECT, G_TYPE_POINTER);
|
|
||||||
|
|
||||||
g_type_class_add_private (object_class, sizeof (ClutterBehaviourPrivate));
|
g_type_class_add_private (object_class, sizeof (ClutterBehaviourPrivate));
|
||||||
}
|
}
|
||||||
@ -192,156 +190,414 @@ clutter_behaviour_init (ClutterBehaviour *self)
|
|||||||
|
|
||||||
self->priv = priv = CLUTTER_BEHAVIOUR_GET_PRIVATE (self);
|
self->priv = priv = CLUTTER_BEHAVIOUR_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
priv->actors = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClutterBehaviour*
|
GType
|
||||||
clutter_behaviour_new (GObject *object,
|
clutter_behaviour_get_type (void)
|
||||||
const char *property)
|
|
||||||
{
|
{
|
||||||
ClutterBehaviour *behave;
|
static GType behaviour_type = 0;
|
||||||
|
|
||||||
behave = g_object_new (CLUTTER_TYPE_BEHAVIOUR,
|
if (G_UNLIKELY (behaviour_type == 0))
|
||||||
"object", object,
|
{
|
||||||
"property", property,
|
const GTypeInfo behaviour_info =
|
||||||
NULL);
|
{
|
||||||
|
sizeof (ClutterBehaviourClass),
|
||||||
|
NULL, /* base init */
|
||||||
|
(GBaseFinalizeFunc) clutter_behaviour_base_finalize,
|
||||||
|
(GClassInitFunc) clutter_behaviour_class_init,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
sizeof (ClutterBehaviour),
|
||||||
|
0,
|
||||||
|
(GInstanceInitFunc) clutter_behaviour_init,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
return behave;
|
behaviour_type =
|
||||||
|
g_type_register_static (G_TYPE_OBJECT, "ClutterBehaviour",
|
||||||
|
&behaviour_info,
|
||||||
|
G_TYPE_FLAG_ABSTRACT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return behaviour_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_behaviour_apply:
|
||||||
|
* @behaviour: a #ClutterBehaviour
|
||||||
|
* @actor: a #ClutterActor
|
||||||
|
*
|
||||||
|
* Applies @behaviour to @actor.
|
||||||
|
*
|
||||||
|
* This function holds a reference on @actor.
|
||||||
|
*
|
||||||
|
* Since: 0.2
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
clutter_behaviour_apply (ClutterBehaviour *behave, ClutterActor *actor)
|
clutter_behaviour_apply (ClutterBehaviour *behaviour,
|
||||||
|
ClutterActor *actor)
|
||||||
{
|
{
|
||||||
g_return_if_fail (actor != NULL);
|
g_return_if_fail (CLUTTER_IS_BEHAVIOUR (behaviour));
|
||||||
|
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||||
|
|
||||||
if (g_slist_find (behave->priv->actors, (gconstpointer)actor))
|
if (g_slist_find (behaviour->priv->actors, actor))
|
||||||
|
{
|
||||||
|
g_warning ("The behaviour of type `%s' has already been "
|
||||||
|
"applied to the actor of type `%s'",
|
||||||
|
G_OBJECT_TYPE_NAME (behaviour),
|
||||||
|
G_OBJECT_TYPE_NAME (actor));
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_ref (behaviour);
|
||||||
|
g_object_freeze_notify (G_OBJECT (behaviour));
|
||||||
|
|
||||||
g_object_ref (actor);
|
g_object_ref (actor);
|
||||||
behave->priv->actors = g_slist_append (behave->priv->actors, actor);
|
behaviour->priv->actors = g_slist_append (behaviour->priv->actors, actor);
|
||||||
|
|
||||||
|
g_object_thaw_notify (G_OBJECT (behaviour));
|
||||||
|
g_object_unref (behaviour);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_behaviour_remove:
|
||||||
|
* @behaviour: a #ClutterBehaviour
|
||||||
|
* @actor: a #ClutterActor
|
||||||
|
*
|
||||||
|
* Removes @behaviour from the list of behaviours
|
||||||
|
* applied to @actor.
|
||||||
|
*
|
||||||
|
* This function removes a reference on @actor.
|
||||||
|
*
|
||||||
|
* Since: 0.2
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
clutter_behaviour_remove (ClutterBehaviour *behave, ClutterActor *actor)
|
clutter_behaviour_remove (ClutterBehaviour *behaviour,
|
||||||
|
ClutterActor *actor)
|
||||||
{
|
{
|
||||||
g_return_if_fail (actor != NULL);
|
g_return_if_fail (CLUTTER_IS_BEHAVIOUR (behaviour));
|
||||||
|
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||||
|
|
||||||
if (g_slist_find (behave->priv->actors, (gconstpointer)actor))
|
g_object_ref (behaviour);
|
||||||
|
g_object_freeze_notify (G_OBJECT (behaviour));
|
||||||
|
|
||||||
|
if (g_slist_find (behaviour->priv->actors, (gconstpointer) actor))
|
||||||
{
|
{
|
||||||
|
behaviour->priv->actors = g_slist_remove (behaviour->priv->actors, actor);
|
||||||
|
|
||||||
g_object_unref (actor);
|
g_object_unref (actor);
|
||||||
behave->priv->actors = g_slist_remove (behave->priv->actors, actor);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_warning ("The behaviour of type `%s' was not applied "
|
||||||
|
"to the actor of type `%s'",
|
||||||
|
G_OBJECT_TYPE_NAME (behaviour),
|
||||||
|
G_OBJECT_TYPE_NAME (actor));
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_thaw_notify (G_OBJECT (behaviour));
|
||||||
|
g_object_unref (behaviour);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_behaviour_actors_foreach:
|
||||||
|
* @behaviour: a #ClutterBehaviour
|
||||||
|
* @func: the function you want to apply to all #ClutterActor objects
|
||||||
|
* @data: data to be passed to @func
|
||||||
|
*
|
||||||
|
* Applies @func to all the actors bound to @behaviour.
|
||||||
|
*
|
||||||
|
* Since: 0.2
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
clutter_behaviour_remove_all (ClutterBehaviour *behave)
|
clutter_behaviour_actors_foreach (ClutterBehaviour *behaviour,
|
||||||
{
|
|
||||||
/* tofix */
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
clutter_behaviour_actors_foreach (ClutterBehaviour *behave,
|
|
||||||
GFunc func,
|
GFunc func,
|
||||||
gpointer userdata)
|
gpointer data)
|
||||||
{
|
{
|
||||||
g_slist_foreach (behave->priv->actors, func, userdata);
|
g_return_if_fail (CLUTTER_IS_BEHAVIOUR (behaviour));
|
||||||
|
g_return_if_fail (func != NULL);
|
||||||
|
|
||||||
|
g_slist_foreach (behaviour->priv->actors, func, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
GObject*
|
/**
|
||||||
clutter_behaviour_get_object (ClutterBehaviour *behave)
|
* clutter_behaviour_get_actors:
|
||||||
|
* @behaviour: a #ClutterBehaviour
|
||||||
|
*
|
||||||
|
* Gets the list of all #ClutterActor objects bound to @behaviour.
|
||||||
|
*
|
||||||
|
* Return value: a GSList with all the actors. The elements of
|
||||||
|
* the list are owned by the #ClutterBehaviour and should not
|
||||||
|
* be freed or modified. You should free the list when done.
|
||||||
|
*
|
||||||
|
* Since: 0.2
|
||||||
|
*/
|
||||||
|
GSList *
|
||||||
|
clutter_behaviour_get_actors (ClutterBehaviour *behaviour)
|
||||||
{
|
{
|
||||||
return behave->priv->object;
|
GSList *retval, *l;
|
||||||
|
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_ACTOR (behaviour), NULL);
|
||||||
|
|
||||||
|
retval = NULL;
|
||||||
|
|
||||||
|
for (l = behaviour->priv->actors; l != NULL; l = l->next)
|
||||||
|
retval = g_slist_prepend (retval, l->data);
|
||||||
|
|
||||||
|
return g_slist_reverse (retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
typedef struct
|
||||||
clutter_behaviour_set_object (ClutterBehaviour *behave,
|
|
||||||
GObject *object)
|
|
||||||
{
|
{
|
||||||
ClutterBehaviourPrivate *priv;
|
GType actor_type;
|
||||||
const char *property;
|
gchar *actor_property;
|
||||||
|
ClutterAlphaTransform transform_func;
|
||||||
|
} BridgeData;
|
||||||
|
|
||||||
priv = CLUTTER_BEHAVIOUR_GET_PRIVATE(behave);
|
static void
|
||||||
|
bridge_data_free (BridgeData *data)
|
||||||
if (priv->object)
|
|
||||||
{
|
|
||||||
property = clutter_behaviour_get_property (behave);
|
|
||||||
clutter_behaviour_set_property (behave, NULL);
|
|
||||||
|
|
||||||
g_object_unref(priv->object);
|
|
||||||
priv->object = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
property = NULL;
|
|
||||||
|
|
||||||
if (object)
|
|
||||||
{
|
|
||||||
priv->object = g_object_ref(object);
|
|
||||||
|
|
||||||
if (property)
|
|
||||||
clutter_behaviour_set_property (behave, property);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *
|
|
||||||
clutter_behaviour_get_property (ClutterBehaviour *behave)
|
|
||||||
{
|
{
|
||||||
if (behave->priv->param_spec)
|
g_free (data->actor_property);
|
||||||
return behave->priv->param_spec->name;
|
g_slice_free (BridgeData, data);
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
GParamSpec *
|
|
||||||
clutter_behaviour_get_param_spec (ClutterBehaviour *behave)
|
|
||||||
{
|
|
||||||
return behave->priv->param_spec;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
notify_cb (GObject *object,
|
clutter_behaviour_apply_value (ClutterBehaviour *behaviour,
|
||||||
GParamSpec *param_spec,
|
GType actor_type,
|
||||||
ClutterBehaviour *behave)
|
const gchar *actor_property,
|
||||||
|
const GValue *value)
|
||||||
{
|
{
|
||||||
g_signal_emit (behave,
|
GSList *l;
|
||||||
signals[SIGNAL_PROPERTY_CHANGE],
|
|
||||||
0,
|
for (l = behaviour->priv->actors; l != NULL; l = l->next)
|
||||||
object,
|
{
|
||||||
param_spec);
|
ClutterActor *actor = l->data;
|
||||||
|
|
||||||
|
if (G_OBJECT_TYPE (actor) == actor_type)
|
||||||
|
{
|
||||||
|
g_object_set_property (G_OBJECT (actor),
|
||||||
|
actor_property,
|
||||||
|
value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
alpha_notify_func (ClutterAlpha *alpha,
|
||||||
|
GParamSpec *alpha_pspec,
|
||||||
|
ClutterBehaviour *behaviour)
|
||||||
|
{
|
||||||
|
ClutterBehaviourClass *klass;
|
||||||
|
GParamSpec **pspecs;
|
||||||
|
guint n_pspecs, i;
|
||||||
|
GValue alpha_value = { 0, };
|
||||||
|
|
||||||
|
klass = CLUTTER_BEHAVIOUR_GET_CLASS (behaviour);
|
||||||
|
|
||||||
|
g_value_init (&alpha_value, G_TYPE_UINT);
|
||||||
|
g_value_set_uint (&alpha_value, clutter_alpha_get_value (alpha));
|
||||||
|
|
||||||
|
pspecs = clutter_behaviour_class_list_properties (klass, &n_pspecs);
|
||||||
|
for (i = 0; i < n_pspecs; i++)
|
||||||
|
{
|
||||||
|
BridgeData *data;
|
||||||
|
GParamSpec *redirect;
|
||||||
|
GValue transform_value = { 0, };
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
redirect = g_param_spec_get_redirect_target (pspecs[i]);
|
||||||
|
if (!redirect)
|
||||||
|
redirect = pspecs[i];
|
||||||
|
|
||||||
|
data = g_param_spec_get_qdata (redirect, quark_property_bridge);
|
||||||
|
g_assert (data != NULL);
|
||||||
|
|
||||||
|
res = data->transform_func (behaviour, redirect,
|
||||||
|
&alpha_value,
|
||||||
|
&transform_value);
|
||||||
|
if (!res)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
clutter_behaviour_apply_value (behaviour,
|
||||||
|
data->actor_type,
|
||||||
|
data->actor_property,
|
||||||
|
&transform_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (pspecs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
clutter_behaviour_set_property (ClutterBehaviour *behave,
|
clutter_behaviour_set_alpha (ClutterBehaviour *behaviour,
|
||||||
const char *property)
|
ClutterAlpha *alpha)
|
||||||
{
|
{
|
||||||
g_return_if_fail (behave->priv->object);
|
ClutterBehaviourPrivate *priv;
|
||||||
|
|
||||||
if (behave->priv->notify_id)
|
g_return_if_fail (CLUTTER_IS_BEHAVIOUR (behaviour));
|
||||||
|
g_return_if_fail (alpha == NULL || CLUTTER_IS_ALPHA (alpha));
|
||||||
|
|
||||||
|
priv = behaviour->priv;
|
||||||
|
|
||||||
|
if (priv->alpha == alpha)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_object_ref (behaviour);
|
||||||
|
|
||||||
|
if (priv->alpha)
|
||||||
{
|
{
|
||||||
g_signal_handler_disconnect (behave->priv->object,
|
g_signal_handlers_disconnect_by_func (priv->alpha,
|
||||||
behave->priv->notify_id);
|
alpha_notify_func,
|
||||||
behave->priv->notify_id = 0;
|
behaviour);
|
||||||
|
g_object_unref (priv->alpha);
|
||||||
|
priv->alpha = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
behave->priv->param_spec = NULL;
|
if (alpha)
|
||||||
|
|
||||||
if (property)
|
|
||||||
{
|
{
|
||||||
guint signal_id;
|
priv->alpha = alpha;
|
||||||
GClosure *closure;
|
g_object_ref_sink (priv->alpha);
|
||||||
|
|
||||||
behave->priv->param_spec =
|
g_signal_connect (priv->alpha, "notify::alpha",
|
||||||
g_object_class_find_property (G_OBJECT_GET_CLASS (behave->priv->object),
|
G_CALLBACK (alpha_notify_func),
|
||||||
property);
|
behaviour);
|
||||||
g_return_if_fail (behave->priv->param_spec);
|
|
||||||
|
|
||||||
signal_id = g_signal_lookup ("notify",
|
|
||||||
G_OBJECT_TYPE (behave->priv->object));
|
|
||||||
closure = g_cclosure_new ((GCallback) notify_cb, behave, NULL);
|
|
||||||
|
|
||||||
behave->priv->notify_id =
|
|
||||||
g_signal_connect_closure_by_id (behave->priv->object,
|
|
||||||
signal_id,
|
|
||||||
g_quark_from_string (property),
|
|
||||||
closure,
|
|
||||||
FALSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (behaviour), "alpha");
|
||||||
|
g_object_unref (behaviour);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClutterAlpha *
|
||||||
|
clutter_behaviour_get_alpha (ClutterBehaviour *behaviour)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR (behaviour), NULL);
|
||||||
|
|
||||||
|
if (behaviour->priv->alpha)
|
||||||
|
return g_object_ref (behaviour->priv->alpha);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_behaviour_class_bind_property:
|
||||||
|
* @klass: a #ClutterBehaviourClass
|
||||||
|
* @actor_type: the type of the actor's class
|
||||||
|
* @actor_property: the name of the actor's class property
|
||||||
|
* @pspec: a #GParamSpec
|
||||||
|
*
|
||||||
|
* FIXME
|
||||||
|
*
|
||||||
|
* Since: 0.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_behaviour_class_bind_property (ClutterBehaviourClass *klass,
|
||||||
|
GType actor_type,
|
||||||
|
const gchar *actor_property,
|
||||||
|
ClutterAlphaTransform func)
|
||||||
|
{
|
||||||
|
GParamSpec *overridden, *pspec;
|
||||||
|
GObjectClass *actor_class;
|
||||||
|
BridgeData *bridge_data;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_BEHAVIOUR_CLASS (klass));
|
||||||
|
g_return_if_fail (actor_type != G_TYPE_INVALID);
|
||||||
|
g_return_if_fail (actor_property != NULL);
|
||||||
|
g_return_if_fail (func != NULL);
|
||||||
|
|
||||||
|
actor_class = g_type_class_ref (actor_type);
|
||||||
|
if (!actor_class)
|
||||||
|
{
|
||||||
|
g_warning (G_STRLOC ": unable to find class `%s'",
|
||||||
|
g_type_name (actor_type));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pspec = g_object_class_find_property (actor_class, actor_property);
|
||||||
|
if (!pspec)
|
||||||
|
{
|
||||||
|
g_warning (G_STRLOC ": objects of class `%s' do not have a "
|
||||||
|
"property called `%s'",
|
||||||
|
g_type_name (actor_type),
|
||||||
|
actor_property);
|
||||||
|
}
|
||||||
|
g_type_class_unref (actor_class);
|
||||||
|
|
||||||
|
overridden = g_param_spec_override (pspec->name, pspec);
|
||||||
|
|
||||||
|
bridge_data = g_slice_new (BridgeData);
|
||||||
|
bridge_data->actor_type = actor_type;
|
||||||
|
bridge_data->actor_property = g_strdup (actor_property);
|
||||||
|
bridge_data->transform_func = func;
|
||||||
|
|
||||||
|
g_param_spec_ref (overridden);
|
||||||
|
g_param_spec_set_qdata_full (overridden, quark_property_bridge,
|
||||||
|
bridge_data,
|
||||||
|
(GDestroyNotify) bridge_data_free);
|
||||||
|
g_param_spec_pool_insert (pspec_pool, overridden, G_OBJECT_CLASS_TYPE (klass));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_behaviour_class_list_properties:
|
||||||
|
* @klass: a #ClutterBehaviourClass
|
||||||
|
* @n_pspecs: return location for the number of properties found
|
||||||
|
*
|
||||||
|
* FIXME
|
||||||
|
*
|
||||||
|
* Return value: an allocated list of #GParamSpec objects. Use
|
||||||
|
* g_free() on the returned value when done.
|
||||||
|
*
|
||||||
|
* Since: 0.2
|
||||||
|
*/
|
||||||
|
GParamSpec **
|
||||||
|
clutter_behaviour_class_list_properties (ClutterBehaviourClass *klass,
|
||||||
|
guint *n_pspecs)
|
||||||
|
{
|
||||||
|
GParamSpec **pspecs;
|
||||||
|
guint n;
|
||||||
|
|
||||||
|
pspecs = g_param_spec_pool_list (pspec_pool,
|
||||||
|
G_OBJECT_CLASS_TYPE (klass),
|
||||||
|
&n);
|
||||||
|
|
||||||
|
if (n_pspecs)
|
||||||
|
*n_pspecs = n;
|
||||||
|
|
||||||
|
return pspecs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_behaviour_class_find_property:
|
||||||
|
* @klass: a #ClutterBehaviourClass
|
||||||
|
* @property_name: the name of the property
|
||||||
|
*
|
||||||
|
* FIXME
|
||||||
|
*
|
||||||
|
* Return value: a #GParamSpec or %NULL
|
||||||
|
*
|
||||||
|
* Since: 0.2
|
||||||
|
*/
|
||||||
|
GParamSpec *
|
||||||
|
clutter_behaviour_class_find_property (ClutterBehaviourClass *klass,
|
||||||
|
const gchar *property_name)
|
||||||
|
{
|
||||||
|
GParamSpec *pspec;
|
||||||
|
GParamSpec *redirect;
|
||||||
|
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR_CLASS (klass), NULL);
|
||||||
|
g_return_val_if_fail (property_name != NULL, NULL);
|
||||||
|
|
||||||
|
pspec = g_param_spec_pool_lookup (pspec_pool,
|
||||||
|
property_name,
|
||||||
|
G_OBJECT_CLASS_TYPE (klass),
|
||||||
|
TRUE);
|
||||||
|
if (pspec)
|
||||||
|
{
|
||||||
|
redirect = g_param_spec_get_redirect_target (pspec);
|
||||||
|
if (redirect)
|
||||||
|
return redirect;
|
||||||
|
else
|
||||||
|
return pspec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1,39 +1,59 @@
|
|||||||
#ifndef _HAVE_CLUTTER_BEHAVIOUR_H
|
/*
|
||||||
#define _HAVE_CLUTTER_BEHAVIOUR_H
|
* Clutter.
|
||||||
|
*
|
||||||
|
* An OpenGL based 'interactive canvas' library.
|
||||||
|
*
|
||||||
|
* Authored By Matthew Allum <mallum@openedhand.com>
|
||||||
|
* Emmanuele Bassi <ebassi@openedhand.com>
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 OpenedHand
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __CLUTTER_BEHAVIOUR_H__
|
||||||
|
#define __CLUTTER_BEHAVIOUR_H__
|
||||||
|
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
#include <clutter/clutter-actor.h>
|
||||||
|
#include <clutter/clutter-alpha.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define CLUTTER_TYPE_BEHAVIOUR clutter_behaviour_get_type()
|
#define CLUTTER_TYPE_BEHAVIOUR (clutter_behaviour_get_type ())
|
||||||
|
#define CLUTTER_BEHAVIOUR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BEHAVIOUR, ClutterBehaviour))
|
||||||
#define CLUTTER_BEHAVIOUR(obj) \
|
#define CLUTTER_BEHAVIOUR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BEHAVIOUR, ClutterBehaviourClass))
|
||||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
#define CLUTTER_IS_BEHAVIOUR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BEHAVIOUR))
|
||||||
CLUTTER_TYPE_BEHAVIOUR, ClutterBehaviour))
|
#define CLUTTER_IS_BEHAVIOUR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BEHAVIOUR))
|
||||||
|
#define CLUTTER_BEHAVIOUR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BEHAVIOUR, ClutterBehaviourClass))
|
||||||
#define CLUTTER_BEHAVIOUR_CLASS(klass) \
|
|
||||||
(G_TYPE_CHECK_CLASS_CAST ((klass), \
|
|
||||||
CLUTTER_TYPE_BEHAVIOUR, ClutterBehaviourClass))
|
|
||||||
|
|
||||||
#define CLUTTER_IS_BEHAVIOUR(obj) \
|
|
||||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
|
||||||
CLUTTER_TYPE_BEHAVIOUR))
|
|
||||||
|
|
||||||
#define CLUTTER_IS_BEHAVIOUR_CLASS(klass) \
|
|
||||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
|
||||||
CLUTTER_TYPE_BEHAVIOUR))
|
|
||||||
|
|
||||||
#define CLUTTER_BEHAVIOUR_GET_CLASS(obj) \
|
|
||||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
|
||||||
CLUTTER_TYPE_BEHAVIOUR, ClutterBehaviourClass))
|
|
||||||
|
|
||||||
typedef struct _ClutterBehaviour ClutterBehaviour;
|
typedef struct _ClutterBehaviour ClutterBehaviour;
|
||||||
typedef struct ClutterBehaviourPrivate ClutterBehaviourPrivate;
|
typedef struct _ClutterBehaviourPrivate ClutterBehaviourPrivate;
|
||||||
typedef struct _ClutterBehaviourClass ClutterBehaviourClass;
|
typedef struct _ClutterBehaviourClass ClutterBehaviourClass;
|
||||||
|
|
||||||
|
typedef gboolean (*ClutterAlphaTransform) (ClutterBehaviour *behaviour,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
const GValue *src,
|
||||||
|
GValue *dest);
|
||||||
|
|
||||||
struct _ClutterBehaviour
|
struct _ClutterBehaviour
|
||||||
{
|
{
|
||||||
GObject parent;
|
GObject parent_instance;
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
ClutterBehaviourPrivate *priv;
|
ClutterBehaviourPrivate *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -41,48 +61,64 @@ struct _ClutterBehaviourClass
|
|||||||
{
|
{
|
||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
|
|
||||||
void (* property_change) (ClutterBehaviour *behave,
|
/* override this to change the way behaviour properties
|
||||||
GObject *object,
|
* are dispatched
|
||||||
GParamSpec *param_spec);
|
*/
|
||||||
|
void (*dispatch_property_changed) (ClutterBehaviour *behaviour,
|
||||||
|
guint n_pspecs,
|
||||||
|
GParamSpec **pspecs);
|
||||||
|
|
||||||
|
/* signals */
|
||||||
|
void (*notify_behaviour) (ClutterBehaviour *behaviour,
|
||||||
|
GParamSpec *pspec);
|
||||||
|
|
||||||
|
/* padding, for future expansion */
|
||||||
|
void (*_clutter_behaviour_1) (void);
|
||||||
|
void (*_clutter_behaviour_2) (void);
|
||||||
|
void (*_clutter_behaviour_3) (void);
|
||||||
|
void (*_clutter_behaviour_4) (void);
|
||||||
};
|
};
|
||||||
|
|
||||||
GType clutter_behaviour_get_type (void);
|
GType clutter_behaviour_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
ClutterBehaviour*
|
void clutter_behaviour_apply (ClutterBehaviour *behaviour,
|
||||||
clutter_behaviour_new (GObject *object,
|
ClutterActor *actor);
|
||||||
const char *property);
|
void clutter_behaviour_remove (ClutterBehaviour *behaviour,
|
||||||
|
ClutterActor *actor);
|
||||||
void
|
void clutter_behaviour_actors_foreach (ClutterBehaviour *behaviour,
|
||||||
clutter_behaviour_apply (ClutterBehaviour *behave, ClutterActor *actor);
|
|
||||||
|
|
||||||
void
|
|
||||||
clutter_behaviour_remove (ClutterBehaviour *behave, ClutterActor *actor);
|
|
||||||
|
|
||||||
void
|
|
||||||
clutter_behaviour_remove_all (ClutterBehaviour *behave);
|
|
||||||
|
|
||||||
void
|
|
||||||
clutter_behaviour_actors_foreach (ClutterBehaviour *behave,
|
|
||||||
GFunc func,
|
GFunc func,
|
||||||
gpointer userdata);
|
gpointer userdata);
|
||||||
|
GSList * clutter_behaviour_get_actors (ClutterBehaviour *behaviour);
|
||||||
|
void clutter_behaviour_set_alpha (ClutterBehaviour *behaviour,
|
||||||
|
ClutterAlpha *alpha);
|
||||||
|
ClutterAlpha *clutter_behaviour_get_alpha (ClutterBehaviour *behaviour);
|
||||||
|
|
||||||
void
|
|
||||||
clutter_behaviour_set_object (ClutterBehaviour *behave,
|
|
||||||
GObject *object);
|
|
||||||
|
|
||||||
GObject*
|
|
||||||
clutter_behaviour_get_object (ClutterBehaviour *behave);
|
|
||||||
|
|
||||||
void
|
#define CLUTTER_BEHAVIOUR_WARN_INVALID_TRANSFORM(behaviour,pspec,value) \
|
||||||
clutter_behaviour_set_property (ClutterBehaviour *behave,
|
G_STMT_START { \
|
||||||
const char *property);
|
ClutterBehaviour *_behaviour = (ClutterBehaviour *) behaviour; \
|
||||||
|
GParamSpec *_pspec = (GParamSpec *) pspec; \
|
||||||
|
GValue *_value = (GValue *) value; \
|
||||||
|
g_warning ("%s: behaviours of type `%s' are unable to transform values " \
|
||||||
|
"of type `%s' into values of type `%s' for property `%s'", \
|
||||||
|
G_STRLOC, \
|
||||||
|
g_type_name (G_OBJECT_TYPE (_behaviour)), \
|
||||||
|
g_type_name (G_VALUE_TYPE (_value)), \
|
||||||
|
g_type_name (G_PARAM_SPEC_TYPE (_pspec)), \
|
||||||
|
_pspec->name); \
|
||||||
|
} G_STMT_END
|
||||||
|
|
||||||
const char*
|
GParamSpec **clutter_behaviour_class_list_properties (ClutterBehaviourClass *klass,
|
||||||
clutter_behaviour_get_property (ClutterBehaviour *behave);
|
guint *n_pspecs);
|
||||||
|
GParamSpec * clutter_behaviour_class_find_property (ClutterBehaviourClass *klass,
|
||||||
|
const gchar *property_name);
|
||||||
|
void clutter_behaviour_class_bind_property (ClutterBehaviourClass *klass,
|
||||||
|
GType actor_type,
|
||||||
|
const gchar *actor_property,
|
||||||
|
ClutterAlphaTransform func);
|
||||||
|
|
||||||
GParamSpec*
|
|
||||||
clutter_behaviour_get_param_spec (ClutterBehaviour *behave);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif
|
#endif /* __CLUTTER_BEHAVIOUR_H__ */
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
#include "clutter-event.h"
|
#include "clutter-event.h"
|
||||||
#include "clutter-timeline.h"
|
#include "clutter-timeline.h"
|
||||||
#include "clutter-behaviour.h"
|
#include "clutter-behaviour.h"
|
||||||
#include "clutter-behaviours.h"
|
#include "clutter-opacity-behaviour.h"
|
||||||
|
#include "clutter-blink-behaviour.h"
|
||||||
#include "clutter-stage.h"
|
#include "clutter-stage.h"
|
||||||
#include "clutter-actor.h"
|
#include "clutter-actor.h"
|
||||||
#include "clutter-rectangle.h"
|
#include "clutter-rectangle.h"
|
||||||
|
@ -14,6 +14,9 @@ main (int argc, char *argv[])
|
|||||||
clutter_init (&argc, &argv);
|
clutter_init (&argc, &argv);
|
||||||
|
|
||||||
stage = clutter_stage_get_default ();
|
stage = clutter_stage_get_default ();
|
||||||
|
g_signal_connect (stage, "button-press-event",
|
||||||
|
G_CALLBACK (clutter_main_quit),
|
||||||
|
NULL);
|
||||||
|
|
||||||
pixbuf = gdk_pixbuf_new_from_file ("redhand.png", NULL);
|
pixbuf = gdk_pixbuf_new_from_file ("redhand.png", NULL);
|
||||||
|
|
||||||
@ -30,13 +33,14 @@ main (int argc, char *argv[])
|
|||||||
|
|
||||||
/* Make a timeline */
|
/* Make a timeline */
|
||||||
timeline = clutter_timeline_new (100, 30); /* num frames, fps */
|
timeline = clutter_timeline_new (100, 30); /* num frames, fps */
|
||||||
g_object_set(timeline, "loop", TRUE, 0);
|
g_object_set (timeline, "loop", TRUE, 0);
|
||||||
|
|
||||||
/* Set an alpha func to power behaviour - ramp is constant rise/fall */
|
/* Set an alpha func to power behaviour - ramp is constant rise/fall */
|
||||||
alpha = clutter_alpha_new (timeline, CLUTTER_ALPHA_RAMP);
|
alpha = clutter_alpha_new (timeline, CLUTTER_ALPHA_RAMP, NULL);
|
||||||
|
|
||||||
/* Create a behaviour for that time line */
|
/* Create a behaviour for that time line */
|
||||||
behave = clutter_behaviour_opacity_new_from_alpha (alpha, 0X33, 0xff);
|
behave = clutter_opacity_behaviour_new (0X33, 0xff, 0x00);
|
||||||
|
clutter_behaviour_set_alpha (CLUTTER_BEHAVIOUR (behave), alpha);
|
||||||
|
|
||||||
/* Apply it to our actor */
|
/* Apply it to our actor */
|
||||||
clutter_behaviour_apply (behave, hand);
|
clutter_behaviour_apply (behave, hand);
|
||||||
@ -48,5 +52,7 @@ main (int argc, char *argv[])
|
|||||||
|
|
||||||
clutter_main();
|
clutter_main();
|
||||||
|
|
||||||
|
g_object_unref (behave);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user