shithub: orca

Download patch

ref: 86e501434117b25898492b9fe2ef9797ed0029db
parent: 2c6ccbaedf7c996e73528f71feffd55e3c27a18e
author: Sigrid Haflínudóttir <ftrvxmtrx@gmail.com>
date: Tue Feb 18 10:17:53 EST 2020

plan9: implement scrolling for fields that don't fit the window

--- a/plan9.c
+++ b/plan9.c
@@ -71,7 +71,7 @@
 static Rune cursor = '@';
 static vlong tick;
 static Point glyphsz;
-static Point cur;
+static Point cur, scroll;
 static Rectangle sel;
 static Field field;
 static Mbuf_reusable mbuf, mscr;
@@ -358,9 +358,11 @@
 static void
 redraw(int complete)
 {
+	static Point oldscroll;
 	Rectangle r;
 	Point p, top, bot;
 	int x, y, rx, ry, i;
+	Point max;
 	int oldbg, oldfg, bg, fg, attr, off;
 	bool selected, grouphl;
 	char s[32];
@@ -369,8 +371,24 @@
 	p = addpt(screen->r.min, Pt(Txtoff, Txtoff));
 	top = p;
 	bot.x = top.x;
-	bot.y = screen->r.max.y - Txtoff - glyphsz.y*2;
+	bot.y = screen->r.max.y - glyphsz.y*2 - Txtoff;
+	max.x = MIN(field.width, (Dx(screen->r) - 2*Txtoff) / glyphsz.x);
+	max.y = MIN(field.height, (bot.y - top.y - glyphsz.y) / glyphsz.y);
 
+	if (cur.x >= max.x+scroll.x-1)
+		scroll.x = cur.x-max.x+1;
+	else if (cur.x < scroll.x)
+		scroll.x = cur.x;
+
+	if (cur.y >= max.y+scroll.y-1)
+		scroll.y = cur.y-max.y+1;
+	else if (cur.y < scroll.y)
+		scroll.y = cur.y;
+
+	if (!eqpt(oldscroll, scroll))
+		complete = 1;
+	oldscroll = scroll;
+
 	if (complete) {
 		r = screen->r;
 		r.max.y = r.min.y + Txtoff;
@@ -378,9 +396,6 @@
 		r = screen->r;
 		r.max.x = r.min.x + Txtoff;
 		draw(screen, r, color[Dback], nil, ZP);
-		r = screen->r;
-		r.min.x += MIN(field.width*glyphsz.x, Dx(r)-Txtoff) + Txtoff;
-		draw(screen, r, color[Dback], nil, ZP);
 	}
 
 	off = field.width*cur.y + cur.x;
@@ -388,9 +403,10 @@
 
 	bg = -1;
 	fg = -1;
-	for (y = 0; y < field.height && p.y < bot.y-glyphsz.y; y++) {
+	r = screen->r;
+	for (y = scroll.y; y < MIN(field.height, scroll.y+max.y); y++) {
 		p.x = top.x;
-		for (x = i = 0; x < field.width && x < screen->r.max.x-Txtoff; x++) {
+		for (x = scroll.x, i = 0; x < MIN(field.width, scroll.x+max.x); x++) {
 			oldbg = bg;
 			oldfg = fg;
 			off = field.width*y + x;
@@ -465,7 +481,7 @@
 				}
 			}
 
-			if (i > 0 && (bg != oldbg || fg != oldfg)) {
+			if (bg != oldbg || fg != oldfg) {
 				p = runestringnbg(screen, p, color[oldfg], ZP, font, linebuf, i, color[oldbg], ZP);
 				i = 0;
 			}
@@ -476,9 +492,13 @@
 	}
 
 	r = screen->r;
-	r.min.y = MIN(top.y + field.height*glyphsz.y, bot.y-glyphsz.y);
+	r.min.x += Txtoff + max.x*glyphsz.x;
 	draw(screen, r, color[Dback], nil, ZP);
 
+	r = screen->r;
+	r.min.y += Txtoff + max.y*glyphsz.y;
+	draw(screen, r, color[Dback], nil, ZP);
+
 	i = 0;
 	sprint(s, "%udx%ud", field.width, field.height);
 	i += runesprint(linebuf, "%-10s", s);
@@ -807,6 +827,8 @@
 	p = subpt(subpt(p, screen->r.min), Pt(Txtoff, Txtoff));
 	p.x /= glyphsz.x;
 	p.y /= glyphsz.y;
+	p.x += scroll.x;
+	p.y += scroll.y;
 
 	return ptclamp(p);
 }
@@ -1018,6 +1040,7 @@
 		case Cresize:
 			getwindow(display, Refnone);
 			complete = true;
+			scroll = ZP;
 			break;
 
 		case Ckey: