| @@ -25,14 +25,16 @@ |
| 25 | 25 | | #include "thumbs.h" |
| 26 | 26 | | #include "util.h" |
| 27 | 27 | | |
| 28 | + | extern int fileidx; |
| 28 | 29 | | extern Imlib_Image *im_broken; |
| 30 | + | |
| 29 | 31 | | const int thumb_dim = THUMB_SIZE + 10; |
| 30 | 32 | | |
| 31 | 33 | | void tns_init(tns_t *tns, int cnt) { |
| 32 | 34 | | if (!tns) |
| 33 | 35 | | return; |
| 34 | 36 | | |
| 35 | | − | tns->cnt = tns->first = tns->sel = 0; |
| 37 | + | tns->cnt = tns->first = 0; |
| 36 | 38 | | tns->thumbs = (thumb_t*) s_malloc(cnt * sizeof(thumb_t)); |
| 37 | 39 | | memset(tns->thumbs, 0, cnt * sizeof(thumb_t)); |
| 38 | 40 | | tns->dirty = 0; |
| @@ -82,37 +84,64 @@ void tns_load(tns_t *tns, win_t *win, const char *filename) { |
| 82 | 84 | | imlib_render_image_part_on_drawable_at_size(0, 0, w, h, |
| 83 | 85 | | 0, 0, t->w, t->h); |
| 84 | 86 | | imlib_free_image(); |
| 85 | | − | |
| 86 | 87 | | tns->dirty = 1; |
| 87 | 88 | | } |
| 88 | 89 | | |
| 90 | + | void tns_check_view(tns_t *tns, Bool scrolled) { |
| 91 | + | if (!tns) |
| 92 | + | return; |
| 93 | + | |
| 94 | + | tns->first -= tns->first % tns->cols; |
| 95 | + | |
| 96 | + | if (scrolled) { |
| 97 | + | /* move selection into visible area */ |
| 98 | + | } else { |
| 99 | + | /* scroll to selection */ |
| 100 | + | if (tns->first + tns->cols * tns->rows <= fileidx) { |
| 101 | + | tns->first = fileidx - fileidx % tns->cols - |
| 102 | + | tns->cols * (tns->rows - 1); |
| 103 | + | tns->dirty = 1; |
| 104 | + | } else if (tns->first > fileidx) { |
| 105 | + | tns->first = fileidx - fileidx % tns->cols; |
| 106 | + | tns->dirty = 1; |
| 107 | + | } |
| 108 | + | } |
| 109 | + | } |
| 110 | + | |
| 89 | 111 | | void tns_render(tns_t *tns, win_t *win) { |
| 90 | | − | int i, cnt, x, y; |
| 112 | + | int i, cnt, r, x, y; |
| 113 | + | thumb_t *t; |
| 91 | 114 | | |
| 92 | 115 | | if (!tns || !tns->dirty || !win) |
| 93 | 116 | | return; |
| 94 | 117 | | |
| 118 | + | win_clear(win); |
| 119 | + | |
| 95 | 120 | | tns->cols = MAX(1, win->w / thumb_dim); |
| 96 | 121 | | tns->rows = MAX(1, win->h / thumb_dim); |
| 97 | 122 | | |
| 98 | | − | cnt = tns->cols * tns->rows; |
| 99 | | − | if (tns->first && tns->first + cnt > tns->cnt) |
| 100 | | − | tns->first = MAX(0, tns->cnt - cnt); |
| 101 | | − | cnt = MIN(tns->first + cnt, tns->cnt); |
| 102 | | − | |
| 103 | | − | win_clear(win); |
| 123 | + | if (tns->cnt < tns->cols * tns->rows) { |
| 124 | + | tns->first = 0; |
| 125 | + | cnt = tns->cnt; |
| 126 | + | } else { |
| 127 | + | tns_check_view(tns, False); |
| 128 | + | cnt = tns->cols * tns->rows; |
| 129 | + | if ((r = tns->first + cnt - tns->cnt) >= tns->cols) |
| 130 | + | tns->first -= r - r % tns->cols; |
| 131 | + | if (r > 0) |
| 132 | + | cnt -= r % tns->cols; |
| 133 | + | } |
| 104 | 134 | | |
| 105 | | − | i = cnt % tns->cols ? 1 : 0; |
| 135 | + | r = cnt % tns->cols ? 1 : 0; |
| 106 | 136 | | tns->x = x = (win->w - MIN(cnt, tns->cols) * thumb_dim) / 2 + 5; |
| 107 | | − | tns->y = y = (win->h - (cnt / tns->cols + i) * thumb_dim) / 2 + 5; |
| 108 | | − | i = tns->first; |
| 109 | | − | |
| 110 | | − | while (i < cnt) { |
| 111 | | − | tns->thumbs[i].x = x + (THUMB_SIZE - tns->thumbs[i].w) / 2; |
| 112 | | − | tns->thumbs[i].y = y + (THUMB_SIZE - tns->thumbs[i].h) / 2; |
| 113 | | − | win_draw_pixmap(win, tns->thumbs[i].pm, tns->thumbs[i].x, |
| 114 | | − | tns->thumbs[i].y, tns->thumbs[i].w, tns->thumbs[i].h); |
| 115 | | − | if (++i % tns->cols == 0) { |
| 137 | + | tns->y = y = (win->h - (cnt / tns->cols + r) * thumb_dim) / 2 + 5; |
| 138 | + | |
| 139 | + | for (i = 0; i < cnt; ++i) { |
| 140 | + | t = &tns->thumbs[tns->first + i]; |
| 141 | + | t->x = x + (THUMB_SIZE - t->w) / 2; |
| 142 | + | t->y = y + (THUMB_SIZE - t->h) / 2; |
| 143 | + | win_draw_pixmap(win, t->pm, t->x, t->y, t->w, t->h); |
| 144 | + | if ((i + 1) % tns->cols == 0) { |
| 116 | 145 | | x = tns->x; |
| 117 | 146 | | y += thumb_dim; |
| 118 | 147 | | } else { |
| @@ -121,61 +150,58 @@ void tns_render(tns_t *tns, win_t *win) { |
| 121 | 150 | | } |
| 122 | 151 | | |
| 123 | 152 | | tns->dirty = 0; |
| 124 | | − | |
| 125 | | − | tns_highlight(tns, win, -1); |
| 153 | + | tns_highlight(tns, win, fileidx, True); |
| 126 | 154 | | } |
| 127 | 155 | | |
| 128 | | − | void tns_highlight(tns_t *tns, win_t *win, int old) { |
| 156 | + | void tns_highlight(tns_t *tns, win_t *win, int n, Bool hl) { |
| 129 | 157 | | thumb_t *t; |
| 130 | 158 | | |
| 131 | 159 | | if (!tns || !win) |
| 132 | 160 | | return; |
| 133 | 161 | | |
| 134 | | − | if (old >= 0 && old < tns->cnt) { |
| 135 | | − | t = &tns->thumbs[old]; |
| 136 | | − | win_draw_rect(win, t->x - 2, t->y - 2, t->w + 4, t->h + 4, False); |
| 137 | | − | } |
| 138 | | − | if (tns->sel < tns->cnt) { |
| 139 | | − | t = &tns->thumbs[tns->sel]; |
| 140 | | − | win_draw_rect(win, t->x - 2, t->y - 2, t->w + 4, t->h + 4, True); |
| 162 | + | if (n >= 0 && n < tns->cnt) { |
| 163 | + | t = &tns->thumbs[n]; |
| 164 | + | win_draw_rect(win, t->x - 2, t->y - 2, t->w + 4, t->h + 4, hl); |
| 141 | 165 | | } |
| 142 | 166 | | |
| 143 | 167 | | win_draw(win); |
| 144 | 168 | | } |
| 145 | 169 | | |
| 146 | 170 | | int tns_move_selection(tns_t *tns, win_t *win, movedir_t dir) { |
| 147 | | − | int sel, old; |
| 171 | + | int old; |
| 148 | 172 | | |
| 149 | 173 | | if (!tns || !win) |
| 150 | 174 | | return 0; |
| 151 | 175 | | |
| 152 | | − | sel = old = tns->sel; |
| 176 | + | old = fileidx; |
| 153 | 177 | | |
| 154 | 178 | | switch (dir) { |
| 155 | 179 | | case MOVE_LEFT: |
| 156 | | − | if (sel % tns->cols > 0) |
| 157 | | − | --sel; |
| 180 | + | if (fileidx > 0) |
| 181 | + | --fileidx; |
| 158 | 182 | | break; |
| 159 | 183 | | case MOVE_RIGHT: |
| 160 | | − | if (sel % tns->cols < tns->cols - 1 && sel < tns->cnt - 1) |
| 161 | | − | ++sel; |
| 184 | + | if (fileidx < tns->cnt - 1) |
| 185 | + | ++fileidx; |
| 162 | 186 | | break; |
| 163 | 187 | | case MOVE_UP: |
| 164 | | − | if (sel / tns->cols > 0) |
| 165 | | − | sel -= tns->cols; |
| 188 | + | if (fileidx >= tns->cols) |
| 189 | + | fileidx -= tns->cols; |
| 166 | 190 | | break; |
| 167 | 191 | | case MOVE_DOWN: |
| 168 | | − | if (sel / tns->cols < tns->rows - 1 && sel + tns->cols < tns->cnt) |
| 169 | | − | sel += tns->cols; |
| 192 | + | if (fileidx + tns->cols < tns->cnt) |
| 193 | + | fileidx += tns->cols; |
| 170 | 194 | | break; |
| 171 | 195 | | } |
| 172 | 196 | | |
| 173 | | − | if (sel != old && tns->thumbs[sel].x != 0) { |
| 174 | | − | tns->sel = sel; |
| 175 | | − | tns_highlight(tns, win, old); |
| 197 | + | if (fileidx != old) { |
| 198 | + | tns_highlight(tns, win, old, False); |
| 199 | + | tns_check_view(tns, False); |
| 200 | + | if (!tns->dirty) |
| 201 | + | tns_highlight(tns, win, fileidx, True); |
| 176 | 202 | | } |
| 177 | 203 | | |
| 178 | | − | return sel != old; |
| 204 | + | return fileidx != old; |
| 179 | 205 | | } |
| 180 | 206 | | |
| 181 | 207 | | int tns_translate(tns_t *tns, int x, int y) { |
| @@ -185,7 +211,8 @@ int tns_translate(tns_t *tns, int x, int y) { |
| 185 | 211 | | if (!tns || x < tns->x || y < tns->y) |
| 186 | 212 | | return -1; |
| 187 | 213 | | |
| 188 | | − | n = (y - tns->y) / thumb_dim * tns->cols + (x - tns->x) / thumb_dim; |
| 214 | + | n = tns->first + (y - tns->y) / thumb_dim * tns->cols + |
| 215 | + | (x - tns->x) / thumb_dim; |
| 189 | 216 | | |
| 190 | 217 | | if (n < tns->cnt) { |
| 191 | 218 | | t = &tns->thumbs[n]; |