diff options
author | aiju <devnull@localhost> | 2014-07-30 15:57:14 +0200 |
---|---|---|
committer | aiju <devnull@localhost> | 2014-07-30 15:57:14 +0200 |
commit | 712fd30652d29dc9e936f11d7837d1cb079575fc (patch) | |
tree | 2915c820a5c05761f1d2ac4d525067f701aa474b /sys/src/cmd/spred/cmdw.c | |
parent | 555a05018b60b28bdfd6ada0310848c68fe20e48 (diff) |
added sprite editor spred
Diffstat (limited to 'sys/src/cmd/spred/cmdw.c')
-rw-r--r-- | sys/src/cmd/spred/cmdw.c | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/sys/src/cmd/spred/cmdw.c b/sys/src/cmd/spred/cmdw.c new file mode 100644 index 000000000..0c838d9aa --- /dev/null +++ b/sys/src/cmd/spred/cmdw.c @@ -0,0 +1,199 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include <thread.h> +#include <draw.h> +#include <mouse.h> +#include <frame.h> +#include "dat.h" +#include "fns.h" + +static int +cmdinit(Win *) +{ + return 0; +} + +static void +scrollbar(Win *w) +{ + int h, t0, t1; + + h = Dy(w->inner); + draw(w->im, rectaddpt(Rect(0, 0, SCRBSIZ+1, h), w->inner.min), w->tab->cols[BORD], nil, ZP); + t0 = w->toprune * h; + t1 = (w->toprune + w->fr.nchars) * h; + if(w->nrunes == 0){ + t0 = 0; + t1 = h; + }else{ + t0 /= w->nrunes; + t1 /= w->nrunes; + } + draw(w->im, rectaddpt(Rect(0, t0, SCRBSIZ, t1), w->inner.min), w->tab->cols[BACK], nil, ZP); +} + +static void +cmddraw(Win *w) +{ + Rectangle r; + + frclear(&w->fr, 0); + r = insetrect(w->inner, 1); + r.min.x += SCRTSIZ; + scrollbar(w); + frinit(&w->fr, r, display->defaultfont, w->im, w->tab->cols); + frinsert(&w->fr, w->runes + w->toprune, w->runes + w->nrunes, 0); +} + +void +cmdscroll(Win *w, int l) +{ + int r; + + if(l == 0) + return; + if(l > 0){ + for(r = w->toprune; r < w->nrunes && l != 0; r++) + if(w->runes[r] == '\n') + l--; + frdelete(&w->fr, 0, r - w->toprune); + w->toprune = r; + }else{ + for(r = w->toprune; r > 0; r--) + if(w->runes[r] == '\n' && --l == 0) + break; + frinsert(&w->fr, w->runes + r, w->runes + w->toprune, 0); + w->toprune = r; + } + scrollbar(w); +} + +static void +cmdclick(Win *w, Mousectl *mc) +{ + if(mc->xy.x <= w->inner.min.x + SCRBSIZ){ + cmdscroll(w, -5); + return; + } + frselect(&w->fr, mc); +} + +static int +cmdrmb(Win *w, Mousectl *mc) +{ + if(mc->xy.x > w->inner.min.x + SCRBSIZ) + return -1; + cmdscroll(w, 5); + return 0; +} + +void +cmdinsert(Win *w, Rune *r, int nr, int rp) +{ + Rune *s; + + if(nr < 0) + for(nr = 0, s = r; *s++ != 0; nr++) + ; + if(rp < 0 || rp > w->nrunes) + rp = w->nrunes; + if(w->nrunes + nr > w->arunes){ + w->runes = realloc(w->runes, w->arunes = w->arunes + (nr + RUNEBLK - 1) & ~(RUNEBLK - 1)); + if(w->runes == nil) + sysfatal("realloc: %r"); + } + if(rp != w->nrunes) + memmove(w->runes + rp, w->runes + rp + nr, (w->nrunes - rp) * sizeof(Rune)); + memmove(w->runes + rp, r, nr * sizeof(Rune)); + w->nrunes += nr; + if(w->toprune > rp) + w->toprune += nr; + else{ + frinsert(&w->fr, w->runes + rp, w->runes + rp + nr, rp - w->toprune); + if(rp == w->nrunes - nr){ + if(w->fr.lastlinefull) + cmdscroll(w, 1); + } + } +} + +static void +cmddel(Win *w, int a, int b) +{ + if(a >= b) + return; + memmove(w->runes + a, w->runes + b, w->nrunes - b); + w->nrunes -= b - a; + if(w->toprune >= b) + w->toprune -= b - a; + else{ + frdelete(&w->fr, a - w->toprune, b - w->toprune); + if(w->toprune >= a) + w->toprune = a; + } +} + +static void +cmdkey(Win *w, Rune r) +{ + static char buf[4096]; + char *p; + Rune *q; + + if(w->fr.p0 < w->fr.p1) + cmddel(w, w->toprune + w->fr.p0, w->toprune + w->fr.p1); + switch(r){ + case 0x00: + case 0x1b: + break; + case '\b': + if(w->fr.p0 > 0) + cmddel(w, w->toprune + w->fr.p0 - 1, w->toprune + w->fr.p0); + break; + case '\n': + cmdinsert(w, &r, 1, w->fr.p0 + w->toprune); + if(w->toprune + w->fr.p0 == w->nrunes){ + q = w->runes + w->toprune + w->fr.p0 - 1; + p = buf; + while(*--q != 0xa && q > w->runes) + ; + if(*q == 0xa) + q++; + while(q < w->runes + w->nrunes && p < buf + nelem(buf) + 1 && *q != 0xa) + p += runetochar(p, q++); + *p = 0; + docmd(buf); + } + break; + default: + cmdinsert(w, &r, 1, w->fr.p0 + w->toprune); + } +} + +void +cmdprint(char *fmt, ...) +{ + Rune *r; + va_list va; + + va_start(va, fmt); + r = runevsmprint(fmt, va); + va_end(va); + if(r != nil) + cmdinsert(cmdw, r, -1, -1); +} + +Wintab cmdtab = { + .init = cmdinit, + .draw = cmddraw, + .click = cmdclick, + .rmb = cmdrmb, + .key = cmdkey, + .hexcols = { + [BORD] DPurpleblue, + [DISB] 0xCCCCEEFF, + [BACK] 0xCCFFFFFF, + [HIGH] DPalegreygreen + } +}; |