diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | main.c | 13 | ||||
| -rw-r--r-- | thumbs.c | 115 | ||||
| -rw-r--r-- | thumbs.h | 2 | 
4 files changed, 76 insertions, 56 deletions
@@ -4,7 +4,7 @@ VERSION=git-20110219  CC?=gcc  PREFIX?=/usr/local -CFLAGS+= -Wall -pedantic -DVERSION=\"$(VERSION)\" +CFLAGS+= -Wall -pedantic -DVERSION=\"$(VERSION)\" -g  LDFLAGS+=   LIBS+= -lX11 -lImlib2 @@ -156,8 +156,8 @@ void update_title() {  	if (mode == MODE_THUMBS) {  		n = snprintf(win_title, TITLE_LEN, "sxiv: [%d/%d] %s", -		             tns.cnt ? tns.sel + 1 : 0, tns.cnt, -		             tns.cnt ? filenames[tns.sel] : ""); +		             tns.cnt ? fileidx + 1 : 0, tns.cnt, +		             tns.cnt ? filenames[fileidx] : "");  	} else {  		if (img.valid) {  			size = filesize; @@ -272,7 +272,7 @@ void on_keypress(XKeyEvent *kev) {  	unsigned int w, h;  	char key;  	KeySym ksym; -	int changed, sel; +	int changed;  	if (!kev)  		return; @@ -381,10 +381,6 @@ void on_keypress(XKeyEvent *kev) {  			/* switch to thumnail mode */  			case XK_Return:  				if (options->thumbnails) { -					if (fileidx < tns.cnt) -						tns.sel = fileidx; -					else -						tns.sel = 0;  					mode = MODE_THUMBS;  					changed = tns.dirty = 1;  				} @@ -401,12 +397,9 @@ void on_keypress(XKeyEvent *kev) {  		}  	} else {  		/* thumbnail mode */ -		sel = tns.sel; -  		switch (ksym) {  			/* open selected image */  			case XK_Return: -				fileidx = sel;  				load_image();  				mode = MODE_NORMAL;  				win_set_cursor(&win, CURSOR_ARROW); @@ -25,14 +25,16 @@  #include "thumbs.h"  #include "util.h" +extern int fileidx;  extern Imlib_Image *im_broken; +  const int thumb_dim = THUMB_SIZE + 10;  void tns_init(tns_t *tns, int cnt) {  	if (!tns)  		return; -	tns->cnt = tns->first = tns->sel = 0; +	tns->cnt = tns->first = 0;  	tns->thumbs = (thumb_t*) s_malloc(cnt * sizeof(thumb_t));  	memset(tns->thumbs, 0, cnt * sizeof(thumb_t));  	tns->dirty = 0; @@ -82,37 +84,64 @@ void tns_load(tns_t *tns, win_t *win, const char *filename) {  	imlib_render_image_part_on_drawable_at_size(0, 0, w, h,  	                                            0, 0, t->w, t->h);  	imlib_free_image(); -  	tns->dirty = 1;  } +void tns_check_view(tns_t *tns, Bool scrolled) { +	if (!tns) +		return; + +	tns->first -= tns->first % tns->cols; + +	if (scrolled) { +		/* move selection into visible area */ +	} else { +		/* scroll to selection */ +		if (tns->first + tns->cols * tns->rows <= fileidx) { +			tns->first = fileidx - fileidx % tns->cols - +			             tns->cols * (tns->rows - 1); +			tns->dirty = 1; +		} else if (tns->first > fileidx) { +			tns->first = fileidx - fileidx % tns->cols; +			tns->dirty = 1; +		} +	} +} +  void tns_render(tns_t *tns, win_t *win) { -	int i, cnt, x, y; +	int i, cnt, r, x, y; +	thumb_t *t;  	if (!tns || !tns->dirty || !win)  		return; +	win_clear(win); +  	tns->cols = MAX(1, win->w / thumb_dim);  	tns->rows = MAX(1, win->h / thumb_dim); -	cnt = tns->cols * tns->rows; -	if (tns->first && tns->first + cnt > tns->cnt) -		tns->first = MAX(0, tns->cnt - cnt); -	cnt = MIN(tns->first + cnt, tns->cnt); - -	win_clear(win); +	if (tns->cnt < tns->cols * tns->rows) { +		tns->first = 0; +		cnt = tns->cnt; +	} else { +		tns_check_view(tns, False); +		cnt = tns->cols * tns->rows; +		if ((r = tns->first + cnt - tns->cnt) >= tns->cols) +			tns->first -= r - r % tns->cols; +		if (r > 0) +			cnt -= r % tns->cols; +	} -	i = cnt % tns->cols ? 1 : 0; +	r = cnt % tns->cols ? 1 : 0;  	tns->x = x = (win->w - MIN(cnt, tns->cols) * thumb_dim) / 2 + 5; -	tns->y = y = (win->h - (cnt / tns->cols + i) * thumb_dim) / 2 + 5; -	i = tns->first; - -	while (i < cnt) { -		tns->thumbs[i].x = x + (THUMB_SIZE - tns->thumbs[i].w) / 2; -		tns->thumbs[i].y = y + (THUMB_SIZE - tns->thumbs[i].h) / 2; -		win_draw_pixmap(win, tns->thumbs[i].pm, tns->thumbs[i].x, -		                tns->thumbs[i].y, tns->thumbs[i].w, tns->thumbs[i].h); -		if (++i % tns->cols == 0) { +	tns->y = y = (win->h - (cnt / tns->cols + r) * thumb_dim) / 2 + 5; + +	for (i = 0; i < cnt; ++i) { +		t = &tns->thumbs[tns->first + i]; +		t->x = x + (THUMB_SIZE - t->w) / 2; +		t->y = y + (THUMB_SIZE - t->h) / 2; +		win_draw_pixmap(win, t->pm, t->x, t->y, t->w, t->h); +		if ((i + 1) % tns->cols == 0) {  			x = tns->x;  			y += thumb_dim;  		} else { @@ -121,61 +150,58 @@ void tns_render(tns_t *tns, win_t *win) {  	}  	tns->dirty = 0; - -	tns_highlight(tns, win, -1); +	tns_highlight(tns, win, fileidx, True);  } -void tns_highlight(tns_t *tns, win_t *win, int old) { +void tns_highlight(tns_t *tns, win_t *win, int n, Bool hl) {  	thumb_t *t;  	if (!tns || !win)  		return; -	if (old >= 0 && old < tns->cnt) { -		t = &tns->thumbs[old]; -		win_draw_rect(win, t->x - 2, t->y - 2, t->w + 4, t->h + 4, False); -	} -	if (tns->sel < tns->cnt) { -		t = &tns->thumbs[tns->sel]; -		win_draw_rect(win, t->x - 2, t->y - 2, t->w + 4, t->h + 4, True); +	if (n >= 0 && n < tns->cnt) { +		t = &tns->thumbs[n]; +		win_draw_rect(win, t->x - 2, t->y - 2, t->w + 4, t->h + 4, hl);  	}  	win_draw(win);  }  int tns_move_selection(tns_t *tns, win_t *win, movedir_t dir) { -	int sel, old; +	int old;  	if (!tns || !win)  		return 0; -	sel = old = tns->sel; +	old = fileidx;  	switch (dir) {  		case MOVE_LEFT: -			if (sel % tns->cols > 0) -				--sel; +			if (fileidx > 0) +				--fileidx;  			break;  		case MOVE_RIGHT: -			if (sel % tns->cols < tns->cols - 1 && sel < tns->cnt - 1) -				++sel; +			if (fileidx < tns->cnt - 1) +				++fileidx;  			break;  		case MOVE_UP: -			if (sel / tns->cols > 0) -				sel -= tns->cols; +			if (fileidx >= tns->cols) +				fileidx -= tns->cols;  			break;  		case MOVE_DOWN: -			if (sel / tns->cols < tns->rows - 1 && sel + tns->cols < tns->cnt) -				sel += tns->cols; +			if (fileidx + tns->cols < tns->cnt) +				fileidx += tns->cols;  			break;  	} -	if (sel != old && tns->thumbs[sel].x != 0) { -		tns->sel = sel; -		tns_highlight(tns, win, old); +	if (fileidx != old) { +		tns_highlight(tns, win, old, False); +		tns_check_view(tns, False); +		if (!tns->dirty) +			tns_highlight(tns, win, fileidx, True);  	} -	return sel != old; +	return fileidx != old;  }  int tns_translate(tns_t *tns, int x, int y) { @@ -185,7 +211,8 @@ int tns_translate(tns_t *tns, int x, int y) {  	if (!tns || x < tns->x || y < tns->y)  		return -1; -	n = (y - tns->y) / thumb_dim * tns->cols + (x - tns->x) / thumb_dim; +	n = tns->first + (y - tns->y) / thumb_dim * tns->cols + +	    (x - tns->x) / thumb_dim;  	if (n < tns->cnt) {  		t = &tns->thumbs[n]; @@ -54,7 +54,7 @@ void tns_free(tns_t*, win_t*);  void tns_load(tns_t*, win_t*, const char*);  void tns_render(tns_t*, win_t*); -void tns_highlight(tns_t*, win_t*, int); +void tns_highlight(tns_t*, win_t*, int, Bool);  int tns_move_selection(tns_t*, win_t*, movedir_t);  | 
