shithub: zuke

Download patch

ref: 4e3601d7e3618bbb1832af2f9e8d8245c5ea0570
parent: f0d9d0399f0923caae9adb54c93200ac72e3588f
author: Sigrid Haflínudóttir <ftrvxmtrx@gmail.com>
date: Sat May 23 15:25:55 EDT 2020

overhaul zuke, add theme customization and make scrollbar work as expected on middle click

--- /dev/null
+++ b/theme.h
@@ -1,0 +1,106 @@
+enum {
+	Dback = 0,
+	Dfhigh,
+	Dfmed,
+	Dflow,
+	Dfinv,
+	Dbhigh,
+	Dbmed,
+	Dblow,
+	Dbinv,
+	Numcolors,
+};
+
+typedef struct ThemeColor ThemeColor;
+
+struct ThemeColor {
+	char *id;
+	u32int rgb;
+	Image *im;
+};
+
+static ThemeColor colors[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},
+};
+
+static void
+runpicker(void *x)
+{
+	int *p, f;
+	char tmp[64];
+
+	snprint(tmp, sizeof(tmp), "new -pid %d -dx %d -dy %d", getpid(), 384, 320);
+	newwindow(tmp);
+
+	p = x;
+	dup(p[0], 0); close(p[0]); close(p[1]);
+	dup(p[3], 1); close(p[3]); close(p[2]);
+	f = open("/dev/null", OWRITE); dup(f, 2); close(f);
+	procexecl(nil, "/bin/picker", "picker", nil);
+
+	threadexits("exec: %r");
+}
+
+static void
+themeproc(void *x)
+{
+	Biobuf *in, *out;
+	char *s, *v[3];
+	int p[4], n, i;
+	void (*redraw)(void);
+
+	redraw = x;
+	threadsetname("themeproc");
+	pipe(p);
+	pipe(p+2);
+	procrfork(runpicker, p, 4096, RFFDG|RFNAMEG);
+	close(p[0]);
+	close(p[3]);
+	out = Bfdopen(p[1], OWRITE);
+	in = Bfdopen(p[2], OREAD);
+
+	for(i = 0; i < nelem(colors); i++)
+		Bprint(out, "%s\t%06ux\n", colors[i].id, colors[i].rgb);
+	Bterm(out);
+
+	for(;;){
+		if((s = Brdstr(in, '\n', 1)) == nil)
+			break;
+		if((n = tokenize(s, v, nelem(v))) == 2){
+			for(i = 0; i < nelem(colors); i++){
+				if(strcmp(colors[i].id, v[0]) == 0){
+					lockdisplay(display);
+					freeimage(colors[i].im);
+					colors[i].rgb = strtoul(v[1], nil, 16);
+					colors[i].im = allocimage(display, Rect(0,0,1,1), RGB24, 1, colors[i].rgb<<8 | 0xff);
+					unlockdisplay(display);
+					redraw();
+					break;
+				}
+			}
+		}
+		free(s);
+		if(n != 2)
+			break;
+	}
+	Bterm(in);
+
+	threadexits(nil);
+}
+
+static void
+themeinit(void)
+{
+	int i;
+
+	for(i = 0; i < Numcolors; i++)
+		colors[i].im = allocimage(display, Rect(0,0,1,1), RGB24, 1, colors[i].rgb<<8 | 0xff);
+}
--- a/zuke.c
+++ b/zuke.c
@@ -7,6 +7,7 @@
 #include <ctype.h>
 #include <bio.h>
 #include "plist.h"
+#include "theme.h"
 
 typedef struct Player Player;
 
@@ -27,7 +28,7 @@
 	Seekbytes = Bps*10, /* 10 seconds */
 	Seekbytesfast = Bps*60, /* 1 minute */
 
-	Scrollwidth = 12,
+	Scrollwidth = 14,
 	Scrollheight = 16,
 
 	Relbufsz = Bps/5, /* 0.2 second */
@@ -53,7 +54,6 @@
 static u64int byteswritten;
 static int pcur, pcurplaying;
 static int scroll, scrollsz;
-static Image *cola, *colb;
 static Font *f;
 static Image *cover;
 static Channel *ev;
@@ -64,6 +64,16 @@
 static int mincolwidth[3];
 static char *covers[] = {"folder", "cover", "Cover", "scans/CD", "Scans/Front", "Covers/Front"};
 
+static char *menu3i[] = {
+	"theme",
+	"exit",
+	nil
+};
+
+static Menu menu3 = {
+	.item = menu3i,
+};
+
 #pragma varargck type "P" int
 static int
 positionfmt(Fmt *f)
@@ -119,7 +129,7 @@
 		return;
 
 	lockdisplay(display);
-	draw(screen, screen->r, cola, nil, ZP);
+	draw(screen, screen->r, colors[Dback].im, nil, ZP);
 
 	scrollsz = Dy(screen->r) / f->height - 1;
 	adjustcolumns();
@@ -128,7 +138,7 @@
 		p.x = sp.x = screen->r.min.x + Scrollwidth;
 		p.y = screen->r.min.y;
 		sp.y = screen->r.max.y;
-		line(screen, p, sp, Endsquare, Endsquare, 0, colb, ZP);
+		line(screen, p, sp, Endsquare, Endsquare, 0, colors[Dfmed].im, ZP);
 
 		r = screen->r;
 		r.max.x = r.min.x + Scrollwidth - 1;
