2007-05-14 Matthew Allum <mallum@openedhand.com>

* clutter/clutter-behaviour-path.c:
        Fix bug where last knot position wouldn't get reached.

        * clutter/clutter-group.c:
        Add some docs

        * clutter/clutter-timeline.h:
        * clutter/clutter-timeline.c:
        Add clutter_timeline_copy (needed for ClutterEffect)

        * clutter/clutter-version.h.in:
        Export windowing system / GL backend etc defines.

        * clutter/Makefile.am:
        * clutter/clutter-effect.c:
        * clutter/clutter-effect.h:
        * clutter/clutter.h:

        * clutter/glx/clutter-backend-glx.c:
        Minor clean ups.

        * clutter/clutter-alpha.h:
        Add a fixme.

        * configure.ac:
        Add FPU define.

        * examples/Makefile.am:
        * examples/slider.c:
        Add Robs slider game.
This commit is contained in:
Matthew Allum 2007-05-14 09:11:23 +00:00
parent e121eb54c8
commit 23ac88ac70
15 changed files with 742 additions and 4 deletions

View File

@ -1,3 +1,36 @@
2007-05-14 Matthew Allum <mallum@openedhand.com>
* clutter/clutter-behaviour-path.c:
Fix bug where last knot position wouldn't get reached.
* clutter/clutter-group.c:
Add some docs
* clutter/clutter-timeline.h:
* clutter/clutter-timeline.c:
Add clutter_timeline_copy (needed for ClutterEffect)
* clutter/clutter-version.h.in:
Export windowing system / GL backend etc defines.
* clutter/Makefile.am:
* clutter/clutter-effect.c:
* clutter/clutter-effect.h:
* clutter/clutter.h:
* clutter/glx/clutter-backend-glx.c:
Minor clean ups.
* clutter/clutter-alpha.h:
Add a fixme.
* configure.ac:
Add FPU define.
* examples/Makefile.am:
* examples/slider.c:
Add Robs slider game.
2007-05-10 Matthew Allum <mallum@openedhand.com> 2007-05-10 Matthew Allum <mallum@openedhand.com>
* clutter/egl/clutter-backend-egl.c: * clutter/egl/clutter-backend-egl.c:

View File

@ -59,6 +59,7 @@ source_h = \
$(srcdir)/clutter-stage.h \ $(srcdir)/clutter-stage.h \
$(srcdir)/clutter-texture.h \ $(srcdir)/clutter-texture.h \
$(srcdir)/clutter-timeline.h \ $(srcdir)/clutter-timeline.h \
$(srcdir)/clutter-effect.h \
$(srcdir)/clutter-util.h \ $(srcdir)/clutter-util.h \
$(srcdir)/clutter-version.h \ $(srcdir)/clutter-version.h \
$(NULL) $(NULL)
@ -146,6 +147,7 @@ source_c = \
clutter-rectangle.c \ clutter-rectangle.c \
clutter-texture.c \ clutter-texture.c \
clutter-timeline.c \ clutter-timeline.c \
$(srcdir)/clutter-effect.c \
clutter-util.c \ clutter-util.c \
$(NULL) $(NULL)

View File

