From a30901210cfde971bac780b5c0bbdeda215ea809 Mon Sep 17 00:00:00 2001
From: Bert <ber.t@gmx.com>
Date: Sun, 20 Feb 2011 00:08:17 +0100
Subject: [PATCH] Mouse-wheel scrolling in thumb mode

---
 Makefile |  2 +-
 main.c   | 20 ++++++++++++++++----
 thumbs.c | 44 ++++++++++++++++++++++++++++++++++++--------
 thumbs.h | 15 ++++++++-------
 4 files changed, 61 insertions(+), 20 deletions(-)

diff --git a/Makefile b/Makefile
index 01f4bf7..7db2bb2 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 all: sxiv
 
-VERSION=git-20110219
+VERSION=git-20110220
 
 CC?=gcc
 PREFIX?=/usr/local
diff --git a/main.c b/main.c
index a863d18..9b5b41b 100644
--- a/main.c
+++ b/main.c
@@ -397,19 +397,25 @@ void on_keypress(XKeyEvent *kev) {
 			/* move selection */
 			case XK_h:
 			case XK_Left:
-				changed = tns_move_selection(&tns, &win, MOVE_LEFT);
+				changed = tns_move_selection(&tns, &win, TNS_LEFT);
 				break;
 			case XK_j:
 			case XK_Down:
-				changed = tns_move_selection(&tns, &win, MOVE_DOWN);
+				changed = tns_move_selection(&tns, &win, TNS_DOWN);
 				break;
 			case XK_k:
 			case XK_Up:
-				changed = tns_move_selection(&tns, &win, MOVE_UP);
+				changed = tns_move_selection(&tns, &win, TNS_UP);
 				break;
 			case XK_l:
 			case XK_Right:
-				changed = tns_move_selection(&tns, &win, MOVE_RIGHT);
+				changed = tns_move_selection(&tns, &win, TNS_RIGHT);
+				break;
+
+			/* scroll */
+			case XK_bracketleft:
+				break;
+			case XK_bracketright:
 				break;
 		}
 	}
@@ -524,6 +530,12 @@ void on_buttonpress(XButtonEvent *bev) {
 					break;
 				}
 				break;
+			case Button4:
+				changed = tns_scroll(&tns, TNS_UP);
+				break;
+			case Button5:
+				changed = tns_scroll(&tns, TNS_DOWN);
+				break;
 		}
 	}
 
diff --git a/thumbs.c b/thumbs.c
index 3de9518..aea40ee 100644
--- a/thumbs.c
+++ b/thumbs.c
@@ -88,21 +88,27 @@ void tns_load(tns_t *tns, win_t *win, const char *filename) {
 }
 
 void tns_check_view(tns_t *tns, Bool scrolled) {
+	int r;
+
 	if (!tns)
 		return;
 
 	tns->first -= tns->first % tns->cols;
+	r = fileidx % tns->cols;
 
 	if (scrolled) {
 		/* move selection into visible area */
+		if (fileidx >= tns->first + tns->cols * tns->rows)
+			fileidx = tns->first + r + tns->cols * (tns->rows - 1);
+		else if (fileidx < tns->first)
+			fileidx = tns->first + r;
 	} else {
 		/* scroll to selection */
 		if (tns->first + tns->cols * tns->rows <= fileidx) {
-			tns->first = fileidx - fileidx % tns->cols -
-			             tns->cols * (tns->rows - 1);
+			tns->first = fileidx - r - tns->cols * (tns->rows - 1);
 			tns->dirty = 1;
 		} else if (tns->first > fileidx) {
-			tns->first = fileidx - fileidx % tns->cols;
+			tns->first = fileidx - r;
 			tns->dirty = 1;
 		}
 	}
@@ -167,7 +173,7 @@ void tns_highlight(tns_t *tns, win_t *win, int n, Bool hl) {
 	win_draw(win);
 }
 
-int tns_move_selection(tns_t *tns, win_t *win, movedir_t dir) {
+int tns_move_selection(tns_t *tns, win_t *win, tnsdir_t dir) {
 	int old;
 
 	if (!tns || !win)
@@ -176,19 +182,19 @@ int tns_move_selection(tns_t *tns, win_t *win, movedir_t dir) {
 	old = fileidx;
 
 	switch (dir) {
-		case MOVE_LEFT:
+		case TNS_LEFT:
 			if (fileidx > 0)
 				--fileidx;
 			break;
-		case MOVE_RIGHT:
+		case TNS_RIGHT:
 			if (fileidx < tns->cnt - 1)
 				++fileidx;
 			break;
-		case MOVE_UP:
+		case TNS_UP:
 			if (fileidx >= tns->cols)
 				fileidx -= tns->cols;
 			break;
-		case MOVE_DOWN:
+		case TNS_DOWN:
 			if (fileidx + tns->cols < tns->cnt)
 				fileidx += tns->cols;
 			break;
@@ -204,6 +210,28 @@ int tns_move_selection(tns_t *tns, win_t *win, movedir_t dir) {
 	return fileidx != old;
 }
 
+int tns_scroll(tns_t *tns, tnsdir_t dir) {
+	int old;
+
+	if (!tns)
+		return 0;
+
+	old = tns->first;
+
+	if (dir == TNS_DOWN && tns->first + tns->cols * tns->rows < tns->cnt)
+		tns->first += tns->cols;
+	else if (dir == TNS_UP && tns->first >= tns->cols)
+		tns->first -= tns->cols;
+
+	if (tns->first != old) {
+		tns_check_view(tns, True);
+		tns->dirty = 1;
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
 int tns_translate(tns_t *tns, int x, int y) {
 	int n;
 	thumb_t *t;
diff --git a/thumbs.h b/thumbs.h
index c545b90..62d2c72 100644
--- a/thumbs.h
+++ b/thumbs.h
@@ -21,12 +21,12 @@
 
 #include "window.h"
 
-typedef enum movedir_e {
-	MOVE_LEFT = 0,
-	MOVE_RIGHT,
-	MOVE_UP,
-	MOVE_DOWN
-} movedir_t;
+typedef enum tnsdir_e {
+	TNS_LEFT = 0,
+	TNS_RIGHT,
+	TNS_UP,
+	TNS_DOWN
+} tnsdir_t;
 
 typedef struct thumb_s {
 	Pixmap pm;
@@ -56,7 +56,8 @@ void tns_load(tns_t*, win_t*, const char*);
 void tns_render(tns_t*, win_t*);
 void tns_highlight(tns_t*, win_t*, int, Bool);
 
-int tns_move_selection(tns_t*, win_t*, movedir_t);
+int tns_move_selection(tns_t*, win_t*, tnsdir_t);
+int tns_scroll(tns_t*, tnsdir_t);
 
 int tns_translate(tns_t*, int, int);