nsxiv8919204
Render thumbnails
+76 −24
6 files changed
- M image.c +26 −21
- M image.h +2 −0
- M main.c +33 −0
- M options.c +7 −3
- M window.c +7 −0
- M window.h +1 −0
| @@ -110,6 +110,32 @@ int img_load(img_t *img, const char *filename) { | |||
| 110 | 110 | return 1; | |
| 111 | 111 | } | |
| 112 | 112 | ||
| 113 | + | int img_load_thumb(thumb_t *tn, const char *filename) { | |
| 114 | + | int w, h; | |
| 115 | + | float z, zw, zh; | |
| 116 | + | ||
| 117 | + | if (!tn) | |
| 118 | + | return 0; | |
| 119 | + | ||
| 120 | + | if (!_imlib_load_image(filename)) | |
| 121 | + | return 0; | |
| 122 | + | ||
| 123 | + | w = imlib_image_get_width(); | |
| 124 | + | h = imlib_image_get_height(); | |
| 125 | + | zw = (float) THUMB_SIZE / (float) w; | |
| 126 | + | zh = (float) THUMB_SIZE / (float) h; | |
| 127 | + | z = MIN(zw, zh); | |
| 128 | + | tn->w = z * w; | |
| 129 | + | tn->h = z * h; | |
| 130 | + | ||
| 131 | + | imlib_context_set_drawable(tn->pm); | |
| 132 | + | imlib_render_image_part_on_drawable_at_size(0, 0, w, h, | |
| 133 | + | 0, 0, tn->w, tn->h); | |
| 134 | + | imlib_free_image(); | |
| 135 | + | ||
| 136 | + | return 1; | |
| 137 | + | } | |
| 138 | + | ||
| 113 | 139 | void img_check_pan(img_t *img, win_t *win) { | |
| 114 | 140 | if (!img || !win) | |
| 115 | 141 | return; | |
| @@ -149,27 +175,6 @@ int img_fit(img_t *img, win_t *win) { | |||
| 149 | 175 | return oz != img->zoom; | |
| 150 | 176 | } | |
| 151 | 177 | ||
| 152 | − | int img_load_thumb(thumb_t *tn, const char *filename) { | |
| 153 | − | int w; | |
| 154 | − | int h; | |
| 155 | − | ||
| 156 | − | if (!tn) | |
| 157 | − | return 0; | |
| 158 | − | ||
| 159 | − | if (!_imlib_load_image(filename)) | |
| 160 | − | return 0; | |
| 161 | − | ||
| 162 | − | w = imlib_image_get_width(); | |
| 163 | − | h = imlib_image_get_height(); | |
| 164 | − | ||
| 165 | − | imlib_context_set_drawable(tn->pm); | |
| 166 | − | imlib_render_image_part_on_drawable_at_size(0, 0, w, h, | |
| 167 | − | 0, 0, THUMB_SIZE, THUMB_SIZE); | |
| 168 | − | imlib_free_image(); | |
| 169 | − | ||
| 170 | − | return 1; | |
| 171 | − | } | |
| 172 | − | ||
| 173 | 178 | void img_render(img_t *img, win_t *win) { | |
| 174 | 179 | int sx, sy, sw, sh; | |
| 175 | 180 | int dx, dy, dw, dh; | |
| @@ -52,6 +52,8 @@ typedef struct img_s { | |||
| 52 | 52 | typedef struct thumb_s { | |
| 53 | 53 | int x; | |
| 54 | 54 | int y; | |
| 55 | + | int w; | |
| 56 | + | int h; | |
| 55 | 57 | Pixmap pm; | |
| 56 | 58 | } thumb_t; | |
| 57 | 59 | ||
| @@ -27,6 +27,7 @@ | |||
| 27 | 27 | #include <X11/Xutil.h> | |
| 28 | 28 | #include <X11/keysym.h> | |
| 29 | 29 | ||
| 30 | + | #include "config.h" | |
| 30 | 31 | #include "image.h" | |
| 31 | 32 | #include "options.h" | |
| 32 | 33 | #include "util.h" | |
| @@ -38,6 +39,7 @@ typedef enum appmode_e { | |||
| 38 | 39 | } appmode_t; | |
| 39 | 40 | ||
| 40 | 41 | void update_title(); | |
| 42 | + | void render_thumbs(); | |
| 41 | 43 | int check_append(const char*); | |
| 42 | 44 | void read_dir_rec(const char*); | |
| 43 | 45 | void run(); | |
| @@ -53,6 +55,7 @@ int filecnt, fileidx; | |||
| 53 | 55 | size_t filesize; | |
| 54 | 56 | ||
| 55 | 57 | thumb_t *thumbs; | |
| 58 | + | int tvis, tcols, trows; | |
| 56 | 59 | ||
| 57 | 60 | #define TITLE_LEN 256 | |
| 58 | 61 | char win_title[TITLE_LEN]; | |
| @@ -137,6 +140,7 @@ int main(int argc, char **argv) { | |||
| 137 | 140 | ||
| 138 | 141 | if (options->thumbnails == 2) { | |
| 139 | 142 | mode = MODE_THUMBS; | |
| 143 | + | render_thumbs(); | |
| 140 | 144 | } else { | |
| 141 | 145 | mode = MODE_NORMAL; | |
| 142 | 146 | load_image(); | |
| @@ -175,6 +179,35 @@ void update_title() { | |||
| 175 | 179 | win_set_title(&win, win_title); | |
| 176 | 180 | } | |
| 177 | 181 | ||
| 182 | + | void render_thumbs() { | |
| 183 | + | int i, cnt, x, y; | |
| 184 | + | ||
| 185 | + | tcols = win.w / (THUMB_SIZE + 10); | |
| 186 | + | trows = win.h / (THUMB_SIZE + 10); | |
| 187 | + | ||
| 188 | + | x = win.w - tcols * (THUMB_SIZE + 10) + 5; | |
| 189 | + | y = win.h - trows * (THUMB_SIZE + 10) + 5; | |
| 190 | + | cnt = MIN(tcols * trows, filecnt); | |
| 191 | + | ||
| 192 | + | win_clear(&win); | |
| 193 | + | ||
| 194 | + | i = 0; | |
| 195 | + | while (i < cnt) { | |
| 196 | + | thumbs[i].x = x + (THUMB_SIZE - thumbs[i].w) / 2; | |
| 197 | + | thumbs[i].y = y + (THUMB_SIZE - thumbs[i].h) / 2; | |
| 198 | + | win_draw_pixmap(&win, thumbs[i].pm, thumbs[i].x, thumbs[i].y, thumbs[i].w, | |
| 199 | + | thumbs[i].h); | |
| 200 | + | if (++i % tcols == 0) { | |
| 201 | + | x = win.w - tcols * (THUMB_SIZE + 10) + 5; | |
| 202 | + | y += THUMB_SIZE + 10; | |
| 203 | + | } else { | |
| 204 | + | x += THUMB_SIZE + 10; | |
| 205 | + | } | |
| 206 | + | } | |
| 207 | + | ||
| 208 | + | win_draw(&win); | |
| 209 | + | } | |
| 210 | + | ||
| 178 | 211 | int check_append(const char *filename) { | |
| 179 | 212 | if (!filename) | |
| 180 | 213 | return 0; | |
| @@ -25,12 +25,13 @@ | |||
| 25 | 25 | ||
| 26 | 26 | #include "config.h" | |
| 27 | 27 | #include "options.h" | |
| 28 | + | #include "util.h" | |
| 28 | 29 | ||
| 29 | 30 | options_t _options; | |
| 30 | 31 | const options_t *options = (const options_t*) &_options; | |
| 31 | 32 | ||
| 32 | 33 | void print_usage() { | |
| 33 | − | printf("usage: sxiv [-dFfhpqrstvZ] [-g GEOMETRY] [-z ZOOM] FILES...\n"); | |
| 34 | + | printf("usage: sxiv [-dFfhpqrsTtvZ] [-g GEOMETRY] [-z ZOOM] FILES...\n"); | |
| 34 | 35 | } | |
| 35 | 36 | ||
| 36 | 37 | void print_version() { | |
| @@ -54,7 +55,7 @@ void parse_options(int argc, char **argv) { | |||
| 54 | 55 | _options.quiet = 0; | |
| 55 | 56 | _options.recursive = 0; | |
| 56 | 57 | ||
| 57 | − | while ((opt = getopt(argc, argv, "dFfg:hpqrstvZz:")) != -1) { | |
| 58 | + | while ((opt = getopt(argc, argv, "dFfg:hpqrsTtvZz:")) != -1) { | |
| 58 | 59 | switch (opt) { | |
| 59 | 60 | case '?': | |
| 60 | 61 | print_usage(); | |
| @@ -86,8 +87,11 @@ void parse_options(int argc, char **argv) { | |||
| 86 | 87 | case 's': | |
| 87 | 88 | _options.scalemode = SCALE_FIT; | |
| 88 | 89 | break; | |
| 90 | + | case 'T': | |
| 91 | + | _options.thumbnails = 2; | |
| 92 | + | break; | |
| 89 | 93 | case 't': | |
| 90 | − | _options.thumbnails = 1; | |
| 94 | + | _options.thumbnails = MAX(_options.thumbnails, 1); | |
| 91 | 95 | break; | |
| 92 | 96 | case 'v': | |
| 93 | 97 | print_version(); | |
| @@ -219,6 +219,13 @@ Pixmap win_create_pixmap(win_t *win) { | |||
| 219 | 219 | win->env.depth); | |
| 220 | 220 | } | |
| 221 | 221 | ||
| 222 | + | void win_draw_pixmap(win_t *win, Pixmap pm, int x, int y, int w, int h) { | |
| 223 | + | if (!win) | |
| 224 | + | return; | |
| 225 | + | ||
| 226 | + | XCopyArea(win->env.dpy, pm, win->pm, bgc, 0, 0, w, h, x, y); | |
| 227 | + | } | |
| 228 | + | ||
| 222 | 229 | void win_clear(win_t *win) { | |
| 223 | 230 | win_env_t *e; | |
| 224 | 231 | XGCValues gcval; | |
| @@ -64,6 +64,7 @@ int win_moveresize(win_t*, int, int, unsigned int, unsigned int); | |||
| 64 | 64 | void win_toggle_fullscreen(win_t*); | |
| 65 | 65 | ||
| 66 | 66 | Pixmap win_create_pixmap(win_t*); | |
| 67 | + | void win_draw_pixmap(win_t*, Pixmap, int, int, int, int); | |
| 67 | 68 | ||
| 68 | 69 | void win_clear(win_t*); | |
| 69 | 70 | void win_draw(win_t*); | |