mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 11:32:04 +00:00
refactoring
This commit is contained in:
parent
1ec99cb5e1
commit
22acd39f0f
@ -1,3 +1,12 @@
|
|||||||
|
2005-03-24 mallum,,, <mallum@openedhand.com>
|
||||||
|
|
||||||
|
* Makefile:
|
||||||
|
* cltr-photo-grid.c:
|
||||||
|
* cltr-photo-grid.h:
|
||||||
|
* cltr.c: (cltr_window_new), (cltr_main_loop):
|
||||||
|
* cltr.h:
|
||||||
|
Split up cltr.c a bit. start refactoring a bit.
|
||||||
|
|
||||||
2005-03-23 mallum,,, <mallum@openedhand.com>
|
2005-03-23 mallum,,, <mallum@openedhand.com>
|
||||||
|
|
||||||
* cltr.c: (cltr_photo_grid_populate), (cltr_photo_grid_redraw),
|
* cltr.c: (cltr_photo_grid_populate), (cltr_photo_grid_redraw),
|
||||||
|
4
Makefile
4
Makefile
@ -4,12 +4,12 @@ CFLAGS=`pkg-config --cflags pangoft2 pango glib-2.0`
|
|||||||
.c.o:
|
.c.o:
|
||||||
$(CC) -g -Wall $(CFLAGS) $(INCS) -c $*.c
|
$(CC) -g -Wall $(CFLAGS) $(INCS) -c $*.c
|
||||||
|
|
||||||
OBJS=cltr.o pixbuf.o util.o fonts.o
|
OBJS=cltr.o pixbuf.o util.o fonts.o cltr-photo-grid.o
|
||||||
|
|
||||||
clutter: $(OBJS)
|
clutter: $(OBJS)
|
||||||
$(CC) -g -Wall -o $@ $(OBJS) $(LIBS)
|
$(CC) -g -Wall -o $@ $(OBJS) $(LIBS)
|
||||||
|
|
||||||
$(OBJS): pixbuf.h util.h fonts.h cltr.h
|
$(OBJS): pixbuf.h util.h fonts.h cltr.h cltr-photo-grid.h
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -fr *.o clutter test
|
rm -fr *.o clutter test
|
||||||
|
543
cltr-photo-grid.c
Normal file
543
cltr-photo-grid.c
Normal file
@ -0,0 +1,543 @@
|
|||||||
|
#include "cltr-photo-grid.h"
|
||||||
|
|
||||||
|
ClutterPhotoGridCell*
|
||||||
|
cltr_photo_grid_cell_new(ClutterPhotoGrid *grid,
|
||||||
|
Pixbuf *pixb,
|
||||||
|
const gchar *filename)
|
||||||
|
{
|
||||||
|
ClutterPhotoGridCell *cell = NULL;
|
||||||
|
int maxw = grid->width, maxh = grid->height;
|
||||||
|
int neww = 0, newh = 0;
|
||||||
|
|
||||||
|
cell = g_malloc0(sizeof(ClutterPhotoGridCell));
|
||||||
|
|
||||||
|
if (pixb->width > pixb->height) /* landscape */
|
||||||
|
{
|
||||||
|
if (pixb->width > maxw)
|
||||||
|
{
|
||||||
|
neww = maxw;
|
||||||
|
newh = (neww * pixb->height) / pixb->width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* portrait */
|
||||||
|
{
|
||||||
|
if (pixb->height > maxh)
|
||||||
|
{
|
||||||
|
newh = maxh;
|
||||||
|
neww = (newh * pixb->width) / pixb->height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (neww || newh)
|
||||||
|
{
|
||||||
|
cell->pixb = pixbuf_scale_down(pixb, neww, newh);
|
||||||
|
pixbuf_unref(pixb);
|
||||||
|
}
|
||||||
|
else cell->pixb = pixb;
|
||||||
|
|
||||||
|
CLTR_DBG ("loaded %s at %ix%i", filename, neww, newh);
|
||||||
|
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cltr_photo_grid_append_cell(ClutterPhotoGrid *grid,
|
||||||
|
ClutterPhotoGridCell *cell)
|
||||||
|
{
|
||||||
|
grid->cells_tail = g_list_append(grid->cells_tail, cell);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ctrl_photo_grid_cell_to_coords(ClutterPhotoGrid *grid,
|
||||||
|
GList *cell,
|
||||||
|
int *x,
|
||||||
|
int *y)
|
||||||
|
{
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
idx = g_list_position(grid->cells_tail, cell);
|
||||||
|
|
||||||
|
*y = idx / grid->n_cols;
|
||||||
|
*x = idx % grid->n_cols;
|
||||||
|
|
||||||
|
CLTR_DBG("idx: %i x: %i, y: %i", idx, *x , *y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ctrl_photo_grid_get_zoomed_coords(ClutterPhotoGrid *grid,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
float zoom,
|
||||||
|
float *tx,
|
||||||
|
float *ty)
|
||||||
|
{
|
||||||
|
int max_x = grid->n_cols-1;
|
||||||
|
|
||||||
|
/* XXX figure out what magic 2.0 value comes from */
|
||||||
|
|
||||||
|
/*
|
||||||
|
*tx = (float)( (max_x-x) - 1.0 ) * 2.0;
|
||||||
|
*ty = (float)( y - 1.0 ) * 2.0;
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
3x3 0,0 -> 2,-2
|
||||||
|
|
||||||
|
5x5 0,0 ->
|
||||||
|
*tx = 4.0;
|
||||||
|
*ty = -4.0;
|
||||||
|
|
||||||
|
4x4 0,0 -> 3.0, -3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
float trange = ((float)(grid->n_cols - 1.0) * 2.0);
|
||||||
|
float xrange = (float)grid->n_cols - 1.0;
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
*tx = ((max_x-x) * (trange/xrange)) - (trange/2);
|
||||||
|
*ty = (y * (trange/xrange)) - (trange/2);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* assumes rows = cols */
|
||||||
|
|
||||||
|
*tx = ((max_x-x) * 2.0) - (grid->n_cols - 1.0);
|
||||||
|
*ty = (y * 2.0) - (grid->n_cols - 1.0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
*tx = ((max_x-x) * (grid->zoom_max/2.0)) - (grid->n_cols - 1.0);
|
||||||
|
*ty = (y * (grid->zoom_max/2.0)) - (grid->n_cols - 1.0);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cltr_photo_grid_navigate(ClutterPhotoGrid *grid,
|
||||||
|
CltrDirection direction)
|
||||||
|
{
|
||||||
|
GList *cell_orig = grid->cell_active;
|
||||||
|
|
||||||
|
switch (direction)
|
||||||
|
{
|
||||||
|
case CLTR_SOUTH:
|
||||||
|
if (g_list_nth(grid->cell_active, grid->n_cols))
|
||||||
|
grid->cell_active = g_list_nth(grid->cell_active, grid->n_cols);
|
||||||
|
break;
|
||||||
|
case CLTR_NORTH:
|
||||||
|
if (g_list_nth_prev(grid->cell_active, grid->n_cols))
|
||||||
|
grid->cell_active = g_list_nth_prev(grid->cell_active, grid->n_cols);
|
||||||
|
break;
|
||||||
|
case CLTR_EAST:
|
||||||
|
if (g_list_next(grid->cell_active))
|
||||||
|
grid->cell_active = g_list_next(grid->cell_active);
|
||||||
|
break;
|
||||||
|
case CLTR_WEST:
|
||||||
|
if (g_list_previous(grid->cell_active))
|
||||||
|
grid->cell_active = g_list_previous(grid->cell_active);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cell_orig != grid->cell_active) /* we've moved */
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
float zoom = grid->zoom_min;
|
||||||
|
|
||||||
|
if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOMED)
|
||||||
|
{
|
||||||
|
grid->state = CLTR_PHOTO_GRID_STATE_ZOOMED_MOVE;
|
||||||
|
grid->view_min_x = grid->view_max_x;
|
||||||
|
grid->view_min_y = grid->view_max_y ;
|
||||||
|
grid->anim_step = 0;
|
||||||
|
zoom = grid->zoom_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctrl_photo_grid_cell_to_coords(grid, grid->cell_active, &x, &y);
|
||||||
|
|
||||||
|
ctrl_photo_grid_get_zoomed_coords(grid, x, y, zoom,
|
||||||
|
&grid->view_max_x,
|
||||||
|
&grid->view_max_y);
|
||||||
|
|
||||||
|
CLTR_DBG("x: %f, y: %f", grid->view_max_x , grid->view_max_y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void /* bleh badly named */
|
||||||
|
cltr_photo_grid_activate_cell(ClutterPhotoGrid *grid)
|
||||||
|
{
|
||||||
|
if (grid->state == CLTR_PHOTO_GRID_STATE_BROWSE)
|
||||||
|
{
|
||||||
|
grid->state = CLTR_PHOTO_GRID_STATE_ZOOM_IN;
|
||||||
|
}
|
||||||
|
else if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOMED)
|
||||||
|
{
|
||||||
|
grid->state = CLTR_PHOTO_GRID_STATE_ZOOM_OUT;
|
||||||
|
/* reset - zoomed moving will have reset */
|
||||||
|
grid->view_min_x = 0.0;
|
||||||
|
grid->view_min_y = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* que a draw ? */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
cltr_photo_grid_populate(ClutterPhotoGrid *grid,
|
||||||
|
const gchar *imgs_path)
|
||||||
|
{
|
||||||
|
GDir *dir;
|
||||||
|
GError *error;
|
||||||
|
const gchar *entry = NULL;
|
||||||
|
gchar *fullpath = NULL;
|
||||||
|
int n_pixb = 0, i =0;
|
||||||
|
GList *cell_item;
|
||||||
|
ClutterFont *font = NULL;
|
||||||
|
|
||||||
|
font = font_new("Sans Bold 96");
|
||||||
|
|
||||||
|
if ((dir = g_dir_open (imgs_path, 0, &error)) == NULL)
|
||||||
|
{
|
||||||
|
/* handle this much better */
|
||||||
|
fprintf(stderr, "failed to open '%s'\n", imgs_path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while((entry = g_dir_read_name (dir)) != NULL)
|
||||||
|
{
|
||||||
|
Pixbuf *pixb = NULL;
|
||||||
|
fullpath = g_strconcat(imgs_path, "/", entry, NULL);
|
||||||
|
|
||||||
|
pixb = pixbuf_new_from_file(fullpath);
|
||||||
|
|
||||||
|
if (pixb)
|
||||||
|
{
|
||||||
|
ClutterPhotoGridCell *cell;
|
||||||
|
gchar buf[24];
|
||||||
|
|
||||||
|
cell = cltr_photo_grid_cell_new(grid, pixb, entry);
|
||||||
|
|
||||||
|
g_snprintf(&buf[0], 24, "%i", n_pixb);
|
||||||
|
font_draw(font, cell->pixb, buf, 10, 10);
|
||||||
|
|
||||||
|
cltr_photo_grid_append_cell(grid, cell);
|
||||||
|
|
||||||
|
n_pixb++;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(fullpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_dir_close (dir);
|
||||||
|
|
||||||
|
grid->cell_active = g_list_first(grid->cells_tail);
|
||||||
|
|
||||||
|
/* Set up textures */
|
||||||
|
|
||||||
|
grid->texs = util_malloc0(sizeof(GLuint)*n_pixb);
|
||||||
|
glGenTextures(n_pixb, grid->texs);
|
||||||
|
|
||||||
|
cell_item = g_list_first(grid->cells_tail);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ClutterPhotoGridCell *cell = (ClutterPhotoGridCell *)cell_item->data;
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, grid->texs[i]);
|
||||||
|
|
||||||
|
CLTR_DBG("loading texture %i", i);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||||
|
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
|
||||||
|
grid->tex_w,
|
||||||
|
grid->tex_h,
|
||||||
|
0, GL_RGBA,
|
||||||
|
GL_UNSIGNED_INT_8_8_8_8,
|
||||||
|
grid->tex_data);
|
||||||
|
|
||||||
|
CLTR_GLERR();
|
||||||
|
|
||||||
|
glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0,
|
||||||
|
(GLsizei)cell->pixb->width,
|
||||||
|
(GLsizei)cell->pixb->height,
|
||||||
|
GL_RGBA, GL_UNSIGNED_INT_8_8_8_8,
|
||||||
|
cell->pixb->data);
|
||||||
|
|
||||||
|
CLTR_GLERR();
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
while ( (cell_item = g_list_next(cell_item)) != NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cltr_photo_grid_redraw(ClutterPhotoGrid *grid)
|
||||||
|
{
|
||||||
|
int x = 0, y = 0, rows = grid->n_rows, cols = 0, i =0;
|
||||||
|
GList *cell_item;
|
||||||
|
float zoom, trans_x, trans_y;
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
glClearColor( 0.6, 0.6, 0.62, 1.0);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
glDisable(GL_LIGHTING);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
/* Assume zoomed out */
|
||||||
|
zoom = grid->zoom_min;
|
||||||
|
trans_x = grid->view_min_x;
|
||||||
|
trans_y = grid->view_min_y;
|
||||||
|
|
||||||
|
if (grid->state != CLTR_PHOTO_GRID_STATE_BROWSE)
|
||||||
|
{
|
||||||
|
/* Assume zoomed in */
|
||||||
|
zoom = grid->zoom_max;
|
||||||
|
trans_x = grid->view_max_x;
|
||||||
|
trans_y = grid->view_max_y;
|
||||||
|
|
||||||
|
if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOM_IN)
|
||||||
|
{
|
||||||
|
grid->anim_step++;
|
||||||
|
|
||||||
|
/* Are we zoomed all the way in > */
|
||||||
|
if (grid->anim_step >= grid->anim_n_steps)
|
||||||
|
{
|
||||||
|
grid->state = CLTR_PHOTO_GRID_STATE_ZOOMED;
|
||||||
|
grid->anim_step = 0;
|
||||||
|
/* zoom = grid->zoom_max; set above */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float f = (float)grid->anim_step/grid->anim_n_steps;
|
||||||
|
|
||||||
|
zoom = grid->zoom_min + ((grid->zoom_max - grid->zoom_min) * f);
|
||||||
|
trans_x = (grid->view_max_x - grid->view_min_x) * f;
|
||||||
|
trans_y = (grid->view_max_y - grid->view_min_y) * f;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOM_OUT)
|
||||||
|
{
|
||||||
|
grid->anim_step++;
|
||||||
|
|
||||||
|
if (grid->anim_step >= grid->anim_n_steps)
|
||||||
|
{
|
||||||
|
zoom = grid->zoom_min;
|
||||||
|
grid->anim_step = 0;
|
||||||
|
grid->state = CLTR_PHOTO_GRID_STATE_BROWSE;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float f = (float)(grid->anim_n_steps - grid->anim_step )
|
||||||
|
/ grid->anim_n_steps;
|
||||||
|
|
||||||
|
zoom = grid->zoom_min + (grid->zoom_max - grid->zoom_min) * f;
|
||||||
|
trans_x = (grid->view_max_x - grid->view_min_x) * f;
|
||||||
|
trans_y = (grid->view_max_y - grid->view_min_y) * f;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
zoom = grid->zoom_min
|
||||||
|
+ (( (grid->zoom_max - grid->zoom_min) / grid->anim_n_steps )
|
||||||
|
* (grid->anim_n_steps - grid->anim_step) );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOMED_MOVE)
|
||||||
|
{
|
||||||
|
grid->anim_step++;
|
||||||
|
|
||||||
|
if (grid->anim_step >= grid->anim_n_steps)
|
||||||
|
{
|
||||||
|
grid->state = CLTR_PHOTO_GRID_STATE_ZOOMED;
|
||||||
|
grid->anim_step = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float f = (float)grid->anim_step/grid->anim_n_steps;
|
||||||
|
|
||||||
|
trans_x = grid->view_min_x + ((grid->view_max_x - grid->view_min_x) * f);
|
||||||
|
trans_y = grid->view_min_y + ((grid->view_max_y - grid->view_min_y) * f);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
glTranslatef( trans_x, trans_y, 0.0);
|
||||||
|
glScalef( zoom, zoom, 0.0);
|
||||||
|
|
||||||
|
cell_item = g_list_first(grid->cells_tail);
|
||||||
|
|
||||||
|
while (rows--)
|
||||||
|
{
|
||||||
|
cols = grid->n_cols;
|
||||||
|
x = 0;
|
||||||
|
while (cols--)
|
||||||
|
{
|
||||||
|
ClutterPhotoGridCell *cell = (ClutterPhotoGridCell *)cell_item->data;
|
||||||
|
Pixbuf *pixb = NULL;
|
||||||
|
float tx, ty;
|
||||||
|
int x1, x2, y1, y2, thumb_w, thumb_h;
|
||||||
|
int ns_border, ew_border;
|
||||||
|
|
||||||
|
pixb = cell->pixb;
|
||||||
|
|
||||||
|
thumb_w = (pixb->width / grid->n_cols);
|
||||||
|
thumb_h = (pixb->height / grid->n_rows);
|
||||||
|
|
||||||
|
ew_border = thumb_w/8;
|
||||||
|
ns_border = thumb_h/8;
|
||||||
|
|
||||||
|
thumb_w -= (2 * ew_border);
|
||||||
|
thumb_h -= (2 * ns_border);
|
||||||
|
|
||||||
|
x1 = x + ew_border;
|
||||||
|
y1 = y + ns_border;
|
||||||
|
|
||||||
|
x2 = x1 + thumb_w;
|
||||||
|
y2 = y1 + thumb_h;
|
||||||
|
|
||||||
|
tx = (float) pixb->width / grid->tex_w;
|
||||||
|
ty = (float) pixb->height / grid->tex_h;
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
glRotatef ( 45.0, x1+(thumb_w/2) - 320, 0.0 /*y2+(thumb_h/2) - 240*/, 0.0);
|
||||||
|
#endif
|
||||||
|
/* Border - why need tex disabled ? */
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
if (cell_item == grid->cell_active
|
||||||
|
&& grid->state == CLTR_PHOTO_GRID_STATE_BROWSE)
|
||||||
|
glColor4f(1.0, 1.0, 1.0, 1.0);
|
||||||
|
else
|
||||||
|
glColor4f(0.8, 0.8, 0.8, 1.0);
|
||||||
|
glRecti(x1-2, y1-2, x2+2, y2+2);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, grid->texs[i]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (cell == grid->cell_active
|
||||||
|
&& grid->state == CLTR_PHOTO_GRID_STATE_BROWSE)
|
||||||
|
{
|
||||||
|
glBegin (GL_QUADS);
|
||||||
|
glTexCoord2f (tx, ty); glVertex2i (x2+5, y2+5);
|
||||||
|
glTexCoord2f (0, ty); glVertex2i (x1-5, y2+5);
|
||||||
|
glTexCoord2f (0, 0); glVertex2i (x1-5, y1-5);
|
||||||
|
glTexCoord2f (tx, 0); glVertex2i (x2+5, y1-5);
|
||||||
|
glEnd ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
glBegin (GL_QUADS);
|
||||||
|
glTexCoord2f (tx, ty); glVertex2i (x2, y2);
|
||||||
|
glTexCoord2f (0, ty); glVertex2i (x1, y2);
|
||||||
|
glTexCoord2f (0, 0); glVertex2i (x1, y1);
|
||||||
|
glTexCoord2f (tx, 0); glVertex2i (x2, y1);
|
||||||
|
glEnd ();
|
||||||
|
}
|
||||||
|
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
cell_item = g_list_next(cell_item);
|
||||||
|
|
||||||
|
if (!cell_item)
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
x += grid->cell_width;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
y += grid->cell_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
finish:
|
||||||
|
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
/*
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
glBlendFunc(GL_ONE, GL_SRC_ALPHA);
|
||||||
|
glColor4f(1.0, 1.0, 1.0, xxx);
|
||||||
|
glRecti(0, 0, 640, 480);
|
||||||
|
|
||||||
|
xxx += 0.01;
|
||||||
|
*/
|
||||||
|
|
||||||
|
glXSwapBuffers(CltrCntx.xdpy, grid->parent->xwin);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ClutterPhotoGrid*
|
||||||
|
cltr_photo_grid_new(ClutterWindow *win,
|
||||||
|
int n_cols,
|
||||||
|
int n_rows,
|
||||||
|
const gchar *imgs_path)
|
||||||
|
{
|
||||||
|
ClutterPhotoGrid *grid = NULL;
|
||||||
|
int x,y;
|
||||||
|
|
||||||
|
grid = util_malloc0(sizeof(ClutterPhotoGrid));
|
||||||
|
|
||||||
|
grid->width = win->width;
|
||||||
|
grid->height = win->height;
|
||||||
|
grid->n_cols = n_cols;
|
||||||
|
grid->n_rows = n_rows;
|
||||||
|
grid->parent = win;
|
||||||
|
|
||||||
|
grid->cell_width = grid->width / n_cols;
|
||||||
|
grid->cell_height = grid->height / n_rows;
|
||||||
|
|
||||||
|
grid->state = CLTR_PHOTO_GRID_STATE_BROWSE;
|
||||||
|
|
||||||
|
grid->anim_n_steps = 50; /* value needs to be calced dep on rows */
|
||||||
|
grid->anim_step = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
grid->zoom_step = 0.05;
|
||||||
|
grid->zoom = 1.0;
|
||||||
|
*/
|
||||||
|
grid->zoom_min = 0.8;
|
||||||
|
grid->view_min_x = 0.0;
|
||||||
|
grid->view_min_y = 0.0;
|
||||||
|
|
||||||
|
|
||||||
|
/* Assmes cols == rows */
|
||||||
|
grid->zoom_max = /* 1.0 + */ (float) (n_rows * 1.0);
|
||||||
|
|
||||||
|
/* Below needs to go else where - some kind of texture manager/helper */
|
||||||
|
|
||||||
|
grid->tex_w = 1024;
|
||||||
|
grid->tex_h = 512;
|
||||||
|
|
||||||
|
grid->tex_data = malloc (grid->tex_w * grid->tex_h * 4);
|
||||||
|
|
||||||
|
/* Load */
|
||||||
|
cltr_photo_grid_populate(grid, imgs_path);
|
||||||
|
|
||||||
|
grid->cell_active = g_list_first(grid->cells_tail);
|
||||||
|
|
||||||
|
ctrl_photo_grid_cell_to_coords(grid, grid->cell_active, &x, &y);
|
||||||
|
|
||||||
|
ctrl_photo_grid_get_zoomed_coords(grid, grid->zoom_min,
|
||||||
|
x, y,
|
||||||
|
&grid->view_max_x,
|
||||||
|
&grid->view_max_y);
|
||||||
|
cltr_photo_grid_redraw(grid);
|
||||||
|
|
||||||
|
return grid;
|
||||||
|
}
|
91
cltr-photo-grid.h
Normal file
91
cltr-photo-grid.h
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#ifndef _HAVE_CLTR_PHOTO_GRID_H
|
||||||
|
#define _HAVE_CLTR_PHOTO_GRID_H
|
||||||
|
|
||||||
|
#include "cltr.h"
|
||||||
|
|
||||||
|
typedef struct ClutterPhotoGrid ClutterPhotoGrid;
|
||||||
|
|
||||||
|
typedef struct ClutterPhotoGridCell ClutterPhotoGridCell;
|
||||||
|
|
||||||
|
typedef enum ClutterPhotoGridState
|
||||||
|
{
|
||||||
|
CLTR_PHOTO_GRID_STATE_BROWSE ,
|
||||||
|
CLTR_PHOTO_GRID_STATE_ZOOM_IN ,
|
||||||
|
CLTR_PHOTO_GRID_STATE_ZOOMED ,
|
||||||
|
CLTR_PHOTO_GRID_STATE_ZOOM_OUT ,
|
||||||
|
CLTR_PHOTO_GRID_STATE_ZOOMED_MOVE ,
|
||||||
|
}
|
||||||
|
ClutterPhotoGridState;
|
||||||
|
|
||||||
|
struct ClutterPhotoGridCell
|
||||||
|
{
|
||||||
|
Pixbuf *pixb;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ClutterPhotoGrid
|
||||||
|
{
|
||||||
|
/* XXX should be base widget stuff */
|
||||||
|
int x,y;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
ClutterWindow *parent;
|
||||||
|
|
||||||
|
/* ****** */
|
||||||
|
|
||||||
|
int n_rows;
|
||||||
|
int n_cols;
|
||||||
|
|
||||||
|
int cell_width;
|
||||||
|
int cell_height;
|
||||||
|
|
||||||
|
GList *cells_tail;
|
||||||
|
GList *cell_active;
|
||||||
|
|
||||||
|
/* animation stuff */
|
||||||
|
|
||||||
|
int anim_n_steps, anim_step;
|
||||||
|
|
||||||
|
float zoom_min, zoom_max, zoom_step;
|
||||||
|
|
||||||
|
/* below needs better naming */
|
||||||
|
float view_min_x, view_max_x, view_min_y, view_max_y;
|
||||||
|
|
||||||
|
int tex_w;
|
||||||
|
int tex_h;
|
||||||
|
int *tex_data;
|
||||||
|
GLuint *texs;
|
||||||
|
|
||||||
|
ClutterPhotoGridState state;
|
||||||
|
};
|
||||||
|
|
||||||
|
ClutterPhotoGridCell*
|
||||||
|
cltr_photo_grid_cell_new(ClutterPhotoGrid *grid,
|
||||||
|
Pixbuf *pixb,
|
||||||
|
const gchar *filename);
|
||||||
|
|
||||||
|
void
|
||||||
|
cltr_photo_grid_append_cell(ClutterPhotoGrid *grid,
|
||||||
|
ClutterPhotoGridCell *cell);
|
||||||
|
|
||||||
|
void
|
||||||
|
cltr_photo_grid_navigate(ClutterPhotoGrid *grid,
|
||||||
|
CltrDirection direction) ;
|
||||||
|
|
||||||
|
void /* bleh badly named */
|
||||||
|
cltr_photo_grid_activate_cell(ClutterPhotoGrid *grid);
|
||||||
|
|
||||||
|
void
|
||||||
|
cltr_photo_grid_populate(ClutterPhotoGrid *grid,
|
||||||
|
const gchar *imgs_path) ;
|
||||||
|
|
||||||
|
void
|
||||||
|
cltr_photo_grid_redraw(ClutterPhotoGrid *grid);
|
||||||
|
|
||||||
|
ClutterPhotoGrid*
|
||||||
|
cltr_photo_grid_new(ClutterWindow *win,
|
||||||
|
int n_cols,
|
||||||
|
int n_rows,
|
||||||
|
const gchar *imgs_path);
|
||||||
|
|
||||||
|
#endif
|
510
cltr.c
510
cltr.c
@ -219,6 +219,7 @@ cltr_window_new(int width, int height)
|
|||||||
glClearColor (0xff, 0xff, 0xff, 0xff);
|
glClearColor (0xff, 0xff, 0xff, 0xff);
|
||||||
glClearDepth (1.0f);
|
glClearDepth (1.0f);
|
||||||
|
|
||||||
|
/* Move to redraw ?
|
||||||
glDisable (GL_DEPTH_TEST);
|
glDisable (GL_DEPTH_TEST);
|
||||||
glDepthMask (GL_FALSE);
|
glDepthMask (GL_FALSE);
|
||||||
glDisable (GL_CULL_FACE);
|
glDisable (GL_CULL_FACE);
|
||||||
@ -227,6 +228,7 @@ cltr_window_new(int width, int height)
|
|||||||
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
*/
|
||||||
|
|
||||||
glLoadIdentity ();
|
glLoadIdentity ();
|
||||||
glOrtho (0, width, height, 0, -1, 1);
|
glOrtho (0, width, height, 0, -1, 1);
|
||||||
@ -257,505 +259,6 @@ cltr_main_loop()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
cltr_photo_grid_append_cell(ClutterPhotoGrid *grid,
|
|
||||||
Pixbuf *pixb,
|
|
||||||
const gchar *filename)
|
|
||||||
{
|
|
||||||
int neww = 0, newh = 0;
|
|
||||||
|
|
||||||
int maxw = grid->width, maxh = grid->height;
|
|
||||||
|
|
||||||
Pixbuf *pixb_scaled = NULL;
|
|
||||||
|
|
||||||
if (pixb->width > pixb->height) /* landscape */
|
|
||||||
{
|
|
||||||
if (pixb->width > maxw)
|
|
||||||
{
|
|
||||||
neww = maxw;
|
|
||||||
newh = (neww * pixb->height) / pixb->width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else /* portrait */
|
|
||||||
{
|
|
||||||
if (pixb->height > maxh)
|
|
||||||
{
|
|
||||||
newh = maxh;
|
|
||||||
neww = (newh * pixb->width) / pixb->height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (neww || newh)
|
|
||||||
{
|
|
||||||
pixb_scaled = pixbuf_scale_down(pixb, neww, newh);
|
|
||||||
pixbuf_unref(pixb);
|
|
||||||
}
|
|
||||||
else pixb_scaled = pixb;
|
|
||||||
|
|
||||||
grid->cells_tail = g_list_append(grid->cells_tail, pixb_scaled);
|
|
||||||
|
|
||||||
CLTR_DBG ("loaded %s at %ix%i", filename, neww, newh);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
ctrl_photo_grid_cell_to_coords(ClutterPhotoGrid *grid,
|
|
||||||
GList *cell,
|
|
||||||
int *x,
|
|
||||||
int *y)
|
|
||||||
{
|
|
||||||
int idx;
|
|
||||||
|
|
||||||
idx = g_list_position(grid->cells_tail, cell);
|
|
||||||
|
|
||||||
*y = idx / grid->n_cols;
|
|
||||||
*x = idx % grid->n_cols;
|
|
||||||
|
|
||||||
CLTR_DBG("idx: %i x: %i, y: %i", idx, *x , *y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
ctrl_photo_grid_get_trans_coords(ClutterPhotoGrid *grid,
|
|
||||||
int x,
|
|
||||||
int y,
|
|
||||||
float *tx,
|
|
||||||
float *ty)
|
|
||||||
{
|
|
||||||
int max_x = grid->n_cols-1;
|
|
||||||
|
|
||||||
/* XXX figure out what magic 2.0 value comes from */
|
|
||||||
|
|
||||||
/*
|
|
||||||
*tx = (float)( (max_x-x) - 1.0 ) * 2.0;
|
|
||||||
*ty = (float)( y - 1.0 ) * 2.0;
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
3x3 0,0 -> 2,-2
|
|
||||||
|
|
||||||
5x5 0,0 ->
|
|
||||||
*tx = 4.0;
|
|
||||||
*ty = -4.0;
|
|
||||||
|
|
||||||
4x4 0,0 -> 3.0, -3.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
float trange = ((float)(grid->n_cols - 1.0) * 2.0);
|
|
||||||
float xrange = (float)grid->n_cols - 1.0;
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
*tx = ((max_x-x) * (trange/xrange)) - (trange/2);
|
|
||||||
*ty = (y * (trange/xrange)) - (trange/2);
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* assumes rows = cols */
|
|
||||||
|
|
||||||
*tx = ((max_x-x) * 2.0) - (grid->n_cols - 1.0);
|
|
||||||
*ty = (y * 2.0) - (grid->n_cols - 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
cltr_photo_grid_navigate(ClutterPhotoGrid *grid,
|
|
||||||
CltrDirection direction)
|
|
||||||
{
|
|
||||||
GList *cell_orig = grid->cell_active;
|
|
||||||
|
|
||||||
switch (direction)
|
|
||||||
{
|
|
||||||
case CLTR_SOUTH:
|
|
||||||
if (g_list_nth(grid->cell_active, grid->n_cols))
|
|
||||||
grid->cell_active = g_list_nth(grid->cell_active, grid->n_cols);
|
|
||||||
break;
|
|
||||||
case CLTR_NORTH:
|
|
||||||
if (g_list_nth_prev(grid->cell_active, grid->n_cols))
|
|
||||||
grid->cell_active = g_list_nth_prev(grid->cell_active, grid->n_cols);
|
|
||||||
break;
|
|
||||||
case CLTR_EAST:
|
|
||||||
if (g_list_next(grid->cell_active))
|
|
||||||
grid->cell_active = g_list_next(grid->cell_active);
|
|
||||||
break;
|
|
||||||
case CLTR_WEST:
|
|
||||||
if (g_list_previous(grid->cell_active))
|
|
||||||
grid->cell_active = g_list_previous(grid->cell_active);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cell_orig != grid->cell_active) /* we've moved */
|
|
||||||
{
|
|
||||||
int x, y;
|
|
||||||
|
|
||||||
if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOMED)
|
|
||||||
{
|
|
||||||
grid->state = CLTR_PHOTO_GRID_STATE_ZOOMED_MOVE;
|
|
||||||
grid->view_min_x = grid->view_max_x;
|
|
||||||
grid->view_min_y = grid->view_max_y ;
|
|
||||||
grid->anim_step = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctrl_photo_grid_cell_to_coords(grid, grid->cell_active, &x, &y);
|
|
||||||
|
|
||||||
ctrl_photo_grid_get_trans_coords(grid, x, y,
|
|
||||||
&grid->view_max_x,
|
|
||||||
&grid->view_max_y);
|
|
||||||
|
|
||||||
CLTR_DBG("x: %f, y: %f", grid->view_max_x , grid->view_max_y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void /* bleh badly named */
|
|
||||||
cltr_photo_grid_activate_cell(ClutterPhotoGrid *grid)
|
|
||||||
{
|
|
||||||
if (grid->state == CLTR_PHOTO_GRID_STATE_BROWSE)
|
|
||||||
{
|
|
||||||
grid->state = CLTR_PHOTO_GRID_STATE_ZOOM_IN;
|
|
||||||
}
|
|
||||||
else if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOMED)
|
|
||||||
{
|
|
||||||
grid->state = CLTR_PHOTO_GRID_STATE_ZOOM_OUT;
|
|
||||||
/* reset - zoomed moving will have reset */
|
|
||||||
grid->view_min_x = 0.0;
|
|
||||||
grid->view_min_y = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* que a draw ? */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
cltr_photo_grid_populate(ClutterPhotoGrid *grid,
|
|
||||||
const char *imgs_path)
|
|
||||||
{
|
|
||||||
GDir *dir;
|
|
||||||
GError *error;
|
|
||||||
const gchar *entry = NULL;
|
|
||||||
gchar *fullpath = NULL;
|
|
||||||
int n_pixb = 0, i =0;
|
|
||||||
GList *cell;
|
|
||||||
ClutterFont *font = NULL;
|
|
||||||
|
|
||||||
font = font_new("Sans Bold 96");
|
|
||||||
|
|
||||||
if ((dir = g_dir_open (imgs_path, 0, &error)) == NULL)
|
|
||||||
{
|
|
||||||
/* handle this much better */
|
|
||||||
fprintf(stderr, "failed to open '%s'\n", imgs_path);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while((entry = g_dir_read_name (dir)) != NULL)
|
|
||||||
{
|
|
||||||
Pixbuf *pixb = NULL;
|
|
||||||
fullpath = g_strconcat(imgs_path, "/", entry, NULL);
|
|
||||||
|
|
||||||
pixb = pixbuf_new_from_file(fullpath);
|
|
||||||
|
|
||||||
if (pixb)
|
|
||||||
{
|
|
||||||
gchar buf[24];
|
|
||||||
|
|
||||||
g_snprintf(&buf[0], 24, "%i", n_pixb);
|
|
||||||
font_draw(font, pixb, buf, 10, 10);
|
|
||||||
|
|
||||||
cltr_photo_grid_append_cell(grid, pixb, entry);
|
|
||||||
|
|
||||||
n_pixb++;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free(fullpath);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_dir_close (dir);
|
|
||||||
|
|
||||||
grid->cell_active = g_list_first(grid->cells_tail);
|
|
||||||
|
|
||||||
/* Set up textures */
|
|
||||||
|
|
||||||
grid->texs = util_malloc0(sizeof(GLuint)*n_pixb);
|
|
||||||
glGenTextures(n_pixb, grid->texs);
|
|
||||||
|
|
||||||
cell = g_list_first(grid->cells_tail);
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
Pixbuf *tpixb = (Pixbuf *)cell->data;
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, grid->texs[i]);
|
|
||||||
|
|
||||||
CLTR_DBG("loading texture %i", i);
|
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
|
|
||||||
grid->tex_w,
|
|
||||||
grid->tex_h,
|
|
||||||
0, GL_RGBA,
|
|
||||||
GL_UNSIGNED_INT_8_8_8_8,
|
|
||||||
grid->tex_data);
|
|
||||||
|
|
||||||
CLTR_GLERR();
|
|
||||||
|
|
||||||
glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0,
|
|
||||||
(GLsizei)tpixb->width,
|
|
||||||
(GLsizei)tpixb->height,
|
|
||||||
GL_RGBA, GL_UNSIGNED_INT_8_8_8_8,
|
|
||||||
tpixb->data);
|
|
||||||
|
|
||||||
CLTR_GLERR();
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
while ( (cell = g_list_next(cell)) != NULL );
|
|
||||||
|
|
||||||
glEnable (GL_TEXTURE_2D);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
cltr_photo_grid_redraw(ClutterPhotoGrid *grid)
|
|
||||||
{
|
|
||||||
int x = 0, y = 0, rows = grid->n_rows, cols = 0, i =0;
|
|
||||||
GList *cell;
|
|
||||||
float zoom, trans_x, trans_y;
|
|
||||||
|
|
||||||
glLoadIdentity (); /* XXX pushmatrix */
|
|
||||||
|
|
||||||
glClearColor( 0.6, 0.6, 0.62, 1.0);
|
|
||||||
glClear (GL_COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
glTranslatef( 0.0, 0.0, 0.1);
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Assume zoomed out */
|
|
||||||
zoom = grid->zoom_min;
|
|
||||||
trans_x = grid->view_min_x;
|
|
||||||
trans_y = grid->view_min_y;
|
|
||||||
|
|
||||||
if (grid->state != CLTR_PHOTO_GRID_STATE_BROWSE)
|
|
||||||
{
|
|
||||||
/* Assume zoomed in */
|
|
||||||
zoom = grid->zoom_max;
|
|
||||||
trans_x = grid->view_max_x;
|
|
||||||
trans_y = grid->view_max_y;
|
|
||||||
|
|
||||||
if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOM_IN)
|
|
||||||
{
|
|
||||||
grid->anim_step++;
|
|
||||||
|
|
||||||
/* Are we zoomed all the way in > */
|
|
||||||
if (grid->anim_step >= grid->anim_n_steps)
|
|
||||||
{
|
|
||||||
grid->state = CLTR_PHOTO_GRID_STATE_ZOOMED;
|
|
||||||
grid->anim_step = 0;
|
|
||||||
/* zoom = grid->zoom_max; set above */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float f = (float)grid->anim_step/grid->anim_n_steps;
|
|
||||||
|
|
||||||
zoom = grid->zoom_min + ((grid->zoom_max - grid->zoom_min) * f);
|
|
||||||
trans_x = (grid->view_max_x - grid->view_min_x) * f;
|
|
||||||
trans_y = (grid->view_max_y - grid->view_min_y) * f;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOM_OUT)
|
|
||||||
{
|
|
||||||
grid->anim_step++;
|
|
||||||
|
|
||||||
if (grid->anim_step >= grid->anim_n_steps)
|
|
||||||
{
|
|
||||||
zoom = grid->zoom_min;
|
|
||||||
grid->anim_step = 0;
|
|
||||||
grid->state = CLTR_PHOTO_GRID_STATE_BROWSE;
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float f = (float)(grid->anim_n_steps - grid->anim_step )
|
|
||||||
/ grid->anim_n_steps;
|
|
||||||
|
|
||||||
zoom = grid->zoom_min + (grid->zoom_max - grid->zoom_min) * f;
|
|
||||||
trans_x = (grid->view_max_x - grid->view_min_x) * f;
|
|
||||||
trans_y = (grid->view_max_y - grid->view_min_y) * f;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
zoom = grid->zoom_min
|
|
||||||
+ (( (grid->zoom_max - grid->zoom_min) / grid->anim_n_steps )
|
|
||||||
* (grid->anim_n_steps - grid->anim_step) );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOMED_MOVE)
|
|
||||||
{
|
|
||||||
grid->anim_step++;
|
|
||||||
|
|
||||||
if (grid->anim_step >= grid->anim_n_steps)
|
|
||||||
{
|
|
||||||
grid->state = CLTR_PHOTO_GRID_STATE_ZOOMED;
|
|
||||||
grid->anim_step = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float f = (float)grid->anim_step/grid->anim_n_steps;
|
|
||||||
|
|
||||||
trans_x = grid->view_min_x + ((grid->view_max_x - grid->view_min_x) * f);
|
|
||||||
trans_y = grid->view_min_y + ((grid->view_max_y - grid->view_min_y) * f);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
glTranslatef( trans_x, trans_y, 0.0);
|
|
||||||
|
|
||||||
glScalef( zoom, zoom, zoom);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
cell = g_list_first(grid->cells_tail);
|
|
||||||
|
|
||||||
while (rows--)
|
|
||||||
{
|
|
||||||
cols = grid->n_cols;
|
|
||||||
x = 0;
|
|
||||||
while (cols--)
|
|
||||||
{
|
|
||||||
Pixbuf *pixb = NULL;
|
|
||||||
float tx, ty;
|
|
||||||
int x1, x2, y1, y2, thumb_w, thumb_h;
|
|
||||||
int ns_border, ew_border;
|
|
||||||
|
|
||||||
pixb = (Pixbuf *)cell->data;
|
|
||||||
|
|
||||||
thumb_w = (pixb->width / grid->n_cols);
|
|
||||||
thumb_h = (pixb->height / grid->n_rows);
|
|
||||||
|
|
||||||
ew_border = thumb_w/8;
|
|
||||||
ns_border = thumb_h/8;
|
|
||||||
|
|
||||||
thumb_w -= (2 * ew_border);
|
|
||||||
thumb_h -= (2 * ns_border);
|
|
||||||
|
|
||||||
x1 = x + ew_border;
|
|
||||||
y1 = y + ns_border;
|
|
||||||
|
|
||||||
x2 = x1 + thumb_w;
|
|
||||||
y2 = y1 + thumb_h;
|
|
||||||
|
|
||||||
tx = (float) pixb->width / grid->tex_w;
|
|
||||||
ty = (float) pixb->height / grid->tex_h;
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, grid->texs[i]);
|
|
||||||
|
|
||||||
glBegin (GL_QUADS);
|
|
||||||
glTexCoord2f (tx, ty); glVertex2i (x2, y2);
|
|
||||||
glTexCoord2f (0, ty); glVertex2i (x1, y2);
|
|
||||||
glTexCoord2f (0, 0); glVertex2i (x1, y1);
|
|
||||||
glTexCoord2f (tx, 0); glVertex2i (x2, y1);
|
|
||||||
glEnd ();
|
|
||||||
|
|
||||||
if (cell == grid->cell_active
|
|
||||||
&& grid->state == CLTR_PHOTO_GRID_STATE_BROWSE)
|
|
||||||
{
|
|
||||||
glBegin (GL_QUADS);
|
|
||||||
glTexCoord2f (tx, ty); glVertex2i (x2+5, y2+5);
|
|
||||||
glTexCoord2f (0, ty); glVertex2i (x1-5, y2+5);
|
|
||||||
glTexCoord2f (0, 0); glVertex2i (x1-5, y1-5);
|
|
||||||
glTexCoord2f (tx, 0); glVertex2i (x2+5, y1-5);
|
|
||||||
glEnd ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glBegin (GL_QUADS);
|
|
||||||
glTexCoord2f (tx, ty); glVertex2i (x2, y2);
|
|
||||||
glTexCoord2f (0, ty); glVertex2i (x1, y2);
|
|
||||||
glTexCoord2f (0, 0); glVertex2i (x1, y1);
|
|
||||||
glTexCoord2f (tx, 0); glVertex2i (x2, y1);
|
|
||||||
glEnd ();
|
|
||||||
}
|
|
||||||
|
|
||||||
cell = g_list_next(cell);
|
|
||||||
|
|
||||||
if (!cell)
|
|
||||||
goto finish;
|
|
||||||
|
|
||||||
x += grid->cell_width;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
y += grid->cell_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
finish:
|
|
||||||
glXSwapBuffers(CltrCntx.xdpy, grid->parent->xwin);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ClutterPhotoGrid*
|
|
||||||
cltr_photo_grid_new(ClutterWindow *win,
|
|
||||||
int n_cols,
|
|
||||||
int n_rows,
|
|
||||||
const char *imgs_path)
|
|
||||||
{
|
|
||||||
ClutterPhotoGrid *grid = NULL;
|
|
||||||
int x,y;
|
|
||||||
|
|
||||||
grid = util_malloc0(sizeof(ClutterPhotoGrid));
|
|
||||||
|
|
||||||
grid->width = win->width;
|
|
||||||
grid->height = win->height;
|
|
||||||
grid->n_cols = n_cols;
|
|
||||||
grid->n_rows = n_rows;
|
|
||||||
grid->parent = win;
|
|
||||||
|
|
||||||
grid->cell_width = grid->width / n_cols;
|
|
||||||
grid->cell_height = grid->height / n_rows;
|
|
||||||
|
|
||||||
grid->state = CLTR_PHOTO_GRID_STATE_BROWSE;
|
|
||||||
|
|
||||||
grid->anim_n_steps = 50; /* value needs to be calced dep on rows */
|
|
||||||
grid->anim_step = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
grid->zoom_step = 0.05;
|
|
||||||
grid->zoom = 1.0;
|
|
||||||
*/
|
|
||||||
grid->zoom_min = 1.0;
|
|
||||||
grid->view_min_x = 0.0;
|
|
||||||
grid->view_min_y = 0.0;
|
|
||||||
|
|
||||||
|
|
||||||
/* Assmes cols == rows */
|
|
||||||
grid->zoom_max = /* 1.0 + */ (float) (n_rows * 1.0) ;
|
|
||||||
|
|
||||||
|
|
||||||
/* Below needs to go else where - some kind of texture manager/helper */
|
|
||||||
|
|
||||||
grid->tex_w = 1024;
|
|
||||||
grid->tex_h = 512;
|
|
||||||
|
|
||||||
grid->tex_data = malloc (grid->tex_w * grid->tex_h * 4);
|
|
||||||
|
|
||||||
/* Load */
|
|
||||||
cltr_photo_grid_populate(grid, imgs_path);
|
|
||||||
|
|
||||||
grid->cell_active = g_list_first(grid->cells_tail);
|
|
||||||
|
|
||||||
ctrl_photo_grid_cell_to_coords(grid, grid->cell_active, &x, &y);
|
|
||||||
|
|
||||||
ctrl_photo_grid_get_trans_coords(grid,
|
|
||||||
x, y,
|
|
||||||
&grid->view_max_x,
|
|
||||||
&grid->view_max_y);
|
|
||||||
cltr_photo_grid_redraw(grid);
|
|
||||||
|
|
||||||
return grid;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
idle_cb(gpointer data)
|
idle_cb(gpointer data)
|
||||||
@ -777,11 +280,18 @@ main(int argc, char **argv)
|
|||||||
ClutterPhotoGrid *grid = NULL;
|
ClutterPhotoGrid *grid = NULL;
|
||||||
ClutterWindow *win = NULL;
|
ClutterWindow *win = NULL;
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
g_printerr("usage: '%s' <path to not too heavily populated image dir>\n"
|
||||||
|
, argv[0]);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
cltr_init(&argc, &argv);
|
cltr_init(&argc, &argv);
|
||||||
|
|
||||||
win = cltr_window_new(640, 480);
|
win = cltr_window_new(640, 480);
|
||||||
|
|
||||||
grid = cltr_photo_grid_new(win, 4, 4, argv[1]);
|
grid = cltr_photo_grid_new(win, 3, 3, argv[1]);
|
||||||
|
|
||||||
Grid = grid; /* laaaaaazy globals */
|
Grid = grid; /* laaaaaazy globals */
|
||||||
|
|
||||||
|
62
cltr.h
62
cltr.h
@ -86,66 +86,6 @@ typedef struct
|
|||||||
}
|
}
|
||||||
CltrXEventSource;
|
CltrXEventSource;
|
||||||
|
|
||||||
|
#include "cltr-photo-grid.h"
|
||||||
/* xxxxxxxxxxxxxPHOTO GRIDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx */
|
|
||||||
|
|
||||||
typedef struct ClutterPhotoGrid ClutterPhotoGrid;
|
|
||||||
|
|
||||||
typedef struct ClutterPhotoGridCell ClutterPhotoGridCell;
|
|
||||||
|
|
||||||
typedef enum ClutterPhotoGridState
|
|
||||||
{
|
|
||||||
CLTR_PHOTO_GRID_STATE_BROWSE ,
|
|
||||||
CLTR_PHOTO_GRID_STATE_ZOOM_IN ,
|
|
||||||
CLTR_PHOTO_GRID_STATE_ZOOMED ,
|
|
||||||
CLTR_PHOTO_GRID_STATE_ZOOM_OUT ,
|
|
||||||
CLTR_PHOTO_GRID_STATE_ZOOMED_MOVE ,
|
|
||||||
}
|
|
||||||
ClutterPhotoGridState;
|
|
||||||
|
|
||||||
struct ClutterPhotoGrid
|
|
||||||
{
|
|
||||||
/* XXX should be base widget stuff */
|
|
||||||
int x,y;
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
ClutterWindow *parent;
|
|
||||||
|
|
||||||
/* ****** */
|
|
||||||
|
|
||||||
int n_rows;
|
|
||||||
int n_cols;
|
|
||||||
|
|
||||||
int cell_width;
|
|
||||||
int cell_height;
|
|
||||||
|
|
||||||
GList *cells_tail;
|
|
||||||
GList *cell_active;
|
|
||||||
|
|
||||||
/* animation stuff */
|
|
||||||
|
|
||||||
int anim_n_steps, anim_step;
|
|
||||||
|
|
||||||
float zoom_min, zoom_max, zoom_step;
|
|
||||||
|
|
||||||
/* below needs better naming */
|
|
||||||
float view_min_x, view_max_x, view_min_y, view_max_y;
|
|
||||||
|
|
||||||
int tex_w;
|
|
||||||
int tex_h;
|
|
||||||
int *tex_data;
|
|
||||||
GLuint *texs;
|
|
||||||
|
|
||||||
ClutterPhotoGridState state;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
cltr_photo_grid_navigate(ClutterPhotoGrid *grid,
|
|
||||||
CltrDirection direction) ;
|
|
||||||
|
|
||||||
void /* bleh badly named */
|
|
||||||
cltr_photo_grid_activate_cell(ClutterPhotoGrid *grid);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user