mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 17:40:40 -05:00
2006-12-08 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/clutter-behaviour.h: Add a function prototype for the foreach function: we need something more specific than GFunc; add clutter_behaviour_get_actors(), used to get a list of the actors. * clutter/clutter-behaviour.c: Add debugging notes; add a warning for behaviour implementations missing the alpha_notify vfunc; add api documentation * clutter/clutter-behaviour-opacity.c: * clutter/clutter-behaviour-path.c: * clutter/clutter-behaviour-scale.c: Reimplement the alpha_notify functions using the new foreach function and, where possible, by directly iterating on the actors: this shaves off the number of recalculations of the property/alpha values, and the number of functions.
This commit is contained in:
parent
a56ea84dd5
commit
aa623df78f
20
ChangeLog
20
ChangeLog
@ -1,3 +1,23 @@
|
||||
2006-12-08 Emmanuele Bassi <ebassi@openedhand.com>
|
||||
|
||||
* clutter/clutter-behaviour.h: Add a function prototype
|
||||
for the foreach function: we need something more specific
|
||||
than GFunc; add clutter_behaviour_get_actors(), used to
|
||||
get a list of the actors.
|
||||
|
||||
* clutter/clutter-behaviour.c: Add debugging notes; add
|
||||
a warning for behaviour implementations missing the
|
||||
alpha_notify vfunc; add api documentation
|
||||
|
||||
* clutter/clutter-behaviour-opacity.c:
|
||||
* clutter/clutter-behaviour-path.c:
|
||||
* clutter/clutter-behaviour-scale.c: Reimplement the
|
||||
alpha_notify functions using the new foreach function
|
||||
and, where possible, by directly iterating on the
|
||||
actors: this shaves off the number of recalculations
|
||||
of the property/alpha values, and the number of
|
||||
functions.
|
||||
|
||||
2006-12-05 Emmanuele Bassi <ebassi@openedhand.com>
|
||||
|
||||
* clutter/clutter-rectangle.c: Forgot to set the
|
||||
|
@ -78,37 +78,36 @@ enum
|
||||
PROP_OPACITY_END
|
||||
};
|
||||
|
||||
static void
|
||||
opacity_frame_foreach (ClutterActor *actor,
|
||||
ClutterBehaviourOpacity *behave)
|
||||
{
|
||||
guint32 alpha;
|
||||
guint8 opacity;
|
||||
ClutterBehaviourOpacityPrivate *priv;
|
||||
ClutterBehaviour *_behave;
|
||||
|
||||
priv = CLUTTER_BEHAVIOUR_OPACITY_GET_PRIVATE (behave);
|
||||
_behave = CLUTTER_BEHAVIOUR (behave);
|
||||
|
||||
alpha = clutter_alpha_get_alpha (clutter_behaviour_get_alpha (_behave));
|
||||
|
||||
opacity = (alpha * (priv->opacity_end - priv->opacity_start))
|
||||
/ CLUTTER_ALPHA_MAX_ALPHA;
|
||||
|
||||
opacity += priv->opacity_start;
|
||||
|
||||
CLUTTER_NOTE (BEHAVIOUR, "alpha %i opacity %i\n", alpha, opacity);
|
||||
|
||||
clutter_actor_set_opacity (actor, opacity);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_behaviour_alpha_notify (ClutterBehaviour *behave,
|
||||
guint32 alpha_value)
|
||||
{
|
||||
clutter_behaviour_actors_foreach (behave,
|
||||
(GFunc) opacity_frame_foreach,
|
||||
CLUTTER_BEHAVIOUR_OPACITY (behave));
|
||||
GSList *actors, *l;
|
||||
guint8 opacity;
|
||||
ClutterBehaviourOpacityPrivate *priv;
|
||||
|
||||
priv = CLUTTER_BEHAVIOUR_OPACITY (behave)->priv;
|
||||
|
||||
actors = clutter_behaviour_get_actors (behave);
|
||||
if (!actors)
|
||||
return;
|
||||
|
||||
opacity = alpha_value
|
||||
* (priv->opacity_end - priv->opacity_start)
|
||||
/ CLUTTER_ALPHA_MAX_ALPHA;
|
||||
|
||||
CLUTTER_NOTE (BEHAVIOUR, "alpha: %i, opacity: %i",
|
||||
alpha_value,
|
||||
opacity);
|
||||
|
||||
for (l = actors; l; l = l->next)
|
||||
{
|
||||
ClutterActor *actor = l->data;
|
||||
|
||||
clutter_actor_set_opacity (actor, opacity);
|
||||
}
|
||||
|
||||
g_slist_free (actors);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -184,9 +184,12 @@ path_total_length (ClutterBehaviourPath *behave)
|
||||
}
|
||||
|
||||
static void
|
||||
actor_apply_knot_foreach (ClutterActor *actor,
|
||||
ClutterKnot *knot)
|
||||
actor_apply_knot_foreach (ClutterBehaviour *behaviour,
|
||||
ClutterActor *actor,
|
||||
gpointer data)
|
||||
{
|
||||
ClutterKnot *knot = data;
|
||||
|
||||
clutter_actor_set_position (actor, knot->x, knot->y);
|
||||
}
|
||||
|
||||
@ -217,7 +220,7 @@ path_alpha_to_position (ClutterBehaviourPath *behave,
|
||||
if (offset == 0)
|
||||
{
|
||||
clutter_behaviour_actors_foreach (behaviour,
|
||||
(GFunc) actor_apply_knot_foreach,
|
||||
actor_apply_knot_foreach,
|
||||
priv->knots->data);
|
||||
|
||||
g_signal_emit (behave, path_signals[KNOT_REACHED], 0,
|
||||
@ -245,7 +248,7 @@ path_alpha_to_position (ClutterBehaviourPath *behave,
|
||||
interpolate (knot, next, &new, t);
|
||||
|
||||
clutter_behaviour_actors_foreach (behaviour,
|
||||
(GFunc)actor_apply_knot_foreach,
|
||||
actor_apply_knot_foreach,
|
||||
&new);
|
||||
|
||||
g_signal_emit (behave, path_signals[KNOT_REACHED], 0, &new);
|
||||
|
@ -81,30 +81,15 @@ enum
|
||||
};
|
||||
|
||||
static void
|
||||
scale_frame_foreach (ClutterActor *actor,
|
||||
ClutterBehaviourScale *behave)
|
||||
scale_frame_foreach (ClutterBehaviour *behaviour,
|
||||
ClutterActor *actor,
|
||||
gpointer data)
|
||||
{
|
||||
ClutterFixed scale, factor;
|
||||
guint32 alpha;
|
||||
ClutterBehaviourScalePrivate *priv;
|
||||
ClutterBehaviour *_behave;
|
||||
gint sw, sh, w, h;
|
||||
guint scale = GPOINTER_TO_UINT (data);
|
||||
|
||||
priv = CLUTTER_BEHAVIOUR_SCALE_GET_PRIVATE (behave);
|
||||
_behave = CLUTTER_BEHAVIOUR (behave);
|
||||
|
||||
alpha = clutter_alpha_get_alpha (clutter_behaviour_get_alpha (_behave));
|
||||
|
||||
/* FIXME: use all fixed if possible
|
||||
factor = CLUTTER_FIXED_DIV(CLUTTER_INT_TO_FIXED(alpha/2),
|
||||
CLUTTER_INT_TO_FIXED(CLUTTER_ALPHA_MAX_ALPHA/2));
|
||||
*/
|
||||
|
||||
factor = CLUTTER_FLOAT_TO_FIXED ((gdouble) alpha / CLUTTER_ALPHA_MAX_ALPHA);
|
||||
|
||||
scale = CLUTTER_FIXED_MUL (factor, (priv->scale_end - priv->scale_begin));
|
||||
|
||||
scale += priv->scale_begin;
|
||||
priv = CLUTTER_BEHAVIOUR_SCALE (behaviour)->priv;
|
||||
|
||||
clutter_actor_set_scalex (actor, scale, scale);
|
||||
|
||||
@ -143,9 +128,24 @@ static void
|
||||
clutter_behaviour_scale_alpha_notify (ClutterBehaviour *behave,
|
||||
guint32 alpha_value)
|
||||
{
|
||||
ClutterFixed scale, factor;
|
||||
ClutterBehaviourScalePrivate *priv;
|
||||
|
||||
priv = CLUTTER_BEHAVIOUR_SCALE (behave)->priv;
|
||||
|
||||
/* FIXME: use all fixed if possible
|
||||
factor = CLUTTER_FIXED_DIV(CLUTTER_INT_TO_FIXED(alpha/2),
|
||||
CLUTTER_INT_TO_FIXED(CLUTTER_ALPHA_MAX_ALPHA/2));
|
||||
*/
|
||||
|
||||
factor = CLUTTER_FLOAT_TO_FIXED ((gdouble) alpha_value / CLUTTER_ALPHA_MAX_ALPHA);
|
||||
|
||||
scale = CLUTTER_FIXED_MUL (factor, (priv->scale_end - priv->scale_begin));
|
||||
scale += priv->scale_begin;
|
||||
|
||||
clutter_behaviour_actors_foreach (behave,
|
||||
(GFunc) scale_frame_foreach,
|
||||
CLUTTER_BEHAVIOUR_SCALE (behave));
|
||||
scale_frame_foreach,
|
||||
GUINT_TO_POINTER (scale));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -144,6 +144,13 @@ clutter_behaviour_get_property (GObject *object,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_behaviour_alpha_notify_unimplemented (ClutterBehaviour *behaviour,
|
||||
guint32 alpha_value)
|
||||
{
|
||||
g_warning ("ClutterBehaviourClass::alpha_notify not implemented for `%s'",
|
||||
g_type_name (G_TYPE_FROM_INSTANCE (behaviour)));
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_behaviour_class_init (ClutterBehaviourClass *klass)
|
||||
@ -163,6 +170,8 @@ clutter_behaviour_class_init (ClutterBehaviourClass *klass)
|
||||
G_PARAM_CONSTRUCT |
|
||||
CLUTTER_PARAM_READWRITE));
|
||||
|
||||
klass->alpha_notify = clutter_behaviour_alpha_notify_unimplemented;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (ClutterBehaviourPrivate));
|
||||
}
|
||||
|
||||
@ -175,6 +184,16 @@ clutter_behaviour_init (ClutterBehaviour *self)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_behaviour_apply:
|
||||
* @behave: a #ClutterBehaviour
|
||||
* @actor: a #ClutterActor
|
||||
*
|
||||
* Applies @behave to @actor. This function adds a reference on
|
||||
* the actor.
|
||||
*
|
||||
* Since: 0.2
|
||||
*/
|
||||
void
|
||||
clutter_behaviour_apply (ClutterBehaviour *behave,
|
||||
ClutterActor *actor)
|
||||
@ -195,6 +214,16 @@ clutter_behaviour_apply (ClutterBehaviour *behave,
|
||||
behave->priv->actors = g_slist_prepend (behave->priv->actors, actor);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_behaviour_remove:
|
||||
* @behave: a #ClutterBehaviour
|
||||
* @actor: a #ClutterActor
|
||||
*
|
||||
* Removes @actor from the list of #ClutterActor<!-- -->s to which
|
||||
* @behave applies. This function removes a reference on the actor.
|
||||
*
|
||||
* Since: 0.2
|
||||
*/
|
||||
void
|
||||
clutter_behaviour_remove (ClutterBehaviour *behave,
|
||||
ClutterActor *actor)
|
||||
@ -215,17 +244,47 @@ clutter_behaviour_remove (ClutterBehaviour *behave,
|
||||
behave->priv->actors = g_slist_remove (behave->priv->actors, actor);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_behaviour_actors_foreach:
|
||||
* @behave: a #ClutterBehaviour
|
||||
* @func: a function called for each actor
|
||||
* @data: optional data to be passed to the function, or %NULL
|
||||
*
|
||||
* Calls @func for every actor driven by @behave.
|
||||
*
|
||||
* Since: 0.2
|
||||
*/
|
||||
void
|
||||
clutter_behaviour_actors_foreach (ClutterBehaviour *behave,
|
||||
GFunc func,
|
||||
gpointer userdata)
|
||||
ClutterBehaviourForeachFunc func,
|
||||
gpointer data)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BEHAVIOUR (behave));
|
||||
g_return_if_fail (func != NULL);
|
||||
|
||||
g_slist_foreach (behave->priv->actors, func, userdata);
|
||||
for (l = behave->priv->actors; l != NULL; l = l->next)
|
||||
{
|
||||
ClutterActor *actor = l->data;
|
||||
|
||||
g_assert (CLUTTER_IS_ACTOR (actor));
|
||||
|
||||
func (behave, actor, data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_behaviour_get_alpha:
|
||||
* @behave: a #ClutterBehaviour
|
||||
*
|
||||
* Retrieves the #ClutterAlpha object bound to @behave.
|
||||
*
|
||||
* Return value: a #ClutterAlpha object, or %NULL if no alpha
|
||||
* object has been bound to this behaviour.
|
||||
*
|
||||
* Since: 0.2
|
||||
*/
|
||||
ClutterAlpha*
|
||||
clutter_behaviour_get_alpha (ClutterBehaviour *behave)
|
||||
{
|
||||
@ -243,16 +302,36 @@ notify_cb (GObject *object,
|
||||
|
||||
klass = CLUTTER_BEHAVIOUR_GET_CLASS (behave);
|
||||
|
||||
CLUTTER_NOTE (BEHAVIOUR, "notify::alpha");
|
||||
|
||||
if (klass->alpha_notify)
|
||||
{
|
||||
guint32 alpha_value;
|
||||
|
||||
alpha_value = clutter_alpha_get_alpha (behave->priv->alpha);
|
||||
|
||||
CLUTTER_NOTE (BEHAVIOUR, "calling %s::alpha_notify (%p, %d)",
|
||||
g_type_name (G_TYPE_FROM_CLASS (klass)),
|
||||
behave, alpha_value);
|
||||
|
||||
klass->alpha_notify (behave, alpha_value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_behaviour_set_alpha:
|
||||
* @behave: a #ClutterBehaviour
|
||||
* @alpha: a #ClutterAlpha or %NULL to unset a previously set alpha
|
||||
*
|
||||
* Binds @alpha to a #ClutterBehaviour. The #ClutterAlpha object
|
||||
* is what makes a behaviour work: for each tick of the timeline
|
||||
* used by #ClutterAlpha a new value of the alpha parameter is
|
||||
* computed by the alpha function; the value should be used by
|
||||
* the #ClutterBehaviour to update one or more properties of the
|
||||
* actors to which the behaviour applies.
|
||||
*
|
||||
* Since: 0.2
|
||||
*/
|
||||
void
|
||||
clutter_behaviour_set_alpha (ClutterBehaviour *behave,
|
||||
ClutterAlpha *alpha)
|
||||
@ -266,12 +345,17 @@ clutter_behaviour_set_alpha (ClutterBehaviour *behave,
|
||||
|
||||
if (priv->notify_id)
|
||||
{
|
||||
CLUTTER_NOTE (BEHAVIOUR, "removing previous notify-id (%d)",
|
||||
priv->notify_id);
|
||||
|
||||
g_signal_handler_disconnect (priv->alpha, priv->notify_id);
|
||||
priv->notify_id = 0;
|
||||
}
|
||||
|
||||
if (priv->alpha)
|
||||
{
|
||||
CLUTTER_NOTE (BEHAVIOUR, "removing previous alpha object");
|
||||
|
||||
g_object_unref (priv->alpha);
|
||||
priv->alpha = NULL;
|
||||
}
|
||||
@ -284,5 +368,33 @@ clutter_behaviour_set_alpha (ClutterBehaviour *behave,
|
||||
priv->notify_id = g_signal_connect (priv->alpha, "notify::alpha",
|
||||
G_CALLBACK(notify_cb),
|
||||
behave);
|
||||
|
||||
CLUTTER_NOTE (BEHAVIOUR, "setting new alpha object (%p, notify:%d)",
|
||||
priv->alpha, priv->notify_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_behaviour_get_actors:
|
||||
* @behaviour: a #ClutterBehaviour
|
||||
*
|
||||
* Retrieves all the actors to which @behaviour applies.
|
||||
*
|
||||
* Return value: a list of actors. You should free the returned list
|
||||
* with g_slist_free() when finished using it.
|
||||
*
|
||||
* Since: 0.2
|
||||
*/
|
||||
GSList *
|
||||
clutter_behaviour_get_actors (ClutterBehaviour *behaviour)
|
||||
{
|
||||
GSList *retval, *l;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_BEHAVIOUR (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);
|
||||
}
|
||||
|
@ -59,6 +59,19 @@ typedef struct _ClutterBehaviour ClutterBehaviour;
|
||||
typedef struct _ClutterBehaviourPrivate ClutterBehaviourPrivate;
|
||||
typedef struct _ClutterBehaviourClass ClutterBehaviourClass;
|
||||
|
||||
/**
|
||||
* ClutterBehaviourFunction:
|
||||
* @behaviour: the #ClutterBehaviour
|
||||
* @actor: an actor driven by @behaviour
|
||||
* @data: optional data passed to the function
|
||||
*
|
||||
* This function is passed to clutter_behaviour_foreach_actor() and
|
||||
* will be called for each actor driven by @behaviour.
|
||||
*/
|
||||
typedef void (*ClutterBehaviourForeachFunc) (ClutterBehaviour *behaviour,
|
||||
ClutterActor *actor,
|
||||
gpointer data);
|
||||
|
||||
struct _ClutterBehaviour
|
||||
{
|
||||
/*< private >*/
|
||||
@ -90,8 +103,9 @@ void clutter_behaviour_apply (ClutterBehaviour *behave,
|
||||
void clutter_behaviour_remove (ClutterBehaviour *behave,
|
||||
ClutterActor *actor);
|
||||
void clutter_behaviour_actors_foreach (ClutterBehaviour *behave,
|
||||
GFunc func,
|
||||
ClutterBehaviourForeachFunc func,
|
||||
gpointer data);
|
||||
GSList * clutter_behaviour_get_actors (ClutterBehaviour *behave);
|
||||
ClutterAlpha *clutter_behaviour_get_alpha (ClutterBehaviour *behave);
|
||||
void clutter_behaviour_set_alpha (ClutterBehaviour *behave,
|
||||
ClutterAlpha *alpha);
|
||||
|
@ -7,7 +7,9 @@
|
||||
|
||||
#define CLUTTER_VERSION @CLUTTER_VERSION@
|
||||
#define CLUTTER_VERSION_S "@CLUTTER_VERSION@"
|
||||
#define CLUTTER_VERSION_HEX 0x@CLUTTER_MAJOR_VERSION@0@CLUTTER_MINOR_VERSION@0@CLUTTER_MICRO_VERSION@
|
||||
#define CLUTTER_VERSION_HEX ((CLUTTER_MAJOR_VERSION << 24) | \
|
||||
(CLUTTER_MINOR_VERSION << 16) | \
|
||||
(CLUTTER_MICRO_VERSION << 8))
|
||||
|
||||
#define CLUTTER_CHECK_VERSION(major,minor,micro) \
|
||||
(CLUTTER_MAJOR_VERSION > (major) || \
|
||||
|
@ -68,7 +68,9 @@ ClutterBehaviour
|
||||
ClutterBehaviourClass
|
||||
clutter_behaviour_apply
|
||||
clutter_behaviour_remove
|
||||
ClutterBehaviourForeachFunc
|
||||
clutter_behaviour_actors_foreach
|
||||
clutter_behaviour_get_actors
|
||||
clutter_behaviour_get_alpha
|
||||
clutter_behaviour_set_alpha
|
||||
<SUBSECTION Standard>
|
||||
|
@ -60,6 +60,16 @@ ClutterBehaviour
|
||||
@actor:
|
||||
|
||||
|
||||
<!-- ##### USER_FUNCTION ClutterBehaviourForeachFunc ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@behaviour:
|
||||
@actor:
|
||||
@data:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION clutter_behaviour_actors_foreach ##### -->
|
||||
<para>
|
||||
|
||||
@ -70,6 +80,15 @@ ClutterBehaviour
|
||||
@data:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION clutter_behaviour_get_actors ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@behave:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION clutter_behaviour_get_alpha ##### -->
|
||||
<para>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user