nsxivb92ebf6
Implemented panning
+74 −21
3 files changed
| @@ -123,11 +123,13 @@ void img_render(img_t *img, win_t *win) { | |||
| 123 | 123 | /* center image in window */ | |
| 124 | 124 | img->x = (win->w - img->w * img->zoom) / 2; | |
| 125 | 125 | img->y = (win->h - img->h * img->zoom) / 2; | |
| 126 | − | } else { | |
| 127 | − | /* typically after zooming and panning */ | |
| 126 | + | } else if (img->cp) { | |
| 127 | + | /* only useful after zooming */ | |
| 128 | 128 | img_check_pan(img, win); | |
| 129 | + | img->cp = 0; | |
| 129 | 130 | } | |
| 130 | 131 | ||
| 132 | + | /* calculate source and destination offsets */ | |
| 131 | 133 | if (img->x < 0) { | |
| 132 | 134 | sx = -img->x / img->zoom; | |
| 133 | 135 | sw = win->w / img->zoom; | |
| @@ -172,6 +174,7 @@ int img_zoom(img_t *img, float z) { | |||
| 172 | 174 | img->x -= (img->w * z - img->w * img->zoom) / 2; | |
| 173 | 175 | img->y -= (img->h * z - img->h * img->zoom) / 2; | |
| 174 | 176 | img->zoom = z; | |
| 177 | + | img->cp = 1; | |
| 175 | 178 | return 1; | |
| 176 | 179 | } else { | |
| 177 | 180 | return 0; | |
| @@ -205,3 +208,32 @@ int img_zoom_out(img_t *img) { | |||
| 205 | 208 | ||
| 206 | 209 | return 0; | |
| 207 | 210 | } | |
| 211 | + | ||
| 212 | + | int img_pan(img_t *img, win_t *win, pandir_t dir) { | |
| 213 | + | int ox, oy; | |
| 214 | + | ||
| 215 | + | if (!img || !win) | |
| 216 | + | return 0; | |
| 217 | + | ||
| 218 | + | ox = img->x; | |
| 219 | + | oy = img->y; | |
| 220 | + | ||
| 221 | + | switch (dir) { | |
| 222 | + | case PAN_LEFT: | |
| 223 | + | img->x += win->w / 5; | |
| 224 | + | break; | |
| 225 | + | case PAN_RIGHT: | |
| 226 | + | img->x -= win->w / 5; | |
| 227 | + | break; | |
| 228 | + | case PAN_UP: | |
| 229 | + | img->y += win->h / 5; | |
| 230 | + | break; | |
| 231 | + | case PAN_DOWN: | |
| 232 | + | img->y -= win->h / 5; | |
| 233 | + | break; | |
| 234 | + | } | |
| 235 | + | ||
| 236 | + | img_check_pan(img, win); | |
| 237 | + | ||
| 238 | + | return ox != img->x || oy != img->y; | |
| 239 | + | } | |
| @@ -27,9 +27,17 @@ enum scalemode { | |||
| 27 | 27 | SCALE_ZOOM | |
| 28 | 28 | }; | |
| 29 | 29 | ||
| 30 | + | typedef enum pandir_e { | |
| 31 | + | PAN_LEFT = 0, | |
| 32 | + | PAN_RIGHT, | |
| 33 | + | PAN_UP, | |
| 34 | + | PAN_DOWN | |
| 35 | + | } pandir_t; | |
| 36 | + | ||
| 30 | 37 | typedef struct img_s { | |
| 31 | 38 | float zoom; | |
| 32 | 39 | unsigned char re; | |
| 40 | + | unsigned char cp; | |
| 33 | 41 | int x; | |
| 34 | 42 | int y; | |
| 35 | 43 | int w; | |
| @@ -45,4 +53,6 @@ void img_render(img_t*, win_t*); | |||
| 45 | 53 | int img_zoom_in(img_t*); | |
| 46 | 54 | int img_zoom_out(img_t*); | |
| 47 | 55 | ||
| 56 | + | int img_pan(img_t*, win_t*, pandir_t); | |
| 57 | + | ||
| 48 | 58 | #endif /* IMAGE_H */ | |
| @@ -108,13 +108,14 @@ void cleanup() { | |||
| 108 | 108 | ||
| 109 | 109 | void on_keypress(XEvent *ev) { | |
| 110 | 110 | char key; | |
| 111 | − | int len; | |
| 112 | 111 | KeySym keysym; | |
| 112 | + | int changed; | |
| 113 | 113 | ||
| 114 | 114 | if (!ev) | |
| 115 | 115 | return; | |
| 116 | 116 | ||
| 117 | − | len = XLookupString(&ev->xkey, &key, 1, &keysym, NULL); | |
| 117 | + | XLookupString(&ev->xkey, &key, 1, &keysym, NULL); | |
| 118 | + | changed = 0; | |
| 118 | 119 | ||
| 119 | 120 | switch (keysym) { | |
| 120 | 121 | case XK_Escape: | |
| @@ -122,48 +123,58 @@ void on_keypress(XEvent *ev) { | |||
| 122 | 123 | exit(2); | |
| 123 | 124 | case XK_space: | |
| 124 | 125 | key = 'n'; | |
| 125 | − | len = 1; | |
| 126 | 126 | break; | |
| 127 | 127 | case XK_BackSpace: | |
| 128 | 128 | key = 'p'; | |
| 129 | − | len = 1; | |
| 130 | 129 | break; | |
| 131 | 130 | } | |
| 132 | 131 | ||
| 133 | − | if (!len) | |
| 134 | − | return; | |
| 135 | − | ||
| 136 | 132 | switch (key) { | |
| 137 | 133 | case 'q': | |
| 138 | 134 | cleanup(); | |
| 139 | 135 | exit(0); | |
| 136 | + | ||
| 137 | + | /* navigate through image list */ | |
| 140 | 138 | case 'n': | |
| 141 | 139 | if (fileidx + 1 < filecnt) { | |
| 142 | 140 | img_load(&img, filenames[++fileidx]); | |
| 143 | − | img_render(&img, &win); | |
| 144 | − | update_title(); | |
| 141 | + | changed = 1; | |
| 145 | 142 | } | |
| 146 | 143 | break; | |
| 147 | 144 | case 'p': | |
| 148 | 145 | if (fileidx > 0) { | |
| 149 | 146 | img_load(&img, filenames[--fileidx]); | |
| 150 | − | img_render(&img, &win); | |
| 151 | − | update_title(); | |
| 147 | + | changed = 1; | |
| 152 | 148 | } | |
| 153 | 149 | break; | |
| 150 | + | ||
| 151 | + | /* zooming */ | |
| 154 | 152 | case '+': | |
| 155 | 153 | case '=': | |
| 156 | − | if (img_zoom_in(&img)) { | |
| 157 | − | img_render(&img, &win); | |
| 158 | − | update_title(); | |
| 159 | − | } | |
| 154 | + | changed = img_zoom_in(&img); | |
| 160 | 155 | break; | |
| 161 | 156 | case '-': | |
| 162 | − | if (img_zoom_out(&img)) { | |
| 163 | − | img_render(&img, &win); | |
| 164 | − | update_title(); | |
| 165 | − | } | |
| 157 | + | changed = img_zoom_out(&img); | |
| 166 | 158 | break; | |
| 159 | + | ||
| 160 | + | /* panning */ | |
| 161 | + | case 'h': | |
| 162 | + | changed = img_pan(&img, &win, PAN_LEFT); | |
| 163 | + | break; | |
| 164 | + | case 'j': | |
| 165 | + | changed = img_pan(&img, &win, PAN_DOWN); | |
| 166 | + | break; | |
| 167 | + | case 'k': | |
| 168 | + | changed = img_pan(&img, &win, PAN_UP); | |
| 169 | + | break; | |
| 170 | + | case 'l': | |
| 171 | + | changed = img_pan(&img, &win, PAN_RIGHT); | |
| 172 | + | break; | |
| 173 | + | } | |
| 174 | + | ||
| 175 | + | if (changed) { | |
| 176 | + | img_render(&img, &win); | |
| 177 | + | update_title(); | |
| 167 | 178 | } | |
| 168 | 179 | } | |
| 169 | 180 | ||