sss

spreadsheets for plan9
git clone git://nsmpr.xyz/sss.git
Log | Files | Refs | README

commit 5ca0d55f8ec8ac5833afdef4eea3f8eb31add7b4
parent 250d761b1b676c0daf8b9af6805416d4b99ca9c1
Author: Pavel Renev <an2qzavok@gmail.com>
Date:   Sun,  4 Oct 2020 18:19:54 +0000

implemented cursor

Diffstat:
Msss.c | 218+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
1 file changed, 142 insertions(+), 76 deletions(-)

diff --git a/sss.c b/sss.c @@ -9,33 +9,53 @@ #include "stack.h" #include "cells.h" +/* cell drawing flags */ enum { - CENTER = 1, + CENTER = 1, HIGHLIGHT = 2, - SELECTED = 4, + SELECTED = 4, + CURSOR = 8, }; Stack *hp, *hr; Stack *T; -Stack *selection; + +struct Selection { + Stack *rows; + Stack *cols; + Stack *cells; + Addr cursor; +} selection; int defcwidth, defcheight; +int mstate; enum { BG, HG, FG, BR }; - Image *Inorm[4], *Isel[4]; Point view; +Rectangle rcells, rrows, rcols, rlbar, rbbar; + +void (*mousefunc)(Mouse); + +Mousectl *mc; +Keyboardctl *kc; + void usage(void); +void calc_rects(void); +void cell_primitive(Image *dst, Rectangle r, char *s, int flag); void clear(void); void draw_columns(void); void draw_cells(void); -void draw_cell(Image*, Rectangle, char*, int); +void draw_cell(Addr); void draw_rows(void); void colors(void); +void mousecells(Mouse); +void mousecols(Mouse); +void mouserows(Mouse); void run_cmd(Mousectl *mc, Keyboardctl *kc); -void edit_cell(Addr addr, Mousectl *mc, Keyboardctl *kc); +void edit_cell(Addr addr); Value* hist_get_value(Stack*, Addr); Addr mouse2addr(Point); int is_selected(Addr); @@ -43,12 +63,9 @@ int is_selected(Addr); void threadmain(int argc, char **argv) { - Mousectl *mc; - Keyboardctl *kc; Mouse mv; Rune kv; int rv[2]; - int mstate; Mouse mv_old; ARGBEGIN{ default: @@ -63,25 +80,22 @@ threadmain(int argc, char **argv) sysfatal("initmouse failed: %r"); if((kc = initkeyboard(0)) == nil) sysfatal("initkeyboard failed: %r"); - Alt alts[4] = { - {kc->c, &kv, CHANRCV}, - {mc->c, &mv, CHANRCV}, - {mc->resizec, rv, CHANRCV}, - {0, 0, CHANEND}, - }; colors(); + mousefunc = nil; mstate = 0; view = ZP; defcheight = font->height + 4; defcwidth = stringwidth(font, "01234567") + 4; - if (argc == 1) T = table_read(argv[0]); else T = newstack(); hp = newstack(); - selection = newstack(); + selection.cells = newstack(); + selection.cursor = xy2addr(0, 0); push(hp, T); + + calc_rects(); clear(); draw_cells(); draw_columns(); @@ -89,40 +103,32 @@ threadmain(int argc, char **argv) draw(screen, Rpt(screen->r.min, addpt(screen->r.min, Pt(defcwidth, defcheight))), display->white, 0, ZP); flushimage(display, 1); + + enum { KBD, MOUSE, RESIZE, CHEND }; + Alt alts[4] = { + [KBD] {kc->c, &kv, CHANRCV}, + [MOUSE] {mc->c, &mv, CHANRCV}, + [RESIZE] {mc->resizec, rv, CHANRCV}, + [CHEND] {0, 0, CHANEND}, + }; + for (;;) { switch (alt(alts)) { - case 0: /* keyboard */ + case KBD: if (kv == 0x7f) threadexitsall(nil); run_cmd(mc, kc); break; - case 1: /* mouse */ + case MOUSE: if (mv.buttons == 0){ mstate = 0; + if (ptinrect(mv.xy, rrows)) mousefunc = mouserows; + if (ptinrect(mv.xy, rcols)) mousefunc = mousecols; + if (ptinrect(mv.xy, rcells)) mousefunc = mousecells; } - if (mv.buttons == 1) { - while (selection->size > 0) { - free(pop(selection)); - } - Addr *a; - a = malloc(sizeof(Addr)); - *a = mouse2addr(mv.xy); - push(selection, a); - draw_cells(); - flushimage(display, 1); + else { + if (mousefunc != nil) mousefunc(mv); } if (mv.buttons == 2) mstate = 1; - if (mv.buttons == 4) { - Addr a; - a = mouse2addr(mv.xy); - 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; @@ -136,9 +142,10 @@ threadmain(int argc, char **argv) } mv_old = mv; break; - case 2: /* resize */ + case RESIZE: if(getwindow(display, Refnone) < 0) sysfatal("resize failed: %r"); + calc_rects(); clear(); draw_cells(); draw_columns(); @@ -152,6 +159,32 @@ threadmain(int argc, char **argv) } void +cell_primitive(Image *dst, Rectangle r, char *s, int flag) +{ + Rectangle rr; + Image **Ipal, *Ibg, *Ibr; + int selected, center, cursor, high; + int dx; + selected = flag & SELECTED; + center = flag & CENTER; + high = flag & HIGHLIGHT; + cursor = flag & CURSOR; + Ipal = selected ? Isel : Inorm; + Ibg = high ? Ipal[HG] : Ipal[BG]; + Ibr = Ipal[BR]; + rr = Rpt(addpt(r.min, Pt(1,1)), subpt(r.max, Pt(1,1))); + if (cursor != 0) { + Ibr = Ipal[FG]; + rr = Rpt(addpt(r.min, Pt(2,2)), subpt(r.max, Pt(2,2))); + } + dx = 0; + if (center != 0) dx = (rr.max.x - rr.min.x - stringwidth(font, s)) / 2; + draw(dst, r, Ibr, 0, ZP); + draw(dst, rr, Ibg, 0, ZP); + string(dst, addpt(Pt(2 + dx, 2), r.min), Ipal[FG], ZP, font, s); +} + +void colors(void) { Inorm[BG] = allocimage(display, Rect(0,0,1,1), RGBA32, 1, 0xFFFFFFFF); @@ -173,6 +206,16 @@ usage(void) } void +calc_rects(void) +{ + Rectangle r; + r = screen->r; + rrows = Rect(r.min.x, r.min.y + defcheight, r.min.x + defcwidth, r.max.y); + rcols = Rect(r.min.x + defcwidth, r.min.y, r.max.x, r.min.y + defcheight); + rcells = Rect(r.min.x + defcwidth, r.min.y + defcheight, r.max.x, r.max.y); +} + +void clear(void) { draw(screen, screen->r, display->white, 0, ZP); @@ -191,7 +234,7 @@ draw_columns(void) if (pt.x >= screen->r.min.x) { r = rectaddpt(Rect(0, 0, defcwidth, defcheight), pt); colnum = smprint("%ld", col); - draw_cell(screen, r, colnum, CENTER|HIGHLIGHT); + cell_primitive(screen, r, colnum, CENTER|HIGHLIGHT); free(colnum); } pt.x += defcwidth; @@ -212,7 +255,7 @@ draw_rows(void) if (pt.y >= screen->r.min.y) { r = rectaddpt(Rect(0, 0, defcwidth, defcheight), pt); rownum = smprint("%ld", row); - draw_cell(screen, r, rownum, CENTER|HIGHLIGHT); + cell_primitive(screen, r, rownum, CENTER|HIGHLIGHT); free(rownum); } pt.y += defcheight; @@ -221,43 +264,21 @@ draw_rows(void) } void -draw_cell(Image *dst, Rectangle r, char *s, int flag) +draw_cell(Addr addr) { - Rectangle rl, rr, rt, rb; - int dx; - Image **Ipal, *Ibg; - int center, selected, high; - center = flag & CENTER; - selected = flag & SELECTED; - high = flag & HIGHLIGHT; - Ipal = selected ? Isel : Inorm; - Ibg = high ? Ipal[HG] : Ipal[BG]; - rl = r; - rr = r; - rt = r; - rb = r; - rl.max.x = rl.min.x + 1; - rr.min.x = rr.max.x - 1; - rt.max.y = rt.min.y + 1; - rb.min.y = rb.max.y - 1; - draw(dst, r, Ibg, 0, ZP); - draw(dst, rl, Ipal[BR], 0, ZP); - draw(dst, rr, Ipal[BR], 0, ZP); - draw(dst, rt, Ipal[BR], 0, ZP); - draw(dst, rb, Ipal[BR], 0, ZP); - dx = 0; - if (center > 0) dx = (r.max.x - r.min.x - stringwidth(font,s)) / 2; - string(dst, addpt(Pt(2 + dx, 2), r.min), Ipal[FG], ZP, font, s); + } void draw_cells(void) { + // TODO: draw cursor Addr addr; Point pt; Rectangle r; long x, y; + int flag; char *text; Value *v; x = 0; @@ -271,7 +292,9 @@ draw_cells(void) v = hist_get_value(hp, addr); if (v == nil) text = ""; else text = v->data; - draw_cell(screen, r, text, is_selected(addr)); + flag = is_selected(addr); + if (addrcmp(addr, selection.cursor) == 0) flag |= CURSOR; + cell_primitive(screen, r, text, flag); }; pt.x += defcwidth; x++; @@ -295,7 +318,7 @@ run_cmd(Mousectl *mc, Keyboardctl *kc) } void -edit_cell(Addr addr, Mousectl *mc, Keyboardctl *kc) +edit_cell(Addr addr) { Value *v; Stack *N; @@ -344,9 +367,53 @@ is_selected(Addr addr) { long i; Addr *a; - for (i = 0; i < selection->size; i++) { - a = selection->data[i]; + for (i = 0; i < selection.cells->size; i++) { + a = selection.cells->data[i]; if (addrcmp(addr, *a) == 0) return SELECTED; } return 0; -} -\ No newline at end of file +} + + +void +mousecells(Mouse mv) +{ + Addr m; + m = mouse2addr(mv.xy); + if (mv.buttons == 1) { + if (mstate == 0) { + mstate = 2; + + while (selection.cells->size > 0) { + free(pop(selection.cells)); + } + } + Addr *a; + a = malloc(sizeof(Addr)); + *a = m; + selection.cursor = m; + push(selection.cells, a); + draw_cells(); + flushimage(display, 1); + } + if (mv.buttons == 4) { + edit_cell(m); + 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); + } +} + +void +mousecols(Mouse mv) +{ +} + +void +mouserows(Mouse mv) +{ +}