shithub: blie

Download patch

ref: bb63f08a8acc62f17975b108c918f4ff20c1f2c0
parent: 2f61e9979e69ab014cdd44ea71fa787ea3454446
author: sirjofri <sirjofri@sirjofri.de>
date: Wed Sep 4 10:33:05 EDT 2024

changes to layer handling

- more common order of layers in layers window
- small toolbox in layers window
- p9image: move CSM buttons to lwin toolbox

--- a/blie.c
+++ b/blie.c
@@ -377,6 +377,8 @@
 		redrawdrawing();
 	if (w & Rtools)
 		redrawtools();
+	if (w & Rlayers)
+		redrawlayers(panels.layers, estate.l);
 }
 
 static void
@@ -394,7 +396,8 @@
 		drawcursor(m->xy, 1);
 		if (m->buttons) {
 			m->xy = subpt(m->xy, panels.layers->r.min);
-			clicklayer(*m, activatelayer);
+			n = clicklayer(ev, estate.l, panels.layers, activatelayer);
+			condredraw(n);
 		}
 		return;
 	}
--- a/blie.h
+++ b/blie.h
@@ -3,6 +3,13 @@
 typedef struct Vdata Vdata;
 typedef struct Vstate Vstate;
 
+typedef enum {
+	Rnil = 0,
+	Rdrawing = 1,
+	Rtools = 2,
+	Rlayers = 4,
+} Redrawwin;
+
 extern Vdata vdata;
 extern Vstate vstate;
 extern int bliedebug;
@@ -28,7 +35,7 @@
 void savelayermeta(Layer*);
 void dirtylayer(Layer*);
 void redrawlayers(Image*, Layer*);
-void clicklayer(Mouse, void (*f)(Layer*));
+Redrawwin clicklayer(Event, Layer*, Image*, void (*f)(Layer*));
 int foreachlayer(void (*f)(Layer*, int, int, void*), void*);
 
 void changecursor(Cursor*, Image*, Point);
@@ -69,12 +76,7 @@
 /* writes memimage to drawing image, considering pan and zoom using dirty flags */
 void sampleview(Image*, Memimage*, int quality);
 
-typedef enum {
-	Rnil = 0,
-	Rdrawing = 1,
-	Rtools = 2,
-} Redrawwin;
-
+/* see editor.txt */
 struct Editor {
 	char *name;
 	void (*init)(void);
@@ -85,8 +87,10 @@
 	int (*overlay)(Layer*, Image*);
 	Rectangle (*toolrect)(Layer*);
 	void (*drawtools)(Layer*, Image*);
+	void (*drawlwin)(Layer*, Image*, Rectangle);
 	Redrawwin (*drawinput)(Layer*, int, Event);
 	Redrawwin (*toolinput)(Layer*, int, Event);
+	Redrawwin (*lwininput)(Layer*, int, Event);
 	int (*savedata)(Layer*);
 	int (*savetools)(Layer*);
 };
--- a/editor.txt
+++ b/editor.txt
@@ -75,6 +75,18 @@
 image.
 
 
+FUNCTION drawlwin*
+
+param:  Layer*     Layer to work with
+param:  Image*     Image to draw layer window tools on
+param:  Rectangle  Rectangle to draw within
+
+This function is supposed to draw some mini editor into the
+layer representation of the given layer in the layer window.
+Consider using this for shortcut tools, mostly for visualization
+purposes or global layer-wide tools like alpha values.
+
+
 FUNCTION drawinput
 
 param:  Layer*     Layer to work with
@@ -98,6 +110,17 @@
 
 This function is analogous to drawinput, just for the tools
 window.
+
+
+FUNCTION lwininput
+
+param:  Layer*     Layer to work with
+param:  int        Event type (currently only Emouse)
+param:  Event      Event structure
+return: Redrawwin  Redraw parameters
+
+This function is analogous to drawinput, just for the small
+tools panel in the layers window.
 
 
 FUNCTION savedata
--- a/layer.c
+++ b/layer.c
@@ -15,6 +15,7 @@
 };
 
 List *firstlayer = nil;
+int numlayers = 0;
 
 static Drawop
 str2op(char *s)
@@ -85,6 +86,7 @@
 	f->next = mallocz(sizeof(List), 1);
 	f->next->layer = l;
 	l->num = f->layer->num + 1;
+	numlayers++;
 }
 
 void
@@ -225,7 +227,7 @@
 	Image *img;
 	Layer *active;
 	Point p;
-	Rectangle r;
+	Rectangle r, sr;
 	
 	data = (void**)aux;
 	img = data[0];
@@ -232,15 +234,25 @@
 	active = data[1];
 	
 	p = img->r.min;
-	p.y += n * layerheight;
+	p.y += numlayers * layerheight;
+	p.y -= n * layerheight;
 	
