mutter/clutter/cltr-animator.c
Matthew Allum 55fdb9bc79 much
2005-05-16 22:38:57 +00:00

233 lines
5.2 KiB
C

#include "cltr-animator.h"
#include "cltr-private.h"
struct CltrAnimator
{
CltrWidget *widget;
gint fps;
int n_steps, step;
CltrAnimatorFinishFunc anim_finish_cb;
gpointer *anim_finish_data;
WidgetPaintMethod wrapped_paint_func;
int zoom_end_x1, zoom_end_y1, zoom_end_x2, zoom_end_y2;
int zoom_start_x1, zoom_start_y1, zoom_start_x2, zoom_start_y2;
};
static void
cltr_animator_wrapped_paint(CltrWidget *widget);
CltrAnimator*
cltr_animator_zoom_new(CltrWidget *widget,
int src_x1,
int src_y1,
int src_x2,
int src_y2,
int dst_x1,
int dst_y1,
int dst_x2,
int dst_y2)
{
CltrAnimator *anim = g_malloc0(sizeof(CltrAnimator));
anim->zoom_end_x1 = dst_x1;
anim->zoom_end_x2 = dst_x2;
anim->zoom_end_y1 = dst_y1;
anim->zoom_end_y2 = dst_y2;
anim->zoom_start_x1 = src_x1;
anim->zoom_start_x2 = src_x2;
anim->zoom_start_y1 = src_y1;
anim->zoom_start_y2 = src_y2;
anim->wrapped_paint_func = widget->paint;
anim->widget = widget;
widget->anim = anim;
anim->n_steps = 10;
anim->step = 0;
anim->fps = 50;
return anim;
}
CltrAnimator*
cltr_animator_fullzoom_new(CltrWidget *widget,
int x1,
int y1,
int x2,
int y2)
{
CltrAnimator *anim = g_malloc0(sizeof(CltrAnimator));
anim->zoom_end_x1 = x1;
anim->zoom_end_x2 = x2;
anim->zoom_end_y1 = y1;
anim->zoom_end_y2 = y2;
anim->zoom_start_x1 = cltr_widget_abs_x(widget);
anim->zoom_start_x2 = cltr_widget_abs_x2(widget);
anim->zoom_start_y1 = cltr_widget_abs_y(widget);
anim->zoom_start_y2 = cltr_widget_abs_y2(widget);
anim->wrapped_paint_func = widget->paint;
anim->widget = widget;
widget->anim = anim;
anim->n_steps = 10;
anim->step = 0;
anim->fps = 50;
return anim;
}
CltrAnimator*
cltr_animator_new(CltrWidget *widget)
{
return NULL;
}
void
cltr_animator_set_args(CltrAnimator *anim)
{
}
static void
cltr_animator_wrapped_paint(CltrWidget *widget)
{
CltrAnimator *anim = widget->anim;
float tx = 0.0, ty = 0.0;
float x1, x2, y1, y2;
/* zoom here */
float f = (float)anim->step/anim->n_steps;
int end_width = anim->zoom_end_x2 - anim->zoom_end_x1;
int start_width = anim->zoom_start_x2 - anim->zoom_start_x1;
int end_height = anim->zoom_end_y2 - anim->zoom_end_y1;
int start_height = anim->zoom_start_y2 - anim->zoom_start_y1;
float max_zoom_x = (float)start_width/end_width;
float max_zoom_y = (float)start_height/end_height;
float trans_y = ((float)anim->zoom_end_y1);
CLTR_MARK();
glPushMatrix();
CLTR_DBG("f is %f ( %i/%i ) max_zoom x: %f y: %f, zooming to %f, %f",
f, anim->step, anim->n_steps, max_zoom_x, max_zoom_y,
(f * max_zoom_x), (f * max_zoom_y));
#if 0
glTranslatef (0.0 /* - (float)(anim->zoom_start_x1) * ( (max_zoom_x * f) )*/,
- trans_y * f * max_zoom_y,
0.0);
if ((f * max_zoom_x) > 1.0 && (f * max_zoom_y) > 1.0)
{
glScalef ((f * max_zoom_x), (f * max_zoom_y), 0.0);
}
#endif
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
/* glOrtho (0, widget->width, widget->height, 0, -1, 1); */
/* 800 -> 80, 800-80 = 720/n_steps = x , cur = 80 + x * (n_steps - steps) */
x2 = anim->zoom_end_x2 + ( ( ((float)anim->zoom_start_x2 - anim->zoom_end_x2)/ (float)anim->n_steps) * (anim->n_steps - anim->step) );
x1 = anim->zoom_end_x1 + ( ( ((float)anim->zoom_start_x1 - anim->zoom_end_x1)/ (float)anim->n_steps) * (anim->n_steps - anim->step) );
y1 = anim->zoom_end_y1 + ( ( ((float)anim->zoom_start_y1 - anim->zoom_end_y1)/ (float)anim->n_steps) * (anim->n_steps - anim->step) );
y2 = anim->zoom_end_y2 + ( ( ((float)anim->zoom_start_y2 - anim->zoom_end_y2)/ (float)anim->n_steps) * (anim->n_steps - anim->step) );
/*
glOrtho( anim->zoom_end_x1, x2-1,
anim->zoom_end_y2-1, anim->zoom_end_y1,
-1, 1);
*/
glOrtho( x1, x2-1, y2-1, y1,
-1, 1);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
anim->wrapped_paint_func(widget);
glPopMatrix();
/* reset here */
}
/* Hack, we need somehow to reset the viewport
* XXX Hook this into anim->widget hide()
* XXX Call this every time for every render ?
*/
void
cltr_animator_reset(CltrAnimator *anim)
{
ClutterMainContext *ctx = CLTR_CONTEXT();
clrt_window_set_gl_viewport(ctx->window);
}
static gboolean
cltr_animator_timeout_cb(gpointer data)
{
CltrAnimator *anim = (CltrAnimator *)data;
CLTR_MARK();
anim->step++;
if (anim->step > anim->n_steps)
{
if (anim->anim_finish_cb)
anim->anim_finish_cb(anim, anim->anim_finish_data);
anim->widget->paint = anim->wrapped_paint_func;
return FALSE;
}
cltr_widget_queue_paint(anim->widget);
return TRUE;
}
void
cltr_animator_run(CltrAnimator *anim,
CltrAnimatorFinishFunc finish_callback,
gpointer *finish_data)
{
anim->anim_finish_cb = finish_callback;
anim->anim_finish_data = finish_data;
anim->widget->paint = cltr_animator_wrapped_paint;
anim->step = 0;
g_timeout_add(FPS_TO_TIMEOUT(anim->fps),
cltr_animator_timeout_cb, anim);
}