2008-11-17 Emmanuele Bassi <ebassi@linux.intel.com>

Bug 1014 - Clutter Animation API Improvements

	* clutter/Makefile.am:
	* clutter/clutter.h: Update the build

	* clutter/clutter-types.h: Add AnimationMode, an enumeration
	for easing functions.

	* clutter/clutter-alpha.[ch]: Add the :mode property to
	control the function bound to an Alpha instance using an
	enumeration value. Also add six new alpha functions:

		- ease-in, ease-out, ease-in-out
		- sine-in, sine-out, sine-in-out

	* clutter/clutter-deprecated.h: Deprecate the #defines for
	the alpha functions. They will be replaced by entries in the
	ClutterAnimationMode.

	* clutter/clutter-interval.[ch]: Add ClutterInterval, an
	object for defining, validating and computing an interval
	between two values.

	* clutter/clutter-animation.[ch]: Add ClutterAnimation, an
	object responsible for animation the properties of a single
	actor along an interval of values. ClutterAnimation memory
	management is automatic. A simple wrapper method for
	ClutterActor is provided:

		clutter_actor_animate()

	which will create, or update, an animation for the passed
	actor.

	* clutter/clutter-debug.h:
	* clutter/clutter-main.c: Add a new 'animation' debug note.

	* clutter/clutter-script.c: Clean up the alpha functions
	whitelist, and add the new functions.

	* doc/reference/clutter/Makefile.am:
	* doc/reference/clutter/clutter-sections.txt: Update the
	API reference.

	* doc/reference/clutter/clutter-animation.xml: Renamed to
	doc/reference/clutter/clutter-animation-tutorial.xml to
	avoid clashes with the ClutterAnimation section.

	* doc/reference/clutter/clutter-docs.sgml: Renamed to
	doc/reference/clutter/clutter-docs.xml, as it was an XML
	file and not a SGML file.

	* tests/Makefile.am:
	* tests/interactive/Makefile.am:
	* tests/interactive/test-animation.c:
	* tests/interactive/test-easing.c: Add two tests for the
	new simple animation API and the easing functions.

	* tests/interactive/test-actors.c:
	* tests/interactive/test-behave.c:
	* tests/interactive/test-depth.c:
	* tests/interactive/test-effects.c:
	* tests/interactive/test-layout.c:
	* tests/interactive/test-multistage.c:
	* tests/interactive/test-paint-wrapper.c:
	* tests/interactive/test-rotate.c:
	* tests/interactive/test-scale.c:
	* tests/interactive/test-texture-quality.c:
	* tests/interactive/test-threads.c:
	* tests/interactive/test-viewport.c: Update interactive tests
	to the deprecations and new alpha API.
This commit is contained in:
Emmanuele Bassi 2008-11-18 09:50:03 +00:00
parent 87a43f3375
commit 62844d5f04
35 changed files with 3634 additions and 278 deletions

146
.gitignore vendored
View File