@ -104,6 +104,7 @@ ClutterTimeline *clutter_alpha_get_timeline (ClutterAlpha *alpha);
#define CLUTTER_ALPHA_RAMP_DEC clutter_ramp_dec_func #define CLUTTER_ALPHA_RAMP_DEC clutter_ramp_dec_func
#define CLUTTER_ALPHA_RAMP clutter_ramp_func #define CLUTTER_ALPHA_RAMP clutter_ramp_func
#define CLUTTER_ALPHA_SINE clutter_sine_func #define CLUTTER_ALPHA_SINE clutter_sine_func
/* FIXME add SINE_INC/DEC */
#define CLUTTER_ALPHA_SQUARE clutter_square_func #define CLUTTER_ALPHA_SQUARE clutter_square_func
guint32 clutter_ramp_inc_func (ClutterAlpha *alpha, guint32 clutter_ramp_inc_func (ClutterAlpha *alpha,

View File

@ -145,6 +145,8 @@ actor_apply_knot_foreach (ClutterBehaviour *behaviour,
{ {
ClutterKnot *knot = data; ClutterKnot *knot = data;
CLUTTER_NOTE (BEHAVIOUR, "Setting actor to %ix%i", knot->x, knot->y);
clutter_actor_set_position (actor, knot->x, knot->y); clutter_actor_set_position (actor, knot->x, knot->y);
} }
@ -172,8 +174,13 @@ path_alpha_to_position (ClutterBehaviourPath *behave,
total_len = path_total_length (behave); total_len = path_total_length (behave);
offset = (alpha * total_len) / CLUTTER_ALPHA_MAX_ALPHA; offset = (alpha * total_len) / CLUTTER_ALPHA_MAX_ALPHA;
CLUTTER_NOTE (BEHAVIOUR, "alpha %i vs %i, len: %i vs %i",
alpha, CLUTTER_ALPHA_MAX_ALPHA,
offset, total_len);
if (offset == 0) if (offset == 0)
{ {
/* first knot */
clutter_behaviour_actors_foreach (behaviour, clutter_behaviour_actors_foreach (behaviour,
actor_apply_knot_foreach, actor_apply_knot_foreach,
priv->knots->data); priv->knots->data);
@ -183,6 +190,20 @@ path_alpha_to_position (ClutterBehaviourPath *behave,
return; return;
} }
if (offset == total_len)
{
/* Special case for last knot */
ClutterKnot *last_knot = (g_slist_last (priv->knots))->data;
clutter_behaviour_actors_foreach (behaviour,
actor_apply_knot_foreach,
last_knot);
g_signal_emit (behave, path_signals[KNOT_REACHED], 0, last_knot);
return;
}
for (l = priv->knots; l != NULL; l = l->next) for (l = priv->knots; l != NULL; l = l->next)
{ {
ClutterKnot *knot = l->data; ClutterKnot *knot = l->data;
@ -192,6 +213,7 @@ path_alpha_to_position (ClutterBehaviourPath *behave,
ClutterKnot *next = l->next->data; ClutterKnot *next = l->next->data;
dist_to_next = node_distance (knot, next); dist_to_next = node_distance (knot, next);
if (offset >= dist && offset < (dist + dist_to_next)) if (offset >= dist && offset < (dist + dist_to_next))
{ {
ClutterKnot new; ClutterKnot new;

348
clutter/clutter-effect.c Normal file
View File

@ -0,0 +1,348 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
* Jorn Baayen <jorn@openedhand.com>
* Emmanuele Bassi <ebassi@openedhand.com>
*
* Copyright (C) 2006 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* SECTION:clutter-effect-template
* @short_description: A utility class
*
*
* Since: 0.4
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#include "clutter-alpha.h"
#include "clutter-main.h"
#include "clutter-marshal.h"
#include "clutter-private.h"
#include "clutter-debug.h"
#include "clutter-behaviour-bspline.h"
#include "clutter-behaviour-ellipse.h"
#include "clutter-behaviour-opacity.h"
#include "clutter-behaviour-path.h"
#include "clutter-behaviour-rotate.h"
#include "clutter-behaviour-scale.h"
#include "clutter-effect.h"
typedef struct ClutterEffectClosure
{
ClutterActor *actor;
ClutterTimeline *timeline;
ClutterAlpha *alpha;
ClutterBehaviour *behave;
gulong signal_id;
ClutterEffectCompleteFunc completed_func;
gpointer completed_data;
ClutterEffectTemplate *template;
}
ClutterEffectClosure;
G_DEFINE_TYPE (ClutterEffectTemplate, clutter_effect_template, G_TYPE_OBJECT);
#define EFFECT_TEMPLATE_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), \
CLUTTER_TYPE_EFFECT_TEMPLATE, \
ClutterEffectTemplatePrivate))
typedef struct _ClutterEffectTemplatePrivate ClutterEffectTemplatePrivate;
struct _ClutterEffectTemplatePrivate
{
ClutterTimeline *timeline;
ClutterAlphaFunc alpha_func;
};
enum
{
PROP_0,
PROP_ALPHA_FUNC,
PROP_TIMELINE,
};
static void
clutter_effect_template_dispose (GObject *object)
{
ClutterEffectTemplate *template;
ClutterEffectTemplatePrivate *priv;
template = CLUTTER_EFFECT_TEMPLATE(object);
priv = EFFECT_TEMPLATE_PRIVATE(template);
g_object_unref (priv->timeline);
priv->timeline = NULL;
priv->alpha_func = NULL;
if (G_OBJECT_CLASS (clutter_effect_template_parent_class)->dispose)
G_OBJECT_CLASS (clutter_effect_template_parent_class)->dispose (object);
}
static void
clutter_effect_template_finalize (GObject *object)
{
G_OBJECT_CLASS (clutter_effect_template_parent_class)->finalize (object);
}
static void
clutter_effect_template_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterEffectTemplate *template;
ClutterEffectTemplatePrivate *priv;
template = CLUTTER_EFFECT_TEMPLATE(object);
priv = EFFECT_TEMPLATE_PRIVATE(template);
switch (prop_id)
{
case PROP_ALPHA_FUNC:
priv->alpha_func = g_value_get_pointer (value);
break;
case PROP_TIMELINE:
priv->timeline = g_value_get_object (value);
g_object_ref(priv->timeline);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
clutter_effect_template_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ClutterEffectTemplate *template;
ClutterEffectTemplatePrivate *priv;
template = CLUTTER_EFFECT_TEMPLATE(object);
priv = EFFECT_TEMPLATE_PRIVATE(template);
switch (prop_id)
{
case PROP_ALPHA_FUNC:
g_value_set_pointer (value, priv->alpha_func);
break;
case PROP_TIMELINE:
g_value_set_object (value, priv->timeline);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
clutter_effect_template_class_init (ClutterEffectTemplateClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
g_type_class_add_private (klass, sizeof (ClutterEffectTemplatePrivate));
object_class->dispose = clutter_effect_template_dispose;
object_class->finalize = clutter_effect_template_finalize;
object_class->set_property = clutter_effect_template_set_property;
object_class->get_property = clutter_effect_template_get_property;
g_object_class_install_property
(object_class,
PROP_ALPHA_FUNC,
g_param_spec_pointer ("alpha-func",
"Alpha-Function",
"Alpha reference Function",
G_PARAM_CONSTRUCT_ONLY |
CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(object_class,
PROP_TIMELINE,
g_param_spec_object ("timeline",
"Timeline",
"Timeline to use as a reference for the Template",
CLUTTER_TYPE_TIMELINE,
G_PARAM_CONSTRUCT_ONLY |
CLUTTER_PARAM_READWRITE));
}
static void
clutter_effect_template_init (ClutterEffectTemplate *self)
{
}
/**
* clutter_effect_template_new:
*
* FIXME
*
* Return value: a #ClutterEffectTemplate
*
* Since: 0.4
*/
ClutterEffectTemplate*
clutter_effect_template_new (ClutterTimeline *timeline,
ClutterAlphaFunc alpha_func)
{
return g_object_new (CLUTTER_TYPE_EFFECT_TEMPLATE,
"timeline", timeline,
"alpha-func", alpha_func,
NULL);
}
static void
clutter_effect_closure_destroy (ClutterEffectClosure *c)
{
g_signal_handler_disconnect (c->timeline, c->signal_id);
clutter_behaviour_remove (c->behave, c->actor);
g_object_unref (c->actor);
g_object_unref (c->template);
g_object_unref (c->behave);
g_object_unref (c->alpha);
g_object_unref (c->timeline);
g_slice_free (ClutterEffectClosure, c);
}
static ClutterEffectClosure*
clutter_effect_closure_new (ClutterEffectTemplate *template,
ClutterActor *actor,
GCallback complete)
{
ClutterEffectClosure *c;
ClutterEffectTemplatePrivate *priv = EFFECT_TEMPLATE_PRIVATE(template);
c = g_slice_new0(ClutterEffectClosure);
g_object_ref (actor);
g_object_ref (template);
c->template = template;
c->actor = actor;
c->timeline = clutter_timeline_copy (priv->timeline);
c->alpha = clutter_alpha_new_full (c->timeline,
priv->alpha_func,
NULL, NULL);
c->signal_id = g_signal_connect (c->timeline,
"completed",
G_CALLBACK(complete),
c);
return c;
}
static void
on_effect_complete (ClutterTimeline *timeline,
gpointer user_data)
{
ClutterEffectClosure *c = (ClutterEffectClosure*)user_data;
if (c->completed_func)
c->completed_func(c->actor, c->completed_data);
clutter_effect_closure_destroy (c);
}
/**
* clutter_effect_fade:
*
* FIXME
*
* Return value: an alpha value.
*
* Since: 0.4
*/
ClutterTimeline*
clutter_effect_fade (ClutterEffectTemplate *template,
ClutterActor *actor,
guint8 start_opacity,
guint8 end_opacity,
ClutterEffectCompleteFunc completed_func,
gpointer completed_userdata)
{
ClutterEffectClosure *c;
c = clutter_effect_closure_new (template,
actor,
G_CALLBACK (on_effect_complete));
c->completed_func = completed_func;
c->completed_data = completed_userdata;
c->behave = clutter_behaviour_opacity_new (c->alpha,
start_opacity,
end_opacity);
clutter_behaviour_apply (c->behave, actor);
clutter_timeline_start (c->timeline);
return c->timeline;
}
/**
* clutter_effect_move:
*
* FIXME
*
* Return value: an alpha value.
*
* Since: 0.4
*/
ClutterTimeline*
clutter_effect_move (ClutterEffectTemplate *template,
ClutterActor *actor,
const ClutterKnot *knots,
guint n_knots,
ClutterEffectCompleteFunc completed_func,
gpointer completed_userdata)
{
ClutterEffectClosure *c;
c = clutter_effect_closure_new (template,
actor,
G_CALLBACK (on_effect_complete));
c->completed_func = completed_func;
c->completed_data = completed_userdata;
c->behave = clutter_behaviour_path_new (c->alpha, knots, n_knots);
clutter_behaviour_apply (c->behave, actor);
clutter_timeline_start (c->timeline);
return c->timeline;
}

97
clutter/clutter-effect.h Normal file
View File

@ -0,0 +1,97 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
*
* Copyright (C) 2006, 2007 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef _CLUTTER_EFFECT
#define _CLUTTER_EFFECT
#include <glib-object.h>
#include <clutter/clutter-timeline.h>
#include <clutter/clutter-alpha.h>
#include <clutter/clutter-behaviour.h>
G_BEGIN_DECLS
typedef void (*ClutterEffectCompleteFunc) (ClutterActor *actor,
gpointer user_data);
#define CLUTTER_TYPE_EFFECT_TEMPLATE clutter_effect_template_get_type()
#define CLUTTER_EFFECT_TEMPLATE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
CLUTTER_TYPE_EFFECT_TEMPLATE, ClutterEffectTemplate))
#define CLUTTER_EFFECT_TEMPLATE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), \
CLUTTER_TYPE_EFFECT_TEMPLATE, ClutterEffectTemplateClass))
#define CLUTTER_IS_EFFECT_TEMPLATE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
CLUTTER_TYPE_EFFECT_TEMPLATE))
#define CLUTTER_IS_EFFECT_TEMPLATE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
CLUTTER_TYPE_EFFECT_TEMPLATE))
#define CLUTTER_EFFECT_TEMPLATE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
CLUTTER_TYPE_EFFECT_TEMPLATE, ClutterEffectTemplateClass))
typedef struct {
GObject parent;
} ClutterEffectTemplate;
typedef struct {
GObjectClass parent_class;
} ClutterEffectTemplateClass;
GType clutter_effect_template_get_type (void);
ClutterEffectTemplate*
clutter_effect_template_new (ClutterTimeline *timeline,
ClutterAlphaFunc alpha_func);
ClutterTimeline*
clutter_effect_fade (ClutterEffectTemplate *template,
ClutterActor *actor,
guint8 start_opacity,
guint8 end_opacity,
ClutterEffectCompleteFunc completed_func,
gpointer completed_data);
ClutterTimeline*
clutter_effect_move (ClutterEffectTemplate *template,
ClutterActor *actor,
const ClutterKnot *knots,
guint n_knots,
ClutterEffectCompleteFunc completed_func,
gpointer completed_data);
G_END_DECLS
#endif /* _CLUTTER_EFFECT */
G_END_DECLS

View File

@ -25,10 +25,15 @@
/** /**
* SECTION:clutter-group * SECTION:clutter-group
* @short_description: Base class for actors which contain multiple child * @short_description: Actor class containing multiple children.
* actors. * actors.
* *
* A #ClutterGroup is an Actor which can contain multiple child actors. * A #ClutterGroup is an Actor which contains multiple child actors positioned
* relative to the #ClutterGroup position. Other operations such as scaling,
* rotating and clipping of the group will child actors.
*
* A ClutterGroup's size is defined by the size and position of it
* it children. Resize requests via parent #ClutterActor will be ignored.
*/ */
#include "config.h" #include "config.h"

View File

@ -627,6 +627,33 @@ clutter_timeline_is_playing (ClutterTimeline *timeline)
return (timeline->priv->timeout_id != 0); return (timeline->priv->timeout_id != 0);
} }
/**
* clutter_timeline_copy:
* @timeline: #ClutterTimeline to duplicate.
*
* Create a new #ClutterTimeline instance which has property values
* matching that of supplied timeline.
*
* Return Value: a new #ClutterTimeline
*
* Since 0.4
*/
ClutterTimeline*
clutter_timeline_copy (ClutterTimeline *timeline)
{
ClutterTimeline *copy;
g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), NULL);
copy = g_object_new (CLUTTER_TYPE_TIMELINE, NULL);
copy->priv->fps = timeline->priv->fps;
copy->priv->n_frames = timeline->priv->n_frames;
copy->priv->loop = timeline->priv->loop;
return copy;
}
/** /**
* clutter_timeline_new: * clutter_timeline_new:
* @n_frames: the number of frames * @n_frames: the number of frames

View File

@ -106,6 +106,7 @@ void clutter_timeline_set_n_frames (ClutterTimeline *timeline,
guint n_frames); guint n_frames);
guint clutter_timeline_get_n_frames (ClutterTimeline *timeline); guint clutter_timeline_get_n_frames (ClutterTimeline *timeline);
gboolean clutter_timeline_is_playing (ClutterTimeline *timeline); gboolean clutter_timeline_is_playing (ClutterTimeline *timeline);
ClutterTimeline* clutter_timeline_copy (ClutterTimeline *timeline);
G_END_DECLS G_END_DECLS

View File

@ -41,6 +41,13 @@
(CLUTTER_MAJOR_VERSION == (major) && CLUTTER_MINOR_VERSION > (minor)) || \ (CLUTTER_MAJOR_VERSION == (major) && CLUTTER_MINOR_VERSION > (minor)) || \
(CLUTTER_MAJOR_VERSION == (major) && CLUTTER_MINOR_VERSION == (minor) && CLUTTER_MICRO_VERSION > (micro))) (CLUTTER_MAJOR_VERSION == (major) && CLUTTER_MINOR_VERSION == (minor) && CLUTTER_MICRO_VERSION > (micro)))
/* GL Windowing system used */
#define CLUTTER_FLAVOUR "@CLUTTER_FLAVOUR@" #define CLUTTER_FLAVOUR "@CLUTTER_FLAVOUR@"
/* cogl backend - gl or gles currently */
#define CLUTTER_COGL "@CLUTTER_COGL@"
/* Set to 1 if clutter built without FPU (i.e fixed math), 0 otherwise */
#define CLUTTER_NO_FPU @CLUTTER_NO_FPU@
#endif /* __CLUTTER_VERSION_H__ */ #endif /* __CLUTTER_VERSION_H__ */

