@@ -73,7 +73,6 @@ int img_check(const char *filename) { | |||
if ((ret = _imlib_load_image(filename))) | |||
imlib_free_image(); | |||
return ret; | |||
} | |||
@@ -194,12 +193,19 @@ int img_fit(img_t *img, win_t *win) { | |||
return oz != img->zoom; | |||
} | |||
void img_center(img_t *img, win_t *win) { | |||
int img_center(img_t *img, win_t *win) { | |||
int ox, oy; | |||
if (!img || !win) | |||
return; | |||
return 0; | |||
ox = img->x; | |||
oy = img->y; | |||
img->x = (win->w - img->w * img->zoom) / 2; | |||
img->y = (win->h - img->h * img->zoom) / 2; | |||
return ox != img->x || oy != img->y; | |||
} | |||
int img_zoom(img_t *img, float z) { | |||
@@ -231,7 +237,6 @@ int img_zoom_in(img_t *img) { | |||
if (zoom_levels[i] > img->zoom * 100.0) | |||
return img_zoom(img, zoom_levels[i] / 100.0); | |||
} | |||
return 0; | |||
} | |||
@@ -245,7 +250,6 @@ int img_zoom_out(img_t *img) { | |||
if (zoom_levels[i] < img->zoom * 100.0) | |||
return img_zoom(img, zoom_levels[i] / 100.0); | |||
} | |||
return 0; | |||
} | |||
@@ -284,11 +288,11 @@ int img_pan(img_t *img, win_t *win, pandir_t dir) { | |||
return 0; | |||
} | |||
int img_rotate(img_t *img, win_t *win, int d) { | |||
void img_rotate(img_t *img, win_t *win, int d) { | |||
int ox, oy, tmp; | |||
if (!img || !win) | |||
return 0; | |||
return; | |||
ox = d == 1 ? img->x : win->w - img->x - img->w * img->zoom; | |||
oy = d == 3 ? img->y : win->h - img->y - img->h * img->zoom; | |||
@@ -303,24 +307,20 @@ int img_rotate(img_t *img, win_t *win, int d) { | |||
img->h = tmp; | |||
img->checkpan = 1; | |||
return 1; | |||
} | |||
int img_rotate_left(img_t *img, win_t *win) { | |||
return img_rotate(img, win, 3); | |||
void img_rotate_left(img_t *img, win_t *win) { | |||
img_rotate(img, win, 3); | |||
} | |||
int img_rotate_right(img_t *img, win_t *win) { | |||
return img_rotate(img, win, 1); | |||
void img_rotate_right(img_t *img, win_t *win) { | |||
img_rotate(img, win, 1); | |||
} | |||
int img_toggle_antialias(img_t *img) { | |||
void img_toggle_antialias(img_t *img) { | |||
if (!img) | |||
return 0; | |||
return; | |||
img->aa ^= 1; | |||
imlib_context_set_anti_alias(img->aa); | |||
return 1; | |||
} |
@@ -55,7 +55,7 @@ int img_load(img_t*, const char*); | |||
void img_render(img_t*, win_t*); | |||
int img_fit(img_t*, win_t*); | |||
void img_center(img_t*, win_t*); | |||
int img_center(img_t*, win_t*); | |||
int img_zoom_in(img_t*); | |||
int img_zoom_out(img_t*); | |||
@@ -63,9 +63,9 @@ int img_zoom_out(img_t*); | |||
int img_move(img_t*, win_t*, int, int); | |||
int img_pan(img_t*, win_t*, pandir_t); | |||
int img_rotate_left(img_t*, win_t*); | |||
int img_rotate_right(img_t*, win_t*); | |||
void img_rotate_left(img_t*, win_t*); | |||
void img_rotate_right(img_t*, win_t*); | |||
int img_toggle_antialias(img_t*); | |||
void img_toggle_antialias(img_t*); | |||
#endif /* IMAGE_H */ |
@@ -44,6 +44,7 @@ win_t win; | |||
#define FNAME_CNT 4096 | |||
const char **filenames; | |||
int filecnt, fileidx; | |||
size_t filesize; | |||
#define TITLE_LEN 256 | |||
char win_title[TITLE_LEN]; | |||
@@ -57,6 +58,17 @@ void cleanup() { | |||
} | |||
} | |||
int load_image() { | |||
struct stat fstats; | |||
if (stat(filenames[fileidx], &fstats)) | |||
warn("could not stat file: %s", filenames[fileidx]); | |||
else | |||
filesize = fstats.st_size; | |||
return img_load(&img, filenames[fileidx]); | |||
} | |||
int main(int argc, char **argv) { | |||
int i; | |||
const char *filename; | |||
@@ -102,7 +114,7 @@ int main(int argc, char **argv) { | |||
win_open(&win); | |||
img_init(&img, &win); | |||
img_load(&img, filenames[fileidx]); | |||
load_image(); | |||
img_render(&img, &win); | |||
update_title(); | |||
@@ -115,10 +127,15 @@ int main(int argc, char **argv) { | |||
void update_title() { | |||
int n; | |||
float size; | |||
const char *unit; | |||
n = snprintf(win_title, TITLE_LEN, "sxiv: [%d/%d] <%d%%> %s", fileidx + 1, | |||
filecnt, (int) (img.zoom * 100.0), filenames[fileidx]); | |||
size = filesize; | |||
size_readable(&size, &unit); | |||
n = snprintf(win_title, TITLE_LEN, "sxiv: [%d/%d] <%d%%> (%.2f%s) %s", | |||
fileidx + 1, filecnt, (int) (img.zoom * 100.0), size, unit, | |||
filenames[fileidx]); | |||
if (n >= TITLE_LEN) { | |||
win_title[TITLE_LEN - 2] = '.'; | |||
win_title[TITLE_LEN - 3] = '.'; | |||
@@ -223,37 +240,39 @@ void on_keypress(XKeyEvent *kev) { | |||
case XK_n: | |||
case XK_space: | |||
if (fileidx + 1 < filecnt) { | |||
changed = img_load(&img, filenames[++fileidx]); | |||
++fileidx; | |||
changed = load_image(); | |||
} | |||
break; | |||
case XK_p: | |||
case XK_BackSpace: | |||
if (fileidx > 0) { | |||
changed = img_load(&img, filenames[--fileidx]); | |||
--fileidx; | |||
changed = load_image(); | |||
} | |||
break; | |||
case XK_bracketleft: | |||
if (fileidx != 0) { | |||
fileidx = MAX(0, fileidx - 10); | |||
changed = img_load(&img, filenames[fileidx]); | |||
changed = load_image(); | |||
} | |||
break; | |||
case XK_bracketright: | |||
if (fileidx != filecnt - 1) { | |||
fileidx = MIN(fileidx + 10, filecnt - 1); | |||
changed = img_load(&img, filenames[fileidx]); | |||
changed = load_image(); | |||
} | |||
break; | |||
case XK_g: | |||
if (fileidx != 0) { | |||
fileidx = 0; | |||
changed = img_load(&img, filenames[fileidx]); | |||
changed = load_image(); | |||
} | |||
break; | |||
case XK_G: | |||
if (fileidx != filecnt - 1) { | |||
fileidx = filecnt - 1; | |||
changed = img_load(&img, filenames[fileidx]); | |||
changed = load_image(); | |||
} | |||
break; | |||
@@ -286,24 +305,29 @@ void on_keypress(XKeyEvent *kev) { | |||
/* rotation */ | |||
case XK_less: | |||
changed = img_rotate_left(&img, &win); | |||
img_rotate_left(&img, &win); | |||
changed = 1; | |||
break; | |||
case XK_greater: | |||
changed = img_rotate_right(&img, &win); | |||
img_rotate_right(&img, &win); | |||
changed = 1; | |||
break; | |||
/* control window */ | |||
case XK_f: | |||
win_toggle_fullscreen(&win); | |||
/* render on next configurenotify */ | |||
break; | |||
/* miscellaneous */ | |||
case XK_a: | |||
changed = img_toggle_antialias(&img); | |||
img_toggle_antialias(&img); | |||
changed = 1; | |||
break; | |||
case XK_r: | |||
changed = img_load(&img, filenames[fileidx]); | |||
changed = load_image(); | |||
break; | |||
; | |||
} | |||
if (changed) { | |||
@@ -326,8 +350,8 @@ void on_buttonpress(XButtonEvent *bev) { | |||
switch (bev->button) { | |||
case Button1: | |||
if (fileidx + 1 < filecnt) { | |||
img_load(&img, filenames[++fileidx]); | |||
changed = 1; | |||
++fileidx; | |||
changed = load_image(); | |||
} | |||
break; | |||
case Button2: | |||
@@ -337,8 +361,8 @@ void on_buttonpress(XButtonEvent *bev) { | |||
break; | |||
case Button3: | |||
if (fileidx > 0) { | |||
img_load(&img, filenames[--fileidx]); | |||
changed = 1; | |||
--fileidx; | |||
changed = load_image(); | |||
} | |||
break; | |||
case Button4: | |||
@@ -66,3 +66,12 @@ void die(const char* fmt, ...) { | |||
cleanup(); | |||
exit(1); | |||
} | |||
void size_readable(float *size, const char **unit) { | |||
const char *units[] = { "", "K", "M", "G" }; | |||
int i; | |||
for (i = 0; i < LEN(units) && *size > 1024; ++i) | |||
*size /= 1024; | |||
*unit = units[MIN(i, LEN(units) - 1)]; | |||
} |
@@ -24,6 +24,7 @@ | |||
#define ABS(a) ((a) < 0 ? (-(a)) : (a)) | |||
#define MIN(a,b) ((a) < (b) ? (a) : (b)) | |||
#define MAX(a,b) ((a) > (b) ? (a) : (b)) | |||
#define LEN(a) (sizeof(a) / sizeof(a[0])) | |||
void* s_malloc(size_t); | |||
void* s_realloc(void*, size_t); | |||
@@ -31,4 +32,6 @@ void* s_realloc(void*, size_t); | |||
void warn(const char*, ...); | |||
void die(const char*, ...); | |||
void size_readable(float*, const char**); | |||
#endif /* UTIL_H */ |