All pastes #935986 Raw Edit

Untitled

public text v1 · immutable
·published 2008-03-10 01:23 UTC
rendered paste body
#include <clutter/clutter.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <clutter-gtk/gtk-clutter-embed.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <math.h>
#include <gtk/gtk.h>
#include <GL/gl.h>

void (*original_paint) (ClutterActor * actor) = 0;

typedef struct _Cover {
	ClutterActor * texture;
	gboolean showing;
} Cover;

typedef struct _App {
	ClutterActor * stage;
	GList * album_list;
	gchar * base_directory;
	gint dimy;
	gint dimx;
	gint screenw;
	gint screenh;
	gint artw;
	gint arth;
	gint posx;
	gint posy;
} App;

static void paint_album (ClutterActor * actor)
{
	glEnable(GL_CULL_FACE);
	glCullFace(GL_FRONT);
	original_paint(actor);
	glDisable(GL_CULL_FACE);
}

static void rotate_finished(ClutterActor * actor,
				gpointer data)
{
	clutter_actor_hide(actor);
}

static gboolean start_rotate(gpointer data)
{
	App * app = (App *) data;
	ClutterEffectTemplate * effect =
		clutter_effect_template_new_for_duration(1000, 
							 CLUTTER_ALPHA_SINE_INC);
	
        Cover *cov1, *cov2;

	if (g_list_length(app->album_list) < (app->dimx * app->dimy))
		return TRUE;

	cov1 = g_list_nth_data(app->album_list,
			       random() % 
			       g_list_length(app->album_list));
	cov2 = g_list_nth_data(app->album_list,
			       random() % 
			       g_list_length(app->album_list));
	
	
	while (!cov1->showing)
		cov1 = g_list_nth_data(app->album_list,
				       random() % 
				       g_list_length(app->album_list));
	while (cov2->showing)
		cov2 = g_list_nth_data(app->album_list,
				       random() %
				       g_list_length(app->album_list));
	
	clutter_actor_show(cov2->texture);
	
	clutter_actor_set_rotation(cov1->texture, CLUTTER_Y_AXIS, 0,
				   0, 0, 0);
	clutter_actor_set_rotation(cov2->texture, CLUTTER_Y_AXIS, 180,
				   0, 0, 0);

	clutter_actor_set_position(cov2->texture,
				   clutter_actor_get_x(cov1->texture),
				   clutter_actor_get_y(cov1->texture));
	
	
	clutter_effect_rotate(effect,cov1->texture,
			      CLUTTER_Y_AXIS, 180,
			      clutter_actor_get_width(cov1->texture)/2,
			      clutter_actor_get_height(cov1->texture)/2,
			      0, CLUTTER_ROTATE_CW, 0, 0);
	clutter_effect_rotate(effect,cov2->texture,
			      CLUTTER_Y_AXIS, 360,
			      clutter_actor_get_width(cov2->texture)/2,
			      clutter_actor_get_height(cov2->texture)/2,
			      0, CLUTTER_ROTATE_CW, 0, 0);
	
	g_object_unref(effect);
	cov1->showing = 0;
	cov2->showing = 1;

	return TRUE;

}

static gboolean
supported_img(const gchar * name)
{
	GdkPixbufFormat * fmt = gdk_pixbuf_get_file_info (name, NULL, NULL);
	if (fmt)
		return (gdk_pixbuf_format_is_disabled (fmt) != TRUE);
	return FALSE;
}
static void load_image(App * app, const gchar * name)
{
	Cover * cov = g_new0(Cover, 1);
	GdkPixbuf * pixbuf;
	
	pixbuf = gdk_pixbuf_new_from_file(name, NULL);	
	
	app->album_list = g_list_append(app->album_list, cov);
	cov->texture = clutter_texture_new_from_pixbuf(pixbuf);
	if (!original_paint)
	{
		original_paint = CLUTTER_ACTOR_GET_CLASS(cov->texture)->paint;
		CLUTTER_ACTOR_GET_CLASS(cov->texture)->paint = paint_album;
	}
	clutter_container_add_actor(CLUTTER_CONTAINER(app->stage), cov->texture);
	clutter_actor_set_size(cov->texture,
			       app->artw,
			       app->arth);
	clutter_actor_show(cov->texture);
	if ((app->posx < app->dimx) && (app->posy < app->dimy))
	{
		ClutterEffectTemplate * effect =
			clutter_effect_template_new_for_duration(500, 
								 CLUTTER_ALPHA_EXP_INC);
		
		cov->showing = 1;
		clutter_actor_set_opacity(cov->texture, 0x00);
		clutter_actor_set_x(cov->texture,
				    app->artw*app->posx);
		clutter_actor_set_y(cov->texture,
				    app->arth*app->posy);
		
		clutter_effect_fade(effect, cov->texture, 255, 0, 0);
		
		g_object_unref(effect);
	}
	else
	{
		clutter_actor_hide(cov->texture);
		cov->showing = 0;
	}

	app->posx++;
	if (app->posx > app->dimx)
	{
		app->posx = 0;
		app->posy++;
	}


	g_object_unref(pixbuf);
}

static void load_directory(App * app, 
			   const gchar * name)
{
	GDir * dir;
	struct stat sbuf;
	const gchar * fname;
	
	dir = g_dir_open(name, 0, NULL);
	if (!dir)
		return;
	g_chdir(name);
	
	while ((fname = g_dir_read_name(dir)))
	{
		while (g_main_context_pending (NULL))
			g_main_context_iteration(NULL, FALSE);
		if (supported_img(fname))
			load_image(app, fname);
		if (g_stat(fname, &sbuf) > -1 && S_ISDIR(sbuf.st_mode))
			load_directory(app, fname);
	}
	g_chdir("..");
	g_dir_close(dir);
}

static gboolean
load_images(gpointer data)
{
	App * app = (App *)data;
	
	clutter_actor_get_size(app->stage, &(app->screenw),
			       &(app->screenh));
	
	app->dimx = app->dimy * (app->screenw / (float)app->screenh);
	app->artw = floor(app->screenw / (float)app->dimx);
	app->arth = floor(app->screenh / (float)app->dimy);
	
	g_timeout_add(5000, start_rotate, app);
	
	load_directory(app, app->base_directory);
	
	return FALSE;
}

int main (int argc, char ** argv)
{
	GtkWidget *window;
	GtkWidget *clutter;
	App * app;
	ClutterColor color = {0x0,0x0,0x0,0xff};
	gint artX, artY, screenX, screenY;
	
	gtk_init(&argc, &argv);
	gtk_clutter_init(&argc, &argv);

	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	clutter = gtk_clutter_embed_new();
	gtk_window_fullscreen(GTK_WINDOW(window));
	
	gtk_container_add(GTK_CONTAINER(window),clutter);
	gtk_widget_show_all(window);

	app = g_new0(App,1);

	app->stage = gtk_clutter_embed_get_stage(GTK_CLUTTER_EMBED(clutter));
	app->dimy = 4; // FIXME
	app->base_directory = *(argv+1);
	app->posx = app->posy = 0;

	clutter_stage_fullscreen(CLUTTER_STAGE(app->stage));
	clutter_stage_set_color(CLUTTER_STAGE(app->stage), &color);
	
	g_timeout_add(100, load_images, app);
	clutter_actor_show_all(app->stage);
	gtk_main();
}