@ -54,60 +54,102 @@ install-sh
libtool
ltmain.sh
missing
stamp-h1
tests/*.o
tests/test-actors
tests/test-behave
tests/test-boxes
tests/test-depth
tests/test-effects
tests/test-entry
tests/test-events
tests/test-fbo
tests/test-fullscreen
tests/test-grab
tests/test-model
tests/test-multistage
tests/test-offscreen
tests/test-opacity
tests/test-perspective
tests/test-project
tests/test-rotate
tests/test-scale
tests/test-score
tests/test-script
tests/test-shader
tests/test-text
tests/test-textures
tests/test-threads
tests/test-timeline
tests/test-timeline-dup-frames
tests/test-timeline-interpolate
tests/test-timeline-rewind
tests/test-timeline-smoothness
tests/test-unproject
tests/test-viewport
tests/test-cogl-offscreen
tests/test-cogl-primitives
tests/test-cogl-tex-convert
tests/test-cogl-tex-foreign
tests/test-cogl-tex-getset
tests/test-cogl-tex-polygon
tests/test-cogl-tex-tile
tests/test-pixmap
tests/test-stage-read-pixels
tests/test-clip
tests/test-layout
tests/test-random-text
tests/test-texture-quality
tests/test-paint-wrapper
tests/test-devices
tests/test-entry-auto
tests/test-invariants
tests/test-label-cache
tests/test-pick
mkinstalldirs
stamp-h1
/tests/interactive/*.o
/tests/conform/*.o
/tests/micro-bench/*.o
/tests/interactive/test-actors
/tests/interactive/test-behave
/tests/interactive/test-boxes
/tests/interactive/test-depth
/tests/interactive/test-effects
/tests/interactive/test-entry
/tests/interactive/test-events
/tests/interactive/test-fbo
/tests/interactive/test-fullscreen
/tests/interactive/test-grab
/tests/interactive/test-model
/tests/interactive/test-multistage
/tests/interactive/test-offscreen
/tests/interactive/test-opacity
/tests/interactive/test-perspective
/tests/interactive/test-project
/tests/interactive/test-rotate
/tests/interactive/test-scale
/tests/interactive/test-score
/tests/interactive/test-script
/tests/interactive/test-shader
/tests/interactive/test-text
/tests/interactive/test-textures
/tests/interactive/test-threads
/tests/interactive/test-timeline
/tests/interactive/test-timeline-dup-frames
/tests/interactive/test-timeline-interpolate
/tests/interactive/test-timeline-rewind
/tests/interactive/test-timeline-smoothness
/tests/interactive/test-unproject
/tests/interactive/test-viewport
/tests/interactive/test-cogl-offscreen
/tests/interactive/test-cogl-primitives
/tests/interactive/test-cogl-tex-convert
/tests/interactive/test-cogl-tex-foreign
/tests/interactive/test-cogl-tex-getset
/tests/interactive/test-cogl-tex-polygon
/tests/interactive/test-cogl-tex-tile
/tests/interactive/test-pixmap
/tests/interactive/test-stage-read-pixels
/tests/interactive/test-clip
/tests/interactive/test-layout
/tests/interactive/test-random-text
/tests/interactive/test-texture-quality
/tests/interactive/test-paint-wrapper
/tests/interactive/test-devices
/tests/interactive/test-label-cache
/tests/interactive/test-pick
/tests/interactive/test-animation
/tests/interactive/test-easing
/tests/interactive/test-interactive
/tests/interactive/redhand.png
/tests/interactive/test-script.json
/tests/conform/test-conformance
/tests/conform/test-conformance-results.xml
/tests/conform/test-conformance-results.html
/tests/conform/test_entry_append_some
/tests/conform/test_entry_cursor
/tests/conform/test_entry_delete_chars
/tests/conform/test_entry_delete_text
/tests/conform/test_entry_empty
/tests/conform/test_entry_event
/tests/conform/test_entry_insert
/tests/conform/test_entry_prepend_some
/tests/conform/test_entry_set_empty
/tests/conform/test_entry_set_text
/tests/conform/test_entry_utf8_validation
/tests/conform/test_fixed_constants
/tests/conform/test_initial_state
/tests/conform/test_label_cache
/tests/conform/test_mapped
/tests/conform/test_pick
/tests/conform/test_realized
/tests/conform/test_rect_set_color
/tests/conform/test_rect_set_size
/tests/conform/test_show_on_set_parent
/tests/conform/test_timeline
/tests/conform/test_timeline_dup_frames
/tests/conform/test_timeline_interpolate
/tests/conform/test_timeline_rewind
/tests/conform/test_timeline_smoothness
/tests/conform/test_label_opacity
/tests/conform/test_mesh_contiguous
/tests/conform/test_mesh_interleved
/tests/conform/test_mesh_mutability
/tests/conform/test_paint_opacity
/tests/conform/test_rectangle_opacity
/tests/micro-bench/test-text
/clutter/x11/clutter-x11-enum-types.[ch]
/clutter/x11/stamp-clutter-x11-enum-types.h
/po/Makefile.in.in
/po/POTFILES
*.swp
*~

View File

@ -1,3 +1,77 @@
2008-11-17 Emmanuele Bassi <ebassi@linux.intel.com>
Bug 1014 - Clutter Animation API Improvements
* clutter/Makefile.am:
* clutter/clutter.h: Update the build
* clutter/clutter-types.h: Add AnimationMode, an enumeration
for easing functions.
* clutter/clutter-alpha.[ch]: Add the :mode property to
control the function bound to an Alpha instance using an
enumeration value. Also add six new alpha functions:
- ease-in, ease-out, ease-in-out
- sine-in, sine-out, sine-in-out
* clutter/clutter-deprecated.h: Deprecate the #defines for
the alpha functions. They will be replaced by entries in the
ClutterAnimationMode.
* clutter/clutter-interval.[ch]: Add ClutterInterval, an
object for defining, validating and computing an interval
between two values.
* clutter/clutter-animation.[ch]: Add ClutterAnimation, an
object responsible for animation the properties of a single
actor along an interval of values. ClutterAnimation memory
management is automatic. A simple wrapper method for
ClutterActor is provided:
clutter_actor_animate()
which will create, or update, an animation for the passed
actor.
* clutter/clutter-debug.h:
* clutter/clutter-main.c: Add a new 'animation' debug note.
* clutter/clutter-script.c: Clean up the alpha functions
whitelist, and add the new functions.
* doc/reference/clutter/Makefile.am:
* doc/reference/clutter/clutter-sections.txt: Update the
API reference.
* doc/reference/clutter/clutter-animation.xml: Renamed to
doc/reference/clutter/clutter-animation-tutorial.xml to
avoid clashes with the ClutterAnimation section.
* doc/reference/clutter/clutter-docs.sgml: Renamed to
doc/reference/clutter/clutter-docs.xml, as it was an XML
file and not a SGML file.
* tests/Makefile.am:
* tests/interactive/Makefile.am:
* tests/interactive/test-animation.c:
* tests/interactive/test-easing.c: Add two tests for the
new simple animation API and the easing functions.
* tests/interactive/test-actors.c:
* tests/interactive/test-behave.c:
* tests/interactive/test-depth.c:
* tests/interactive/test-effects.c:
* tests/interactive/test-layout.c:
* tests/interactive/test-multistage.c:
* tests/interactive/test-paint-wrapper.c:
* tests/interactive/test-rotate.c:
* tests/interactive/test-scale.c:
* tests/interactive/test-texture-quality.c:
* tests/interactive/test-threads.c:
* tests/interactive/test-viewport.c: Update interactive tests
to the deprecations and new alpha API.
2008-11-17 Emmanuele Bassi <ebassi@linux.intel.com>
* clutter/clutter-entry.c:

View File

@ -47,6 +47,7 @@ BUILT_SOURCES = $(MARSHALFILES) $(ENUMFILES)
source_h = \
$(srcdir)/clutter-actor.h \
$(srcdir)/clutter-alpha.h \
$(srcdir)/clutter-animation.h \
$(srcdir)/clutter-backend.h \
$(srcdir)/clutter-behaviour.h \
$(srcdir)/clutter-behaviour-bspline.h \
@ -68,6 +69,7 @@ source_h = \
$(srcdir)/clutter-fixed.h \
$(srcdir)/clutter-frame-source.h \
$(srcdir)/clutter-group.h \
$(srcdir)/clutter-interval.h \
$(srcdir)/clutter-keysyms.h \
$(srcdir)/clutter-label.h \
$(srcdir)/clutter-list-model.h \
@ -133,6 +135,7 @@ CLEANFILES = $(STAMPFILES)
source_c = \
clutter-actor.c \
clutter-alpha.c \
clutter-animation.c \
clutter-backend.c \
clutter-behaviour.c \
clutter-behaviour-bspline.c \
@ -155,6 +158,7 @@ source_c = \
clutter-frame-source.c \
clutter-group.c \
clutter-id-pool.c \
clutter-interval.c \
clutter-label.c \
clutter-list-model.c \
clutter-main.c \

View File

@ -58,10 +58,11 @@
#include <math.h>
#include "clutter-alpha.h"
#include "clutter-debug.h"
#include "clutter-enum-types.h"
#include "clutter-main.h"
#include "clutter-marshal.h"
#include "clutter-private.h"
#include "clutter-debug.h"
G_DEFINE_TYPE (ClutterAlpha, clutter_alpha, G_TYPE_INITIALLY_UNOWNED);
@ -74,6 +75,8 @@ struct _ClutterAlphaPrivate
guint32 alpha;
GClosure *closure;
ClutterAnimationMode mode;
};
enum
@ -81,7 +84,8 @@ enum
PROP_0,
PROP_TIMELINE,
PROP_ALPHA
PROP_ALPHA,
PROP_MODE
};
static void
@ -113,6 +117,9 @@ clutter_alpha_set_property (GObject *object,
case PROP_TIMELINE:
clutter_alpha_set_timeline (alpha, g_value_get_object (value));
break;
case PROP_MODE:
clutter_alpha_set_mode (alpha, g_value_get_enum (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -139,6 +146,9 @@ clutter_alpha_get_property (GObject *object,
case PROP_ALPHA:
g_value_set_uint (value, priv->alpha);
break;
case PROP_MODE:
g_value_set_enum (value, priv->mode);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -209,6 +219,25 @@ clutter_alpha_class_init (ClutterAlphaClass *klass)
CLUTTER_ALPHA_MAX_ALPHA,
0,
CLUTTER_PARAM_READABLE));
/**
* ClutterAlpha:mode:
*
* The progress function as a #ClutterAnimationMode enumeration
* value. If %CLUTTER_CUSTOM_MODE is used then the function set
* using clutter_alpha_set_closure() or clutter_alpha_set_func()
* will be used.
*
* Since: 1.0
*/
g_object_class_install_property (object_class,
PROP_MODE,
g_param_spec_enum ("mode",
"Mode",
"Progress mode",
CLUTTER_TYPE_ANIMATION_MODE,
CLUTTER_CUSTOM_MODE,
G_PARAM_CONSTRUCT |
CLUTTER_PARAM_READWRITE));
}
static void
@ -217,6 +246,8 @@ clutter_alpha_init (ClutterAlpha *self)
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
CLUTTER_TYPE_ALPHA,
ClutterAlphaPrivate);
self->priv->mode = CLUTTER_CUSTOM_MODE;
}
/**
@ -302,6 +333,9 @@ clutter_alpha_set_closure (ClutterAlpha *alpha,
g_closure_set_marshal (closure, marshal);
}
priv->mode = CLUTTER_CUSTOM_MODE;
g_object_notify (G_OBJECT (alpha), "mode");
}
/**
@ -370,6 +404,8 @@ clutter_alpha_set_timeline (ClutterAlpha *alpha,
G_CALLBACK (timeline_new_frame_cb),
alpha);
}
g_object_notify (G_OBJECT (alpha), "timeline");
}
/**
@ -444,6 +480,106 @@ clutter_alpha_new_full (ClutterTimeline *timeline,
return retval;
}
/**
* clutter_alpha_new_for_mode:
* @mode: a #ClutterAnimationMode value
*
* Creates a new #ClutterAlpha using @mode to set the
* progress function using its symbolic name.
*
* Return value: the newly created #ClutterAlpha
*
* Since: 1.0
*/
ClutterAlpha *
clutter_alpha_new_for_mode (ClutterAnimationMode mode)
{
return g_object_new (CLUTTER_TYPE_ALPHA,
"mode", mode,
NULL);
}
/**
* clutter_alpha_get_mode:
* @alpha: a #ClutterAlpha
*
* Retrieves the #ClutterAnimatioMode used by @alpha.
*
* Return value: the animation mode
*
* Since: 1.0
*/
ClutterAnimationMode
clutter_alpha_get_mode (ClutterAlpha *alpha)
{
g_return_val_if_fail (CLUTTER_IS_ALPHA (alpha), CLUTTER_CUSTOM_MODE);
return alpha->priv->mode;
}
/**
* clutter_alpha_set_mode:
* @alpha: a #ClutterAlpha
* @mode: a #ClutterAnimationMode
*
* Sets the progress function of @alpha using the symbolic value
* of @mode, as taken by the #ClutterAnimationMode enumeration
*
* Since: 1.0
*/
void
clutter_alpha_set_mode (ClutterAlpha *alpha,
ClutterAnimationMode mode)
{
ClutterAlphaPrivate *priv;
g_return_if_fail (CLUTTER_IS_ALPHA (alpha));
priv = alpha->priv;
priv->mode = mode;
switch (priv->mode)
{
case CLUTTER_LINEAR:
clutter_alpha_set_func (alpha, clutter_ramp_inc_func, NULL, NULL);
break;
case CLUTTER_SINE_IN:
clutter_alpha_set_func (alpha, clutter_sine_in_func, NULL, NULL);
break;
case CLUTTER_SINE_OUT:
clutter_alpha_set_func (alpha, clutter_sine_out_func, NULL, NULL);
break;
case CLUTTER_SINE_IN_OUT:
clutter_alpha_set_func (alpha, clutter_sine_inc_func, NULL, NULL);
break;
case CLUTTER_EASE_IN:
clutter_alpha_set_func (alpha, clutter_ease_in_func, NULL, NULL);
break;
case CLUTTER_EASE_OUT:
clutter_alpha_set_func (alpha, clutter_ease_out_func, NULL, NULL);
break;
case CLUTTER_EASE_IN_OUT:
clutter_alpha_set_func (alpha, clutter_ease_in_out_func, NULL, NULL);
break;
case CLUTTER_CUSTOM_MODE:
break;
default:
g_assert_not_reached ();
break;
}
g_object_notify (G_OBJECT (alpha), "mode");
}
/**
* CLUTTER_ALPHA_RAMP_INC:
*
@ -789,11 +925,11 @@ guint32
clutter_sine_half_func (ClutterAlpha *alpha,
gpointer dummy)
{
ClutterTimeline * timeline;
gint frame;
gint n_frames;
ClutterAngle x;
ClutterFixed sine;
ClutterTimeline *timeline;
gint frame;
gint n_frames;
ClutterAngle x;
ClutterFixed sine;
timeline = clutter_alpha_get_timeline (alpha);
frame = clutter_timeline_get_current_frame (timeline);
@ -803,7 +939,115 @@ clutter_sine_half_func (ClutterAlpha *alpha,
sine = cogl_angle_sin (x) * CLUTTER_ALPHA_MAX_ALPHA;
return COGL_FIXED_TO_INT (sine);
return ((guint32) sine) >> COGL_FIXED_Q;
}
/**
* clutter_sine_in_func:
* @alpha: a #ClutterAlpha
* @dummy: unused argument
*
* Convenience alpha function for (sin(x) + 1) over the
* interval [-pi/2, 0].
*
* You can use this function as the alpha function for
* clutter_alpha_set_func().
*
* Return value: an alpha value.
*
* Since: 1.0
*/
guint32
clutter_sine_in_func (ClutterAlpha *alpha,
gpointer dummy)
{
ClutterTimeline *timeline;
gint frame;
gint n_frames;
ClutterAngle x;
ClutterFixed sine;
timeline = clutter_alpha_get_timeline (alpha);
frame = clutter_timeline_get_current_frame (timeline);
n_frames = clutter_timeline_get_n_frames (timeline);
/* XXX- if we use 768 we overflow */
x = 256 * frame / n_frames + 767;
sine = (cogl_angle_sin (x) + 1) * CLUTTER_ALPHA_MAX_ALPHA;
return ((guint32) sine) >> COGL_FIXED_Q;
}
/**
* clutter_sine_in_func:
* @alpha: a #ClutterAlpha
* @dummy: unused argument
*
* Convenience alpha function for sin(x) over the interval [0, pi/2].
*
* You can use this function as the alpha function for
* clutter_alpha_set_func().
*
* Return value: an alpha value.
*
* Since: 1.0
*/
guint32
clutter_sine_out_func (ClutterAlpha *alpha,
gpointer dummy)
{
ClutterTimeline *timeline;
gint frame;
gint n_frames;
ClutterAngle x;
ClutterFixed sine;
timeline = clutter_alpha_get_timeline (alpha);
frame = clutter_timeline_get_current_frame (timeline);
n_frames = clutter_timeline_get_n_frames (timeline);
x = 256 * frame / n_frames;
sine = cogl_angle_sin (x) * CLUTTER_ALPHA_MAX_ALPHA;
return ((guint32) sine) >> COGL_FIXED_Q;
}
/**
* clutter_sine_in_out_func:
* @alpha: a #ClutterAlpha
* @dummy: unused argument
*
* Convenience alpha function for (sin(x) + 1) / 2 over the
* interval [-pi/2, pi/2].
*
* You can use this function as the alpha function for
* clutter_alpha_set_func().
*
* Return value: an alpha value.
*
* Since: 1.0
*/
guint32
clutter_sine_in_out_func (ClutterAlpha *alpha,
gpointer dummy)
{
ClutterTimeline *timeline;
gint frame;
gint n_frames;
ClutterAngle x;
ClutterFixed sine;
timeline = clutter_alpha_get_timeline (alpha);
frame = clutter_timeline_get_current_frame (timeline);
n_frames = clutter_timeline_get_n_frames (timeline);
x = -256 * frame / n_frames + 256;
sine = (cogl_angle_sin (x) + 1) / 2 * CLUTTER_ALPHA_MAX_ALPHA;
return ((guint32) sine) >> COGL_FIXED_Q;
}
/**
@ -812,6 +1056,8 @@ clutter_sine_half_func (ClutterAlpha *alpha,
* Convenience symbol for clutter_square_func().
*
* Since: 0.4
*
* Deprecated: 1.0: Use clutter_square_func() instead
*/
/**
@ -1025,3 +1271,131 @@ clutter_exp_dec_func (ClutterAlpha *alpha,
return result;
}
static inline gdouble
clutter_cubic_bezier (ClutterAlpha *alpha,
gdouble x_1,
gdouble y_1,
gdouble x_2,
gdouble y_2)
{
ClutterTimeline *timeline;
gdouble t, b_t, res;
/* the cubic bezier has a parametric form of:
*
* B(t) = (1 - t)^3 * P_0
* + 3t * (1 - t)^2 * P_1
* + 3t^2 * (1 - t) * P_2
* + 3t^3 * P_3 (with t included in [0, 1])
*
* the P_0 and P_3 points are set to (0, 0) and (1, 1) respectively,
* and the curve never passes through P_1 and P_2 - with these two
* points merely acting as control points for the curve starting
* from P_0 and ending at P_3.
*
* since the starting point is (0, 0) we can simplify the previous
* parametric form to:
*
* B(t) = 3t * (1 - t)^2 * P_1
* + 3t^2 * (1 - t) * P_2
* + 3t^3 * P_3 (with t included in [0, 1])
*
* and, similarly, since the final point is (1, 1) we can simplify
* it further to:
*
* B(t) = 3t * (1 - t)^2 * P_1
* + 3t^2 * (1 - t) * P_2
* + 3t^3 (with t included in [0, 1])
*
* since an alpha function has only a time parameter and we have two
* coordinates for each point, we pass the time as the first
* coordinate for the point and then we solve the cubic beziér curve
* for the second coordinate at the same point.
*/
timeline = clutter_alpha_get_timeline (alpha);
t = clutter_timeline_get_progress (timeline);
b_t = 3 * t * pow (1 - t, 2) * x_1
+ 3 * pow (t, 2) * (1 - t) * x_2
+ 3 * pow (t, 3);
res = 3 * b_t * pow (1 - b_t, 2) * y_1
+ 3 * pow (b_t, 2) * (1 - b_t) * y_2
+ 3 * pow (b_t, 3);
return res;
}
/**
* clutter_ease_in_func:
* @alpha: a #ClutterAlpha
* @dummy: unused argument
*
* Convenience alpha function for a cubic Beziér curve with control
* points at (0.42, 0) and (1, 0). You can use this function as the
* alpha function for clutter_alpha_set_func().
*
* Return value: an alpha value.
*
* Since: 1.0
*/
guint32
clutter_ease_in_func (ClutterAlpha *alpha,
gpointer dummy)
{
gdouble res;
res = clutter_cubic_bezier (alpha, 0.42, 0, 1, 0);
return CLAMP (res * CLUTTER_ALPHA_MAX_ALPHA, 0, CLUTTER_ALPHA_MAX_ALPHA);
}
/**
* clutter_ease_out_func:
* @alpha: a #ClutterAlpha
* @dummy: unused argument
*
* Convenience alpha function for a cubic Beziér curve with control
* points at (0, 0) and (0.58, 1). You can use this function as the
* alpha function for clutter_alpha_set_func().
*
* Return value: an alpha value.
*
* Since: 1.0
*/
guint32
clutter_ease_out_func (ClutterAlpha *alpha,
gpointer dummy)
{
gdouble res;
res = clutter_cubic_bezier (alpha, 0, 0, 0.58, 1);
return CLAMP (res * CLUTTER_ALPHA_MAX_ALPHA, 0, CLUTTER_ALPHA_MAX_ALPHA);
}
/**
* clutter_ease_in_out_func:
* @alpha: a #ClutterAlpha
* @dummy: unused argument
*
* Convenience alpha function for a cubic Beziér curve with control
* points at (0.42, 0) and (0.58, 1). You can use this function as
* the alpha function for clutter_alpha_set_func().
*
* Return value: an alpha value.
*
* Since: 1.0
*/
guint32
clutter_ease_in_out_func (ClutterAlpha *alpha,
gpointer dummy)
{
gdouble res;
res = clutter_cubic_bezier (alpha, 0.42, 0, 0.58, 1);
return CLAMP (res * CLUTTER_ALPHA_MAX_ALPHA, 0, CLUTTER_ALPHA_MAX_ALPHA);
}

