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