commit 41d3cbadc1f2d6d470c8f5727fbfb32ccb0d1c2b
parent 05746a1dde99df53d5122c11b9244a4ee4246ba0
Author: Pavel Renev <an2qzavok@gmail.com>
Date: Sat, 26 Sep 2020 18:24:55 +0000
implement basic cell editing and scrolling.
Diffstat:
M | README | | | 10 | +++++++++- |
M | cells.c | | | 28 | ++++++++++++++-------------- |
M | sss.c | | | 140 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------- |
3 files changed, 125 insertions(+), 53 deletions(-)
diff --git a/README b/README
@@ -1 +1,8 @@
-spreadsheets for plan9
+ssss - SuperSpreadsheet64, a spreadsheets program for plan9 operating
+system.
+
+# UI
+
+Look around by pressing middle mouse button and moving mouse around.
+
+Edit a cell by pressing right mouse button and entering new value.
+\ No newline at end of file
diff --git a/cells.c b/cells.c
@@ -40,7 +40,7 @@ mk_value(Addr addr, char *data)
void
free_value(Value v)
{
- free(v.data);
+ if (v.data != 0) free(v.data);
}
/*** TABLE ***/
@@ -117,9 +117,10 @@ table_get(Table T, Addr addr)
{
Value **V, v;
v.addr = addr;
- v.data = "";
+ v.data = strdup("");
for (V = T; *V != nil; V++) {
if (addrcmp((*V)->addr, addr) == 0) {
+ free(v.data);
v.data = strdup((*V)->data);
break;
}
@@ -132,35 +133,35 @@ table_read(char *path)
{
Table T, N;
char b, *buf;
- long bufsize, col, row;
+ long bufsize, x, y;
int fd;
- T = empty_table();
+ N = T = empty_table();
bufsize = 0;
- col = 0;
+ x = 0;
buf = nil;
- row = 0;
+ y = 0;
fd = open(path, OREAD);
if (fd == 0) return nil;
while (read(fd, &b, 1) > 0) {
switch (b){
case '\t':
- N = table_put(T, mk_value(xy2addr(row, col), buf));
+ N = table_put(T, mk_value(xy2addr(x, y), buf));
free_table(T);
free(T);
T = N;
bufsize = 0;
buf = realloc(buf, 0);
- col++;
+ x++;
break;
case '\n':
- N = table_put(T, mk_value(xy2addr(row, col), buf));
+ N = table_put(T, mk_value(xy2addr(x, y), buf));
free_table(T);
free(T);
T = N;
bufsize = 0;
buf = realloc(buf, 0);
- row++;
- col = 0;
+ y++;
+ x = 0;
break;
default:
buf = realloc(buf, bufsize+2);
@@ -170,7 +171,7 @@ table_read(char *path)
}
}
if (buf != nil) {
- N = table_put(T, mk_value(xy2addr(row, col), buf));
+ N = table_put(T, mk_value(xy2addr(x, y), buf));
free_table(T);
free(T);
}
@@ -189,4 +190,4 @@ print_table(Table T)
for (i = 0; T[i] != nil; i++) {
print("%ld:%ld %s\n", T[i]->addr.x, T[i]->addr.y, T[i]->data);
}
-}
-\ No newline at end of file
+}
diff --git a/sss.c b/sss.c
@@ -19,8 +19,11 @@ Hist *hp;
int defcwidth, defcheight;
+
Image *Iborder, *Ibg, *Ifg, *Ibg2;
+Point view;
+
void usage(void);
void clear(void);
void draw_columns(void);
@@ -28,7 +31,8 @@ void draw_cells(void);
void draw_cell(Image*, Rectangle, Image*, Image*, Image*, char*, int);
void draw_rows(void);
void colors(void);
-void runcmd(Mousectl *mc, Keyboardctl *kc);
+void run_cmd(Mousectl *mc, Keyboardctl *kc);
+void edit_cell(Addr addr, Mousectl *mc, Keyboardctl *kc);
void
threadmain(int argc, char **argv)
@@ -38,11 +42,14 @@ threadmain(int argc, char **argv)
Mouse mv;
Rune kv;
int rv[2];
+ int mstate;
+ Mouse mv_old;
ARGBEGIN{
default:
usage();
break;
- }ARGEND;
+ }
+ ARGEND;
if(initdraw(0, 0, "Super Spreadsheet 64!") < 0)
sysfatal("inidraw failed: %r");
@@ -56,41 +63,73 @@ threadmain(int argc, char **argv)
{mc->resizec, rv, CHANRCV},
{0, 0, CHANEND},
};
-
+
colors();
+ mstate = 0;
+ view = ZP;
defcheight = font->height + 4;
defcwidth = stringwidth(font, "01234567") + 4;
hp = malloc(sizeof(Hist));
- if (argc == 1) {
- fprint(2, "loading %s\n...", argv[0]);
- hp->T = table_read(argv[0]);
- }
+ if (argc == 1) hp->T = table_read(argv[0]);
else hp->T = empty_table();
if (hp->T == nil) exits("failed to create initial table");
clear();
+ draw_cells();
draw_columns();
draw_rows();
- draw_cells();
+ draw(screen, Rpt(screen->r.min, addpt(screen->r.min,
+ Pt(defcwidth, defcheight))), display->white, 0, ZP);
flushimage(display, 1);
for (;;) {
switch (alt(alts)) {
- case 0: /* keyboard */
- if (kv == 0x7f) threadexitsall(nil);
- runcmd(mc, kc);
- break;
- case 1: /* mouse */
- break;
- case 2: /* resize */
- if(getwindow(display, Refnone) < 0)
- sysfatal("resize failed: %r");
- clear();
+ case 0: /* keyboard */
+ if (kv == 0x7f) threadexitsall(nil);
+ run_cmd(mc, kc);
+ break;
+ case 1: /* mouse */
+ if (mv.buttons == 0){
+ mstate = 0;
+ }
+ if (mv.buttons == 2) mstate = 1;
+ if (mv.buttons == 4){
+ Addr a;
+ a.x = (mv.xy.x - view.x - screen->r.min.x)/defcwidth - 1;
+ a.y = (mv.xy.y - view.y - screen->r.min.y)/defcheight - 1;
+ edit_cell(a, mc, kc);
+ draw_cells();
draw_columns();
draw_rows();
+ draw(screen, Rpt(screen->r.min, addpt(screen->r.min,
+ Pt(defcwidth, defcheight))), display->white, 0, ZP);
+ flushimage(display, 1);
+ flushimage(display, 1);
+ }
+ if (mstate == 1){
+ view = addpt(view, subpt(mv.xy, mv_old.xy));
+ if (view.x > 0) view.x = 0;
+ if (view.y > 0) view.y = 0;
draw_cells();
+ draw_columns();
+ draw_rows();
+ draw(screen, Rpt(screen->r.min, addpt(screen->r.min,
+ Pt(defcwidth, defcheight))), display->white, 0, ZP);
flushimage(display, 1);
- break;
+ }
+ mv_old = mv;
+ break;
+ case 2: /* resize */
+ if(getwindow(display, Refnone) < 0)
+ sysfatal("resize failed: %r");
+ clear();
+ draw_cells();
+ draw_columns();
+ draw_rows();
+ draw(screen, Rpt(screen->r.min, addpt(screen->r.min,
+ Pt(defcwidth, defcheight))), display->white, 0, ZP);
+ flushimage(display, 1);
+ break;
}
}
}
@@ -113,7 +152,7 @@ usage(void)
void
clear(void)
{
- draw(screen, screen->r, display->black, 0, ZP);
+ draw(screen, screen->r, display->white, 0, ZP);
}
void
@@ -124,8 +163,8 @@ draw_columns(void)
long col;
char *colnum;
col = 0;
- pt = addpt(Pt(defcwidth, 0), screen->r.min);
- while (pt.x < screen->r.max.x - defcwidth + 1) {
+ pt = addpt(Pt(defcwidth + view.x, 0), screen->r.min);
+ while (pt.x < screen->r.max.x) {
r = rectaddpt(Rect(0, 0, defcwidth, defcheight), pt);
colnum = smprint("%ld", col);
draw_cell(screen, r, Ibg2, Iborder, Ifg, colnum, 0);
@@ -143,8 +182,8 @@ draw_rows(void)
long row;
char *colnum;
row = 0;
- pt = addpt(Pt(0, defcheight), screen->r.min);
- while (pt.y < screen->r.max.y - defcheight + 1) {
+ pt = addpt(Pt(0, defcheight + view.y), screen->r.min);
+ while (pt.y < screen->r.max.y) {
r = rectaddpt(Rect(0, 0, defcwidth, defcheight), pt);
colnum = smprint("%ld", row);
draw_cell(screen, r, Ibg2, Iborder, Ifg, colnum, 0);
@@ -174,7 +213,7 @@ draw_cell(Image *dst, Rectangle r, Image *bg, Image *brd, Image*fg, char *s, int
draw(dst, rb, brd, 0, ZP);
dx = (r.max.x - r.min.x - stringwidth(font,s));
if (align == 0) dx = dx / 2;
- if (align < 0) dx = 0;
+ if (align < 0) dx = 0;
string(dst, addpt(Pt(2 + dx, 2), r.min), fg, ZP, font, s);
}
@@ -184,34 +223,59 @@ draw_cells(void)
{
Point pt;
Rectangle r;
- long col, row;
+ long x, y;
char *text;
Value v;
- col = 0;
- row = 0;
+ x = 0;
+ y = 0;
pt = addpt(Pt(defcwidth, defcheight), screen->r.min);
- while (pt.y < screen->r.max.y - defcheight + 1){
+ pt = addpt(pt, view);
+ while (pt.y < screen->r.max.y){
r = rectaddpt(Rect(0,0,defcwidth, defcheight), pt);
- v = table_get(hp->T, xy2addr(row, col));
+ v = table_get(hp->T, xy2addr(x, y));
text = v.data;
draw_cell(screen, r, Ibg, Iborder, Ifg, text, -1);
pt.x += defcwidth;
- col++;
- if (pt.x > screen->r.max.x - defcwidth + 1){
- pt.x = screen->r.min.x + defcwidth;
+ x++;
+ if (pt.x > screen->r.max.x){
+ pt.x = screen->r.min.x + defcwidth + view.x;
pt.y += defcheight;
- row++;
- col = 0;
+ y++;
+ x = 0;
}
}
}
void
-runcmd(Mousectl *mc, Keyboardctl *kc)
+run_cmd(Mousectl *mc, Keyboardctl *kc)
{
char buf[1024];
*buf = 0;
- enter("cmd: ", buf, 1024, mc, kc, 0);
-
+ enter("cmd:", buf, 1024, mc, kc, 0);
+
+}
+
+void
+edit_cell(Addr addr, Mousectl *mc, Keyboardctl *kc)
+{
+ Value v;
+ char prompt[256], buf[1024];
+ struct Hist *hn;
+ snprint(prompt, 256, "%ld,%ld:", addr.x, addr.y);
+ v = table_get(hp->T, addr);
+ *buf = 0;
+ if (v.data != 0) strncat(buf, v.data, 1024);
+ if (enter(prompt, buf, 1024, mc, kc, 0) < 0) {
+ free_value(v);
+ return;
+ }
+ if (strcmp(v.data, buf) == 0){
+ free_value(v);
+ return;
+ }
+ hn = malloc(sizeof(struct Hist));
+ hn->prev = hp;
+ hn->T = table_put(hp->T, mk_value(addr, buf));
+ hp = hn;
}