View File

@ -31,9 +31,9 @@
#ifndef __CLUTTER_ALPHA_H__
#define __CLUTTER_ALPHA_H__
#include <glib-object.h>
#include <clutter/clutter-timeline.h>
#include <clutter/clutter-fixed.h>
#include <clutter/clutter-timeline.h>
#include <clutter/clutter-types.h>
G_BEGIN_DECLS
@ -125,42 +125,36 @@ struct _ClutterAlphaClass
GType clutter_alpha_get_type (void) G_GNUC_CONST;
ClutterAlpha * clutter_alpha_new (void);
ClutterAlpha * clutter_alpha_new_full (ClutterTimeline *timeline,
ClutterAlphaFunc func,
gpointer data,
GDestroyNotify destroy);
guint32 clutter_alpha_get_alpha (ClutterAlpha *alpha);
void clutter_alpha_set_func (ClutterAlpha *alpha,
ClutterAlphaFunc func,
gpointer data,
GDestroyNotify destroy);
void clutter_alpha_set_closure (ClutterAlpha *alpha,
GClosure *closure);
void clutter_alpha_set_timeline (ClutterAlpha *alpha,
ClutterTimeline *timeline);
ClutterTimeline *clutter_alpha_get_timeline (ClutterAlpha *alpha);
ClutterAlpha * clutter_alpha_new (void);
ClutterAlpha * clutter_alpha_new_full (ClutterTimeline *timeline,
ClutterAlphaFunc func,
gpointer data,
GDestroyNotify destroy);
ClutterAlpha * clutter_alpha_new_for_mode (ClutterAnimationMode mode);
guint32 clutter_alpha_get_alpha (ClutterAlpha *alpha);
void clutter_alpha_set_func (ClutterAlpha *alpha,
ClutterAlphaFunc func,
gpointer data,
GDestroyNotify destroy);
void clutter_alpha_set_closure (ClutterAlpha *alpha,
GClosure *closure);
void clutter_alpha_set_timeline (ClutterAlpha *alpha,
ClutterTimeline *timeline);
ClutterTimeline * clutter_alpha_get_timeline (ClutterAlpha *alpha);
void clutter_alpha_set_mode (ClutterAlpha *alpha,
ClutterAnimationMode mode);
ClutterAnimationMode clutter_alpha_get_mode (ClutterAlpha *alpha);
/* convenience functions */
#define CLUTTER_ALPHA_RAMP_INC clutter_ramp_inc_func
#define CLUTTER_ALPHA_RAMP_DEC clutter_ramp_dec_func
#define CLUTTER_ALPHA_RAMP clutter_ramp_func
#define CLUTTER_ALPHA_SINE clutter_sine_func
#define CLUTTER_ALPHA_SINE_INC clutter_sine_inc_func
#define CLUTTER_ALPHA_SINE_DEC clutter_sine_dec_func
#define CLUTTER_ALPHA_SINE_HALF clutter_sine_half_func
#define CLUTTER_ALPHA_SQUARE clutter_square_func
#define CLUTTER_ALPHA_SMOOTHSTEP_INC clutter_smoothstep_inc_func
#define CLUTTER_ALPHA_SMOOTHSTEP_DEC clutter_smoothstep_dec_func
#define CLUTTER_ALPHA_EXP_INC clutter_exp_inc_func
#define CLUTTER_ALPHA_EXP_DEC clutter_exp_dec_func
guint32 clutter_ramp_inc_func (ClutterAlpha *alpha,
gpointer dummy);
guint32 clutter_ramp_dec_func (ClutterAlpha *alpha,
gpointer dummy);
guint32 clutter_ramp_func (ClutterAlpha *alpha,
gpointer dummy);
guint32 clutter_sine_func (ClutterAlpha *alpha,
gpointer dummy);
guint32 clutter_sine_inc_func (ClutterAlpha *alpha,
@ -169,17 +163,33 @@ guint32 clutter_sine_dec_func (ClutterAlpha *alpha,
gpointer dummy);
guint32 clutter_sine_half_func (ClutterAlpha *alpha,
gpointer dummy);
guint32 clutter_sine_in_func (ClutterAlpha *alpha,
gpointer dummy);
guint32 clutter_sine_out_func (ClutterAlpha *alpha,
gpointer dummy);
guint32 clutter_sine_in_out_func (ClutterAlpha *alpha,
gpointer dummy);
guint32 clutter_square_func (ClutterAlpha *alpha,
gpointer dummy);
guint32 clutter_smoothstep_inc_func (ClutterAlpha *alpha,
gpointer dummy);
guint32 clutter_smoothstep_dec_func (ClutterAlpha *alpha,
gpointer dummy);
guint32 clutter_exp_inc_func (ClutterAlpha *alpha,
gpointer dummy);
guint32 clutter_exp_dec_func (ClutterAlpha *alpha,
gpointer dummy);
guint32 clutter_ease_in_func (ClutterAlpha *alpha,
gpointer dummy);
guint32 clutter_ease_out_func (ClutterAlpha *alpha,
gpointer dummy);
guint32 clutter_ease_in_out_func (ClutterAlpha *alpha,
gpointer dummy);
G_END_DECLS
#endif /* __CLUTTER_ALPHA_H__ */

1431
clutter/clutter-animation.c Normal file

File diff suppressed because it is too large Load Diff

149
clutter/clutter-animation.h Normal file
View File

@ -0,0 +1,149 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2008 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_ANIMATION_H__
#define __CLUTTER_ANIMATION_H__
#include <clutter/clutter-actor.h>
#include <clutter/clutter-alpha.h>
#include <clutter/clutter-interval.h>
#include <clutter/clutter-timeline.h>
#include <clutter/clutter-types.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_ANIMATION (clutter_animation_get_type ())
#define CLUTTER_ANIMATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ANIMATION, ClutterAnimation))
#define CLUTTER_IS_ANIMATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ANIMATION))
#define CLUTTER_ANIMATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ANIMATION, ClutterAnimationClass))
#define CLUTTER_IS_ANIMATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ANIMATION))
#define CLUTTER_ANIMATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ANIMATION, ClutterAnimationClass))
typedef struct _ClutterAnimation ClutterAnimation;
typedef struct _ClutterAnimationPrivate ClutterAnimationPrivate;
typedef struct _ClutterAnimationClass ClutterAnimationClass;
/**
* ClutterAnimation:
*
* The #ClutterAnimation structure contains only private data and should
* be accessed using the provided functions.
*
* Since: 1.0
*/
struct _ClutterAnimation
{
/*< private >*/
GInitiallyUnowned parent_instance;
ClutterAnimationPrivate *priv;
};
/**
* ClutterAnimationClass:
* @completed: class handler for the #ClutterAnimation::completed signal
*
* The #ClutterAnimationClass structure contains only private data and
* should be accessed using the provided functions.
*
* Since: 1.0
*/
struct _ClutterAnimationClass
{
/*< private >*/
GInitiallyUnownedClass parent_class;
/*< public >*/
void (* completed) (ClutterAnimation *animation);
/*< private >*/
/* padding for future expansion */
void (*_clutter_reserved1) (void);
void (*_clutter_reserved2) (void);
void (*_clutter_reserved3) (void);
void (*_clutter_reserved4) (void);
void (*_clutter_reserved5) (void);
void (*_clutter_reserved6) (void);
void (*_clutter_reserved7) (void);
void (*_clutter_reserved8) (void);
};
GType clutter_animation_get_type (void) G_GNUC_CONST;
ClutterAnimation * clutter_animation_new (void);
void clutter_animation_set_actor (ClutterAnimation *animation,
ClutterActor *actor);
ClutterActor * clutter_animation_get_actor (ClutterAnimation *animation);
void clutter_animation_set_mode (ClutterAnimation *animation,
ClutterAnimationMode mode);
ClutterAnimationMode clutter_animation_get_mode (ClutterAnimation *animation);
void clutter_animation_set_duration (ClutterAnimation *animation,
gint msecs);
guint clutter_animation_get_duration (ClutterAnimation *animation);
void clutter_animation_set_loop (ClutterAnimation *animation,
gboolean loop);
gboolean clutter_animation_get_loop (ClutterAnimation *animation);
void clutter_animation_set_timeline (ClutterAnimation *animation,
ClutterTimeline *timeline);
ClutterTimeline * clutter_animation_get_timeline (ClutterAnimation *animation);
void clutter_animation_set_alpha (ClutterAnimation *animation,
ClutterAlpha *alpha);
ClutterAlpha * clutter_animation_get_alpha (ClutterAnimation *animation);
void clutter_animation_bind_property (ClutterAnimation *animation,
const gchar *property_name,
ClutterInterval *interval);
gboolean clutter_animation_has_property (ClutterAnimation *animation,
const gchar *property_name);
void clutter_animation_update_property (ClutterAnimation *animation,
const gchar *property_name,
ClutterInterval *interval);
void clutter_animation_unbind_property (ClutterAnimation *animation,
const gchar *property_name);
ClutterInterval *clutter_animation_get_interval (ClutterAnimation *animation,
const gchar *property_name);
ClutterAnimation * clutter_actor_animate (ClutterActor *actor,
ClutterAnimationMode mode,
guint duration,
const gchar *first_property_name,
...) G_GNUC_NULL_TERMINATED;
ClutterAnimation * clutter_actor_animate_with_timeline (ClutterActor *actor,
ClutterAnimationMode mode,
ClutterTimeline *timeline,
const gchar *first_property_name,
...) G_GNUC_NULL_TERMINATED;
ClutterAnimation * clutter_actor_animate_with_alpha (ClutterActor *actor,
ClutterAlpha *alpha,
const gchar *first_property_name,
...) G_GNUC_NULL_TERMINATED;
G_END_DECLS
#endif /* __CLUTTER_ANIMATION_H__ */

View File

@ -20,7 +20,8 @@ typedef enum {
CLUTTER_DEBUG_SCHEDULER = 1 << 10,
CLUTTER_DEBUG_SCRIPT = 1 << 11,
CLUTTER_DEBUG_SHADER = 1 << 12,
CLUTTER_DEBUG_MULTISTAGE = 1 << 13
CLUTTER_DEBUG_MULTISTAGE = 1 << 13,
CLUTTER_DEBUG_ANIMATION = 1 << 14
} ClutterDebugFlag;
#ifdef CLUTTER_ENABLE_DEBUG

View File

@ -52,4 +52,17 @@
#define clutter_actor_get_abs_size clutter_actor_get_abs_size_REPLACED_BY_clutter_actor_get_transformed_size
#define clutter_actor_get_abs_opacity clutter_actor_get_abs_opacity_REPLACED_BY_clutter_actor_get_paint_opacity
#define CLUTTER_ALPHA_RAMP_INC CLUTTER_ALPHA_RAMP_INC_DEPRECATED_BY_clutter_ramp_inc_func
#define CLUTTER_ALPHA_RAMP_DEC CLUTTER_ALPHA_RAMP_DEC_DEPRECATED_BY_clutter_ramp_dec_func
#define CLUTTER_ALPHA_RAMP CLUTTER_ALPHA_RAMP_DEPRECATED_BY_clutter_ramp_func
#define CLUTTER_ALPHA_SINE_INC CLUTTER_ALPHA_SINE_INC_DEPRECATED_BY_clutter_sine_inc_func
#define CLUTTER_ALPHA_SINE_DEC CLUTTER_ALPHA_SINE_DEC_DEPRECATED_BY_clutter_sine_dec_func
#define CLUTTER_ALPHA_SINE_HALF CLUTTER_ALPHA_SINE_HALF_DEPRECATED_BY_clutter_sine_half_func
#define CLUTTER_ALPHA_SINE CLUTTER_ALPHA_SINE_DEPRECATED_BY_clutter_sine_func
#define CLUTTER_ALPHA_SQUARE CLUTTER_ALPHA_SQUARE_DEPRECATED_BY_clutter_quare_func
#define CLUTTER_ALPHA_SMOOTHSTEP_INC CLUTTER_ALPHA_SMOOTHSTEP_INC_DEPRECATED_BY_clutter_smoothstep_inc_func
#define CLUTTER_ALPHA_SMOOTHSTEP_DEC CLUTTER_ALPHA_SMOOTHSTEP_DEC_DEPRECATED_BY_clutter_smoothstep_dec_func
#define CLUTTER_ALPHA_EXP_INC CLUTTER_ALPHA_EXP_INC_DEPRECATED_BY_clutter_exp_inc_func
#define CLUTTER_ALPHA_EXP_DEC CLUTTER_ALPHA_EXP_DEC_DEPRECATED_BY_clutter_exp_dec_func
#endif /* CLUTTER_DEPRECATED_H */

836
clutter/clutter-interval.c Normal file
View File

@ -0,0 +1,836 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2008 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-interval
* @short_description: An object holding an interval of two values
*
* #ClutterInterval is a simple object that can hold two values
* defining an interval. #ClutterInterval can hold any value that
* can be enclosed inside a #GValue.
*
* Once a #ClutterInterval for a specific #GType has been instantiated
* the #ClutterInterval:value-type property cannot be changed anymore.
*
* #ClutterInterval starts with a floating reference; this means that
* any object taking a reference on a #ClutterInterval instance should
* also take ownership of the interval by using g_object_ref_sink().
*
* #ClutterInterval is used by #ClutterAnimation to define the
* interval of values that an implicit animation should tween over.
*
* #ClutterInterval can be subclassed to override the validation
* and value computation.
*
* #ClutterInterval is available since Clutter 1.0
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <glib-object.h>
#include <gobject/gvaluecollector.h>
#include "clutter-interval.h"
#include "clutter-units.h"
#include "clutter-fixed.h"
enum
{
PROP_0,
PROP_VALUE_TYPE
};
#define CLUTTER_INTERVAL_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_INTERVAL, ClutterIntervalPrivate))
struct _ClutterIntervalPrivate
{
GType value_type;
GValue *values;
};
G_DEFINE_TYPE (ClutterInterval, clutter_interval, G_TYPE_INITIALLY_UNOWNED);
static gboolean
clutter_interval_real_validate (ClutterInterval *interval,
GParamSpec *pspec)
{
GType pspec_gtype = G_PARAM_SPEC_VALUE_TYPE (pspec);
/* check the GTypes we provide first */
if (pspec_gtype == CLUTTER_TYPE_UNIT)
{
ClutterParamSpecUnit *pspec_unit = CLUTTER_PARAM_SPEC_UNIT (pspec);
ClutterFixed a, b;
a = b = 0;
clutter_interval_get_interval (interval, &a, &b);
if ((a >= pspec_unit->minimum && a <= pspec_unit->maximum) &&
(b >= pspec_unit->minimum && b <= pspec_unit->maximum))
return TRUE;
else
return FALSE;
}
else if (pspec_gtype == CLUTTER_TYPE_FIXED)
{
ClutterParamSpecFixed *pspec_fixed = CLUTTER_PARAM_SPEC_FIXED (pspec);
ClutterFixed a, b;
a = b = 0;
clutter_interval_get_interval (interval, &a, &b);
if ((a >= pspec_fixed->minimum && a <= pspec_fixed->maximum) &&
(b >= pspec_fixed->minimum && b <= pspec_fixed->maximum))
return TRUE;
else
return FALSE;
}
/* then check the fundamental types */
switch (G_TYPE_FUNDAMENTAL (pspec_gtype))
{
case G_TYPE_INT:
{
GParamSpecInt *pspec_int = G_PARAM_SPEC_INT (pspec);
gint a, b;
a = b = 0;
clutter_interval_get_interval (interval, &a, &b);
if ((a >= pspec_int->minimum && a <= pspec_int->maximum) &&
(b >= pspec_int->minimum && b <= pspec_int->maximum))
return TRUE;
else
return FALSE;
}
break;
case G_TYPE_UINT:
{
GParamSpecUInt *pspec_uint = G_PARAM_SPEC_UINT (pspec);
guint a, b;
a = b = 0;
clutter_interval_get_interval (interval, &a, &b);
if ((a >= pspec_uint->minimum && a <= pspec_uint->maximum) &&
(b >= pspec_uint->minimum && b <= pspec_uint->maximum))
return TRUE;
else
return FALSE;
}
break;
case G_TYPE_UCHAR:
{
GParamSpecUChar *pspec_uchar = G_PARAM_SPEC_UCHAR (pspec);
guchar a, b;
a = b = 0;
clutter_interval_get_interval (interval, &a, &b);
if ((a >= pspec_uchar->minimum && a <= pspec_uchar->maximum) &&
(b >= pspec_uchar->minimum && b <= pspec_uchar->maximum))
return TRUE;
else
return FALSE;
}
break;
case G_TYPE_BOOLEAN:
return TRUE;
default:
break;
}
return TRUE;
}
static void
clutter_interval_real_compute_value (ClutterInterval *interval,
gdouble factor,
GValue *value)
{
GValue *initial, *final;
GType value_type;
initial = clutter_interval_peek_initial_value (interval);
final = clutter_interval_peek_final_value (interval);
value_type = clutter_interval_get_value_type (interval);
switch (G_TYPE_FUNDAMENTAL (value_type))
{
case G_TYPE_INT:
{
gint ia, ib, res;
ia = g_value_get_int (initial);
ib = g_value_get_int (final);
res = (factor * (ib - ia)) + ia;
g_value_set_int (value, res);
}
break;
case G_TYPE_UINT:
{
guint ia, ib, res;
ia = g_value_get_uint (initial);
ib = g_value_get_uint (final);
res = (factor * (ib - ia)) + ia;
g_value_set_uint (value, res);
}
break;
case G_TYPE_UCHAR:
{
guchar ia, ib, res;
ia = g_value_get_uchar (initial);
ib = g_value_get_uchar (final);
res = (factor * (ib - ia)) + ia;
g_value_set_uchar (value, res);
}
break;
case G_TYPE_FLOAT:
case G_TYPE_DOUBLE:
{
gdouble ia, ib, res;
ia = g_value_get_double (initial);
ib = g_value_get_double (final);
res = (factor * (ib - ia)) + ia;
if (value_type == G_TYPE_DOUBLE)
g_value_set_double (value, res);
else
g_value_set_float (value, res);
}
break;
case G_TYPE_BOOLEAN:
if (COGL_FIXED_FROM_FLOAT (factor) > COGL_FIXED_0_5)
g_value_set_boolean (value, TRUE);
else
g_value_set_boolean (value, FALSE);
break;
default:
break;
}
}
static void
clutter_interval_finalize (GObject *gobject)
{
ClutterIntervalPrivate *priv = CLUTTER_INTERVAL (gobject)->priv;
g_value_unset (&priv->values[0]);
g_value_unset (&priv->values[1]);
g_free (priv->values);
}
static void
clutter_interval_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterIntervalPrivate *priv = CLUTTER_INTERVAL_GET_PRIVATE (gobject);
switch (prop_id)
{
case PROP_VALUE_TYPE:
priv->value_type = g_value_get_gtype (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_interval_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ClutterIntervalPrivate *priv = CLUTTER_INTERVAL_GET_PRIVATE (gobject);
switch (prop_id)
{
case PROP_VALUE_TYPE:
g_value_set_gtype (value, priv->value_type);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_interval_class_init (ClutterIntervalClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
g_type_class_add_private (klass, sizeof (ClutterIntervalPrivate));
klass->validate = clutter_interval_real_validate;
klass->compute_value = clutter_interval_real_compute_value;
gobject_class->set_property = clutter_interval_set_property,
gobject_class->get_property = clutter_interval_get_property;
gobject_class->finalize = clutter_interval_finalize;
/**
* ClutterInterval:value-type:
*
* The type of the values in the interval.
*
* Since: 1.0
*/
pspec = g_param_spec_gtype ("value-type",
"Value Type",
"The type of the values in the interval",
G_TYPE_NONE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_property (gobject_class, PROP_VALUE_TYPE, pspec);
}
static void
clutter_interval_init (ClutterInterval *self)
{
ClutterIntervalPrivate *priv;
self->priv = priv = CLUTTER_INTERVAL_GET_PRIVATE (self);
priv->value_type = G_TYPE_INVALID;
priv->values = g_malloc0 (sizeof (GValue) * 2);
}
static void
clutter_interval_set_interval_valist (ClutterInterval *interval,
va_list var_args)
{
GType gtype = interval->priv->value_type;
GValue value = { 0, };
gchar *error;
/* initial value */
g_value_init (&value, gtype);
G_VALUE_COLLECT (&value, var_args, 0, &error);
if (error)
{
g_warning ("%s: %s", G_STRLOC, error);
/* we leak the value here as it might not be in a valid state
* given the error and calling g_value_unset() might lead to
* undefined behaviour
*/
g_free (error);
return;
}
clutter_interval_set_initial_value (interval, &value);
g_value_unset (&value);
/* final value */
g_value_init (&value, gtype);
G_VALUE_COLLECT (&value, var_args, 0, &error);
if (error)
{
g_warning ("%s: %s", G_STRLOC, error);
/* see above */
g_free (error);
return;
}
clutter_interval_set_final_value (interval, &value);
g_value_unset (&value);
}
static void
clutter_interval_get_interval_valist (ClutterInterval *interval,
va_list var_args)
{
GType gtype = interval->priv->value_type;
GValue value = { 0, };
gchar *error;
/* initial value */
g_value_init (&value, gtype);
clutter_interval_get_initial_value (interval, &value);
G_VALUE_LCOPY (&value, var_args, 0, &error);
if (error)
{
g_warning ("%s: %s", G_STRLOC, error);
g_free (error);
g_value_unset (&value);
return;
}
g_value_unset (&value);
/* final value */
g_value_init (&value, gtype);
clutter_interval_get_final_value (interval, &value);
G_VALUE_LCOPY (&value, var_args, 0, &error);
if (error)
{
g_warning ("%s: %s", G_STRLOC, error);
g_free (error);
g_value_unset (&value);
return;
}
g_value_unset (&value);
}
/**
* clutter_interval_new:
* @gtype: the type of the values in the interval
* @Varargs: the initial value and the final value of the interval
*
* Creates a new #ClutterInterval holding values of type @gtype.
*
* This function avoids using a #GValue for the initial and final values
* of the interval:
*
* |[
* interval = clutter_interval_new (G_TYPE_FLOAT, 0.0, 1.0);
* interval = clutter_interval_new (G_TYPE_BOOLEAN, FALSE, TRUE);
* interval = clutter_interval_new (G_TYPE_INT, 0, 360);
* ]|
*
* Return value: the newly created #ClutterInterval
*
* Since: 1.0
*/
ClutterInterval *
clutter_interval_new (GType gtype,
...)
{
ClutterInterval *retval;
va_list args;
g_return_val_if_fail (gtype != G_TYPE_INVALID, NULL);
retval = g_object_new (CLUTTER_TYPE_INTERVAL, "value-type", gtype, NULL);
va_start (args, gtype);
clutter_interval_set_interval_valist (retval, args);
va_end (args);
return retval;
}
/**
* clutter_interval_new_with_values:
* @gtype: the type of the values in the interval
* @initial: a #GValue holding the initial value of the interval
* @final: a #GValue holding the final value of the interval
*
* Creates a new #ClutterInterval of type @gtype, between @initial
* and @final.
*
* This function is useful for language bindings.
*
* Return value: the newly created #ClutterInterval
*
* Since: 1.0
*/
ClutterInterval *
clutter_interval_new_with_values (GType gtype,
const GValue *initial,
const GValue *final)
{
ClutterInterval *retval;
g_return_val_if_fail (gtype != G_TYPE_INVALID, NULL);
g_return_val_if_fail (initial != NULL, NULL);
g_return_val_if_fail (final != NULL, NULL);
g_return_val_if_fail (G_VALUE_TYPE (initial) == gtype, NULL);
g_return_val_if_fail (G_VALUE_TYPE (final) == gtype, NULL);
retval = g_object_new (CLUTTER_TYPE_INTERVAL, "value-type", gtype, NULL);
clutter_interval_set_initial_value (retval, initial);
clutter_interval_set_final_value (retval, final);
return retval;
}
/**
* clutter_interval_clone:
* @interval: a #ClutterInterval
*
* Creates a copy of @interval.
*
* Return value: the newly created #ClutterInterval
*
* Since: 1.0
*/
ClutterInterval *
clutter_interval_clone (ClutterInterval *interval)
{
ClutterInterval *retval;
GType gtype;
GValue *tmp;
g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), NULL);
g_return_val_if_fail (interval->priv->value_type != G_TYPE_INVALID, NULL);
gtype = interval->priv->value_type;
retval = g_object_new (CLUTTER_TYPE_INTERVAL, "value-type", gtype, NULL);
tmp = clutter_interval_peek_initial_value (interval);
clutter_interval_set_initial_value (retval, tmp);
tmp = clutter_interval_peek_final_value (interval);
clutter_interval_set_final_value (retval, tmp);
return retval;
}
/**
* clutter_interval_get_value_type:
* @interval: a #ClutterInterval
*
* Retrieves the #GType of the values inside @interval.
*
* Return value: the type of the value, or G_TYPE_INVALID
*
* Since: 1.0
*/
GType
clutter_interval_get_value_type (ClutterInterval *interval)
{
g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), G_TYPE_INVALID);
return interval->priv->value_type;
}
static inline void
clutter_interval_set_value_internal (ClutterInterval *interval,
gint index_,
const GValue *value)
{
ClutterIntervalPrivate *priv = interval->priv;
if (G_IS_VALUE (&priv->values[index_]))
g_value_unset (&priv->values[index_]);
g_value_init (&priv->values[index_], priv->value_type);
g_value_copy (value, &priv->values[index_]);
}
static inline void
clutter_interval_get_value_internal (ClutterInterval *interval,
gint index_,
GValue *value)
{
ClutterIntervalPrivate *priv = interval->priv;
g_value_copy (&priv->values[index_], value);
}
/**
* clutter_interval_set_initial_value:
* @interval: a #ClutterInterval
* @value: a #GValue
*
* Sets the initial value of @interval to @value. The value is copied
* inside the #ClutterInterval.
*
* Since: 1.0
*/
void
clutter_interval_set_initial_value (ClutterInterval *interval,
const GValue *value)
{
ClutterIntervalPrivate *priv;
g_return_if_fail (CLUTTER_IS_INTERVAL (interval));
g_return_if_fail (value != NULL);
priv = interval->priv;
g_return_if_fail (G_VALUE_TYPE (value) == priv->value_type);
clutter_interval_set_value_internal (interval, 0, value);
}
/**
* clutter_interval_get_initial_value:
* @interval: a #ClutterInterval
* @value: a #GValue
*
* Retrieves the initial value of @interval and copies
* it into @value.
*
* The passed #GValue must be initialized to the value held by
* the #ClutterInterval.
*
* Since: 1.0
*/
void
clutter_interval_get_initial_value (ClutterInterval *interval,
GValue *value)
{
ClutterIntervalPrivate *priv;
g_return_if_fail (CLUTTER_IS_INTERVAL (interval));
g_return_if_fail (value != NULL);
priv = interval->priv;
clutter_interval_get_value_internal (interval, 0, value);
}
/**
* clutter_interval_peek_initial_value:
* @interval: a #ClutterInterval
*
* Gets the pointer to the initial value of @interval
*
* Return value: the initial value of the interval. The value
* is owned by the #ClutterInterval and it should not be
* modified or freed
*
* Since: 1.0
*/
GValue *
clutter_interval_peek_initial_value (ClutterInterval *interval)
{
g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), NULL);
return interval->priv->values;
}
/**
* clutter_interval_set_final_value:
* @interval: a #ClutterInterval
* @value: a #GValue
*
* Sets the final value of @interval to @value. The value is
* copied inside the #ClutterInterval.
*
* Since: 1.0
*/
void
clutter_interval_set_final_value (ClutterInterval *interval,
const GValue *value)
{
ClutterIntervalPrivate *priv;
g_return_if_fail (CLUTTER_IS_INTERVAL (interval));
g_return_if_fail (value != NULL);
priv = interval->priv;
g_return_if_fail (G_VALUE_TYPE (value) == priv->value_type);
clutter_interval_set_value_internal (interval, 1, value);
}
/**
* clutter_interval_get_final_value:
* @interval: a #ClutterInterval
* @value: a #GValue
*
* Retrieves the final value of @interval and copies
* it into @value.
*
* The passed #GValue must be initialized to the value held by
* the #ClutterInterval.
*
* Since: 1.0
*/
void
clutter_interval_get_final_value (ClutterInterval *interval,
GValue *value)
{
ClutterIntervalPrivate *priv;
g_return_if_fail (CLUTTER_IS_INTERVAL (interval));
g_return_if_fail (value != NULL);
priv = interval->priv;
clutter_interval_get_value_internal (interval, 1, value);
}
/**
* clutter_interval_peek_final_value:
* @interval: a #ClutterInterval
*
* Gets the pointer to the final value of @interval
*
* Return value: the final value of the interval. The value
* is owned by the #ClutterInterval and it should not be
* modified or freed
*
* Since: 1.0
*/
GValue *
clutter_interval_peek_final_value (ClutterInterval *interval)
{
g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), NULL);
return interval->priv->values + 1;
}
/**
* clutter_interval_set_interval:
* @interval: a #ClutterInterval
* @Varargs: the initial and final values of the interval
*
* Variable arguments wrapper for clutter_interval_set_initial_value()
* and clutter_interval_set_final_value() that avoids using the
* #GValue arguments:
*
* |[
* clutter_interval_set_interval (interval, 0, 50);
* clutter_interval_set_interval (interval, 1.0, 0.0);
* clutter_interval_set_interval (interval, FALSE, TRUE);
* ]|
*
* This function is meant for the convenience of the C API; bindings
* should reimplement this function using the #GValue-based API.
*
* Since: 1.0
*/
void
clutter_interval_set_interval (ClutterInterval *interval,
...)
{
va_list args;
g_return_if_fail (CLUTTER_IS_INTERVAL (interval));
g_return_if_fail (interval->priv->value_type != G_TYPE_INVALID);
va_start (args, interval);
clutter_interval_set_interval_valist (interval, args);
va_end (args);
}
/**
* clutter_interval_get_interval:
* @interval: a #ClutterInterval
* @Varargs: return locations for the initial and final values of
* the interval
*
* Variable arguments wrapper for clutter_interval_get_initial_value()
* and clutter_interval_get_final_value() that avoids using the
* #GValue arguments:
*
* |[
* gint a = 0, b = 0;
* clutter_interval_get_interval (interval, &a, &b);
* ]|
*
* This function is meant for the convenience of the C API; bindings
* should reimplement this function using the #GValue-based API.
*
* Since: 1.0
*/
void
clutter_interval_get_interval (ClutterInterval *interval,
...)
{
va_list args;
g_return_if_fail (CLUTTER_IS_INTERVAL (interval));
g_return_if_fail (interval->priv->value_type != G_TYPE_INVALID);
va_start (args, interval);
clutter_interval_get_interval_valist (interval, args);
va_end (args);
}
/**
* clutter_interval_validate:
* @interval: a #ClutterInterval
* @pspec: a #GParamSpec
*
* Validates the initial and final values of @interval against
* a #GParamSpec.
*
* Return value: %TRUE if the #ClutterInterval is valid, %FALSE otherwise
*
* Since: 1.0
*/
gboolean
clutter_interval_validate (ClutterInterval *interval,
GParamSpec *pspec)
{
g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), FALSE);
g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE);
return CLUTTER_INTERVAL_GET_CLASS (interval)->validate (interval, pspec);
}
/**
* clutter_interval_compute_value:
* @interval: a #ClutterInterval
* @factor: the progress factor, between 0 and 1
* @value: return location for an initialized #GValue
*
* Computes the value between the @interval boundaries given the
* progress @factor and puts it into @value.
*
* Since: 1.0
*/
void
clutter_interval_compute_value (ClutterInterval *interval,
gdouble factor,
GValue *value)
{
g_return_if_fail (CLUTTER_IS_INTERVAL (interval));
g_return_if_fail (value != NULL);
factor = CLAMP (factor, 0.0, 1.0);
CLUTTER_INTERVAL_GET_CLASS (interval)->compute_value (interval,
factor,
value);
}

