commit 5ca0d55f8ec8ac5833afdef4eea3f8eb31add7b4
parent 250d761b1b676c0daf8b9af6805416d4b99ca9c1
Author: Pavel Renev <an2qzavok@gmail.com>
Date: Sun, 4 Oct 2020 18:19:54 +0000
implemented cursor
Diffstat:
M | sss.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)
+{
+}