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: