diff options
| author | guns <self@sungpae.com> | 2016-05-28 00:45:33 -0500 | 
|---|---|---|
| committer | guns <self@sungpae.com> | 2016-05-28 00:45:33 -0500 | 
| commit | 36b09fa038a8b7996a12e45419c28821c5596308 (patch) | |
| tree | 36e759b0bd5d94fa4ef8817a746f43b6e6e9d5c4 | |
| parent | 7db8895f8cfb3d58b8e9b4c7a5a64a4df9bb1af0 (diff) | |
Add prev_dir and next_dir navigation actions
Many image collections are organized by directory, so it is nice to have
jump-to-adjacent-directory navigation.
e.g. Given the following file hierarchy:
    .
    ├── A
    │   ├── 1.jpg
    │   ├── 2.jpg
    │   └── C
    │       ├── 1.jpg
    │       ├── 2.jpg
    │       └── 3.jpg
    └── B
        ├── 1.jpg
        ├── 2.jpg
        └── 3.jpg
`feh --recursive` creates the following filelist:
    A/1.jpg <---- current_file
    A/2.jpg
    A/C/1.jpg
    A/C/2.jpg
    A/C/3.jpg
    B/1.jpg
    B/2.jpg
    B/3.jpg
If we press [next_dir], we move the current_file pointer to:
    A/1.jpg
    A/2.jpg
    A/C/1.jpg <-- current_file
    A/C/2.jpg
    A/C/3.jpg
    B/1.jpg
    B/2.jpg
    B/3.jpg
Pressing [next_dir] again moves the pointer to:
    A/1.jpg
    A/2.jpg
    A/C/1.jpg
    A/C/2.jpg
    A/C/3.jpg
    B/1.jpg <---- current_file
    B/2.jpg
    B/3.jpg
[next_dir] now moves the pointer back to the top of the list:
    A/1.jpg <---- current_file
    A/2.jpg
    A/C/1.jpg
    A/C/2.jpg
    A/C/3.jpg
    B/1.jpg
    B/2.jpg
    B/3.jpg
Pressing [prev_dir] from here moves backwards to the first image of the
previous directory:
    A/1.jpg
    A/2.jpg
    A/C/1.jpg
    A/C/2.jpg
    A/C/3.jpg
    B/1.jpg <---- current_file
    B/2.jpg
    B/3.jpg
When starting from an position that is not the first image of a
directory, [prev_dir] moves the pointer to the first image of the
current directory.
These actions combine well with `--sort dirname` since all regular files
in a directory will be sorted before any subdirectories, avoiding a
filelist like the following:
    A/1.jpg
    A/SUBDIR/2.jpg
    A/SUBDIR/3.jpg
    A/4.jpg
With `--sort dirname` that filelist becomes:
    A/1.jpg
    A/4.jpg
    A/SUBDIR/2.jpg
    A/SUBDIR/3.jpg
| -rw-r--r-- | man/feh.pre | 6 | ||||
| -rw-r--r-- | src/feh.h | 4 | ||||
| -rw-r--r-- | src/keyevents.c | 14 | ||||
| -rw-r--r-- | src/options.h | 2 | ||||
| -rw-r--r-- | src/slideshow.c | 38 | 
5 files changed, 63 insertions, 1 deletions
| diff --git a/man/feh.pre b/man/feh.pre index 609ef57..dfa5cae 100644 --- a/man/feh.pre +++ b/man/feh.pre @@ -1284,6 +1284,12 @@ Close current window  .  Jump to a random position in the current filelist  . +.It \&[, \&] Bq prev_dir, next_dir +. +Jump to the first image of the previous or next sequence of images sharing +a directory name in the current filelist.  Use --sort dirname if you would +like to ensure that all images in a directory are grouped together. +.  .It < , > Bq orient_3 , orient_1  .  In place editing - rotate the images 90 degrees (counter)clockwise. @@ -102,7 +102,9 @@ enum text_bg { TEXT_BG_CLEAR = 0, TEXT_BG_TINTED };  enum slide_change { SLIDE_NEXT, SLIDE_PREV, SLIDE_RAND, SLIDE_FIRST, SLIDE_LAST,  	SLIDE_JUMP_FWD, -	SLIDE_JUMP_BACK +	SLIDE_JUMP_BACK, +	SLIDE_JUMP_NEXT_DIR, +	SLIDE_JUMP_PREV_DIR  };  enum image_bg { IMAGE_BG_CHECKS = 1, IMAGE_BG_BLACK, IMAGE_BG_WHITE }; diff --git a/src/keyevents.c b/src/keyevents.c index 8977111..4837c0b 100644 --- a/src/keyevents.c +++ b/src/keyevents.c @@ -110,6 +110,8 @@ void init_keyevents(void) {  	feh_set_kb(&keys.next_img  , 0, XK_Right     , 0, XK_n         , 0, XK_space);  	feh_set_kb(&keys.jump_back , 0, XK_Page_Up   , 0, XK_KP_Page_Up, 0, 0);  	feh_set_kb(&keys.jump_fwd  , 0, XK_Page_Down , 0, XK_KP_Page_Down,0,0); +	feh_set_kb(&keys.prev_dir  , 0, XK_bracketleft, 0, 0           , 0, 0); +	feh_set_kb(&keys.next_dir  , 0, XK_bracketright, 0, 0          , 0, 0);  	feh_set_kb(&keys.jump_random,0, XK_z         , 0, 0            , 0, 0);  	feh_set_kb(&keys.quit      , 0, XK_Escape    , 0, XK_q         , 0, 0);  	feh_set_kb(&keys.close     , 0, XK_x         , 0, 0            , 0, 0); @@ -222,6 +224,10 @@ void init_keyevents(void) {  			cur_kb = &keys.jump_back;  		else if (!strcmp(action, "jump_fwd"))  			cur_kb = &keys.jump_fwd; +		else if (!strcmp(action, "prev_dir")) +			cur_kb = &keys.prev_dir; +		else if (!strcmp(action, "next_dir")) +			cur_kb = &keys.next_dir;  		else if (!strcmp(action, "jump_random"))  			cur_kb = &keys.jump_random;  		else if (!strcmp(action, "quit")) @@ -532,6 +538,14 @@ void feh_event_handle_keypress(XEvent * ev)  		else if (winwid->type == WIN_TYPE_THUMBNAIL)  			feh_thumbnail_select_next(winwid, 10);  	} +	else if (feh_is_kp(&keys.next_dir, keysym, state)) { +		if (opt.slideshow) +			slideshow_change_image(winwid, SLIDE_JUMP_NEXT_DIR, 1); +	} +	else if (feh_is_kp(&keys.prev_dir, keysym, state)) { +		if (opt.slideshow) +			slideshow_change_image(winwid, SLIDE_JUMP_PREV_DIR, 1); +	}  	else if (feh_is_kp(&keys.quit, keysym, state)) {  		winwidget_destroy_all();  	} diff --git a/src/options.h b/src/options.h index 0052d5d..bbf129f 100644 --- a/src/options.h +++ b/src/options.h @@ -153,6 +153,8 @@ struct __fehkb {  	struct __fehkey jump_back;  	struct __fehkey quit;  	struct __fehkey jump_fwd; +	struct __fehkey prev_dir; +	struct __fehkey next_dir;  	struct __fehkey remove;  	struct __fehkey delete;  	struct __fehkey jump_first; diff --git a/src/slideshow.c b/src/slideshow.c index 7636d31..2af78c9 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -322,6 +322,44 @@ void slideshow_change_image(winwidget winwid, int change, int render)  			   try the previous file, not another jmp */  			change = SLIDE_NEXT;  			break; +		case SLIDE_JUMP_NEXT_DIR: +			{ +				char old_dir[FEH_MAX_DIRNAME_LEN], new_dir[FEH_MAX_DIRNAME_LEN]; +				int j; + +				feh_file_dirname(old_dir, FEH_FILE(current_file->data), FEH_MAX_DIRNAME_LEN); + +				for (j = 0; j < our_filelist_len; j++) { +					current_file = feh_list_jump(filelist, current_file, FORWARD, 1); +					feh_file_dirname(new_dir, FEH_FILE(current_file->data), FEH_MAX_DIRNAME_LEN); +					if (strcmp(old_dir, new_dir) != 0) +						break; +				} +			} +			change = SLIDE_NEXT; +			break; +		case SLIDE_JUMP_PREV_DIR: +			{ +				char old_dir[FEH_MAX_DIRNAME_LEN], new_dir[FEH_MAX_DIRNAME_LEN]; +				int j; + +				/* Start the search from the previous file in case we are on +				   the first file of a directory */ +				current_file = feh_list_jump(filelist, current_file, BACK, 1); +				feh_file_dirname(old_dir, FEH_FILE(current_file->data), FEH_MAX_DIRNAME_LEN); + +				for (j = 0; j < our_filelist_len; j++) { +					current_file = feh_list_jump(filelist, current_file, BACK, 1); +					feh_file_dirname(new_dir, FEH_FILE(current_file->data), FEH_MAX_DIRNAME_LEN); +					if (strcmp(old_dir, new_dir) != 0) +						break; +				} + +				/* Next file is the first entry of prev_dir */ +				current_file = feh_list_jump(filelist, current_file, FORWARD, 1); +			} +			change = SLIDE_NEXT; +			break;  		default:  			eprintf("BUG!\n");  			break; | 
