Commit 5c7e317b authored by Bruno Coudoin's avatar Bruno Coudoin

- Animation code reviewed and documented by Joe Neeman

	- Improved wartercycle to use latest animation code. Made a new
	  boat animation based on Frank's fishing boat.
	- Implemented XRANDR support in gcompris.c
parent 373de052
2005-03-26 Bruno coudoin <bruno.coudoin@free.fr>
- Animation code reviewed and documented by Joe Neeman
- Improved wartercycle to use latest animation code. Made a new
boat animation based on Frank's fishing boat.
- Implemented XRANDR support in gcompris.c
* boards/watercycle/fishingboat.gif:
* boards/watercycle/fishingboat.png:
* boards/watercycle/fishingboat_tux.png:
* boards/watercycle/tuxboat.gif:
* boards/watercycle/tuxboat.png:
* boards/watercycle/tuxboat.txt:
* docs/C/python.xml:
* src/boards/py-mod-anim.c: (Animation_free), (AnimCanvas_init),
(AnimCanvas_free), (AnimCanvas_getattr),
(py_gcompris_animcanvas_setstate),
(python_gcompris_anim_module_init):
* src/boards/py-mod-anim.h:
* src/boards/python/watercycle.py:
* src/gcompris/anim.c: (gcompris_load_animation),
(gcompris_activate_animation), (gcompris_deactivate_animation),
(gcompris_free_animation), (gcompris_set_anim_state), (anim_tick):
* src/gcompris/anim.h:
* src/gcompris/gcompris.c:
2005-03-26 Bruno coudoin <bruno.coudoin@free.fr>
reviewed by: <delete if not using a buddy>
* boards/watercycle/fishingboat.gif:
* boards/watercycle/fishingboat.png:
* boards/watercycle/fishingboat_tux.png:
* boards/watercycle/tuxboat.gif:
* boards/watercycle/tuxboat.png:
* boards/watercycle/tuxboat.txt:
* docs/C/python.xml:
* src/boards/py-mod-anim.c: (Animation_free), (AnimCanvas_init),
(AnimCanvas_free), (AnimCanvas_getattr),
(py_gcompris_animcanvas_setstate),
(python_gcompris_anim_module_init):
* src/boards/py-mod-anim.h:
* src/boards/python/watercycle.py:
* src/gcompris/anim.c: (gcompris_load_animation),
(gcompris_activate_animation), (gcompris_deactivate_animation),
(gcompris_free_animation), (gcompris_set_anim_state), (anim_tick):
* src/gcompris/anim.h:
2005-03-26 Bruno coudoin <bruno.coudoin@free.fr>
Fixed by Jose to have a decreasing boat speed.
......
watercycle/tuxboat.gif
watercycle/fishingboat.gif
watercycle/fishingboat_tux.png
gcompris/misc/fishingboat.png
......@@ -115,6 +115,22 @@ AC_MSG_ERROR([You must have popt 1.5 or newer to compile gcompris.]))
AM_ICONV
dnl XRANDR Allow us to set the screen resolution dynamically
RANDR_LIBS=
found_randr=no
AC_CHECK_LIB(Xrandr, XRRSetScreenConfigAndRate,
[AC_CHECK_HEADER(X11/extensions/Xrandr.h,
RANDR_LIBS=-lXrandr found_randr=yes,,
[#include <X11/Xlib.h>])],
, -lXrender $ALL_X_LIBS )
if test "x$found_randr" = "xno"; then
AC_MSG_NOTICE(["Suitable Xrandr extension library not found - you need at least X 4.3. Will not use xrandr for fullscreen."])
AC_DEFINE_UNQUOTED(XRANDR, 1, [XRANDR Available])
fi
dnl Add the languages which your application supports here.
ALL_LINGUAS="am ar az bg ca cs da de el en_CA en_GB es et fi fr ga gu he hi hr hu it lt mk ml ms nl nb nn pa pl pt pt_BR ro ru sk sl sq sr sr@Latn sv tr wa zh_CN"
......
......@@ -843,6 +843,69 @@ attribute is readeable and/or writable.</para>
</sect2>
</sect1>
<sect1>
<title>anim.h structures Mapping</title>
<para>The gcompris.anim module supplies two objects, Animation and CanvasItems, corresponding to GcomprisAnimation and GcomprisAnimCanvasItem respectively.</para>
<sect2>
<title>Animation</title>
<para>The Animation object represents a set of animation files loaded into memory; it has no methods or members, only a constructor and a destructor. The constructor takes a single argument, the name of a text file containing a space-separated list of animation files. Each animation file in the text file corresponds to an animation state; the animations states are numbered from 0 to n-1.</para>
</sect2>
<sect2>
<title>CanvasItem</title>
<para>The CanvasItem object is a bit more interesting than the Animation object. It represents an active instance of an animation file. Its constructor takes two arguments, an Animation and a GnomeCanvasGroup (the parent of the desired active animation).</para>
<sect3>
<title>Members</title>
<informaltable>
<tgroup cols="4">
<thead>
<row>
<entry>Structure member</entry>
<entry>Type</entry>
<entry>Readable</entry>
<entry>Writable</entry>
</row>
</thead>
<tbody>
<row>
<entry>gnome_canvas</entry>
<entry>gnome.canvas.CanvasPixbuf</entry>
<entry>Y</entry>
<entry>N</entry>
</row>
<row>
<entry>num_states</entry>
<entry>int</entry>
<entry>Y</entry>
<entry>N</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</sect3>
<sect3>
<title>Functions</title>
<informaltable>
<tgroup cols="3">
<thead>
<row>
<entry>Python function</entry>
<entry>C equivalent</entry>
<entry>Notes</entry>
</row>
</thead>
<tbody>
<row>
<entry>gcompris.anim.CanvasItem.setState(int)</entry>
<entry>gcompris_set_anim_state(GcomprisAnimCanvasItem*, int)</entry>
<entry></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</sect3>
</sect2>
</sect1>
</article>
<!-- Keep this comment at the end of the file
......
......@@ -7,22 +7,21 @@
static int Animation_init(py_GcomprisAnimation *self, PyObject*, PyObject*);
static void Animation_free(py_GcomprisAnimation *self);
/* Animation methods */
static PyObject *py_gcompris_activate_animation_m(PyObject *self,
PyObject *args);
static int AnimCanvas_init(py_GcomprisAnimCanvas*, PyObject*, PyObject*);
static void AnimCanvas_free(py_GcomprisAnimCanvas*);
static PyObject *AnimCanvas_getattr(py_GcomprisAnimCanvas*, char*);
/* global methods */
static PyObject *py_gcompris_activate_animation(PyObject *self,
PyObject *args);
static PyObject *py_gcompris_deactivate_animation(PyObject *self,
PyObject *args);
/* AnimCanvas methods */
static PyObject *py_gcompris_animcanvas_setstate(PyObject*, PyObject*);
static PyMethodDef AnimCanvasMethods[] = {
{"setState", py_gcompris_animcanvas_setstate, METH_VARARGS,
"gcompris_animcanvas_setstate"},
{NULL, NULL, 0, NULL}
};
static PyMethodDef AnimationMethods[] = {
{"activate", py_gcompris_activate_animation_m, METH_VARARGS,
"gcompris_activate_animation_m"},
{"deactivate", py_gcompris_deactivate_animation, METH_VARARGS,
"gcompris_deactivate_animation"},
{NULL}
{NULL, NULL, 0, NULL}
};
static PyTypeObject py_GcomprisAnimationType = {
......@@ -67,14 +66,55 @@ static PyTypeObject py_GcomprisAnimationType = {
0, /* tp_new */
};
static PyTypeObject py_GcomprisAnimCanvasType = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
"pyGcomprisAnimCanvas", /* tp_name */
sizeof(py_GcomprisAnimCanvas), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)AnimCanvas_free, /* tp_dealloc */
0, /* tp_print */
(getattrfunc)AnimCanvas_getattr, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
"Animated canvas objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
AnimCanvasMethods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)AnimCanvas_init, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
};
static PyMethodDef PythonGcomprisAnimModule[] = {
{"activate_animation", py_gcompris_activate_animation, METH_VARARGS,
"gcompris_activate_animation"},
{"deactivate_animation", py_gcompris_deactivate_animation, METH_VARARGS,
"gcompris_deactivate_animation"},
{NULL}
{NULL, NULL, 0, NULL}
};
/*============================================================================*/
/* GcomprisAnimation functions */
/*============================================================================*/
static int
Animation_init(py_GcomprisAnimation *self, PyObject *args, PyObject *key)
{
......@@ -111,63 +151,68 @@ Animation_init(py_GcomprisAnimation *self, PyObject *args, PyObject *key)
static void Animation_free(py_GcomprisAnimation *self)
{
printf("*** Garbage collecting Animation ***\n");
gcompris_free_animation(self->a);
PyObject_DEL(self);
}
/*============================================================================*/
/* Animation Methods */
/*============================================================================*/
static PyObject*
py_gcompris_activate_animation_m(PyObject *s, PyObject *args)
static int
AnimCanvas_init(py_GcomprisAnimCanvas *self, PyObject *args, PyObject *key)
{
GnomeCanvasItem *item;
GcomprisAnimCanvasItem *item;
GcomprisAnimation *anim;
GnomeCanvasGroup *parent;
PyObject *py_p;
py_GcomprisAnimation *self = (py_GcomprisAnimation*) s;
PyObject *py_p, *py_a;
if(!PyArg_ParseTuple(args, "O:gcompris_activate_animation_m", &py_p))
return NULL;
if(!PyArg_ParseTuple(args, "OO:AnimCanvas_init", &py_a, &py_p))
return -1;
parent = (GnomeCanvasGroup*) pygobject_get(py_p);
item = (GnomeCanvasItem*) gcompris_activate_animation(parent, self->a);
return (PyObject*) pygobject_new((GObject*) item);
anim = ( (py_GcomprisAnimation*)py_a )->a;
item = (GcomprisAnimCanvasItem*) gcompris_activate_animation(parent, anim);
self->item = item;
self->anim = py_a;
Py_INCREF(self->anim);
return 0;
}
static PyObject*
py_gcompris_deactivate_animation(PyObject *s, PyObject *args)
static void
AnimCanvas_free(py_GcomprisAnimCanvas *self)
{
GnomeCanvasItem *item;
PyObject *pyitem;
printf("*** garbage collecting AnimCanvas ***\n");
gcompris_deactivate_animation(self->item);
Py_DECREF(self->anim);
PyObject_DEL(self);
}
if(!PyArg_ParseTuple(args, "O:gcompris_deactivate_animation", &pyitem) )
return NULL;
static PyObject *AnimCanvas_getattr(py_GcomprisAnimCanvas *self, char *name)
{
if(!strcmp(name, "gnome_canvas"))
return (PyObject*) pygobject_new( (GObject*) self->item->canvas );
else if(!strcmp(name, "num_states"))
return Py_BuildValue("i", self->item->anim->numstates);
item = (GnomeCanvasItem*) pygobject_get(pyitem);
gcompris_deactivate_animation(item);
Py_INCREF(Py_None);
return Py_None;
return Py_FindMethod(AnimCanvasMethods, (PyObject *)self, name);
}
/*============================================================================*/
/* Global Methods */
/*============================================================================*/
static PyObject*
py_gcompris_activate_animation(PyObject *self, PyObject *args)
py_gcompris_animcanvas_setstate(PyObject *self, PyObject *args)
{
py_GcomprisAnimation *anim;
PyObject *py_p;
GnomeCanvasGroup *parent;
int state;
GcomprisAnimCanvasItem *item = ( (py_GcomprisAnimCanvas*)self )->item;
if(!PyArg_ParseTuple(args, "OO:gcompris_activate_animation", &anim, &py_p))
return NULL;
if(!PyArg_ParseTuple(args, "i:gcompris_animcanvas_setstate", &state))
return NULL;
parent = (GnomeCanvasGroup*) pygobject_get(py_p);
gcompris_set_anim_state( item, state );
GnomeCanvasItem *item;
item = (GnomeCanvasItem*) gcompris_activate_animation(parent, anim->a);
return (PyObject*) pygobject_new((GObject*) item);
Py_INCREF(Py_None);
return Py_None;
}
#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
......@@ -180,12 +225,18 @@ python_gcompris_anim_module_init(void)
py_GcomprisAnimationType.tp_new = PyType_GenericNew;
py_GcomprisAnimationType.ob_type = &PyType_Type;
py_GcomprisAnimCanvasType.tp_new = PyType_GenericNew;
py_GcomprisAnimCanvasType.ob_type = &PyType_Type;
if (PyType_Ready(&py_GcomprisAnimationType) < 0)
return;
if (PyType_Ready(&py_GcomprisAnimCanvasType) < 0)
return;
m = Py_InitModule("_gcompris_anim", PythonGcomprisAnimModule);
Py_INCREF(&py_GcomprisAnimationType);
Py_INCREF(&py_GcomprisAnimCanvasType);
PyModule_AddObject(m, "Animation", (PyObject *)&py_GcomprisAnimationType);
PyModule_AddObject(m, "CanvasItem", (PyObject *)&py_GcomprisAnimCanvasType);
}
......@@ -11,4 +11,10 @@ typedef struct {
GcomprisAnimation *a;
} py_GcomprisAnimation;
typedef struct {
PyObject_HEAD
PyObject *anim;
GcomprisAnimCanvasItem *item;
} py_GcomprisAnimCanvas;
#endif
......@@ -46,6 +46,9 @@ class Gcompris_watercycle:
# The basic tick for object moves
self.timerinc = 50
# The tick for the boat is variable
self.boat_timerinc = self.timerinc
# Need to manage the timers to quit properly
self.boat_timer = 0
self.sun_timer = 0
......@@ -194,16 +197,12 @@ class Gcompris_watercycle:
# The tuxboat
self.tuxboatanim = gcompris.anim.Animation("watercycle/tuxboat.txt")
self.tuxboatitem = self.tuxboatanim.activate(self.rootitem)
self.tuxboatitem.set( x=10.0, y=470.0 )
self.tuxboatitem = gcompris.anim.CanvasItem( self.tuxboatanim, self.rootitem );
numstates = self.tuxboatitem.num_states
print "numstates: " + str(numstates)
self.tuxboatcanvas = self.tuxboatitem.gnome_canvas
self.tuxboatcanvas.set( x=-100.0, y=430.0 )
# self.tuxboatitem = self.rootitem.add(
# self.tuxboatanim.activate(self.rootitem),
# pixbuf = gcompris.utils.load_pixmap("gcompris/misc/tuxboat.png"),
# x=10.0,
# y=470.0
# )
# Tux in the shower (without water)
self.tuxshoweritem = self.rootitem.add(
gnome.canvas.CanvasPixbuf,
......@@ -357,28 +356,31 @@ class Gcompris_watercycle:
def move_boat(self):
if( self.tuxboatitem.get_bounds()[2] < 745 ) :
#Tried to make the boat slow down when arriving
if( self.tuxboatitem.get_bounds()[2] < 600 ) :
self.tuxboatitem.move(3, 0)
else:
self.tuxboatitem.move(2, 0)
self.boat_timer = gtk.timeout_add(self.timerinc, self.move_boat)
if( self.tuxboatcanvas.get_bounds()[2] < 770 ) :
# Make the boat slow down when arriving
if(self.tuxboatcanvas.get_bounds()[2]==700 or self.tuxboatcanvas.get_bounds()[2]==701):
self.boat_timerinc+=50
self.tuxboatcanvas.move(2, 0)
self.boat_timer = gtk.timeout_add(self.boat_timerinc, self.move_boat)
else:
if self.tuxboatitem.get_bounds()[2] < 790 :
if self.tuxboatcanvas.get_bounds()[2] < 800 :
# Park the boat
self.tuxboatitem.move(1, -1)
self.tuxboatcanvas.move(0.7, -0.7)
self.tuxboatitem.setState(1)
self.boat_timer = gtk.timeout_add(self.timerinc, self.move_boat)
else :
# We are parked, change the boat to remove tux
self.tuxboatanim.deactivate(self.tuxboatitem)
self.tuxboatitem.set(
pixbuf = gcompris.utils.load_pixmap("gcompris/misc/fishingboat.png"),
width = 100.0,
height = 48.0,
width_set = 1,
height_set = 1,
)
#self.tuxboatcanvas.set(
# pixbuf = gcompris.utils.load_pixmap("gcompris/misc/fishingboat.png"),
# width = 100.0,
# height = 48.0,
# width_set = 1,
# height_set = 1,
# )
self.tuxboatitem.setState(2)
# Now display tux in the shower
self.tuxshoweritem.show()
self.tuxisinshower = 1
......
......@@ -24,57 +24,41 @@
#define TICK_TIME 20
/* used for keeping track of active animations */
typedef struct {
GnomeCanvasGroup *parent;
GnomeCanvasPixbuf *item;
GcomprisAnimation *anim;
GdkPixbufAnimationIter *iter;
} ActiveAnim;
/* a list of ActiveAnim*s */
static GSList *active_list;
/* the list of active animations; we need to update it if active != NULL */
static GSList *active;
/* private callback */
static gboolean anim_tick(ActiveAnim*);
/* compare function to test if an ActiveAnim has a particular CanvasPixbuf */
static gint anim_item_cmpr(const ActiveAnim*, const ActiveAnim*);
static gint anim_anim_cmpr(const ActiveAnim*, const ActiveAnim*);
static gboolean anim_tick(void*);
GcomprisAnimation *gcompris_load_animation(char *filename)
{
GIOChannel *ch;
FILE *f;
if(filename[0] == '/') /* we were probably called by load_animation_asset */
{
ch = g_io_channel_new_file(filename, "r", NULL);
f = fopen(filename, "r");
}
else
{
gchar *tmp = g_strdup_printf("%s/%s", PACKAGE_DATA_DIR, filename);
ch = g_io_channel_new_file(tmp, "r", NULL);
f = fopen(tmp, "r");
g_free(tmp);
}
if(!ch)
if(!f)
{
g_warning("Couldn't open animation-spec file\n");
return NULL;
}
gchar *tmp = NULL;
char tmp[100];
GSList *files = NULL;
GcomprisAnimation *anim = NULL;
/* read whitespace-separated filenames form the animation spec-file */
while(g_io_channel_read_line(ch, &tmp, NULL, NULL, NULL)==G_IO_STATUS_NORMAL)
/* read filenames, one per line, from the animation spec-file */
while(fscanf(f, "%99s", tmp) == 1)
{
char *c;
for(c=tmp; *c && !isspace(*c); c++) /* get rid of everything from the
* first whitespace onwards */
;
*c = '\0';
files = g_slist_append(files, tmp);
files = g_slist_append(files,
g_strdup_printf("%s/%s", PACKAGE_DATA_DIR, tmp));
}
anim = g_malloc(sizeof(GcomprisAnimation));
......@@ -84,22 +68,21 @@ GcomprisAnimation *gcompris_load_animation(char *filename)
/* open the animations and assign them */
GError *error = NULL;
GSList *cur;
char *name;
int i;
for(cur=files, i=0; cur; cur = g_slist_next(cur), i++)
{
tmp = g_strdup_printf("%s/%s", PACKAGE_DATA_DIR, (char*)cur->data);
anim->anim[i] = gdk_pixbuf_animation_new_from_file(tmp, &error);
printf("Opened animation %s\n", tmp);
g_free(tmp);
name = (char*) cur->data;
anim->anim[i] = gdk_pixbuf_animation_new_from_file(name, &error);
printf("Opened animation %s\n", name);
if(!anim->anim[i])
{
tmp = g_strdup_printf("Couldn't open animation %s: %s\n",
(char*)cur->data,
error->message);
printf("%s\n", tmp);
g_free(tmp);
g_critical("Couldn't open animation %s: %s\n", name, error->message);
return NULL;
}
g_free(name);
}
g_slist_free(files);
return anim;
}
......@@ -118,89 +101,87 @@ GcomprisAnimation *gcompris_load_animation_asset(gchar *dataset,
return NULL;
}
GnomeCanvasPixbuf *gcompris_activate_animation(GnomeCanvasGroup *parent,
GcomprisAnimation *anim)
GcomprisAnimCanvasItem *gcompris_activate_animation(GnomeCanvasGroup *parent,
GcomprisAnimation *anim)
{
ActiveAnim *active = g_malloc(sizeof(ActiveAnim));
GcomprisAnimCanvasItem *item = g_malloc(sizeof(GcomprisAnimCanvasItem));
active->parent = parent;
active->anim = anim;
active->iter = gdk_pixbuf_animation_get_iter(anim->anim[0], NULL);
active->item = (GnomeCanvasPixbuf*) gnome_canvas_item_new(
item->state = 0;
item->anim = anim;
item->iter = gdk_pixbuf_animation_get_iter(anim->anim[0], NULL);
item->canvas = (GnomeCanvasPixbuf*) gnome_canvas_item_new(
parent,
GNOME_TYPE_CANVAS_PIXBUF,
"pixbuf",
gdk_pixbuf_animation_iter_get_pixbuf(active->iter),
gdk_pixbuf_animation_iter_get_pixbuf(item->iter),
NULL);
if(active_list == NULL)
if(active == NULL)
g_timeout_add(TICK_TIME, (GSourceFunc)anim_tick, NULL);
/* update the active list */
active_list = g_slist_append(active_list, active);
return active->item;
active = g_slist_append(active, item);
return item;
}
void gcompris_deactivate_animation(GnomeCanvasItem *item)
void gcompris_deactivate_animation(GcomprisAnimCanvasItem *item)
{
ActiveAnim dummy;
dummy.item = (GnomeCanvasPixbuf*)item;
GSList *active_node = g_slist_find_custom(active_list,
&dummy,
(GCompareFunc)anim_item_cmpr);
GSList *node = g_slist_find( active, item );
if( !node )
{
g_critical( "Tried to deactive non-existant animation" );
return;
}
active = g_slist_delete_link(active, node);
g_object_unref(item->iter);
g_free(item);
}
if(!active_node)
void gcompris_free_animation(GcomprisAnimation *anim)
{
int i;
for(i=0; i<anim->numstates; i++)
{
g_warning("tried to deactivate inactive animation\n");
return;
g_object_unref(anim->anim[i]);
}
ActiveAnim *active = (ActiveAnim*) active_node->data;
g_object_unref(active->iter);
g_object_unref(active->item);
g_free(active);
active_list = g_slist_delete_link(active_list, active_node);
g_free(anim);
}
gboolean gcompris_free_animation(GcomprisAnimation *anim)
void gcompris_set_anim_state(GcomprisAnimCanvasItem *item, int state)
{
ActiveAnim dummy;
dummy.anim = anim;
/* if any active animations are using anim, abort */
if(g_slist_find_custom(active_list, &dummy, (GCompareFunc)anim_anim_cmpr)
!= NULL)
if(state < item->anim->numstates)
{
g_warning("Tried to free an active animation\n");
return FALSE;
item->state = state;
}
int i;
for(i=0; i<anim->numstates; i++)
else
{
g_object_unref(anim->anim[i]);
item->state = 0;
}
g_free(anim);
return TRUE;
g_object_unref( item->iter );
item->iter = gdk_pixbuf_animation_get_iter( item->anim->anim[item->state],
NULL );
gnome_canvas_item_set( (GnomeCanvasItem*)item->canvas, "pixbuf",
gdk_pixbuf_animation_iter_get_pixbuf(item->iter),
NULL);
}
/* private callback functions */
static gboolean anim_tick(ActiveAnim *ignore)
static gboolean anim_tick(void *ignore)
{
if(active_list == NULL)
if(active == NULL)
{
printf("deactivating anim_tick\n");
return FALSE;
}
GSList *cur;
for(cur=active_list; cur; cur = g_slist_next(cur))
for(cur=active; cur; cur = g_slist_next(cur))
{
ActiveAnim *a = (ActiveAnim*)cur->data;
GcomprisAnimCanvasItem *a = (GcomprisAnimCanvasItem*)cur->data;
if( gdk_pixbuf_animation_iter_advance( a->iter, NULL) )
{
gnome_canvas_item_set((GnomeCanvasItem*)a->item, "pixbuf",
gnome_canvas_item_set((GnomeCanvasItem*)a->canvas, "pixbuf",
gdk_pixbuf_animation_iter_get_pixbuf(a->iter),
NULL);
}
......@@ -208,16 +189,3 @@ static gboolean anim_tick(ActiveAnim *ignore)
return TRUE;
}
static gint anim_item_cmpr(const ActiveAnim *a1, const ActiveAnim *a2)
{
if(a1->item == a2->item)
return 0;
return 1;
}
static gint anim_anim_cmpr(const ActiveAnim *a1, const ActiveAnim *a2)
{
if(a1->anim == a2->anim)
return 0;
return 1;
}
......@@ -32,9 +32,16 @@ typedef struct {
int numstates;
} GcomprisAnimation;
typedef struct {
GnomeCanvasPixbuf *canvas;