/* gcompris - anim.c
*
* Copyright (C) 2005 Joe Neeman
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see .
*/
#include "anim.h"
#include
#define TICK_TIME 20
/* the list of active animations; we need to update it if active != NULL */
static GSList *active;
/* private callback */
static gboolean anim_tick(void*);
GcomprisAnimation *
gc_anim_load(char *filename)
{
FILE *f = NULL;
gchar *absolute_filename;
absolute_filename = gc_file_find_absolute(filename);
if (absolute_filename){
f = g_fopen(absolute_filename, "r");
g_free(absolute_filename);
}
if(!f)
{
g_warning("Couldn't open animation-spec file '%s'\n", filename);
return NULL;
}
char tmp[100];
GSList *files = NULL;
GcomprisAnimation *anim = NULL;
/* read filenames, one per line, from the animation spec-file */
while(fscanf(f, "%99s", tmp) == 1)
{
GcomprisBoard *gcomprisBoard = gc_board_get_current();
files = g_slist_append(files,
g_strdup_printf("%s/%s", gcomprisBoard->board_dir, tmp));
}
fclose(f);
anim = g_malloc(sizeof(GcomprisAnimation));
anim->numstates = g_slist_length(files);
anim->anim = g_malloc(sizeof(GdkPixbuf*) * anim->numstates);
/* 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++)
{
name = (char*) cur->data;
anim->anim[i] = gdk_pixbuf_animation_new_from_file(name, &error);
g_warning("Opened animation %s\n", name);
if(!anim->anim[i])
{
g_critical("Couldn't open animation %s: %s\n", name, error->message);
return NULL;
}
g_free(name);
}
g_slist_free(files);
return anim;
}
GcomprisAnimCanvasItem *
gc_anim_activate(GnomeCanvasGroup *parent,
GcomprisAnimation *anim)
{
GcomprisAnimCanvasItem *item = g_malloc(sizeof(GcomprisAnimCanvasItem));
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(item->iter),
NULL);
if(active == NULL)
g_timeout_add(TICK_TIME, (GSourceFunc)anim_tick, NULL);
active = g_slist_append(active, item);
return item;
}
void
gc_anim_swap(GcomprisAnimCanvasItem *item, GcomprisAnimation *new_anim)
{
item->anim = new_anim;
gc_anim_set_state(item, 0);
}
void
gc_anim_deactivate(GcomprisAnimCanvasItem *item)
{
GSList *node = g_slist_find( active, item );
if( !node )
{
g_critical( "Tried to deactive non-existant animation" );
return;
}
if (GNOME_IS_CANVAS_ITEM(item->canvas)){
gtk_object_destroy(GTK_OBJECT(item->canvas));
item->canvas = NULL;
}
active = g_slist_delete_link(active, node);
g_object_unref(item->iter);
g_free(item);
}
void
gc_anim_free(GcomprisAnimation *anim)
{
int i;
for(i=0; inumstates; i++)
{
g_object_unref(anim->anim[i]);
}
g_free(anim->anim);
g_free(anim);
}
void
gc_anim_set_state(GcomprisAnimCanvasItem *item, int state)
{
if(state < item->anim->numstates)
{
item->state = state;
}
else
{
item->state = 0;
}
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(void *ignore)
{
if(active == NULL)
{
g_warning("deactivating anim_tick\n");
return FALSE;
}
GSList *cur;
for(cur=active; cur; cur = g_slist_next(cur))
{
GcomprisAnimCanvasItem *a = (GcomprisAnimCanvasItem*)cur->data;
if( gdk_pixbuf_animation_iter_advance( a->iter, NULL) )
{
gnome_canvas_item_set((GnomeCanvasItem*)a->canvas, "pixbuf",
gdk_pixbuf_animation_iter_get_pixbuf(a->iter),
NULL);
}
}
return TRUE;
}