131
clutter/clutter-interval.h Normal file
View File

@ -0,0 +1,131 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2008 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_INTERVAL_H__
#define __CLUTTER_INTERVAL_H__
#include <glib-object.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_INTERVAL (clutter_interval_get_type ())
#define CLUTTER_INTERVAL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_INTERVAL, ClutterInterval))
#define CLUTTER_IS_INTERVAL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_INTERVAL))
#define CLUTTER_INTERVAL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_INTERVAL, ClutterIntervalClass))
#define CLUTTER_IS_INTERVAL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_INTERVAL))
#define CLUTTER_INTERVAL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_INTERVAL, ClutterIntervalClass))
typedef struct _ClutterInterval ClutterInterval;
typedef struct _ClutterIntervalPrivate ClutterIntervalPrivate;
typedef struct _ClutterIntervalClass ClutterIntervalClass;
/**
* ClutterInterval:
*
* The #ClutterInterval structure contains only private data and should
* be accessed using the provided functions.
*
* Since: 1.0
*/
struct _ClutterInterval
{
/*< private >*/
GInitiallyUnowned parent_instance;
ClutterIntervalPrivate *priv;
};
/**
* ClutterIntervalClass:
* @validate: virtual function for validating an interval
* using a #GParamSpec
* @compute_value: virtual function for computing the value
* inside an interval using an adimensional factor between 0 and 1
*
* The #ClutterIntervalClass contains only private data.
*
* Since: 1.0
*/
struct _ClutterIntervalClass
{
/*< private >*/
GInitiallyUnownedClass parent_class;
/*< public >*/
gboolean (* validate) (ClutterInterval *interval,
GParamSpec *pspec);
void (* compute_value) (ClutterInterval *interval,
gdouble factor,
GValue *value);
/*< private >*/
/* padding for future expansion */
void (*_clutter_reserved1) (void);
void (*_clutter_reserved2) (void);
void (*_clutter_reserved3) (void);
void (*_clutter_reserved4) (void);
void (*_clutter_reserved5) (void);
void (*_clutter_reserved6) (void);
};
GType clutter_interval_get_type (void) G_GNUC_CONST;
ClutterInterval *clutter_interval_new (GType gtype,
...);
ClutterInterval *clutter_interval_new_with_values (GType gtype,
const GValue *initial,
const GValue *final);
ClutterInterval *clutter_interval_clone (ClutterInterval *interval);
GType clutter_interval_get_value_type (ClutterInterval *interval);
void clutter_interval_set_initial_value (ClutterInterval *interval,
const GValue *value);
void clutter_interval_get_initial_value (ClutterInterval *interval,
GValue *value);
GValue * clutter_interval_peek_initial_value (ClutterInterval *interval);
void clutter_interval_set_final_value (ClutterInterval *interval,
const GValue *value);
void clutter_interval_get_final_value (ClutterInterval *interval,
GValue *value);
GValue * clutter_interval_peek_final_value (ClutterInterval *interval);
void clutter_interval_set_interval (ClutterInterval *interval,
...);
void clutter_interval_get_interval (ClutterInterval *interval,
...);
gboolean clutter_interval_validate (ClutterInterval *interval,
GParamSpec *pspec);
void clutter_interval_compute_value (ClutterInterval *interval,
gdouble factor,
GValue *value);
G_END_DECLS
#endif /* __CLUTTER_INTERVAL_H__ */

