From 1024676bc6ad5ef8b073cefd5da22c89dbb59dde Mon Sep 17 00:00:00 2001 From: rodri Date: Sun, 14 Jun 2020 19:54:18 +0000 Subject: now it's possible to paint on any given layer. also changed worldrf. --- canvas.c | 25 +++++++++------- dat.h | 3 ++ fns.h | 9 ++++-- layer.c | 17 ++++------- main.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++------------- mkfile | 1 + 6 files changed, 112 insertions(+), 42 deletions(-) diff --git a/canvas.c b/canvas.c index abd0089..d2632bb 100644 --- a/canvas.c +++ b/canvas.c @@ -5,17 +5,8 @@ #include "dat.h" #include "fns.h" -static int -alphachan(ulong chan) -{ - for(; chan; chan >>= 8) - if(TYPE(chan) == CAlpha) - return 1; - return 0; -} - Canvas* -newcanvas(Point2 p, Rectangle r, ulong chan) +newcanvas(char *name, Point2 p, Rectangle r, ulong chan) { Canvas *c; @@ -23,9 +14,23 @@ newcanvas(Point2 p, Rectangle r, ulong chan) c->p = p; c->bx = Vec2(1,0); c->by = Vec2(0,1); + c->name = strdup(name); c->image = eallocimage(display, r, chan, 0, alphachan(chan)? DTransparent: DNofill); memset(&c->layers, 0, sizeof(Layer)); c->layers.next = &c->layers; c->layers.prev = &c->layers; + c->curlayer = nil; return c; } + +void +rmcanvas(Canvas *c) +{ + Layer *l; + + for(l = c->layers.next; l != &c->layers; l = l->next) + rmlayer(l); + freeimage(c->image); + free(c->name); + free(c); +} diff --git a/dat.h b/dat.h index b913602..ce1cd64 100644 --- a/dat.h +++ b/dat.h @@ -4,6 +4,7 @@ typedef struct Canvas Canvas; struct Layer { RFrame; + char *name; Image *image; Layer *prev, *next; }; @@ -11,6 +12,8 @@ struct Layer struct Canvas { RFrame; + char *name; Image *image; Layer layers; + Layer *curlayer; }; diff --git a/fns.h b/fns.h index 6667415..cd9b91e 100644 --- a/fns.h +++ b/fns.h @@ -4,8 +4,13 @@ void *erealloc(void*, ulong); Image *eallocimage(Display*, Rectangle, ulong, int, ulong); /* canvas */ -Canvas *newcanvas(Point2, Rectangle, ulong); +Canvas *newcanvas(char*, Point2, Rectangle, ulong); +void rmcanvas(Canvas*); /* layer */ -Layer *newlayer(Canvas*); +Layer *newlayer(char*, Canvas*); void rmlayer(Layer*); + +/* utils */ +double fclamp(double, double, double); +int alphachan(ulong); diff --git a/layer.c b/layer.c index e3a389d..77584bc 100644 --- a/layer.c +++ b/layer.c @@ -5,17 +5,8 @@ #include "dat.h" #include "fns.h" -static int -alphachan(ulong chan) -{ - for(; chan; chan >>= 8) - if(TYPE(chan) == CAlpha) - return 1; - return 0; -} - Layer* -newlayer(Canvas *c) +newlayer(char *name, Canvas *c) { Layer *l; @@ -23,11 +14,14 @@ newlayer(Canvas *c) l->p = Pt2(0,0,1); l->bx = c->bx; l->by = c->by; - l->image = eallocimage(display, c->image->r, c->image->chan, 0, alphachan(c->image->chan)? DTransparent: DNofill); + l->name = strdup(name); + l->image = eallocimage(display, c->image->r, c->image->chan, 0, 0); l->prev = c->layers.prev; l->next = &c->layers; c->layers.prev->next = l; c->layers.prev = l; + if(c->curlayer == nil) + c->curlayer = l; return l; } @@ -37,5 +31,6 @@ rmlayer(Layer *l) l->prev->next = l->next; l->next->prev = l->prev; freeimage(l->image); + free(l->name); free(l); } diff --git a/main.c b/main.c index dad91f1..720bc56 100644 --- a/main.c +++ b/main.c @@ -20,6 +20,8 @@ Image *pal[NCOLOR]; Image *background; Canvas *curcanvas; +void resized(void); + Point toscreen(Point2 p) { @@ -70,6 +72,8 @@ drawcanvas(Canvas *c) { Layer *l; + if(c == nil) + return; for(l = c->layers.next; l != &c->layers; l = l->next) drawlayer(c, l); draw(screen, rectaddpt(c->image->r, toscreen(c->p)), c->image, nil, ZP); @@ -81,23 +85,11 @@ redraw(void) lockdisplay(display); draw(screen, screen->r, pal[PCBlack], nil, ZP); draw(screen, curcanvas == nil? screen->r: rectaddpt(curcanvas->image->r, toscreen(curcanvas->p)), background, nil, ZP); - if(curcanvas != nil) - drawcanvas(curcanvas); + drawcanvas(curcanvas); flushimage(display, 1); unlockdisplay(display); } -void -resized(void) -{ - lockdisplay(display); - if(getwindow(display, Refnone) < 0) - sysfatal("resize failed"); - unlockdisplay(display); - worldrf.p = Pt2(screen->r.min.x,screen->r.max.y,1); - redraw(); -} - void rmb(Mousectl *mc, Keyboardctl *kc) { @@ -114,6 +106,7 @@ rmb(Mousectl *mc, Keyboardctl *kc) char buf[256], chanstr[9+1], *s; ulong w, h, chan; Point2 cpos; + Layer *l; switch(menuhit(3, mc, &menu, nil)){ case NEW: @@ -124,20 +117,77 @@ rmb(Mousectl *mc, Keyboardctl *kc) w = strtoul(buf, &s, 10); h = strtoul(s, &s, 10); chan = strtochan(s); - cpos = Pt2(Dx(screen->r)/2 - w/2,Dy(screen->r)/2 + h/2,1); - curcanvas = newcanvas(cpos, Rect(0,0,w,h), chan); + cpos = Pt2(Dx(screen->r)/2 - w/2,Dy(screen->r)/2 - h/2,1); + curcanvas = newcanvas("default", cpos, Rect(0,0,w,h), chan); + fprint(2, "created canvas %s\n", curcanvas->name); break; case NEWLAYER: if(curcanvas == nil) break; - newlayer(curcanvas); + buf[0] = 0; + while(strlen(buf) == 0) + enter("layer name", buf, sizeof buf, mc, kc, nil); + l = newlayer(buf, curcanvas); + fprint(2, "created layer %s\n", l->name); break; } } +static char* +genlayeritem(int idx) +{ + Layer *l; + + l = curcanvas->layers.next; + while(l != &curcanvas->layers && idx--) + l = l->next; + if(l == &curcanvas->layers) + return nil; + return l->name; +} + +void +mmb(Mousectl *mc, Keyboardctl *) +{ + static Menu menu = { .gen = genlayeritem }; + int layeridx; + Layer *l; + + if(curcanvas == nil) + return; + layeridx = menuhit(2, mc, &menu, nil); + if(layeridx >= 0){ + l = curcanvas->layers.next; + while(l != &curcanvas->layers && layeridx--) + l = l->next; + curcanvas->curlayer = l; + fprint(2, "curlayer %s\n", l->name); + } +} + +void +lmb(Mousectl *mc, Keyboardctl *) +{ + Rectangle r; + Point2 mpos; + Point p; + + if(curcanvas == nil) + return; + r = Rect(0,0,1,1); + mpos = fromscreen(mc->xy); + mpos = rframexform(mpos, *curcanvas); + p = Pt(mpos.x,mpos.y); + draw(curcanvas->curlayer->image, rectaddpt(r, p), pal[PCBlack], nil, ZP); +} + void mouse(Mousectl *mc, Keyboardctl *kc) { + if((mc->buttons&1) != 0) + lmb(mc, kc); + if((mc->buttons&2) != 0) + mmb(mc, kc); if((mc->buttons&4) != 0) rmb(mc, kc); } @@ -179,9 +229,9 @@ threadmain(int argc, char *argv[]) if((kc = initkeyboard(nil)) == nil) sysfatal("initkeyboard: %r"); - worldrf.p = Pt2(screen->r.min.x,screen->r.max.y,1); - worldrf.bx = Vec2(1, 0); - worldrf.by = Vec2(0,-1); + worldrf.p = Pt2(screen->r.min.x,screen->r.min.y,1); + worldrf.bx = Vec2(1,0); + worldrf.by = Vec2(0,1); initpalette(); background = mkcheckerboard(4, 4); @@ -213,3 +263,14 @@ threadmain(int argc, char *argv[]) redraw(); } } + +void +resized(void) +{ + lockdisplay(display); + if(getwindow(display, Refnone) < 0) + sysfatal("resize failed"); + unlockdisplay(display); + worldrf.p = Pt2(screen->r.min.x,screen->r.min.y,1); + redraw(); +} diff --git a/mkfile b/mkfile index e83852c..5fa680c 100644 --- a/mkfile +++ b/mkfile @@ -3,6 +3,7 @@ BIN=/$objtype/bin TARG=puppeteer OFILES=\ + utils.$O\ alloc.$O\ layer.$O\ canvas.$O\ -- cgit v1.2.3