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,
};