View File

@ -39,6 +39,7 @@
#include "clutter-behaviour-path.h" #include "clutter-behaviour-path.h"
#include "clutter-behaviour-rotate.h" #include "clutter-behaviour-rotate.h"
#include "clutter-behaviour-scale.h" #include "clutter-behaviour-scale.h"
#include "clutter-effect.h"
#include "clutter-stage.h" #include "clutter-stage.h"
#include "clutter-actor.h" #include "clutter-actor.h"
#include "clutter-rectangle.h" #include "clutter-rectangle.h"

View File

@ -167,6 +167,7 @@ clutter_backend_glx_init_stage (ClutterBackend *backend,
} }
/* At least GL 1.2 is needed for CLAMP_TO_EDGE */ /* At least GL 1.2 is needed for CLAMP_TO_EDGE */
/* FIXME: move to cogl... */
if (!is_gl_version_at_least_12 ()) if (!is_gl_version_at_least_12 ())
{ {
g_set_error (error, CLUTTER_INIT_ERROR, g_set_error (error, CLUTTER_INIT_ERROR,

View File

@ -239,6 +239,8 @@ fi
AC_SUBST(CLUTTER_DEBUG_CFLAGS) AC_SUBST(CLUTTER_DEBUG_CFLAGS)
CLUTTER_NO_FPU=0
AC_ARG_WITH(fpu, AC_ARG_WITH(fpu,
AS_HELP_STRING([--without-fpu], AS_HELP_STRING([--without-fpu],
[Assume target hardware has no fpu]), [Assume target hardware has no fpu]),
@ -246,9 +248,12 @@ AC_ARG_WITH(fpu,
[with_fpu=yes]) [with_fpu=yes])
if test "x$with_fpu" != "xyes" ; then if test "x$with_fpu" != "xyes" ; then
CLUTTER_NO_FPU=1
CLUTTER_FIXED_CFLAGS="-DCFX_NO_FPU" CLUTTER_FIXED_CFLAGS="-DCFX_NO_FPU"
fi fi
AC_SUBST(CLUTTER_HAS_FPU)
dnl = GTK Doc check ======================================================== dnl = GTK Doc check ========================================================
GTK_DOC_CHECK([1.4]) GTK_DOC_CHECK([1.4])

View File

@ -1,8 +1,13 @@
noinst_PROGRAMS = test super-oh behave test-text noinst_PROGRAMS = test super-oh behave test-text slider
INCLUDES = -I$(top_srcdir)/ INCLUDES = -I$(top_srcdir)/
LDADD = $(top_builddir)/clutter/libclutter-@CLUTTER_FLAVOUR@-@CLUTTER_MAJORMINOR@.la LDADD = $(top_builddir)/clutter/libclutter-@CLUTTER_FLAVOUR@-@CLUTTER_MAJORMINOR@.la
AM_CFLAGS = $(CLUTTER_CFLAGS)
LDFLAGS = $(CLUTTER_LIBS)
slider_SOURCES = slider.c
test_SOURCES = test.c test_SOURCES = test.c
test_CFLAGS = $(CLUTTER_CFLAGS) $(GCONF_CFLAGS) test_CFLAGS = $(CLUTTER_CFLAGS) $(GCONF_CFLAGS)
test_LDFLAGS = \ test_LDFLAGS = \

183
examples/slider.c Normal file
View File

@ -0,0 +1,183 @@
#include <clutter/clutter.h>
typedef struct Tile
{
ClutterActor *actor;
gint orig_pos;
}
Tile;
static Tile *Tiles[4][4];
static int TileW, TileH, BlankTileX, BlankTileY;
static ClutterEffectTemplate *Template;
static ClutterTimeline *EffectTimeline;
ClutterActor*
make_tiles (GdkPixbuf *pixbuf)
{
int x, y , w, h;
int i = 0, j = 0;
int pos = 0;
ClutterActor *group;
group = clutter_group_new();
w = gdk_pixbuf_get_width (pixbuf);
h = gdk_pixbuf_get_height (pixbuf);
TileW = w / 4;
TileH = h / 4;
for (y = 0; y < h; y += TileH)
{
for (x = 0; x < w; x += TileW)
{
GdkPixbuf *subpixbuf;
Tile *tile;
subpixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE,
8, TileW, TileH);
gdk_pixbuf_copy_area (pixbuf, x, y, TileW, TileH,
subpixbuf, 0, 0);
tile = g_slice_new0 (Tile);
if (pos != 15)
{
tile->actor = clutter_texture_new_from_pixbuf (subpixbuf);
clutter_group_add (CLUTTER_GROUP (group), tile->actor);
clutter_actor_set_position (tile->actor, x, y);
}
else
{
/* blank tile */
tile->actor = NULL;
BlankTileX = i;
BlankTileY = j;
}
g_object_unref (subpixbuf);
tile->orig_pos = pos;
Tiles[j][i] = tile;
pos++; i++;
}
i=0; j++;
}
return group;
}
static void
switch_blank_tile (int i, int j)
{
Tile *tmp;
ClutterKnot knots[2];
knots[0].x = i * TileW;
knots[0].y = j * TileH;
knots[1].x = BlankTileX * TileW;
knots[1].y = BlankTileY * TileH;
EffectTimeline = clutter_effect_move (Template,
Tiles[j][i]->actor,
knots,
2,
NULL,
NULL);
/* Add a week pointer to returned timeline so we know whilst its
* playing and thus valid.
*/
g_object_add_weak_pointer (G_OBJECT(EffectTimeline),
(gpointer*)&EffectTimeline);
tmp = Tiles[BlankTileY][BlankTileX];
Tiles[BlankTileY][BlankTileX] = Tiles[j][i];
Tiles[j][i] = tmp;
BlankTileY = j;
BlankTileX = i;
}
static void
key_press_event_cb (ClutterStage *stage,
ClutterKeyEvent *event,
gpointer user_data)
{
Tile *tmp, *tmp2;
if (clutter_key_event_symbol(event) == CLUTTER_q)
clutter_main_quit();
/* Do move if there is a move already happening */
if (EffectTimeline != NULL)
return;
switch (clutter_key_event_symbol(event))
{
case CLUTTER_Up:
if (BlankTileY < 3)
switch_blank_tile (BlankTileX, BlankTileY+1);
break;
case CLUTTER_Down:
if (BlankTileY > 0)
switch_blank_tile (BlankTileX, BlankTileY-1);
break;
case CLUTTER_Left:
if (BlankTileX < 3)
switch_blank_tile (BlankTileX+1, BlankTileY);
break;
case CLUTTER_Right:
if (BlankTileX > 0)
switch_blank_tile (BlankTileX-1, BlankTileY);
break;
default:
break;
}
}
int
main (int argc, char **argv)
{
GdkPixbuf *pixbuf;
ClutterActor *stage, *group;
ClutterColor bgcolour;
/* Initiate clutter */
clutter_init (&argc, &argv);
/* Setup the stage */
stage = clutter_stage_get_default ();
g_object_set (stage, "fullscreen", TRUE, NULL);
clutter_color_parse ("#000000", &bgcolour);
clutter_stage_set_color (CLUTTER_STAGE (stage), &bgcolour);
/* Create Tiles */
pixbuf = gdk_pixbuf_new_from_file ("image.jpg", NULL);
group = make_tiles (pixbuf);
/* Add to stage and center */
clutter_group_add (CLUTTER_GROUP (stage), group);
clutter_actor_set_position (group,
(clutter_actor_get_width (stage) - clutter_actor_get_width (group)) / 2,
(clutter_actor_get_height (stage) - clutter_actor_get_height (group)) / 2);
/* Link up event collection */
g_signal_connect (stage,
"key-press-event",
G_CALLBACK(key_press_event_cb),
NULL);
/* Template to use for slider animation */
Template = clutter_effect_template_new (clutter_timeline_new (15, 60),
CLUTTER_ALPHA_RAMP_INC);
clutter_actor_show_all (stage);
clutter_main();
}