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); |