diff options
-rw-r--r-- | image.c | 36 | ||||
-rw-r--r-- | image.h | 10 | ||||
-rw-r--r-- | main.c | 49 |
3 files changed, 74 insertions, 21 deletions
@@ -123,11 +123,13 @@ void img_render(img_t *img, win_t *win) { /* center image in window */ img->x = (win->w - img->w * img->zoom) / 2; img->y = (win->h - img->h * img->zoom) / 2; - } else { - /* typically after zooming and panning */ + } else if (img->cp) { + /* only useful after zooming */ img_check_pan(img, win); + img->cp = 0; } + /* calculate source and destination offsets */ if (img->x < 0) { sx = -img->x / img->zoom; sw = win->w / img->zoom; @@ -172,6 +174,7 @@ int img_zoom(img_t *img, float z) { img->x -= (img->w * z - img->w * img->zoom) / 2; img->y -= (img->h * z - img->h * img->zoom) / 2; img->zoom = z; + img->cp = 1; return 1; } else { return 0; @@ -205,3 +208,32 @@ int img_zoom_out(img_t *img) { return 0; } + +int img_pan(img_t *img, win_t *win, pandir_t dir) { + int ox, oy; + + if (!img || !win) + return 0; + + ox = img->x; + oy = img->y; + + switch (dir) { + case PAN_LEFT: + img->x += win->w / 5; + break; + case PAN_RIGHT: + img->x -= win->w / 5; + break; + case PAN_UP: + img->y += win->h / 5; + break; + case PAN_DOWN: + img->y -= win->h / 5; + break; + } + + img_check_pan(img, win); + + return ox != img->x || oy != img->y; +} @@ -27,9 +27,17 @@ enum scalemode { SCALE_ZOOM }; +typedef enum pandir_e { + PAN_LEFT = 0, + PAN_RIGHT, + PAN_UP, + PAN_DOWN +} pandir_t; + typedef struct img_s { float zoom; unsigned char re; + unsigned char cp; int x; int y; int w; @@ -45,4 +53,6 @@ void img_render(img_t*, win_t*); int img_zoom_in(img_t*); int img_zoom_out(img_t*); +int img_pan(img_t*, win_t*, pandir_t); + #endif /* IMAGE_H */ @@ -108,13 +108,14 @@ void cleanup() { void on_keypress(XEvent *ev) { char key; - int len; KeySym keysym; + int changed; if (!ev) return; - len = XLookupString(&ev->xkey, &key, 1, &keysym, NULL); + XLookupString(&ev->xkey, &key, 1, &keysym, NULL); + changed = 0; switch (keysym) { case XK_Escape: @@ -122,48 +123,58 @@ void on_keypress(XEvent *ev) { exit(2); case XK_space: key = 'n'; - len = 1; break; case XK_BackSpace: key = 'p'; - len = 1; break; } - if (!len) - return; - switch (key) { case 'q': cleanup(); exit(0); + + /* navigate through image list */ case 'n': if (fileidx + 1 < filecnt) { img_load(&img, filenames[++fileidx]); - img_render(&img, &win); - update_title(); + changed = 1; } break; case 'p': if (fileidx > 0) { img_load(&img, filenames[--fileidx]); - img_render(&img, &win); - update_title(); + changed = 1; } break; + + /* zooming */ case '+': case '=': - if (img_zoom_in(&img)) { - img_render(&img, &win); - update_title(); - } + changed = img_zoom_in(&img); break; case '-': - if (img_zoom_out(&img)) { - img_render(&img, &win); - update_title(); - } + changed = img_zoom_out(&img); break; + + /* panning */ + case 'h': + changed = img_pan(&img, &win, PAN_LEFT); + break; + case 'j': + changed = img_pan(&img, &win, PAN_DOWN); + break; + case 'k': + changed = img_pan(&img, &win, PAN_UP); + break; + case 'l': + changed = img_pan(&img, &win, PAN_RIGHT); + break; + } + + if (changed) { + img_render(&img, &win); + update_title(); } } |