summaryrefslogtreecommitdiff
path: root/sys/src/cmd/spred/cmdw.c
diff options
context:
space:
mode:
authoraiju <devnull@localhost>2014-07-30 15:57:14 +0200
committeraiju <devnull@localhost>2014-07-30 15:57:14 +0200
commit712fd30652d29dc9e936f11d7837d1cb079575fc (patch)
tree2915c820a5c05761f1d2ac4d525067f701aa474b /sys/src/cmd/spred/cmdw.c
parent555a05018b60b28bdfd6ada0310848c68fe20e48 (diff)
added sprite editor spred
Diffstat (limited to 'sys/src/cmd/spred/cmdw.c')
-rw-r--r--sys/src/cmd/spred/cmdw.c199
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
+ }
+};