shithub: vdir

Download patch

ref: de7e069124978b0b38c2e0084aa2ad797d98900a
parent: 127edcedd0467bdcb3e474f50b51867be20e0d84
author: phil9 <telephil9@gmail.com>
date: Tue Feb 22 00:38:23 EST 2022

use /dev/theme when available

	colors are now based on /dev/theme when available

--- a/mkfile
+++ b/mkfile
@@ -2,7 +2,7 @@
 
 BIN=$home/bin/$objtype
 TARG=vdir
-OFILES=vdir.$O alert.$O
+OFILES=vdir.$O alert.$O theme.$O
 HFILES=icons.h
 
 </sys/src/cmd/mkone
--- /dev/null
+++ b/theme.c
@@ -1,0 +1,84 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <draw.h>
+#include "theme.h"
+
+Image*
+ereadcol(char *s)
+{
+	Image *i;
+	char *e;
+	ulong c;
+
+	c = strtoul(s, &e, 16);
+	if(e == nil || e == s)
+		return nil;
+	c = (c << 8) | 0xff;
+	i = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, c);
+	if(i == nil)
+		sysfatal("allocimage: %r");
+	return i;
+}
+
+Theme*
+loadtheme(void)
+{
+	Theme *theme;
+	Biobuf *bp;
+	char *s;
+
+	if(access("/dev/theme", AREAD) < 0)
+		return 0;
+	bp = Bopen("/dev/theme", OREAD);
+	if(bp == nil)
+		return 0;
+	theme = malloc(sizeof *theme);
+	if(theme == nil){
+		Bterm(bp);
+		return nil;
+	}
+	for(;;){
+		s = Brdstr(bp, '\n', 1);
+		if(s == nil)
+			break;
+		if(strncmp(s, "back", 4) == 0)
+			theme->back = ereadcol(s+5);
+		else if(strncmp(s, "high", 4) == 0)
+			theme->high = ereadcol(s+5);
+		else if(strncmp(s, "border", 6) == 0)
+			theme->border = ereadcol(s+7);
+		else if(strncmp(s, "text", 4) == 0)
+			theme->text = ereadcol(s+5);
+		else if(strncmp(s, "htext", 5) == 0)
+			theme->htext = ereadcol(s+6);
+		else if(strncmp(s, "title", 5) == 0)
+			theme->title = ereadcol(s+6);
+		else if(strncmp(s, "ltitle", 6) == 0)
+			theme->ltitle = ereadcol(s+7);
+		else if(strncmp(s, "hold", 4) == 0)
+			theme->hold = ereadcol(s+5);
+		else if(strncmp(s, "lhold", 5) == 0)
+			theme->lhold = ereadcol(s+6);
+		else if(strncmp(s, "palehold", 8) == 0)
+			theme->palehold = ereadcol(s+9);
+		else if(strncmp(s, "paletext", 8) == 0)
+			theme->paletext = ereadcol(s+9);
+		else if(strncmp(s, "size", 4) == 0)
+			theme->size = ereadcol(s+5);
+		else if(strncmp(s, "menuback", 8) == 0)
+			theme->menuback = ereadcol(s+9);
+		else if(strncmp(s, "menuhigh", 8) == 0)
+			theme->menuhigh = ereadcol(s+9);
+		else if(strncmp(s, "menubord", 8) == 0)
+			theme->menubord = ereadcol(s+9);
+		else if(strncmp(s, "menutext", 8) == 0)
+			theme->menutext = ereadcol(s+9);
+		else if(strncmp(s, "menuhtext", 5) == 0)
+			theme->menuhtext = ereadcol(s+6);
+		free(s);
+	}
+	Bterm(bp);
+	return theme;
+}
+
--- /dev/null
+++ b/theme.h
@@ -1,0 +1,25 @@
+typedef struct Theme Theme;
+
+struct Theme
+{
+	Image *back;
+	Image *high;
+	Image *border;
+	Image *text;
+	Image *htext;
+	Image *title;
+	Image *ltitle;
+	Image *hold;
+	Image *lhold;
+	Image *palehold;
+	Image *paletext;
+	Image *size;
+	Image *menubar;
+	Image *menuback;
+	Image *menuhigh;
+	Image *menubord;
+	Image *menutext;
+	Image *menuhtext;
+};
+
+Theme* loadtheme(void);
--- a/vdir.c
+++ b/vdir.c
@@ -7,6 +7,7 @@
 #include <plumb.h>
 #include <bio.h>
 #include "icons.h"
+#include "theme.h"
 
 extern void alert(const char *title, const char *message, Mousectl *mctl, Keyboardctl *kctl);
 void redraw(void);
@@ -55,6 +56,8 @@
 Image *toolfg;
 Image *viewbg;
 Image *viewfg;
+Image *selbg;
+Image *selfg;
 Image *scrollbg;
 Image *scrollfg;
 int sizew;
