commit 64a8e14e70cd6a5cea2637ea39b9185ed02e929b
parent b365d0f4a6832b9e4a34fe5e5c6a3f1281a9bd6c
Author: rpa <rpa@laika>
Date: Sun, 4 Dec 2022 01:22:48 +0000
tabul: add scrolling
Diffstat:
M | src/tabul/tabul.c | | | 153 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------- |
1 file changed, 117 insertions(+), 36 deletions(-)
diff --git a/src/tabul/tabul.c b/src/tabul/tabul.c
@@ -18,8 +18,7 @@ struct Table{
};
Image *bord, *text, *bg, *curbg;
-Rectangle cell, cells;
-Point cur;
+Rectangle cell, blank;
Mousectl *mctl;
Keyboardctl *kctl;
Mouse mv;
@@ -40,6 +39,12 @@ void flushedit(void);
void setedit(void);
void drawedit(void);
+struct {
+ Rectangle r;
+ Point scroll;
+ Point cur;
+} cells;
+
Table view;
void resizeview(Rectangle r);
@@ -100,11 +105,13 @@ void
_cell(Image *screen, Rectangle r, Image *brd, Image *bg, Image *fg, int t, Font *font, char *text)
{
Rectangle r2 = insetrect(r, t);
- int n = strlen(text);
- while (stringnwidth(font, text, n) > Dx(r2)) n--;
draw(screen, r, brd, nil, ZP);
draw(screen, r2, bg, nil, ZP);
- stringn(screen, addpt(r2.min, Pt(1,(Dy(r2) - font->height)/2)), fg, ZP, font, text, n);
+ if (text != nil) {
+ int n = strlen(text);
+ while (stringnwidth(font, text, n) > Dx(r2)) n--;
+ stringn(screen, addpt(r2.min, Pt(1,(Dy(r2) - font->height)/2)), fg, ZP, font, text, n);
+ }
}
void
@@ -113,11 +120,14 @@ drawcell(Point xy)
Image *cellbg = bg;
char *s = "";
int t = 1;
- if (eqpt(xy, cur) != 0) {
+ if (eqpt(xy, cells.cur) != 0) {
t = 2;
cellbg = curbg;
}
- Rectangle r = rectaddpt(cell, addpt(Pt(xy.x * cell.max.x, xy.y * cell.max.y), cells.min));
+ Rectangle r = rectaddpt(cell, addpt(Pt(
+ (xy.x - cells.scroll.x) * cell.max.x,
+ (xy.y - cells.scroll.y) * cell.max.y), cells.r.min));
+ if (ptinrect(r.min, cells.r) != 1) return;
char **v = getview(xy);
if ((v != nil) && (*v != nil)) s = *v;
_cell(screen, r, bord, cellbg, text, t, font, s);
@@ -130,21 +140,63 @@ resize(void)
screen->r.min,
Pt(screen->r.max.x, screen->r.min.y + font->height)
);
- cells = Rpt(
- addpt(screen->r.min, Pt(0, Dy(edit.r))),
+ blank = rectaddpt(cell, addpt(screen->r.min, Pt(0, Dy(edit.r))));
+ cells.r = Rpt(
+ blank.max,
screen->r.max
);
}
void
-redraw(void)
+drawcolumns(void)
+{
+ char buf[9];
+ buf[8] = '\0';
+ Rectangle r = rectaddpt(blank, Pt(Dx(cell), 0));
+ int x;
+ for (
+ x = cells.scroll.x;
+ rectXrect(r, screen->r) != 0;
+ x++, r = rectaddpt(r, Pt(Dx(cell), 0))) {
+ snprint(buf, 8, "%d", x);
+ _cell(screen, r, bord, curbg, text, 1, font, buf);
+ }
+}
+
+void
+drawrows(void)
+{
+ char buf[9];
+ int y;
+ buf[8] = '\0';
+ Rectangle r = rectaddpt(blank, Pt(0, Dy(cell)));
+ for (
+ y = cells.scroll.y;
+ rectXrect(r, screen->r) != 0;
+ y++, r = rectaddpt(r, Pt(0, Dy(cell)))) {
+ snprint(buf, 8, "%d", y);
+ _cell(screen, r, bord, curbg, text, 1, font, buf);
+ }
+}
+
+void
+drawcells(void)
{
int x, y, maxx, maxy;
- maxx = Dx(cells) / cell.max.x;
- maxy = Dy(cells) / cell.max.y;
- drawedit();
+ maxx = Dx(cells.r) / cell.max.x;
+ maxy = Dy(cells.r) / cell.max.y;
for (x = 0; x <= maxx; x++) for (y = 0; y <= maxy; y++)
- drawcell(Pt(x, y));
+ drawcell(Pt(x + cells.scroll.x, y + cells.scroll.y));
+}
+
+void
+redraw(void)
+{
+ drawedit();
+ draw(screen, blank, curbg, nil, ZP);
+ drawcolumns();
+ drawrows();
+ drawcells();
}
void
@@ -159,13 +211,21 @@ colors(void)
void
mouse(Mouse m)
{
+ enum { MFREE, MSELECT, MSCROLL, };
+ static state = MFREE;
+ static Point startxy, scroll;
+ if (m.buttons == 0) {
+ state = MFREE;
+ }
if (m.buttons == 1) {
- if (ptinrect(m.xy, cells) != 0) {
- Point mr = subpt(m.xy, cells.min);
- Point newcur = Pt(mr.x / cell.max.x, mr.y / cell.max.y);
- if ((cur.x != newcur.x) || (cur.y != newcur.y)) {
- Point oldcur = cur;
- cur = newcur;
+ state = MSELECT;
+ if (ptinrect(m.xy, cells.r) != 0) {
+ Point mr = subpt(m.xy, cells.r.min);
+ Point newcur = addpt(Pt(mr.x / cell.max.x, mr.y / cell.max.y), cells.scroll);
+ if ((cells.cur.x != newcur.x) || (cells.cur.y != newcur.y)) {
+ Point oldcur = cells.cur;
+ flushedit();
+ cells.cur = newcur;
drawcell(oldcur);
drawcell(newcur);
setedit();
@@ -173,8 +233,27 @@ mouse(Mouse m)
flushimage(display, 1);
}
}
+ } else if (m.buttons == 2) {
+ if (state != MSCROLL) {
+ state = MSCROLL;
+ startxy = m.xy;
+ scroll = cells.scroll;
+ }
+ Point diff = subpt(startxy, m.xy);
+ diff.x /= Dx(cell);
+ diff.y /= Dy(cell);
+ Point newscroll = addpt(scroll, diff);
+ if (newscroll.x < 0) newscroll.x = 0;
+ if (newscroll.y < 0) newscroll.y = 0;
+ if (eqpt(cells.scroll, newscroll) != 1) {
+ cells.scroll = newscroll;
+ drawcolumns();
+ drawrows();
+ drawcells();
+ flushimage(display, 1);
+ }
} else if (m.buttons == 4) {
- static char *items[] = {"load", "save", nil};
+ static char *items[] = {"load", "save", "exit", nil};
static Menu menu = {
items,
nil,
@@ -197,6 +276,9 @@ mouse(Mouse m)
savefile(strdup(buf));
}
break;
+ case 2: /* exit */
+ threadexitsall(nil);
+ break;
}
}
}
@@ -209,20 +291,20 @@ kbd(Rune r)
threadexitsall(nil);
case 0x0a: /* newline */
flushedit();
- cur.y++;
+ cells.cur.y++;
setedit();
drawedit();
- drawcell(cur);
- drawcell(subpt(cur, Pt(0,1)));
+ drawcell(cells.cur);
+ drawcell(subpt(cells.cur, Pt(0,1)));
flushimage(display, 1);
break;
case 0x09: /* tab */
flushedit();
- cur.x++;
+ cells.cur.x++;
setedit();
drawedit();
- drawcell(cur);
- drawcell(subpt(cur, Pt(1,0)));
+ drawcell(cells.cur);
+ drawcell(subpt(cells.cur, Pt(1,0)));
flushimage(display, 1);
break;
case 0x08: /* backspace */
@@ -257,7 +339,8 @@ init(void)
kctl = initkeyboard(nil);
cell = Rect(0, 0, stringwidth(font, "0") * 8 + 4, font->height + 4);
edit.str = s_new();
- cur = ZP;
+ cells.cur = ZP;
+ cells.scroll = Pt(5, 7);
setedit();
resize();
redraw();
@@ -299,17 +382,17 @@ threadmain(int argc, char **argv)
void
flushedit(void)
{
- char **v = getview(cur);
+ char **v = getview(cells.cur);
if ((v == nil) || (*v == nil) || (strcmp(s_to_c(edit.str), *v) != 0)) {
- if (strlen(s_to_c(edit.str)) != 0) setview(cur, strdup(s_to_c(edit.str)));
- else setview(cur, nil);
+ if (strlen(s_to_c(edit.str)) != 0) setview(cells.cur, strdup(s_to_c(edit.str)));
+ else setview(cells.cur, nil);
}
}
void
setedit(void)
{
- char **v = getview(cur);
+ char **v = getview(cells.cur);
s_reset(edit.str);
if ((v != nil) && (*v != nil)) s_append(edit.str, *v);
}
@@ -318,13 +401,11 @@ void
drawedit(void)
{
char buf[256];
- snprint(buf, 16, "[%d %d] ", cur.x, cur.y);
+ snprint(buf, 16, "[%d %d] ", cells.cur.x, cells.cur.y);
if (edit.str != nil) {
strncat(buf, s_to_c(edit.str), 256 - strlen(buf));
}
- _cell(screen, edit.r, bord, bg, text, 1, font, buf);
- //draw(screen, edit.r, curbg, nil, ZP);
- //string(screen, p, text, ZP, font, buf);
+ _cell(screen, edit.r, bord, curbg, text, 1, font, buf);
}
void