View File

@ -87,6 +87,7 @@ static const GDebugKey clutter_debug_keys[] = {
{ "script", CLUTTER_DEBUG_SCRIPT },
{ "shader", CLUTTER_DEBUG_SHADER },
{ "multistage", CLUTTER_DEBUG_MULTISTAGE },
{ "animation", CLUTTER_DEBUG_ANIMATION }
};
#endif /* CLUTTER_ENABLE_DEBUG */

View File

@ -526,66 +526,26 @@ static const struct
const gchar *short_name;
ClutterAlphaFunc symbol;
} clutter_alphas[] = {
{
"clutter_ramp_inc_func",
"ramp-inc",
CLUTTER_ALPHA_RAMP_INC
},
{
"clutter_ramp_dec_func",
"ramp-dec",
CLUTTER_ALPHA_RAMP_DEC
},
{
"clutter_ramp_func",
"ramp",
CLUTTER_ALPHA_RAMP
},
{
"clutter_sine_inc_func",
"sine-inc",
CLUTTER_ALPHA_SINE_INC
},
{
"clutter_sine_dec_func",
"sine-dec",
CLUTTER_ALPHA_SINE_DEC
},
{
"clutter_sine_half_func",
"sine-half",
CLUTTER_ALPHA_SINE_HALF
},
{
"clutter_sine_func",
"sine",
CLUTTER_ALPHA_SINE
},
{
"clutter_square_func",
"square",
CLUTTER_ALPHA_SQUARE
},
{
"clutter_smoothstep_inc_func",
"smoothstep-inc",
CLUTTER_ALPHA_SMOOTHSTEP_INC
},
{
"clutter_smoothstep_dec_func",
"smoothstep-dec",
CLUTTER_ALPHA_SMOOTHSTEP_DEC
},
{
"clutter_exp_inc_func",
"exp-inc",
CLUTTER_ALPHA_EXP_INC
},
{
"clutter_exp_dec_func",
"exp-dec",
CLUTTER_ALPHA_EXP_DEC
}
#define ALPHA_FUNC(func,nick) { #func, nick, func }
ALPHA_FUNC (clutter_ramp_inc_func, "ramp-inc"),
ALPHA_FUNC (clutter_ramp_dec_func, "ramp-dec"),
ALPHA_FUNC (clutter_ramp_func, "ramp"),
ALPHA_FUNC (clutter_sine_inc_func, "sine-inc"),
ALPHA_FUNC (clutter_sine_dec_func, "sine-dec"),
ALPHA_FUNC (clutter_sine_half_func, "sine-half"),
ALPHA_FUNC (clutter_sine_in_func, "sine-in"),
ALPHA_FUNC (clutter_sine_out_func, "sine-out"),
ALPHA_FUNC (clutter_sine_in_out_func, "sine-in-out"),
ALPHA_FUNC (clutter_sine_func, "sine"),
ALPHA_FUNC (clutter_square_func, "square"),
ALPHA_FUNC (clutter_smoothstep_inc_func, "smoothstep-inc"),
ALPHA_FUNC (clutter_smoothstep_dec_func, "smoothstep-dec"),
ALPHA_FUNC (clutter_exp_inc_func, "exp-inc"),
ALPHA_FUNC (clutter_exp_dec_func, "exp-dec"),
ALPHA_FUNC (clutter_ease_in_func, "ease-in"),
ALPHA_FUNC (clutter_ease_out_func, "ease-out"),
ALPHA_FUNC (clutter_ease_in_out_func, "ease-in-out")
#undef ALPHA_FUNC
};
static const gint n_clutter_alphas = G_N_ELEMENTS (clutter_alphas);

View File

@ -186,6 +186,33 @@ typedef enum {
CLUTTER_REQUEST_WIDTH_FOR_HEIGHT
} ClutterRequestMode;
/**
* ClutterAnimationMode:
* @CLUTTER_CUSTOM_MODE: custom progress function
* @CLUTTER_LINEAR: linear progress
* @CLUTTER_SINE_IN: sine-in progress
* @CLUTTER_SINE_OUT: sine-out progress
* @CLUTTER_SINE_IN_OUT: sine-in-out progress
* @CLUTTER_EASE_IN: ease-in progress
* @CLUTTER_EASE_OUT: ease-out progress
* @CLUTTER_EASE_IN_OUT: ease-in-out progress
*
* The animation modes used by #ClutterAlpha and #ClutterAnimation. This
* enumeration can be expanded in later versions of Clutter.
*
* Since: 1.0
*/
typedef enum {
CLUTTER_CUSTOM_MODE,
CLUTTER_LINEAR,
CLUTTER_SINE_IN,
CLUTTER_SINE_OUT,
CLUTTER_SINE_IN_OUT,
CLUTTER_EASE_IN,
CLUTTER_EASE_OUT,
CLUTTER_EASE_IN_OUT
} ClutterAnimationMode;
G_END_DECLS
#endif /* __CLUTTER_TYPES_H__ */

View File

@ -30,6 +30,7 @@
#include "clutter-actor.h"
#include "clutter-alpha.h"
#include "clutter-animation.h"
#include "clutter-backend.h"
#include "clutter-color.h"
#include "clutter-container.h"
@ -50,6 +51,7 @@
#include "clutter-feature.h"
#include "clutter-rectangle.h"
#include "clutter-group.h"
#include "clutter-interval.h"
#include "clutter-keysyms.h"
#include "clutter-label.h"
#include "clutter-list-model.h"

View File

@ -12,7 +12,7 @@ AUTOMAKE_OPTIONS = 1.6
DOC_MODULE=clutter
# The top-level SGML file. You can change this if you want to.
DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml
# The directory containing the source code. Relative to $(srcdir).
# gtk-doc will search all .c & .h files beneath here for inline comments
@ -99,7 +99,7 @@ HTML_IMAGES=\
content_files= \
version.xml \
subclassing-ClutterActor.xml \
clutter-animation.xml \
clutter-animation-tutorial.xml \
creating-behaviours.xml \
clutter-overview.xml \
building-clutter.xml
@ -109,7 +109,7 @@ content_files= \
# e.g. expand_content_files=running.sgml
expand_content_files= \
subclassing-ClutterActor.xml \
clutter-animation.xml \
clutter-animation-tutorial.xml \
creating-behaviours.xml \
clutter-overview.xml \
building-clutter.xml

View File

@ -52,7 +52,8 @@ rotate_actor (gpointer data)
clutter_actor_set_rotationx (clos-&gt;actor, clos-&gt;current_angle, 0, 0, 0);
clos-&gt;current_angle += CFX_ONE;
/* add one degree */
clos-&gt;current_angle += COGL_FIXED_ONE;
if (clos-&gt;current_angle == clos-&gt;final_angle)
return FALSE;
@ -60,16 +61,27 @@ rotate_actor (gpointer data)
return TRUE;
}
static void
rotate_actor_cleanup (gpointer data)
{
RotationClosure *clos = data;
g_object_unref (clos-&gt;actor);
g_free (clos);
}
...
RotationClosure clos = { NULL, }
RotationClosure *clos = NULL;
clos.actor = an_actor;
clos.final_angle = CLUTTER_FLOAT_TO_FIXED (360.0);
clos.current_angle = 0;
clos = g_new (RotationClosure, 1);
clos-&gt;actor = g_object_ref (an_actor);
clos-&gt;final_angle = CLUTTER_FLOAT_TO_FIXED (360.0);
clos-&gt;current_angle = 0;
g_timeout_add (1000 / 360, /* fps to interval in milliseconds */
rotate_actor,
&amp;clos);
g_timeout_add_full (1000 / 360, /* fps to interval in milliseconds */
rotate_actor,
clos,
rotate_actor_cleanup);
</programlisting>
</example>
@ -140,7 +152,7 @@ clutter_timeline_new_for_duration (msecs);
The speed, duration and number of frames of the timeline then be
modifed via the objects properties and API calls. The timeline can
be made to loop by settings it "loop" property to %TRUE.
be made to loop by setting its "loop" property to %TRUE.
</para>
<para>
@ -153,7 +165,7 @@ clutter_timeline_new_for_duration (msecs);
</para>
<para>
By attaching a handler to the timeline's ClutterTimeline::new-frame
By attaching a handler to the timeline's #ClutterTimeline::new-frame
signal a timeline can then be used to drive an animation by altering
an actor's visual properties in this callback. The callback looks like:
@ -164,13 +176,12 @@ on_new_frame (ClutterTimeline *timeline,
gint frame_num,
gpointer user_data)
{
}
</programlisting>
<para>
The <literal>frame_num</literal> parameter is set to the timeline's
current frame number (which is between 0 and the "num-frames" property).
current frame number (which is between 1 and the "num-frames" property).
This value can be used to compute the state of a particular animation
that is dependant on the frame numer. The clutter_timeline_get_progress()
function can also be used to get a normalised value of the timeline's
@ -235,7 +246,7 @@ main (int argc, char *argv[])
clutter_actor_set_position (actor, 100, 100);
timeline = clutter_timeline_new_for (360, 60); /* a degree per frame */
timeline = clutter_timeline_new_for (360, 60); /* one degree per frame */
clutter_timeline_set_loop (timeline, TRUE);
g_signal_connect (timeline, "new-frame", G_CALLBACK (on_new_frame), actor);
@ -263,7 +274,7 @@ main (int argc, char *argv[])
<para>
With a large application containing many animations, the use of just
timelines can become unweldy and difficult to manage with much code
timelines can become unwieldy and difficult to manage with much code
duplication in the new-frame handlers that can require over complex
code changes for minor animation modifications. To ease these
problems the #ClutterAlpha and #ClutterBehaviour classes were created.
@ -279,7 +290,7 @@ main (int argc, char *argv[])
</para>
<para>
A ClutterAlpha is simply a 'function of time' (not pixel alpha!). It
A ClutterAlpha is simply a 'function of time' (not a pixel alpha!). It
is created by referencing a source timeline and a function which
produces a value between 0 and %CLUTTER_ALPHA_MAX dependant on the
timeline position. Various prebuilt alpha functions are included
@ -344,7 +355,7 @@ main (int argc, char *argv[])
<para>
A Behaviour is created with a #ClutterAlpha and a set of limits for
whatever the behaviour modifys actor wise. The current #ClutterAlpha
whatever the behaviour modifies in an actor. The current #ClutterAlpha
value is then mapped to a value between these limits and this value
set on any applied actors. With the #ClutterAlpha's underlying
timeline playing the produced value will change and the behaviour
@ -353,8 +364,8 @@ main (int argc, char *argv[])
</para>
<para>
A #ClutterBehaviour is effectively 'driven' by a supplied #ClutterAlpha and
when then applied to an actor it will modify a visual property or
A #ClutterBehaviour is effectively 'driven' by a supplied #ClutterAlpha
and when then applied to an actor it will modify a visual property or
feature of the actor dependant on the Alpha's value. For example a
path based behaviour applied to an actor will alter its position
along the path dependant on the current alpha value over time. The
@ -431,7 +442,7 @@ main (int argc, char *argv[])
</para>
<example id="clutter-timeline-example">
<example id="clutter-behaviour-example">
<para>
The following example demonstrates an ellipse behaviour in action.
</para>
@ -503,72 +514,81 @@ main (int argc, char *argv[])
<warning><para>Combining behaviours that effect the same actor properties
(i.e two separate paths) will cause unexpected results. The values
will not be merged in any way with essentially a the last applied
behaviour taking precedence.</para></warning>
will not be merged in any way with only the last applied behaviour taking
precedence.</para></warning>
<para>
Tips for implementing a new behaviour can be found <link
linkend="creating-your-own-behaviours">here</link>.
</para>
<para>
Tips for implementing a new behaviour can be found <link
linkend="creating-your-own-behaviours">here</link>.
</para>
</section>
<section id="clutter-animation-effects">
<title>Effects</title>
<section id="clutter-animation-implicit">
<title>Implicit Animations</title>
<para>Using behaviours for simple animations of a single actor may
be too complicated, in terms of memory management and bookkeeping
of the object instances. For this reason, Clutter also provides a
simple animation API for implicit animations using properties of
an actor: clutter_actor_animate().</para>
<para>The clutter_actor_animate() family of functions will create
and use an implicit #ClutterAnimation instance, which will then
handle the animation of one or more #ClutterActor properties between
a range of values.</para>
<example id="clutter-actor-animate-example">
<para>
Clutter effects API provide a simplified abstraction for firing simple
transitions from code. Clutter effects are created from a
#ClutterEffectTemplate which is an abstraction of a timeline and
an alpha function. An effect template can be created with:
The following example demonstrates how to use the
clutter_actor_animate() method to tween an actor
between the current position and a new set of coordinates.
The animation takes 200 milliseconds to complete and
uses a linear speed.
</para>
<programlisting>
ClutterEffectTemplate *etemplate =
clutter_effect_template_new_for_duration (2000, CLUTTER_ALPHA_RAMP_INC);
clutter_actor_animate (actor, CLUTTER_LINEAR, 200
"x", 200,
"y", 200,
NULL);
</programlisting>
</example>
<para>The clutter_actor_animate() method returns a #ClutterAnimation
instance that can be used to start, stop and modify the animation
while it's running. The #ClutterAnimation::completed signal will
be emitted when the animation has been completed.</para>
<warning><para>When the animation is complete it will be automatically
unreferenced, and disposed if nothing else is holding a reference
on it.</para></warning>
<para>Calling clutter_actor_animate() multiple times on an
actor which is being animated will cause the animation to be updated
with the new values.</para>
<example id="clutter-actor-animate-multi-example">
<para>
This will create an effect template lasting 2000 milliseconds (2
seconds) and use an alpha function of %CLUTTER_ALPHA_RAMP_INC, there
are other more advanced forms for creating effect templates from
existing timelines, as well as attaching a callback to be called
with user_data when the effect template is destroyed.
</para>
<para>
When we have an effect template we can create a temporary behaviour
animating an actor simply by issuing:
The following example demonstrates how to animate an actor
inside the signal handler for a button press event. If the
user presses the button on a new position while the animation
is running, the animation will be restarted with the new
final values updated.
</para>
<programlisting>
clutter_effect_move (etemplate, actor, 23, 42, NULL, NULL);
static gboolean
on_button_press (ClutterActor *actor,
ClutterButtonEvent *event,
gpointer user_data)
{
clutter_actor_animate (actor, CLUTTER_SINE_IN_OUT, 500,
"x", event-&gt;x,
"y", event-&gt;y,
NULL);
return TRUE;
}
</programlisting>
<para>
and the actor will move from its current position to the coordinates
(23, 42) in 2 seconds. Effects can also be stacked, so calling:
</para>
<programlisting>
clutter_effect_move (etemplate, actor, 23, 42, NULL, NULL);
clutter_effect_fade (etemplate, actor, 0, NULL, NULL);
</programlisting>
<para>
The actor will move and fade out at the same time.
</para>
<para>
</example>
Since effects return a #ClutterTimeline, you can stop an effect from
immediatly happening by calling clutter_timeline_stop () on the
returned timeline.
</para>
<para>
The timeline and all the effect infrastructure is unreferenced as soon
as the timeline emits the ClutterTimeline::completed signal.
</para>
</section>
<section id="clutter-animation-conclusion">
@ -582,9 +602,9 @@ The actor will move and fade out at the same time.
</para>
<para>
Of course animations can be created outside of Clutter Utilities,
they are not expected to cover every kind of possible animation
scenario.
Of course animations can becreated outside of the Clutter animation
framework, as the framework is not expected to cover every kind of
possible animation scenario.
</para>
<para>

View File

@ -101,9 +101,10 @@
</chapter>
<chapter>
<title>Simple effects API</title>
<title>High Level API</title>
<xi:include href="xml/clutter-effect.xml"/>
<xi:include href="xml/clutter-interval.xml"/>
<xi:include href="xml/clutter-animation.xml"/>
</chapter>
</part>
@ -164,7 +165,7 @@
<xi:include href="subclassing-ClutterActor.xml"/>
<xi:include href="clutter-animation.xml"/>
<xi:include href="clutter-animation-tutorial.xml"/>
<xi:include href="creating-behaviours.xml"/>

View File

@ -143,6 +143,7 @@ ClutterAlpha
ClutterAlphaClass
clutter_alpha_new
clutter_alpha_new_full
clutter_alpha_new_for_mode
clutter_alpha_get_alpha
CLUTTER_ALPHA_MAX_ALPHA
ClutterAlphaFunc
@ -150,30 +151,29 @@ clutter_alpha_set_func
clutter_alpha_set_closure
clutter_alpha_set_timeline
clutter_alpha_get_timeline
CLUTTER_ALPHA_RAMP_INC
clutter_alpha_set_mode
clutter_alpha_get_mode
<SUBSECTION>
clutter_ramp_inc_func
CLUTTER_ALPHA_RAMP_DEC
clutter_ramp_dec_func
CLUTTER_ALPHA_RAMP
clutter_ramp_func
CLUTTER_ALPHA_SINE
clutter_sine_func
CLUTTER_ALPHA_SINE_INC
clutter_sine_inc_func
CLUTTER_ALPHA_SINE_DEC
clutter_sine_dec_func
CLUTTER_ALPHA_SINE_HALF
clutter_sine_half_func
CLUTTER_ALPHA_SQUARE
clutter_sine_in_func
clutter_sine_out_func
clutter_sine_in_out_func
clutter_square_func
CLUTTER_ALPHA_SMOOTHSTEP_INC
clutter_smoothstep_inc_func
CLUTTER_ALPHA_SMOOTHSTEP_DEC
clutter_smoothstep_dec_func
CLUTTER_ALPHA_EXP_INC
clutter_exp_inc_func
CLUTTER_ALPHA_EXP_DEC
clutter_exp_dec_func
clutter_ease_in_func
clutter_ease_out_func
clutter_ease_in_out_func
<SUBSECTION Standard>
CLUTTER_ALPHA
CLUTTER_IS_ALPHA
@ -181,6 +181,7 @@ CLUTTER_TYPE_ALPHA
CLUTTER_ALPHA_CLASS
CLUTTER_IS_ALPHA_CLASS
CLUTTER_ALPHA_GET_CLASS
<SUBSECTION Private>
ClutterAlphaPrivate
clutter_alpha_get_type
@ -1516,3 +1517,79 @@ ClutterShaderPrivate
clutter_shader_get_type
clutter_shader_error_quark
</SECTION>
<SECTION>
<TITLE>Implicit Animations</TITLE>
<FILE>clutter-animation</FILE>
ClutterAnimation
ClutterAnimationClass
ClutterAnimationMode
clutter_animation_new
clutter_animation_set_actor
clutter_animation_get_actor
clutter_animation_set_mode
clutter_animation_get_mode
clutter_animation_set_duration
clutter_animation_get_duration
clutter_animation_set_loop
clutter_animation_get_loop
clutter_animation_set_timeline
clutter_animation_get_timeline
clutter_animation_set_alpha
clutter_animation_get_alpha
<SUBSECTION>
clutter_animation_bind_property
clutter_animation_update_property
clutter_animation_has_property
clutter_animation_unbind_property
clutter_animation_get_interval
<SUBSECTION>
clutter_actor_animate
clutter_actor_animate_with_timeline
clutter_actor_animate_with_alpha
<SUBSECTION Standard>
CLUTTER_TYPE_ANIMATION
CLUTTER_ANIMATION
CLUTTER_ANIMATION_CLASS
CLUTTER_IS_ANIMATION
CLUTTER_IS_ANIMATION_CLASS
CLUTTER_ANIMATION_GET_CLASS
<SUBSECTION Private>
ClutterAnimationPrivate
clutter_animation_get_type
</SECTION>
<SECTION>
<TITLE>Value intervals</TITLE>
<FILE>clutter-interval</FILE>
ClutterInterval
ClutterIntervalClass
clutter_interval_new
clutter_interval_new_with_values
clutter_interval_clone
clutter_interval_get_value_type
clutter_interval_set_initial_value
clutter_interval_get_initial_value
clutter_interval_peek_initial_value
clutter_interval_set_final_value
clutter_interval_get_final_value
clutter_interval_peek_final_value
clutter_interval_set_interval
clutter_interval_get_interval
<SUBSECTION Standard>
CLUTTER_TYPE_INTERVAL
CLUTTER_INTERVAL
CLUTTER_INTERVAL_CLASS
CLUTTER_IS_INTERVAL
CLUTTER_IS_INTERVAL_CLASS
CLUTTER_INTERVAL_GET_CLASS
<SUBSECTION Private>
ClutterIntervalPrivate
clutter_interval_get_type
</SECTION>

View File

@ -1,4 +1,3 @@
SUBDIRS = data conform interactive micro-bench tools
EXTRA_DIST = README
@ -12,4 +11,3 @@ test-report full-report:
# run make test as part of make check
check-local: test

View File

@ -35,7 +35,9 @@ UNIT_TESTS = \
test-clip.c \
test-paint-wrapper.c \
test-texture-quality.c \
test-layout.c
test-layout.c \
test-animation.c \
test-easing.c
if X11_TESTS
UNIT_TESTS += test-pixmap.c

View File

@ -168,7 +168,7 @@ test_actors_main (int argc, char *argv[])
g_signal_connect (timeline, "new-frame", G_CALLBACK (frame_cb), oh);
/* Set up some behaviours to handle scaling */
alpha = clutter_alpha_new_full (timeline, CLUTTER_ALPHA_SINE, NULL, NULL);
alpha = clutter_alpha_new_full (timeline, clutter_sine_func, NULL, NULL);
scaler_1 = clutter_behaviour_scale_new (alpha,
0.5, 0.5,

View File

@ -0,0 +1,95 @@
#include <stdlib.h>
#include <gmodule.h>
#include <clutter/clutter.h>
static gboolean is_expanded = FALSE;
static void
on_animation_complete (ClutterAnimation *animation,
ClutterActor *actor)
{
is_expanded = !is_expanded;
g_print ("Animation complete\n");
clutter_actor_set_reactive (actor, TRUE);
}
static gboolean
on_button_press (ClutterActor *actor,
ClutterButtonEvent *event,
gpointer dummy)
{
ClutterAnimation *animation;
gint old_x, old_y, new_x, new_y;
gint old_width, old_height, new_width, new_height;
guint8 old_op, new_op;
clutter_actor_get_position (actor, &old_x, &old_y);
clutter_actor_get_size (actor, &old_width, &old_height);
old_op = clutter_actor_get_opacity (actor);
if (!is_expanded)
{
new_x = old_x - 100;
new_y = old_y - 100;
new_width = old_width + 200;
new_height = old_height + 200;
new_op = 255;
}
else
{
new_x = old_x + 100;
new_y = old_y + 100;
new_width = old_width - 200;
new_height = old_height - 200;
new_op = 128;
}
animation =
clutter_actor_animate (actor, CLUTTER_EASE_IN, 2000,
"x", new_x,
"y", new_y,
"width", new_width,
"height", new_height,
"opacity", new_op,
"fixed::reactive", FALSE,
NULL);
g_signal_connect (animation,
"completed", G_CALLBACK (on_animation_complete),
actor);
return TRUE;
}
G_MODULE_EXPORT int
test_animation_main (int argc, char *argv[])
{
ClutterActor *stage, *rect;
ClutterColor stage_color = { 0x66, 0x66, 0xdd, 0xff };
ClutterColor rect_color = { 0x44, 0xdd, 0x44, 0xff };
clutter_init (&argc, &argv);
stage = clutter_stage_get_default ();
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
rect = clutter_rectangle_new_with_color (&rect_color);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
clutter_actor_set_size (rect, 50, 50);
clutter_actor_set_anchor_point (rect, 25, 25);
clutter_actor_set_position (rect,
clutter_actor_get_width (stage) / 2,
clutter_actor_get_height (stage) / 2);
clutter_actor_set_opacity (rect, 0x88);
clutter_actor_set_reactive (rect, TRUE);
g_signal_connect (rect,
"button-press-event", G_CALLBACK (on_button_press),
NULL);
clutter_actor_show (stage);
clutter_main ();
return EXIT_SUCCESS;
}

View File

@ -173,10 +173,9 @@ test_behave_main (int argc, char *argv[])
"completed", G_CALLBACK (timeline_completed),
NULL);
/* Set an alpha func to power behaviour - ramp is constant rise/fall */
alpha = clutter_alpha_new_full (timeline,
CLUTTER_ALPHA_RAMP_INC,
NULL, NULL);
/* Set an alpha func to power behaviour - ramp is constant rise */
alpha = clutter_alpha_new_for_mode (CLUTTER_LINEAR);
clutter_alpha_set_timeline (alpha, timeline);
/* Create a behaviour for that alpha */
o_behave = clutter_behaviour_opacity_new (alpha, 0X33, 0xff);

