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);
+}