+	r.min = r.max = p;
+	r.max.x += vdata.layerwinwidth;
+	r.max.y += layerheight;
+	sr.min = Pt(r.min.x, r.max.y);
+	sr.max = r.max;
+	
 	if (l == active) {
-		r.min = r.max = p;
-		r.max.x += vdata.layerwinwidth;
-		r.max.y += layerheight;
 		draw(img, r, vdata.gray, nil, ZP);
 	}
 	string(img, addpt(p, Pt(2, 2)), display->black, ZP, font, l->label);
+	
+	if (l == active && l->editor && l->editor->drawlwin) {
+		r.min.y += vdata.fontheight;
+		l->editor->drawlwin(l, img, r);
+	}
+	line(img, sr.min, sr.max, Endsquare, Endsquare, 0, display->black, ZP);
 }
 
 void
@@ -249,7 +261,7 @@
 	void *data[2];
 	data[0] = img;
 	data[1] = active;
-	layerheight = vdata.fontheight + 10;
+	layerheight = vdata.fontheight + 20;
 	draw(img, img->r, display->white, nil, ZP);
 	foreachlayer(redrawlayer, data);
 	line(img, img->r.min, Pt(img->r.min.x, img->r.max.y),
@@ -262,25 +274,62 @@
 	void **a;
 	void (*factivate)(Layer*);
 	int *w;
+	Image *img;
+	Event *ev;
+	Layer *active;
+	Redrawwin *ret;
+	Rectangle r;
 	
 	a = (void**)aux;
 	factivate = a[0];
 	w = a[1];
+	img = a[2];
+	ev = a[3];
+	active = a[4];
+	ret = a[5];
 	
-	if (n == *w)
+	USED(img);
+	
+	if (n != *w)
+		return;
+	
+	if (l != active) {
 		factivate(l);
+		return;
+	}
+	r.min = r.max = ZP;
+	r.max.x = vdata.layerwinwidth;
+	r.min.y += numlayers * layerheight;
+	r.min.y -= n * layerheight;
+	r.max.y = r.min.y + layerheight;
+	r.min.y += vdata.fontheight;
+	
+	if (l->editor && l->editor->lwininput) {
+		if (ptinrect(ev->mouse.xy, r)) {
+			ev->mouse.xy.x -= r.min.x;
+			ev->mouse.xy.y -= r.min.y;
+			*ret |= l->editor->lwininput(l, Emouse, *ev);
+		}
+	}
 }
 
-void
-clicklayer(Mouse m, void (*f)(Layer*))
+Redrawwin
+clicklayer(Event ev, Layer *active, Image *img, void (*f)(Layer*))
 {
-	void *aux[2];
+	void *aux[6];
 	int d;
+	Redrawwin result;
 	
 	aux[0] = f;
 	aux[1] = &d;
+	aux[2] = img;
+	aux[3] = &ev;
+	aux[4] = active;
+	aux[5] = &result;
 	
-	d = m.xy.y / layerheight;
+	result = Rnil;
+	d = numlayers - ev.mouse.xy.y / layerheight;
 	
 	foreachlayer(checkclick, aux);
+	return result;
 }
--- a/p9image.c
+++ b/p9image.c
@@ -44,6 +44,8 @@
 Point toolcell;
 #define NUMCELLS (5)
 
+int lwinoffset = 10;
+
 Image *tmpcol;
 
 #define SLIST(DO) \
@@ -110,9 +112,7 @@
 static Brush*
 getcurrentbrush(void)
 {
-	if (tstate.curbrush < 4) /* three cells reserved */
-		return &tstate.brushes[3];
-	if (tstate.curbrush >= NUMCELLS)
+	if (tstate.curbrush > NUMCELLS || tstate.curbrush < 0)
 		return nil;
 	return &tstate.brushes[tstate.curbrush];
 }
@@ -190,8 +190,8 @@
 			*byteaddr(tstate.circlebrush, Pt(x, y)) = isaturate(n);
 		}
 	
-	tstate.brushes[3].i = tstate.circlebrush;
-	tstate.brushes[3].r = tstate.brushrad;
+	tstate.brushes[0].i = tstate.circlebrush;
+	tstate.brushes[0].r = tstate.brushrad;
 }
 
 static void
@@ -268,7 +268,7 @@
 	
 	setcirclebrush(20, 1., 1.);
 	setcolorbrush(DRed);
-	tstate.curbrush = 3;
+	tstate.curbrush = 0;
 	tstate.curcolor = -1;
 	
 	/* load tools */
@@ -335,7 +335,7 @@
 }
 
 static int
-p9writedata(Layer *l, Data *d)
+p9writedata(Layer*, Data *d)
 {
 	Db *db;
 	Dpack *dv;
@@ -392,7 +392,6 @@
 	Db *db;
 	Dpack *dv;
 	char *s;
-	int i;
 	
 	clog("readdata: %s", l->name);
 	
@@ -532,7 +531,7 @@
 }
 
 static Rectangle
-p9toolrect(Layer *l)
+p9toolrect(Layer*)
 {
 	return Rect(0, 0, 200, 50);
 }
@@ -543,6 +542,7 @@
 	Rectangle r;
 	r.min = p;
 	r.max = addpt(p, toolcell);
