commit 11bb1bb1fcc688b91f19405b272c130028e9db92
parent 60f1065a5f1d9ec64e66e1112d9e4ca6ec6f1a9d
Author: rpa <rpa@laika>
Date: Sun, 22 Jan 2023 22:50:38 +0000
wave/inst: prog editor takes form
Diffstat:
M | src/wave/inst.c | | | 110 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- |
1 file changed, 100 insertions(+), 10 deletions(-)
diff --git a/src/wave/inst.c b/src/wave/inst.c
@@ -45,6 +45,7 @@ enum {
};
typedef struct FBuf FBuf;
+typedef struct ProgEd ProgEd;
typedef struct Widget Widget;
typedef struct UI UI;
@@ -54,6 +55,11 @@ struct FBuf {
char *p;
};
+struct ProgEd {
+ char *p;
+ int curl, curc;
+};
+
struct UI {
Mousectl *mctl;
Mouse mv;
@@ -78,20 +84,24 @@ void usage(void);
void threadsynth(void *);
void threadkbd(void *);
void handlemouse(UI *);
+void handlekeyboard(UI *);
int loadfile(char *, void *, long);
void rcalc(UI *);
Widget * findhot(UI *);
void drawwidgets(UI *);
void wxfiledraw(UI *, void *);
void wxfileactivate(UI *, void *);
+void wxprogdraw(UI *, void *);
const Rectangle ZR = {0, 0, 1, 1};
FBuf wavetable, prog;
UI ui;
-Widget wxf_wt, wxf_prog;
-Image *palette[8];
+ProgEd ped;
+Widget wxf_wt, wxf_prog, wx_prog;
+Image *progmask, *palette[8];
Channel *synthc;
+int cw, ch; /* character width and height */
void
threadmain(int argc, char **argv)
@@ -127,7 +137,28 @@ threadmain(int argc, char **argv)
palette[0] = allocimage(display, ZR, XRGB32, 1, 0x7f0000ff);
palette[1] = allocimage(display, ZR, XRGB32, 1, 0xffff00ff);
palette[2] = allocimage(display, ZR, XRGB32, 1, 0xff0000ff);
+ palette[3] = allocimage(display, ZR, XRGB32, 1, 0x1f0000ff);
+ const char barsample[] = "00|00 ff|01 ff|02 ff|03 ff|04 ff|05 ff|06 ff|07 ff";
+ cw = stringwidth(font, "0");
+ ch = font->height;
+
+ progmask = allocimage(display,
+ Rect(0, 0, strlen(barsample) * cw, 256 * ch), GREY1, 0, DBlack);
+
+ int i;
+ for (i = 0; i < 128; i++) {
+ Point pt = Pt(0, i * ch);
+ char buf[256];
+ char *prp = prog.p + i * 16;
+ snprint(buf, 256,
+ "%02uhhX %02uhhX:%02uhhX %02uhhX:%02uhhX %02uhhX:%02uhhX %02uhhX:%02uhhX %02uhhX:%02uhhX %02uhhX:%02uhhX %02uhhX:%02uhhX %02uhhX:%02uhhX\0",
+ i,
+ prp[0], prp[1], prp[2], prp[3], prp[4], prp[5], prp[6], prp[7],
+ prp[8], prp[9], prp[10], prp[11], prp[12], prp[13], prp[14], prp[15]);
+
+ string(progmask, pt, display->white, ZP, font, buf);
+ }
wxf_wt = (Widget) {
ZR, palette, &wavetable, wxfiledraw, wxfileactivate,
@@ -135,13 +166,16 @@ threadmain(int argc, char **argv)
wxf_prog = (Widget) {
ZR, palette, &prog, wxfiledraw, wxfileactivate,
};
+ wx_prog = (Widget) {
+ ZR, palette, &ped, wxprogdraw, nil,
+ };
- Widget *wp[] = {&wxf_wt, &wxf_prog, nil};
+ Widget *wp[] = {&wxf_wt, &wxf_prog, &wx_prog, nil};
ui.wp = wp;
rcalc(&ui);
- draw(screen, screen->r, display->black, nil, ZP);
+ draw(screen, screen->r, palette[3], nil, ZP);
drawwidgets(&ui);
flushimage(display, 1);
@@ -155,7 +189,7 @@ threadmain(int argc, char **argv)
for (;;) switch (alt(alts)) {
case 0: /* resize */
if(getwindow(display, Refnone) < 0) sysfatal("resize failed: %r");
- draw(screen, screen->r, display->black, nil, ZP);
+ draw(screen, screen->r, palette[3], nil, ZP);
rcalc(&ui);
drawwidgets(&ui);
flushimage(display, 1);
@@ -164,6 +198,7 @@ threadmain(int argc, char **argv)
handlemouse(&ui);
break;
case 2: /* keyboard */
+ handlekeyboard(&ui);
break;
}
}
@@ -283,7 +318,7 @@ handlemouse(UI *ui)
case MFree:
ui->hot = findhot(ui);
if ((ui->mv.buttons == 1) && (ui->hot != nil)) {
- ui->hot->activate(ui, ui->hot);
+ if (ui->hot->activate) ui->hot->activate(ui, ui->hot);
drawwidgets(ui);
flushimage(display, 1);
}
@@ -292,6 +327,31 @@ handlemouse(UI *ui)
}
}
+void
+handlekeyboard(UI *ui)
+{
+ switch (ui->kv) {
+ case Kup:
+ ped.curl--;
+ if (ped.curl < 0) ped.curl = 127;
+ break;
+ case Kdown:
+ ped.curl++;
+ if (ped.curl >= 128) ped.curl = 0;
+ break;
+ case Kleft:
+ ped.curc--;
+ if (ped.curc < 0) ped.curc = 31;
+ break;
+ case Kright:
+ ped.curc++;
+ if (ped.curc >= 32) ped.curc = 0;
+ break;
+ }
+ drawwidgets(ui);
+ flushimage(display, 1);
+}
+
int
loadfile(char *path, void *p, long size)
{
@@ -319,10 +379,12 @@ rcalc(UI *ui)
Point min = screen->r.min;
Point max = screen->r.max;
- Rectangle r = Rpt(min, Pt(max.x, min.y + font->height));
- ui->wp[0]->r = r;
- Rectangle r2 = Rpt(Pt(r.min.x, r.max.y), Pt(max.x, r.max.y + font->height));
+ Rectangle r1 = Rpt(min, Pt(max.x, min.y + ch));
+ ui->wp[0]->r = r1;
+ Rectangle r2 = Rpt(Pt(min.x, r1.max.y), Pt(max.x, r1.max.y + ch));
ui->wp[1]->r = r2;
+ Rectangle r3 = Rpt(Pt(min.x, r2.max.y), max);
+ ui->wp[2]->r = r3;
}
@@ -342,7 +404,7 @@ drawwidgets(UI *ui)
{
Widget **wp = ui->wp;
while (*wp != nil) {
- (*wp)->draw(ui, *wp);
+ if ((*wp)->draw) (*wp)->draw(ui, *wp);
wp++;
};
}
@@ -368,3 +430,31 @@ wxfileactivate(UI *ui, void *arg)
loadfile(fb->path, fb->p, fb->n);
}
}
+
+void
+wxprogdraw(UI *, void *arg)
+{
+ int n;
+ Rectangle r;
+ Widget *w = (Widget *) arg;
+ ProgEd *ped = w->aux;
+
+ draw(screen, w->r, w->palette[3], nil, ZP);
+
+ r = w->r;
+ r.min.y += ped->curl * ch;
+ r.max.y = r.min.y + ch;
+ draw(screen, r, w->palette[0], nil, ZP);
+
+
+ draw(screen, w->r, w->palette[2], progmask, ZP);
+
+ n = ped->curc + 3 + (ped->curc)/2;
+
+ r = w->r;
+ r.min.x += n * cw;
+ r.max.x = r.min.x + cw;
+ r.min.y += ped->curl * ch;
+ r.max.y = r.min.y + ch;
+ draw(screen, r, w->palette[1], progmask, subpt(r.min, w->r.min));
+}