@@ -224,12 +227,28 @@
 void
 initcolors(void)
 {
-	toolbg = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xEFEFEFFF);
-	toolfg = display->black;
-	viewbg = display->white;
-	viewfg = display->black;
-	scrollbg = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x999999FF);
-	scrollfg = display->white;
+	Theme *theme;
+
+	theme = loadtheme();
+	if(theme == nil){
+		toolbg = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xEFEFEFFF);
+		toolfg = display->black;
+		viewbg = display->white;
+		viewfg = display->black;
+		selbg  = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xEFEFEFFF);
+		selfg  = display->black;
+		scrollbg = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x999999FF);
+		scrollfg = display->white;
+	}else{
+		toolbg = theme->back;
+		toolfg = theme->text;
+		viewbg = theme->back;
+		viewfg = theme->text;
+		selbg  = theme->border;
+		selfg  = theme->text;
+		scrollbg = theme->border;
+		scrollfg = theme->back;
+	}
 }
 
 Image*
@@ -274,13 +293,13 @@
 }
 
 Rectangle
-drawbutton(Point *p, Image *i)
+drawbutton(Point *p, Image *c, Image *i)
 {
 	Rectangle r;
 
 	p->x += Toolpadding;
 	r = Rect(p->x, p->y, p->x+16, p->y+16);
-	draw(screen, r, i, nil, ZP);
+	draw(screen, r, c, i, ZP);
 	p->x += 16+Toolpadding;
 	return r;
 }
@@ -308,7 +327,7 @@
 {
 	char buf[255], *t;
 	Dir d;
-	Image *img;
+	Image *img, *bg, *fg;
 	Point p;
 	Rectangle r;
 	int dy;
@@ -315,11 +334,13 @@
 
 	if(offset+n>=ndirs)
 		return;
+	bg = selected ? selbg : viewbg;
+	fg = selected ? selfg : viewfg;
 	d = dirs[offset+n];
 	p = addpt(viewr.min, Pt(Toolpadding, Toolpadding));
 	p.y += n*lineh;
 	r = Rpt(p, addpt(p, Pt(Dx(viewr)-2*Toolpadding, lineh)));
-	draw(screen, r, selected?toolbg:viewbg, nil, ZP);
+	draw(screen, r, bg, nil, ZP);
 	t = mdate(d);
 	snprint(buf, sizeof buf, "%*lld  %s", sizew, d.length, t);
 	free(t);
@@ -326,12 +347,12 @@
 	img = (d.qid.type&QTDIR) ? folder : file;
 	p.y -= Padding;
 	dy = (lineh-12)/2;
-	draw(screen, Rect(p.x, p.y+dy, p.x+12, p.y+dy+12), img, nil, ZP);
+	draw(screen, Rect(p.x, p.y+dy, p.x+12, p.y+dy+12), fg, img, ZP);
 	p.x += 12+4+Padding;
 	p.y += Padding;
-	p = drawtext(p, viewfg, d.name, viewr.max.x - stringwidth(font, buf) - 2*Padding - Toolpadding);
+	p = drawtext(p, fg, d.name, viewr.max.x - stringwidth(font, buf) - 2*Padding - Toolpadding);
 	p.x = viewr.max.x - stringwidth(font, buf) - 2*Padding - Toolpadding;
-	string(screen, p, viewfg, ZP, font, buf);
+	string(screen, p, fg, ZP, font, buf);
 }
 
 void
@@ -352,13 +373,13 @@
 	Point p;
 	int i, h, y;
 
-	draw(screen, screen->r, display->white, nil, ZP);
+	draw(screen, screen->r, viewbg, nil, ZP);
 	p = addpt(screen->r.min, Pt(0, Toolpadding));
 	draw(screen, toolr, toolbg, nil, ZP);
 	line(screen, Pt(toolr.min.x, toolr.max.y), toolr.max, 0, 0, 0, toolfg, ZP);
-	homer = drawbutton(&p, ihome);
-	cdr = drawbutton(&p, icd);
-	upr = drawbutton(&p, iup);
+	homer = drawbutton(&p, toolfg, ihome);
+	cdr = drawbutton(&p, toolfg, icd);
+	upr = drawbutton(&p, toolfg, iup);
 	p.x += Toolpadding;
 	p.y = toolr.min.y + (Toolpadding+16+Toolpadding-font->height)/2;
 	pathr = Rect(p.x, p.y, p.x + stringwidth(font, path), p.y + font->height);
@@ -365,8 +386,8 @@
 	p = drawtext(p, toolfg, path, screen->r.max.x - 2*(Toolpadding+16+Toolpadding));
 	p.x = screen->r.max.x - 2*(Toolpadding+16+Toolpadding);
 	p.y = screen->r.min.y + Toolpadding;
-	newdirr = drawbutton(&p, inewfolder);
-	newfiler = drawbutton(&p, inewfile);
+	newdirr = drawbutton(&p, toolfg, inewfolder);
+	newfiler = drawbutton(&p, toolfg, inewfile);
 	draw(screen, scrollr, scrollbg, nil, ZP);
 	if(ndirs>0){
 		h = ((double)nlines/ndirs)*Dy(scrollr);
@@ -374,7 +395,7 @@
 		scrposr = Rect(scrollr.min.x, scrollr.min.y+y, scrollr.max.x-1, scrollr.min.y+y+h);
 	}else
 		scrposr = Rect(scrollr.min.x, scrollr.min.y, scrollr.max.x-1, scrollr.max.y);
-	draw(screen, scrposr, display->white, nil, ZP);
+	draw(screen, scrposr, scrollfg, nil, ZP);
 	for(i = 0; i<nlines && offset+i<ndirs; i++){
 		drawdir(i, 0);
 	}