commit 4527308533b5f09c3a0c383177be6a93312471df
parent 72d7d4897d2f50c80daa55551156b483b69661d7
Author: Renev Pavel <an2qzavok@gmail.com>
Date: Tue, 29 Nov 2022 01:15:17 +0000
tabul: refactor, file saving
Diffstat:
M | src/tabul/tabul.c | | | 229 | ++++++++++++++++++++++++++++++++++++++++++++++++------------------------------- |
1 file changed, 138 insertions(+), 91 deletions(-)
diff --git a/src/tabul/tabul.c b/src/tabul/tabul.c
@@ -11,16 +11,12 @@
#include <keyboard.h>
#include <mouse.h>
-typedef struct Ed Ed;
-
-struct Ed {
- Ed *prev;
- int x;
- int y;
- char *s;
+typedef struct Table Table;
+struct Table{
+ Rectangle r;
+ char **s;
};
-Ed *head;
Image *bord, *text, *bg, *curbg;
Rectangle cell, cells;
Point cur;
@@ -40,30 +36,16 @@ struct {
String *str;
} edit;
-Ed *
-ed(Ed *parent, int x, int y, char *s)
-{
- Ed *e = malloc(sizeof(Ed));
- *e = (Ed){parent, x, y, s};
- return e;
-}
+void flushedit(void);
+void setedit(void);
+void drawedit(void);
+Table view;
-void
-freeed(Ed *e)
-{
- if (e != nil) free(e->s), free(e);
-}
-
-
-Ed *
-getcell(Point p)
-{
- Ed *ep = head;
- while ((ep != nil) && ((ep->x != p.x) || (ep->y != p.y)))
- ep = ep->prev;
- return ep;
-}
+void resizeview(Rectangle r);
+void clearview(void);
+void setview(Point xy, char *s);
+char ** getview(Point xy);
void
loadfile(char *newfile)
@@ -80,7 +62,7 @@ loadfile(char *newfile)
while( (s = Brdstr(b, '\n', 1)) != nil ) {
n = getfields(s, args, 64, 0, "\t");
for (x = 0; x < n; x++) {
- head = ed(head, x, y, strdup(args[x]));
+ if (strlen(args[x]) != 0) setview(Pt(x, y), strdup(args[x]));
};
free(s);
y++;
@@ -89,54 +71,39 @@ loadfile(char *newfile)
}
void
-savefile(char *)
+savefile(char *newfile)
{
- // find max xy in ed list
- // alloc char * array of the max xy size
- // loop through eds and apply ed's xy to array xy
- // print array to file, adding tabs and newlines as necessary
-}
-
-void
-flushedit(void)
-{
- Ed *ep = getcell(cur);
- if (strcmp(s_to_c(edit.str), ep->s) != 0)
- head = ed(head, cur.x, cur.y, strdup(s_to_c(edit.str)));
-}
-
-void
-setedit(void)
-{
- Ed *ep = getcell(cur);
- s_reset(edit.str);
- if (ep != nil) s_append(edit.str, ep->s);
+ // TODO clean up trainling whitespace (tabs and newlines)
+ // TODO switch over to bio
+ int fd = create(newfile, OWRITE, 0666);
+ if (fd < 0) {
+ fprint(2, "savefile: %r\n");
+ return;
+ }
+ free(file);
+ file = newfile;
+ int x, y;
+ for (y = view.r.min.y; y < view.r.max.y; y++) {
+ for (x = view.r.min.x; x < view.r.max.x; x++) {
+ char **v = getview(Pt(x, y));
+ if (x != view.r.min.x) fprint(fd, "\t");
+ if ((v != nil) && (*v != nil)) fprint(fd, "%s", *v);
+ }
+ fprint(fd, "\n");
+ }
+ close(fd);
}
void
-drawcell(int x, int y)
+drawcell(Point xy)
{
- Ed *ep;
Image *cellbg = bg;
- if ((x == cur.x) && (y == cur.y)) cellbg = curbg;
- Rectangle r = rectaddpt(cell, addpt(Pt(x * cell.max.x, y * cell.max.y), cells.min));
+ if (eqpt(xy, cur) != 0) cellbg = curbg;
+ Rectangle r = rectaddpt(cell, addpt(Pt(xy.x * cell.max.x, xy.y * cell.max.y), cells.min));
draw(screen, r, bord, nil, ZP);
draw(screen, insetrect(r, 1), cellbg, nil, ZP);
- ep = getcell(Pt(x, y));
- if (ep != nil) stringn(screen, addpt(r.min, Pt(3, 3)), text, ZP, font, ep->s, 8);
-}
-
-void
-drawedit(void)
-{
- char buf[256];
- snprint(buf, 16, "[%d %d] ", cur.x, cur.y);
- draw(screen, edit.r, curbg, nil, ZP);
- Point p = edit.r.min;
- if (edit.str != nil) {
- strncat(buf, s_to_c(edit.str), 256 - strlen(buf));
- }
- string(screen, p, text, ZP, font, buf);
+ char **v = getview(xy);
+ if ((v != nil) && (*v != nil)) stringn(screen, addpt(r.min, Pt(3, 3)), text, ZP, font, *v, 8);
}
void
@@ -160,7 +127,7 @@ redraw(void)
maxy = Dy(cells) / cell.max.y;
drawedit();
for (x = 0; x <= maxx; x++) for (y = 0; y <= maxy; y++)
- drawcell(x, y);
+ drawcell(Pt(x, y));
}
void
@@ -182,8 +149,8 @@ mouse(Mouse m)
if ((cur.x != newcur.x) || (cur.y != newcur.y)) {
Point oldcur = cur;
cur = newcur;
- drawcell(oldcur.x, oldcur.y);
- drawcell(newcur.x, newcur.y);
+ drawcell(oldcur);
+ drawcell(newcur);
setedit();
drawedit();
flushimage(display, 1);
@@ -200,19 +167,15 @@ mouse(Mouse m)
buf[0] = '\0';
if (file != nil) strncat(buf, file, 1024);
switch (menuhit(3, mctl, &menu, nil)) {
- case 0:
+ case 0: /* load */
if (enter("load", buf, 1024, mctl, kctl, nil) > 0) {
- while (head != nil) {
- Ed *prev = head->prev;
- freeed(head);
- head = prev;
- }
+ clearview();
loadfile(strdup(buf));
redraw();
flushimage(display, 1);
}
break;
- case 1:
+ case 1: /* save */
if (enter("save", buf, 1024, mctl, kctl, nil) > 0) {
savefile(strdup(buf));
}
@@ -229,7 +192,7 @@ kbd(Rune r)
threadexitsall(nil);
case 0x0a: /* newline */
flushedit();
- drawcell(cur.x, cur.y);
+ drawcell(cur);
flushimage(display, 1);
break;
case 0x09: /* tab */
@@ -237,8 +200,8 @@ kbd(Rune r)
cur.x++;
setedit();
drawedit();
- drawcell(cur.x, cur.y);
- drawcell(cur.x-1, cur.y);
+ drawcell(cur);
+ drawcell(subpt(cur, Pt(1,1)));
flushimage(display, 1);
break;
case 0x08: /* backspace */
@@ -256,6 +219,14 @@ kbd(Rune r)
}
}
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s [tsv_file]\n", argv0);
+ threadexitsall("usage");
+}
+
void
init(void)
{
@@ -273,13 +244,6 @@ init(void)
}
void
-usage(void)
-{
- fprint(2, "usage: %s [tsv_file]\n", argv0);
- threadexitsall("usage");
-}
-
-void
threadmain(int argc, char **argv)
{
ARGBEGIN {
@@ -310,3 +274,86 @@ threadmain(int argc, char **argv)
}
}
}
+
+void
+flushedit(void)
+{
+ char **v = getview(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);
+ }
+}
+
+void
+setedit(void)
+{
+ char **v = getview(cur);
+ s_reset(edit.str);
+ if ((v != nil) && (*v != nil)) s_append(edit.str, *v);
+}
+
+void
+drawedit(void)
+{
+ char buf[256];
+ snprint(buf, 16, "[%d %d] ", cur.x, cur.y);
+ draw(screen, edit.r, curbg, nil, ZP);
+ Point p = edit.r.min;
+ if (edit.str != nil) {
+ strncat(buf, s_to_c(edit.str), 256 - strlen(buf));
+ }
+ string(screen, p, text, ZP, font, buf);
+}
+
+void
+resizeview(Rectangle r)
+{
+ char **s = mallocz(sizeof(char *) * Dx(r) * Dy(r), 1);
+ int x, y;
+ for (x = r.min.x; x < r.max.x; x++)
+ for (y = r.min.x; y < r.max.y; y++) {
+ int i = x - r.min.x + y * Dx(r);
+ char **v = getview(Pt(x, y));
+ s[i] = (v == nil) ? nil : *v;
+ }
+ free(view.s);
+ view.r = r;
+ view.s = s;
+}
+
+void
+clearview(void)
+{
+ int i;
+ if ((view.s == nil) || (Dx(view.r) * Dy(view.r) == 0)) return;
+ for (i = 0; i < Dx(view.r) * Dy(view.r); i++) {
+ free(view.s[i]);
+ view.s[i] = nil;
+ }
+}
+
+void
+setview(Point xy, char *s)
+{
+ Rectangle new = {
+ 0,
+ 0,
+ (xy.x >= view.r.max.x) ? xy.x + 1 : view.r.max.x,
+ (xy.y >= view.r.max.y) ? xy.y + 1 : view.r.max.y,
+ };
+ if (eqrect(new, view.r) == 0) {
+ resizeview(new);
+ }
+ char **v = getview(xy);
+ free(*v);
+ *v = s;
+}
+
+char **
+getview(Point xy)
+{
+ if ((view.s == nil) || (ptinrect(xy, view.r) == 0)) return nil;
+ int i = xy.x + xy.y * Dx(view.r);
+ return &view.s[i];
+}