shithub: dmenu

Download patch

ref: bc69d3c62762f155e54e487f2145cd7fe3224ce7
parent: 4519e5d0d0836c3993f1ef05fb18bade6e88d6ee
author: glenda <glenda@9front.local>
date: Sun Sep 5 18:44:31 EDT 2021

line: implement wheel scrolling

--- a/line.c
+++ b/line.c
@@ -19,7 +19,7 @@
 
 Image *color[NCOLORS];
 char **lines, **matches, *buffer;
-usize nlines, nmatches;
+usize nlines, nmatches, scroll;
 Rune kbinput[512];
 int selected;
 
@@ -50,6 +50,7 @@
 static Point
 linetopoint(int ln)
 {
+	ln -= scroll;
 	return Pt(screen->r.min.x, screen->r.min.y + (ln + 2) * font->height);
 }
 
@@ -56,7 +57,7 @@
 static int
 pointtoline(Point pt)
 {
-	return (pt.y - screen->r.min.y) / font->height - 2;
+	return (pt.y - screen->r.min.y) / font->height - 2 + scroll;
 }
 
 static void
@@ -91,12 +92,14 @@
 static void
 drawprompt(void)
 {
+	Point pt;
 	char buf[512];
 
-	drawbackground(linetopoint(-2), color[BACK]);
-	drawbackground(linetopoint(-1), color[BACK]);
 	snprint(buf, sizeof buf, PROMPT"%S▏", kbinput);
-	tabstring(screen, linetopoint(-1), color[TEXT], ZP, font, buf);
+	pt = Pt(screen->r.max.x, screen->r.min.y + font->height * 2);
+	draw(screen, Rpt(screen->r.min, pt), color[BACK], nil, ZP);
+	pt = Pt(screen->r.min.x, screen->r.min.y + font->height);
+	tabstring(screen, pt, color[TEXT], ZP, font, buf);
 }
 
 static int
@@ -105,6 +108,8 @@
 	Point pt = linetopoint(ln);
 	Image *bgcolor, *txcolor;
 
+	if(ln < scroll)
+		return 1;
 	if(ln == selected){
 		bgcolor = color[HBACK];
 		txcolor = color[HTEXT];
@@ -128,7 +133,7 @@
 		sysfatal("resize failed: %r");
 
 	drawprompt();
-	for(i = 0; drawline(i); i++);
+	for(i = scroll; drawline(i); i++);
 }
 
 int
@@ -163,6 +168,7 @@
 		}
 
 	selected = 0;
+	scroll = 0;
 	free(buf);
 	eresized(0); /* possibly different lines: redraw everything */
 }
@@ -232,6 +238,20 @@
 }
 
 static void
+kbscroll(int percent)
+{
+	int ln = Dy(screen->r) / font->height * percent / 100;
+
+	if(ln < 0 && abs(ln) > scroll)
+		scroll = 0;
+	else if(ln > 0 && scroll + ln >= nmatches)
+		scroll = nmatches - 1 + (nmatches > 0);
+	else
+		scroll += ln;
+	eresized(0);
+}
+
+static void
 mselect(Point pt)
 {
 	int old, sel = pointtoline(pt);
@@ -238,7 +258,7 @@
 
 	if(sel < 0)
 		sel = 0;
-	if(sel >= nmatches)
+	if(nmatches > 0 && sel >= nmatches)
 		sel = nmatches - 1;
 	if(sel != selected){
 		old = selected;
@@ -314,6 +334,12 @@
 			case Kdown:
 				kbmove(+1);
 				break;
+			case Kpgdown:
+				kbscroll(+40);
+				break;
+			case Kpgup:
+				kbscroll(-40);
+				break;
 			default:
 				kbadd(e.kbdc);
 				break;
@@ -325,6 +351,10 @@
 				mselect(e.mouse.xy);
 			if(e.mouse.buttons&4)
 				goto End;
+			if(e.mouse.buttons&8)
+				kbscroll(-40);
+			if(e.mouse.buttons&16)
+				kbscroll(+40);
 			break;
 		}
 	}