Krolyxon
Commit 7a75c42

Branches

Refs →

nsxiv7a75c42

make thumbnail bindings configureable via config.h (#167)

this allows for configuring thumbnail mode mouse bindings similar to
image mode bindings.

however we can't put the thumbnails bindings into the existing buttons[]
array due to fallthrough. For example M3 would switch mode and then end
up selecting an image.

which is why thumbnail bindings have been put into it's own array
`buttons_tns[]` and `buttons[]` has been renamed to `buttons_img[]` for
consistency.
Author
N-R-K
Date
2022-01-10 16:52 +0000
Committer
GitHub · 2022-01-10 16:52 +0000
Parent
157cda5
Commit
7a75c42b37b08f44c72f9a7c98eb6076967470fb

+82 −53

4 files changed

  1. M commands.c +55 −0
  2. M commands.h +6 −0
  3. M config.def.h +12 −1
  4. M main.c +9 −52
M commands.c View
@@ -42,6 +42,7 @@ extern appmode_t mode;
4242 extern img_t img;
4343 extern tns_t tns;
4444 extern win_t win;
45+extern const XButtonEvent *xbutton_ev;
4546
4647 extern fileinfo_t *files;
4748 extern int filecnt, fileidx;
@@ -436,3 +437,57 @@ bool ct_reload_all(arg_t _)
436437 tns.dirty = true;
437438 return true;
438439 }
440+
441+bool ct_scroll(arg_t dir)
442+{
443+ return tns_scroll(&tns, dir, false);
444+}
445+
446+bool ct_drag_mark_image(arg_t _)
447+{
448+ int sel;
449+
450+ if ((sel = tns_translate(&tns, xbutton_ev->x, xbutton_ev->y)) >= 0) {
451+ XEvent e;
452+ bool on = !(files[sel].flags & FF_MARK);
453+
454+ while (true) {
455+ if (sel >= 0 && mark_image(sel, on))
456+ redraw();
457+ XMaskEvent(win.env.dpy,
458+ ButtonPressMask | ButtonReleaseMask | PointerMotionMask, &e);
459+ if (e.type == ButtonPress || e.type == ButtonRelease)
460+ break;
461+ while (XCheckTypedEvent(win.env.dpy, MotionNotify, &e));
462+ sel = tns_translate(&tns, e.xbutton.x, e.xbutton.y);
463+ }
464+ }
465+
466+ return false;
467+}
468+
469+bool ct_select(arg_t _)
470+{
471+ int sel;
472+ bool dirty = false;
473+ static Time firstclick;
474+
475+ if ((sel = tns_translate(&tns, xbutton_ev->x, xbutton_ev->y)) >= 0) {
476+ if (sel != fileidx) {
477+ tns_highlight(&tns, fileidx, false);
478+ tns_highlight(&tns, sel, true);
479+ fileidx = sel;
480+ firstclick = xbutton_ev->time;
481+ dirty = true;
482+ } else if (xbutton_ev->time - firstclick <= TO_DOUBLE_CLICK) {
483+ mode = MODE_IMAGE;
484+ set_timeout(reset_cursor, TO_CURSOR_HIDE, true);
485+ load_image(fileidx);
486+ dirty = true;
487+ } else {
488+ firstclick = xbutton_ev->time;
489+ }
490+ }
491+
492+ return dirty;
493+}
M commands.h View
@@ -39,6 +39,9 @@ bool ci_toggle_antialias(arg_t);
3939 /* thumbnails mode */
4040 bool ct_move_sel(arg_t);
4141 bool ct_reload_all(arg_t);
42+bool ct_scroll(arg_t);
43+bool ct_drag_mark_image(arg_t);
44+bool ct_select(arg_t);
4245
4346 /* global */
4447 #define g_change_gamma { cg_change_gamma, MODE_ALL }
@@ -79,5 +82,8 @@ bool ct_reload_all(arg_t);
7982 /* thumbnails mode */
8083 #define t_move_sel { ct_move_sel, MODE_THUMB }
8184 #define t_reload_all { ct_reload_all, MODE_THUMB }
85+#define t_scroll { ct_scroll, MODE_THUMB }
86+#define t_drag_mark_image { ct_drag_mark_image, MODE_THUMB }
87+#define t_select { ct_select, MODE_THUMB }
8288
8389 #endif /* COMMANDS_H */
M config.def.h View
@@ -175,7 +175,7 @@ static const keymap_t keys[] = {
175175 };
176176
177177 /* mouse button mappings for image mode: */
178−static const button_t buttons[] = {
178+static const button_t buttons_img[] = {
179179 /* modifiers button function argument */
180180 { 0, 1, i_cursor_navigate, None },
181181 { ControlMask, 1, i_drag, DRAG_RELATIVE },
@@ -185,6 +185,17 @@ static const button_t buttons[] = {
185185 { 0, 5, g_zoom, -1 },
186186 };
187187
188+/* mouse button mappings for thumbnail mode: */
189+static const button_t buttons_tns[] = {
190+ /* modifiers button function argument */
191+ { 0, 1, t_select, None },
192+ { 0, 3, t_drag_mark_image, None },
193+ { 0, 4, t_scroll, DIR_UP },
194+ { 0, 5, t_scroll, DIR_DOWN },
195+ { ControlMask, 4, g_scroll_screen, DIR_UP },
196+ { ControlMask, 5, g_scroll_screen, DIR_DOWN },
197+};
198+
188199 /* true means NAV_WIDTH is relative (33%), false means absolute (33 pixels) */
189200 static const bool NAV_IS_REL = true;
190201 /* width of navigation area, 0 disables cursor navigation, */
M main.c View
@@ -57,6 +57,7 @@ arl_t arl;
5757 img_t img;
5858 tns_t tns;
5959 win_t win;
60+const XButtonEvent *xbutton_ev;
6061
6162 fileinfo_t *files;
6263 int filecnt, fileidx;
@@ -661,64 +662,19 @@ static void on_keypress(XKeyEvent *kev)
661662 prefix = 0;
662663 }
663664
664−static void on_buttonpress(XButtonEvent *bev)
665+static void on_buttonpress(const XButtonEvent *bev)
665666 {
666− int sel;
667667 bool dirty = false;
668− static Time firstclick;
669668
670669 if (mode == MODE_IMAGE) {
671670 set_timeout(reset_cursor, TO_CURSOR_HIDE, true);
672671 reset_cursor();
673− dirty = process_bindings(buttons, ARRLEN(buttons), bev->button, bev->state, 0);
674− if (dirty)
675− redraw();
676− } else {
677− /* thumbnail mode (hard-coded) */
678− switch (bev->button) {
679− case Button1:
680− if ((sel = tns_translate(&tns, bev->x, bev->y)) >= 0) {
681− if (sel != fileidx) {
682− tns_highlight(&tns, fileidx, false);
683− tns_highlight(&tns, sel, true);
684− fileidx = sel;
685− firstclick = bev->time;
686− redraw();
687− } else if (bev->time - firstclick <= TO_DOUBLE_CLICK) {
688− mode = MODE_IMAGE;
689− set_timeout(reset_cursor, TO_CURSOR_HIDE, true);
690− load_image(fileidx);
691− redraw();
692− } else {
693− firstclick = bev->time;
694− }
695− }
696− break;
697− case Button3:
698− if ((sel = tns_translate(&tns, bev->x, bev->y)) >= 0) {
699− bool on = !(files[sel].flags & FF_MARK);
700− XEvent e;
701−
702− while (true) {
703− if (sel >= 0 && mark_image(sel, on))
704− redraw();
705− XMaskEvent(win.env.dpy,
706− ButtonPressMask | ButtonReleaseMask | PointerMotionMask, &e);
707− if (e.type == ButtonPress || e.type == ButtonRelease)
708− break;
709− while (XCheckTypedEvent(win.env.dpy, MotionNotify, &e));
710− sel = tns_translate(&tns, e.xbutton.x, e.xbutton.y);
711− }
712− }
713− break;
714− case Button4:
715− case Button5:
716− if (tns_scroll(&tns, bev->button == Button4 ? DIR_UP : DIR_DOWN,
717− (bev->state & ControlMask) != 0))
718− redraw();
719− break;
720− }
672+ dirty = process_bindings(buttons_img, ARRLEN(buttons_img), bev->button, bev->state, 0);
673+ } else { /* thumbnail mode */
674+ dirty = process_bindings(buttons_tns, ARRLEN(buttons_tns), bev->button, bev->state, 0);
721675 }
676+ if (dirty)
677+ redraw();
722678 prefix = 0;
723679 }
724680
@@ -731,13 +687,14 @@ static void run(void)
731687 bool discard, init_thumb, load_thumb, to_set;
732688 XEvent ev, nextev;
733689
690+ xbutton_ev = &ev.xbutton;
734691 while (true) {
735692 to_set = check_timeouts(&timeout);
736693 init_thumb = mode == MODE_THUMB && tns.initnext < filecnt;
737694 load_thumb = mode == MODE_THUMB && tns.loadnext < tns.end;
738695
739696 if ((init_thumb || load_thumb || to_set || info.fd != -1 ||
740− arl.fd != -1) && XPending(win.env.dpy) == 0)
697+ arl.fd != -1) && XPending(win.env.dpy) == 0)
741698 {
742699 if (load_thumb) {
743700 set_timeout(redraw, TO_REDRAW_THUMBS, false);