From 22acd39f0fdbc857f54756a694f7eee503571055 Mon Sep 17 00:00:00 2001 From: Matthew Allum Date: Thu, 24 Mar 2005 16:46:49 +0000 Subject: [PATCH] refactoring --- ChangeLog | 9 + Makefile | 4 +- cltr-photo-grid.c | 543 ++++++++++++++++++++++++++++++++++++++++++++++ cltr-photo-grid.h | 91 ++++++++ cltr.c | 510 +------------------------------------------ cltr.h | 62 +----- 6 files changed, 656 insertions(+), 563 deletions(-) create mode 100644 cltr-photo-grid.c create mode 100644 cltr-photo-grid.h diff --git a/ChangeLog b/ChangeLog index 18442b2d5..fe54fc6da 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2005-03-24 mallum,,, + + * 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,,, * cltr.c: (cltr_photo_grid_populate), (cltr_photo_grid_redraw), diff --git a/Makefile b/Makefile index 8f304990a..01f2a8a80 100644 --- a/Makefile +++ b/Makefile @@ -4,12 +4,12 @@ CFLAGS=`pkg-config --cflags pangoft2 pango glib-2.0` .c.o: $(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) $(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: rm -fr *.o clutter test diff --git a/cltr-photo-grid.c b/cltr-photo-grid.c new file mode 100644 index 000000000..5e3998e42 --- /dev/null +++ b/cltr-photo-grid.c @@ -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; +} diff --git a/cltr-photo-grid.h b/cltr-photo-grid.h new file mode 100644 index 000000000..a2fc892c4 --- /dev/null +++ b/cltr-photo-grid.h @@ -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 diff --git a/cltr.c b/cltr.c index 3a3197347..0b72b1e7d 100644 --- a/cltr.c +++ b/cltr.c @@ -219,6 +219,7 @@ cltr_window_new(int width, int height) glClearColor (0xff, 0xff, 0xff, 0xff); glClearDepth (1.0f); + /* Move to redraw ? glDisable (GL_DEPTH_TEST); glDepthMask (GL_FALSE); glDisable (GL_CULL_FACE); @@ -227,6 +228,7 @@ cltr_window_new(int width, int height) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); + */ glLoadIdentity (); 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 idle_cb(gpointer data) @@ -777,11 +280,18 @@ main(int argc, char **argv) ClutterPhotoGrid *grid = NULL; ClutterWindow *win = NULL; + if (argc < 2) + { + g_printerr("usage: '%s' \n" + , argv[0]); + exit(-1); + } + cltr_init(&argc, &argv); 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 */ diff --git a/cltr.h b/cltr.h index 6a259dd8e..aa89808bb 100644 --- a/cltr.h +++ b/cltr.h @@ -86,66 +86,6 @@ typedef struct } CltrXEventSource; - -/* 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); - +#include "cltr-photo-grid.h" #endif