shithub: neindaw

Download patch

ref: f5929fb0d242dbb338e5f6cae46e8f8a5a980aae
parent: 54d0561599f831b9babc4ca8d847139177fe8f7d
author: Sigrid Haflínudóttir <[email protected]>
date: Fri Mar 27 23:04:35 EDT 2020

begin the custom ui part

--- /dev/null
+++ b/ui/mkfile
@@ -1,0 +1,11 @@
+</$objtype/mkfile
+
+TARG=ui
+BIN=/$objtype/bin/daw
+
+OFILES=\
+	ui.$O\
+
+default:V:	all
+
+</sys/src/cmd/mkone
--- /dev/null
+++ b/ui/ui.c
@@ -1,0 +1,233 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <mouse.h>
+#include <keyboard.h>
+#include <thread.h>
+
+enum {
+	Dback = 0,
+	Dfhigh,
+	Dfmed,
+	Dflow,
+	Dfinv,
+	Dbhigh,
+	Dbmed,
+	Dblow,
+	Dbinv,
+	Numcolors,
+
+	Knobleft360 = 0<<0,
+	Knobtop180 = 1<<0,
+	Knobvaluetop = 0<<1,
+	Knobvaluebot = 1<<1,
+};
+
+#define MIN(a,b) ((a)<=(b)?(a):(b))
+#define MAX(a,b) ((a)>=(b)?(a):(b))
+
+static struct {
+	char *id;
+	u32int color;
+}theme[Numcolors] = {
+	[Dback]  = {"background", 0x000000},
+	[Dfhigh] = {"f_high",     0xffffff},
+	[Dfmed]  = {"f_med",      0x777777},
+	[Dflow]  = {"f_low",      0x444444},
+	[Dfinv]  = {"f_inv",      0x000000},
+	[Dbhigh] = {"b_high",     0xdddddd},
+	[Dbmed]  = {"b_med",      0x72dec2},
+	[Dblow]  = {"b_low",      0x222222},
+	[Dbinv]  = {"b_inv",      0xffb545},
+};
+
+typedef struct Style Style;
+
+struct Style {
+	struct {
+		int r;
+		int w;
+	}knob;
+	int margin;
+	Font *font;
+};
+
+static Style style = {
+	.knob = {
+		.r = 24,
+		.w = 4,
+	},
+	.margin = 4,
+};
+
+static Image *color[Numcolors];
+static Rectangle knobs[8][2];
+
+static Rectangle
+knob(Rectangle r, char *d, char *vs, float v, int kt)
+{
+	Point c, t, p0, p1;
+	int a, hw, dw, vw;
+
+	dw = stringwidth(style.font, d);
+	vw = stringwidth(style.font, vs);
+	hw = MAX(style.knob.r, MAX(dw, vw)/2); /* "half width", center of the component */
+	r.max = r.min;
+	r.max.x += hw*2;
+
+	/* value */
+	if (vw > 0 && !(kt&Knobvaluebot)) {
+valuebot:
+		t.x = r.min.x + hw - vw/2;
+		t.y = r.max.y;
+		string(screen, t, color[Dfhigh], ZP, style.font, vs);
+		r.max.y = t.y + style.font->height + style.margin;
+		if (kt & Knobvaluebot)
+			return r;
+	}
+
+	/* knob */
+	a = (kt&Knobtop180) ? 90 : 180;
+	v = v*((kt&Knobtop180) ? -180 : -360);
+	c.x = r.min.x + Dx(r)/2;
+	c.y = r.max.y + style.knob.r;
+	fillarc(screen, c, style.knob.r, style.knob.r, color[Dfhigh], ZP, a, v);
+	fillellipse(screen, c, style.knob.r-style.knob.w, style.knob.r-style.knob.w, color[Dflow], ZP);
+	icossin(a+v, &p0.x, &p0.y);
+	p1.x = c.x + p0.x*(style.knob.r-style.knob.w*4/3)/1024;
+	p1.y = c.y - p0.y*(style.knob.r-style.knob.w*4/3)/1024;
+	p0.x = c.x + p0.x*style.knob.w/1024;
+	p0.y = c.y - p0.y*style.knob.w/1024;
+	line(screen, p0, p1, 0, 0, 0, color[Dfhigh], ZP);
+	r.max.y += 2*style.knob.r;
+
+	/* description */
+	if (dw > 0) {
+		t.x = r.min.x + hw - dw/2;
+		t.y = r.max.y + style.margin;
+		string(screen, t, color[Dfhigh], ZP, style.font, d);
+		r.max.y = t.y + style.font->height;
+	}
+
+	if (kt & Knobvaluebot) {
+		r.max.y += style.margin;
+		goto valuebot;
+	}
+
+	return r;
+}
+
+static void
+redraw(void)
+{
+	float f;
+	Rectangle r, t;
+	char s[16];
+	int i;
+
+	lockdisplay(display);
+	r = screen->r;
+	draw(screen, r, color[Dback], nil, ZP);
+
+	r.min.x += style.margin;
+	r.min.y += style.margin;
+	for (i = 0; i < nelem(knobs); i++) {
+		f = (i+1)*0.1;
+		sprint(s, "%g", f);
+		t = knob(r, nil, s+1, f, Knobleft360);
+		knobs[i][0] = t;
+		r.min.y += Dy(t) + 2*style.margin;
+
+		f = (i-4)*0.2;
+		sprint(s, "%+g", f);
+		if (s[2] != 0)
+			s[1] = s[0];
+		knobs[i][1] = knob(r, nil, s+1, f, Knobtop180|Knobvaluebot);
+		r = t;
+		r.min.x += Dx(r) + 2*style.margin;
+	}
+
+	flushimage(display, 1);
+	unlockdisplay(display);
+}
+
+void
+threadmain(int argc, char **argv)
+{
+	Mousectl *mctl;
+	Keyboardctl *kctl;
+	Rune key;
+	Mouse m;
+	int n, oldbuttons;
+	Point oldxy;
+	float zoom, oldzoom;
+	Style s;
+	Alt a[] = {
+		{ nil, &m, CHANRCV },
+		{ nil, nil, CHANRCV },
+		{ nil, &key, CHANRCV },
+		{ nil, nil, CHANEND },
+	};
+
+	USED(argc); USED(argv);
+
+	if (initdraw(nil, nil, "daw/ui") < 0)
+		sysfatal("initdraw: %r");
+	style.font = font;
+	display->locking = 1;
+	unlockdisplay(display);
+	if ((mctl = initmouse(nil, screen)) == nil)
+		sysfatal("initmouse: %r");
+	if ((kctl = initkeyboard(nil)) == nil)
+		sysfatal("initkeyboard: %r");
+
+	for (n = 0; n < Numcolors; n++)
+		color[n] = allocimage(display, Rect(0, 0, 1, 1), RGB24, 1, theme[n].color<<8 | 0xff);
+
+	a[0].c = mctl->c;
+	a[1].c = mctl->resizec;
+	a[2].c = kctl->c;
+
+	threadsetname("daw/ui");
+	redraw();
+	oldbuttons = 0;
+	oldxy = ZP;
+	memmove(&s, &style, sizeof(s));
+	oldzoom = 1.0f;
+
+	for (;;) {
+		switch (alt(a)) {
+		case 0: /* mouse */
+			if (m.buttons == 2) {
+				if (oldbuttons == 0) {
+					oldxy = m.xy;
+				} else if (oldbuttons == 2) {
+					zoom = MAX(0, oldzoom + m.xy.y-oldxy.y);
+					style.knob.r = s.knob.r*(1 + zoom/100.f);
+					style.knob.w = s.knob.w*(1 + zoom/100.f);
+					redraw();
+				}
+			} else if (m.buttons == 0) {
+				if (oldbuttons == 2)
+					oldzoom = zoom;
+			}
+			oldbuttons = m.buttons;
+			break;
+
+		case 1: /* resize */
+			getwindow(display, Refnone);
+			redraw();
+			break;
+
+		case 2: /* keyboard */
+			switch (key) {
+			case Kdel:
+				goto end;
+			}
+			break;
+		}
+	}
+
+end:
+	threadexitsall(nil);
+}