@@ -139,7 +149,7 @@
 			scrollcenter = (Dy(screen->r)-Scrollheight*5/4)*scroll / (plnum - scrollsz);
 		r.min.y += scrollcenter + Scrollheight/4;
 		r.max.y = r.min.y + Scrollheight;
-		draw(screen, r, colb, nil, ZP);
+		draw(screen, r, colors[Dfmed].im, nil, ZP);
 
 		left += Scrollwidth + 4;
 	}
@@ -147,12 +157,12 @@
 	p.x = sp.x = left + colwidth[0] + 4;
 	p.y = 0;
 	sp.y = screen->r.max.y;
-	line(screen, p, sp, Endsquare, Endsquare, 0, colb, ZP);
+	line(screen, p, sp, Endsquare, Endsquare, 0, colors[Dfmed].im, ZP);
 
 	p.x = sp.x = left + colwidth[0] + 8 + colwidth[1] + 4;
 	p.y = 0;
 	sp.y = screen->r.max.y;
-	line(screen, p, sp, Endsquare, Endsquare, 0, colb, ZP);
+	line(screen, p, sp, Endsquare, Endsquare, 0, colors[Dfmed].im, ZP);
 
 	sp.x = sp.y = 0;
 	p.x = left + 2;
@@ -169,10 +179,10 @@
 			sel.min.y = p.y;
 			sel.max.x = screen->r.max.x;
 			sel.max.y = p.y + f->height;
-			draw(screen, sel, colb, nil, ZP);
-			col = cola;
+			draw(screen, sel, colors[Dbmed].im, nil, ZP);
+			col = colors[Dfinv].im;
 		}else{
-			col = colb;
+			col = colors[pcurplaying == i ? Dfhigh : Dfmed].im;
 		}
 
 		sel = screen->r;
@@ -200,9 +210,9 @@
 			leftp.y = rightp.y = p.y - 1;
 			leftp.x = left;
 			rightp.x = screen->r.max.x;
-			line(screen, leftp, rightp, 0, 0, 0, colb, sp);
+			line(screen, leftp, rightp, 0, 0, 0, colors[Dfmed].im, sp);
 			leftp.y = rightp.y = p.y + f->height;
-			line(screen, leftp, rightp, 0, 0, 0, colb, sp);
+			line(screen, leftp, rightp, 0, 0, 0, colors[Dfmed].im, sp);
 		}
 	}
 
@@ -210,7 +220,7 @@
 		r = screen->r;
 		r.min.x = r.max.x - cover->r.max.x - 8;
 		r.min.y = r.max.y - cover->r.max.y - 8 - f->height - 4;
-		draw(screen, r, display->black, nil, ZP);
+		draw(screen, r, colors[Dblow].im, nil, ZP);
 		r.min.x += 4;
 		r.min.y += 4;
 		r.max.x -= 4;
@@ -225,10 +235,10 @@
 	r = screen->r;
 	r.min.x = r.max.x - stringwidth(f, tmp) - 4;
 	r.min.y = r.max.y - f->height - 4;
-	draw(screen, r, display->black, nil, ZP);
+	draw(screen, r, colors[Dblow].im, nil, ZP);
 	r.min.x += 2;
 	r.min.y += 2;
-	string(screen, r.min, cola, sp, f, tmp);
+	string(screen, r.min, colors[Dfhigh].im, sp, f, tmp);
 
 	flushimage(display, 1);
 	unlockdisplay(display);
@@ -753,7 +763,7 @@
 		{ nil, &key, CHANRCV },
 		{ nil, nil, CHANEND },
 	};
-	int fd, scrolling, oldpcur;
+	int fd, n, scrolling, oldpcur, oldbuttons;
 
 	USED(argc); USED(argv);
 
@@ -780,8 +790,6 @@
 	a[2].c = kctl->c;
 
 	f = display->defaultfont;
-	cola = display->white;
-	colb = display->black;
 	srand(time(0));
 	pcurplaying = -1;
 	chvolume(0);
@@ -794,7 +802,10 @@
 		close(fd);
 	}
 
+	themeinit();
 	redraw();
+	oldbuttons = 0;
+	scrolling = 0;
 
 	for(;;){
 		oldpcur = pcur;
@@ -801,7 +812,11 @@
 
 		switch(alt(a)){
 		case 0:
-			scrolling = m.buttons & 2;
+			if(oldbuttons == 0 && m.buttons == 2 && m.xy.x <= screen->r.min.x+Scrollwidth)
+				scrolling = 1;
+			else if(m.buttons != 2)
+				scrolling = 0;
+			oldbuttons = m.buttons;
 			if(m.buttons == 0)
 				break;
 
@@ -814,13 +829,18 @@
 				if(scroll < 0)
 					scroll = 0;
 				redraw();
-			}else{
+			}else if(m.buttons != 4){
 				pcur = scroll + (m.xy.y - screen->r.min.y)/f->height;
-				if(m.buttons == 4){
+				if(m.buttons == 2){
 					stop(playercurr);
 					playercurr = newplayer(pcur, 1);
 					start(playercurr);
 				}
+			}else if((n = menuhit(3, mctl, &menu3, nil)) >= 0){
+				if(n == 0)
+					proccreate(themeproc, redraw, 4096);
+				else if(n == 1)
+					goto end;
 			}
 			break;
 		case 1: /* resize */
@@ -940,7 +960,5 @@
 	}
 
 end:
-	closemouse(mctl);
-	closekeyboard(kctl);
 	threadexitsall(nil);
 }