+	draw(i, r, display->white, nil, ZP);
 	border(i, r, 1, vdata.gray, ZP);
 	if (hl) {
 		r = insetrect(r, 2);
@@ -564,7 +564,7 @@
 }
 
 static void
-drbrush(Image *i, Point p, int n, int hl)
+drbrush(Image *i, Point p, int, int hl)
 {
 	Rectangle r;
 	r.min = p;
@@ -573,7 +573,7 @@
 }
 
 static void
-p9drawtools(Layer *l, Image *i)
+p9drawtools(Layer*, Image *i)
 {
 	int n;
 	Point p;
@@ -580,14 +580,7 @@
 	p = i->r.min;
 	draw(i, i->r, display->white, nil, ZP);
 	
-	drcells(i, p, "C", tstate.mode == Composite);
-	p.x += toolcell.x;
-	drcells(i, p, "S", tstate.mode == Img);
-	p.x += toolcell.x;
-	drcells(i, p, "M", tstate.mode == Mask);
-	p.x += toolcell.x;
-	
-	for (n = 3; n < NUMCELLS; n++) {
+	for (n = 0; n < NUMCELLS; n++) {
 		drbrush(i, p, n, tstate.curbrush == n);
 		p.x += toolcell.x;
 	}
@@ -728,6 +721,9 @@
 static void
 selectbrush(int num)
 {
+	if (num < 0 || num >= NUMCELLS)
+		return;
+	tstate.curbrush = num;
 }
 
 static void
@@ -741,6 +737,7 @@
 static void
 setbrush(int num)
 {
+	// TODO: implement (brush logic)
 }
 
 static void
@@ -778,7 +775,7 @@
 }
 
 static Redrawwin
-p9toolinput(Layer *l, int e, Event ev)
+p9toolinput(Layer*, int e, Event ev)
 {
 	Point xy;
 	if (e != Emouse)
@@ -786,23 +783,6 @@
 	
 	if (!ev.mouse.buttons)
 		return Rnil;
-	
-	if (ev.mouse.xy.y / toolcell.y == 0) {
-		switch (ev.mouse.xy.x / toolcell.x) {
-		case 0:
-			tstate.mode = Composite;
-			tstate.drawtarget = DTimg;
-			goto Out;
-		case 1:
-			tstate.mode = Img;
-			tstate.drawtarget = DTimg;
-			goto Out;
-		case 2:
-			tstate.mode = Mask;
-			tstate.drawtarget = DTmask;
-			goto Out;
-		}
-	}
 	xy.x = ev.mouse.xy.x / toolcell.x;
 	xy.y = ev.mouse.xy.y / toolcell.y;
 	
@@ -810,8 +790,6 @@
 		/* left mouse button */
 		switch (xy.y) {
 		case 0:
-			if (xy.x < 3)
-				return Rnil;
 			selectbrush(xy.x);
 			return Rtools;
 		case 1:
@@ -824,9 +802,7 @@
 		/* right mouse button */
 		switch (xy.y) {
 		case 0:
-			if (xy.x < 3)
-				return Rnil;
-			if (xy.x == 3) {
+			if (xy.x == 0) {
 				/* special case for circle brush */
 				configcirclebrush(&ev.mouse);
 				return Rnil;
@@ -840,9 +816,48 @@
 		return Rnil;
 	}
 	return Rnil;
+}
+
+static void
+p9drawlwin(Layer*, Image *i, Rectangle r)
+{
+	Point p;
+	p = r.min;
+	p.x += lwinoffset;
+	
+	drcells(i, p, "C", tstate.mode == Composite);
+	p.x += toolcell.x;
+	drcells(i, p, "S", tstate.mode == Img);
+	p.x += toolcell.x;
+	drcells(i, p, "M", tstate.mode == Mask);
+	p.x += toolcell.x;
+}
+
+static Redrawwin
+p9lwininput(Layer*, int, Event ev)
+{
+	ev.mouse.xy.x -= lwinoffset;
+	
+	if (ev.mouse.xy.y / toolcell.y == 0) {
+		switch (ev.mouse.xy.x / toolcell.x) {
+		case 0:
+			tstate.mode = Composite;
+			tstate.drawtarget = DTimg;
+			goto Out;
+		case 1:
+			tstate.mode = Img;
+			tstate.drawtarget = DTimg;
+			goto Out;
+		case 2:
+			tstate.mode = Mask;
+			tstate.drawtarget = DTmask;
+			goto Out;
+		}
+	}
+	return Rnil;
 Out:
 	setdrawingdirty(Dcontent);
-	return Rdrawing|Rtools;
+	return Rlayers|Rdrawing;
 }
 
 Editor p9image = {
@@ -854,8 +869,10 @@
 	.overlay = p9overlay,
 	.toolrect = p9toolrect,
 	.drawtools = p9drawtools,
+	.drawlwin = p9drawlwin,
 	.savedata = p9savedata,
 	.savetools = p9savetools,
 	.drawinput = p9drawinput,
 	.toolinput = p9toolinput,
+	.lwininput = p9lwininput,
 };