View File

@ -160,7 +160,7 @@ test_depth_main (int argc, char *argv[])
NULL);
d_behave = clutter_behaviour_depth_new (clutter_alpha_new_full (timeline,
CLUTTER_ALPHA_RAMP_INC,
clutter_ramp_inc_func,
NULL, NULL),
-100, 100);
clutter_behaviour_apply (d_behave, label);
@ -171,7 +171,7 @@ test_depth_main (int argc, char *argv[])
clutter_actor_set_position (janus, 300, 350);
r_behave = clutter_behaviour_rotate_new (clutter_alpha_new_full (timeline,
CLUTTER_ALPHA_RAMP_INC,
clutter_ramp_inc_func,
NULL, NULL),
CLUTTER_Y_AXIS,
CLUTTER_ROTATE_CW,
@ -188,7 +188,7 @@ test_depth_main (int argc, char *argv[])
clutter_actor_set_opacity (box, 0x44);
r_behave = clutter_behaviour_rotate_new (clutter_alpha_new_full (timeline,
CLUTTER_ALPHA_RAMP_INC,
clutter_ramp_inc_func,
NULL, NULL),
CLUTTER_Y_AXIS,
CLUTTER_ROTATE_CW,

View File

@ -0,0 +1,113 @@
#include <stdlib.h>
#include <gmodule.h>
#include <clutter/clutter.h>
const struct {
const gchar *name;
ClutterAnimationMode mode;
} easing_modes[] = {
{ "linear", CLUTTER_LINEAR },
{ "sine-in", CLUTTER_SINE_IN },
{ "sine-out", CLUTTER_SINE_OUT },
{ "sine-in-out", CLUTTER_SINE_IN_OUT },
{ "ease-in", CLUTTER_EASE_IN },
{ "ease-out", CLUTTER_EASE_OUT },
{ "ease-in-out", CLUTTER_EASE_IN_OUT }
};
static const gint n_easing_modes = G_N_ELEMENTS (easing_modes);
static gint current_mode = 0;
static ClutterActor *main_stage = NULL;
static ClutterActor *easing_mode_label = NULL;
static gboolean
on_button_press (ClutterActor *actor,
ClutterButtonEvent *event,
ClutterActor *rectangle)
{
ClutterAnimation *animation;
ClutterAnimationMode cur_mode;
gchar *text;
gint stage_width, stage_height;
gint label_width, label_height;
text = g_strdup_printf ("Easing mode: %s (%d of %d)\n",
easing_modes[current_mode].name,
current_mode + 1,
n_easing_modes);
clutter_label_set_text (CLUTTER_LABEL (easing_mode_label), text);
g_free (text);
clutter_actor_get_size (main_stage, &stage_width, &stage_height);
clutter_actor_get_size (easing_mode_label, &label_width, &label_height);
clutter_actor_set_position (easing_mode_label,
stage_width - label_width - 10,
stage_height - label_height - 10);
cur_mode = easing_modes[current_mode].mode;
animation =
clutter_actor_animate (rectangle, cur_mode, 2000,
"x", event->x,
"y", event->y,
NULL);
current_mode = (current_mode + 1 < n_easing_modes) ? current_mode + 1 : 0;
return TRUE;
}
G_MODULE_EXPORT int
test_easing_main (int argc, char *argv[])
{
ClutterActor *stage, *rect, *label;
ClutterColor stage_color = { 0x66, 0x66, 0xdd, 0xff };
ClutterColor rect_color = { 0x44, 0xdd, 0x44, 0xff };
gchar *text;
gint stage_width, stage_height;
gint label_width, label_height;
clutter_init (&argc, &argv);
stage = clutter_stage_get_default ();
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
main_stage = stage;
clutter_actor_get_size (stage, &stage_width, &stage_height);
rect = clutter_rectangle_new_with_color (&rect_color);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
clutter_actor_set_size (rect, 50, 50);
clutter_actor_set_anchor_point (rect, 25, 25);
clutter_actor_set_position (rect, stage_width / 2, stage_height / 2);
clutter_actor_set_opacity (rect, 0x88);
g_signal_connect (stage,
"button-press-event", G_CALLBACK (on_button_press),
rect);
text = g_strdup_printf ("Easing mode: %s (%d of %d)\n",
easing_modes[current_mode].name,
current_mode + 1,
n_easing_modes);
label = clutter_label_new ();
clutter_container_add_actor (CLUTTER_CONTAINER (stage), label);
clutter_label_set_font_name (CLUTTER_LABEL (label), "Sans 18px");
clutter_label_set_text (CLUTTER_LABEL (label), text);
clutter_actor_get_size (label, &label_width, &label_height);
clutter_actor_set_position (label,
stage_width - label_width - 10,
stage_height - label_height - 10);
easing_mode_label = label;
g_free (text);
clutter_actor_show (stage);
clutter_main ();
return EXIT_SUCCESS;
}

View File

@ -18,7 +18,7 @@ test_effects_main (int argc, char *argv[])
timeline = clutter_timeline_new_for_duration (5000);
clutter_timeline_set_loop (timeline, TRUE);
tmpl =
clutter_effect_template_new (timeline, CLUTTER_ALPHA_RAMP_INC);
clutter_effect_template_new (timeline, clutter_ramp_inc_func);
stage = clutter_stage_get_default ();
container = CLUTTER_CONTAINER (stage);

View File

@ -765,7 +765,7 @@ test_layout_main (int argc, char *argv[])
NULL);
behaviour = clutter_behaviour_scale_new (clutter_alpha_new_full (main_timeline,
CLUTTER_ALPHA_SINE,
clutter_sine_func,
NULL, NULL),
1.0, 1.0, 2.0, 2.0);

View File

@ -75,10 +75,8 @@ on_button_press (ClutterActor *actor,
timeline = clutter_timeline_new_for_duration (2000);
g_object_set (timeline, "loop", TRUE, NULL);
alpha = clutter_alpha_new_full (timeline,
CLUTTER_ALPHA_RAMP_INC,
NULL, NULL);
alpha = clutter_alpha_new_for_mode (CLUTTER_LINEAR);
clutter_alpha_set_timeline (alpha, timeline);
r_behave = clutter_behaviour_rotate_new (alpha,
CLUTTER_Y_AXIS,
CLUTTER_ROTATE_CW,

View File

@ -197,7 +197,7 @@ test_paint_wrapper_main (int argc, char *argv[])
g_signal_connect (timeline, "new-frame", G_CALLBACK (frame_cb), oh);
/* Set up some behaviours to handle scaling */
alpha = clutter_alpha_new_full (timeline, CLUTTER_ALPHA_SINE, NULL, NULL);
alpha = clutter_alpha_new_full (timeline, clutter_sine_func, NULL, NULL);
scaler_1 = clutter_behaviour_scale_new (alpha,
0.5, 0.5,

View File

@ -44,10 +44,9 @@ test_rotate_main (int argc, char *argv[])
timeline = clutter_timeline_new (200, 26); /* num frames, fps */
g_object_set (timeline, "loop", TRUE, NULL);
/* Set an alpha func to power behaviour - ramp is constant rise/fall */
alpha = clutter_alpha_new_full (timeline,
CLUTTER_ALPHA_RAMP_INC,
NULL, NULL);
/* Set an alpha func to power behaviour */
alpha = clutter_alpha_new_for_mode (CLUTTER_LINEAR);
clutter_alpha_set_timeline (alpha, timeline);
/* Create a behaviour for that alpha */
r_behave = clutter_behaviour_rotate_new (alpha,

View File

@ -62,7 +62,7 @@ test_scale_main (int argc, char *argv[])
timeline = clutter_timeline_new_for_duration (750);
alpha = clutter_alpha_new_full (timeline,
CLUTTER_ALPHA_RAMP,
clutter_ramp_func,
NULL, NULL);
behave = clutter_behaviour_scale_new (alpha,

View File

@ -43,6 +43,7 @@ G_MODULE_EXPORT gint
test_texture_quality_main (int argc, char *argv[])
{
ClutterTimeline *timeline;
ClutterAlpha *alpha;
ClutterBehaviour *depth_behavior;
ClutterActor *stage;
ClutterActor *image;
@ -80,10 +81,9 @@ test_texture_quality_main (int argc, char *argv[])
"completed", G_CALLBACK (timeline_completed),
NULL);
depth_behavior = clutter_behaviour_depth_new (
clutter_alpha_new_full (timeline, CLUTTER_ALPHA_RAMP_INC, NULL, NULL),
-2500, 400);
alpha = clutter_alpha_new_for_mode (CLUTTER_LINEAR);
clutter_alpha_set_timeline (alpha, timeline);
depth_behavior = clutter_behaviour_depth_new (alpha, -2500, 400);
clutter_behaviour_apply (depth_behavior, image);
clutter_actor_show (stage);

View File

@ -213,7 +213,7 @@ test_threads_main (int argc, char *argv[])
timeline = clutter_timeline_new (150, 50);
clutter_timeline_set_loop (timeline, TRUE);
r_behaviour = clutter_behaviour_rotate_new (clutter_alpha_new_full (timeline,
CLUTTER_ALPHA_RAMP_INC,
clutter_ramp_inc_func,
NULL, NULL),
CLUTTER_Z_AXIS,
CLUTTER_ROTATE_CW,
@ -221,7 +221,7 @@ test_threads_main (int argc, char *argv[])
clutter_behaviour_apply (r_behaviour, rect);
p_behaviour = clutter_behaviour_path_new (clutter_alpha_new_full (timeline,
CLUTTER_ALPHA_SINE,
clutter_ramp_inc_func,
NULL, NULL),
knots,
G_N_ELEMENTS (knots));

View File

@ -37,12 +37,11 @@ test_viewport_main (int argc, char *argv[])
/* Make a timeline */
timeline = clutter_timeline_new (200, 26); /* num frames, fps */
g_object_set (timeline, "loop", TRUE, NULL);
clutter_timeline_set_loop (timeline, TRUE);
/* Set an alpha func to power behaviour - ramp is constant rise/fall */
alpha = clutter_alpha_new_full (timeline,
CLUTTER_ALPHA_RAMP_INC,
NULL, NULL);
/* Set an alpha func to power behaviour */
alpha = clutter_alpha_new_for_mode (CLUTTER_LINEAR);
clutter_alpha_set_timeline (alpha, timeline);
/* Create a behaviour for that alpha */
r_behave = clutter_behaviour_rotate_new (alpha,