shithub: mpl

Download patch

ref: 050d602a44f44ccc0fbcb0c55fd35e43d762470b
parent: a313478754f5ee50a5cc7545bd3a8dc94d3adeb6
author: Jacob Moody <jsmoody@iastate.edu>
date: Thu Dec 5 12:34:15 EST 2019

functions for showing playlist as sidebar

--- a/dat.h
+++ b/dat.h
@@ -97,11 +97,22 @@
 	char *name;
 };
 
+enum {
+	CSONG,
+	CLIST,
+};
+
 typedef struct Click Click;
 struct Click{
 	Rectangle r;
+	int type; /* Either CSONG or CLIST */
+
+	/* For song events */
 	Album *a;
 	int songnum;
+
+	/* For list events */
+	char *list;
 };
 
 /*
--- a/draw.c
+++ b/draw.c
@@ -230,6 +230,7 @@
 		c.r = Rpt(p, Pt(p.x+runestrlen(tracktitle)*f->width,p.y+f->height));
 		c.a = a;
 		c.songnum = i;
+		c.type = CSONG;
 		send(clickout, &c);
 		p.y += f->height;
 	}
@@ -241,11 +242,17 @@
 }
 
 void
-drawlibrary(Album *start, Album *stop, Album *cur, Image *textcolor, Image *active, int cursong, Channel *clickout)
+drawlibrary(Lib *l, Point p, Image *textcolor, Image *active, Channel *clickout)
 {
-	Point p = screen->r.min;
-	int height = screen->r.max.y - screen->r.min.y;
-	Album *screenstop = start+(height/256)-1;
+	Album *start, *stop, *cur, *screenstop;
+	int cursong, height;
+
+	start = l->cur;
+	stop = l->stop;
+	cur = l->cur;
+	cursong = l->cursong;
+	height = screen->r.max.y - screen->r.min.y;
+	screenstop = start+(height/256)-1;
 	stop = screenstop < stop ? screenstop : stop;
 	stop+=1;
 
@@ -255,6 +262,58 @@
 	for(;start!=stop;start++){
 		p = drawalbum(start, textcolor, active, p, start == cur ? cursong : -1, clickout);
 	}
+}
+
+void
+drawlists(Point p, Image *textcolor, Image *active, Image *background, Channel *clickout)
+{
+	Rectangle r;
+	int n, i;
+	int fd;
+	Dir *files;
+	char buf[512];
+	Font *f = screen->display->defaultfont;
+	Hmap *h;
+	char **keys, *dot;
+	Click c;
+
+	libdir(buf, sizeof buf);
+	fd = open(buf, OREAD);
+	if(fd < 0)
+		sysfatal("could not open libdir");
+
+	n = dirreadall(fd, &files);
+	close(fd);
+	if(n <= 0){
+		free(files);
+		return;
+	}
+
+	h = allocmap(32);
+	r.min = p;
+	r.max.x = r.min.x + 256;
+	r.max.y = screen->r.max.y;
+	draw(screen, r, background, nil, ZP);
+	for(i=0;i<n;i++){
+		if((dot = strrchr(files[i].name, '.')) != nil)
+			*dot = '\0';
+		//vals can not be nil so we use a dummy
+		mapinsert(h, files[i].name, &r);
+	}
+	keys = emalloc(sizeof(char*)*n);
+	n = mapdumpkey(h, keys, n);
+	for(i=0;i<n;i++){
+		string(screen, p, textcolor, ZP, f, keys[i]);
+		c.r = Rpt(p, Pt(p.x+strlen(keys[i])*f->width,p.y+f->height));
+		c.list = strdup(keys[i]);
+		c.type = CLIST;
+		send(clickout, &c);
+		p.y += f->height;
+	}
+
+	freemap(h);
+	free(keys);
+	free(files);
 }
 
 void
--- a/lib.c
+++ b/lib.c
@@ -96,9 +96,18 @@
 			handlemsg(NEXT);
 			break;
 		case EIN:
-			lib.cur = c.a;
-			lib.cursong = c.songnum;
-			sendp(queuein, nextsong(&lib));
+			switch(c.type){
+			case CSONG:
+				lib.cur = c.a;
+				lib.cursong = c.songnum;
+				sendp(queuein, nextsong(&lib));
+				break;
+			case CLIST:
+				//TODO clean more
+				free(lib.name);
+				lib.name = c.list;
+				goto Load;
+			}
 			break;
 		case OUT:
 			continue;
@@ -116,8 +125,10 @@
 			free(radiotitle);
 			break;
 		case LOADC:
+			//TODO: clean more
 			free(lib.name);
 			lib.name = strdup(toload);
+Load:
 			loadlib(&lib);
 			lib.stop = lib.start+(lib.nalbum-1);
 			lib.cursong = 0;
--- a/mpl.c
+++ b/mpl.c
@@ -21,7 +21,8 @@
 Channel		*ctl, *lout, *loadc;
 Channel		*vctl, *vlevel;
 Channel		*clickin, *clickreset;
-int		decpid;
+int			decpid;
+int 		showlists;
 
 int mflag, sflag, pflag, rflag, fflag;
 
@@ -51,13 +52,19 @@
 {
 	int level;
 	Lib lib;
+	Point p;
 	if(isnew && getwindow(display, Refnone) < 0)
 		quit("eresized: Can't reattach to window");
 
+	p = screen->r.min;
 	send(clickreset, nil);
 	draw(screen, screen->r, background, nil, ZP);
 	recv(lout, &lib);
-	drawlibrary(lib.cur, lib.stop, lib.cur, black, red, lib.cursong, clickin);
+	if(showlists) {
+		drawlists(p, black, red, background, clickin);
+		p.x+=256;
+	}
+	drawlibrary(&lib, p, black, red, clickin);
 	recv(vlevel, &level);
 	drawvolume(level, black);
 	flushimage(display, Refnone);
@@ -128,6 +135,7 @@
 	int resize[2];
 	ctl = vctl = vlevel = nil;
 	mflag = sflag = pflag = rflag = fflag = 0;
+	showlists = 0;
 
 	/*
 	 * This shouldn't need to be buffered,
@@ -147,7 +155,7 @@
 	}ARGEND
 
 	if(mflag+sflag+pflag+rflag+fflag < 1){
-		fprint(2, "Please specify a playlist flag(m, s, r, or p)\n");
+		fprint(2, "Please specify a playlist flag(m, s, r, f, or p)\n");
 		threadexits(nil);
 	}